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.
This commit is contained in:
parent
386d1fc257
commit
bf80cc770e
|
@ -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
|
||||
* 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
|
|||
|
||||
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:
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include <vector>
|
||||
#include <gr_basic.h>
|
||||
#include <class_netclass.h>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <hashtables.h>
|
||||
|
||||
|
||||
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<const wxString, NETINFO_ITEM*, WXSTRING_HASH> 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<NETINFO_ITEM*> m_NetBuffer; ///< net list (name, design constraints ..)
|
||||
|
||||
std::vector<D_PAD*> 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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() );
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in New Issue