1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12 */
13 #include <osgDB/DotOsgWrapper>
14 #include <osgDB/Registry>
15
16 using namespace osgDB;
17
DotOsgWrapper(osg::Object * proto,const std::string & name,const std::string & associates,ReadFunc readFunc,WriteFunc writeFunc,ReadWriteMode readWriteMode)18 DotOsgWrapper::DotOsgWrapper(osg::Object* proto,
19 const std::string& name,
20 const std::string& associates,
21 ReadFunc readFunc,
22 WriteFunc writeFunc,
23 ReadWriteMode readWriteMode)
24 {
25
26
27 _prototype = proto;
28 _name = name;
29
30
31 // copy the names in the space delimited associates input into
32 // a vector of separated names.
33 std::string::size_type start_of_name = associates.find_first_not_of(' ');
34 while (start_of_name!=std::string::npos)
35 {
36 std::string::size_type end_of_name = associates.find_first_of(' ',start_of_name);
37 if (end_of_name!=std::string::npos)
38 {
39 _associates.push_back(std::string(associates,start_of_name,end_of_name-start_of_name));
40 start_of_name = associates.find_first_not_of(' ',end_of_name);
41 }
42 else
43 {
44 _associates.push_back(std::string(associates,start_of_name,associates.size()-start_of_name));
45 start_of_name = end_of_name;
46 }
47 }
48
49 _readFunc = readFunc;
50 _writeFunc = writeFunc;
51
52 _readWriteMode = readWriteMode;
53 }
54
55
RegisterDotOsgWrapperProxy(osg::Object * proto,const std::string & name,const std::string & associates,DotOsgWrapper::ReadFunc readFunc,DotOsgWrapper::WriteFunc writeFunc,DotOsgWrapper::ReadWriteMode readWriteMode)56 RegisterDotOsgWrapperProxy::RegisterDotOsgWrapperProxy(osg::Object* proto,
57 const std::string& name,
58 const std::string& associates,
59 DotOsgWrapper::ReadFunc readFunc,
60 DotOsgWrapper::WriteFunc writeFunc,
61 DotOsgWrapper::ReadWriteMode readWriteMode)
62 {
63 if (Registry::instance())
64 {
65 _wrapper = new DotOsgWrapper(proto,name,associates,readFunc,writeFunc,readWriteMode);
66 Registry::instance()->getDeprecatedDotOsgObjectWrapperManager()->addDotOsgWrapper(_wrapper.get());
67 }
68 }
69
~RegisterDotOsgWrapperProxy()70 RegisterDotOsgWrapperProxy::~RegisterDotOsgWrapperProxy()
71 {
72 if (Registry::instance())
73 {
74 Registry::instance()->getDeprecatedDotOsgObjectWrapperManager()->removeDotOsgWrapper(_wrapper.get());
75 }
76 }
77
78
79
addDotOsgWrapper(DotOsgWrapper * wrapper)80 void DeprecatedDotOsgWrapperManager::addDotOsgWrapper(DotOsgWrapper* wrapper)
81 {
82 if (wrapper==0L) return;
83
84 //OSG_INFO << "osg::Registry::addDotOsgWrapper("<<wrapper->getName()<<")"<< std::endl;
85 const DotOsgWrapper::Associates& assoc = wrapper->getAssociates();
86
87 for(DotOsgWrapper::Associates::const_iterator itr=assoc.begin();
88 itr!=assoc.end();
89 ++itr)
90 {
91 //OSG_INFO << " ("<<*itr<<")"<< std::endl;
92 }
93
94 const std::string& name = wrapper->getName();
95 const osg::Object* proto = wrapper->getPrototype();
96
97 _objectWrapperMap[name] = wrapper;
98 if (wrapper->getReadWriteMode()==DotOsgWrapper::READ_AND_WRITE) _classNameWrapperMap[name] = wrapper;
99
100 if (proto)
101 {
102 std::string libraryName = proto->libraryName();
103 std::string compositeName = libraryName + "::" + name;
104
105 _objectWrapperMap[compositeName] = wrapper;
106 if (wrapper->getReadWriteMode()==DotOsgWrapper::READ_AND_WRITE) _classNameWrapperMap[compositeName] = wrapper;
107
108 if (dynamic_cast<const osg::Image*>(proto))
109 {
110 _imageWrapperMap[name] = wrapper;
111 _imageWrapperMap[compositeName] = wrapper;
112 }
113 if (dynamic_cast<const osg::Drawable*>(proto))
114 {
115 _drawableWrapperMap[name] = wrapper;
116 _drawableWrapperMap[compositeName] = wrapper;
117 }
118 if (dynamic_cast<const osg::StateAttribute*>(proto))
119 {
120 _stateAttrWrapperMap[name] = wrapper;
121 _stateAttrWrapperMap[compositeName] = wrapper;
122 }
123 if (dynamic_cast<const osg::Uniform*>(proto))
124 {
125 _uniformWrapperMap[name] = wrapper;
126 _uniformWrapperMap[compositeName] = wrapper;
127 }
128 if (dynamic_cast<const osg::Node*>(proto))
129 {
130 _nodeWrapperMap[name] = wrapper;
131 _nodeWrapperMap[compositeName] = wrapper;
132 }
133 if (dynamic_cast<const osg::Shader*>(proto))
134 {
135 _shaderWrapperMap[name] = wrapper;
136 _shaderWrapperMap[compositeName] = wrapper;
137 }
138
139
140 }
141 }
142
143 // need to change to delete all instances of wrapper, since we
144 // now can have a wrapper entered twice with the addition of the
145 // library::class composite name.
eraseWrapper(DotOsgWrapperMap & wrappermap,DotOsgWrapper * wrapper)146 void DeprecatedDotOsgWrapperManager::eraseWrapper(DotOsgWrapperMap& wrappermap,DotOsgWrapper* wrapper)
147 {
148 typedef std::vector<DotOsgWrapperMap::iterator> EraseList;
149 EraseList eraseList;
150 for(DotOsgWrapperMap::iterator witr=wrappermap.begin();
151 witr!=wrappermap.end();
152 ++witr)
153 {
154 if (witr->second==wrapper) eraseList.push_back(witr);
155 }
156 for(EraseList::iterator eitr=eraseList.begin();
157 eitr!=eraseList.end();
158 ++eitr)
159 {
160 wrappermap.erase(*eitr);
161 }
162 }
163
removeDotOsgWrapper(DotOsgWrapper * wrapper)164 void DeprecatedDotOsgWrapperManager::removeDotOsgWrapper(DotOsgWrapper* wrapper)
165 {
166 if (wrapper==0L) return;
167
168 eraseWrapper(_objectWrapperMap,wrapper);
169 eraseWrapper(_classNameWrapperMap,wrapper);
170 eraseWrapper(_imageWrapperMap,wrapper);
171 eraseWrapper(_drawableWrapperMap,wrapper);
172 eraseWrapper(_uniformWrapperMap,wrapper);
173 eraseWrapper(_stateAttrWrapperMap,wrapper);
174 eraseWrapper(_nodeWrapperMap,wrapper);
175 eraseWrapper(_shaderWrapperMap,wrapper);
176 }
177
178 struct concrete_wrapper: basic_type_wrapper
179 {
~concrete_wrapperconcrete_wrapper180 virtual ~concrete_wrapper() {}
concrete_wrapperconcrete_wrapper181 concrete_wrapper(const osg::Object *myobj) : myobj_(myobj) {}
matchesconcrete_wrapper182 bool matches(const osg::Object *proto) const
183 {
184 return myobj_->isSameKindAs(proto);
185 }
186 const osg::Object *myobj_;
187 };
188
189
readObjectOfType(const osg::Object & compObj,Input & fr)190 osg::Object* DeprecatedDotOsgWrapperManager::readObjectOfType(const osg::Object& compObj,Input& fr)
191 {
192 return readObjectOfType(concrete_wrapper(&compObj), fr);
193 }
194
getLibraryFileNamesToTry(const std::string & name,FileNames & fileNames)195 bool DeprecatedDotOsgWrapperManager::getLibraryFileNamesToTry(const std::string& name, FileNames& fileNames)
196 {
197 FileNames::size_type sizeBefore = fileNames.size();
198
199 std::string libraryName = osgDB::Registry::instance()->createLibraryNameForNodeKit(name);
200 if (!libraryName.empty()) fileNames.push_back(libraryName);
201
202 libraryName = osgDB::Registry::instance()->createLibraryNameForExtension(std::string("deprecated_")+name);
203 if (!libraryName.empty()) fileNames.push_back(libraryName);
204
205 libraryName = osgDB::Registry::instance()->createLibraryNameForExtension(name);
206 if (!libraryName.empty()) fileNames.push_back(libraryName);
207
208 return fileNames.size() != sizeBefore;
209 }
210
readObjectOfType(const basic_type_wrapper & btw,Input & fr)211 osg::Object* DeprecatedDotOsgWrapperManager::readObjectOfType(const basic_type_wrapper &btw,Input& fr)
212 {
213 const char *str = fr[0].getStr();
214 if (str==NULL) return NULL;
215
216 if (fr[0].matchWord("Use"))
217 {
218 if (fr[1].isString())
219 {
220 osg::Object* obj = fr.getObjectForUniqueID(fr[1].getStr());
221 if (obj && btw.matches(obj))
222 {
223 fr+=2;
224 return obj;
225 }
226 }
227 else return NULL;
228
229 }
230
231 std::string name = str;
232 DotOsgWrapperMap::iterator ow_itr = _objectWrapperMap.find(name);
233 if (ow_itr==_objectWrapperMap.end())
234 {
235 // not found so check if a library::class composite name.
236 std::string token = fr[0].getStr();
237 std::string::size_type posDoubleColon = token.rfind("::");
238 if (posDoubleColon != std::string::npos)
239 {
240 // we have a composite name so now strip off the library name
241 // are try to load it, and then retry the readObject to see
242 // if we can recognize the objects.
243 std::string libraryName = std::string(token,0,posDoubleColon);
244
245 FileNames fileNames;
246 if (getLibraryFileNamesToTry(libraryName, fileNames))
247 {
248 for(FileNames::iterator itr = fileNames.begin();
249 itr != fileNames.end();
250 ++itr)
251 {
252 if (osgDB::Registry::instance()->loadLibrary(*itr)==osgDB::Registry::LOADED) return readObjectOfType(btw,fr);
253 }
254 }
255 }
256 }
257 else if (fr[1].isOpenBracket())
258 {
259 DotOsgWrapper* wrapper = ow_itr->second.get();
260 const osg::Object* proto = wrapper->getPrototype();
261 if (proto==NULL)
262 {
263 OSG_WARN<<"Token "<<fr[0].getStr()<<" read, but has no prototype, cannot load."<< std::endl;
264 return NULL;
265 }
266
267 if (!btw.matches(proto))
268 {
269 return NULL;
270 }
271
272 // record the number of nested brackets move the input iterator
273 // over the name { tokens.
274 int entry = fr[0].getNoNestedBrackets();
275 fr+=2;
276
277 const DotOsgWrapper::Associates& assoc = wrapper->getAssociates();
278 osg::Object* obj = proto->cloneType();
279
280 while(!fr.eof() && fr[0].getNoNestedBrackets()>entry)
281 {
282 bool iteratorAdvanced = false;
283 if (fr[0].matchWord("UniqueID") && fr[1].isString())
284 {
285 fr.registerUniqueIDForObject(fr[1].getStr(),obj);
286 fr += 2;
287 iteratorAdvanced = true;
288 }
289
290 // read the local data by iterating through the associate
291 // list, mapping the associate names to DotOsgWrapper's which
292 // in turn have the appropriate functions.
293 for(DotOsgWrapper::Associates::const_iterator aitr=assoc.begin();
294 aitr!=assoc.end();
295 ++aitr)
296 {
297 DotOsgWrapperMap::iterator mitr = _objectWrapperMap.find(*aitr);
298 if (mitr==_objectWrapperMap.end())
299 {
300 // not found so check if a library::class composite name.
301 std::string token = *aitr;
302 std::string::size_type posDoubleColon = token.rfind("::");
303 if (posDoubleColon != std::string::npos)
304 {
305 // we have a composite name so now strip off the library name
306 // and try to load it, and then retry the find to see
307 // if we can recognize the objects.
308 std::string libraryName = std::string(token,0,posDoubleColon);
309
310 FileNames fileNames;
311 if (getLibraryFileNamesToTry(libraryName, fileNames))
312 {
313 for(FileNames::iterator itr = fileNames.begin();
314 itr != fileNames.end() && mitr==_objectWrapperMap.end();
315 ++itr)
316 {
317 if (osgDB::Registry::instance()->loadLibrary(*itr)==osgDB::Registry::LOADED)
318 {
319 mitr = _objectWrapperMap.find(*aitr);
320 }
321 }
322 }
323 }
324 }
325
326 if (mitr!=_objectWrapperMap.end())
327 {
328 // get the function to read the data...
329 DotOsgWrapper::ReadFunc rf = mitr->second->getReadFunc();
330 if (rf && (*rf)(*obj,fr)) iteratorAdvanced = true;
331 }
332
333 }
334
335 if (!iteratorAdvanced) fr.advanceOverCurrentFieldOrBlock();
336 }
337 ++fr; // step over trailing '}'
338
339 return obj;
340
341 }
342 return 0L;
343 }
344
345 //
346 // read object from input iterator.
347 //
readObject(DotOsgWrapperMap & dowMap,Input & fr)348 osg::Object* DeprecatedDotOsgWrapperManager::readObject(DotOsgWrapperMap& dowMap,Input& fr)
349 {
350 const char *str = fr[0].getStr();
351 if (str==NULL) return NULL;
352
353 std::string name = str;
354 DotOsgWrapperMap::iterator dow_itr = dowMap.find(name);
355 if (dow_itr==dowMap.end())
356 {
357 // not found so check if a library::class composite name.
358 std::string token = fr[0].getStr();
359 std::string::size_type posDoubleColon = token.rfind("::");
360 if (posDoubleColon != std::string::npos)
361 {
362 // we have a composite name so now strip off the library name
363 // are try to load it, and then retry the readObject to see
364 // if we can recognize the objects.
365
366 std::string libraryName = std::string(token,0,posDoubleColon);
367
368 FileNames fileNames;
369 if (getLibraryFileNamesToTry(libraryName, fileNames))
370 {
371 for(FileNames::iterator itr = fileNames.begin();
372 itr != fileNames.end();
373 ++itr)
374 {
375 if (osgDB::Registry::instance()->loadLibrary(*itr)==osgDB::Registry::LOADED) return readObject(dowMap,fr);
376 }
377 }
378 }
379 }
380 else if (fr[1].isOpenBracket())
381 {
382
383 DotOsgWrapper* wrapper = dow_itr->second.get();
384 const osg::Object* proto = wrapper->getPrototype();
385 if (proto==NULL)
386 {
387 OSG_WARN<<"Token "<<fr[0].getStr()<<" read, but has no prototype, cannot load."<< std::endl;
388 return NULL;
389 }
390
391 // record the number of nested brackets move the input iterator
392 // over the name { tokens.
393 int entry = fr[0].getNoNestedBrackets();
394 fr+=2;
395
396 const DotOsgWrapper::Associates& assoc = wrapper->getAssociates();
397 osg::Object* obj = proto->cloneType();
398
399 while(!fr.eof() && fr[0].getNoNestedBrackets()>entry)
400 {
401 bool iteratorAdvanced = false;
402 if (fr[0].matchWord("UniqueID") && fr[1].isString())
403 {
404 fr.registerUniqueIDForObject(fr[1].getStr(),obj);
405 fr += 2;
406 iteratorAdvanced = true;
407 }
408
409 // read the local data by iterating through the associate
410 // list, mapping the associate names to DotOsgWrapper's which
411 // in turn have the appropriate functions.
412 for(DotOsgWrapper::Associates::const_iterator aitr=assoc.begin();
413 aitr!=assoc.end();
414 ++aitr)
415 {
416 DotOsgWrapperMap::iterator mitr = _objectWrapperMap.find(*aitr);
417 if (mitr==_objectWrapperMap.end())
418 {
419 // not found so check if a library::class composite name.
420 std::string token = *aitr;
421 std::string::size_type posDoubleColon = token.rfind("::");
422 if (posDoubleColon != std::string::npos)
423 {
424
425 // we have a composite name so now strip off the library name
426 // are try to load it, and then retry the find to see
427 // if we can recognize the objects.
428
429 std::string libraryName = std::string(token,0,posDoubleColon);
430
431 FileNames fileNames;
432 if (getLibraryFileNamesToTry(libraryName, fileNames))
433 {
434 for(FileNames::iterator itr = fileNames.begin();
435 itr != fileNames.end() && mitr==_objectWrapperMap.end();
436 ++itr)
437 {
438 if (osgDB::Registry::instance()->loadLibrary(*itr)==osgDB::Registry::LOADED)
439 {
440 mitr = _objectWrapperMap.find(*aitr);
441 }
442 }
443 }
444 }
445 }
446
447 if (mitr!=_objectWrapperMap.end())
448 {
449 // get the function to read the data...
450 DotOsgWrapper::ReadFunc rf = mitr->second->getReadFunc();
451 if (rf && (*rf)(*obj,fr)) iteratorAdvanced = true;
452 }
453
454 }
455
456 if (!iteratorAdvanced) fr.advanceOverCurrentFieldOrBlock();
457 }
458 ++fr; // step over trailing '}'
459
460 return obj;
461
462 }
463
464 return 0L;
465 }
466
467 //
468 // read object from input iterator.
469 //
readObject(Input & fr)470 osg::Object* DeprecatedDotOsgWrapperManager::readObject(Input& fr)
471 {
472 if (fr[0].matchWord("Use"))
473 {
474 if (fr[1].isString())
475 {
476 osg::Object* obj = fr.getObjectForUniqueID(fr[1].getStr());
477 if (obj) fr+=2;
478 return obj;
479 }
480 else return NULL;
481
482 }
483
484 return readObject(_objectWrapperMap,fr);
485 }
486
487
488 //
489 // read image from input iterator.
490 //
readImage(Input & fr)491 osg::Image* DeprecatedDotOsgWrapperManager::readImage(Input& fr)
492 {
493 if (fr[0].matchWord("Use"))
494 {
495 if (fr[1].isString())
496 {
497 osg::Image* image = dynamic_cast<osg::Image*>(fr.getObjectForUniqueID(fr[1].getStr()));
498 if (image) fr+=2;
499 return image;
500 }
501 else return NULL;
502
503 }
504
505 osg::Object* obj = readObject(_imageWrapperMap,fr);
506 osg::Image* image = dynamic_cast<osg::Image*>(obj);
507 if (image) return image;
508 else if (obj) obj->unref();
509
510 return NULL;
511 }
512
513
514 //
515 // read drawable from input iterator.
516 //
readDrawable(Input & fr)517 osg::Drawable* DeprecatedDotOsgWrapperManager::readDrawable(Input& fr)
518 {
519 if (fr[0].matchWord("Use"))
520 {
521 if (fr[1].isString())
522 {
523 osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(fr.getObjectForUniqueID(fr[1].getStr()));
524 if (drawable) fr+=2;
525 return drawable;
526 }
527 else return NULL;
528
529 }
530
531 osg::Object* obj = readObject(_drawableWrapperMap,fr);
532 osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(obj);
533 if (drawable) return drawable;
534 else if (obj) obj->unref();
535
536 return NULL;
537 }
538
539 //
540 // read drawable from input iterator.
541 //
readStateAttribute(Input & fr)542 osg::StateAttribute* DeprecatedDotOsgWrapperManager::readStateAttribute(Input& fr)
543 {
544
545 if (fr[0].matchWord("Use"))
546 {
547 if (fr[1].isString())
548 {
549 osg::StateAttribute* attribute = dynamic_cast<osg::StateAttribute*>(fr.getObjectForUniqueID(fr[1].getStr()));
550 if (attribute) fr+=2;
551 return attribute;
552 }
553 else return NULL;
554
555 }
556
557 return dynamic_cast<osg::StateAttribute*>(readObject(_stateAttrWrapperMap,fr));
558 }
559
560 //
561 // read drawable from input iterator.
562 //
readUniform(Input & fr)563 osg::Uniform* DeprecatedDotOsgWrapperManager::readUniform(Input& fr)
564 {
565
566 if (fr[0].matchWord("Use"))
567 {
568 if (fr[1].isString())
569 {
570 osg::Uniform* attribute = dynamic_cast<osg::Uniform*>(fr.getObjectForUniqueID(fr[1].getStr()));
571 if (attribute) fr+=2;
572 return attribute;
573 }
574 else return NULL;
575
576 }
577
578 return dynamic_cast<osg::Uniform*>(readObject(_uniformWrapperMap,fr));
579 }
580
581 //
582 // read node from input iterator.
583 //
readNode(Input & fr)584 osg::Node* DeprecatedDotOsgWrapperManager::readNode(Input& fr)
585 {
586 if (fr[0].matchWord("Use"))
587 {
588 if (fr[1].isString())
589 {
590 osg::Node* node = dynamic_cast<osg::Node*>(fr.getObjectForUniqueID(fr[1].getStr()));
591 if (node) fr+=2;
592 return node;
593 }
594 else return NULL;
595
596 }
597
598 osg::Object* obj = readObject(_nodeWrapperMap,fr);
599 osg::Node* node = dynamic_cast<osg::Node*>(obj);
600 if (node) return node;
601 else if (obj) obj->unref();
602
603 return NULL;
604 }
605
606 //
607 // read image from input iterator.
608 //
readShader(Input & fr)609 osg::Shader* DeprecatedDotOsgWrapperManager::readShader(Input& fr)
610 {
611 if (fr[0].matchWord("Use"))
612 {
613 if (fr[1].isString())
614 {
615 osg::Shader* shader = dynamic_cast<osg::Shader*>(fr.getObjectForUniqueID(fr[1].getStr()));
616 if (shader) fr+=2;
617 return shader;
618 }
619 else return NULL;
620
621 }
622
623 osg::Object* obj = readObject(_shaderWrapperMap,fr);
624 osg::Shader* shader = dynamic_cast<osg::Shader*>(obj);
625 if (shader) return shader;
626 else if (obj) obj->unref();
627
628 return NULL;
629 }
630
631 //
632 // Write object to output
633 //
writeObject(const osg::Object & obj,Output & fw)634 bool DeprecatedDotOsgWrapperManager::writeObject(const osg::Object& obj,Output& fw)
635 {
636
637 if (obj.referenceCount()>1)
638 {
639 std::string uniqueID;
640 if (fw.getUniqueIDForObject(&obj,uniqueID))
641 {
642 fw.writeUseID( uniqueID );
643 return true;
644 }
645 }
646
647 const std::string classname( obj.className() );
648 const std::string libraryName( obj.libraryName() );
649 const std::string compositeName( libraryName + "::" + classname );
650
651 // try composite name first
652 DotOsgWrapperMap::iterator cnw_itr = _classNameWrapperMap.find(compositeName);
653
654 if (cnw_itr==_classNameWrapperMap.end())
655 {
656 FileNames fileNames;
657 if (getLibraryFileNamesToTry(libraryName, fileNames))
658 {
659 for(FileNames::iterator itr = fileNames.begin();
660 itr != fileNames.end();
661 ++itr)
662 {
663 if (osgDB::Registry::instance()->loadLibrary(*itr)==osgDB::Registry::LOADED) return writeObject(obj,fw);
664 }
665 }
666
667 // otherwise try simple class name
668 if (cnw_itr == _classNameWrapperMap.end())
669 cnw_itr = _classNameWrapperMap.find(classname);
670 }
671
672 if (cnw_itr!=_classNameWrapperMap.end())
673 {
674 DotOsgWrapper* wrapper = cnw_itr->second.get();
675 const DotOsgWrapper::Associates& assoc = wrapper->getAssociates();
676
677 if (libraryName=="osg")
678 {
679 // member of the core osg, so no need to have composite library::class name.
680 fw.writeBeginObject( wrapper->getName() );
681 }
682 else
683 {
684 // member of the node kit so must use composite library::class name.
685 std::string::size_type posDoubleColon = wrapper->getName().find("::");
686 if (posDoubleColon != std::string::npos)
687 {
688 fw.writeBeginObject( wrapper->getName() );
689 }
690 else
691 {
692 fw.writeBeginObject( libraryName + "::" + wrapper->getName() );
693 }
694 }
695 fw.moveIn();
696
697
698 // write out the unique ID if required.
699 if (obj.referenceCount()>1)
700 {
701 std::string uniqueID;
702 fw.createUniqueIDForObject(&obj,uniqueID);
703 fw.registerUniqueIDForObject(&obj,uniqueID);
704 fw.writeUniqueID( uniqueID );
705 }
706
707 // read the local data by iterating through the associate
708 // list, mapping the associate names to DotOsgWrapper's which
709 // in turn have the appropriate functions.
710 for(DotOsgWrapper::Associates::const_iterator aitr=assoc.begin();
711 aitr!=assoc.end();
712 ++aitr)
713 {
714 DotOsgWrapperMap::iterator mitr = _objectWrapperMap.find(*aitr);
715 if (mitr==_objectWrapperMap.end())
716 {
717 // not found so check if a library::class composite name.
718 std::string token = *aitr;
719 std::string::size_type posDoubleColon = token.rfind("::");
720 if (posDoubleColon != std::string::npos)
721 {
722
723 // we have a composite name so now strip off the library name
724 // are try to load it, and then retry the find to see
725 // if we can recognize the objects.
726
727 std::string assoc_libraryName = std::string(token,0,posDoubleColon);
728
729 FileNames fileNames;
730 if (getLibraryFileNamesToTry(assoc_libraryName, fileNames))
731 {
732 for(FileNames::iterator itr = fileNames.begin();
733 itr != fileNames.end() && mitr==_objectWrapperMap.end();
734 ++itr)
735 {
736 if (osgDB::Registry::instance()->loadLibrary(*itr)==osgDB::Registry::LOADED)
737 {
738 mitr = _objectWrapperMap.find(*aitr);
739 }
740 }
741 }
742 }
743 }
744 if (mitr!=_objectWrapperMap.end())
745 {
746 // get the function to read the data...
747 DotOsgWrapper::WriteFunc wf = mitr->second->getWriteFunc();
748 if (wf) (*wf)(obj,fw);
749 }
750
751 }
752
753 fw.moveOut();
754 fw.writeEndObject();
755
756 return true;
757 }
758
759 return false;
760 }
761
762