KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbexpr_evaluator.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24
25#include <cstdio>
26#include <memory>
27#include <mutex>
28#include <board.h>
29#include <footprint.h>
30#include <lset.h>
32#include <pcbexpr_evaluator.h>
33#include <drc/drc_engine.h>
34
35/* --------------------------------------------------------------------------------------------
36 * Specialized Expression References
37 */
38
40{
41 wxASSERT( dynamic_cast<const PCBEXPR_CONTEXT*>( aCtx ) );
42
43 const PCBEXPR_CONTEXT* ctx = static_cast<const PCBEXPR_CONTEXT*>( aCtx );
44 BOARD_ITEM* item = ctx->GetItem( m_itemIndex );
45 return item;
46}
47
48
50{
51public:
53 LIBEVAL::VALUE( LayerName( aLayer ) ),
54 m_layer( aLayer )
55 {};
56
57 virtual bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override
58 {
59 // For boards with user-defined layer names there will be 2 entries for each layer
60 // in the ENUM_MAP: one for the canonical layer name and one for the user layer name.
61 // We need to check against both.
62
63 wxPGChoices& layerMap = ENUM_MAP<PCB_LAYER_ID>::Instance().Choices();
64 const wxString& layerName = b->AsString();
65 BOARD* board = static_cast<PCBEXPR_CONTEXT*>( aCtx )->GetBoard();
66
67 {
68 std::shared_lock<std::shared_mutex> readLock( board->m_CachesMutex );
69
70 auto i = board->m_LayerExpressionCache.find( layerName );
71
72 if( i != board->m_LayerExpressionCache.end() )
73 return i->second.Contains( m_layer );
74 }
75
76 LSET mask;
77
78 for( unsigned ii = 0; ii < layerMap.GetCount(); ++ii )
79 {
80 wxPGChoiceEntry& entry = layerMap[ii];
81
82 if( entry.GetText().Matches( layerName ) )
83 mask.set( ToLAYER_ID( entry.GetValue() ) );
84 }
85
86 {
87 std::unique_lock<std::shared_mutex> writeLock( board->m_CachesMutex );
88 board->m_LayerExpressionCache[ layerName ] = mask;
89 }
90
91 return mask.Contains( m_layer );
92 }
93
94protected:
96};
97
98
100{
101public:
102 PCBEXPR_PINTYPE_VALUE( const wxString& aPinTypeName ) :
103 LIBEVAL::VALUE( aPinTypeName )
104 {};
105
106 bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override
107 {
108 const wxString& thisStr = AsString();
109 const wxString& otherStr = b->AsString();
110
111 // Case insensitive
112 if( thisStr.IsSameAs( otherStr, false ) )
113 return true;
114
115 // Wildcards
116 if( thisStr.Matches( otherStr ) )
117 return true;
118
119 // Handle cases where the netlist token is different from the EEschema token
120 wxString altStr;
121
122 if( thisStr == wxT( "tri_state" ) )
123 altStr = wxT( "Tri-state" );
124 else if( thisStr == wxT( "power_in" ) )
125 altStr = wxT( "Power input" );
126 else if( thisStr == wxT( "power_out" ) )
127 altStr = wxT( "Power output" );
128 else if( thisStr == wxT( "no_connect" ) )
129 altStr = wxT( "Unconnected" );
130
131 if( !altStr.IsEmpty() )
132 {
133 // Case insensitive
134 if( altStr.IsSameAs( otherStr, false ) )
135 return true;
136
137 // Wildcards
138 if( altStr.Matches( otherStr ) )
139 return true;
140 }
141
142 return false;
143 }
144};
145
146
148{
149public:
151 LIBEVAL::VALUE( wxEmptyString ),
152 m_item( aItem )
153 {};
154
155 const wxString& AsString() const override
156 {
157 const_cast<PCBEXPR_NETCLASS_VALUE*>( this )->Set(
160 }
161
162 bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override
163 {
164 if( const PCBEXPR_NETCLASS_VALUE* bValue = dynamic_cast<const PCBEXPR_NETCLASS_VALUE*>( b ) )
165 {
166 return *( m_item->GetEffectiveNetClass() )
167 == *( bValue->m_item->GetEffectiveNetClass() );
168 }
169 else
170 {
171 return LIBEVAL::VALUE::EqualTo( aCtx, b );
172 }
173 }
174
175 bool NotEqualTo( LIBEVAL::CONTEXT* aCtx, const LIBEVAL::VALUE* b ) const override
176 {
177 if( const PCBEXPR_NETCLASS_VALUE* bValue = dynamic_cast<const PCBEXPR_NETCLASS_VALUE*>( b ) )
178 return m_item->GetEffectiveNetClass() != bValue->m_item->GetEffectiveNetClass();
179 else
180 return LIBEVAL::VALUE::NotEqualTo( aCtx, b );
181 }
182
183protected:
185};
186
187
189{
190public:
192 LIBEVAL::VALUE( wxEmptyString ), m_item( dynamic_cast<FOOTPRINT*>( aItem ) )
193 {};
194
195 const wxString& AsString() const override
196 {
197 if( !m_item )
199
200 if( const COMPONENT_CLASS* compClass = m_item->GetComponentClass() )
201 const_cast<PCBEXPR_COMPONENT_CLASS_VALUE*>( this )->Set( compClass->GetFullName() );
202
204 }
205
206 bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override
207 {
208 if( const PCBEXPR_COMPONENT_CLASS_VALUE* bValue =
209 dynamic_cast<const PCBEXPR_COMPONENT_CLASS_VALUE*>( b ) )
210 {
211 if( !m_item || !bValue->m_item )
212 return LIBEVAL::VALUE::EqualTo( aCtx, b );
213
214 const COMPONENT_CLASS* aClass = m_item->GetComponentClass();
215 const COMPONENT_CLASS* bClass = bValue->m_item->GetComponentClass();
216
217 // Note this depends on COMPONENT_CLASS_MANAGER maintaining ownership
218 // of all unique component class objects
219 return aClass == bClass;
220 }
221 else
222 {
223 return LIBEVAL::VALUE::EqualTo( aCtx, b );
224 }
225 }
226
227 bool NotEqualTo( LIBEVAL::CONTEXT* aCtx, const LIBEVAL::VALUE* b ) const override
228 {
229 if( const PCBEXPR_COMPONENT_CLASS_VALUE* bValue =
230 dynamic_cast<const PCBEXPR_COMPONENT_CLASS_VALUE*>( b ) )
231 {
232 if( !m_item || !bValue->m_item )
233 return LIBEVAL::VALUE::EqualTo( aCtx, b );
234
235 const COMPONENT_CLASS* aClass = m_item->GetComponentClass();
236 const COMPONENT_CLASS* bClass = bValue->m_item->GetComponentClass();
237
238 // Note this depends on COMPONENT_CLASS_MANAGER maintaining ownership
239 // of all unique component class objects
240 return aClass != bClass;
241 }
242 else
243 {
244 return LIBEVAL::VALUE::NotEqualTo( aCtx, b );
245 }
246 }
247
248protected:
250};
251
252
254{
255public:
257 LIBEVAL::VALUE( wxEmptyString ),
258 m_item( aItem )
259 {};
260
261 const wxString& AsString() const override
262 {
263 const_cast<PCBEXPR_NET_VALUE*>( this )->Set( m_item->GetNetname() );
265 }
266
267 bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override
268 {
269 if( const PCBEXPR_NET_VALUE* bValue = dynamic_cast<const PCBEXPR_NET_VALUE*>( b ) )
270 return m_item->GetNetCode() == bValue->m_item->GetNetCode();
271 else
272 return LIBEVAL::VALUE::EqualTo( aCtx, b );
273 }
274
275 bool NotEqualTo( LIBEVAL::CONTEXT* aCtx, const LIBEVAL::VALUE* b ) const override
276 {
277 if( const PCBEXPR_NET_VALUE* bValue = dynamic_cast<const PCBEXPR_NET_VALUE*>( b ) )
278 return m_item->GetNetCode() != bValue->m_item->GetNetCode();
279 else
280 return LIBEVAL::VALUE::NotEqualTo( aCtx, b );
281 }
282
283protected:
285};
286
287
289{
290 PCBEXPR_CONTEXT* context = static_cast<PCBEXPR_CONTEXT*>( aCtx );
291
292 if( m_type == LIBEVAL::VT_NULL )
294
295 if( m_itemIndex == 2 )
296 return new PCBEXPR_LAYER_VALUE( context->GetLayer() );
297
298 BOARD_ITEM* item = GetObject( aCtx );
299
300 if( !item )
301 return new LIBEVAL::VALUE();
302
303 auto it = m_matchingTypes.find( TYPE_HASH( *item ) );
304
305 if( it == m_matchingTypes.end() )
306 {
307 // Don't force user to type "A.Type == 'via' && A.Via_Type == 'buried'" when the
308 // simpler "A.Via_Type == 'buried'" is perfectly clear. Instead, return an undefined
309 // value when the property doesn't appear on a particular object.
310
311 return new LIBEVAL::VALUE();
312 }
313 else
314 {
316 {
317 if( m_isOptional )
318 {
319 auto val = item->Get<std::optional<int>>( it->second );
320
321 if( val.has_value() )
322 return new LIBEVAL::VALUE( static_cast<double>( val.value() ) );
323
325 }
326
327 return new LIBEVAL::VALUE( static_cast<double>( item->Get<int>( it->second ) ) );
328 }
329 else
330 {
331 wxString str;
332
333 if( !m_isEnum )
334 {
335 str = item->Get<wxString>( it->second );
336
337 if( it->second->Name() == wxT( "Pin Type" ) )
338 return new PCBEXPR_PINTYPE_VALUE( str );
339 else
340 return new LIBEVAL::VALUE( str );
341 }
342 else
343 {
344 const wxAny& any = item->Get( it->second );
345 PCB_LAYER_ID layer;
346
347 if( it->second->Name() == wxT( "Layer" )
348 || it->second->Name() == wxT( "Layer Top" )
349 || it->second->Name() == wxT( "Layer Bottom" ) )
350 {
351 if( any.GetAs<PCB_LAYER_ID>( &layer ) )
352 return new PCBEXPR_LAYER_VALUE( layer );
353 else if( any.GetAs<wxString>( &str ) )
354 return new PCBEXPR_LAYER_VALUE( context->GetBoard()->GetLayerID( str ) );
355 }
356 else
357 {
358 if( any.GetAs<wxString>( &str ) )
359 return new LIBEVAL::VALUE( str );
360 }
361 }
362
363 return new LIBEVAL::VALUE();
364 }
365 }
366}
367
368
370{
371 BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( GetObject( aCtx ) );
372
373 if( !item )
374 return new LIBEVAL::VALUE();
375
376 return new PCBEXPR_NETCLASS_VALUE( item );
377}
378
379
381{
382 BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( GetObject( aCtx ) );
383
384 if( !item || item->Type() != PCB_FOOTPRINT_T )
385 return new LIBEVAL::VALUE();
386
387 return new PCBEXPR_COMPONENT_CLASS_VALUE( item );
388}
389
390
392{
393 BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( GetObject( aCtx ) );
394
395 if( !item )
396 return new LIBEVAL::VALUE();
397
398 return new PCBEXPR_NET_VALUE( item );
399}
400
401
403{
404 BOARD_ITEM* item = GetObject( aCtx );
405
406 if( !item )
407 return new LIBEVAL::VALUE();
408
409 return new LIBEVAL::VALUE( ENUM_MAP<KICAD_T>::Instance().ToString( item->Type() ) );
410}
411
412
414{
416
417 return registry.Get( aName.Lower() );
418}
419
420
421std::unique_ptr<LIBEVAL::VAR_REF> PCBEXPR_UCODE::CreateVarRef( const wxString& aVar,
422 const wxString& aField )
423{
425 std::unique_ptr<PCBEXPR_VAR_REF> vref;
426
427 if( aVar.IsSameAs( wxT( "null" ), false ) )
428 {
429 vref = std::make_unique<PCBEXPR_VAR_REF>( 0 );
430 vref->SetType( LIBEVAL::VT_NULL );
431 return vref;
432 }
433
434 // Check for a couple of very common cases and compile them straight to "object code".
435
436 if( aField.CmpNoCase( wxT( "NetClass" ) ) == 0 )
437 {
438 if( aVar == wxT( "A" ) )
439 return std::make_unique<PCBEXPR_NETCLASS_REF>( 0 );
440 else if( aVar == wxT( "B" ) )
441 return std::make_unique<PCBEXPR_NETCLASS_REF>( 1 );
442 else
443 return nullptr;
444 }
445 else if( aField.CmpNoCase( wxT( "ComponentClass" ) ) == 0 )
446 {
447 if( aVar == wxT( "A" ) )
448 return std::make_unique<PCBEXPR_COMPONENT_CLASS_REF>( 0 );
449 else if( aVar == wxT( "B" ) )
450 return std::make_unique<PCBEXPR_COMPONENT_CLASS_REF>( 1 );
451 else
452 return nullptr;
453 }
454 else if( aField.CmpNoCase( wxT( "NetName" ) ) == 0 )
455 {
456 if( aVar == wxT( "A" ) )
457 return std::make_unique<PCBEXPR_NETNAME_REF>( 0 );
458 else if( aVar == wxT( "B" ) )
459 return std::make_unique<PCBEXPR_NETNAME_REF>( 1 );
460 else
461 return nullptr;
462 }
463 else if( aField.CmpNoCase( wxT( "Type" ) ) == 0 )
464 {
465 if( aVar == wxT( "A" ) )
466 return std::make_unique<PCBEXPR_TYPE_REF>( 0 );
467 else if( aVar == wxT( "B" ) )
468 return std::make_unique<PCBEXPR_TYPE_REF>( 1 );
469 else
470 return nullptr;
471 }
472
473 if( aVar == wxT( "A" ) || aVar == wxT( "AB" ) )
474 vref = std::make_unique<PCBEXPR_VAR_REF>( 0 );
475 else if( aVar == wxT( "B" ) )
476 vref = std::make_unique<PCBEXPR_VAR_REF>( 1 );
477 else if( aVar == wxT( "L" ) )
478 vref = std::make_unique<PCBEXPR_VAR_REF>( 2 );
479 else
480 return nullptr;
481
482 if( aField.length() == 0 ) // return reference to base object
483 return vref;
484
485 wxString field( aField );
486 field.Replace( wxT( "_" ), wxT( " " ) );
487
488 for( const PROPERTY_MANAGER::CLASS_INFO& cls : propMgr.GetAllClasses() )
489 {
490 if( propMgr.IsOfType( cls.type, TYPE_HASH( BOARD_ITEM ) ) )
491 {
492 PROPERTY_BASE* prop = propMgr.GetProperty( cls.type, field );
493
494 if( prop )
495 {
496 vref->AddAllowedClass( cls.type, prop );
497
498 if( prop->TypeHash() == TYPE_HASH( int ) )
499 {
500 vref->SetType( LIBEVAL::VT_NUMERIC );
501 }
502 else if( prop->TypeHash() == TYPE_HASH( std::optional<int> ) )
503 {
504 vref->SetType( LIBEVAL::VT_NUMERIC );
505 vref->SetIsOptional();
506 }
507 else if( prop->TypeHash() == TYPE_HASH( bool ) )
508 {
509 vref->SetType( LIBEVAL::VT_NUMERIC );
510 }
511 else if( prop->TypeHash() == TYPE_HASH( wxString ) )
512 {
513 vref->SetType( LIBEVAL::VT_STRING );
514 }
515 else if ( prop->HasChoices() )
516 { // it's an enum, we treat it as string
517 vref->SetType( LIBEVAL::VT_STRING );
518 vref->SetIsEnum( true );
519 }
520 else
521 {
522 wxString msg = wxString::Format( wxT( "PCBEXPR_UCODE::createVarRef: Unknown "
523 "property type %s from %s." ),
524 cls.name,
525 field );
526 wxFAIL_MSG( msg );
527 }
528 }
529 }
530 }
531
532 if( vref->GetType() == LIBEVAL::VT_UNDEFINED )
533 vref->SetType( LIBEVAL::VT_PARSE_ERROR );
534
535 return vref;
536}
537
538
540{
541 if( m_items[0] )
542 return m_items[0]->GetBoard();
543
544 return nullptr;
545}
546
547
548/* --------------------------------------------------------------------------------------------
549 * Unit Resolvers
550 */
551
552const std::vector<wxString>& PCBEXPR_UNIT_RESOLVER::GetSupportedUnits() const
553{
554 static const std::vector<wxString> pcbUnits = { wxT( "mil" ), wxT( "mm" ), wxT( "in" ) };
555
556 return pcbUnits;
557}
558
559
561{
562 return _( "must be mm, in, or mil" );
563}
564
565
566double PCBEXPR_UNIT_RESOLVER::Convert( const wxString& aString, int unitId ) const
567{
568 double v = wxAtof( aString );
569
570 switch( unitId )
571 {
572 case 0: return EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::MILS, aString );
573 case 1: return EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::MILLIMETRES, aString );
574 case 2: return EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::INCHES, aString );
575 default: return v;
576 }
577};
578
579
580const std::vector<wxString>& PCBEXPR_UNITLESS_RESOLVER::GetSupportedUnits() const
581{
582 static const std::vector<wxString> emptyUnits;
583
584 return emptyUnits;
585}
586
587
588double PCBEXPR_UNITLESS_RESOLVER::Convert( const wxString& aString, int unitId ) const
589{
590 return wxAtof( aString );
591};
592
593
595{
596 m_unitResolver.reset( aUnitResolver );
597}
598
599
600/* --------------------------------------------------------------------------------------------
601 * PCB Expression Evaluator
602 */
603
605 m_result( 0 ),
606 m_compiler( aUnitResolver ),
607 m_ucode(),
608 m_errorStatus()
609{
610}
611
612
614{
615}
616
617
618bool PCBEXPR_EVALUATOR::Evaluate( const wxString& aExpr )
619{
620 PCBEXPR_UCODE ucode;
621 PCBEXPR_CONTEXT preflightContext( NULL_CONSTRAINT, F_Cu );
622
623 if( !m_compiler.Compile( aExpr.ToUTF8().data(), &ucode, &preflightContext ) )
624 return false;
625
626 PCBEXPR_CONTEXT evaluationContext( NULL_CONSTRAINT, F_Cu );
627 LIBEVAL::VALUE* result = ucode.Run( &evaluationContext );
628
629 if( result->GetType() == LIBEVAL::VT_NUMERIC )
630 m_result = KiROUND( result->AsDouble() );
631
632 return true;
633}
634
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
BASE_SET & set(size_t pos)
Definition: base_set.h:116
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual NETCLASS * GetEffectiveNetClass() const
Return the NETCLASS for this item.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:47
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:295
PCB_LAYER_ID GetLayerID(const wxString &aLayerName) const
Return the ID of a layer.
Definition: board.cpp:593
std::unordered_map< wxString, LSET > m_LayerExpressionCache
Definition: board.h:1310
std::shared_mutex m_CachesMutex
Definition: board.h:1304
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
static ENUM_MAP< T > & Instance()
Definition: property.h:680
const COMPONENT_CLASS * GetComponentClass() const
Definition: footprint.h:1026
wxAny Get(PROPERTY_BASE *aProperty) const
Definition: inspectable.h:100
std::unique_ptr< UNIT_RESOLVER > m_unitResolver
bool Compile(const wxString &aString, UCODE *aCode, CONTEXT *aPreflightContext)
VALUE * Run(CONTEXT *ctx)
void Set(double aValue)
virtual const wxString & AsString() const
static VALUE * MakeNullValue()
virtual bool NotEqualTo(CONTEXT *aCtx, const VALUE *b) const
virtual double AsDouble() const
VAR_TYPE_T GetType() const
virtual bool EqualTo(CONTEXT *aCtx, const VALUE *b) const
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
Definition: lset.h:63
const wxString GetName() const
Gets the name of this (maybe aggregate) netclass in a format for internal usage or for export to exte...
Definition: netclass.cpp:314
LIBEVAL::FUNC_CALL_REF Get(const wxString &name)
static PCBEXPR_BUILTIN_FUNCTIONS & Instance()
PCBEXPR_COMPILER(LIBEVAL::UNIT_RESOLVER *aUnitResolver)
LIBEVAL::VALUE * GetValue(LIBEVAL::CONTEXT *aCtx) override
bool NotEqualTo(LIBEVAL::CONTEXT *aCtx, const LIBEVAL::VALUE *b) const override
const wxString & AsString() const override
PCBEXPR_COMPONENT_CLASS_VALUE(BOARD_ITEM *aItem)
bool EqualTo(LIBEVAL::CONTEXT *aCtx, const VALUE *b) const override
BOARD_ITEM * m_items[2]
BOARD * GetBoard() const
PCB_LAYER_ID GetLayer() const
BOARD_ITEM * GetItem(int index) const
PCBEXPR_EVALUATOR(LIBEVAL::UNIT_RESOLVER *aUnitResolver)
PCBEXPR_COMPILER m_compiler
bool Evaluate(const wxString &aExpr)
PCBEXPR_LAYER_VALUE(PCB_LAYER_ID aLayer)
virtual bool EqualTo(LIBEVAL::CONTEXT *aCtx, const VALUE *b) const override
LIBEVAL::VALUE * GetValue(LIBEVAL::CONTEXT *aCtx) override
bool EqualTo(LIBEVAL::CONTEXT *aCtx, const VALUE *b) const override
BOARD_CONNECTED_ITEM * m_item
PCBEXPR_NETCLASS_VALUE(BOARD_CONNECTED_ITEM *aItem)
const wxString & AsString() const override
bool NotEqualTo(LIBEVAL::CONTEXT *aCtx, const LIBEVAL::VALUE *b) const override
LIBEVAL::VALUE * GetValue(LIBEVAL::CONTEXT *aCtx) override
bool EqualTo(LIBEVAL::CONTEXT *aCtx, const VALUE *b) const override
BOARD_CONNECTED_ITEM * m_item
PCBEXPR_NET_VALUE(BOARD_CONNECTED_ITEM *aItem)
bool NotEqualTo(LIBEVAL::CONTEXT *aCtx, const LIBEVAL::VALUE *b) const override
const wxString & AsString() const override
bool EqualTo(LIBEVAL::CONTEXT *aCtx, const VALUE *b) const override
PCBEXPR_PINTYPE_VALUE(const wxString &aPinTypeName)
LIBEVAL::VALUE * GetValue(LIBEVAL::CONTEXT *aCtx) override
virtual std::unique_ptr< LIBEVAL::VAR_REF > CreateVarRef(const wxString &aVar, const wxString &aField) override
virtual LIBEVAL::FUNC_CALL_REF CreateFuncCall(const wxString &aName) override
const std::vector< wxString > & GetSupportedUnits() const override
double Convert(const wxString &aString, int unitId) const override
double Convert(const wxString &aString, int unitId) const override
wxString GetSupportedUnitsMessage() const override
const std::vector< wxString > & GetSupportedUnits() const override
std::unordered_map< TYPE_ID, PROPERTY_BASE * > m_matchingTypes
LIBEVAL::VALUE * GetValue(LIBEVAL::CONTEXT *aCtx) override
LIBEVAL::VAR_TYPE_T m_type
BOARD_ITEM * GetObject(const LIBEVAL::CONTEXT *aCtx) const
virtual size_t TypeHash() const =0
Return type-id of the property type.
virtual bool HasChoices() const
Return true if this PROPERTY has a limited set of possible values.
Definition: property.h:241
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
CLASSES_INFO GetAllClasses()
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:87
PROPERTY_BASE * GetProperty(TYPE_ID aType, const wxString &aProperty) const
Return a property for a specific type.
bool IsOfType(TYPE_ID aDerived, TYPE_ID aBase) const
Return true if aDerived is inherited from aBase.
@ NULL_CONSTRAINT
Definition: drc_rule.h:48
#define _(s)
wxString LayerName(int aLayer)
Returns the default display name for a given layer.
Definition: layer_id.cpp:31
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ F_Cu
Definition: layer_ids.h:64
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:699
KICOMMON_API double DoubleValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Convert aTextValue to a double.
Definition: eda_units.cpp:553
std::function< void(CONTEXT *, void *)> FUNC_CALL_REF
BOARD * GetBoard()
#define TYPE_HASH(x)
Definition: property.h:71
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86