Open Inventor Reference
MeVis/ThirdParty/Sources/Inventor/inventor/lib/database/include/Inventor/nodes/SoSubNode.h
Go to the documentation of this file.
00001 /*
00002  *
00003  *  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved. 
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Lesser General Public
00007  *  License as published by the Free Software Foundation; either
00008  *  version 2.1 of the License, or (at your option) any later version.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Lesser General Public License for more details.
00014  *
00015  *  Further, this software is distributed without any warranty that it is
00016  *  free of the rightful claim of any third person regarding infringement
00017  *  or the like.  Any license provided herein, whether implied or
00018  *  otherwise, applies only to this software file.  Patent licenses, if
00019  *  any, provided herein do not apply to combinations of this program with
00020  *  other software, or any other product whatsoever.
00021  * 
00022  *  You should have received a copy of the GNU Lesser General Public
00023  *  License along with this library; if not, write to the Free Software
00024  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025  *
00026  *  Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
00027  *  Mountain View, CA  94043, or:
00028  * 
00029  *  http://www.sgi.com 
00030  * 
00031  *  For further information regarding this notice, see: 
00032  * 
00033  *  http://oss.sgi.com/projects/GenInfo/NoticeExplan/
00034  *
00035  */
00036 
00037 
00038 /*
00039  * Copyright (C) 1990,91   Silicon Graphics, Inc.
00040  *
00041  _______________________________________________________________________
00042  ______________  S I L I C O N   G R A P H I C S   I N C .  ____________
00043  |
00044  |   $Revision: 1.1.1.1 $
00045  |
00046  |   Description:
00047  |      This file defines some macros that implement things common to
00048  |      many subclasses of SoNode. They may be used to make SoNode
00049  |      subclassing easier. In all of the macros, the "className"
00050  |      parameter refers to the name of the node subclass.
00051  |
00052  |      Methods containing the word "ABSTRACT" are to be used for
00053  |      abstract subclasses in place of the corresponding regular
00054  |      macro.  Note that abstract classes may not have fields (you
00055  |      cannot call ADD_FIELD in their constructor).
00056  |
00057  |   Defined macros:
00058  |
00059  |      Within class header:
00060  |
00061  |              SO_NODE_HEADER(className)
00062  |              SO_NODE_ABSTRACT_HEADER(className)
00063  |
00064  |      Within class source:
00065  |
00066  |          At file scope:
00067  |
00068  |              SO_NODE_SOURCE(className)
00069  |              SO_NODE_ABSTRACT_SOURCE(className)
00070  |
00071  |          Class initialization (initClass):
00072  |
00073  |              SO_NODE_INIT_CLASS()
00074  |              SO_NODE_INIT_ABSTRACT_CLASS()
00075  |
00076  |          Constructor initialization:
00077  |
00078  |              SO_NODE_CONSTRUCTOR(className)
00079  |              SO_NODE_ADD_FIELD(fieldMember,(defaultValue))
00080  |              SO_NODE_DEFINE_ENUM_VALUE(enumType,enumValue)
00081  |              SO_NODE_IS_FIRST_INSTANCE()     //!< a boolean value
00082  |
00083  |                 //!< the following are defined in <fields/So[SM]fEnum.h>:
00084  |              SO_NODE_SET_SF_ENUM_TYPE(fieldName,enumType)
00085  |              SO_NODE_SET_MF_ENUM_TYPE(fieldName,enumType)
00086  |
00087  |   Author(s)          : Paul S. Strauss, Gavin Bell, Ronen Barzel
00088  |
00089  ______________  S I L I C O N   G R A P H I C S   I N C .  ____________
00090  _______________________________________________________________________
00091  */
00092 
00093 #ifndef  _SO_SUB_NODE_
00094 #define  _SO_SUB_NODE_
00095 
00096 #include <Inventor/system/SbSystem.h>
00097 #include <Inventor/errors/SoDebugError.h>
00098 #include <Inventor/fields/SoFieldData.h>
00099 #include <Inventor/nodes/SoNode.h>
00100 
00101 
00105 
00110 #ifdef DEBUG
00111 #define SO__NODE_CHECK_INIT(className) {                                      \
00112 int _value_false_node_check_init = 0;                        \
00113 do {                                                                          \
00114     if (classTypeId == SoType::badType()) {                                   \
00115         SoDebugError::post("SO_NODE_CONSTRUCTOR",                             \
00116                            "Can't construct a node of type "                  \
00117                            SO__QUOTE(className)                               \
00118                            " until initClass() has been called");             \
00119         return;                                                               \
00120     }                                                                         \
00121 } while (_value_false_node_check_init);                                                       \
00122 }
00123 
00124 #define SO__NODE_CHECK_CONSTRUCT(where) {                                     \
00125 int _value_false_node_check_construct = 0;                \
00126 do {                                                                          \
00127     if (fieldData == NULL) {                                                  \
00128         SoDebugError::post(where,                                             \
00129                            "Instance not properly constructed.\n"             \
00130                            "Did you forget to put SO_NODE_CONSTRUCTOR()"      \
00131                            " in the constructor?");                           \
00132         fieldData = new                                                       \
00133             SoFieldData(parentFieldData ? *parentFieldData : NULL);           \
00134     }                                                                         \
00135 } while (_value_false_node_check_construct);                                                          \
00136 }
00137 
00138 #else
00139 #define SO__NODE_CHECK_INIT(className)  { int _value_false_node_check_init = 0; while(_value_false_node_check_init) {} }
00140 #define SO__NODE_CHECK_CONSTRUCT(where) { int _value_false_node_check_construct = 0; while(_value_false_node_check_construct) {} }
00141 #endif
00142 
00148 
00154 
00155 #define SO_NODE_ABSTRACT_HEADER(className)                                    \
00156   public:                                                                     \
00157     static SoType       getClassTypeId()        /* Returns class type id */   \
00158                                     { return classTypeId; }                   \
00159     virtual SoType      getTypeId() const;      /* Returns type id      */    \
00160   protected:                                                                  \
00161     virtual const SoFieldData   *getFieldData() const;                        \
00162     static const SoFieldData **getFieldDataPtr()                              \
00163         { return (const SoFieldData **)&fieldData; }                          \
00164   private:                                                                    \
00165     static SoType       classTypeId;            /* Type id              */    \
00166     static SbBool       firstInstance; /* true until 2nd c'tor call */        \
00167     static SoFieldData          *fieldData;                                   \
00168     static const SoFieldData    **parentFieldData
00169 
00174 #define SO_NODE_HEADER(className)                                             \
00175     SO_NODE_ABSTRACT_HEADER(className);                                       \
00176     static void *createInstance()
00177 
00182 
00188 
00189 #define SO__NODE_ABSTRACT_VARS(className)                                     \
00190     SoType              className::classTypeId;                               \
00191     SoFieldData        *className::fieldData;                                 \
00192     const SoFieldData **className::parentFieldData;                           \
00193     SbBool              className::firstInstance = TRUE
00194 
00198 #define SO__NODE_VARS(className)                                              \
00199     SO__NODE_ABSTRACT_VARS(className)
00200 
00205 
00206 #define SO__NODE_ABSTRACT_METHODS(className)                                  \
00207                                                                               \
00208     SoType                                                                    \
00209     className::getTypeId() const                                              \
00210     {                                                                         \
00211         return classTypeId;                                                   \
00212     }                                                                         \
00213                                                                               \
00214     const SoFieldData *                                                       \
00215     className::getFieldData() const                                           \
00216     {                                                                         \
00217         SO__NODE_CHECK_CONSTRUCT(SO__QUOTE(className));                       \
00218         return fieldData;                                                     \
00219     }
00220 
00226 
00227 #define SO__NODE_METHODS(className)                                           \
00228                                                                               \
00229     SO__NODE_ABSTRACT_METHODS(className)                                      \
00230                                                                               \
00231     void *                                                                    \
00232     className::createInstance()                                               \
00233     {                                                                         \
00234         return (void *)(new className);                                       \
00235     }
00236 
00237 
00243 
00244 #define SO_NODE_SOURCE(className)                                             \
00245     SO__NODE_VARS(className);                                                 \
00246     SO__NODE_METHODS(className)
00247 
00248 #define SO_NODE_ABSTRACT_SOURCE(className)                                    \
00249     SO__NODE_ABSTRACT_VARS(className);                                        \
00250     SO__NODE_ABSTRACT_METHODS(className)
00251 
00252 
00257 
00258 #define SO__NODE_INIT_CLASS(className,classPrintName,parentClass) {           \
00259 int _value_false= 0;                                                          \
00260 do {                                                                          \
00261     classTypeId =                                                             \
00262         SoType::createType(parentClass::getClassTypeId(),                     \
00263                    classPrintName,                                            \
00264                    &className::createInstance,                                \
00265                    SoNode::nextActionMethodIndex++);                          \
00266     parentFieldData = parentClass::getFieldDataPtr();                         \
00267 } while (_value_false);                                                       \
00268 }
00269 
00270 #define SO__NODE_INIT_ABSTRACT_CLASS(className,classPrintName,parentClass) {  \
00271 int _value_false= 0;                                                          \
00272 do {                                                                          \
00273     classTypeId =                                                             \
00274         SoType::createType(parentClass::getClassTypeId(),                     \
00275                    classPrintName,                                            \
00276                    NULL,                                                      \
00277                    SoNode::nextActionMethodIndex++);                          \
00278     parentFieldData = parentClass::getFieldDataPtr();                         \
00279 } while (_value_false);                                                       \
00280 }
00281 
00289 
00290 #define SO_NODE_INIT_CLASS(className,parentClass,parentPrintClass) {          \
00291 int _value_false= 0;                                                          \
00292 do {                                                                          \
00293     classTypeId =                                                             \
00294         SoType::createType(SoType::fromName(parentPrintClass),                \
00295                    SO__QUOTE(className),                                      \
00296                    &className::createInstance,                                \
00297                    SoNode::nextActionMethodIndex++);                          \
00298     parentFieldData = parentClass::getFieldDataPtr();                         \
00299 } while (_value_false);                                                       \
00300 }
00301 
00302 #define SO_NODE_INIT_ABSTRACT_CLASS(className, parentClass, parentPrintClass) {  \
00303 int _value_false= 0;                                                          \
00304 do {                                                                          \
00305     classTypeId =                                                             \
00306         SoType::createType(SoType::fromName(parentPrintClass),                \
00307                    SO__QUOTE(className),                                      \
00308                    NULL,                                                      \
00309                    SoNode::nextActionMethodIndex++);                          \
00310     parentFieldData = parentClass::getFieldDataPtr();                         \
00311 } while (_value_false);                                                       \
00312 }
00313 
00319 
00320 #define SO_NODE_CONSTRUCTOR(className) {                                      \
00321 int _value_false= 0;                                                          \
00322 do {                                                                          \
00323     SO__NODE_CHECK_INIT(className);                                           \
00324     if (fieldData == NULL)                                                    \
00325         fieldData = new SoFieldData(                                          \
00326             parentFieldData ? *parentFieldData : NULL);                       \
00327     else                                                                      \
00328         firstInstance = FALSE;                                                \
00329     isBuiltIn = FALSE;                                                        \
00330 } while (_value_false);                                                       \
00331 }
00332 
00338 
00339 #define SO_NODE_IS_FIRST_INSTANCE()                                           \
00340     (firstInstance == TRUE)
00341 
00342 
00358 
00359 #define SO_NODE_ADD_FIELD(fieldName,defValue) {                               \
00360     int _value_false= 0;                                                      \
00361     do {                                                                      \
00362         SO__NODE_CHECK_CONSTRUCT(__FILE__);                                   \
00363         if (firstInstance)                                                    \
00364             fieldData->addField(this, SO__QUOTE(fieldName),                   \
00365                                 &this->fieldName);                            \
00366         this->fieldName.setValue defValue;                                    \
00367         this->fieldName.setContainer(this);                                   \
00368     } while (_value_false);                                                   \
00369     }
00370 
00392 
00393 #define SO_NODE_DEFINE_ENUM_VALUE(enumType,enumValue) {                       \
00394     int _value_false= 0;                                                      \
00395     do {                                                                      \
00396         SO__NODE_CHECK_CONSTRUCT(__FILE__);                                   \
00397         if (firstInstance)                                                    \
00398             fieldData->addEnumValue(SO__QUOTE(enumType),                      \
00399                                 SO__QUOTE(enumValue),                         \
00400                                 enumValue);                                   \
00401     } while (_value_false);                                                   \
00402     }
00403 
00404 
00405 #endif /* _SO_SUB_NODE_ */
00406