root/branches/Dirk_CPtr/Doc/to_port/FieldContainer.dox

Revision 585, 16.5 kB (checked in by allenb, 2 years ago)

Added documentation files that needed ported. See ticket:166.

Line 
1 #include <OSGConfig.h>
2
3 using namespace OSG;
4
5 /*! \defgroup GrpSystemFieldContainer Field Container
6     \ingroup GrpSystem
7  */
8
9 /*! \defgroup GrpSystemFieldContainerFuncs Field Container Functions
10     \ingroup GrpSystem
11  */
12
13 /*! \defgroup GrpSystemMultithreading Multithreading
14     \ingroup GrpSystem
15  */
16
17 /*! \page PageSystemFieldsNFieldContainers Fields & Field Containers
18
19 \latexonly Starter:NewChapter \endlatexonly
20
21 One central goal in OpenSG's design is easy to use thread-safe data. To do
22 that right, you need to replicate the data so that every thread can have its
23 private copy (called aspect) to work on. At some point these different copies
24 will have to be synchronized, and then the parts that actually changed need to
25 be copied from one aspect to another. To do that, the system needs to know
26 what actually changed. As C++ is not reflective, i.e. the classes cannot tell
27 the system which members they have, OpenSG needs to keep track of the changes.
28 That's what Fields and FieldContainers are for.
29
30 \section PageSystemFCInstance Creating a FieldContainer instance
31
32 FieldContainer can be created in two ways: By using the FieldContainerFactory
33 or from the class's prototype. You cannot create instances of FieldContainers
34 neither by creating automatic or static variables nor by calling new. You have
35 to use the mentioned two ways.
36
37 For generic loaders it is useful to create an object by name, and this is what
38 the factory is for. The factory is a singleton, the single instance can be
39 accessed via FieldContainerFactory::the(), which has functions to create
40 arbitrary field containers, with some special versions to directly create
41 different subsets of field containers (Nodes, NodeCores, Attachments).
42
43 For reasons connected to multi-threading (s. [threadsafety]) specific kinds of
44 pointers have to be used. For every FieldContainer type fc there is a specific
45 pointer type fcPtr. It has all the features of a standard pointer, i.e. it can
46 be dereferenced via -> and it can be downcasted to a derived type by
47 DerivedPtr.dcast( ParentPtr );.
48
49 Creating a new instance of a specific class is done by calling fcPtr
50 var=fcPtr::create().
51
52 \section PageSystemRefCount Reference counting
53
54 FieldContainers are reference-counted. They are created with a reference count
55 of 0, and the reference count can be manipulated through addRefCP() and
56 subRefCP().
57
58 The system increases the reference count only when it stores a reference to an
59 object in the system, e.g. when a node is attached to another node. It does
60 not increase the reference counter for every parameter that is passed around,
61 the pointers mentioned in [fcinstance] are not smart pointers.
62
63 The reference count is decreased when an object is removed from the system,
64 e.g. when a node is detached from another node, or explicitly using
65 subRefCP(). If the reference count goes to or below 0, the object is removed.
66 Note that objects are created with a reference count of zero, so if a new
67 object (refCnt: 0) is attached to a node (increasing the refCnt to 1) and
68 removed later on (decreasing it to 0), it will be destroyed. Increasing the
69 reference count before removing it is needed to prevent the destruction.
70
71 \section PageSystemFCManip Manipulation
72
73 The FieldContainer is the basic unit for multi-thread safety. To synchronize
74 changes between different copies of the data the system needs to know when and
75 what changed.
76
77 This has to be done explicitly by the program. Thus, before changing a
78 FieldContainer beginEditCP(fcPtr, fieldMask); has to be called. After the
79 changes to the FieldContainer are done this also has to be communicated by
80 calling endEditCP(fcPtr, fieldMask);. Here, fcPtr is the pointer to the
81 FieldContainer being changed, fieldMask is a bit mask describing the fields
82 that are changed.
83
84 Every FieldContainer defines constants for all its fields that can be used to
85 set up this mask. The naming convention is
86 [FieldContainer]::[FieldName]FieldMask, e.g. Geometry::PositionsFieldMask.
87 These masks can be or-ed together to create the full mask of fields that are
88 changed.
89
90 To simplify the begin/endEdit sequences and make it easier to not forget closing
91 the edit (which can result in pretty surprising error) there is a helper class
92 osg::CPEditor.
93
94 The CPEditor is an equivalent to the std::auto_ptr in the sense that as it calls
95 the beginEdit as soon as it is created and calls the endEdit as soon as it goes
96 out of scope.
97
98 \example Use CPEditor for begin/endEdit:
99
100 \code
101
102     GeoPTypesPtr type = GeoPTypesUI8::create();       
103     {
104         CPEditor te(type, GeoPTypesUI8::GeoPropDataFieldMask);
105        
106         type->addValue(GL_POLYGON  );
107         type->addValue(GL_TRIANGLES);
108         type->addValue(GL_QUADS    );
109     }
110
111 \endcode
112
113 \endexample
114
115 As a further (small) simplification there is a CPEdit macro that creates the
116 CPEditor instance automatically.
117
118 \example Use CPEdit for begin/endEdit:
119
120 \code
121
122     GeoPTypesPtr type = GeoPTypesUI8::create();       
123     {
124         CPEdit(type, GeoPTypesUI8::GeoPropDataFieldMask);
125        
126         type->addValue(GL_POLYGON  );
127         type->addValue(GL_TRIANGLES);
128         type->addValue(GL_QUADS    );
129     }
130
131 \endcode
132
133 \endexample
134
135
136
137 \section PageSystemAttachments FieldContainer attachments
138
139 OpenSG field containers and nodes do not feature an unused pointer to attach
140 data, usually called user data in other systems. Instead, many field
141 containers feature a map to attach specific kinds of field containers called
142 attachments. The most important ones are Nodes and NodeCores, but many other
143 like Window, Viewport, Camera, etc. are derived from AttachmentContainer and,
144 therefore, can carry attachments.
145
146 Attachments have to be derived from Attachment (see
147 \ref PageSystemFieldContainerExt for
148 details on how to do that). There are also predefined attachments, right now the
149 only one is NameAttachment, which allows assigning a name to the field
150 containers.
151
152 Every AttachmentContainer can hold an arbitrary number of attachments.
153 Attachments are divided into separate groups, and there can be only one
154 attachment of every group attached to an AC. Most attachments are a group, but
155 if needed new ones can be used as replacements for their parents.
156
157 \section PageSystemFCThreadsafety Data separation & Thread safety
158
159 One of the primary design goals of OpenSG is supporting multi-threaded
160 applications. For asynchronous threads that means that every thread might need
161 its private copy of the data. To combine that with easy usability and
162 efficient access we decided to replicate at the field container level.
163
164 When a field container is created not only one instance is created but
165 multiple, per default 2. These are called aspects, and every running thread is
166 associated with one of them. Whenever data is changed in a thread, only the
167 aspect that's associated with it is changed, the rest is left as is.
168
169 */
170
171 #if defined(OSG_DO_DOC) || OSG_DOC_LEVEL > 1
172
173 /*! \page PageSystemFieldContainerExt Creating New FieldContainer Classes
174
175 Most developers who use OpenSG as a scene-graph library will probable never
176 create their own OpenSG FieldContainer classes. Similar to widget libs (e.g.
177 qt, gtk) people just use instances (the widgets) but never create new
178 classes.
179
180 However, you can always extend the type system of OpenSG to integrate new
181 cores (e.g. a fancy LOD switch) or application specific FieldContainers.
182
183 FieldContainers are the system's central mechanisms to deal with any kind of
184 thread safe data (see \ref PageSystemFieldsNFieldContainers). Therefore, the
185 class declaration must include various extra meta information for the field
186 and FieldContainer type handling.
187
188 In most systems (e.g. Inventor), you would probably start writing a new class
189 or node by just 'copy and paste'-ing an existing implementation. However,
190 since OpenSG needs all this extra meta data it is not a simple but very error
191 prone process to create the field container source by hand. Instead, we
192 provide a graphical tool to create and manage the FieldContainer description
193 and implementation.
194
195 The basic idea is that you use the 'field container description editor'
196 ($OSGROOT/Tools/fcdEdit) to create an XML file including the description of
197 your FieldContainer fields and interfaces.
198
199 The tool is also able to create all necessary C++ source files. The
200 FieldContainer code is split into classes (e.g. for a Foo FieldContainer:
201 FooBase and Foo). This strategy has various advantages:
202
203 \li Type system changes: If the OpenSG core team decides to change the code
204 interface for the FieldContainer type management we can just recreate the base
205 classes from the XML description. No adaptations 'by hand' are needed.
206
207 \li Interface changes: If you would like to change the interface of your
208 FieldContainer (e.g. add another field) later on you can just re-edit the XML
209 file in fcdEdit and recreate the base classes. All necessary access methods
210 are created automatically.
211
212 \section PageSystemFieldContainerExtFCD XML Description (Foo.fcd)
213
214 Includes all field and meta descriptions for a single FieldContainer. Can be
215 read and written by the fcdEdit tool. You should only change it by hand when
216 you're sure of what you're doing.
217
218 \section PageSystemFieldContainerExtFieldTypes Field Types (FooFields.h)
219
220 Include the field and pointer declarations the the FieldContainer to be used
221 in other FieldContainers as reference. You should not change the file by hand.
222
223 \section PageSystemFieldContainerExtBase Base/Meta Type (FooBase.h, FooBase.inl,
224 FooBase.cpp)
225
226 Holds all the meta and field information. Do not change it by hand. Use the
227 fcdEdit tool to create the files anew whenever you change the XML
228 description.
229
230 \section PageSystemFieldContainerExtUser 'User Code' implementation (Foo.h,
231 Foo.inl, Foo.cpp)
232
233 Holds the 'user code'. The fcdEdit is able to create a skeleton for your
234 FieldContainer implementation. The code does not include any meta information,
235 therefore, it is not necessary to create it anew whenever you change the
236 interface.
237
238 Include new action handlers or whatever you need as functionality.
239
240 \image html fcdEdit-numbered.png "fcdEdit"
241
242 \image latex fcdEdit-numbered.eps "fcdEdit" width=8cm
243
244 A quick explanation of the different buttons/input fields:
245
246 <ol>
247
248 <li>The name of the FieldContainer. Should follow the capitalization rules.</li>
249
250 <li>Defines whether the FC is a part of the OpenSG system. This mainly
251 influences the way system headers are included (with or without the OpenSG/
252 prefix). </li>
253
254 <li>Defines whether the FC can be decorated. Currentl only used for
255 osg::CameraDecorator classes, but usable in general. The main effect is to turn
256 all Field access emthods into virtual functions, to allow overriding them, and
257 creating the necessary default Decorator classes.</li>
258
259 <li>The name of the parent class of the FC.</li>
260
261 <li>Defines if the parent class is a system component.</li>
262
263 <li>The name of the library this FC will be included in. If it is only to be
264 used in application programs, just leave it blank and the appropriate code for
265 an application component will be generated.</li>
266
267 <li>Define whether Field types for pointers to this type of FC should be
268 created.</li>
269
270 <li>Defines whether this FC is abstract or concrete (i.e. whether it can be
271 instantiated or not).</li>
272
273 <li>A general description of this FC. It will be included in the actual FC
274 code. As this code cannot be regenerated changing this description after the
275 code has been generated will not make a difference.</li>
276
277 <li>A list of the Fields of this FC.</li>
278
279 <li>The name of the currently selected Field.</li>
280
281 <li>The type of the currently selected Field. There is a list of predefined
282 types that can be selected from, but it is also possible to just write the type
283 of the Field here.</li>
284
285 <li>The cardinality of the Field, i.e. if it's a single (osg::SField) or multi
286 element (osg::MField) field.</li>
287
288 <li>The access type of the field: private, protected or public. In general
289 Fields should be public, if they are internal they should be protected.</li>
290
291 <li>The visibility of the Field mainly influences whether the Field is written
292 to files etc. Fields that have no meaning beyond the current execution of the
293 program should be internal, Fields that hold configuration data should be
294 external.</li>
295
296 <li>The header containing the declaration of the Field's type. If left empty a
297 name is guessed, using the name <tt>OSG<type>Fields.h</tt>. For type names
298 ending in \c Ptr (the default for FieldContainerPtr types) the \c Ptr is
299 removed. This works for all system types and for standard user-defined types.
300 For other types, just enter the header file name into this field, excluding the "
301 delimiters. </li>
302
303 <li>The default value of the Field. Used to initialize the Field, and put
304 verbatim into the constructor definition for the given Field (e.g. <tt>FC::FC() :
305 Field(default) { }</tt>) </li>
306
307 <li>The header needed to declare the default value. Useful to access enum or
308 constants from external files (like opengl.h).</li>
309
310 <li>A short description of the Field's contents and function. Will be put into
311 the code documentation.</li>
312
313 <li>Creates a new Field.</li>
314
315 <li>Deletes a Field.</li>
316
317 <li>Clones a Field.</li>
318
319 <li>Moves the Field up in the list.</li>
320
321 <li>Moves the Field down in the list.</li>
322
323 <li>Clear the whole system, start from scratch.</li>
324
325 <li>Load an .fcd file.</li>
326
327 <li>Currently unused.</li>
328
329 <li>Save the current settings to the .fcd file.</li>
330
331 <li>Write the FieldContainer Base code. This can also be done by calling
332 fcdEdit with the <tt>-b</tt> command line option and the .fcd file. It is safe
333 to do that, as no user changes should be done to the Base code.</li>
334
335 <li>Currently unused.</li>
336
337 <li>Currently unused.</li>
338
339 <li>Save the current settings to a different .fcd file.</li>
340
341 <li>Write the actual FieldContainer code. This can also be done by calling
342 fcdEdit with the <tt>-f</tt> command line option and the .fcd file. This will
343 not keep any changes made to the FC code, and thus can quickly destroy whatever
344 work has been done to it. To prevent that from happening on accident, it will not
345 overwrite existing files.</li>
346
347 <li>Minimal info about the progam.</li>
348
349 <li>Leave the program.</li>
350
351 </ol>
352
353 \section PageSystemFieldContainerExtPrototype Prototype Replacement
354
355 If you create a replacement for a system component, e.g. a smarter DistanceLOD
356 node that can handle predictive LOD selection, and want the system to use your
357 version of the DistanceLOD from now on you can do that. Internally all field
358 container instances are created by cloning a prototype instance. You can
359 access the prototype for a given FieldContainer via its class type which you
360 can access using FC::getClassType(). The class type has a setPrototype()
361 method to assign the prototype.
362
363 Be careful to only replace the prototype with classes derived from the
364 original class, or the behavior of the system is undefined.
365
366 \section PageSystemFieldContainerExtInit Initialization / Deinitalization
367
368 As OpenSG uses object replication for thread-safe data, constructors and
369 destructors are not always the right place for initialisation and deletion
370 anymore. They are called for every aspect, which usually is more than once.
371 For initialisation that should be done only once per object, the onCreate()
372 method can be used. Similarly, onDestroy() is called once, when the object is
373 destroyed.
374
375 There is also a difference between the constructors. The copy constructor is
376 called for every aspect of an object, the default constructor is only called
377 once, during the static init phase, to create the initial prototype instance
378 for the class. As code running in the static init phase faces some
379 restrictions (e.g. the order of initializations is undefined, thus any other
380 object might not yet have been initialized) a saver way to do class-global
381 initializations was added. The initMethod() method is called during osgInit(),
382 which is after all static inits are done.
383
384 As a summary here's a list of when which method is called:
385
386 \li default constructor: once, during static init, to create the initial
387 prototype
388
389 \li initMethod(): once, during osgInit()
390
391 \li copy constructor: during object instance creation, once for every aspect
392
393 \li onCreate(): during object instance creation, once
394
395 \li onDestroy(): during object instance deletion, once
396
397 \li destructor: during object instance deletion, once for every aspect
398
399 onCreate() and on Destroy() are also called for the initial prototype
400 creation. Not all prototypes might need the resources a real instance needs,
401 and initial prototype creation is run during static init, where it might not
402 be safe to access other classes. To allow a destinction between prototype
403 creation and the standard running state of the system there's a global
404 variable GlobalSystemState, which will be set to Startup during static init
405 and Running after osgInit() is finished. During osgExit() it will be set to
406 Shutdown.
407
408 */
409
410 #endif
411
Note: See TracBrowser for help on using the browser.