Improved the speed of the ValueObject get/setting by utilizing typeid() and static_cast<> in place of original dynamic_cast<>'s
This commit is contained in:
parent
d8d37e3da7
commit
b4eb8d4597
@ -170,6 +170,14 @@ class OSG_EXPORT Object : public Referenced
|
||||
* Equivalent to dynamic_cast<const CallbackObject*>(this).*/
|
||||
virtual const CallbackObject* asCallbackObject() const { return 0; }
|
||||
|
||||
/** Convert 'this' into a UserDataContainer pointer if Object is a UserDataContainer, otherwise return 0.
|
||||
* Equivalent to dynamic_cast<UserDataContainer*>(this).*/
|
||||
virtual UserDataContainer* asUserDataContainer() { return 0; }
|
||||
|
||||
/** convert 'const this' into a const UserDataContainer pointer if Object is a UserDataContainer, otherwise return 0.
|
||||
* Equivalent to dynamic_cast<const UserDataContainer*>(this).*/
|
||||
virtual const UserDataContainer* asUserDataContainer() const { return 0; }
|
||||
|
||||
|
||||
/** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
|
||||
virtual void setThreadSafeRefUnref(bool threadSafe);
|
||||
@ -366,7 +374,6 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -39,6 +39,14 @@ class OSG_EXPORT UserDataContainer : public osg::Object
|
||||
by derived classes.*/
|
||||
virtual const char* className() const { return "UserDataContainer"; }
|
||||
|
||||
/** Convert 'this' into a UserDataContainer pointer if Object is a UserDataContainer, otherwise return 0.
|
||||
* Equivalent to dynamic_cast<UserDataContainer*>(this).*/
|
||||
virtual UserDataContainer* asUserDataContainer() { return this; }
|
||||
|
||||
/** convert 'const this' into a const UserDataContainer pointer if Object is a UserDataContainer, otherwise return 0.
|
||||
* Equivalent to dynamic_cast<const UserDataContainer*>(this).*/
|
||||
virtual const UserDataContainer* asUserDataContainer() const { return this; }
|
||||
|
||||
/**
|
||||
* Set user data, data must be subclassed from Referenced to allow
|
||||
* automatic memory handling. If your own data isn't directly
|
||||
@ -209,7 +217,6 @@ inline const Object* getUserObject(const osg::Object* object, const std::string&
|
||||
return udc ? udc->getUserObject(name) : 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <osg/BoundingBox>
|
||||
#include <osg/BoundingSphere>
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
namespace osg {
|
||||
|
||||
// forward declare core OSG math classes
|
||||
@ -126,6 +128,10 @@ class TemplateValueObject : public ValueObject
|
||||
ValueObject(),
|
||||
_value() {}
|
||||
|
||||
TemplateValueObject(const T& value) :
|
||||
ValueObject(),
|
||||
_value(value) {}
|
||||
|
||||
TemplateValueObject(const std::string& name, const T& value) :
|
||||
ValueObject(name),
|
||||
_value(value) {}
|
||||
@ -189,12 +195,15 @@ bool osg::Object::getUserValue(const std::string& name, T& value) const
|
||||
{
|
||||
typedef TemplateValueObject<T> UserValueObject;
|
||||
|
||||
const osg::UserDataContainer* udc = dynamic_cast<const osg::UserDataContainer*>(this);
|
||||
const osg::UserDataContainer* udc = asUserDataContainer();
|
||||
if (!udc) udc = _userDataContainer;
|
||||
|
||||
const UserValueObject* uvo = udc ? dynamic_cast<const UserValueObject*>(udc->getUserObject(name)) : 0;
|
||||
if (uvo)
|
||||
if (!udc) return false;
|
||||
|
||||
const Object* obj = udc->getUserObject(name);
|
||||
if (obj && typeid(*obj)==typeid(UserValueObject))
|
||||
{
|
||||
const UserValueObject* uvo = static_cast<const UserValueObject*>(obj);
|
||||
value = uvo->getValue();
|
||||
return true;
|
||||
}
|
||||
@ -210,7 +219,7 @@ void osg::Object::setUserValue(const std::string& name, const T& value)
|
||||
{
|
||||
typedef TemplateValueObject<T> UserValueObject;
|
||||
|
||||
osg::UserDataContainer* udc = dynamic_cast<osg::UserDataContainer*>(this);
|
||||
osg::UserDataContainer* udc = asUserDataContainer();
|
||||
if (!udc)
|
||||
{
|
||||
getOrCreateUserDataContainer();
|
||||
@ -218,11 +227,62 @@ void osg::Object::setUserValue(const std::string& name, const T& value)
|
||||
}
|
||||
|
||||
unsigned int i = udc->getUserObjectIndex(name);
|
||||
if (i<udc->getNumUserObjects()) udc->setUserObject(i, new UserValueObject(name,value));
|
||||
else udc->addUserObject(new UserValueObject(name,value));
|
||||
if (i<udc->getNumUserObjects())
|
||||
{
|
||||
Object* obj = udc->getUserObject(i);
|
||||
if (typeid(*obj)==typeid(UserValueObject))
|
||||
{
|
||||
UserValueObject* uvo = static_cast<UserValueObject*>(obj);
|
||||
uvo->setValue(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
udc->setUserObject(i, new UserValueObject(name, value));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
udc->addUserObject(new UserValueObject(name,value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class P, class T>
|
||||
T* getOrCreateUserObjectOfType(P* parent)
|
||||
{
|
||||
T* object=0;
|
||||
const char* name = typeid(T).name();
|
||||
osg::UserDataContainer* udc = parent->getOrCreateUserDataContainer();
|
||||
unsigned int index = udc->getUserObjectIndex(name);
|
||||
if (index<udc->getNumUserObjects())
|
||||
{
|
||||
osg::Object* userObject = udc->getUserObject(index);
|
||||
if (typeid(*userObject)==typeid(T))
|
||||
{
|
||||
object = static_cast<T*>(userObject);
|
||||
// OSG_NOTICE<<"Reusing "<<name<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// OSG_NOTICE<<"Replacing "<<name<<", original object "<<userObject->className()<<std::endl;
|
||||
|
||||
object = new T;
|
||||
object->setName(name);
|
||||
udc->setUserObject(index, object);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
object = new T;
|
||||
object->setName(name);
|
||||
udc->addUserObject(object);
|
||||
// OSG_NOTICE<<"Creating new "<<name<<std::endl;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user