![]() |
http://www.sim.no/ http://www.coin3d.org/ |
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) by Kongsberg Oil & Gas Technologies. 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 Kongsberg Oil & Gas Technologies 00018 * about acquiring a Coin Professional Edition License. 00019 * 00020 * See http://www.coin3d.org/ for more information. 00021 * 00022 * Kongsberg Oil & Gas Technologies, Bygdoy Alle 5, 0257 Oslo, 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/C/tidbits.h> 00031 #include <Inventor/engines/SoEngine.h> 00032 #include <Inventor/engines/SoOutputData.h> 00033 #include <Inventor/fields/SoFieldData.h> 00034 00035 // ************************************************************************* 00036 00037 // 00038 // FIXME: document macros. pederb, 20000309 00039 // 00040 00041 #define PRIVATE_ENGINE_TYPESYSTEM_HEADER( ) \ 00042 public: \ 00043 static SoType getClassTypeId(void); \ 00044 virtual SoType getTypeId(void) const; \ 00045 private: \ 00046 static SoType classTypeId 00047 00048 #define SO_ENGINE_ABSTRACT_HEADER(_classname_) \ 00049 PRIVATE_ENGINE_TYPESYSTEM_HEADER(); \ 00050 protected: \ 00051 static const SoFieldData ** getInputDataPtr(void); \ 00052 static const SoEngineOutputData ** getOutputDataPtr(void); \ 00053 public: \ 00054 virtual const SoFieldData * getFieldData(void) const; \ 00055 virtual const SoEngineOutputData * getOutputData(void) const; \ 00056 private: \ 00057 static unsigned int classinstances; \ 00058 static SoFieldData * inputdata; \ 00059 static const SoFieldData ** parentinputdata; \ 00060 static SoEngineOutputData * outputdata; \ 00061 static const SoEngineOutputData ** parentoutputdata; \ 00062 static void atexit_cleanup(void) 00063 00064 #define SO_ENGINE_HEADER(_classname_) \ 00065 SO_ENGINE_ABSTRACT_HEADER(_classname_); \ 00066 public: \ 00067 static void * createInstance(void) 00068 00069 // ************************************************************************* 00070 00071 #define PRIVATE_ENGINE_TYPESYSTEM_SOURCE(_class_) \ 00072 SoType _class_::getClassTypeId(void) { return _class_::classTypeId; } \ 00073 SoType _class_::getTypeId(void) const { return _class_::classTypeId; } \ 00074 SoType _class_::classTypeId STATIC_SOTYPE_INIT 00075 00076 #define SO_ENGINE_ABSTRACT_SOURCE(_class_) \ 00077 PRIVATE_ENGINE_TYPESYSTEM_SOURCE(_class_); \ 00078 \ 00079 unsigned int _class_::classinstances = 0; \ 00080 SoFieldData * _class_::inputdata = NULL; \ 00081 const SoFieldData ** _class_::parentinputdata = NULL; \ 00082 SoEngineOutputData * _class_::outputdata = NULL; \ 00083 const SoEngineOutputData ** _class_::parentoutputdata = NULL; \ 00084 \ 00085 const SoFieldData ** \ 00086 _class_::getInputDataPtr(void) \ 00087 { \ 00088 return const_cast<const SoFieldData **>(&_class_::inputdata); \ 00089 } \ 00090 \ 00091 const SoFieldData * \ 00092 _class_::getFieldData(void) const \ 00093 { \ 00094 return _class_::inputdata; \ 00095 } \ 00096 \ 00097 const SoEngineOutputData ** \ 00098 _class_::getOutputDataPtr(void) \ 00099 { \ 00100 return const_cast<const SoEngineOutputData**>(&_class_::outputdata); \ 00101 } \ 00102 \ 00103 const SoEngineOutputData * \ 00104 _class_::getOutputData(void) const \ 00105 { \ 00106 return _class_::outputdata; \ 00107 } \ 00108 \ 00109 void \ 00110 _class_::atexit_cleanup(void) \ 00111 { \ 00112 delete _class_::inputdata; \ 00113 delete _class_::outputdata; \ 00114 _class_::inputdata = NULL; \ 00115 _class_::outputdata = NULL; \ 00116 _class_::parentinputdata = NULL; \ 00117 _class_::parentoutputdata = NULL; \ 00118 assert(_class_::classTypeId != SoType::badType()); \ 00119 SoType::removeType(_class_::classTypeId.getName()); \ 00120 _class_::classTypeId STATIC_SOTYPE_INIT; \ 00121 _class_::classinstances = 0; \ 00122 } 00123 00124 #define SO_ENGINE_SOURCE(_class_) \ 00125 SO_ENGINE_ABSTRACT_SOURCE(_class_); \ 00126 \ 00127 void * \ 00128 _class_::createInstance(void) \ 00129 { \ 00130 return new _class_; \ 00131 } 00132 00133 // ************************************************************************* 00134 00135 #define SO_ENGINE_IS_FIRST_INSTANCE() \ 00136 (classinstances == 1) 00137 00138 #define SO_ENGINE_CONSTRUCTOR(_class_) \ 00139 do { \ 00140 SoBase::staticDataLock(); \ 00141 _class_::classinstances++; \ 00142 /* Catch attempts to use an engine class which has not been initialized. */ \ 00143 assert(_class_::classTypeId != SoType::badType()); \ 00144 /* Initialize a inputdata container for the class only once. */ \ 00145 if (!_class_::inputdata) { \ 00146 _class_::inputdata = \ 00147 new SoFieldData(_class_::parentinputdata ? \ 00148 *_class_::parentinputdata : NULL); \ 00149 _class_::outputdata = \ 00150 new SoEngineOutputData(_class_::parentoutputdata ? \ 00151 *_class_::parentoutputdata : NULL); \ 00152 } \ 00153 /* Extension classes from the application programmers should not be */ \ 00154 /* considered native. This is important to get the export code to do */ \ 00155 /* the Right Thing. */ \ 00156 this->isBuiltIn = FALSE; \ 00157 SoBase::staticDataUnlock(); \ 00158 } while (0) 00159 00160 // ************************************************************************* 00161 00162 #define PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, _classname_, _createfunc_, _parentclass_) \ 00163 do { \ 00164 /* Make sure we only initialize once. */ \ 00165 assert(_class_::classTypeId == SoType::badType()); \ 00166 /* Make sure superclass gets initialized before subclass. */ \ 00167 assert(_parentclass_::getClassTypeId() != SoType::badType()); \ 00168 \ 00169 /* Set up entry in the type system. */ \ 00170 _class_::classTypeId = \ 00171 SoType::createType(_parentclass_::getClassTypeId(), \ 00172 _classname_, \ 00173 _createfunc_); \ 00174 \ 00175 /* Store parent's data pointers for later use in the constructor. */ \ 00176 _class_::parentinputdata = _parentclass_::getInputDataPtr(); \ 00177 _class_::parentoutputdata = _parentclass_::getOutputDataPtr(); \ 00178 cc_coin_atexit_static_internal \ 00179 (reinterpret_cast<coin_atexit_f*>(_class_::atexit_cleanup)); \ 00180 } while (0) 00181 00182 00183 #define SO_ENGINE_INIT_CLASS(_class_, _parentclass_, _parentname_) \ 00184 do { \ 00185 const char * classname = SO__QUOTE(_class_); \ 00186 PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, classname, &_class_::createInstance, _parentclass_); \ 00187 } while (0) 00188 00189 #define SO_ENGINE_INIT_ABSTRACT_CLASS(_class_, _parentclass_, _parentname_) \ 00190 do { \ 00191 const char * classname = SO__QUOTE(_class_); \ 00192 PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, classname, NULL, _parentclass_); \ 00193 } while (0) 00194 00195 // ************************************************************************* 00196 00197 #define SO_ENGINE_ADD_INPUT(_input_, _defaultval_) \ 00198 do { \ 00199 this->_input_.setValue _defaultval_;\ 00200 this->_input_.setContainer(this); \ 00201 inputdata->addField(this, SO__QUOTE(_input_), &this->_input_);\ 00202 } while (0) 00203 00204 #define SO_ENGINE_ADD_OUTPUT(_output_, _type_) \ 00205 do { \ 00206 outputdata->addOutput(this, SO__QUOTE(_output_), \ 00207 &this->_output_, \ 00208 _type_::getClassTypeId()); \ 00209 this->_output_.setContainer(this); \ 00210 } while(0) 00211 00212 // ************************************************************************* 00213 00214 #define SO_ENGINE_DEFINE_ENUM_VALUE(_enumname_, _enumval_) \ 00215 do { \ 00216 inputdata->addEnumValue(SO__QUOTE(_enumname_), \ 00217 SO__QUOTE(_enumval_), _enumval_); \ 00218 } while (0) 00219 00220 #define SO_ENGINE_OUTPUT(_engineout_, _fieldtype_, _writeop_) \ 00221 do { \ 00222 if (_engineout_.isEnabled()) { \ 00223 /* No fields can be added or removed during this loop, as it */ \ 00224 /* is a "closed" operation. (The fields are disabled for */ \ 00225 /* notification while the loop runs). */ \ 00226 int SO_ENGINE_OUTPUT_numconnections = _engineout_.getNumConnections(); \ 00227 /* The reason we use the perverted variable names is to */ \ 00228 /* avoid the possibility of getting _extremely_ hard */ \ 00229 /* to find bugs when _writeop_ contains the same variable */ \ 00230 /* names we are using internally in the macro. */ \ 00231 for (int SO_ENGINE_OUTPUT_i = 0; SO_ENGINE_OUTPUT_i < SO_ENGINE_OUTPUT_numconnections; SO_ENGINE_OUTPUT_i++) { \ 00232 _fieldtype_ * SO_ENGINE_OUTPUT_field = \ 00233 static_cast<_fieldtype_*>(_engineout_[SO_ENGINE_OUTPUT_i]); \ 00234 if (!SO_ENGINE_OUTPUT_field->isReadOnly()) { SO_ENGINE_OUTPUT_field->_writeop_; } \ 00235 } \ 00236 /* paranoid assertion */ \ 00237 assert(_engineout_.getNumConnections() == SO_ENGINE_OUTPUT_numconnections); \ 00238 } \ 00239 } while (0) 00240 00241 // ************************************************************************* 00242 00243 #define SO_COMPOSE__HEADER(_name_) \ 00244 SO_ENGINE_HEADER(_name_); \ 00245 private: \ 00246 virtual void evaluate(); \ 00247 protected: \ 00248 virtual ~_name_();\ 00249 public: \ 00250 _name_(); \ 00251 static void initClass() 00252 00253 // ************************************************************************* 00254 00255 #endif // !COIN_SOSUBENGINE_H
Copyright © 1998-2010 by Kongsberg Oil & Gas Technologies. All rights reserved.
Generated on Sun May 1 2011 02:58:22 for Coin by Doxygen 1.7.3.