Coin Logo http://www.sim.no
http://www.coin3d.org

SoSubEngine.h
1#ifndef COIN_SOSUBENGINE_H
2#define COIN_SOSUBENGINE_H
3
4/**************************************************************************\
5 *
6 * This file is part of the Coin 3D visualization library.
7 * Copyright (C) 1998-2007 by Systems in Motion. All rights reserved.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * ("GPL") version 2 as published by the Free Software Foundation.
12 * See the file LICENSE.GPL at the root directory of this source
13 * distribution for additional information about the GNU GPL.
14 *
15 * For using Coin with software that can not be combined with the GNU
16 * GPL, and for taking advantage of the additional benefits of our
17 * support services, please contact Systems in Motion about acquiring
18 * a Coin Professional Edition License.
19 *
20 * See http://www.coin3d.org/ for more information.
21 *
22 * Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY.
23 * http://www.sim.no/ sales@sim.no coin-support@coin3d.org
24 *
25\**************************************************************************/
26
27#include <assert.h>
28#include <Inventor/SbName.h>
29#include <Inventor/SoType.h>
30#include <Inventor/engines/SoEngine.h>
31#include <Inventor/engines/SoOutputData.h>
32#include <Inventor/fields/SoFieldData.h>
33
34// *************************************************************************
35
36//
37// FIXME: document macros. pederb, 20000309
38//
39
40#define PRIVATE_ENGINE_TYPESYSTEM_HEADER( ) \
41public: \
42 static SoType getClassTypeId(void); \
43 virtual SoType getTypeId(void) const; \
44private: \
45 static SoType classTypeId
46
47#define SO_ENGINE_ABSTRACT_HEADER(_classname_) \
48 PRIVATE_ENGINE_TYPESYSTEM_HEADER(); \
49protected: \
50 static const SoFieldData ** getInputDataPtr(void); \
51 static const SoEngineOutputData ** getOutputDataPtr(void); \
52public: \
53 virtual const SoFieldData * getFieldData(void) const; \
54 virtual const SoEngineOutputData * getOutputData(void) const; \
55private: \
56 static unsigned int classinstances; \
57 static SoFieldData * inputdata; \
58 static const SoFieldData ** parentinputdata; \
59 static SoEngineOutputData * outputdata; \
60 static const SoEngineOutputData ** parentoutputdata; \
61 static void atexit_cleanup(void)
62
63#define SO_ENGINE_HEADER(_classname_) \
64 SO_ENGINE_ABSTRACT_HEADER(_classname_); \
65 public: \
66 static void * createInstance(void)
67
68// *************************************************************************
69
70#define PRIVATE_ENGINE_TYPESYSTEM_SOURCE(_class_) \
71SoType _class_::getClassTypeId(void) { return _class_::classTypeId; } \
72SoType _class_::getTypeId(void) const { return _class_::classTypeId; } \
73SoType _class_::classTypeId STATIC_SOTYPE_INIT
74
75#define SO_ENGINE_ABSTRACT_SOURCE(_class_) \
76PRIVATE_ENGINE_TYPESYSTEM_SOURCE(_class_); \
77 \
78unsigned int _class_::classinstances = 0; \
79SoFieldData * _class_::inputdata = NULL; \
80const SoFieldData ** _class_::parentinputdata = NULL; \
81SoEngineOutputData * _class_::outputdata = NULL; \
82const SoEngineOutputData ** _class_::parentoutputdata = NULL; \
83 \
84const SoFieldData ** \
85_class_::getInputDataPtr(void) \
86{ \
87 return (const SoFieldData **)&_class_::inputdata; \
88} \
89 \
90const SoFieldData * \
91_class_::getFieldData(void) const \
92{ \
93 return _class_::inputdata; \
94} \
95 \
96const SoEngineOutputData ** \
97_class_::getOutputDataPtr(void) \
98{ \
99 return (const SoEngineOutputData**)&_class_::outputdata; \
100} \
101 \
102const SoEngineOutputData * \
103_class_::getOutputData(void) const \
104{ \
105 return _class_::outputdata; \
106}
107
108#define SO_ENGINE_SOURCE(_class_) \
109SO_ENGINE_ABSTRACT_SOURCE(_class_); \
110 \
111void * \
112_class_::createInstance(void) \
113{ \
114 return new _class_; \
115} \
116 \
117void \
118_class_::atexit_cleanup(void) \
119{ \
120 delete _class_::inputdata; \
121 delete _class_::outputdata; \
122 _class_::inputdata = NULL; \
123 _class_::outputdata = NULL; \
124 _class_::parentinputdata = NULL; \
125 _class_::parentoutputdata = NULL; \
126 _class_::classTypeId STATIC_SOTYPE_INIT; \
127 _class_::classinstances = 0; \
128}
129
130// *************************************************************************
131
132#define SO_ENGINE_IS_FIRST_INSTANCE() \
133 (classinstances == 1)
134
135#define SO_ENGINE_CONSTRUCTOR(_class_) \
136 do { \
137 SoBase::staticDataLock(); \
138 _class_::classinstances++; \
139 /* Catch attempts to use an engine class which has not been initialized. */ \
140 assert(_class_::classTypeId != SoType::badType()); \
141 /* Initialize a inputdata container for the class only once. */ \
142 if (!_class_::inputdata) { \
143 _class_::inputdata = \
144 new SoFieldData(_class_::parentinputdata ? \
145 *_class_::parentinputdata : NULL); \
146 _class_::outputdata = \
147 new SoEngineOutputData(_class_::parentoutputdata ? \
148 *_class_::parentoutputdata : NULL); \
149 } \
150 /* Extension classes from the application programmers should not be */ \
151 /* considered native. This is important to get the export code to do */ \
152 /* the Right Thing. */ \
153 this->isBuiltIn = FALSE; \
154 SoBase::staticDataUnlock(); \
155 } while (0)
156
157// *************************************************************************
158
159#define PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, _classname_, _createfunc_, _parentclass_) \
160 do { \
161 /* Make sure we only initialize once. */ \
162 assert(_class_::classTypeId == SoType::badType()); \
163 /* Make sure superclass gets initialized before subclass. */ \
164 assert(_parentclass_::getClassTypeId() != SoType::badType()); \
165 \
166 /* Set up entry in the type system. */ \
167 _class_::classTypeId = \
168 SoType::createType(_parentclass_::getClassTypeId(), \
169 _classname_, \
170 _createfunc_); \
171 \
172 /* Store parent's data pointers for later use in the constructor. */ \
173 _class_::parentinputdata = _parentclass_::getInputDataPtr(); \
174 _class_::parentoutputdata = _parentclass_::getOutputDataPtr(); \
175 } while (0)
176
177
178#define SO_ENGINE_INIT_CLASS(_class_, _parentclass_, _parentname_) \
179 do { \
180 const char * classname = SO__QUOTE(_class_); \
181 PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, classname, &_class_::createInstance, _parentclass_); \
182 } while (0)
183
184#define SO_ENGINE_EXIT_CLASS(_class_) \
185 _class_::atexit_cleanup()
186
187#define SO_ENGINE_INIT_ABSTRACT_CLASS(_class_, _parentclass_, _parentname_) \
188 do { \
189 const char * classname = SO__QUOTE(_class_); \
190 PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, classname, NULL, _parentclass_); \
191 } while (0)
192
193// *************************************************************************
194
195#define SO_ENGINE_ADD_INPUT(_input_, _defaultval_) \
196 do { \
197 this->_input_.setValue _defaultval_;\
198 this->_input_.setContainer(this); \
199 inputdata->addField(this, SO__QUOTE(_input_), &this->_input_);\
200 } while (0)
201
202#define SO_ENGINE_ADD_OUTPUT(_output_, _type_) \
203 do { \
204 outputdata->addOutput(this, SO__QUOTE(_output_), \
205 &this->_output_, \
206 _type_::getClassTypeId()); \
207 this->_output_.setContainer(this); \
208 } while(0)
209
210// *************************************************************************
211
212#define SO_ENGINE_DEFINE_ENUM_VALUE(_enumname_, _enumval_) \
213 do { \
214 inputdata->addEnumValue(SO__QUOTE(_enumname_), \
215 SO__QUOTE(_enumval_), _enumval_); \
216 } while (0)
217
218#define SO_ENGINE_OUTPUT(_engineout_, _fieldtype_, _writeop_) \
219 do { \
220 if (_engineout_.isEnabled()) { \
221 /* No fields can be added or removed during this loop, as it */ \
222 /* is a "closed" operation. (The fields are disabled for */ \
223 /* notification while the loop runs). */ \
224 int SO_ENGINE_OUTPUT_numconnections = _engineout_.getNumConnections(); \
225 /* The reason we use the perverted variable names is to */ \
226 /* avoid the possibility of getting _extremely_ hard */ \
227 /* to find bugs when _writeop_ contains the same variable */ \
228 /* names we are using internally in the macro. */ \
229 for (int SO_ENGINE_OUTPUT_i = 0; SO_ENGINE_OUTPUT_i < SO_ENGINE_OUTPUT_numconnections; SO_ENGINE_OUTPUT_i++) { \
230 _fieldtype_ * SO_ENGINE_OUTPUT_field = (_fieldtype_*) _engineout_[SO_ENGINE_OUTPUT_i]; \
231 if (!SO_ENGINE_OUTPUT_field->isReadOnly()) { SO_ENGINE_OUTPUT_field->_writeop_; } \
232 } \
233 /* paranoid assertion */ \
234 assert(_engineout_.getNumConnections() == SO_ENGINE_OUTPUT_numconnections); \
235 } \
236 } while (0)
237
238// *************************************************************************
239
240#define SO_COMPOSE__HEADER(_name_) \
241 SO_ENGINE_HEADER(_name_); \
242 private: \
243 virtual void evaluate(); \
244 protected: \
245 ~_name_();\
246 public: \
247 _name_(); \
248 static void initClass()
249
250// *************************************************************************
251
252#endif // !COIN_SOSUBENGINE_H

Copyright © 1998-2007 by Systems in Motion AS. All rights reserved.

Generated on Wed Jul 19 2023 for Coin by Doxygen. 1.9.7