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().
This commit is contained in:
@@ -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; }
|
||||
|
||||
|
||||
@@ -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<osg::Image*>(_object.get()); if (image) { image->ref(); _object==NULL; } return image; }
|
||||
osg::Node* takeNode() { osg::Node* node=dynamic_cast<osg::Node*>(_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<osg::Image*>(_object.get()); if (image) { image->ref(); _object=NULL; image->unref_nodelete(); } return image; }
|
||||
osg::Node* takeNode() { osg::Node* node=dynamic_cast<osg::Node*>(_object.get()); if (node) { node->ref(); _object=NULL; node->unref_nodelete(); } return node; }
|
||||
|
||||
const std::string& message() const { return _message; }
|
||||
|
||||
|
||||
@@ -32,36 +32,37 @@ class OSGReaderWriter : public ReaderWriter
|
||||
Input fr;
|
||||
fr.attach(&fin);
|
||||
|
||||
Group* group = new Group;
|
||||
group->setName("import group");
|
||||
typedef std::vector<osg::Node*> 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
|
||||
|
||||
Reference in New Issue
Block a user