KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pns_logger.cpp
Go to the documentation of this file.
1/*
2 * KiRouter - a push-and-(sometimes-)shove PCB router
3 *
4 * Copyright (C) 2013-2014 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * Author: Tomasz Wlostowski <[email protected]>
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "pns_logger.h"
23
24#include <json_common.h>
25
26#include <wx/log.h>
27#include <wx/tokenzr.h>
28#include <locale_io.h>
29
30#include <board_item.h>
31
32#include "pns_item.h"
33#include "pns_via.h"
34#include "pns_segment.h"
35#include "pns_line.h"
36#include "pns_router.h"
37
38
39void to_json( nlohmann::json& aJson, const VECTOR2I& aPoint )
40{
41 aJson = nlohmann::json
42 {
43 { "x", aPoint.x },
44 { "y", aPoint.y }
45 };
46}
47
48
49void from_json( const nlohmann::json& aJson, VECTOR2I& aPoint )
50{
51 aPoint.x = aJson.at( "x" ).get<int>();
52 aPoint.y = aJson.at( "y" ).get<int>();
53}
54
55
56namespace PNS {
57
59{
60}
61
62
66
67
69{
70 m_events.clear();
71}
72
73
74void LOGGER::LogM( LOGGER::EVENT_TYPE evt, const VECTOR2I& pos, std::vector<ITEM*> items,
75 const SIZES_SETTINGS* sizes, int aLayer )
76{
78
79 ent.type = evt;
80 ent.p = pos;
81 ent.layer = aLayer;
82
83 if( sizes )
84 {
85 ent.sizes = *sizes;
86 }
87
88 for( auto& item : items )
89 {
90 if( item && item->Parent() )
91 ent.uuids.push_back( item->Parent()->m_Uuid );
92 }
93
94 m_events.push_back( ent );
95}
96
97
98void LOGGER::Log( LOGGER::EVENT_TYPE evt, const VECTOR2I& pos, const ITEM* item,
99 const SIZES_SETTINGS* sizes, int aLayer )
100{
101 std::vector<ITEM*> items;
102 items.push_back( const_cast<ITEM*>( item ) );
103 LogM( evt, pos, items, sizes, aLayer );
104}
105
106wxString LOGGER::FormatLogFileAsJSON( const LOG_DATA& aLogData )
107{
108 nlohmann::json json;
109
110
111 json["mode"] = aLogData.m_Mode;
112
113 if( aLogData.m_TestCaseType.has_value() )
114 {
115 json["test_case_type"] = static_cast<int>( aLogData.m_TestCaseType.value() );
116 }
117
118 if( aLogData.m_BoardHash.has_value() )
119 {
120 json["board_hash"] = aLogData.m_BoardHash.value();
121 }
122
123 nlohmann::json events = nlohmann::json::array();
124 for( const EVENT_ENTRY& evt : aLogData.m_Events )
125 events.push_back ( LOGGER::FormatEventAsJSON( evt ) );
126 json["events"] = events;
127
128 nlohmann::json removed = nlohmann::json::array();
129 for( const KIID& uuid : aLogData.m_RemovedItems )
130 removed.push_back( uuid );
131 json["removedItems"] = removed;
132
133 nlohmann::json added = nlohmann::json::array();
134 for( ITEM* item : aLogData.m_AddedItems )
135 added.push_back( formatRouterItemAsJSON( item ) );
136 json["addedItems"] = added;
137
138 nlohmann::json headItems = nlohmann::json::array();
139 for( ITEM* item : aLogData.m_Heads )
140 headItems.push_back( formatRouterItemAsJSON( item ) );
141 json["headItems"] = headItems;
142
144
145 std::stringstream buffer;
146 buffer << std::setw( 2 ) << json << std::endl;
147
148 return buffer.str();
149}
150
151
152nlohmann::json LOGGER::FormatEventAsJSON( const LOGGER::EVENT_ENTRY& aEvent )
153{
154 nlohmann::json ret;
155
156 ret["position"] = aEvent.p;
157 ret["type"] = aEvent.type;
158 ret["layer"] = aEvent.layer;
159
160 nlohmann::json uuids = nlohmann::json::array();
161
162 for( int i = 0; i < (int) aEvent.uuids.size(); i++ )
163 uuids.push_back( aEvent.uuids[i].AsString() );
164
165 ret["uuids"] = uuids;
166 ret["sizes"] = LOGGER::formatSizesAsJSON( aEvent.sizes );
167
168 return ret;
169}
170
171
172nlohmann::json LOGGER::formatRouterItemAsJSON( const PNS::ITEM* aItem )
173 {
174 ROUTER* router = ROUTER::GetInstance();
175 ROUTER_IFACE* iface = router ? router->GetInterface() : nullptr;
176
177 nlohmann::json ret;
178
179 ret ["kind"] = aItem->KindStr();
180
181 if( iface )
182 {
183 ret ["net"] = iface->GetNetName( aItem->Net() );
184 }
185
186 ret ["layers"] = nlohmann::json{ aItem->Layers().Start(), aItem->Layers().End() };
187
188 switch( aItem->Kind() )
189 {
190 case ITEM::SEGMENT_T:
191 case ITEM::ARC_T:
192 ret["shape"] = formatShapeAsJSON( aItem->Shape( aItem->Layer() ) );
193 break;
194
195 case ITEM::VIA_T:
196 {
197 auto via = static_cast<const VIA*>( aItem );
198 ret["shape"] = formatShapeAsJSON( aItem->Shape( aItem->Layers().Start() ) ); // JE: pad stacks
199 ret["drill"] = via->Drill();
200 break;
201 }
202 default:
203 break; // currently we don't need to log anything else
204 }
205
206 return ret;
207}
208
209
210nlohmann::json LOGGER::formatSizesAsJSON( const SIZES_SETTINGS& aSizes )
211{
212 return nlohmann::json( {
213
214 { "trackWidth", aSizes.TrackWidth() },
215 { "viaDiameter", aSizes.ViaDiameter() },
216 { "viaDrill", aSizes.ViaDrill() },
217 { "trackWidthIsExplicit", aSizes.TrackWidthIsExplicit() },
218 { "layerBottom", aSizes.GetLayerBottom() },
219 { "layerTop", aSizes.GetLayerTop() },
220 { "viaType", aSizes.ViaType() } } );
221}
222
223
224nlohmann::json LOGGER::formatShapeAsJSON( const SHAPE* aShape )
225{
226 switch( aShape->Type() )
227 {
228 case SH_SEGMENT:
229 {
230 auto seg = static_cast<const SHAPE_SEGMENT*>( aShape );
231 return nlohmann::json( {
232 { "type", "segment" },
233 { "width", seg->GetWidth() },
234 { "start", seg->GetStart() },
235 { "end", seg->GetEnd() }
236 } );
237 }
238 case SH_ARC:
239 {
240 auto arc = static_cast<const SHAPE_ARC*>( aShape );
241 return nlohmann::json( {
242 { "type", "arc" },
243 { "width", arc->GetWidth() },
244 { "start", arc->GetStart() },
245 { "end", arc->GetEnd() },
246 { "mid", arc->GetArcMid() }
247 } );
248 }
249 case SH_CIRCLE:
250 {
251 auto circle = static_cast<const SHAPE_CIRCLE*>( aShape );
252 return nlohmann::json( {
253 { "type", "circle" },
254 { "radius", circle->GetRadius() },
255 { "center", circle->GetCenter() },
256 } );
257 }
258
259 default:
260 break;
261 }
262
263 return nlohmann::json();
264}
265
266
268{
269 wxStringTokenizer tokens( aLine );
270 wxString cmd = tokens.GetNextToken();
271
272 int n_uuids = 0;
273
274 wxCHECK_MSG( cmd == wxT( "event" ), EVENT_ENTRY(), "Line doesn't contain an event!" );
275
276 EVENT_ENTRY evt;
277 evt.p.x = wxAtoi( tokens.GetNextToken() );
278 evt.p.y = wxAtoi( tokens.GetNextToken() );
279 evt.type = (PNS::LOGGER::EVENT_TYPE) wxAtoi( tokens.GetNextToken() );
280 evt.layer = wxAtoi( tokens.GetNextToken() );
281 n_uuids = wxAtoi( tokens.GetNextToken() );
282
283 for( int i = 0; i < n_uuids; i++)
284 evt.uuids.push_back( KIID( tokens.GetNextToken() ) );
285
286 return evt;
287}
288
289
291{
292 EVENT_ENTRY evt;
293
294 evt.p = aJSON.at("position").get<VECTOR2I>();
295 evt.type = static_cast<EVENT_TYPE>( aJSON.at("type").get<int>() );
296 evt.layer = aJSON.at("layer").get<int>();
297
298 for( auto &uuid : aJSON.at("uuids") )
299 evt.uuids.push_back( uuid.get<KIID>() );
300
301 return evt;
302}
303
304
305}
306
Definition kiid.h:48
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:41
Base class for PNS router board items.
Definition pns_item.h:98
virtual const SHAPE * Shape(int aLayer) const
Return the geometrical shape of the item.
Definition pns_item.h:242
const PNS_LAYER_RANGE & Layers() const
Definition pns_item.h:212
virtual NET_HANDLE Net() const
Definition pns_item.h:210
PnsKind Kind() const
Return the type (kind) of the item.
Definition pns_item.h:173
virtual int Layer() const
Definition pns_item.h:216
std::string KindStr() const
Definition pns_item.cpp:304
static wxString FormatLogFileAsJSON(const LOG_DATA &aLogData)
void Log(EVENT_TYPE evt, const VECTOR2I &pos=VECTOR2I(), const ITEM *item=nullptr, const SIZES_SETTINGS *sizes=nullptr, int aLayer=0)
static nlohmann::json formatShapeAsJSON(const SHAPE *aShape)
static EVENT_ENTRY ParseEventFromJSON(const nlohmann::json &aJSON)
static nlohmann::json FormatEventAsJSON(const EVENT_ENTRY &aEvent)
void LogM(EVENT_TYPE evt, const VECTOR2I &pos=VECTOR2I(), std::vector< ITEM * > items={}, const SIZES_SETTINGS *sizes=nullptr, int aLayer=0)
std::vector< EVENT_ENTRY > m_events
Definition pns_logger.h:135
static nlohmann::json formatRouterItemAsJSON(const PNS::ITEM *aItem)
static EVENT_ENTRY ParseEvent(const wxString &aLine)
static nlohmann::json formatSizesAsJSON(const SIZES_SETTINGS &aEvent)
virtual wxString GetNetName(PNS::NET_HANDLE aNet) const =0
ROUTER_IFACE * GetInterface() const
Definition pns_router.h:236
static ROUTER * GetInstance()
bool TrackWidthIsExplicit() const
int Start() const
int End() const
SHAPE_TYPE Type() const
Return the type of the shape.
Definition shape.h:98
An abstract shape on 2D plane.
Definition shape.h:126
nlohmann::json json
Definition gerbview.cpp:50
Push and Shove diff pair dimensions (gap) settings dialog.
void from_json(const nlohmann::json &aJson, VECTOR2I &aPoint)
void to_json(nlohmann::json &aJson, const VECTOR2I &aPoint)
@ SH_CIRCLE
circle
Definition shape.h:50
@ SH_SEGMENT
line segment
Definition shape.h:48
@ SH_ARC
circular arc
Definition shape.h:54
std::vector< FAB_LAYER_COLOR > dummy
Definition pns_logger.h:71
int layer
Definition pns_logger.h:76
SIZES_SETTINGS sizes
Definition pns_logger.h:75
std::vector< KIID > uuids
Definition pns_logger.h:74
EVENT_TYPE type
Definition pns_logger.h:73
VECTOR2I p
Definition pns_logger.h:72
std::optional< wxString > m_BoardHash
Definition pns_logger.h:99
std::optional< TEST_CASE_TYPE > m_TestCaseType
Definition pns_logger.h:104
std::vector< ITEM * > m_AddedItems
Definition pns_logger.h:100
std::vector< EVENT_ENTRY > m_Events
Definition pns_logger.h:103
std::set< KIID > m_RemovedItems
Definition pns_logger.h:101
std::vector< ITEM * > m_Heads
Definition pns_logger.h:102
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687