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, 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 m_router->SetMode( aLog->GetMode() );
106
107 for( auto evt : aLog->Events() )
108 {
109 if( eventIdx < aFrom || ( aTo >= 0 && eventIdx > aTo ) )
110 continue;
111
112 auto items = aLog->ItemsById( evt );
113 PNS::ITEM_SET ritems;
114
115 printf("items: %zu\n", items.size() );
116 ITEM* ritem = nullptr;
117
118 if( items.size() && items[0] )
119 ritem = m_router->GetWorld()->FindItemByParent( items[0] );
120
121 int routingLayer = ritem ? ritem->Layers().Start() : evt.layer;
122
123 for( BOARD_CONNECTED_ITEM* item : items )
124 {
125 if( ITEM* routerItem = m_router->GetWorld()->FindItemByParent( item ) )
126 ritems.Add( routerItem );
127 }
128
129 eventIdx++;
130
131 switch( evt.type )
132 {
134 {
135 wxString msg;
136 PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
137 m_iface->SetStartLayerFromPNS( routingLayer );
138 m_iface->ImportSizes( sizes, ritem, nullptr, evt.p );
139 m_router->UpdateSizes( sizes );
140
141 m_debugDecorator->NewStage( "route-start", 0, PNSLOGINFO );
142 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
143
144 bool status = m_router->StartRouting( evt.p, ritem, routingLayer );
145
146 msg = wxString::Format( "event [%d/%d]: route-start (%d, %d), layer %d, startitem %p status %d", eventIdx,
147 totalEvents, evt.p.x, evt.p.y, routingLayer, ritem, status ? 1 : 0 );
148
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 auto msg = wxString::Format( "event [%d/%d]: drag-start (%d, %d)", eventIdx,
167 totalEvents, evt.p.x, evt.p.y );
168
170 m_reporter->Report( msg );
171
172 bool rv = m_router->StartDragging( evt.p, ritems, 0 );
173 break;
174 }
175
176 case LOGGER::EVT_FIX:
177 {
179 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
180 m_debugDecorator->Message( wxString::Format( "fix (%d, %d)", evt.p.x, evt.p.y ) );
181 bool rv = m_router->FixRoute( evt.p, ritem, false, false );
182 printf( " fix -> (%d, %d) ret %d\n", evt.p.x, evt.p.y, rv ? 1 : 0 );
183 break;
184 }
185
187 {
188 m_debugDecorator->NewStage( "unfix", 0, PNSLOGINFO );
189 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
190 m_debugDecorator->Message( wxString::Format( "unfix (%d, %d)", evt.p.x, evt.p.y ) );
191 printf( " unfix\n" );
192 m_router->UndoLastSegment();
193 break;
194 }
195
196 case LOGGER::EVT_MOVE:
197 {
198 m_debugDecorator->NewStage( "move", 0, PNSLOGINFO );
199 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
200
201 auto msg = wxString::Format( "event [%d/%d]: move (%d, %d)", eventIdx, totalEvents, evt.p.x, evt.p.y );
202
204 m_reporter->Report( msg );
205
206 bool ret = m_router->Move( evt.p, ritem );
208 break;
209 }
210
212 {
213 m_debugDecorator->NewStage( "toggle-via", 0, PNSLOGINFO );
214
215 auto msg = wxString::Format( "event [%d/%d]: toggle-via", eventIdx, totalEvents );
216
218 m_reporter->Report( msg );
219
220 m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
221 m_router->ToggleViaPlacement();
222 break;
223 }
224
225 default: break;
226 }
227
228 PNS::NODE* node = nullptr;
229
230#if 0
231 if( m_router->GetState() == PNS::ROUTER::ROUTE_TRACK )
232 {
233 m_debugDecorator->BeginGroup( "current route", 0 );
234
235 auto traces = m_router->Placer()->Traces();
236
237 for( const auto& t : traces.CItems() )
238 {
239 const LINE *l = static_cast<LINE*>(t.item);
240 const auto& sh = l->CLine();
241
242 m_debugDecorator->AddItem( l, YELLOW, 0, wxT( "line seg" ) );
243 }
244
246
247 node = m_router->Placer()->CurrentNode( true );
248 }
249 else if( m_router->GetState() == PNS::ROUTER::DRAG_SEGMENT )
250 {
251 node = m_router->GetDragger()->CurrentNode();
252 }
253 if( !node )
254 return;
255
256 NODE::ITEM_VECTOR removed, added;
257
258 node->GetUpdatedItems( removed, added );
259
260 if( ! added.empty() )
261 {
262 bool first = true;
263 m_debugDecorator->BeginGroup( wxT( "node-added-items" ), 0 );
264
265 for( auto t : added )
266 {
267 m_debugDecorator->AddItem( t, MAGENTA, 0, wxT( "seg" ) );
268 }
269
271 }
272#endif
273 }
274
275 wxASSERT_MSG( m_router->Mode() == aLog->GetMode(), "didn't set the router mode correctly?" );
276
277 if( aUpdateExpectedResult )
278 {
279 std::vector<PNS::ITEM*> added, removed, heads;
280 m_router->GetUpdatedItems( removed, added, heads );
281
282 std::set<KIID> removedKIIDs;
283
284 for( auto item : removed )
285 {
286 // fixme: should we check for that?
287 // wxASSERT_MSG( item->Parent() != nullptr, "removed an item with no parent uuid?" );
288
289 if( item->Parent() )
290 removedKIIDs.insert( item->Parent()->m_Uuid );
291 }
292
293 std::vector<std::unique_ptr<PNS::ITEM>> myOwnedItems;
294 PNS_LOG_FILE::COMMIT_STATE routerCommitState;
295 routerCommitState.m_addedItems = added;
296 routerCommitState.m_removedIds = removedKIIDs;
297 routerCommitState.m_heads = heads;
298
299 for( PNS::ITEM* head : heads )
300 myOwnedItems.emplace_back( head );
301
302 aLog->SetExpectedResult( routerCommitState, std::move( myOwnedItems ) );
303
304 int test = 0;
305 }
306}
307
308
310{
311 auto cstate = GetRouterUpdatedItems();
312
313 printf("Comparing %zu added/%zu removed items\n", cstate.m_addedItems.size(), cstate.m_removedIds.size() );
314 return cstate.Compare( aLog->GetExpectedResult() );
315}
316
317
319 m_viewTracker( aViewTracker )
320{
321}
322
324{
325}
326
328{
329 //printf("DBG hide %p\n", aItem);
330 m_viewTracker->HideItem( aItem );
331}
332
333void PNS_LOG_PLAYER_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit,
334 int aFlags )
335{
336 //printf("DBG disp %p\n", aItem);
337 m_viewTracker->DisplayItem( aItem );
338}
339
340
342{
343 if( aNet )
344 return static_cast<NETINFO_ITEM*>( aNet )->GetNetCode();
345 else
346 return -1;
347}
348
349
351{
352 if( aNet )
353 return static_cast<NETINFO_ITEM*>( aNet )->GetNetname();
354 else
355 return wxEmptyString;
356}
357
358
360{
361}
362
364{
365}
366
368{
369 m_currentStage = aStage;
371}
372
374{
375 ENTRY ent;
376 ent.m_isHideOp = true;
377 ent.m_item = aItem;
378 ent.m_ownedItem = nullptr; // I don't own it!
379 m_vitems[m_currentStage].push_back( std::move( ent ) );
380}
381
383{
384 ENTRY ent;
385 ent.m_isHideOp = false;
386 ent.m_item = aItem->Clone();
387 ent.m_ownedItem.reset( ent.m_item ); //delete me when ENTRY is deleted
388 m_vitems[m_currentStage].push_back( std::move( ent ) );
389 //printf("DBG disp cur %d cnt %d\n", m_currentStage, m_vitems[m_currentStage].size() );
390}
391
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:118
void Add(const LINE &aLine)
Definition: pns_itemset.cpp:33
Base class for PNS router board items.
Definition: pns_item.h:98
const PNS_LAYER_RANGE & Layers() const
Definition: pns_item.h:200
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:1446
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:55
#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