From 5e2cf51309a45d77a8ee11a394df5f73baaa2156 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 22 Apr 2019 11:14:47 +0100 Subject: [PATCH] Improve robustness of SCH_PIN storage architecture. In particular, allow short-term storage of pointers to SCH_PINs. --- eeschema/connection_graph.cpp | 24 ++++--- eeschema/sch_component.cpp | 121 ++++++++++++++++------------------ eeschema/sch_component.h | 21 +++--- eeschema/sch_painter.cpp | 29 ++++---- eeschema/sch_pin.cpp | 86 +++++++++++++++++------- eeschema/sch_pin.h | 28 ++++---- 6 files changed, 163 insertions(+), 146 deletions(-) diff --git a/eeschema/connection_graph.cpp b/eeschema/connection_graph.cpp index b2a2e96bea..f9fe24e883 100644 --- a/eeschema/connection_graph.cpp +++ b/eeschema/connection_graph.cpp @@ -432,27 +432,26 @@ void CONNECTION_GRAPH::updateItemConnectivity( SCH_SHEET_PATH aSheet, } else if( item->Type() == SCH_COMPONENT_T ) { - auto component = static_cast( item ); + SCH_COMPONENT* component = static_cast( item ); + TRANSFORM t = component->GetTransform(); component->UpdatePins( &aSheet ); - for( auto& it : component->GetPinMap() ) + for( SCH_PIN& pin : component->GetPins() ) { - SCH_PIN* pin = &it.second; - - wxPoint pos = pin->GetTransformedPosition(); + wxPoint pos = t.TransformCoordinate( pin.GetPosition() ) + component->GetPosition(); // because calling the first time is not thread-safe - pin->GetDefaultNetName( aSheet ); - pin->ConnectedItems().clear(); + pin.GetDefaultNetName( aSheet ); + pin.ConnectedItems().clear(); // Invisible power pins need to be post-processed later - if( pin->IsPowerConnection() && !pin->IsVisible() ) - m_invisible_power_pins.push_back( std::make_pair( aSheet, pin ) ); + if( pin.IsPowerConnection() && !pin.IsVisible() ) + m_invisible_power_pins.push_back( std::make_pair( aSheet, &pin ) ); - connection_map[ pos ].push_back( pin ); - m_items.insert( pin ); + connection_map[ pos ].push_back( &pin ); + m_items.insert( &pin ); } } else @@ -464,8 +463,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( SCH_SHEET_PATH aSheet, switch( item->Type() ) { case SCH_LINE_T: - conn->SetType( ( item->GetLayer() == LAYER_BUS ) ? - CONNECTION_BUS : CONNECTION_NET ); + conn->SetType( item->GetLayer() == LAYER_BUS ? CONNECTION_BUS : CONNECTION_NET ); break; case SCH_BUS_BUS_ENTRY_T: diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index 0fa40ef1b7..6039f5aa43 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -22,11 +22,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -/** - * @file sch_component.cpp - * @brief Implementation of the class SCH_COMPONENT. - */ - #include #include #include @@ -175,16 +170,17 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) : m_Fields = aComponent.m_Fields; // Re-parent the fields, which before this had aComponent as parent - for( int i = 0; i < GetFieldCount(); ++i ) - { - GetField( i )->SetParent( this ); - } + for( SCH_FIELD field : m_Fields ) + field.SetParent( this ); - // Copy the pins, and re-parent them - for( const auto& it : aComponent.m_pins ) + m_pins = aComponent.m_pins; + m_pinMap.clear(); + + // Re-parent the pins and build the pinMap + for( SCH_PIN pin : m_pins ) { - m_pins.emplace( std::make_pair( it.first, it.second ) ); - m_pins.at( it.first ).SetParentComponent( this ); + pin.SetParent( this ); + m_pinMap[ pin.GetLibPin() ] = &pin; } m_fieldsAutoplaced = aComponent.m_fieldsAutoplaced; @@ -428,10 +424,8 @@ void SCH_COMPONENT::UpdatePins( SCH_SHEET_PATH* aSheet ) { if( PART_SPTR part = m_part.lock() ) { - std::set stalePins; - - for( auto& it : m_pins ) - stalePins.insert( it.first ); + m_pinMap.clear(); + int i = 0; for( LIB_PIN* libPin = part->GetNextPin(); libPin; libPin = part->GetNextPin( libPin ) ) { @@ -443,25 +437,29 @@ void SCH_COMPONENT::UpdatePins( SCH_SHEET_PATH* aSheet ) if( libPin->GetConvert() && m_convert && ( m_convert != libPin->GetConvert() ) ) continue; - if( !m_pins.count( libPin ) ) - m_pins.emplace( std::make_pair( libPin, SCH_PIN( libPin, this ) ) ); + if( m_pins.size() <= i || m_pins[ i ].GetLibPin() != libPin ) + { + if( m_pins.size() > i ) + m_pins.erase( m_pins.begin() + i, m_pins.end() ); + + m_pins.emplace_back( SCH_PIN( libPin, this ) ); + } + + m_pinMap[ libPin ] = &m_pins[ i ]; if( aSheet ) - m_pins.at( libPin ).InitializeConnection( *aSheet ); + m_pins[ i ].InitializeConnection( *aSheet ); - stalePins.erase( libPin ); + ++i; } - - for( auto& stalePin : stalePins ) - m_pins.erase( stalePin ); } } SCH_CONNECTION* SCH_COMPONENT::GetConnectionForPin( LIB_PIN* aPin, const SCH_SHEET_PATH& aSheet ) { - if( m_pins.count( aPin ) ) - return m_pins.at( aPin ).Connection( aSheet ); + if( m_pinMap.count( aPin ) ) + return m_pinMap.at( aPin )->Connection( aSheet ); return nullptr; } @@ -929,12 +927,6 @@ void SCH_COMPONENT::GetPins( std::vector& aPinsList ) } -SCH_PINS& SCH_COMPONENT::GetPinMap() -{ - return m_pins; -} - - void SCH_COMPONENT::SwapData( SCH_ITEM* aItem ) { wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_COMPONENT_T), @@ -1474,12 +1466,12 @@ bool SCH_COMPONENT::UpdateDanglingState( std::vector& aItemLi { bool changed = false; - for( auto& it : m_pins ) + for( SCH_PIN& pin : m_pins ) { - bool previousState = it.second.IsDangling(); - it.second.SetIsDangling( true ); + bool previousState = pin.IsDangling(); + pin.SetIsDangling( true ); - wxPoint pos = m_transform.TransformCoordinate( it.second.GetPosition() ) + m_Pos; + wxPoint pos = m_transform.TransformCoordinate( pin.GetPosition() ) + m_Pos; for( DANGLING_END_ITEM& each_item : aItemList ) { @@ -1501,7 +1493,7 @@ bool SCH_COMPONENT::UpdateDanglingState( std::vector& aItemLi case JUNCTION_END: if( pos == each_item.GetPosition() ) - it.second.SetIsDangling( false ); + pin.SetIsDangling( false ); break; @@ -1509,11 +1501,11 @@ bool SCH_COMPONENT::UpdateDanglingState( std::vector& aItemLi break; } - if( !it.second.IsDangling() ) + if( !pin.IsDangling() ) break; } - changed = ( changed || ( previousState != it.second.IsDangling() ) ); + changed = ( changed || ( previousState != pin.IsDangling() ) ); } return changed; @@ -1546,8 +1538,8 @@ bool SCH_COMPONENT::IsSelectStateChanged( const wxRect& aRect ) void SCH_COMPONENT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const { - for( auto& it : m_pins ) - aPoints.push_back( m_transform.TransformCoordinate( it.second.GetPosition() ) + m_Pos ); + for( const SCH_PIN& pin : m_pins ) + aPoints.push_back( m_transform.TransformCoordinate( pin.GetPosition() ) + m_Pos ); } @@ -1757,19 +1749,20 @@ SCH_ITEM& SCH_COMPONENT::operator=( const SCH_ITEM& aItem ) m_PathsAndReferences = c->m_PathsAndReferences; - m_Fields = c->m_Fields; // std::vector's assignment operator. + m_Fields = c->m_Fields; // std::vector's assignment operator // Reparent fields after assignment to new component. - for( int ii = 0; ii < GetFieldCount(); ++ii ) - { - GetField( ii )->SetParent( this ); - } + for( SCH_FIELD field : m_Fields ) + field.SetParent( this ); - // Copy the pins, and re-parent them - for( const auto& it : c->m_pins ) + m_pins = c->m_pins; // std::vector's assignment operator + m_pinMap.clear(); + + // Re-parent the pins and build the pinMap + for( SCH_PIN pin : m_pins ) { - m_pins.emplace( std::make_pair( it.first, it.second ) ); - m_pins.at( it.first ).SetParentComponent( this ); + pin.SetParent( this ); + m_pinMap[ pin.GetLibPin() ] = &pin; } } @@ -1809,9 +1802,9 @@ bool SCH_COMPONENT::doIsConnected( const wxPoint& aPosition ) const { wxPoint new_pos = m_transform.InverseTransform().TransformCoordinate( aPosition - m_Pos ); - for( const auto& it : m_pins ) + for( const SCH_PIN& pin : m_pins ) { - if( it.second.GetPosition() == new_pos ) + if( pin.GetPosition() == new_pos ) return true; } @@ -1836,8 +1829,8 @@ void SCH_COMPONENT::Plot( PLOTTER* aPlotter ) part->Plot( aPlotter, GetUnit(), GetConvert(), m_Pos, temp ); - for( size_t i = 0; i < m_Fields.size(); i++ ) - m_Fields[i].Plot( aPlotter ); + for( SCH_FIELD field : m_Fields ) + field.Plot( aPlotter ); aPlotter->EndBlock( nullptr ); } @@ -1846,9 +1839,9 @@ void SCH_COMPONENT::Plot( PLOTTER* aPlotter ) bool SCH_COMPONENT::HasBrightenedPins() { - for( auto& it : m_pins ) + for( const SCH_PIN& pin : m_pins ) { - if( it.second.IsBrightened() ) + if( pin.IsBrightened() ) return true; } @@ -1858,29 +1851,29 @@ bool SCH_COMPONENT::HasBrightenedPins() void SCH_COMPONENT::ClearBrightenedPins() { - for( auto& it : m_pins ) - it.second.ClearBrightened(); + for( SCH_PIN& pin : m_pins ) + pin.ClearBrightened(); } void SCH_COMPONENT::BrightenPin( LIB_PIN* aPin ) { - if( m_pins.count( aPin ) ) - m_pins.at( aPin ).SetBrightened(); + if( m_pinMap.count( aPin ) ) + m_pinMap.at( aPin )->SetBrightened(); } void SCH_COMPONENT::ClearHighlightedPins() { - for( auto& it : m_pins ) - it.second.ClearHighlighted(); + for( SCH_PIN& pin : m_pins ) + pin.ClearHighlighted(); } void SCH_COMPONENT::HighlightPin( LIB_PIN* aPin ) { - if( m_pins.count( aPin ) ) - m_pins.at( aPin ).SetHighlighted(); + if( m_pinMap.count( aPin ) ) + m_pinMap.at( aPin )->SetHighlighted(); } diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index 9a102917fa..f4a33f4bc5 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -4,7 +4,7 @@ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com * Copyright (C) 2015 Wayne Stambaugh - * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -24,11 +24,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -/** - * @file sch_component.h - * @brief Definition the SCH_COMPONENT class for Eeschema. - */ - #ifndef COMPONENT_CLASS_H #define COMPONENT_CLASS_H @@ -56,7 +51,10 @@ class SYMBOL_LIB_TABLE; /// Pins, mapped by their corresponding LIB_PINs. -typedef std::unordered_map SCH_PINS; +typedef std::unordered_map SCH_PIN_MAP; + +/// A container for several SCH_PIN items +typedef std::vector SCH_PINS; /// A container for several SCH_FIELD items typedef std::vector SCH_FIELDS; @@ -96,7 +94,8 @@ private: PART_REF m_part; ///< points into the PROJECT's libraries to the LIB_PART for this component - SCH_PINS m_pins; + SCH_PINS m_pins; ///< the component's pins + SCH_PIN_MAP m_pinMap; ///< the component's pins mapped by LIB_PIN*. AUTOPLACED m_fieldsAutoplaced; ///< indicates status of field autoplacement @@ -461,11 +460,7 @@ public: */ void GetPins( std::vector& aPinsList ); - /** - * Return a map of library pins to their SCH_PIN equivalents. - * @return - */ - SCH_PINS& GetPinMap(); + SCH_PINS& GetPins() { return m_pins; } /** * Draw a component diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index ef777e31d2..ad531bb164 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -943,7 +943,7 @@ void SCH_PAINTER::draw( SCH_LINE *aLine, int aLayer ) VECTOR2D start = aLine->GetStartPoint(); VECTOR2D end = aLine->GetEndPoint(); - EDA_RECT clip( wxPoint( start.x, start.y ), wxSize( end.x - start.x, end.y - start.y ) ); + EDA_RECT clip( (wxPoint)start, wxSize( end.x - start.x, end.y - start.y ) ); clip.Normalize(); double theta = atan2( end.y - start.y, end.x - start.x ); @@ -1093,13 +1093,9 @@ void SCH_PAINTER::draw( SCH_COMPONENT *aComp, int aLayer ) // Use dummy part if the actual couldn't be found (or couldn't be locked). LIB_PART* originalPart = originalPartSptr ? originalPartSptr.get() : dummy(); - LIB_PINS originalPins; - originalPart->GetPins( originalPins, aComp->GetUnit(), aComp->GetConvert() ); // Copy the source so we can re-orient and translate it. LIB_PART tempPart( *originalPart ); - LIB_PINS tempPins; - tempPart.GetPins( tempPins, aComp->GetUnit(), aComp->GetConvert() ); tempPart.SetFlags( aComp->GetFlags() ); @@ -1108,24 +1104,21 @@ void SCH_PAINTER::draw( SCH_COMPONENT *aComp, int aLayer ) for( auto& tempItem : tempPart.GetDrawItems() ) tempItem.Move( tempItem.GetPosition() + (wxPoint) mapCoords( aComp->GetPosition() ) ); - // Copy pin info from the component - SCH_PINS pinMap = aComp->GetPinMap(); + // Copy the pin info from the component to the temp pins + LIB_PINS tempPins; + tempPart.GetPins( tempPins, aComp->GetUnit(), aComp->GetConvert() ); + const SCH_PINS& compPins = aComp->GetPins(); - for( unsigned i = 0; i < originalPins.size() && i < tempPins.size(); ++i ) + for( int i = 0; i < tempPins.size() && i < compPins.size(); ++ i ) { - LIB_PIN* originalPin = originalPins[ i ]; LIB_PIN* tempPin = tempPins[ i ]; + const SCH_PIN& compPin = compPins[ i ]; - if( pinMap.count( originalPin ) ) - { - const SCH_PIN& schPin = pinMap.at( originalPin ); + tempPin->ClearFlags(); + tempPin->SetFlags( compPin.GetFlags() ); // SELECTED, HIGHLIGHTED, BRIGHTENED - tempPin->ClearFlags(); - tempPin->SetFlags( schPin.GetFlags() ); // SELECTED, HIGHLIGHTED, BRIGHTENED - - if( schPin.IsDangling() ) - tempPin->SetFlags( IS_DANGLING ); - } + if( compPin.IsDangling() ) + tempPin->SetFlags( IS_DANGLING ); } draw( &tempPart, aLayer, false, aComp->GetUnit(), aComp->GetConvert() ); diff --git a/eeschema/sch_pin.cpp b/eeschema/sch_pin.cpp index 681621280e..62e5d48c6f 100644 --- a/eeschema/sch_pin.cpp +++ b/eeschema/sch_pin.cpp @@ -2,6 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2018 CERN + * Copyright (C) 2019 KiCad Developers, see change_log.txt for contributors. * @author Jon Evans * * This program is free software; you can redistribute it and/or @@ -25,9 +26,8 @@ SCH_PIN::SCH_PIN( LIB_PIN* aLibPin, SCH_COMPONENT* aParentComponent ) : - SCH_ITEM( nullptr, SCH_PIN_T ), - m_pin( aLibPin ), - m_comp( aParentComponent ) + SCH_ITEM( aParentComponent, SCH_PIN_T ), + m_libPin( aLibPin ) { SetPosition( aLibPin->GetPosition() ); m_isDangling = true; @@ -35,37 +35,48 @@ SCH_PIN::SCH_PIN( LIB_PIN* aLibPin, SCH_COMPONENT* aParentComponent ) : SCH_PIN::SCH_PIN( const SCH_PIN& aPin ) : - SCH_ITEM( aPin ) + SCH_ITEM( aPin ) { - m_pin = aPin.m_pin; - m_comp = aPin.m_comp; + m_libPin = aPin.m_libPin; m_position = aPin.m_position; m_isDangling = aPin.m_isDangling; } +SCH_PIN& SCH_PIN::operator=( const SCH_PIN& aPin ) +{ + SCH_ITEM::operator=( aPin ); + + m_libPin = aPin.m_libPin; + m_position = aPin.m_position; + m_isDangling = aPin.m_isDangling; +} + + +SCH_COMPONENT* SCH_PIN::GetParentComponent() const +{ + return static_cast( GetParent() ); +} + + wxString SCH_PIN::GetSelectMenuText( EDA_UNITS_T aUnits ) const { - wxString tmp; + return wxString::Format( "%s %s", + GetParentComponent()->GetSelectMenuText( aUnits ), + m_libPin->GetSelectMenuText( aUnits ) ); +} -#ifdef DEBUG - tmp.Printf( "SCH_PIN for %s %s", - m_comp->GetSelectMenuText( aUnits ), - m_pin->GetSelectMenuText( aUnits ) ); -#else - tmp.Printf( "%s %s", - m_comp->GetSelectMenuText( aUnits ), - m_pin->GetSelectMenuText( aUnits ) ); -#endif - return tmp; +void SCH_PIN::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList ) +{ + m_libPin->GetMsgPanelInfo( aUnits, aList, GetParentComponent() ); } wxString SCH_PIN::GetDefaultNetName( const SCH_SHEET_PATH aPath ) { - if( m_pin->IsPowerConnection() ) - return m_pin->GetName(); + if( m_libPin->IsPowerConnection() ) + return m_libPin->GetName(); std::lock_guard lock( m_netmap_mutex ); @@ -74,13 +85,13 @@ wxString SCH_PIN::GetDefaultNetName( const SCH_SHEET_PATH aPath ) wxString name = "Net-("; - name << m_comp->GetRef( &aPath ); + name << GetParentComponent()->GetRef( &aPath ); // TODO(JE) do we need adoptTimestamp? if( /* adoptTimestamp && */ name.Last() == '?' ) - name << m_comp->GetTimeStamp(); + name << GetParentComponent()->GetTimeStamp(); - name << "-Pad" << m_pin->GetNumber() << ")"; + name << "-Pad" << m_libPin->GetNumber() << ")"; m_net_name_map[ aPath ] = name; @@ -90,7 +101,32 @@ wxString SCH_PIN::GetDefaultNetName( const SCH_SHEET_PATH aPath ) wxPoint SCH_PIN::GetTransformedPosition() const { - auto t = m_comp->GetTransform(); - return ( t.TransformCoordinate( GetPosition() ) + - m_comp->GetPosition() ); + TRANSFORM t = GetParentComponent()->GetTransform(); + return ( t.TransformCoordinate( GetPosition() ) + GetParentComponent()->GetPosition() ); } + + +const EDA_RECT SCH_PIN::GetBoundingBox() const +{ + // Due to pins being relative to their component parent's position, this is unlikely + // to do what a caller wants. Use HitTest() directly instead. + wxFAIL_MSG( "SCH_PINs bounding box is relative to parent component" ); + + return m_libPin->GetBoundingBox(); +} + + +bool SCH_PIN::HitTest( const wxPoint& aPosition ) const +{ + // Pin hit testing is relative to the components position and orientation in the + // schematic. The hit test position must be converted to library coordinates. + TRANSFORM t = GetParentComponent()->GetTransform().InverseTransform(); + wxPoint pos = t.TransformCoordinate( aPosition - GetParentComponent()->GetPosition() ); + + pos.y *= -1; // Y axis polarity in schematic is inverted from library. + + return m_libPin->GetBoundingBox().Contains( pos ); +} + + + diff --git a/eeschema/sch_pin.h b/eeschema/sch_pin.h index d2a976db97..c83c2a8130 100644 --- a/eeschema/sch_pin.h +++ b/eeschema/sch_pin.h @@ -2,6 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2018 CERN + * Copyright (C) 2019 KiCad Developers, see change_log.txt for contributors. * @author Jon Evans * * This program is free software; you can redistribute it and/or @@ -33,8 +34,7 @@ class SCH_COMPONENT; class SCH_PIN : public SCH_ITEM { - LIB_PIN* m_pin; - SCH_COMPONENT* m_comp; + LIB_PIN* m_libPin; wxPoint m_position; bool m_isDangling; @@ -48,36 +48,38 @@ public: SCH_PIN( const SCH_PIN& aPin ); + SCH_PIN& operator=( const SCH_PIN& aPin ); + wxString GetClass() const override { return wxT( "SCH_PIN" ); } - LIB_PIN* GetLibPin() const { return m_pin; } + SCH_COMPONENT* GetParentComponent() const; - SCH_COMPONENT* GetParentComponent() const { return m_comp; } - void SetParentComponent( SCH_COMPONENT* aComp ) { m_comp = aComp; } + LIB_PIN* GetLibPin() const { return m_libPin; } wxString GetDefaultNetName( const SCH_SHEET_PATH aPath ); wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; + void GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList ) override; void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset ) override {} void Move( const wxPoint& aMoveVector ) override {} void MirrorY( int aYaxis_position ) override {} - void MirrorX( int aXaxis_position ) override {} void Rotate( wxPoint aPosition ) override {} wxPoint GetPosition() const override { return m_position; } - void SetPosition( const wxPoint& aPosition ) override { m_position = aPosition; } - bool IsDangling() const override { return m_isDangling; } + const EDA_RECT GetBoundingBox() const override; + bool HitTest( const wxPoint& aPosition ) const override; + bool IsDangling() const override { return m_isDangling; } void SetIsDangling( bool isDangling ) { m_isDangling = isDangling; } /// Returns the pin's position in global coordinates @@ -88,15 +90,15 @@ public: * 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(); } + bool IsVisible() const { return m_libPin->IsVisible(); } - const wxString& GetName() const { return m_pin->GetName(); } + const wxString& GetName() const { return m_libPin->GetName(); } - const wxString& GetNumber() const { return m_pin->GetNumber(); } + const wxString& GetNumber() const { return m_libPin->GetNumber(); } - ELECTRICAL_PINTYPE GetType() const { return m_pin->GetType(); } + ELECTRICAL_PINTYPE GetType() const { return m_libPin->GetType(); } - bool IsPowerConnection() const { return m_pin->IsPowerConnection(); } + bool IsPowerConnection() const { return m_libPin->IsPowerConnection(); } #if defined(DEBUG)