KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pns_log_file.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.
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
25// WARNING - this Tom's crappy PNS hack tool code. Please don't complain about its quality
26// (unless you want to improve it).
27
28#include <wx/filename.h>
29#include <wx/ffile.h>
30#include <wx/stdstream.h>
31#include <wx/wfstream.h>
32
33#include "pns_log_file.h"
34#include "pns_arc.h"
35
36#include <router/pns_segment.h>
37
39
42
43#include <project.h>
45
47
48std::vector<BOARD_CONNECTED_ITEM*> PNS_LOG_FILE::ItemsById( const PNS::LOGGER::EVENT_ENTRY& evt )
49{
50 std::vector<BOARD_CONNECTED_ITEM*> parents;
51
52 parents.resize( evt.uuids.size() );
53
54 for( BOARD_CONNECTED_ITEM* item : m_board->AllConnectedItems() )
55 {
56 for( int i = 0; i < evt.uuids.size(); i++ )
57 {
58 if( item->m_Uuid == evt.uuids[i] )
59 {
60 parents[i] = item;
61 break;
62 };
63 }
64 }
65
66 return parents;
67}
68
70{
71 auto parents = ItemsById( evt );
72 if ( parents.size() > 0 )
73 return parents[0];
74
75 return nullptr;
76}
77
78
79static const wxString readLine( FILE* f )
80{
81 char str[16384];
82 fgets( str, sizeof( str ) - 1, f );
83 return wxString( str );
84}
85
86
88 m_mode( PNS::ROUTER_MODE::PNS_MODE_ROUTE_SINGLE )
89{
90 m_routerSettings.reset( new PNS::ROUTING_SETTINGS( nullptr, "" ) );
91}
92
93
94std::shared_ptr<SHAPE> PNS_LOG_FILE::parseShape( const nlohmann::json& aJSON )
95{
96 const wxString type = static_cast<wxString>( aJSON.at( "type" ).get<wxString>() );
97
98 if( type == wxT("segment") )
99 {
100 std::shared_ptr<SHAPE_SEGMENT> sh( new SHAPE_SEGMENT );
101 sh->SetSeg( SEG( aJSON.at( "start" ).get<VECTOR2I>(), aJSON.at( "end" ).get<VECTOR2I>() ) );
102 sh->SetWidth( aJSON.at( "width" ).get<int>() );
103 return sh;
104 }
105 else if( type == wxT("circle") )
106 {
107 std::shared_ptr<SHAPE_CIRCLE> sh( new SHAPE_CIRCLE );
108 sh->SetCenter( aJSON.at( "center" ).get<VECTOR2I>() );
109 sh->SetRadius( aJSON.at( "radius" ).get<int>() );
110 return sh;
111 }
112 else if( type == wxT("arc") )
113 {
114 VECTOR2I start = aJSON.at( "start" ).get<VECTOR2I>();
115 VECTOR2I mid = aJSON.at( "mid" ).get<VECTOR2I>();
116 VECTOR2I end = aJSON.at( "end" ).get<VECTOR2I>();
117 int width = aJSON.at( "width" ).get<int>();
118
119 std::shared_ptr<SHAPE_ARC> sh( new SHAPE_ARC( start, mid, end, width ) );
120 return sh;
121 }
122
123 return nullptr;
124}
125
126
127std::shared_ptr<SHAPE> PNS_LOG_FILE::parseLegacyShape( SHAPE_TYPE expectedType, wxStringTokenizer& aTokens )
128{
129 SHAPE_TYPE type = static_cast<SHAPE_TYPE> ( wxAtoi( aTokens.GetNextToken() ) );
130
131 if( type == SHAPE_TYPE::SH_SEGMENT )
132 {
133 std::shared_ptr<SHAPE_SEGMENT> sh( new SHAPE_SEGMENT );
134 VECTOR2I a, b;
135 a.x = wxAtoi( aTokens.GetNextToken() );
136 a.y = wxAtoi( aTokens.GetNextToken() );
137 b.x = wxAtoi( aTokens.GetNextToken() );
138 b.y = wxAtoi( aTokens.GetNextToken() );
139 int width = wxAtoi( aTokens.GetNextToken() );
140 sh->SetSeg( SEG( a, b ));
141 sh->SetWidth( width );
142 return sh;
143 }
144 else if( type == SHAPE_TYPE::SH_CIRCLE )
145 {
146 std::shared_ptr<SHAPE_CIRCLE> sh( new SHAPE_CIRCLE );
147 VECTOR2I a;
148 a.x = wxAtoi( aTokens.GetNextToken() );
149 a.y = wxAtoi( aTokens.GetNextToken() );
150 int radius = wxAtoi( aTokens.GetNextToken() );
151 sh->SetCenter( a );
152 sh->SetRadius( radius );
153 return sh;
154 }
155
156 return nullptr;
157}
158
159bool PNS_LOG_FILE::parseLegacyCommonPnsProps( PNS::ITEM* aItem, const wxString& cmd,
160 wxStringTokenizer& aTokens )
161{
162 if( cmd == wxS( "net" ) )
163 {
164 aItem->SetNet( m_board->FindNet( wxAtoi( aTokens.GetNextToken() ) ) );
165 return true;
166 }
167 else if( cmd == wxS( "layers" ) )
168 {
169 int start = wxAtoi( aTokens.GetNextToken() );
170 int end = wxAtoi( aTokens.GetNextToken() );
171 aItem->SetLayers( PNS_LAYER_RANGE( start, end ) );
172 return true;
173 }
174 return false;
175}
176
177
178bool PNS_LOG_FILE::parseCommonPnsProps( const nlohmann::json& aJSON, PNS::ITEM* aItem )
179{
180 aItem->SetNet( m_board->FindNet( aJSON.at( "net" ).get<wxString>() ) );
181 aItem->SetLayers(
182 PNS_LAYER_RANGE( aJSON.at( "layers" ).at( 0 ).get<int>(), aJSON.at( "layers" ).at( 1 ).get<int>() ) );
183
184 return true;
185}
186
187std::unique_ptr<PNS::SEGMENT> PNS_LOG_FILE::parseLegacyPnsSegmentFromString( wxStringTokenizer& aTokens )
188{
189 std::unique_ptr<PNS::SEGMENT> seg( new PNS::SEGMENT() );
190
191 while( aTokens.CountTokens() )
192 {
193 wxString cmd = aTokens.GetNextToken();
194
195 if( !parseLegacyCommonPnsProps( seg.get(), cmd, aTokens ) )
196 {
197 if( cmd == wxS( "shape" ) )
198 {
199 std::shared_ptr<SHAPE> sh = parseLegacyShape( SH_SEGMENT, aTokens );
200
201 if( !sh )
202 return nullptr;
203
204 seg->SetShape( *static_cast<SHAPE_SEGMENT*>( sh.get() ) );
205
206 }
207 }
208 }
209
210 return seg;
211}
212
213std::unique_ptr<PNS::VIA> PNS_LOG_FILE::parseLegacyPnsViaFromString( wxStringTokenizer& aTokens )
214{
215 std::unique_ptr<PNS::VIA> via( new PNS::VIA() );
216
217 while( aTokens.CountTokens() )
218 {
219 wxString cmd = aTokens.GetNextToken();
220
221 if( !parseLegacyCommonPnsProps( via.get(), cmd, aTokens ) )
222 {
223 if( cmd == wxS( "shape" ) )
224 {
225 std::shared_ptr<SHAPE> sh = parseLegacyShape( SH_CIRCLE, aTokens );
226
227 if( !sh )
228 return nullptr;
229
230 SHAPE_CIRCLE* sc = static_cast<SHAPE_CIRCLE*>( sh.get() );
231
232 via->SetPos( sc->GetCenter() );
233 via->SetDiameter( PNS::VIA::ALL_LAYERS, 2 * sc->GetRadius() );
234 }
235 else if( cmd == wxS( "drill" ) )
236 {
237 via->SetDrill( wxAtoi( aTokens.GetNextToken() ) );
238 }
239 }
240 }
241
242 return via;
243}
244
245std::unique_ptr<PNS::ITEM> PNS_LOG_FILE::parseItem( const nlohmann::json& aJSON )
246{
247 wxString kind = aJSON.at("kind").get<wxString>();
248
249 if( kind == wxT("segment") )
250 {
251 auto parsedShape = parseShape( aJSON.at("shape") );
252
253 if( !parsedShape )
254 return nullptr;
255
256 auto shape = static_cast<const SHAPE_SEGMENT*>( parsedShape.get() );
257 std::unique_ptr<PNS::SEGMENT> seg( new PNS::SEGMENT( *shape, nullptr ) );
258 parseCommonPnsProps( aJSON, seg.get() );
259 return std::move( seg );
260 }
261 else if ( kind == wxT( "arc" ) )
262 {
263 auto parsedShape = parseShape( aJSON.at("shape") );
264
265 if( !parsedShape )
266 return nullptr;
267
268 auto shape = static_cast<const SHAPE_ARC*>( parsedShape.get() );
269 std::unique_ptr<PNS::ARC> arc( new PNS::ARC( *shape, nullptr ) );
270 parseCommonPnsProps( aJSON, arc.get() );
271 return std::move( arc );
272 }
273 else if ( kind == wxT( "via" ) )
274 {
275 auto parsedShape = parseShape( aJSON.at("shape") );
276
277 if( !parsedShape )
278 return nullptr;
279
280 auto shape = static_cast<const SHAPE_CIRCLE*>( parsedShape.get() );
281 std::unique_ptr<PNS::VIA> via( new PNS::VIA() );
282 parseCommonPnsProps( aJSON, via.get() );
283 via->SetPos( shape->Centre() );
284 via->SetDiameter( via->Layers().Start(), shape->GetRadius() * 2 );
285 via->SetDrill( aJSON.at("drill").get<int>() );
286 return std::move(via);
287 }
288
289 return nullptr;
290}
291
292
293std::unique_ptr<PNS::ITEM> PNS_LOG_FILE::parseLegacyItemFromString( wxStringTokenizer& aTokens )
294{
295 wxString type = aTokens.GetNextToken();
296
297 if( type == wxS( "segment" ) )
298 return parseLegacyPnsSegmentFromString( aTokens );
299 else if( type == wxS( "via" ) )
300 return parseLegacyPnsViaFromString( aTokens );
301
302 return nullptr;
303}
304
305bool comparePnsItems( const PNS::ITEM* a , const PNS::ITEM* b )
306{
307 if( a->Kind() != b->Kind() )
308 return false;
309
310 if( a->Net() != b->Net() )
311 return false;
312
313 if( a->Layers() != b->Layers() )
314 return false;
315
316 if( a->Kind() == PNS::ITEM::VIA_T )
317 {
318 const PNS::VIA* va = static_cast<const PNS::VIA*>(a);
319 const PNS::VIA* vb = static_cast<const PNS::VIA*>(b);
320
321 // TODO(JE) padstacks
323 return false;
324
325 if( va->Drill() != vb->Drill() )
326 return false;
327
328 if( va->Pos() != vb->Pos() )
329 return false;
330
331 }
332 else if ( a->Kind() == PNS::ITEM::SEGMENT_T )
333 {
334 const PNS::SEGMENT* sa = static_cast<const PNS::SEGMENT*>(a);
335 const PNS::SEGMENT* sb = static_cast<const PNS::SEGMENT*>(b);
336
337 if( sa->Seg() != sb->Seg() )
338 return false;
339
340 if( sa->Width() != sb->Width() )
341 return false;
342 }
343
344 return true;
345}
346
347
348const std::set<PNS::ITEM*> deduplicate( const std::vector<PNS::ITEM*>& items )
349{
350 std::set<PNS::ITEM*> rv;
351
352 for( PNS::ITEM* item : items )
353 {
354 bool isDuplicate = false;
355
356 for( PNS::ITEM* ritem : rv )
357 {
358 if( comparePnsItems( ritem, item) )
359 {
360 isDuplicate = true;
361 break;
362 }
363
364 if( !isDuplicate )
365 rv.insert( item );
366 }
367 }
368
369 return rv;
370}
371
372
374{
375 COMMIT_STATE check( aOther );
376
377 //printf("pre-compare: %d/%d\n", check.m_addedItems.size(), check.m_removedIds.size() );
378 //printf("pre-compare (log): %d/%d\n", m_addedItems.size(), m_removedIds.size() );
379
380 for( const KIID& uuid : m_removedIds )
381 {
382 if( check.m_removedIds.find( uuid ) != check.m_removedIds.end() )
383 check.m_removedIds.erase( uuid );
384 else
385 return false; // removed twice? wtf
386 }
387
388 std::set<PNS::ITEM*> addedItems = deduplicate( m_addedItems );
389 std::set<PNS::ITEM*> chkAddedItems = deduplicate( check.m_addedItems );
390
391 for( PNS::ITEM* item : addedItems )
392 {
393 for( PNS::ITEM* chk : chkAddedItems )
394 {
395 if( comparePnsItems( item, chk ) )
396 {
397 chkAddedItems.erase( chk );
398 break;
399 }
400 }
401 }
402
403 //printf("post-compare: %d/%d\n", chkAddedItems.size(), check.m_removedIds.size() );
404
405 if( chkAddedItems.empty() && check.m_removedIds.empty() )
406 return true;
407 else
408 return false; // Set breakpoint here to trap failing tests
409}
410
411
412bool PNS_LOG_FILE::SaveLog( const wxFileName& logFileName, REPORTER* aRpt )
413{
414 PNS::LOGGER::LOG_DATA logData;
415
416 logData.m_AddedItems = m_commitState.m_addedItems;
417 logData.m_RemovedItems = m_commitState.m_removedIds;
418 logData.m_Heads = m_commitState.m_heads;
419 logData.m_BoardHash = m_boardHash;
421 logData.m_Events = m_events;
422 logData.m_Mode = m_mode;
423
424 wxString logString = PNS::LOGGER::FormatLogFileAsJSON( logData );
425
426 wxFFileOutputStream fp( logFileName.GetFullPath(), wxT( "wt" ) );
427
428 if( !fp.IsOk() )
429 {
430 if( aRpt )
431 {
432 aRpt->Report( wxString::Format( wxT("Failed to write log file: %s"), logFileName.GetFullPath() ), RPT_SEVERITY_ERROR );
433 }
434 return false;
435 }
436
437 wxScopedCharBuffer utf8 = logString.ToUTF8();
438 fp.Write( utf8.data(), utf8.length() );
439 fp.Close();
440
441 return true;
442}
443
444
445bool PNS_LOG_FILE::Load( const wxFileName& logFileName, REPORTER* aRpt, const wxString boardFileName )
446{
447 wxFileName fname_log( logFileName );
448 fname_log.SetExt( wxT( "log" ) );
449
450 wxFileName fname_dump( logFileName );
451 fname_dump.SetExt( wxT( "dump" ) );
452
453 if( !boardFileName.IsEmpty() )
454 {
455 fname_dump = boardFileName;
456 }
457
458 wxFileName fname_project( logFileName );
459 fname_project.SetExt( wxT( "kicad_pro" ) );
460 fname_project.MakeAbsolute();
461
462 wxFileName fname_settings( logFileName );
463 fname_settings.SetExt( wxT( "settings" ) );
464
465 aRpt->Report( wxString::Format( wxT( "Loading router settings from '%s'" ),
466 fname_settings.GetFullPath() ) );
467
468 bool ok = m_routerSettings->LoadFromRawFile( fname_settings.GetFullPath() );
469
470 if( !ok )
471 {
472 aRpt->Report( wxT( "Failed to load routing settings. Using defaults." ),
474 }
475
476 aRpt->Report( wxString::Format( wxT( "Loading project settings from '%s'" ),
477 fname_settings.GetFullPath() ) );
478
479 m_settingsMgr.reset( new SETTINGS_MANAGER );
480 m_settingsMgr->LoadProject( fname_project.GetFullPath() );
481 PROJECT* project = m_settingsMgr->GetProject( fname_project.GetFullPath() );
482 project->SetReadOnly();
483
484 try
485 {
487 aRpt->Report( wxString::Format( wxT("Loading board snapshot from '%s'"),
488 fname_dump.GetFullPath() ) );
489
490 m_board.reset( io.LoadBoard( fname_dump.GetFullPath(), nullptr, nullptr ) );
491 m_board->SetProject( project );
492
493 std::shared_ptr<DRC_ENGINE> drcEngine( new DRC_ENGINE );
494
495 BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
496
497 bds.m_DRCEngine = drcEngine;
498 bds.m_UseConnectedTrackWidth = project->GetLocalSettings().m_AutoTrackWidth;
499
500 m_board->SynchronizeNetsAndNetClasses( true );
501
502 drcEngine->SetBoard( m_board.get() );
503 drcEngine->SetDesignSettings( &bds );
504 drcEngine->SetLogReporter( aRpt );
505 drcEngine->InitEngine( wxFileName() );
506 }
507 catch( const PARSE_ERROR& parse_error )
508 {
509 aRpt->Report( wxString::Format( "parse error : %s (%s)\n",
510 parse_error.Problem(),
511 parse_error.What() ),
513
514 return false;
515 }
516
517
518 ok = loadJsonLog( logFileName.GetFullPath(), aRpt, false );
519 if( !ok && logFileName.FileExists() )
520 {
521 aRpt->Report("Falling back to legacy log format...\n", RPT_SEVERITY_WARNING);
522 ok = loadLegacyLog( logFileName.GetFullPath(), aRpt );
523 }
524
525 return ok;
526}
527
528
529bool PNS_LOG_FILE::loadJsonLog( const wxString& aFilename, REPORTER* aRpt, bool aHashOnly )
530{
531 wxFFileInputStream fp( aFilename, wxT( "rt" ) );
532 wxStdInputStream fstream( fp );
533
534
535 if ( aRpt )
536 {
537 aRpt->Report( wxString::Format( "Loading log from: %s", aFilename ) );
538 }
539
540 if( !fp.IsOk() )
541 {
542 if( aRpt )
543 aRpt->Report( wxT("Failed to load."), RPT_SEVERITY_ERROR );
544
545 return false;
546 }
547
548 try
549 {
550 nlohmann::json logJson = nlohmann::json::parse( fstream, nullptr,
551 /* allow_exceptions = */ true,
552 /* ignore_comments = */ true );
553
554 if( logJson.contains("board_hash") )
555 {
556 m_boardHash = logJson.at("board_hash").get<wxString>();
557 }
558
559 if( logJson.contains("test_case_type") )
560 {
561 m_testCaseType = static_cast<PNS::LOGGER::TEST_CASE_TYPE>( logJson.at("test_case_type").get<int>() );
562 }
563
564 if ( aHashOnly )
565 return true;
566
567 m_mode = static_cast<PNS::ROUTER_MODE>( logJson.at( "mode" ).get<int>() );
568
569 for( const nlohmann::json& event : logJson.at( "events" ) )
570 {
571 m_events.push_back( std::move( PNS::LOGGER::ParseEventFromJSON( event ) ) );
572 }
573
574 for( const nlohmann::json& addedItem : logJson.at( "addedItems" ) )
575 {
576 m_parsed_items.push_back( std::move( parseItem( addedItem ) ) );
577 m_commitState.m_addedItems.push_back( m_parsed_items.back().get() );
578 }
579
580 for( const nlohmann::json& addedItem : logJson.at( "removedItems" ) )
581 {
582 m_commitState.m_removedIds.insert( addedItem.get<KIID>() );
583 }
584
585 if( aRpt )
586 {
587 aRpt->Report( wxString::Format( "JSON log load: %lu events, %lu added, %lu removed\n", m_events.size(),
588 m_commitState.m_addedItems.size(), m_commitState.m_removedIds.size() ),
590 }
591
592
593 }
594 catch( const std::exception& exc )
595 {
596 if( aRpt )
597 {
598 aRpt->Report( wxString::Format( "JSON log parse failure: %s\n", exc.what() ), RPT_SEVERITY_ERROR );
599 }
600 return false;
601 }
602
603 return true;
604}
605
606
607bool PNS_LOG_FILE::loadLegacyLog( const wxString& aFilename, REPORTER* aRpt )
608{
609 FILE* f = fopen( aFilename.c_str(), "rb" );
610
611 aRpt->Report( wxString::Format( "Loading log from '%s'", aFilename ) );
612
613 if( !f )
614 {
615 aRpt->Report( wxT( "Failed to load log file." ), RPT_SEVERITY_ERROR );
616 return false;
617 }
618
619 try
620 {
621 while( !feof( f ) )
622 {
623 wxString line = readLine( f );
624 wxStringTokenizer tokens( line );
625
626 if( !tokens.CountTokens() )
627 continue;
628
629 wxString cmd = tokens.GetNextToken();
630
631 if( cmd == wxT( "mode" ) )
632 {
633 m_mode = static_cast<PNS::ROUTER_MODE>( wxAtoi( tokens.GetNextToken() ) );
634 }
635 else if( cmd == wxT( "event" ) )
636 {
637 m_events.push_back( std::move( PNS::LOGGER::ParseEvent( line ) ) );
638 }
639 else if( cmd == wxT( "added" ) )
640 {
641 m_parsed_items.push_back( std::move( parseLegacyItemFromString( tokens ) ) );
642 m_commitState.m_addedItems.push_back( m_parsed_items.back().get() );
643 }
644 else if( cmd == wxT( "removed" ) )
645 {
646 m_commitState.m_removedIds.insert( KIID( tokens.GetNextToken() ) );
647 }
648 }
649 }
650 catch( ... )
651 {
652 return false;
653 }
654
655 fclose( f );
656 return true;
657}
658
659const std::optional<wxString> PNS_LOG_FILE::GetLogBoardHash( const wxString& logFileName )
660{
661 loadJsonLog( logFileName, nullptr, true );
662 return m_boardHash;
663}
664
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
Container for design settings for a BOARD object.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
Design Rule Checker object that performs all the DRC tests.
Definition drc_engine.h:133
virtual const wxString What() const
A composite of Problem() and Where()
virtual const wxString Problem() const
what was the problem?
Definition kiid.h:48
A #PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
Base class for PNS router board items.
Definition pns_item.h:98
void SetLayers(const PNS_LAYER_RANGE &aLayers)
Definition pns_item.h:213
const PNS_LAYER_RANGE & Layers() const
Definition pns_item.h:212
virtual NET_HANDLE Net() const
Definition pns_item.h:210
PnsKind Kind() const
Return the type (kind) of the item.
Definition pns_item.h:173
void SetNet(NET_HANDLE aNet)
Definition pns_item.h:209
static wxString FormatLogFileAsJSON(const LOG_DATA &aLogData)
static EVENT_ENTRY ParseEventFromJSON(const nlohmann::json &aJSON)
static EVENT_ENTRY ParseEvent(const wxString &aLine)
Contain all persistent settings of the router, such as the mode, optimization effort,...
const SEG & Seg() const
int Width() const override
Definition pns_segment.h:96
int Diameter(int aLayer) const
Definition pns_via.h:227
const VECTOR2I & Pos() const
Definition pns_via.h:206
int Drill() const
Definition pns_via.h:247
static constexpr int ALL_LAYERS
Definition pns_via.h:78
Represent a contiguous set of PCB layers.
bool parseCommonPnsProps(const nlohmann::json &aJSON, PNS::ITEM *aItem)
BOARD_CONNECTED_ITEM * ItemById(const PNS::LOGGER::EVENT_ENTRY &evt)
std::unique_ptr< PNS::VIA > parseLegacyPnsViaFromString(wxStringTokenizer &aTokens)
const std::optional< wxString > GetLogBoardHash(const wxString &logFileName)
bool SaveLog(const wxFileName &logFileName, REPORTER *aRpt)
bool loadLegacyLog(const wxString &aFilename, REPORTER *aRpt)
PNS::ROUTER_MODE m_mode
std::shared_ptr< BOARD > m_board
bool parseLegacyCommonPnsProps(PNS::ITEM *aItem, const wxString &cmd, wxStringTokenizer &aTokens)
std::shared_ptr< SETTINGS_MANAGER > m_settingsMgr
std::shared_ptr< SHAPE > parseShape(const nlohmann::json &aJSON)
std::unique_ptr< PNS::ITEM > parseItem(const nlohmann::json &aJSON)
std::shared_ptr< SHAPE > parseLegacyShape(SHAPE_TYPE expectedType, wxStringTokenizer &aTokens)
std::vector< std::unique_ptr< PNS::ITEM > > m_parsed_items
std::optional< wxString > m_boardHash
COMMIT_STATE m_commitState
bool loadJsonLog(const wxString &aFilename, REPORTER *aRpt, bool aHashOnly=false)
std::vector< PNS::LOGGER::EVENT_ENTRY > m_events
std::vector< BOARD_CONNECTED_ITEM * > ItemsById(const PNS::LOGGER::EVENT_ENTRY &evt)
std::unique_ptr< PNS::SEGMENT > parseLegacyPnsSegmentFromString(wxStringTokenizer &aTokens)
std::optional< PNS::LOGGER::TEST_CASE_TYPE > m_testCaseType
std::unique_ptr< PNS::ROUTING_SETTINGS > m_routerSettings
bool Load(const wxFileName &logFileName, REPORTER *aRpt, const wxString boardFileName=wxT(""))
std::unique_ptr< PNS::ITEM > parseLegacyItemFromString(wxStringTokenizer &aTokens)
Container for project specific data.
Definition project.h:66
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:73
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:102
Definition seg.h:42
int GetRadius() const
const VECTOR2I GetCenter() const
Push and Shove diff pair dimensions (gap) settings dialog.
ROUTER_MODE
Definition pns_router.h:67
bool comparePnsItems(const PNS::ITEM *a, const PNS::ITEM *b)
static const wxString readLine(FILE *f)
const std::set< PNS::ITEM * > deduplicate(const std::vector< PNS::ITEM * > &items)
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_INFO
SHAPE_TYPE
Lists all supported shapes.
Definition shape.h:46
@ SH_CIRCLE
circle
Definition shape.h:50
@ SH_SEGMENT
line segment
Definition shape.h:48
A filename or source description, a problem input line, a line number, a byte offset,...
Definition pns_logger.h:71
std::vector< KIID > uuids
Definition pns_logger.h:74
std::optional< wxString > m_BoardHash
Definition pns_logger.h:99
std::optional< TEST_CASE_TYPE > m_TestCaseType
Definition pns_logger.h:104
std::vector< ITEM * > m_AddedItems
Definition pns_logger.h:100
std::vector< EVENT_ENTRY > m_Events
Definition pns_logger.h:103
std::set< KIID > m_RemovedItems
Definition pns_logger.h:101
std::vector< ITEM * > m_Heads
Definition pns_logger.h:102
std::set< KIID > m_removedIds
bool Compare(const COMMIT_STATE &aOther)
std::vector< PNS::ITEM * > m_addedItems
int radius
VECTOR2I end
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687