Open Inventor Release 2023.2.3
 
Loading...
Searching...
No Matches
SoSubElement.h
Go to the documentation of this file.
1/*=======================================================================
2 * Copyright 1991-1996, Silicon Graphics, Inc.
3 * ALL RIGHTS RESERVED
4 *
5 * UNPUBLISHED -- Rights reserved under the copyright laws of the United
6 * States. Use of a copyright notice is precautionary only and does not
7 * imply publication or disclosure.
8 *
9 * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
10 * Use, duplication or disclosure by the Government is subject to restrictions
11 * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
12 * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
13 * in similar or successor clauses in the FAR, or the DOD or NASA FAR
14 * Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
15 * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
16 *
17 * THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
18 * INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
19 * DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
20 * PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
21 * GRAPHICS, INC.
22**=======================================================================*/
23/*=======================================================================
24** Author : Paul S. Strauss (MMM yyyy)
25**=======================================================================*/
26/*=======================================================================
27 *** THE CONTENT OF THIS WORK IS PROPRIETARY TO FEI S.A.S, (FEI S.A.S.), ***
28 *** AND IS DISTRIBUTED UNDER A LICENSE AGREEMENT. ***
29 *** ***
30 *** REPRODUCTION, DISCLOSURE, OR USE, IN WHOLE OR IN PART, OTHER THAN AS ***
31 *** SPECIFIED IN THE LICENSE ARE NOT TO BE UNDERTAKEN EXCEPT WITH PRIOR ***
32 *** WRITTEN AUTHORIZATION OF FEI S.A.S. ***
33 *** ***
34 *** RESTRICTED RIGHTS LEGEND ***
35 *** USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT OF THE CONTENT OF THIS ***
36 *** WORK OR RELATED DOCUMENTATION IS SUBJECT TO RESTRICTIONS AS SET FORTH IN ***
37 *** SUBPARAGRAPH (C)(1) OF THE COMMERCIAL COMPUTER SOFTWARE RESTRICTED RIGHT ***
38 *** CLAUSE AT FAR 52.227-19 OR SUBPARAGRAPH (C)(1)(II) OF THE RIGHTS IN ***
39 *** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 52.227-7013. ***
40 *** ***
41 *** COPYRIGHT (C) 1996-2020 BY FEI S.A.S, ***
42 *** BORDEAUX, FRANCE ***
43 *** ALL RIGHTS RESERVED ***
44**=======================================================================*/
45/*=======================================================================
46** Modified by : VSG (MMM YYYY)
47**=======================================================================*/
48
49
50#ifndef _SO_SUB_ELEMENT_
51#define _SO_SUB_ELEMENT_
52
54
55#if defined(_DEBUG)
56#include <Inventor/SoDB.h>
57#endif
58
60//
61// Macros to be called within the class definition header for a element
62// subclass:
63//
64
66//
67// These define type-identifier and stack index variables and methods
68// that all subclasses must support.
69//
70
71//
72// This one is for abstract element classes.
73//
74
75#define SO_ELEMENT_ABSTRACT_HEADER(className) \
76 public: \
77 \
78 static SoType getClassTypeId(); \
79 \
83 static int getClassStackIndex(); \
84 private: \
85 \
86 static SoElement::SoElementKeyType getClassElementKey(); \
87 virtual SoElement::SoElementKeyType getElementKey() const; \
88 virtual int getClassStackIndexInternal() const; \
89 private: \
90 className(); \
91 private: \
92 static int classStackIndex; \
93 static SoType classTypeId; \
94 static SoElement::SoElementKeyType s_classElementKey;
95
96//
97// This one is for non-abstract element classes.
98//
99#define SO_ELEMENT_HEADER(className) \
100 SO_ELEMENT_ABSTRACT_HEADER(className); \
101 private: \
102 static void *createInstance(SoType* dynamicType = NULL)
103
105//
106// Macros to be called within the source file for a element subclass:
107//
108
110//
111// This declares the static variables defined in SO_ELEMENT_HEADER
112// or SO_ELEMENT_ABSTRACT_HEADER.
113//
114
115#define SO__ELEMENT_ABSTRACT_VARS(className) \
116 SoType className::classTypeId; \
117 int className::classStackIndex = 0; \
118 SoElement::SoElementKeyType className::s_classElementKey = SoElement::badElementKey();
119
120#define SO__ELEMENT_VARS(className) \
121SO__ELEMENT_ABSTRACT_VARS(className)
122
123#if defined(_DEBUG)
124#define SO_ELEMENT_CHECK_INIT(className) { \
125 if (classTypeId.isBad()) { \
126 SoDebugError::post("Element Constructor", \
127 "Can't construct an element of type " \
128 SO__QUOTE(className) \
129 " until initClass() has been called"); \
130 className::initClass(); \
131 } \
132 SoTypedObject::checkDatabase(SO__QUOTE(className), this, className::getClassTypeId(), classTypeId); \
133}
134#else
135#define SO_ELEMENT_CHECK_INIT(className) { \
136 if (classTypeId.isBad()) { \
137 className::initClass(); \
138 } \
139}
140#endif
141
143// Methods on an abstract type
144//
145#define SO__ELEMENT_ABSTRACT_METHODS(className) \
146 \
147className::className() \
148{ \
149 SO_ELEMENT_CHECK_INIT(className); \
150 commonInit() ; \
151} \
152 \
153SoType \
154className::getClassTypeId() \
155{ \
156 return classTypeId; \
157} \
158 \
159int \
160className::getClassStackIndex() \
161{ \
162 return classStackIndex; \
163} \
164 \
165int \
166className::getClassStackIndexInternal() const \
167{ \
168return className::classStackIndex; \
169} \
170 \
171SoElement::SoElementKeyType \
172className::getClassElementKey() \
173{ \
174return className::s_classElementKey; \
175} \
176 \
177SoElement::SoElementKeyType \
178className::getElementKey() const \
179{ \
180return className::s_classElementKey; \
181}
182
183
184
186// Methods on a non-abstract type
187//
188#define SO__ELEMENT_METHODS(className) \
189 \
190className::className() \
191{ \
192 SO_ELEMENT_CHECK_INIT(className); \
193 commonInit() ; \
194 setTypeId(classTypeId); \
195 setStackIndex(classStackIndex); \
196} \
197 \
198void * \
199className::createInstance(SoType *) \
200{ \
201 return new className; \
202} \
203 \
204SoType \
205className::getClassTypeId() \
206{ \
207 return classTypeId; \
208} \
209 \
210int \
211className::getClassStackIndex() \
212{ \
213 return classStackIndex; \
214} \
215 \
216int \
217className::getClassStackIndexInternal() const \
218{ \
219return className::classStackIndex; \
220} \
221 \
222SoElement::SoElementKeyType \
223className::getClassElementKey() \
224{ \
225 return className::s_classElementKey; \
226} \
227 \
228SoElement::SoElementKeyType \
229className::getElementKey() const \
230{ \
231 return className::s_classElementKey; \
232}
233
234
236//
237// These include all the definitions required
238// at file scope
239//
240
241#define SO_ELEMENT_ABSTRACT_SOURCE(className) \
242 SO__ELEMENT_ABSTRACT_VARS(className); \
243 SO__ELEMENT_ABSTRACT_METHODS(className)
244
245#define SO_ELEMENT_SOURCE(className) \
246 SO__ELEMENT_VARS(className); \
247 SO__ELEMENT_METHODS(className)
248
250//
251// This initializes the type identifer variables defined in
252// SO_ELEMENT_HEADER or SO_ELEMENT_ABSTRACT_HEADER. This macro
253// should be called from within initClass(). The parentClass argument
254// should be the class that this subclass is derived from.
255//
256#if defined(_DEBUG)
257#define SO_ELEMENT_INIT_CLASS_CHECK_PARENT(className, parentClass) \
258 if (parentClass::getClassTypeId().isBad()) { \
259 SoDebugError::post( SO__QUOTE(className)"::initClass", \
260 SO__QUOTE(className)" initialized before parent class " \
261 SO__QUOTE(parentClass)"\n"); \
262 parentClass::initClass(); \
263 }
264#else
265#define SO_ELEMENT_INIT_CLASS_CHECK_PARENT(className, parentClass) \
266 if (parentClass::getClassTypeId().isBad()) \
267 parentClass::initClass()
268#endif
269
270#define SO_ELEMENT_INIT_ABSTRACT_CLASS_INTERNAL(className,parentClass) \
271 SO_ELEMENT_INIT_CLASS_CHECK_PARENT(className, parentClass); \
272 classTypeId = SoType::createType( parentClass::getClassTypeId(), \
273 SO__QUOTE(className), \
274 NULL); \
275 classStackIndex = parentClass::getClassStackIndex(); \
276 if(s_classElementKey == SoElement::badElementKey()) \
277 s_classElementKey = createElementKey();
278
279#define SO_ELEMENT_INIT_ABSTRACT_CLASS(className, parentClass) \
280 SO_ELEMENT_INIT_ABSTRACT_CLASS_INTERNAL(className, parentClass);
281
282#define SO_ELEMENT_INIT_CLASS_INTERNAL(className,parentClass) \
283 SO_ELEMENT_INIT_CLASS_CHECK_PARENT(className, parentClass); \
284 classTypeId = SoType::createType( parentClass::getClassTypeId(), \
285 SO__QUOTE(className), \
286 &className::createInstance); \
287 if (classStackIndex == 0) \
288 { \
289 if (parentClass::getClassStackIndex() < 0) \
290 classStackIndex = createStackIndex(classTypeId); \
291 else \
292 classStackIndex = parentClass::getClassStackIndex(); \
293 } \
294 if(s_classElementKey == SoElement::badElementKey()) \
295 s_classElementKey = createElementKey();
296
297#define SO_ELEMENT_INIT_CLASS(className, parentClass) \
298 SO_ELEMENT_INIT_CLASS_INTERNAL(className, parentClass);
299
300#if defined(_DEBUG)
301#define SO_ELEMENT_EXIT_CLASS(className) \
302 if (! SoType::removeType(classTypeId.getName())) { \
303 SoDebugError::post(SO__QUOTE(className)"::exitClass", \
304 "Unable to remove type (%s) for this class. Check exitClass() " \
305 "method is implemented and is called only once.\n", \
306 classTypeId.getName().getString() ); \
307 } \
308 else { \
309 classTypeId = SoType::badType(); \
310 classStackIndex = 0; \
311 }
312#else
313#define SO_ELEMENT_EXIT_CLASS(className) \
314 SoType::removeType(classTypeId.getName()); \
315 classTypeId = SoType::badType(); \
316 classStackIndex = 0
317#endif
318
319#endif /* _SO_SUB_ELEMENT_ */
320
321