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

Reply via email to