1 /*---------------------------------------------------------------------------*\
5 * Copyright 2000-2002 by OpenSG Forum *
7 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
9 \*---------------------------------------------------------------------------*/
10 /*---------------------------------------------------------------------------*\
13 * This library is free software; you can redistribute it and/or modify it *
14 * under the terms of the GNU Library General Public License as published *
15 * by the Free Software Foundation, version 2. *
17 * This library is distributed in the hope that it will be useful, but *
18 * WITHOUT ANY WARRANTY; without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
20 * Library General Public License for more details. *
22 * You should have received a copy of the GNU Library General Public *
23 * License along with this library; if not, write to the Free Software *
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
26 \*---------------------------------------------------------------------------*/
27 /*---------------------------------------------------------------------------*\
35 \*---------------------------------------------------------------------------*/
37 //---------------------------------------------------------------------------
39 //---------------------------------------------------------------------------
41 #include "OSGOSGWriter.h"
42 //#include "OSGAttachment.h"
43 //#include "OSGSimpleAttachments.h"
44 //#include "OSGVRMLNodeDescs.h"
46 #include "OSGAttachmentMapSFields.h"
47 #include "OSGAttachment.h"
48 #include "OSGNameAttachment.h"
50 #include <boost/bind.hpp>
57 #if defined(OSG_WIN32_ICL)
58 #pragma warning (disable : 383)
61 #if defined(OSG_WIN32_ICL)
62 #pragma warning (default : 383)
66 const UInt32
OSGWriter::DefaultSFWidth
= TypeTraits
<UInt32
>::getMax();
67 const UInt32
OSGWriter::DefaultMFWidth
= 60;
69 /*-------------------------------------------------------------------------*/
72 /*! Constructor. Set members to initial values.
74 OSGWriter::FCInfoHelper::FCInfoHelper(void) :
81 /*! Constructor. Set members to initial values.
83 OSGWriter::OSGWriter(OutStream
&stream
, UInt32 indentStep
) :
89 /*-------------------------------------------------------------------------*/
92 /*! Destructor. There are no dynamic members to destroy.
94 OSGWriter::~OSGWriter(void)
98 /*-------------------------------------------------------------------------*/
101 /*! Write a single FieldContainer with all its "children", i.e. everything
102 * that can be reached via Ptr-Fields.
104 void OSGWriter::write(FieldContainer
*container
)
106 _visitedFCMap
.clear();
107 // _indent.setIndent(0);
109 _outStream
<< "#OSG V1.0 ";
112 visitContainer(container
);
113 writeContainer(container
, true);
117 /*! Write all FieldContainers in containers with their "children",
118 * i.e. everything that can be reached via Ptr-Fields.
120 void OSGWriter::write(std::vector
<FieldContainer
*> containers
)
122 _visitedFCMap
.clear();
123 // _indent.setIndent(0);
125 _outStream
<< "#OSG V1.0 " << "\n";
127 std::vector
<FieldContainer
*>::reverse_iterator iter
;
129 for(iter
= containers
.rbegin(); iter
!= containers
.rend(); ++iter
)
131 visitContainer(*iter
);
134 for(iter
= containers
.rbegin(); iter
!= containers
.rend(); ++iter
)
136 writeContainer(*iter
, true);
141 /*! Set the name by which this FieldContainer is referenced. If available
142 * a NameAttachment is used, otherwise the name is constructed from
143 * the type name and the container id.
146 void OSGWriter::FCInfoHelper::setName(FieldContainer
* const pFC
)
148 AttachmentContainer
*pAttCon
= dynamic_cast<AttachmentContainer
*>(pFC
);
152 const Char8
*szName
= getName(pAttCon
);
156 containerName
= szName
;
161 //no NameAttachment. Build name from Type and Id
162 containerName
= pFC
->getTypeName();
164 TypeTraits
<UInt32
>::putToString(pFC
->getId(), containerName
);
168 void OSGWriter::visitContainer(FieldContainer
* const pFC
)
176 typedef std::pair
<FCInfoHelperMap::iterator
, bool> MapInsertInfo
;
178 std::string containerName
;
179 // const FieldContainerType &fcType = pFC->getType();
180 UInt32 numFields
= pFC
->getNumFields();
181 MapInsertInfo insertInfo
;
183 insertInfo
= _visitedFCMap
.insert(std::make_pair(pFC
, FCInfoHelper()));
185 if(insertInfo
.second
== true)
187 //the FC was NOT visited before
188 for(UInt32 field
= 1; field
<= numFields
; field
++)
190 GetFieldHandlePtr fHandle
= pFC
->getField(field
);
192 if(fHandle
== NULL
|| (fHandle
!= NULL
&& fHandle
->isInternal()))
202 //the FC was in the map => FC is shared
204 FCInfoHelperMap::iterator iter
= _visitedFCMap
.find(pFC
);
206 if(iter
== _visitedFCMap
.end())
208 SWARNING
<< "OSGWriter::visitContainer(): FieldContainer * "
209 << "not found in map" << std::endl
;
212 if(iter
->second
.hasName
== false)
214 iter
->second
.setName(pFC
);
215 iter
->second
.hasName
= true;
220 void OSGWriter::visitField(GetFieldHandlePtr hF
)
222 if(hF
->isValid() == false)
227 // const FieldType &fType = hF->getType();
229 GetMapFieldHandlePtr sfMap
=
230 boost::dynamic_pointer_cast
<
231 GetMapFieldHandle
>(hF
);
233 if(sfMap
!= NULL
&& sfMap
->isValid() == true)
235 sfMap
->traverse(boost::bind(&OSGWriter::visitContainer
, this, _1
));
239 FieldContainerPtrSFieldBase::GetHandlePtr sfFCPtr
=
240 boost::dynamic_pointer_cast
<
241 FieldContainerPtrSFieldBase::GetHandle
>(hF
);
243 FieldContainerPtrMFieldBase::GetHandlePtr mfFCPtr
=
244 boost::dynamic_pointer_cast
<
245 FieldContainerPtrMFieldBase::GetHandle
>(hF
);
247 if(sfFCPtr
!= NULL
&& sfFCPtr
->isValid() == true)
249 visitContainer((*sfFCPtr
)->getValue());
251 else if(mfFCPtr
!= NULL
&& mfFCPtr
->isValid() == true)
253 SizeT mfSize
= (*mfFCPtr
)->size();
255 for(SizeT i
= 0; i
< mfSize
; i
++)
257 visitContainer((**mfFCPtr
)[i
]);
264 void OSGWriter::writeContainer(FieldContainer
* const pFC
,
272 UInt32 numFields
= pFC
->getNumFields();
274 FCInfoHelperMap::iterator iter
= _visitedFCMap
.find(pFC
);
276 if(iter
== _visitedFCMap
.end())
278 SWARNING
<< "OSGWriter::writeContainer(): FieldContainer * "
279 << "not found in map" << std::endl
;
283 if(!iter
->second
.written
)
285 //FC is not written yet
286 iter
->second
.written
= true;
290 _outStream
<< BeginElem
;
293 if(iter
->second
.hasName
)
296 << iter
->second
.containerName
298 << pFC
->getTypeName()
306 _outStream
<< pFC
->getTypeName()
313 _outStream
<< IncIndent
;
315 for(UInt32 field
= numFields
; field
> 0; field
--)
317 GetFieldHandlePtr fHandle
= pFC
->getField(field
);
319 if(fHandle
== NULL
|| (fHandle
!= NULL
&& fHandle
->isInternal()))
327 _outStream
<< DecIndent
;
329 _outStream
<< BeginElem
335 //FC is already written -> its shared -> write reference
336 if(!iter
->second
.hasName
)
338 SWARNING
<< "OSGWriter::writeContainer(): FieldContainer is "
339 << "shared, but not named"
346 _outStream
<< BeginElem
;
350 << iter
->second
.containerName
357 void OSGWriter::writeField(GetFieldHandlePtr hF
)
359 if(hF
->isValid() == false)
364 // const FieldType& fType = hF->getType();
366 GetMapFieldHandlePtr sfMap
=
367 boost::dynamic_pointer_cast
<
368 GetMapFieldHandle
>(hF
);
370 FieldContainerPtrSFieldBase::GetHandlePtr sfFCPtr
=
371 boost::dynamic_pointer_cast
<FieldContainerPtrSFieldBase::GetHandle
>(hF
);
373 FieldContainerPtrMFieldBase::GetHandlePtr mfFCPtr
=
374 boost::dynamic_pointer_cast
<FieldContainerPtrMFieldBase::GetHandle
>(hF
);
376 if(sfMap
!= NULL
&& sfMap
->isValid() == true)
378 _outStream
<< BeginElem
381 //if the Attachment Map is empty write [] as its content
382 if(sfMap
->empty() == true)
384 _outStream
<< " [ ] " << EndElemNL
;
388 _outStream
<< EndElemNL
393 _outStream
<< IncIndent
;
395 EditMapFieldHandle::MapList fcList
;
397 sfMap
->flatten(fcList
);
399 EditMapFieldHandle::MapList::iterator iter
= fcList
.begin();
400 EditMapFieldHandle::MapList::iterator end
= fcList
.end ();
402 for(; iter
!=end
; ++iter
)
404 _outStream
<< BeginElem
411 _outStream
<< IncIndent
;
413 _outStream
<< BeginElem
420 _outStream
<< IncIndent
;
422 std::vector
<std::string
>::const_iterator kIt
=
425 std::vector
<std::string
>::const_iterator kEnd
=
428 for(; kIt
!= kEnd
; ++kIt
)
430 _outStream
<< BeginElem
437 _outStream
<< DecIndent
;
439 _outStream
<< BeginElem
443 _outStream
<< BeginElem
446 if(iter
->second
== NULL
)
453 writeContainer(iter
->second
, false);
454 _outStream
<< EndElemNL
;
457 _outStream
<< DecIndent
;
459 _outStream
<< BeginElem
464 _outStream
<< DecIndent
;
466 _outStream
<< BeginElem
471 else if(sfFCPtr
!= NULL
|| mfFCPtr
!= NULL
)
473 //this Field points to FC
475 if(hF
->getDescription()->isDynamic() == true)
477 _outStream
<< BeginElem
479 << hF
->getType().getCName()
485 _outStream
<< BeginElem
489 if(sfFCPtr
!= NULL
&& sfFCPtr
->isValid() == true)
491 if((*sfFCPtr
)->getValue() == NULL
)
493 _outStream
<< " NULL" << EndElemNL
;
498 writeContainer((*sfFCPtr
)->getValue(), false);
501 else if(mfFCPtr
!= NULL
&& mfFCPtr
->isValid() == true)
503 _outStream
<< EndElemNL
508 _outStream
<< IncIndent
;
510 SizeT mfSize
= (*mfFCPtr
)->size();
512 for(SizeT i
= 0; i
< mfSize
; i
++)
514 if((*(*mfFCPtr
))[i
] == NULL
)
516 _outStream
<< BeginElem
522 writeContainer((*(*mfFCPtr
))[i
], true);
526 _outStream
<< DecIndent
;
528 _outStream
<< BeginElem
535 //this Field contains data -> write it out
537 if(hF
->getDescription()->isDynamic() == true)
539 _outStream
<< BeginElem
541 << hF
->getType().getCName()
547 _outStream
<< BeginElem
<< hF
->getName();
550 //to access the content of a field via a Field*
551 //one must know the cardinality
552 if(hF
->getCardinality() == FieldType::SingleField
)
556 hF
->pushValueToStream(_outStream
);
558 _outStream
<< EndElemNL
;
560 else if(hF
->getCardinality() == FieldType::MultiField
)
564 hF
->pushSizeToStream(_outStream
);
566 _outStream
<< EndElemNL
571 _outStream
<< IncIndent
;
574 hF
->pushValueToStream(_outStream
);
576 _outStream
<< EndElemNL
;
580 _outStream
<< DecIndent
;
582 _outStream
<< BeginElem