Open Inventor
Release 2024.2.1
Loading...
Searching...
No Matches
SoSubFieldContainer.h
1
/*=======================================================================
2
*** THE CONTENT OF THIS WORK IS PROPRIETARY TO FEI S.A.S, (FEI S.A.S.), ***
3
*** AND IS DISTRIBUTED UNDER A LICENSE AGREEMENT. ***
4
*** ***
5
*** REPRODUCTION, DISCLOSURE, OR USE, IN WHOLE OR IN PART, OTHER THAN AS ***
6
*** SPECIFIED IN THE LICENSE ARE NOT TO BE UNDERTAKEN EXCEPT WITH PRIOR ***
7
*** WRITTEN AUTHORIZATION OF FEI S.A.S. ***
8
*** ***
9
*** RESTRICTED RIGHTS LEGEND ***
10
*** USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT OF THE CONTENT OF THIS ***
11
*** WORK OR RELATED DOCUMENTATION IS SUBJECT TO RESTRICTIONS AS SET FORTH IN ***
12
*** SUBPARAGRAPH (C)(1) OF THE COMMERCIAL COMPUTER SOFTWARE RESTRICTED RIGHT ***
13
*** CLAUSE AT FAR 52.227-19 OR SUBPARAGRAPH (C)(1)(II) OF THE RIGHTS IN ***
14
*** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 52.227-7013. ***
15
*** ***
16
*** COPYRIGHT (C) 1996-2014 BY FEI S.A.S, ***
17
*** BORDEAUX, FRANCE ***
18
*** ALL RIGHTS RESERVED ***
19
**=======================================================================*/
20
/*=======================================================================
21
** Author : Nicolas DAGUISE (Aug 2007)
22
**=======================================================================*/
23
24
25
#ifndef SO_SUB_FIELDCONTAINER_H
26
#define SO_SUB_FIELDCONTAINER_H
27
28
#include <Inventor/threads/SbThreadMutex.h>
29
#include <Inventor/fields/SoFieldData.h>
30
32
// These defines type-identifier and naming variables and methods that
33
// all subclasses and abstract subclasses must support.
34
//
35
#define SO_FIELDCONTAINER_ABSTRACT_HEADER(className) \
36
public: \
37
\
38
static SoType getClassTypeId(); \
39
\
40
virtual SoType getTypeId() const; \
41
private: \
42
virtual SbBool getIsBuiltIn() const ; \
43
virtual const SoFieldData* getFieldData() const; \
44
static void initClass(); \
45
static void exitClass(); \
46
private: \
47
static const SoFieldData** getFieldDataPtr(); \
48
private: \
49
static SbThreadMutex classMutex; \
50
static SoType classTypeId; \
51
static SbBool isBuiltIn; \
52
static SbBool firstInstance; \
53
static SoFieldData* fieldData; \
54
static const SoFieldData** parentFieldData
55
57
// Non-abstract classes have everything abstract classes have, plus a way
58
// to create an instance
59
//
60
#define SO_FIELDCONTAINER_HEADER(className) \
61
SO_FIELDCONTAINER_ABSTRACT_HEADER(className); \
62
private: \
63
static void* createInstance(SoType* dynamicType = NULL)
64
65
#if defined(_DEBUG)
66
68
#define SO__FIELDCONTAINER_CHECK_INIT(className) \
69
if (classTypeId.isBad()) \
70
{ \
71
SoDebugError::post( \
72
"SO_FIELDCONTAINER_CONSTRUCTOR", \
73
"Can't construct a node of type " \
74
SO__QUOTE(className) \
75
" until initClass() has been called"); \
76
className::initClass(); \
77
} \
78
SoTypedObject::checkDatabase(SO__QUOTE(className), this, className::getClassTypeId(), classTypeId);
79
81
#define SO__FIELDCONTAINER_CHECK_CONSTRUCT(where) \
82
if (fieldData == NULL) \
83
{ \
84
SoDebugError::post( \
85
where, \
86
"Instance not properly constructed.\n" \
87
"Did you forget to put SO_FIELDCONTAINER_CONSTRUCTOR()" \
88
" in the constructor?" ); \
89
fieldData = new SoFieldData( \
90
parentFieldData ? *parentFieldData : NULL); \
91
}
92
93
#else
94
96
#define SO__FIELDCONTAINER_CHECK_INIT(className) \
97
if (classTypeId.isBad()) \
98
className::initClass()
99
101
#define SO__FIELDCONTAINER_CHECK_CONSTRUCT(where) \
102
if (fieldData == NULL) \
103
fieldData = new SoFieldData( \
104
parentFieldData ? *parentFieldData : NULL)
105
106
#endif
107
109
// This declares the static variables defined in SO_FIELDCONTAINER_HEADER
110
// or SO_FIELDCONTAINER_ABSTRACT_HEADER.
111
//
112
#define SO__FIELDCONTAINER_VARS(className) \
113
SbThreadMutex className::classMutex; \
114
SoType className::classTypeId; \
115
SbBool className::isBuiltIn = TRUE; \
116
SoFieldData* className::fieldData = NULL; \
117
const SoFieldData** className::parentFieldData = NULL; \
118
SbBool className::firstInstance = TRUE
119
121
#define SO_FIELDCONTAINER_ABSTRACT_SOURCE(className) \
122
SO__FIELDCONTAINER_VARS(className); \
123
SoType className::getTypeId() const \
124
{ \
125
return classTypeId; \
126
} \
127
\
128
const SoFieldData* className::getFieldData() const \
129
{ \
130
classMutex.lock(); \
131
SO__FIELDCONTAINER_CHECK_CONSTRUCT(SO__QUOTE(className)); \
132
SoFieldData* result = fieldData; \
133
classMutex.unlock(); \
134
return result; \
135
} \
136
\
137
SoType className::getClassTypeId() \
138
{ \
139
return classTypeId; \
140
} \
141
\
142
SbBool className::getIsBuiltIn() const \
143
{ \
144
return isBuiltIn; \
145
} \
146
\
147
const SoFieldData** className::getFieldDataPtr() \
148
{ \
149
classMutex.lock(); \
150
const SoFieldData** result = (const SoFieldData**)&fieldData; \
151
classMutex.unlock(); \
152
return result; \
153
}
154
156
#define SO_FIELDCONTAINER_SOURCE(className) \
157
SO_FIELDCONTAINER_ABSTRACT_SOURCE(className); \
158
\
159
void* className::createInstance(SoType* ) \
160
{ \
161
return (void *)(new className); \
162
}
163
164
#if defined(_DEBUG)
165
#define SO_FIELDCONTAINER_INIT_CLASS_CHECK_PARENT(className, parentClass) \
166
if (parentClass::getClassTypeId().isBad()) { \
167
SoDebugError::post( SO__QUOTE(className)"::initClass", \
168
SO__QUOTE(className)" initialized before parent class " \
169
SO__QUOTE(parentClass)"\n"); \
170
parentClass::initClass(); \
171
}
172
#else
173
#define SO_FIELDCONTAINER_INIT_CLASS_CHECK_PARENT(className, parentClass) \
174
if (parentClass::getClassTypeId().isBad()) \
175
parentClass::initClass()
176
#endif
177
179
// This initializes the type identifer variables defined in
180
// SO_FIELDCONTAINER_HEADER or SO_FIELDCONTAINER_ABSTRACT_HEADER. This macro
181
// should be called from within initClass(). The parentClass argument
182
// should be the class that this subclass is derived from.
183
//
184
#define SO_FIELDCONTAINER_INIT_CLASS(className, classPrintName, parentClass) \
185
classMutex.lock(); \
186
SO_FIELDCONTAINER_INIT_CLASS_CHECK_PARENT(className, parentClass); \
187
classTypeId = SoType::createType( parentClass::getClassTypeId(), \
188
classPrintName, \
189
&className::createInstance, 0 ); \
190
parentFieldData = parentClass::getFieldDataPtr(); \
191
classMutex.unlock()
192
194
#define SO_FIELDCONTAINER_INIT_ABSTRACT_CLASS(className, classPrintName, parentClass) \
195
classMutex.lock(); \
196
SO_FIELDCONTAINER_INIT_CLASS_CHECK_PARENT(className, parentClass); \
197
classTypeId = SoType::createType( parentClass::getClassTypeId(), \
198
classPrintName, \
199
NULL, 0 ); \
200
parentFieldData = parentClass::getFieldDataPtr(); \
201
classMutex.unlock()
202
203
#if defined(_DEBUG)
204
#define SO__FIELDCONTAINER_EXIT_CLASS(className) \
205
if (! SoType::removeType(classTypeId.getName())) { \
206
SoDebugError::post(SO__QUOTE(className)"::exitClass", \
207
"Unable to remove type (%s) for this class. Check exitClass() " \
208
"method is implemented and is called only once.\n", \
209
classTypeId.getName().getString() ); \
210
} \
211
else \
212
{ \
213
classTypeId = SoType::badType(); \
214
firstInstance = TRUE; \
215
if (fieldData != NULL) \
216
{ \
217
delete fieldData; \
218
fieldData = NULL; \
219
} \
220
parentFieldData = NULL; \
221
firstInstance = TRUE; \
222
}
223
#else
224
#define SO__FIELDCONTAINER_EXIT_CLASS(className) \
225
SoType::removeType(classTypeId.getName()); \
226
classTypeId = SoType::badType(); \
227
firstInstance = TRUE; \
228
if (fieldData != NULL) \
229
{ \
230
delete fieldData; \
231
fieldData = NULL; \
232
} \
233
parentFieldData = NULL; \
234
firstInstance = TRUE
235
#endif
236
238
// This is a boolean value that can be tested
239
// in constructors.
240
//
241
#define SO_FIELDCONTAINER_IS_FIRST_INSTANCE() \
242
(firstInstance == TRUE)
243
245
#define SO__FIELDCONTAINER_ADD_MFIELD( fieldName, type ) \
246
classMutex.lock(); \
247
SO__FIELDCONTAINER_CHECK_CONSTRUCT(__FILE__); \
248
if (firstInstance) \
249
fieldData->addField(this, SO__QUOTE(fieldName), &this->fieldName); \
250
this->fieldName.setContainer(this); \
251
this->fieldName.setFieldType(type); \
252
classMutex.unlock()
253
255
#define SO__FIELDCONTAINER_ADD_FIELD( fieldName, defValue, type ) \
256
classMutex.lock(); \
257
SO__FIELDCONTAINER_CHECK_CONSTRUCT(__FILE__); \
258
if (firstInstance) \
259
fieldData->addField(this, SO__QUOTE(fieldName), &this->fieldName); \
260
this->fieldName.setValue defValue; \
261
this->fieldName.setContainer(this); \
262
this->fieldName.setFieldType(type); \
263
classMutex.unlock()
264
266
#define SO_FIELDCONTAINER_ADD_FIELD( fieldName, defValue ) \
267
SO__FIELDCONTAINER_ADD_FIELD( fieldName, defValue, SoField::EXPOSED_FIELD )
268
270
#define SO_FIELDCONTAINER_ADD_HIDDEN_FIELD( fieldName, defValue ) \
271
SO__FIELDCONTAINER_ADD_FIELD( fieldName, defValue, SoField::INTERNAL_FIELD )
272
274
#define SO_FIELDCONTAINER_ADD_PRIVATEFIELD( fieldName, defValue ) \
275
SO__FIELDCONTAINER_ADD_FIELD( fieldName, defValue, SoField::HIDDEN_FIELD )
276
278
#define SO_FIELDCONTAINER_SET_SF_ENUM_TYPE( fieldName, enumType ) \
279
SO__SF_ENUM_SET_TYPE( fieldName, enumType, "FIELDCONTAINER", fieldData )
280
282
#define SO_FIELDCONTAINER_CONSTRUCTOR(className) \
283
SoBaseInitializer sbi(this); \
284
classMutex.lock(); \
285
SO__FIELDCONTAINER_CHECK_INIT(className); \
286
if (fieldData == NULL) \
287
fieldData = new SoFieldData( parentFieldData ? \
288
(SoFieldData *)*parentFieldData : \
289
(SoFieldData *)NULL); \
290
else \
291
firstInstance = FALSE; \
292
classMutex.unlock()
293
295
#define SO__FIELDCONTAINER_DEFINE_ENUM_VALUE( enumType, enumValueName, enumValue ) \
296
classMutex.lock(); \
297
if (firstInstance) \
298
fieldData->addEnumValue(SO__QUOTE(enumType), \
299
SO__QUOTE(enumValueName), \
300
enumValue); \
301
classMutex.unlock()
302
304
#define SO_FIELDCONTAINER_DEFINE_ENUM_VALUE( enumType, enumValue ) \
305
SO__FIELDCONTAINER_DEFINE_ENUM_VALUE( enumType, enumValue, enumValue )
306
307
#endif
// SO_SUB_FIELDCONTAINER_H
308
309
310
311
Inventor
fields
SoSubFieldContainer.h
Generated by
1.9.8