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