diff --git a/pcbnew/router/pns_logger.cpp b/pcbnew/router/pns_logger.cpp index 6cc09787f0..7266875ae7 100644 --- a/pcbnew/router/pns_logger.cpp +++ b/pcbnew/router/pns_logger.cpp @@ -43,24 +43,6 @@ void LOGGER::Clear() } -void LOGGER::Save( const std::string& aFilename ) -{ - FILE* f = fopen( aFilename.c_str(), "wb" ); - - wxLogTrace( wxT( "PNS" ), wxT( "Saving to '%s' [%p]" ), aFilename.c_str(), f ); - - for( const EVENT_ENTRY& evt : m_events ) - { - uint64_t id = 0; - - fprintf( f, "event %d %d %d %s\n", evt.type, evt.p.x, evt.p.y, - static_cast( evt.uuid.AsString().c_str() ) ); - } - - fclose( f ); -} - - void LOGGER::Log( LOGGER::EVENT_TYPE evt, const VECTOR2I& pos, const ITEM* item, const SIZES_SETTINGS* sizes ) { @@ -81,4 +63,57 @@ void LOGGER::Log( LOGGER::EVENT_TYPE evt, const VECTOR2I& pos, const ITEM* item, m_events.push_back( ent ); } + +wxString LOGGER::FormatLogFileAsString( int aMode, + const std::vector& aAddedItems, + const std::set& aRemovedItems, + const std::vector& aHeads, + const std::vector& aEvents ) +{ + wxString result = wxString::Format( "mode %d\n", aMode ); + + for( const EVENT_ENTRY& evt : aEvents ) + result += PNS::LOGGER::FormatEvent( evt ); + + for( const KIID& uuid : aRemovedItems ) + result += wxString::Format( "removed %s\n", uuid.AsString().c_str() ); + + for( ITEM* item : aAddedItems ) + result += wxString::Format( "added %s\n", item->Format().c_str() ); + + for( ITEM* item : aHeads ) + result += wxString::Format( "head %s\n", item->Format().c_str() ); + + return result; +} + + +wxString LOGGER::FormatEvent( const LOGGER::EVENT_ENTRY& aEvent ) +{ + return wxString::Format( + "event %d %d %d %s %d %d %d %d %d %d %d\n", aEvent.p.x, aEvent.p.y, aEvent.type, + static_cast( aEvent.uuid.AsString().c_str() ), aEvent.sizes.TrackWidth(), + aEvent.sizes.ViaDiameter(), aEvent.sizes.ViaDrill(), + aEvent.sizes.TrackWidthIsExplicit() ? 1 : 0, aEvent.sizes.GetLayerBottom(), + aEvent.sizes.GetLayerTop(), static_cast( aEvent.sizes.ViaType() ) ); + +} + + +LOGGER::EVENT_ENTRY LOGGER::ParseEvent( const wxString& aLine ) +{ + wxStringTokenizer tokens( aLine ); + wxString cmd = tokens.GetNextToken(); + + wxCHECK_MSG( cmd == wxT( "event" ), EVENT_ENTRY(), "Line doesn't contain an event!" ); + + EVENT_ENTRY evt; + evt.p.x = wxAtoi( tokens.GetNextToken() ); + evt.p.y = wxAtoi( tokens.GetNextToken() ); + evt.type = (PNS::LOGGER::EVENT_TYPE) wxAtoi( tokens.GetNextToken() ); + evt.uuid = KIID( tokens.GetNextToken() ); + + return evt; +} + } diff --git a/pcbnew/router/pns_logger.h b/pcbnew/router/pns_logger.h index 534ffef78f..efc656c394 100644 --- a/pcbnew/router/pns_logger.h +++ b/pcbnew/router/pns_logger.h @@ -63,8 +63,8 @@ public: LOGGER(); ~LOGGER(); - void Save( const std::string& aFilename ); void Clear(); + void Log( EVENT_TYPE evt, const VECTOR2I& pos = VECTOR2I(), const ITEM* item = nullptr, const SIZES_SETTINGS* sizes = nullptr ); @@ -73,6 +73,16 @@ public: return m_events; } + static wxString FormatLogFileAsString( int aMode, + const std::vector& aAddedItems, + const std::set& aRemovedItems, + const std::vector& aHeads, + const std::vector& aEvents ); + + static wxString FormatEvent( const EVENT_ENTRY& aEvent ); + + static EVENT_ENTRY ParseEvent( const wxString& aLine ); + private: std::vector m_events; }; diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index eac47c114d..339ec69f51 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -606,29 +606,10 @@ void ROUTER_TOOL::saveRouterDebugLog() if( !rv ) return; - FILE* f = wxFopen( fname_settings.GetFullPath(), "wb" ); + FILE* settings_f = wxFopen( fname_settings.GetFullPath(), "wb" ); std::string settingsStr = m_router->Settings().FormatAsString(); - fprintf( f, "%s\n", settingsStr.c_str() ); - fclose( f ); - - f = wxFopen( fname_log.GetFullPath(), "wb" ); - - fprintf(f, "mode %d\n", m_router->Mode() ); - - const auto& events = logger->GetEvents(); - - for( const auto& evt : events) - { - fprintf( f, "event %d %d %d %s %d %d %d %d %d %d %d\n", evt.p.x, evt.p.y, evt.type, - static_cast( evt.uuid.AsString().c_str() ), - evt.sizes.TrackWidth(), - evt.sizes.ViaDiameter(), - evt.sizes.ViaDrill(), - evt.sizes.TrackWidthIsExplicit() ? 1: 0, - evt.sizes.GetLayerBottom(), - evt.sizes.GetLayerTop(), - static_cast( evt.sizes.ViaType() ) ); - } + fprintf( settings_f, "%s\n", settingsStr.c_str() ); + fclose( settings_f ); // Export as *.kicad_pcb format, using a strategy which is specifically chosen // as an example on how it could also be used to send it to the system clipboard. @@ -641,27 +622,26 @@ void ROUTER_TOOL::saveRouterDebugLog() prj->GetProjectFile().SaveAs( cwd, "pns" ); prj->GetLocalSettings().SaveAs( cwd, "pns" ); + // Build log file: std::vector added, removed, heads; m_router->GetUpdatedItems( removed, added, heads ); + std::set removedKIIDs; + for( auto item : removed ) { - fprintf(f, "removed %s\n", item->Parent() ? - item->Parent()->m_Uuid.AsString().c_str().AsChar() : - item->Format().c_str() ); + wxASSERT_MSG( item->Parent() != nullptr, "removed an item with no parent uuid?" ); + + if( item->Parent() ) + removedKIIDs.insert( item->Parent()->m_Uuid ); } - for( auto item : added ) - { - fprintf(f, "added %s\n", item->Format().c_str() ); - } - - for( auto item : heads ) - { - fprintf(f, "head %s\n", item->Format().c_str() ); - } - - fclose( f ); + FILE* log_f = wxFopen( fname_log.GetFullPath(), "wb" ); + wxString logString = PNS::LOGGER::FormatLogFileAsString( m_router->Mode(), + added, removedKIIDs, heads, + logger->GetEvents() ); + fprintf( log_f, "%s\n", logString.c_str().AsChar() ); + fclose( log_f ); logger->Clear(); // prevent re-entry } diff --git a/qa/tools/pns/pns_log_file.cpp b/qa/tools/pns/pns_log_file.cpp index 393020ae16..6b08355467 100644 --- a/qa/tools/pns/pns_log_file.cpp +++ b/qa/tools/pns/pns_log_file.cpp @@ -39,7 +39,7 @@ #include <../../tests/common/console_log.h> -BOARD_CONNECTED_ITEM* PNS_LOG_FILE::ItemById( const PNS_LOG_FILE::EVENT_ENTRY& evt ) +BOARD_CONNECTED_ITEM* PNS_LOG_FILE::ItemById( const PNS::LOGGER::EVENT_ENTRY& evt ) { BOARD_CONNECTED_ITEM* parent = nullptr; @@ -236,7 +236,7 @@ bool comparePnsItems( const PNS::ITEM*a , const PNS::ITEM* b ) } -const std::set deduplicate( const std::set& items ) +const std::set deduplicate( const std::vector& items ) { std::set rv; @@ -267,7 +267,7 @@ bool PNS_LOG_FILE::COMMIT_STATE::Compare( const PNS_LOG_FILE::COMMIT_STATE& aOth //printf("pre-compare: %d/%d\n", check.m_addedItems.size(), check.m_removedIds.size() ); //printf("pre-compare (log): %d/%d\n", m_addedItems.size(), m_removedIds.size() ); - for( auto uuid : m_removedIds ) + for( const KIID& uuid : m_removedIds ) { if( check.m_removedIds.find( uuid ) != check.m_removedIds.end() ) { @@ -321,11 +321,15 @@ bool PNS_LOG_FILE::Load( const wxFileName& logFileName, REPORTER* aRpt ) aRpt->Report( wxString::Format( "Loading log from '%s'", fname_log.GetFullPath() ) ); if( !f ) + { + aRpt->Report( wxT( "Failed to load log" ), RPT_SEVERITY_ERROR ); return false; + } while( !feof( f ) ) { - wxStringTokenizer tokens( readLine( f ) ); + wxString line = readLine( f ); + wxStringTokenizer tokens( line ); if( !tokens.CountTokens() ) continue; @@ -338,17 +342,12 @@ bool PNS_LOG_FILE::Load( const wxFileName& logFileName, REPORTER* aRpt ) } else if( cmd == wxT("event") ) { - EVENT_ENTRY evt; - evt.p.x = wxAtoi( tokens.GetNextToken() ); - evt.p.y = wxAtoi( tokens.GetNextToken() ); - evt.type = (PNS::LOGGER::EVENT_TYPE) wxAtoi( tokens.GetNextToken() ); - evt.uuid = KIID( tokens.GetNextToken() ); - m_events.push_back( evt ); + m_events.push_back( PNS::LOGGER::ParseEvent( line ) ); } else if ( cmd == wxT("added") ) { auto item = parseItemFromString( tokens ); - m_commitState.m_addedItems.insert( item ); + m_commitState.m_addedItems.push_back( item ); } else if ( cmd == wxT("removed") ) { diff --git a/qa/tools/pns/pns_log_file.h b/qa/tools/pns/pns_log_file.h index 442bf646e7..5c2cdec09d 100644 --- a/qa/tools/pns/pns_log_file.h +++ b/qa/tools/pns/pns_log_file.h @@ -53,15 +53,7 @@ public: PNS_LOG_FILE(); ~PNS_LOG_FILE() {} - struct EVENT_ENTRY - { - VECTOR2I p; - PNS::LOGGER::EVENT_TYPE type; - const PNS::ITEM* item; - KIID uuid; - }; - - struct COMMIT_STATE + struct COMMIT_STATE { COMMIT_STATE() {}; COMMIT_STATE( const COMMIT_STATE& aOther ) : @@ -72,7 +64,7 @@ public: } std::set m_removedIds; - std::set m_addedItems; + std::vector m_addedItems; bool Compare( const COMMIT_STATE& aOther ); }; @@ -80,9 +72,9 @@ public: // Loads a P&S event log and the associated board file. These two always go together. bool Load( const wxFileName& logFileName, REPORTER* aRpt ); - BOARD_CONNECTED_ITEM* ItemById( const EVENT_ENTRY& evt ); + BOARD_CONNECTED_ITEM* ItemById( const PNS::LOGGER::EVENT_ENTRY& evt ); - std::vector& Events() { return m_events; } + std::vector& Events() { return m_events; } void SetBoard( std::shared_ptr brd ) { m_board = brd; } std::shared_ptr GetBoard() const { return m_board; } @@ -96,7 +88,7 @@ public: private: std::shared_ptr m_settingsMgr; std::unique_ptr m_routerSettings; - std::vector m_events; + std::vector m_events; std::shared_ptr m_board; COMMIT_STATE m_commitState; PNS::ROUTER_MODE m_mode; diff --git a/qa/tools/pns/pns_log_player.cpp b/qa/tools/pns/pns_log_player.cpp index 87c9120af0..3fd62dadc3 100644 --- a/qa/tools/pns/pns_log_player.cpp +++ b/qa/tools/pns/pns_log_player.cpp @@ -79,7 +79,7 @@ const PNS_LOG_FILE::COMMIT_STATE PNS_LOG_PLAYER::GetRouterUpdatedItems() for( auto item : added ) { - state.m_addedItems.insert( item ); + state.m_addedItems.push_back( item ); } // fixme: update the state with the head trace (not supported in current testsuite)