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 #ifndef _SO_SUB_ELEMENT_
00051 #define _SO_SUB_ELEMENT_
00052
00053 #include <Inventor/elements/SoElement.h>
00054
00055 #if defined(_DEBUG)
00056 #include <Inventor/SoDB.h>
00057 #endif
00058
00060
00061
00062
00063
00064
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 #define SO_ELEMENT_ABSTRACT_HEADER(className) \
00076 public: \
00077 \
00078 static SoType getClassTypeId(); \
00079 \
00083 static int getClassStackIndex(); \
00084 private: \
00085 \
00086 virtual int getClassStackIndexInternal() const; \
00087 private: \
00088 className(); \
00089 private: \
00090 static int classStackIndex; \
00091 static SoType classTypeId
00092
00093
00094
00095
00096 #define SO_ELEMENT_HEADER(className) \
00097 SO_ELEMENT_ABSTRACT_HEADER(className); \
00098 private: \
00099 static void *createInstance(SoType* dynamicType = NULL)
00100
00102
00103
00104
00105
00107
00108
00109
00110
00111
00112 #define SO__ELEMENT_ABSTRACT_VARS(className) \
00113 SoType className::classTypeId; \
00114 int className::classStackIndex = 0;
00115
00116 #define SO__ELEMENT_VARS(className) \
00117 SO__ELEMENT_ABSTRACT_VARS(className)
00118
00119 #if defined(_DEBUG)
00120 #define SO_ELEMENT_CHECK_INIT(className) { \
00121 if (classTypeId.isBad()) { \
00122 SoDebugError::post("Element Constructor", \
00123 "Can't construct an element of type " \
00124 SO__QUOTE(className) \
00125 " until initClass() has been called"); \
00126 className::initClass(); \
00127 } \
00128 SoTypedObject::checkDatabase(SO__QUOTE(className), this, className::getClassTypeId(), classTypeId); \
00129 }
00130 #else
00131 #define SO_ELEMENT_CHECK_INIT(className) { \
00132 if (classTypeId.isBad()) { \
00133 className::initClass(); \
00134 } \
00135 }
00136 #endif
00137
00138
00139
00140
00141 #define SO__ELEMENT_ABSTRACT_METHODS(className) \
00142 \
00143 className::className() \
00144 { \
00145 SO_ELEMENT_CHECK_INIT(className); \
00146 commonInit() ; \
00147 } \
00148 \
00149 SoType \
00150 className::getClassTypeId() \
00151 { \
00152 return classTypeId; \
00153 } \
00154 \
00155 int \
00156 className::getClassStackIndex() \
00157 { \
00158 return classStackIndex; \
00159 } \
00160 \
00161 int \
00162 className::getClassStackIndexInternal() const \
00163 { \
00164 return className::classStackIndex; \
00165 }
00166
00167
00168
00169
00170
00171
00172 #define SO__ELEMENT_METHODS(className) \
00173 \
00174 className::className() \
00175 { \
00176 SO_ELEMENT_CHECK_INIT(className); \
00177 commonInit() ; \
00178 setTypeId(classTypeId); \
00179 setStackIndex(classStackIndex); \
00180 } \
00181 \
00182 void * \
00183 className::createInstance(SoType *) \
00184 { \
00185 return new className; \
00186 } \
00187 \
00188 SoType \
00189 className::getClassTypeId() \
00190 { \
00191 return classTypeId; \
00192 } \
00193 \
00194 int \
00195 className::getClassStackIndex() \
00196 { \
00197 return classStackIndex; \
00198 } \
00199 \
00200 int \
00201 className::getClassStackIndexInternal() const \
00202 { \
00203 return className::classStackIndex; \
00204 }
00205
00206
00208
00209
00210
00211
00212
00213 #define SO_ELEMENT_ABSTRACT_SOURCE(className) \
00214 SO__ELEMENT_ABSTRACT_VARS(className); \
00215 SO__ELEMENT_ABSTRACT_METHODS(className)
00216
00217 #define SO_ELEMENT_SOURCE(className) \
00218 SO__ELEMENT_VARS(className); \
00219 SO__ELEMENT_METHODS(className)
00220
00222
00223
00224
00225
00226
00227
00228 #if defined(_DEBUG)
00229 #define SO_ELEMENT_INIT_CLASS_CHECK_PARENT(className, parentClass) \
00230 if (parentClass::getClassTypeId().isBad()) { \
00231 SoDebugError::post( SO__QUOTE(className)"::initClass", \
00232 SO__QUOTE(className)" initialized before parent class " \
00233 SO__QUOTE(parentClass)"\n"); \
00234 parentClass::initClass(); \
00235 }
00236 #else
00237 #define SO_ELEMENT_INIT_CLASS_CHECK_PARENT(className, parentClass) \
00238 if (parentClass::getClassTypeId().isBad()) \
00239 parentClass::initClass()
00240 #endif
00241
00242 #define SO_ELEMENT_INIT_ABSTRACT_CLASS_INTERNAL(className,parentClass) \
00243 SO_ELEMENT_INIT_CLASS_CHECK_PARENT(className, parentClass); \
00244 classTypeId = SoType::createType( parentClass::getClassTypeId(), \
00245 SO__QUOTE(className), \
00246 NULL); \
00247 classStackIndex = parentClass::getClassStackIndex();
00248
00249 #define SO_ELEMENT_INIT_ABSTRACT_CLASS(className, parentClass) \
00250 SO_ELEMENT_INIT_ABSTRACT_CLASS_INTERNAL(className, parentClass);
00251
00252 #define SO_ELEMENT_INIT_CLASS_INTERNAL(className,parentClass) \
00253 SO_ELEMENT_INIT_CLASS_CHECK_PARENT(className, parentClass); \
00254 classTypeId = SoType::createType( parentClass::getClassTypeId(), \
00255 SO__QUOTE(className), \
00256 &className::createInstance); \
00257 if (classStackIndex == 0) \
00258 { \
00259 if (parentClass::getClassStackIndex() < 0) \
00260 classStackIndex = createStackIndex(classTypeId); \
00261 else \
00262 classStackIndex = parentClass::getClassStackIndex(); \
00263 }
00264
00265 #define SO_ELEMENT_INIT_CLASS(className, parentClass) \
00266 SO_ELEMENT_INIT_CLASS_INTERNAL(className, parentClass);
00267
00268 #if defined(_DEBUG)
00269 #define SO_ELEMENT_EXIT_CLASS(className) \
00270 if (! SoType::removeType(classTypeId.getName())) { \
00271 SoDebugError::post(SO__QUOTE(className)"::exitClass", \
00272 "Unable to remove type (%s) for this class. Check exitClass() " \
00273 "method is implemented and is called only once.\n", \
00274 classTypeId.getName().getString() ); \
00275 } \
00276 else { \
00277 classTypeId = SoType::badType(); \
00278 classStackIndex = 0; \
00279 }
00280 #else
00281 #define SO_ELEMENT_EXIT_CLASS(className) \
00282 SoType::removeType(classTypeId.getName()); \
00283 classTypeId = SoType::badType(); \
00284 classStackIndex = 0
00285 #endif
00286
00287 #endif
00288
00289
00290