Coin Logo http://www.coin3d.org/
http://www.kongsberg.com/kogt/

SoSubNode.h
1 #ifndef COIN_SOSUBNODE_H
2 #define COIN_SOSUBNODE_H
3 
4 /**************************************************************************\
5  * Copyright (c) Kongsberg Oil & Gas Technologies AS
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met:
11  *
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  *
19  * Neither the name of the copyright holder nor the names of its
20  * contributors may be used to endorse or promote products derived from
21  * this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 \**************************************************************************/
35 
36 /*
37  The most used macros and their arguments:
38 
39  header files:
40  SO_NODE_HEADER(classname)
41  SO_NODE_ABSTRACT_HEADER(classname)
42 
43  source files:
44  SO_NODE_SOURCE(classname)
45  SO_NODE_ABSTRACT_SOURCE(classname)
46  in constructor:
47  SO_NODE_CONSTRUCTOR(classname)
48  SO_NODE_DEFINE_ENUM_VALUE(enumname, enumvalue)
49  SO_NODE_ADD_FIELD(fieldname, (defaultvalue))
50  in initClass():
51  SO_NODE_INIT_CLASS(classname, parentclassname, parentclassname)
52  SO_NODE_INIT_ABSTRACT_CLASS(classname, parentclassname, parentclassname)
53 */
54 
55 // *************************************************************************
56 
57 #include <string.h> /* strcmp used in assert() */
58 #include <Inventor/SbName.h>
59 #include <Inventor/SoType.h>
60 #include <Inventor/fields/SoFieldData.h>
61 #include <Inventor/nodes/SoNode.h>
62 #include <Inventor/C/tidbits.h>
63 
64 // *************************************************************************
65 
66 #define PRIVATE_NODE_TYPESYSTEM_HEADER( ) \
67 public: \
68  static SoType getClassTypeId(void); \
69  virtual SoType getTypeId(void) const; \
70 private: \
71  static SoType classTypeId
72 
73 // FIXME: document. 20000103 mortene.
74 #define SO_NODE_ABSTRACT_HEADER(_class_) \
75  PRIVATE_NODE_TYPESYSTEM_HEADER(); \
76 protected: \
77  static const SoFieldData ** getFieldDataPtr(void); \
78  virtual const SoFieldData * getFieldData(void) const; \
79 private: \
80  static void atexit_cleanup(void); \
81  static const SoFieldData ** parentFieldData; \
82  static SoFieldData * fieldData; \
83  /* Counts number of instances of subclasses aswell as "direct" */ \
84  /* instances from non-abstract classes. */ \
85  static unsigned int classinstances
86 
87 
88 // FIXME: document. 20000103 mortene.
89 #define SO_NODE_HEADER(_class_) \
90  SO_NODE_ABSTRACT_HEADER(_class_); \
91 private: \
92  static void * createInstance(void)
93 
94 // *************************************************************************
95 
96 #define PRIVATE_NODE_TYPESYSTEM_SOURCE(_class_) \
97 SoType _class_::getClassTypeId(void) { return _class_::classTypeId; } \
98 SoType _class_::getTypeId(void) const { return _class_::classTypeId; } \
99 SoType _class_::classTypeId STATIC_SOTYPE_INIT
100 
101 
102 // FIXME: document. 20000103 mortene.
103 #define SO_NODE_ABSTRACT_SOURCE(_class_) \
104 PRIVATE_NODE_TYPESYSTEM_SOURCE(_class_); \
105  \
106 unsigned int _class_::classinstances = 0; \
107 const SoFieldData ** _class_::parentFieldData = NULL; \
108 SoFieldData * _class_::fieldData = NULL; \
109  \
110 const SoFieldData ** \
111 _class_::getFieldDataPtr(void) \
112 { \
113  return const_cast<const SoFieldData **>(&_class_::fieldData); \
114 } \
115  \
116 const SoFieldData * \
117 _class_::getFieldData(void) const \
118 { \
119  return _class_::fieldData; \
120 } \
121  \
122 void \
123 _class_::atexit_cleanup(void) \
124 { \
125  delete _class_::fieldData; \
126  _class_::fieldData = NULL; \
127  _class_::parentFieldData = NULL; \
128  SoType::removeType(_class_::classTypeId.getName()); \
129  _class_::classTypeId STATIC_SOTYPE_INIT; \
130  _class_::classinstances = 0; \
131 }
132 
133 // FIXME: document. 20000103 mortene.
134 #define SO_NODE_SOURCE(_class_) \
135 SO_NODE_ABSTRACT_SOURCE(_class_) \
136  \
137  \
140 void * \
141 _class_::createInstance(void) \
142 { \
143  return new _class_; \
144 }
145 
146 // *************************************************************************
147 
148 // FIXME: document. 20000103 mortene.
149 #define SO_NODE_IS_FIRST_INSTANCE() \
150  (classinstances == 1)
151 
152 // FIXME: document. 20000103 mortene.
153 #define SO_NODE_CONSTRUCTOR_NOLOCK(_class_) \
154  do { \
155  _class_::classinstances++; \
156  /* Catch attempts to use a node class which has not been initialized. */ \
157  assert(_class_::classTypeId != SoType::badType() && "you forgot init()!"); \
158  /* Initialize a fielddata container for the class only once. */ \
159  if (!_class_::fieldData) { \
160  /* FIXME: this is a "static" memory leak. 20030131 mortene. */ \
161  /* Internal Coin nodes are handled properly though. pederb, 20041122 */ \
162  _class_::fieldData = \
163  new SoFieldData(_class_::parentFieldData ? \
164  *_class_::parentFieldData : NULL); \
165  } \
166  /* Extension classes from the application programmers should not be \
167  considered native. This is important to get the export code to do \
168  the Right Thing. */ \
169  this->isBuiltIn = FALSE; \
170  } while (0)
171 
172 // FIXME: document. 20000103 mortene.
173 #define SO_NODE_CONSTRUCTOR(_class_) \
174  do { \
175  SoBase::staticDataLock(); \
176  SO_NODE_CONSTRUCTOR_NOLOCK(_class_); \
177  SoBase::staticDataUnlock(); \
178  } while (0)
179 
180 // *************************************************************************
181 
182 // FIXME: create-type with get-next and inc-next must be an atomic step in an MT
183 // environment 20020216 larsa
184 // FIXME: you can not use the _parentclass_ argument directly as a class specifier
185 // in initClass because such usage causes dynamic loading to fail when trying to
186 // invoke the initClass method in the case where _parentclass_ also has to be
187 // dynamically loaded. that is the reason for this roundabout way of getting the
188 // parent class type. 20020216 larsa
189 
190 #define PRIVATE_COMMON_INIT_CODE(_class_, _classname_, _createfunc_, _parentclass_) \
191  do { \
192  /* Make sure we only initialize once. */ \
193  assert(_class_::classTypeId == SoType::badType() && "don't init() twice!"); \
194  /* Make sure superclass gets initialized before subclass. */ \
195  assert(strcmp(SO__QUOTE(_parentclass_), "inherited")); \
196  SoType parentType(SoType::fromName(SO__QUOTE(_parentclass_))); \
197  assert(parentType != SoType::badType() && "you forgot init() on parentclass!"); \
198  \
199  /* Set up entry in the type system. */ \
200  _class_::classTypeId = \
201  SoType::createType(parentType, \
202  _classname_, \
203  _createfunc_, \
204  SoNode::getNextActionMethodIndex()); \
205  SoNode::incNextActionMethodIndex(); \
206  \
207  /* Store parent's fielddata pointer for later use in the constructor. */ \
208  _class_::parentFieldData = _parentclass_::getFieldDataPtr(); \
209 \
210  /* Make sure also external nodes are cleaned up */ \
211  cc_coin_atexit_static_internal(_class_::atexit_cleanup); \
212  } while (0)
213 
214 
215 // FIXME: document. 20000103 mortene.
216 #define SO_NODE_INIT_CLASS(_class_, _parentclass_, _parentname_) \
217  do { \
218  const char * classname = SO__QUOTE(_class_); \
219  PRIVATE_COMMON_INIT_CODE(_class_, classname, &_class_::createInstance, _parentclass_); \
220  } while (0)
221 
222 // FIXME: document. 20000103 mortene.
223 #define SO_NODE_INIT_ABSTRACT_CLASS(_class_, _parentclass_, _parentname_) \
224  do { \
225  const char * classname = SO__QUOTE(_class_); \
226  PRIVATE_COMMON_INIT_CODE(_class_, classname, NULL, _parentclass_); \
227  } while (0)
228 
229 
230 // *************************************************************************
231 
232 // FIXME: document. 20000103 mortene.
233 #define SO_NODE_ADD_FIELD(_field_, _defaultval_) \
234  do { \
235  this->_field_.setValue _defaultval_;\
236  this->_field_.setContainer(this); \
237  fieldData->addField(this, SO__QUOTE(_field_), &this->_field_); \
238  } while (0)
239 
240 // New for Coin-3
241 #define SO_NODE_ADD_EMPTY_MFIELD(_field_) \
242  do { \
243  this->_field_.setContainer(this); \
244  fieldData->addField(this, SO__QUOTE(_field_), &this->_field_);\
245  } while (0)
246 
247 
248 // FIXME: document. 20000103 mortene.
249 #define SO_NODE_DEFINE_ENUM_VALUE(_enumname_, _enumval_) \
250  do { \
251  fieldData->addEnumValue(SO__QUOTE(_enumname_), \
252  SO__QUOTE(_enumval_), _enumval_); \
253  } while (0)
254 
255 // *************************************************************************
256 
257 #endif // !COIN_SOSUBNODE_H

Copyright © by Kongsberg Oil & Gas Technologies. All rights reserved.

Generated for Coin by Doxygen