Don't capture stack-defined lambdas by reference.
This commit is contained in:
parent
7561715ffe
commit
b9ffe2aca8
|
@ -188,9 +188,9 @@ static void isPlated( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
}
|
||||
|
||||
|
||||
static bool insideFootprintCourtyard( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox,
|
||||
bool calcIsInsideCourtyard( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox,
|
||||
std::shared_ptr<SHAPE>& aItemShape, PCB_EXPR_CONTEXT* aCtx,
|
||||
FOOTPRINT* aFootprint, PCB_LAYER_ID aSide = UNDEFINED_LAYER )
|
||||
FOOTPRINT* aFootprint, PCB_LAYER_ID aSide )
|
||||
{
|
||||
SHAPE_POLY_SET footprintCourtyard;
|
||||
|
||||
|
@ -215,6 +215,38 @@ static bool insideFootprintCourtyard( BOARD_ITEM* aItem, const EDA_RECT& aItemBB
|
|||
};
|
||||
|
||||
|
||||
bool isInsideCourtyard( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox,
|
||||
std::shared_ptr<SHAPE>& aItemShape, PCB_EXPR_CONTEXT* aCtx,
|
||||
FOOTPRINT* aFootprint, PCB_LAYER_ID aSide )
|
||||
{
|
||||
if( !aFootprint )
|
||||
return false;
|
||||
|
||||
BOARD* board = aItem->GetBoard();
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
std::pair<BOARD_ITEM*, BOARD_ITEM*> key( aFootprint, aItem );
|
||||
|
||||
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, bool >* cache;
|
||||
|
||||
switch( aSide )
|
||||
{
|
||||
case F_Cu: cache = &board->m_InsideFCourtyardCache; break;
|
||||
case B_Cu: cache = &board->m_InsideBCourtyardCache; break;
|
||||
default: cache = &board->m_InsideCourtyardCache; break;
|
||||
}
|
||||
|
||||
auto i = cache->find( key );
|
||||
|
||||
if( i != cache->end() )
|
||||
return i->second;
|
||||
|
||||
bool res = calcIsInsideCourtyard( aItem, aItemBBox, aItemShape, aCtx, aFootprint, aSide );
|
||||
|
||||
(*cache)[ key ] = res;
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
static void insideCourtyard( LIBEVAL::CONTEXT* aCtx, void* self )
|
||||
{
|
||||
PCB_EXPR_CONTEXT* context = static_cast<PCB_EXPR_CONTEXT*>( aCtx );
|
||||
|
@ -241,30 +273,8 @@ static void insideCourtyard( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
if( !item )
|
||||
return;
|
||||
|
||||
auto insideFootprint =
|
||||
[context]( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox,
|
||||
std::shared_ptr<SHAPE>& aItemShape, FOOTPRINT* aFootprint ) -> bool
|
||||
{
|
||||
if( !aFootprint )
|
||||
return false;
|
||||
|
||||
BOARD* board = aItem->GetBoard();
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
std::pair<BOARD_ITEM*, BOARD_ITEM*> key( aFootprint, aItem );
|
||||
auto i = board->m_InsideCourtyardCache.find( key );
|
||||
|
||||
if( i != board->m_InsideCourtyardCache.end() )
|
||||
return i->second;
|
||||
|
||||
bool res = insideFootprintCourtyard( aItem, aItemBBox, aItemShape, context,
|
||||
aFootprint );
|
||||
|
||||
board->m_InsideCourtyardCache[ key ] = res;
|
||||
return res;
|
||||
};
|
||||
|
||||
result->SetDeferredEval(
|
||||
[item, arg, context, &insideFootprint]() -> double
|
||||
[item, arg, context]() -> double
|
||||
{
|
||||
BOARD* board = item->GetBoard();
|
||||
EDA_RECT itemBBox;
|
||||
|
@ -277,23 +287,24 @@ static void insideCourtyard( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
|
||||
if( arg->AsString() == "A" )
|
||||
{
|
||||
FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( context->GetItem( 0 ) );
|
||||
return insideFootprint( item, itemBBox, itemShape, footprint ) ? 1.0 : 0.0;
|
||||
FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( context->GetItem( 0 ) );
|
||||
|
||||
if( isInsideCourtyard( item, itemBBox, itemShape, context, fp, In1_Cu ) )
|
||||
return 1.0;
|
||||
}
|
||||
else if( arg->AsString() == "B" )
|
||||
{
|
||||
FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( context->GetItem( 1 ) );
|
||||
return insideFootprint( item, itemBBox, itemShape, footprint ) ? 1.0 : 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( FOOTPRINT* candidate : board->Footprints() )
|
||||
{
|
||||
if( candidate->GetReference().Matches( arg->AsString() ) )
|
||||
{
|
||||
if( insideFootprint( item, itemBBox, itemShape, candidate ) )
|
||||
FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( context->GetItem( 1 ) );
|
||||
|
||||
if( isInsideCourtyard( item, itemBBox, itemShape, context, fp, In1_Cu ) )
|
||||
return 1.0;
|
||||
}
|
||||
else for( FOOTPRINT* fp : board->Footprints() )
|
||||
{
|
||||
if( fp->GetReference().Matches( arg->AsString() ) )
|
||||
{
|
||||
if( isInsideCourtyard( item, itemBBox, itemShape, context, fp, In1_Cu ) )
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,30 +339,8 @@ static void insideFrontCourtyard( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
if( !item )
|
||||
return;
|
||||
|
||||
auto insideFootprint =
|
||||
[context]( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox,
|
||||
std::shared_ptr<SHAPE>& aItemShape, FOOTPRINT* aFootprint ) -> bool
|
||||
{
|
||||
if( !aFootprint )
|
||||
return false;
|
||||
|
||||
BOARD* board = aItem->GetBoard();
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
std::pair<BOARD_ITEM*, BOARD_ITEM*> key( aFootprint, aItem );
|
||||
auto i = board->m_InsideFCourtyardCache.find( key );
|
||||
|
||||
if( i != board->m_InsideFCourtyardCache.end() )
|
||||
return i->second;
|
||||
|
||||
bool res = insideFootprintCourtyard( aItem, aItemBBox, aItemShape, context,
|
||||
aFootprint, F_Cu );
|
||||
|
||||
board->m_InsideFCourtyardCache[ key ] = res;
|
||||
return res;
|
||||
};
|
||||
|
||||
result->SetDeferredEval(
|
||||
[item, arg, context, &insideFootprint]() -> double
|
||||
[item, arg, context]() -> double
|
||||
{
|
||||
BOARD* board = item->GetBoard();
|
||||
EDA_RECT itemBBox;
|
||||
|
@ -364,23 +353,24 @@ static void insideFrontCourtyard( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
|
||||
if( arg->AsString() == "A" )
|
||||
{
|
||||
FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( context->GetItem( 0 ) );
|
||||
return insideFootprint( item, itemBBox, itemShape, footprint ) ? 1.0 : 0.0;
|
||||
FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( context->GetItem( 0 ) );
|
||||
|
||||
if( isInsideCourtyard( item, itemBBox, itemShape, context, fp, F_Cu ) )
|
||||
return 1.0;
|
||||
}
|
||||
else if( arg->AsString() == "B" )
|
||||
{
|
||||
FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( context->GetItem( 1 ) );
|
||||
return insideFootprint( item, itemBBox, itemShape, footprint ) ? 1.0 : 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( FOOTPRINT* candidate : board->Footprints() )
|
||||
{
|
||||
if( candidate->GetReference().Matches( arg->AsString() ) )
|
||||
{
|
||||
if( insideFootprint( item, itemBBox, itemShape, candidate ) )
|
||||
FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( context->GetItem( 1 ) );
|
||||
|
||||
if( isInsideCourtyard( item, itemBBox, itemShape, context, fp, F_Cu ) )
|
||||
return 1.0;
|
||||
}
|
||||
else for( FOOTPRINT* fp : board->Footprints() )
|
||||
{
|
||||
if( fp->GetReference().Matches( arg->AsString() ) )
|
||||
{
|
||||
if( isInsideCourtyard( item, itemBBox, itemShape, context, fp, F_Cu ) )
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,30 +404,8 @@ static void insideBackCourtyard( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
if( !item )
|
||||
return;
|
||||
|
||||
auto insideFootprint =
|
||||
[context]( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox,
|
||||
std::shared_ptr<SHAPE>& aItemShape, FOOTPRINT* aFootprint ) -> bool
|
||||
{
|
||||
if( !aFootprint )
|
||||
return false;
|
||||
|
||||
BOARD* board = aItem->GetBoard();
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
std::pair<BOARD_ITEM*, BOARD_ITEM*> key( aFootprint, aItem );
|
||||
auto i = board->m_InsideBCourtyardCache.find( key );
|
||||
|
||||
if( i != board->m_InsideBCourtyardCache.end() )
|
||||
return i->second;
|
||||
|
||||
bool res = insideFootprintCourtyard( aItem, aItemBBox, aItemShape, context,
|
||||
aFootprint, B_Cu );
|
||||
|
||||
board->m_InsideBCourtyardCache[ key ] = res;
|
||||
return res;
|
||||
};
|
||||
|
||||
result->SetDeferredEval(
|
||||
[item, arg, context, &insideFootprint]() -> double
|
||||
[item, arg, context]() -> double
|
||||
{
|
||||
BOARD* board = item->GetBoard();
|
||||
EDA_RECT itemBBox;
|
||||
|
@ -450,23 +418,24 @@ static void insideBackCourtyard( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
|
||||
if( arg->AsString() == "A" )
|
||||
{
|
||||
FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( context->GetItem( 0 ) );
|
||||
return insideFootprint( item, itemBBox, itemShape, footprint ) ? 1.0 : 0.0;
|
||||
FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( context->GetItem( 0 ) );
|
||||
|
||||
if( isInsideCourtyard( item, itemBBox, itemShape, context, fp, B_Cu ) )
|
||||
return 1.0;
|
||||
}
|
||||
else if( arg->AsString() == "B" )
|
||||
{
|
||||
FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( context->GetItem( 1 ) );
|
||||
return insideFootprint( item, itemBBox, itemShape, footprint ) ? 1.0 : 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( FOOTPRINT* candidate : board->Footprints() )
|
||||
{
|
||||
if( candidate->GetReference().Matches( arg->AsString() ) )
|
||||
{
|
||||
if( insideFootprint( item, itemBBox, itemShape, candidate ) )
|
||||
FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( context->GetItem( 1 ) );
|
||||
|
||||
if( isInsideCourtyard( item, itemBBox, itemShape, context, fp, B_Cu ) )
|
||||
return 1.0;
|
||||
}
|
||||
else for( FOOTPRINT* fp : board->Footprints() )
|
||||
{
|
||||
if( fp->GetReference().Matches( arg->AsString() ) )
|
||||
{
|
||||
if( isInsideCourtyard( item, itemBBox, itemShape, context, fp, B_Cu ) )
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -475,35 +444,9 @@ static void insideBackCourtyard( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
}
|
||||
|
||||
|
||||
static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
||||
bool calcIsInsideArea( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox, PCB_EXPR_CONTEXT* aCtx,
|
||||
ZONE* aArea )
|
||||
{
|
||||
PCB_EXPR_CONTEXT* context = static_cast<PCB_EXPR_CONTEXT*>( aCtx );
|
||||
LIBEVAL::VALUE* arg = aCtx->Pop();
|
||||
LIBEVAL::VALUE* result = aCtx->AllocValue();
|
||||
|
||||
result->Set( 0.0 );
|
||||
aCtx->Push( result );
|
||||
|
||||
if( !arg )
|
||||
{
|
||||
if( aCtx->HasErrorCallback() )
|
||||
{
|
||||
aCtx->ReportError( wxString::Format( _( "Missing argument to '%s'" ),
|
||||
wxT( "insideArea()" ) ) );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
|
||||
BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
|
||||
|
||||
if( !item )
|
||||
return;
|
||||
|
||||
auto itemIsInsideArea =
|
||||
[context]( BOARD_ITEM* aItem, ZONE* aArea, const EDA_RECT& aItemBBox ) -> bool
|
||||
{
|
||||
BOARD* board = aArea->GetBoard();
|
||||
std::shared_ptr<SHAPE> shape;
|
||||
|
||||
|
@ -543,10 +486,9 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
|
||||
if( ( footprint->GetFlags() & MALFORMED_COURTYARDS ) != 0 )
|
||||
{
|
||||
if( context->HasErrorCallback() )
|
||||
if( aCtx->HasErrorCallback() )
|
||||
{
|
||||
context->ReportError( _( "Footprint's courtyard is not a single, "
|
||||
"closed shape." ) );
|
||||
aCtx->ReportError( _( "Footprint's courtyard is not a single, closed shape." ) );
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -558,8 +500,8 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
|
||||
if( courtyard.OutlineCount() == 0 )
|
||||
{
|
||||
if( context->HasErrorCallback() )
|
||||
context->ReportError( _( "Footprint has no front courtyard." ) );
|
||||
if( aCtx->HasErrorCallback() )
|
||||
aCtx->ReportError( _( "Footprint has no front courtyard." ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -575,8 +517,8 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
|
||||
if( courtyard.OutlineCount() == 0 )
|
||||
{
|
||||
if( context->HasErrorCallback() )
|
||||
context->ReportError( _( "Footprint has no back courtyard." ) );
|
||||
if( aCtx->HasErrorCallback() )
|
||||
aCtx->ReportError( _( "Footprint has no back courtyard." ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -614,15 +556,16 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
else
|
||||
{
|
||||
if( !shape )
|
||||
shape = aItem->GetEffectiveShape( context->GetLayer() );
|
||||
shape = aItem->GetEffectiveShape( aCtx->GetLayer() );
|
||||
|
||||
return areaOutline.Collide( shape.get() );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
auto checkArea =
|
||||
[&itemIsInsideArea]( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox, ZONE* aArea ) -> bool
|
||||
{
|
||||
|
||||
bool isInsideArea( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox, PCB_EXPR_CONTEXT* aCtx,
|
||||
ZONE* aArea )
|
||||
{
|
||||
if( !aArea || aArea == aItem || aArea->GetParent() == aItem )
|
||||
return false;
|
||||
|
||||
|
@ -634,14 +577,41 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
if( i != board->m_InsideAreaCache.end() )
|
||||
return i->second;
|
||||
|
||||
bool isInside = itemIsInsideArea( aItem, aArea, aItemBBox );
|
||||
bool isInside = calcIsInsideArea( aItem, aItemBBox, aCtx, aArea );
|
||||
|
||||
board->m_InsideAreaCache[ key ] = isInside;
|
||||
return isInside;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
||||
{
|
||||
PCB_EXPR_CONTEXT* context = static_cast<PCB_EXPR_CONTEXT*>( aCtx );
|
||||
LIBEVAL::VALUE* arg = aCtx->Pop();
|
||||
LIBEVAL::VALUE* result = aCtx->AllocValue();
|
||||
|
||||
result->Set( 0.0 );
|
||||
aCtx->Push( result );
|
||||
|
||||
if( !arg )
|
||||
{
|
||||
if( aCtx->HasErrorCallback() )
|
||||
{
|
||||
aCtx->ReportError( wxString::Format( _( "Missing argument to '%s'" ),
|
||||
wxT( "insideArea()" ) ) );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
|
||||
BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
|
||||
|
||||
if( !item )
|
||||
return;
|
||||
|
||||
result->SetDeferredEval(
|
||||
[item, arg, context, &checkArea]() -> double
|
||||
[item, arg, context]() -> double
|
||||
{
|
||||
BOARD* board = item->GetBoard();
|
||||
EDA_RECT itemBBox;
|
||||
|
@ -654,12 +624,12 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
if( arg->AsString() == "A" )
|
||||
{
|
||||
ZONE* zone = dynamic_cast<ZONE*>( context->GetItem( 0 ) );
|
||||
return checkArea( item, itemBBox, zone ) ? 1.0 : 0.0;
|
||||
return isInsideArea( item, itemBBox, context, zone ) ? 1.0 : 0.0;
|
||||
}
|
||||
else if( arg->AsString() == "B" )
|
||||
{
|
||||
ZONE* zone = dynamic_cast<ZONE*>( context->GetItem( 1 ) );
|
||||
return checkArea( item, itemBBox, zone ) ? 1.0 : 0.0;
|
||||
return isInsideArea( item, itemBBox, context, zone ) ? 1.0 : 0.0;
|
||||
}
|
||||
else if( KIID::SniffTest( arg->AsString() ) )
|
||||
{
|
||||
|
@ -670,7 +640,7 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
// Only a single zone can match the UUID; exit once we find a match whether
|
||||
// "inside" or not
|
||||
if( area->m_Uuid == target )
|
||||
return checkArea( item, itemBBox, area ) ? 1.0 : 0.0;
|
||||
return isInsideArea( item, itemBBox, context, area ) ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
for( FOOTPRINT* footprint : board->Footprints() )
|
||||
|
@ -680,7 +650,7 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
// Only a single zone can match the UUID; exit once we find a match
|
||||
// whether "inside" or not
|
||||
if( area->m_Uuid == target )
|
||||
return checkArea( item, itemBBox, area ) ? 1.0 : 0.0;
|
||||
return isInsideArea( item, itemBBox, context, area ) ? 1.0 : 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -693,7 +663,7 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
if( area->GetZoneName().Matches( arg->AsString() ) )
|
||||
{
|
||||
// Many zones can match the name; exit only when we find an "inside"
|
||||
if( checkArea( item, itemBBox, area ) )
|
||||
if( isInsideArea( item, itemBBox, context, area ) )
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
@ -705,7 +675,7 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
// Many zones can match the name; exit only when we find an "inside"
|
||||
if( area->GetZoneName().Matches( arg->AsString() ) )
|
||||
{
|
||||
if( checkArea( item, itemBBox, area ) )
|
||||
if( isInsideArea( item, itemBBox, context, area ) )
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue