From Marco Jez, "Problems fixed:

1. type converters created automatically by the I_BaseType macro use
static_cast<> even for base-to-derived conversions. dynamic_cast<> should be
used instead.
2. as a consequence of the above fix, I_BaseType must now differentiate
between polymorphic and non-polymorphic base classes, because the latter
can't be dynamic_cast'd to derived classes. Some template magic (see
is_polymorphic<> in ReflectionMacros) is used to detect polymorphism at
compile time (I'm NOT sure it works on all platforms as it's partly
implementation-dependent. Please test!).
3. predefined custom property getters/setters/counters/etc. (as those
defined for STL containers) only work on Value objects that contain
non-pointer instances. This was an unwanted restriction that no longer
exists.

Wrappers will need to be recompiled. This is a good time to give them a
fresh update with genwrapper.

NOTE: fix #1 should get rid of those crashes and strange behaviours that
some users noticed while using osgIntrospection through osgTcl or in their
own code."
This commit is contained in:
Robert Osfield
2005-09-28 14:18:31 +00:00
parent f26c3da074
commit 3ef0406105
3 changed files with 98 additions and 57 deletions

View File

@@ -21,6 +21,25 @@
#include <osgIntrospection/ConverterProxy>
#include <osgIntrospection/Converter>
namespace osgIntrospection
{
/** Compile-time polymorphism detector.
The enumeration constant "value" evaluates
to true only if T is a polymorphic class,
false otherwise. T must be a subclassable
type.
*/
template<typename T>
struct is_polymorphic
{
class dummy1: public T { ~dummy1(); };
class dummy2: public T { virtual ~dummy2(); };
enum { value = sizeof(dummy1) == sizeof(dummy2) };
};
}
// --------------------------------------------------------------------------
// "private" macros, not to be used outside this file
// --------------------------------------------------------------------------
@@ -145,31 +164,49 @@
#define I_ReaderWriter(x) setReaderWriter(new x);
#define I_Comparator(x) setComparator(new x);
template<typename x, typename reflected_type, bool polymorphic>
struct BaseTypeConverters
{
BaseTypeConverters()
{
const osgIntrospection::Type& st = typeof(reflected_type*); \
const osgIntrospection::Type& cst = typeof(const reflected_type*); \
const osgIntrospection::Type& dt = typeof(x*); \
const osgIntrospection::Type& cdt = typeof(const x*); \
osgIntrospection::ConverterProxy cp1(st, dt, new osgIntrospection::StaticConverter<reflected_type* , x*>); \
osgIntrospection::ConverterProxy cp2(cst, cdt, new osgIntrospection::StaticConverter<const reflected_type* , const x*>); \
osgIntrospection::ConverterProxy cp1c(st, cdt, new osgIntrospection::StaticConverter<reflected_type* , const x*>); \
}
};
template<typename x, typename reflected_type>
struct BaseTypeConverters<x, reflected_type, true>
{
BaseTypeConverters()
{
const osgIntrospection::Type& st = typeof(reflected_type*); \
const osgIntrospection::Type& cst = typeof(const reflected_type*); \
const osgIntrospection::Type& dt = typeof(x*); \
const osgIntrospection::Type& cdt = typeof(const x*); \
osgIntrospection::ConverterProxy cp1(st, dt, new osgIntrospection::StaticConverter<reflected_type* , x*>); \
osgIntrospection::ConverterProxy cp2(cst, cdt, new osgIntrospection::StaticConverter<const reflected_type* , const x*>); \
osgIntrospection::ConverterProxy cp1c(st, cdt, new osgIntrospection::StaticConverter<reflected_type* , const x*>); \
osgIntrospection::ConverterProxy cp3(dt, st, new osgIntrospection::DynamicConverter<x*, reflected_type* >); \
osgIntrospection::ConverterProxy cp4(cdt, cst, new osgIntrospection::DynamicConverter<const x*, const reflected_type* >); \
osgIntrospection::ConverterProxy cp3c(dt, cst, new osgIntrospection::DynamicConverter<x*, const reflected_type* >); \
}
};
#define I_BaseType(x) \
{ \
addBaseType(typeof(x)); \
const osgIntrospection::Type& st = typeof(reflected_type* ); \
const osgIntrospection::Type& cst = typeof(const reflected_type* ); \
const osgIntrospection::Type& dt = typeof(x *); \
const osgIntrospection::Type& cdt = typeof(const x *); \
osgIntrospection::ConverterProxy cp1(st, dt, new osgIntrospection::StaticConverter<reflected_type* , x *>); \
osgIntrospection::ConverterProxy cp2(cst, cdt, new osgIntrospection::StaticConverter<const reflected_type* , const x *>); \
osgIntrospection::ConverterProxy cp1c(st, cdt, new osgIntrospection::StaticConverter<reflected_type* , const x *>); \
osgIntrospection::ConverterProxy cp3(dt, st, new osgIntrospection::StaticConverter<x *, reflected_type* >); \
osgIntrospection::ConverterProxy cp4(cdt, cst, new osgIntrospection::StaticConverter<const x *, const reflected_type* >); \
osgIntrospection::ConverterProxy cp3c(dt, cst, new osgIntrospection::StaticConverter<x *, const reflected_type* >); \
addBaseType(typeof(x )); \
BaseTypeConverters<x, reflected_type, osgIntrospection::is_polymorphic<x >::value> btc; \
}
#define I_VirtualBaseType(x) \
{ \
addBaseType(typeof(x)); \
const osgIntrospection::Type& st = typeof(reflected_type* ); \
const osgIntrospection::Type& cst = typeof(const reflected_type* ); \
const osgIntrospection::Type& dt = typeof(x *); \
const osgIntrospection::Type& cdt = typeof(const x *); \
osgIntrospection::ConverterProxy cp1(st, dt, new osgIntrospection::StaticConverter<reflected_type* , x *>); \
osgIntrospection::ConverterProxy cp2(cst, cdt, new osgIntrospection::StaticConverter<const reflected_type* , const x *>); \
osgIntrospection::ConverterProxy cp1c(st, cdt, new osgIntrospection::StaticConverter<reflected_type* , const x *>); \
addBaseType(typeof(x )); \
BaseTypeConverters<x, reflected_type, false> btc; \
}
#define I_EnumLabel(x) addEnumLabel(x, #x, true);