diff --git a/eeschema/connection_graph.cpp b/eeschema/connection_graph.cpp index 6d27f3c136..8a70972675 100644 --- a/eeschema/connection_graph.cpp +++ b/eeschema/connection_graph.cpp @@ -110,9 +110,9 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers ) // We have multiple options, and they are all hierarchical // sheet pins. Let's prefer outputs over inputs. - for( auto c : candidates ) + for( SCH_ITEM* c : candidates ) { - auto p = static_cast( c ); + SCH_SHEET_PIN* p = static_cast( c ); if( p->GetShape() == PINSHEETLABEL_SHAPE::PS_OUTPUT ) { @@ -123,6 +123,21 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers ) } else { + // See if a previous driver is still a candidate + void* previousDriver = nullptr; + + for( SCH_ITEM* member : m_items ) + { + if( SCH_CONNECTION* mc = member->Connection( &m_sheet ) ) + { + if( mc->GetLastDriver() ) + { + previousDriver = mc->GetLastDriver(); + break; + } + } + } + // For all other driver types, sort by name std::sort( candidates.begin(), candidates.end(), [&]( SCH_ITEM* a, SCH_ITEM* b ) -> bool @@ -134,7 +149,12 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers ) if( ac->IsBus() && bc->IsBus() ) return bc->IsSubsetOf( ac ); - return GetNameForDriver( a ) < GetNameForDriver( b ); + if( a == previousDriver ) + return true; + else if( b == previousDriver ) + return false; + else + return GetNameForDriver( a ) < GetNameForDriver( b ); } ); } } @@ -750,7 +770,7 @@ void CONNECTION_GRAPH::buildConnectionGraph() * you regenerate. * * Right now, we are clearing out the old connections up in - * UpdateItemConnectivity(), but that is useful information, so maybe we + * updateItemConnectivity(), but that is useful information, so maybe we * need to just set the dirty flag or something. * * That way, ResolveDrivers() can check what the driver of the subgraph was diff --git a/eeschema/sch_connection.cpp b/eeschema/sch_connection.cpp index 211ce00f4c..7a51ab3794 100644 --- a/eeschema/sch_connection.cpp +++ b/eeschema/sch_connection.cpp @@ -98,7 +98,7 @@ void SCH_CONNECTION::SetDriver( SCH_ITEM* aItem ) recacheName(); - for( const auto& member : m_members ) + for( const std::shared_ptr& member : m_members ) member->SetDriver( aItem ); } @@ -109,7 +109,7 @@ void SCH_CONNECTION::SetSheet( SCH_SHEET_PATH aSheet ) recacheName(); - for( const auto& member : m_members ) + for( const std::shared_ptr& member : m_members ) member->SetSheet( aSheet ); } @@ -203,6 +203,7 @@ void SCH_CONNECTION::Reset() m_prefix.Empty(); m_bus_prefix.Empty(); m_suffix .Empty(); + m_lastDriver = m_driver; m_driver = nullptr; m_members.clear(); m_dirty = true; @@ -220,6 +221,7 @@ void SCH_CONNECTION::Clone( SCH_CONNECTION& aOther ) { m_graph = aOther.m_graph; m_type = aOther.Type(); + m_lastDriver = aOther.GetLastDriver(); m_driver = aOther.Driver(); m_sheet = aOther.Sheet(); m_name = aOther.m_name; @@ -270,6 +272,19 @@ bool SCH_CONNECTION::IsDriver() const } +bool SCH_CONNECTION::HasDriverChanged() const +{ + return m_driver != m_lastDriver; +} + + +void SCH_CONNECTION::ClearDriverChanged() +{ + m_lastDriver = m_driver; +} + + + wxString SCH_CONNECTION::Name( bool aIgnoreSheet ) const { wxASSERT( !m_cached_name.IsEmpty() ); diff --git a/eeschema/sch_connection.h b/eeschema/sch_connection.h index 620cd59aad..f407093085 100644 --- a/eeschema/sch_connection.h +++ b/eeschema/sch_connection.h @@ -101,23 +101,12 @@ public: */ void Clone( SCH_CONNECTION& aOther ); - SCH_ITEM* Parent() const - { - return m_parent; - } - - SCH_ITEM* Driver() const - { - return m_driver; - } - - SCH_SHEET_PATH Sheet() const - { - return m_sheet; - } + SCH_ITEM* Parent() const { return m_parent; } + SCH_ITEM* Driver() const { return m_driver; } void SetDriver( SCH_ITEM* aItem ); + SCH_SHEET_PATH Sheet() const { return m_sheet; } void SetSheet( SCH_SHEET_PATH aSheet ); /** @@ -138,28 +127,16 @@ public: return ( m_type == CONNECTION_TYPE::NET ); } - bool IsDirty() const - { - return m_dirty; - } + bool IsDirty() const { return m_dirty; } + void SetDirty() { m_dirty = true; } + void ClearDirty() { m_dirty = false; } - void SetDirty() - { - m_dirty = true; - } - - void ClearDirty() - { - m_dirty = false; - } + bool HasDriverChanged() const; + void ClearDriverChanged(); + void* GetLastDriver() const { return m_lastDriver; } wxString Name( bool aIgnoreSheet = false ) const; - const wxString& RawName() const - { - return m_name; - } - wxString LocalName() const { return m_local_name; } wxString FullLocalName() const @@ -173,29 +150,15 @@ public: recacheName(); } - wxString Prefix() const - { - return m_prefix; - } - - wxString BusPrefix() const - { - return m_bus_prefix; - } - - wxString Suffix() const - { - return m_suffix; - } - + wxString Prefix() const { return m_prefix; } void SetPrefix( const wxString& aPrefix ); + wxString BusPrefix() const { return m_bus_prefix; } + + wxString Suffix() const { return m_suffix; } void SetSuffix( const wxString& aSuffix ); - CONNECTION_TYPE Type() const - { - return m_type; - } + CONNECTION_TYPE Type() const { return m_type; } void SetType( CONNECTION_TYPE aType ) { @@ -203,55 +166,21 @@ public: recacheName(); } - int NetCode() const - { - return m_net_code; - } + int NetCode() const { return m_net_code; } + void SetNetCode( int aCode ) { m_net_code = aCode; } - void SetNetCode( int aCode ) - { - m_net_code = aCode; - } + int BusCode() const { return m_bus_code; } + void SetBusCode( int aCode ) { m_bus_code = aCode; } - int BusCode() const - { - return m_bus_code; - } + int SubgraphCode() const { return m_subgraph_code; } + void SetSubgraphCode( int aCode ) { m_subgraph_code = aCode; } - void SetBusCode( int aCode ) - { - m_bus_code = aCode; - } + long VectorStart() const { return m_vector_start; } + long VectorEnd() const { return m_vector_end; } - int SubgraphCode() const - { - return m_subgraph_code; - } + long VectorIndex() const { return m_vector_index; } - void SetSubgraphCode( int aCode ) - { - m_subgraph_code = aCode; - } - - long VectorStart() const - { - return m_vector_start; - } - - long VectorEnd() const - { - return m_vector_end; - } - - long VectorIndex() const - { - return m_vector_index; - } - - wxString VectorPrefix() const - { - return m_vector_prefix; - } + wxString VectorPrefix() const { return m_vector_prefix; } std::vector< std::shared_ptr< SCH_CONNECTION > >& Members() { @@ -311,6 +240,9 @@ private: SCH_ITEM* m_parent; ///< The SCH_ITEM this connection is owned by + void* m_lastDriver; ///< WEAK POINTER (there is no guarantee it is still allocated) + ///< Equality comparisons are OK, but that's pretty much it + SCH_ITEM* m_driver; ///< The SCH_ITEM that drives this connection's net CONNECTION_TYPE m_type; ///< @see enum CONNECTION_TYPE diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 23b4122f2b..b1f7ee82e9 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -714,6 +715,21 @@ void SCH_EDIT_FRAME::OnModify() if( ADVANCED_CFG::GetCfg().m_realTimeConnectivity && CONNECTION_GRAPH::m_allowRealTime ) RecalculateConnections( NO_CLEANUP ); + GetCanvas()->GetView()->UpdateAllItemsConditionally( KIGFX::REPAINT, + []( KIGFX::VIEW_ITEM* aItem ) + { + SCH_ITEM* item = dynamic_cast( aItem ); + SCH_CONNECTION* connection = item ? item->Connection() : nullptr; + + if( connection && connection->HasDriverChanged() ) + { + connection->ClearDriverChanged(); + return true; + } + + return false; + } ); + GetCanvas()->Refresh(); }