KiCad PCB EDA Suite
pns_log_player.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 (C) 2020-2021 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
25#include "pns_log_file.h"
26#include "pns_log_player.h"
27
29
30#define PNSLOGINFO PNS::DEBUG_DECORATOR::SRC_LOCATION_INFO( __FILE__, __FUNCTION__, __LINE__ )
31
32using namespace PNS;
33
35{
37}
38
39
41{
43 delete m_debugDecorator;
44}
45
47{
50 m_router.reset( new ROUTER );
51 m_iface->SetBoard( m_board.get() );
52 m_router->SetInterface( m_iface.get() );
53 m_router->ClearWorld();
54 m_router->SyncWorld();
55 m_router->LoadSettings( new PNS::ROUTING_SETTINGS( nullptr, "" ) );
56 m_router->Settings().SetMode( PNS::RM_Walkaround );
57 m_router->Sizes().SetTrackWidth( 250000 );
58
59 //m_router->Settings().SetOptimizeDraggedTrack( true );
60
63 m_iface->SetDebugDecorator( m_debugDecorator );
64}
65
66
68{
70 std::vector<PNS::ITEM*> added, removed, heads;
71 m_router->GetUpdatedItems( removed, added, heads );
72
73 //printf("a %d r %d\n", added.size(), removed.size() );
74 for( auto item : removed )
75 {
76 state.m_removedIds.insert( item->Parent()->m_Uuid );
77 }
78
79 for( auto item : added )
80 {
81 state.m_addedItems.insert( item );
82 }
83
84 // fixme: update the state with the head trace (not supported in current testsuite)
85
86 return state;
87}
88
89void PNS_LOG_PLAYER::ReplayLog( PNS_LOG_FILE* aLog, int aStartEventIndex, int aFrom, int aTo )
90{
91 m_board = aLog->GetBoard();
92
94
95 m_router->LoadSettings( aLog->GetRoutingSettings() );
96
97 int eventIdx = 0;
98 int totalEvents = aLog->Events().size();
99
100 for( auto evt : aLog->Events() )
101 {
102 if( eventIdx < aFrom || ( aTo >= 0 && eventIdx > aTo ) )
103 continue;
104
105 auto item = aLog->ItemById( evt );
106 ITEM* ritem = item ? m_router->GetWorld()->FindItemByParent( item ) : nullptr;
107
108 eventIdx++;
109
110 switch( evt.type )
111 {
112 case LOGGER::EVT_START_ROUTE:
113 {
114 m_debugDecorator->NewStage( "route-start", 0, PNSLOGINFO );
115 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
116
117 auto msg = wxString::Format( "event [%d/%d]: route-start (%d, %d)", eventIdx, totalEvents, evt.p.x, evt.p.y );
118
120 m_reporter->Report( msg );
121
122 m_router->StartRouting( evt.p, ritem, ritem ? ritem->Layers().Start() : F_Cu );
123 break;
124 }
125
126 case LOGGER::EVT_START_DRAG:
127 {
128 m_debugDecorator->NewStage( "drag-start", 0, PNSLOGINFO );
129 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
130
131 auto msg = wxString::Format( "event [%d/%d]: drag-start (%d, %d)", eventIdx, totalEvents, evt.p.x, evt.p.y );
132
134 m_reporter->Report( msg );
135
136 bool rv = m_router->StartDragging( evt.p, ritem, 0 );
137 break;
138 }
139
140 case LOGGER::EVT_FIX:
141 {
143 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
144 m_debugDecorator->Message( wxString::Format( "fix (%d, %d)", evt.p.x, evt.p.y ) );
145 bool rv = m_router->FixRoute( evt.p, ritem );
146 printf( " fix -> (%d, %d) ret %d\n", evt.p.x, evt.p.y, rv ? 1 : 0 );
147 break;
148 }
149
150 case LOGGER::EVT_UNFIX:
151 {
152 m_debugDecorator->NewStage( "unfix", 0, PNSLOGINFO );
153 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
154 m_debugDecorator->Message( wxString::Format( "unfix (%d, %d)", evt.p.x, evt.p.y ) );
155 printf( " unfix\n" );
156 m_router->UndoLastSegment();
157 break;
158 }
159
160 case LOGGER::EVT_MOVE:
161 {
162 m_debugDecorator->NewStage( "move", 0, PNSLOGINFO );
163 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
164
165 auto msg = wxString::Format( "event [%d/%d]: move (%d, %d)", eventIdx, totalEvents, evt.p.x, evt.p.y );
166
168 m_reporter->Report( msg );
169
170 bool ret = m_router->Move( evt.p, ritem );
172 break;
173 }
174
175 case LOGGER::EVT_TOGGLE_VIA:
176 {
177 m_debugDecorator->NewStage( "toggle-via", 0, PNSLOGINFO );
178
179 auto msg = wxString::Format( "event [%d/%d]: toggle-via", eventIdx, totalEvents );
180
182 m_reporter->Report( msg );
183
184 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
185 m_router->ToggleViaPlacement();
186 break;
187 }
188
189 default: break;
190 }
191
192 PNS::NODE* node = nullptr;
193
194#if 0
195 if( m_router->GetState() == PNS::ROUTER::ROUTE_TRACK )
196 {
197 m_debugDecorator->BeginGroup( "current route", 0 );
198
199 auto traces = m_router->Placer()->Traces();
200
201 for( const auto& t : traces.CItems() )
202 {
203 const LINE *l = static_cast<LINE*>(t.item);
204 const auto& sh = l->CLine();
205
206 m_debugDecorator->AddItem( l, YELLOW, 0, wxT( "line seg" ) );
207 }
208
210
211 node = m_router->Placer()->CurrentNode( true );
212 }
213 else if( m_router->GetState() == PNS::ROUTER::DRAG_SEGMENT )
214 {
215 node = m_router->GetDragger()->CurrentNode();
216 }
217 if( !node )
218 return;
219
220 NODE::ITEM_VECTOR removed, added;
221
222 node->GetUpdatedItems( removed, added );
223
224 if( ! added.empty() )
225 {
226 bool first = true;
227 m_debugDecorator->BeginGroup( wxT( "node-added-items" ), 0 );
228
229 for( auto t : added )
230 {
231 m_debugDecorator->AddItem( t, MAGENTA, 0, wxT( "seg" ) );
232 }
233
235 }
236#endif
237 }
238
239
240}
241
242
244{
245 auto cstate = GetRouterUpdatedItems();
246
247 printf("Comparing %zu added/%zu removed items\n", cstate.m_addedItems.size(), cstate.m_removedIds.size() );
248 return cstate.Compare( aLog->GetExpectedResult() );
249}
250
251
253 m_viewTracker( aViewTracker )
254{
255}
256
258{
259}
260
262{
263 //printf("DBG hide %p\n", aItem);
264 m_viewTracker->HideItem( aItem );
265}
266
267void PNS_LOG_PLAYER_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit, bool aIsHeadTrace )
268{
269 //printf("DBG disp %p\n", aItem);
270 m_viewTracker->DisplayItem( aItem );
271}
272
273
275{
276}
277
279{
280}
281
283{
284 m_currentStage = aStage;
286}
287
289{
290 ENTRY ent;
291 ent.isHideOp = true;
292 ent.item = aItem;
293 m_vitems[m_currentStage].push_back( ent );
294}
295
297{
298 ENTRY ent;
299 ent.isHideOp = false;
300 ent.item = aItem->Clone();
301 m_vitems[m_currentStage].push_back( ent );
302 //printf("DBG disp cur %d cnt %d\n", m_currentStage, m_vitems[m_currentStage].size() );
303}
304
int Start() const
Definition: pns_layerset.h:82
static REPORTER & GetInstance()
Definition: reporter.cpp:117
Base class for PNS router board items.
Definition: pns_item.h:56
virtual ITEM * Clone() const =0
Return a deep copy of the item.
const LAYER_RANGE & Layers() const
Definition: pns_item.h:156
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition: pns_line.h:61
const SHAPE_LINE_CHAIN & CLine() const
Definition: pns_line.h:142
Keep the router "world" - i.e.
Definition: pns_node.h:156
std::vector< ITEM * > ITEM_VECTOR
Definition: pns_node.h:167
void GetUpdatedItems(ITEM_VECTOR &aRemoved, ITEM_VECTOR &aAdded)
Return the list of items removed and added in this branch with respect to the root branch.
Definition: pns_node.cpp:1400
Contain all persistent settings of the router, such as the mode, optimization effort,...
std::vector< EVENT_ENTRY > & Events()
Definition: pns_log_file.h:85
const COMMIT_STATE & GetExpectedResult() const
Definition: pns_log_file.h:92
BOARD_CONNECTED_ITEM * ItemById(const EVENT_ENTRY &evt)
PNS::ROUTING_SETTINGS * GetRoutingSettings() const
Definition: pns_log_file.h:90
std::shared_ptr< BOARD > GetBoard() const
Definition: pns_log_file.h:88
void DisplayItem(const PNS::ITEM *aItem, int aClearance, bool aEdit=false, bool aIsHeadTrace=false) override
PNS_LOG_PLAYER_KICAD_IFACE(PNS_LOG_VIEW_TRACKER *aViewTracker)
PNS_LOG_VIEW_TRACKER * m_viewTracker
void HideItem(PNS::ITEM *aItem) override
PNS_TEST_DEBUG_DECORATOR * m_debugDecorator
std::shared_ptr< BOARD > m_board
const PNS_LOG_FILE::COMMIT_STATE GetRouterUpdatedItems()
REPORTER * m_reporter
bool CompareResults(PNS_LOG_FILE *aLog)
std::unique_ptr< PNS::ROUTER > m_router
std::shared_ptr< PNS_LOG_VIEW_TRACKER > m_viewTracker
std::unique_ptr< PNS_LOG_PLAYER_KICAD_IFACE > m_iface
void ReplayLog(PNS_LOG_FILE *aLog, int aStartEventIndex=0, int aFrom=0, int aTo=-1)
void SetReporter(REPORTER *aReporter)
std::map< int, VIEW_ENTRIES > m_vitems
void DisplayItem(const PNS::ITEM *aItem)
void HideItem(PNS::ITEM *aItem)
std::vector< ENTRY > VIEW_ENTRIES
void SetStage(int aStage)
virtual void AddItem(const PNS::ITEM *aItem, const KIGFX::COLOR4D &aColor, int aOverrideWidth=0, const wxString &aName=wxT(""), const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
virtual void Message(const wxString &msg, const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
virtual void BeginGroup(const wxString &name, int aLevel=0, const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
virtual void EndGroup(const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
virtual void NewStage(const wxString &name, int iter, const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
virtual void Clear() override
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
@ MAGENTA
Definition: color4d.h:60
@ YELLOW
Definition: color4d.h:67
@ F_Cu
Definition: layer_ids.h:64
Push and Shove diff pair dimensions (gap) settings dialog.
@ RM_Walkaround
Only walk around.
#define PNSLOGINFO
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
std::set< KIID > m_removedIds
Definition: pns_log_file.h:74
std::set< PNS::ITEM * > m_addedItems
Definition: pns_log_file.h:75