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_ACTION_
00051 #define _SO_SUB_ACTION_
00052
00053 #include <Inventor/actions/SoAction.h>
00054 #include <Inventor/SbString.h>
00055 #include <Inventor/errors/SoDebugError.h>
00056
00058
00059
00060
00061
00062
00064
00065
00066
00067
00068
00069 #define SO_ACTION_HEADER(className) \
00070 public: \
00071 \
00072 virtual SoType getTypeId() const; \
00073 \
00074 static SoType getClassTypeId(); \
00075 private:\
00076 static void addMethod(SoType t, SoActionMethod* method); \
00077 \
00078 static void enableElement(SoType t, int stkIndex); \
00079 \
00080
00081 virtual const SoEnabledElementsList & getEnabledElements() const; \
00082 private: \
00083 \
00084 static SoEnabledElementsList *enabledElements; \
00085 static SoActionMethodList *methods; \
00086 \
00087 private: \
00088 virtual SoActionMethodList * getActionMethods(); \
00089 \
00090 private: \
00091 static SoType classTypeId; \
00092 static SbBool classTypeIdIsSet
00093
00094
00095 #define SO_ACTION_HEADER_WITH_DEF(className) \
00096 SO_ACTION_HEADER(className)
00097
00099
00100
00101
00102
00104
00105
00106
00107
00108 #define SO__ACTION_VARS(className) \
00109 SoEnabledElementsList *className::enabledElements = NULL; \
00110 SoActionMethodList *className::methods = NULL; \
00111 SoType className::classTypeId; \
00112 SbBool className::classTypeIdIsSet = FALSE
00113
00115
00116
00117
00118 #define SO_ACTION_SOURCE(className) \
00119 SO__ACTION_VARS(className); \
00120 SO__ACTION_METHODS(className)
00121
00122 #define SO_ACTION_AUTOINIT_SOURCE(className, parentClass) \
00123 SO__ACTION_VARS(className); \
00124 SO__ACTION_AUTOINIT_METHODS(className, parentClass)
00125
00127
00128
00129
00130
00131
00132 #if defined(_DEBUG)
00133 #define SO_ACTION_INIT_CLASS_CHECK_PARENT(className, parentClass) \
00134 if (parentClass::getClassTypeId().isBad()) { \
00135 SoDebugError::post( SO__QUOTE(className)"::initClass", \
00136 SO__QUOTE(className)" initialized before parent class " \
00137 SO__QUOTE(parentClass)"\n"); \
00138 parentClass::initClass(); \
00139 }
00140 #else
00141 #define SO_ACTION_INIT_CLASS_CHECK_PARENT(className, parentClass) \
00142 if (parentClass::getClassTypeId().isBad()) \
00143 parentClass::initClass()
00144 #endif
00145
00146 #define SO_ACTION_INIT_CLASS_INTERNAL(className, parentClass) \
00147 enabledElements = new SoEnabledElementsList(parentClass::enabledElements); \
00148 methods = new ::SoActionMethodList(parentClass::methods); \
00149 SO_ACTION_INIT_CLASS_CHECK_PARENT(className, parentClass); \
00150 classTypeId = SoType::createType(parentClass::getClassTypeId(), \
00151 SO__QUOTE(className), NULL); \
00152 classTypeIdIsSet = TRUE;
00153
00154 #define SO_ACTION_INIT_CLASS(className, parentClass) \
00155 SO_ACTION_INIT_CLASS_INTERNAL(className, parentClass)
00156
00157 #if defined(_DEBUG)
00158 #define SO_ACTION_EXIT_CLASS(className) \
00159 if (! SoType::removeType(classTypeId.getName())) { \
00160 SoDebugError::post(SO__QUOTE(className)"::exitClass", \
00161 "Unable to remove type (%s) for this class. Check exitClass() " \
00162 "method is implemented and is called only once.\n", \
00163 classTypeId.getName().getString() ); \
00164 } \
00165 else { \
00166 classTypeId = SoType::badType(); \
00167 if (enabledElements) \
00168 { \
00169 delete enabledElements; \
00170 enabledElements = NULL; \
00171 } \
00172 if (methods) \
00173 { \
00174 delete methods; \
00175 methods = NULL; \
00176 } \
00177 classTypeIdIsSet = FALSE; \
00178 }
00179 #else
00180 #define SO_ACTION_EXIT_CLASS(className) \
00181 SoType::removeType(classTypeId.getName()); \
00182 classTypeId = SoType::badType(); \
00183 if (enabledElements) \
00184 { \
00185 delete enabledElements; \
00186 enabledElements = NULL; \
00187 } \
00188 if (methods) \
00189 { \
00190 delete methods; \
00191 methods = NULL; \
00192 } \
00193 classTypeIdIsSet = FALSE
00194 #endif
00195
00196 #if defined(_DEBUG)
00197 #define SO__ACTION_CHECK_INIT(className) { \
00198 if (classTypeId.isBad()) { \
00199 SoDebugError::post("SO_ACTION_CONSTRUCTOR", \
00200 "Can't construct an action of type " \
00201 SO__QUOTE(className) \
00202 " until initClass() has been called." \
00203 " Check SoDB::init() has been called."); \
00204 className::initClass(); \
00205 } \
00206 SoTypedObject::checkDatabase(SO__QUOTE(className), this, className::getClassTypeId(), classTypeId); \
00207 }
00208 #else
00209 #define SO__ACTION_CHECK_INIT(className) { \
00210 if (classTypeId.isBad()) { \
00211 className::initClass(); \
00212 } \
00213 }
00214 #endif
00215
00217
00218
00219
00220
00221
00222 #define SO_ACTION_CONSTRUCTOR(className) \
00223 SO__ACTION_CHECK_INIT(className);
00224
00226
00227
00228
00229
00230
00231
00232 #define SO_ACTION_ADD_METHOD(nodeClass, method) \
00233 addMethod(nodeClass::getClassTypeId(), method)
00234
00236
00237
00238
00239
00240 #define SO__ACTION_ELEMENTS_METHODS(className) \
00241 const SoEnabledElementsList & \
00242 className::getEnabledElements() const \
00243 { \
00244 return *enabledElements; \
00245 } \
00246 \
00247 SoActionMethodList * \
00248 className::getActionMethods() \
00249 { \
00250 return methods; \
00251 } \
00252 \
00253 void \
00254 className::addMethod(SoType t, SoActionMethod* method) \
00255 { \
00256 methods->addMethod(t, method); \
00257 } \
00258 \
00259 void \
00260 className::enableElement(SoType t, int stkIndex) \
00261 { \
00262 if ( t.isBad()) \
00263 { \
00264 SoDebugError::post("SO_ENABLE_ELEMENT", \
00265 "Can't enable element for " \
00266 SO__QUOTE(className) \
00267 " until the element initClass function has been called"); \
00268 return; \
00269 } \
00270 enabledElements->enable(t, stkIndex); \
00271 }
00272
00273 #define SO__ACTION_METHODS(className) \
00274 SoType \
00275 className::getClassTypeId() \
00276 { \
00277 return classTypeId; \
00278 } \
00279 \
00280 SoType \
00281 className::getTypeId() const \
00282 { \
00283 return classTypeId; \
00284 } \
00285 \
00286 SO__ACTION_ELEMENTS_METHODS(className)
00287
00289
00290
00291
00292
00293
00294 #define SO__ACTION_AUTOINIT_METHODS(className, parentClass) \
00295 SoType \
00296 className::getClassTypeId() \
00297 { \
00298 if (!classTypeIdIsSet) { \
00299 SO_ACTION_INIT_CLASS(className, parentClass); \
00300 } \
00301 return classTypeId; \
00302 } \
00303 \
00304 SoType \
00305 className::getTypeId() const \
00306 { \
00307 if (classTypeIdIsSet == FALSE) { \
00308 SO_ACTION_INIT_CLASS(className, parentClass); \
00309 } \
00310 return classTypeId; \
00311 } \
00312 \
00313 SO__ACTION_ELEMENTS_METHODS(className)
00314
00315 #endif
00316
00317
00318