1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2014 CERN
5  * Copyright (C) 2004-2021 KiCad Developers, see change_log.txt for contributors.
6  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
24  */
25 
26 #ifndef __KICAD_TYPEINFO_H
27 #define __KICAD_TYPEINFO_H
28 
29 
30 #ifndef SWIG
31 #include <type_traits>
32 
33 /**
34  * Check if the type of aObject is T.
35  *
36  * @param aObject the object for type check.
37  * @return true, if aObject type equals T.
38  */
39 template <class T, class I>
IsA(const I * aObject)40 bool IsA( const I* aObject )
41 {
42     return aObject && std::remove_pointer<T>::type::ClassOf( aObject );
43 }
44 
45 template <class T, class I>
IsA(const I & aObject)46 bool IsA( const I& aObject )
47 {
48     return std::remove_pointer<T>::type::ClassOf( &aObject );
49 }
50 
51 /**
52  * A lightweight dynamic downcast.
53  *
54  * Cast \a aObject to type Casted*.  Uses #EDA_ITEM::Type() and #EDA_ITEM::ClassOf() to
55  * check if type matches.
56  *
57  * @param aObject object to be casted.
58  * @return down-casted object or NULL if type doesn't match Casted.
59  */
60 template<class Casted, class From>
dyn_cast(From aObject)61 Casted dyn_cast( From aObject )
62 {
63     if( std::remove_pointer<Casted>::type::ClassOf ( aObject ) )
64         return static_cast<Casted>( aObject );
65 
66     return nullptr;
67 }
68 
69 class EDA_ITEM;
70 
71 #endif  // SWIG
72 
73 
74 /**
75  * The set of class identification values stored in #EDA_ITEM::m_structType
76  */
77 enum KICAD_T
78 {
79     NOT_USED = -1, ///< the 3d code uses this value
80 
81     EOT = 0, ///< search types array terminator (End Of Types)
82 
83     TYPE_NOT_INIT = 0,
84     PCB_T,
85     SCREEN_T, ///< not really an item, used to identify a screen
86 
87     // Items in pcb
88     PCB_FOOTPRINT_T,        ///< class FOOTPRINT, a footprint
89     PCB_PAD_T,              ///< class PAD, a pad in a footprint
90     PCB_SHAPE_T,            ///< class PCB_SHAPE, a segment not on copper layers
91     PCB_TEXT_T,             ///< class PCB_TEXT, text on a layer
92     PCB_FP_TEXT_T,          ///< class FP_TEXT, text in a footprint
93     PCB_FP_SHAPE_T,         ///< class FP_SHAPE, a footprint edge
94     PCB_FP_ZONE_T,          ///< class ZONE, managed by a footprint
95     PCB_TRACE_T,            ///< class PCB_TRACK, a track segment (segment on a copper layer)
96     PCB_VIA_T,              ///< class PCB_VIA, a via (like a track segment on a copper layer)
97     PCB_ARC_T,              ///< class PCB_ARC, an arc track segment on a copper layer
98     PCB_MARKER_T,           ///< class PCB_MARKER, a marker used to show something
99     PCB_DIMENSION_T,        ///< class PCB_DIMENSION_BASE: abstract dimension meta-type
100     PCB_DIM_ALIGNED_T,      ///< class PCB_DIM_ALIGNED, a linear dimension (graphic item)
101     PCB_DIM_LEADER_T,       ///< class PCB_DIM_LEADER, a leader dimension (graphic item)
102     PCB_DIM_CENTER_T,       ///< class PCB_DIM_CENTER, a center point marking (graphic item)
103     PCB_DIM_ORTHOGONAL_T,   ///< class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
104     PCB_TARGET_T,           ///< class PCB_TARGET, a target (graphic item)
105     PCB_ZONE_T,             ///< class ZONE, a copper pour area
106     PCB_ITEM_LIST_T,        ///< class BOARD_ITEM_LIST, a list of board items
107     PCB_NETINFO_T,          ///< class NETINFO_ITEM, a description of a net
108     PCB_GROUP_T,            ///< class PCB_GROUP, a set of BOARD_ITEMs
109 
110     PCB_LOCATE_STDVIA_T,
111     PCB_LOCATE_UVIA_T,
112     PCB_LOCATE_BBVIA_T,
113     PCB_LOCATE_TEXT_T,
114     PCB_LOCATE_GRAPHIC_T,
115     PCB_LOCATE_HOLE_T,
116     PCB_LOCATE_PTH_T,
117     PCB_LOCATE_NPTH_T,
118     PCB_LOCATE_BOARD_EDGE_T,
119 
120     // Schematic draw Items.  The order of these items effects the sort order.
121     // It is currently ordered to mimic the old Eeschema locate behavior where
122     // the smallest item is the selected item.
123     SCH_MARKER_T,
124     SCH_JUNCTION_T,
125     SCH_NO_CONNECT_T,
126     SCH_BUS_WIRE_ENTRY_T,
127     SCH_BUS_BUS_ENTRY_T,
128     SCH_LINE_T,
129     SCH_BITMAP_T,
130     SCH_TEXT_T,
131     SCH_LABEL_T,
132     SCH_GLOBAL_LABEL_T,
133     SCH_HIER_LABEL_T,
134     SCH_FIELD_T,
135     SCH_SYMBOL_T,
136     SCH_SHEET_PIN_T,
137     SCH_SHEET_T,
138     SCH_PIN_T,
139 
140     // Be prudent with these types:
141     // they should be used only to locate a specific field type among SCH_FIELD_Ts
142     // N.B. If you add a type here, be sure to add it below to the BaseType()
143     SCH_FIELD_LOCATE_REFERENCE_T,
144     SCH_FIELD_LOCATE_VALUE_T,
145     SCH_FIELD_LOCATE_FOOTPRINT_T,
146     SCH_FIELD_LOCATE_DATASHEET_T,
147 
148     // Same for picking wires and buses from SCH_LINE_T items
149     SCH_LINE_LOCATE_WIRE_T,
150     SCH_LINE_LOCATE_BUS_T,
151     SCH_LINE_LOCATE_GRAPHIC_LINE_T,
152 
153     // Same for picking labels attached to wires and/or buses
154     SCH_LABEL_LOCATE_WIRE_T,
155     SCH_LABEL_LOCATE_BUS_T,
156 
157     // Same for picking symbols which are power symbols
158     SCH_SYMBOL_LOCATE_POWER_T,
159 
160     // matches any type
161     SCH_LOCATE_ANY_T,
162 
163     // General
164     SCH_SCREEN_T,
165 
166     SCHEMATIC_T,
167 
168     /*
169      * Draw items in library symbol.
170      *
171      * The order of these items effects the sort order for items inside the
172      * "DRAW/ENDDRAW" section of the symbol definition in a library file.
173      * If you add a new draw item, type, please make sure you add it so the
174      * sort order is logical.
175      */
176     LIB_SYMBOL_T,
177     LIB_ALIAS_T,
178     LIB_SHAPE_T,
179     LIB_TEXT_T,
180     LIB_PIN_T,
181 
182     /*
183      * Fields are not saved inside the "DRAW/ENDDRAW".  Add new draw item
184      * types before this line.
185      */
186     LIB_FIELD_T,
187 
188     /*
189      * For GerbView: item types:
190      */
191     GERBER_LAYOUT_T,
192     GERBER_DRAW_ITEM_T,
193     GERBER_IMAGE_T,
194 
195     /*
196      * For Pl_Editor: item types:
197      */
198     WSG_LINE_T,
199     WSG_RECT_T,
200     WSG_POLY_T,
201     WSG_TEXT_T,
202     WSG_BITMAP_T,
203     WSG_PAGE_T,
204 
205     // serialized layout used in undo/redo commands
206     WS_PROXY_UNDO_ITEM_T,      // serialized layout used in undo/redo commands
207     WS_PROXY_UNDO_ITEM_PLUS_T, // serialized layout plus page and title block settings
208 
209     /*
210      * FOR PROJECT::_ELEMs
211      */
212     SYMBOL_LIB_TABLE_T,
213     FP_LIB_TABLE_T,
214     SYMBOL_LIBS_T,
215     SEARCH_STACK_T,
216     S3D_CACHE_T,
217 
218     // End value
219     MAX_STRUCT_TYPE_ID
220 };
221 
222 /**
223  * Return the underlying type of the given type.
224  *
225  * This is useful for finding the element type given one of the "non-type" types such as
226  * SCH_LINE_LOCATE_WIRE_T.
227  *
228  * @param aType Given type to resolve.
229  * @return Base type.
230  */
BaseType(const KICAD_T aType)231 constexpr KICAD_T BaseType( const KICAD_T aType )
232 {
233     switch( aType )
234     {
235     case SCH_FIELD_LOCATE_REFERENCE_T:
236     case SCH_FIELD_LOCATE_VALUE_T:
237     case SCH_FIELD_LOCATE_FOOTPRINT_T:
238     case SCH_FIELD_LOCATE_DATASHEET_T:
239         return SCH_FIELD_T;
240 
241     case SCH_LINE_LOCATE_WIRE_T:
242     case SCH_LINE_LOCATE_BUS_T:
243     case SCH_LINE_LOCATE_GRAPHIC_LINE_T:
244         return SCH_LINE_T;
245 
246     case SCH_LABEL_LOCATE_WIRE_T:
247     case SCH_LABEL_LOCATE_BUS_T:
248         return SCH_LABEL_T;
249 
250     case SCH_SYMBOL_LOCATE_POWER_T:
251         return SCH_SYMBOL_T;
252 
253     case PCB_LOCATE_HOLE_T:
254     case PCB_LOCATE_PTH_T:
255     case PCB_LOCATE_NPTH_T:
256         return PCB_LOCATE_HOLE_T;
257 
258     case PCB_DIM_ALIGNED_T:
259     case PCB_DIM_CENTER_T:
260     case PCB_DIM_ORTHOGONAL_T:
261     case PCB_DIM_LEADER_T:
262         return PCB_DIMENSION_T;
263 
264     default:
265         return aType;
266     }
267 }
268 
IsNullType(const KICAD_T aType)269 constexpr bool IsNullType( const KICAD_T aType )
270 {
271     return aType <= 0;
272 }
273 
IsInstantiableType(const KICAD_T aType)274 constexpr bool IsInstantiableType( const KICAD_T aType )
275 {
276     if( IsNullType( aType ) )
277         return false;
278 
279     switch( aType )
280     {
281     case SCH_LOCATE_ANY_T:
282 
283     case SCH_FIELD_LOCATE_REFERENCE_T:
284     case SCH_FIELD_LOCATE_VALUE_T:
285     case SCH_FIELD_LOCATE_FOOTPRINT_T:
286     case SCH_FIELD_LOCATE_DATASHEET_T:
287 
288     case SCH_LINE_LOCATE_WIRE_T:
289     case SCH_LINE_LOCATE_BUS_T:
290     case SCH_LINE_LOCATE_GRAPHIC_LINE_T:
291 
292     case SCH_LABEL_LOCATE_WIRE_T:
293     case SCH_LABEL_LOCATE_BUS_T:
294 
295     case SCH_SYMBOL_LOCATE_POWER_T:
296 
297     case PCB_LOCATE_STDVIA_T:
298     case PCB_LOCATE_UVIA_T:
299     case PCB_LOCATE_BBVIA_T:
300     case PCB_LOCATE_TEXT_T:
301     case PCB_LOCATE_GRAPHIC_T:
302     case PCB_LOCATE_HOLE_T:
303     case PCB_LOCATE_PTH_T:
304     case PCB_LOCATE_NPTH_T:
305     case PCB_LOCATE_BOARD_EDGE_T:
306 
307     case PCB_DIMENSION_T:
308 
309     case SCH_SCREEN_T:
310     case PCB_ITEM_LIST_T:
311         return false;
312 
313     default:
314         break;
315     }
316 
317     return true;
318 
319 }
320 
IsEeschemaType(const KICAD_T aType)321 constexpr bool IsEeschemaType( const KICAD_T aType )
322 {
323     switch( aType )
324     {
325     case SCH_MARKER_T:
326     case SCH_JUNCTION_T:
327     case SCH_NO_CONNECT_T:
328     case SCH_BUS_WIRE_ENTRY_T:
329     case SCH_BUS_BUS_ENTRY_T:
330     case SCH_LINE_T:
331     case SCH_BITMAP_T:
332     case SCH_TEXT_T:
333     case SCH_LABEL_T:
334     case SCH_GLOBAL_LABEL_T:
335     case SCH_HIER_LABEL_T:
336     case SCH_FIELD_T:
337     case SCH_SYMBOL_T:
338     case SCH_SHEET_PIN_T:
339     case SCH_SHEET_T:
340     case SCH_PIN_T:
341 
342     case SCH_FIELD_LOCATE_REFERENCE_T:
343     case SCH_FIELD_LOCATE_VALUE_T:
344     case SCH_FIELD_LOCATE_FOOTPRINT_T:
345     case SCH_FIELD_LOCATE_DATASHEET_T:
346 
347     case SCH_LINE_LOCATE_WIRE_T:
348     case SCH_LINE_LOCATE_BUS_T:
349     case SCH_LINE_LOCATE_GRAPHIC_LINE_T:
350 
351     case SCH_LABEL_LOCATE_WIRE_T:
352     case SCH_LABEL_LOCATE_BUS_T:
353 
354     case SCH_SYMBOL_LOCATE_POWER_T:
355     case SCH_LOCATE_ANY_T:
356 
357     case SCH_SCREEN_T:
358     case SCHEMATIC_T:
359 
360     case LIB_SYMBOL_T:
361     case LIB_ALIAS_T:
362     case LIB_SHAPE_T:
363     case LIB_TEXT_T:
364     case LIB_PIN_T:
365 
366     case LIB_FIELD_T:
367         return true;
368 
369     default:
370         return false;
371     }
372 }
373 
IsPcbnewType(const KICAD_T aType)374 constexpr bool IsPcbnewType( const KICAD_T aType )
375 {
376     switch( aType )
377     {
378     case PCB_T:
379 
380     case PCB_FOOTPRINT_T:
381     case PCB_PAD_T:
382     case PCB_SHAPE_T:
383     case PCB_TEXT_T:
384     case PCB_FP_TEXT_T:
385     case PCB_FP_SHAPE_T:
386     case PCB_FP_ZONE_T:
387     case PCB_TRACE_T:
388     case PCB_VIA_T:
389     case PCB_ARC_T:
390     case PCB_MARKER_T:
391     case PCB_DIMENSION_T:
392     case PCB_DIM_ALIGNED_T:
393     case PCB_DIM_LEADER_T:
394     case PCB_DIM_CENTER_T:
395     case PCB_DIM_ORTHOGONAL_T:
396     case PCB_TARGET_T:
397     case PCB_ZONE_T:
398     case PCB_ITEM_LIST_T:
399     case PCB_NETINFO_T:
400     case PCB_GROUP_T:
401 
402     case PCB_LOCATE_STDVIA_T:
403     case PCB_LOCATE_UVIA_T:
404     case PCB_LOCATE_BBVIA_T:
405     case PCB_LOCATE_TEXT_T:
406     case PCB_LOCATE_GRAPHIC_T:
407     case PCB_LOCATE_HOLE_T:
408     case PCB_LOCATE_PTH_T:
409     case PCB_LOCATE_NPTH_T:
410     case PCB_LOCATE_BOARD_EDGE_T:
411         return true;
412 
413     default:
414         return false;
415     }
416 }
417 
IsGerbviewType(const KICAD_T aType)418 constexpr bool IsGerbviewType( const KICAD_T aType )
419 {
420     switch( aType )
421     {
422     case GERBER_LAYOUT_T:
423     case GERBER_DRAW_ITEM_T:
424     case GERBER_IMAGE_T:
425         return true;
426 
427     default:
428         return false;
429     }
430 }
431 
IsPageLayoutEditorType(const KICAD_T aType)432 constexpr bool IsPageLayoutEditorType( const KICAD_T aType )
433 {
434     switch( aType )
435     {
436     case WSG_LINE_T:
437     case WSG_RECT_T:
438     case WSG_POLY_T:
439     case WSG_TEXT_T:
440     case WSG_BITMAP_T:
441     case WSG_PAGE_T:
442 
443     case WS_PROXY_UNDO_ITEM_T:
444     case WS_PROXY_UNDO_ITEM_PLUS_T:
445         return true;
446 
447     default:
448         return false;
449     }
450 }
451 
IsMiscType(const KICAD_T aType)452 constexpr bool IsMiscType( const KICAD_T aType )
453 {
454     switch( aType )
455     {
456     case SCREEN_T:
457 
458     case SYMBOL_LIB_TABLE_T:
459     case FP_LIB_TABLE_T:
460     case SYMBOL_LIBS_T:
461     case SEARCH_STACK_T:
462     case S3D_CACHE_T:
463         return true;
464 
465     default:
466         return false;
467     }
468 }
469 
IsTypeCorrect(KICAD_T aType)470 constexpr bool IsTypeCorrect( KICAD_T aType )
471 {
472     return IsNullType( aType )
473         || IsEeschemaType( aType )
474         || IsPcbnewType( aType )
475         || IsGerbviewType( aType )
476         || IsPageLayoutEditorType( aType )
477         || IsMiscType( aType );
478 }
479 
IsTypeAvailable(KICAD_T aType)480 constexpr bool IsTypeAvailable( KICAD_T aType )
481 {
482     if( !IsInstantiableType( aType ) )
483         return false;
484 
485     if( IsEeschemaType( aType ) )
486     {
487 #ifdef EESCHEMA
488         return true;
489 #endif // EESCHEMA
490     }
491 
492     if( IsPcbnewType( aType ) )
493     {
494 #ifdef PCBNEW
495         return true;
496 #endif // PCBNEW
497     }
498 
499     if( IsGerbviewType( aType ) )
500     {
501 #ifdef GERBVIEW
502         return true;
503 #endif // GERBVIEW
504     }
505 
506     if( IsPageLayoutEditorType( aType ) )
507     {
508 #ifdef PL_EDITOR
509         return true;
510 #endif // PL_EDITOR
511     }
512 
513     return false;
514 }
515 
516 #endif // __KICAD_TYPEINFO_H
517