Coin Logo http://www.sim.no
http://www.coin3d.org

SoSubEngine.h

00001 #ifndef COIN_SOSUBENGINE_H
00002 #define COIN_SOSUBENGINE_H
00003 
00004 /**************************************************************************\
00005  *
00006  *  This file is part of the Coin 3D visualization library.
00007  *  Copyright (C) 1998-2007 by Systems in Motion.  All rights reserved.
00008  *
00009  *  This library is free software; you can redistribute it and/or
00010  *  modify it under the terms of the GNU General Public License
00011  *  ("GPL") version 2 as published by the Free Software Foundation.
00012  *  See the file LICENSE.GPL at the root directory of this source
00013  *  distribution for additional information about the GNU GPL.
00014  *
00015  *  For using Coin with software that can not be combined with the GNU
00016  *  GPL, and for taking advantage of the additional benefits of our
00017  *  support services, please contact Systems in Motion about acquiring
00018  *  a Coin Professional Edition License.
00019  *
00020  *  See http://www.coin3d.org/ for more information.
00021  *
00022  *  Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY.
00023  *  http://www.sim.no/  sales@sim.no  coin-support@coin3d.org
00024  *
00025 \**************************************************************************/
00026 
00027 #include <assert.h>
00028 #include <Inventor/SbName.h>
00029 #include <Inventor/SoType.h>
00030 #include <Inventor/engines/SoEngine.h>
00031 #include <Inventor/engines/SoOutputData.h>
00032 #include <Inventor/fields/SoFieldData.h>
00033 
00034 // *************************************************************************
00035 
00036 //
00037 // FIXME: document macros. pederb, 20000309
00038 //
00039 
00040 #define PRIVATE_ENGINE_TYPESYSTEM_HEADER( ) \
00041 public: \
00042   static SoType getClassTypeId(void); \
00043   virtual SoType getTypeId(void) const; \
00044 private: \
00045   static SoType classTypeId
00046 
00047 #define SO_ENGINE_ABSTRACT_HEADER(_classname_) \
00048   PRIVATE_ENGINE_TYPESYSTEM_HEADER(); \
00049 protected: \
00050   static const SoFieldData ** getInputDataPtr(void); \
00051   static const SoEngineOutputData ** getOutputDataPtr(void); \
00052 public: \
00053   virtual const SoFieldData * getFieldData(void) const; \
00054   virtual const SoEngineOutputData * getOutputData(void) const; \
00055 private: \
00056   static unsigned int classinstances; \
00057   static SoFieldData * inputdata; \
00058   static const SoFieldData ** parentinputdata; \
00059   static SoEngineOutputData * outputdata; \
00060   static const SoEngineOutputData ** parentoutputdata; \
00061   static void atexit_cleanup(void)
00062 
00063 #define SO_ENGINE_HEADER(_classname_) \
00064     SO_ENGINE_ABSTRACT_HEADER(_classname_); \
00065   public: \
00066     static void * createInstance(void)
00067 
00068 // *************************************************************************
00069 
00070 #define PRIVATE_ENGINE_TYPESYSTEM_SOURCE(_class_) \
00071 SoType _class_::getClassTypeId(void) { return _class_::classTypeId; } \
00072 SoType _class_::getTypeId(void) const { return _class_::classTypeId; } \
00073 SoType _class_::classTypeId STATIC_SOTYPE_INIT
00074 
00075 #define SO_ENGINE_ABSTRACT_SOURCE(_class_) \
00076 PRIVATE_ENGINE_TYPESYSTEM_SOURCE(_class_); \
00077  \
00078 unsigned int _class_::classinstances = 0; \
00079 SoFieldData * _class_::inputdata = NULL; \
00080 const SoFieldData ** _class_::parentinputdata = NULL; \
00081 SoEngineOutputData * _class_::outputdata = NULL; \
00082 const SoEngineOutputData ** _class_::parentoutputdata = NULL; \
00083  \
00084 const SoFieldData ** \
00085 _class_::getInputDataPtr(void) \
00086 { \
00087   return (const SoFieldData **)&_class_::inputdata; \
00088 } \
00089  \
00090 const SoFieldData * \
00091 _class_::getFieldData(void) const \
00092 { \
00093   return _class_::inputdata; \
00094 } \
00095  \
00096 const SoEngineOutputData ** \
00097 _class_::getOutputDataPtr(void) \
00098 { \
00099   return (const SoEngineOutputData**)&_class_::outputdata; \
00100 } \
00101  \
00102 const SoEngineOutputData * \
00103 _class_::getOutputData(void) const \
00104 { \
00105   return _class_::outputdata; \
00106 }
00107 
00108 #define SO_ENGINE_SOURCE(_class_) \
00109 SO_ENGINE_ABSTRACT_SOURCE(_class_); \
00110  \
00111 void * \
00112 _class_::createInstance(void) \
00113 { \
00114   return new _class_; \
00115 } \
00116  \
00117 void \
00118 _class_::atexit_cleanup(void) \
00119 { \
00120   delete _class_::inputdata; \
00121   delete _class_::outputdata; \
00122   _class_::inputdata = NULL; \
00123   _class_::outputdata = NULL; \
00124   _class_::parentinputdata = NULL; \
00125   _class_::parentoutputdata = NULL; \
00126   _class_::classTypeId STATIC_SOTYPE_INIT; \
00127   _class_::classinstances = 0; \
00128 }
00129 
00130 // *************************************************************************
00131 
00132 #define SO_ENGINE_IS_FIRST_INSTANCE() \
00133    (classinstances == 1) 
00134 
00135 #define SO_ENGINE_CONSTRUCTOR(_class_) \
00136   do { \
00137     SoBase::staticDataLock(); \
00138     _class_::classinstances++; \
00139     /* Catch attempts to use an engine class which has not been initialized. */ \
00140     assert(_class_::classTypeId != SoType::badType()); \
00141     /* Initialize a inputdata container for the class only once. */ \
00142     if (!_class_::inputdata) { \
00143       _class_::inputdata = \
00144         new SoFieldData(_class_::parentinputdata ? \
00145                         *_class_::parentinputdata : NULL); \
00146       _class_::outputdata = \
00147         new SoEngineOutputData(_class_::parentoutputdata ? \
00148                                *_class_::parentoutputdata : NULL); \
00149     } \
00150     /* Extension classes from the application programmers should not be */ \
00151     /* considered native. This is important to get the export code to do */ \
00152     /* the Right Thing. */ \
00153     this->isBuiltIn = FALSE; \
00154     SoBase::staticDataUnlock(); \
00155   } while (0)
00156 
00157 // *************************************************************************
00158 
00159 #define PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, _classname_, _createfunc_, _parentclass_) \
00160   do { \
00161     /* Make sure we only initialize once. */ \
00162     assert(_class_::classTypeId == SoType::badType()); \
00163     /* Make sure superclass gets initialized before subclass. */ \
00164     assert(_parentclass_::getClassTypeId() != SoType::badType()); \
00165  \
00166     /* Set up entry in the type system. */ \
00167     _class_::classTypeId = \
00168       SoType::createType(_parentclass_::getClassTypeId(), \
00169                          _classname_, \
00170                          _createfunc_); \
00171  \
00172     /* Store parent's data pointers for later use in the constructor. */ \
00173     _class_::parentinputdata = _parentclass_::getInputDataPtr(); \
00174     _class_::parentoutputdata = _parentclass_::getOutputDataPtr(); \
00175   } while (0)
00176 
00177 
00178 #define SO_ENGINE_INIT_CLASS(_class_, _parentclass_, _parentname_) \
00179   do { \
00180     const char * classname = SO__QUOTE(_class_); \
00181     PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, classname, &_class_::createInstance, _parentclass_); \
00182   } while (0)
00183 
00184 #define SO_ENGINE_EXIT_CLASS(_class_) \
00185   _class_::atexit_cleanup()
00186 
00187 #define SO_ENGINE_INIT_ABSTRACT_CLASS(_class_, _parentclass_, _parentname_) \
00188   do { \
00189     const char * classname = SO__QUOTE(_class_); \
00190     PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, classname, NULL, _parentclass_); \
00191   } while (0)
00192 
00193 // *************************************************************************
00194 
00195 #define SO_ENGINE_ADD_INPUT(_input_, _defaultval_) \
00196   do { \
00197     this->_input_.setValue _defaultval_;\
00198     this->_input_.setContainer(this); \
00199     inputdata->addField(this, SO__QUOTE(_input_), &this->_input_);\
00200   } while (0)
00201 
00202 #define SO_ENGINE_ADD_OUTPUT(_output_, _type_) \
00203   do { \
00204     outputdata->addOutput(this, SO__QUOTE(_output_), \
00205                           &this->_output_, \
00206                           _type_::getClassTypeId()); \
00207     this->_output_.setContainer(this); \
00208   } while(0)
00209 
00210 // *************************************************************************
00211 
00212 #define SO_ENGINE_DEFINE_ENUM_VALUE(_enumname_, _enumval_) \
00213   do { \
00214     inputdata->addEnumValue(SO__QUOTE(_enumname_), \
00215                             SO__QUOTE(_enumval_), _enumval_); \
00216   } while (0)
00217 
00218 #define SO_ENGINE_OUTPUT(_engineout_, _fieldtype_, _writeop_) \
00219   do { \
00220     if (_engineout_.isEnabled()) { \
00221       /* No fields can be added or removed during this loop, as it */ \
00222       /* is a "closed" operation. (The fields are disabled for */ \
00223       /* notification while the loop runs). */ \
00224       int SO_ENGINE_OUTPUT_numconnections = _engineout_.getNumConnections(); \
00225       /* The reason we use the perverted variable names is to */ \
00226       /* avoid the possibility of getting _extremely_ hard */ \
00227       /* to find bugs when _writeop_ contains the same variable */ \
00228       /* names we are using internally in the macro. */ \
00229       for (int SO_ENGINE_OUTPUT_i = 0; SO_ENGINE_OUTPUT_i < SO_ENGINE_OUTPUT_numconnections; SO_ENGINE_OUTPUT_i++) { \
00230         _fieldtype_ * SO_ENGINE_OUTPUT_field = (_fieldtype_*) _engineout_[SO_ENGINE_OUTPUT_i]; \
00231         if (!SO_ENGINE_OUTPUT_field->isReadOnly()) { SO_ENGINE_OUTPUT_field->_writeop_; } \
00232       } \
00233       /* paranoid assertion */ \
00234       assert(_engineout_.getNumConnections() == SO_ENGINE_OUTPUT_numconnections); \
00235     } \
00236   } while (0)
00237 
00238 // *************************************************************************
00239 
00240 #define SO_COMPOSE__HEADER(_name_) \
00241   SO_ENGINE_HEADER(_name_); \
00242   private: \
00243     virtual void evaluate(); \
00244   protected: \
00245     ~_name_();\
00246   public: \
00247    _name_(); \
00248     static void initClass()
00249 
00250 // *************************************************************************
00251 
00252 #endif // !COIN_SOSUBENGINE_H

Copyright © 1998-2007 by Systems in Motion AS. All rights reserved.

Generated on Mon Feb 23 16:33:32 2009 for Coin by Doxygen. 1.5.8