Hi Robert,

This looks pretty straightforward and I agree that less complexity is
good.  However a would modify it slightly to support two related
features I have been lobbying for, which are the ability to share
UserDataContainers between osg::Objects, and the ability to subclass a
custom UserDataContainer implementation.

The idea is that there is generally not a 1:1 correlation between the
application entity model and the scene graph.  Because of this, one
often wants to be able to share or inherit metadata information, or look
up metadata on the fly to avoid copying large amounts of application
data into the scene graph.

I think it feasible to add one level of indirection without adding too
much complexity.  For example:

- Make osg::UserDataContainer a pure abstract class.

        class OSG_EXPORT UserDataContainer : public osg::Referenced
        {
            public:
        void addUserObject(Object* owner, Object* obj) = 0;
        void setUserObject(Object* owner, unsigned int i, Object* obj) = 0;
        void removeUserObject(Object* owner, unsigned int i);

        unsigned int getUserObjectIndex(Object* owner, const osg::Object* obj) 
const = 0;
        unsigned int getUserObjectIndex(Object* owner, const std::string& name) 
const = 0;

        Object* getUserObject(Object* owner, unsigned int i) = 0;
        const Object* getUserObject(Object* owner, unsigned int i) const = 0;

        Object* getUserObject(Object* owner, const std::string& name) = 0;
        const Object* getUserObject(Object* owner, const std::string& name) 
const = 0;

        unsigned int getNumUserObjects(Object* owner) const = 0;
              
        };

- Provide a default implementation which doesn't do anything with the "owner" 
field
        class OSG_EXPORT DefaultUserDataContainer : public UserDataContainer
        {
                ref_ptr<Referenced>     _userData;
b               DescriptionList         _descriptionList;
                ObjectList              _objectList;
          public:
             void addUserObject(Object* owner, Object* obj) {
                _objectList.push_back(obj);
             }
        /* etc */
};


- The methods implementated in osg::Object just forward to the container along 
with the owner:

        void osg::Object::addUserObject(Object* obj) {
            if (!_container) {
               _container = new osg::DefaultUserDataContainer();
            }
            _container->addUserObject(this, obj);
        }

        void osg::Object::setUserObject(Object* owner, unsigned int i, Object* 
obj) {
            if (!_container) {
               _container = new osg::DefaultUserDataContainer();
            }
            _container->setUserObject(this, i, obj);
        }

        /* etc */

- osg::Object also gains a couple of new methods:
        osg::UserDataContainer* osg::Object::getUserDataContainer();
        osg::Object::setUserDataContainer(osg::UserDataContainer*);


Does this seem reasonable?

- Peter

-- 
Peter Amstutz
Senior Software Engineer
Technology Solutions Experts
Natick, MA
02131

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to