Hi Peter, On Thu, Jun 9, 2011 at 10:07 PM, Peter Amstutz <peter.amst...@tseboston.com> wrote: > 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().
Having UserDataContainer::getUserDataContainer() return this would still create a circular reference as any code that chained calls to use data would end up in an infinite loop. The osg::Object serializers automatically write out the UserDataContainer so is one example of code that would end up in an infinite loop. One could put work arounds in to such code but it's not particularily robust. Logically I don't think it make sense either, as osg::Object agregates UserDataContainer, and UserDataContainer "is a" osg::Object so should logically do the same. I don't think the UserDataContainer having an active getUserDataContainer() is a problem, but osg::Object::set/getUserValue not working how you'd expect in on a UserDataContainer is so I would suggest that this template functions implementation be tweaked to return use this pointer if it's dynamic_cast<> to UserDataContainer. I have gone for the following implemetation: /** provide implementation of osg::Object::getUserValue(..) template*/ template<typename T> 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); if (!udc) udc = _userDataContainer; const UserValueObject* uvo = udc ? dynamic_cast<const UserValueObject*>(udc->getUserObject(name)) : 0; if (uvo) { value = uvo->getValue(); return true; } else { return false; } } /** provide implementation of osg::Object::setUserValue(..) template.*/ template<typename T> void osg::Object::setUserValue(const std::string& name, const T& value) { typedef TemplateValueObject<T> UserValueObject; osg::UserDataContainer* udc = dynamic_cast<osg::UserDataContainer*>(this); if (!udc) { getOrCreateUserDataContainer(); udc = _userDataContainer; } unsigned int i = udc->getUserObjectIndex(name); if (i<udc->getNumUserObjects()) udc->setUserObject(i, new UserValueObject(name,value)); else udc->addUserObject(new UserValueObject(name,value)); } Let me know if you spot a problem with this approach. Cheers, Robert. Robert. _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org