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 );
536 const std::set<wxString>& netclasses )
543 const std::set<wxString>& netclasses )
560 if( assignment.first->GetPattern() == pattern )
562 assignment.second = netclass;
570 { std::make_unique<EDA_COMBINED_MATCHER>( pattern,
CTX_NETCLASS ), netclass } );
577 std::vector<std::pair<std::unique_ptr<EDA_COMBINED_MATCHER>, wxString>>&& netclassPatterns )
584std::vector<std::pair<std::unique_ptr<EDA_COMBINED_MATCHER>, wxString>>&
601 wxString compositeNetclassName =
649 auto getExplicitNetclass = [
this](
const wxString& netclass ) -> std::shared_ptr<NETCLASS>
665 auto getOrAddImplicitNetcless = [
this](
const wxString& netclass ) -> std::shared_ptr<NETCLASS>
671 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( netclass,
false );
672 nc->SetPriority( std::numeric_limits<int>().max() - 1 );
683 if( aNetName.IsEmpty() )
690 return cacheItr->second;
693 std::vector<std::shared_ptr<NETCLASS>> resolvedNetclasses;
700 for(
const wxString& netclassName : it->second )
702 std::shared_ptr<NETCLASS> netclass = getExplicitNetclass( netclassName );
706 resolvedNetclasses.push_back( std::move( netclass ) );
710 resolvedNetclasses.push_back(
711 getOrAddImplicitNetcless( netclassName ) );
719 if( matcher->StartsWith( aNetName ) )
721 std::shared_ptr<NETCLASS> netclass = getExplicitNetclass( netclassName );
725 resolvedNetclasses.push_back( std::move( netclass ) );
729 resolvedNetclasses.push_back( getOrAddImplicitNetcless( netclassName ) );
735 if( resolvedNetclasses.size() == 0 )
745 std::vector<NETCLASS*> netclassPtrs;
747 for( std::shared_ptr<NETCLASS>& nc : resolvedNetclasses )
748 netclassPtrs.push_back( nc.get() );
751 name.Printf(
"Effective for net: %s", aNetName );
752 std::shared_ptr<NETCLASS> effectiveNetclass = std::make_shared<NETCLASS>(
name,
false );
755 if( netclassPtrs.size() == 1 )
759 return resolvedNetclasses[0];
763 effectiveNetclass->SetConstituentNetclasses( std::move( netclassPtrs ) );
768 return effectiveNetclass;
778 std::vector<NETCLASS*> constituents = nc->GetConstituentNetclasses();
780 wxASSERT( constituents.size() > 0 );
785 constituents.pop_back();
789 nc->ResetParameters();
791 nc->SetConstituentNetclasses( std::move( constituents ) );
797 std::vector<NETCLASS*>& constituentNetclasses )
const
801 std::sort( constituentNetclasses.begin(), constituentNetclasses.end(),
804 int p1 = nc1->GetPriority();
805 int p2 = nc2->GetPriority();
811 return nc1->GetName().Cmp( nc2->GetName() ) < 0;
817 for(
auto itr = constituentNetclasses.rbegin(); itr != constituentNetclasses.rend(); ++itr )
824 effectiveNetclass->SetClearanceParent( nc );
830 effectiveNetclass->SetTrackWidthParent( nc );
836 effectiveNetclass->SetViaDiameterParent( nc );
841 effectiveNetclass->SetViaDrill( nc->
GetViaDrill() );
842 effectiveNetclass->SetViaDrillParent( nc );
848 effectiveNetclass->SetuViaDiameterParent( nc );
854 effectiveNetclass->SetuViaDrillParent( nc );
860 effectiveNetclass->SetDiffPairWidthParent( nc );
866 effectiveNetclass->SetDiffPairGapParent( nc );
872 effectiveNetclass->SetDiffPairViaGapParent( nc );
878 effectiveNetclass->SetWireWidthParent( nc );
883 effectiveNetclass->SetBusWidth( nc->
GetBusWidth() );
884 effectiveNetclass->SetBusWidthParent( nc );
890 effectiveNetclass->SetLineStyleParent( nc );
895 if( pcbColor != COLOR4D::UNSPECIFIED )
897 effectiveNetclass->SetPcbColor( pcbColor );
898 effectiveNetclass->SetPcbColorParent( nc );
903 if( schColor != COLOR4D::UNSPECIFIED )
905 effectiveNetclass->SetSchematicColor( schColor );
906 effectiveNetclass->SetSchematicColorParent( nc );
918 bool addedDefault =
false;
1015 return c ==
'_' || c ==
'^' || c ==
'~';
1020 std::vector<wxString>* aMemberList )
1024 static wxString digits( wxT(
"0123456789" ) );
1025 return digits.Contains( c );
1028 size_t busLen = aBus.length();
1035 int braceNesting = 0;
1037 prefix.reserve( busLen );
1041 for( ; i < busLen; ++i )
1043 if( aBus[i] ==
'{' )
1050 else if( aBus[i] ==
'}' )
1055 if( aBus[i] ==
' ' || aBus[i] ==
']' )
1058 if( aBus[i] ==
'[' )
1071 for( ; i < busLen; ++i )
1073 if( aBus[i] ==
'.' && i + 1 < busLen && aBus[i+1] ==
'.' )
1075 tmp.ToLong( &begin );
1088 tmp = wxEmptyString;
1093 for( ; i < busLen; ++i )
1095 if( aBus[i] ==
']' )
1110 for( ; i < busLen; ++i )
1112 if( aBus[i] ==
'}' )
1123 if( braceNesting != 0 )
1128 else if( begin > end )
1129 std::swap( begin, end );
1136 for(
long idx = begin; idx <= end; ++idx )
1138 wxString str = prefix;
1142 aMemberList->emplace_back( str );
1151 std::vector<wxString>* aMemberList )
1153 size_t groupLen = aGroup.length();
1157 int braceNesting = 0;
1159 prefix.reserve( groupLen );
1163 for( ; i < groupLen; ++i )
1165 if( aGroup[i] ==
'{' )
1172 else if( aGroup[i] ==
'}' )
1177 if( aGroup[i] ==
' ' || aGroup[i] ==
'[' || aGroup[i] ==
']' )
1180 prefix += aGroup[i];
1183 if( braceNesting != 0 )
1196 for( ; i < groupLen; ++i )
1198 if( aGroup[i] ==
'{' )
1205 else if( aGroup[i] ==
'}' )
1213 if( aMemberList && !tmp.IsEmpty() )
1221 if( aGroup[i] ==
' ' || aGroup[i] ==
',' )
1223 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.
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.
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.
void ClearNetclassLabelAssignment(const wxString &netName)
Clears a specific net name to netclass assignment.
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.
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.
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.
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.
void SetNetclassPatternAssignment(const wxString &pattern, const wxString &netclass)
Sets a netclass pattern assignment.
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.
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.
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.
void SetDefaultNetclass(std::shared_ptr< NETCLASS > netclass)
Sets the default netclass for the project.
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.
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