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