Refactored the UserDataContainer so that the osg::UserDataContainer is now a pure virtual base class,

with a osg::DefaultUserDataContainer subclassed from this.  The user object access methods have now all
been moved from osg::Object into the UserDataContainer class, except for the set/getUserData() methods
that are left in osg::Object for backwards compatibility, and the description list access methods have
been moved back into osg::Node.

main UserObject access methods are now all def
This commit is contained in:
Robert Osfield
2011-06-09 12:57:14 +00:00
parent 1016092720
commit 22bc0391c7
10 changed files with 317 additions and 234 deletions

View File

@@ -17,6 +17,7 @@
#include <osg/Notify>
#include <osg/OccluderNode>
#include <osg/Transform>
#include <osg/UserDataContainer>
#include <algorithm>
@@ -472,6 +473,51 @@ bool Node::containsOccluderNodes() const
return _numChildrenWithOccluderNodes>0 || dynamic_cast<const OccluderNode*>(this);
}
void Node::setDescriptions(const DescriptionList& descriptions)
{
getOrCreateUserDataContainer()->setDescriptions(descriptions);
}
Node::DescriptionList& Node::getDescriptions()
{
return getOrCreateUserDataContainer()->getDescriptions();
}
static OpenThreads::Mutex s_mutex_StaticDescriptionList;
static const Node::DescriptionList& getStaticDescriptionList()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_StaticDescriptionList);
static Node::DescriptionList s_descriptionList;
return s_descriptionList;
}
const Node::DescriptionList& Node::getDescriptions() const
{
if (_userDataContainer) return _userDataContainer->getDescriptions();
else return getStaticDescriptionList();
}
std::string& Node::getDescription(unsigned int i)
{
return getOrCreateUserDataContainer()->getDescriptions()[i];
}
const std::string& Node::getDescription(unsigned int i) const
{
if (_userDataContainer) return _userDataContainer->getDescriptions()[i];
else return getStaticDescriptionList()[i];
}
unsigned int Node::getNumDescriptions() const
{
return _userDataContainer ? _userDataContainer->getDescriptions().size() : 0;
}
void Node::addDescription(const std::string& desc)
{
getOrCreateUserDataContainer()->getDescriptions().push_back(desc);
}
BoundingSphere Node::computeBound() const
{
return BoundingSphere();

View File

@@ -23,143 +23,66 @@ namespace osg
Object::Object(const Object& obj,const CopyOp& copyop):
Referenced(),
_name(obj._name),
_dataVariance(obj._dataVariance)
_dataVariance(obj._dataVariance),
_userDataContainer(0)
{
if (obj._userDataContainer.valid())
if (obj._userDataContainer)
{
if (copyop.getCopyFlags()&osg::CopyOp::DEEP_COPY_USERDATA)
{
_userDataContainer = obj.getUserDataContainer()->clone(copyop);
setUserDataContainer(osg::clone(obj._userDataContainer,copyop));
}
else
{
_userDataContainer = obj._userDataContainer;
setUserDataContainer(obj._userDataContainer);
}
}
}
Object::~Object()
{
if (_userDataContainer) _userDataContainer->unref();
}
void Object::setThreadSafeRefUnref(bool threadSafe)
{
Referenced::setThreadSafeRefUnref(threadSafe);
if (_userDataContainer.valid()) _userDataContainer->setThreadSafeRefUnref(threadSafe);
if (_userDataContainer) _userDataContainer->setThreadSafeRefUnref(threadSafe);
}
osg::Object* Object::getOrCreateUserDataContainer()
void Object::setUserDataContainer(osg::UserDataContainer* udc)
{
if (!_userDataContainer) _userDataContainer = new UserDataContainer();
return _userDataContainer.get();
if (_userDataContainer == udc) return;
if (_userDataContainer) _userDataContainer->unref();
_userDataContainer = udc;
if (_userDataContainer) _userDataContainer->ref();
}
osg::UserDataContainer* Object::getOrCreateUserDataContainer()
{
if (!_userDataContainer) setUserDataContainer(new DefaultUserDataContainer());
return _userDataContainer;
}
void Object::setUserData(Referenced* obj)
{
if (getUserData()==obj) return;
getOrCreateUserDataContainer()->setUserData(obj);
}
Referenced* Object::getUserData()
{
return _userDataContainer.valid() ? _userDataContainer->getUserData() : 0;
return _userDataContainer ? _userDataContainer->getUserData() : 0;
}
const Referenced* Object::getUserData() const
{
return _userDataContainer.valid() ? _userDataContainer->getUserData() : 0;
}
unsigned int Object::addUserObject(Object* obj)
{
// make sure the UserDataContainer exists
return getOrCreateUserDataContainer()->addUserObject(obj);
}
void Object::removeUserObject(unsigned int i)
{
if (_userDataContainer.valid()) _userDataContainer->removeUserObject(i);
}
void Object::setUserObject(unsigned int i, Object* obj)
{
// make sure the UserDataContainer exists
getOrCreateUserDataContainer()->setUserObject(i,obj);
}
Object* Object::getUserObject(unsigned int i)
{
return _userDataContainer.valid() ? _userDataContainer->getUserObject(i) : 0;
}
const Object* Object::getUserObject(unsigned int i) const
{
return _userDataContainer.valid() ? _userDataContainer->getUserObject(i) : 0;
}
unsigned int Object::getNumUserObjects() const
{
return _userDataContainer.valid() ? _userDataContainer->getNumUserObjects() : 0;
}
unsigned int Object::getUserObjectIndex(const osg::Object* obj, unsigned int startPos) const
{
return _userDataContainer.valid() ? _userDataContainer->getUserObjectIndex(obj, startPos) : 0;
}
unsigned int Object::getUserObjectIndex(const std::string& name, unsigned int startPos) const
{
return _userDataContainer.valid() ? _userDataContainer->getUserObjectIndex(name, startPos) : 0;
}
Object* Object::getUserObject(const std::string& name, unsigned int startPos)
{
return getUserObject(getUserObjectIndex(name, startPos));
}
const Object* Object::getUserObject(const std::string& name, unsigned int startPos) const
{
return getUserObject(getUserObjectIndex(name, startPos));
}
void Object::setDescriptions(const DescriptionList& descriptions)
{
getOrCreateUserDataContainer()->setDescriptions(descriptions);
}
Object::DescriptionList& Object::getDescriptions()
{
return getOrCreateUserDataContainer()->getDescriptions();
}
static OpenThreads::Mutex s_mutex_StaticDescriptionList;
static const Object::DescriptionList& getStaticDescriptionList()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_StaticDescriptionList);
static Object::DescriptionList s_descriptionList;
return s_descriptionList;
}
const Object::DescriptionList& Object::getDescriptions() const
{
if (_userDataContainer.valid()) return _userDataContainer->getDescriptions();
else return getStaticDescriptionList();
}
std::string& Object::getDescription(unsigned int i)
{
return getOrCreateUserDataContainer()->getDescriptions()[i];
}
const std::string& Object::getDescription(unsigned int i) const
{
if (_userDataContainer.valid()) return _userDataContainer->getDescriptions()[i];
else return getStaticDescriptionList()[i];
}
unsigned int Object::getNumDescriptions() const
{
return _userDataContainer.valid() ? _userDataContainer->getDescriptions().size() : 0;
}
void Object::addDescription(const std::string& desc)
{
getOrCreateUserDataContainer()->getDescriptions().push_back(desc);
return _userDataContainer ? _userDataContainer->getUserData() : 0;
}
} // end of namespace osg

View File

@@ -26,12 +26,35 @@ UserDataContainer::UserDataContainer():
UserDataContainer::UserDataContainer(const UserDataContainer& udc, const osg::CopyOp& copyop):
Object(udc, copyop)
{
}
Object* UserDataContainer::getUserObject(const std::string& name, unsigned int startPos)
{
return getUserObject(getUserObjectIndex(name, startPos));
}
const Object* UserDataContainer::getUserObject(const std::string& name, unsigned int startPos) const
{
return getUserObject(getUserObjectIndex(name, startPos));
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// DefaultUserDataContainer
//
DefaultUserDataContainer::DefaultUserDataContainer()
{
}
DefaultUserDataContainer::DefaultUserDataContainer(const DefaultUserDataContainer& udc, const osg::CopyOp& copyop):
UserDataContainer(udc, copyop)
{
_userData = udc._userData;
_descriptionList = udc._descriptionList;
}
void UserDataContainer::setThreadSafeRefUnref(bool threadSafe)
void DefaultUserDataContainer::setThreadSafeRefUnref(bool threadSafe)
{
Object::setThreadSafeRefUnref(threadSafe);
@@ -45,22 +68,22 @@ void UserDataContainer::setThreadSafeRefUnref(bool threadSafe)
}
}
void UserDataContainer::setUserData(Referenced* obj)
void DefaultUserDataContainer::setUserData(Referenced* obj)
{
_userData = obj;
}
Referenced* UserDataContainer::getUserData()
Referenced* DefaultUserDataContainer::getUserData()
{
return _userData.get();
}
const Referenced* UserDataContainer::getUserData() const
const Referenced* DefaultUserDataContainer::getUserData() const
{
return _userData.get();
}
unsigned int UserDataContainer::addUserObject(Object* obj)
unsigned int DefaultUserDataContainer::addUserObject(Object* obj)
{
// make sure that the object isn't already in the container
unsigned int i = getUserObjectIndex(obj);
@@ -78,7 +101,7 @@ unsigned int UserDataContainer::addUserObject(Object* obj)
return pos;
}
void UserDataContainer::removeUserObject(unsigned int i)
void DefaultUserDataContainer::removeUserObject(unsigned int i)
{
if (i<_objectList.size())
{
@@ -86,7 +109,7 @@ void UserDataContainer::removeUserObject(unsigned int i)
}
}
void UserDataContainer::setUserObject(unsigned int i, Object* obj)
void DefaultUserDataContainer::setUserObject(unsigned int i, Object* obj)
{
if (i<_objectList.size())
{
@@ -94,7 +117,7 @@ void UserDataContainer::setUserObject(unsigned int i, Object* obj)
}
}
Object* UserDataContainer::getUserObject(unsigned int i)
Object* DefaultUserDataContainer::getUserObject(unsigned int i)
{
if (i<_objectList.size())
{
@@ -103,7 +126,7 @@ Object* UserDataContainer::getUserObject(unsigned int i)
return 0;
}
const Object* UserDataContainer::getUserObject(unsigned int i) const
const Object* DefaultUserDataContainer::getUserObject(unsigned int i) const
{
if (i<_objectList.size())
{
@@ -112,12 +135,12 @@ const Object* UserDataContainer::getUserObject(unsigned int i) const
return 0;
}
unsigned int UserDataContainer::getNumUserObjects() const
unsigned int DefaultUserDataContainer::getNumUserObjects() const
{
return _objectList.size();
}
unsigned int UserDataContainer::getUserObjectIndex(const osg::Object* obj, unsigned int startPos) const
unsigned int DefaultUserDataContainer::getUserObjectIndex(const osg::Object* obj, unsigned int startPos) const
{
for(unsigned int i = startPos; i < _objectList.size(); ++i)
{
@@ -126,7 +149,7 @@ unsigned int UserDataContainer::getUserObjectIndex(const osg::Object* obj, unsig
return _objectList.size();
}
unsigned int UserDataContainer::getUserObjectIndex(const std::string& name, unsigned int startPos) const
unsigned int DefaultUserDataContainer::getUserObjectIndex(const std::string& name, unsigned int startPos) const
{
for(unsigned int i = startPos; i < _objectList.size(); ++i)
{
@@ -136,21 +159,29 @@ unsigned int UserDataContainer::getUserObjectIndex(const std::string& name, unsi
return _objectList.size();
}
void UserDataContainer::setDescriptions(const DescriptionList& descriptions)
void DefaultUserDataContainer::setDescriptions(const DescriptionList& descriptions)
{
_descriptionList = descriptions;
}
Object::DescriptionList& UserDataContainer::getDescriptions()
UserDataContainer::DescriptionList& DefaultUserDataContainer::getDescriptions()
{
return _descriptionList;
}
const Object::DescriptionList& UserDataContainer::getDescriptions() const
const UserDataContainer::DescriptionList& DefaultUserDataContainer::getDescriptions() const
{
return _descriptionList;
}
unsigned int DefaultUserDataContainer::getNumDescriptions() const
{
return _descriptionList.size();
}
void DefaultUserDataContainer::addDescription(const std::string& desc)
{
_descriptionList.push_back(desc);
}
} // end of namespace osg

View File

@@ -1,4 +1,5 @@
#include <osg/Object>
#include <osg/UserDataContainer>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
@@ -45,6 +46,6 @@ REGISTER_OBJECT_WRAPPER( Object,
UPDATE_TO_VERSION( 77 )
{
REMOVE_SERIALIZER( UserData );
ADD_OBJECT_SERIALIZER( UserDataContainer, osg::Object, NULL );
ADD_OBJECT_SERIALIZER( UserDataContainer, osg::UserDataContainer, NULL );
}
}

View File

@@ -4,12 +4,12 @@
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkUDC_UserData( const osg::UserDataContainer& udc )
static bool checkUDC_UserData( const osg::DefaultUserDataContainer& udc )
{
return dynamic_cast<const osg::Object*>(udc.getUserData())!=0;
}
static bool readUDC_UserData( osgDB::InputStream& is, osg::UserDataContainer& udc )
static bool readUDC_UserData( osgDB::InputStream& is, osg::DefaultUserDataContainer& udc )
{
is >> osgDB::BEGIN_BRACKET;
osg::Object* object = is.readObject();
@@ -18,7 +18,7 @@ static bool readUDC_UserData( osgDB::InputStream& is, osg::UserDataContainer& ud
return true;
}
static bool writeUDC_UserData( osgDB::OutputStream& os, const osg::UserDataContainer& udc )
static bool writeUDC_UserData( osgDB::OutputStream& os, const osg::DefaultUserDataContainer& udc )
{
os << osgDB::BEGIN_BRACKET << std::endl;
os.writeObject(dynamic_cast<const osg::Object*>(udc.getUserData()));
@@ -27,12 +27,12 @@ static bool writeUDC_UserData( osgDB::OutputStream& os, const osg::UserDataConta
}
// _descriptions
static bool checkUDC_Descriptions( const osg::UserDataContainer& udc )
static bool checkUDC_Descriptions( const osg::DefaultUserDataContainer& udc )
{
return udc.getNumDescriptions()>0;
}
static bool readUDC_Descriptions( osgDB::InputStream& is, osg::UserDataContainer& udc )
static bool readUDC_Descriptions( osgDB::InputStream& is, osg::DefaultUserDataContainer& udc )
{
unsigned int size = is.readSize(); is >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
@@ -45,11 +45,11 @@ static bool readUDC_Descriptions( osgDB::InputStream& is, osg::UserDataContainer
return true;
}
static bool writeUDC_Descriptions( osgDB::OutputStream& os, const osg::UserDataContainer& udc )
static bool writeUDC_Descriptions( osgDB::OutputStream& os, const osg::DefaultUserDataContainer& udc )
{
const osg::Object::DescriptionList& slist = udc.getDescriptions();
const osg::UserDataContainer::DescriptionList& slist = udc.getDescriptions();
os.writeSize(slist.size()); os << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::Object::DescriptionList::const_iterator itr=slist.begin();
for ( osg::UserDataContainer::DescriptionList::const_iterator itr=slist.begin();
itr!=slist.end(); ++itr )
{
os.writeWrappedString( *itr );
@@ -60,12 +60,12 @@ static bool writeUDC_Descriptions( osgDB::OutputStream& os, const osg::UserDataC
}
static bool checkUDC_UserObjects( const osg::UserDataContainer& udc )
static bool checkUDC_UserObjects( const osg::DefaultUserDataContainer& udc )
{
return udc.getNumUserObjects()>0;
}
static bool readUDC_UserObjects( osgDB::InputStream& is, osg::UserDataContainer& udc )
static bool readUDC_UserObjects( osgDB::InputStream& is, osg::DefaultUserDataContainer& udc )
{
unsigned int size = is.readSize(); is >> osgDB::BEGIN_BRACKET;
for( unsigned int i=0; i<size; ++i )
@@ -77,7 +77,7 @@ static bool readUDC_UserObjects( osgDB::InputStream& is, osg::UserDataContainer&
return true;
}
static bool writeUDC_UserObjects( osgDB::OutputStream& os, const osg::UserDataContainer& udc )
static bool writeUDC_UserObjects( osgDB::OutputStream& os, const osg::DefaultUserDataContainer& udc )
{
unsigned int numObjects = udc.getNumUserObjects();
os.writeSize(numObjects); os << osgDB::BEGIN_BRACKET << std::endl;
@@ -90,13 +90,25 @@ static bool writeUDC_UserObjects( osgDB::OutputStream& os, const osg::UserDataCo
}
REGISTER_OBJECT_WRAPPER( UserDataContainer,
new osg::UserDataContainer,
osg::UserDataContainer,
"osg::Object osg::UserDataContainer" )
namespace UserDataContainerNamespace
{
ADD_USER_SERIALIZER( UDC_UserData ); // _userData
ADD_USER_SERIALIZER( UDC_Descriptions ); // _descriptions
ADD_USER_SERIALIZER( UDC_UserObjects ); // _userData
REGISTER_OBJECT_WRAPPER( UserDataContainer,
0,
osg::UserDataContainer,
"osg::Object osg::UserDataContainer" )
{
}
}
namespace DefaultUserDataContainerNamespace
{
REGISTER_OBJECT_WRAPPER( DefaultUserDataContainer,
new osg::DefaultUserDataContainer,
osg::DefaultUserDataContainer,
"osg::Object osg::UserDataContainer osg::DefaultUserDataContainer" )
{
ADD_USER_SERIALIZER( UDC_UserData ); // _userData
ADD_USER_SERIALIZER( UDC_Descriptions ); // _descriptions
ADD_USER_SERIALIZER( UDC_UserObjects ); // _userData
}
}