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/