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 (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{
42}
43
45{
48 m_router.reset( new ROUTER );
49 m_iface->SetBoard( m_board.get() );
50 m_router->SetInterface( m_iface.get() );
51 m_router->ClearWorld();
52 m_router->SyncWorld();
53
54 m_routingSettings.reset( new PNS::ROUTING_SETTINGS( nullptr, "" ) );
55 m_router->LoadSettings( m_routingSettings.get() );
56 m_router->Settings().SetMode( PNS::RM_Walkaround );
57 m_router->Sizes().SetTrackWidth( 250000 );
58
61 m_iface->SetDebugDecorator( m_debugDecorator );
62}
63
64
66{
68 std::vector<PNS::ITEM*> added, removed, heads;
69 m_router->GetUpdatedItems( removed, added, heads );
70
71 //printf("a %d r %d\n", added.size(), removed.size() );
72 for( auto item : removed )
73 {
74 if( item->Parent() )
75 {
76 state.m_removedIds.insert( item->Parent()->m_Uuid );
77 }
78 }
79
80 for( auto item : added )
81 {
82 state.m_addedItems.push_back( item );
83 }
84
85 // fixme: update the state with the head trace (not supported in current testsuite)
86 // Note: we own the head items (cloned inside GetUpdatedItems) - we need to delete them!
87 for( auto head : heads )
88 delete head;
89
90 return state;
91}
92
93void PNS_LOG_PLAYER::ReplayLog( PNS_LOG_FILE* aLog, int aStartEventIndex, int aFrom, int aTo,
94 bool aUpdateExpectedResult )
95{
96 m_board = aLog->GetBoard();
97
99
100 m_router->LoadSettings( aLog->GetRoutingSettings() );
101
102 int eventIdx = 0;
103 int totalEvents = aLog->Events().size();
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 printf("items: %zu\n", items.size() );
114 ITEM* ritem = nullptr;
115
116 if( items.size() && items[0] )
117 ritem = m_router->GetWorld()->FindItemByParent( items[0] );
118
119 int routingLayer = ritem ? ritem->Layers().Start() : evt.layer;
120
121 for( BOARD_CONNECTED_ITEM* item : items )
122 {
123 if( ITEM* routerItem = m_router->GetWorld()->FindItemByParent( item ) )
124 ritems.Add( routerItem );
125 }
126
127 eventIdx++;
128
129 switch( evt.type )
130 {
132 {
133 wxString msg;
134 PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
135 m_iface->SetStartLayerFromPNS( routingLayer );
136 m_iface->ImportSizes( sizes, ritem, nullptr, evt.p );
137 m_router->UpdateSizes( sizes );
138
139 m_debugDecorator->NewStage( "route-start", 0, PNSLOGINFO );
140 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
141
142 bool status = m_router->StartRouting( evt.p, ritem, routingLayer );
143
144 msg = wxString::Format( "event [%d/%d]: route-start (%d, %d), layer %d, startitem %p status %d", eventIdx,
145 totalEvents, evt.p.x, evt.p.y, routingLayer, ritem, status ? 1 : 0 );
146
148 m_reporter->Report( msg );
149
150 break;
151 }
152
155 {
156 PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
157 m_iface->SetStartLayerFromPNS( routingLayer );
158 m_iface->ImportSizes( sizes, ritem, nullptr, evt.p );
159 m_router->UpdateSizes( sizes );
160
161 m_debugDecorator->NewStage( "drag-start", 0, PNSLOGINFO );
162 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
163
164 auto msg = wxString::Format( "event [%d/%d]: drag-start (%d, %d)", eventIdx,
165 totalEvents, evt.p.x, evt.p.y );
166
168 m_reporter->Report( msg );
169
170 bool rv = m_router->StartDragging( evt.p, ritems, 0 );
171 break;
172 }
173
174 case LOGGER::EVT_FIX:
175 {
177 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
178 m_debugDecorator->Message( wxString::Format( "fix (%d, %d)", evt.p.x, evt.p.y ) );
179 bool rv = m_router->FixRoute( evt.p, ritem, false, false );
180 printf( " fix -> (%d, %d) ret %d\n", evt.p.x, evt.p.y, rv ? 1 : 0 );
181 break;
182 }
183
185 {
186 m_debugDecorator->NewStage( "unfix", 0, PNSLOGINFO );
187 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
188 m_debugDecorator->Message( wxString::Format( "unfix (%d, %d)", evt.p.x, evt.p.y ) );
189 printf( " unfix\n" );
190 m_router->UndoLastSegment();
191 break;
192 }
193
194 case LOGGER::EVT_MOVE:
195 {
196 m_debugDecorator->NewStage( "move", 0, PNSLOGINFO );
197 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
198
199 auto msg = wxString::Format( "event [%d/%d]: move (%d, %d)", eventIdx, totalEvents, evt.p.x, evt.p.y );
200
202 m_reporter->Report( msg );
203
204 bool ret = m_router->Move( evt.p, ritem );
206 break;
207 }
208
210 {
211 m_debugDecorator->NewStage( "toggle-via", 0, PNSLOGINFO );
212
213 auto msg = wxString::Format( "event [%d/%d]: toggle-via", eventIdx, totalEvents );
214
216 m_reporter->Report( msg );
217
218 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
219 m_router->ToggleViaPlacement();
220 break;
221 }
222
223 default: break;
224 }
225
226 PNS::NODE* node = nullptr;
227
228#if 0
229 if( m_router->GetState() == PNS::ROUTER::ROUTE_TRACK )
230 {
231 m_debugDecorator->BeginGroup( "current route", 0 );
232
233 auto traces = m_router->Placer()->Traces();
234
235 for( const auto& t : traces.CItems() )
236 {
237 const LINE *l = static_cast<LINE*>(t.item);
238 const auto& sh = l->CLine();
239
240 m_debugDecorator->AddItem( l, YELLOW, 0, wxT( "line seg" ) );
241 }
242
244
245 node = m_router->Placer()->CurrentNode( true );
246 }
247 else if( m_router->GetState() == PNS::ROUTER::DRAG_SEGMENT )
248 {
249 node = m_router->GetDragger()->CurrentNode();
250 }
251 if( !node )
252 return;
253
254 NODE::ITEM_VECTOR removed, added;
255
256 node->GetUpdatedItems( removed, added );
257
258 if( ! added.empty() )
259 {
260 bool first = true;
261 m_debugDecorator->BeginGroup( wxT( "node-added-items" ), 0 );
262
263 for( auto t : added )
264 {
265 m_debugDecorator->AddItem( t, MAGENTA, 0, wxT( "seg" ) );
266 }
267
269 }
270#endif
271 }
272
273 wxASSERT_MSG( m_router->Mode() == aLog->GetMode(), "didn't set the router mode correctly?" );
274
275 if( aUpdateExpectedResult )
276 {
277 std::vector<PNS::ITEM*> added, removed, heads;
278 m_router->GetUpdatedItems( removed, added, heads );
279
280 std::set<KIID> removedKIIDs;
281
282 for( auto item : removed )
283 {
284 // fixme: should we check for that?
285 // wxASSERT_MSG( item->Parent() != nullptr, "removed an item with no parent uuid?" );
286
287 if( item->Parent() )
288 removedKIIDs.insert( item->Parent()->m_Uuid );
289 }
290
291 std::vector<std::unique_ptr<PNS::ITEM>> myOwnedItems;
292 PNS_LOG_FILE::COMMIT_STATE routerCommitState;
293 routerCommitState.m_addedItems = added;
294 routerCommitState.m_removedIds = removedKIIDs;
295 routerCommitState.m_heads = heads;
296
297 for( PNS::ITEM* head : heads )
298 myOwnedItems.emplace_back( head );
299
300 aLog->SetExpectedResult( routerCommitState, std::move( myOwnedItems ) );
301
302 int test = 0;
303 }
304}
305
306
308{
309 auto cstate = GetRouterUpdatedItems();
310
311 printf("Comparing %zu added/%zu removed items\n", cstate.m_addedItems.size(), cstate.m_removedIds.size() );
312 return cstate.Compare( aLog->GetExpectedResult() );
313}
314
315
317 m_viewTracker( aViewTracker )
318{
319}
320
322{
323}
324
326{
327 //printf("DBG hide %p\n", aItem);
328 m_viewTracker->HideItem( aItem );
329}
330
331void PNS_LOG_PLAYER_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit,
332 int aFlags )
333{
334 //printf("DBG disp %p\n", aItem);
335 m_viewTracker->DisplayItem( aItem );
336}
337
338
340{
341 if( aNet )
342 return static_cast<NETINFO_ITEM*>( aNet )->GetNetCode();
343 else
344 return -1;
345}
346
347
349{
350 if( aNet )
351 return static_cast<NETINFO_ITEM*>( aNet )->GetNetname();
352 else
353 return wxEmptyString;
354}
355
356
358{
359}
360
362{
363}
364
366{
367 m_currentStage = aStage;
369}
370
372{
373 ENTRY ent;
374 ent.m_isHideOp = true;
375 ent.m_item = aItem;
376 ent.m_ownedItem = nullptr; // I don't own it!
377 m_vitems[m_currentStage].push_back( std::move( ent ) );
378}
379
381{
382 ENTRY ent;
383 ent.m_isHideOp = false;
384 ent.m_item = aItem->Clone();
385 ent.m_ownedItem.reset( ent.m_item ); //delete me when ENTRY is deleted
386 m_vitems[m_currentStage].push_back( std::move( ent ) );
387 //printf("DBG disp cur %d cnt %d\n", m_currentStage, m_vitems[m_currentStage].size() );
388}
389
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:56
static REPORTER & GetInstance()
Definition: reporter.cpp:115
void Add(const LINE &aLine)
Definition: pns_itemset.cpp:33
Base class for PNS router board items.
Definition: pns_item.h:97
const PNS_LAYER_RANGE & Layers() const
Definition: pns_item.h:199
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:138
@ EVT_START_ROUTE
Definition: pns_logger.h:47
@ EVT_START_MULTIDRAG
Definition: pns_logger.h:54
@ EVT_START_DRAG
Definition: pns_logger.h:48
@ EVT_TOGGLE_VIA
Definition: pns_logger.h:52
Keep the router "world" - i.e.
Definition: pns_node.h:231
std::vector< ITEM * > ITEM_VECTOR
Definition: pns_node.h:242
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:1443
Contain all persistent settings of the router, such as the mode, optimization effort,...
int Start() const
Definition: pns_layerset.h:86
void SetExpectedResult(const COMMIT_STATE &aCommitState, std::vector< std::unique_ptr< PNS::ITEM > > aParsedItems)
Definition: pns_log_file.h:90
const COMMIT_STATE & GetExpectedResult() const
Definition: pns_log_file.h:88
PNS::ROUTING_SETTINGS * GetRoutingSettings() const
Definition: pns_log_file.h:86
PNS::ROUTER_MODE GetMode() const
Definition: pns_log_file.h:97
std::vector< PNS::LOGGER::EVENT_ENTRY > & Events()
Definition: pns_log_file.h:81
std::shared_ptr< BOARD > GetBoard() const
Definition: pns_log_file.h:84
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)
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
Push and Shove diff pair dimensions (gap) settings dialog.
@ RM_Walkaround
Only walk around.
void * NET_HANDLE
Definition: pns_item.h:54
#define PNSLOGINFO
std::set< KIID > m_removedIds
Definition: pns_log_file.h:65
std::vector< PNS::ITEM * > m_addedItems
Definition: pns_log_file.h:66
std::vector< PNS::ITEM * > m_heads
Definition: pns_log_file.h:67
std::unique_ptr< const PNS::ITEM > m_ownedItem
const PNS::ITEM * m_item