Hi guys,
I have coded up a proposal for a general-purpose property system for
osg::Object and would
like to present it for comments and discussion.
Properties must be derived from osg::Referenced and are stored in a map by name:
class PropertyMap : public Referenced, public std::map<std::string,
ref_ptr<Referenced> >
- osg::Object has a 'osg::ref_ptr<osg::PropertyMap> _properties'
- this is only valid if there are any properties stored, so consumes minimal
memory.
- the properties map is created when a property is first added.
- for now it's never deleted but an explicit call for that could be added; it
could also
be deleted when the map becomes empty.
- user data is stored/retrieved under the 'osg.data' name. The API is
unchanged.
- descriptions are stored/retrieved under the 'osg.desc' name. The API is
unchanged.
- 'osg::Object _userData' and 'osg::Node _descriptions' are removed.
The general osg::Object API for properties is:
- void setProperty(const std::string& name, Referenced* prop);
- void clearProperty(name);
- const Referenced* getProperty(name) const;
- Referenced* getProperty(name);
For data that is not derived from osg::Referenced (like floats, int, strings)
instead of
using a variant class I've created the following template class:
template <typename T> class Property : public Referenced {
public:
//...
void set(const T& data) { _data = data; }
const T& get() const { return _data; }
T& get() { return _data; }
private:
T _data;
};
Data is stored like this:
osg::Property<int>* ip = new osg::Property<int>(42);
obj->setProperty("my.int", ip);
and retrieved like this:
osg::Property<int>* ip0 = dynamic_cast<osg::Property<int>
>(obj->getProperty("my.int"));
ip0->get() == 42;
For convenience I've created template versions in osg::Object so that one can
write:
obj->setProperty<int>("my.int", 42); // creates and stores Property<int>(42)
obj->getProperty<int>("my.int")->get() == 42;
(int) (*obj->getProperty<int>("my.int")) == 42;
With this the osg::Node description is simply stored as a
osg::Property<osg::Node::DescriptionList> as 'osg.desc' with wrappers to keep
the original
API:
const DescriptionList& getDescriptions() const {
return getOrCreateProperty<DescriptionList>("osg.desc")->get();
}
const std::string& getDescription(unsigned int i) const {
return getOrCreateProperty<DescriptionList>("osg.desc")->get()[i];
}
At the moment there are some missing bits like saving the entire properties map
(not only
userdata/descriptions) and the copyop integration, and also some ugly parts,
for example
the _properties is mutable so that I could keep the existing Descriptions API.
I'm eagerly awaiting your thoughts and comments.
Happy New Year everyone and 'Guten Rutsch' (as we say in Germany).
Cheers,
/ulrich
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org