Performance improvements for DRC rules.

This commit is contained in:
Jeff Young 2021-01-11 22:08:07 +00:00
parent a36f655dcd
commit 63e2046eb0
3 changed files with 91 additions and 7 deletions

View File

@ -265,6 +265,12 @@ public:
class CONTEXT
{
public:
CONTEXT() :
m_stackPtr( 0 )
{
m_ownedValues.reserve( 20 );
}
virtual ~CONTEXT()
{
for( VALUE* value : m_ownedValues )
@ -280,25 +286,23 @@ public:
void Push( VALUE* v )
{
m_stack.push( v );
m_stack[ m_stackPtr++ ] = v;
}
VALUE* Pop()
{
if( m_stack.size() == 0 )
if( m_stackPtr == 0 )
{
ReportError( _( "Malformed expression" ) );
return AllocValue();
}
VALUE* value = m_stack.top();
m_stack.pop();
return value;
return m_stack[ --m_stackPtr ];
}
int SP() const
{
return m_stack.size();
return m_stackPtr;
};
void SetErrorCallback( std::function<void( const wxString& aMessage, int aOffset )> aCallback )
@ -312,7 +316,8 @@ public:
private:
std::vector<VALUE*> m_ownedValues;
std::stack<VALUE*> m_stack;
VALUE* m_stack[100]; // std::stack not performant enough
int m_stackPtr;
ERROR_STATUS m_errorStatus;
std::function<void( const wxString& aMessage, int aOffset )> m_errorCallback;

View File

@ -613,6 +613,34 @@ LIBEVAL::VALUE PCB_EXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
}
LIBEVAL::VALUE PCB_EXPR_NETCLASS_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
{
BOARD_ITEM* item = GetObject( aCtx );
if( !item )
return LIBEVAL::VALUE();
if( item->IsConnected() )
return LIBEVAL::VALUE( static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetClassName() );
else
return LIBEVAL::VALUE();
}
LIBEVAL::VALUE PCB_EXPR_NETNAME_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
{
BOARD_ITEM* item = GetObject( aCtx );
if( !item )
return LIBEVAL::VALUE();
if( item->IsConnected() )
return LIBEVAL::VALUE( static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetname() );
else
return LIBEVAL::VALUE();
}
LIBEVAL::FUNC_CALL_REF PCB_EXPR_UCODE::CreateFuncCall( const wxString& aName )
{
PCB_EXPR_BUILTIN_FUNCTIONS& registry = PCB_EXPR_BUILTIN_FUNCTIONS::Instance();
@ -627,6 +655,27 @@ std::unique_ptr<LIBEVAL::VAR_REF> PCB_EXPR_UCODE::CreateVarRef( const wxString&
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
std::unique_ptr<PCB_EXPR_VAR_REF> vref;
// Check for a couple of very common cases and compile them straight to "object code".
if( aField.CmpNoCase( "NetClass" ) )
{
if( aVar == "A" )
return std::make_unique<PCB_EXPR_NETCLASS_REF>( 0 );
else if( aVar == "B" )
return std::make_unique<PCB_EXPR_NETCLASS_REF>( 1 );
else
return nullptr;
}
else if( aField.CmpNoCase( "NetName" ) )
{
if( aVar == "A" )
return std::make_unique<PCB_EXPR_NETNAME_REF>( 0 );
else if( aVar == "B" )
return std::make_unique<PCB_EXPR_NETNAME_REF>( 1 );
else
return nullptr;
}
if( aVar == "A" )
vref = std::make_unique<PCB_EXPR_VAR_REF>( 0 );
else if( aVar == "B" )

View File

@ -116,6 +116,36 @@ private:
};
// "Object code" version of a netclass reference (for performance).
class PCB_EXPR_NETCLASS_REF : public PCB_EXPR_VAR_REF
{
public:
PCB_EXPR_NETCLASS_REF( int aItemIndex ) :
PCB_EXPR_VAR_REF( aItemIndex )
{
SetType( LIBEVAL::VT_STRING );
//printf("*** CreateVarRef %p %d\n", this, aItemIndex );
}
LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx ) override;
};
// "Object code" version of a netname reference (for performance).
class PCB_EXPR_NETNAME_REF : public PCB_EXPR_VAR_REF
{
public:
PCB_EXPR_NETNAME_REF( int aItemIndex ) :
PCB_EXPR_VAR_REF( aItemIndex )
{
SetType( LIBEVAL::VT_STRING );
//printf("*** CreateVarRef %p %d\n", this, aItemIndex );
}
LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx ) override;
};
class PCB_EXPR_BUILTIN_FUNCTIONS
{
public: