Commit bf80cc77 authored by Maciej Suminski's avatar Maciej Suminski

Changed the way of looking up NETINFO_ITEM using net names (using...

Changed the way of looking up NETINFO_ITEM using net names (using boost::unordered_map). Added a hash function (wxString) for that. Introduced NETINFO_ITEM::GetNetItem( wxString ). BOARD::FindNet() uses the map.
Net codes are updated upon net list update. (BOARD::ReplaceNetlist())
Added in some places (mostly class_board.cpp) pad->SetNet() calls to synchronize net codes.
On creation of NETINFO_LIST, the first NETINFO_ITEM is added (the unconnected items net).
Removed COMPONENT_NET::m_netNumber, as it was not used anywhere.
Added an assert to D_PAD::GetNetname(), checking if net code and net name is consistent for unconnected pads. Added an assert for NETINFO_LIST::AppendNet() to assure that appended nets are unique.

It seems that at this point:
- Updating net lists works fine. The only difference between the file ouput is that after changes it contains empty nets as well.
- Nets are not saved in the lexical order. Still, net names and net codes are properly assigned to all items in the .kicad_pcb file. It is going to be addressed in the next commit. I believe it should not create any problems, as pads are sorted by their net names anyway (NETINFO_LIST::buildPadsFullList())

Performed tests:
- Created a blank PCB, saved as pic_programmer.kicad_pcb (from demos folder). Updated net lists. .kicad_pcb file (comparing to the results from master branch) differ with net order (as mentioned before), net codes and timestamps.
- Removed some of components from the above .kicad_pcb file and updated net lists. Modules reappeared. .kicad_pcb file differs in the same way as described above.
- Trying to change a pad net name (via properties dialog) results in assert being fired. It is done on purpose (as there is a call to GetNetname() and net name and net code do not match). This will not happen after the next commit.
- Prepared a simple project (starting with schematics). Imported net list, changed schematic, reimported net list - changes are applied.
- Eagle & KiCad legacy boards seem to load without any problem.
parent 386d1fc2
...@@ -98,6 +98,24 @@ struct fnv_1a ...@@ -98,6 +98,24 @@ struct fnv_1a
}; };
/// Hash function for wxString, counterpart of std::string hash
struct WXSTRING_HASH : std::unary_function<wxString, std::size_t>
{
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 * Type KEYWORD_MAP
* is a hashtable made of a const char* and an int. Note that use of this * is a hashtable made of a const char* and an int. Note that use of this
......
...@@ -1355,79 +1355,7 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const ...@@ -1355,79 +1355,7 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
{ {
// the first valid netcode is 1. return m_NetInfo.GetNetItem( aNetname );
// 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;
} }
...@@ -2618,7 +2546,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, ...@@ -2618,7 +2546,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
} }
if( !aNetlist.IsDryRun() ) if( !aNetlist.IsDryRun() )
{
pad->SetNetname( wxEmptyString ); pad->SetNetname( wxEmptyString );
pad->SetNet( 0 );
}
} }
} }
else // Footprint pad has a net. else // Footprint pad has a net.
...@@ -2638,7 +2569,19 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, ...@@ -2638,7 +2569,19 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
} }
if( !aNetlist.IsDryRun() ) if( !aNetlist.IsDryRun() )
{
pad->SetNetname( net.GetNetName() ); 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, ...@@ -2711,6 +2654,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
aReporter->Report( msg ); aReporter->Report( msg );
} }
previouspad->SetNetname( wxEmptyString ); previouspad->SetNetname( wxEmptyString );
previouspad->SetNet( 0 );
} }
netname = pad->GetNetname(); netname = pad->GetNetname();
count = 1; count = 1;
...@@ -2723,7 +2667,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, ...@@ -2723,7 +2667,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
// Examine last pad // Examine last pad
if( pad && count == 1 ) if( pad && count == 1 )
{
pad->SetNetname( wxEmptyString ); pad->SetNetname( wxEmptyString );
pad->SetNet( 0 );
}
} }
// Last step: Some tests: // Last step: Some tests:
......
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
#include <vector> #include <vector>
#include <gr_basic.h> #include <gr_basic.h>
#include <class_netclass.h> #include <class_netclass.h>
#include <boost/unordered_map.hpp>
#include <hashtables.h>
class wxDC; class wxDC;
...@@ -115,7 +117,6 @@ public: ...@@ -115,7 +117,6 @@ public:
}; };
/** /**
* Class NETINFO * Class NETINFO
* is a container class for NETINFO_ITEM elements, which are the nets. That makes * is a container class for NETINFO_ITEM elements, which are the nets. That makes
...@@ -141,6 +142,20 @@ public: ...@@ -141,6 +142,20 @@ public:
return m_NetBuffer[aNetcode]; 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 * Function GetNetCount
* @return the number of nets ( always >= 1 ) * @return the number of nets ( always >= 1 )
...@@ -188,6 +203,8 @@ public: ...@@ -188,6 +203,8 @@ public:
void Show() const; void Show() const;
#endif #endif
typedef boost::unordered_map<const wxString, NETINFO_ITEM*, WXSTRING_HASH> NETNAMES_MAP;
private: private:
/** /**
...@@ -214,6 +231,7 @@ private: ...@@ -214,6 +231,7 @@ private:
void buildPadsFullList(); void buildPadsFullList();
BOARD* m_Parent; BOARD* m_Parent;
NETNAMES_MAP m_netNames; ///< map for a fast look up by net names
std::vector<NETINFO_ITEM*> m_NetBuffer; ///< net list (name, design constraints ..) std::vector<NETINFO_ITEM*> m_NetBuffer; ///< net list (name, design constraints ..)
std::vector<D_PAD*> m_PadsFullList; ///< contains all pads, sorted by pad's netname. std::vector<D_PAD*> m_PadsFullList; ///< contains all pads, sorted by pad's netname.
...@@ -394,15 +412,15 @@ public: ...@@ -394,15 +412,15 @@ public:
/** /**
* Function GetNetname * 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 * 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 * Function GetMsgPanelInfo
......
...@@ -15,9 +15,10 @@ ...@@ -15,9 +15,10 @@
// Constructor and destructor // 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() ...@@ -34,14 +35,20 @@ void NETINFO_LIST::clear()
m_NetBuffer.clear(); m_NetBuffer.clear();
m_PadsFullList.clear(); m_PadsFullList.clear();
m_netNames.clear();
} }
void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement ) 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 ); 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() ...@@ -74,18 +81,13 @@ void NETINFO_LIST::buildListOfNets()
{ {
D_PAD* pad; D_PAD* pad;
int nodes_count = 0; int nodes_count = 0;
NETINFO_ITEM* net_item;
// Build the PAD list, sorted by net // Build the PAD list, sorted by net
buildPadsFullList(); buildPadsFullList();
// Restore the initial state of NETINFO_ITEMs // Restore the initial state of NETINFO_ITEMs
for( unsigned i = 0; i < GetNetCount(); ++i ) for( unsigned i = 0; i < GetNetCount(); ++i )
{
GetNetItem( i )->Clear(); GetNetItem( i )->Clear();
}
std::cout << m_PadsFullList.size() << std::endl;
// Assign pads to appropriate NETINFO_ITEMs // Assign pads to appropriate NETINFO_ITEMs
for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ ) for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ )
...@@ -95,8 +97,8 @@ void NETINFO_LIST::buildListOfNets() ...@@ -95,8 +97,8 @@ void NETINFO_LIST::buildListOfNets()
if( pad->GetNet() == 0 ) // pad not connected if( pad->GetNet() == 0 ) // pad not connected
continue; continue;
net_item = GetNetItem( pad->GetNet() ); // Add pad to the appropriate list of pads
net_item->m_PadInNetList.push_back( pad ); GetNetItem( pad->GetNet() )->m_PadInNetList.push_back( pad );
++nodes_count; ++nodes_count;
} }
......
...@@ -413,6 +413,7 @@ void D_PAD::CopyNetlistSettings( D_PAD* aPad ) ...@@ -413,6 +413,7 @@ void D_PAD::CopyNetlistSettings( D_PAD* aPad )
wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) ); wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) );
aPad->SetNetname( GetNetname() ); aPad->SetNetname( GetNetname() );
aPad->SetNet( GetNet() );
aPad->SetLocalClearance( m_LocalClearance ); aPad->SetLocalClearance( m_LocalClearance );
aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin ); aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin );
......
...@@ -128,7 +128,13 @@ public: ...@@ -128,7 +128,13 @@ public:
* Function GetNetname * Function GetNetname
* @return const wxString& - the full netname * @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 * Function GetShortNetname
......
...@@ -142,6 +142,7 @@ void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw ) ...@@ -142,6 +142,7 @@ void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw )
// Update the pad properties. // Update the pad properties.
Import_Pad_Settings( pad, false ); Import_Pad_Settings( pad, false );
pad->SetNetname( wxEmptyString ); pad->SetNetname( wxEmptyString );
pad->SetNet( 0 );
pad->SetPosition( GetCrossHairPosition() ); pad->SetPosition( GetCrossHairPosition() );
......
...@@ -47,16 +47,14 @@ class REPORTER; ...@@ -47,16 +47,14 @@ class REPORTER;
class COMPONENT_NET class COMPONENT_NET
{ {
wxString m_pinName; wxString m_pinName;
wxString m_netNumber;
wxString m_netName; wxString m_netName;
public: public:
COMPONENT_NET() {} 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; } const wxString& GetPinName() const { return m_pinName; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment