KiCad PCB EDA Suite
Loading...
Searching...
No Matches
netinfo_list.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include "netinfo.h"
21
22#include <wx/log.h>
23
24#include <board.h>
25#include <board_commit.h>
26#include <footprint.h>
27#include <macros.h>
28#include <pad.h>
29#include <pcb_shape.h>
30#include <pcb_track.h>
31#include <string_utils.h>
32#include <zone.h>
33#include <unordered_map>
34
35
36// Constructor and destructor
38 m_parent( aParent ),
39 m_newNetCode( 0 )
40{
41 // Make sure that the unconnected net has number 0
42 AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) );
43}
44
45
50
51
53{
54 NETNAMES_MAP::iterator it, itEnd;
55
56 for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
57 delete it->second;
58
59 detachAll();
60}
61
62
64{
65 m_netNames.clear();
66 m_netCodes.clear();
67 m_newNetCode = 0;
68}
69
70
72{
73 NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode );
74
75 if( result != m_netCodes.end() )
76 return (*result).second;
77
78 return nullptr;
79}
80
81
82NETINFO_ITEM* NETINFO_LIST::GetNetItem( const wxString& aNetName ) const
83{
84 NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
85
86 if( result != m_netNames.end() )
87 return (*result).second;
88
89 return nullptr;
90}
91
92
94{
95 bool removed = false;
96
97 for( NETCODES_MAP::iterator i = m_netCodes.begin(); i != m_netCodes.end(); ++i )
98 {
99 if ( i->second == aNet )
100 {
101 removed = true;
102 m_netCodes.erase(i);
103 break;
104 }
105 }
106
107 for( NETNAMES_MAP::iterator i = m_netNames.begin(); i != m_netNames.end(); ++i )
108 {
109 if ( i->second == aNet )
110 {
111 wxASSERT_MSG( removed, wxT( "NETINFO_LIST::RemoveNet: target net found in m_netNames "
112 "but not m_netCodes!" ) );
113 m_netNames.erase(i);
114 break;
115 }
116 }
117
118 if( removed )
119 {
120 m_newNetCode = std::min( m_newNetCode, aNet->m_netCode - 1 );
122 }
123}
124
125
127{
128 NETCODES_MAP existingNets = m_netCodes;
129 std::vector<NETINFO_ITEM*> unusedNets;
130
131 m_netCodes.clear();
132 m_netNames.clear();
133
134 for( const auto& [ netCode, netInfo ] : existingNets )
135 {
136 if( netInfo->IsCurrent() )
137 {
138 m_netNames.insert( std::make_pair( netInfo->GetNetname(), netInfo ) );
139 m_netCodes.insert( std::make_pair( netCode, netInfo ) );
140 }
141 else
142 {
144
145 if( aCommit )
146 aCommit->Removed( netInfo );
147 }
148 }
149}
150
151
153{
154 // if there is a net with such name then just assign the correct number
155 NETINFO_ITEM* sameName = GetNetItem( aNewElement->GetNetname() );
156
157 if( sameName != nullptr )
158 {
159 aNewElement->m_netCode = sameName->GetNetCode();
160
161 return;
162 }
163 else if( aNewElement->m_netCode != (int) m_netCodes.size() || aNewElement->m_netCode < 0 )
164 {
165 // be sure that net codes are consecutive
166 // negative net code means that it has to be auto assigned
167 aNewElement->m_netCode = getFreeNetCode();
168 }
169
170 // net names & codes are supposed to be unique
171 assert( GetNetItem( aNewElement->GetNetname() ) == nullptr );
172 assert( GetNetItem( aNewElement->GetNetCode() ) == nullptr );
173
174 // add an entry for fast look up by a net name using a map
175 m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) );
176 m_netCodes.insert( std::make_pair( aNewElement->GetNetCode(), aNewElement ) );
177
179}
180
181
183{
184 // Preserve any parsed net-chain names and terminal pad UUIDs before clearing. The GUI load
185 // path calls BuildListOfNets() after the board file is parsed (see files.cpp) which was
186 // unintentionally wiping the m_netChain field set by the (net_chains ...) section. Cache and
187 // restore them so persisted chains survive the rebuild.
188 std::unordered_map<int, wxString> preservedNetChains;
189 std::unordered_map<int, KIID> preservedPad0;
190 std::unordered_map<int, KIID> preservedPad1;
191
192 preservedNetChains.reserve( GetNetCount() );
193 preservedPad0.reserve( GetNetCount() );
194 preservedPad1.reserve( GetNetCount() );
195
196 for( NETINFO_ITEM* net : *this )
197 {
198 preservedNetChains[ net->GetNetCode() ] = net->GetNetChain();
199 preservedPad0[ net->GetNetCode() ] = net->GetTerminalPadUuid( 0 );
200 preservedPad1[ net->GetNetCode() ] = net->GetTerminalPadUuid( 1 );
201 }
202
203 // Restore the initial state of NETINFO_ITEMs (except chains & terminal pad UUIDs which we reapply)
204 for( NETINFO_ITEM* net : *this )
205 net->Clear();
206
207 for( NETINFO_ITEM* net : *this )
208 {
209 auto it = preservedNetChains.find( net->GetNetCode() );
210 if( it != preservedNetChains.end() )
211 net->SetNetChain( it->second );
212
213 auto ip0 = preservedPad0.find( net->GetNetCode() );
214 if( ip0 != preservedPad0.end() )
215 net->SetTerminalPadUuid( 0, ip0->second );
216
217 auto ip1 = preservedPad1.find( net->GetNetCode() );
218 if( ip1 != preservedPad1.end() )
219 net->SetTerminalPadUuid( 1, ip1->second );
220 }
221
222 m_parent->SynchronizeNetsAndNetClasses( false );
223 m_parent->SetAreasNetCodesFromNetNames();
224}
225
226
228{
229 std::map<wxString, std::vector<wxString>> shortNameMap;
230
231 for( NETINFO_ITEM* net : *this )
232 shortNameMap[net->m_shortNetname].push_back( net->m_netname );
233
234 for( NETINFO_ITEM* net : *this )
235 {
236 if( shortNameMap[net->m_shortNetname].size() == 1 )
237 {
239 }
240 else
241 {
242 wxArrayString parts = wxSplit( net->m_netname, '/' );
243 std::vector<wxArrayString> aggregateParts;
244 std::optional<size_t> firstNonCommon;
245
246 for( const wxString& longName : shortNameMap[net->m_shortNetname] )
247 aggregateParts.push_back( wxSplit( longName, '/' ) );
248
249 for( size_t ii = 0; ii < parts.size() && !firstNonCommon; ++ii )
250 {
251 for( const wxArrayString& otherParts : aggregateParts )
252 {
253 if( ii < otherParts.size() && otherParts[ii] == parts[ii] )
254 continue;
255
256 firstNonCommon = ii;
257 break;
258 }
259 }
260
261 if( firstNonCommon.value_or( 0 ) > 0 && firstNonCommon.value() < parts.size() )
262 {
263 wxString disambiguatedName;
264
265 for( size_t ii = firstNonCommon.value(); ii < parts.size(); ++ii )
266 {
267 if( !disambiguatedName.IsEmpty() )
268 disambiguatedName += wxS( "/" );
269
270 disambiguatedName += parts[ii];
271 }
272
273 net->m_displayNetname = UnescapeString( disambiguatedName );
274 }
275 else
276 {
278 }
279 }
280 }
281
283}
284
285
286#if defined(DEBUG)
287void NETINFO_LIST::Show() const
288{
289 int i = 0;
290 NETNAMES_MAP::const_iterator it, itEnd;
291
292 for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
293 {
294 wxLogDebug( wxT( "[%d]: netcode:%d netname:<%s>\n" ),
295 i++,
296 it->second->GetNetCode(),
297 TO_UTF8( it->second->GetNetname() ) );
298 }
299}
300#endif
301
302
304{
305 do
306 {
307 if( m_newNetCode < 0 )
308 m_newNetCode = 0;
309 } while( m_netCodes.count( ++m_newNetCode ) != 0 );
310
311 return m_newNetCode;
312}
313
314
315const int NETINFO_LIST::UNCONNECTED = 0;
316const int NETINFO_LIST::ORPHANED = -1;
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Definition commit.h:92
Handle the data for a net.
Definition netinfo.h:46
wxString m_shortNetname
Short net name, like vout from /sheet/subsheet/vout.
Definition netinfo.h:192
const wxString & GetNetChain() const
Definition netinfo.h:112
const KIID & GetTerminalPadUuid(int aIndex) const
Definition netinfo.h:118
wxString m_displayNetname
Unescaped netname for display.
Definition netinfo.h:194
const wxString & GetNetname() const
Definition netinfo.h:100
void Clear()
Set all fields to their default values.
void SetTerminalPadUuid(int aIndex, const KIID &aUuid)
Definition netinfo.h:117
int GetNetCode() const
Definition netinfo.h:94
int m_netCode
A number equivalent to the net name.
Definition netinfo.h:190
void SetNetChain(const wxString &aNetChain)
Definition netinfo.h:113
wxString m_netname
Full net name like /sheet/subsheet/vout used by Eeschema.
Definition netinfo.h:191
int getFreeNetCode()
Return the first available net code that is not used by any other net.
void RemoveUnusedNets(BOARD_COMMIT *aCommit)
friend class BOARD
Definition netinfo.h:222
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition netinfo.h:256
NETCODES_MAP m_netCodes
map of <int, NETINFO_ITEM*> is NOT owner
Definition netinfo.h:389
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition netinfo.h:260
int m_newNetCode
possible value for new net code assignment
Definition netinfo.h:391
unsigned GetNetCount() const
Definition netinfo.h:244
void detachAll()
Drop all entries from the lookup maps without freeing the items.
void RemoveNet(NETINFO_ITEM *aNet)
Remove a net from the net list.
BOARD * m_parent
Definition netinfo.h:386
NETINFO_ITEM * GetNetItem(int aNetCode) const
NETINFO_LIST(BOARD *aParent)
void clear()
Delete the list of nets (and free memory).
NETNAMES_MAP m_netNames
map of <wxString, NETINFO_ITEM*>, is NETINFO_ITEM owner
Definition netinfo.h:388
void AppendNet(NETINFO_ITEM *aNewElement)
Add aNewElement to the end of the net list.
bool m_DisplayNetnamesDirty
Definition netinfo.h:383
void RebuildDisplayNetnames() const
void buildListOfNets()
Rebuild the list of NETINFO_ITEMs.
This file contains miscellaneous commonly used macros and functions.
std::map< int, NETINFO_ITEM * > NETCODES_MAP
Definition netinfo.h:215
wxString UnescapeString(const wxString &aSource)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
wxString result
Test unit parsing edge cases and error handling.