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