From 8656adb4639da28299637aacf0adcbf3d6ae34d8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Mar 2002 14:03:30 +0000 Subject: [PATCH] Added a Referenced::unref_nodelete() method which unreferences but does not delete the object even if its count goes to 0 or below. This should only be called in special circumstances, the ReaderWriter::ReadResult being one of them. This new method has allowed the problem of objects being multiple referenced on return from readNodeFile() & readImageFile(). --- include/osg/Referenced | 10 +++++++ include/osgDB/ReaderWriter | 6 ++-- src/osgPlugins/osg/ReaderWriterOSG.cpp | 39 +++++++++++++------------- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/include/osg/Referenced b/include/osg/Referenced index ea01a07a3..aecf71412 100644 --- a/include/osg/Referenced +++ b/include/osg/Referenced @@ -22,11 +22,21 @@ class SG_EXPORT Referenced /** increment the reference count by one, indicating that this object has another pointer which is referencing it.*/ inline void ref() const { ++_refCount; } + /** decrement the reference count by one, indicating that a pointer to this object is referencing it. If the reference count goes to zero, it is assumed that this object is no longer referenced and is automatically deleted.*/ inline void unref() const { --_refCount; if (_refCount<=0) delete this; } + + /** decrement the reference count by one, indicating that + a pointer to this object is referencing it. However, do + not delete it, even if ref count goes to 0. Warning, unref_nodelete() + should only be called if the user knows exactly who will + be resonsible for, one should prefer unref() over unref_nodelete() + as the later can lead to memory leaks.*/ + inline void unref_nodelete() const { --_refCount; } + /** return the number pointers currently referencing this object. */ inline const int referenceCount() const { return _refCount; } diff --git a/include/osgDB/ReaderWriter b/include/osgDB/ReaderWriter index 8b31e5370..89e4b6bc4 100644 --- a/include/osgDB/ReaderWriter +++ b/include/osgDB/ReaderWriter @@ -67,9 +67,9 @@ class OSGDB_EXPORT ReaderWriter : public osg::Referenced const bool validImage() { return getImage()!=0; } const bool validNode() { return getNode()!=0; } - osg::Object* takeObject() { osg::Object* obj = _object.get(); if (obj) { obj->ref(); _object=NULL; } return obj; } - osg::Image* takeImage() { osg::Image* image=dynamic_cast(_object.get()); if (image) { image->ref(); _object==NULL; } return image; } - osg::Node* takeNode() { osg::Node* node=dynamic_cast(_object.get()); if (node) { node->ref(); _object==NULL; } return node; } + osg::Object* takeObject() { osg::Object* obj = _object.get(); if (obj) { obj->ref(); _object=NULL; obj->unref_nodelete(); } return obj; } + osg::Image* takeImage() { osg::Image* image=dynamic_cast(_object.get()); if (image) { image->ref(); _object=NULL; image->unref_nodelete(); } return image; } + osg::Node* takeNode() { osg::Node* node=dynamic_cast(_object.get()); if (node) { node->ref(); _object=NULL; node->unref_nodelete(); } return node; } const std::string& message() const { return _message; } diff --git a/src/osgPlugins/osg/ReaderWriterOSG.cpp b/src/osgPlugins/osg/ReaderWriterOSG.cpp index efd31baa9..1ff40ea02 100644 --- a/src/osgPlugins/osg/ReaderWriterOSG.cpp +++ b/src/osgPlugins/osg/ReaderWriterOSG.cpp @@ -32,36 +32,37 @@ class OSGReaderWriter : public ReaderWriter Input fr; fr.attach(&fin); - Group* group = new Group; - group->setName("import group"); + typedef std::vector NodeList; + NodeList nodeList; // load all nodes in file, placing them in a group. while(!fr.eof()) { Node *node = fr.readNode(); - if (node) group->addChild(node); + if (node) nodeList.push_back(node); else fr.advanceOverCurrentFieldOrBlock(); } - if (group->getNumChildren()>1) - { - return group; - } - else if (group->getNumChildren()==1) - { - // only one node loaded so just return that one node, - // and delete the redundent group. Note, the - // child must be referenced before defrencing - // the group so to avoid delete its children. - Node* node = group->getChild(0); - node->ref(); - group->unref(); - return node; - } // group->getNumChildren()==0 - else + if (nodeList.empty()) { return ReadResult("No data loaded from "+fileName); } + else if (nodeList.size()==1) + { + return nodeList.front(); + } + else + { + Group* group = new Group; + group->setName("import group"); + for(NodeList::iterator itr=nodeList.begin(); + itr!=nodeList.end(); + ++itr) + { + group->addChild(*itr); + } + return group; + } } else