95 if( !symbol || aProperty->
Name() !=
_HKI(
"Text" ) )
101 wxString newValue = aItem->
Get<wxString>( aProperty );
105 symbol->
SetRef( &sheetPath, newValue );
113 wxString ref = symbol->
GetRef( &sheetPath );
119 std::vector<SCH_SYMBOL*> otherUnits;
125 switch( field->
GetId() )
132 aCommit->
Modify( otherUnit, sheet.LastScreen() );
134 otherUnit->GetField( field->
GetId() )->SetText( newValue );
186 project.m_ErcSettings =
nullptr;
189 delete project.m_SchematicSettings;
190 project.m_SchematicSettings =
nullptr;
201 project.m_SchematicSettings->LoadFromFile();
202 project.m_SchematicSettings->m_NgspiceSettings->LoadFromFile();
203 project.m_ErcSettings->LoadFromFile();
215 std::shared_ptr<REFDES_TRACKER> refdesTracker =
m_project->GetProjectFile().m_SchematicSettings->m_refDesTracker;
224 refdesTracker->Insert( ref.GetFullRef(
false ).ToStdString() );
240 return std::any_of( references.
begin(), references.
end(),
243 return ref.GetFullRef( true ) == aRef.GetFullRef( true );
298 rootSheetPath.push_back( rootSheet );
299 rootSheetPath.SetPageNumber( wxT(
"1" ) );
329 m_variantNames.insert( variantNames.begin(), variantNames.end() );
336 for(
const auto& [
name, description] :
Settings().m_VariantDescriptions )
344 wxCHECK_RET( !aSheets.empty(), wxS(
"Cannot set empty top-level sheets!" ) );
350 std::vector<SCH_SHEET*> validSheets;
351 validSheets.reserve( aSheets.size() );
356 if( sheet && sheet->m_Uuid !=
niluuid )
357 validSheets.push_back( sheet );
360 if( validSheets.empty() )
363 if( !wasAlreadySetting )
372 std::set<SCH_SHEET*> desiredSheets( validSheets.begin(), validSheets.end() );
380 if( sheet && !desiredSheets.contains( sheet ) )
435 auto add = [&](
const wxString& aVar )
438 aVars->push_back( aVar );
443 add( wxT(
"SHEETPATH" ) );
444 add( wxT(
"SHEETNAME" ) );
445 add( wxT(
"FILENAME" ) );
446 add( wxT(
"FILEPATH" ) );
447 add( wxT(
"PROJECTNAME" ) );
448 add( wxT(
"VARIANT" ) );
449 add( wxT(
"VARIANT_DESC" ) );
454 for( std::pair<wxString, wxString> entry :
m_project->GetTextVars() )
461 wxCHECK( aSheetPath,
false );
463 if( token->IsSameAs( wxT(
"#" ) ) )
468 else if( token->IsSameAs( wxT(
"##" ) ) )
470 *token = wxString::Format(
"%i",
Root().CountSheets() );
473 else if( token->IsSameAs( wxT(
"SHEETPATH" ) ) )
478 else if( token->IsSameAs( wxT(
"SHEETNAME" ) ) )
483 else if( token->IsSameAs( wxT(
"FILENAME" ) ) )
486 *token = fn.GetFullName();
489 else if( token->IsSameAs( wxT(
"FILEPATH" ) ) )
492 *token = fn.GetFullPath();
495 else if( token->IsSameAs( wxT(
"PROJECTNAME" ) ) )
500 else if( token->IsSameAs( wxT(
"VARIANTNAME" ) ) || token->IsSameAs( wxT(
"VARIANT" ) ) )
505 else if( token->IsSameAs( wxT(
"VARIANT_DESC" ) ) )
515 if(
m_project->TextVarResolver( token ) )
527 return wxString( wxEmptyString );
532 return wxString( wxEmptyString );
541 return defaultSettings;
544 return *
m_project->GetProjectFile().m_SchematicSettings;
551 return *
m_project->GetProjectFile().m_ErcSettings;
565 std::set<wxString> migratedExclusions;
581 if( settingsKey != wxT(
"pin_to_pin" ) && settingsKey != wxT(
"hier_label_mismatch" )
582 && settingsKey != wxT(
"different_unit_net" ) )
597 settings.
m_ErcExclusions.insert( migratedExclusions.begin(), migratedExclusions.end() );
607 std::set<wxString>::iterator it = settings.
m_ErcExclusions.find( serialized );
617 std::vector<SCH_MARKER*> newMarkers;
626 newMarkers.push_back( marker );
638 for(
const std::shared_ptr<BUS_ALIAS>& alias :
m_busAliases )
640 if( alias && alias->GetName() == aLabel )
653 auto sameDefinition = [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
655 return candidate && candidate->GetName() == aAlias->GetName() && candidate->Members() == aAlias->Members();
673 for(
const std::shared_ptr<BUS_ALIAS>& alias : aAliases )
678 std::shared_ptr<BUS_ALIAS> clone = alias->Clone();
680 auto sameDefinition = [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
682 return candidate && candidate->GetName() == clone->GetName() && candidate->Members() == clone->Members();
702 const auto& projectAliases =
m_project->GetProjectFile().m_BusAliases;
704 for(
const auto& alias : projectAliases )
706 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
708 busAlias->SetName( alias.first );
709 busAlias->SetMembers( alias.second );
721 auto& projectAliases =
m_project->GetProjectFile().m_BusAliases;
723 projectAliases.clear();
725 std::set<wxString> seen;
727 for(
const std::shared_ptr<BUS_ALIAS>& alias :
m_busAliases )
732 if( !seen.insert( alias->GetName() ).second )
735 projectAliases.emplace( alias->GetName(), alias->Members() );
742 std::set<wxString> names;
751 names.insert( key.Name );
762 wxString ref = token->BeforeFirst(
':', &remainder );
768 if(
path.size() > 1 )
776 wxString variantName;
777 wxString fieldName = remainder;
778 int colonPos = remainder.Find(
':' );
780 if( colonPos != wxNOT_FOUND )
782 fieldName = remainder.Left( colonPos );
783 variantName = remainder.Mid( colonPos + 1 );
795 bool resolved = refSymbol->
ResolveTextVar( &sheetPath, &fieldName, variantName, aDepth + 1 );
799 *token = std::move( fieldName );
804 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ), refSymbol->
GetRef( &sheetPath,
false ), fieldName );
815 wxString remainderBefore = remainder;
817 if( refSheet->
ResolveTextVar( &sheetPath, &remainder, aDepth + 1 ) )
818 *token = std::move( remainder );
822 if( remainderBefore.Contains( wxT(
"${" ) ) || remainderBefore.Contains( wxT(
"@{" ) ) )
838 for(
int ii = 0; ii < (int) refs.
GetCount(); ii++ )
844 if( symbolRef == ref )
852 if( symbolRef.StartsWith( ref ) && symbolRef.Length() == ref.Length() + 1 )
854 wxChar lastChar = symbolRef.Last();
855 if( lastChar >=
'A' && lastChar <=
'Z' )
866 bool resolved = foundSymbol->
ResolveTextVar( &foundPath, &fieldName, variantName, aDepth + 1 );
870 *token = std::move( fieldName );
875 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ), foundSymbol->
GetRef( &foundPath,
false ),
883 *token = wxString::Format( wxT(
"<Unresolved: %s>" ), ref );
888 *token = wxString::Format( wxT(
"<Unknown reference: %s>" ), ref );
895 std::map<int, wxString> namesMap;
899 if( sheet.size() == 1 )
900 namesMap[sheet.GetVirtualPageNumber()] =
_(
"<root sheet>" );
902 namesMap[sheet.GetVirtualPageNumber()] = sheet.Last()->GetName();
911 std::map<int, wxString> pagesMap;
914 pagesMap[sheet.GetVirtualPageNumber()] = sheet.GetPageNumber();
923 size_t sourceLen = aSource.length();
925 for(
size_t i = 0; i < sourceLen; ++i )
929 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
930 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
933 newbuf.append( aSource[i] );
934 newbuf.append( aSource[i + 1] );
935 newbuf.append( aSource[i + 2] );
940 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
942 if( aSource[i] ==
'{' )
944 else if( aSource[i] ==
'}' )
947 newbuf.append( aSource[i] );
953 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
956 bool isCrossRef =
false;
959 for( i = i + 2; i < sourceLen; ++i )
961 if( aSource[i] ==
'{' && ( aSource[i - 1] ==
'_' || aSource[i - 1] ==
'^' || aSource[i - 1] ==
'~' ) )
966 if( aSource[i] ==
'}' )
974 if( aSource[i] ==
':' )
977 token.append( aSource[i] );
983 wxString ref = token.BeforeFirst(
':', &remainder );
988 for(
size_t jj = 0; jj < references.
GetCount(); jj++ )
990 SCH_SYMBOL* refSymbol = references[jj].GetSymbol();
992 if( ref == refSymbol->
GetRef( &references[jj].GetSheetPath(),
true ) )
997 token =
path.AsString() + wxS(
":" ) + remainder;
1003 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
1007 newbuf.append( aSource[i] );
1018 size_t sourceLen = aSource.length();
1020 for(
size_t i = 0; i < sourceLen; ++i )
1024 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
1025 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
1028 newbuf.append( aSource[i] );
1029 newbuf.append( aSource[i + 1] );
1030 newbuf.append( aSource[i + 2] );
1035 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
1037 if( aSource[i] ==
'{' )
1039 else if( aSource[i] ==
'}' )
1042 newbuf.append( aSource[i] );
1048 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
1051 bool isCrossRef =
false;
1053 for( i = i + 2; i < sourceLen; ++i )
1055 if( aSource[i] ==
'}' )
1058 if( aSource[i] ==
':' )
1061 token.append( aSource[i] );
1067 wxString ref = token.BeforeFirst(
':', &remainder );
1073 if(
path.size() > 1 )
1082 token = refSymbol->
GetRef( &sheetPath,
true ) + wxS(
":" ) + remainder;
1086 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
1090 newbuf.append( aSource[i] );
1113 size_t startIdx = 0;
1119 return wxEmptyString;
1122 wxString filename = rootFn.GetName();
1148 sheet_count += topSheet->CountSheets();
1157 int sheet_number = 1;
1161 for( screen = s_list.
GetFirst(); screen !=
nullptr; screen = s_list.
GetNext() )
1179 if( sheet.Path() == current_sheetpath )
1185 for( screen = s_list.
GetFirst(); screen !=
nullptr; screen = s_list.
GetNext() )
1196 std::map<wxString, std::set<int>>& pageRefsMap =
GetPageRefsMap();
1198 pageRefsMap.clear();
1205 wxString resolvedLabel = global->
GetShownText( &sheet,
false );
1207 pageRefsMap[resolvedLabel].insert( sheet.GetVirtualPageNumber() );
1216 std::vector<SCH_GLOBALLABEL*> currentSheetGlobalLabels;
1219 currentSheetGlobalLabels.push_back(
static_cast<SCH_GLOBALLABEL*
>( item ) );
1223 std::vector<SCH_FIELD>& fields = globalLabel->GetFields();
1225 fields[0].SetVisible( show );
1229 if( fields.size() == 1 && fields[0].GetTextPos() == globalLabel->GetPosition() )
1234 for(
SCH_FIELD& field : globalLabel->GetFields() )
1235 field.ClearBoundingBoxCache();
1237 globalLabel->ClearBoundingBoxCache();
1248 wxString spiceNetName( aNetName.Lower() );
1251 if( spiceNetName == wxS(
"gnd" ) || spiceNetName == wxS(
"0" ) )
1252 return wxEmptyString;
1272 std::deque<EDA_ITEM*> allItems;
1274 for(
SCH_ITEM* item : screen->Items() )
1275 allItems.push_back( item );
1278 for(
const VECTOR2I& point : screen->GetNeededJunctions( allItems ) )
1283 screen->Append( junction );
1286 for(
SCH_LINE* wire : screen->GetBusesAndWires( point,
true ) )
1289 screen->Append( newSegment );
1356 for(
unsigned i = 0; i < sheetList.size(); i++ )
1412 for(
auto& [
name, libSym] : screen->GetLibSymbols() )
1413 aFunction( libSym->GetEmbeddedFiles() );
1420 std::set<KIFONT::OUTLINE_FONT*>
fonts;
1426 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
1438 if( outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::EDITABLE
1439 || outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::INSTALLABLE )
1441 fonts.insert( outline );
1461 wxLogTrace(
"EMBED",
"Failed to add font file: %s", font->GetFileName() );
1472 std::set<const SCH_SCREEN*> retv;
1485 const std::vector<SCH_SYMBOL_INSTANCE> symbolInstances = symbol->
GetInstances();
1489 if( !hierarchy.
HasPath( instance.m_Path ) )
1491 retv.insert( screen );
1496 if( retv.count( screen ) )
1513 wxCHECK2( screen,
continue );
1515 if( screen->GetRefCount() > 1 )
1526 std::vector<SCH_LINE*> lines;
1527 std::vector<SCH_JUNCTION*> junctions;
1528 std::vector<SCH_NO_CONNECT*> ncs;
1529 std::vector<SCH_ITEM*> items_to_remove;
1530 bool changed =
true;
1532 if( aScreen ==
nullptr )
1535 auto remove_item = [&](
SCH_ITEM* aItem ) ->
void
1543 if( aItem->IsSelected() && selectionTool )
1550 aCommit->
Removed( aItem, aScreen );
1562 items_to_remove.push_back( item );
1565 junctions.push_back(
static_cast<SCH_JUNCTION*
>( item ) );
1568 for(
SCH_ITEM* item : items_to_remove )
1569 remove_item( item );
1577 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
1578 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
1584 remove_item( aSecond );
1590 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
1591 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
1597 remove_item( aSecond );
1601 auto minX = [](
const SCH_LINE* l )
1603 return std::min( l->GetStartPoint().x, l->GetEndPoint().x );
1606 auto maxX = [](
const SCH_LINE* l )
1608 return std::max( l->GetStartPoint().x, l->GetEndPoint().x );
1611 auto minY = [](
const SCH_LINE* l )
1613 return std::min( l->GetStartPoint().y, l->GetEndPoint().y );
1616 auto maxY = [](
const SCH_LINE* l )
1618 return std::max( l->GetStartPoint().y, l->GetEndPoint().y );
1631 lines.push_back(
static_cast<SCH_LINE*
>( item ) );
1635 std::sort( lines.begin(), lines.end(),
1638 return minX( a ) < minX( b );
1641 for(
auto it1 = lines.begin(); it1 != lines.end(); ++it1 )
1648 if( firstLine->
IsNull() )
1650 remove_item( firstLine );
1654 int firstRightXEdge = maxX( firstLine );
1657 for( ++it2; it2 != lines.end(); ++it2 )
1660 int secondLeftXEdge = minX( secondLine );
1663 if( secondLeftXEdge > firstRightXEdge )
1667 if( !( std::max( minY( firstLine ), minY( secondLine ) )
1668 <= std::min( maxY( firstLine ), maxY( secondLine ) ) ) )
1686 remove_item( secondLine );
1694 if( mergedLine !=
nullptr )
1696 remove_item( firstLine );
1697 remove_item( secondLine );
1699 if( m_schematicHolder )
1701 m_schematicHolder->AddToScreen( mergedLine, aScreen );
1704 aCommit->Added( mergedLine, aScreen );
1707 selectionTool->AddItemToSel( mergedLine,
true );
1720 std::function<
void(
SCH_ITEM* )>* aChangedItemHandler,
1729 aCommit = &localCommit;
1741 CleanUp( aCommit, sheet.LastScreen() );
1745 wxLogTrace(
"CONN_PROFILE",
"SchematicCleanUp() %0.4f ms", timer.
msecs() );
1754 m_project->GetProjectFile().NetSettings()->ClearAllCaches();
1757 std::unordered_set<SCH_SCREEN*> all_screens;
1760 all_screens.insert(
path.LastScreen() );
1777 std::set<SCH_ITEM*> changed_items;
1778 std::set<VECTOR2I> pts;
1779 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> item_paths;
1782 std::unordered_set<SCH_SCREEN*> changed_screens;
1783 std::set<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> changed_rule_areas;
1784 std::vector<CHANGED_ITEM> changed_connectable_items;
1787 auto addItemToChangeSet = [&changed_items, &pts, &item_paths]( CHANGED_ITEM itemData )
1789 std::vector<SCH_SHEET_PATH>& paths = itemData.screen->GetClientSheetPaths();
1791 std::vector<VECTOR2I> tmp_pts = itemData.item->GetConnectionPoints();
1792 pts.insert( tmp_pts.begin(), tmp_pts.end() );
1793 changed_items.insert( itemData.item );
1796 item_paths.insert( std::make_pair(
path, itemData.item ) );
1798 if( !itemData.linked_item || !itemData.linked_item->IsConnectable() )
1801 tmp_pts = itemData.linked_item->GetConnectionPoints();
1802 pts.insert( tmp_pts.begin(), tmp_pts.end() );
1803 changed_items.insert( itemData.linked_item );
1809 std::vector<SCH_PIN*> pins = symbol->GetPins();
1810 changed_items.insert( pins.begin(), pins.end() );
1814 item_paths.insert( std::make_pair(
path, itemData.linked_item ) );
1818 for(
unsigned ii = 0; ii < aLastChangeList->
GetCount(); ++ii )
1836 changed_screens.insert( screen );
1841 changed_rule_areas.insert( { ruleArea, screen } );
1846 changed_connectable_items.push_back( { item, linked_item, screen } );
1852 std::vector<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> forceUpdateRuleAreas =
1855 std::for_each( forceUpdateRuleAreas.begin(), forceUpdateRuleAreas.end(),
1856 [&]( std::pair<SCH_RULE_AREA*, SCH_SCREEN*>& updatedRuleArea )
1858 changed_rule_areas.insert( updatedRuleArea );
1863 std::map<KIID, EDA_ITEM*> itemMap;
1864 list.FillItemMap( itemMap );
1870 if( itemMap.contains( pastItem ) )
1871 addItemToChangeSet( {
static_cast<SCH_ITEM*
>( itemMap[pastItem] ),
nullptr, screen } );
1875 addItemToChangeSet( { containedItem,
nullptr, screen } );
1878 for(
const auto& [changedRuleArea, screen] : changed_rule_areas )
1879 addPastAndPresentContainedItems( changedRuleArea, screen );
1882 for( CHANGED_ITEM& changed_item_data : changed_connectable_items )
1884 addItemToChangeSet( changed_item_data );
1890 const std::vector<VECTOR2I> labelConnectionPoints = changed_item_data.item->GetConnectionPoints();
1892 auto candidateRuleAreas = changed_item_data.screen->Items().Overlapping(
1895 for(
SCH_ITEM* candidateRuleArea : candidateRuleAreas )
1901 addPastAndPresentContainedItems( ruleArea, changed_item_data.screen );
1911 if( !item->IsConnectable() )
1919 if( item->HitTest( pt ) )
1921 changed_items.insert( item );
1924 item_paths.insert( std::make_pair(
path, item ) );
1927 else if( item->Type() ==
SCH_SYMBOL_T && item->IsConnected( pt ) )
1930 std::vector<SCH_PIN*> pins = symbol->
GetPins();
1932 changed_items.insert( pins.begin(), pins.end() );
1937 item_paths.insert( std::make_pair(
path,
pin ) );
1944 wxCHECK2( sheet,
continue );
1946 std::vector<SCH_SHEET_PIN*> sheetPins = sheet->
GetPins();
1947 changed_items.insert( sheetPins.begin(), sheetPins.end() );
1952 item_paths.insert( std::make_pair(
path,
pin ) );
1957 if( item->IsConnected( pt ) )
1959 changed_items.insert( item );
1962 item_paths.insert( std::make_pair(
path, item ) );
1968 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> all_items =
1971 all_items.insert( item_paths.begin(), item_paths.end() );
1977 std::shared_ptr<NET_SETTINGS> netSettings =
m_project->GetProjectFile().NetSettings();
1979 std::set<wxString> affectedNets;
1981 for(
auto& [
path, item] : all_items )
1983 wxCHECK2( item,
continue );
1984 item->SetConnectivityDirty();
1988 affectedNets.insert( conn->
Name() );
1993 for(
const CHANGED_ITEM& changedItem : changed_connectable_items )
1997 const wxString& driverName = label->GetCachedDriverName();
1999 if( !driverName.IsEmpty() )
2000 affectedNets.insert( driverName );
2005 const wxString& driverName = linkedLabel->GetCachedDriverName();
2007 if( !driverName.IsEmpty() )
2008 affectedNets.insert( driverName );
2013 for(
const wxString& netName : affectedNets )
2014 netSettings->ClearCacheForNet( netName );
2016 new_graph.
Recalculate( list,
false, aChangedItemHandler, aProgressReporter );
2020 if( !localCommit.
Empty() )
2021 localCommit.
Push(
_(
"Schematic Cleanup" ) );
2060 size_t index =
static_cast<size_t>( aIndex );
2070 wxCHECK_RET( aSheet, wxS(
"Cannot add null sheet!" ) );
2071 wxCHECK_RET( aSheet->
GetScreen(), wxS(
"Cannot add virtual root as top-level sheet!" ) );
2104 m_rootSheet->GetScreen()->Items().remove( aSheet );
2131 wxLogTrace(
traceSchSheetPaths,
"BuildSheetListSortedByPageNumbers: %zu top-level sheets",
2143 wxLogTrace(
traceSchSheetPaths,
" Top-level sheet: '%s' (UUID=%s, isVirtualRoot=%d)", sheet->GetName(),
2144 sheet->m_Uuid.AsString(), sheet->m_Uuid ==
niluuid ? 1 : 0 );
2153 hierarchy.push_back(
path );
2179 sheets.push_back(
path );
2190 wxArrayString variantNames;
2196 variantNames.Add(
name );
2200 return variantNames;
2207 return wxEmptyString;
2215 wxString newVariant;
2219 newVariant = aVariantName;
2234 for(
SCH_ITEM* item : screen->Items() )
2235 item->ClearCaches();
2248 if( descriptions.find( aVariantName ) == descriptions.end() )
2249 descriptions[aVariantName] = wxEmptyString;
2270 wxCHECK( !aOldName.IsEmpty() && !aNewName.IsEmpty(), );
2278 if( descriptions.count( aOldName ) )
2280 descriptions[aNewName] = descriptions[aOldName];
2281 descriptions.erase( aOldName );
2296 wxCHECK( !aSourceVariant.IsEmpty() && !aNewVariant.IsEmpty(), );
2304 if( descriptions.count( aSourceVariant ) )
2305 descriptions[aNewVariant] = descriptions[aSourceVariant];
2308 allScreens.
CopyVariant( aSourceVariant, aNewVariant, aCommit );
2315 auto it = descriptions.find( aVariantName );
2317 if( it != descriptions.end() )
2320 return wxEmptyString;
2328 if( aDescription.IsEmpty() )
2329 descriptions.erase( aVariantName );
2331 descriptions[aVariantName] = aDescription;
2341 m_variantNames.insert( variantNames.begin(), variantNames.end() );
2346 for(
const wxString&
name : variantNames )
2348 if( descriptions.find(
name ) == descriptions.end() )
2349 descriptions[
name] = wxEmptyString;
2354 for(
const auto& [
name, description] : descriptions )
2365 wxString projPath =
m_project->GetProjectPath();
2367 if( projPath.IsEmpty() )
2371 if( !projPath.IsSameAs( aProjectPath ) )
2373 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver skipping - project path mismatch: %s vs %s" ), projPath,
2379 if( !projPath.EndsWith( wxFILE_SEP_PATH ) )
2380 projPath += wxFILE_SEP_PATH;
2382 wxFileName historyRoot( projPath, wxEmptyString );
2383 historyRoot.AppendDir( wxS(
".history" ) );
2384 wxString historyRootPath = historyRoot.GetPath();
2391 KICAD_FORMAT::FORMAT_MODE mode = KICAD_FORMAT::FORMAT_MODE::NORMAL;
2394 mode = KICAD_FORMAT::FORMAT_MODE::COMPACT_TEXT_PROPERTIES;
2401 if( !sheet || !screen )
2409 wxString absPath = abs.GetFullPath();
2411 if( absPath.IsEmpty() || !absPath.StartsWith( projPath ) )
2414 wxString rel = absPath.Mid( projPath.length() );
2417 wxFileName dst( rel );
2419 if( dst.IsRelative() )
2420 dst.MakeAbsolute( historyRootPath );
2422 dst.SetPath( historyRootPath );
2425 wxFileName dstDir( dst );
2426 dstDir.SetFullName( wxEmptyString );
2428 if( !dstDir.DirExists() )
2429 wxFileName::Mkdir( dstDir.GetPath(), 0777, wxPATH_MKDIR_FULL );
2437 entry.
path = dst.GetFullPath();
2441 aFileData.push_back( std::move( entry ) );
2443 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver serialized %zu bytes for '%s' -> '%s'" ),
2444 aFileData.back().content.size(), absPath, dst.GetFullPath() );
2448 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver serialize failed for '%s': %s" ), absPath,
2449 wxString::FromUTF8( ioe.
What() ) );
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void SetPageCount(int aPageCount)
void SetPageNumber(const wxString &aPageNumber)
void SetVirtualPageNumber(int aPageNumber)
Represent a set of changes (additions, deletions or modifications) of a data model (e....
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Calculate the connectivity of a schematic and generates netlists.
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Update the connection graph for the given list of sheets.
std::set< std::pair< SCH_SHEET_PATH, SCH_ITEM * > > ExtractAffectedItems(const std::set< SCH_ITEM * > &aItems)
For a set of items, this will remove the connected items and their associated data including subgraph...
void SetLastCodes(const CONNECTION_GRAPH *aOther)
void Merge(CONNECTION_GRAPH &aGraph)
Combine the input graph contents into the current graph.
A subgraph is a set of items that are electrically connected on a single sheet.
static PRIORITY GetDriverPriority(SCH_ITEM *aDriver)
Return the priority (higher is more important) of a candidate driver.
const SCH_CONNECTION * GetDriverConnection() const
EDA_ITEM_FLAGS GetEditFlags() const
KICAD_T Type() const
Returns the type of object.
EDA_ITEM * GetParent() const
virtual void SetParent(EDA_ITEM *aParent)
EDA_ITEM_FLAGS GetFlags() const
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
SHAPE_POLY_SET & GetPolyShape()
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
EE_TYPE OfType(KICAD_T aType) const
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
Container for ERC settings.
std::map< wxString, wxString > m_ErcExclusionComments
std::set< wxString > m_ErcExclusions
Class that other classes need to inherit from, in order to be inspectable.
wxAny Get(PROPERTY_BASE *aProperty) const
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
FONT is an abstract base class for both outline and stroke fonts.
virtual bool IsStroke() const
Class OUTLINE_FONT implements outline font drawing.
A logical library item identifier and consists of various portions much like a URI.
std::shared_ptr< RC_ITEM > GetRCItem() const
void SetExcluded(bool aExcluded, const wxString &aComment=wxEmptyString)
wxString GetComment() const
static void ConvertToSpiceMarkup(wxString *aNetName)
Remove formatting wrappers and replace illegal spice net name characters with underscores.
A holder to handle information on schematic or board items.
UNDO_REDO GetPickedItemStatus(unsigned int aIdx) const
EDA_ITEM * GetPickedItemLink(unsigned int aIdx) const
unsigned GetCount() const
BASE_SCREEN * GetScreenForItem(unsigned int aIdx) const
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
A small class to help profiling.
void Stop()
Save the time when this function was called, and set the counter stane to stop.
double msecs(bool aSinceLast=false)
A progress reporter interface for use in multi-threaded environments.
The backing store for a PROJECT, in JSON format.
Container for project specific data.
const wxString & Name() const
static PROPERTY_MANAGER & Instance()
void UnregisterListeners(TYPE_ID aType)
void RegisterListener(TYPE_ID aType, PROPERTY_LISTENER aListenerFunc)
Registers a listener for the given type.
wxString GetSettingsKey() const
virtual void OnSchItemsRemoved(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
virtual void OnSchItemsChanged(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
virtual void OnSchSheetChanged(SCHEMATIC &aSch)
virtual void OnSchItemsAdded(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
These are loaded from Eeschema settings but then overwritten by the project settings.
bool m_IntersheetRefsShow
std::map< wxString, wxString > m_VariantDescriptions
A map of variant names to their descriptions.
void SetCurrentVariant(const wxString &aVariantName)
bool m_settingTopLevelSheets
Re-entry guard to prevent infinite recursion between ensureDefaultTopLevelSheet and RefreshHierarchy ...
void Reset()
Initialize this schematic to a blank one, unloading anything existing.
std::set< const SCH_SCREEN * > GetSchematicsSharedByMultipleProjects() const
Return a list of schematic files in the current project that contain instance data for multiple proje...
void CreateDefaultScreens()
void SetLegacySymbolInstanceData()
Update the symbol value and footprint instance data for legacy designs.
void OnItemsAdded(std::vector< SCH_ITEM * > &aNewItems)
Must be used if Add() is used using a BULK_x ADD_MODE to generate a change event for listeners.
CONNECTION_GRAPH * m_connectionGraph
Hold and calculate connectivity information of this schematic.
bool IsTopLevelSheet(const SCH_SHEET *aSheet) const
Check if a sheet is a top-level sheet (direct child of virtual root).
void loadBusAliasesFromProject()
void AddTopLevelSheet(SCH_SHEET *aSheet)
Add a new top-level sheet to the schematic.
SCH_SHEET_LIST m_hierarchy
Cache of the entire schematic hierarchy sorted by sheet page number.
void rebuildHierarchyState(bool aResetConnectionGraph)
void ResolveERCExclusionsPostUpdate()
Update markers to match recorded exclusions.
void DeleteVariant(const wxString &aVariantName, SCH_COMMIT *aCommit=nullptr)
Delete all information for aVariantName.
void RecomputeIntersheetRefs()
Update the schematic's page reference map for all global labels, and refresh the labels so that they ...
void CacheExistingAnnotation()
Store all existing annotations in the REFDES_TRACKER.
wxString GetVariantDescription(const wxString &aVariantName) const
Return the description for a variant.
void LoadVariants()
This is a throw away method for variant testing.
SCH_SHEET_LIST BuildSheetListSortedByPageNumbers() const
void RemoveListener(SCHEMATIC_LISTENER *aListener)
Remove the specified listener.
bool IsComplexHierarchy() const
Test if the schematic is a complex hierarchy.
void OnSchSheetChanged()
Notify the schematic and its listeners that the current sheet has been changed.
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
SCH_SHEET_PATH * m_currentSheet
The sheet path of the sheet currently being edited or displayed.
std::vector< SCH_SHEET * > m_topLevelSheets
List of top-level sheets (direct children of virtual root)
wxString GetOperatingPoint(const wxString &aNetName, int aPrecision, const wxString &aRange)
void CleanUp(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
void OnItemsRemoved(std::vector< SCH_ITEM * > &aRemovedItems)
Must be used if Remove() is used using a BULK_x REMOVE_MODE to generate a change event for listeners.
void AddVariant(const wxString &aVariantName)
int FixupJunctionsAfterImport()
Add junctions to this schematic where required.
std::shared_ptr< BUS_ALIAS > GetBusAlias(const wxString &aLabel) const
Return a pointer to a bus alias object for the given label, or null if one doesn't exist.
void CopyVariant(const wxString &aSourceVariant, const wxString &aNewVariant, SCH_COMMIT *aCommit=nullptr)
Copy a variant from aSourceVariant to aNewVariant.
std::vector< SCH_MARKER * > ResolveERCExclusions()
void SaveToHistory(const wxString &aProjectPath, std::vector< HISTORY_FILE_DATA > &aFileData)
Serialize schematic sheets into HISTORY_FILE_DATA for non-blocking history commit.
void EmbedFonts() override
Embed fonts in the schematic.
SCHEMATIC_SETTINGS & Settings() const
SCH_SCREEN * GetCurrentScreen() const
wxString ConvertKIIDsToRefs(const wxString &aSource) const
SCH_ITEM * ResolveItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr, bool aAllowNullptrReturn=false) const
void ensureCurrentSheetIsTopLevel()
void RecordERCExclusions()
Scan existing markers and record data from any that are Excluded.
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
wxString m_currentVariant
std::map< wxString, std::set< int > > & GetPageRefsMap()
SCH_SHEET_LIST BuildUnorderedSheetList() const
void RenameVariant(const wxString &aOldName, const wxString &aNewName, SCH_COMMIT *aCommit=nullptr)
Rename a variant from aOldName to aNewName.
std::set< KIFONT::OUTLINE_FONT * > GetFonts() const override
Get a set of fonts used in the schematic.
SCH_SHEET * GetTopLevelSheet(int aIndex=0) const
bool RemoveTopLevelSheet(SCH_SHEET *aSheet)
Remove a top-level sheet from the schematic.
bool Contains(const SCH_REFERENCE &aRef) const
Check if the schematic contains the specified reference.
wxString ConvertRefsToKIIDs(const wxString &aSource) const
void SetProject(PROJECT *aPrj)
wxString GetCurrentVariant() const
Return the current variant being edited.
void AddListener(SCHEMATIC_LISTENER *aListener)
Add a listener to the schematic to receive calls whenever something on the schematic has been modifie...
std::map< int, wxString > GetVirtualPageToSheetPagesMap() const
EMBEDDED_FILES * GetEmbeddedFiles() override
CONNECTION_GRAPH * ConnectionGraph() const
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
bool ResolveTextVar(const SCH_SHEET_PATH *aSheetPath, wxString *token, int aDepth) const
std::set< wxString > GetNetClassAssignmentCandidates()
Return the set of netname candidates for netclass assignment.
std::vector< std::shared_ptr< BUS_ALIAS > > m_busAliases
void InvokeListeners(Func &&aFunc, Args &&... args)
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
void updateProjectBusAliases()
void SetVariantDescription(const wxString &aVariantName, const wxString &aDescription)
Set the description for a variant.
static bool m_IsSchematicExists
True if a SCHEMATIC exists, false if not.
void RemoveAllListeners()
Remove all listeners.
void SetTopLevelSheets(const std::vector< SCH_SHEET * > &aSheets)
void GetContextualTextVars(wxArrayString *aVars) const
void ensureDefaultTopLevelSheet()
std::map< int, wxString > GetVirtualPageToSheetNamesMap() const
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
std::vector< SCH_SHEET * > GetTopLevelSheets() const
Get the list of top-level sheets.
wxArrayString GetVariantNamesForUI() const
Return an array of variant names for using in wxWidgets UI controls.
void RunOnNestedEmbeddedFiles(const std::function< void(EMBEDDED_FILES *)> &aFunction) override
Provide access to nested embedded files, such as symbols in schematics and footprints in boards.
SCHEMATIC_HOLDER * m_schematicHolder
What currently "Holds" the schematic, i.e.
wxString GetUniqueFilenameForCurrentSheet()
Get the unique file name for the current sheet.
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
void SetBusAliases(const std::vector< std::shared_ptr< BUS_ALIAS > > &aAliases)
std::vector< SCHEMATIC_LISTENER * > m_listeners
Currently installed listeners.
SCH_SHEET_PATH & CurrentSheet() const
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, TOOL_MANAGER *aToolManager, PROGRESS_REPORTER *aProgressReporter=nullptr, KIGFX::SCH_VIEW *aSchView=nullptr, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PICKED_ITEMS_LIST *aLastChangeList=nullptr)
Generate the connection data for the entire schematic hierarchy.
std::map< wxString, double > m_operatingPoints
Simulation operating points for text variable substitution.
ERC_SETTINGS & ErcSettings() const
std::set< wxString > m_variantNames
void OnItemsChanged(std::vector< SCH_ITEM * > &aItems)
Notify the schematic and its listeners that an item on the schematic has been modified in some way.
SCH_SHEET * m_rootSheet
The virtual root sheet (has no screen, contains all top-level sheets)
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString Name(bool aIgnoreSheet=false) const
A SCH_IO derivation for loading schematic files using the new s-expression file format.
void FormatSchematicToFormatter(OUTPUTFORMATTER *aOut, SCH_SHEET *aSheet, SCHEMATIC *aSchematic, const std::map< std::string, UTF8 > *aProperties=nullptr)
Serialize a schematic sheet to an OUTPUTFORMATTER without file I/O or Prettify.
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual bool IsConnectable() const
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
VECTOR2I GetPosition() const override
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const override
Segment description base class to describe items which have 2 end points (track, wire,...
SCH_LINE * NonGroupAware_BreakAt(const VECTOR2I &aPoint)
This version should only be used when importing files.
bool IsParallel(const SCH_LINE *aLine) const
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
SCH_LINE * MergeOverlap(SCH_SCREEN *aScreen, SCH_LINE *aLine, bool aCheckJunctions)
Check line against aLine to see if it overlaps and merge if it does.
bool IsStrokeEquivalent(const SCH_LINE *aLine)
bool IsEndPoint(const VECTOR2I &aPoint) const override
Test if aPt is an end point of this schematic object.
static SCH_MARKER * DeserializeFromString(const SCH_SHEET_LIST &aSheetList, const wxString &data)
wxString SerializeToString() const
bool IsLegacyMarker() const
Determine if this marker is legacy (i.e.
VECTOR2I GetPosition() const override
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
SCH_SYMBOL * GetSymbol() const
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const override
Make a set of SHAPE objects representing the EDA_SHAPE.
const std::unordered_set< SCH_ITEM * > & GetContainedItems() const
Return a set of all items contained within the rule area.
static std::vector< std::pair< SCH_RULE_AREA *, SCH_SCREEN * > > UpdateRuleAreasInScreens(std::unordered_set< SCH_SCREEN * > &screens, KIGFX::SCH_VIEW *view)
Update all rule area connectvity / caches in the given sheet paths.
const std::unordered_set< KIID > & GetPastContainedItems() const
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
void CopyVariant(const wxString &aSourceVariant, const wxString &aNewVariant, SCH_COMMIT *aCommit=nullptr)
void RenameVariant(const wxString &aOldName, const wxString &aNewName, SCH_COMMIT *aCommit=nullptr)
std::set< wxString > GetVariantNames() const
void DeleteVariant(const wxString &aVariantName, SCH_COMMIT *aCommit=nullptr)
void SetLegacySymbolInstanceData()
Update the symbol value and footprint instance data for legacy designs.
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
std::vector< SCH_SHEET_PATH > & GetClientSheetPaths()
Return the number of times this screen is used.
bool IsExplicitJunction(const VECTOR2I &aPosition) const
Indicate that a junction dot is necessary at the given location.
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const wxString & GetFileName() const
const KIID & GetUuid() const
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
const TITLE_BLOCK & GetTitleBlock() const
void Update(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Update aItem's bounding box in the tree.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
SCH_ITEM * ResolveItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr, bool aAllowNullptrReturn=false) const
Fetch a SCH_ITEM by ID.
void SortByPageNumbers(bool aUpdateVirtualPageNums=true)
Sort the list of sheets by page number.
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
void BuildSheetList(SCH_SHEET *aSheet, bool aCheckIntegrity)
Build the list of sheets and their sheet path from aSheet.
bool HasPath(const KIID_PATH &aPath) const
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SCREEN * LastScreen()
wxString GetPageNumber() const
SCH_SHEET * at(size_t aIndex) const
Forwarded method from std::vector.
void SetVirtualPageNumber(int aPageNumber)
Set the sheet instance virtual page number.
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false, bool aEscapeSheetNames=false) const
Return the sheet path in a human readable form made from the sheet names.
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
size_t size() const
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
int CountSheets() const
Count the number of sheets found in "this" sheet including all of the subsheets.
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
std::vector< SCH_SHEET_PIN * > & GetPins()
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the sheet.
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
const LIB_ID & GetLibId() const override
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
bool CollideEdge(const VECTOR2I &aPoint, VERTEX_INDEX *aClosestVertex=nullptr, int aClearance=0) const
Check whether aPoint collides with any edge of any of the contours of the polygon.
Helper class to recognize Spice formatted values.
wxString ToString() const
Return string value as when converting double to string (e.g.
bool TextVarResolver(wxString *aToken, const PROJECT *aProject, int aFlags=0) const
static void GetContextualTextVars(wxArrayString *aVars)
static bool empty(const wxTextEntryBase *aCtrl)
#define SELECTED_BY_DRAG
Item was algorithmically selected as a dragged item.
#define STRUCT_DELETED
flag indication structures to be erased
const wxChar *const traceAutoSave
Flag to enable auto save feature debug tracing.
const wxChar *const traceSchSheetPaths
Flag to enable debug output of schematic symbol sheet path manipulation code.
void ignore_unused(const T &)
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
void for_all_pairs(_InputIterator __first, _InputIterator __last, _Function __f)
Apply a function to every possible pair of elements of a sequence.
void CollectOtherUnits(const wxString &aRef, int aUnit, const LIB_ID &aLibId, SCH_SHEET_PATH &aSheet, std::vector< SCH_SYMBOL * > *otherUnits)
wxString GetDefaultVariantName()
int SortVariantNames(const wxString &aLhs, const wxString &aRhs)
Data produced by a registered saver on the UI thread, consumed by the background commit thread.
std::string content
Serialized content (mutually exclusive with sourcePath)
wxString path
Destination inside .history/.
KICAD_FORMAT::FORMAT_MODE formatMode
A simple container for schematic symbol instance information.
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxLogTrace helper definitions.
VECTOR2< int32_t > VECTOR2I