5 /*! \page PageBaseFieldContainer FieldContainer
7 \section PageBaseNodeCore NodeCore
8 \section PageBaseGlobalsAttachment Globals Attachment
31 /*! \page PageBaseFieldsNFieldContainers Fields & Field Containers
33 \latexonly Starter:NewChapter \endlatexonly
35 One central goal in OpenSG's design is easy to use thread-safe data. To do
36 that right, you need to replicate the data so that every thread can have its
37 private copy (called aspect) to work on. At some point these different copies
38 will have to be synchronized, and then the parts that actually changed need to
39 be copied from one aspect to another. To do that, the system needs to know
40 what actually changed. As C++ is not reflective, i.e. the classes cannot tell
41 the system which members they have, OpenSG needs to keep track of the changes.
42 That's what Fields and FieldContainers are for.
44 \section PageSystemFCInstance Creating a FieldContainer instance
46 FieldContainer can be created in two ways: By using the FieldContainerFactory
47 or from the class's prototype. You cannot create instances of FieldContainers
48 neither by creating automatic or static variables nor by calling new. You have
49 to use the mentioned two ways.
51 For generic loaders it is useful to create an object by name, and this is what
52 the factory is for. The factory is a singleton, the single instance can be
53 accessed via FieldContainerFactory::the(), which has functions to create
54 arbitrary field containers, with some special versions to directly create
55 different subsets of field containers (Nodes, NodeCores, Attachments).
57 For reasons connected to multi-threading (s. [threadsafety]) specific kinds of
58 pointers have to be used. For every FieldContainer type fc there is a specific
59 pointer type fcPtr. It has all the features of a standard pointer, i.e. it can
60 be dereferenced via -> and it can be downcasted to a derived type by
61 DerivedPtr.dcast( ParentPtr );.
63 Creating a new instance of a specific class is done by calling fcPtr
66 \section PageSystemRefCount Reference counting
68 FieldContainers are reference-counted. They are created with a reference count
69 of 0, and the reference count can be manipulated through addRefCP() and
72 The system increases the reference count only when it stores a reference to an
73 object in the system, e.g. when a node is attached to another node. It does
74 not increase the reference counter for every parameter that is passed around,
75 the pointers mentioned in [fcinstance] are not smart pointers.
77 The reference count is decreased when an object is removed from the system,
78 e.g. when a node is detached from another node, or explicitly using
79 subRefCP(). If the reference count goes to or below 0, the object is removed.
80 Note that objects are created with a reference count of zero, so if a new
81 object (refCnt: 0) is attached to a node (increasing the refCnt to 1) and
82 removed later on (decreasing it to 0), it will be destroyed. Increasing the
83 reference count before removing it is needed to prevent the destruction.
85 \section PageSystemFCManip Manipulation
87 The FieldContainer is the basic unit for multi-thread safety. To synchronize
88 changes between different copies of the data the system needs to know when and
91 This has to be done explicitly by the program. Thus, before changing a
92 FieldContainer beginEditCP(fcPtr, fieldMask); has to be called. After the
93 changes to the FieldContainer are done this also has to be communicated by
94 calling endEditCP(fcPtr, fieldMask);. Here, fcPtr is the pointer to the
95 FieldContainer being changed, fieldMask is a bit mask describing the fields
98 Every FieldContainer defines constants for all its fields that can be used to
99 set up this mask. The naming convention is
100 [FieldContainer]::[FieldName]FieldMask, e.g. Geometry::PositionsFieldMask.
101 These masks can be or-ed together to create the full mask of fields that are
106 \section PageSystemAttachments FieldContainer attachments
108 OpenSG field containers and nodes do not feature an unused pointer to attach
109 data, usually called user data in other systems. Instead, many field
110 containers feature a map to attach specific kinds of field containers called
111 attachments. The most important ones are Nodes and NodeCores, but many other
112 like Window, Viewport, Camera, etc. are derived from AttachmentContainer and,
113 therefore, can carry attachments.
115 Attachments have to be derived from Attachment (see
116 \ref PageBaseFieldContainerExt for
117 details on how to do that). There are also predefined attachments, right now the
118 only one is NameAttachment, which allows assigning a name to the field
121 Every AttachmentContainer can hold an arbitrary number of attachments.
122 Attachments are divided into separate groups, and there can be only one
123 attachment of every group attached to an AC. Most attachments are a group, but
124 if needed new ones can be used as replacements for their parents.
126 \section PageSystemFCThreadsafety Data separation & Thread safety
128 One of the primary design goals of OpenSG is supporting multi-threaded
129 applications. For asynchronous threads that means that every thread might need
130 its private copy of the data. To combine that with easy usability and
131 efficient access we decided to replicate at the field container level.
133 When a field container is created not only one instance is created but
134 multiple, per default 2. These are called aspects, and every running thread is
135 associated with one of them. Whenever data is changed in a thread, only the
136 aspect that's associated with it is changed, the rest is left as is.
140 #if defined(OSG_DO_DOC) || OSG_DOC_LEVEL > 1
142 /*! \page PageBaseFieldContainerExt Creating New FieldContainer Classes
144 Most developers who use OpenSG as a scene-graph library will probable never
145 create their own OpenSG FieldContainer classes. Similar to widget libs (e.g.
146 qt, gtk) people just use instances (the widgets) but never create new
149 However, you can always extend the type system of OpenSG to integrate new
150 cores (e.g. a fancy LOD switch) or application specific FieldContainers.
152 FieldContainers are the system's central mechanisms to deal with any kind of
153 thread safe data (see \ref PageBaseFieldsNFieldContainers). Therefore, the
154 class declaration must include various extra meta information for the field
155 and FieldContainer type handling.
157 In most systems (e.g. Inventor), you would probably start writing a new class
158 or node by just 'copy and paste'-ing an existing implementation. However,
159 since OpenSG needs all this extra meta data it is not a simple but very error
160 prone process to create the field container source by hand. Instead, we
161 provide a graphical tool to create and manage the FieldContainer description
164 The basic idea is that you use the 'field container description editor'
165 ($OSGROOT/Tools/fcdEdit) to create an XML file including the description of
166 your FieldContainer fields and interfaces.
168 The tool is also able to create all necessary C++ source files. The
169 FieldContainer code is split into classes (e.g. for a Foo FieldContainer:
170 FooBase and Foo). This strategy has various advantages:
172 \li Type system changes: If the OpenSG core team decides to change the code
173 interface for the FieldContainer type management we can just recreate the base
174 classes from the XML description. No adaptations 'by hand' are needed.
176 \li Interface changes: If you would like to change the interface of your
177 FieldContainer (e.g. add another field) later on you can just re-edit the XML
178 file in fcdEdit and recreate the base classes. All necessary access methods
179 are created automatically.
181 \section PageSystemFieldContainerExtFCD XML Description (Foo.fcd)
183 Includes all field and meta descriptions for a single FieldContainer. Can be
184 read and written by the fcdEdit tool. You should only change it by hand when
185 you're sure of what you're doing.
187 \section PageSystemFieldContainerExtFieldTypes Field Types (FooFields.h)
189 Include the field and pointer declarations the the FieldContainer to be used
190 in other FieldContainers as reference. You should not change the file by hand.
192 \section PageSystemFieldContainerExtBase Base/Meta Type (FooBase.h, FooBase.inl,
195 Holds all the meta and field information. Do not change it by hand. Use the
196 fcdEdit tool to create the files anew whenever you change the XML
199 \section PageSystemFieldContainerExtUser 'User Code' implementation (Foo.h,
202 Holds the 'user code'. The fcdEdit is able to create a skeleton for your
203 FieldContainer implementation. The code does not include any meta information,
204 therefore, it is not necessary to create it anew whenever you change the
207 Include new action handlers or whatever you need as functionality.
209 \image html fcdEdit-numbered.png "fcdEdit"
211 \image latex fcdEdit-numbered.eps "fcdEdit" width=8cm
213 A quick explanation of the different buttons/input fields:
217 <li>The name of the FieldContainer. Should follow the capitalization rules.</li>
219 <li>Defines whether the FC is a part of the OpenSG system. This mainly
220 influences the way system headers are included (with or without the OpenSG/
223 <li>Defines whether the FC can be decorated. Currentl only used for
224 OSG::CameraDecorator classes, but usable in general. The main effect is to turn
225 all Field access emthods into virtual functions, to allow overriding them, and
226 creating the necessary default Decorator classes.</li>
228 <li>The name of the parent class of the FC.</li>
230 <li>Defines if the parent class is a system component.</li>
232 <li>The name of the library this FC will be included in. If it is only to be
233 used in application programs, just leave it blank and the appropriate code for
234 an application component will be generated.</li>
236 <li>Define whether Field types for pointers to this type of FC should be
239 <li>Defines whether this FC is abstract or concrete (i.e. whether it can be
240 instantiated or not).</li>
242 <li>A general description of this FC. It will be included in the actual FC
243 code. As this code cannot be regenerated changing this description after the
244 code has been generated will not make a difference.</li>
246 <li>A list of the Fields of this FC.</li>
248 <li>The name of the currently selected Field.</li>
250 <li>The type of the currently selected Field. There is a list of predefined
251 types that can be selected from, but it is also possible to just write the type
252 of the Field here.</li>
254 <li>The cardinality of the Field, i.e. if it's a single (OSG::SField) or multi
255 element (OSG::MField) field.</li>
257 <li>The access type of the field: private, protected or public. In general
258 Fields should be public, if they are internal they should be protected.</li>
260 <li>The visibility of the Field mainly influences whether the Field is written
261 to files etc. Fields that have no meaning beyond the current execution of the
262 program should be internal, Fields that hold configuration data should be
265 <li>The header containing the declaration of the Field's type. If left empty a
266 name is guessed, using the name <tt>OSG<type>Fields.h</tt>. For type names
267 ending in \c Ptr (the default for FieldContainerPtr types) the \c Ptr is
268 removed. This works for all system types and for standard user-defined types.
269 For other types, just enter the header file name into this field, excluding the ""
272 <li>The default value of the Field. Used to initialize the Field, and put
273 verbatim into the constructor definition for the given Field (e.g. <tt>FC::FC() :
274 Field(default) { }</tt>) </li>
276 <li>The header needed to declare the default value. Useful to access enum or
277 constants from external files (like opengl.h).</li>
279 <li>A short description of the Field's contents and function. Will be put into
280 the code documentation.</li>
282 <li>Creates a new Field.</li>
284 <li>Deletes a Field.</li>
286 <li>Clones a Field.</li>
288 <li>Moves the Field up in the list.</li>
290 <li>Moves the Field down in the list.</li>
292 <li>Clear the whole system, start from scratch.</li>
294 <li>Load an .fcd file.</li>
296 <li>Currently unused.</li>
298 <li>Save the current settings to the .fcd file.</li>
300 <li>Write the FieldContainer Base code. This can also be done by calling
301 fcdEdit with the <tt>-b</tt> command line option and the .fcd file. It is safe
302 to do that, as no user changes should be done to the Base code.</li>
304 <li>Currently unused.</li>
306 <li>Currently unused.</li>
308 <li>Save the current settings to a different .fcd file.</li>
310 <li>Write the actual FieldContainer code. This can also be done by calling
311 fcdEdit with the <tt>-f</tt> command line option and the .fcd file. This will
312 not keep any changes made to the FC code, and thus can quickly destroy whatever
313 work has been done to it. To prevent that from happening on accident, it will not
314 overwrite existing files.</li>
316 <li>Minimal info about the progam.</li>
318 <li>Leave the program.</li>
322 \section PageSystemFieldContainerExtPrototype Prototype Replacement
324 If you create a replacement for a system component, e.g. a smarter DistanceLOD
325 node that can handle predictive LOD selection, and want the system to use your
326 version of the DistanceLOD from now on you can do that. Internally all field
327 container instances are created by cloning a prototype instance. You can
328 access the prototype for a given FieldContainer via its class type which you
329 can access using FC::getClassType(). The class type has a setPrototype()
330 method to assign the prototype.
332 Be careful to only replace the prototype with classes derived from the
333 original class, or the behavior of the system is undefined.
335 \section PageSystemFieldContainerExtInit Initialization / Deinitalization
337 As OpenSG uses object replication for thread-safe data, constructors and
338 destructors are not always the right place for initialisation and deletion
339 anymore. They are called for every aspect, which usually is more than once.
340 For initialisation that should be done only once per object, the onCreate()
341 method can be used. Similarly, onDestroy() is called once, when the object is
344 There is also a difference between the constructors. The copy constructor is
345 called for every aspect of an object, the default constructor is only called
346 once, during the static init phase, to create the initial prototype instance
347 for the class. As code running in the static init phase faces some
348 restrictions (e.g. the order of initializations is undefined, thus any other
349 object might not yet have been initialized) a saver way to do class-global
350 initializations was added. The initMethod() method is called during osgInit(),
351 which is after all static inits are done.
353 As a summary here's a list of when which method is called:
355 \li default constructor: once, during static init, to create the initial
358 \li initMethod(): once, during osgInit()
360 \li copy constructor: during object instance creation, once for every aspect
362 \li onCreate(): during object instance creation, once
364 \li onDestroy(): during object instance deletion, once
366 \li destructor: during object instance deletion, once for every aspect
368 onCreate() and on Destroy() are also called for the initial prototype
369 creation. Not all prototypes might need the resources a real instance needs,
370 and initial prototype creation is run during static init, where it might not
371 be safe to access other classes. To allow a destinction between prototype
372 creation and the standard running state of the system there's a global
373 variable GlobalSystemState, which will be set to Startup during static init
374 and Running after osgInit() is finished. During osgExit() it will be set to
375 Shutdown and to PostShutdown at the end.