1 /**************************************************************************\ 2 * Copyright (c) Kongsberg Oil & Gas Technologies AS 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * Neither the name of the copyright holder nor the names of its 17 * contributors may be used to endorse or promote products derived from 18 * this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 \**************************************************************************/ 32 33 #ifndef COIN_SOSUBNODEENGINE_H 34 #define COIN_SOSUBNODEENGINE_H 35 36 #include <Inventor/nodes/SoSubNode.h> 37 #include <Inventor/engines/SoSubEngine.h> 38 39 #define SO_NODEENGINE_ABSTRACT_HEADER(_class_) \ 40 SO_NODE_ABSTRACT_HEADER(_class_); \ 41 protected: \ 42 static const SoEngineOutputData ** getOutputDataPtr(void); \ 43 public: \ 44 virtual const SoEngineOutputData * getOutputData(void) const; \ 45 private: \ 46 static void atexit_cleanupnodeengine(void); \ 47 static SoEngineOutputData * outputdata; \ 48 static const SoEngineOutputData ** parentoutputdata 49 50 #define SO_NODEENGINE_HEADER(_class_) \ 51 SO_NODEENGINE_ABSTRACT_HEADER(_class_); \ 52 public: \ 53 static void * createInstance(void) 54 55 #define SO_NODEENGINE_ABSTRACT_SOURCE(_class_) \ 56 SO_NODE_ABSTRACT_SOURCE(_class_); \ 57 SoEngineOutputData * _class_::outputdata = NULL; \ 58 const SoEngineOutputData ** _class_::parentoutputdata = NULL; \ 59 \ 60 const SoEngineOutputData ** \ 61 _class_::getOutputDataPtr(void) \ 62 { \ 63 return (const SoEngineOutputData**)&_class_::outputdata; \ 64 } \ 65 \ 66 const SoEngineOutputData * \ 67 _class_::getOutputData(void) const \ 68 { \ 69 return _class_::outputdata; \ 70 } \ 71 \ 72 void \ 73 _class_::atexit_cleanupnodeengine(void) { \ 74 delete _class_::outputdata; \ 75 _class_::outputdata = NULL; \ 76 _class_::parentoutputdata = NULL; \ 77 _class_::classTypeId STATIC_SOTYPE_INIT; \ 78 } 79 80 #define SO_NODEENGINE_SOURCE(_class_) \ 81 SO_NODEENGINE_ABSTRACT_SOURCE(_class_); \ 82 \ 83 void * \ 84 _class_::createInstance(void) \ 85 { \ 86 return new _class_; \ 87 } 88 89 #define SO_NODEENGINE_CONSTRUCTOR(_class_) \ 90 do { \ 91 SoBase::staticDataLock(); \ 92 _class_::classinstances++; \ 93 /* Catch attempts to use an engine class which has not been initialized. */ \ 94 assert(_class_::classTypeId != SoType::badType()); \ 95 /* Initialize a inputdata container for the class only once. */ \ 96 if (!_class_::fieldData) { \ 97 _class_::fieldData = \ 98 new SoFieldData(_class_::parentFieldData ? \ 99 *_class_::parentFieldData : NULL); \ 100 _class_::outputdata = \ 101 new SoEngineOutputData(_class_::parentoutputdata ? \ 102 *_class_::parentoutputdata : NULL); \ 103 } \ 104 /* Extension classes from the application programmers should not be */ \ 105 /* considered native. This is important to get the export code to do */ \ 106 /* the Right Thing. */ \ 107 this->isBuiltIn = FALSE; \ 108 SoBase::staticDataUnlock(); \ 109 } WHILE_0 110 111 #define PRIVATE_COMMON_NODEENGINE_INIT_CODE(_class_, _classname_, _createfunc_, _parentclass_) \ 112 do { \ 113 /* Make sure we only initialize once. */ \ 114 assert(_class_::classTypeId == SoType::badType() && "don't init() twice!"); \ 115 /* Make sure superclass gets initialized before subclass. */ \ 116 assert(_parentclass_::getClassTypeId() != SoType::badType() && "you forgot init() on parentclass!"); \ 117 \ 118 /* Set up entry in the type system. */ \ 119 _class_::classTypeId = \ 120 SoType::createType(_parentclass_::getClassTypeId(), \ 121 _classname_, \ 122 _createfunc_, \ 123 SoNode::getNextActionMethodIndex()); \ 124 SoNode::incNextActionMethodIndex(); \ 125 \ 126 /* Store parent's fielddata pointer for later use in the constructor. */ \ 127 _class_::parentFieldData = _parentclass_::getFieldDataPtr(); \ 128 _class_::parentoutputdata = _parentclass_::getOutputDataPtr(); \ 129 } WHILE_0 130 131 #define SO_NODEENGINE_INIT_CLASS(_class_, _parentclass_, _parentname_) \ 132 do { \ 133 const char * classname = SO__QUOTE(_class_); \ 134 PRIVATE_COMMON_INIT_CODE(_class_, classname, &_class_::createInstance, _parentclass_); \ 135 } WHILE_0 136 137 #define SO_NODEENGINE_EXIT_CLASS(_class_) \ 138 _class_::atexit_cleanupnodeengine(); 139 140 #define SO_NODEENGINE_INIT_ABSTRACT_CLASS(_class_, _parentclass_, _parentname_) \ 141 do { \ 142 const char * classname = SO__QUOTE(_class_); \ 143 PRIVATE_COMMON_INIT_CODE(_class_, classname, NULL, _parentclass_); \ 144 } WHILE_0 145 146 #define SO_NODEENGINE_ADD_OUTPUT(_output_, _type_) \ 147 do { \ 148 outputdata->addOutput(this, SO__QUOTE(_output_), \ 149 &this->_output_, \ 150 _type_::getClassTypeId()); \ 151 this->_output_.setNodeContainer(this); \ 152 } WHILE_0 153 154 #endif // COIN_SOSUBNODEENGINE_H 155