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
38
39
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
60 m_debugDecorator->Clear();
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
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 auto msg = wxString::Format( "event [%d/%d]: drag-start (%d, %d)", eventIdx,
167 totalEvents, evt.p.x, evt.p.y );
168
169 m_debugDecorator->Message( msg );
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 {
178 m_debugDecorator->NewStage( "fix", 0, PNSLOGINFO );
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
203 m_debugDecorator->Message( msg );
204 m_reporter->Report( msg );
205
206 bool ret = m_router->Move( evt.p, ritem );
207 m_debugDecorator->SetCurrentStageStatus( ret );
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
217 m_debugDecorator->Message( msg );
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
245 m_debugDecorator->EndGroup( PNSLOGINFO );
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
270 m_debugDecorator->EndGroup();
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
322
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
362
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:54
static REPORTER & GetInstance()
Definition reporter.cpp:96
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:138
@ EVT_START_MULTIDRAG
Definition pns_logger.h:54
Keep the router "world" - i.e.
Definition pns_node.h:232
std::vector< ITEM * > ITEM_VECTOR
Definition pns_node.h:243
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)
@ 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
std::vector< PNS::ITEM * > m_addedItems
std::vector< PNS::ITEM * > m_heads
std::unique_ptr< const PNS::ITEM > m_ownedItem