Hi Robert,

This is great! Being able to store meta-data in any osg::Object derived
class has been something we've wanted for a while now.

Regarding serialization, will your changes break loading of older models
that contained node descriptions? This is a big concern for us because we
have hundreds of models that contain description strings.

Anyways, I'll begin playing around with these changes and report any issues
I encounter.

Cheers,
Farshid

On Tue, May 31, 2011 at 7:19 AM, Robert Osfield <[email protected]>wrote:

> Hi All,
>
> This morning I've been experimenting with extending the user data
> support in the OSG, along the lines set out by Sukender.  I've tried
> to keep the class count down, and keep the user interface relatively
> straight forward.  Implementation wise I have gone for an
> osg::Object::UserDataContainer that is used an internal implementation
> structure in osg::Object, and this doesn't have any public interface.
> This simple nested class is defined within the osg::Object protected
> scope and looks like:
>
>        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;
>        };
>
> Access methods for the old UserData and Descriptions list are
> maintained, with the later moved in from osg::Node to allow all
> osg::Object classes access to these convinience methods.  These
> methods automatically create the UserDataContainer when required and
> can be used in an identical was as before.
>
> The new element is the ObjectList vector in UserDataContainer, this
> can store any object subclasses from osg::Object which can be access
> either via index into the vector or by the name of the osg::Object
> (i.e. Object::setName()/getName()).  I have put convience methods into
> osg::Object public scope to access the UserDataContainer:
>
>        void addUserObject(Object* obj);
>        void setUserObject(unsigned int i, Object* obj);
>        void removeUserObject(unsigned int i);
>
>        unsigned int getUserObjectIndex(const osg::Object* obj) const;
>        unsigned int getUserObjectIndex(const std::string& name) const;
>
>        Object* getUserObject(unsigned int i);
>        const Object* getUserObject(unsigned int i) const;
>
>        Object* getUserObject(const std::string& name);
>        const Object* getUserObject(const std::string& name) const;
>
>        unsigned int getNumUserObjects() const;
>
> This gets us so far, but... it forces us to provide our own subclasses
> of osg::Object to be able to put in our own Data, to ease the burden I
> have introduced a template<typename T> ValueObject implementation that
> "has a" T _value member.
>
> template<typename T>
> class ValueObject : public osg::Object
> {
>    public:
>
>        ValueObject():
>            Object(true),
>            _value()
>        {
>        }
>
>        ValueObject(const std::string& name, T value):
>            Object(true),
>            _value(value)
>        {
>            setName(name);
>        }
>
>        ValueObject(const ValueObject& rhs, const osg::CopyOp
> copyop=osg::CopyOp::SHALLOW_COPY):
>            Object(rhs,copyop),
>            _value(rhs._value)
>        {
>        }
>
>        META_Object(osg, ValueObject)
>
>        void setValue(const T& value) { _value = value; }
>        const T& getValue() const { return _value; }
>
>    protected:
>
>        T _value;
> };
>
> And a couple of convinience methods in osg::Object to create/access these:
>
>        template<typename T>
>        bool getUserValue(const std::string& name, T& value) const
>        {
>            typedef ValueObject<T> UserValueObject;
>            UserValueObject* uvo =
> dynamic_cast<UserValueObject*>(getUserObject(name));
>            if (uvo)
>            {
>                value = uvo->getValue();
>                return true;
>            }
>            else
>            {
>                return false;
>            }
>        }
>
>        template<typename T>
>        void setUserValue(const std::string& name, const T& value)
>        {
>            typedef ValueObject<T> UserValueObject;
>
>            unsigned int i = getUserObjectIndex(name);
>            if (i<getNumUserObjects()) setUserObject(i, new
> UserValueObject(name,value));
>            else addUserObject(new UserValueObject(name,value));
>        }
>
>
> It's these methods that I'd expect the access to go through.  As a
> quick test I have created an osguserdata example than we can use as a
> test bed for this new functionality.  My current rev looks like:
>
> int main(int argc, char** argv)
> {
>    osg::ref_ptr<osg::Group> node = new osg::Group;
>
>    int i = 10;
>    node->setUserValue("Int value",i);
>
>    int j = 0;
>    if (node->getUserValue("Int value",j))
>    {
>        OSG_NOTICE<<"Int value="<<j<<std::endl;
>    }
>    else
>    {
>        OSG_NOTICE<<"Int value not found"<<std::endl;
>    }
>
>    std::string testString("All seems fine");
>    node->setUserValue("Status",testString);
>
>    std::string readString;
>    if (node->getUserValue("Status",readString))
>    {
>        OSG_NOTICE<<"Status="<<readString<<std::endl;
>    }
>    else
>    {
>        OSG_NOTICE<<"Status not found"<<std::endl;
>    }
>
>    return 0;
> }
>
> So far I'm getting the correct values, and everything compiles OK
> under g++ 4.5.2, hopefully the use of template methods want cause
> problems across platforms.
>
> I haven't yet tackled the IO side.  I'm hoping that providing wrappers
> for a ValueObject<int>, ValueObject<unsigned int>, ValueObject<float>,
> ValueObject<string> etc. will be sufficient.  This will be my next
> experiment.
>
> I am a little nervous about the potential for build and runtime
> breakage so will post to the list a warning that I'm about to check
> these changes in.  I have attached my versions of include/osg/Object
> and src/osg/Object.cpp for those keep to review the changes.
>
> Let me know what you think,
> Robert.
>
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to