25#include <nlohmann/json.hpp>
41static std::optional<int>
getInPcbUnits(
const nlohmann::json& aObj,
const std::string& aKey,
42 std::optional<int> aDefault = std::optional<int>() )
44 if( aObj.contains( aKey ) && aObj[aKey].is_number() )
51static std::optional<int>
getInSchUnits(
const nlohmann::json& aObj,
const std::string& aKey,
52 std::optional<int> aDefault = std::optional<int>() )
54 if( aObj.contains( aKey ) && aObj[aKey].is_number() )
68 []( nlohmann::json& json_array,
const std::shared_ptr<NETCLASS>& nc )
72 nlohmann::json nc_json = { {
"name", nc->GetName().ToUTF8() },
73 {
"priority", nc->GetPriority() },
74 {
"schematic_color", nc->GetSchematicColor(
true ) },
75 {
"pcb_color", nc->GetPcbColor(
true ) } };
78 []( nlohmann::json&
json,
const std::string& aKey,
int aValue )
83 if( nc->HasWireWidth() )
87 if( nc->HasBusWidth() )
90 if( nc->HasLineStyle() )
91 nc_json.push_back( {
"line_style", nc->GetLineStyle() } );
93 if( nc->HasClearance() )
94 saveInPcbUnits( nc_json,
"clearance", nc->GetClearance() );
96 if( nc->HasTrackWidth() )
97 saveInPcbUnits( nc_json,
"track_width", nc->GetTrackWidth() );
99 if( nc->HasViaDiameter() )
100 saveInPcbUnits( nc_json,
"via_diameter", nc->GetViaDiameter() );
102 if( nc->HasViaDrill() )
103 saveInPcbUnits( nc_json,
"via_drill", nc->GetViaDrill() );
105 if( nc->HasuViaDiameter() )
106 saveInPcbUnits( nc_json,
"microvia_diameter", nc->GetuViaDiameter() );
108 if( nc->HasuViaDrill() )
109 saveInPcbUnits( nc_json,
"microvia_drill", nc->GetuViaDrill() );
111 if( nc->HasDiffPairWidth() )
112 saveInPcbUnits( nc_json,
"diff_pair_width", nc->GetDiffPairWidth() );
114 if( nc->HasDiffPairGap() )
115 saveInPcbUnits( nc_json,
"diff_pair_gap", nc->GetDiffPairGap() );
117 if( nc->HasDiffPairViaGap() )
118 saveInPcbUnits( nc_json,
"diff_pair_via_gap", nc->GetDiffPairViaGap() );
120 json_array.push_back( nc_json );
124 [](
const nlohmann::json& entry )
126 wxString
name = entry[
"name"];
128 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>(
name,
false );
130 int priority = entry[
"priority"];
131 nc->SetPriority( priority );
134 nc->SetClearance( *value );
137 nc->SetTrackWidth( *value );
140 nc->SetViaDiameter( *value );
143 nc->SetViaDrill( *value );
145 if(
auto value =
getInPcbUnits( entry,
"microvia_diameter" ) )
146 nc->SetuViaDiameter( *value );
149 nc->SetuViaDrill( *value );
152 nc->SetDiffPairWidth( *value );
155 nc->SetDiffPairGap( *value );
157 if(
auto value =
getInPcbUnits( entry,
"diff_pair_via_gap" ) )
158 nc->SetDiffPairViaGap( *value );
161 nc->SetWireWidth( *value );
164 nc->SetBusWidth( *value );
166 if( entry.contains(
"line_style" ) && entry[
"line_style"].is_number() )
167 nc->SetLineStyle( entry[
"line_style"].get<int>() );
169 if( entry.contains(
"pcb_color" ) && entry[
"pcb_color"].is_string() )
170 nc->SetPcbColor( entry[
"pcb_color"].get<KIGFX::COLOR4D>() );
172 if( entry.contains(
"schematic_color" )
173 && entry[
"schematic_color"].is_string() )
175 nc->SetSchematicColor( entry[
"schematic_color"].get<KIGFX::COLOR4D>() );
182 [&]() -> nlohmann::json
184 nlohmann::json ret = nlohmann::json::array();
186 if( m_defaultNetClass )
187 saveNetclass( ret, m_defaultNetClass );
189 for(
const auto& [
name, netclass] : m_netClasses )
190 saveNetclass( ret, netclass );
194 [&](
const nlohmann::json& aJson )
196 if( !aJson.is_array() )
199 m_netClasses.clear();
201 for(
const nlohmann::json& entry : aJson )
203 if( !entry.is_object() || !entry.contains(
"name" ) )
206 std::shared_ptr<NETCLASS> nc = readNetClass( entry );
208 if( nc->IsDefault() )
209 m_defaultNetClass = nc;
211 m_netClasses[nc->GetName()] = nc;
217 [&]() -> nlohmann::json
219 nlohmann::json ret = {};
221 for(
const auto& [netname,
color] : m_netColorAssignments )
223 std::string key( netname.ToUTF8() );
224 ret[ std::move( key ) ] =
color;
229 [&](
const nlohmann::json& aJson )
231 if( !aJson.is_object() )
234 m_netColorAssignments.clear();
236 for(
const auto& pair : aJson.items() )
238 wxString key( pair.key().c_str(), wxConvUTF8 );
239 m_netColorAssignments[std::move( key )] = pair.value().get<
KIGFX::COLOR4D>();
245 [&]() -> nlohmann::json
247 nlohmann::json ret = {};
249 for(
const auto& [netname, netclassNames] : m_netClassLabelAssignments )
251 nlohmann::json netclassesJson = nlohmann::json::array();
253 for(
const auto& netclass : netclassNames )
255 std::string netclassStr( netclass.ToUTF8() );
256 netclassesJson.push_back( std::move( netclassStr ) );
259 std::string key( netname.ToUTF8() );
260 ret[std::move( key )] = netclassesJson;
265 [&](
const nlohmann::json& aJson )
267 if( !aJson.is_object() )
270 m_netClassLabelAssignments.clear();
272 for(
const auto& pair : aJson.items() )
274 wxString key( pair.key().c_str(), wxConvUTF8 );
276 for(
const auto& netclassName : pair.value() )
277 m_netClassLabelAssignments[key].insert( netclassName.get<wxString>() );
283 [&]() -> nlohmann::json
285 nlohmann::json ret = nlohmann::json::array();
287 for(
const auto& [matcher, netclassName] : m_netClassPatternAssignments )
289 nlohmann::json pattern_json = {
290 {
"pattern", matcher->GetPattern().ToUTF8() },
291 {
"netclass", netclassName.ToUTF8() }
294 ret.push_back( std::move( pattern_json ) );
299 [&](
const nlohmann::json& aJson )
301 if( !aJson.is_array() )
304 m_netClassPatternAssignments.clear();
306 for(
const nlohmann::json& entry : aJson )
308 if( !entry.is_object() )
311 if( entry.contains(
"pattern" ) && entry[
"pattern"].is_string()
312 && entry.contains(
"netclass" ) && entry[
"netclass"].is_string() )
314 wxString pattern = entry[
"pattern"].get<wxString>();
315 wxString netclass = entry[
"netclass"].get<wxString>();
317 m_netClassPatternAssignments.push_back(
318 { std::make_unique<EDA_COMBINED_MATCHER>( pattern,
CTX_NETCLASS ),
372 for(
auto& netClass :
m_internals->At(
"classes" ).items() )
374 if( netClass.value().contains(
"nets" ) && netClass.value()[
"nets"].is_array() )
376 nlohmann::json migrated = nlohmann::json::array();
378 for(
auto& net : netClass.value()[
"nets"].items() )
381 netClass.value()[
"nets"] = migrated;
400 nlohmann::json patterns = nlohmann::json::array();
402 for(
auto& netClass :
m_internals->At(
"classes" ).items() )
404 if( netClass.value().contains(
"name" )
405 && netClass.value().contains(
"nets" )
406 && netClass.value()[
"nets"].is_array() )
408 wxString netClassName = netClass.value()[
"name"].get<wxString>();
410 for(
auto& net : netClass.value()[
"nets"].items() )
412 nlohmann::json pattern_json = {
413 {
"pattern", net.value().get<wxString>() },
414 {
"netclass", netClassName }
417 patterns.push_back( pattern_json );
422 m_internals->SetFromString(
"netclass_patterns", patterns );
436 for(
auto& netClass :
m_internals->At(
"classes" ).items() )
439 netClass.value()[
"priority"] = std::numeric_limits<int>::max();
441 netClass.value()[
"priority"] = priority++;
446 if(
m_internals->contains(
"netclass_assignments" )
447 &&
m_internals->At(
"netclass_assignments" ).is_object() )
449 nlohmann::json migrated = {};
451 for(
const auto& pair :
m_internals->At(
"netclass_assignments" ).items() )
453 nlohmann::json netclassesJson = nlohmann::json::array();
455 if( pair.value().get<wxString>() != wxEmptyString )
456 netclassesJson.push_back( pair.value() );
458 migrated[pair.key()] = netclassesJson;
461 m_internals->SetFromString(
"netclass_assignments", migrated );
538 const std::set<wxString>& netclasses )
545 const std::set<wxString>& netclasses )
562 if( assignment.first->GetPattern() == pattern )
564 assignment.second = netclass;
572 { std::make_unique<EDA_COMBINED_MATCHER>( pattern,
CTX_NETCLASS ), netclass } );
579 std::vector<std::pair<std::unique_ptr<EDA_COMBINED_MATCHER>, wxString>>&& netclassPatterns )
586std::vector<std::pair<std::unique_ptr<EDA_COMBINED_MATCHER>, wxString>>&
650 auto getExplicitNetclass = [
this](
const wxString& netclass ) -> std::shared_ptr<NETCLASS>
666 auto getOrAddImplicitNetcless = [
this](
const wxString& netclass ) -> std::shared_ptr<NETCLASS>
672 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( netclass,
false );
673 nc->SetPriority( std::numeric_limits<int>().max() - 1 );
684 if( aNetName.IsEmpty() )
691 return cacheItr->second;
694 std::vector<std::shared_ptr<NETCLASS>> resolvedNetclasses;
701 for(
const wxString& netclassName : it->second )
703 std::shared_ptr<NETCLASS> netclass = getExplicitNetclass( netclassName );
707 resolvedNetclasses.push_back( std::move( netclass ) );
711 resolvedNetclasses.push_back(
712 getOrAddImplicitNetcless( netclassName ) );
720 if( matcher->StartsWith( aNetName ) )
722 std::shared_ptr<NETCLASS> netclass = getExplicitNetclass( netclassName );
726 resolvedNetclasses.push_back( std::move( netclass ) );
730 resolvedNetclasses.push_back( getOrAddImplicitNetcless( netclassName ) );
736 if( resolvedNetclasses.size() == 0 )
746 std::vector<NETCLASS*> netclassPtrs;
748 for( std::shared_ptr<NETCLASS>& nc : resolvedNetclasses )
749 netclassPtrs.push_back( nc.get() );
752 name.Printf(
"Effective for net: %s", aNetName );
753 std::shared_ptr<NETCLASS> effectiveNetclass = std::make_shared<NETCLASS>(
name,
false );
756 if( netclassPtrs.size() == 1 )
760 return resolvedNetclasses[0];
764 effectiveNetclass->SetConstituentNetclasses( std::move( netclassPtrs ) );
769 return effectiveNetclass;
779 std::vector<NETCLASS*> constituents = nc->GetConstituentNetclasses();
781 wxASSERT( constituents.size() > 0 );
786 constituents.pop_back();
790 nc->ResetParameters();
792 nc->SetConstituentNetclasses( std::move( constituents ) );
798 std::vector<NETCLASS*>& constituentNetclasses )
const
802 std::sort( constituentNetclasses.begin(), constituentNetclasses.end(),
805 int p1 = nc1->GetPriority();
806 int p2 = nc2->GetPriority();
812 return nc1->GetName().Cmp( nc2->GetName() ) < 0;
818 for(
auto itr = constituentNetclasses.rbegin(); itr != constituentNetclasses.rend(); ++itr )
825 effectiveNetclass->SetClearanceParent( nc );
831 effectiveNetclass->SetTrackWidthParent( nc );
837 effectiveNetclass->SetViaDiameterParent( nc );
842 effectiveNetclass->SetViaDrill( nc->
GetViaDrill() );
843 effectiveNetclass->SetViaDrillParent( nc );
849 effectiveNetclass->SetuViaDiameterParent( nc );
855 effectiveNetclass->SetuViaDrillParent( nc );
861 effectiveNetclass->SetDiffPairWidthParent( nc );
867 effectiveNetclass->SetDiffPairGapParent( nc );
873 effectiveNetclass->SetDiffPairViaGapParent( nc );
879 effectiveNetclass->SetWireWidthParent( nc );
884 effectiveNetclass->SetBusWidth( nc->
GetBusWidth() );
885 effectiveNetclass->SetBusWidthParent( nc );
891 effectiveNetclass->SetLineStyleParent( nc );
896 if( pcbColor != COLOR4D::UNSPECIFIED )
898 effectiveNetclass->SetPcbColor( pcbColor );
899 effectiveNetclass->SetPcbColorParent( nc );
904 if( schColor != COLOR4D::UNSPECIFIED )
906 effectiveNetclass->SetSchematicColor( schColor );
907 effectiveNetclass->SetSchematicColorParent( nc );
919 bool addedDefault =
false;
1016 return c ==
'_' || c ==
'^' || c ==
'~';
1021 std::vector<wxString>* aMemberList )
1025 static wxString digits( wxT(
"0123456789" ) );
1026 return digits.Contains( c );
1029 size_t busLen = aBus.length();
1036 int braceNesting = 0;
1038 prefix.reserve( busLen );
1042 for( ; i < busLen; ++i )
1044 if( aBus[i] ==
'{' )
1051 else if( aBus[i] ==
'}' )
1056 if( aBus[i] ==
' ' || aBus[i] ==
']' )
1059 if( aBus[i] ==
'[' )
1072 for( ; i < busLen; ++i )
1074 if( aBus[i] ==
'.' && i + 1 < busLen && aBus[i+1] ==
'.' )
1076 tmp.ToLong( &begin );
1089 tmp = wxEmptyString;
1094 for( ; i < busLen; ++i )
1096 if( aBus[i] ==
']' )
1111 for( ; i < busLen; ++i )
1113 if( aBus[i] ==
'}' )
1124 if( braceNesting != 0 )
1129 else if( begin > end )
1130 std::swap( begin, end );
1137 for(
long idx = begin; idx <= end; ++idx )
1139 wxString str = prefix;
1143 aMemberList->emplace_back( str );
1152 std::vector<wxString>* aMemberList )
1154 size_t groupLen = aGroup.length();
1158 int braceNesting = 0;
1160 prefix.reserve( groupLen );
1164 for( ; i < groupLen; ++i )
1166 if( aGroup[i] ==
'{' )
1173 else if( aGroup[i] ==
'}' )
1178 if( aGroup[i] ==
' ' || aGroup[i] ==
'[' || aGroup[i] ==
']' )
1181 prefix += aGroup[i];
1184 if( braceNesting != 0 )
1197 for( ; i < groupLen; ++i )
1199 if( aGroup[i] ==
'{' )
1206 else if( aGroup[i] ==
'}' )
1214 if( aMemberList && !tmp.IsEmpty() )
1222 if( aGroup[i] ==
' ' || aGroup[i] ==
',' )
1224 if( aMemberList && !tmp.IsEmpty() )
constexpr EDA_IU_SCALE schIUScale
constexpr EDA_IU_SCALE pcbIUScale
void ReleaseNestedSettings(NESTED_SETTINGS *aSettings)
Saves and frees a nested settings object, if it exists within this one.
std::unique_ptr< JSON_SETTINGS_INTERNALS > m_internals
A color representation with 4 components: red, green, blue, alpha.
NESTED_SETTINGS is a JSON_SETTINGS that lives inside a JSON_SETTINGS.
JSON_SETTINGS * m_parent
A pointer to the parent object to load and store from.
A collection of nets and the parameters used to route or test these nets.
void SetViaDiameter(int aDia)
void SetViaDrill(int aSize)
bool HasLineStyle() const
int GetViaDiameter() const
void SetWireWidthParent(NETCLASS *parent)
static const char Default[]
the name of the default NETCLASS
void SetuViaDrillParent(NETCLASS *parent)
bool HasuViaDrill() const
void SetDiffPairWidthParent(NETCLASS *parent)
void SetuViaDiameter(int aSize)
void SetDiffPairWidth(int aSize)
int GetDiffPairViaGap() const
void SetViaDrillParent(NETCLASS *parent)
void SetDiffPairGapParent(NETCLASS *parent)
int GetDiffPairGap() const
bool HasViaDiameter() const
bool HasDiffPairWidth() const
bool HasuViaDiameter() const
void SetTrackWidthParent(NETCLASS *parent)
int GetuViaDiameter() const
bool HasTrackWidth() const
void SetViaDiameterParent(NETCLASS *parent)
int GetDiffPairWidth() const
void SetuViaDrill(int aSize)
void SetDiffPairGap(int aSize)
void SetBusWidthParent(NETCLASS *parent)
void SetClearance(int aClearance)
COLOR4D GetPcbColor(bool aIsForSave=false) const
bool HasDiffPairGap() const
COLOR4D GetSchematicColor(bool aIsForSave=false) const
void SetBusWidth(int aWidth)
void SetClearanceParent(NETCLASS *parent)
int GetTrackWidth() const
void SetWireWidth(int aWidth)
bool HasWireWidth() const
void SetuViaDiameterParent(NETCLASS *parent)
void SetTrackWidth(int aWidth)
bool HasDiffPairViaGap() const
bool HasClearance() const
NET_SETTINGS stores various net-related settings in a project context.
void ClearAllCaches()
Clears the effective netclass cache for all nets.
std::map< wxString, std::shared_ptr< NETCLASS > > m_compositeNetClasses
Map of netclass names to netclass definitions for.
bool addMissingDefaults(NETCLASS *nc) const
Adds any missing fields to the given netclass from the default netclass.
void ClearNetColorAssignments()
Clears all net name to color assignments Calling user is responsible for resetting the effective netc...
bool operator==(const NET_SETTINGS &aOther) const
void ClearCacheForNet(const wxString &netName)
Clears effective netclass cache for the given net.
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const wxString &aNetName)
Fetches the effective (may be aggregate) netclass for the given net name.
bool HasEffectiveNetClass(const wxString &aNetName) const
Determines if an effective netclass for the given net name has been cached.
void ClearNetclassLabelAssignments()
Clears all net name to netclasses assignments Calling user is responsible for resetting the effective...
void ClearNetclassLabelAssignment(const wxString &netName)
Clears a specific net name to netclass assignment Calling user is responsible for resetting the effec...
void ClearNetclassPatternAssignments()
Clears all netclass pattern assignments.
std::map< wxString, KIGFX::COLOR4D > m_netColorAssignments
A map of fully-qualified net names to colors used in the board context.
void SetNetclasses(const std::map< wxString, std::shared_ptr< NETCLASS > > &netclasses)
Sets all netclass Calling this method will reset the effective netclass calculation caches.
bool HasNetclassLabelAssignment(const wxString &netName) const
Determines if a given net name has netclasses assigned.
void SetNetclassLabelAssignment(const wxString &netName, const std::set< wxString > &netclasses)
Sets a net name to netclasses assignment Calling user is responsible for resetting the effective netc...
std::shared_ptr< NETCLASS > m_defaultNetClass
The default netclass.
static bool ParseBusGroup(const wxString &aGroup, wxString *name, std::vector< wxString > *aMemberList)
Parse a bus group label into the name and a list of components.
void ClearNetclasses()
Clears all netclasses Calling this method will reset the effective netclass calculation caches.
std::map< wxString, std::shared_ptr< NETCLASS > > m_impicitNetClasses
Map of netclass names to netclass definitions for implicit netclasses.
const std::map< wxString, std::shared_ptr< NETCLASS > > & GetCompositeNetclasses() const
Gets all composite (multiple assignment / missing defaults) netclasses.
std::vector< std::pair< std::unique_ptr< EDA_COMBINED_MATCHER >, wxString > > m_netClassPatternAssignments
List of net class pattern assignments.
std::map< wxString, std::shared_ptr< NETCLASS > > m_effectiveNetclassCache
Cache of nets to pattern-matched netclasses.
void SetNetclassPatternAssignments(std::vector< std::pair< std::unique_ptr< EDA_COMBINED_MATCHER >, wxString > > &&netclassPatterns)
Sets all netclass pattern assignments Calling user is responsible for resetting the effective netclas...
void SetNetclassPatternAssignment(const wxString &pattern, const wxString &netclass)
Sets a netclass pattern assignment Calling this method will reset the effective netclass calculation ...
std::map< wxString, std::shared_ptr< NETCLASS > > m_netClasses
Map of netclass names to netclass definitions.
const std::map< wxString, std::set< wxString > > & GetNetclassLabelAssignments() const
Gets all current net name to netclasses assignments.
const std::map< wxString, std::shared_ptr< NETCLASS > > & GetNetclasses() const
Gets all netclasses.
std::shared_ptr< NETCLASS > GetDefaultNetclass()
Gets the default netclass for the project.
static bool ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parse a bus vector (e.g.
const std::map< wxString, KIGFX::COLOR4D > & GetNetColorAssignments() const
Gets all net name to color assignments.
std::vector< std::pair< std::unique_ptr< EDA_COMBINED_MATCHER >, wxString > > & GetNetclassPatternAssignments()
Gets the netclass pattern assignments.
void RecomputeEffectiveNetclasses()
Recomputes the internal values of all aggregate effective netclasses Called when a value of a user-de...
std::shared_ptr< NETCLASS > GetCachedEffectiveNetClass(const wxString &aNetName) const
Returns an already cached effective netclass for the given net name.
std::map< wxString, std::set< wxString > > m_netClassLabelAssignments
Map of net names to resolved netclasses.
void SetNetclass(const wxString &netclassName, std::shared_ptr< NETCLASS > &netclass)
Sets the given netclass Calling user is responsible for resetting the effective netclass calculation ...
void makeEffectiveNetclass(std::shared_ptr< NETCLASS > &effectiveNetclass, std::vector< NETCLASS * > &netclasses) const
Creates an effective aggregate netclass from the given constituent netclasses.
void AppendNetclassLabelAssignment(const wxString &netName, const std::set< wxString > &netclasses)
Apppends to a net name to netclasses assignment Calling user is responsible for resetting the effecti...
void SetDefaultNetclass(std::shared_ptr< NETCLASS > netclass)
Sets the default netclass for the project Calling user is responsible for resetting the effective net...
std::shared_ptr< NETCLASS > GetNetClassByName(const wxString &aNetName) const
Get a NETCLASS object from a given Netclass name string.
void SetNetColorAssignment(const wxString &netName, const KIGFX::COLOR4D &color)
Sets a net to color assignment Calling user is responsible for resetting the effective netclass calcu...
NET_SETTINGS(JSON_SETTINGS *aParent, const std::string &aPath)
bool HasNetclass(const wxString &netclassName) const
Determines if the given netclass exists.
Like a normal param, but with custom getter and setter functions.
static bool isSuperSubOverbar(wxChar c)
const int netSettingsSchemaVersion
static std::optional< int > getInSchUnits(const nlohmann::json &aObj, const std::string &aKey, std::optional< int > aDefault=std::optional< int >())
static std::optional< int > getInPcbUnits(const nlohmann::json &aObj, const std::string &aKey, std::optional< int > aDefault=std::optional< int >())
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
constexpr double IUTomm(int iu) const
constexpr int IUToMils(int iu) const
constexpr int MilsToIU(int mils) const
constexpr int mmToIU(double mm) const