Fold various SCH pin shadow data structures into SCH_PIN.

This commit is contained in:
Jeff Young 2019-04-03 10:14:36 +01:00
parent 920d9e3d46
commit 3ace73fbdd
19 changed files with 300 additions and 377 deletions

View File

@ -210,7 +210,7 @@ set( EESCHEMA_SRCS
sch_line.cpp sch_line.cpp
sch_marker.cpp sch_marker.cpp
sch_no_connect.cpp sch_no_connect.cpp
sch_pin_connection.cpp sch_pin.cpp
sch_plugin.cpp sch_plugin.cpp
sch_preview_panel.cpp sch_preview_panel.cpp
sch_screen.cpp sch_screen.cpp

View File

@ -29,7 +29,7 @@
#include <sch_bus_entry.h> #include <sch_bus_entry.h>
#include <sch_component.h> #include <sch_component.h>
#include <sch_line.h> #include <sch_line.h>
#include <sch_pin_connection.h> #include <sch_pin.h>
#include <sch_screen.h> #include <sch_screen.h>
#include <sch_sheet.h> #include <sch_sheet.h>
#include <sch_sheet_path.h> #include <sch_sheet_path.h>
@ -66,17 +66,17 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
case SCH_SHEET_PIN_T: item_priority = 2; break; case SCH_SHEET_PIN_T: item_priority = 2; break;
case SCH_HIERARCHICAL_LABEL_T: item_priority = 3; break; case SCH_HIERARCHICAL_LABEL_T: item_priority = 3; break;
case SCH_LABEL_T: item_priority = 4; break; case SCH_LABEL_T: item_priority = 4; break;
case SCH_PIN_CONNECTION_T: case SCH_PIN_T:
{ {
auto pin_connection = static_cast<SCH_PIN_CONNECTION*>( item ); auto sch_pin = static_cast<SCH_PIN*>( item );
if( pin_connection->m_pin->IsPowerConnection() ) if( sch_pin->IsPowerConnection() )
item_priority = 5; item_priority = 5;
else else
item_priority = 1; item_priority = 1;
// Skip power flags, etc // Skip power flags, etc
if( item_priority == 1 && !pin_connection->m_comp->IsInNetlist() ) if( item_priority == 1 && !sch_pin->GetParentComponent()->IsInNetlist() )
continue; continue;
break; break;
@ -110,8 +110,8 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
std::sort( candidates.begin(), candidates.end(), std::sort( candidates.begin(), candidates.end(),
[this]( SCH_ITEM* a, SCH_ITEM* b) -> bool [this]( SCH_ITEM* a, SCH_ITEM* b) -> bool
{ {
auto pin_a = static_cast<SCH_PIN_CONNECTION*>( a ); auto pin_a = static_cast<SCH_PIN*>( a );
auto pin_b = static_cast<SCH_PIN_CONNECTION*>( b ); auto pin_b = static_cast<SCH_PIN*>( b );
auto name_a = pin_a->GetDefaultNetName( m_sheet ); auto name_a = pin_a->GetDefaultNetName( m_sheet );
auto name_b = pin_b->GetDefaultNetName( m_sheet ); auto name_b = pin_b->GetDefaultNetName( m_sheet );
@ -144,11 +144,11 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
// For power connections, we allow multiple drivers // For power connections, we allow multiple drivers
if( highest_priority == 5 && candidates.size() > 1 && if( highest_priority == 5 && candidates.size() > 1 &&
candidates[0]->Type() == SCH_PIN_CONNECTION_T ) candidates[0]->Type() == SCH_PIN_T )
{ {
auto pc = static_cast<SCH_PIN_CONNECTION*>( candidates[0] ); auto pin = static_cast<SCH_PIN*>( candidates[0] );
wxASSERT( pc->m_pin->IsPowerConnection() ); wxASSERT( pin->IsPowerConnection() );
m_multiple_power_ports = true; m_multiple_power_ports = true;
} }
@ -332,23 +332,24 @@ void CONNECTION_GRAPH::updateItemConnectivity( SCH_SHEET_PATH aSheet,
{ {
auto component = static_cast<SCH_COMPONENT*>( item ); auto component = static_cast<SCH_COMPONENT*>( item );
component->UpdatePinConnections( aSheet ); component->UpdatePins( &aSheet );
for( auto it : component->PinConnections() ) for( auto& it : component->GetPinMap() )
{ {
auto pin_connection = it.second; SCH_PIN* pin = &it.second;
// TODO(JE) use cached location from m_Pins // TODO(JE) use cached location from m_Pins
auto pin_pos = pin_connection->m_pin->GetPosition(); // Now needs to be the other way around: move m_Pins to SCH_PINs
auto pin_pos = pin->GetLibPin()->GetPosition();
auto pos = component->GetTransform().TransformCoordinate( pin_pos ) + auto pos = component->GetTransform().TransformCoordinate( pin_pos ) +
component->GetPosition(); component->GetPosition();
// because calling the first time is not thread-safe // because calling the first time is not thread-safe
pin_connection->GetDefaultNetName( aSheet ); pin->GetDefaultNetName( aSheet );
pin_connection->ConnectedItems().clear(); pin->ConnectedItems().clear();
connection_map[ pos ].push_back( pin_connection ); connection_map[ pos ].push_back( pin );
m_items.insert( pin_connection ); m_items.insert( pin );
} }
} }
else else
@ -376,7 +377,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( SCH_SHEET_PATH aSheet,
conn->SetType( CONNECTION_BUS ); conn->SetType( CONNECTION_BUS );
break; break;
case SCH_PIN_CONNECTION_T: case SCH_PIN_T:
case SCH_BUS_WIRE_ENTRY_T: case SCH_BUS_WIRE_ENTRY_T:
conn->SetType( CONNECTION_NET ); conn->SetType( CONNECTION_NET );
break; break;
@ -394,12 +395,12 @@ void CONNECTION_GRAPH::updateItemConnectivity( SCH_SHEET_PATH aSheet,
item->SetConnectivityDirty( false ); item->SetConnectivityDirty( false );
} }
for( auto it : connection_map ) for( const auto& it : connection_map )
{ {
auto connection_vec = it.second; auto connection_vec = it.second;
SCH_ITEM* junction = nullptr; SCH_ITEM* junction = nullptr;
for( auto connected_item : connection_vec ) for( SCH_ITEM* connected_item : connection_vec )
{ {
// Look for junctions. For points that have a junction, we want all // Look for junctions. For points that have a junction, we want all
// items to connect to the junction but not to each other. // items to connect to the junction but not to each other.
@ -541,19 +542,18 @@ void CONNECTION_GRAPH::buildConnectionGraph()
{ {
subgraph->m_no_connect = item; subgraph->m_no_connect = item;
} }
else if( item->Type() == SCH_PIN_CONNECTION_T ) else if( item->Type() == SCH_PIN_T )
{ {
auto pc = static_cast<SCH_PIN_CONNECTION*>( item ); auto pin = static_cast<SCH_PIN*>( item );
if( pc->m_pin->GetType() == PIN_NC ) if( pin->GetType() == PIN_NC )
subgraph->m_no_connect = item; subgraph->m_no_connect = item;
// Invisible power pins need to be post-processed later // Invisible power pins need to be post-processed later
if( pc->m_pin->IsPowerConnection() && if( pin->IsPowerConnection() && !pin->IsVisible() )
!pc->m_pin->IsVisible() )
{ {
m_invisible_power_pins.push_back( pc ); m_invisible_power_pins.push_back( pin );
} }
} }
@ -666,9 +666,9 @@ void CONNECTION_GRAPH::buildConnectionGraph()
connection->ConfigureFromLabel( txt ); connection->ConfigureFromLabel( txt );
break; break;
} }
case SCH_PIN_CONNECTION_T: case SCH_PIN_T:
{ {
auto pin = static_cast<SCH_PIN_CONNECTION*>( driver ); auto pin = static_cast<SCH_PIN*>( driver );
// NOTE(JE) GetDefaultNetName is not thread-safe. // NOTE(JE) GetDefaultNetName is not thread-safe.
connection->ConfigureFromLabel( pin->GetDefaultNetName( sheet ) ); connection->ConfigureFromLabel( pin->GetDefaultNetName( sheet ) );
@ -726,10 +726,10 @@ void CONNECTION_GRAPH::buildConnectionGraph()
m_global_label_cache[name].push_back( subgraph ); m_global_label_cache[name].push_back( subgraph );
break; break;
} }
case SCH_PIN_CONNECTION_T: case SCH_PIN_T:
{ {
auto pc = static_cast<SCH_PIN_CONNECTION*>( driver ); auto pin = static_cast<SCH_PIN*>( driver );
wxASSERT( pc->m_pin->IsPowerConnection() ); wxASSERT( pin->IsPowerConnection() );
m_global_label_cache[name].push_back( subgraph ); m_global_label_cache[name].push_back( subgraph );
break; break;
} }
@ -761,27 +761,15 @@ void CONNECTION_GRAPH::buildConnectionGraph()
auto conn = subgraph->m_driver_connection; auto conn = subgraph->m_driver_connection;
auto name = conn->Name(); auto name = conn->Name();
auto local_name = conn->Name( true );
bool conflict = false; bool conflict = false;
// First check the caches // First check the caches
try if( m_global_label_cache.count( name ) )
{
auto v = m_global_label_cache.at( name );
conflict = true; conflict = true;
}
catch( const std::out_of_range& oor )
{}
try if( m_local_label_cache.count( std::make_pair( subgraph->m_sheet, local_name ) ) )
{
auto local_name = conn->Name( true );
auto v = m_local_label_cache.at( std::make_pair( subgraph->m_sheet,
local_name ) );
conflict = true; conflict = true;
}
catch( const std::out_of_range& oor )
{}
if( conflict ) if( conflict )
{ {
@ -836,11 +824,11 @@ void CONNECTION_GRAPH::buildConnectionGraph()
if( connection->IsBus() ) if( connection->IsBus() )
{ {
try if( m_bus_name_to_code_map.count( name ) )
{ {
code = m_bus_name_to_code_map.at( name ); code = m_bus_name_to_code_map.at( name );
} }
catch( const std::out_of_range& oor ) else
{ {
code = m_last_bus_code++; code = m_last_bus_code++;
m_bus_name_to_code_map[ name ] = code; m_bus_name_to_code_map[ name ] = code;
@ -938,13 +926,13 @@ void CONNECTION_GRAPH::buildConnectionGraph()
for( auto pc : m_invisible_power_pins ) for( auto pc : m_invisible_power_pins )
{ {
if( pc->ConnectedItems().size() > 0 && !pc->m_pin->GetParent()->IsPower() ) if( pc->ConnectedItems().size() > 0 && !pc->GetLibPin()->GetParent()->IsPower() )
{ {
// ERC will warn about this: user has wired up an invisible pin // ERC will warn about this: user has wired up an invisible pin
continue; continue;
} }
auto name = pc->m_pin->GetName(); auto name = pc->GetName();
int code = -1; int code = -1;
auto sheet = all_sheets[0]; auto sheet = all_sheets[0];
@ -960,11 +948,11 @@ void CONNECTION_GRAPH::buildConnectionGraph()
continue; continue;
} }
try if( m_net_name_to_code_map.count( name ) )
{ {
code = m_net_name_to_code_map.at( name ); code = m_net_name_to_code_map.at( name );
} }
catch( const std::out_of_range& oor ) else
{ {
code = assignNewNetCode( *connection ); code = assignNewNetCode( *connection );
} }
@ -978,14 +966,8 @@ void CONNECTION_GRAPH::buildConnectionGraph()
CONNECTION_SUBGRAPH* subgraph = nullptr; CONNECTION_SUBGRAPH* subgraph = nullptr;
try if( m_net_code_to_subgraphs_map.count( code ) )
{ subgraph = m_net_code_to_subgraphs_map.at( code )[0];
auto subgraphs = m_net_code_to_subgraphs_map.at( code );
subgraph = subgraphs[0];
}
catch( const std::out_of_range& oor )
{
}
if( subgraph && subgraph->m_driver_connection ) if( subgraph && subgraph->m_driver_connection )
{ {
@ -1027,7 +1009,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
if( obj == subgraph->m_driver ) if( obj == subgraph->m_driver )
continue; continue;
auto power_object = dynamic_cast<SCH_PIN_CONNECTION*>( obj ); auto power_object = dynamic_cast<SCH_PIN*>( obj );
// Skip drivers that aren't power ports // Skip drivers that aren't power ports
if( !power_object ) if( !power_object )
@ -1036,14 +1018,8 @@ void CONNECTION_GRAPH::buildConnectionGraph()
auto name = power_object->GetDefaultNetName( subgraph->m_sheet ); auto name = power_object->GetDefaultNetName( subgraph->m_sheet );
int code = -1; int code = -1;
try if( m_net_name_to_code_map.count( name ) == 0 )
{
code = m_net_name_to_code_map.at( name );
}
catch( const std::out_of_range& oor )
{
continue; continue;
}
for( auto subgraph_to_update : m_subgraphs ) for( auto subgraph_to_update : m_subgraphs )
{ {
@ -1106,7 +1082,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
{ {
auto neighbor_conn = neighbor->m_driver_connection; auto neighbor_conn = neighbor->m_driver_connection;
try if( m_net_name_to_code_map.count( neighbor_conn->Name() ) )
{ {
int c = m_net_name_to_code_map.at( neighbor_conn->Name() ); int c = m_net_name_to_code_map.at( neighbor_conn->Name() );
@ -1120,7 +1096,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
#endif #endif
} }
} }
catch( const std::out_of_range& oor ) else
{ {
#ifdef CONNECTIVITY_DEBUG #ifdef CONNECTIVITY_DEBUG
wxASSERT_MSG( false, "No net code found for an existing net" ); wxASSERT_MSG( false, "No net code found for an existing net" );
@ -1364,11 +1340,11 @@ int CONNECTION_GRAPH::assignNewNetCode( SCH_CONNECTION& aConnection )
{ {
int code; int code;
try if( m_net_name_to_code_map.count( aConnection.Name() ) )
{ {
code = m_net_name_to_code_map.at( aConnection.Name() ); code = m_net_name_to_code_map.at( aConnection.Name() );
} }
catch( const std::out_of_range& oor ) else
{ {
code = m_last_net_code++; code = m_last_net_code++;
m_net_name_to_code_map[ aConnection.Name() ] = code; m_net_name_to_code_map[ aConnection.Name() ] = code;
@ -1382,14 +1358,10 @@ int CONNECTION_GRAPH::assignNewNetCode( SCH_CONNECTION& aConnection )
std::shared_ptr<BUS_ALIAS> CONNECTION_GRAPH::GetBusAlias( wxString aName ) std::shared_ptr<BUS_ALIAS> CONNECTION_GRAPH::GetBusAlias( wxString aName )
{ {
try if( m_bus_alias_cache.count( aName ) )
{
return m_bus_alias_cache.at( aName ); return m_bus_alias_cache.at( aName );
}
catch( const std::out_of_range& oor )
{
return nullptr; return nullptr;
}
} }
@ -1605,9 +1577,9 @@ bool CONNECTION_GRAPH::ercCheckBusToBusConflicts( CONNECTION_SUBGRAPH* aSubgraph
{ {
bool match = false; bool match = false;
for( auto member : label->Connection( sheet )->Members() ) for( const auto& member : label->Connection( sheet )->Members() )
{ {
for( auto test : port->Connection( sheet )->Members() ) for( const auto& test : port->Connection( sheet )->Members() )
{ {
if( test != member && member->Name() == test->Name() ) if( test != member && member->Name() == test->Name() )
{ {
@ -1736,7 +1708,7 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( CONNECTION_SUBGRAPH* aSubgraph,
if( aSubgraph->m_no_connect != nullptr ) if( aSubgraph->m_no_connect != nullptr )
{ {
bool has_invalid_items = false; bool has_invalid_items = false;
SCH_PIN_CONNECTION* pin = nullptr; SCH_PIN* pin = nullptr;
std::vector<SCH_ITEM*> invalid_items; std::vector<SCH_ITEM*> invalid_items;
// Any subgraph that contains both a pin and a no-connect should not // Any subgraph that contains both a pin and a no-connect should not
@ -1746,8 +1718,8 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( CONNECTION_SUBGRAPH* aSubgraph,
{ {
switch( item->Type() ) switch( item->Type() )
{ {
case SCH_PIN_CONNECTION_T: case SCH_PIN_T:
pin = static_cast<SCH_PIN_CONNECTION*>( item ); pin = static_cast<SCH_PIN*>( item );
break; break;
case SCH_NO_CONNECT_T: case SCH_NO_CONNECT_T:
@ -1764,8 +1736,8 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( CONNECTION_SUBGRAPH* aSubgraph,
{ {
auto pos = pin->GetPosition(); auto pos = pin->GetPosition();
msg.Printf( _( "Pin %s of component %s has a no-connect marker but is connected" ), msg.Printf( _( "Pin %s of component %s has a no-connect marker but is connected" ),
GetChars( pin->m_pin->GetName() ), GetChars( pin->GetName() ),
GetChars( pin->m_comp->GetRef( &aSubgraph->m_sheet ) ) ); GetChars( pin->GetParentComponent()->GetRef( &aSubgraph->m_sheet ) ) );
auto marker = new SCH_MARKER(); auto marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() ); marker->SetTimeStamp( GetNewTimeStamp() );
@ -1781,7 +1753,7 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( CONNECTION_SUBGRAPH* aSubgraph,
else else
{ {
bool has_other_connections = false; bool has_other_connections = false;
SCH_PIN_CONNECTION* pin = nullptr; SCH_PIN* pin = nullptr;
// Any subgraph that lacks a no-connect and contains a pin should also // Any subgraph that lacks a no-connect and contains a pin should also
// contain at least one other connectable item. // contain at least one other connectable item.
@ -1790,9 +1762,9 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( CONNECTION_SUBGRAPH* aSubgraph,
{ {
switch( item->Type() ) switch( item->Type() )
{ {
case SCH_PIN_CONNECTION_T: case SCH_PIN_T:
if( !pin ) if( !pin )
pin = static_cast<SCH_PIN_CONNECTION*>( item ); pin = static_cast<SCH_PIN*>( item );
else else
has_other_connections = true; has_other_connections = true;
break; break;
@ -1804,13 +1776,12 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( CONNECTION_SUBGRAPH* aSubgraph,
} }
} }
if( pin && !has_other_connections && if( pin && !has_other_connections && pin->GetType() != PIN_NC )
pin->m_pin->GetType() != PIN_NC )
{ {
auto pos = pin->GetPosition(); auto pos = pin->GetPosition();
msg.Printf( _( "Pin %s of component %s is unconnected." ), msg.Printf( _( "Pin %s of component %s is unconnected." ),
GetChars( pin->m_pin->GetName() ), GetChars( pin->GetName() ),
GetChars( pin->m_comp->GetRef( &aSubgraph->m_sheet ) ) ); GetChars( pin->GetParentComponent()->GetRef( &aSubgraph->m_sheet ) ) );
auto marker = new SCH_MARKER(); auto marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() ); marker->SetTimeStamp( GetNewTimeStamp() );
@ -1851,7 +1822,7 @@ bool CONNECTION_GRAPH::ercCheckLabels( CONNECTION_SUBGRAPH* aSubgraph,
text = static_cast<SCH_TEXT*>( item ); text = static_cast<SCH_TEXT*>( item );
break; break;
case SCH_PIN_CONNECTION_T: case SCH_PIN_T:
has_other_connections = true; has_other_connections = true;
break; break;

View File

@ -39,7 +39,7 @@
// TODO(JE) re-enable this once performance concerns are sorted out // TODO(JE) re-enable this once performance concerns are sorted out
// #define CONNECTIVITY_REAL_TIME // #define CONNECTIVITY_REAL_TIME
class SCH_PIN_CONNECTION; class SCH_PIN;
class SCH_EDIT_FRAME; class SCH_EDIT_FRAME;
@ -191,7 +191,7 @@ private:
std::vector<CONNECTION_SUBGRAPH*> m_subgraphs; std::vector<CONNECTION_SUBGRAPH*> m_subgraphs;
std::vector<SCH_PIN_CONNECTION*> m_invisible_power_pins; std::vector<SCH_PIN*> m_invisible_power_pins;
std::unordered_map<wxString, std::shared_ptr<BUS_ALIAS>> m_bus_alias_cache; std::unordered_map<wxString, std::shared_ptr<BUS_ALIAS>> m_bus_alias_cache;

View File

@ -469,7 +469,7 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
} }
} }
m_cmp->UpdatePinCache(); m_cmp->UpdatePins();
GetParent()->TestDanglingEnds(); GetParent()->TestDanglingEnds();
GetParent()->RefreshItem( m_cmp ); GetParent()->RefreshItem( m_cmp );

View File

@ -384,7 +384,7 @@ void SCH_EDIT_FRAME::ConvertPart( SCH_COMPONENT* aComponent )
// The alternate symbol may cause a change in the connection status so test the // The alternate symbol may cause a change in the connection status so test the
// connections so the connection indicators are drawn correctly. // connections so the connection indicators are drawn correctly.
aComponent->UpdatePinCache(); aComponent->UpdatePins();
TestDanglingEnds(); TestDanglingEnds();
aComponent->ClearFlags(); aComponent->ClearFlags();
aComponent->SetFlags( flags ); // Restore m_Flag (modified by SetConvert()) aComponent->SetFlags( flags ); // Restore m_Flag (modified by SetConvert())

View File

@ -117,7 +117,7 @@ bool SCH_EDIT_FRAME::SetCurrentSheetHighlightFlags( std::vector<EDA_ITEM*>* aIte
{ {
auto pin_conn = comp->GetConnectionForPin( pin, *g_CurrentSheet ); auto pin_conn = comp->GetConnectionForPin( pin, *g_CurrentSheet );
if( pin_conn && pin_conn->Name( false, true ) == m_SelectedNetName ) if( pin_conn && pin_conn->Name( false ) == m_SelectedNetName )
{ {
comp->BrightenPin( pin ); comp->BrightenPin( pin );
redraw = true; redraw = true;

View File

@ -506,7 +506,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets( bool aUseGraph )
{ {
wxASSERT( m_graph ); wxASSERT( m_graph );
for( auto it : m_graph->m_net_code_to_subgraphs_map ) for( const auto& it : m_graph->m_net_code_to_subgraphs_map )
{ {
bool added = false; bool added = false;
@ -522,12 +522,12 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets( bool aUseGraph )
for( auto item : subgraph->m_items ) for( auto item : subgraph->m_items )
{ {
if( item->Type() == SCH_PIN_CONNECTION_T ) if( item->Type() == SCH_PIN_T )
{ {
auto pc = static_cast<SCH_PIN_CONNECTION*>( item ); auto pin = static_cast<SCH_PIN*>( item );
auto refText = pc->m_comp->GetRef( &sheet ); auto refText = pin->GetParentComponent()->GetRef( &sheet );
auto pinText = pc->m_pin->GetNumber(); auto pinText = pin->GetNumber();
// Skip power symbols and virtual components // Skip power symbols and virtual components
if( refText[0] == wxChar( '#' ) ) if( refText[0] == wxChar( '#' ) )

View File

@ -80,16 +80,16 @@ bool NETLIST_EXPORTER_KICAD::WriteNetlist( const wxString& aOutFileName, unsigne
for( auto item : subgraph->m_items ) for( auto item : subgraph->m_items )
{ {
if( item->Type() == SCH_PIN_CONNECTION_T ) if( item->Type() == SCH_PIN_T )
{ {
auto pc = static_cast<SCH_PIN_CONNECTION*>( item ); auto pin = static_cast<SCH_PIN*>( item );
if( pc->m_pin->IsPowerConnection() || if( pin->IsPowerConnection() ||
(LIB_PART*)( pc->m_pin->GetParent() )->IsPower() ) (LIB_PART*)( pin->GetLibPin()->GetParent() )->IsPower() )
continue; continue;
wxString refText = pc->m_comp->GetRef( &sheet ); const wxString& refText = pin->GetParentComponent()->GetRef( &sheet );
wxString pinText = pc->m_pin->GetNumber(); const wxString& pinText = pin->GetNumber();
net_pins.insert( refText + "-" + pinText ); net_pins.insert( refText + "-" + pinText );
} }

View File

@ -148,7 +148,7 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, LIB_ID aLibId, SCH_SHEET_PATH* sh
UpdateFields( true, true ); UpdateFields( true, true );
// Update the pin locations // Update the pin locations
UpdatePinCache(); UpdatePins();
// Update the reference -- just the prefix for now. // Update the reference -- just the prefix for now.
if( sheet ) if( sheet )
@ -167,7 +167,6 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
m_convert = aComponent.m_convert; m_convert = aComponent.m_convert;
m_lib_id = aComponent.m_lib_id; m_lib_id = aComponent.m_lib_id;
m_part = aComponent.m_part; m_part = aComponent.m_part;
m_Pins = aComponent.m_Pins;
SetTimeStamp( aComponent.m_TimeStamp ); SetTimeStamp( aComponent.m_TimeStamp );
@ -177,12 +176,18 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
m_Fields = aComponent.m_Fields; m_Fields = aComponent.m_Fields;
// Re-parent the fields, which before this had aComponent as parent // Re-parent the fields, which before this had aComponent as parent
for( int i = 0; i<GetFieldCount(); ++i ) for( int i = 0; i < GetFieldCount(); ++i )
{ {
GetField( i )->SetParent( this ); GetField( i )->SetParent( this );
} }
m_isDangling = aComponent.m_isDangling; // Copy the pins, and re-parent them
for( const auto& it : aComponent.m_pins )
{
m_pins.emplace( std::make_pair( it.first, it.second ) );
m_pins.at( it.first ).SetParentComponent( this );
}
m_fieldsAutoplaced = aComponent.m_fieldsAutoplaced; m_fieldsAutoplaced = aComponent.m_fieldsAutoplaced;
} }
@ -391,7 +396,7 @@ void SCH_COMPONENT::ResolveAll( const SCH_COLLECTOR& aComponents, PART_LIBS* aLi
SCH_COMPONENT* cmp = cmp_list[ii]; SCH_COMPONENT* cmp = cmp_list[ii];
curr_libid = cmp->m_lib_id; curr_libid = cmp->m_lib_id;
cmp->Resolve( aLibs ); cmp->Resolve( aLibs );
cmp->UpdatePinCache(); cmp->UpdatePins();
// Propagate the m_part pointer to other members using the same lib_id // Propagate the m_part pointer to other members using the same lib_id
for( unsigned jj = ii+1; jj < cmp_list.size (); ++jj ) for( unsigned jj = ii+1; jj < cmp_list.size (); ++jj )
@ -403,11 +408,7 @@ void SCH_COMPONENT::ResolveAll( const SCH_COLLECTOR& aComponents, PART_LIBS* aLi
next_cmp->m_part = cmp->m_part; next_cmp->m_part = cmp->m_part;
if( ( cmp->m_unit == next_cmp->m_unit ) && ( cmp->m_convert == next_cmp->m_convert ) ) next_cmp->UpdatePins();
// Propagate the pin cache vector as well
next_cmp->m_Pins = cmp->m_Pins;
else
next_cmp->UpdatePinCache();
ii = jj; ii = jj;
} }
@ -439,7 +440,7 @@ void SCH_COMPONENT::ResolveAll( const SCH_COLLECTOR& aComponents, SYMBOL_LIB_TAB
SCH_COMPONENT* cmp = cmp_list[ii]; SCH_COMPONENT* cmp = cmp_list[ii];
curr_libid = cmp->m_lib_id; curr_libid = cmp->m_lib_id;
cmp->Resolve( aLibTable, aCacheLib ); cmp->Resolve( aLibTable, aCacheLib );
cmp->UpdatePinCache(); cmp->UpdatePins();
// Propagate the m_part pointer to other members using the same lib_id // Propagate the m_part pointer to other members using the same lib_id
for( unsigned jj = ii+1; jj < cmp_list.size (); ++jj ) for( unsigned jj = ii+1; jj < cmp_list.size (); ++jj )
@ -451,11 +452,7 @@ void SCH_COMPONENT::ResolveAll( const SCH_COLLECTOR& aComponents, SYMBOL_LIB_TAB
next_cmp->m_part = cmp->m_part; next_cmp->m_part = cmp->m_part;
if( ( cmp->m_unit == next_cmp->m_unit ) && ( cmp->m_convert == next_cmp->m_convert ) ) next_cmp->UpdatePins();
// Propagate the pin cache vector as well
next_cmp->m_Pins = cmp->m_Pins;
else
next_cmp->UpdatePinCache();
ii = jj; ii = jj;
} }
@ -463,104 +460,48 @@ void SCH_COMPONENT::ResolveAll( const SCH_COLLECTOR& aComponents, SYMBOL_LIB_TAB
} }
void SCH_COMPONENT::UpdatePinCache()
{
if( PART_SPTR part = m_part.lock() )
{
m_Pins.clear();
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
{
wxASSERT( pin->Type() == LIB_PIN_T );
if( pin->GetUnit() && m_unit && ( m_unit != pin->GetUnit() ) )
continue;
if( pin->GetConvert() && m_convert && ( m_convert != pin->GetConvert() ) )
continue;
m_Pins.push_back( pin->GetPosition() );
}
}
}
void SCH_COMPONENT::UpdateAllPinCaches( const SCH_COLLECTOR& aComponents ) void SCH_COMPONENT::UpdateAllPinCaches( const SCH_COLLECTOR& aComponents )
{ {
// Usually, many components use the same part lib.
// to avoid too long calculation time the list of components is grouped
// and once the lib part is found for one member of a group, it is also
// set for all other members of this group
std::vector<SCH_COMPONENT*> cmp_list;
// build the cmp list.
for( int i = 0; i < aComponents.GetCount(); ++i ) for( int i = 0; i < aComponents.GetCount(); ++i )
{ {
SCH_COMPONENT* cmp = dynamic_cast<SCH_COMPONENT*>( aComponents[i] ); SCH_COMPONENT* cmp = dynamic_cast<SCH_COMPONENT*>( aComponents[i] );
wxASSERT( cmp ); wxASSERT( cmp );
if( cmp ) // cmp == NULL should not occur. cmp->UpdatePins();
cmp_list.push_back( cmp );
}
// sort it by lib part. Cmp will be grouped by same lib part.
std::sort( cmp_list.begin(), cmp_list.end(), sort_by_libid );
LIB_ID curr_libid;
for( unsigned ii = 0; ii < cmp_list.size (); ++ii )
{
SCH_COMPONENT* cmp = cmp_list[ii];
curr_libid = cmp->m_lib_id;
cmp->UpdatePinCache();
// Propagate the m_Pins vector to other members using the same lib_id
for( unsigned jj = ii+1; jj < cmp_list.size (); ++jj )
{
SCH_COMPONENT* next_cmp = cmp_list[jj];
if( ( curr_libid != next_cmp->m_lib_id )
|| ( cmp->m_unit != next_cmp->m_unit )
|| ( cmp->m_convert != next_cmp->m_convert ) )
break;
// Propagate the pin cache vector as well
next_cmp->m_Pins = cmp->m_Pins;
ii = jj;
}
} }
} }
void SCH_COMPONENT::UpdatePinConnections( SCH_SHEET_PATH aSheet ) void SCH_COMPONENT::UpdatePins( SCH_SHEET_PATH* aSheet )
{ {
if( PART_SPTR part = m_part.lock() ) if( PART_SPTR part = m_part.lock() )
{ {
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) ) for( auto& it : m_pins )
{ it.second.ClearFlags( BUSY );
wxASSERT( pin->Type() == LIB_PIN_T );
if( pin->GetUnit() && m_unit && ( m_unit != pin->GetUnit() ) ) for( LIB_PIN* libPin = part->GetNextPin(); libPin; libPin = part->GetNextPin( libPin ) )
{
wxASSERT( libPin->Type() == LIB_PIN_T );
if( libPin->GetUnit() && m_unit && ( m_unit != libPin->GetUnit() ) )
continue; continue;
if( pin->GetConvert() && m_convert && ( m_convert != pin->GetConvert() ) ) if( libPin->GetConvert() && m_convert && ( m_convert != libPin->GetConvert() ) )
continue; continue;
SCH_PIN_CONNECTION* connection = nullptr; if( !m_pins.count( libPin ) )
m_pins.emplace( std::make_pair( libPin, SCH_PIN( libPin, this ) ) );
try if( aSheet )
{ m_pins.at( libPin ).InitializeConnection( *aSheet );
connection = m_pin_connections.at( pin );
} m_pins.at( libPin ).SetFlags( BUSY );
catch( const std::out_of_range& oor )
{
connection = new SCH_PIN_CONNECTION();
m_pin_connections[ pin ] = connection;
} }
connection->m_pin = pin; for( auto& it : m_pins )
connection->m_comp = this; {
connection->InitializeConnection( aSheet ); if( !( it.second.GetFlags() & BUSY ) )
m_pins.erase( it.first );
} }
} }
} }
@ -568,13 +509,8 @@ void SCH_COMPONENT::UpdatePinConnections( SCH_SHEET_PATH aSheet )
SCH_CONNECTION* SCH_COMPONENT::GetConnectionForPin( LIB_PIN* aPin, const SCH_SHEET_PATH& aSheet ) SCH_CONNECTION* SCH_COMPONENT::GetConnectionForPin( LIB_PIN* aPin, const SCH_SHEET_PATH& aSheet )
{ {
if( m_pin_connections.count( aPin ) ) if( m_pins.count( aPin ) )
{ return m_pins.at( aPin ).Connection( aSheet );
SCH_PIN_CONNECTION* pin_conn = m_pin_connections.at( aPin );
if( pin_conn )
return pin_conn->Connection( aSheet );
}
return nullptr; return nullptr;
} }
@ -641,12 +577,17 @@ void SCH_COMPONENT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOff
if( PART_SPTR part = m_part.lock() ) if( PART_SPTR part = m_part.lock() )
{ {
// Draw pin targets if part is being dragged LIB_PINS libPins;
bool dragging = aPanel->GetScreen()->GetCurItem() == this && aPanel->IsMouseCaptured(); part->GetPins( libPins, m_unit, m_convert );
if( !dragging ) for( LIB_PIN *libPin : libPins )
{ {
opts.dangling = m_isDangling; bool isDangling = true;
if( m_pins.count( libPin ) )
isDangling = m_pins.at( libPin ).IsDangling();
opts.dangling.push_back( isDangling );
} }
part->Draw( aPanel, aDC, m_Pos + aOffset, m_unit, m_convert, opts ); part->Draw( aPanel, aDC, m_Pos + aOffset, m_unit, m_convert, opts );
@ -1086,6 +1027,12 @@ void SCH_COMPONENT::GetPins( std::vector<LIB_PIN*>& aPinsList )
} }
SCH_PINS& SCH_COMPONENT::GetPinMap()
{
return m_pins;
}
void SCH_COMPONENT::SwapData( SCH_ITEM* aItem ) void SCH_COMPONENT::SwapData( SCH_ITEM* aItem )
{ {
wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_COMPONENT_T), wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_COMPONENT_T),
@ -1098,9 +1045,7 @@ void SCH_COMPONENT::SwapData( SCH_ITEM* aItem )
std::swap( m_Pos, component->m_Pos ); std::swap( m_Pos, component->m_Pos );
std::swap( m_unit, component->m_unit ); std::swap( m_unit, component->m_unit );
std::swap( m_convert, component->m_convert ); std::swap( m_convert, component->m_convert );
std::swap( m_pins, component->m_pins );
std::swap( m_Pins, component->m_Pins );
std::swap( m_isDangling, component->m_isDangling );
TRANSFORM tmp = m_transform; TRANSFORM tmp = m_transform;
@ -1642,21 +1587,12 @@ bool SCH_COMPONENT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemLi
{ {
bool changed = false; bool changed = false;
for( size_t i = 0; i < m_Pins.size(); ++i ) for( auto& it : m_pins )
{ {
bool previousState; bool previousState = it.second.IsDangling();
wxPoint pos = m_transform.TransformCoordinate( m_Pins[ i ] ) + m_Pos; it.second.SetIsDangling( true );
if( i < m_isDangling.size() ) wxPoint pos = m_transform.TransformCoordinate( it.second.GetPosition() ) + m_Pos;
{
previousState = m_isDangling[ i ];
m_isDangling[ i ] = true;
}
else
{
previousState = true;
m_isDangling.push_back( true );
}
for( DANGLING_END_ITEM& each_item : aItemList ) for( DANGLING_END_ITEM& each_item : aItemList )
{ {
@ -1678,7 +1614,7 @@ bool SCH_COMPONENT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemLi
case JUNCTION_END: case JUNCTION_END:
if( pos == each_item.GetPosition() ) if( pos == each_item.GetPosition() )
m_isDangling[ i ] = false; it.second.SetIsDangling( false );
break; break;
@ -1686,16 +1622,13 @@ bool SCH_COMPONENT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemLi
break; break;
} }
if( !m_isDangling[ i ] ) if( !it.second.IsDangling() )
break; break;
} }
changed = ( changed || ( previousState != m_isDangling[ i ] ) ); changed = ( changed || ( previousState != it.second.IsDangling() ) );
} }
while( m_isDangling.size() > m_Pins.size() )
m_isDangling.pop_back();
return changed; return changed;
} }
@ -1726,31 +1659,17 @@ bool SCH_COMPONENT::IsSelectStateChanged( const wxRect& aRect )
void SCH_COMPONENT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const void SCH_COMPONENT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
{ {
for( auto pin : m_Pins ) for( auto& it : m_pins )
aPoints.push_back( m_transform.TransformCoordinate( pin ) + m_Pos ); aPoints.push_back( m_transform.TransformCoordinate( it.second.GetPosition() ) + m_Pos );
} }
LIB_ITEM* SCH_COMPONENT::GetDrawItem( const wxPoint& aPosition, KICAD_T aType ) LIB_ITEM* SCH_COMPONENT::GetDrawItem( const wxPoint& aPosition, KICAD_T aType )
{ {
UpdatePins();
if( PART_SPTR part = m_part.lock() ) if( PART_SPTR part = m_part.lock() )
{ {
m_Pins.clear();
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
{
wxASSERT( pin->Type() == LIB_PIN_T );
if( pin->GetUnit() && m_unit && ( m_unit != pin->GetUnit() ) )
continue;
if( pin->GetConvert() && m_convert && ( m_convert != pin->GetConvert() ) )
continue;
m_Pins.push_back( pin->GetPosition() );
}
// Calculate the position relative to the component. // Calculate the position relative to the component.
wxPoint libPosition = aPosition - m_Pos; wxPoint libPosition = aPosition - m_Pos;
@ -1948,7 +1867,6 @@ SCH_ITEM& SCH_COMPONENT::operator=( const SCH_ITEM& aItem )
m_unit = c->m_unit; m_unit = c->m_unit;
m_convert = c->m_convert; m_convert = c->m_convert;
m_transform = c->m_transform; m_transform = c->m_transform;
m_Pins = c->m_Pins;
m_PathsAndReferences = c->m_PathsAndReferences; m_PathsAndReferences = c->m_PathsAndReferences;
@ -1959,6 +1877,13 @@ SCH_ITEM& SCH_COMPONENT::operator=( const SCH_ITEM& aItem )
{ {
GetField( ii )->SetParent( this ); GetField( ii )->SetParent( this );
} }
// Copy the pins, and re-parent them
for( const auto& it : c->m_pins )
{
m_pins.emplace( std::make_pair( it.first, it.second ) );
m_pins.at( it.first ).SetParentComponent( this );
}
} }
return *this; return *this;
@ -1996,7 +1921,14 @@ bool SCH_COMPONENT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccura
bool SCH_COMPONENT::doIsConnected( const wxPoint& aPosition ) const bool SCH_COMPONENT::doIsConnected( const wxPoint& aPosition ) const
{ {
wxPoint new_pos = m_transform.InverseTransform().TransformCoordinate( aPosition - m_Pos ); wxPoint new_pos = m_transform.InverseTransform().TransformCoordinate( aPosition - m_Pos );
return std::find( m_Pins.begin(), m_Pins.end(), new_pos ) != m_Pins.end();
for( const auto& it : m_pins )
{
if( it.second.GetPosition() == new_pos )
return true;
}
return false;
} }
@ -2030,43 +1962,41 @@ void SCH_COMPONENT::Plot( PLOTTER* aPlotter )
bool SCH_COMPONENT::HasBrightenedPins() bool SCH_COMPONENT::HasBrightenedPins()
{ {
return m_brightenedPins.size() > 0; for( auto& it : m_pins )
{
if( it.second.IsBrightened() )
return true;
}
return false;
} }
void SCH_COMPONENT::ClearBrightenedPins() void SCH_COMPONENT::ClearBrightenedPins()
{ {
m_brightenedPins.clear(); for( auto& it : m_pins )
it.second.ClearBrightened();
} }
void SCH_COMPONENT::BrightenPin( LIB_PIN* aPin ) void SCH_COMPONENT::BrightenPin( LIB_PIN* aPin )
{ {
m_brightenedPins.insert( aPin->GetNumber() ); if( m_pins.count( aPin ) )
} m_pins.at( aPin ).SetBrightened();
bool SCH_COMPONENT::IsPinBrightened( const LIB_PIN* aPin )
{
return m_brightenedPins.find( aPin->GetNumber() ) != m_brightenedPins.end();
} }
void SCH_COMPONENT::ClearHighlightedPins() void SCH_COMPONENT::ClearHighlightedPins()
{ {
m_highlightedPins.clear(); for( auto& it : m_pins )
it.second.ClearHighlighted();
} }
void SCH_COMPONENT::HighlightPin( LIB_PIN* aPin ) void SCH_COMPONENT::HighlightPin( LIB_PIN* aPin )
{ {
m_highlightedPins.insert( aPin->GetNumber() ); if( m_pins.count( aPin ) )
} m_pins.at( aPin ).SetHighlighted();
bool SCH_COMPONENT::IsPinHighlighted( const LIB_PIN* aPin )
{
return m_highlightedPins.find( aPin->GetNumber() ) != m_highlightedPins.end();
} }

View File

@ -40,7 +40,7 @@
#include <vector> #include <vector>
#include <set> #include <set>
#include <lib_draw_item.h> #include <lib_draw_item.h>
#include <sch_pin_connection.h> #include <sch_pin.h>
class SCH_SCREEN; class SCH_SCREEN;
class SCH_SHEET_PATH; class SCH_SHEET_PATH;
@ -55,6 +55,9 @@ class SCH_SCREEN;
class SYMBOL_LIB_TABLE; class SYMBOL_LIB_TABLE;
/// Pins, mapped by their corresponding LIB_PINs.
typedef std::unordered_map<LIB_PIN*, SCH_PIN> SCH_PINS;
/// A container for several SCH_FIELD items /// A container for several SCH_FIELD items
typedef std::vector<SCH_FIELD> SCH_FIELDS; typedef std::vector<SCH_FIELD> SCH_FIELDS;
@ -93,10 +96,7 @@ private:
PART_REF m_part; ///< points into the PROJECT's libraries to the LIB_PART for this component PART_REF m_part; ///< points into the PROJECT's libraries to the LIB_PART for this component
std::vector<bool> m_isDangling; ///< One isDangling per pin SCH_PINS m_pins;
std::vector<wxPoint> m_Pins;
std::set<wxString> m_highlightedPins; ///< God forgive me - Tom
std::set<wxString> m_brightenedPins; ///< ... and me too - Jeff
AUTOPLACED m_fieldsAutoplaced; ///< indicates status of field autoplacement AUTOPLACED m_fieldsAutoplaced; ///< indicates status of field autoplacement
@ -108,8 +108,6 @@ private:
*/ */
wxArrayString m_PathsAndReferences; wxArrayString m_PathsAndReferences;
std::unordered_map<LIB_PIN*, SCH_PIN_CONNECTION*> m_pin_connections;
void Init( const wxPoint& pos = wxPoint( 0, 0 ) ); void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
public: public:
@ -204,11 +202,6 @@ public:
int GetUnit() const { return m_unit; } int GetUnit() const { return m_unit; }
/**
* Updates the local cache of pin positions
*/
void UpdatePinCache();
/** /**
* Update the pin cache for all components in \a aComponents * Update the pin cache for all components in \a aComponents
* *
@ -219,18 +212,13 @@ public:
/** /**
* Updates the local cache of SCH_PIN_CONNECTION objects for each pin * Updates the local cache of SCH_PIN_CONNECTION objects for each pin
*/ */
void UpdatePinConnections( SCH_SHEET_PATH aSheet ); void UpdatePins( SCH_SHEET_PATH* aSheet = nullptr );
/** /**
* Retrieves the connection for a given pin of the component * Retrieves the connection for a given pin of the component
*/ */
SCH_CONNECTION* GetConnectionForPin( LIB_PIN* aPin, const SCH_SHEET_PATH& aSheet ); SCH_CONNECTION* GetConnectionForPin( LIB_PIN* aPin, const SCH_SHEET_PATH& aSheet );
const std::unordered_map<LIB_PIN*, SCH_PIN_CONNECTION*>& PinConnections()
{
return m_pin_connections;
}
/** /**
* Change the unit number to \a aUnit * Change the unit number to \a aUnit
* *
@ -478,13 +466,17 @@ public:
LIB_PIN* GetPin( const wxString& number ); LIB_PIN* GetPin( const wxString& number );
/** /**
* Populate a vector with all the pins. * Populate a vector with all the pins from the library object.
* *
* @param aPinsList is the list to populate with all of the pins. * @param aPinsList is the list to populate with all of the pins.
*/ */
void GetPins( std::vector<LIB_PIN*>& aPinsList ); void GetPins( std::vector<LIB_PIN*>& aPinsList );
std::vector<bool>* GetDanglingPinFlags() { return &m_isDangling; } /**
* Return a map of library pins to their SCH_PIN equivalents.
* @return
*/
SCH_PINS& GetPinMap();
void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
GR_DRAWMODE aDrawMode, COLOR4D aColor = COLOR4D::UNSPECIFIED ) override GR_DRAWMODE aDrawMode, COLOR4D aColor = COLOR4D::UNSPECIFIED ) override
@ -669,14 +661,10 @@ public:
void BrightenPin( LIB_PIN* aPin ); void BrightenPin( LIB_PIN* aPin );
bool IsPinBrightened( const LIB_PIN* aPin );
void ClearHighlightedPins(); void ClearHighlightedPins();
void HighlightPin( LIB_PIN* aPin ); void HighlightPin( LIB_PIN* aPin );
bool IsPinHighlighted( const LIB_PIN* aPin );
private: private:
bool doIsConnected( const wxPoint& aPosition ) const override; bool doIsConnected( const wxPoint& aPosition ) const override;
}; };

View File

@ -22,7 +22,6 @@
#include <wx/tokenzr.h> #include <wx/tokenzr.h>
#include <connection_graph.h> #include <connection_graph.h>
#include <sch_pin_connection.h>
#include <sch_screen.h> #include <sch_screen.h>
#include <sch_connection.h> #include <sch_connection.h>
@ -231,7 +230,7 @@ bool SCH_CONNECTION::IsDriver() const
case SCH_LABEL_T: case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T: case SCH_GLOBAL_LABEL_T:
case SCH_HIERARCHICAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T:
case SCH_PIN_CONNECTION_T: case SCH_PIN_T:
case SCH_SHEET_PIN_T: case SCH_SHEET_PIN_T:
case SCH_SHEET_T: case SCH_SHEET_T:
case LIB_PIN_T: case LIB_PIN_T:
@ -243,7 +242,7 @@ bool SCH_CONNECTION::IsDriver() const
} }
wxString SCH_CONNECTION::Name( bool aIgnoreSheet, bool aForceSheet ) const wxString SCH_CONNECTION::Name( bool aIgnoreSheet ) const
{ {
wxString ret = m_name + m_suffix; wxString ret = m_name + m_suffix;
@ -256,7 +255,7 @@ wxString SCH_CONNECTION::Name( bool aIgnoreSheet, bool aForceSheet ) const
{ {
switch( m_driver->Type() ) switch( m_driver->Type() )
{ {
case SCH_PIN_CONNECTION_T: case SCH_PIN_T:
// Pins are either power connections or belong to a uniquely-annotated // Pins are either power connections or belong to a uniquely-annotated
// component, so they don't need a path if they are driving the subgraph // component, so they don't need a path if they are driving the subgraph
prepend_path = false; prepend_path = false;
@ -271,7 +270,7 @@ wxString SCH_CONNECTION::Name( bool aIgnoreSheet, bool aForceSheet ) const
} }
} }
if( aForceSheet || ( prepend_path && !aIgnoreSheet ) ) if( prepend_path && !aIgnoreSheet )
ret = m_sheet.PathHumanReadable() + ret; ret = m_sheet.PathHumanReadable() + ret;
return ret; return ret;

View File

@ -145,7 +145,7 @@ public:
m_dirty = false; m_dirty = false;
} }
wxString Name( bool aIgnoreSheet = false, bool aForceSheet = false ) const; wxString Name( bool aIgnoreSheet = false ) const;
wxString Prefix() const wxString Prefix() const
{ {

View File

@ -1247,7 +1247,6 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
// Save the pin positions // Save the pin positions
auto& schLibTable = *m_kiway->Prj().SchSymbolLibTable(); auto& schLibTable = *m_kiway->Prj().SchSymbolLibTable();
wxCHECK( component->Resolve( schLibTable ), /*void*/ ); wxCHECK( component->Resolve( schLibTable ), /*void*/ );
component->UpdatePinCache();
std::vector<LIB_PIN*> pins; std::vector<LIB_PIN*> pins;
component->GetPins( pins ); component->GetPins( pins );
@ -2551,7 +2550,6 @@ bool SCH_EAGLE_PLUGIN::checkConnections( const SCH_COMPONENT* aComponent, const
void SCH_EAGLE_PLUGIN::addImplicitConnections( SCH_COMPONENT* aComponent, void SCH_EAGLE_PLUGIN::addImplicitConnections( SCH_COMPONENT* aComponent,
SCH_SCREEN* aScreen, bool aUpdateSet ) SCH_SCREEN* aScreen, bool aUpdateSet )
{ {
aComponent->UpdatePinCache();
auto partRef = aComponent->GetPartRef().lock(); auto partRef = aComponent->GetPartRef().lock();
wxCHECK( partRef, /*void*/ ); wxCHECK( partRef, /*void*/ );

View File

@ -92,11 +92,11 @@ SCH_CONNECTION* SCH_ITEM::Connection( const SCH_SHEET_PATH& aSheet ) const
{ {
SCH_CONNECTION* conn = nullptr; SCH_CONNECTION* conn = nullptr;
try if( m_connection_map.count( aSheet ) )
{ {
conn = m_connection_map.at( aSheet ); conn = m_connection_map.at( aSheet );
} }
catch( const std::out_of_range& oor ) else
{ {
// TODO(JE) should we just call InitializeConnection here? // TODO(JE) should we just call InitializeConnection here?
} }

View File

@ -244,8 +244,8 @@ bool SCH_PAINTER::isUnitAndConversionShown( const LIB_ITEM* aItem )
} }
void SCH_PAINTER::draw( LIB_PART *aComp, int aLayer, bool aDrawFields, int aUnit, int aConvert, void SCH_PAINTER::draw( LIB_PART *aPart, int aLayer, bool aDrawFields, int aUnit, int aConvert,
std::vector<bool>* aDanglingPinFlags ) SCH_PINS* aPinMap )
{ {
if( !aUnit ) if( !aUnit )
aUnit = m_schSettings.m_ShowUnit; aUnit = m_schSettings.m_ShowUnit;
@ -253,9 +253,7 @@ void SCH_PAINTER::draw( LIB_PART *aComp, int aLayer, bool aDrawFields, int aUnit
if( !aConvert ) if( !aConvert )
aConvert = m_schSettings.m_ShowConvert; aConvert = m_schSettings.m_ShowConvert;
size_t pinIndex = 0; for( auto& item : aPart->GetDrawItems() )
for( auto& item : aComp->GetDrawItems() )
{ {
if( !aDrawFields && item.Type() == LIB_FIELD_T ) if( !aDrawFields && item.Type() == LIB_FIELD_T )
continue; continue;
@ -268,14 +266,13 @@ void SCH_PAINTER::draw( LIB_PART *aComp, int aLayer, bool aDrawFields, int aUnit
if( item.Type() == LIB_PIN_T ) if( item.Type() == LIB_PIN_T )
{ {
auto pin = static_cast<LIB_PIN*>( &item ); LIB_PIN* libPin = static_cast<LIB_PIN*>( &item );
bool dangling = true; SCH_PIN* schPin = nullptr;
if( aDanglingPinFlags && pinIndex < aDanglingPinFlags->size() ) if( aPinMap && aPinMap->count( libPin ) )
dangling = (*aDanglingPinFlags)[ pinIndex ]; schPin = &aPinMap->at( libPin );
draw( pin, aLayer, dangling, aComp->IsMoving() ); draw( libPin, aLayer, schPin, aPart->IsMoving() );
pinIndex++;
} }
else else
Draw( &item, aLayer ); Draw( &item, aLayer );
@ -528,7 +525,7 @@ static void drawPinDanglingSymbol( GAL* aGal, const VECTOR2I& aPos, const COLOR4
} }
void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer, bool aIsDangling, bool isMoving ) void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer, SCH_PIN* aSchPin, bool isParentMoving )
{ {
if( aLayer != LAYER_DEVICE ) if( aLayer != LAYER_DEVICE )
return; return;
@ -536,13 +533,14 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer, bool aIsDangling, bool isMovi
if( !isUnitAndConversionShown( aPin ) ) if( !isUnitAndConversionShown( aPin ) )
return; return;
if( aPin->IsMoving() ) bool isMoving = isParentMoving || aPin->IsMoving();
isMoving = true; bool isDangling = !aSchPin || aSchPin->IsDangling();
bool isBrightened = aSchPin && aSchPin->IsBrightened();
VECTOR2I pos = mapCoords( aPin->GetPosition() ); VECTOR2I pos = mapCoords( aPin->GetPosition() );
COLOR4D color; COLOR4D color;
if( aPin->IsBrightened() ) if( isBrightened )
color = m_schSettings.GetLayerColor( LAYER_BRIGHTENED ); color = m_schSettings.GetLayerColor( LAYER_BRIGHTENED );
else else
color = getOverlayColor( aPin, m_schSettings.GetLayerColor( LAYER_PIN ), false ); color = getOverlayColor( aPin, m_schSettings.GetLayerColor( LAYER_PIN ), false );
@ -555,7 +553,7 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer, bool aIsDangling, bool isMovi
} }
else else
{ {
if( aIsDangling && aPin->IsPowerConnection() ) if( isDangling && aPin->IsPowerConnection() )
drawPinDanglingSymbol( m_gal, pos, color ); drawPinDanglingSymbol( m_gal, pos, color );
return; return;
@ -676,10 +674,10 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer, bool aIsDangling, bool isMovi
m_gal->DrawLine( pos + VECTOR2D( 1, -1 ) * TARGET_PIN_RADIUS , m_gal->DrawLine( pos + VECTOR2D( 1, -1 ) * TARGET_PIN_RADIUS ,
pos + VECTOR2D( -1, 1 ) * TARGET_PIN_RADIUS ); pos + VECTOR2D( -1, 1 ) * TARGET_PIN_RADIUS );
aIsDangling = false; // PIN_NC pin type is always not connected and dangling. isDangling = false; // PIN_NC pin type is always not connected and dangling.
} }
if( aIsDangling && ( aPin->IsVisible() || aPin->IsPowerConnection() ) ) if( isDangling && ( aPin->IsVisible() || aPin->IsPowerConnection() ) )
drawPinDanglingSymbol( m_gal, pos, color ); drawPinDanglingSymbol( m_gal, pos, color );
// Draw the labels // Draw the labels
@ -1125,11 +1123,27 @@ static void orientComponent( LIB_PART *part, int orientation )
void SCH_PAINTER::draw( SCH_COMPONENT *aComp, int aLayer ) void SCH_PAINTER::draw( SCH_COMPONENT *aComp, int aLayer )
{ {
PART_SPTR part = aComp->GetPartRef().lock(); PART_SPTR partSptr = aComp->GetPartRef().lock();
// Use dummy part if the actual couldn't be found (or couldn't be locked). // Use dummy part if the actual couldn't be found (or couldn't be locked).
// In either case copy it so we can re-orient and translate it. LIB_PART* part = partSptr ? partSptr.get() : dummy();
std::unique_ptr<LIB_PART> temp( new LIB_PART( part ? *part.get() : *dummy() ) );
// Copy the source it so we can re-orient and translate it.
std::unique_ptr<LIB_PART> temp( new LIB_PART( *part ) );
// Update the pinMap to be indexed by the temp part's pins
LIB_PIN* libPin = part->GetNextPin();
LIB_PIN* tempPin = temp->GetNextPin();
SCH_PINS& pinMap = aComp->GetPinMap();
SCH_PINS tempPinMap;
while( libPin && tempPin )
{
if( pinMap.count( libPin ) )
tempPinMap.emplace( std::make_pair( tempPin, SCH_PIN( pinMap.at( libPin ) ) ) );
libPin = part->GetNextPin( libPin );
tempPin = temp->GetNextPin( tempPin );
}
if( aComp->IsMoving() ) if( aComp->IsMoving() )
temp->SetFlags( IS_MOVED ); temp->SetFlags( IS_MOVED );
@ -1144,20 +1158,9 @@ void SCH_PAINTER::draw( SCH_COMPONENT *aComp, int aLayer )
auto rp = aComp->GetPosition(); auto rp = aComp->GetPosition();
auto ip = item.GetPosition(); auto ip = item.GetPosition();
item.Move( wxPoint( rp.x + ip.x, ip.y - rp.y ) ); item.Move( wxPoint( rp.x + ip.x, ip.y - rp.y ) );
if( item.Type() == LIB_PIN_T )
{
auto pin = static_cast<LIB_PIN*>( &item );
if( aComp->IsPinBrightened( pin ) )
pin->SetFlags( BRIGHTENED );
else if( aComp->IsPinHighlighted( pin ) )
pin->SetFlags( HIGHLIGHTED );
}
} }
draw( temp.get(), aLayer, false, draw( temp.get(), aLayer, false, aComp->GetUnit(), aComp->GetConvert(), &tempPinMap );
aComp->GetUnit(), aComp->GetConvert(), aComp->GetDanglingPinFlags() );
// The fields are SCH_COMPONENT-specific and so don't need to be copied/ // The fields are SCH_COMPONENT-specific and so don't need to be copied/
// oriented/translated. // oriented/translated.

View File

@ -25,8 +25,11 @@
#ifndef __SCH_PAINTER_H #ifndef __SCH_PAINTER_H
#define __SCH_PAINTER_H #define __SCH_PAINTER_H
#include <sch_component.h>
#include <painter.h> #include <painter.h>
class LIB_RECTANGLE; class LIB_RECTANGLE;
class LIB_PIN; class LIB_PIN;
class LIB_CIRCLE; class LIB_CIRCLE;
@ -132,11 +135,11 @@ public:
private: private:
void draw( LIB_RECTANGLE* aRect, int aLayer ); void draw( LIB_RECTANGLE* aRect, int aLayer );
void draw( LIB_PIN* aPin, int aLayer, bool aIsDangling = true, bool isMoving = false ); void draw( LIB_PIN* aPin, int aLayer, SCH_PIN* aSchPin = nullptr, bool isParentMoving = false );
void draw( LIB_CIRCLE* aCircle, int aLayer ); void draw( LIB_CIRCLE* aCircle, int aLayer );
void draw( LIB_ITEM *, int aLayer ); void draw( LIB_ITEM *, int aLayer );
void draw( LIB_PART* aComp, int, bool aDrawFields = true, int aUnit = 0, int aConvert = 0, void draw( LIB_PART* aPart, int, bool aDrawFields = true, int aUnit = 0, int aConvert = 0,
std::vector<bool>* aDanglingPinFlags = nullptr ); SCH_PINS* aPinMap = nullptr );
void draw( LIB_ALIAS* aAlias, int aLayer ); void draw( LIB_ALIAS* aAlias, int aLayer );
void draw( LIB_ARC* aArc, int aLayer ); void draw( LIB_ARC* aArc, int aLayer );
void draw( LIB_POLYLINE* aLine, int aLayer ); void draw( LIB_POLYLINE* aLine, int aLayer );

View File

@ -20,22 +20,36 @@
#include <lib_pin.h> #include <lib_pin.h>
#include <sch_component.h> #include <sch_component.h>
#include <sch_pin_connection.h> #include <sch_pin.h>
#include <sch_sheet_path.h> #include <sch_sheet_path.h>
SCH_PIN_CONNECTION::SCH_PIN_CONNECTION( EDA_ITEM* aParent ) : SCH_PIN::SCH_PIN( LIB_PIN* aLibPin, SCH_COMPONENT* aParentComponent ) :
SCH_ITEM( aParent, SCH_PIN_CONNECTION_T ) SCH_ITEM( nullptr, SCH_PIN_T ),
m_pin( aLibPin ),
m_comp( aParentComponent )
{ {
SetPosition( aLibPin->GetPosition() );
m_isDangling = true;
} }
wxString SCH_PIN_CONNECTION::GetSelectMenuText( EDA_UNITS_T aUnits ) const SCH_PIN::SCH_PIN( const SCH_PIN& aPin ) :
SCH_ITEM( aPin )
{
m_pin = aPin.m_pin;
m_comp = aPin.m_comp;
m_position = aPin.m_position;
m_isDangling = aPin.m_isDangling;
}
wxString SCH_PIN::GetSelectMenuText( EDA_UNITS_T aUnits ) const
{ {
wxString tmp; wxString tmp;
#ifdef DEBUG #ifdef DEBUG
tmp.Printf( _( "SCH_PIN_CONNECTION for %s %s" ), tmp.Printf( _( "SCH_PIN for %s %s" ),
GetChars( m_comp->GetSelectMenuText( aUnits ) ), GetChars( m_comp->GetSelectMenuText( aUnits ) ),
GetChars( m_pin->GetSelectMenuText( aUnits ) ) ); GetChars( m_pin->GetSelectMenuText( aUnits ) ) );
#else #else
@ -48,7 +62,7 @@ wxString SCH_PIN_CONNECTION::GetSelectMenuText( EDA_UNITS_T aUnits ) const
} }
wxString SCH_PIN_CONNECTION::GetDefaultNetName( const SCH_SHEET_PATH aPath ) wxString SCH_PIN::GetDefaultNetName( const SCH_SHEET_PATH aPath )
{ {
if( m_pin->IsPowerConnection() ) if( m_pin->IsPowerConnection() )
return m_pin->GetName(); return m_pin->GetName();
@ -72,10 +86,3 @@ wxString SCH_PIN_CONNECTION::GetDefaultNetName( const SCH_SHEET_PATH aPath )
} }
wxPoint SCH_PIN_CONNECTION::GetPosition() const
{
auto pos = m_comp->GetPosition();
auto transform = m_comp->GetTransform();
return pos + transform.TransformCoordinate( m_pin->GetPosition() );
}

View File

@ -28,27 +28,38 @@
class SCH_COMPONENT; class SCH_COMPONENT;
/** class SCH_PIN : public SCH_ITEM
* Container to describe the net connectivity of a specific pin on a component.
*/
class SCH_PIN_CONNECTION : public SCH_ITEM
{ {
LIB_PIN* m_pin;
SCH_COMPONENT* m_comp;
wxPoint m_position;
bool m_isDangling;
/// The name that this pin connection will drive onto a net
std::map<const SCH_SHEET_PATH, wxString> m_net_name_map;
public: public:
SCH_PIN_CONNECTION( EDA_ITEM* aParent = nullptr ); SCH_PIN( LIB_PIN* aLibPin, SCH_COMPONENT* aParentComponent );
SCH_PIN( const SCH_PIN& aPin );
wxString GetClass() const override wxString GetClass() const override
{ {
return wxT( "SCH_PIN_CONNECTION" ); return wxT( "SCH_PIN" );
} }
LIB_PIN* GetLibPin() const { return m_pin; }
SCH_COMPONENT* GetParentComponent() const { return m_comp; }
void SetParentComponent( SCH_COMPONENT* aComp ) { m_comp = aComp; }
wxString GetDefaultNetName( const SCH_SHEET_PATH aPath ); wxString GetDefaultNetName( const SCH_SHEET_PATH aPath );
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
GR_DRAWMODE aDrawMode, COLOR4D aColor = COLOR4D::UNSPECIFIED ) override GR_DRAWMODE aDrawMode, COLOR4D aColor = COLOR4D::UNSPECIFIED ) override {}
{
}
void Move( const wxPoint& aMoveVector ) override {} void Move( const wxPoint& aMoveVector ) override {}
@ -58,20 +69,33 @@ public:
void Rotate( wxPoint aPosition ) override {} void Rotate( wxPoint aPosition ) override {}
wxPoint GetPosition() const override; wxPoint GetPosition() const override { return m_position; }
void SetPosition( const wxPoint& aPosition ) override { m_position = aPosition; }
bool IsDangling() const override { return m_isDangling; }
void SetIsDangling( bool isDangling ) { m_isDangling = isDangling; }
/*
* While many of these are currently simply covers for the equivalent LIB_PIN methods,
* the new EESchema file format will soon allow us to override them at the SCH level.
*/
bool IsVisible() const { return m_pin->IsVisible(); }
const wxString& GetName() const { return m_pin->GetName(); }
const wxString& GetNumber() const { return m_pin->GetNumber(); }
ELECTRICAL_PINTYPE GetType() const { return m_pin->GetType(); }
bool IsPowerConnection() const { return m_pin->IsPowerConnection(); }
void SetPosition( const wxPoint& aPosition ) override {}
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const override {} void Show( int nestLevel, std::ostream& os ) const override {}
#endif #endif
LIB_PIN* m_pin;
SCH_COMPONENT* m_comp;
/// The name that this pin connection will drive onto a net
std::map<const SCH_SHEET_PATH, wxString> m_net_name_map;
}; };
#endif #endif

View File

@ -121,7 +121,7 @@ enum KICAD_T
SCH_COMPONENT_T, SCH_COMPONENT_T,
SCH_SHEET_PIN_T, SCH_SHEET_PIN_T,
SCH_SHEET_T, SCH_SHEET_T,
SCH_PIN_CONNECTION_T, SCH_PIN_T,
// Be prudent with these 3 types: // Be prudent with these 3 types:
// they should be used only to locate a specific field type // they should be used only to locate a specific field type