KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 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#include <core/profile.h>
21
23#include "pns_log_file.h"
24#include "pns_log_player.h"
25
27
28#define PNSLOGINFO PNS::DEBUG_DECORATOR::SRC_LOCATION_INFO( __FILE__, __FUNCTION__, __LINE__ )
29
30using namespace PNS;
31
36
37
41
43{
46 m_router.reset( new ROUTER );
47 m_iface->SetBoard( m_board.get() );
48 m_router->SetInterface( m_iface.get() );
49 m_router->ClearWorld();
50 m_router->SyncWorld();
51
52 m_routingSettings.reset( new PNS::ROUTING_SETTINGS( nullptr, "" ) );
53 m_router->LoadSettings( m_routingSettings.get() );
54 m_router->Settings().SetMode( PNS::RM_Walkaround );
55 m_router->Sizes().SetTrackWidth( 250000 );
56
58 m_debugDecorator->Clear();
59 m_iface->SetDebugDecorator( m_debugDecorator );
60}
61
62
64{
66 std::vector<PNS::ITEM*> added, removed, heads;
67 m_router->GetUpdatedItems( removed, added, heads );
68
69 //printf("a %d r %d\n", added.size(), removed.size() );
70 for( auto item : removed )
71 {
72 if( item->Parent() )
73 {
74 state.m_removedIds.insert( item->Parent()->m_Uuid );
75 }
76 }
77
78 for( auto item : added )
79 {
80 state.m_addedItems.push_back( item );
81 }
82
83 // fixme: update the state with the head trace (not supported in current testsuite)
84 // Note: we own the head items (cloned inside GetUpdatedItems) - we need to delete them!
85 for( auto head : heads )
86 delete head;
87
88 return state;
89}
90
91void PNS_LOG_PLAYER::ReplayLog( PNS_LOG_FILE* aLog, int aStartEventIndex, int aFrom, int aTo,
92 bool aUpdateExpectedResult )
93{
94 m_board = aLog->GetBoard();
95
97
98 m_router->LoadSettings( aLog->GetRoutingSettings() );
99
100 int eventIdx = 0;
101 int totalEvents = aLog->Events().size();
102
103 m_router->SetMode( aLog->GetMode() );
104
105 for( auto evt : aLog->Events() )
106 {
107 if( eventIdx < aFrom || ( aTo >= 0 && eventIdx > aTo ) )
108 continue;
109
110 auto items = aLog->ItemsById( evt );
111 PNS::ITEM_SET ritems;
112
113 ITEM* ritem = nullptr;
114
115 if( items.size() && items[0] )
116 ritem = m_router->GetWorld()->FindItemByParent( items[0] );
117
118 int routingLayer = ritem ? ritem->Layers().Start() : evt.layer;
119
120 for( BOARD_CONNECTED_ITEM* item : items )
121 {
122 if( ITEM* routerItem = m_router->GetWorld()->FindItemByParent( item ) )
123 ritems.Add( routerItem );
124 }
125
126 eventIdx++;
127
128 switch( evt.type )
129 {
131 {
132 wxString msg;
133 PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
134 m_iface->SetStartLayerFromPNS( routingLayer );
135 m_iface->ImportSizes( sizes, ritem, nullptr, evt.p );
136 m_router->UpdateSizes( sizes );
137
138 m_debugDecorator->NewStage( "route-start", 0, PNSLOGINFO );
139 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
140
141 PROF_TIMER tmr("route-start");
142 bool status = m_router->StartRouting( evt.p, ritem, routingLayer );
143 tmr.Stop();
144 double msecs = tmr.msecs();
145
146 msg = wxString::Format( "event [%d/%d]: route-start (%d, %d), layer %d, startitem %p status %d time %.0f ms", eventIdx,
147 totalEvents, evt.p.x, evt.p.y, routingLayer, ritem, status ? 1 : 0, msecs);
148
149 m_debugDecorator->Message( msg );
150 m_reporter->Report( msg );
151
152 break;
153 }
154
157 {
158 PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
159 m_iface->SetStartLayerFromPNS( routingLayer );
160 m_iface->ImportSizes( sizes, ritem, nullptr, evt.p );
161 m_router->UpdateSizes( sizes );
162
163 m_debugDecorator->NewStage( "drag-start", 0, PNSLOGINFO );
164 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
165
166
167
168 PROF_TIMER tmr("drag-start");
169 bool rv = m_router->StartDragging( evt.p, ritems, 0 );
170 tmr.Stop();
171 double msecs = tmr.msecs();
172
173
174
175 auto msg = wxString::Format( "event [%d/%d]: drag-start (%d, %d) time %.0f ms", eventIdx,
176 totalEvents, evt.p.x, evt.p.y, msecs );
177
178 m_debugDecorator->Message( msg );
179 m_reporter->Report( msg );
180
181 break;
182 }
183
184 case LOGGER::EVT_FIX:
185 {
186 m_debugDecorator->NewStage( "fix", 0, PNSLOGINFO );
187 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
188 m_debugDecorator->Message( wxString::Format( "fix (%d, %d)", evt.p.x, evt.p.y ) );
189 bool rv = m_router->FixRoute( evt.p, ritem, false, false );
190 printf( " fix -> (%d, %d) ret %d\n", evt.p.x, evt.p.y, rv ? 1 : 0 );
191 break;
192 }
193
195 {
196 m_debugDecorator->NewStage( "unfix", 0, PNSLOGINFO );
197 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
198 m_debugDecorator->Message( wxString::Format( "unfix (%d, %d)", evt.p.x, evt.p.y ) );
199 printf( " unfix\n" );
200 m_router->UndoLastSegment();
201 break;
202 }
203
204 case LOGGER::EVT_MOVE:
205 {
206 m_debugDecorator->NewStage( "move", 0, PNSLOGINFO );
207 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
208
209
210 PROF_TIMER tmr("drag-start");
211 bool ret = m_router->Move( evt.p, ritem );
212 tmr.Stop();
213 double msecs = tmr.msecs();
214
215 auto msg = wxString::Format( "event [%d/%d]: move (%d, %d) time %.0f ms", eventIdx, totalEvents, evt.p.x, evt.p.y, msecs );
216
217 m_debugDecorator->Message( msg );
218 m_reporter->Report( msg );
219 m_debugDecorator->SetCurrentStageStatus( ret );
220 break;
221 }
222
224 {
225 m_debugDecorator->NewStage( "toggle-via", 0, PNSLOGINFO );
226
227 auto msg = wxString::Format( "event [%d/%d]: toggle-via", eventIdx, totalEvents );
228
229 m_debugDecorator->Message( msg );
230 m_reporter->Report( msg );
231
232 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
233 m_router->ToggleViaPlacement();
234 break;
235 }
236
237 default: break;
238 }
239
240 PNS::NODE* node = nullptr;
241
242#if 0
243 if( m_router->GetState() == PNS::ROUTER::ROUTE_TRACK )
244 {
245 m_debugDecorator->BeginGroup( "current route", 0 );
246
247 auto traces = m_router->Placer()->Traces();
248
249 for( const auto& t : traces.CItems() )
250 {
251 const LINE *l = static_cast<LINE*>(t.item);
252 const auto& sh = l->CLine();
253
254 m_debugDecorator->AddItem( l, YELLOW, 0, wxT( "line seg" ) );
255 }
256
257 m_debugDecorator->EndGroup( PNSLOGINFO );
258
259 node = m_router->Placer()->CurrentNode( true );
260 }
261 else if( m_router->GetState() == PNS::ROUTER::DRAG_SEGMENT )
262 {
263 node = m_router->GetDragger()->CurrentNode();
264 }
265 if( !node )
266 return;
267
268 NODE::ITEM_VECTOR removed, added;
269
270 node->GetUpdatedItems( removed, added );
271
272 if( ! added.empty() )
273 {
274 bool first = true;
275 m_debugDecorator->BeginGroup( wxT( "node-added-items" ), 0 );
276
277 for( auto t : added )
278 {
279 m_debugDecorator->AddItem( t, MAGENTA, 0, wxT( "seg" ) );
280 }
281
282 m_debugDecorator->EndGroup();
283 }
284#endif
285 }
286
287 wxASSERT_MSG( m_router->Mode() == aLog->GetMode(), "didn't set the router mode correctly?" );
288
289 if( aUpdateExpectedResult )
290 {
291 std::vector<PNS::ITEM*> added, removed, heads;
292 m_router->GetUpdatedItems( removed, added, heads );
293
294 std::set<KIID> removedKIIDs;
295
296 for( auto item : removed )
297 {
298 // fixme: should we check for that?
299 // wxASSERT_MSG( item->Parent() != nullptr, "removed an item with no parent uuid?" );
300
301 if( item->Parent() )
302 removedKIIDs.insert( item->Parent()->m_Uuid );
303 }
304
305 std::vector<std::unique_ptr<PNS::ITEM>> myOwnedItems;
306 PNS_LOG_FILE::COMMIT_STATE routerCommitState;
307 routerCommitState.m_addedItems = added;
308 routerCommitState.m_removedIds = removedKIIDs;
309 routerCommitState.m_heads = heads;
310
311 for( PNS::ITEM* head : heads )
312 myOwnedItems.emplace_back( head );
313
314 aLog->SetExpectedResult( routerCommitState, std::move( myOwnedItems ) );
315
316 int test = 0;
317 }
318}
319
320
322{
323 auto cstate = GetRouterUpdatedItems();
324 return cstate.Compare( aLog->GetExpectedResult() );
325}
326
327
332
336
338{
339 //printf("DBG hide %p\n", aItem);
340 m_viewTracker->HideItem( aItem );
341}
342
343void PNS_LOG_PLAYER_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit,
344 int aFlags )
345{
346 //printf("DBG disp %p\n", aItem);
347 m_viewTracker->DisplayItem( aItem );
348}
349
350
352{
353 if( aNet )
354 return static_cast<NETINFO_ITEM*>( aNet )->GetNetCode();
355 else
356 return -1;
357}
358
359
361{
362 if( aNet )
363 return static_cast<NETINFO_ITEM*>( aNet )->GetNetname();
364 else
365 return wxEmptyString;
366}
367
368
372
376
378{
379 m_currentStage = aStage;
381}
382
384{
385 ENTRY ent;
386 ent.m_isHideOp = true;
387 ent.m_item = aItem;
388 ent.m_ownedItem = nullptr; // I don't own it!
389 m_vitems[m_currentStage].push_back( std::move( ent ) );
390}
391
393{
394 ENTRY ent;
395 ent.m_isHideOp = false;
396 ent.m_item = aItem->Clone();
397 ent.m_ownedItem.reset( ent.m_item ); //delete me when ENTRY is deleted
398 m_vitems[m_currentStage].push_back( std::move( ent ) );
399 //printf("DBG disp cur %d cnt %d\n", m_currentStage, m_vitems[m_currentStage].size() );
400}
401
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
Handle the data for a net.
Definition netinfo.h:46
static REPORTER & GetInstance()
Definition reporter.cpp:120
void Add(const LINE &aLine)
Base class for PNS router board items.
Definition pns_item.h:98
const PNS_LAYER_RANGE & Layers() const
Definition pns_item.h:212
virtual ITEM * Clone() const =0
Return a deep copy of the item.
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition pns_line.h:62
const SHAPE_LINE_CHAIN & CLine() const
Definition pns_line.h:142
@ EVT_START_MULTIDRAG
Definition pns_logger.h:68
Keep the router "world" - i.e.
Definition pns_node.h:242
std::vector< ITEM * > ITEM_VECTOR
Definition pns_node.h:253
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.
Contain all persistent settings of the router, such as the mode, optimization effort,...
int Start() const
void SetExpectedResult(const COMMIT_STATE &aCommitState, std::vector< std::unique_ptr< PNS::ITEM > > aParsedItems)
const COMMIT_STATE & GetExpectedResult() const
PNS::ROUTING_SETTINGS * GetRoutingSettings() const
PNS::ROUTER_MODE GetMode() const
std::vector< PNS::LOGGER::EVENT_ENTRY > & Events()
std::shared_ptr< BOARD > GetBoard() const
std::vector< BOARD_CONNECTED_ITEM * > ItemsById(const PNS::LOGGER::EVENT_ENTRY &evt)
int GetNetCode(PNS::NET_HANDLE aNet) const override
PNS_LOG_PLAYER_KICAD_IFACE(PNS_LOG_VIEW_TRACKER *aViewTracker)
PNS_LOG_VIEW_TRACKER * m_viewTracker
void HideItem(PNS::ITEM *aItem) override
void DisplayItem(const PNS::ITEM *aItem, int aClearance, bool aEdit=false, int aFlags=0) override
wxString GetNetName(PNS::NET_HANDLE aNet) const override
PNS_TEST_DEBUG_DECORATOR * m_debugDecorator
std::unique_ptr< PNS::ROUTING_SETTINGS > m_routingSettings
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
void ReplayLog(PNS_LOG_FILE *aLog, int aStartEventIndex=0, int aFrom=0, int aTo=-1, bool aUpdateExpectedResult=false)
std::shared_ptr< PNS_LOG_VIEW_TRACKER > m_viewTracker
std::unique_ptr< PNS_LOG_PLAYER_KICAD_IFACE > m_iface
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)
A small class to help profiling.
Definition profile.h:46
void Stop()
Save the time when this function was called, and set the counter stane to stop.
Definition profile.h:86
double msecs(bool aSinceLast=false)
Definition profile.h:147
@ MAGENTA
Definition color4d.h:56
@ YELLOW
Definition color4d.h:63
Push and Shove diff pair dimensions (gap) settings dialog.
@ RM_Walkaround
Only walk around.
void * NET_HANDLE
Definition pns_item.h:55
#define PNSLOGINFO
std::set< KIID > m_removedIds
std::vector< PNS::ITEM * > m_addedItems
std::vector< PNS::ITEM * > m_heads
std::unique_ptr< const PNS::ITEM > m_ownedItem