Open Inventor Reference
SoSubEngine.h
Go to the documentation of this file.
1/*
2 *
3 * Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * Further, this software is distributed without any warranty that it is
16 * free of the rightful claim of any third person regarding infringement
17 * or the like. Any license provided herein, whether implied or
18 * otherwise, applies only to this software file. Patent licenses, if
19 * any, provided herein do not apply to combinations of this program with
20 * other software, or any other product whatsoever.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
27 * Mountain View, CA 94043, or:
28 *
29 * http://www.sgi.com
30 *
31 * For further information regarding this notice, see:
32 *
33 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
34 *
35 */
36
37
38/*
39 * Copyright (C) 1990,91 Silicon Graphics, Inc.
40 *
41 _______________________________________________________________________
42 ______________ S I L I C O N G R A P H I C S I N C . ____________
43 |
44 | $Revision: 1.1.1.1 $
45 |
46 | Description:
47 | This file defines some macros that implement things common to
48 | subclasses of SoEngine. They may be used to make SoEngine
49 | subclassing easier. In all of the macros, the "className"
50 | parameter refers to the name of the engine subclass.
51 |
52 | Defined macros:
53 |
54 | Within class header:
55 |
56 | SO_ENGINE_HEADER(className)
57 | SO_ENGINE_ABSTRACT_HEADER(className)
58 |
59 | Within class source:
60 |
61 | At file scope:
62 |
63 | SO_ENGINE_SOURCE(className)
64 | SO_ENGINE_ABSTRACT_SOURCE(className)
65 |
66 | Inside the initClass method:
67 |
68 | SO_ENGINE_INIT_CLASS()
69 | SO_ENGINE_INIT_ABSTRACT_CLASS()
70 |
71 | Inside the constructor:
72 |
73 | SO_ENGINE_CONSTRUCTOR(className)
74 | SO_ENGINE_ADD_INPUT(inputName, (defaultValue))
75 | SO_ENGINE_ADD_OUTPUT(outputName, outputType)
76 | SO_ENGINE_DEFINE_ENUM_VALUE(enumType, enumValue)
77 | SO_ENGINE_IS_FIRST_INSTANCE() //!< a boolean value
78 |
79 | //!< the following are defined in <fields/So[SM]fEnum.h>:
80 | SO_ENGINE_SET_SF_ENUM_TYPE(fieldName,enumType)
81 | SO_ENGINE_SET_MF_ENUM_TYPE(fieldName,enumType)
82 |
83 | Inside the evaluate method:
84 |
85 | SO_ENGINE_OUTPUT(outputName, outputType, method)
86 |
87 | Author(s) : Paul S. Strauss, Gavin Bell
88 |
89 ______________ S I L I C O N G R A P H I C S I N C . ____________
90 _______________________________________________________________________
91 */
92
93#ifndef _SO_SUB_ENGINE_
94#define _SO_SUB_ENGINE_
95
100
101
106#ifdef DEBUG
107#define SO__ENGINE_CHECK_INIT(className) \
108 if (classTypeId == SoType::badType()) { \
109 SoDebugError::post("SO_ENGINE_CONSTRUCTOR", \
110 "Can't construct an engine of type " \
111 SO__QUOTE(className), \
112 "until initClass() has been called"); \
113 return; \
114 }
115
116#define SO__ENGINE_CHECK_CONSTRUCT(where) { \
117 if (inputData == NULL) { \
118 SoDebugError::post(where, \
119 "Instance not properly constructed.\n" \
120 "Did you forget to put " \
121 "SO_ENGINE_CONSTRUCTOR()" \
122 " in the constructor?"); \
123 inputData = new SoFieldData(parentInputData ? \
124 *parentInputData : NULL); \
125 outputData = new SoEngineOutputData(parentOutputData ? \
126 *parentOutputData : NULL); \
127 } \
128 }
129
130#else
131#define SO__ENGINE_CHECK_INIT(className)
132#define SO__ENGINE_CHECK_CONSTRUCT(where)
133#endif
134
139
145
146#define SO_ENGINE_ABSTRACT_HEADER(className) \
147 public: \
148 static SoType getClassTypeId() { return classTypeId; } \
149 virtual SoType getTypeId() const; /* Returns type id */ \
150 public: \
151 virtual const SoFieldData * getFieldData() const; \
152 virtual const SoEngineOutputData * getOutputData() const; \
153 protected: \
154 static const SoFieldData ** getInputDataPtr() \
155 { return (const SoFieldData **)&inputData; } \
156 static const SoEngineOutputData ** getOutputDataPtr() \
157 { return (const SoEngineOutputData **)&outputData; } \
158 private: \
159 static SoType classTypeId; /* Type id */ \
160 static bool firstInstance; /* True for first ctor call */ \
161 static SoFieldData *inputData; /* Info on input fields */ \
162 static SoEngineOutputData *outputData; /* Info on outputs */ \
163 static const SoFieldData **parentInputData; /* parent's fields */ \
164 static const SoEngineOutputData **parentOutputData
165
166#define SO_ENGINE_HEADER(className) \
167 \
168 SO_ENGINE_ABSTRACT_HEADER(className); \
169 \
170 private: \
171 static void *createInstance() /* Creates and returns instance */
172
177
178#define SO__ENGINE_ABSTRACT_VARS(className) \
179 SoType className::classTypeId; \
180 bool className::firstInstance=TRUE; \
181 SoEngineOutputData *className::outputData; \
182 SoFieldData * className::inputData; \
183 const SoEngineOutputData **className::parentOutputData; \
184 const SoFieldData ** className::parentInputData
185
186#define SO__ENGINE_VARS(className) \
187 SO__ENGINE_ABSTRACT_VARS(className)
188
193
194#define SO__ENGINE_ABSTRACT_METHODS(className) \
195 \
196 SoType \
197 className::getTypeId() const \
198 { \
199 return classTypeId; \
200 } \
201 \
202 const SoFieldData * \
203 className::getFieldData() const \
204 { \
205 return inputData; \
206 } \
207 \
208 const SoEngineOutputData * \
209 className::getOutputData() const \
210 { \
211 return outputData; \
212 }
213
214#define SO__ENGINE_METHODS(className) \
215 \
216 SO__ENGINE_ABSTRACT_METHODS(className) \
217 \
218 void * \
219 className::createInstance() \
220 { \
221 return (void *)(new className); \
222 }
223
228
229#define SO_ENGINE_SOURCE(className) \
230 SO__ENGINE_VARS(className); \
231 SO__ENGINE_METHODS(className)
232
233#define SO_ENGINE_ABSTRACT_SOURCE(className) \
234 SO__ENGINE_ABSTRACT_VARS(className); \
235 SO__ENGINE_ABSTRACT_METHODS(className)
236
241
242#define SO__ENGINE_INIT_CLASS(className, classPrintName, parentClass) { \
243 classTypeId = \
244 SoType::createType(parentClass::getClassTypeId(), \
245 classPrintName, \
246 &className::createInstance); \
247 parentInputData = parentClass::getInputDataPtr(); \
248 parentOutputData = parentClass::getOutputDataPtr(); \
249 }
250
251#define SO__ENGINE_INIT_ABSTRACT_CLASS(className,classPrintName,parent) { \
252 classTypeId = SoType::createType(parent::getClassTypeId(), \
253 classPrintName); \
254 parentInputData = parent::getInputDataPtr(); \
255 parentOutputData = parent::getOutputDataPtr(); \
256 }
257
264
265#define SO_ENGINE_INIT_CLASS(className,parentClass,parentPrintClass) { \
266 classTypeId = \
267 SoType::createType(SoType::fromName(parentPrintClass), \
268 SO__QUOTE(className), \
269 &className::createInstance); \
270 parentInputData = parentClass::getInputDataPtr(); \
271 parentOutputData = parentClass::getOutputDataPtr(); \
272 }
273
274#define SO_ENGINE_INIT_ABSTRACT_CLASS(className,parent,parentPrintClass) { \
275 classTypeId = SoType::createType(SoType::fromName(parentPrintClass), \
276 SO__QUOTE(className)); \
277 parentInputData = parent::getInputDataPtr(); \
278 parentOutputData = parent::getOutputDataPtr(); \
279 }
280
285
286#define SO_ENGINE_CONSTRUCTOR(className) { \
287 SO__ENGINE_CHECK_INIT(className); \
288 if (inputData == NULL) { \
289 inputData = new SoFieldData(parentInputData ? \
290 *parentInputData : NULL); \
291 outputData = new SoEngineOutputData(parentOutputData ? \
292 *parentOutputData : NULL); \
293 } \
294 else \
295 firstInstance = FALSE; \
296 isBuiltIn = FALSE; \
297 }
298
304
305#define SO_ENGINE_IS_FIRST_INSTANCE() (firstInstance == TRUE)
306
323
324#define SO_ENGINE_ADD_INPUT(inputName, defValue) { \
325 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \
326 if (firstInstance) \
327 inputData->addField(this, SO__QUOTE(inputName), \
328 &this->inputName); \
329 this->inputName.setValue defValue; \
330 this->inputName.setContainer(this); \
331 }
332
349
350#define SO_ENGINE_ADD_OUTPUT(outputName, type) { \
351 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \
352 if (firstInstance) \
353 outputData->addOutput(this, SO__QUOTE(outputName), \
354 &this->outputName, \
355 type::getClassTypeId()); \
356 this->outputName.setContainer(this); \
357 }
358
380
381#define SO_ENGINE_DEFINE_ENUM_VALUE(enumType,enumValue) { \
382 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \
383 if (firstInstance) \
384 inputData->addEnumValue(SO__QUOTE(enumType), \
385 SO__QUOTE(enumValue), enumValue); \
386 }
387
393
394#define SO_ENGINE_OUTPUT(outputName,type,code) { \
395 if (outputName.isEnabled()) { \
396 for (int _eng_out_i = 0; \
397 _eng_out_i < outputName.getNumConnections(); \
398 _eng_out_i++) { \
399 type *_eng_out_temp = (type *) outputName[_eng_out_i]; \
400 if (!_eng_out_temp->isReadOnly()) { \
401 _eng_out_temp->code; \
402 } \
403 } \
404 } \
405 }
406
407
408#endif /* _SO_SUB_ENGINE_ */