![]() |
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) 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 28 2011 10:11:58 for Coin by Doxygen. 1.7.3