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
00052 #ifndef _SO_SUB_NODE_
00053 #define _SO_SUB_NODE_
00054
00055 #include <Inventor/errors/SoDebugError.h>
00056 #include <Inventor/fields/SoFieldData.h>
00057 #include <Inventor/threads/SbThreadLocalStorage.h>
00058 #include <Inventor/threads/SbThreadMutex.h>
00059 #include <Inventor/SbRenderEngineMode.h>
00060 #include <Inventor/SoDB.h>
00061
00062
00063
00064
00065
00067
00068
00069
00070 #if defined(_DEBUG)
00071 #define SO__NODE_CHECK_INIT(className) { \
00072 if (classTypeId.isBad()) { \
00073 SoDebugError::post("SO_NODE_CONSTRUCTOR", \
00074 "Can't construct a node of type " \
00075 SO__QUOTE(className) \
00076 " until initClass() has been called"); \
00077 className::initClass(); \
00078 } \
00079 SoTypedObject::checkDatabase(SO__QUOTE(className), this, className::getClassTypeId(), classTypeId); \
00080 }
00081
00082 #define SO__NODE_CHECK_CONSTRUCT(where) { \
00083 if (fieldData == NULL) { \
00084 SoDebugError::post(where, \
00085 "Instance not properly constructed.\n" \
00086 "Did you forget to put SO_NODE_CONSTRUCTOR()" \
00087 " in the constructor?"); \
00088 fieldData = new SoFieldData(parentFieldData ? *parentFieldData : NULL); \
00089 } \
00090 }
00091
00092 #else
00093 #define SO__NODE_CHECK_INIT(className) { \
00094 if (classTypeId.isBad()) { \
00095 className::initClass(); \
00096 } \
00097 }
00098
00099 #define SO__NODE_CHECK_CONSTRUCT(where) { \
00100 if (fieldData == NULL) { \
00101 fieldData = new SoFieldData(parentFieldData ? *parentFieldData : NULL); \
00102 } \
00103 }
00104 #endif
00105
00107
00108
00109
00110
00111
00113
00114
00115
00116
00117
00118 #define SO_NODE_ABSTRACT_HEADER(className) \
00119 public: \
00120 \
00121 static SoType getClassTypeId() \
00122 { return classTypeId; } \
00123 \
00124 virtual SoType getTypeId() const; \
00125 \
00126
00127 virtual const SbRenderEngineMode& getRenderEngineMode() const \
00128 { return className::getClassRenderEngineMode(); } \ \
00130
00131 static SbRenderEngineMode& getClassRenderEngineMode() \
00132 { return s_renderEngineMode; } \
00133 private: \
00134 virtual SbBool getIsBuiltIn() const ; \
00135 virtual const SoFieldData *getFieldData() const; \
00136 private: \
00137 static const SoFieldData **getFieldDataPtr(); \
00138 private: \
00139 static SbThreadMutex classMutex; \
00140 static SoType classTypeId; \
00141 static SbBool isBuiltIn; \
00142 static SbBool firstInstance; \
00143 static SoFieldData *fieldData; \
00144 static const SoFieldData **parentFieldData; \
00145 static SbRenderEngineMode s_renderEngineMode
00146
00147
00148
00149
00150
00151 #define SO_NODE_HEADER(className) \
00152 SO_NODE_ABSTRACT_HEADER(className); \
00153 static void *createInstance(SoType* dynamicType = NULL)
00154
00156
00157
00158
00159
00161
00162
00163
00164
00165
00166 #define SO__NODE_ABSTRACT_VARS(className) \
00167 SbThreadMutex className::classMutex; \
00168 SoType className::classTypeId; \
00169 SbBool className::isBuiltIn = FALSE; \
00170 SoFieldData *className::fieldData = NULL; \
00171 const SoFieldData **className::parentFieldData = NULL; \
00172 SbBool className::firstInstance = TRUE; \
00173 SbRenderEngineMode className::s_renderEngineMode;
00174
00175
00176
00177
00178 #define SO__NODE_VARS(className) \
00179 SO__NODE_ABSTRACT_VARS(className)
00180
00182
00183
00184
00185
00186 #define SO__NODE_ABSTRACT_METHODS(className) \
00187 \
00188 SoType \
00189 className::getTypeId() const \
00190 { \
00191 return classTypeId; \
00192 } \
00193 \
00194 const SoFieldData * \
00195 className::getFieldData() const \
00196 { \
00197 classMutex.lock(); \
00198 SO__NODE_CHECK_CONSTRUCT(SO__QUOTE(className)); \
00199 SoFieldData * result = fieldData; \
00200 classMutex.unlock(); \
00201 return result; \
00202 } \
00203 \
00204 SbBool className::getIsBuiltIn() const \
00205 { \
00206 return isBuiltIn; \
00207 } \
00208 \
00209 const SoFieldData **className::getFieldDataPtr() \
00210 { \
00211 classMutex.lock(); \
00212 const SoFieldData **result = (const SoFieldData **)&fieldData; \
00213 classMutex.unlock(); \
00214 return result; \
00215 }
00216
00218
00219
00220
00221
00222
00223 #define SO__NODE_METHODS(className) \
00224 \
00225 SO__NODE_ABSTRACT_METHODS(className) \
00226 \
00227 void * \
00228 className::createInstance(SoType *) \
00229 { \
00230 return (void *)(new className); \
00231 }
00232
00233
00234
00236
00237
00238
00239
00240
00241 #define SO_NODE_SOURCE(className) \
00242 SO__NODE_VARS(className); \
00243 SO__NODE_METHODS(className)
00244
00245 #define SO_NODE_ABSTRACT_SOURCE(className) \
00246 SO__NODE_ABSTRACT_VARS(className); \
00247 SO__NODE_ABSTRACT_METHODS(className)
00248
00249
00251
00252
00253
00254
00255 #if defined(_DEBUG)
00256 #define SO_NODE_INIT_CLASS_CHECK_PARENT(className, parentClass) \
00257 if (parentClass::getClassTypeId().isBad()) { \
00258 SoDebugError::post( SO__QUOTE(className)"::initClass", \
00259 SO__QUOTE(className)" initialized before parent class " \
00260 SO__QUOTE(parentClass)"\n"); \
00261 parentClass::initClass(); \
00262 }
00263 #else
00264 #define SO_NODE_INIT_CLASS_CHECK_PARENT(className, parentClass) \
00265 if (parentClass::getClassTypeId().isBad()) \
00266 parentClass::initClass()
00267 #endif
00268
00269 #if defined(LIBRARYBUILD)
00270
00271 #define SO_NODE_INIT_RENDERING_MODE(className, parentClass) \
00272 className::getClassRenderEngineMode().setRenderMode(SbRenderEngineMode::OIV_OPENINVENTOR_RENDERING);\
00273 if (parentClass::getClassRenderEngineMode().isChildrenInherit()) \
00274 className::getClassRenderEngineMode().setChildrenInherit(parentClass::getClassRenderEngineMode().isChildrenInherit())
00275 #else
00276
00277
00278 #define SO_NODE_INIT_RENDERING_MODE(className, parentClass) \
00279 if ( className::getClassRenderEngineMode().isNotDefined() ) \
00280 { \
00281 if (parentClass::getClassRenderEngineMode().isChildrenInherit()) \
00282 s_renderEngineMode = parentClass::getClassRenderEngineMode(); \
00283 else \
00284 SbRenderEngineMode::postInitWarning( OIV_FUNCTION); \
00285 }
00286 #endif
00287
00288 #define SO__NODE_INIT_CLASS_INTERNAL(className,classPrintName,parentClass) \
00289 classMutex.lock(); \
00290 SO_NODE_INIT_RENDERING_MODE(className, parentClass); \
00291 SO_NODE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
00292 classTypeId = SoType::createType( parentClass::getClassTypeId(), \
00293 classPrintName, \
00294 &className::createInstance, \
00295 (short)SoNode::getNextActionMethodIndex()); \
00296 if (parentFieldData == NULL) \
00297 SoNode::incNextActionMethodIndex(); \
00298 parentFieldData = parentClass::getFieldDataPtr(); \
00299 classMutex.unlock();
00300
00301 #define SO__NODE_INIT_CLASS(className,classPrintName,parentClass) \
00302 SO__NODE_INIT_CLASS_INTERNAL(className,classPrintName,parentClass)
00303
00304 #define SO__NODE_INIT_ABSTRACT_CLASS_INTERNAL(className,classPrintName,parentClass) \
00305 classMutex.lock(); \
00306 SO_NODE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
00307 classTypeId = SoType::createType( parentClass::getClassTypeId(), \
00308 classPrintName, \
00309 NULL, \
00310 (short)SoNode::getNextActionMethodIndex()); \
00311 if (parentFieldData == NULL) \
00312 SoNode::incNextActionMethodIndex(); \
00313 parentFieldData = parentClass::getFieldDataPtr(); \
00314 classMutex.unlock();
00315
00316 #define SO__NODE_INIT_ABSTRACT_CLASS(className,classPrintName,parentClass) \
00317 SO__NODE_INIT_ABSTRACT_CLASS_INTERNAL(className,classPrintName,parentClass)
00318
00319 #if defined(_DEBUG)
00320 #define SO__NODE_EXIT_CLASS(className) \
00321 if (! SoType::removeType(classTypeId.getName())) { \
00322 SoDebugError::post(SO__QUOTE(className)"::exitClass", \
00323 "Unable to remove type (%s) for this class. Check exitClass() " \
00324 "method is implemented and is called only once.\n", \
00325 classTypeId.getName().getString() ); \
00326 } \
00327 else \
00328 { \
00329 classTypeId = SoType::badType(); \
00330 if (fieldData != NULL) \
00331 { \
00332 delete fieldData; \
00333 fieldData = NULL; \
00334 } \
00335 parentFieldData = NULL; \
00336 firstInstance = TRUE; \
00337 }
00338 #else
00339 #define SO__NODE_EXIT_CLASS(className) \
00340 SoType::removeType(classTypeId.getName()); \
00341 classTypeId = SoType::badType(); \
00342 if (fieldData != NULL) \
00343 { \
00344 delete fieldData; \
00345 fieldData = NULL; \
00346 } \
00347 parentFieldData = NULL; \
00348 firstInstance = TRUE
00349 #endif
00350
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 #define SO_THREAD_NODE_INIT_CLASS(className,structName) \
00366 \
00367 SB_THREAD_INIT_CLASS(className,structName)
00368
00369 #define SO_THREAD_NODE_EXIT_CLASS(className) \
00370 \
00371 SB_THREAD_EXIT_CLASS(className)
00372
00373 #define LOCAL_THREAD_VAR(_className_, _structName_, _varName_) \
00374 \
00375 GET_THREAD_LOCAL_VAR(_className_, _structName_, _varName_)
00376
00377 #define LOCAL_THREAD_STORAGE(_className_) \
00378 \
00379 GET_THREAD_LOCAL_STORAGE(_className_)
00380
00381
00383
00384
00385
00386
00387
00388
00389 #define SO_NODE_INIT_CLASS_INTERNAL(className,parentClass,parentPrintClass) \
00390 classMutex.lock(); \
00391 SO_NODE_INIT_RENDERING_MODE(className, parentClass); \
00392 SO_NODE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
00393 classTypeId = SoType::createType( SoType::fromName(parentPrintClass), \
00394 SO__QUOTE(className), \
00395 &className::createInstance, \
00396 (short)SoNode::getNextActionMethodIndex()); \
00397 if (parentFieldData == NULL) \
00398 SoNode::incNextActionMethodIndex(); \
00399 parentFieldData = parentClass::getFieldDataPtr(); \
00400 classMutex.unlock();
00401
00402 #define SO_NODE_INIT_CLASS(className,parentClass,parentPrintClass) \
00403 \
00404 SO_NODE_INIT_CLASS_INTERNAL(className,parentClass,parentPrintClass)
00405
00406 #define SO_NODE_INIT_ABSTRACT_CLASS_INTERNAL(className, parentClass, parentPrintClass) \
00407 classMutex.lock(); \
00408 SO_NODE_INIT_RENDERING_MODE(className,parentClass); \
00409 SO_NODE_INIT_CLASS_CHECK_PARENT(className, parentClass); \
00410 classTypeId = SoType::createType( SoType::fromName(parentPrintClass), \
00411 SO__QUOTE(className), \
00412 NULL, \
00413 (short)SoNode::getNextActionMethodIndex()); \
00414 if (parentFieldData == NULL) \
00415 SoNode::incNextActionMethodIndex(); \
00416 parentFieldData = parentClass::getFieldDataPtr(); \
00417 classMutex.unlock();
00418
00419 #define SO_NODE_INIT_ABSTRACT_CLASS(className, parentClass, parentPrintClass) \
00420 \
00421 SO_NODE_INIT_ABSTRACT_CLASS_INTERNAL(className,parentClass,parentPrintClass)
00422
00427 #define SO_NODE_CONSTRUCTOR(className) \
00428 SoBaseInitializer sbi(this); \
00429 classMutex.lock(); \
00430 SO__NODE_CHECK_INIT(className); \
00431 if (fieldData == NULL) \
00432 fieldData = new SoFieldData(parentFieldData ? \
00433 (SoFieldData *)*parentFieldData : \
00434 (SoFieldData *)NULL); \
00435 else \
00436 firstInstance = FALSE; \
00437 classMutex.unlock();
00438
00439
00443 #define SO_NODE_IS_FIRST_INSTANCE() \
00444 \
00445 (firstInstance == TRUE)
00446
00447
00448
00464 #if defined(_DEBUG)
00465
00466 #define CHECK_FIELD_INIT(fieldName)
00467
00468
00469
00470 #define CHECK_MFIELD_INIT(fieldName) \
00471 if ( dynamic_cast<SoSField*>(&this->fieldName) != NULL) \
00472 SoDebugError::post("SO_NODE_ADD_MFIELD","Used for a SoSFField.")
00473 #else
00474 #define CHECK_FIELD_INIT(fieldName)
00475 #define CHECK_MFIELD_INIT(fieldName)
00476 #endif
00477
00478 #define SO_NODE_ADD_FIELD(fieldName,defValue) { \
00479 classMutex.lock(); \
00480 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00481 if (firstInstance) \
00482 fieldData->addField(this, SO__QUOTE(fieldName), \
00483 &this->fieldName); \
00484 this->fieldName.setValue defValue; \
00485 this->fieldName.setContainer(this); \
00486 this->fieldName.setFieldType(SoField::EXPOSED_FIELD); \
00487 CHECK_FIELD_INIT(fieldName); \
00488 classMutex.unlock(); \
00489 }
00490
00492
00493
00494
00495
00496 #define SO_NODE_ADD_NAMED_FIELD(fieldName,memberName,defValue) { \
00497 classMutex.lock(); \
00498 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00499 if (firstInstance) \
00500 fieldData->addField(this, SO__QUOTE(fieldName), \
00501 &this->memberName); \
00502 this->memberName.setValue defValue; \
00503 this->memberName.setContainer(this); \
00504 this->memberName.setFieldType(SoField::EXPOSED_FIELD); \
00505 classMutex.unlock(); \
00506 }
00507
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 #define SO_NODE_ADD_MFIELD(fieldName) { \
00525 classMutex.lock(); \
00526 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00527 if (firstInstance) \
00528 fieldData->addField(this, SO__QUOTE(fieldName), \
00529 &this->fieldName); \
00530 this->fieldName.setContainer(this); \
00531 this->fieldName.setFieldType(SoField::EXPOSED_FIELD); \
00532 CHECK_MFIELD_INIT(fieldName); \
00533 classMutex.unlock(); \
00534 }
00535
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 #define SO_NODE_ADD_PRIVATEFIELD(fieldName,defValue) { \
00553 classMutex.lock(); \
00554 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00555 if (firstInstance) \
00556 fieldData->addField(this, SO__QUOTE(fieldName), &this->fieldName); \
00557 this->fieldName.setValue defValue; \
00558 this->fieldName.setContainer(this); \
00559 this->fieldName.setFieldType(SoField::HIDDEN_FIELD); \
00560 classMutex.unlock(); \
00561 }
00562
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 #define SO_NODE_ADD_PRIVATEMFIELD(fieldName) { \
00580 classMutex.lock(); \
00581 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00582 if (firstInstance) \
00583 fieldData->addField(this, SO__QUOTE(fieldName), \
00584 &this->fieldName); \
00585 this->fieldName.setContainer(this); \
00586 this->fieldName.setFieldType(SoField::HIDDEN_FIELD); \
00587 classMutex.unlock(); \
00588 }
00589
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 #define SO_NODE_ADD_EXPOSEDFIELD(fieldName,defValue) { \
00610 classMutex.lock(); \
00611 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00612 if (firstInstance) \
00613 fieldData->addField(this, SO__QUOTE(fieldName), \
00614 &this->fieldName); \
00615 this->fieldName.setValue defValue; \
00616 this->fieldName.setContainer(this); \
00617 this->fieldName.setFieldType(SoField::EXPOSED_FIELD); \
00618 classMutex.unlock(); \
00619 }
00620
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 #define SO_NODE_ADD_EVENTIN(fieldName) { \
00635 classMutex.lock(); \
00636 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00637 if (firstInstance) \
00638 fieldData->addField(this, SO__QUOTE(fieldName), \
00639 &this->fieldName); \
00640 this->fieldName.setContainer(this); \
00641 this->fieldName.setFieldType(SoField::EVENTIN_FIELD); \
00642 classMutex.unlock(); \
00643 }
00644
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 #define SO_NODE_ADD_EVENTOUT(fieldName, defValue) { \
00659 classMutex.lock(); \
00660 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00661 if (firstInstance) \
00662 fieldData->addField(this, SO__QUOTE(fieldName), \
00663 &this->fieldName); \
00664 this->fieldName.setValue defValue; \
00665 this->fieldName.setContainer(this); \
00666 this->fieldName.setFieldType(SoField::EVENTOUT_FIELD); \
00667 classMutex.unlock(); \
00668 }
00669
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 #define SO_NODE_ADD_HIDDEN_FIELD(fieldName, defValue) { \
00684 classMutex.lock(); \
00685 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00686 if (firstInstance) \
00687 fieldData->addField(this, SO__QUOTE(fieldName), \
00688 &this->fieldName); \
00689 this->fieldName.setValue defValue; \
00690 this->fieldName.setContainer(this); \
00691 this->fieldName.setFieldType(SoField::INTERNAL_FIELD); \
00692 classMutex.unlock(); \
00693 }
00694
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 #define SO_NODE_ADD_FIELD_EVENTIN(fieldName, defValue) { \
00707 classMutex.lock(); \
00708 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00709 if (firstInstance) \
00710 fieldData->addField(this, SO__QUOTE(fieldName), \
00711 &this->fieldName); \
00712 this->fieldName.setValue defValue; \
00713 this->fieldName.setContainer(this); \
00714 this->fieldName.setFieldType(SoField::FIELD_EVENTIN_FIELD); \
00715 classMutex.unlock(); \
00716 }
00717
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 #define SO_NODE_DEFINE_ENUM_VALUE(enumType,enumValue) { \
00741 classMutex.lock(); \
00742 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00743 if (firstInstance) \
00744 fieldData->addEnumValue(SO__QUOTE(enumType), \
00745 SO__QUOTE(enumValue), \
00746 enumValue); \
00747 classMutex.unlock(); \
00748 }
00749
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 #define SO__NODE_DEFINE_ENUM_VALUE(enumType,enumValueName,enumValue) { \
00775 classMutex.lock(); \
00776 SO__NODE_CHECK_CONSTRUCT(__FILE__); \
00777 if (firstInstance) \
00778 fieldData->addEnumValue(SO__QUOTE(enumType), \
00779 enumValueName, \
00780 enumValue); \
00781 classMutex.unlock(); \
00782 }
00783
00784 #endif
00785
00786