![]() |
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-2005 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 <URL:http://www.coin3d.org/> for more information. 00021 * 00022 * Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY. 00023 * <URL:http://www.sim.no/>. 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 00062 #define SO_ENGINE_HEADER(_classname_) \ 00063 SO_ENGINE_ABSTRACT_HEADER(_classname_); \ 00064 public: \ 00065 static void * createInstance(void) 00066 00067 // ************************************************************************* 00068 00069 #define PRIVATE_ENGINE_TYPESYSTEM_SOURCE(_class_) \ 00070 SoType _class_::getClassTypeId(void) { return _class_::classTypeId; } \ 00071 SoType _class_::getTypeId(void) const { return _class_::classTypeId; } \ 00072 SoType _class_::classTypeId STATIC_SOTYPE_INIT 00073 00074 #define SO_ENGINE_ABSTRACT_SOURCE(_class_) \ 00075 PRIVATE_ENGINE_TYPESYSTEM_SOURCE(_class_); \ 00076 \ 00077 unsigned int _class_::classinstances = 0; \ 00078 SoFieldData * _class_::inputdata = NULL; \ 00079 const SoFieldData ** _class_::parentinputdata = NULL; \ 00080 SoEngineOutputData * _class_::outputdata = NULL; \ 00081 const SoEngineOutputData ** _class_::parentoutputdata = NULL; \ 00082 \ 00083 const SoFieldData ** \ 00084 _class_::getInputDataPtr(void) \ 00085 { \ 00086 return (const SoFieldData **)&_class_::inputdata; \ 00087 } \ 00088 \ 00089 const SoFieldData * \ 00090 _class_::getFieldData(void) const \ 00091 { \ 00092 return _class_::inputdata; \ 00093 } \ 00094 \ 00095 const SoEngineOutputData ** \ 00096 _class_::getOutputDataPtr(void) \ 00097 { \ 00098 return (const SoEngineOutputData**)&_class_::outputdata; \ 00099 } \ 00100 \ 00101 const SoEngineOutputData * \ 00102 _class_::getOutputData(void) const \ 00103 { \ 00104 return _class_::outputdata; \ 00105 } 00106 00107 #define SO_ENGINE_SOURCE(_class_) \ 00108 SO_ENGINE_ABSTRACT_SOURCE(_class_); \ 00109 \ 00110 void * \ 00111 _class_::createInstance(void) \ 00112 { \ 00113 return new _class_; \ 00114 } 00115 00116 // ************************************************************************* 00117 00118 #define SO_ENGINE_IS_FIRST_INSTANCE() \ 00119 (classinstances == 1) 00120 00121 #define SO_ENGINE_CONSTRUCTOR(_class_) \ 00122 do { \ 00123 SoBase::staticDataLock(); \ 00124 _class_::classinstances++; \ 00125 /* Catch attempts to use an engine class which has not been initialized. */ \ 00126 assert(_class_::classTypeId != SoType::badType()); \ 00127 /* Initialize a inputdata container for the class only once. */ \ 00128 if (!_class_::inputdata) { \ 00129 _class_::inputdata = \ 00130 new SoFieldData(_class_::parentinputdata ? \ 00131 *_class_::parentinputdata : NULL); \ 00132 _class_::outputdata = \ 00133 new SoEngineOutputData(_class_::parentoutputdata ? \ 00134 *_class_::parentoutputdata : NULL); \ 00135 } \ 00136 /* Extension classes from the application programmers should not be */ \ 00137 /* considered native. This is important to get the export code to do */ \ 00138 /* the Right Thing. */ \ 00139 this->isBuiltIn = FALSE; \ 00140 SoBase::staticDataUnlock(); \ 00141 } while (0) 00142 00143 // ************************************************************************* 00144 00145 #define PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, _classname_, _createfunc_, _parentclass_) \ 00146 do { \ 00147 /* Make sure we only initialize once. */ \ 00148 assert(_class_::classTypeId == SoType::badType()); \ 00149 /* Make sure superclass gets initialized before subclass. */ \ 00150 assert(_parentclass_::getClassTypeId() != SoType::badType()); \ 00151 \ 00152 /* Set up entry in the type system. */ \ 00153 _class_::classTypeId = \ 00154 SoType::createType(_parentclass_::getClassTypeId(), \ 00155 _classname_, \ 00156 _createfunc_); \ 00157 \ 00158 /* Store parent's data pointers for later use in the constructor. */ \ 00159 _class_::parentinputdata = _parentclass_::getInputDataPtr(); \ 00160 _class_::parentoutputdata = _parentclass_::getOutputDataPtr(); \ 00161 } while (0) 00162 00163 00164 #define SO_ENGINE_INIT_CLASS(_class_, _parentclass_, _parentname_) \ 00165 do { \ 00166 const char * classname = SO__QUOTE(_class_); \ 00167 PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, classname, &_class_::createInstance, _parentclass_); \ 00168 } while (0) 00169 00170 00171 #define SO_ENGINE_INIT_ABSTRACT_CLASS(_class_, _parentclass_, _parentname_) \ 00172 do { \ 00173 const char * classname = SO__QUOTE(_class_); \ 00174 PRIVATE_COMMON_ENGINE_INIT_CODE(_class_, classname, NULL, _parentclass_); \ 00175 } while (0) 00176 00177 // ************************************************************************* 00178 00179 #define SO_ENGINE_ADD_INPUT(_input_, _defaultval_) \ 00180 do { \ 00181 this->_input_.setValue _defaultval_;\ 00182 this->_input_.setContainer(this); \ 00183 inputdata->addField(this, SO__QUOTE(_input_), &this->_input_);\ 00184 } while (0) 00185 00186 #define SO_ENGINE_ADD_OUTPUT(_output_, _type_) \ 00187 do { \ 00188 outputdata->addOutput(this, SO__QUOTE(_output_), \ 00189 &this->_output_, \ 00190 _type_::getClassTypeId()); \ 00191 this->_output_.setContainer(this); \ 00192 } while(0) 00193 00194 // ************************************************************************* 00195 00196 #define SO_ENGINE_DEFINE_ENUM_VALUE(_enumname_, _enumval_) \ 00197 do { \ 00198 inputdata->addEnumValue(SO__QUOTE(_enumname_), \ 00199 SO__QUOTE(_enumval_), _enumval_); \ 00200 } while (0) 00201 00202 #define SO_ENGINE_OUTPUT(_engineout_, _fieldtype_, _writeop_) \ 00203 do { \ 00204 if (_engineout_.isEnabled()) { \ 00205 /* No fields can be added or removed during this loop, as it */ \ 00206 /* is a "closed" operation. (The fields are disabled for */ \ 00207 /* notification while the loop runs). */ \ 00208 int SO_ENGINE_OUTPUT_numconnections = _engineout_.getNumConnections(); \ 00209 /* The reason we use the perverted variable names is to */ \ 00210 /* avoid the possibility of getting _extremely_ hard */ \ 00211 /* to find bugs when _writeop_ contains the same variable */ \ 00212 /* names we are using internally in the macro. */ \ 00213 for (int SO_ENGINE_OUTPUT_i = 0; SO_ENGINE_OUTPUT_i < SO_ENGINE_OUTPUT_numconnections; SO_ENGINE_OUTPUT_i++) { \ 00214 _fieldtype_ * SO_ENGINE_OUTPUT_field = (_fieldtype_*) _engineout_[SO_ENGINE_OUTPUT_i]; \ 00215 if (!SO_ENGINE_OUTPUT_field->isReadOnly()) { SO_ENGINE_OUTPUT_field->_writeop_; } \ 00216 } \ 00217 /* paranoid assertion */ \ 00218 assert(_engineout_.getNumConnections() == SO_ENGINE_OUTPUT_numconnections); \ 00219 } \ 00220 } while (0) 00221 00222 // ************************************************************************* 00223 00224 #define SO_COMPOSE__HEADER(_name_) \ 00225 SO_ENGINE_HEADER(_name_); \ 00226 private: \ 00227 virtual void evaluate(); \ 00228 protected: \ 00229 ~_name_();\ 00230 public: \ 00231 _name_(); \ 00232 static void initClass() 00233 00234 // ************************************************************************* 00235 00236 #endif // !COIN_SOSUBENGINE_H
Copyright © 1998-2005 by Systems in Motion AS. All rights reserved.
Generated on Sun Aug 21 16:51:12 2005 for Coin by Doxygen. 1.3.9.1