Introduced new user object support into osg::Object that allows assignment of a list of user objects to an osg::Object.

Refactored original UserData and Descriptions strings to be managed alongside the new user object suppport within
a single osg::Object::UserDataContainer.
This commit is contained in:
Robert Osfield
2011-06-02 22:04:08 +00:00
parent 4103319059
commit c703f39459
7 changed files with 535 additions and 46 deletions

View File

@@ -15,11 +15,231 @@
namespace osg
{
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Object
//
Object::Object(const Object& obj,const CopyOp& copyop):
Referenced(),
_name(obj._name),
_dataVariance(obj._dataVariance),
_userData(copyop(obj._userData.get())) {}
_dataVariance(obj._dataVariance)
{
if (copyop.getCopyFlags()&osg::CopyOp::DEEP_COPY_USERDATA)
{
_userDataContainer = new UserDataContainer(*obj._userDataContainer, copyop);
}
else
{
_userDataContainer = obj._userDataContainer;
}
}
void Object::setThreadSafeRefUnref(bool threadSafe)
{
Referenced::setThreadSafeRefUnref(threadSafe);
if (_userDataContainer.valid()) _userDataContainer->setThreadSafeRefUnref(threadSafe);
}
void Object::setUserData(Referenced* obj)
{
getOrCreateUserDataContainer()->_userData = obj;
}
Referenced* Object::getUserData()
{
return _userDataContainer.valid() ? _userDataContainer->_userData.get() : 0;
}
const Referenced* Object::getUserData() const
{
return _userDataContainer.valid() ? _userDataContainer->_userData.get() : 0;
}
void Object::addUserObject(Object* obj)
{
// make sure the UserDataContainer exists
getOrCreateUserDataContainer();
// make sure that the object isn't already in the container
unsigned int i = getUserObjectIndex(obj);
if (i<_userDataContainer->_objectList.size())
{
// object already in container so just return.
return;
}
// object not already on user data container so add it in.
_userDataContainer->_objectList.push_back(obj);
}
void Object::removeUserObject(unsigned int i)
{
if (_userDataContainer.valid() && i<_userDataContainer->_objectList.size())
{
_userDataContainer->_objectList.erase(_userDataContainer->_objectList.begin()+i);
}
}
void Object::setUserObject(unsigned int i, Object* obj)
{
if (_userDataContainer.valid() && i<_userDataContainer->_objectList.size())
{
_userDataContainer->_objectList[i] = obj;
}
}
Object* Object::getUserObject(unsigned int i)
{
if (_userDataContainer.valid() && i<_userDataContainer->_objectList.size())
{
return _userDataContainer->_objectList[i].get();
}
return 0;
}
const Object* Object::getUserObject(unsigned int i) const
{
if (_userDataContainer.valid() && i<_userDataContainer->_objectList.size())
{
return _userDataContainer->_objectList[i].get();
}
return 0;
}
unsigned int Object::getUserObjectIndex(const osg::Object* obj) const
{
if (_userDataContainer.valid())
{
for(unsigned int i = 0; i < _userDataContainer->_objectList.size(); ++i)
{
if (_userDataContainer->_objectList[i]==obj) return i;
}
return _userDataContainer->_objectList.size();
}
return 0;
}
unsigned int Object::getUserObjectIndex(const std::string& name) const
{
if (_userDataContainer.valid())
{
for(unsigned int i = 0; i < _userDataContainer->_objectList.size(); ++i)
{
Object* obj = _userDataContainer->_objectList[i].get();
if (obj && obj->getName()==name) return i;
}
return _userDataContainer->_objectList.size();
}
return 0;
}
Object* Object::getUserObject(const std::string& name)
{
if (_userDataContainer.valid())
{
unsigned int i = getUserObjectIndex(name);
return (i<_userDataContainer->_objectList.size()) ? _userDataContainer->_objectList[i].get() : 0;
}
else
{
return 0;
}
}
const Object* Object::getUserObject(const std::string& name) const
{
if (_userDataContainer.valid())
{
unsigned int i = getUserObjectIndex(name);
return (i<_userDataContainer->_objectList.size()) ? _userDataContainer->_objectList[i].get() : 0;
}
else
{
return 0;
}
}
unsigned int Object::getNumUserObjects() const
{
return _userDataContainer.valid() ? _userDataContainer->_objectList.size() : 0;
}
void Object::setDescriptions(const DescriptionList& descriptions)
{
getOrCreateUserDataContainer()->_descriptionList = descriptions;
}
Object::DescriptionList& Object::getDescriptions()
{
return getOrCreateUserDataContainer()->_descriptionList;
}
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->_descriptionList;
else return getStaticDescriptionList();
}
std::string& Object::getDescription(unsigned int i)
{
return getOrCreateUserDataContainer()->_descriptionList[i];
}
const std::string& Object::getDescription(unsigned int i) const
{
if (_userDataContainer.valid()) return _userDataContainer->_descriptionList[i];
else return getStaticDescriptionList()[i];
}
unsigned int Object::getNumDescriptions() const
{
return _userDataContainer.valid() ? _userDataContainer->_descriptionList.size() : 0;
}
void Object::addDescription(const std::string& desc)
{
getOrCreateUserDataContainer()->_descriptionList.push_back(desc);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// UserDataContainer
//
Object::UserDataContainer::UserDataContainer():
Referenced(true)
{
}
Object::UserDataContainer::UserDataContainer(const UserDataContainer& udc, const osg::CopyOp& copyop):
Referenced(true)
{
_userData = udc._userData;
_descriptionList = udc._descriptionList;
}
void Object::UserDataContainer::setThreadSafeRefUnref(bool threadSafe)
{
Referenced::setThreadSafeRefUnref(threadSafe);
if (_userData.valid()) _userData->setThreadSafeRefUnref(threadSafe);
for(ObjectList::iterator itr = _objectList.begin();
itr != _objectList.end();
++itr)
{
(*itr)->setThreadSafeRefUnref(threadSafe);
}
}
} // end of namespace osg