00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #ifndef _SO_SUB_ENGINE_
00052 #define _SO_SUB_ENGINE_
00053
00054 #include <Inventor/engines/SoEngine.h>
00055 #include <Inventor/engines/SoOutputData.h>
00056 #include <Inventor/errors/SoDebugError.h>
00057 #include <Inventor/fields/SoFieldData.h>
00058
00059
00061
00062
00063
00064 #if defined(_DEBUG)
00065 #define SO__ENGINE_CHECK_INIT(className) { \
00066 if (classTypeId.isBad()) { \
00067 SoDebugError::post("SO_ENGINE_CONSTRUCTOR", \
00068 "Can't construct an engine of type " \
00069 SO__QUOTE(className) \
00070 " until initClass() has been called"); \
00071 className::initClass(); \
00072 } \
00073 SoTypedObject::checkDatabase(SO__QUOTE(className), this, className::getClassTypeId(), classTypeId); \
00074 }
00075
00076 #define SO__ENGINE_CHECK_CONSTRUCT(where) \
00077 if (inputData == NULL) { \
00078 SoDebugError::post(where, \
00079 "Instance not properly constructed.\n" \
00080 "Did you forget to put " \
00081 "SO_ENGINE_CONSTRUCTOR()" \
00082 " in the constructor?"); \
00083 inputData = new SoFieldData(parentInputData ? \
00084 *parentInputData : NULL); \
00085 outputData = new SoEngineOutputData(parentOutputData ? \
00086 *parentOutputData : NULL); \
00087 }
00088
00089 #else
00090 #define SO__ENGINE_CHECK_INIT(className) \
00091 if (classTypeId.isBad()) { \
00092 className::initClass(); \
00093 }
00094
00095 #define SO__ENGINE_CHECK_CONSTRUCT(where) \
00096 if (inputData == NULL) { \
00097 inputData = new SoFieldData(parentInputData ? *parentInputData : NULL); \
00098 outputData = new SoEngineOutputData(parentOutputData ? *parentOutputData : NULL); \
00099 }
00100 #endif
00101
00103
00104
00105
00106
00108
00109
00110
00111
00112
00113 #define SO_ENGINE_ABSTRACT_HEADER(className) \
00114 public: \
00115 \
00116 static SoType getClassTypeId(); \
00117 \
00118 virtual SoType getTypeId() const; \
00119 private: \
00120 virtual SbBool getIsBuiltIn() const; \
00121 \
00122 virtual const SoFieldData * getFieldData() const; \
00123 \
00124 virtual const SoEngineOutputData * getOutputData() const; \
00125 private: \
00126 static const SoFieldData ** getInputDataPtr(); \
00127 static const SoEngineOutputData ** getOutputDataPtr(); \
00128 private: \
00129 static SoType classTypeId; \
00130 static SbBool isBuiltIn; \
00131 static SbBool firstInstance; \
00132 static SoFieldData *inputData; \
00133 static SoEngineOutputData *outputData; \
00134 static const SoFieldData **parentInputData; \
00135 static const SoEngineOutputData **parentOutputData
00136
00137 #define SO_ENGINE_HEADER(className) \
00138 \
00139 SO_ENGINE_ABSTRACT_HEADER(className); \
00140 \
00141 private: \
00142 \
00143 static void *createInstance(SoType* dynamicType = NULL)
00144
00146
00147
00148
00149
00150 #define SO__ENGINE_ABSTRACT_VARS(className) \
00151 SoType className::classTypeId; \
00152 SbBool className::isBuiltIn = FALSE; \
00153 SbBool className::firstInstance = TRUE; \
00154 SoEngineOutputData *className::outputData = NULL; \
00155 SoFieldData * className::inputData = NULL; \
00156 const SoEngineOutputData **className::parentOutputData = NULL; \
00157 const SoFieldData ** className::parentInputData = NULL
00158
00159 #define SO__ENGINE_VARS(className) \
00160 SO__ENGINE_ABSTRACT_VARS(className)
00161
00163
00164
00165
00166
00167 #define SO__ENGINE_ABSTRACT_METHODS(className) \
00168 SoType \
00169 className::getClassTypeId() \
00170 { \
00171 return classTypeId; \
00172 } \
00173 \
00174 SoType \
00175 className::getTypeId() const \
00176 { \
00177 return classTypeId; \
00178 } \
00179 \
00180 SbBool className::getIsBuiltIn() const \
00181 { \
00182 return isBuiltIn; \
00183 } \
00184 \
00185 const SoFieldData * \
00186 className::getFieldData() const \
00187 { \
00188 return inputData; \
00189 } \
00190 \
00191 const SoEngineOutputData * \
00192 className::getOutputData() const \
00193 { \
00194 return outputData; \
00195 } \
00196 const SoFieldData ** \
00197 className::getInputDataPtr() \
00198 { \
00199 return (const SoFieldData **)&inputData; \
00200 } \
00201 const SoEngineOutputData ** \
00202 className::getOutputDataPtr() \
00203 { \
00204 return (const SoEngineOutputData **)&outputData; \
00205 }
00206
00207 #define SO__ENGINE_METHODS(className) \
00208 \
00209 SO__ENGINE_ABSTRACT_METHODS(className) \
00210 \
00211 void * \
00212 className::createInstance(SoType* ) \
00213 { \
00214 return (void *)(new className); \
00215 }
00216
00218
00219
00220
00221
00222 #define SO_ENGINE_SOURCE(className) \
00223 SO__ENGINE_VARS(className); \
00224 SO__ENGINE_METHODS(className)
00225
00226 #define SO_ENGINE_ABSTRACT_SOURCE(className) \
00227 SO__ENGINE_ABSTRACT_VARS(className); \
00228 SO__ENGINE_ABSTRACT_METHODS(className)
00229
00230
00231 #if defined(_DEBUG)
00232 #define SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass) \
00233 if (parentClass::getClassTypeId().isBad()) { \
00234 SoDebugError::post( SO__QUOTE(className)"::initClass", \
00235 SO__QUOTE(className)" initialized before parent class " \
00236 SO__QUOTE(parentClass)"\n"); \
00237 parentClass::initClass(); \
00238 }
00239 #else
00240 #define SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass) \
00241 if (parentClass::getClassTypeId().isBad()) \
00242 parentClass::initClass()
00243 #endif
00244
00246
00247
00248
00249
00250 #define SO__ENGINE_INIT_CLASS_INTERNAL(className, classPrintName, parentClass) { \
00251 SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
00252 classTypeId = SoType::createType( parentClass::getClassTypeId(), \
00253 classPrintName, \
00254 &className::createInstance); \
00255 parentInputData = parentClass::getInputDataPtr(); \
00256 parentOutputData = parentClass::getOutputDataPtr(); \
00257 }
00258
00259 #define SO__ENGINE_INIT_CLASS(className, classPrintName, parentClass) \
00260 SO__ENGINE_INIT_CLASS_INTERNAL(className, classPrintName, parentClass);
00261
00262 #define SO__ENGINE_INIT_ABSTRACT_CLASS_INTERNAL(className,classPrintName,parentClass) { \
00263 SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
00264 classTypeId = SoType::createType(parentClass::getClassTypeId(), \
00265 classPrintName); \
00266 parentInputData = parentClass::getInputDataPtr(); \
00267 parentOutputData = parentClass::getOutputDataPtr(); \
00268 }
00269
00270 #define SO__ENGINE_INIT_ABSTRACT_CLASS(className,classPrintName,parent) \
00271 SO__ENGINE_INIT_ABSTRACT_CLASS_INTERNAL(className,classPrintName,parent);
00272
00274
00275
00276
00277
00278
00279
00280 #define SO_ENGINE_INIT_CLASS_INTERNAL(className,parentClass,parentPrintClass) { \
00281 SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
00282 classTypeId = SoType::createType(SoType::fromName(parentPrintClass), \
00283 SO__QUOTE(className), \
00284 &className::createInstance); \
00285 parentInputData = parentClass::getInputDataPtr(); \
00286 parentOutputData = parentClass::getOutputDataPtr(); \
00287 }
00288
00289 #define SO_ENGINE_INIT_CLASS(className,parentClass,parentPrintClass) \
00290 SO_ENGINE_INIT_CLASS_INTERNAL(className,parentClass,parentPrintClass);
00291
00292 #define SO_ENGINE_INIT_ABSTRACT_CLASS_INTERNAL(className,parentClass,parentPrintClass) { \
00293 SO_ENGINE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
00294 classTypeId = SoType::createType(SoType::fromName(parentPrintClass), \
00295 SO__QUOTE(className)); \
00296 parentInputData = parentClass::getInputDataPtr(); \
00297 parentOutputData = parentClass::getOutputDataPtr(); \
00298 }
00299
00300 #define SO_ENGINE_INIT_ABSTRACT_CLASS(className,parent,parentPrintClass) \
00301 SO_ENGINE_INIT_ABSTRACT_CLASS_INTERNAL(className,parent,parentPrintClass);
00302
00303
00304 #define SO_ENGINE_EXIT_CLASS(className) \
00305 SoType::removeType(classTypeId.getName()); \
00306 classTypeId = SoType::badType(); \
00307 if (inputData) \
00308 { \
00309 delete inputData; \
00310 inputData = NULL;\
00311 } \
00312 if (outputData) \
00313 { \
00314 delete outputData;\
00315 outputData = NULL; \
00316 }\
00317 firstInstance = TRUE
00318
00320
00321
00322
00323
00324 #define SO_ENGINE_CONSTRUCTOR(className) \
00325 SoBaseInitializer sbi(this); \
00326 SO__ENGINE_CHECK_INIT(className); \
00327 if (inputData == NULL) { \
00328 inputData = new SoFieldData(parentInputData ? *parentInputData : NULL); \
00329 outputData = new SoEngineOutputData(parentOutputData ? *parentOutputData : NULL); \
00330 } \
00331 else { \
00332 firstInstance = FALSE; \
00333 }
00334
00336
00337
00338
00339
00340
00341 #define SO_ENGINE_IS_FIRST_INSTANCE() (firstInstance == TRUE)
00342
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 #define SO_ENGINE_ADD_INPUT(inputName, defValue) { \
00361 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \
00362 if (firstInstance) \
00363 inputData->addField(this, SO__QUOTE(inputName), \
00364 &this->inputName); \
00365 this->inputName.setValue defValue; \
00366 this->inputName.setContainer(this); \
00367 }
00368
00369
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 #define SO_ENGINE_ADD_OUTPUT(outputName, type) { \
00388 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \
00389 if (firstInstance) \
00390 outputData->addOutput(this, SO__QUOTE(outputName), \
00391 &this->outputName, \
00392 type::getClassTypeId()); \
00393 this->outputName.setContainer(this); \
00394 }
00395
00396
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 #define SO_ENGINE_DEFINE_ENUM_VALUE(enumType,enumValue) { \
00420 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \
00421 if (firstInstance) \
00422 inputData->addEnumValue(SO__QUOTE(enumType), \
00423 SO__QUOTE(enumValue), enumValue); \
00424 }
00425
00426
00428
00429
00430
00431
00432
00433 #define SO_ENGINE_OUTPUT(outputName,type,code) { \
00434 if (outputName.isEnabled()) { \
00435 for (int _eng_out_i = 0; \
00436 _eng_out_i < outputName.getNumConnections(); \
00437 _eng_out_i++) { \
00438 type *_eng_out_temp = (type *) outputName[_eng_out_i]; \
00439 if (!_eng_out_temp->isReadOnly()) { \
00440 _eng_out_temp->code; \
00441 } \
00442 } \
00443 } \
00444 }
00445
00446
00447
00448 #endif
00449
00450
00451