Open Inventor Release 2023.2.3
 
Loading...
Searching...
No Matches
SoSubEngine.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** Modified by : Gavin Bell (MMM yyyy)
26**=======================================================================*/
27/*=======================================================================
28 *** THE CONTENT OF THIS WORK IS PROPRIETARY TO FEI S.A.S, (FEI S.A.S.), ***
29 *** AND IS DISTRIBUTED UNDER A LICENSE AGREEMENT. ***
30 *** ***
31 *** REPRODUCTION, DISCLOSURE, OR USE, IN WHOLE OR IN PART, OTHER THAN AS ***
32 *** SPECIFIED IN THE LICENSE ARE NOT TO BE UNDERTAKEN EXCEPT WITH PRIOR ***
33 *** WRITTEN AUTHORIZATION OF FEI S.A.S. ***
34 *** ***
35 *** RESTRICTED RIGHTS LEGEND ***
36 *** USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT OF THE CONTENT OF THIS ***
37 *** WORK OR RELATED DOCUMENTATION IS SUBJECT TO RESTRICTIONS AS SET FORTH IN ***
38 *** SUBPARAGRAPH (C)(1) OF THE COMMERCIAL COMPUTER SOFTWARE RESTRICTED RIGHT ***
39 *** CLAUSE AT FAR 52.227-19 OR SUBPARAGRAPH (C)(1)(II) OF THE RIGHTS IN ***
40 *** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 52.227-7013. ***
41 *** ***
42 *** COPYRIGHT (C) 1996-2014 BY FEI S.A.S, ***
43 *** BORDEAUX, FRANCE ***
44 *** ALL RIGHTS RESERVED ***
45**=======================================================================*/
46/*=======================================================================
47** Modified by : VSG (MMM YYYY)
48**=======================================================================*/
49
50
51#ifndef _SO_SUB_ENGINE_
52#define _SO_SUB_ENGINE_
53
58
59
61//
62// Debugging macros called by other macros in this file
63//
64#if defined(_DEBUG)
65#define SO__ENGINE_CHECK_INIT(className) { \
66 if (classTypeId.isBad()) { \
67 SoDebugError::post("SO_ENGINE_CONSTRUCTOR", \
68 "Can't construct an engine of type " \
69 SO__QUOTE(className) \
70 " until initClass() has been called"); \
71 className::initClass(); \
72 } \
73 SoTypedObject::checkDatabase(SO__QUOTE(className), this, className::getClassTypeId(), classTypeId); \
74}
75
76#define SO__ENGINE_CHECK_CONSTRUCT(where) \
77 if (inputData == NULL) { \
78 SoDebugError::post(where, \
79 "Instance not properly constructed.\n" \
80 "Did you forget to put " \
81 "SO_ENGINE_CONSTRUCTOR()" \
82 " in the constructor?"); \
83 inputData = new SoFieldData(parentInputData ? \
84 *parentInputData : NULL); \
85 outputData = new SoEngineOutputData(parentOutputData ? \
86 *parentOutputData : NULL); \
87 }
88
89#else
90#define SO__ENGINE_CHECK_INIT(className) \
91 if (classTypeId.isBad()) { \
92 className::initClass(); \
93 }
94
95#define SO__ENGINE_CHECK_CONSTRUCT(where) \
96 if (inputData == NULL) { \
97 inputData = new SoFieldData(parentInputData ? *parentInputData : NULL); \
98 outputData = new SoEngineOutputData(parentOutputData ? *parentOutputData : NULL); \
99 }
100#endif
101
103//
104// Macros to be called within the class definition header:
105//
106
108//
109// These defines type-identifier and naming variables and methods that
110// all engines and abstract engines must support
111//
112
113#define SO_ENGINE_ABSTRACT_HEADER(className) \
114 public: \
115 \
116 static SoType getClassTypeId(); \
117 \
118 virtual SoType getTypeId() const; \
119 private: \
120 virtual SbBool getIsBuiltIn() const; \
121 \
122 virtual const SoFieldData * getFieldData() const; \
123 \
124 virtual const SoEngineOutputData * getOutputData() const; \
125 private: \
126 static const SoFieldData ** getInputDataPtr(); \
127 static const SoEngineOutputData ** getOutputDataPtr(); \
128 private: \
129 static SoType classTypeId; /* Type id */ \
130 static SbBool isBuiltIn; \
131 static SbBool firstInstance; /* True for first ctor call */ \
132 static SoFieldData *inputData; /* Info on input fields */ \
133 static SoEngineOutputData *outputData; /* Info on outputs */ \
134 static const SoFieldData **parentInputData; /* parent's fields */ \
135 static const SoEngineOutputData **parentOutputData
136
137#define SO_ENGINE_HEADER(className) \
138 \
139 SO_ENGINE_ABSTRACT_HEADER(className); \
140 \
141 private: \
142 /* Creates and returns instance */ \
143 static void *createInstance(SoType* dynamicType = NULL)
144
146//
147// This declares the static variables defined in SO_ENGINE_HEADER
148//
149
150#define SO__ENGINE_ABSTRACT_VARS(className) \
151 SoType className::classTypeId; \
152 SbBool className::isBuiltIn = FALSE; \
153 SbBool className::firstInstance = TRUE; \
154 SoEngineOutputData *className::outputData = NULL; \
155 SoFieldData * className::inputData = NULL; \
156 const SoEngineOutputData **className::parentOutputData = NULL; \
157 const SoFieldData ** className::parentInputData = NULL
158
159#define SO__ENGINE_VARS(className) \
160 SO__ENGINE_ABSTRACT_VARS(className)
161
163//
164// These implement the methods defined in SO_ENGINE_HEADER
165//
166
167#define SO__ENGINE_ABSTRACT_METHODS(className) \
168 SoType \
169 className::getClassTypeId() \
170 { \
171 return classTypeId; \
172 } \
173 \
174 SoType \
175 className::getTypeId() const \
176 { \
177 return classTypeId; \
178 } \
179 \
180 SbBool className::getIsBuiltIn() const \
181 { \
182 return isBuiltIn; \
183 } \
184 \
185 const SoFieldData * \
186 className::getFieldData() const \
187 { \
188 return inputData; \
189 } \
190 \
191 const SoEngineOutputData * \
192 className::getOutputData() const \
193 { \
194 return outputData; \
195 } \
196 const SoFieldData ** \
197 className::getInputDataPtr() \
198 { \
199 return (const SoFieldData **)&inputData; \
200 } \
201 const SoEngineOutputData ** \
202 className::getOutputDataPtr() \
203 { \
204 return (const SoEngineOutputData **)&outputData; \
205 }
206
207#define SO__ENGINE_METHODS(className) \
208 \
209 SO__ENGINE_ABSTRACT_METHODS(className) \
210 \
211 void * \
212 className::createInstance(SoType* ) \
213 { \
214 return (void *)(new className); \
215 }
216
218//
219// Macros to be called within the source file for a engine subclass:
220//
221
222#define SO_ENGINE_SOURCE(className) \
223 SO__ENGINE_VARS(className); \
224 SO__ENGINE_METHODS(className)
225
226#define SO_ENGINE_ABSTRACT_SOURCE(className) \
227 SO__ENGINE_ABSTRACT_VARS(className); \
228 SO__ENGINE_ABSTRACT_METHODS(className)
229
230
231#if defined(_DEBUG)
232#define SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass) \
233 if (parentClass::getClassTypeId().isBad()) { \
234 SoDebugError::post( SO__QUOTE(className)"::initClass", \
235 SO__QUOTE(className)" initialized before parent class " \
236 SO__QUOTE(parentClass)"\n"); \
237 parentClass::initClass(); \
238 }
239#else
240#define SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass) \
241 if (parentClass::getClassTypeId().isBad()) \
242 parentClass::initClass()
243#endif
244
246//
247// Internal initialization macros
248//
249
250#define SO__ENGINE_INIT_CLASS_INTERNAL(className, classPrintName, parentClass) { \
251 SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
252 classTypeId = SoType::createType( parentClass::getClassTypeId(), \
253 classPrintName, \
254 &className::createInstance); \
255 parentInputData = parentClass::getInputDataPtr(); \
256 parentOutputData = parentClass::getOutputDataPtr(); \
257}
258
259#define SO__ENGINE_INIT_CLASS(className, classPrintName, parentClass) \
260 SO__ENGINE_INIT_CLASS_INTERNAL(className, classPrintName, parentClass);
261
262#define SO__ENGINE_INIT_ABSTRACT_CLASS_INTERNAL(className,classPrintName,parentClass) { \
263 SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
264 classTypeId = SoType::createType(parentClass::getClassTypeId(), \
265 classPrintName); \
266 parentInputData = parentClass::getInputDataPtr(); \
267 parentOutputData = parentClass::getOutputDataPtr(); \
268}
269
270#define SO__ENGINE_INIT_ABSTRACT_CLASS(className,classPrintName,parent) \
271 SO__ENGINE_INIT_ABSTRACT_CLASS_INTERNAL(className,classPrintName,parent);
272
274//
275// This initializes the type identifer variables
276// This macro should be called from within initClass(). The parentClass
277// argument should be the class that this subclass is derived from.
278//
279
280#define SO_ENGINE_INIT_CLASS_INTERNAL(className,parentClass,parentPrintClass) { \
281 SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
282 classTypeId = SoType::createType(SoType::fromName(parentPrintClass), \
283 SO__QUOTE(className), \
284 &className::createInstance); \
285 parentInputData = parentClass::getInputDataPtr(); \
286 parentOutputData = parentClass::getOutputDataPtr(); \
287}
288
289#define SO_ENGINE_INIT_CLASS(className,parentClass,parentPrintClass) \
290 SO_ENGINE_INIT_CLASS_INTERNAL(className,parentClass,parentPrintClass);
291
292#define SO_ENGINE_INIT_ABSTRACT_CLASS_INTERNAL(className,parentClass,parentPrintClass) { \
293 SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
294 classTypeId = SoType::createType(SoType::fromName(parentPrintClass), \
295 SO__QUOTE(className)); \
296 parentInputData = parentClass::getInputDataPtr(); \
297 parentOutputData = parentClass::getOutputDataPtr(); \
298}
299
300#define SO_ENGINE_INIT_ABSTRACT_CLASS(className,parent,parentPrintClass) \
301 SO_ENGINE_INIT_ABSTRACT_CLASS_INTERNAL(className,parent,parentPrintClass);
302
303
304#define SO_ENGINE_EXIT_CLASS(className) \
305 SoType::removeType(classTypeId.getName()); \
306 classTypeId = SoType::badType(); \
307 if (inputData) \
308 { \
309 delete inputData; \
310 inputData = NULL;\
311 } \
312 if (outputData) \
313 { \
314 delete outputData;\
315 outputData = NULL; \
316 }\
317 firstInstance = TRUE
318
320//
321// Macro to be called within each constructor
322//
323
324#define SO_ENGINE_CONSTRUCTOR(className) \
325 SoBaseInitializer sbi(this); \
326 SO__ENGINE_CHECK_INIT(className); \
327 if (inputData == NULL) { \
328 inputData = new SoFieldData(parentInputData ? *parentInputData : NULL); \
329 outputData = new SoEngineOutputData(parentOutputData ? *parentOutputData : NULL); \
330 } \
331 else { \
332 firstInstance = FALSE; \
333 }
334
336//
337// This is a boolean value that can be tested
338// in constructors.
339//
340
341#define SO_ENGINE_IS_FIRST_INSTANCE() (firstInstance == TRUE)
342
344//
345// This adds the info for an input to the SoFieldData and sets the
346// default value for it. The parameters are as follows:
347// inputName: the name of the input (as a member)
348// defValue: the default value enclosed in parentheses
349//
350// For example,
351//
352// SO_ENGINE_ADD_INPUT(vector1, (0, 0, 0));
353// SO_ENGINE_ADD_INPUT(triggerTime, (0.0));
354//
355// adds info about inputs named vector1 and triggerTime with the
356// given default values. The inputs must be public member variables
357// of a type derived from SoField.
358//
359
360#define SO_ENGINE_ADD_INPUT(inputName, defValue) { \
361 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \
362 if (firstInstance) \
363 inputData->addField(this, SO__QUOTE(inputName), \
364 &this->inputName); \
365 this->inputName.setValue defValue; \
366 this->inputName.setContainer(this); \
367}
368
369
371//
372// This adds the info for an output to the SoEngineOutputData.
373// The parameters are as follows:
374// fieldName: the name of the output (as a member)
375// type: the type of the output (name of SoField subclass)
376//
377// For example,
378//
379// SO_ENGINE_ADD_OUTPUT(result, SoSFVec3f);
380// SO_ENGINE_ADD_OUTPUT(hour, SoSFInt32);
381//
382// adds info about outputs named result and int32_t that can be hooked up
383// to fields of the given type.
384// The outputs must be public member variables of type SoEngineOutput.
385//
386
387#define SO_ENGINE_ADD_OUTPUT(outputName, type) { \
388 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \
389 if (firstInstance) \
390 outputData->addOutput(this, SO__QUOTE(outputName), \
391 &this->outputName, \
392 type::getClassTypeId()); \
393 this->outputName.setContainer(this); \
394}
395
396
398//
399// This registers a value of an enum type.
400// enumType: the name of the enum type
401// enumValue: the name of a value of that enum type
402//
403// If a engine defines an enum, each of the enum's values
404// should be registered using this macro. For example:
405//
406// [ in MyFunc.h file: ]
407// class MyFunc {
408// ...
409// enum Chipmunk { ALVIN, SIMON, THEODORE };
410// ...
411// }
412//
413// [ in constructor MyFunc::MyFunc(): ]
414// SO_ENGINE_DEFINE_ENUM_VALUE(Chipmunk, ALVIN);
415// SO_ENGINE_DEFINE_ENUM_VALUE(Chipmunk, SIMON);
416// SO_ENGINE_DEFINE_ENUM_VALUE(Chipmunk, THEODORE);
417//
418
419#define SO_ENGINE_DEFINE_ENUM_VALUE(enumType,enumValue) { \
420 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \
421 if (firstInstance) \
422 inputData->addEnumValue(SO__QUOTE(enumType), \
423 SO__QUOTE(enumValue), enumValue); \
424}
425
426
428//
429// This takes care of writing the value to all connected outputs.
430// This should be called in the evaluate() routine.
431//
432
433#define SO_ENGINE_OUTPUT(outputName,type,code) { \
434 if (outputName.isEnabled()) { \
435 for (int _eng_out_i = 0; \
436 _eng_out_i < outputName.getNumConnections(); \
437 _eng_out_i++) { \
438 type *_eng_out_temp = (type *) outputName[_eng_out_i]; \
439 if (!_eng_out_temp->isReadOnly()) { \
440 _eng_out_temp->code; \
441 } \
442 } \
443 } \
444}
445
446
447
448#endif /* _SO_SUB_ENGINE_ */
449
450