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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include "netinfo.h"
25
26#include <wx/log.h>
27
28#include <board.h>
29#include <board_commit.h>
30#include <footprint.h>
31#include <macros.h>
32#include <pad.h>
33#include <pcb_shape.h>
34#include <pcb_track.h>
35#include <string_utils.h>
36#include <zone.h>
37#include <unordered_map>
38
39
40// Constructor and destructor
42 m_parent( aParent ),
43 m_newNetCode( 0 )
44{
45 // Make sure that the unconnected net has number 0
46 AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) );
47}
48
49
54
55
57{
58 NETNAMES_MAP::iterator it, itEnd;
59
60 for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
61 delete it->second;
62
63 detachAll();
64}
65
66
68{
69 m_netNames.clear();
70 m_netCodes.clear();
71 m_newNetCode = 0;
72}
73
74
76{
77 NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode );
78
79 if( result != m_netCodes.end() )
80 return (*result).second;
81
82 return nullptr;
83}
84
85
86NETINFO_ITEM* NETINFO_LIST::GetNetItem( const wxString& aNetName ) const
87{
88 NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
89
90 if( result != m_netNames.end() )
91 return (*result).second;
92
93 return nullptr;
94}
95
96
98{
99 bool removed = false;
100
101 for( NETCODES_MAP::iterator i = m_netCodes.begin(); i != m_netCodes.end(); ++i )
102 {
103 if ( i->second == aNet )
104 {
105 removed = true;
106 m_netCodes.erase(i);
107 break;
108 }
109 }
110
111 for( NETNAMES_MAP::iterator i = m_netNames.begin(); i != m_netNames.end(); ++i )
112 {
113 if ( i->second == aNet )
114 {
115 wxASSERT_MSG( removed, wxT( "NETINFO_LIST::RemoveNet: target net found in m_netNames "
116 "but not m_netCodes!" ) );
117 m_netNames.erase(i);
118 break;
119 }
120 }
121
122 if( removed )
123 {
124 m_newNetCode = std::min( m_newNetCode, aNet->m_netCode - 1 );
126 }
127}
128
129
131{
132 NETCODES_MAP existingNets = m_netCodes;
133 std::vector<NETINFO_ITEM*> unusedNets;
134
135 m_netCodes.clear();
136 m_netNames.clear();
137
138 for( const auto& [ netCode, netInfo ] : existingNets )
139 {
140 if( netInfo->IsCurrent() )
141 {
142 m_netNames.insert( std::make_pair( netInfo->GetNetname(), netInfo ) );
143 m_netCodes.insert( std::make_pair( netCode, netInfo ) );
144 }
145 else
146 {
148
149 if( aCommit )
150 aCommit->Removed( netInfo );
151 }
152 }
153}
154
155
157{
158 // if there is a net with such name then just assign the correct number
159 NETINFO_ITEM* sameName = GetNetItem( aNewElement->GetNetname() );
160
161 if( sameName != nullptr )
162 {
163 aNewElement->m_netCode = sameName->GetNetCode();
164
165 return;
166 }
167 else if( aNewElement->m_netCode != (int) m_netCodes.size() || aNewElement->m_netCode < 0 )
168 {
169 // be sure that net codes are consecutive
170 // negative net code means that it has to be auto assigned
171 aNewElement->m_netCode = getFreeNetCode();
172 }
173
174 // net names & codes are supposed to be unique
175 assert( GetNetItem( aNewElement->GetNetname() ) == nullptr );
176 assert( GetNetItem( aNewElement->GetNetCode() ) == nullptr );
177
178 // add an entry for fast look up by a net name using a map
179 m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) );
180 m_netCodes.insert( std::make_pair( aNewElement->GetNetCode(), aNewElement ) );
181
183}
184
185
187{
188 // Preserve any parsed net-chain names and terminal pad UUIDs before clearing. The GUI load
189 // path calls BuildListOfNets() after the board file is parsed (see files.cpp) which was
190 // unintentionally wiping the m_netChain field set by the (net_chains ...) section. Cache and
191 // restore them so persisted chains survive the rebuild.
192 std::unordered_map<int, wxString> preservedNetChains;
193 std::unordered_map<int, KIID> preservedPad0;
194 std::unordered_map<int, KIID> preservedPad1;
195
196 preservedNetChains.reserve( GetNetCount() );
197 preservedPad0.reserve( GetNetCount() );
198 preservedPad1.reserve( GetNetCount() );
199
200 for( NETINFO_ITEM* net : *this )
201 {
202 preservedNetChains[ net->GetNetCode() ] = net->GetNetChain();
203 preservedPad0[ net->GetNetCode() ] = net->GetTerminalPadUuid( 0 );
204 preservedPad1[ net->GetNetCode() ] = net->GetTerminalPadUuid( 1 );
205 }
206
207 // Restore the initial state of NETINFO_ITEMs (except chains & terminal pad UUIDs which we reapply)
208 for( NETINFO_ITEM* net : *this )
209 net->Clear();
210
211 for( NETINFO_ITEM* net : *this )
212 {
213 auto it = preservedNetChains.find( net->GetNetCode() );
214 if( it != preservedNetChains.end() )
215 net->SetNetChain( it->second );
216
217 auto ip0 = preservedPad0.find( net->GetNetCode() );
218 if( ip0 != preservedPad0.end() )
219 net->SetTerminalPadUuid( 0, ip0->second );
220
221 auto ip1 = preservedPad1.find( net->GetNetCode() );
222 if( ip1 != preservedPad1.end() )
223 net->SetTerminalPadUuid( 1, ip1->second );
224 }
225
226 m_parent->SynchronizeNetsAndNetClasses( false );
227 m_parent->SetAreasNetCodesFromNetNames();
228}
229
230
232{
233 std::map<wxString, std::vector<wxString>> shortNameMap;
234
235 for( NETINFO_ITEM* net : *this )
236 shortNameMap[net->m_shortNetname].push_back( net->m_netname );
237
238 for( NETINFO_ITEM* net : *this )
239 {
240 if( shortNameMap[net->m_shortNetname].size() == 1 )
241 {
243 }
244 else
245 {
246 wxArrayString parts = wxSplit( net->m_netname, '/' );
247 std::vector<wxArrayString> aggregateParts;
248 std::optional<size_t> firstNonCommon;
249
250 for( const wxString& longName : shortNameMap[net->m_shortNetname] )
251 aggregateParts.push_back( wxSplit( longName, '/' ) );
252
253 for( size_t ii = 0; ii < parts.size() && !firstNonCommon; ++ii )
254 {
255 for( const wxArrayString& otherParts : aggregateParts )
256 {
257 if( ii < otherParts.size() && otherParts[ii] == parts[ii] )
258 continue;
259
260 firstNonCommon = ii;
261 break;
262 }
263 }
264
265 if( firstNonCommon.value_or( 0 ) > 0 && firstNonCommon.value() < parts.size() )
266 {
267 wxString disambiguatedName;
268
269 for( size_t ii = firstNonCommon.value(); ii < parts.size(); ++ii )
270 {
271 if( !disambiguatedName.IsEmpty() )
272 disambiguatedName += wxS( "/" );
273
274 disambiguatedName += parts[ii];
275 }
276
277 net->m_displayNetname = UnescapeString( disambiguatedName );
278 }
279 else
280 {
282 }
283 }
284 }
285
287}
288
289
290#if defined(DEBUG)
291void NETINFO_LIST::Show() const
292{
293 int i = 0;
294 NETNAMES_MAP::const_iterator it, itEnd;
295
296 for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
297 {
298 wxLogDebug( wxT( "[%d]: netcode:%d netname:<%s>\n" ),
299 i++,
300 it->second->GetNetCode(),
301 TO_UTF8( it->second->GetNetname() ) );
302 }
303}
304#endif
305
306
308{
309 do
310 {
311 if( m_newNetCode < 0 )
312 m_newNetCode = 0;
313 } while( m_netCodes.count( ++m_newNetCode ) != 0 );
314
315 return m_newNetCode;
316}
317
318
319const int NETINFO_LIST::UNCONNECTED = 0;
320const int NETINFO_LIST::ORPHANED = -1;
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Definition commit.h:96
Handle the data for a net.
Definition netinfo.h:50
wxString m_shortNetname
Short net name, like vout from /sheet/subsheet/vout.
Definition netinfo.h:195
const wxString & GetNetChain() const
Definition netinfo.h:115
const KIID & GetTerminalPadUuid(int aIndex) const
Definition netinfo.h:121
wxString m_displayNetname
Unescaped netname for display.
Definition netinfo.h:197
const wxString & GetNetname() const
Definition netinfo.h:103
void Clear()
Set all fields to their default values.
void SetTerminalPadUuid(int aIndex, const KIID &aUuid)
Definition netinfo.h:120
int GetNetCode() const
Definition netinfo.h:97
int m_netCode
A number equivalent to the net name.
Definition netinfo.h:193
void SetNetChain(const wxString &aNetChain)
Definition netinfo.h:116
wxString m_netname
Full net name like /sheet/subsheet/vout used by Eeschema.
Definition netinfo.h:194
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:225
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition netinfo.h:259
NETCODES_MAP m_netCodes
map of <int, NETINFO_ITEM*> is NOT owner
Definition netinfo.h:392
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition netinfo.h:263
int m_newNetCode
possible value for new net code assignment
Definition netinfo.h:394
unsigned GetNetCount() const
Definition netinfo.h:247
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:389
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:391
void AppendNet(NETINFO_ITEM *aNewElement)
Add aNewElement to the end of the net list.
bool m_DisplayNetnamesDirty
Definition netinfo.h:386
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:218
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.