Added ability to subclass from osg::Object to provide custom user data functionality. A new UserDataContainer provides the
default implementation of the user data functionality.
This commit is contained in:
@@ -21,10 +21,53 @@
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/WriteFile>
|
||||
|
||||
#include <osg/io_utils>
|
||||
#include <osg/ArgumentParser>
|
||||
#include <osg/UserDataContainer>
|
||||
|
||||
#include <osg/ValueObject>
|
||||
|
||||
namespace MyNamespace
|
||||
{
|
||||
|
||||
/** Provide an simple example of customizing the default UserDataContainer.*/
|
||||
class OSG_EXPORT MyUserDataContainer : public osg::UserDataContainer
|
||||
{
|
||||
public:
|
||||
MyUserDataContainer() {}
|
||||
MyUserDataContainer(const MyUserDataContainer& udc, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
|
||||
UserDataContainer(udc, copyop) {}
|
||||
|
||||
META_Object(MyNamespace, MyUserDataContainer)
|
||||
|
||||
virtual Object* getUserObject(unsigned int i)
|
||||
{
|
||||
OSG_NOTICE<<"MyUserDataContainer::getUserObject("<<i<<")"<<std::endl;
|
||||
return osg::UserDataContainer::getUserObject(i);
|
||||
}
|
||||
|
||||
virtual const Object* getUserObject(unsigned int i) const
|
||||
{
|
||||
OSG_NOTICE<<"MyUserDataContainer::getUserObject("<<i<<") const"<<std::endl;
|
||||
return osg::UserDataContainer::getUserObject(i);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
virtual ~MyUserDataContainer() {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/** Provide basic example of providing serialization support for the MyUserDataContainer.*/
|
||||
REGISTER_OBJECT_WRAPPER( MyUserDataContainer,
|
||||
new MyNamespace::MyUserDataContainer,
|
||||
MyNamespace::MyUserDataContainer,
|
||||
"osg::Object osg::UserDataContainer MyNamespace::MyUserDataContainer" )
|
||||
{
|
||||
}
|
||||
|
||||
class MyGetValueVisitor : public osg::ValueObject::GetValueVisitor
|
||||
{
|
||||
public:
|
||||
@@ -134,8 +177,15 @@ void testResults(osg::Node* node)
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
osg::ArgumentParser arguments(&argc, argv);
|
||||
|
||||
osg::ref_ptr<osg::Group> node = new osg::Group;
|
||||
|
||||
if (arguments.read("--MyUserDataContainer") || arguments.read("--mydc"))
|
||||
{
|
||||
node->setUserDataContainer(new MyNamespace::MyUserDataContainer);
|
||||
}
|
||||
|
||||
int i = 10;
|
||||
node->setUserValue("Int value",i);
|
||||
|
||||
|
||||
@@ -188,50 +188,66 @@ class OSG_EXPORT Object : public Referenced
|
||||
virtual void computeDataVariance() {}
|
||||
|
||||
|
||||
/** set the UserDataContainer object.*/
|
||||
void setUserDataContainer(osg::Object* udc) { _userDataContainer = udc; }
|
||||
|
||||
/** get the UserDataContainer attached to this object.*/
|
||||
osg::Object* getUserDataContainer() { return _userDataContainer.get(); }
|
||||
|
||||
/** get the const UserDataContainer attached to this object.*/
|
||||
const osg::Object* getUserDataContainer() const { return _userDataContainer.get(); }
|
||||
|
||||
/** Convinience method that returns the UserDataContainer, and if one doesn't already exist creates and assigns
|
||||
* one to the Object and then return this new UserDataContainer.*/
|
||||
osg::Object* getOrCreateUserDataContainer();
|
||||
|
||||
|
||||
/**
|
||||
* Set user data, data must be subclassed from Referenced to allow
|
||||
* automatic memory handling. If your own data isn't directly
|
||||
* subclassed from Referenced then create an adapter object
|
||||
* which points to your own object and handles the memory addressing.
|
||||
*/
|
||||
void setUserData(Referenced* obj);
|
||||
virtual void setUserData(Referenced* obj);
|
||||
|
||||
/** Get user data.*/
|
||||
Referenced* getUserData();
|
||||
virtual Referenced* getUserData();
|
||||
|
||||
/** Get const user data.*/
|
||||
const Referenced* getUserData() const;
|
||||
|
||||
virtual const Referenced* getUserData() const;
|
||||
|
||||
/** Add user data object. Returns the index position of object added. */
|
||||
unsigned int addUserObject(Object* obj);
|
||||
virtual unsigned int addUserObject(Object* obj);
|
||||
|
||||
/** Add element to list of user data objects.*/
|
||||
void setUserObject(unsigned int i, Object* obj);
|
||||
virtual void setUserObject(unsigned int i, Object* obj);
|
||||
|
||||
/** Remove element from the list of user data objects.*/
|
||||
void removeUserObject(unsigned int i);
|
||||
virtual void removeUserObject(unsigned int i);
|
||||
|
||||
/** Get the index position of specified user data object.*/
|
||||
unsigned int getUserObjectIndex(const osg::Object* obj, unsigned int startPos=0) const;
|
||||
|
||||
/** Get the index position of first user data object that matches specified name.*/
|
||||
unsigned int getUserObjectIndex(const std::string& name, unsigned int startPos=0) const;
|
||||
|
||||
/** Get user data object as specified index position. */
|
||||
Object* getUserObject(unsigned int i);
|
||||
virtual Object* getUserObject(unsigned int i);
|
||||
|
||||
/** Get const user data object as specified index position. */
|
||||
const Object* getUserObject(unsigned int i) const;
|
||||
virtual const Object* getUserObject(unsigned int i) const;
|
||||
|
||||
/** Get number of user objects assigned to this object.*/
|
||||
virtual unsigned int getNumUserObjects() const;
|
||||
|
||||
/** Get the index position of specified user data object.*/
|
||||
virtual unsigned int getUserObjectIndex(const osg::Object* obj, unsigned int startPos=0) const;
|
||||
|
||||
/** Get the index position of first user data object that matches specified name.*/
|
||||
virtual unsigned int getUserObjectIndex(const std::string& name, unsigned int startPos=0) const;
|
||||
|
||||
|
||||
/** Get first user data object with specified name. */
|
||||
Object* getUserObject(const std::string& name, unsigned int startPos=0);
|
||||
|
||||
/** Get first const user data object with specified name. */
|
||||
const Object* getUserObject(const std::string& name, unsigned int startPos=0) const;
|
||||
|
||||
/** Get number of user objects assigned to this object.*/
|
||||
unsigned int getNumUserObjects() const;
|
||||
|
||||
/** Convinience method that casts the named UserObject to osg::TemplateValueObject<T> and gets the value.
|
||||
* To use this template method you need to include the osg/ValueObject header.*/
|
||||
@@ -245,18 +261,18 @@ class OSG_EXPORT Object : public Referenced
|
||||
void setUserValue(const std::string& name, const T& value);
|
||||
|
||||
|
||||
|
||||
/** A vector of std::string's which are used to describe the object.*/
|
||||
typedef std::vector<std::string> DescriptionList;
|
||||
|
||||
/** Set the list of string descriptions.*/
|
||||
void setDescriptions(const DescriptionList& descriptions);
|
||||
virtual void setDescriptions(const DescriptionList& descriptions);
|
||||
|
||||
/** Get the description list of the node.*/
|
||||
DescriptionList& getDescriptions();
|
||||
virtual DescriptionList& getDescriptions();
|
||||
|
||||
/** Get the const description list of the const node.*/
|
||||
const DescriptionList& getDescriptions() const;
|
||||
virtual const DescriptionList& getDescriptions() const;
|
||||
|
||||
|
||||
/** Get a single const description of the const node.*/
|
||||
const std::string& getDescription(unsigned int i) const;
|
||||
@@ -270,6 +286,7 @@ class OSG_EXPORT Object : public Referenced
|
||||
/** Add a description string to the node.*/
|
||||
void addDescription(const std::string& desc);
|
||||
|
||||
|
||||
|
||||
/** Resize any per context GLObject buffers to specified size. */
|
||||
virtual void resizeGLObjectBuffers(unsigned int /*maxSize*/) {}
|
||||
@@ -294,34 +311,7 @@ class OSG_EXPORT Object : public Referenced
|
||||
std::string _name;
|
||||
DataVariance _dataVariance;
|
||||
|
||||
/** Internal structure for storing all user data.*/
|
||||
class OSG_EXPORT UserDataContainer : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
UserDataContainer();
|
||||
UserDataContainer(const UserDataContainer& udc, const osg::CopyOp& copyop=CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual void setThreadSafeRefUnref(bool threadSafe);
|
||||
|
||||
typedef std::vector< osg::ref_ptr<osg::Object> > ObjectList;
|
||||
|
||||
ref_ptr<Referenced> _userData;
|
||||
DescriptionList _descriptionList;
|
||||
ObjectList _objectList;
|
||||
|
||||
protected:
|
||||
virtual ~UserDataContainer() {}
|
||||
};
|
||||
|
||||
ref_ptr<UserDataContainer> _userDataContainer;
|
||||
|
||||
/** Convinience method that returns the UserDataContainer, and if one doesn't already exist creates and assigns
|
||||
* one to the Object and then return this new UserDataContainer.*/
|
||||
UserDataContainer* getOrCreateUserDataContainer()
|
||||
{
|
||||
if (!_userDataContainer.valid()) _userDataContainer = new UserDataContainer;
|
||||
return _userDataContainer.get();
|
||||
}
|
||||
ref_ptr<osg::Object> _userDataContainer;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
99
include/osg/UserDataContainer
Normal file
99
include/osg/UserDataContainer
Normal file
@@ -0,0 +1,99 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSG_USERDATACONTAINER
|
||||
#define OSG_USERDATACONTAINER 1
|
||||
|
||||
#include <osg/Object>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace osg {
|
||||
|
||||
/** Internal structure for storing all user data.*/
|
||||
class OSG_EXPORT UserDataContainer : public osg::Object
|
||||
{
|
||||
public:
|
||||
UserDataContainer();
|
||||
UserDataContainer(const UserDataContainer& udc, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(osg, UserDataContainer)
|
||||
|
||||
|
||||
virtual void setThreadSafeRefUnref(bool threadSafe);
|
||||
|
||||
/**
|
||||
* Set user data, data must be subclassed from Referenced to allow
|
||||
* automatic memory handling. If your own data isn't directly
|
||||
* subclassed from Referenced then create an adapter object
|
||||
* which points to your own object and handles the memory addressing.
|
||||
*/
|
||||
virtual void setUserData(Referenced* obj);
|
||||
|
||||
/** Get user data.*/
|
||||
virtual Referenced* getUserData();
|
||||
|
||||
/** Get const user data.*/
|
||||
virtual const Referenced* getUserData() const;
|
||||
|
||||
/** Add user data object. Returns the index position of object added. */
|
||||
virtual unsigned int addUserObject(Object* obj);
|
||||
|
||||
/** Add element to list of user data objects.*/
|
||||
virtual void setUserObject(unsigned int i, Object* obj);
|
||||
|
||||
/** Remove element from the list of user data objects.*/
|
||||
virtual void removeUserObject(unsigned int i);
|
||||
|
||||
|
||||
/** Get user data object as specified index position. */
|
||||
virtual Object* getUserObject(unsigned int i);
|
||||
|
||||
/** Get const user data object as specified index position. */
|
||||
virtual const Object* getUserObject(unsigned int i) const;
|
||||
|
||||
/** Get number of user objects assigned to this object.*/
|
||||
virtual unsigned int getNumUserObjects() const;
|
||||
|
||||
/** Get the index position of specified user data object.*/
|
||||
virtual unsigned int getUserObjectIndex(const osg::Object* obj, unsigned int startPos=0) const;
|
||||
|
||||
/** Get the index position of first user data object that matches specified name.*/
|
||||
virtual unsigned int getUserObjectIndex(const std::string& name, unsigned int startPos=0) const;
|
||||
|
||||
|
||||
/** Set the list of string descriptions.*/
|
||||
virtual void setDescriptions(const DescriptionList& descriptions);
|
||||
|
||||
/** Get the description list of the node.*/
|
||||
virtual DescriptionList& getDescriptions();
|
||||
|
||||
/** Get the const description list of the const node.*/
|
||||
virtual const DescriptionList& getDescriptions() const;
|
||||
|
||||
|
||||
protected:
|
||||
virtual ~UserDataContainer() {}
|
||||
|
||||
typedef std::vector< osg::ref_ptr<osg::Object> > ObjectList;
|
||||
|
||||
ref_ptr<Referenced> _userData;
|
||||
DescriptionList _descriptionList;
|
||||
ObjectList _objectList;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -172,6 +172,8 @@ SET(TARGET_H
|
||||
${HEADER_PATH}/TriangleFunctor
|
||||
${HEADER_PATH}/TriangleIndexFunctor
|
||||
${HEADER_PATH}/Uniform
|
||||
${HEADER_PATH}/UserDataContainer
|
||||
${HEADER_PATH}/ValueObject
|
||||
${HEADER_PATH}/Vec2
|
||||
${HEADER_PATH}/Vec2b
|
||||
${HEADER_PATH}/Vec2d
|
||||
@@ -337,6 +339,7 @@ SET(TARGET_SRC
|
||||
TransferFunction.cpp
|
||||
Transform.cpp
|
||||
Uniform.cpp
|
||||
UserDataContainer.cpp
|
||||
Version.cpp
|
||||
VertexProgram.cpp
|
||||
View.cpp
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
#include <osg/Object>
|
||||
#include <osg/UserDataContainer>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
@@ -28,7 +29,7 @@ Object::Object(const Object& obj,const CopyOp& copyop):
|
||||
{
|
||||
if (copyop.getCopyFlags()&osg::CopyOp::DEEP_COPY_USERDATA)
|
||||
{
|
||||
_userDataContainer = new UserDataContainer(*obj._userDataContainer, copyop);
|
||||
_userDataContainer = obj.getUserDataContainer()->clone(copyop);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -43,146 +44,87 @@ void Object::setThreadSafeRefUnref(bool threadSafe)
|
||||
if (_userDataContainer.valid()) _userDataContainer->setThreadSafeRefUnref(threadSafe);
|
||||
}
|
||||
|
||||
osg::Object* Object::getOrCreateUserDataContainer()
|
||||
{
|
||||
if (!_userDataContainer) _userDataContainer = new UserDataContainer();
|
||||
return _userDataContainer.get();
|
||||
}
|
||||
|
||||
void Object::setUserData(Referenced* obj)
|
||||
{
|
||||
getOrCreateUserDataContainer()->_userData = obj;
|
||||
getOrCreateUserDataContainer()->setUserData(obj);
|
||||
}
|
||||
|
||||
Referenced* Object::getUserData()
|
||||
{
|
||||
return _userDataContainer.valid() ? _userDataContainer->_userData.get() : 0;
|
||||
return _userDataContainer.valid() ? _userDataContainer->getUserData() : 0;
|
||||
}
|
||||
|
||||
const Referenced* Object::getUserData() const
|
||||
{
|
||||
return _userDataContainer.valid() ? _userDataContainer->_userData.get() : 0;
|
||||
return _userDataContainer.valid() ? _userDataContainer->getUserData() : 0;
|
||||
}
|
||||
|
||||
unsigned int 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 i;
|
||||
}
|
||||
|
||||
unsigned int pos = _userDataContainer->_objectList.size();
|
||||
|
||||
// object not already on user data container so add it in.
|
||||
_userDataContainer->_objectList.push_back(obj);
|
||||
|
||||
return pos;
|
||||
return getOrCreateUserDataContainer()->addUserObject(obj);
|
||||
}
|
||||
|
||||
void Object::removeUserObject(unsigned int i)
|
||||
{
|
||||
if (_userDataContainer.valid() && i<_userDataContainer->_objectList.size())
|
||||
{
|
||||
_userDataContainer->_objectList.erase(_userDataContainer->_objectList.begin()+i);
|
||||
}
|
||||
if (_userDataContainer.valid()) _userDataContainer->removeUserObject(i);
|
||||
}
|
||||
|
||||
void Object::setUserObject(unsigned int i, Object* obj)
|
||||
{
|
||||
// make sure the UserDataContainer exists
|
||||
getOrCreateUserDataContainer();
|
||||
|
||||
if (i<_userDataContainer->_objectList.size())
|
||||
{
|
||||
_userDataContainer->_objectList[i] = obj;
|
||||
}
|
||||
// make sure the UserDataContainer exists
|
||||
getOrCreateUserDataContainer()->setUserObject(i,obj);
|
||||
}
|
||||
|
||||
Object* Object::getUserObject(unsigned int i)
|
||||
{
|
||||
if (_userDataContainer.valid() && i<_userDataContainer->_objectList.size())
|
||||
{
|
||||
return _userDataContainer->_objectList[i].get();
|
||||
}
|
||||
return 0;
|
||||
return _userDataContainer.valid() ? _userDataContainer->getUserObject(i) : 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, unsigned int startPos) const
|
||||
{
|
||||
if (_userDataContainer.valid())
|
||||
{
|
||||
for(unsigned int i = startPos; 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, unsigned int startPos) const
|
||||
{
|
||||
if (_userDataContainer.valid())
|
||||
{
|
||||
for(unsigned int i = startPos; 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, unsigned int startPos)
|
||||
{
|
||||
if (_userDataContainer.valid())
|
||||
{
|
||||
unsigned int i = getUserObjectIndex(name, startPos);
|
||||
return (i<_userDataContainer->_objectList.size()) ? _userDataContainer->_objectList[i].get() : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const Object* Object::getUserObject(const std::string& name, unsigned int startPos) const
|
||||
{
|
||||
if (_userDataContainer.valid())
|
||||
{
|
||||
unsigned int i = getUserObjectIndex(name, startPos);
|
||||
return (i<_userDataContainer->_objectList.size()) ? _userDataContainer->_objectList[i].get() : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return _userDataContainer.valid() ? _userDataContainer->getUserObject(i) : 0;
|
||||
}
|
||||
|
||||
unsigned int Object::getNumUserObjects() const
|
||||
{
|
||||
return _userDataContainer.valid() ? _userDataContainer->_objectList.size() : 0;
|
||||
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()->_descriptionList = descriptions;
|
||||
getOrCreateUserDataContainer()->setDescriptions(descriptions);
|
||||
}
|
||||
|
||||
Object::DescriptionList& Object::getDescriptions()
|
||||
{
|
||||
return getOrCreateUserDataContainer()->_descriptionList;
|
||||
return getOrCreateUserDataContainer()->getDescriptions();
|
||||
}
|
||||
|
||||
static OpenThreads::Mutex s_mutex_StaticDescriptionList;
|
||||
@@ -195,61 +137,29 @@ static const Object::DescriptionList& getStaticDescriptionList()
|
||||
|
||||
const Object::DescriptionList& Object::getDescriptions() const
|
||||
{
|
||||
if (_userDataContainer.valid()) return _userDataContainer->_descriptionList;
|
||||
if (_userDataContainer.valid()) return _userDataContainer->getDescriptions();
|
||||
else return getStaticDescriptionList();
|
||||
}
|
||||
|
||||
std::string& Object::getDescription(unsigned int i)
|
||||
{
|
||||
return getOrCreateUserDataContainer()->_descriptionList[i];
|
||||
return getOrCreateUserDataContainer()->getDescriptions()[i];
|
||||
}
|
||||
|
||||
const std::string& Object::getDescription(unsigned int i) const
|
||||
{
|
||||
if (_userDataContainer.valid()) return _userDataContainer->_descriptionList[i];
|
||||
if (_userDataContainer.valid()) return _userDataContainer->getDescriptions()[i];
|
||||
else return getStaticDescriptionList()[i];
|
||||
}
|
||||
|
||||
unsigned int Object::getNumDescriptions() const
|
||||
{
|
||||
return _userDataContainer.valid() ? _userDataContainer->_descriptionList.size() : 0;
|
||||
return _userDataContainer.valid() ? _userDataContainer->getDescriptions().size() : 0;
|
||||
}
|
||||
|
||||
void Object::addDescription(const std::string& desc)
|
||||
{
|
||||
getOrCreateUserDataContainer()->_descriptionList.push_back(desc);
|
||||
getOrCreateUserDataContainer()->getDescriptions().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
|
||||
|
||||
156
src/osg/UserDataContainer.cpp
Normal file
156
src/osg/UserDataContainer.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
#include <osg/UserDataContainer>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// UserDataContainer
|
||||
//
|
||||
UserDataContainer::UserDataContainer():
|
||||
Object(true)
|
||||
{
|
||||
}
|
||||
|
||||
UserDataContainer::UserDataContainer(const UserDataContainer& udc, const osg::CopyOp& copyop):
|
||||
Object(udc, copyop)
|
||||
{
|
||||
_userData = udc._userData;
|
||||
_descriptionList = udc._descriptionList;
|
||||
}
|
||||
|
||||
void UserDataContainer::setThreadSafeRefUnref(bool threadSafe)
|
||||
{
|
||||
Object::setThreadSafeRefUnref(threadSafe);
|
||||
|
||||
if (_userData.valid()) _userData->setThreadSafeRefUnref(threadSafe);
|
||||
|
||||
for(ObjectList::iterator itr = _objectList.begin();
|
||||
itr != _objectList.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->setThreadSafeRefUnref(threadSafe);
|
||||
}
|
||||
}
|
||||
|
||||
void UserDataContainer::setUserData(Referenced* obj)
|
||||
{
|
||||
_userData = obj;
|
||||
}
|
||||
|
||||
Referenced* UserDataContainer::getUserData()
|
||||
{
|
||||
return _userData.get();
|
||||
}
|
||||
|
||||
const Referenced* UserDataContainer::getUserData() const
|
||||
{
|
||||
return _userData.get();
|
||||
}
|
||||
|
||||
unsigned int UserDataContainer::addUserObject(Object* obj)
|
||||
{
|
||||
// make sure that the object isn't already in the container
|
||||
unsigned int i = getUserObjectIndex(obj);
|
||||
if (i<_objectList.size())
|
||||
{
|
||||
// object already in container so just return.
|
||||
return i;
|
||||
}
|
||||
|
||||
unsigned int pos = _objectList.size();
|
||||
|
||||
// object not already on user data container so add it in.
|
||||
_objectList.push_back(obj);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void UserDataContainer::removeUserObject(unsigned int i)
|
||||
{
|
||||
if (i<_objectList.size())
|
||||
{
|
||||
_objectList.erase(_objectList.begin()+i);
|
||||
}
|
||||
}
|
||||
|
||||
void UserDataContainer::setUserObject(unsigned int i, Object* obj)
|
||||
{
|
||||
if (i<_objectList.size())
|
||||
{
|
||||
_objectList[i] = obj;
|
||||
}
|
||||
}
|
||||
|
||||
Object* UserDataContainer::getUserObject(unsigned int i)
|
||||
{
|
||||
if (i<_objectList.size())
|
||||
{
|
||||
return _objectList[i].get();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Object* UserDataContainer::getUserObject(unsigned int i) const
|
||||
{
|
||||
if (i<_objectList.size())
|
||||
{
|
||||
return _objectList[i].get();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int UserDataContainer::getNumUserObjects() const
|
||||
{
|
||||
return _objectList.size();
|
||||
}
|
||||
|
||||
unsigned int UserDataContainer::getUserObjectIndex(const osg::Object* obj, unsigned int startPos) const
|
||||
{
|
||||
for(unsigned int i = startPos; i < _objectList.size(); ++i)
|
||||
{
|
||||
if (_objectList[i]==obj) return i;
|
||||
}
|
||||
return _objectList.size();
|
||||
}
|
||||
|
||||
unsigned int UserDataContainer::getUserObjectIndex(const std::string& name, unsigned int startPos) const
|
||||
{
|
||||
for(unsigned int i = startPos; i < _objectList.size(); ++i)
|
||||
{
|
||||
Object* obj = _objectList[i].get();
|
||||
if (obj && obj->getName()==name) return i;
|
||||
}
|
||||
return _objectList.size();
|
||||
}
|
||||
|
||||
void UserDataContainer::setDescriptions(const DescriptionList& descriptions)
|
||||
{
|
||||
_descriptionList = descriptions;
|
||||
}
|
||||
|
||||
Object::DescriptionList& UserDataContainer::getDescriptions()
|
||||
{
|
||||
return _descriptionList;
|
||||
}
|
||||
|
||||
const Object::DescriptionList& UserDataContainer::getDescriptions() const
|
||||
{
|
||||
return _descriptionList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // end of namespace osg
|
||||
@@ -77,6 +77,12 @@ REGISTER_OBJECT_WRAPPER( Node,
|
||||
ADD_OBJECT_SERIALIZER( CullCallback, osg::NodeCallback, NULL ); // _cullCallback
|
||||
ADD_BOOL_SERIALIZER( CullingActive, true ); // _cullingActive
|
||||
ADD_HEXINT_SERIALIZER( NodeMask, 0xffffffff ); // _nodeMask
|
||||
ADD_USER_SERIALIZER( Descriptions ); // _descriptions
|
||||
|
||||
ADD_USER_SERIALIZER( Descriptions ); // _descriptions, deprecated
|
||||
UPDATE_TO_VERSION( 77 )
|
||||
{
|
||||
REMOVE_SERIALIZER( Descriptions );
|
||||
}
|
||||
|
||||
ADD_OBJECT_SERIALIZER( StateSet, osg::StateSet, NULL ); // _stateset
|
||||
}
|
||||
|
||||
@@ -27,35 +27,6 @@ static bool writeUserData( osgDB::OutputStream& os, const osg::Object& obj )
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool checkUserObjects( const osg::Object& obj )
|
||||
{
|
||||
return obj.getNumUserObjects()>0;
|
||||
}
|
||||
|
||||
static bool readUserObjects( osgDB::InputStream& is, osg::Object& obj )
|
||||
{
|
||||
unsigned int size = is.readSize(); is >> osgDB::BEGIN_BRACKET;
|
||||
for( unsigned int i=0; i<size; ++i )
|
||||
{
|
||||
osg::Object* read_object = is.readObject();
|
||||
if (read_object) obj.addUserObject( read_object );
|
||||
}
|
||||
is >> osgDB::END_BRACKET;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool writeUserObjects( osgDB::OutputStream& os, const osg::Object& obj )
|
||||
{
|
||||
unsigned int numObjects = obj.getNumUserObjects();
|
||||
os.writeSize(numObjects); os << osgDB::BEGIN_BRACKET << std::endl;
|
||||
for ( unsigned int i=0; i<numObjects; ++i )
|
||||
{
|
||||
os << obj.getUserObject(i);
|
||||
}
|
||||
os << osgDB::END_BRACKET << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
REGISTER_OBJECT_WRAPPER( Object,
|
||||
/*new osg::Object*/NULL,
|
||||
osg::Object,
|
||||
@@ -69,10 +40,11 @@ REGISTER_OBJECT_WRAPPER( Object,
|
||||
ADD_ENUM_VALUE( UNSPECIFIED );
|
||||
END_ENUM_SERIALIZER(); // _dataVariance
|
||||
|
||||
ADD_USER_SERIALIZER( UserData ); // _userData
|
||||
ADD_USER_SERIALIZER( UserData ); // _userData, deprecated
|
||||
|
||||
UPDATE_TO_VERSION( 77 )
|
||||
{
|
||||
ADD_USER_SERIALIZER( UserObjects ); // _userData
|
||||
REMOVE_SERIALIZER( UserData );
|
||||
ADD_OBJECT_SERIALIZER( UserDataContainer, osg::Object, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
102
src/osgWrappers/serializers/osg/UserDataContainer.cpp
Normal file
102
src/osgWrappers/serializers/osg/UserDataContainer.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#include <osg/UserDataContainer>
|
||||
|
||||
#include <osgDB/ObjectWrapper>
|
||||
#include <osgDB/InputStream>
|
||||
#include <osgDB/OutputStream>
|
||||
|
||||
static bool checkUDC_UserData( const osg::UserDataContainer& udc )
|
||||
{
|
||||
return dynamic_cast<const osg::Object*>(udc.getUserData())!=0;
|
||||
}
|
||||
|
||||
static bool readUDC_UserData( osgDB::InputStream& is, osg::UserDataContainer& udc )
|
||||
{
|
||||
is >> osgDB::BEGIN_BRACKET;
|
||||
osg::Object* object = is.readObject();
|
||||
if(object) udc.setUserData(object);
|
||||
is >> osgDB::END_BRACKET;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool writeUDC_UserData( osgDB::OutputStream& os, const osg::UserDataContainer& udc )
|
||||
{
|
||||
os << osgDB::BEGIN_BRACKET << std::endl;
|
||||
os.writeObject(dynamic_cast<const osg::Object*>(udc.getUserData()));
|
||||
os << osgDB::END_BRACKET << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
// _descriptions
|
||||
static bool checkUDC_Descriptions( const osg::UserDataContainer& udc )
|
||||
{
|
||||
return udc.getNumDescriptions()>0;
|
||||
}
|
||||
|
||||
static bool readUDC_Descriptions( osgDB::InputStream& is, osg::UserDataContainer& udc )
|
||||
{
|
||||
unsigned int size = is.readSize(); is >> osgDB::BEGIN_BRACKET;
|
||||
for ( unsigned int i=0; i<size; ++i )
|
||||
{
|
||||
std::string value;
|
||||
is.readWrappedString( value );
|
||||
udc.addDescription( value );
|
||||
}
|
||||
is >> osgDB::END_BRACKET;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool writeUDC_Descriptions( osgDB::OutputStream& os, const osg::UserDataContainer& udc )
|
||||
{
|
||||
const osg::Object::DescriptionList& slist = udc.getDescriptions();
|
||||
os.writeSize(slist.size()); os << osgDB::BEGIN_BRACKET << std::endl;
|
||||
for ( osg::Object::DescriptionList::const_iterator itr=slist.begin();
|
||||
itr!=slist.end(); ++itr )
|
||||
{
|
||||
os.writeWrappedString( *itr );
|
||||
os << std::endl;
|
||||
}
|
||||
os << osgDB::END_BRACKET << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool checkUDC_UserObjects( const osg::UserDataContainer& udc )
|
||||
{
|
||||
return udc.getNumUserObjects()>0;
|
||||
}
|
||||
|
||||
static bool readUDC_UserObjects( osgDB::InputStream& is, osg::UserDataContainer& udc )
|
||||
{
|
||||
unsigned int size = is.readSize(); is >> osgDB::BEGIN_BRACKET;
|
||||
for( unsigned int i=0; i<size; ++i )
|
||||
{
|
||||
osg::Object* read_object = is.readObject();
|
||||
if (read_object) udc.addUserObject( read_object );
|
||||
}
|
||||
is >> osgDB::END_BRACKET;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool writeUDC_UserObjects( osgDB::OutputStream& os, const osg::UserDataContainer& udc )
|
||||
{
|
||||
unsigned int numObjects = udc.getNumUserObjects();
|
||||
os.writeSize(numObjects); os << osgDB::BEGIN_BRACKET << std::endl;
|
||||
for ( unsigned int i=0; i<numObjects; ++i )
|
||||
{
|
||||
os << udc.getUserObject(i);
|
||||
}
|
||||
os << osgDB::END_BRACKET << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
REGISTER_OBJECT_WRAPPER( UserDataContainer,
|
||||
new osg::UserDataContainer,
|
||||
osg::UserDataContainer,
|
||||
"osg::Object osg::UserDataContainer" )
|
||||
{
|
||||
ADD_USER_SERIALIZER( UDC_UserData ); // _userData
|
||||
ADD_USER_SERIALIZER( UDC_Descriptions ); // _descriptions
|
||||
ADD_USER_SERIALIZER( UDC_UserObjects ); // _userData
|
||||
}
|
||||
Reference in New Issue
Block a user