KiCad PCB EDA Suite
Loading...
Searching...
No Matches
net_settings.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2020 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Jon Evans <[email protected]>
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <algorithm>
23#include <limits>
24
25#include <json_common.h>
26
28#include <settings/parameters.h>
30#include <string_utils.h>
31#include <base_units.h>
32#include <unordered_set>
33
34
35// const int netSettingsSchemaVersion = 0;
36// const int netSettingsSchemaVersion = 1; // new overbar syntax
37// const int netSettingsSchemaVersion = 2; // exclude buses from netclass members
38// const int netSettingsSchemaVersion = 3; // netclass assignment patterns
39// const int netSettingsSchemaVersion = 4; // netclass ordering
40const int netSettingsSchemaVersion = 5; // Tuning profile names
41
42
43static std::optional<int> getInPcbUnits( const nlohmann::json& aObj, const std::string& aKey,
44 std::optional<int> aDefault = std::optional<int>() )
45{
46 if( aObj.contains( aKey ) && aObj[aKey].is_number() )
47 return pcbIUScale.mmToIU( aObj[aKey].get<double>() );
48 else
49 return aDefault;
50};
51
52
53static std::optional<int> getInSchUnits( const nlohmann::json& aObj, const std::string& aKey,
54 std::optional<int> aDefault = std::optional<int>() )
55{
56 if( aObj.contains( aKey ) && aObj[aKey].is_number() )
57 return schIUScale.MilsToIU( aObj[aKey].get<double>() );
58 else
59 return aDefault;
60};
61
62
63NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
64 NESTED_SETTINGS( "net_settings", netSettingsSchemaVersion, aParent, aPath, false )
65{
66 m_defaultNetClass = std::make_shared<NETCLASS>( NETCLASS::Default, true );
67 m_defaultNetClass->SetDescription( _( "This is the default net class." ) );
68 m_defaultNetClass->SetPriority( std::numeric_limits<int>::max() );
69
70 auto saveNetclass =
71 []( nlohmann::json& json_array, const std::shared_ptr<NETCLASS>& nc )
72 {
73 // Note: we're in common/, but we do happen to know which of these
74 // fields are used in which units system.
75 nlohmann::json nc_json = { { "name", nc->GetName().ToUTF8() },
76 { "priority", nc->GetPriority() },
77 { "schematic_color", nc->GetSchematicColor( true ) },
78 { "pcb_color", nc->GetPcbColor( true ) },
79 { "tuning_profile", nc->GetTuningProfile() } };
80
81 auto saveInPcbUnits =
82 []( nlohmann::json& json, const std::string& aKey, int aValue )
83 {
84 json.push_back( { aKey, pcbIUScale.IUTomm( aValue ) } );
85 };
86
87 if( nc->HasWireWidth() )
88 nc_json.push_back(
89 { "wire_width", schIUScale.IUToMils( nc->GetWireWidth() ) } );
90
91 if( nc->HasBusWidth() )
92 nc_json.push_back( { "bus_width", schIUScale.IUToMils( nc->GetBusWidth() ) } );
93
94 if( nc->HasLineStyle() )
95 nc_json.push_back( { "line_style", nc->GetLineStyle() } );
96
97 if( nc->HasClearance() )
98 saveInPcbUnits( nc_json, "clearance", nc->GetClearance() );
99
100 if( nc->HasTrackWidth() )
101 saveInPcbUnits( nc_json, "track_width", nc->GetTrackWidth() );
102
103 if( nc->HasViaDiameter() )
104 saveInPcbUnits( nc_json, "via_diameter", nc->GetViaDiameter() );
105
106 if( nc->HasViaDrill() )
107 saveInPcbUnits( nc_json, "via_drill", nc->GetViaDrill() );
108
109 if( nc->HasuViaDiameter() )
110 saveInPcbUnits( nc_json, "microvia_diameter", nc->GetuViaDiameter() );
111
112 if( nc->HasuViaDrill() )
113 saveInPcbUnits( nc_json, "microvia_drill", nc->GetuViaDrill() );
114
115 if( nc->HasDiffPairWidth() )
116 saveInPcbUnits( nc_json, "diff_pair_width", nc->GetDiffPairWidth() );
117
118 if( nc->HasDiffPairGap() )
119 saveInPcbUnits( nc_json, "diff_pair_gap", nc->GetDiffPairGap() );
120
121 if( nc->HasDiffPairViaGap() )
122 saveInPcbUnits( nc_json, "diff_pair_via_gap", nc->GetDiffPairViaGap() );
123
124 json_array.push_back( nc_json );
125 };
126
127 auto readNetClass =
128 []( const nlohmann::json& entry )
129 {
130 wxString name = entry["name"];
131
132 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( name, false );
133
134 int priority = entry["priority"];
135 nc->SetPriority( priority );
136
137 nc->SetTuningProfile( entry["tuning_profile"] );
138
139 if( auto value = getInPcbUnits( entry, "clearance" ) )
140 nc->SetClearance( *value );
141
142 if( auto value = getInPcbUnits( entry, "track_width" ) )
143 nc->SetTrackWidth( *value );
144
145 if( auto value = getInPcbUnits( entry, "via_diameter" ) )
146 nc->SetViaDiameter( *value );
147
148 if( auto value = getInPcbUnits( entry, "via_drill" ) )
149 nc->SetViaDrill( *value );
150
151 if( auto value = getInPcbUnits( entry, "microvia_diameter" ) )
152 nc->SetuViaDiameter( *value );
153
154 if( auto value = getInPcbUnits( entry, "microvia_drill" ) )
155 nc->SetuViaDrill( *value );
156
157 if( auto value = getInPcbUnits( entry, "diff_pair_width" ) )
158 nc->SetDiffPairWidth( *value );
159
160 if( auto value = getInPcbUnits( entry, "diff_pair_gap" ) )
161 nc->SetDiffPairGap( *value );
162
163 if( auto value = getInPcbUnits( entry, "diff_pair_via_gap" ) )
164 nc->SetDiffPairViaGap( *value );
165
166 if( auto value = getInSchUnits( entry, "wire_width" ) )
167 nc->SetWireWidth( *value );
168
169 if( auto value = getInSchUnits( entry, "bus_width" ) )
170 nc->SetBusWidth( *value );
171
172 if( entry.contains( "line_style" ) && entry["line_style"].is_number() )
173 nc->SetLineStyle( entry["line_style"].get<int>() );
174
175 if( entry.contains( "pcb_color" ) && entry["pcb_color"].is_string() )
176 nc->SetPcbColor( entry["pcb_color"].get<KIGFX::COLOR4D>() );
177
178 if( entry.contains( "schematic_color" )
179 && entry["schematic_color"].is_string() )
180 {
181 nc->SetSchematicColor( entry["schematic_color"].get<KIGFX::COLOR4D>() );
182 }
183
184 return nc;
185 };
186
187 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "classes",
188 [&]() -> nlohmann::json
189 {
190 nlohmann::json ret = nlohmann::json::array();
191
193 saveNetclass( ret, m_defaultNetClass );
194
195 for( const auto& [name, netclass] : m_netClasses )
196 saveNetclass( ret, netclass );
197
198 return ret;
199 },
200 [&]( const nlohmann::json& aJson )
201 {
202 if( !aJson.is_array() )
203 return;
204
205 m_netClasses.clear();
206
207 for( const nlohmann::json& entry : aJson )
208 {
209 if( !entry.is_object() || !entry.contains( "name" ) )
210 continue;
211
212 std::shared_ptr<NETCLASS> nc = readNetClass( entry );
213
214 if( nc->IsDefault() )
216 else
217 m_netClasses[nc->GetName()] = nc;
218 }
219 },
220 {} ) );
221
222 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "net_colors",
223 [&]() -> nlohmann::json
224 {
225 nlohmann::json ret = {};
226
227 for( const auto& [netname, color] : m_netColorAssignments )
228 {
229 std::string key( netname.ToUTF8() );
230 ret[ std::move( key ) ] = color;
231 }
232
233 return ret;
234 },
235 [&]( const nlohmann::json& aJson )
236 {
237 if( !aJson.is_object() )
238 return;
239
240 m_netColorAssignments.clear();
241
242 for( const auto& pair : aJson.items() )
243 {
244 wxString key( pair.key().c_str(), wxConvUTF8 );
245 m_netColorAssignments[std::move( key )] = pair.value().get<KIGFX::COLOR4D>();
246 }
247 },
248 {} ) );
249
250 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "netclass_assignments",
251 [&]() -> nlohmann::json
252 {
253 nlohmann::json ret = {};
254
255 for( const auto& [netname, netclassNames] : m_netClassLabelAssignments )
256 {
257 nlohmann::json netclassesJson = nlohmann::json::array();
258
259 for( const auto& netclass : netclassNames )
260 {
261 std::string netclassStr( netclass.ToUTF8() );
262 netclassesJson.push_back( std::move( netclassStr ) );
263 }
264
265 std::string key( netname.ToUTF8() );
266 ret[std::move( key )] = netclassesJson;
267 }
268
269 return ret;
270 },
271 [&]( const nlohmann::json& aJson )
272 {
273 if( !aJson.is_object() )
274 return;
275
277
278 for( const auto& pair : aJson.items() )
279 {
280 wxString key( pair.key().c_str(), wxConvUTF8 );
281
282 for( const auto& netclassName : pair.value() )
283 m_netClassLabelAssignments[key].insert( netclassName.get<wxString>() );
284 }
285 },
286 {} ) );
287
288 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "netclass_patterns",
289 [&]() -> nlohmann::json
290 {
291 nlohmann::json ret = nlohmann::json::array();
292
293 for( const auto& [matcher, netclassName] : m_netClassPatternAssignments )
294 {
295 nlohmann::json pattern_json = {
296 { "pattern", matcher->GetPattern().ToUTF8() },
297 { "netclass", netclassName.ToUTF8() }
298 };
299
300 ret.push_back( std::move( pattern_json ) );
301 }
302
303 return ret;
304 },
305 [&]( const nlohmann::json& aJson )
306 {
307 if( !aJson.is_array() )
308 return;
309
311
312 for( const nlohmann::json& entry : aJson )
313 {
314 if( !entry.is_object() )
315 continue;
316
317 if( entry.contains( "pattern" ) && entry["pattern"].is_string()
318 && entry.contains( "netclass" ) && entry["netclass"].is_string() )
319 {
320 wxString pattern = entry["pattern"].get<wxString>();
321 wxString netclass = entry["netclass"].get<wxString>();
322
323 // Expand bus patterns so individual bus member nets can be matched
324 ForEachBusMember( pattern,
325 [&]( const wxString& memberPattern )
326 {
327 addSinglePatternAssignment( memberPattern, netclass );
328 } );
329 }
330 }
331 },
332 {} ) );
333
334 registerMigration( 0, 1, std::bind( &NET_SETTINGS::migrateSchema0to1, this ) );
335 registerMigration( 1, 2, std::bind( &NET_SETTINGS::migrateSchema1to2, this ) );
336 registerMigration( 2, 3, std::bind( &NET_SETTINGS::migrateSchema2to3, this ) );
337 registerMigration( 3, 4, std::bind( &NET_SETTINGS::migrateSchema3to4, this ) );
338 registerMigration( 4, 5, std::bind( &NET_SETTINGS::migrateSchema4to5, this ) );
339}
340
341
343{
344 // Release early before destroying members
345 if( m_parent )
346 {
347 m_parent->ReleaseNestedSettings( this );
348 m_parent = nullptr;
349 }
350}
351
352
353bool NET_SETTINGS::operator==( const NET_SETTINGS& aOther ) const
354{
355 if( !std::equal( std::begin( m_netClasses ), std::end( m_netClasses ),
356 std::begin( aOther.m_netClasses ) ) )
357 return false;
358
359 if( !std::equal( std::begin( m_netClassPatternAssignments ),
361 std::begin( aOther.m_netClassPatternAssignments ) ) )
362 return false;
363
364 if( !std::equal( std::begin( m_netClassLabelAssignments ),
365 std::end( m_netClassLabelAssignments ),
366 std::begin( aOther.m_netClassLabelAssignments ) ) )
367 return false;
368
369
370 if( !std::equal( std::begin( m_netColorAssignments ), std::end( m_netColorAssignments ),
371 std::begin( aOther.m_netColorAssignments ) ) )
372 return false;
373
374 return true;
375}
376
377
379{
380 if( m_internals->contains( "classes" ) && m_internals->At( "classes" ).is_array() )
381 {
382 for( auto& netClass : m_internals->At( "classes" ).items() )
383 {
384 if( netClass.value().contains( "nets" ) && netClass.value()["nets"].is_array() )
385 {
386 nlohmann::json migrated = nlohmann::json::array();
387
388 for( auto& net : netClass.value()["nets"].items() )
389 migrated.push_back( ConvertToNewOverbarNotation( net.value().get<wxString>() ) );
390
391 netClass.value()["nets"] = migrated;
392 }
393 }
394 }
395
396 return true;
397}
398
399
401{
402 return true;
403}
404
405
407{
408 if( m_internals->contains( "classes" ) && m_internals->At( "classes" ).is_array() )
409 {
410 nlohmann::json patterns = nlohmann::json::array();
411
412 for( auto& netClass : m_internals->At( "classes" ).items() )
413 {
414 if( netClass.value().contains( "name" )
415 && netClass.value().contains( "nets" )
416 && netClass.value()["nets"].is_array() )
417 {
418 wxString netClassName = netClass.value()["name"].get<wxString>();
419
420 for( auto& net : netClass.value()["nets"].items() )
421 {
422 nlohmann::json pattern_json = {
423 { "pattern", net.value().get<wxString>() },
424 { "netclass", netClassName }
425 };
426
427 patterns.push_back( pattern_json );
428 }
429 }
430 }
431
432 m_internals->SetFromString( "netclass_patterns", patterns );
433 }
434
435 return true;
436}
437
438
440{
441 // Add priority field to netclasses
442 if( m_internals->contains( "classes" ) && m_internals->At( "classes" ).is_array() )
443 {
444 int priority = 0;
445
446 for( auto& netClass : m_internals->At( "classes" ).items() )
447 {
448 if( netClass.value()["name"].get<wxString>() == NETCLASS::Default )
449 netClass.value()["priority"] = std::numeric_limits<int>::max();
450 else
451 netClass.value()["priority"] = priority++;
452 }
453 }
454
455 // Move netclass assignments to a list
456 if( m_internals->contains( "netclass_assignments" )
457 && m_internals->At( "netclass_assignments" ).is_object() )
458 {
459 nlohmann::json migrated = {};
460
461 for( const auto& pair : m_internals->At( "netclass_assignments" ).items() )
462 {
463 nlohmann::json netclassesJson = nlohmann::json::array();
464
465 if( pair.value().get<wxString>() != wxEmptyString )
466 netclassesJson.push_back( pair.value() );
467
468 migrated[pair.key()] = netclassesJson;
469 }
470
471 m_internals->SetFromString( "netclass_assignments", migrated );
472 }
473
474 return true;
475}
476
477
479{
480 // Add tuning profile name field to netclasses
481 if( m_internals->contains( "classes" ) && m_internals->At( "classes" ).is_array() )
482 {
483 const wxString emptyStr = "";
484
485 for( auto& netClass : m_internals->At( "classes" ).items() )
486 netClass.value()["tuning_profile"] = emptyStr.ToUTF8();
487 }
488
489 return true;
490}
491
492
493void NET_SETTINGS::SetDefaultNetclass( std::shared_ptr<NETCLASS> netclass )
494{
495 m_defaultNetClass = netclass;
496}
497
498
499std::shared_ptr<NETCLASS> NET_SETTINGS::GetDefaultNetclass()
500{
501 return m_defaultNetClass;
502}
503
504
505bool NET_SETTINGS::HasNetclass( const wxString& netclassName ) const
506{
507 return m_netClasses.find( netclassName ) != m_netClasses.end();
508}
509
510
511void NET_SETTINGS::SetNetclass( const wxString& netclassName, std::shared_ptr<NETCLASS>& netclass )
512{
513 m_netClasses[netclassName] = netclass;
514}
515
516
517void NET_SETTINGS::SetNetclasses( const std::map<wxString, std::shared_ptr<NETCLASS>>& netclasses )
518{
519 m_netClasses = netclasses;
521}
522
523
524const std::map<wxString, std::shared_ptr<NETCLASS>>& NET_SETTINGS::GetNetclasses() const
525{
526 return m_netClasses;
527}
528
529
530const std::map<wxString, std::shared_ptr<NETCLASS>>& NET_SETTINGS::GetCompositeNetclasses() const
531{
533}
534
535
537{
538 m_netClasses.clear();
539 m_impicitNetClasses.clear();
541}
542
543
544const std::map<wxString, std::set<wxString>>& NET_SETTINGS::GetNetclassLabelAssignments() const
545{
547}
548
549
554
555
556void NET_SETTINGS::ClearNetclassLabelAssignment( const wxString& netName )
557{
558 m_netClassLabelAssignments.erase( netName );
559}
560
561
562void NET_SETTINGS::SetNetclassLabelAssignment( const wxString& netName,
563 const std::set<wxString>& netclasses )
564{
565 m_netClassLabelAssignments[netName] = netclasses;
566}
567
568
570 const std::set<wxString>& netclasses )
571{
572 m_netClassLabelAssignments[netName].insert( netclasses.begin(), netclasses.end() );
573}
574
575
576bool NET_SETTINGS::HasNetclassLabelAssignment( const wxString& netName ) const
577{
578 return m_netClassLabelAssignments.find( netName ) != m_netClassLabelAssignments.end();
579}
580
581
582void NET_SETTINGS::SetNetclassPatternAssignment( const wxString& pattern, const wxString& netclass )
583{
584 // Expand bus patterns (vector buses and bus groups) to individual member patterns.
585 // This is necessary because the regex/wildcard matchers interpret brackets and braces
586 // as special characters, not as bus notation.
587 ForEachBusMember( pattern,
588 [&]( const wxString& memberPattern )
589 {
590 addSinglePatternAssignment( memberPattern, netclass );
591 } );
592
594}
595
596
597void NET_SETTINGS::addSinglePatternAssignment( const wxString& pattern, const wxString& netclass )
598{
599 // Avoid exact duplicates - these shouldn't cause problems, due to later de-duplication
600 // but they are unnecessary.
601 for( auto& assignment : m_netClassPatternAssignments )
602 {
603 if( assignment.first->GetPattern() == pattern && assignment.second == netclass )
604 return;
605 }
606
607 // No assignment, add a new one
609 { std::make_unique<EDA_COMBINED_MATCHER>( pattern, CTX_NETCLASS ), netclass } );
610}
611
612
614 std::vector<std::pair<std::unique_ptr<EDA_COMBINED_MATCHER>, wxString>>&& netclassPatterns )
615{
616 m_netClassPatternAssignments = std::move( netclassPatterns );
618}
619
620
621std::vector<std::pair<std::unique_ptr<EDA_COMBINED_MATCHER>, wxString>>&
626
627
632
633
634void NET_SETTINGS::ClearCacheForNet( const wxString& netName )
635{
636 if( m_effectiveNetclassCache.count( netName ) )
637 {
638 wxString compositeNetclassName = m_effectiveNetclassCache[netName]->GetName();
639 m_compositeNetClasses.erase( compositeNetclassName );
640 m_effectiveNetclassCache.erase( netName );
641 }
642}
643
644
650
651
652void NET_SETTINGS::SetNetColorAssignment( const wxString& netName, const KIGFX::COLOR4D& color )
653{
654 m_netColorAssignments[netName] = color;
655}
656
657
658const std::map<wxString, KIGFX::COLOR4D>& NET_SETTINGS::GetNetColorAssignments() const
659{
661}
662
663
668
669
670bool NET_SETTINGS::HasEffectiveNetClass( const wxString& aNetName ) const
671{
672 return m_effectiveNetclassCache.count( aNetName ) > 0;
673}
674
675
676std::shared_ptr<NETCLASS> NET_SETTINGS::GetCachedEffectiveNetClass( const wxString& aNetName ) const
677{
678 return m_effectiveNetclassCache.at( aNetName );
679}
680
681
682std::shared_ptr<NETCLASS> NET_SETTINGS::GetEffectiveNetClass( const wxString& aNetName )
683{
684 // Lambda to fetch an explicit netclass. Returns a nullptr if not found
685 auto getExplicitNetclass =
686 [this]( const wxString& netclass ) -> std::shared_ptr<NETCLASS>
687 {
688 if( netclass == NETCLASS::Default )
689 return m_defaultNetClass;
690
691 auto ii = m_netClasses.find( netclass );
692
693 if( ii == m_netClasses.end() )
694 return {};
695 else
696 return ii->second;
697 };
698
699 // Lambda to fetch or create an implicit netclass (defined with a label, but not configured)
700 // These are needed as while they do not provide any netclass parameters, they do now appear in
701 // DRC matching strings as an assigned netclass.
702 auto getOrAddImplicitNetcless =
703 [this]( const wxString& netclass ) -> std::shared_ptr<NETCLASS>
704 {
705 auto ii = m_impicitNetClasses.find( netclass );
706
707 if( ii == m_impicitNetClasses.end() )
708 {
709 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( netclass, false );
710 nc->SetPriority( std::numeric_limits<int>::max() - 1 ); // Priority > default netclass
711 m_impicitNetClasses[netclass] = nc;
712 return nc;
713 }
714 else
715 {
716 return ii->second;
717 }
718 };
719
720 // <no net> is forced to be part of the default netclass.
721 if( aNetName.IsEmpty() )
722 return m_defaultNetClass;
723
724 // First check if we have a cached resolved netclass
725 auto cacheItr = m_effectiveNetclassCache.find( aNetName );
726
727 if( cacheItr != m_effectiveNetclassCache.end() )
728 return cacheItr->second;
729
730 // No cache found - build a vector of all netclasses assigned to or matching this net
731 std::unordered_set<std::shared_ptr<NETCLASS>> resolvedNetclasses;
732
733 // First find explicit netclass assignments
734 auto it = m_netClassLabelAssignments.find( aNetName );
735
736 if( it != m_netClassLabelAssignments.end() && it->second.size() > 0 )
737 {
738 for( const wxString& netclassName : it->second )
739 {
740 std::shared_ptr<NETCLASS> netclass = getExplicitNetclass( netclassName );
741
742 if( netclass )
743 {
744 resolvedNetclasses.insert( std::move( netclass ) );
745 }
746 else
747 {
748 resolvedNetclasses.insert( getOrAddImplicitNetcless( netclassName ) );
749 }
750 }
751 }
752
753 // Now find any pattern-matched netclass assignments
754 for( const auto& [matcher, netclassName] : m_netClassPatternAssignments )
755 {
756 if( matcher->StartsWith( aNetName ) )
757 {
758 std::shared_ptr<NETCLASS> netclass = getExplicitNetclass( netclassName );
759
760 if( netclass )
761 {
762 resolvedNetclasses.insert( std::move( netclass ) );
763 }
764 else
765 {
766 resolvedNetclasses.insert( getOrAddImplicitNetcless( netclassName ) );
767 }
768 }
769 }
770
771 // Handle zero resolved netclasses
772 if( resolvedNetclasses.size() == 0 )
773 {
774 // For bus patterns, check if all members share the same netclass.
775 // If they do, the bus inherits that netclass for coloring purposes.
776 std::shared_ptr<NETCLASS> sharedNetclass;
777 bool allSameNetclass = true;
778 bool isBusPattern = false;
779
780 ForEachBusMember( aNetName,
781 [&]( const wxString& member )
782 {
783 // If ForEachBusMember gives us back the same name, it's not a bus.
784 // Skip to avoid infinite recursion.
785 if( member == aNetName )
786 return;
787
788 isBusPattern = true;
789
790 if( !allSameNetclass )
791 return;
792
793 std::shared_ptr<NETCLASS> memberNc = GetEffectiveNetClass( member );
794
795 if( !sharedNetclass )
796 {
797 sharedNetclass = memberNc;
798 }
799 else if( memberNc->GetName() != sharedNetclass->GetName() )
800 {
801 allSameNetclass = false;
802 }
803 } );
804
805 if( isBusPattern && allSameNetclass && sharedNetclass
806 && sharedNetclass->GetName() != NETCLASS::Default )
807 {
808 m_effectiveNetclassCache[aNetName] = sharedNetclass;
809 return sharedNetclass;
810 }
811
813
814 return m_defaultNetClass;
815 }
816
817 // Make and cache the effective netclass. Note that makeEffectiveNetclass will add the default
818 // netclass to resolvedNetclasses if it is needed to complete the netclass paramters set. It
819 // will also sort resolvedNetclasses by priority order.
820 std::vector<NETCLASS*> netclassPtrs;
821
822 for( const std::shared_ptr<NETCLASS>& nc : resolvedNetclasses )
823 netclassPtrs.push_back( nc.get() );
824
825 wxString name;
826 name.Printf( "Effective for net: %s", aNetName );
827 std::shared_ptr<NETCLASS> effectiveNetclass = std::make_shared<NETCLASS>( name, false );
828 makeEffectiveNetclass( effectiveNetclass, netclassPtrs );
829
830 if( netclassPtrs.size() == 1 )
831 {
832 // No defaults were added - just return the primary netclass
833 m_effectiveNetclassCache[aNetName] = *resolvedNetclasses.begin();
834 return *resolvedNetclasses.begin();
835 }
836 else
837 {
838 effectiveNetclass->SetConstituentNetclasses( std::move( netclassPtrs ) );
839
840 m_compositeNetClasses[effectiveNetclass->GetName()] = effectiveNetclass;
841 m_effectiveNetclassCache[aNetName] = effectiveNetclass;
842
843 return effectiveNetclass;
844 }
845}
846
847
849{
850 for( auto& [ncName, nc] : m_compositeNetClasses )
851 {
852 // Note this needs to be a copy in case we now need to add the default netclass
853 std::vector<NETCLASS*> constituents = nc->GetConstituentNetclasses();
854
855 wxASSERT( constituents.size() > 0 );
856
857 // If the last netclass is Default, remove it (it will be re-added if still needed)
858 if( ( *constituents.rbegin() )->GetName() == NETCLASS::Default )
859 {
860 constituents.pop_back();
861 }
862
863 // Remake the netclass from original constituents
864 nc->ResetParameters();
865 makeEffectiveNetclass( nc, constituents );
866 nc->SetConstituentNetclasses( std::move( constituents ) );
867 }
868}
869
870
871void NET_SETTINGS::makeEffectiveNetclass( std::shared_ptr<NETCLASS>& effectiveNetclass,
872 std::vector<NETCLASS*>& constituentNetclasses ) const
873{
874 // Sort the resolved netclasses by priority (highest first), with same-priority netclasses
875 // ordered alphabetically
876 std::sort( constituentNetclasses.begin(), constituentNetclasses.end(),
877 []( NETCLASS* nc1, NETCLASS* nc2 )
878 {
879 int p1 = nc1->GetPriority();
880 int p2 = nc2->GetPriority();
881
882 if( p1 < p2 )
883 return true;
884
885 if (p1 == p2)
886 return nc1->GetName().Cmp( nc2->GetName() ) < 0;
887
888 return false;
889 } );
890
891 // Iterate from lowest priority netclass and fill effective netclass parameters
892 for( auto itr = constituentNetclasses.rbegin(); itr != constituentNetclasses.rend(); ++itr )
893 {
894 NETCLASS* nc = *itr;
895
896 if( nc->HasClearance() )
897 {
898 effectiveNetclass->SetClearance( nc->GetClearance() );
899 effectiveNetclass->SetClearanceParent( nc );
900 }
901
902 if( nc->HasTrackWidth() )
903 {
904 effectiveNetclass->SetTrackWidth( nc->GetTrackWidth() );
905 effectiveNetclass->SetTrackWidthParent( nc );
906 }
907
908 if( nc->HasViaDiameter() )
909 {
910 effectiveNetclass->SetViaDiameter( nc->GetViaDiameter() );
911 effectiveNetclass->SetViaDiameterParent( nc );
912 }
913
914 if( nc->HasViaDrill() )
915 {
916 effectiveNetclass->SetViaDrill( nc->GetViaDrill() );
917 effectiveNetclass->SetViaDrillParent( nc );
918 }
919
920 if( nc->HasuViaDiameter() )
921 {
922 effectiveNetclass->SetuViaDiameter( nc->GetuViaDiameter() );
923 effectiveNetclass->SetuViaDiameterParent( nc );
924 }
925
926 if( nc->HasuViaDrill() )
927 {
928 effectiveNetclass->SetuViaDrill( nc->GetuViaDrill() );
929 effectiveNetclass->SetuViaDrillParent( nc );
930 }
931
932 if( nc->HasDiffPairWidth() )
933 {
934 effectiveNetclass->SetDiffPairWidth( nc->GetDiffPairWidth() );
935 effectiveNetclass->SetDiffPairWidthParent( nc );
936 }
937
938 if( nc->HasDiffPairGap() )
939 {
940 effectiveNetclass->SetDiffPairGap( nc->GetDiffPairGap() );
941 effectiveNetclass->SetDiffPairGapParent( nc );
942 }
943
944 if( nc->HasDiffPairViaGap() )
945 {
946 effectiveNetclass->SetDiffPairViaGap( nc->GetDiffPairViaGap() );
947 effectiveNetclass->SetDiffPairViaGapParent( nc );
948 }
949
950 if( nc->HasWireWidth() )
951 {
952 effectiveNetclass->SetWireWidth( nc->GetWireWidth() );
953 effectiveNetclass->SetWireWidthParent( nc );
954 }
955
956 if( nc->HasBusWidth() )
957 {
958 effectiveNetclass->SetBusWidth( nc->GetBusWidth() );
959 effectiveNetclass->SetBusWidthParent( nc );
960 }
961
962 if( nc->HasLineStyle() )
963 {
964 effectiveNetclass->SetLineStyle( nc->GetLineStyle() );
965 effectiveNetclass->SetLineStyleParent( nc );
966 }
967
968 COLOR4D pcbColor = nc->GetPcbColor();
969
970 if( pcbColor != COLOR4D::UNSPECIFIED )
971 {
972 effectiveNetclass->SetPcbColor( pcbColor );
973 effectiveNetclass->SetPcbColorParent( nc );
974 }
975
976 COLOR4D schColor = nc->GetSchematicColor();
977
978 if( schColor != COLOR4D::UNSPECIFIED )
979 {
980 effectiveNetclass->SetSchematicColor( schColor );
981 effectiveNetclass->SetSchematicColorParent( nc );
982 }
983
984 if( nc->HasTuningProfile() )
985 {
986 effectiveNetclass->SetTuningProfile( nc->GetTuningProfile() );
987 effectiveNetclass->SetTuningProfileParent( nc );
988 }
989 }
990
991 // Fill in any required defaults
992 if( addMissingDefaults( effectiveNetclass.get() ) )
993 constituentNetclasses.push_back( m_defaultNetClass.get() );
994}
995
996
998{
999 bool addedDefault = false;
1000
1001 if( !nc->HasClearance() )
1002 {
1003 addedDefault = true;
1004 nc->SetClearance( m_defaultNetClass->GetClearance() );
1006 }
1007
1008 if( !nc->HasTrackWidth() )
1009 {
1010 addedDefault = true;
1011 nc->SetTrackWidth( m_defaultNetClass->GetTrackWidth() );
1013 }
1014
1015 if( !nc->HasViaDiameter() )
1016 {
1017 addedDefault = true;
1018 nc->SetViaDiameter( m_defaultNetClass->GetViaDiameter() );
1020 }
1021
1022 if( !nc->HasViaDrill() )
1023 {
1024 addedDefault = true;
1025 nc->SetViaDrill( m_defaultNetClass->GetViaDrill() );
1027 }
1028
1029 if( !nc->HasuViaDiameter() )
1030 {
1031 addedDefault = true;
1032 nc->SetuViaDiameter( m_defaultNetClass->GetuViaDiameter() );
1034 }
1035
1036 if( !nc->HasuViaDrill() )
1037 {
1038 addedDefault = true;
1039 nc->SetuViaDrill( m_defaultNetClass->GetuViaDrill() );
1041 }
1042
1043 if( !nc->HasDiffPairWidth() )
1044 {
1045 addedDefault = true;
1046 nc->SetDiffPairWidth( m_defaultNetClass->GetDiffPairWidth() );
1048 }
1049
1050 if( !nc->HasDiffPairGap() )
1051 {
1052 addedDefault = true;
1053 nc->SetDiffPairGap( m_defaultNetClass->GetDiffPairGap() );
1055 }
1056
1057 // Currently this is only on the default netclass, and not editable in the setup panel
1058 // if( !nc->HasDiffPairViaGap() )
1059 // {
1060 // addedDefault = true;
1061 // nc->SetDiffPairViaGap( m_defaultNetClass->GetDiffPairViaGap() );
1062 // nc->SetDiffPairViaGapParent( m_defaultNetClass.get() );
1063 // }
1064
1065 if( !nc->HasWireWidth() )
1066 {
1067 addedDefault = true;
1068 nc->SetWireWidth( m_defaultNetClass->GetWireWidth() );
1070 }
1071
1072 if( !nc->HasBusWidth() )
1073 {
1074 addedDefault = true;
1075 nc->SetBusWidth( m_defaultNetClass->GetBusWidth() );
1077 }
1078
1079 // The tuning profile can be empty - only fill if a default tuning profile is set
1080 if( !nc->HasTuningProfile() && m_defaultNetClass->HasTuningProfile() )
1081 {
1082 addedDefault = true;
1083 nc->SetTuningProfile( m_defaultNetClass->GetTuningProfile() );
1085 }
1086
1087 return addedDefault;
1088}
1089
1090
1091std::shared_ptr<NETCLASS> NET_SETTINGS::GetNetClassByName( const wxString& aNetClassName ) const
1092{
1093 auto ii = m_netClasses.find( aNetClassName );
1094
1095 if( ii == m_netClasses.end() )
1096 return m_defaultNetClass;
1097 else
1098 return ii->second;
1099}
1100
1101
1102static bool isSuperSubOverbar( wxChar c )
1103{
1104 return c == '_' || c == '^' || c == '~';
1105}
1106
1107
1108bool NET_SETTINGS::ParseBusVector( const wxString& aBus, wxString* aName,
1109 std::vector<wxString>* aMemberList )
1110{
1111 auto isDigit =
1112 []( wxChar c )
1113 {
1114 static wxString digits( wxT( "0123456789" ) );
1115 return digits.Contains( c );
1116 };
1117
1118 size_t busLen = aBus.length();
1119 size_t i = 0;
1120 wxString prefix;
1121 wxString suffix;
1122 wxString tmp;
1123 long begin = 0;
1124 long end = 0;
1125 int braceNesting = 0;
1126
1127 prefix.reserve( busLen );
1128
1129 // Parse prefix
1130 //
1131 for( ; i < busLen; ++i )
1132 {
1133 if( aBus[i] == '{' )
1134 {
1135 if( i > 0 && isSuperSubOverbar( aBus[i-1] ) )
1136 {
1137 braceNesting++;
1138
1139 if( !prefix.IsEmpty() )
1140 prefix.RemoveLast();
1141
1142 continue;
1143 }
1144 else
1145 return false;
1146 }
1147 else if( aBus[i] == '}' )
1148 {
1149 braceNesting--;
1150 }
1151
1152 if( aBus[i] == ' ' || aBus[i] == ']' )
1153 return false;
1154
1155 if( aBus[i] == '[' )
1156 break;
1157
1158 prefix += aBus[i];
1159 }
1160
1161 // Parse start number
1162 //
1163 i++; // '[' character
1164
1165 if( i >= busLen )
1166 return false;
1167
1168 for( ; i < busLen; ++i )
1169 {
1170 if( aBus[i] == '.' && i + 1 < busLen && aBus[i+1] == '.' )
1171 {
1172 tmp.ToLong( &begin );
1173 i += 2;
1174 break;
1175 }
1176
1177 if( !isDigit( aBus[i] ) )
1178 return false;
1179
1180 tmp += aBus[i];
1181 }
1182
1183 // Parse end number
1184 //
1185 tmp = wxEmptyString;
1186
1187 if( i >= busLen )
1188 return false;
1189
1190 for( ; i < busLen; ++i )
1191 {
1192 if( aBus[i] == ']' )
1193 {
1194 tmp.ToLong( &end );
1195 ++i;
1196 break;
1197 }
1198
1199 if( !isDigit( aBus[i] ) )
1200 return false;
1201
1202 tmp += aBus[i];
1203 }
1204
1205 // Parse suffix
1206 //
1207 for( ; i < busLen; ++i )
1208 {
1209 if( aBus[i] == '}' )
1210 {
1211 braceNesting--;
1212 }
1213 else if( aBus[i] == '+' || aBus[i] == '-' || aBus[i] == 'P' || aBus[i] == 'N' )
1214 {
1215 suffix += aBus[i];
1216 }
1217 else
1218 {
1219 return false;
1220 }
1221 }
1222
1223 if( braceNesting != 0 )
1224 return false;
1225
1226 if( begin == end )
1227 return false;
1228 else if( begin > end )
1229 std::swap( begin, end );
1230
1231 if( aName )
1232 *aName = prefix;
1233
1234 if( aMemberList )
1235 {
1236 for( long idx = begin; idx <= end; ++idx )
1237 {
1238 wxString str = prefix;
1239 str << idx;
1240 str << suffix;
1241
1242 aMemberList->emplace_back( str );
1243 }
1244 }
1245
1246 return true;
1247}
1248
1249
1250bool NET_SETTINGS::ParseBusGroup( const wxString& aGroup, wxString* aName,
1251 std::vector<wxString>* aMemberList )
1252{
1253 size_t groupLen = aGroup.length();
1254 size_t i = 0;
1255 wxString prefix;
1256 wxString tmp;
1257 int braceNesting = 0;
1258
1259 prefix.reserve( groupLen );
1260
1261 // Parse prefix
1262 //
1263 for( ; i < groupLen; ++i )
1264 {
1265 if( aGroup[i] == '{' )
1266 {
1267 if( i > 0 && isSuperSubOverbar( aGroup[i-1] ) )
1268 {
1269 braceNesting++;
1270
1271 if( !prefix.IsEmpty() )
1272 prefix.RemoveLast();
1273
1274 continue;
1275 }
1276 else
1277 break;
1278 }
1279 else if( aGroup[i] == '}' )
1280 {
1281 braceNesting--;
1282 }
1283
1284 if( aGroup[i] == ' ' || aGroup[i] == '[' || aGroup[i] == ']' )
1285 return false;
1286
1287 prefix += aGroup[i];
1288 }
1289
1290 if( braceNesting != 0 )
1291 return false;
1292
1293 if( aName )
1294 *aName = prefix;
1295
1296 // Parse members
1297 //
1298 i++; // '{' character
1299
1300 if( i >= groupLen )
1301 return false;
1302
1303 for( ; i < groupLen; ++i )
1304 {
1305 if( aGroup[i] == '{' )
1306 {
1307 if( i > 0 && isSuperSubOverbar( aGroup[i-1] ) )
1308 {
1309 braceNesting++;
1310
1311 if( !tmp.IsEmpty() )
1312 tmp.RemoveLast();
1313
1314 continue;
1315 }
1316 else
1317 return false;
1318 }
1319 else if( aGroup[i] == '}' )
1320 {
1321 if( braceNesting )
1322 {
1323 braceNesting--;
1324 continue;
1325 }
1326 else
1327 {
1328 if( aMemberList && !tmp.IsEmpty() )
1329 aMemberList->push_back( EscapeString( tmp, CTX_NETNAME ) );
1330
1331 return true;
1332 }
1333 }
1334
1335 // Commas aren't strictly legal, but we can be pretty sure what the author had in mind.
1336 if( aGroup[i] == ' ' || aGroup[i] == ',' )
1337 {
1338 if( aMemberList && !tmp.IsEmpty() )
1339 aMemberList->push_back( EscapeString( tmp, CTX_NETNAME ) );
1340
1341 tmp.Clear();
1342 continue;
1343 }
1344
1345 tmp += aGroup[i];
1346 }
1347
1348 return false;
1349}
1350
1351
1352void NET_SETTINGS::ForEachBusMember( const wxString& aBusPattern,
1353 const std::function<void( const wxString& )>& aFunction )
1354{
1355 std::vector<wxString> members;
1356
1357 if( ParseBusVector( aBusPattern, nullptr, &members ) )
1358 {
1359 // Vector bus: call function for each expanded member
1360 for( const wxString& member : members )
1361 aFunction( member );
1362 }
1363 else if( ParseBusGroup( aBusPattern, nullptr, &members ) )
1364 {
1365 // Bus group: recursively expand each member (which may itself be a vector or group)
1366 for( const wxString& member : members )
1367 ForEachBusMember( member, aFunction );
1368 }
1369 else
1370 {
1371 // Not a bus pattern: call function with the original pattern
1372 aFunction( aBusPattern );
1373 }
1374}
const char * name
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:114
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:112
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:402
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
void registerMigration(int aOldSchemaVersion, int aNewSchemaVersion, std::function< bool(void)> aMigrator)
Registers a migration from one schema version to another.
JSON_SETTINGS(const wxString &aFilename, SETTINGS_LOC aLocation, int aSchemaVersion)
std::unique_ptr< JSON_SETTINGS_INTERNALS > m_internals
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:105
JSON_SETTINGS * m_parent
A pointer to the parent object to load and store from.
NESTED_SETTINGS(const std::string &aName, int aSchemaVersion, JSON_SETTINGS *aParent, const std::string &aPath, bool aLoadFromFile=true)
A collection of nets and the parameters used to route or test these nets.
Definition netclass.h:45
void SetViaDiameter(int aDia)
Definition netclass.h:135
void SetViaDrill(int aSize)
Definition netclass.h:143
bool HasLineStyle() const
Definition netclass.h:233
int GetViaDiameter() const
Definition netclass.h:133
int GetViaDrill() const
Definition netclass.h:141
void SetWireWidthParent(NETCLASS *parent)
Definition netclass.h:208
static const char Default[]
the name of the default NETCLASS
Definition netclass.h:47
void SetuViaDrillParent(NETCLASS *parent)
Definition netclass.h:161
bool HasBusWidth() const
Definition netclass.h:211
bool HasuViaDrill() const
Definition netclass.h:156
void SetDiffPairWidthParent(NETCLASS *parent)
Definition netclass.h:169
void SetuViaDiameter(int aSize)
Definition netclass.h:151
void SetDiffPairWidth(int aSize)
Definition netclass.h:167
int HasViaDrill() const
Definition netclass.h:140
int GetDiffPairViaGap() const
Definition netclass.h:181
void SetViaDrillParent(NETCLASS *parent)
Definition netclass.h:145
wxString GetTuningProfile() const
Definition netclass.h:246
void SetDiffPairGapParent(NETCLASS *parent)
Definition netclass.h:177
void SetTuningProfileParent(NETCLASS *aParent)
Definition netclass.h:247
int GetDiffPairGap() const
Definition netclass.h:173
int GetuViaDrill() const
Definition netclass.h:157
bool HasViaDiameter() const
Definition netclass.h:132
int GetLineStyle() const
Definition netclass.h:234
bool HasDiffPairWidth() const
Definition netclass.h:164
bool HasuViaDiameter() const
Definition netclass.h:148
void SetTrackWidthParent(NETCLASS *parent)
Definition netclass.h:129
int GetuViaDiameter() const
Definition netclass.h:149
bool HasTrackWidth() const
Definition netclass.h:124
void SetViaDiameterParent(NETCLASS *parent)
Definition netclass.h:137
int GetDiffPairWidth() const
Definition netclass.h:165
void SetuViaDrill(int aSize)
Definition netclass.h:159
int GetWireWidth() const
Definition netclass.h:204
void SetDiffPairGap(int aSize)
Definition netclass.h:175
void SetBusWidthParent(NETCLASS *parent)
Definition netclass.h:216
void SetClearance(int aClearance)
Definition netclass.h:119
COLOR4D GetPcbColor(bool aIsForSave=false) const
Definition netclass.h:189
bool HasDiffPairGap() const
Definition netclass.h:172
COLOR4D GetSchematicColor(bool aIsForSave=false) const
Definition netclass.h:219
void SetBusWidth(int aWidth)
Definition netclass.h:214
void SetClearanceParent(NETCLASS *parent)
Definition netclass.h:121
int GetTrackWidth() const
Definition netclass.h:125
void SetWireWidth(int aWidth)
Definition netclass.h:206
void SetTuningProfile(const wxString &aTuningProfile)
Definition netclass.h:245
bool HasTuningProfile() const
Definition netclass.h:244
bool HasWireWidth() const
Definition netclass.h:203
int GetClearance() const
Definition netclass.h:117
void SetuViaDiameterParent(NETCLASS *parent)
Definition netclass.h:153
void SetTrackWidth(int aWidth)
Definition netclass.h:127
bool HasDiffPairViaGap() const
Definition netclass.h:180
int GetBusWidth() const
Definition netclass.h:212
bool HasClearance() const
Definition netclass.h:116
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 addSinglePatternAssignment(const wxString &pattern, const wxString &netclass)
Adds a single pattern assignment without bus expansion (internal helper)
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.
virtual ~NET_SETTINGS()
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.
bool migrateSchema3to4()
bool migrateSchema0to1()
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 ...
bool migrateSchema2to3()
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.
bool migrateSchema1to2()
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.
bool migrateSchema4to5()
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...
static void ForEachBusMember(const wxString &aBusPattern, const std::function< void(const wxString &)> &aFunction)
Call a function for each member of an expanded bus pattern.
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.
Definition parameters.h:296
bool isDigit(char cc)
Definition dsnlexer.cpp:469
#define _(s)
@ CTX_NETCLASS
nlohmann::json json
Definition gerbview.cpp:50
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:...
@ CTX_NETNAME
VECTOR2I end