On 6/9/2011 11:54 AM, Robert Osfield wrote:
> I debated setting the UserDataContainer's _userDataContainer to itself but it
> woudl create a circular reference so ceratinly a no go.
>
> Potentially you could override the Object::s/getUserDataContainer
> methods to return self
> but would in itself introduce an inconsistency between how objects and
> containers behave.
> I also have no objection to UserDataContainer's having their own User
> data objects
> nested within them.

I can't think of a use case for allowing a UserDataContainer to have its
own separate UserDataContainer (meta-meta-data?).  If you need to chain
them together or be nested, you can just as easily have an entry in the
user data object list point to another UserDataContainer.

I understand the circular reference problem with setting
_userDataContainer to "this", so overriding get/setUserDataContainer()
and ignoring _userDataContainer seems like a reasonable solution to me. 
Making _userDataContainer a private (not protected) field of osg::Object
prevents end-runs around subclasses that overrides getUserDataContainer().

I have attached a patch which makes
osg::UserDataContainer::getUserDataContainer() and related methods
return "this" as I describe above.

In the patch, get/setUserValue() call getUserDataContainer() and use the
container that is returned, rather than accessing _userDataContainer
directly.  This means the behavior will defer to the embeded
_userDataContainer  by default except when the object is itself a
UserDataContainer, in which case get/setUserValue() operate on the
object itself.

Arguably this is slightly inconsistent, but I think it is much more
useful and desirable behavior than manipulating the _userDataContainer
itself embedded in _userDataContainer.

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

Index: include/osg/Object
===================================================================
--- include/osg/Object  (revision 12513)
+++ include/osg/Object  (working copy)
@@ -122,17 +122,17 @@
 
 
         /** set the UserDataContainer object.*/
-        void setUserDataContainer(osg::UserDataContainer* udc);
+        virtual void setUserDataContainer(osg::UserDataContainer* udc);
 
         /** get the UserDataContainer attached to this object.*/
-        osg::UserDataContainer* getUserDataContainer() { return 
_userDataContainer; }
+        virtual osg::UserDataContainer* getUserDataContainer() { return 
_userDataContainer; }
 
         /** get the const UserDataContainer attached to this object.*/
-        const osg::UserDataContainer* getUserDataContainer() const { return 
_userDataContainer; }
+        virtual const osg::UserDataContainer* getUserDataContainer() const { 
return _userDataContainer; }
 
         /** Convinience method that returns the UserDataContainer, and if one 
doesn't already exist creates and assigns
          * a DefaultUserDataContainer to the Object and then return this new 
UserDataContainer.*/
-        osg::UserDataContainer* getOrCreateUserDataContainer();
+        virtual osg::UserDataContainer* getOrCreateUserDataContainer();
 
 
         /**
@@ -186,10 +186,10 @@
         std::string _name;
         DataVariance _dataVariance;
 
+    private:
+    
         osg::UserDataContainer* _userDataContainer;
 
-    private:
-
         /** disallow any copy operator.*/
         Object& operator = (const Object&) { return *this; }
 };
Index: include/osg/UserDataContainer
===================================================================
--- include/osg/UserDataContainer       (revision 12513)
+++ include/osg/UserDataContainer       (working copy)
@@ -158,9 +158,6 @@
         /** 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);
 
@@ -175,6 +172,18 @@
 
         /** Add a description string.*/
         virtual void addDescription(const std::string& desc);
+        
+        /** Not allowed to set user data on a user data. */
+        virtual void setUserDataContainer(osg::UserDataContainer* udc) { }
+
+        /** Return self */
+        virtual osg::UserDataContainer* getUserDataContainer() { return this; }
+        
+        /** Return self */
+        virtual const osg::UserDataContainer* getUserDataContainer() const { 
return this; }
+        
+          /** Return self */
+        virtual osg::UserDataContainer* getOrCreateUserDataContainer() { 
return this; }
 
 protected:
 
Index: include/osg/ValueObject
===================================================================
--- include/osg/ValueObject     (revision 12513)
+++ include/osg/ValueObject     (working copy)
@@ -172,7 +172,9 @@
 bool osg::Object::getUserValue(const std::string& name, T& value) const
 {
     typedef TemplateValueObject<T> UserValueObject;
-    const UserValueObject* uvo = _userDataContainer ? dynamic_cast<const 
UserValueObject*>(_userDataContainer->getUserObject(name)) : 0;
+    
+    UserDataContainer* udc = getOrCreateUserDataContainer();
+    const UserValueObject* uvo = udc ? dynamic_cast<const 
UserValueObject*>(udc->getUserObject(name)) : 0;
     if (uvo)
     {
         value = uvo->getValue();
@@ -190,11 +192,11 @@
 {
     typedef TemplateValueObject<T> UserValueObject;
 
-    getOrCreateUserDataContainer();
+    UserDataContainer* udc = getOrCreateUserDataContainer();
     
-    unsigned int i = _userDataContainer->getUserObjectIndex(name);
-    if (i<_userDataContainer->getNumUserObjects()) 
_userDataContainer->setUserObject(i, new UserValueObject(name,value));
-    else _userDataContainer->addUserObject(new UserValueObject(name,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));
 }
 
 }
Index: src/osg/Node.cpp
===================================================================
--- src/osg/Node.cpp    (revision 12513)
+++ src/osg/Node.cpp    (working copy)
@@ -493,7 +493,7 @@
 
 const Node::DescriptionList& Node::getDescriptions() const
 {
-    if (_userDataContainer) return _userDataContainer->getDescriptions();
+    if (getUserDataContainer()) return 
getUserDataContainer()->getDescriptions();
     else return getStaticDescriptionList();
 }
 
@@ -504,13 +504,13 @@
 
 const std::string& Node::getDescription(unsigned int i) const
 {
-    if (_userDataContainer) return _userDataContainer->getDescriptions()[i];
+    if (getUserDataContainer()) return 
getUserDataContainer()->getDescriptions()[i];
     else return getStaticDescriptionList()[i];
 }
 
 unsigned int Node::getNumDescriptions() const
 {
-    return _userDataContainer ? _userDataContainer->getDescriptions().size() : 
0;
+    return getUserDataContainer() ? 
getUserDataContainer()->getDescriptions().size() : 0;
 }
 
 void Node::addDescription(const std::string& desc)
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to