Coin Logo Coin3D is Free Software,
published under the BSD 3-clause license.
https://bitbucket.org/Coin3D/
http://www.kongsberg.com/kogt/
SoSubNodeEngine.h
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