Hi Ruben,

For example, for the Geodes, this is the output of osgintrospection
sample program:

osg::Geode
       derived from: osg::Node
       * public methods:
    [...]
       * properties:
           {G   }  BoundingBox (const osg::BoundingBox &)
           {GSCA}  Drawable (osg::Drawable *)   [ARRAY]
           {G   }  DrawableList (const std::vector< osg::ref_ptr<
osg::Drawable > > &)
           { S  }  ThreadSafeRefUnref (bool)

As you can see, there are two paths to get the drawables of a geode
(Drawable and DrawableList properties). It happens with other things,

There are two paths because the class' interface provides two paths. Genwrapper, which is responsible of generating introspection wrappers, can't silently drop one of them just because they seem to access the same information. In fact it doesn't even know they are related one to each other. Genwrapper does some heuristics to detect those methods that qualify as "property getter" or "property setter". In the example above, the read-only DrawableList property is created after the getter method Geode::getDrawableList(), while the Drawable property is recognized as an array property based on methods addDrawable(), getDrawable(), setDrawable(), getNumDrawables() and so on. Clearly the class provides two different paths to the same information: you can either get the (const) list of drawables in one call, or you can use individual accessor methods to manipulate the same list. From the genwrapper's point of view they are just two different properties with a similar name.

Is this really necessary? Or could one of the paths be removed? I would
like to keep the ARRAY path and remove the other one, the ARRAY fits
better with the reflection API.

Can't you just ignore the other property? After all, this is what you do every time you deal with a Geode's drawable in your C++ program, unless you need to get the drawable list as a whole for some reason. The purpose of osgIntrospection is to reflect the entire interface of a C++ class, and it aims to do so even though it's far from being perfect. Since osgIntrospection is basically a multi-domain library, it's nearly impossible to determine in advance whether some reflected element will be useful to the majority of application domains or not. For example, reflection of class methods is vital for scripting, while it is totally useless for object persistence and serialization (which rely on properties instead). Usually you would create a thin abstraction layer over osgIntrospection that is particularly tailored for a specific domain, hiding unnecessary details.

Anyway, if it's a common feeling that some reflected element is really unnecessary, you can prevent genwrapper from reflecting it by modifying the genwrapper.conf file.

For another part, the StateSet reflection is too much complicated. To
get the state attributes I must navigate through 4 objects:

*** osg::StateSet
       derived from: osg::Object
       * properties:
           {GS  }  AttributeList (std::map<
osg::StateAttribute::TypeMemberPair, osg::StateSet::RefAttributePair >
&)
    [...]

*** std::map< osg::StateAttribute::TypeMemberPair,
osg::StateSet::RefAttributePair >
       * properties:
           {GS  }  Item (std::pair< osg::ref_ptr< osg::StateAttribute
, osg::StateAttribute::OverrideValue >)   [INDEXED]
[...]

*** std::pair< osg::ref_ptr< osg::StateAttribute >,
osg::StateAttribute::OverrideValue >
       * properties:
           {GS  }  first (osg::ref_ptr< osg::StateAttribute >)
           {GS  }  second (unsigned int)

*** osg::ref_ptr< osg::StateAttribute >
       * properties:
           {G   }   (osg::StateAttribute *)

I think that the first "AttributeList" property should be directly
indexed, and the "first" attribute of the std::pair... should be a
pointer, this would remove two levels of indirection. Is this possible?
Can something similar be applied to the texture attributes also? They
have two more indirection levels for the texture units when only one
more should be needed :(

Again, the complexity is that of C++ :-)
osgIntrospection was designed to operate at several levels of abstraction, the lowest being a plain mapping between C++ entities and the reflected structure. This is basically the complexity you see above. A further abstraction is obtained through properties, which of course don't have a direct mapping to C++ features and therefore can't be automatically determined during source code analysis (doxygen+genwrapper). While genwrapper does try to detect accessor methods and group them together to form a property, it can't enter the developer's mind and guess his/her intentions, so higher levels of abstraction must be defined manually. By editing genwrapper.conf you can already force new properties to be created by specifying accessor methods explicitely. If this is not enough you can extend osgIntrospection by providing custom property getter/setter mechanisms that don't necessarily map to existing class methods or that provide a convenient way to jump over several levels of indirection (examples are custom reflectors for standard containers, see osgIntrospection/Reflector).

I'm afraid I can't get deeper right now, I'm constantly busy and usually I can't even read the mailing list. :-/
BTW it's a pleasure to write here again.

Cheers,
Marco

_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

Reply via email to