45using JSON = nlohmann::json;
46using KEY = std::pair<std::string, std::string>;
47using ROWS = std::map<KEY, JSON>;
49std::string utf8(
const wxString& aText )
51 return aText.ToStdString( wxConvUTF8 );
55std::string serialize( ROWS& aRows )
59 for(
auto& [key, row] : aRows )
60 result.push_back( std::move( row ) );
62 return result.dump( 2 ) +
"\n";
82 std::set<std::string> classes;
87 classes.insert( utf8( constituent->GetName() ) );
94JSON valueRow(
const wxString& aName,
const wxString& aLocalName,
const char* aType,
97 return { {
"name", utf8( aName ) }, {
"local_name", utf8( aLocalName ) }, {
"type", aType },
99 {
"driver_path", aDriver ? utf8( aDriverPath.
AsString() ) :
"" },
100 {
"members", JSON::array() }, {
"netclasses", resolvedClasses( aName, aSettings ) } };
106 const wxString& aNamePrefix,
const wxString& aLocalPrefix,
SCH_ITEM* aDriver,
111 if( aNode.
kind == NODE::KIND::NET )
113 const auto& leaf = aMembers.
leaves.at( aNode.
leaf.value() );
114 return valueRow( leaf.Name(), aMembers.
schema->leaves.at( aNode.
leaf.value() ).name,
115 "net", leaf.Driver(), leaf.Sheet(), aSettings );
118 const wxString localName = aLocalPrefix + aNode.
text;
119 JSON row = valueRow( aPath + aNamePrefix + aNode.
text, localName,
120 aNode.
kind == NODE::KIND::VECTOR ?
"vector" :
"group", aDriver, aDriverPath, aSettings );
121 wxString namePrefix = aNamePrefix;
122 wxString localPrefix = aLocalPrefix;
124 if( aNode.
kind == NODE::KIND::GROUP && !aNode.
prefix.empty() )
126 namePrefix += aNode.
prefix +
".";
127 localPrefix += aNode.
prefix +
".";
130 for(
const auto& member : aNode.
members )
132 row[
"members"].push_back( memberRow( member, aMembers, aPath, namePrefix, localPrefix, aDriver, aDriverPath,
147 JSON row = valueRow(
name, aView.
FullLocalName(), typeName( aType ), driver, driverPath, aSettings );
148 const auto members = aView.
Members();
153 const auto groupPrefix = [&](
const wxString& aPrefix )
155 if( aPrefix.empty() )
158 return aComponent.
suffix ? wxString::Format(
"%s_%u.", aPrefix, aComponent.
suffix ) : aPrefix + wxS(
"." );
161 const wxString localPrefix =
group ? groupPrefix( members.tree->prefix ) : wxString();
162 const auto& best = aComponent.
content->best;
165 const wxString namePrefix =
group && best && best->schema
167 ? groupPrefix( best->schema->prefix )
169 const wxString
path =
name.Left(
name.length() - aView.
Name(
true ).length() );
171 for(
const auto& member : members.tree->members )
173 row[
"members"].push_back( memberRow( member, members,
path, namePrefix, localPrefix, driver, driverPath,
184 return valueRow( wxString(), wxString(),
"none",
nullptr,
KIID_PATH(),
nullptr );
186 const wxString
name = !aConnection->
Driver() && aConnection->
Name(
true ) ==
"<NO NET>"
187 ? wxString() : aConnection->Name();
189 aConnection->
Sheet().
Path(), aSettings );
192 for(
const auto& member : aConnection->
Members() )
193 row[
"members"].push_back( connectionRow( member.get(), aSettings ) );
209 const std::string pathId = utf8(
path.Path().AsString() );
213 const std::string itemId = utf8( aItem->m_Uuid.AsString() );
214 JSON row = connectionRow( aItem->Connection( &
path ), settings );
215 row[
"path"] = pathId;
216 row[
"item"] = itemId;
217 row[
"dangling"] = aItem->IsDangling();
218 row[
"dangling_ends"] = { aItem->IsDangling() };
220 if(
auto* line =
dynamic_cast<SCH_LINE*
>( aItem ) )
222 row[
"dangling_ends"] = { line->IsStartDangling(), line->IsEndDangling() };
226 row[
"dangling_ends"] = { entry->IsStartDangling(), entry->IsEndDangling() };
229 std::set<std::string> connected;
232 connected.insert( utf8( neighbour->m_Uuid.AsString() ) );
234 row[
"connected"] = connected;
236 if( !rows.emplace( KEY{ pathId, itemId }, std::move( row ) ).second )
237 throw std::runtime_error(
"Duplicate connectivity item " + pathId + itemId );
252 else if( item->IsConnectable() )
259 return serialize( rows );
265 const auto& publication = aFacade.
Published();
266 const auto& keys = aFacade.
Keys();
267 const auto& auxiliary = publication.Auxiliary();
268 std::unique_ptr<NET_SETTINGS> settings;
273 settings = std::make_unique<NET_SETTINGS>(
nullptr,
"" );
274 settings->CopyFrom( *source );
278 for(
const auto& [owner, patterns] : source->GetChainPatternAssignments() )
280 for(
const auto& [matcher,
name] : patterns )
281 settings->SetChainPatternAssignment( owner, matcher->GetPattern(),
name );
285 std::map<INST_ID, SCH_SCREEN*> screens;
289 if(
auto instance = keys.FindInstance(
path.Path() ) )
290 screens.emplace( *instance,
path.LastScreen() );
295 for(
const auto& [key,
result] : publication.Rows() )
301 throw std::runtime_error(
"Cannot dump stale connectivity publication" );
303 JSON row = connectionRow( *view, publication.Components().at(
result.component ),
result.itemType,
305 const std::string pathId = utf8(
path.AsString() );
306 const std::string itemId = utf8( key.item.AsString() );
307 row[
"path"] = pathId;
308 row[
"item"] = itemId;
309 const auto& island = auxiliary.Islands().at( auxiliary.IslandOf().at( key ) ).value;
310 const auto dangling = island.dangling.at( key.item );
311 row[
"dangling"] = dangling != 0;
312 row[
"dangling_ends"] = { dangling != 0 };
313 const auto screen = screens.find( key.inst );
315 if( screen == screens.end() || !screen->second )
316 throw std::runtime_error(
"Cannot dump connectivity without its source instance" );
318 SCH_ITEM* item = screen->second->GetConnectivityItem( key.item );
321 throw std::runtime_error(
"Cannot dump connectivity without its source item" );
324 row[
"dangling_ends"] = { ( dangling & 1 ) != 0, ( dangling & 2 ) != 0 };
334 std::set<std::string> connected;
335 const auto neighbors = auxiliary.NeighborsOf().find( key );
337 if( neighbors != auxiliary.NeighborsOf().end() )
339 for(
const KIID& neighbor : neighbors->second )
340 connected.insert( utf8( neighbor.
AsString() ) );
343 row[
"connected"] = connected;
344 rows.emplace( KEY{ pathId, itemId }, std::move( row ) );
347 return serialize( rows );
KICAD_T Type() const
Returns the type of object.
wxString AsString() const
wxString AsString() const
A collection of nets and the parameters used to route or test these nets.
const std::vector< NETCLASS * > & GetConstituentNetclasses() const
Gets the netclasses which make up this netclass.
NET_SETTINGS stores various net-related settings in a project context.
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const wxString &aNetName)
Fetches the effective (may be aggregate) netclass for the given net name.
std::shared_ptr< NET_SETTINGS > & NetSettings()
virtual PROJECT_FILE & GetProjectFile() const
Holds all the data relating to one schematic.
SCH_SHEET_LIST BuildSheetListSortedByPageNumbers() const
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
PROJECT & Project() const
Return a reference to the project this schematic is part of.
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Base class for a bus or wire entry.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString FullLocalName() const
SCH_SHEET_PATH Sheet() const
CONNECTION_TYPE Type() const
wxString Name(bool aIgnoreSheet=false) const
SCH_ITEM * Driver() const
const std::vector< std::shared_ptr< SCH_CONNECTION > > & Members() const
Model-owned source resolver.
void ApplyNetclasses(NET_SETTINGS &aSettings) const
Replace label-derived assignments from a complete publication; invalidate changed net caches.
const SESSION_KEYS & Keys() const
std::optional< ITEM_VIEW > Connection(const KIID &aItem, const KIID_PATH &aPath) const
const PUBLICATION & Published() const
wxString FullLocalName() const
BUS_MEMBERS Members() const
SCH_ITEM * Driver() const
wxString Name(bool aIgnoreSheet=false) const
Base class for any item which can be embedded within the SCHEMATIC container class,...
const std::vector< SCH_ITEM * > & ConnectedItems(const SCH_SHEET_PATH &aPath) const
Retrieve the set of items connected to this item on the given sheet.
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Segment description base class to describe items which have 2 end points (track, wire,...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
std::string Dump(SCHEMATIC &aSchematic)
Canonical, pointer-free connectivity rows for migration and rebuild comparisons.
@ BUS
This item represents a bus vector.
@ NET
This item represents a net.
@ NONE
No connection to this item.
@ BUS_GROUP
This item represents a bus group.
Query-time snapshot; reacquire after Update.
std::shared_ptr< const BUS_SCHEMA > schema
std::vector< NET_VIEW > leaves
One node of the presentation tree.
wxString text
Container label text.
std::optional< size_t > leaf
Leaf ordinal of a NET node.
std::vector< NODE > members
@ GROUP
A list such as I2C{SDA SCL}. Members align by name with another group.
One published net or bus with its identity.
uint32_t suffix
Zero for the holder of the base name.
std::shared_ptr< const COMPONENT_CONTENT > content
wxString result
Test unit parsing edge cases and error handling.