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 item = aLog->ItemById( evt );
111 ITEM* ritem = item ? m_router->GetWorld()->FindItemByParent( item ) : nullptr;
112 int routingLayer = ritem ? ritem->Layers().Start() : F_Cu;
113
114 eventIdx++;
115
116 switch( evt.type )
117 {
119 {
120 PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
121 m_iface->SetStartLayer( routingLayer );
122 m_iface->ImportSizes( sizes, ritem, nullptr );
123 m_router->UpdateSizes( sizes );
124
125 m_debugDecorator->NewStage( "route-start", 0, PNSLOGINFO );
126 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
127
128 auto msg = wxString::Format( "event [%d/%d]: route-start (%d, %d)", eventIdx,
129 totalEvents, evt.p.x, evt.p.y );
130
132 m_reporter->Report( msg );
133
134 m_router->StartRouting( evt.p, ritem, routingLayer );
135 break;
136 }
137
139 {
140 PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
141 m_iface->SetStartLayer( routingLayer );
142 m_iface->ImportSizes( sizes, ritem, nullptr );
143 m_router->UpdateSizes( sizes );
144
145 m_debugDecorator->NewStage( "drag-start", 0, PNSLOGINFO );
146 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
147
148 auto msg = wxString::Format( "event [%d/%d]: drag-start (%d, %d)", eventIdx,
149 totalEvents, evt.p.x, evt.p.y );
150
152 m_reporter->Report( msg );
153
154 bool rv = m_router->StartDragging( evt.p, ritem, 0 );
155 break;
156 }
157
158 case LOGGER::EVT_FIX:
159 {
161 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
162 m_debugDecorator->Message( wxString::Format( "fix (%d, %d)", evt.p.x, evt.p.y ) );
163 bool rv = m_router->FixRoute( evt.p, ritem, false, false );
164 printf( " fix -> (%d, %d) ret %d\n", evt.p.x, evt.p.y, rv ? 1 : 0 );
165 break;
166 }
167
169 {
170 m_debugDecorator->NewStage( "unfix", 0, PNSLOGINFO );
171 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
172 m_debugDecorator->Message( wxString::Format( "unfix (%d, %d)", evt.p.x, evt.p.y ) );
173 printf( " unfix\n" );
174 m_router->UndoLastSegment();
175 break;
176 }
177
178 case LOGGER::EVT_MOVE:
179 {
180 m_debugDecorator->NewStage( "move", 0, PNSLOGINFO );
181 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
182
183 auto msg = wxString::Format( "event [%d/%d]: move (%d, %d)", eventIdx, totalEvents, evt.p.x, evt.p.y );
184
186 m_reporter->Report( msg );
187
188 bool ret = m_router->Move( evt.p, ritem );
190 break;
191 }
192
194 {
195 m_debugDecorator->NewStage( "toggle-via", 0, PNSLOGINFO );
196
197 auto msg = wxString::Format( "event [%d/%d]: toggle-via", eventIdx, totalEvents );
198
200 m_reporter->Report( msg );
201
202 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
203 m_router->ToggleViaPlacement();
204 break;
205 }
206
207 default: break;
208 }
209
210 PNS::NODE* node = nullptr;
211
212#if 0
213 if( m_router->GetState() == PNS::ROUTER::ROUTE_TRACK )
214 {
215 m_debugDecorator->BeginGroup( "current route", 0 );
216
217 auto traces = m_router->Placer()->Traces();
218
219 for( const auto& t : traces.CItems() )
220 {
221 const LINE *l = static_cast<LINE*>(t.item);
222 const auto& sh = l->CLine();
223
224 m_debugDecorator->AddItem( l, YELLOW, 0, wxT( "line seg" ) );
225 }
226
228
229 node = m_router->Placer()->CurrentNode( true );
230 }
231 else if( m_router->GetState() == PNS::ROUTER::DRAG_SEGMENT )
232 {
233 node = m_router->GetDragger()->CurrentNode();
234 }
235 if( !node )
236 return;
237
238 NODE::ITEM_VECTOR removed, added;
239
240 node->GetUpdatedItems( removed, added );
241
242 if( ! added.empty() )
243 {
244 bool first = true;
245 m_debugDecorator->BeginGroup( wxT( "node-added-items" ), 0 );
246
247 for( auto t : added )
248 {
249 m_debugDecorator->AddItem( t, MAGENTA, 0, wxT( "seg" ) );
250 }
251
253 }
254#endif
255 }
256
257 wxASSERT_MSG( m_router->Mode() == aLog->GetMode(), "didn't set the router mode correctly?" );
258
259 if( aUpdateExpectedResult )
260 {
261 std::vector<PNS::ITEM*> added, removed, heads;
262 m_router->GetUpdatedItems( removed, added, heads );
263
264 std::set<KIID> removedKIIDs;
265
266 for( auto item : removed )
267 {
268 wxASSERT_MSG( item->Parent() != nullptr, "removed an item with no parent uuid?" );
269
270 if( item->Parent() )
271 removedKIIDs.insert( item->Parent()->m_Uuid );
272 }
273
274 std::vector<std::unique_ptr<PNS::ITEM>> myOwnedItems;
275 PNS_LOG_FILE::COMMIT_STATE routerCommitState;
276 routerCommitState.m_addedItems = added;
277 routerCommitState.m_removedIds = removedKIIDs;
278 routerCommitState.m_heads = heads;
279
280 for( PNS::ITEM* head : heads )
281 myOwnedItems.emplace_back( head );
282
283 aLog->SetExpectedResult( routerCommitState, std::move( myOwnedItems ) );
284
285 int test = 0;
286 }
287}
288
289
291{
292 auto cstate = GetRouterUpdatedItems();
293
294 printf("Comparing %zu added/%zu removed items\n", cstate.m_addedItems.size(), cstate.m_removedIds.size() );
295 return cstate.Compare( aLog->GetExpectedResult() );
296}
297
298
300 m_viewTracker( aViewTracker )
301{
302}
303
305{
306}
307
309{
310 //printf("DBG hide %p\n", aItem);
311 m_viewTracker->HideItem( aItem );
312}
313
314void PNS_LOG_PLAYER_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit,
315 int aFlags )
316{
317 //printf("DBG disp %p\n", aItem);
318 m_viewTracker->DisplayItem( aItem );
319}
320
321
323{
324 if( aNet )
325 return static_cast<NETINFO_ITEM*>( aNet )->GetNetCode();
326 else
327 return -1;
328}
329
330
332{
333 if( aNet )
334 return static_cast<NETINFO_ITEM*>( aNet )->GetNetname();
335 else
336 return wxEmptyString;
337}
338
339
341{
342}
343
345{
346}
347
349{
350 m_currentStage = aStage;
352}
353
355{
356 ENTRY ent;
357 ent.m_isHideOp = true;
358 ent.m_item = aItem;
359 ent.m_ownedItem = nullptr; // I don't own it!
360 m_vitems[m_currentStage].push_back( std::move( ent ) );
361}
362
364{
365 ENTRY ent;
366 ent.m_isHideOp = false;
367 ent.m_item = aItem->Clone();
368 ent.m_ownedItem.reset( ent.m_item ); //delete me when ENTRY is deleted
369 m_vitems[m_currentStage].push_back( std::move( ent ) );
370 //printf("DBG disp cur %d cnt %d\n", m_currentStage, m_vitems[m_currentStage].size() );
371}
372
int Start() const
Definition: pns_layerset.h:82
Handle the data for a net.
Definition: netinfo.h:56
static REPORTER & GetInstance()
Definition: reporter.cpp:119
Base class for PNS router board items.
Definition: pns_item.h:97
virtual ITEM * Clone() const =0
Return a deep copy of the item.
const LAYER_RANGE & Layers() const
Definition: pns_item.h:195
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:136
@ EVT_START_ROUTE
Definition: pns_logger.h:47
@ 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:207
std::vector< ITEM * > ITEM_VECTOR
Definition: pns_node.h:218
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:1416
Contain all persistent settings of the router, such as the mode, optimization effort,...
BOARD_CONNECTED_ITEM * ItemById(const PNS::LOGGER::EVENT_ENTRY &evt)
void SetExpectedResult(const COMMIT_STATE &aCommitState, std::vector< std::unique_ptr< PNS::ITEM > > aParsedItems)
Definition: pns_log_file.h:89
const COMMIT_STATE & GetExpectedResult() const
Definition: pns_log_file.h:87
PNS::ROUTING_SETTINGS * GetRoutingSettings() const
Definition: pns_log_file.h:85
PNS::ROUTER_MODE GetMode() const
Definition: pns_log_file.h:96
std::vector< PNS::LOGGER::EVENT_ENTRY > & Events()
Definition: pns_log_file.h:80
std::shared_ptr< BOARD > GetBoard() const
Definition: pns_log_file.h:83
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
@ F_Cu
Definition: layer_ids.h:64
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