24#include <wx/filename.h>
26#include <wx/stdstream.h>
27#include <wx/wfstream.h>
47 std::vector<BOARD_CONNECTED_ITEM*> parents;
49 parents.resize( evt.
uuids.size() );
53 for(
int i = 0; i < evt.
uuids.size(); i++ )
55 if( item->m_Uuid == evt.
uuids[i] )
69 if ( parents.size() > 0 )
79 fgets( str,
sizeof( str ) - 1, f );
80 return wxString( str );
85 m_mode(
PNS::ROUTER_MODE::PNS_MODE_ROUTE_SINGLE )
93 const wxString type =
static_cast<wxString
>( aJSON.at(
"type" ).get<wxString>() );
95 if( type == wxT(
"segment") )
98 sh->SetSeg(
SEG( aJSON.at(
"start" ).get<
VECTOR2I>(), aJSON.at(
"end" ).get<
VECTOR2I>() ) );
99 sh->SetWidth( aJSON.at(
"width" ).get<
int>() );
102 else if( type == wxT(
"circle") )
105 sh->SetCenter( aJSON.at(
"center" ).get<
VECTOR2I>() );
106 sh->SetRadius( aJSON.at(
"radius" ).get<
int>() );
109 else if( type == wxT(
"arc") )
114 int width = aJSON.at(
"width" ).get<
int>();
116 std::shared_ptr<SHAPE_ARC> sh(
new SHAPE_ARC( start, mid,
end, width ) );
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 );
145 a.
x = wxAtoi( aTokens.GetNextToken() );
146 a.
y = wxAtoi( aTokens.GetNextToken() );
147 int radius = wxAtoi( aTokens.GetNextToken() );
157 wxStringTokenizer& aTokens )
159 if( cmd == wxS(
"net" ) )
161 aItem->
SetNet(
m_board->FindNet( wxAtoi( aTokens.GetNextToken() ) ) );
164 else if( cmd == wxS(
"layers" ) )
166 int start = wxAtoi( aTokens.GetNextToken() );
167 int end = wxAtoi( aTokens.GetNextToken() );
177 aItem->
SetNet(
m_board->FindNet( aJSON.at(
"net" ).get<wxString>() ) );
179 PNS_LAYER_RANGE( aJSON.at(
"layers" ).at( 0 ).get<
int>(), aJSON.at(
"layers" ).at( 1 ).get<
int>() ) );
186 std::unique_ptr<PNS::SEGMENT> seg(
new PNS::SEGMENT() );
188 while( aTokens.CountTokens() )
190 wxString cmd = aTokens.GetNextToken();
194 if( cmd == wxS(
"shape" ) )
214 while( aTokens.CountTokens() )
216 wxString cmd = aTokens.GetNextToken();
220 if( cmd == wxS(
"shape" ) )
232 else if( cmd == wxS(
"drill" ) )
234 via->SetDrill( wxAtoi( aTokens.GetNextToken() ) );
244 wxString kind = aJSON.at(
"kind").get<wxString>();
246 if( kind == wxT(
"segment") )
248 auto parsedShape =
parseShape( aJSON.at(
"shape") );
253 auto shape =
static_cast<const SHAPE_SEGMENT*
>( parsedShape.get() );
254 std::unique_ptr<PNS::SEGMENT> seg(
new PNS::SEGMENT( *shape,
nullptr ) );
256 return std::move( seg );
258 else if ( kind == wxT(
"arc" ) )
260 auto parsedShape =
parseShape( aJSON.at(
"shape") );
265 auto shape =
static_cast<const SHAPE_ARC*
>( parsedShape.get() );
266 std::unique_ptr<PNS::ARC> arc(
new PNS::ARC( *shape,
nullptr ) );
268 return std::move( arc );
270 else if ( kind == wxT(
"via" ) )
272 auto parsedShape =
parseShape( aJSON.at(
"shape") );
277 auto shape =
static_cast<const SHAPE_CIRCLE*
>( parsedShape.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);
292 wxString type = aTokens.GetNextToken();
294 if( type == wxS(
"segment" ) )
296 else if( type == wxS(
"via" ) )
307 if( a->
Net() != b->
Net() )
325 if( va->
Pos() != vb->
Pos() )
334 if( sa->
Seg() != sb->
Seg() )
345const std::set<PNS::ITEM*>
deduplicate(
const std::vector<PNS::ITEM*>& items )
347 std::set<PNS::ITEM*> rv;
351 bool isDuplicate =
false;
394 chkAddedItems.erase( chk );
402 if( chkAddedItems.empty() && check.
m_removedIds.empty() )
423 wxFFileOutputStream fp( logFileName.GetFullPath(), wxT(
"wt" ) );
429 aRpt->
Report( wxString::Format( wxT(
"Failed to write log file: %s"), logFileName.GetFullPath() ),
RPT_SEVERITY_ERROR );
434 wxScopedCharBuffer utf8 = logString.ToUTF8();
435 fp.Write( utf8.data(), utf8.length() );
444 wxFileName fname_log( logFileName );
445 fname_log.SetExt( wxT(
"log" ) );
447 wxFileName fname_dump( logFileName );
448 fname_dump.SetExt( wxT(
"dump" ) );
450 if( !boardFileName.IsEmpty() )
452 fname_dump = boardFileName;
455 wxFileName fname_project( logFileName );
456 fname_project.SetExt( wxT(
"kicad_pro" ) );
457 fname_project.MakeAbsolute();
459 wxFileName fname_settings( logFileName );
460 fname_settings.SetExt( wxT(
"settings" ) );
462 aRpt->
Report( wxString::Format( wxT(
"Loading router settings from '%s'" ),
463 fname_settings.GetFullPath() ) );
465 bool ok =
m_routerSettings->LoadFromRawFile( fname_settings.GetFullPath() );
469 aRpt->
Report( wxT(
"Failed to load routing settings. Using defaults." ),
473 aRpt->
Report( wxString::Format( wxT(
"Loading project settings from '%s'" ),
474 fname_settings.GetFullPath() ) );
484 aRpt->
Report( wxString::Format( wxT(
"Loading board snapshot from '%s'"),
485 fname_dump.GetFullPath() ) );
487 m_board.reset( io.
LoadBoard( fname_dump.GetFullPath(),
nullptr,
nullptr ) );
490 std::shared_ptr<DRC_ENGINE> drcEngine(
new DRC_ENGINE );
497 m_board->SynchronizeNetsAndNetClasses(
true );
499 drcEngine->SetBoard(
m_board.get() );
500 drcEngine->SetDesignSettings( &bds );
501 drcEngine->SetLogReporter( aRpt );
504 wxFileName fname_rules( logFileName );
507 if( fname_rules.FileExists() )
508 drcEngine->InitEngine( fname_rules );
510 drcEngine->InitEngine( wxFileName() );
514 aRpt->
Report( wxString::Format(
"parse error : %s (%s)\n",
516 parse_error.
What() ),
523 ok =
loadJsonLog( logFileName.GetFullPath(), aRpt,
false );
524 if( !ok && logFileName.FileExists() )
536 wxFFileInputStream fp( aFilename, wxT(
"rt" ) );
537 wxStdInputStream fstream( fp );
542 aRpt->
Report( wxString::Format(
"Loading log from: %s", aFilename ) );
555 nlohmann::json logJson = nlohmann::json::parse( fstream,
nullptr,
559 if( logJson.contains(
"board_hash") )
561 m_boardHash = logJson.at(
"board_hash").get<wxString>();
564 if( logJson.contains(
"test_case_type") )
574 for(
const nlohmann::json& event : logJson.at(
"events" ) )
579 for(
const nlohmann::json& addedItem : logJson.at(
"addedItems" ) )
585 for(
const nlohmann::json& addedItem : logJson.at(
"removedItems" ) )
592 aRpt->
Report( wxString::Format(
"JSON log load: %lu events, %lu added, %lu removed\n",
m_events.size(),
599 catch(
const std::exception& exc )
614 FILE* f = fopen( aFilename.c_str(),
"rb" );
616 aRpt->
Report( wxString::Format(
"Loading log from '%s'", aFilename ) );
629 wxStringTokenizer tokens( line );
631 if( !tokens.CountTokens() )
634 wxString cmd = tokens.GetNextToken();
636 if( cmd == wxT(
"mode" ) )
640 else if( cmd == wxT(
"event" ) )
644 else if( cmd == wxT(
"added" ) )
649 else if( cmd == wxT(
"removed" ) )
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
bool m_UseConnectedTrackWidth
Design Rule Checker object that performs all the DRC tests.
virtual const wxString What() const
A composite of Problem() and Where()
virtual const wxString Problem() const
what was the problem?
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.
void SetLayers(const PNS_LAYER_RANGE &aLayers)
const PNS_LAYER_RANGE & Layers() const
virtual NET_HANDLE Net() const
PnsKind Kind() const
Return the type (kind) of the item.
void SetNet(NET_HANDLE aNet)
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,...
int Width() const override
int Diameter(int aLayer) const
const VECTOR2I & Pos() const
static constexpr int ALL_LAYERS
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)
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.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
const VECTOR2I GetCenter() const
static const std::string DesignRulesFileExtension
Push and Shove diff pair dimensions (gap) settings dialog.
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)
SHAPE_TYPE
Lists all supported shapes.
A filename or source description, a problem input line, a line number, a byte offset,...
std::vector< KIID > uuids
std::optional< wxString > m_BoardHash
std::optional< TEST_CASE_TYPE > m_TestCaseType
std::vector< ITEM * > m_AddedItems
std::vector< EVENT_ENTRY > m_Events
std::set< KIID > m_RemovedItems
std::vector< ITEM * > m_Heads
std::set< KIID > m_removedIds
bool Compare(const COMMIT_STATE &aOther)
std::vector< PNS::ITEM * > m_addedItems
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.