From b21e3e45d9eafd46983732da97cd6a007cec8280 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Sun, 3 Aug 2025 08:08:32 -0700 Subject: [PATCH] Extract generic item connectivity update and add QA --- eeschema/connection_graph.cpp | 113 +++++++++--------- eeschema/connection_graph.h | 19 +++ qa/tests/eeschema/CMakeLists.txt | 2 +- ...cpp => test_update_items_connectivity.cpp} | 108 ++++++++++++++++- 4 files changed, 184 insertions(+), 58 deletions(-) rename qa/tests/eeschema/{test_update_symbol_connectivity.cpp => test_update_items_connectivity.cpp} (56%) diff --git a/eeschema/connection_graph.cpp b/eeschema/connection_graph.cpp index 48dd41b5a8..e6ddd3dde4 100644 --- a/eeschema/connection_graph.cpp +++ b/eeschema/connection_graph.cpp @@ -1232,6 +1232,63 @@ void CONNECTION_GRAPH::updateSymbolConnectivity( const SCH_SHEET_PATH& aSheet, } +void CONNECTION_GRAPH::updatePinConnectivity( const SCH_SHEET_PATH& aSheet, SCH_PIN* aPin, SCH_CONNECTION* aConn ) +{ + aConn->SetType( CONNECTION_TYPE::NET ); + + // because calling the first time is not thread-safe + wxString name = aPin->GetDefaultNetName( aSheet ); + aPin->ClearConnectedItems( aSheet ); + + if( aPin->IsGlobalPower() ) + { + aConn->SetName( name ); + m_global_power_pins.emplace_back( std::make_pair( aSheet, aPin ) ); + } +} + + +void CONNECTION_GRAPH::updateGenericItemConnectivity( const SCH_SHEET_PATH& aSheet, SCH_ITEM* aItem, + std::map>& aConnectionMap ) +{ + std::vector points = aItem->GetConnectionPoints(); + aItem->ClearConnectedItems( aSheet ); + + m_items.emplace_back( aItem ); + SCH_CONNECTION* conn = aItem->InitializeConnection( aSheet, this ); + + switch( aItem->Type() ) + { + case SCH_LINE_T: + conn->SetType( aItem->GetLayer() == LAYER_BUS ? CONNECTION_TYPE::BUS : CONNECTION_TYPE::NET ); + break; + + case SCH_BUS_BUS_ENTRY_T: + conn->SetType( CONNECTION_TYPE::BUS ); + static_cast( aItem )->m_connected_bus_items[0] = nullptr; + static_cast( aItem )->m_connected_bus_items[1] = nullptr; + break; + + case SCH_PIN_T: + if( points.empty() ) + points = { static_cast( aItem )->GetPosition() }; + + updatePinConnectivity( aSheet, static_cast( aItem ), conn ); + break; + + case SCH_BUS_WIRE_ENTRY_T: + conn->SetType( CONNECTION_TYPE::NET ); + static_cast( aItem )->m_connected_bus_item = nullptr; + break; + + default: break; + } + + for( const VECTOR2I& point : points ) + aConnectionMap[point].push_back( aItem ); +} + + void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet, const std::vector& aItemList ) { @@ -1239,22 +1296,6 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet, aSheet.Last()->GetFileName(), aItemList.size() ); std::map> connection_map; - auto updatePin = [&]( SCH_PIN* aPin, SCH_CONNECTION* aConn ) - { - aConn->SetType( CONNECTION_TYPE::NET ); - - // because calling the first time is not thread-safe - wxString name = aPin->GetDefaultNetName( aSheet ); - aPin->ClearConnectedItems( aSheet ); - - // power symbol pins need to be post-processed later - if( aPin->IsGlobalPower() ) - { - aConn->SetName( name ); - m_global_power_pins.emplace_back( std::make_pair( aSheet, aPin ) ); - } - }; - for( SCH_ITEM* item : aItemList ) { std::vector points = item->GetConnectionPoints(); @@ -1278,45 +1319,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet, } else { - m_items.emplace_back( item ); - SCH_CONNECTION* conn = item->InitializeConnection( aSheet, this ); - - // Set bus/net property here so that the propagation code uses it - switch( item->Type() ) - { - case SCH_LINE_T: - conn->SetType( item->GetLayer() == LAYER_BUS ? CONNECTION_TYPE::BUS : - CONNECTION_TYPE::NET ); - break; - - case SCH_BUS_BUS_ENTRY_T: - conn->SetType( CONNECTION_TYPE::BUS ); - - // clean previous (old) links: - static_cast( item )->m_connected_bus_items[0] = nullptr; - static_cast( item )->m_connected_bus_items[1] = nullptr; - break; - - case SCH_PIN_T: - if( points.empty() ) - points = { static_cast( item )->GetPosition() }; - - updatePin( static_cast( item ), conn ); - break; - - case SCH_BUS_WIRE_ENTRY_T: - conn->SetType( CONNECTION_TYPE::NET ); - - // clean previous (old) link: - static_cast( item )->m_connected_bus_item = nullptr; - break; - - default: - break; - } - - for( const VECTOR2I& point : points ) - connection_map[ point ].push_back( item ); + updateGenericItemConnectivity( aSheet, item, connection_map ); } } diff --git a/eeschema/connection_graph.h b/eeschema/connection_graph.h index 153fdd3c05..d34ad6013b 100644 --- a/eeschema/connection_graph.h +++ b/eeschema/connection_graph.h @@ -377,6 +377,7 @@ public: // Define QA friend functions to allow testing of private methods friend void boost_test_update_symbol_connectivity(); + friend void boost_test_update_generic_connectivity(); void Reset(); @@ -513,6 +514,24 @@ private: SCH_SYMBOL* aSymbol, std::map>& aConnectionMap ); + /** + * Update the connectivity of a pin and its connections. + * This is called by updateItemConnectivity() for each pin + * in the schematic. + */ + void updatePinConnectivity( const SCH_SHEET_PATH& aSheet, + SCH_PIN* aPin, + SCH_CONNECTION* aConnection ); + + /** + * Update the connectivity of items that are not pins or symbols. + * This is called by updateItemConnectivity() for each item + * in the schematic that is not a symbol or pin. + */ + void updateGenericItemConnectivity( const SCH_SHEET_PATH& aSheet, + SCH_ITEM* aItem, + std::map>& aConnectionMap ); + /** * Update the graphical connectivity between items (i.e. where they touch) * The items passed in must be on the same sheet. diff --git a/qa/tests/eeschema/CMakeLists.txt b/qa/tests/eeschema/CMakeLists.txt index 425326e3bf..92941f633c 100644 --- a/qa/tests/eeschema/CMakeLists.txt +++ b/qa/tests/eeschema/CMakeLists.txt @@ -88,7 +88,7 @@ set( QA_EESCHEMA_SRCS test_schematic.cpp test_symbol_library_manager.cpp test_resolve_drivers.cpp - test_update_symbol_connectivity.cpp + test_update_items_connectivity.cpp ) if( WIN32 ) diff --git a/qa/tests/eeschema/test_update_symbol_connectivity.cpp b/qa/tests/eeschema/test_update_items_connectivity.cpp similarity index 56% rename from qa/tests/eeschema/test_update_symbol_connectivity.cpp rename to qa/tests/eeschema/test_update_items_connectivity.cpp index c1126ba726..433b8d9844 100644 --- a/qa/tests/eeschema/test_update_symbol_connectivity.cpp +++ b/qa/tests/eeschema/test_update_items_connectivity.cpp @@ -22,15 +22,19 @@ #include #include #include + +#include +#include #include #include #include +#include #include #include +#include #include - void boost_test_update_symbol_connectivity() { // Create root sheet and screen @@ -131,9 +135,109 @@ void boost_test_update_symbol_connectivity() delete sheet; // deletes screen } -BOOST_AUTO_TEST_SUITE( UpdateSymbolConnectivity ) + +void boost_test_update_generic_connectivity() +{ + std::map> cmap; + + // Create root sheet and screen + SCH_SCREEN* screen = new SCH_SCREEN( nullptr ); + SCH_SHEET* sheet = new SCH_SHEET( nullptr, VECTOR2I( 0, 0 ), VECTOR2I( 1000, 1000 ) ); + sheet->SetScreen( screen ); + + SCH_SHEET_PATH sheetPath; + sheetPath.push_back( sheet ); + + CONNECTION_GRAPH graph; + + // Wire line + SCH_LINE wire( VECTOR2I( 0, 0 ), LAYER_WIRE ); + wire.SetEndPoint( VECTOR2I( 100, 0 ) ); + + graph.updateGenericItemConnectivity( sheetPath, &wire, cmap ); + SCH_CONNECTION* wireConn = wire.Connection( &sheetPath ); + BOOST_REQUIRE( wireConn ); + BOOST_CHECK( wireConn->Type() == CONNECTION_TYPE::NET ); + BOOST_CHECK( cmap.count( wire.GetStartPoint() ) ); + BOOST_CHECK( cmap.count( wire.GetEndPoint() ) ); + + // Bus line + cmap.clear(); + SCH_LINE bus( VECTOR2I( 0, 0 ), LAYER_BUS ); + bus.SetEndPoint( VECTOR2I( 0, 100 ) ); + + graph.updateGenericItemConnectivity( sheetPath, &bus, cmap ); + SCH_CONNECTION* busConn = bus.Connection( &sheetPath ); + BOOST_REQUIRE( busConn ); + BOOST_CHECK( busConn->Type() == CONNECTION_TYPE::BUS ); + BOOST_CHECK( cmap.count( bus.GetStartPoint() ) ); + BOOST_CHECK( cmap.count( bus.GetEndPoint() ) ); + + // Bus-to-bus entry + cmap.clear(); + SCH_BUS_BUS_ENTRY busEntry( VECTOR2I( 0, 0 ), false ); + SCH_LINE dummy1( VECTOR2I( 0, 0 ), LAYER_BUS ); + SCH_LINE dummy2( VECTOR2I( 0, 0 ), LAYER_BUS ); + busEntry.m_connected_bus_items[0] = &dummy1; + busEntry.m_connected_bus_items[1] = &dummy2; + + graph.updateGenericItemConnectivity( sheetPath, &busEntry, cmap ); + SCH_CONNECTION* bbConn = busEntry.Connection( &sheetPath ); + BOOST_REQUIRE( bbConn ); + BOOST_CHECK( bbConn->Type() == CONNECTION_TYPE::BUS ); + BOOST_CHECK( busEntry.m_connected_bus_items[0] == nullptr ); + BOOST_CHECK( busEntry.m_connected_bus_items[1] == nullptr ); + auto ptsBB = busEntry.GetConnectionPoints(); + BOOST_CHECK( cmap.count( ptsBB[0] ) ); + BOOST_CHECK( cmap.count( ptsBB[1] ) ); + + // Bus-wire entry + cmap.clear(); + SCH_BUS_WIRE_ENTRY bwEntry( VECTOR2I( 0, 0 ), false ); + SCH_LINE dummyBus( VECTOR2I( 0, 0 ), LAYER_BUS ); + bwEntry.m_connected_bus_item = &dummyBus; + + graph.updateGenericItemConnectivity( sheetPath, &bwEntry, cmap ); + SCH_CONNECTION* bwConn = bwEntry.Connection( &sheetPath ); + BOOST_REQUIRE( bwConn ); + BOOST_CHECK( bwConn->Type() == CONNECTION_TYPE::NET ); + BOOST_CHECK( bwEntry.m_connected_bus_item == nullptr ); + auto ptsBW = bwEntry.GetConnectionPoints(); + BOOST_CHECK( cmap.count( ptsBW[0] ) ); + BOOST_CHECK( cmap.count( ptsBW[1] ) ); + + // Pin + cmap.clear(); + LIB_SYMBOL libSymbol( "PWR", nullptr ); + SCH_PIN* libPin = new SCH_PIN( &libSymbol ); + libPin->SetNumber( "1" ); + libPin->SetName( "P" ); + libPin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN ); + libPin->SetPosition( VECTOR2I( 10, 10 ) ); + libSymbol.AddDrawItem( libPin ); + libSymbol.SetGlobalPower(); + + SCH_SYMBOL symbol( libSymbol, libSymbol.GetLibId(), &sheetPath, 0, 0, VECTOR2I( 0, 0 ) ); + symbol.SetRef( &sheetPath, "U1" ); + symbol.UpdatePins(); + SCH_PIN* pin = symbol.GetPins( &sheetPath )[0]; + + graph.updateGenericItemConnectivity( sheetPath, pin, cmap ); + SCH_CONNECTION* pinConn = pin->Connection( &sheetPath ); + BOOST_REQUIRE( pinConn ); + BOOST_CHECK( pinConn->Type() == CONNECTION_TYPE::NET ); + BOOST_CHECK( graph.m_global_power_pins.size() == 1 ); + BOOST_CHECK( cmap.count( pin->GetPosition() ) ); +} + +BOOST_AUTO_TEST_SUITE( UpdateItemsConnectivity ) BOOST_AUTO_TEST_CASE( SymbolConnectivityLinksPins ) { boost_test_update_symbol_connectivity(); } +BOOST_AUTO_TEST_CASE( GenericItemConnectivity ) +{ + boost_test_update_generic_connectivity(); +} + BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file