diff --git a/include/hashtables.h b/include/hashtables.h index edb3f798e0..ed319ec64c 100644 --- a/include/hashtables.h +++ b/include/hashtables.h @@ -98,6 +98,24 @@ struct fnv_1a }; +/// Hash function for wxString, counterpart of std::string hash +struct WXSTRING_HASH : std::unary_function +{ + std::size_t operator()( const wxString& aString ) const + { + std::size_t hash = 2166136261u; + + for( wxString::const_iterator it = aString.begin(); it != aString.end(); ++it ) + { + hash ^= (unsigned char) *it; + hash *= 16777619; + } + + return hash; + } +}; + + /** * Type KEYWORD_MAP * is a hashtable made of a const char* and an int. Note that use of this diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index a56c226d63..214e78f5de 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1355,79 +1355,7 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const { - // the first valid netcode is 1. - // zero is reserved for "no connection" and is not used. - if( aNetname.IsEmpty() ) - return NULL; - - int ncount = m_NetInfo.GetNetCount(); - - // Search for a netname = aNetname -#if 0 - - // Use a sequential search: easy to understand, but slow - for( int ii = 1; ii < ncount; ii++ ) - { - NETINFO_ITEM* item = m_NetInfo.GetNetItem( ii ); - - if( item && item->GetNetname() == aNetname ) - { - return item; - } - } - -#else - - // Use a fast binary search, - // this is possible because Nets are alphabetically ordered in list - // see NETINFO_LIST::BuildListOfNets() and - // NETINFO_LIST::Build_Pads_Full_List() - int imax = ncount - 1; - int index = imax; - - while( ncount > 0 ) - { - int ii = ncount; - ncount >>= 1; - - if( (ii & 1) && ( ii > 1 ) ) - ncount++; - - NETINFO_ITEM* item = m_NetInfo.GetNetItem( index ); - - if( item == NULL ) - return NULL; - - int icmp = item->GetNetname().Cmp( aNetname ); - - if( icmp == 0 ) // found ! - { - return item; - } - - if( icmp < 0 ) // must search after item - { - index += ncount; - - if( index > imax ) - index = imax; - - continue; - } - - if( icmp > 0 ) // must search before item - { - index -= ncount; - - if( index < 1 ) - index = 1; - - continue; - } - } - -#endif - return NULL; + return m_NetInfo.GetNetItem( aNetname ); } @@ -2618,7 +2546,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, } if( !aNetlist.IsDryRun() ) + { pad->SetNetname( wxEmptyString ); + pad->SetNet( 0 ); + } } } else // Footprint pad has a net. @@ -2638,7 +2569,19 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, } if( !aNetlist.IsDryRun() ) + { pad->SetNetname( net.GetNetName() ); + + NETINFO_ITEM* netinfo = FindNet( net.GetNetName() ); + if( netinfo == NULL ) + { + // It is a new net, we have to add it + netinfo = new NETINFO_ITEM( this, net.GetNetName(), m_NetInfo.GetNetCount() ); + m_NetInfo.AppendNet( netinfo ); + } + + pad->SetNet( netinfo->GetNet() ); + } } } } @@ -2711,6 +2654,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, aReporter->Report( msg ); } previouspad->SetNetname( wxEmptyString ); + previouspad->SetNet( 0 ); } netname = pad->GetNetname(); count = 1; @@ -2723,7 +2667,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, // Examine last pad if( pad && count == 1 ) + { pad->SetNetname( wxEmptyString ); + pad->SetNet( 0 ); + } } // Last step: Some tests: diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index a3c1807e14..c0e81a684e 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -37,6 +37,8 @@ #include #include #include +#include +#include class wxDC; @@ -115,7 +117,6 @@ public: }; - /** * Class NETINFO * is a container class for NETINFO_ITEM elements, which are the nets. That makes @@ -141,6 +142,20 @@ public: return m_NetBuffer[aNetcode]; } + /** + * Function GetItem + * @param aNetName = net name to identify a given NETINFO_ITEM + * @return NETINFO_ITEM* - by \a aNetName, or NULL if not found + */ + NETINFO_ITEM* GetNetItem( const wxString& aNetName ) const + { + NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName ); + if( result != m_netNames.end() ) + return (*result).second; + + return NULL; + } + /** * Function GetNetCount * @return the number of nets ( always >= 1 ) @@ -188,6 +203,8 @@ public: void Show() const; #endif + typedef boost::unordered_map NETNAMES_MAP; + private: /** @@ -214,6 +231,7 @@ private: void buildPadsFullList(); BOARD* m_Parent; + NETNAMES_MAP m_netNames; ///< map for a fast look up by net names std::vector m_NetBuffer; ///< net list (name, design constraints ..) std::vector m_PadsFullList; ///< contains all pads, sorted by pad's netname. @@ -394,15 +412,15 @@ public: /** * Function GetNetname - * @return const wxString * , a pointer to the full netname + * @return const wxString&, a reference to the full netname */ - wxString GetNetname() const { return m_Netname; } + const wxString& GetNetname() const { return m_Netname; } /** * Function GetShortNetname - * @return const wxString * , a pointer to the short netname + * @return const wxString &, a reference to the short netname */ - wxString GetShortNetname() const { return m_ShortNetname; } + const wxString& GetShortNetname() const { return m_ShortNetname; } /** * Function GetMsgPanelInfo diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index 75bad023a2..561e845e21 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -15,9 +15,10 @@ // Constructor and destructor -NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) +NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) : m_Parent( aParent ) { - m_Parent = aParent; + // Make sure that the unconnected net has number 0 + AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) ); } @@ -34,14 +35,20 @@ void NETINFO_LIST::clear() m_NetBuffer.clear(); m_PadsFullList.clear(); + m_netNames.clear(); } void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement ) { + // net names & codes are supposed to be unique + assert( GetNetItem( aNewElement->GetNetname() ) == NULL ); + assert( GetNetItem( aNewElement->GetNet() ) == NULL ); + m_NetBuffer.push_back( aNewElement ); - // D(Show();) + // add an entry for fast look up by a net name using a map + m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) ); } @@ -74,18 +81,13 @@ void NETINFO_LIST::buildListOfNets() { D_PAD* pad; int nodes_count = 0; - NETINFO_ITEM* net_item; // Build the PAD list, sorted by net buildPadsFullList(); // Restore the initial state of NETINFO_ITEMs for( unsigned i = 0; i < GetNetCount(); ++i ) - { GetNetItem( i )->Clear(); - } - - std::cout << m_PadsFullList.size() << std::endl; // Assign pads to appropriate NETINFO_ITEMs for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ ) @@ -95,8 +97,8 @@ void NETINFO_LIST::buildListOfNets() if( pad->GetNet() == 0 ) // pad not connected continue; - net_item = GetNetItem( pad->GetNet() ); - net_item->m_PadInNetList.push_back( pad ); + // Add pad to the appropriate list of pads + GetNetItem( pad->GetNet() )->m_PadInNetList.push_back( pad ); ++nodes_count; } diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index f984e4aa9b..2b707ead14 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -413,6 +413,7 @@ void D_PAD::CopyNetlistSettings( D_PAD* aPad ) wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) ); aPad->SetNetname( GetNetname() ); + aPad->SetNet( GetNet() ); aPad->SetLocalClearance( m_LocalClearance ); aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin ); diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 5a385ea917..3c0b567c28 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -128,7 +128,13 @@ public: * Function GetNetname * @return const wxString& - the full netname */ - const wxString& GetNetname() const { return m_Netname; } + const wxString& GetNetname() const + { + assert( ( GetNet() == 0 ) == m_Netname.IsEmpty() ); + // assert( GetBoard()->FindNet( GetNet() ) == GetBoard()->FindNet( m_Netname ) ); + + return m_Netname; + } /** * Function GetShortNetname diff --git a/pcbnew/pad_edition_functions.cpp b/pcbnew/pad_edition_functions.cpp index b99bd1580a..3e890af710 100644 --- a/pcbnew/pad_edition_functions.cpp +++ b/pcbnew/pad_edition_functions.cpp @@ -142,6 +142,7 @@ void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw ) // Update the pad properties. Import_Pad_Settings( pad, false ); pad->SetNetname( wxEmptyString ); + pad->SetNet( 0 ); pad->SetPosition( GetCrossHairPosition() ); diff --git a/pcbnew/pcb_netlist.h b/pcbnew/pcb_netlist.h index ff9544e10f..58ab9bf17d 100644 --- a/pcbnew/pcb_netlist.h +++ b/pcbnew/pcb_netlist.h @@ -47,16 +47,14 @@ class REPORTER; class COMPONENT_NET { wxString m_pinName; - wxString m_netNumber; wxString m_netName; public: COMPONENT_NET() {} - COMPONENT_NET( const wxString& aPinName, const wxString& aNetName ) + COMPONENT_NET( const wxString& aPinName, const wxString& aNetName ) : + m_pinName( aPinName ), m_netName( aNetName ) { - m_pinName = aPinName; - m_netName = aNetName; } const wxString& GetPinName() const { return m_pinName; }