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_ */