Open Inventor Reference
|
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 | subclasses of SoEngine. They may be used to make SoEngine 00049 | subclassing easier. In all of the macros, the "className" 00050 | parameter refers to the name of the engine subclass. 00051 | 00052 | Defined macros: 00053 | 00054 | Within class header: 00055 | 00056 | SO_ENGINE_HEADER(className) 00057 | SO_ENGINE_ABSTRACT_HEADER(className) 00058 | 00059 | Within class source: 00060 | 00061 | At file scope: 00062 | 00063 | SO_ENGINE_SOURCE(className) 00064 | SO_ENGINE_ABSTRACT_SOURCE(className) 00065 | 00066 | Inside the initClass method: 00067 | 00068 | SO_ENGINE_INIT_CLASS() 00069 | SO_ENGINE_INIT_ABSTRACT_CLASS() 00070 | 00071 | Inside the constructor: 00072 | 00073 | SO_ENGINE_CONSTRUCTOR(className) 00074 | SO_ENGINE_ADD_INPUT(inputName, (defaultValue)) 00075 | SO_ENGINE_ADD_OUTPUT(outputName, outputType) 00076 | SO_ENGINE_DEFINE_ENUM_VALUE(enumType, enumValue) 00077 | SO_ENGINE_IS_FIRST_INSTANCE() //!< a boolean value 00078 | 00079 | //!< the following are defined in <fields/So[SM]fEnum.h>: 00080 | SO_ENGINE_SET_SF_ENUM_TYPE(fieldName,enumType) 00081 | SO_ENGINE_SET_MF_ENUM_TYPE(fieldName,enumType) 00082 | 00083 | Inside the evaluate method: 00084 | 00085 | SO_ENGINE_OUTPUT(outputName, outputType, method) 00086 | 00087 | Author(s) : Paul S. Strauss, Gavin Bell 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_ENGINE_ 00094 #define _SO_SUB_ENGINE_ 00095 00096 #include <Inventor/engines/SoEngine.h> 00097 #include <Inventor/engines/SoOutputData.h> 00098 #include <Inventor/errors/SoDebugError.h> 00099 #include <Inventor/fields/SoFieldData.h> 00100 00101 00106 #ifdef DEBUG 00107 #define SO__ENGINE_CHECK_INIT(className) \ 00108 if (classTypeId == SoType::badType()) { \ 00109 SoDebugError::post("SO_ENGINE_CONSTRUCTOR", \ 00110 "Can't construct an engine of type " \ 00111 SO__QUOTE(className), \ 00112 "until initClass() has been called"); \ 00113 return; \ 00114 } 00115 00116 #define SO__ENGINE_CHECK_CONSTRUCT(where) { \ 00117 int _value_false= 0; \ 00118 do { \ 00119 if (inputData == NULL) { \ 00120 SoDebugError::post(where, \ 00121 "Instance not properly constructed.\n" \ 00122 "Did you forget to put " \ 00123 "SO_ENGINE_CONSTRUCTOR()" \ 00124 " in the constructor?"); \ 00125 inputData = new SoFieldData(parentInputData ? \ 00126 *parentInputData : NULL); \ 00127 outputData = new SoEngineOutputData(parentOutputData ? \ 00128 *parentOutputData : NULL); \ 00129 } \ 00130 } while(_value_false); \ 00131 } 00132 00133 #else 00134 #define SO__ENGINE_CHECK_INIT(className) { int _value_false= 0; while(_value_false) {} } 00135 #define SO__ENGINE_CHECK_CONSTRUCT(where) { int _value_false= 0; while(_value_false) {} } 00136 #endif 00137 00142 00148 00149 #define SO_ENGINE_ABSTRACT_HEADER(className) \ 00150 public: \ 00151 static SoType getClassTypeId() { return classTypeId; } \ 00152 virtual SoType getTypeId() const; /* Returns type id */ \ 00153 public: \ 00154 virtual const SoFieldData * getFieldData() const; \ 00155 virtual const SoEngineOutputData * getOutputData() const; \ 00156 protected: \ 00157 static const SoFieldData ** getInputDataPtr() \ 00158 { return (const SoFieldData **)&inputData; } \ 00159 static const SoEngineOutputData ** getOutputDataPtr() \ 00160 { return (const SoEngineOutputData **)&outputData; } \ 00161 private: \ 00162 static SoType classTypeId; /* Type id */ \ 00163 static SbBool firstInstance; /* True for first ctor call */ \ 00164 static SoFieldData *inputData; /* Info on input fields */ \ 00165 static SoEngineOutputData *outputData; /* Info on outputs */ \ 00166 static const SoFieldData **parentInputData; /* parent's fields */ \ 00167 static const SoEngineOutputData **parentOutputData 00168 00169 #define SO_ENGINE_HEADER(className) \ 00170 \ 00171 SO_ENGINE_ABSTRACT_HEADER(className); \ 00172 \ 00173 private: \ 00174 static void *createInstance() /* Creates and returns instance */ 00175 00180 00181 #define SO__ENGINE_ABSTRACT_VARS(className) \ 00182 SoType className::classTypeId; \ 00183 SbBool className::firstInstance=TRUE; \ 00184 SoEngineOutputData *className::outputData; \ 00185 SoFieldData * className::inputData; \ 00186 const SoEngineOutputData **className::parentOutputData; \ 00187 const SoFieldData ** className::parentInputData 00188 00189 #define SO__ENGINE_VARS(className) \ 00190 SO__ENGINE_ABSTRACT_VARS(className) 00191 00196 00197 #define SO__ENGINE_ABSTRACT_METHODS(className) \ 00198 \ 00199 SoType \ 00200 className::getTypeId() const \ 00201 { \ 00202 return classTypeId; \ 00203 } \ 00204 \ 00205 const SoFieldData * \ 00206 className::getFieldData() const \ 00207 { \ 00208 return inputData; \ 00209 } \ 00210 \ 00211 const SoEngineOutputData * \ 00212 className::getOutputData() const \ 00213 { \ 00214 return outputData; \ 00215 } 00216 00217 #define SO__ENGINE_METHODS(className) \ 00218 \ 00219 SO__ENGINE_ABSTRACT_METHODS(className) \ 00220 \ 00221 void * \ 00222 className::createInstance() \ 00223 { \ 00224 return (void *)(new className); \ 00225 } 00226 00231 00232 #define SO_ENGINE_SOURCE(className) \ 00233 SO__ENGINE_VARS(className); \ 00234 SO__ENGINE_METHODS(className) 00235 00236 #define SO_ENGINE_ABSTRACT_SOURCE(className) \ 00237 SO__ENGINE_ABSTRACT_VARS(className); \ 00238 SO__ENGINE_ABSTRACT_METHODS(className) 00239 00244 00245 #define SO__ENGINE_INIT_CLASS(className, classPrintName, parentClass) { \ 00246 int _value_false= 0; \ 00247 do { \ 00248 classTypeId = \ 00249 SoType::createType(parentClass::getClassTypeId(), \ 00250 classPrintName, \ 00251 &className::createInstance); \ 00252 parentInputData = parentClass::getInputDataPtr(); \ 00253 parentOutputData = parentClass::getOutputDataPtr(); \ 00254 } while (_value_false); \ 00255 } 00256 00257 #define SO__ENGINE_INIT_ABSTRACT_CLASS(className,classPrintName,parent) { \ 00258 int _value_false= 0; \ 00259 do { \ 00260 classTypeId = SoType::createType(parent::getClassTypeId(), \ 00261 classPrintName); \ 00262 parentInputData = parent::getInputDataPtr(); \ 00263 parentOutputData = parent::getOutputDataPtr(); \ 00264 } while (_value_false); \ 00265 } 00266 00273 00274 #define SO_ENGINE_INIT_CLASS(className,parentClass,parentPrintClass) { \ 00275 int _value_false= 0; \ 00276 do { \ 00277 classTypeId = \ 00278 SoType::createType(SoType::fromName(parentPrintClass), \ 00279 SO__QUOTE(className), \ 00280 &className::createInstance); \ 00281 parentInputData = parentClass::getInputDataPtr(); \ 00282 parentOutputData = parentClass::getOutputDataPtr(); \ 00283 } while (_value_false); \ 00284 } 00285 00286 #define SO_ENGINE_INIT_ABSTRACT_CLASS(className,parent,parentPrintClass) { \ 00287 int _value_false= 0; \ 00288 do { \ 00289 classTypeId = SoType::createType(SoType::fromName(parentPrintClass), \ 00290 SO__QUOTE(className)); \ 00291 parentInputData = parent::getInputDataPtr(); \ 00292 parentOutputData = parent::getOutputDataPtr(); \ 00293 } while (_value_false); \ 00294 } 00295 00300 00301 #define SO_ENGINE_CONSTRUCTOR(className) { \ 00302 int _value_false= 0; \ 00303 do { \ 00304 SO__ENGINE_CHECK_INIT(className); \ 00305 if (inputData == NULL) { \ 00306 inputData = new SoFieldData(parentInputData ? \ 00307 *parentInputData : NULL); \ 00308 outputData = new SoEngineOutputData(parentOutputData ? \ 00309 *parentOutputData : NULL); \ 00310 } \ 00311 else \ 00312 firstInstance = FALSE; \ 00313 isBuiltIn = FALSE; \ 00314 } while (_value_false); \ 00315 } 00316 00322 00323 #define SO_ENGINE_IS_FIRST_INSTANCE() (firstInstance == TRUE) 00324 00341 00342 #define SO_ENGINE_ADD_INPUT(inputName, defValue) { \ 00343 int _value_false= 0; \ 00344 do { \ 00345 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \ 00346 if (firstInstance) \ 00347 inputData->addField(this, SO__QUOTE(inputName), \ 00348 &this->inputName); \ 00349 this->inputName.setValue defValue; \ 00350 this->inputName.setContainer(this); \ 00351 } while (_value_false); \ 00352 } 00353 00370 00371 #define SO_ENGINE_ADD_OUTPUT(outputName, type) { \ 00372 int _value_false= 0; \ 00373 do { \ 00374 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \ 00375 if (firstInstance) \ 00376 outputData->addOutput(this, SO__QUOTE(outputName), \ 00377 &this->outputName, \ 00378 type::getClassTypeId()); \ 00379 this->outputName.setContainer(this); \ 00380 } while (_value_false); \ 00381 } 00382 00404 00405 #define SO_ENGINE_DEFINE_ENUM_VALUE(enumType,enumValue) { \ 00406 int _value_false= 0; \ 00407 do { \ 00408 SO__ENGINE_CHECK_CONSTRUCT(__FILE__); \ 00409 if (firstInstance) \ 00410 inputData->addEnumValue(SO__QUOTE(enumType), \ 00411 SO__QUOTE(enumValue), enumValue); \ 00412 } while (_value_false); \ 00413 } 00414 00420 00421 #define SO_ENGINE_OUTPUT(outputName,type,code) { \ 00422 int _value_false= 0; \ 00423 do { \ 00424 if (outputName.isEnabled()) { \ 00425 for (int _eng_out_i = 0; \ 00426 _eng_out_i < outputName.getNumConnections(); \ 00427 _eng_out_i++) { \ 00428 type *_eng_out_temp = (type *) outputName[_eng_out_i]; \ 00429 if (!_eng_out_temp->isReadOnly()) { \ 00430 _eng_out_temp->code; \ 00431 } \ 00432 } \ 00433 } \ 00434 } while (_value_false); \ 00435 } 00436 00437 00438 #endif /* _SO_SUB_ENGINE_ */