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() )
69 []( nlohmann::json& json_array,
const std::shared_ptr<NETCLASS>& nc )
73 nlohmann::json nc_json = { {
"name", nc->GetName().ToUTF8() },
74 {
"priority", nc->GetPriority() },
75 {
"schematic_color", nc->GetSchematicColor(
true ) },
76 {
"pcb_color", nc->GetPcbColor(
true ) } };
79 []( nlohmann::json&
json,
const std::string& aKey,
int aValue )
84 if( nc->HasWireWidth() )
88 if( nc->HasBusWidth() )
91 if( nc->HasLineStyle() )
92 nc_json.push_back( {
"line_style", nc->GetLineStyle() } );
94 if( nc->HasClearance() )
95 saveInPcbUnits( nc_json,
"clearance", nc->GetClearance() );
97 if( nc->HasTrackWidth() )
98 saveInPcbUnits( nc_json,
"track_width", nc->GetTrackWidth() );
100 if( nc->HasViaDiameter() )
101 saveInPcbUnits( nc_json,
"via_diameter", nc->GetViaDiameter() );
103 if( nc->HasViaDrill() )
104 saveInPcbUnits( nc_json,
"via_drill", nc->GetViaDrill() );
106 if( nc->HasuViaDiameter() )
107 saveInPcbUnits( nc_json,
"microvia_diameter", nc->GetuViaDiameter() );
109 if( nc->HasuViaDrill() )
110 saveInPcbUnits( nc_json,
"microvia_drill", nc->GetuViaDrill() );
112 if( nc->HasDiffPairWidth() )
113 saveInPcbUnits( nc_json,
"diff_pair_width", nc->GetDiffPairWidth() );
115 if( nc->HasDiffPairGap() )
116 saveInPcbUnits( nc_json,
"diff_pair_gap", nc->GetDiffPairGap() );
118 if( nc->HasDiffPairViaGap() )
119 saveInPcbUnits( nc_json,
"diff_pair_via_gap", nc->GetDiffPairViaGap() );
121 json_array.push_back( nc_json );
125 [](
const nlohmann::json& entry )
127 wxString
name = entry[
"name"];
129 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>(
name,
false );
131 int priority = entry[
"priority"];
132 nc->SetPriority( priority );
135 nc->SetClearance( *value );
138 nc->SetTrackWidth( *value );
141 nc->SetViaDiameter( *value );
144 nc->SetViaDrill( *value );
146 if(
auto value =
getInPcbUnits( entry,
"microvia_diameter" ) )
147 nc->SetuViaDiameter( *value );
150 nc->SetuViaDrill( *value );
153 nc->SetDiffPairWidth( *value );
156 nc->SetDiffPairGap( *value );
158 if(
auto value =
getInPcbUnits( entry,
"diff_pair_via_gap" ) )
159 nc->SetDiffPairViaGap( *value );
162 nc->SetWireWidth( *value );
165 nc->SetBusWidth( *value );
167 if( entry.contains(
"line_style" ) && entry[
"line_style"].is_number() )
168 nc->SetLineStyle( entry[
"line_style"].get<int>() );
170 if( entry.contains(
"pcb_color" ) && entry[
"pcb_color"].is_string() )
171 nc->SetPcbColor( entry[
"pcb_color"].get<KIGFX::COLOR4D>() );
173 if( entry.contains(
"schematic_color" )
174 && entry[
"schematic_color"].is_string() )
176 nc->SetSchematicColor( entry[
"schematic_color"].get<KIGFX::COLOR4D>() );
183 [&]() -> nlohmann::json
185 nlohmann::json ret = nlohmann::json::array();
187 if( m_defaultNetClass )
188 saveNetclass( ret, m_defaultNetClass );
190 for(
const auto& [
name, netclass] : m_netClasses )
191 saveNetclass( ret, netclass );
195 [&](
const nlohmann::json& aJson )
197 if( !aJson.is_array() )
200 m_netClasses.clear();
202 for(
const nlohmann::json& entry : aJson )
204 if( !entry.is_object() || !entry.contains(
"name" ) )
207 std::shared_ptr<NETCLASS> nc = readNetClass( entry );
209 if( nc->IsDefault() )
210 m_defaultNetClass = nc;
212 m_netClasses[nc->GetName()] = nc;
218 [&]() -> nlohmann::json
220 nlohmann::json ret = {};
222 for(
const auto& [netname,
color] : m_netColorAssignments )
224 std::string key( netname.ToUTF8() );
225 ret[ std::move( key ) ] =
color;
230 [&](
const nlohmann::json& aJson )
232 if( !aJson.is_object() )
235 m_netColorAssignments.clear();
237 for(
const auto& pair : aJson.items() )
239 wxString key( pair.key().c_str(), wxConvUTF8 );
240 m_netColorAssignments[std::move( key )] = pair.value().get<
KIGFX::COLOR4D>();
246 [&]() -> nlohmann::json
248 nlohmann::json ret = {};
250 for(
const auto& [netname, netclassNames] : m_netClassLabelAssignments )
252 nlohmann::json netclassesJson = nlohmann::json::array();
254 for(
const auto& netclass : netclassNames )
256 std::string netclassStr( netclass.ToUTF8() );
257 netclassesJson.push_back( std::move( netclassStr ) );
260 std::string key( netname.ToUTF8() );
261 ret[std::move( key )] = netclassesJson;
266 [&](
const nlohmann::json& aJson )
268 if( !aJson.is_object() )
271 m_netClassLabelAssignments.clear();
273 for(
const auto& pair : aJson.items() )
275 wxString key( pair.key().c_str(), wxConvUTF8 );
277 for(
const auto& netclassName : pair.value() )
278 m_netClassLabelAssignments[key].insert( netclassName.get<wxString>() );
284 [&]() -> nlohmann::json
286 nlohmann::json ret = nlohmann::json::array();
288 for(
const auto& [matcher, netclassName] : m_netClassPatternAssignments )
290 nlohmann::json pattern_json = {
291 {
"pattern", matcher->GetPattern().ToUTF8() },
292 {
"netclass", netclassName.ToUTF8() }
295 ret.push_back( std::move( pattern_json ) );
300 [&](
const nlohmann::json& aJson )
302 if( !aJson.is_array() )
305 m_netClassPatternAssignments.clear();
307 for(
const nlohmann::json& entry : aJson )
309 if( !entry.is_object() )
312 if( entry.contains(
"pattern" ) && entry[
"pattern"].is_string()
313 && entry.contains(
"netclass" ) && entry[
"netclass"].is_string() )
315 wxString pattern = entry[
"pattern"].get<wxString>();
316 wxString netclass = entry[
"netclass"].get<wxString>();
318 m_netClassPatternAssignments.push_back(
319 { std::make_unique<EDA_COMBINED_MATCHER>( pattern,
CTX_NETCLASS ),
373 for(
auto& netClass :
m_internals->At(
"classes" ).items() )
375 if( netClass.value().contains(
"nets" ) && netClass.value()[
"nets"].is_array() )
377 nlohmann::json migrated = nlohmann::json::array();
379 for(
auto& net : netClass.value()[
"nets"].items() )
382 netClass.value()[
"nets"] = migrated;
401 nlohmann::json patterns = nlohmann::json::array();
403 for(
auto& netClass :
m_internals->At(
"classes" ).items() )
405 if( netClass.value().contains(
"name" )
406 && netClass.value().contains(
"nets" )
407 && netClass.value()[
"nets"].is_array() )
409 wxString netClassName = netClass.value()[
"name"].get<wxString>();
411 for(
auto& net : netClass.value()[
"nets"].items() )
413 nlohmann::json pattern_json = {
414 {
"pattern", net.value().get<wxString>() },
415 {
"netclass", netClassName }
418 patterns.push_back( pattern_json );
423 m_internals->SetFromString(
"netclass_patterns", patterns );
437 for(
auto& netClass :
m_internals->At(
"classes" ).items() )
440 netClass.value()[
"priority"] = std::numeric_limits<int>::max();
442 netClass.value()[
"priority"] = priority++;
447 if(
m_internals->contains(
"netclass_assignments" )
448 &&
m_internals->At(
"netclass_assignments" ).is_object() )
450 nlohmann::json migrated = {};
452 for(
const auto& pair :
m_internals->At(
"netclass_assignments" ).items() )
454 nlohmann::json netclassesJson = nlohmann::json::array();
456 if( pair.value().get<wxString>() != wxEmptyString )
457 netclassesJson.push_back( pair.value() );
459 migrated[pair.key()] = netclassesJson;
462 m_internals->SetFromString(
"netclass_assignments", migrated );
539 const std::set<wxString>& netclasses )
546 const std::set<wxString>& netclasses )
563 if( assignment.first->GetPattern() == pattern )
565 assignment.second = netclass;
573 { std::make_unique<EDA_COMBINED_MATCHER>( pattern,
CTX_NETCLASS ), netclass } );
580 std::vector<std::pair<std::unique_ptr<EDA_COMBINED_MATCHER>, wxString>>&& netclassPatterns )
587std::vector<std::pair<std::unique_ptr<EDA_COMBINED_MATCHER>, wxString>>&
651 auto getExplicitNetclass = [
this](
const wxString& netclass ) -> std::shared_ptr<NETCLASS>
667 auto getOrAddImplicitNetcless = [
this](
const wxString& netclass ) -> std::shared_ptr<NETCLASS>
673 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( netclass,
false );
674 nc->SetPriority( std::numeric_limits<int>::max() - 1 );
685 if( aNetName.IsEmpty() )
692 return cacheItr->second;
695 std::vector<std::shared_ptr<NETCLASS>> resolvedNetclasses;
702 for(
const wxString& netclassName : it->second )
704 std::shared_ptr<NETCLASS> netclass = getExplicitNetclass( netclassName );
708 resolvedNetclasses.push_back( std::move( netclass ) );
712 resolvedNetclasses.push_back(
713 getOrAddImplicitNetcless( netclassName ) );
721 if( matcher->StartsWith( aNetName ) )
723 std::shared_ptr<NETCLASS> netclass = getExplicitNetclass( netclassName );
727 resolvedNetclasses.push_back( std::move( netclass ) );
731 resolvedNetclasses.push_back( getOrAddImplicitNetcless( netclassName ) );
737 if( resolvedNetclasses.size() == 0 )
747 std::vector<NETCLASS*> netclassPtrs;
749 for( std::shared_ptr<NETCLASS>& nc : resolvedNetclasses )
750 netclassPtrs.push_back( nc.get() );
753 name.Printf(
"Effective for net: %s", aNetName );
754 std::shared_ptr<NETCLASS> effectiveNetclass = std::make_shared<NETCLASS>(
name,
false );
757 if( netclassPtrs.size() == 1 )
761 return resolvedNetclasses[0];
765 effectiveNetclass->SetConstituentNetclasses( std::move( netclassPtrs ) );
770 return effectiveNetclass;
780 std::vector<NETCLASS*> constituents = nc->GetConstituentNetclasses();
782 wxASSERT( constituents.size() > 0 );
787 constituents.pop_back();
791 nc->ResetParameters();
793 nc->SetConstituentNetclasses( std::move( constituents ) );
799 std::vector<NETCLASS*>& constituentNetclasses )
const
803 std::sort( constituentNetclasses.begin(), constituentNetclasses.end(),
806 int p1 = nc1->GetPriority();
807 int p2 = nc2->GetPriority();
813 return nc1->GetName().Cmp( nc2->GetName() ) < 0;
819 for(
auto itr = constituentNetclasses.rbegin(); itr != constituentNetclasses.rend(); ++itr )
826 effectiveNetclass->SetClearanceParent( nc );
832 effectiveNetclass->SetTrackWidthParent( nc );
838 effectiveNetclass->SetViaDiameterParent( nc );
843 effectiveNetclass->SetViaDrill( nc->
GetViaDrill() );
844 effectiveNetclass->SetViaDrillParent( nc );
850 effectiveNetclass->SetuViaDiameterParent( nc );
856 effectiveNetclass->SetuViaDrillParent( nc );
862 effectiveNetclass->SetDiffPairWidthParent( nc );
868 effectiveNetclass->SetDiffPairGapParent( nc );
874 effectiveNetclass->SetDiffPairViaGapParent( nc );
880 effectiveNetclass->SetWireWidthParent( nc );
885 effectiveNetclass->SetBusWidth( nc->
GetBusWidth() );
886 effectiveNetclass->SetBusWidthParent( nc );
892 effectiveNetclass->SetLineStyleParent( nc );
897 if( pcbColor != COLOR4D::UNSPECIFIED )
899 effectiveNetclass->SetPcbColor( pcbColor );
900 effectiveNetclass->SetPcbColorParent( nc );
905 if( schColor != COLOR4D::UNSPECIFIED )
907 effectiveNetclass->SetSchematicColor( schColor );
908 effectiveNetclass->SetSchematicColorParent( nc );
920 bool addedDefault =
false;
1000 return addedDefault;
1017 return c ==
'_' || c ==
'^' || c ==
'~';
1022 std::vector<wxString>* aMemberList )
1026 static wxString digits( wxT(
"0123456789" ) );
1027 return digits.Contains( c );
1030 size_t busLen = aBus.length();
1037 int braceNesting = 0;
1039 prefix.reserve( busLen );
1043 for( ; i < busLen; ++i )
1045 if( aBus[i] ==
'{' )
1052 else if( aBus[i] ==
'}' )
1057 if( aBus[i] ==
' ' || aBus[i] ==
']' )
1060 if( aBus[i] ==
'[' )
1073 for( ; i < busLen; ++i )
1075 if( aBus[i] ==
'.' && i + 1 < busLen && aBus[i+1] ==
'.' )
1077 tmp.ToLong( &begin );
1090 tmp = wxEmptyString;
1095 for( ; i < busLen; ++i )
1097 if( aBus[i] ==
']' )
1112 for( ; i < busLen; ++i )
1114 if( aBus[i] ==
'}' )
1125 if( braceNesting != 0 )
1130 else if( begin >
end )
1131 std::swap( begin,
end );
1138 for(
long idx = begin; idx <=
end; ++idx )
1140 wxString str = prefix;
1144 aMemberList->emplace_back( str );
1153 std::vector<wxString>* aMemberList )
1155 size_t groupLen = aGroup.length();
1159 int braceNesting = 0;
1161 prefix.reserve( groupLen );
1165 for( ; i < groupLen; ++i )
1167 if( aGroup[i] ==
'{' )
1174 else if( aGroup[i] ==
'}' )
1179 if( aGroup[i] ==
' ' || aGroup[i] ==
'[' || aGroup[i] ==
']' )
1182 prefix += aGroup[i];
1185 if( braceNesting != 0 )
1198 for( ; i < groupLen; ++i )
1200 if( aGroup[i] ==
'{' )
1207 else if( aGroup[i] ==
'}' )
1215 if( aMemberList && !tmp.IsEmpty() )
1223 if( aGroup[i] ==
' ' || aGroup[i] ==
',' )
1225 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