From caceb94db8c21be58c38f5b5080c43a98ecb7521 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 22 Feb 2012 10:46:35 +0000 Subject: [PATCH] From Miha Ravsel, "While trying to create my custom serializer class, i created some dummy data which accidentally popped-up bug in InputStream readObjectFields function. Bug description: Let's say we have class A namespace Bug { class A : public osg::Object { public: //... typedef std::vector > AList; protected: AList _alist; //... } } REGISTER_OBJECT_WRAPPER( A, new Bug::A, Bug::A, "osg::Object Bug::A" ) { ADD_LIST_SERIALIZER(A,Bug::A::AList); } Bug: We create say 3 instances of class A: A1,A2,A3 and then we add A2 and A3 and A1 as child instances of A1 so we get next structure: A1 |- A2,A3,A1 we call osgDB::writeObjectFile(A1,"/data/a.osgt") -> saved correctly( third element in list is saved as unique id that references parentClass now we call A1 = osgDB::readObjectFile("/data/a.osgt"); Everything is deserialized correctely except last element in list which should be same instance as parent A1. The attached code resolves this issue by passing UniqueID in readObjectFields method and saving object in _identifierMap as soon as we have valid object instance so we can make reference to parent object from any child instance. " --- include/osgDB/InputStream | 2 +- src/osgDB/InputStream.cpp | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/include/osgDB/InputStream b/include/osgDB/InputStream index af431f46c..cf0999815 100644 --- a/include/osgDB/InputStream +++ b/include/osgDB/InputStream @@ -138,7 +138,7 @@ public: osg::PrimitiveSet* readPrimitiveSet(); osg::Image* readImage(bool readFromExternal=true); osg::Object* readObject( osg::Object* existingObj=0 ); - osg::Object* readObjectFields( const std::string& className, osg::Object* existingObj=0); + osg::Object* readObjectFields( const std::string& className, unsigned int id, osg::Object* existingObj=0); /// set an input iterator, used directly when not using InputStream with a traditional file releated stream. void setInputIterator( InputIterator* ii ) { _in = ii; } diff --git a/src/osgDB/InputStream.cpp b/src/osgDB/InputStream.cpp index a86820bfe..47ed5ba64 100644 --- a/src/osgDB/InputStream.cpp +++ b/src/osgDB/InputStream.cpp @@ -599,9 +599,7 @@ osg::Image* InputStream::readImage(bool readFromExternal) image->setWriteHint( (osg::Image::WriteHint)writeHint ); } - image = static_cast( readObjectFields(className, image.get()) ); - - _identifierMap[id] = image; + image = static_cast( readObjectFields(className, id, image.get()) ); return image.release(); } @@ -620,16 +618,14 @@ osg::Object* InputStream::readObject( osg::Object* existingObj ) return itr->second.get(); } - osg::ref_ptr obj = readObjectFields( className, existingObj ); - - _identifierMap[id] = obj; + osg::ref_ptr obj = readObjectFields( className, id, existingObj ); advanceToCurrentEndBracket(); return obj.release(); } -osg::Object* InputStream::readObjectFields( const std::string& className, osg::Object* existingObj ) +osg::Object* InputStream::readObjectFields( const std::string& className, unsigned int id, osg::Object* existingObj ) { ObjectWrapper* wrapper = Registry::instance()->getObjectWrapperManager()->findWrapper( className ); if ( !wrapper ) @@ -641,6 +637,7 @@ osg::Object* InputStream::readObjectFields( const std::string& className, osg::O _fields.push_back( className ); osg::ref_ptr obj = existingObj ? existingObj : wrapper->getProto()->cloneType(); + _identifierMap[id] = obj; if ( obj.valid() ) { const StringList& associates = wrapper->getAssociates();