Changed tabs to four spaces

This commit is contained in:
Robert Osfield 2005-03-14 09:28:31 +00:00
parent 21ae4c6c65
commit 4beb385d2d
22 changed files with 5677 additions and 5677 deletions

View File

@ -8,238 +8,238 @@
namespace osgIntrospection
{
/// By adding this attribute to a PropertyInfo you specify that there
/// is no default value for that property.
class NoDefaultValueAttribute: public CustomAttribute {};
/// By adding this attribute to a PropertyInfo you specify that there
/// is no default value for that property.
class NoDefaultValueAttribute: public CustomAttribute {};
/// By adding this attribute to a PropertyInfo you specify a custom
/// default value for that property.
class DefaultValueAttribute: public CustomAttribute
{
public:
DefaultValueAttribute(const Value &v): v_(v) {}
const Value &getDefaultValue() const { return v_; }
private:
Value v_;
};
/// By adding this attribute to a PropertyInfo you specify a custom
/// default value for that property.
class DefaultValueAttribute: public CustomAttribute
{
public:
DefaultValueAttribute(const Value &v): v_(v) {}
const Value &getDefaultValue() const { return v_; }
private:
Value v_;
};
/// Base struct for custom property getters. Descendants may override
/// one or more of the get() methods to provide the means for retrieving
/// the value of a property. The first version of get() is used with
/// indexed properties, the second one serves simple properties and the
/// last one is used with array properties.
struct PropertyGetter
{
virtual Value get(const Value &instance, const ValueList &indices) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::IGET); }
virtual Value get(const Value &instance) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::GET); }
virtual Value get(const Value &instance, int i) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::AGET); }
virtual ~PropertyGetter() {}
};
/// Base struct for custom property getters. Descendants may override
/// one or more of the get() methods to provide the means for retrieving
/// the value of a property. The first version of get() is used with
/// indexed properties, the second one serves simple properties and the
/// last one is used with array properties.
struct PropertyGetter
{
virtual Value get(const Value &instance, const ValueList &indices) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::IGET); }
virtual Value get(const Value &instance) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::GET); }
virtual Value get(const Value &instance, int i) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::AGET); }
virtual ~PropertyGetter() {}
};
/// By setting an attribute of this class you can specify a custom object
/// that will be used to retrieve the value of a property instead of the
/// default getter method.
class CustomPropertyGetAttribute: public CustomAttribute
{
public:
CustomPropertyGetAttribute(const PropertyGetter *getter)
: CustomAttribute(), getter_(getter) {}
/// By setting an attribute of this class you can specify a custom object
/// that will be used to retrieve the value of a property instead of the
/// default getter method.
class CustomPropertyGetAttribute: public CustomAttribute
{
public:
CustomPropertyGetAttribute(const PropertyGetter *getter)
: CustomAttribute(), getter_(getter) {}
const PropertyGetter *getGetter() const { return getter_; }
const PropertyGetter *getGetter() const { return getter_; }
~CustomPropertyGetAttribute()
{
delete getter_;
}
~CustomPropertyGetAttribute()
{
delete getter_;
}
private:
const PropertyGetter *getter_;
};
private:
const PropertyGetter *getter_;
};
/// Base struct for custom property setters. Descendants may override
/// one or more of the set() methods to provide the means for setting
/// the value of a property. The first version of set() is used with
/// indexed properties, the second one serves simple properties and the
/// last one is used with array properties.
struct PropertySetter
{
virtual void set(Value &instance, ValueList &indices, const Value &value) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::ISET); }
virtual void set(Value &instance, const Value &value) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::SET); }
virtual void set(Value &instance, int i, const Value &value) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::ASET); }
virtual ~PropertySetter() {}
};
/// Base struct for custom property setters. Descendants may override
/// one or more of the set() methods to provide the means for setting
/// the value of a property. The first version of set() is used with
/// indexed properties, the second one serves simple properties and the
/// last one is used with array properties.
struct PropertySetter
{
virtual void set(Value &instance, ValueList &indices, const Value &value) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::ISET); }
virtual void set(Value &instance, const Value &value) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::SET); }
virtual void set(Value &instance, int i, const Value &value) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::ASET); }
virtual ~PropertySetter() {}
};
/// By setting an attribute of this class you can specify a custom object
/// that will be used to set the value of a property instead of the
/// default setter method.
class CustomPropertySetAttribute: public CustomAttribute
{
public:
CustomPropertySetAttribute(const PropertySetter *setter)
: CustomAttribute(), setter_(setter) {}
/// By setting an attribute of this class you can specify a custom object
/// that will be used to set the value of a property instead of the
/// default setter method.
class CustomPropertySetAttribute: public CustomAttribute
{
public:
CustomPropertySetAttribute(const PropertySetter *setter)
: CustomAttribute(), setter_(setter) {}
const PropertySetter *getSetter() const { return setter_; }
const PropertySetter *getSetter() const { return setter_; }
~CustomPropertySetAttribute()
{
delete setter_;
}
~CustomPropertySetAttribute()
{
delete setter_;
}
private:
const PropertySetter *setter_;
};
private:
const PropertySetter *setter_;
};
/// Base struct for custom array property counters. Descendants should
/// override the count() method which must return the number of items
/// in a chosen array property for the given instance.
struct PropertyCounter
{
virtual int count(const Value &instance) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::COUNT); }
virtual ~PropertyCounter() {}
};
/// Base struct for custom array property counters. Descendants should
/// override the count() method which must return the number of items
/// in a chosen array property for the given instance.
struct PropertyCounter
{
virtual int count(const Value &instance) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::COUNT); }
virtual ~PropertyCounter() {}
};
/// By setting an attribute of this class you can specify a custom object
/// that will be used to count the number of items in an array property.
class CustomPropertyCountAttribute: public CustomAttribute
{
public:
CustomPropertyCountAttribute(const PropertyCounter *counter)
: CustomAttribute(), counter_(counter) {}
/// By setting an attribute of this class you can specify a custom object
/// that will be used to count the number of items in an array property.
class CustomPropertyCountAttribute: public CustomAttribute
{
public:
CustomPropertyCountAttribute(const PropertyCounter *counter)
: CustomAttribute(), counter_(counter) {}
const PropertyCounter *getCounter() const { return counter_; }
const PropertyCounter *getCounter() const { return counter_; }
~CustomPropertyCountAttribute()
{
delete counter_;
}
~CustomPropertyCountAttribute()
{
delete counter_;
}
private:
const PropertyCounter *counter_;
};
private:
const PropertyCounter *counter_;
};
/// Base struct for custom array property adders. Descendants should
/// override the add() method whose purpose is to add a new item to
/// an array property.
struct PropertyAdder
{
virtual void add(Value&, const Value&) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::ADD); }
virtual ~PropertyAdder() {}
};
/// Base struct for custom array property adders. Descendants should
/// override the add() method whose purpose is to add a new item to
/// an array property.
struct PropertyAdder
{
virtual void add(Value&, const Value&) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::ADD); }
virtual ~PropertyAdder() {}
};
/// By setting an attribute of this class you can specify a custom object
/// that will be used to add a new item to an array property.
class CustomPropertyAddAttribute: public CustomAttribute
{
public:
CustomPropertyAddAttribute(const PropertyAdder *adder)
: CustomAttribute(), adder_(adder) {}
/// By setting an attribute of this class you can specify a custom object
/// that will be used to add a new item to an array property.
class CustomPropertyAddAttribute: public CustomAttribute
{
public:
CustomPropertyAddAttribute(const PropertyAdder *adder)
: CustomAttribute(), adder_(adder) {}
const PropertyAdder *getAdder() const { return adder_; }
const PropertyAdder *getAdder() const { return adder_; }
~CustomPropertyAddAttribute()
{
delete adder_;
}
~CustomPropertyAddAttribute()
{
delete adder_;
}
private:
const PropertyAdder *adder_;
};
private:
const PropertyAdder *adder_;
};
/// This struct allows customization of an indexed property's index set.
/// You must derive from this struct and provide a concrete implementation
/// of getIndexValueSet(), which must return (in parameter values) a list
/// of valid values to be used as indices. The whichindex parameter
/// specifies which index is being queried (0 = first index, 1 = second
/// index, ...).
/// See CustomIndexAttribute for details.
struct IndexInfo
{
virtual const ParameterInfoList &getIndexParameters() const = 0;
virtual void getIndexValueSet(int whichindex, const Value &instance, ValueList &values) const = 0;
virtual ~IndexInfo() {}
};
/// This struct allows customization of an indexed property's index set.
/// You must derive from this struct and provide a concrete implementation
/// of getIndexValueSet(), which must return (in parameter values) a list
/// of valid values to be used as indices. The whichindex parameter
/// specifies which index is being queried (0 = first index, 1 = second
/// index, ...).
/// See CustomIndexAttribute for details.
struct IndexInfo
{
virtual const ParameterInfoList &getIndexParameters() const = 0;
virtual void getIndexValueSet(int whichindex, const Value &instance, ValueList &values) const = 0;
virtual ~IndexInfo() {}
};
/// By default each index in an indexed property is assumed to be an
/// enumeration. When serialization is performed, indices are chosen
/// from the set of enum labels that were defined for the index type.
/// With this attribute you can provide custom code to determine the
/// set of values to be used as indices, instead of the default enum
/// values. This attribute is required, for example, when the number
/// and/or value of indices is not constant over time (such as in
/// associative containers).
class CustomIndexAttribute: public CustomAttribute
{
public:
CustomIndexAttribute(const IndexInfo *ii)
: CustomAttribute(), ii_(ii) {}
/// By default each index in an indexed property is assumed to be an
/// enumeration. When serialization is performed, indices are chosen
/// from the set of enum labels that were defined for the index type.
/// With this attribute you can provide custom code to determine the
/// set of values to be used as indices, instead of the default enum
/// values. This attribute is required, for example, when the number
/// and/or value of indices is not constant over time (such as in
/// associative containers).
class CustomIndexAttribute: public CustomAttribute
{
public:
CustomIndexAttribute(const IndexInfo *ii)
: CustomAttribute(), ii_(ii) {}
const IndexInfo *getIndexInfo() const
{
return ii_;
}
const IndexInfo *getIndexInfo() const
{
return ii_;
}
~CustomIndexAttribute()
{
delete ii_;
}
~CustomIndexAttribute()
{
delete ii_;
}
private:
const IndexInfo *ii_;
};
private:
const IndexInfo *ii_;
};
/// Attribute for overriding the type of a property with a custom
/// type. If you add this attribute to a PropertyInfo object, then
/// all subsequent calls to getValue()/getArrayItem()/getIndexedValue()
/// will perform a conversion from the actual property's type to
/// the custom type specified through this attribute. Similarly, all
/// methods in PropertyInfo that alter the property's value will accept
/// a value of the custom type instead of the actual type. In this
/// case the conversion is implicit and occurs later within the accessor
/// methods.
class PropertyTypeAttribute: public CustomAttribute
{
public:
PropertyTypeAttribute(const Type &type)
: CustomAttribute(), type_(type) {}
/// Attribute for overriding the type of a property with a custom
/// type. If you add this attribute to a PropertyInfo object, then
/// all subsequent calls to getValue()/getArrayItem()/getIndexedValue()
/// will perform a conversion from the actual property's type to
/// the custom type specified through this attribute. Similarly, all
/// methods in PropertyInfo that alter the property's value will accept
/// a value of the custom type instead of the actual type. In this
/// case the conversion is implicit and occurs later within the accessor
/// methods.
class PropertyTypeAttribute: public CustomAttribute
{
public:
PropertyTypeAttribute(const Type &type)
: CustomAttribute(), type_(type) {}
const Type &getPropertyType() const
{
return type_;
}
const Type &getPropertyType() const
{
return type_;
}
private:
const Type &type_;
};
private:
const Type &type_;
};
/// Attribute for overriding the type of an index (of an indexed
/// property) with a custom type. Behaves like PropertyTypeAttribute,
/// but it affects the value of an index instead of the property's
/// value itself.
/// NOTE: property with custom indexing attributes are not affected
/// by this attribute!
class IndexTypeAttribute: public CustomAttribute
{
public:
IndexTypeAttribute(int whichindex, const Type &type)
: CustomAttribute(), wi_(whichindex), type_(type) {}
/// Attribute for overriding the type of an index (of an indexed
/// property) with a custom type. Behaves like PropertyTypeAttribute,
/// but it affects the value of an index instead of the property's
/// value itself.
/// NOTE: property with custom indexing attributes are not affected
/// by this attribute!
class IndexTypeAttribute: public CustomAttribute
{
public:
IndexTypeAttribute(int whichindex, const Type &type)
: CustomAttribute(), wi_(whichindex), type_(type) {}
int getWhichIndex() const
{
return wi_;
}
int getWhichIndex() const
{
return wi_;
}
const Type &getIndexType() const
{
return type_;
}
const Type &getIndexType() const
{
return type_;
}
private:
int wi_;
const Type &type_;
};
private:
int wi_;
const Type &type_;
};
}

View File

@ -4,13 +4,13 @@
namespace osgIntrospection
{
/// The base class for custom attributes. This is an empty class
/// for now.
class CustomAttribute
{
public:
virtual ~CustomAttribute() {}
};
/// The base class for custom attributes. This is an empty class
/// for now.
class CustomAttribute
{
public:
virtual ~CustomAttribute() {}
};
}

View File

@ -10,102 +10,102 @@
namespace osgIntrospection
{
// forward declarations
class Type;
class CustomAttribute;
class CustomAttributeProvider;
// forward declarations
class Type;
class CustomAttribute;
class CustomAttributeProvider;
// vector of attributes
typedef std::vector<const CustomAttribute *> CustomAttributeList;
// vector of attributes
typedef std::vector<const CustomAttribute *> CustomAttributeList;
// vector of attribute providers
typedef std::vector<const CustomAttributeProvider *> CustomAttributeProviderList;
// vector of attribute providers
typedef std::vector<const CustomAttributeProvider *> CustomAttributeProviderList;
/// This is the base class for custom attribute providers, that is objects
/// that can be assigned a list of custom attributes. Methods defined in
/// this class provide the means for adding, retrieving and searching for
/// attributes.
class OSGINTROSPECTION_EXPORT CustomAttributeProvider
{
public:
/// Returns the const list of custom attributes.
inline const CustomAttributeList &getCustomAttributes() const
{
return attribs_;
}
/// This is the base class for custom attribute providers, that is objects
/// that can be assigned a list of custom attributes. Methods defined in
/// this class provide the means for adding, retrieving and searching for
/// attributes.
class OSGINTROSPECTION_EXPORT CustomAttributeProvider
{
public:
/// Returns the const list of custom attributes.
inline const CustomAttributeList &getCustomAttributes() const
{
return attribs_;
}
/// Returns the list of custom attributes.
inline CustomAttributeList &getCustomAttributes()
{
return attribs_;
}
/// Returns the list of custom attributes.
inline CustomAttributeList &getCustomAttributes()
{
return attribs_;
}
/// Adds a new attribute to the list.
inline CustomAttributeProvider *addAttribute(const CustomAttribute *attr)
{
attribs_.push_back(attr);
return this;
}
/// Adds a new attribute to the list.
inline CustomAttributeProvider *addAttribute(const CustomAttribute *attr)
{
attribs_.push_back(attr);
return this;
}
/// Returns whether at least one attribute of the given type is
/// present in the attribute list. If the inherit parameter is
/// set to true, the search is forwarded to base types.
bool isDefined(const Type &type, bool inherit) const;
/// Returns whether at least one attribute of the given type is
/// present in the attribute list. If the inherit parameter is
/// set to true, the search is forwarded to base types.
bool isDefined(const Type &type, bool inherit) const;
/// Returns whether at least one attribute of the given type is
/// present in the attribute list. If the inherit parameter is
/// set to true, the search is forwarded to base types.
/// [template version]
template<typename T> inline bool isDefined(bool inherit) const
{
for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i)
if (typeid(**i) == typeid(T)) return true;
if (inherit)
{
CustomAttributeProviderList providers;
getInheritedProviders(providers);
for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i)
{
if ((*i)->isDefined<T>(true)) return true;
}
}
return false;
}
/// Returns whether at least one attribute of the given type is
/// present in the attribute list. If the inherit parameter is
/// set to true, the search is forwarded to base types.
/// [template version]
template<typename T> inline bool isDefined(bool inherit) const
{
for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i)
if (typeid(**i) == typeid(T)) return true;
if (inherit)
{
CustomAttributeProviderList providers;
getInheritedProviders(providers);
for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i)
{
if ((*i)->isDefined<T>(true)) return true;
}
}
return false;
}
/// Searchs for an attribute of the given type and returns a pointer
/// to it if found, a null pointer otherwise. If the inherit parameter
/// is set to true, the search is forwarded to base types.
const CustomAttribute *getAttribute(const Type &type, bool inherit) const;
/// Searchs for an attribute of the given type and returns a pointer
/// to it if found, a null pointer otherwise. If the inherit parameter
/// is set to true, the search is forwarded to base types.
const CustomAttribute *getAttribute(const Type &type, bool inherit) const;
/// Searchs for an attribute of the given type and returns a pointer
/// to it if found, a null pointer otherwise. If the inherit parameter
/// is set to true, the search is forwarded to base types.
/// [template version]
template<typename T> inline const T *getAttribute(bool inherit) const
{
for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i)
if (typeid(**i) == typeid(T)) return static_cast<const T *>(*i);
if (inherit)
{
CustomAttributeProviderList providers;
getInheritedProviders(providers);
for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i)
{
const T *ca = (*i)->getAttribute<T>(true);
if (ca) return ca;
}
}
return 0;
}
/// Searchs for an attribute of the given type and returns a pointer
/// to it if found, a null pointer otherwise. If the inherit parameter
/// is set to true, the search is forwarded to base types.
/// [template version]
template<typename T> inline const T *getAttribute(bool inherit) const
{
for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i)
if (typeid(**i) == typeid(T)) return static_cast<const T *>(*i);
if (inherit)
{
CustomAttributeProviderList providers;
getInheritedProviders(providers);
for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i)
{
const T *ca = (*i)->getAttribute<T>(true);
if (ca) return ca;
}
}
return 0;
}
protected:
virtual void getInheritedProviders(CustomAttributeProviderList &providers) const = 0;
virtual ~CustomAttributeProvider() {}
protected:
virtual void getInheritedProviders(CustomAttributeProviderList &providers) const = 0;
virtual ~CustomAttributeProvider() {}
private:
CustomAttributeList attribs_;
};
private:
CustomAttributeList attribs_;
};
}

View File

@ -7,182 +7,182 @@
namespace osgIntrospection
{
class Exception
{
public:
Exception(const std::string &msg): msg_(msg) {}
const std::string &what() const throw() { return msg_; }
class Exception
{
public:
Exception(const std::string &msg): msg_(msg) {}
const std::string &what() const throw() { return msg_; }
private:
std::string msg_;
};
private:
std::string msg_;
};
struct ReflectionException: public Exception
{
ReflectionException(const std::string &msg): Exception(msg) {}
};
struct ReflectionException: public Exception
{
ReflectionException(const std::string &msg): Exception(msg) {}
};
struct TypeNotDefinedException: public ReflectionException
{
TypeNotDefinedException(const std::type_info &ti)
: ReflectionException("type `" + std::string(ti.name()) + "' is declared but not defined")
{
}
};
struct TypeNotDefinedException: public ReflectionException
{
TypeNotDefinedException(const std::type_info &ti)
: ReflectionException("type `" + std::string(ti.name()) + "' is declared but not defined")
{
}
};
struct TypeIsAbstractException: public ReflectionException
{
TypeIsAbstractException(const std::type_info &ti)
: ReflectionException("cannot create instances of abstract type `" + std::string(ti.name()) + "'")
{
}
};
struct TypeIsAbstractException: public ReflectionException
{
TypeIsAbstractException(const std::type_info &ti)
: ReflectionException("cannot create instances of abstract type `" + std::string(ti.name()) + "'")
{
}
};
struct InvalidFunctionPointerException: public ReflectionException
{
InvalidFunctionPointerException()
: ReflectionException("invalid function pointer during invoke()")
{
}
};
struct InvalidFunctionPointerException: public ReflectionException
{
InvalidFunctionPointerException()
: ReflectionException("invalid function pointer during invoke()")
{
}
};
struct ConstIsConstException: public ReflectionException
{
ConstIsConstException()
: ReflectionException("cannot modify a const value")
{
}
};
struct ConstIsConstException: public ReflectionException
{
ConstIsConstException()
: ReflectionException("cannot modify a const value")
{
}
};
struct EmptyValueException: public ReflectionException
{
EmptyValueException()
: ReflectionException("cannot retrieve an empty value")
{
}
};
struct TypeNotFoundException: public ReflectionException
{
TypeNotFoundException(const std::string &qname)
: ReflectionException("type `" + qname + "' not found")
{
}
};
struct EmptyValueException: public ReflectionException
{
EmptyValueException()
: ReflectionException("cannot retrieve an empty value")
{
}
};
struct TypeNotFoundException: public ReflectionException
{
TypeNotFoundException(const std::string &qname)
: ReflectionException("type `" + qname + "' not found")
{
}
};
struct MethodNotFoundException: public ReflectionException
{
MethodNotFoundException(const std::string &name, const std::string &cname)
: ReflectionException("could not find a suitable method of name `" + name + "' in class `" + cname + "'")
{
}
};
struct MethodNotFoundException: public ReflectionException
{
MethodNotFoundException(const std::string &name, const std::string &cname)
: ReflectionException("could not find a suitable method of name `" + name + "' in class `" + cname + "'")
{
}
};
struct StreamWriteErrorException: public ReflectionException
{
StreamWriteErrorException()
: ReflectionException("an error occured while trying to write to a stream")
{
}
};
struct StreamWriteErrorException: public ReflectionException
{
StreamWriteErrorException()
: ReflectionException("an error occured while trying to write to a stream")
{
}
};
struct StreamReadErrorException: public ReflectionException
{
StreamReadErrorException()
: ReflectionException("an error occured while trying to read from a stream")
{
}
};
struct StreamReadErrorException: public ReflectionException
{
StreamReadErrorException()
: ReflectionException("an error occured while trying to read from a stream")
{
}
};
class StreamingNotSupportedException: public ReflectionException
{
public:
enum OperationType
{
ANY,
TEXT_WRITE,
TEXT_READ,
BINARY_WRITE,
BINARY_READ
};
class StreamingNotSupportedException: public ReflectionException
{
public:
enum OperationType
{
ANY,
TEXT_WRITE,
TEXT_READ,
BINARY_WRITE,
BINARY_READ
};
StreamingNotSupportedException(OperationType op, const std::type_info &type)
: ReflectionException(build_msg(op, type))
{
}
StreamingNotSupportedException(OperationType op, const std::type_info &type)
: ReflectionException(build_msg(op, type))
{
}
private:
std::string build_msg(OperationType op, const std::type_info &type)
{
std::string opstr;
switch (op)
{
case TEXT_WRITE: opstr = "writing to text stream"; break;
case TEXT_READ: opstr = "reading from text stream"; break;
case BINARY_WRITE: opstr = "writing to binary stream"; break;
case BINARY_READ: opstr = "reading from binary stream"; break;
case ANY:
default: opstr = "streaming";
}
return opstr + std::string(" is not supported on type `" + std::string(type.name()) + "'");
}
};
private:
std::string build_msg(OperationType op, const std::type_info &type)
{
std::string opstr;
switch (op)
{
case TEXT_WRITE: opstr = "writing to text stream"; break;
case TEXT_READ: opstr = "reading from text stream"; break;
case BINARY_WRITE: opstr = "writing to binary stream"; break;
case BINARY_READ: opstr = "reading from binary stream"; break;
case ANY:
default: opstr = "streaming";
}
return opstr + std::string(" is not supported on type `" + std::string(type.name()) + "'");
}
};
struct TypeConversionException: public ReflectionException
{
TypeConversionException(const std::type_info &type1, const std::type_info &type2)
: ReflectionException("cannot convert from type `" + std::string(type1.name()) + "' to type `" + std::string(type2.name()) + "'")
{
}
};
struct TypeConversionException: public ReflectionException
{
TypeConversionException(const std::type_info &type1, const std::type_info &type2)
: ReflectionException("cannot convert from type `" + std::string(type1.name()) + "' to type `" + std::string(type2.name()) + "'")
{
}
};
class PropertyAccessException: public ReflectionException
{
public:
enum AccessType
{
GET,
SET,
IGET,
ISET,
AGET,
ASET,
ADD,
COUNT
};
class PropertyAccessException: public ReflectionException
{
public:
enum AccessType
{
GET,
SET,
IGET,
ISET,
AGET,
ASET,
ADD,
COUNT
};
PropertyAccessException(const std::string &pname, AccessType denied)
: ReflectionException(build_msg(pname, denied))
{
}
PropertyAccessException(const std::string &pname, AccessType denied)
: ReflectionException(build_msg(pname, denied))
{
}
private:
std::string build_msg(const std::string &pname, AccessType denied) const
{
std::string msg;
switch (denied)
{
case GET: msg = "retrieved"; break;
case SET: msg = "set"; break;
case IGET: msg = "retrieved with indices"; break;
case ISET: msg = "set with indices"; break;
case AGET: msg = "retrieved with array index"; break;
case ASET: msg = "set with array index"; break;
case ADD: msg = "added"; break;
case COUNT: msg = "counted"; break;
default: msg = "?";
}
return std::string("value for property `" + pname + "' cannot be " + msg);
}
};
private:
std::string build_msg(const std::string &pname, AccessType denied) const
{
std::string msg;
switch (denied)
{
case GET: msg = "retrieved"; break;
case SET: msg = "set"; break;
case IGET: msg = "retrieved with indices"; break;
case ISET: msg = "set with indices"; break;
case AGET: msg = "retrieved with array index"; break;
case ASET: msg = "set with array index"; break;
case ADD: msg = "added"; break;
case COUNT: msg = "counted"; break;
default: msg = "?";
}
return std::string("value for property `" + pname + "' cannot be " + msg);
}
};
struct IndexValuesNotDefinedException: ReflectionException
{
IndexValuesNotDefinedException(const std::string &name, const std::string &iname)
: ReflectionException("couldn't determine a finite set of values for index `" + iname + "' of property `" + name + "'. Make sure that either: 1) the index is an enumeration, or 2) a valid custom indexing attribute was assigned to the property.")
{
}
};
struct IndexValuesNotDefinedException: ReflectionException
{
IndexValuesNotDefinedException(const std::string &name, const std::string &iname)
: ReflectionException("couldn't determine a finite set of values for index `" + iname + "' of property `" + name + "'. Make sure that either: 1) the index is an enumeration, or 2) a valid custom indexing attribute was assigned to the property.")
{
}
};
}

View File

@ -24,13 +24,13 @@
#endif
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__) || defined( __MWERKS__)
# ifdef OSGINTROSPECTION_LIBRARY
# define OSGINTROSPECTION_EXPORT __declspec(dllexport)
# else
# define OSGINTROSPECTION_EXPORT __declspec(dllimport)
# endif /* OSGINTROSPECTION_LIBRARY */
# ifdef OSGINTROSPECTION_LIBRARY
# define OSGINTROSPECTION_EXPORT __declspec(dllexport)
# else
# define OSGINTROSPECTION_EXPORT __declspec(dllimport)
# endif /* OSGINTROSPECTION_LIBRARY */
#else
# define OSGINTROSPECTION_EXPORT
# define OSGINTROSPECTION_EXPORT
#endif
// set up define for whether member templates are supported by VisualStudio compilers.

View File

@ -14,112 +14,112 @@
namespace osgIntrospection
{
class Type;
class Type;
/// Class MethodInfo stores information about a class method. It is an
/// abstract class, so it must be derived to provide the actual
/// implementation of isConst() and invoke(). Instances of this class
/// can't be modified after their creation.
class OSGINTROSPECTION_EXPORT MethodInfo: public CustomAttributeProvider
{
public:
/// Direct initialization constructor.
inline MethodInfo(const std::string &qname, const Type &decltype, const Type &rtype, const ParameterInfoList &plist);
/// Class MethodInfo stores information about a class method. It is an
/// abstract class, so it must be derived to provide the actual
/// implementation of isConst() and invoke(). Instances of this class
/// can't be modified after their creation.
class OSGINTROSPECTION_EXPORT MethodInfo: public CustomAttributeProvider
{
public:
/// Direct initialization constructor.
inline MethodInfo(const std::string &qname, const Type &decltype, const Type &rtype, const ParameterInfoList &plist);
/// Returns the Type object associated to the type that
/// declares the reflected method.
inline virtual const Type &getDeclaringType() const;
/// Returns the Type object associated to the type that
/// declares the reflected method.
inline virtual const Type &getDeclaringType() const;
/// Returns the name of the reflected method.
inline virtual const std::string &getName() const;
/// Returns the name of the reflected method.
inline virtual const std::string &getName() const;
/// Returns the return type of the reflected method.
inline const Type &getReturnType() const;
/// Returns the return type of the reflected method.
inline const Type &getReturnType() const;
/// Returns a list of objects that describe the reflected
/// method's parameters.
inline const ParameterInfoList &getParameters() const;
/// Returns a list of objects that describe the reflected
/// method's parameters.
inline const ParameterInfoList &getParameters() const;
/// Returns whether the reflected method is const or not.
virtual bool isConst() const = 0;
/// Returns whether the reflected method is const or not.
virtual bool isConst() const = 0;
/// Invokes the reflected method dynamically on the given const
/// instance, passing it the arguments as a list of Value objects.
virtual Value invoke(const Value &instance, ValueList &args) const = 0;
/// Invokes the reflected method dynamically on the given const
/// instance, passing it the arguments as a list of Value objects.
virtual Value invoke(const Value &instance, ValueList &args) const = 0;
/// Invokes the reflected method dynamically on the given instance,
/// passing it the arguments as a list of Value objects.
virtual Value invoke(Value &instance, ValueList &args) const = 0;
/// Invokes the reflected method dynamically on the given instance,
/// passing it the arguments as a list of Value objects.
virtual Value invoke(Value &instance, ValueList &args) const = 0;
/// Invokes the reflected method dynamically on the given const
/// instance, without arguments.
inline Value invoke(const Value &instance) const;
/// Invokes the reflected method dynamically on the given const
/// instance, without arguments.
inline Value invoke(const Value &instance) const;
/// Invokes the reflected method dynamically on the given
/// instance, without arguments.
inline Value invoke(Value &instance) const;
/// Invokes the reflected method dynamically on the given
/// instance, without arguments.
inline Value invoke(Value &instance) const;
private:
inline std::string strip_namespace(const std::string &s) const;
private:
inline std::string strip_namespace(const std::string &s) const;
virtual void getInheritedProviders(CustomAttributeProviderList &providers) const;
virtual void getInheritedProviders(CustomAttributeProviderList &providers) const;
std::string name_;
const Type &decltype_;
const Type &rtype_;
ParameterInfoList params_;
};
std::string name_;
const Type &decltype_;
const Type &rtype_;
ParameterInfoList params_;
};
// INLINE METHODS
inline MethodInfo::MethodInfo(const std::string &qname, const Type &decltype, const Type &rtype, const ParameterInfoList &plist)
: CustomAttributeProvider(),
decltype_(decltype),
rtype_(rtype),
params_(plist)
{
name_ = strip_namespace(qname);
}
// INLINE METHODS
inline MethodInfo::MethodInfo(const std::string &qname, const Type &decltype, const Type &rtype, const ParameterInfoList &plist)
: CustomAttributeProvider(),
decltype_(decltype),
rtype_(rtype),
params_(plist)
{
name_ = strip_namespace(qname);
}
inline std::string MethodInfo::strip_namespace(const std::string &s) const
{
std::string::size_type p = s.rfind("::");
if (p != std::string::npos)
return s.substr(p+2);
return s;
}
inline std::string MethodInfo::strip_namespace(const std::string &s) const
{
std::string::size_type p = s.rfind("::");
if (p != std::string::npos)
return s.substr(p+2);
return s;
}
inline const std::string &MethodInfo::getName() const
{
return name_;
}
inline const std::string &MethodInfo::getName() const
{
return name_;
}
inline const Type &MethodInfo::getDeclaringType() const
{
return decltype_;
}
inline const Type &MethodInfo::getDeclaringType() const
{
return decltype_;
}
inline const Type &MethodInfo::getReturnType() const
{
return rtype_;
}
inline const Type &MethodInfo::getReturnType() const
{
return rtype_;
}
inline const ParameterInfoList &MethodInfo::getParameters() const
{
return params_;
}
inline const ParameterInfoList &MethodInfo::getParameters() const
{
return params_;
}
inline Value MethodInfo::invoke(const Value &instance) const
{
ValueList args;
return invoke(instance, args);
}
inline Value MethodInfo::invoke(const Value &instance) const
{
ValueList args;
return invoke(instance, args);
}
inline Value MethodInfo::invoke(Value &instance) const
{
ValueList args;
return invoke(instance, args);
}
inline Value MethodInfo::invoke(Value &instance) const
{
ValueList args;
return invoke(instance, args);
}
}

View File

@ -10,86 +10,86 @@
namespace osgIntrospection
{
/// This class stores information about a function parameter. A parameter
/// is defined by its name, its type, its position within the parameter
/// list, and zero or more attributes. Attributes describe how the
/// parameter behave, for example whether it is an input or an output
/// parameter.
class ParameterInfo
{
public:
enum ParameterAttributes
{
NONE = 0,
/// This class stores information about a function parameter. A parameter
/// is defined by its name, its type, its position within the parameter
/// list, and zero or more attributes. Attributes describe how the
/// parameter behave, for example whether it is an input or an output
/// parameter.
class ParameterInfo
{
public:
enum ParameterAttributes
{
NONE = 0,
IN = 1, // parameter is used to pass data to the function
OUT = 2, // parameter is used to return data from the function
IN = 1, // parameter is used to pass data to the function
OUT = 2, // parameter is used to return data from the function
INOUT = IN | OUT
};
INOUT = IN | OUT
};
/// Direct initialization constructor.
inline ParameterInfo(const std::string &name, const Type &type, int position, int attribs);
/// Direct initialization constructor.
inline ParameterInfo(const std::string &name, const Type &type, int position, int attribs);
/// Returns the parameter's name.
inline const std::string &getName() const;
/// Returns the parameter's name.
inline const std::string &getName() const;
/// Return the parameter's position within the function's parameter
/// list. This position is zero-based.
inline int getPosition() const;
/// Return the parameter's position within the function's parameter
/// list. This position is zero-based.
inline int getPosition() const;
/// Returns the parameter's type.
inline const Type &getParameterType() const;
/// Returns the parameter's type.
inline const Type &getParameterType() const;
/// Returns the parameter's attributes.
inline int getAttributes() const;
/// Returns the parameter's attributes.
inline int getAttributes() const;
/// Returns whether the parameter has the IN attribute.
inline bool isIn() const { return (attribs_ & IN) != 0; }
/// Returns whether the parameter has the IN attribute.
inline bool isIn() const { return (attribs_ & IN) != 0; }
/// Returns whether the parameter has the OUT attribute.
inline bool isOut() const { return (attribs_ & OUT) != 0; }
/// Returns whether the parameter has the OUT attribute.
inline bool isOut() const { return (attribs_ & OUT) != 0; }
/// Returns whether the parameter has both the IN and the
/// OUT attribute.
inline bool isInOut() const { return isIn() && isOut(); }
/// Returns whether the parameter has both the IN and the
/// OUT attribute.
inline bool isInOut() const { return isIn() && isOut(); }
private:
std::string name_;
const Type &type_;
int position_;
int attribs_;
};
private:
std::string name_;
const Type &type_;
int position_;
int attribs_;
};
// INLINE METHODS
// INLINE METHODS
inline ParameterInfo::ParameterInfo(const std::string &name, const Type &type, int position, int attribs)
: name_(name),
type_(type),
position_(position),
attribs_(attribs)
{
}
inline ParameterInfo::ParameterInfo(const std::string &name, const Type &type, int position, int attribs)
: name_(name),
type_(type),
position_(position),
attribs_(attribs)
{
}
inline const std::string &ParameterInfo::getName() const
{
return name_;
}
inline const std::string &ParameterInfo::getName() const
{
return name_;
}
inline int ParameterInfo::getPosition() const
{
return position_;
}
inline int ParameterInfo::getPosition() const
{
return position_;
}
inline const Type &ParameterInfo::getParameterType() const
{
return type_;
}
inline const Type &ParameterInfo::getParameterType() const
{
return type_;
}
inline int ParameterInfo::getAttributes() const
{
return attribs_;
}
inline int ParameterInfo::getAttributes() const
{
return attribs_;
}
}

View File

@ -14,248 +14,248 @@
namespace osgIntrospection
{
/// This class keeps information about a class' property. A property is
/// defined by a name and a set of methods that store and retrieve
/// values. When the user wants to "get" the value of a property, the
/// getter method will be invoked and its value returned. When the user
/// wants to "set" the value of a property, the setter method will be
/// called. There are three kinds of property: simple (get/set), indexed
/// (get[i1, i2, ...]/set[i1, i2, ...]), and array (count/add/get[i]/
/// set[i]).
/// Objects of class PropertyInfo can't be modified once they have been
/// created, but they can be queried without restrictions. You can either
/// retrieve the accessor methods and invoke them manually, or you can
/// call getValue() / setValue() etc. methods to perform direct operations
/// on the property, given an instance of the declaring type to work on.
/// The latter technique is preferred because it checks for custom
/// attributes associated to the PropertyInfo object and passes control
/// to them when needed.
///
class OSGINTROSPECTION_EXPORT PropertyInfo: public CustomAttributeProvider
{
public:
/// Direct initialization constructor for simple and indexed
/// properties.
/// You must pass the Type object associated to the class that
/// declares the property, the Type object that describes the
/// type of the property's value, the property name and the
/// getter/setter methods. Either the setter or the getter can
/// be null, meaning a restricted access. If both are null, the
/// user is expected to add a custom accessor attribute to this
/// PropertyInfo object.
/// If the getter method has parameters, the property is considered
/// to be indexed. The same is true if the getter is null and the
/// setter has more than one parameter.
PropertyInfo(const Type &decltype, const Type &ptype, const std::string &name, const MethodInfo *getm, const MethodInfo *setm)
: CustomAttributeProvider(),
decltype_(decltype),
ptype_(ptype),
name_(name),
getm_(getm),
setm_(setm),
numm_(0),
addm_(0),
is_array_(false)
{
if (getm_)
{
for (ParameterInfoList::size_type i=0; i<getm_->getParameters().size(); ++i)
indices_.push_back(getm_->getParameters().at(i));
}
else
{
if (setm_)
{
for (ParameterInfoList::size_type i=0; i<(setm_->getParameters().size()-1); ++i)
indices_.push_back(setm_->getParameters().at(i));
}
}
}
/// This class keeps information about a class' property. A property is
/// defined by a name and a set of methods that store and retrieve
/// values. When the user wants to "get" the value of a property, the
/// getter method will be invoked and its value returned. When the user
/// wants to "set" the value of a property, the setter method will be
/// called. There are three kinds of property: simple (get/set), indexed
/// (get[i1, i2, ...]/set[i1, i2, ...]), and array (count/add/get[i]/
/// set[i]).
/// Objects of class PropertyInfo can't be modified once they have been
/// created, but they can be queried without restrictions. You can either
/// retrieve the accessor methods and invoke them manually, or you can
/// call getValue() / setValue() etc. methods to perform direct operations
/// on the property, given an instance of the declaring type to work on.
/// The latter technique is preferred because it checks for custom
/// attributes associated to the PropertyInfo object and passes control
/// to them when needed.
///
class OSGINTROSPECTION_EXPORT PropertyInfo: public CustomAttributeProvider
{
public:
/// Direct initialization constructor for simple and indexed
/// properties.
/// You must pass the Type object associated to the class that
/// declares the property, the Type object that describes the
/// type of the property's value, the property name and the
/// getter/setter methods. Either the setter or the getter can
/// be null, meaning a restricted access. If both are null, the
/// user is expected to add a custom accessor attribute to this
/// PropertyInfo object.
/// If the getter method has parameters, the property is considered
/// to be indexed. The same is true if the getter is null and the
/// setter has more than one parameter.
PropertyInfo(const Type &decltype, const Type &ptype, const std::string &name, const MethodInfo *getm, const MethodInfo *setm)
: CustomAttributeProvider(),
decltype_(decltype),
ptype_(ptype),
name_(name),
getm_(getm),
setm_(setm),
numm_(0),
addm_(0),
is_array_(false)
{
if (getm_)
{
for (ParameterInfoList::size_type i=0; i<getm_->getParameters().size(); ++i)
indices_.push_back(getm_->getParameters().at(i));
}
else
{
if (setm_)
{
for (ParameterInfoList::size_type i=0; i<(setm_->getParameters().size()-1); ++i)
indices_.push_back(setm_->getParameters().at(i));
}
}
}
/// Direct initialization constructor for "array" properties.
/// You must pass the Type object associated to the type that
/// declares the property, the Type object that describes the
/// type of the property's value, the property name and the
/// getter/setter/counter/adder methods.
PropertyInfo(const Type &decltype, const Type &ptype, const std::string &name, const MethodInfo *getm, const MethodInfo *setm, const MethodInfo *numm, const MethodInfo *addm)
: CustomAttributeProvider(),
decltype_(decltype),
ptype_(ptype),
name_(name),
getm_(getm),
setm_(setm),
numm_(numm),
addm_(addm),
is_array_(true)
{
}
/// Direct initialization constructor for "array" properties.
/// You must pass the Type object associated to the type that
/// declares the property, the Type object that describes the
/// type of the property's value, the property name and the
/// getter/setter/counter/adder methods.
PropertyInfo(const Type &decltype, const Type &ptype, const std::string &name, const MethodInfo *getm, const MethodInfo *setm, const MethodInfo *numm, const MethodInfo *addm)
: CustomAttributeProvider(),
decltype_(decltype),
ptype_(ptype),
name_(name),
getm_(getm),
setm_(setm),
numm_(numm),
addm_(addm),
is_array_(true)
{
}
/// Returns the number of indices
inline int getNumIndices() const
{
return static_cast<int>(getIndexParameters().size());
}
/// Returns the number of indices
inline int getNumIndices() const
{
return static_cast<int>(getIndexParameters().size());
}
/// Returns the name of the property being described.
inline virtual const std::string &getName() const
{
return name_;
}
/// Returns the name of the property being described.
inline virtual const std::string &getName() const
{
return name_;
}
/// Returns the type that declares the property.
inline virtual const Type &getDeclaringType() const
{
return decltype_;
}
/// Returns the type that declares the property.
inline virtual const Type &getDeclaringType() const
{
return decltype_;
}
/// Returns the type of the reflected property.
inline const Type &getPropertyType() const
{
const PropertyTypeAttribute *pta = getAttribute<PropertyTypeAttribute>(false);
if (pta) return pta->getPropertyType();
return ptype_;
}
/// Returns the type of the reflected property.
inline const Type &getPropertyType() const
{
const PropertyTypeAttribute *pta = getAttribute<PropertyTypeAttribute>(false);
if (pta) return pta->getPropertyType();
return ptype_;
}
/// Returns the getter method.
inline const MethodInfo *getGetMethod() const
{
return getm_;
}
/// Returns the getter method.
inline const MethodInfo *getGetMethod() const
{
return getm_;
}
/// Returns the setter method.
inline const MethodInfo *getSetMethod() const
{
return setm_;
}
/// Returns the setter method.
inline const MethodInfo *getSetMethod() const
{
return setm_;
}
/// Returns the counter method.
inline const MethodInfo *getCountMethod() const
{
return numm_;
}
/// Returns the counter method.
inline const MethodInfo *getCountMethod() const
{
return numm_;
}
/// Returns the adder method.
inline const MethodInfo *getAddMethod() const
{
return addm_;
}
/// Returns the adder method.
inline const MethodInfo *getAddMethod() const
{
return addm_;
}
/// Returns whether the property's value can be retrieved.
inline bool canGet() const
{
return (getm_ != 0) || isDefined<CustomPropertyGetAttribute>(false);
}
/// Returns whether the property's value can be retrieved.
inline bool canGet() const
{
return (getm_ != 0) || isDefined<CustomPropertyGetAttribute>(false);
}
/// Returns whether the property's value can be set.
inline bool canSet() const
{
return setm_ != 0 || isDefined<CustomPropertySetAttribute>(false);
}
/// Returns whether the property's value can be set.
inline bool canSet() const
{
return setm_ != 0 || isDefined<CustomPropertySetAttribute>(false);
}
/// Returns whether the property's array of values can be counted.
inline bool canCount() const
{
return numm_ != 0 || isDefined<CustomPropertyCountAttribute>(false);
}
/// Returns whether the property's array of values can be counted.
inline bool canCount() const
{
return numm_ != 0 || isDefined<CustomPropertyCountAttribute>(false);
}
/// Returns whether items can be added to the array property.
inline bool canAdd() const
{
return addm_ != 0 || isDefined<CustomPropertyAddAttribute>(false);
}
/// Returns whether items can be added to the array property.
inline bool canAdd() const
{
return addm_ != 0 || isDefined<CustomPropertyAddAttribute>(false);
}
/// Returns whether the property is simple.
inline bool isSimple() const
{
return !isIndexed() && !isArray();
}
/// Returns whether the property is simple.
inline bool isSimple() const
{
return !isIndexed() && !isArray();
}
/// Returns whether the property is indexed.
inline bool isIndexed() const
{
return getNumIndices() > 0;
}
/// Returns whether the property is indexed.
inline bool isIndexed() const
{
return getNumIndices() > 0;
}
/// Returns whether the property is an array.
inline bool isArray() const
{
return is_array_;
}
/// Returns whether the property is an array.
inline bool isArray() const
{
return is_array_;
}
/// Returns the list of index parameters.
/// If the property is not indexed, this list is empty. If neither
/// the get method nor the set method are defined, this list is
/// empty unless a custom indexing attribute is defined.
const ParameterInfoList &getIndexParameters() const;
/// Returns the list of index parameters.
/// If the property is not indexed, this list is empty. If neither
/// the get method nor the set method are defined, this list is
/// empty unless a custom indexing attribute is defined.
const ParameterInfoList &getIndexParameters() const;
/// Returns a list of valid values that can be used for the specified
/// index. If a custom indexing attribute is defined for this property,
/// then it will be queried for the index set, otherwise the index
/// will be treated as an enumeration and the set of enumeration
/// values will be returned.
void getIndexValueSet(int whichindex, const Value &instance, ValueList &values) const;
/// Returns a list of valid values that can be used for the specified
/// index. If a custom indexing attribute is defined for this property,
/// then it will be queried for the index set, otherwise the index
/// will be treated as an enumeration and the set of enumeration
/// values will be returned.
void getIndexValueSet(int whichindex, const Value &instance, ValueList &values) const;
/// Invokes the getter method on the given instance and
/// returns the property's value. If a custom getter attribute
/// is defined, it will be invoked instead.
Value getValue(const Value &instance) const;
/// Invokes the getter method on the given instance and
/// returns the property's value. If a custom getter attribute
/// is defined, it will be invoked instead.
Value getValue(const Value &instance) const;
/// Invokes the setter method on the given instance and
/// sets the property's value. If a custom setter attribute
/// is defined, it will be invoked instead.
void setValue(Value &instance, const Value &value) const;
/// Invokes the setter method on the given instance and
/// sets the property's value. If a custom setter attribute
/// is defined, it will be invoked instead.
void setValue(Value &instance, const Value &value) const;
/// Invokes the getter method on the given instance passing a list
/// of indices and returns the indexed property's value. If a custom
/// getter attribute is defined, it will be invoked instead.
Value getIndexedValue(const Value &instance, ValueList &indices) const;
/// Invokes the getter method on the given instance passing a list
/// of indices and returns the indexed property's value. If a custom
/// getter attribute is defined, it will be invoked instead.
Value getIndexedValue(const Value &instance, ValueList &indices) const;
/// Invokes the setter method on the given instance passing a list
/// of indices and sets the indexed property's value. If a custom
/// setter attribute is defined, it will be invoked instead.
void setIndexedValue(Value &instance, ValueList &indices, const Value &value) const;
/// Invokes the setter method on the given instance passing a list
/// of indices and sets the indexed property's value. If a custom
/// setter attribute is defined, it will be invoked instead.
void setIndexedValue(Value &instance, ValueList &indices, const Value &value) const;
/// Invokes the counter method on the given instance and returns
/// the number of items of the array property. If a custom counter
/// attribute is defined, it will be invoked instead.
int getNumArrayItems(const Value &instance) const;
/// Invokes the counter method on the given instance and returns
/// the number of items of the array property. If a custom counter
/// attribute is defined, it will be invoked instead.
int getNumArrayItems(const Value &instance) const;
/// Invokes the getter method on the given instance and returns
/// the i-th item of the array property. If a custom getter attribute
/// us defined, it will be invoked instead.
Value getArrayItem(const Value &instance, int i) const;
/// Invokes the getter method on the given instance and returns
/// the i-th item of the array property. If a custom getter attribute
/// us defined, it will be invoked instead.
Value getArrayItem(const Value &instance, int i) const;
/// Invokes the setter method on the given instance and sets
/// the i-th item of the array property. If a custom setter attribute
/// is defined, it will be invoked instead.
void setArrayItem(Value &instance, int i, const Value &value) const;
/// Invokes the setter method on the given instance and sets
/// the i-th item of the array property. If a custom setter attribute
/// is defined, it will be invoked instead.
void setArrayItem(Value &instance, int i, const Value &value) const;
/// Invokes the adder method on the given instance and adds
/// an item to the array property. If a custom adder attribute is
/// defined, it will be invoked instead.
void addArrayItem(Value &instance, const Value &value) const;
/// Invokes the adder method on the given instance and adds
/// an item to the array property. If a custom adder attribute is
/// defined, it will be invoked instead.
void addArrayItem(Value &instance, const Value &value) const;
/// Returns the default value associated to the reflected property.
/// If no default value has been specified, this method tries to
/// create an instance of the property type and then returns its
/// value. There are some attributes that change the behavior of
/// this method, for example NoDefaultValueAttribute.
Value getDefaultValue() const;
/// Returns the default value associated to the reflected property.
/// If no default value has been specified, this method tries to
/// create an instance of the property type and then returns its
/// value. There are some attributes that change the behavior of
/// this method, for example NoDefaultValueAttribute.
Value getDefaultValue() const;
protected:
virtual void getInheritedProviders(CustomAttributeProviderList &providers) const;
protected:
virtual void getInheritedProviders(CustomAttributeProviderList &providers) const;
private:
const Type &decltype_;
const Type &ptype_;
std::string name_;
const MethodInfo *getm_;
const MethodInfo *setm_;
const MethodInfo *numm_;
const MethodInfo *addm_;
ParameterInfoList indices_;
bool is_array_;
};
private:
const Type &decltype_;
const Type &ptype_;
std::string name_;
const MethodInfo *getm_;
const MethodInfo *setm_;
const MethodInfo *numm_;
const MethodInfo *addm_;
ParameterInfoList indices_;
bool is_array_;
};
}

View File

@ -16,255 +16,255 @@
namespace osg
{
/// ----------------------------------------------------------------------
/// TEMPORARY FIX
/// (currently osg::Vec? classes don't support input streaming)
/// (currently osg::ref_ptr<> class doesn't support I/O streaming)
inline std::istream& operator >> (std::istream& input, Vec2f& vec)
{
input >> vec._v[0] >> vec._v[1];
return input;
}
/// ----------------------------------------------------------------------
/// TEMPORARY FIX
/// (currently osg::Vec? classes don't support input streaming)
/// (currently osg::ref_ptr<> class doesn't support I/O streaming)
inline std::istream& operator >> (std::istream& input, Vec2f& vec)
{
input >> vec._v[0] >> vec._v[1];
return input;
}
inline std::istream& operator >> (std::istream& input, Vec3f& vec)
{
input >> vec._v[0] >> vec._v[1] >> vec._v[2];
return input;
}
inline std::istream& operator >> (std::istream& input, Vec3f& vec)
{
input >> vec._v[0] >> vec._v[1] >> vec._v[2];
return input;
}
inline std::istream& operator >> (std::istream& input, Vec4& vec)
{
input >> vec._v[0] >> vec._v[1] >> vec._v[2] >> vec._v[3];
return input;
}
inline std::istream& operator >> (std::istream& input, Vec4& vec)
{
input >> vec._v[0] >> vec._v[1] >> vec._v[2] >> vec._v[3];
return input;
}
template<typename T>
std::ostream &operator << (std::ostream &s, const osg::ref_ptr<T> &r)
{
return s << r.get();
}
template<typename T>
std::ostream &operator << (std::ostream &s, const osg::ref_ptr<T> &r)
{
return s << r.get();
}
template<typename T>
std::istream &operator >> (std::istream &s, osg::ref_ptr<T> &r)
{
void *ptr;
s >> ptr;
r = (T *)ptr;
return s;
}
template<typename T>
std::istream &operator >> (std::istream &s, osg::ref_ptr<T> &r)
{
void *ptr;
s >> ptr;
r = (T *)ptr;
return s;
}
///
/// END OF TEMPORARY FIX
/// ----------------------------------------------------------------------
///
/// END OF TEMPORARY FIX
/// ----------------------------------------------------------------------
}
namespace osgIntrospection
{
/// This is the base class for reader/writer objects. A ReaderWriter's
/// purpose is to provide the means for writing the content of a Value
/// object to a stream and for reading it back. Descendants can either
/// be specialized for just one data type or they can handle several
/// types, that's up to the implementor. A derived class is not required
/// to support all streaming operations (text write, text read, bin write
/// and bin read), it can implement just some of them, although full
/// support is strongly encouraged.
class ReaderWriter
{
public:
class Options
{
public:
Options(): fno_(false) {}
virtual ~Options() {}
/// This is the base class for reader/writer objects. A ReaderWriter's
/// purpose is to provide the means for writing the content of a Value
/// object to a stream and for reading it back. Descendants can either
/// be specialized for just one data type or they can handle several
/// types, that's up to the implementor. A derived class is not required
/// to support all streaming operations (text write, text read, bin write
/// and bin read), it can implement just some of them, although full
/// support is strongly encouraged.
class ReaderWriter
{
public:
class Options
{
public:
Options(): fno_(false) {}
virtual ~Options() {}
bool getForceNumericOutput() const { return fno_; }
void setForceNumericOutput(bool fno) { fno_ = fno; }
bool getForceNumericOutput() const { return fno_; }
void setForceNumericOutput(bool fno) { fno_ = fno; }
private:
bool fno_;
};
private:
bool fno_;
};
/// Writes a textual representation of the value's content to a stream.
virtual std::ostream &writeTextValue(std::ostream &, const Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::TEXT_WRITE, v.getType().getStdTypeInfo()); }
/// Writes a textual representation of the value's content to a stream.
virtual std::ostream &writeTextValue(std::ostream &, const Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::TEXT_WRITE, v.getType().getStdTypeInfo()); }
/// Reads a textual representation of the value's content from a stream.
virtual std::istream &readTextValue(std::istream &, Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::TEXT_READ, v.getType().getStdTypeInfo()); }
/// Reads a textual representation of the value's content from a stream.
virtual std::istream &readTextValue(std::istream &, Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::TEXT_READ, v.getType().getStdTypeInfo()); }
/// Writes a binary representation of the value's content to a stream.
virtual std::ostream &writeBinaryValue(std::ostream &, const Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::BINARY_WRITE, v.getType().getStdTypeInfo()); }
/// Writes a binary representation of the value's content to a stream.
virtual std::ostream &writeBinaryValue(std::ostream &, const Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::BINARY_WRITE, v.getType().getStdTypeInfo()); }
/// Reads a binary representation of the value's content from a stream.
virtual std::istream &readBinaryValue(std::istream &, Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::BINARY_READ, v.getType().getStdTypeInfo()); }
/// Reads a binary representation of the value's content from a stream.
virtual std::istream &readBinaryValue(std::istream &, Value &v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::BINARY_READ, v.getType().getStdTypeInfo()); }
/// Virtual destructor.
virtual ~ReaderWriter() {}
};
/// Virtual destructor.
virtual ~ReaderWriter() {}
};
/// This class template provides basic default streaming capabilities
/// for all types that define streaming operators (<< and >>). Most of
/// the standard types are able to be read and written this way, so the
/// StdReaderWriter template can be a convenient default for several
/// types. The binary representation is a raw copy of the memory content.
///
/// TO-DO: improve binary streaming and avoid arch dependency.
///
template<typename T>
class StdReaderWriter: public ReaderWriter
{
public:
virtual std::ostream &writeTextValue(std::ostream &os, const Value &v, const Options * = 0) const
{
return (os << variant_cast<T>(v));
}
/// This class template provides basic default streaming capabilities
/// for all types that define streaming operators (<< and >>). Most of
/// the standard types are able to be read and written this way, so the
/// StdReaderWriter template can be a convenient default for several
/// types. The binary representation is a raw copy of the memory content.
///
/// TO-DO: improve binary streaming and avoid arch dependency.
///
template<typename T>
class StdReaderWriter: public ReaderWriter
{
public:
virtual std::ostream &writeTextValue(std::ostream &os, const Value &v, const Options * = 0) const
{
return (os << variant_cast<T>(v));
}
virtual std::istream &readTextValue(std::istream &is, Value &v, const Options * = 0) const
{
if (v.isEmpty()) v = Value(T());
return (is >> variant_cast<T &>(v));
}
virtual std::istream &readTextValue(std::istream &is, Value &v, const Options * = 0) const
{
if (v.isEmpty()) v = Value(T());
return (is >> variant_cast<T &>(v));
}
virtual std::ostream &writeBinaryValue(std::ostream &os, const Value &v, const Options * = 0) const
{
return os.write(reinterpret_cast<const char *>(extract_raw_data<T>(v)), sizeof(T));
}
virtual std::ostream &writeBinaryValue(std::ostream &os, const Value &v, const Options * = 0) const
{
return os.write(reinterpret_cast<const char *>(extract_raw_data<T>(v)), sizeof(T));
}
virtual std::istream &readBinaryValue(std::istream &is, Value &v, const Options * = 0) const
{
if (v.isEmpty()) v = Value(T());
return is.read(reinterpret_cast<char *>(extract_raw_data<T>(v)), sizeof(T));
}
virtual std::istream &readBinaryValue(std::istream &is, Value &v, const Options * = 0) const
{
if (v.isEmpty()) v = Value(T());
return is.read(reinterpret_cast<char *>(extract_raw_data<T>(v)), sizeof(T));
}
};
};
/// This ReaderWriter can be used to read and write enumeration values.
/// The textual representation will be the enum label, if found, or the
/// numerical value. The binary representation doesn't take label names
/// into account.
template<typename T>
class EnumReaderWriter: public ReaderWriter
{
virtual std::ostream &writeTextValue(std::ostream &os, const Value &v, const Options *options = 0) const
{
int numeric = static_cast<int>(variant_cast<T>(v));
/// This ReaderWriter can be used to read and write enumeration values.
/// The textual representation will be the enum label, if found, or the
/// numerical value. The binary representation doesn't take label names
/// into account.
template<typename T>
class EnumReaderWriter: public ReaderWriter
{
virtual std::ostream &writeTextValue(std::ostream &os, const Value &v, const Options *options = 0) const
{
int numeric = static_cast<int>(variant_cast<T>(v));
if (!options || !options->getForceNumericOutput())
{
const Type &type = v.getType();
const EnumLabelMap &elm = type.getEnumLabels();
EnumLabelMap::const_iterator i = elm.find(numeric);
if (i != elm.end())
{
os << i->second;
return os;
}
else
{
std::vector<std::string> labels;
if (!options || !options->getForceNumericOutput())
{
const Type &type = v.getType();
const EnumLabelMap &elm = type.getEnumLabels();
EnumLabelMap::const_iterator i = elm.find(numeric);
if (i != elm.end())
{
os << i->second;
return os;
}
else
{
std::vector<std::string> labels;
// it could be a bitmask
for (EnumLabelMap::const_iterator i=elm.begin(); i!=elm.end(); ++i)
{
if (i->first != 0 && ((i->first & numeric) == i->first))
{
numeric ^= i->first;
labels.push_back(i->second);
}
}
// it could be a bitmask
for (EnumLabelMap::const_iterator i=elm.begin(); i!=elm.end(); ++i)
{
if (i->first != 0 && ((i->first & numeric) == i->first))
{
numeric ^= i->first;
labels.push_back(i->second);
}
}
// check whether all bits were discovered
if (numeric == 0)
{
for (std::vector<std::string>::const_iterator i=labels.begin(); i!=labels.end(); ++i)
{
os << *i;
if ((i+1) != labels.end()) os << " | ";
}
return os;
}
}
}
// check whether all bits were discovered
if (numeric == 0)
{
for (std::vector<std::string>::const_iterator i=labels.begin(); i!=labels.end(); ++i)
{
os << *i;
if ((i+1) != labels.end()) os << " | ";
}
return os;
}
}
}
return os << numeric;
}
return os << numeric;
}
virtual std::istream &readTextValue(std::istream &is, Value &v, const Options * = 0) const
{
if (v.isEmpty()) v = Value(T());
virtual std::istream &readTextValue(std::istream &is, Value &v, const Options * = 0) const
{
if (v.isEmpty()) v = Value(T());
int i;
if (is >> i)
{
variant_cast<T &>(v) = static_cast<T>(i);
return is;
}
int i;
if (is >> i)
{
variant_cast<T &>(v) = static_cast<T>(i);
return is;
}
is.clear();
is.clear();
std::string s;
if (is >> s)
{
const Type &type = v.getType();
const EnumLabelMap &elm = type.getEnumLabels();
for (EnumLabelMap::const_iterator i=elm.begin(); i!=elm.end(); ++i)
{
if (i->second.compare(s) == 0)
{
variant_cast<T &>(v) = static_cast<T>(i->first);
return is;
}
}
}
std::string s;
if (is >> s)
{
const Type &type = v.getType();
const EnumLabelMap &elm = type.getEnumLabels();
for (EnumLabelMap::const_iterator i=elm.begin(); i!=elm.end(); ++i)
{
if (i->second.compare(s) == 0)
{
variant_cast<T &>(v) = static_cast<T>(i->first);
return is;
}
}
}
return is;
}
return is;
}
virtual std::ostream &writeBinaryValue(std::ostream &os, const Value &v, const Options *options = 0) const
{
return os.write(reinterpret_cast<const char *>(extract_raw_data<T>(v)), sizeof(T));
}
virtual std::ostream &writeBinaryValue(std::ostream &os, const Value &v, const Options *options = 0) const
{
return os.write(reinterpret_cast<const char *>(extract_raw_data<T>(v)), sizeof(T));
}
virtual std::istream &readBinaryValue(std::istream &is, Value &v, const Options *options = 0) const
{
if (v.isEmpty())
v = Value(T());
return is.read(reinterpret_cast<char *>(extract_raw_data<T>(v)), sizeof(T));
}
virtual std::istream &readBinaryValue(std::istream &is, Value &v, const Options *options = 0) const
{
if (v.isEmpty())
v = Value(T());
return is.read(reinterpret_cast<char *>(extract_raw_data<T>(v)), sizeof(T));
}
};
};
/// This is a ReaderWriter class that can be used to read and write
/// pointer values. Note: template parameter T must be a pointer!
template<typename T>
class PtrReaderWriter: public ReaderWriter
{
public:
virtual std::ostream &writeTextValue(std::ostream &os, const Value &v, const Options* = 0) const
{
return (os << (void*)variant_cast<T>(v));
}
/// This is a ReaderWriter class that can be used to read and write
/// pointer values. Note: template parameter T must be a pointer!
template<typename T>
class PtrReaderWriter: public ReaderWriter
{
public:
virtual std::ostream &writeTextValue(std::ostream &os, const Value &v, const Options* = 0) const
{
return (os << (void*)variant_cast<T>(v));
}
virtual std::istream &readTextValue(std::istream &is, Value &v, const Options* = 0) const
{
void *ptr;
is >> ptr;
v = Value(T(ptr));
return is;
}
virtual std::istream &readTextValue(std::istream &is, Value &v, const Options* = 0) const
{
void *ptr;
is >> ptr;
v = Value(T(ptr));
return is;
}
virtual std::ostream &writeBinaryValue(std::ostream &os, const Value &v, const Options* = 0) const
{
return os.write(reinterpret_cast<const char *>(extract_raw_data<T>(v)), sizeof(T));
}
virtual std::ostream &writeBinaryValue(std::ostream &os, const Value &v, const Options* = 0) const
{
return os.write(reinterpret_cast<const char *>(extract_raw_data<T>(v)), sizeof(T));
}
virtual std::istream &readBinaryValue(std::istream &is, Value &v, const Options* = 0) const
{
T ptr;
is.read(reinterpret_cast<char *>(&ptr), sizeof(T));
v = Value(ptr);
return is;
}
};
virtual std::istream &readBinaryValue(std::istream &is, Value &v, const Options* = 0) const
{
T ptr;
is.read(reinterpret_cast<char *>(&ptr), sizeof(T));
v = Value(ptr);
return is;
}
};
}

View File

@ -14,67 +14,67 @@
namespace osgIntrospection
{
class Type;
class Type;
/// This predicate compares two instances of std::type_info for equality.
/// Note that we can't rely on default pointer comparison because it is
/// not guaranteed that &typeid(T) always returns the same pointer for a
/// given T (thanks Andrew Koenig).
struct TypeInfoCmp
{
bool operator()(const std::type_info *t1, const std::type_info *t2) const
{
return t1->before(*t2) != 0;
}
};
/// This predicate compares two instances of std::type_info for equality.
/// Note that we can't rely on default pointer comparison because it is
/// not guaranteed that &typeid(T) always returns the same pointer for a
/// given T (thanks Andrew Koenig).
struct TypeInfoCmp
{
bool operator()(const std::type_info *t1, const std::type_info *t2) const
{
return t1->before(*t2) != 0;
}
};
/// A map of types, indexed by their associated type_info structure.
typedef std::map<const std::type_info *, Type *, TypeInfoCmp> TypeMap;
/// A map of types, indexed by their associated type_info structure.
typedef std::map<const std::type_info *, Type *, TypeInfoCmp> TypeMap;
/// This class provides basic reflection services such as registration
/// of new types and queries on the global type map.
class OSGINTROSPECTION_EXPORT Reflection
{
public:
/// Returns the Type object associated to the given type_info
/// structure. If the type hasn't been created yet it is
/// automatically created and added to the global type map.
/// Please note that such type will have the status of
/// "declared", you still need to give details about it through
/// a Reflector class before you can query it.
static const Type &getType(const std::type_info &ti);
/// This class provides basic reflection services such as registration
/// of new types and queries on the global type map.
class OSGINTROSPECTION_EXPORT Reflection
{
public:
/// Returns the Type object associated to the given type_info
/// structure. If the type hasn't been created yet it is
/// automatically created and added to the global type map.
/// Please note that such type will have the status of
/// "declared", you still need to give details about it through
/// a Reflector class before you can query it.
static const Type &getType(const std::type_info &ti);
/// Finds a Type object given its qualified name, which must
/// be identical to the qualified name returned by that Type's
/// getQualifiedName() method. If the type hasn't been created
/// yet, an exception is thrown.
static const Type &getType(const std::string &qname);
/// Finds a Type object given its qualified name, which must
/// be identical to the qualified name returned by that Type's
/// getQualifiedName() method. If the type hasn't been created
/// yet, an exception is thrown.
static const Type &getType(const std::string &qname);
/// Returns the global map of types.
static const TypeMap &getTypes();
/// Returns the global map of types.
static const TypeMap &getTypes();
/// Return the Type object associated to the C++ type 'void'.
/// This is a shortcut for typeof(void), which may be slow if
/// the type map is large.
static const Type &type_void();
private:
template<typename C> friend class Reflector;
/// Return the Type object associated to the C++ type 'void'.
/// This is a shortcut for typeof(void), which may be slow if
/// the type map is large.
static const Type &type_void();
private:
template<typename C> friend class Reflector;
struct StaticData
{
TypeMap typemap;
const Type *type_void;
};
struct StaticData
{
TypeMap typemap;
const Type *type_void;
};
static StaticData &getOrCreateStaticData();
static Type *registerType(const std::type_info &ti);
static Type *registerOrReplaceType(const std::type_info &ti);
static StaticData &getOrCreateStaticData();
static Type *registerType(const std::type_info &ti);
static Type *registerOrReplaceType(const std::type_info &ti);
private:
static StaticData *staticdata__;
};
private:
static StaticData *staticdata__;
};
}

View File

@ -32,19 +32,19 @@
// --------------------------------------------------------------------------
#define BEGIN_ENUM_REFLECTOR(c) \
namespace { struct OSG_RM_LINEID(reflector): public osgIntrospection::EnumReflector<c > { OSG_RM_LINEID(reflector)(): inherited(#c) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType();
namespace { struct OSG_RM_LINEID(reflector): public osgIntrospection::EnumReflector<c > { OSG_RM_LINEID(reflector)(): inherited(#c) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType();
#define BEGIN_VALUE_REFLECTOR(c) \
namespace { struct OSG_RM_LINEID(reflector): public osgIntrospection::ValueReflector<c > { OSG_RM_LINEID(reflector)(): inherited(#c, 0) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType();
namespace { struct OSG_RM_LINEID(reflector): public osgIntrospection::ValueReflector<c > { OSG_RM_LINEID(reflector)(): inherited(#c, 0) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType();
#define BEGIN_OBJECT_REFLECTOR(c) \
namespace { struct OSG_RM_LINEID(reflector): public osgIntrospection::ObjectReflector<c > { OSG_RM_LINEID(reflector)(): inherited(#c) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType();
namespace { struct OSG_RM_LINEID(reflector): public osgIntrospection::ObjectReflector<c > { OSG_RM_LINEID(reflector)(): inherited(#c) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType();
#define BEGIN_ABSTRACT_OBJECT_REFLECTOR(c) \
namespace { struct OSG_RM_LINEID(reflector): public osgIntrospection::AbstractObjectReflector<c > { OSG_RM_LINEID(reflector)(): inherited(#c) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType();
namespace { struct OSG_RM_LINEID(reflector): public osgIntrospection::AbstractObjectReflector<c > { OSG_RM_LINEID(reflector)(): inherited(#c) { osgIntrospection::ParameterInfoList params; osgIntrospection::CustomAttributeProvider *cap = getType();
#define END_REFLECTOR \
} } OSG_RM_LINEID(reflector_instance); }
} } OSG_RM_LINEID(reflector_instance); }
// --------------------------------------------------------------------------
@ -66,62 +66,62 @@
// --------------------------------------------------------------------------
#define Property(t, n) \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method0(t, get##n), \
Method1(void, set##n, IN, t, value)))
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method0(t, get##n), \
Method1(void, set##n, IN, t, value)))
#define ReadOnlyProperty(t, n) \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method0(t, get##n), \
0))
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method0(t, get##n), \
0))
#define WriteOnlyProperty(t, n) \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
0, \
Method1(void, set##n, IN, t, value)))
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
0, \
Method1(void, set##n, IN, t, value)))
#define PropertyWithCustomAccessors(t, n) \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
0, \
0))
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
0, \
0))
#define ArrayProperty(t, n, np) \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #np, \
Method1(t, get##n, IN, unsigned int, index), \
Method2(void, set##n, IN, unsigned int, index, IN, t, value), \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #np, \
Method1(t, get##n, IN, unsigned int, index), \
Method2(void, set##n, IN, unsigned int, index, IN, t, value), \
Method0(unsigned int, getNum##np), \
Method1(void, add##n, IN, t, value)))
Method1(void, add##n, IN, t, value)))
#define ArrayPropertyWithCustomAccessors(t, n, np) \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #np, \
0, \
0, \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #np, \
0, \
0))
0, \
0, \
0))
#define ArrayPropertyWithReturnType(t, n, np, r) \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method1(t, get##n, IN, unsigned int, index), \
Method2(r, set##n, IN, unsigned int, index, IN, t, value), \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method1(t, get##n, IN, unsigned int, index), \
Method2(r, set##n, IN, unsigned int, index, IN, t, value), \
Method0(unsigned int, getNum##np), \
Method1(r, add##n, IN, t, value)))
Method1(r, add##n, IN, t, value)))
#define IndexedProperty IndexedProperty1
#define IndexedProperty1(t, n, i0, n0) \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method1(t, get##n, IN, i0, n0), \
Method2(void, set##n, IN, i0, n0, IN, t, value)))
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method1(t, get##n, IN, i0, n0), \
Method2(void, set##n, IN, i0, n0, IN, t, value)))
#define IndexedProperty2(t, n, i0, n0, i1, n1) \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method2(t, get##n, IN, i0, n0, IN, i1, n1), \
Method3(void, set##n, IN, i0, n0, IN i1, n1, IN, t, value)))
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method2(t, get##n, IN, i0, n0, IN, i1, n1), \
Method3(void, set##n, IN, i0, n0, IN i1, n1, IN, t, value)))
#define IndexedProperty3(t, n, i0, n0, i1, n1, i2, n2) \
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method3(t, get##n, IN, i0, n0, IN, i1, n1, IN, i2, n2), \
Method4(void, set##n, IN, i0, n0, IN i1, n1, IN, i2, n2, IN, t, value)))
cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \
Method3(t, get##n, IN, i0, n0, IN, i1, n1, IN, i2, n2), \
Method4(void, set##n, IN, i0, n0, IN i1, n1, IN, i2, n2, IN, t, value)))
// --------------------------------------------------------------------------
// ENUM LABELS

File diff suppressed because it is too large Load Diff

View File

@ -14,394 +14,394 @@
namespace osgIntrospection
{
// forward declarations
class MethodInfo;
class PropertyInfo;
class ParameterInfo;
class ReaderWriter;
// typedefs for member info lists
typedef std::vector<const MethodInfo *> MethodInfoList;
typedef std::vector<const PropertyInfo *> PropertyInfoList;
typedef std::vector<const ParameterInfo *> ParameterInfoList;
// typedef for enum label map
typedef std::map<int, std::string> EnumLabelMap;
/// Base class for instance creators. An instance creator is
/// a lightweight object that creates a Value containing an
/// instance of some type. Every non-abstract Type object has
/// an instance creator that creates instances of that type.
/// This is an abstract interface, it must be derived to
/// provide the actual implementation of createInstance().
struct InstanceCreatorBase
{
virtual Value createInstance() const = 0;
};
/// This is an instance creator to be used with types that ought to
/// be created on the heap, for example all classes derived from
/// osg::Referenced.
template<typename T>
struct InstanceCreator: public InstanceCreatorBase
{
Value createInstance() const
{
return new T();
}
};
/// This is an instance creator to be used with types that can be
/// created on the stack (for example: int, std::string, or other
/// possibly small user-defined structs or classes).
template<typename T>
struct ValueInstanceCreator: public InstanceCreatorBase
{
Value createInstance() const
{
return T();
}
};
/// Objects of class Type are used to maintain information about
/// reflected types. They also provide a number of services, like
/// instance creation and dynamic calling of methods.
/// All details about the data type being described are available
/// at runtime, provided that the type was defined (and not just
/// declared) through a Reflector class.
/// It is not possible to modify a Type object once it has been
/// created, unless you are a class derived from Reflector (which
/// has firm friendship with this class).
class OSGINTROSPECTION_EXPORT Type: public CustomAttributeProvider
{
public:
/// Destructor. Note that this class is not meant to be subclassed.
~Type();
/// Returns a reference to the std::type_info instance associated
/// to this Type.
inline const std::type_info &getStdTypeInfo() const;
/// Returns true if this Type is defined, false if it's just
/// declared. See class Reflector if you want to create a new Type.
inline bool isDefined() const;
/// Returns the name of the reflected type.
inline const std::string &getName() const;
/// Returns the namespace of the reflected type.
inline const std::string &getNamespace() const;
/// Returns the qualified name of the reflected type. The qualified
/// name is formed by the namespace, if present, plus other modifiers
/// like 'const' and/or '*' (pointer) where applicable.
inline std::string getQualifiedName() const;
/// Returns the number of base types.
/// This number is zero if the type is not derived from any other
/// type.
inline int getNumBaseTypes() const;
/// Returns the i-th base type.
inline const Type &getBaseType(int i) const;
/// Returns whether the reflected type is abstract.
inline bool isAbstract() const;
/// Returns whether the reflected type is "atomic", that is
/// it can be rendered to and decoded from a stream directly.
inline bool isAtomic() const;
/// Returns whether the reflected type is an enumeration.
inline bool isEnum() const;
/// Returns whether the reflected type is the type void.
inline bool isVoid() const;
/// Returns true if the reflected type is a pointer, false otherwise.
inline bool isPointer() const;
/// Returns true if the reflected type is a pointer AND it is const,
/// false otherwise.
inline bool isConstPointer() const;
/// Returns true if the reflected type is a pointer AND it is not
/// const, false otherwise.
inline bool isNonConstPointer() const;
/// Returns the pointed type. If the reflected type is not a pointer,
/// the object returned is typeof(void).
inline const Type &getPointedType() const;
/// Returns the list of properties defined for this type. The list
/// does not include properties inherited from base types.
inline const PropertyInfoList &getProperties() const;
/// Fills a list of properties that are either defined in this Type
/// or in inherited types.
void getAllProperties(PropertyInfoList &props) const;
/// Returns the list of methods defined for this type. The list
/// does not include methods inherited from base types.
inline const MethodInfoList &getMethods() const;
/// Fills a list of methods that are either defined in this Type
/// or in inherited types.
void getAllMethods(MethodInfoList &methods) const;
/// Returns the map of enumeration labels. If the type is not an
/// enumeration, an empty map is returned.
inline const EnumLabelMap &getEnumLabels() const;
/// Searches for a method that can be called with the given list of
/// arguments without raising type conversion errors. If more than
/// one method are suitable for calling, the best match is returned.
const MethodInfo *getCompatibleMethod(const std::string &name, const ValueList &values, bool inherit) const;
/// Searches for a method whose parameters match exactly the given
/// list of parameter descriptions.
const MethodInfo *getMethod(const std::string &name, const ParameterInfoList &params, bool inherit) const;
/// Searches for a property given its name, type and list of indices.
/// Only exact matches are returned.
const PropertyInfo *getProperty(const std::string &name, const Type &ptype, const ParameterInfoList &indices, bool inherit) const;
/// Searches for a suitable method and invokes it with the given list
/// of arguments (const instance).
Value invokeMethod(const std::string &name, const Value &instance, ValueList &args, bool inherit) const;
/// Searches for a suitable method and invokes it with the given list
/// of arguments.
Value invokeMethod(const std::string &name, Value &instance, ValueList &args, bool inherit) const;
/// Returns whether the reflected type is derived from another type.
bool isSubclassOf(const Type &type) const;
// forward declarations
class MethodInfo;
class PropertyInfo;
class ParameterInfo;
class ReaderWriter;
// typedefs for member info lists
typedef std::vector<const MethodInfo *> MethodInfoList;
typedef std::vector<const PropertyInfo *> PropertyInfoList;
typedef std::vector<const ParameterInfo *> ParameterInfoList;
// typedef for enum label map
typedef std::map<int, std::string> EnumLabelMap;
/// Base class for instance creators. An instance creator is
/// a lightweight object that creates a Value containing an
/// instance of some type. Every non-abstract Type object has
/// an instance creator that creates instances of that type.
/// This is an abstract interface, it must be derived to
/// provide the actual implementation of createInstance().
struct InstanceCreatorBase
{
virtual Value createInstance() const = 0;
};
/// This is an instance creator to be used with types that ought to
/// be created on the heap, for example all classes derived from
/// osg::Referenced.
template<typename T>
struct InstanceCreator: public InstanceCreatorBase
{
Value createInstance() const
{
return new T();
}
};
/// This is an instance creator to be used with types that can be
/// created on the stack (for example: int, std::string, or other
/// possibly small user-defined structs or classes).
template<typename T>
struct ValueInstanceCreator: public InstanceCreatorBase
{
Value createInstance() const
{
return T();
}
};
/// Objects of class Type are used to maintain information about
/// reflected types. They also provide a number of services, like
/// instance creation and dynamic calling of methods.
/// All details about the data type being described are available
/// at runtime, provided that the type was defined (and not just
/// declared) through a Reflector class.
/// It is not possible to modify a Type object once it has been
/// created, unless you are a class derived from Reflector (which
/// has firm friendship with this class).
class OSGINTROSPECTION_EXPORT Type: public CustomAttributeProvider
{
public:
/// Destructor. Note that this class is not meant to be subclassed.
~Type();
/// Returns a reference to the std::type_info instance associated
/// to this Type.
inline const std::type_info &getStdTypeInfo() const;
/// Returns true if this Type is defined, false if it's just
/// declared. See class Reflector if you want to create a new Type.
inline bool isDefined() const;
/// Returns the name of the reflected type.
inline const std::string &getName() const;
/// Returns the namespace of the reflected type.
inline const std::string &getNamespace() const;
/// Returns the qualified name of the reflected type. The qualified
/// name is formed by the namespace, if present, plus other modifiers
/// like 'const' and/or '*' (pointer) where applicable.
inline std::string getQualifiedName() const;
/// Returns the number of base types.
/// This number is zero if the type is not derived from any other
/// type.
inline int getNumBaseTypes() const;
/// Returns the i-th base type.
inline const Type &getBaseType(int i) const;
/// Returns whether the reflected type is abstract.
inline bool isAbstract() const;
/// Returns whether the reflected type is "atomic", that is
/// it can be rendered to and decoded from a stream directly.
inline bool isAtomic() const;
/// Returns whether the reflected type is an enumeration.
inline bool isEnum() const;
/// Returns whether the reflected type is the type void.
inline bool isVoid() const;
/// Returns true if the reflected type is a pointer, false otherwise.
inline bool isPointer() const;
/// Returns true if the reflected type is a pointer AND it is const,
/// false otherwise.
inline bool isConstPointer() const;
/// Returns true if the reflected type is a pointer AND it is not
/// const, false otherwise.
inline bool isNonConstPointer() const;
/// Returns the pointed type. If the reflected type is not a pointer,
/// the object returned is typeof(void).
inline const Type &getPointedType() const;
/// Returns the list of properties defined for this type. The list
/// does not include properties inherited from base types.
inline const PropertyInfoList &getProperties() const;
/// Fills a list of properties that are either defined in this Type
/// or in inherited types.
void getAllProperties(PropertyInfoList &props) const;
/// Returns the list of methods defined for this type. The list
/// does not include methods inherited from base types.
inline const MethodInfoList &getMethods() const;
/// Fills a list of methods that are either defined in this Type
/// or in inherited types.
void getAllMethods(MethodInfoList &methods) const;
/// Returns the map of enumeration labels. If the type is not an
/// enumeration, an empty map is returned.
inline const EnumLabelMap &getEnumLabels() const;
/// Searches for a method that can be called with the given list of
/// arguments without raising type conversion errors. If more than
/// one method are suitable for calling, the best match is returned.
const MethodInfo *getCompatibleMethod(const std::string &name, const ValueList &values, bool inherit) const;
/// Searches for a method whose parameters match exactly the given
/// list of parameter descriptions.
const MethodInfo *getMethod(const std::string &name, const ParameterInfoList &params, bool inherit) const;
/// Searches for a property given its name, type and list of indices.
/// Only exact matches are returned.
const PropertyInfo *getProperty(const std::string &name, const Type &ptype, const ParameterInfoList &indices, bool inherit) const;
/// Searches for a suitable method and invokes it with the given list
/// of arguments (const instance).
Value invokeMethod(const std::string &name, const Value &instance, ValueList &args, bool inherit) const;
/// Searches for a suitable method and invokes it with the given list
/// of arguments.
Value invokeMethod(const std::string &name, Value &instance, ValueList &args, bool inherit) const;
/// Returns whether the reflected type is derived from another type.
bool isSubclassOf(const Type &type) const;
/// Returns the instance of the reader/writer object assigned to
/// this type, if any. Otherwise it returns the null pointer.
inline const ReaderWriter *getReaderWriter() const;
/// Creates an instance of the reflected type. The returned Value
/// can be casted to T*, where T is the reflected type. If the type
/// is abstract, an exception is thrown.
inline Value createInstance() const;
protected:
Type(const std::type_info &ti)
: ti_(ti),
is_const_(false),
pointed_type_(0),
is_defined_(false),
icb_(0),
rw_(0)
{
}
// throws an exception if the type is not defined.
void check_defined() const;
virtual void getInheritedProviders(CustomAttributeProviderList &providers) const;
void set_instance_creator(const InstanceCreatorBase *icb)
{
delete icb_;
icb_ = icb;
}
private:
template<typename C> friend class Reflector;
friend class Reflection;
Type(const Type &copy): CustomAttributeProvider(copy), ti_(copy.ti_) {}
const std::type_info &ti_;
std::string name_;
std::string namespace_;
typedef std::vector<const Type *> TypeList;
TypeList base_;
bool is_const_;
const Type *pointed_type_;
PropertyInfoList props_;
MethodInfoList methods_;
EnumLabelMap labels_;
bool is_defined_;
const InstanceCreatorBase *icb_;
const ReaderWriter *rw_;
};
// OPERATORS
/// Equality test operator. Returns true if the two instances of Type
/// describe the same type, false otherwise.
inline bool operator==(const Type &t1, const Type &t2)
{
return (t1.getStdTypeInfo() == t2.getStdTypeInfo()) != 0;
}
/// Inequality test operator. Returns false if the two instances of Type
/// describe the same type, true otherwise.
inline bool operator!=(const Type &t1, const Type &t2)
{
return (t1.getStdTypeInfo() != t2.getStdTypeInfo()) != 0;
}
/// Less than operator. Returns true if the first type comes before the
/// second one. The actual ordering is implementation-dependent.
inline bool operator<(const Type &t1, const Type &t2)
{
return (t1.getStdTypeInfo().before(t2.getStdTypeInfo())) != 0;
}
/// Greater than or equal to operator. Returns !operator<().
inline bool operator>=(const Type &t1, const Type &t2)
{
return !operator<(t1, t2);
}
// INLINE METHODS
inline void Type::check_defined() const
{
if (!is_defined_)
throw TypeNotDefinedException(ti_);
}
inline const std::type_info &Type::getStdTypeInfo() const
{
return ti_;
}
inline const std::string &Type::getName() const
{
check_defined();
return name_;
}
inline const std::string &Type::getNamespace() const
{
check_defined();
return namespace_;
}
inline std::string Type::getQualifiedName() const
{
check_defined();
std::string qname;
if (is_const_) qname = "const ";
if (!namespace_.empty())
{
qname.append(namespace_);
qname.append("::");
}
qname.append(name_);
if (pointed_type_)
qname.append(" *");
return qname;
}
inline int Type::getNumBaseTypes() const
{
check_defined();
return static_cast<int>(base_.size());
}
inline bool Type::isConstPointer() const
{
check_defined();
return is_const_ && pointed_type_;
}
inline bool Type::isNonConstPointer() const
{
check_defined();
return !is_const_ && pointed_type_;
}
inline bool Type::isAbstract() const
{
check_defined();
return icb_ == 0;
}
inline bool Type::isAtomic() const
{
check_defined();
return rw_ != 0;
}
inline const PropertyInfoList &Type::getProperties() const
{
check_defined();
return props_;
}
inline const MethodInfoList &Type::getMethods() const
{
check_defined();
return methods_;
}
inline bool Type::isPointer() const
{
check_defined();
return pointed_type_ != 0;
}
inline bool Type::isVoid() const
{
return (ti_ == typeid(void)) != 0;
}
inline const Type &Type::getPointedType() const
{
check_defined();
if (pointed_type_)
return *pointed_type_;
return Reflection::type_void();
}
inline bool Type::isEnum() const
{
check_defined();
return !labels_.empty();
}
inline const EnumLabelMap &Type::getEnumLabels() const
{
check_defined();
return labels_;
}
inline bool Type::isDefined() const
{
return is_defined_;
}
inline const ReaderWriter *Type::getReaderWriter() const
{
check_defined();
return rw_;
}
inline const Type &Type::getBaseType(int i) const
{
check_defined();
return *base_.at(i);
}
inline Value Type::createInstance() const
{
check_defined();
if (!icb_)
throw TypeIsAbstractException(ti_);
return icb_->createInstance();
}
/// Returns the instance of the reader/writer object assigned to
/// this type, if any. Otherwise it returns the null pointer.
inline const ReaderWriter *getReaderWriter() const;
/// Creates an instance of the reflected type. The returned Value
/// can be casted to T*, where T is the reflected type. If the type
/// is abstract, an exception is thrown.
inline Value createInstance() const;
protected:
Type(const std::type_info &ti)
: ti_(ti),
is_const_(false),
pointed_type_(0),
is_defined_(false),
icb_(0),
rw_(0)
{
}
// throws an exception if the type is not defined.
void check_defined() const;
virtual void getInheritedProviders(CustomAttributeProviderList &providers) const;
void set_instance_creator(const InstanceCreatorBase *icb)
{
delete icb_;
icb_ = icb;
}
private:
template<typename C> friend class Reflector;
friend class Reflection;
Type(const Type &copy): CustomAttributeProvider(copy), ti_(copy.ti_) {}
const std::type_info &ti_;
std::string name_;
std::string namespace_;
typedef std::vector<const Type *> TypeList;
TypeList base_;
bool is_const_;
const Type *pointed_type_;
PropertyInfoList props_;
MethodInfoList methods_;
EnumLabelMap labels_;
bool is_defined_;
const InstanceCreatorBase *icb_;
const ReaderWriter *rw_;
};
// OPERATORS
/// Equality test operator. Returns true if the two instances of Type
/// describe the same type, false otherwise.
inline bool operator==(const Type &t1, const Type &t2)
{
return (t1.getStdTypeInfo() == t2.getStdTypeInfo()) != 0;
}
/// Inequality test operator. Returns false if the two instances of Type
/// describe the same type, true otherwise.
inline bool operator!=(const Type &t1, const Type &t2)
{
return (t1.getStdTypeInfo() != t2.getStdTypeInfo()) != 0;
}
/// Less than operator. Returns true if the first type comes before the
/// second one. The actual ordering is implementation-dependent.
inline bool operator<(const Type &t1, const Type &t2)
{
return (t1.getStdTypeInfo().before(t2.getStdTypeInfo())) != 0;
}
/// Greater than or equal to operator. Returns !operator<().
inline bool operator>=(const Type &t1, const Type &t2)
{
return !operator<(t1, t2);
}
// INLINE METHODS
inline void Type::check_defined() const
{
if (!is_defined_)
throw TypeNotDefinedException(ti_);
}
inline const std::type_info &Type::getStdTypeInfo() const
{
return ti_;
}
inline const std::string &Type::getName() const
{
check_defined();
return name_;
}
inline const std::string &Type::getNamespace() const
{
check_defined();
return namespace_;
}
inline std::string Type::getQualifiedName() const
{
check_defined();
std::string qname;
if (is_const_) qname = "const ";
if (!namespace_.empty())
{
qname.append(namespace_);
qname.append("::");
}
qname.append(name_);
if (pointed_type_)
qname.append(" *");
return qname;
}
inline int Type::getNumBaseTypes() const
{
check_defined();
return static_cast<int>(base_.size());
}
inline bool Type::isConstPointer() const
{
check_defined();
return is_const_ && pointed_type_;
}
inline bool Type::isNonConstPointer() const
{
check_defined();
return !is_const_ && pointed_type_;
}
inline bool Type::isAbstract() const
{
check_defined();
return icb_ == 0;
}
inline bool Type::isAtomic() const
{
check_defined();
return rw_ != 0;
}
inline const PropertyInfoList &Type::getProperties() const
{
check_defined();
return props_;
}
inline const MethodInfoList &Type::getMethods() const
{
check_defined();
return methods_;
}
inline bool Type::isPointer() const
{
check_defined();
return pointed_type_ != 0;
}
inline bool Type::isVoid() const
{
return (ti_ == typeid(void)) != 0;
}
inline const Type &Type::getPointedType() const
{
check_defined();
if (pointed_type_)
return *pointed_type_;
return Reflection::type_void();
}
inline bool Type::isEnum() const
{
check_defined();
return !labels_.empty();
}
inline const EnumLabelMap &Type::getEnumLabels() const
{
check_defined();
return labels_;
}
inline bool Type::isDefined() const
{
return is_defined_;
}
inline const ReaderWriter *Type::getReaderWriter() const
{
check_defined();
return rw_;
}
inline const Type &Type::getBaseType(int i) const
{
check_defined();
return *base_.at(i);
}
inline Value Type::createInstance() const
{
check_defined();
if (!icb_)
throw TypeIsAbstractException(ti_);
return icb_->createInstance();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -11,416 +11,416 @@
namespace osgIntrospection
{
class Type;
class OSGINTROSPECTION_EXPORT Value
{
public:
/// Default constructor. Initializes internal structures
/// so that the Type returned by getType() is typeof(void),
/// and the value is empty so that isEmpty() returns true.
/// Be careful when using empty values, as some operations
/// on them may throw an exception.
inline Value();
/// Direct initialization constructor for void pointers.
/// Although one of the constructor templates below could
/// certainly handle void pointers as well, we need to treat
/// them separately because void* can't be dereferenced.
inline Value(void *v);
/// Direct initialization constructor for const void pointers.
/// Although one of the constructor templates below could
/// certainly handle void pointers as well, we need to treat
/// them separately because void* can't be dereferenced.
inline Value(const void *v);
/// Direct initialization constructor template for non-const
/// pointers. By initializing an instance of Value through
/// this constructor, internal structures will be configured
/// to handle polymorphic types. This means you'll be able to
/// call getInstanceType() to get the actual type of the
/// dereferenced value.
template<typename T> Value(T *v);
/// Direct initialization constructor template for non-const
/// pointers. By initializing an instance of Value through
/// this constructor, internal structures will be configured
/// to handle polymorphic types. This means you'll be able to
/// call getInstanceType() to get the actual type of the
/// dereferenced value.
template<typename T> Value(const T *v);
/// Direct initialization constructor template for all types
/// that are not handled by any of the constructors above.
/// Calling getInstanceType() on an instance constructed
/// this way returns the same as getType().
template<typename T> Value(const T &v);
/// Copy constructor. The underlying value's type must have
/// consistent copy semantics.
inline Value(const Value &copy);
/// Destructor. Frees internal resources but it does NOT delete
/// the value held. For example, this function will produce a
/// memory leak: void f() { Value v(new int); }
inline ~Value();
/// Assignment operator. Behaves like the copy constructor.
inline Value &operator=(const Value &copy);
/// Returns whether the value is a pointer and it points to
/// something whose type is different than void.
inline bool isTypedPointer() const;
/// Returns whether this Value is empty.
inline bool isEmpty() const;
/// Returns whether the value is a null pointer.
inline bool isNullPointer() const;
/// Returns the exact type of the value held.
inline const Type &getType() const;
/// If the value is a pointer to a non-void type, this method
/// returns the actual type of the dereferenced pointer. Please
/// note it is not the same as getType().getPointedType(),
/// because the latter would return the non-polymorphic type.
/// If the value is not a pointer, this method behaves like
/// getType().
inline const Type &getInstanceType() const;
/// Equality test operator. Returns true if the value passed
/// as parameter is equal to this instance. The compare() method
/// is used to perform the actual comparison.
inline bool operator==(const Value &other) const;
/// Inequality test operator. Returns !operator==(other).
inline bool operator!=(const Value &other) const;
/// Conversion to bool operator. Returns true if the value is
/// not empty, false otherwise.
inline operator bool() const;
/// Tries to convert this instance to a Value of the given type.
/// The conversion is performed by rendering to a temporary stream
/// in the source format and trying to read back from the stream
/// in the destination format. If either the source or destination
/// types, or both, don't have a ReaderWriter object, the conversion
/// fails and an exception is thrown. If the conversion can't be
/// completed for other reasons, other exceptions may be thrown.
Value convertTo(const Type &outtype) const;
/// Tries to convert this instance to a Value of the given type.
/// The conversion is performed by rendering to a temporary stream
/// in the source format and trying to read back from the stream
/// in the destination format. If either the source or destination
/// types, or both, don't have a ReaderWriter object, the conversion
/// fails and an empty Value is returned.
/// Please note that unlike convertTo(), this method does not
/// intentionally throw any exceptions.
Value tryConvertTo(const Type &outtype) const;
/// Tries to get a string representation of the underlying value.
/// This requires the value's type to have a ReaderWriter object
/// associated to it. If the conversion can't be completed, an
/// exception is thrown.
std::string toString() const;
/// Compares two values for equality. Two empty values are considered
/// equal. If the two values' types are different, a conversion is
/// attempted and then the equality test is performed again.
static bool compare(const Value &v1, const Value &v2);
private:
// It's good to have friends!
template<typename T> friend T variant_cast(const Value &v);
template<typename T> friend T *extract_raw_data(Value &v);
template<typename T> friend const T *extract_raw_data(const Value &v);
// throw an exception if the value is empty
void check_empty() const;
// Base class for holding values. Provides a clone() method
// which must be overriden in descendant classes.
struct Instance_base
{
virtual Instance_base *clone() const = 0;
virtual ~Instance_base() {}
};
// Generic descendant of Instance_base for holding values of
// type T. Note that values are created on the stack.
template<typename T>
struct Instance: Instance_base
{
Instance(T data): data_(data) {}
virtual Instance_base *clone() const { return new Instance<T>(*this); }
virtual ~Instance() {}
T data_;
};
// Base class for storage of Instance objects. Actually three
// instances are created: the main instance which keeps the
// desired value, an additional instance that keeps a reference
// to that value, and another instance that keeps a const
// reference to that value. These additional instances are queried
// when casting the Value to a reference type.
struct Instance_box_base
{
Instance_box_base()
: inst_(0),
ref_inst_(0),
const_ref_inst_(0)
{
}
virtual ~Instance_box_base()
{
delete inst_;
delete ref_inst_;
delete const_ref_inst_;
}
// clones the instance box
virtual Instance_box_base *clone() const = 0;
// returns the type of the value held
virtual const Type *type() const = 0;
// returns the actual pointed type if applicable
virtual const Type *ptype() const { return 0; }
// tests for equality
virtual bool equal(const Value &v) const = 0;
// returns whether the data is a null pointer
virtual bool nullptr() const = 0;
Instance_base *inst_;
Instance_base *ref_inst_;
Instance_base *const_ref_inst_;
};
// Generic instance box for non-pointer values.
template<typename T>
struct Instance_box: Instance_box_base
{
Instance_box(): Instance_box_base(), nullptr_(false) {}
Instance_box(const T &d, bool nullptr = false)
: Instance_box_base(),
nullptr_(nullptr)
{
Instance<T> *vl = new Instance<T>(d);
inst_ = vl;
ref_inst_ = new Instance<T &>(vl->data_);
const_ref_inst_ = new Instance<const T &>(vl->data_);
}
virtual Instance_box_base *clone() const
{
Instance_box<T> *new_inbox = new Instance_box<T>();
// ??? this static_cast<> shouldn't be necessary, but the
// MSVC++ compiler complains about invalid casting without it!
Instance<T> *vl = static_cast<Instance<T> *>(inst_->clone());
new_inbox->inst_ = vl;
new_inbox->ref_inst_ = new Instance<T &>(vl->data_);
new_inbox->const_ref_inst_ = new Instance<const T &>(vl->data_);
new_inbox->nullptr_ = nullptr_;
return new_inbox;
}
virtual const Type *type() const
{
return &typeof(static_cast<Instance<T> *>(inst_)->data_);
}
virtual bool equal(const Value &v) const
{
return static_cast<Instance<T> *>(static_cast<Instance_box<T> *>(v.inbox_)->inst_)->data_ ==
static_cast<Instance<T> *>(inst_)->data_;
}
virtual bool nullptr() const
{
return nullptr_;
}
private:
bool nullptr_;
};
// Generic instance box for pointer values. Unlike Instance_box<>,
// this struct template provides a ptype() method that unreferences
// the pointer (T is supposed to be a pointer) and gets its actual
// type.
template<typename T>
struct Ptr_instance_box: Instance_box_base
{
Ptr_instance_box(): Instance_box_base() {}
Ptr_instance_box(const T &d)
: Instance_box_base()
{
Instance<T> *vl = new Instance<T>(d);
inst_ = vl;
ref_inst_ = new Instance<T &>(vl->data_);
const_ref_inst_ = new Instance<const T &>(vl->data_);
}
virtual Instance_box_base *clone() const
{
Ptr_instance_box<T> *new_inbox = new Ptr_instance_box<T>();
// ??? this static_cast<> shouldn't be necessary, but the
// MSVC++ compiler complains about invalid casting without it!
Instance<T> *vl = static_cast<Instance<T> *>(inst_->clone());
new_inbox->inst_ = vl;
new_inbox->ref_inst_ = new Instance<T &>(vl->data_);
new_inbox->const_ref_inst_ = new Instance<const T &>(vl->data_);
return new_inbox;
}
virtual const Type *type() const
{
return &typeof(static_cast<Instance<T> *>(inst_)->data_);
}
virtual const Type *ptype() const
{
if (!static_cast<Instance<T> *>(inst_)->data_) return 0;
return &typeof(*static_cast<Instance<T> *>(inst_)->data_);
}
virtual bool equal(const Value &v) const
{
return static_cast<Instance<T> *>(static_cast<Instance_box<T> *>(v.inbox_)->inst_)->data_ ==
static_cast<Instance<T> *>(inst_)->data_;
}
virtual bool nullptr() const
{
return static_cast<Instance<T> *>(inst_)->data_ == 0;
}
};
Instance_box_base *inbox_;
const Type *type_;
const Type *ptype_;
};
/// A vector of values.
typedef std::vector<Value> ValueList;
// INLINE METHODS
inline Value::Value()
: inbox_(0),
type_(&Reflection::type_void()),
ptype_(0)
{
}
template<typename T> Value::Value(const T &v)
: ptype_(0)
{
inbox_ = new Instance_box<T>(v);
type_ = inbox_->type();
}
inline Value::Value(const void *v)
: ptype_(0)
{
inbox_ = new Instance_box<const void *>(v, v == 0);
type_ = inbox_->type();
}
inline Value::Value(void *v)
: ptype_(0)
{
inbox_ = new Instance_box<void *>(v, v == 0);
type_ = inbox_->type();
}
template<typename T> Value::Value(const T *v)
{
inbox_ = new Ptr_instance_box<const T *>(v);
type_ = inbox_->type();
ptype_ = inbox_->ptype();
}
template<typename T> Value::Value(T *v)
{
inbox_ = new Ptr_instance_box<T *>(v);
type_ = inbox_->type();
ptype_ = inbox_->ptype();
}
inline Value::Value(const Value &copy)
: inbox_(copy.inbox_? copy.inbox_->clone(): 0),
type_(copy.type_),
ptype_(copy.ptype_)
{
}
inline Value &Value::operator=(const Value &copy)
{
std::auto_ptr<Instance_box_base> new_inbox(copy.inbox_? copy.inbox_->clone(): 0);
delete inbox_;
inbox_ = new_inbox.release();
type_ = copy.type_;
ptype_ = copy.ptype_;
return *this;
}
inline bool Value::operator==(const Value &other) const
{
return compare(*this, other);
}
inline bool Value::operator!=(const Value &other) const
{
return !compare(*this, other);
}
inline Value::operator bool() const
{
return !isEmpty();
}
inline Value::~Value()
{
delete inbox_;
}
inline const Type &Value::getType() const
{
return *type_;
}
inline const Type &Value::getInstanceType() const
{
if (ptype_)
return *ptype_;
return *type_;
}
inline bool Value::isTypedPointer() const
{
return ptype_ != 0;
}
inline bool Value::isEmpty() const
{
return inbox_ == 0;
}
inline bool Value::isNullPointer() const
{
return inbox_->nullptr();
}
class Type;
class OSGINTROSPECTION_EXPORT Value
{
public:
/// Default constructor. Initializes internal structures
/// so that the Type returned by getType() is typeof(void),
/// and the value is empty so that isEmpty() returns true.
/// Be careful when using empty values, as some operations
/// on them may throw an exception.
inline Value();
/// Direct initialization constructor for void pointers.
/// Although one of the constructor templates below could
/// certainly handle void pointers as well, we need to treat
/// them separately because void* can't be dereferenced.
inline Value(void *v);
/// Direct initialization constructor for const void pointers.
/// Although one of the constructor templates below could
/// certainly handle void pointers as well, we need to treat
/// them separately because void* can't be dereferenced.
inline Value(const void *v);
/// Direct initialization constructor template for non-const
/// pointers. By initializing an instance of Value through
/// this constructor, internal structures will be configured
/// to handle polymorphic types. This means you'll be able to
/// call getInstanceType() to get the actual type of the
/// dereferenced value.
template<typename T> Value(T *v);
/// Direct initialization constructor template for non-const
/// pointers. By initializing an instance of Value through
/// this constructor, internal structures will be configured
/// to handle polymorphic types. This means you'll be able to
/// call getInstanceType() to get the actual type of the
/// dereferenced value.
template<typename T> Value(const T *v);
/// Direct initialization constructor template for all types
/// that are not handled by any of the constructors above.
/// Calling getInstanceType() on an instance constructed
/// this way returns the same as getType().
template<typename T> Value(const T &v);
/// Copy constructor. The underlying value's type must have
/// consistent copy semantics.
inline Value(const Value &copy);
/// Destructor. Frees internal resources but it does NOT delete
/// the value held. For example, this function will produce a
/// memory leak: void f() { Value v(new int); }
inline ~Value();
/// Assignment operator. Behaves like the copy constructor.
inline Value &operator=(const Value &copy);
/// Returns whether the value is a pointer and it points to
/// something whose type is different than void.
inline bool isTypedPointer() const;
/// Returns whether this Value is empty.
inline bool isEmpty() const;
/// Returns whether the value is a null pointer.
inline bool isNullPointer() const;
/// Returns the exact type of the value held.
inline const Type &getType() const;
/// If the value is a pointer to a non-void type, this method
/// returns the actual type of the dereferenced pointer. Please
/// note it is not the same as getType().getPointedType(),
/// because the latter would return the non-polymorphic type.
/// If the value is not a pointer, this method behaves like
/// getType().
inline const Type &getInstanceType() const;
/// Equality test operator. Returns true if the value passed
/// as parameter is equal to this instance. The compare() method
/// is used to perform the actual comparison.
inline bool operator==(const Value &other) const;
/// Inequality test operator. Returns !operator==(other).
inline bool operator!=(const Value &other) const;
/// Conversion to bool operator. Returns true if the value is
/// not empty, false otherwise.
inline operator bool() const;
/// Tries to convert this instance to a Value of the given type.
/// The conversion is performed by rendering to a temporary stream
/// in the source format and trying to read back from the stream
/// in the destination format. If either the source or destination
/// types, or both, don't have a ReaderWriter object, the conversion
/// fails and an exception is thrown. If the conversion can't be
/// completed for other reasons, other exceptions may be thrown.
Value convertTo(const Type &outtype) const;
/// Tries to convert this instance to a Value of the given type.
/// The conversion is performed by rendering to a temporary stream
/// in the source format and trying to read back from the stream
/// in the destination format. If either the source or destination
/// types, or both, don't have a ReaderWriter object, the conversion
/// fails and an empty Value is returned.
/// Please note that unlike convertTo(), this method does not
/// intentionally throw any exceptions.
Value tryConvertTo(const Type &outtype) const;
/// Tries to get a string representation of the underlying value.
/// This requires the value's type to have a ReaderWriter object
/// associated to it. If the conversion can't be completed, an
/// exception is thrown.
std::string toString() const;
/// Compares two values for equality. Two empty values are considered
/// equal. If the two values' types are different, a conversion is
/// attempted and then the equality test is performed again.
static bool compare(const Value &v1, const Value &v2);
private:
// It's good to have friends!
template<typename T> friend T variant_cast(const Value &v);
template<typename T> friend T *extract_raw_data(Value &v);
template<typename T> friend const T *extract_raw_data(const Value &v);
// throw an exception if the value is empty
void check_empty() const;
// Base class for holding values. Provides a clone() method
// which must be overriden in descendant classes.
struct Instance_base
{
virtual Instance_base *clone() const = 0;
virtual ~Instance_base() {}
};
// Generic descendant of Instance_base for holding values of
// type T. Note that values are created on the stack.
template<typename T>
struct Instance: Instance_base
{
Instance(T data): data_(data) {}
virtual Instance_base *clone() const { return new Instance<T>(*this); }
virtual ~Instance() {}
T data_;
};
// Base class for storage of Instance objects. Actually three
// instances are created: the main instance which keeps the
// desired value, an additional instance that keeps a reference
// to that value, and another instance that keeps a const
// reference to that value. These additional instances are queried
// when casting the Value to a reference type.
struct Instance_box_base
{
Instance_box_base()
: inst_(0),
ref_inst_(0),
const_ref_inst_(0)
{
}
virtual ~Instance_box_base()
{
delete inst_;
delete ref_inst_;
delete const_ref_inst_;
}
// clones the instance box
virtual Instance_box_base *clone() const = 0;
// returns the type of the value held
virtual const Type *type() const = 0;
// returns the actual pointed type if applicable
virtual const Type *ptype() const { return 0; }
// tests for equality
virtual bool equal(const Value &v) const = 0;
// returns whether the data is a null pointer
virtual bool nullptr() const = 0;
Instance_base *inst_;
Instance_base *ref_inst_;
Instance_base *const_ref_inst_;
};
// Generic instance box for non-pointer values.
template<typename T>
struct Instance_box: Instance_box_base
{
Instance_box(): Instance_box_base(), nullptr_(false) {}
Instance_box(const T &d, bool nullptr = false)
: Instance_box_base(),
nullptr_(nullptr)
{
Instance<T> *vl = new Instance<T>(d);
inst_ = vl;
ref_inst_ = new Instance<T &>(vl->data_);
const_ref_inst_ = new Instance<const T &>(vl->data_);
}
virtual Instance_box_base *clone() const
{
Instance_box<T> *new_inbox = new Instance_box<T>();
// ??? this static_cast<> shouldn't be necessary, but the
// MSVC++ compiler complains about invalid casting without it!
Instance<T> *vl = static_cast<Instance<T> *>(inst_->clone());
new_inbox->inst_ = vl;
new_inbox->ref_inst_ = new Instance<T &>(vl->data_);
new_inbox->const_ref_inst_ = new Instance<const T &>(vl->data_);
new_inbox->nullptr_ = nullptr_;
return new_inbox;
}
virtual const Type *type() const
{
return &typeof(static_cast<Instance<T> *>(inst_)->data_);
}
virtual bool equal(const Value &v) const
{
return static_cast<Instance<T> *>(static_cast<Instance_box<T> *>(v.inbox_)->inst_)->data_ ==
static_cast<Instance<T> *>(inst_)->data_;
}
virtual bool nullptr() const
{
return nullptr_;
}
private:
bool nullptr_;
};
// Generic instance box for pointer values. Unlike Instance_box<>,
// this struct template provides a ptype() method that unreferences
// the pointer (T is supposed to be a pointer) and gets its actual
// type.
template<typename T>
struct Ptr_instance_box: Instance_box_base
{
Ptr_instance_box(): Instance_box_base() {}
Ptr_instance_box(const T &d)
: Instance_box_base()
{
Instance<T> *vl = new Instance<T>(d);
inst_ = vl;
ref_inst_ = new Instance<T &>(vl->data_);
const_ref_inst_ = new Instance<const T &>(vl->data_);
}
virtual Instance_box_base *clone() const
{
Ptr_instance_box<T> *new_inbox = new Ptr_instance_box<T>();
// ??? this static_cast<> shouldn't be necessary, but the
// MSVC++ compiler complains about invalid casting without it!
Instance<T> *vl = static_cast<Instance<T> *>(inst_->clone());
new_inbox->inst_ = vl;
new_inbox->ref_inst_ = new Instance<T &>(vl->data_);
new_inbox->const_ref_inst_ = new Instance<const T &>(vl->data_);
return new_inbox;
}
virtual const Type *type() const
{
return &typeof(static_cast<Instance<T> *>(inst_)->data_);
}
virtual const Type *ptype() const
{
if (!static_cast<Instance<T> *>(inst_)->data_) return 0;
return &typeof(*static_cast<Instance<T> *>(inst_)->data_);
}
virtual bool equal(const Value &v) const
{
return static_cast<Instance<T> *>(static_cast<Instance_box<T> *>(v.inbox_)->inst_)->data_ ==
static_cast<Instance<T> *>(inst_)->data_;
}
virtual bool nullptr() const
{
return static_cast<Instance<T> *>(inst_)->data_ == 0;
}
};
Instance_box_base *inbox_;
const Type *type_;
const Type *ptype_;
};
/// A vector of values.
typedef std::vector<Value> ValueList;
// INLINE METHODS
inline Value::Value()
: inbox_(0),
type_(&Reflection::type_void()),
ptype_(0)
{
}
template<typename T> Value::Value(const T &v)
: ptype_(0)
{
inbox_ = new Instance_box<T>(v);
type_ = inbox_->type();
}
inline Value::Value(const void *v)
: ptype_(0)
{
inbox_ = new Instance_box<const void *>(v, v == 0);
type_ = inbox_->type();
}
inline Value::Value(void *v)
: ptype_(0)
{
inbox_ = new Instance_box<void *>(v, v == 0);
type_ = inbox_->type();
}
template<typename T> Value::Value(const T *v)
{
inbox_ = new Ptr_instance_box<const T *>(v);
type_ = inbox_->type();
ptype_ = inbox_->ptype();
}
template<typename T> Value::Value(T *v)
{
inbox_ = new Ptr_instance_box<T *>(v);
type_ = inbox_->type();
ptype_ = inbox_->ptype();
}
inline Value::Value(const Value &copy)
: inbox_(copy.inbox_? copy.inbox_->clone(): 0),
type_(copy.type_),
ptype_(copy.ptype_)
{
}
inline Value &Value::operator=(const Value &copy)
{
std::auto_ptr<Instance_box_base> new_inbox(copy.inbox_? copy.inbox_->clone(): 0);
delete inbox_;
inbox_ = new_inbox.release();
type_ = copy.type_;
ptype_ = copy.ptype_;
return *this;
}
inline bool Value::operator==(const Value &other) const
{
return compare(*this, other);
}
inline bool Value::operator!=(const Value &other) const
{
return !compare(*this, other);
}
inline Value::operator bool() const
{
return !isEmpty();
}
inline Value::~Value()
{
delete inbox_;
}
inline const Type &Value::getType() const
{
return *type_;
}
inline const Type &Value::getInstanceType() const
{
if (ptype_)
return *ptype_;
return *type_;
}
inline bool Value::isTypedPointer() const
{
return ptype_ != 0;
}
inline bool Value::isEmpty() const
{
return inbox_ == 0;
}
inline bool Value::isNullPointer() const
{
return inbox_->nullptr();
}
}

View File

@ -9,54 +9,54 @@
namespace osgIntrospection
{
/// Tries to convert an instance of Value to an object of type T.
/// If T is a plain type or a pointer type (either const or non-const),
/// and it matches the type of the value contained in v, then the actual
/// value of type T is returned. If T is a [const] reference type, and
/// its base (non reference) type matches the internal value's type,
/// then a [const] reference to the internal value is returned.
/// If none of the above conditions are met, a conversion is attempted
/// as described in Value::convert() and then variant_cast is called again
/// with the converted value as parameter.
/// If the conversion can't be completed, an exception is thrown.
/// Conversions that attempt to make a const pointer non-const will fail.
template<typename T> T variant_cast(const Value &v)
{
// return value
Value::Instance<T> *i = dynamic_cast<Value::Instance<T> *>(v.inbox_->inst_);
if (i) return i->data_;
/// Tries to convert an instance of Value to an object of type T.
/// If T is a plain type or a pointer type (either const or non-const),
/// and it matches the type of the value contained in v, then the actual
/// value of type T is returned. If T is a [const] reference type, and
/// its base (non reference) type matches the internal value's type,
/// then a [const] reference to the internal value is returned.
/// If none of the above conditions are met, a conversion is attempted
/// as described in Value::convert() and then variant_cast is called again
/// with the converted value as parameter.
/// If the conversion can't be completed, an exception is thrown.
/// Conversions that attempt to make a const pointer non-const will fail.
template<typename T> T variant_cast(const Value &v)
{
// return value
Value::Instance<T> *i = dynamic_cast<Value::Instance<T> *>(v.inbox_->inst_);
if (i) return i->data_;
// return reference to value
i = dynamic_cast<Value::Instance<T> *>(v.inbox_->ref_inst_);
if (i) return i->data_;
// return reference to value
i = dynamic_cast<Value::Instance<T> *>(v.inbox_->ref_inst_);
if (i) return i->data_;
// return const reference to value
i = dynamic_cast<Value::Instance<T> *>(v.inbox_->const_ref_inst_);
if (i) return i->data_;
// return const reference to value
i = dynamic_cast<Value::Instance<T> *>(v.inbox_->const_ref_inst_);
if (i) return i->data_;
// try to convert v to type T and restart
return variant_cast<T>(v.convertTo(typeof(T)));
}
// try to convert v to type T and restart
return variant_cast<T>(v.convertTo(typeof(T)));
}
/// Returns a typed pointer to the data contained in a Value
/// instance. If the value's type is not identical to type T,
/// a null pointer is returned.
template<typename T> T *extract_raw_data(Value &v)
{
Value::Instance<T> *i = dynamic_cast<Value::Instance<T> *>(v.inbox_->inst_);
if (i) return &i->data_;
return 0;
}
/// Returns a typed pointer to the data contained in a Value
/// instance. If the value's type is not identical to type T,
/// a null pointer is returned.
template<typename T> T *extract_raw_data(Value &v)
{
Value::Instance<T> *i = dynamic_cast<Value::Instance<T> *>(v.inbox_->inst_);
if (i) return &i->data_;
return 0;
}
/// Returns a typed pointer to the data contained in a const Value
/// instance. If the value's type is not identical to type T, a
/// null pointer is returned.
template<typename T> const T *extract_raw_data(const Value &v)
{
Value::Instance<T> *i = dynamic_cast<Value::Instance<T> *>(v.inbox_->inst_);
if (i) return &i->data_;
return 0;
}
/// Returns a typed pointer to the data contained in a const Value
/// instance. If the value's type is not identical to type T, a
/// null pointer is returned.
template<typename T> const T *extract_raw_data(const Value &v)
{
Value::Instance<T> *i = dynamic_cast<Value::Instance<T> *>(v.inbox_->inst_);
if (i) return &i->data_;
return 0;
}
}

View File

@ -5,39 +5,39 @@ using namespace osgIntrospection;
bool CustomAttributeProvider::isDefined(const Type &type, bool inherit) const
{
for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i)
if (typeid(**i) == type.getStdTypeInfo()) return true;
for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i)
if (typeid(**i) == type.getStdTypeInfo()) return true;
if (inherit)
{
CustomAttributeProviderList providers;
getInheritedProviders(providers);
if (inherit)
{
CustomAttributeProviderList providers;
getInheritedProviders(providers);
for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i)
{
if ((*i)->isDefined(type, true)) return true;
}
}
for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i)
{
if ((*i)->isDefined(type, true)) return true;
}
}
return false;
return false;
}
const CustomAttribute *CustomAttributeProvider::getAttribute(const Type &type, bool inherit) const
{
for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i)
if (typeid(**i) == type.getStdTypeInfo()) return *i;
for (CustomAttributeList::const_iterator i=attribs_.begin(); i!=attribs_.end(); ++i)
if (typeid(**i) == type.getStdTypeInfo()) return *i;
if (inherit)
{
CustomAttributeProviderList providers;
getInheritedProviders(providers);
if (inherit)
{
CustomAttributeProviderList providers;
getInheritedProviders(providers);
for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i)
{
const CustomAttribute *ca = (*i)->getAttribute(type, true);
if (ca) return ca;
}
}
for (CustomAttributeProviderList::const_iterator i=providers.begin(); i!=providers.end(); ++i)
{
const CustomAttribute *ca = (*i)->getAttribute(type, true);
if (ca) return ca;
}
}
return 0;
return 0;
}

View File

@ -4,12 +4,12 @@ using namespace osgIntrospection;
void MethodInfo::getInheritedProviders(CustomAttributeProviderList &providers) const
{
for (int i=0; i<decltype_.getNumBaseTypes(); ++i)
{
const MethodInfo *mi = decltype_.getBaseType(i).getMethod(name_, params_, false);
if (mi)
{
providers.push_back(mi);
}
}
for (int i=0; i<decltype_.getNumBaseTypes(); ++i)
{
const MethodInfo *mi = decltype_.getBaseType(i).getMethod(name_, params_, false);
if (mi)
{
providers.push_back(mi);
}
}
}

View File

@ -6,228 +6,228 @@ using namespace osgIntrospection;
void PropertyInfo::getInheritedProviders(CustomAttributeProviderList &providers) const
{
for (int i=0; i<decltype_.getNumBaseTypes(); ++i)
{
const PropertyInfo *pi = decltype_.getBaseType(i).getProperty(name_, ptype_, getIndexParameters(), false);
if (pi)
{
providers.push_back(pi);
}
}
for (int i=0; i<decltype_.getNumBaseTypes(); ++i)
{
const PropertyInfo *pi = decltype_.getBaseType(i).getProperty(name_, ptype_, getIndexParameters(), false);
if (pi)
{
providers.push_back(pi);
}
}
}
Value PropertyInfo::getValue(const Value &instance) const
{
const PropertyTypeAttribute *pta = getAttribute<PropertyTypeAttribute>(false);
const CustomPropertyGetAttribute *cget = getAttribute<CustomPropertyGetAttribute>(false);
const PropertyTypeAttribute *pta = getAttribute<PropertyTypeAttribute>(false);
const CustomPropertyGetAttribute *cget = getAttribute<CustomPropertyGetAttribute>(false);
if (cget)
{
if (pta)
return cget->getGetter()->get(instance).convertTo(pta->getPropertyType());
return cget->getGetter()->get(instance);
}
if (cget)
{
if (pta)
return cget->getGetter()->get(instance).convertTo(pta->getPropertyType());
return cget->getGetter()->get(instance);
}
if (!getm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::GET);
if (!getm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::GET);
if (pta)
return getm_->invoke(instance).convertTo(pta->getPropertyType());
return getm_->invoke(instance);
if (pta)
return getm_->invoke(instance).convertTo(pta->getPropertyType());
return getm_->invoke(instance);
}
void PropertyInfo::setValue(Value &instance, const Value &value) const
{
const CustomPropertySetAttribute *cset = getAttribute<CustomPropertySetAttribute>(false);
const CustomPropertySetAttribute *cset = getAttribute<CustomPropertySetAttribute>(false);
if (cset)
{
cset->getSetter()->set(instance, value);
return;
}
if (cset)
{
cset->getSetter()->set(instance, value);
return;
}
if (!setm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::SET);
if (!setm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::SET);
ValueList args;
args.push_back(value);
setm_->invoke(instance, args);
ValueList args;
args.push_back(value);
setm_->invoke(instance, args);
}
Value PropertyInfo::getIndexedValue(const Value &instance, ValueList &args) const
{
const PropertyTypeAttribute *pta = getAttribute<PropertyTypeAttribute>(false);
const CustomPropertyGetAttribute *cget = getAttribute<CustomPropertyGetAttribute>(false);
const PropertyTypeAttribute *pta = getAttribute<PropertyTypeAttribute>(false);
const CustomPropertyGetAttribute *cget = getAttribute<CustomPropertyGetAttribute>(false);
if (cget)
{
if (pta)
return cget->getGetter()->get(instance, args).convertTo(pta->getPropertyType());
return cget->getGetter()->get(instance, args);
}
if (cget)
{
if (pta)
return cget->getGetter()->get(instance, args).convertTo(pta->getPropertyType());
return cget->getGetter()->get(instance, args);
}
if (!getm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::IGET);
if (!getm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::IGET);
if (pta)
return getm_->invoke(instance, args).convertTo(pta->getPropertyType());
return getm_->invoke(instance, args);
if (pta)
return getm_->invoke(instance, args).convertTo(pta->getPropertyType());
return getm_->invoke(instance, args);
}
void PropertyInfo::setIndexedValue(Value &instance, ValueList &args, const Value &value) const
{
const CustomPropertySetAttribute *cset = getAttribute<CustomPropertySetAttribute>(false);
if (cset)
{
cset->getSetter()->set(instance, args, value);
return;
}
const CustomPropertySetAttribute *cset = getAttribute<CustomPropertySetAttribute>(false);
if (cset)
{
cset->getSetter()->set(instance, args, value);
return;
}
if (!setm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::ISET);
if (!setm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::ISET);
args.push_back(value);
setm_->invoke(instance, args);
args.pop_back();
args.push_back(value);
setm_->invoke(instance, args);
args.pop_back();
}
int PropertyInfo::getNumArrayItems(const Value &instance) const
{
const CustomPropertyCountAttribute *ccount = getAttribute<CustomPropertyCountAttribute>(false);
if (ccount) return ccount->getCounter()->count(instance);
const CustomPropertyCountAttribute *ccount = getAttribute<CustomPropertyCountAttribute>(false);
if (ccount) return ccount->getCounter()->count(instance);
if (!numm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::COUNT);
if (!numm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::COUNT);
return variant_cast<int>(numm_->invoke(instance));
return variant_cast<int>(numm_->invoke(instance));
}
Value PropertyInfo::getArrayItem(const Value &instance, int i) const
{
const PropertyTypeAttribute *pta = getAttribute<PropertyTypeAttribute>(false);
const CustomPropertyGetAttribute *cget = getAttribute<CustomPropertyGetAttribute>(false);
const PropertyTypeAttribute *pta = getAttribute<PropertyTypeAttribute>(false);
const CustomPropertyGetAttribute *cget = getAttribute<CustomPropertyGetAttribute>(false);
if (cget)
{
if (pta)
return cget->getGetter()->get(instance, i).convertTo(pta->getPropertyType());
return cget->getGetter()->get(instance, i);
}
if (cget)
{
if (pta)
return cget->getGetter()->get(instance, i).convertTo(pta->getPropertyType());
return cget->getGetter()->get(instance, i);
}
if (!getm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::AGET);
if (!getm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::AGET);
ValueList args;
args.push_back(i);
ValueList args;
args.push_back(i);
if (pta)
return getm_->invoke(instance, args).convertTo(pta->getPropertyType());
return getm_->invoke(instance, args);
if (pta)
return getm_->invoke(instance, args).convertTo(pta->getPropertyType());
return getm_->invoke(instance, args);
}
void PropertyInfo::setArrayItem(Value &instance, int i, const Value &value) const
{
const CustomPropertySetAttribute *cset = getAttribute<CustomPropertySetAttribute>(false);
if (cset)
{
cset->getSetter()->set(instance, i, value);
return;
}
if (!setm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::ASET);
const CustomPropertySetAttribute *cset = getAttribute<CustomPropertySetAttribute>(false);
if (cset)
{
cset->getSetter()->set(instance, i, value);
return;
}
if (!setm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::ASET);
ValueList args;
args.push_back(i);
args.push_back(value);
setm_->invoke(instance, args);
ValueList args;
args.push_back(i);
args.push_back(value);
setm_->invoke(instance, args);
}
void PropertyInfo::addArrayItem(Value &instance, const Value &value) const
{
const CustomPropertyAddAttribute *cadd = getAttribute<CustomPropertyAddAttribute>(false);
if (cadd)
{
cadd->getAdder()->add(instance, value);
return;
}
const CustomPropertyAddAttribute *cadd = getAttribute<CustomPropertyAddAttribute>(false);
if (cadd)
{
cadd->getAdder()->add(instance, value);
return;
}
if (!addm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::ADD);
if (!addm_)
throw PropertyAccessException(decltype_.getQualifiedName() + "::" + name_, PropertyAccessException::ADD);
ValueList args;
args.push_back(value);
addm_->invoke(instance, args);
ValueList args;
args.push_back(value);
addm_->invoke(instance, args);
}
Value PropertyInfo::getDefaultValue() const
{
if (isArray() || isIndexed()) return Value();
if (isArray() || isIndexed()) return Value();
const CustomAttributeList &cal = getCustomAttributes();
for (CustomAttributeList::const_iterator i=cal.begin(); i!=cal.end(); ++i)
{
if (dynamic_cast<const NoDefaultValueAttribute *>(*i) != 0)
return Value();
const CustomAttributeList &cal = getCustomAttributes();
for (CustomAttributeList::const_iterator i=cal.begin(); i!=cal.end(); ++i)
{
if (dynamic_cast<const NoDefaultValueAttribute *>(*i) != 0)
return Value();
const DefaultValueAttribute *dv = dynamic_cast<const DefaultValueAttribute *>(*i);
if (dv)
{
return dv->getDefaultValue();
}
}
const DefaultValueAttribute *dv = dynamic_cast<const DefaultValueAttribute *>(*i);
if (dv)
{
return dv->getDefaultValue();
}
}
if (decltype_.isAbstract())
{
if (ptype_.isAbstract() || !ptype_.isDefined())
return Value();
return ptype_.createInstance();
}
if (decltype_.isAbstract())
{
if (ptype_.isAbstract() || !ptype_.isDefined())
return Value();
return ptype_.createInstance();
}
// auto default value
Value instance = decltype_.createInstance();
return getValue(instance);
// auto default value
Value instance = decltype_.createInstance();
return getValue(instance);
}
void PropertyInfo::getIndexValueSet(int whichindex, const Value &instance, ValueList &values) const
{
const CustomIndexAttribute *cia = getAttribute<CustomIndexAttribute>(false);
if (cia)
{
cia->getIndexInfo()->getIndexValueSet(whichindex, instance, values);
}
else
{
std::map<int, const IndexTypeAttribute *> ita_map;
const CustomAttributeList &cal = getCustomAttributes();
for (CustomAttributeList::const_iterator i=cal.begin(); i!=cal.end(); ++i)
{
const IndexTypeAttribute *ita = dynamic_cast<const IndexTypeAttribute *>(*i);
if (ita)
ita_map[ita->getWhichIndex()] = ita;
}
const CustomIndexAttribute *cia = getAttribute<CustomIndexAttribute>(false);
if (cia)
{
cia->getIndexInfo()->getIndexValueSet(whichindex, instance, values);
}
else
{
std::map<int, const IndexTypeAttribute *> ita_map;
const CustomAttributeList &cal = getCustomAttributes();
for (CustomAttributeList::const_iterator i=cal.begin(); i!=cal.end(); ++i)
{
const IndexTypeAttribute *ita = dynamic_cast<const IndexTypeAttribute *>(*i);
if (ita)
ita_map[ita->getWhichIndex()] = ita;
}
const EnumLabelMap &elm = getIndexParameters().at(whichindex)->getParameterType().getEnumLabels();
if (elm.empty())
throw IndexValuesNotDefinedException(name_, getIndexParameters().at(whichindex)->getName());
const EnumLabelMap &elm = getIndexParameters().at(whichindex)->getParameterType().getEnumLabels();
if (elm.empty())
throw IndexValuesNotDefinedException(name_, getIndexParameters().at(whichindex)->getName());
for (EnumLabelMap::const_iterator i=elm.begin(); i!=elm.end(); ++i)
{
if (ita_map[whichindex])
values.push_back(Value(i->first).convertTo(ita_map[whichindex]->getIndexType()));
else
values.push_back(Value(i->first).convertTo(indices_[whichindex]->getParameterType()));
}
}
for (EnumLabelMap::const_iterator i=elm.begin(); i!=elm.end(); ++i)
{
if (ita_map[whichindex])
values.push_back(Value(i->first).convertTo(ita_map[whichindex]->getIndexType()));
else
values.push_back(Value(i->first).convertTo(indices_[whichindex]->getParameterType()));
}
}
}
const ParameterInfoList &PropertyInfo::getIndexParameters() const
{
const CustomIndexAttribute *cia = getAttribute<CustomIndexAttribute>(false);
if (cia)
{
return cia->getIndexInfo()->getIndexParameters();
}
const CustomIndexAttribute *cia = getAttribute<CustomIndexAttribute>(false);
if (cia)
{
return cia->getIndexInfo()->getIndexParameters();
}
return indices_;
return indices_;
}

View File

@ -13,66 +13,66 @@ Reflection::StaticData *Reflection::staticdata__ = 0;
const TypeMap &Reflection::getTypes()
{
return getOrCreateStaticData().typemap;
return getOrCreateStaticData().typemap;
}
Reflection::StaticData &Reflection::getOrCreateStaticData()
{
static OpenThreads::Mutex access_mtx;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(access_mtx);
static OpenThreads::Mutex access_mtx;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(access_mtx);
if (!staticdata__)
{
staticdata__ = new StaticData;
std::auto_ptr<Type> tvoid(new Type(typeid(void)));
staticdata__->typemap.insert(std::make_pair(&typeid(void), tvoid.get()));
staticdata__->type_void = tvoid.release();
}
return *staticdata__;
if (!staticdata__)
{
staticdata__ = new StaticData;
std::auto_ptr<Type> tvoid(new Type(typeid(void)));
staticdata__->typemap.insert(std::make_pair(&typeid(void), tvoid.get()));
staticdata__->type_void = tvoid.release();
}
return *staticdata__;
}
const Type &Reflection::getType(const std::type_info &ti)
{
const TypeMap &types = getTypes();
const TypeMap &types = getTypes();
TypeMap::const_iterator i = types.find(&ti);
if (i == types.end())
{
return *registerType(ti);
}
return *i->second;
TypeMap::const_iterator i = types.find(&ti);
if (i == types.end())
{
return *registerType(ti);
}
return *i->second;
}
const Type &Reflection::getType(const std::string &qname)
{
const TypeMap &types = getTypes();
const TypeMap &types = getTypes();
for (TypeMap::const_iterator i=types.begin(); i!=types.end(); ++i)
if (i->second->isDefined() && i->second->getQualifiedName().compare(qname) == 0)
return *i->second;
for (TypeMap::const_iterator i=types.begin(); i!=types.end(); ++i)
if (i->second->isDefined() && i->second->getQualifiedName().compare(qname) == 0)
return *i->second;
throw TypeNotFoundException(qname);
throw TypeNotFoundException(qname);
}
const Type &Reflection::type_void()
{
return *getOrCreateStaticData().type_void;
return *getOrCreateStaticData().type_void;
}
Type *Reflection::registerType(const std::type_info &ti)
{
std::auto_ptr<Type> type(new Type(ti));
getOrCreateStaticData().typemap.insert(std::make_pair(&ti, type.get()));
return type.release();
std::auto_ptr<Type> type(new Type(ti));
getOrCreateStaticData().typemap.insert(std::make_pair(&ti, type.get()));
return type.release();
}
Type *Reflection::registerOrReplaceType(const std::type_info &ti)
{
TypeMap &tm = getOrCreateStaticData().typemap;
TypeMap::iterator i = tm.find(&ti);
TypeMap &tm = getOrCreateStaticData().typemap;
TypeMap::iterator i = tm.find(&ti);
if (i != tm.end())
return new (i->second) Type(ti);
if (i != tm.end())
return new (i->second) Type(ti);
return registerType(ti);
return registerType(ti);
}

View File

@ -13,235 +13,235 @@ using namespace osgIntrospection;
namespace
{
struct MethodMatch
{
int list_pos;
int exact_args;
const MethodInfo *method;
struct MethodMatch
{
int list_pos;
int exact_args;
const MethodInfo *method;
bool operator < (const MethodMatch &m) const
{
if (exact_args > m.exact_args) return true;
if (exact_args < m.exact_args) return false;
if (list_pos < m.list_pos) return true;
return false;
}
};
bool operator < (const MethodMatch &m) const
{
if (exact_args > m.exact_args) return true;
if (exact_args < m.exact_args) return false;
if (list_pos < m.list_pos) return true;
return false;
}
};
}
Type::~Type()
{
for (PropertyInfoList::const_iterator i=props_.begin(); i!=props_.end(); ++i)
delete *i;
for (MethodInfoList::const_iterator i=methods_.begin(); i!=methods_.end(); ++i)
delete *i;
delete icb_;
delete rw_;
for (PropertyInfoList::const_iterator i=props_.begin(); i!=props_.end(); ++i)
delete *i;
for (MethodInfoList::const_iterator i=methods_.begin(); i!=methods_.end(); ++i)
delete *i;
delete icb_;
delete rw_;
}
bool Type::isSubclassOf(const Type &type) const
{
check_defined();
for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i)
{
if (**i == type.getStdTypeInfo())
return true;
if ((*i)->isSubclassOf(type))
return true;
}
return false;
check_defined();
for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i)
{
if (**i == type.getStdTypeInfo())
return true;
if ((*i)->isSubclassOf(type))
return true;
}
return false;
}
const MethodInfo *Type::getCompatibleMethod(const std::string &name, const ValueList &values, bool inherit) const
{
check_defined();
check_defined();
MethodInfoList allmethods;
const MethodInfoList *methods;
if (inherit)
{
getAllMethods(allmethods);
methods = &allmethods;
}
else
methods = &methods_;
MethodInfoList allmethods;
const MethodInfoList *methods;
if (inherit)
{
getAllMethods(allmethods);
methods = &allmethods;
}
else
methods = &methods_;
typedef std::vector<MethodMatch> MatchList;
MatchList matches;
typedef std::vector<MethodMatch> MatchList;
MatchList matches;
int pos = 0;
for (MethodInfoList::const_iterator j=methods->begin(); j!=methods->end(); ++j, ++pos)
{
const MethodInfo *mi = *j;
if (mi->getName().compare(name) == 0)
{
const ParameterInfoList &other_params = mi->getParameters();
if (values.size() == other_params.size())
{
if (values.empty())
return mi;
ParameterInfoList::const_iterator i1 = other_params.begin();
ValueList::const_iterator i2 = values.begin();
bool candidate = true;
int exact_args = 0;
for (; i1<other_params.end(); ++i1, ++i2)
{
if ((*i1)->getParameterType() != i2->getType())
{
if (i2->tryConvertTo((*i1)->getParameterType()).isEmpty())
{
candidate = false;
break;
}
}
else
++exact_args;
}
if (candidate)
{
MethodMatch mm;
mm.list_pos = pos;
mm.exact_args = exact_args;
mm.method = mi;
matches.push_back(mm);
}
}
}
}
int pos = 0;
for (MethodInfoList::const_iterator j=methods->begin(); j!=methods->end(); ++j, ++pos)
{
const MethodInfo *mi = *j;
if (mi->getName().compare(name) == 0)
{
const ParameterInfoList &other_params = mi->getParameters();
if (values.size() == other_params.size())
{
if (values.empty())
return mi;
ParameterInfoList::const_iterator i1 = other_params.begin();
ValueList::const_iterator i2 = values.begin();
bool candidate = true;
int exact_args = 0;
for (; i1<other_params.end(); ++i1, ++i2)
{
if ((*i1)->getParameterType() != i2->getType())
{
if (i2->tryConvertTo((*i1)->getParameterType()).isEmpty())
{
candidate = false;
break;
}
}
else
++exact_args;
}
if (candidate)
{
MethodMatch mm;
mm.list_pos = pos;
mm.exact_args = exact_args;
mm.method = mi;
matches.push_back(mm);
}
}
}
}
if (!matches.empty())
{
std::sort(matches.begin(), matches.end());
return matches.front().method;
}
if (!matches.empty())
{
std::sort(matches.begin(), matches.end());
return matches.front().method;
}
return 0;
return 0;
}
const MethodInfo *Type::getMethod(const std::string &name, const ParameterInfoList &params, bool inherit) const
{
check_defined();
for (MethodInfoList::const_iterator j=methods_.begin(); j!=methods_.end(); ++j)
{
const MethodInfo &mi = **j;
if (mi.getName().compare(name) == 0)
{
const ParameterInfoList &other_params = mi.getParameters();
if (params.size() == other_params.size())
{
if (params.empty())
return &mi;
ParameterInfoList::const_iterator i1 = params.begin();
ParameterInfoList::const_iterator i2 = other_params.begin();
for (; i1<params.end(); ++i1, ++i2)
{
const ParameterInfo &p1 = **i1;
const ParameterInfo &p2 = **i2;
if (p1.getParameterType() == p2.getParameterType() &&
p1.getAttributes() == p2.getAttributes() &&
p1.getPosition() == p2.getPosition())
{
return &mi;
}
}
}
}
}
check_defined();
for (MethodInfoList::const_iterator j=methods_.begin(); j!=methods_.end(); ++j)
{
const MethodInfo &mi = **j;
if (mi.getName().compare(name) == 0)
{
const ParameterInfoList &other_params = mi.getParameters();
if (params.size() == other_params.size())
{
if (params.empty())
return &mi;
ParameterInfoList::const_iterator i1 = params.begin();
ParameterInfoList::const_iterator i2 = other_params.begin();
for (; i1<params.end(); ++i1, ++i2)
{
const ParameterInfo &p1 = **i1;
const ParameterInfo &p2 = **i2;
if (p1.getParameterType() == p2.getParameterType() &&
p1.getAttributes() == p2.getAttributes() &&
p1.getPosition() == p2.getPosition())
{
return &mi;
}
}
}
}
}
if (inherit)
{
for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i)
{
const MethodInfo *mi = (*i)->getMethod(name, params, true);
if (mi) return mi;
}
}
if (inherit)
{
for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i)
{
const MethodInfo *mi = (*i)->getMethod(name, params, true);
if (mi) return mi;
}
}
return 0;
return 0;
}
void Type::getInheritedProviders(CustomAttributeProviderList &providers) const
{
check_defined();
providers.assign(base_.begin(), base_.end());
check_defined();
providers.assign(base_.begin(), base_.end());
}
const PropertyInfo *Type::getProperty(const std::string &name, const Type &ptype, const ParameterInfoList &indices, bool inherit) const
{
check_defined();
for (PropertyInfoList::const_iterator i=props_.begin(); i!=props_.end(); ++i)
{
const PropertyInfo &pi = **i;
if (pi.getName() == name && pi.getPropertyType() == ptype)
{
const ParameterInfoList &other_indices = pi.getIndexParameters();
if (indices.size() == other_indices.size())
{
if (indices.empty())
return &pi;
ParameterInfoList::const_iterator i1 = indices.begin();
ParameterInfoList::const_iterator i2 = other_indices.begin();
for (; i1<indices.end(); ++i1, ++i2)
{
const ParameterInfo &p1 = **i1;
const ParameterInfo &p2 = **i2;
if (p1.getParameterType() == p2.getParameterType() &&
p1.getAttributes() == p2.getAttributes() &&
p1.getPosition() == p2.getPosition())
{
return &pi;
}
}
}
}
}
check_defined();
for (PropertyInfoList::const_iterator i=props_.begin(); i!=props_.end(); ++i)
{
const PropertyInfo &pi = **i;
if (pi.getName() == name && pi.getPropertyType() == ptype)
{
const ParameterInfoList &other_indices = pi.getIndexParameters();
if (indices.size() == other_indices.size())
{
if (indices.empty())
return &pi;
ParameterInfoList::const_iterator i1 = indices.begin();
ParameterInfoList::const_iterator i2 = other_indices.begin();
for (; i1<indices.end(); ++i1, ++i2)
{
const ParameterInfo &p1 = **i1;
const ParameterInfo &p2 = **i2;
if (p1.getParameterType() == p2.getParameterType() &&
p1.getAttributes() == p2.getAttributes() &&
p1.getPosition() == p2.getPosition())
{
return &pi;
}
}
}
}
}
if (inherit)
{
for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i)
{
const PropertyInfo *pi = (*i)->getProperty(name, ptype, indices, true);
if (pi) return pi;
}
}
if (inherit)
{
for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i)
{
const PropertyInfo *pi = (*i)->getProperty(name, ptype, indices, true);
if (pi) return pi;
}
}
return 0;
return 0;
}
Value Type::invokeMethod(const std::string &name, const Value &instance, ValueList &args, bool inherit) const
{
check_defined();
const MethodInfo *mi = getCompatibleMethod(name, args, inherit);
if (!mi) throw MethodNotFoundException(name, name_);
return mi->invoke(instance, args);
check_defined();
const MethodInfo *mi = getCompatibleMethod(name, args, inherit);
if (!mi) throw MethodNotFoundException(name, name_);
return mi->invoke(instance, args);
}
Value Type::invokeMethod(const std::string &name, Value &instance, ValueList &args, bool inherit) const
{
check_defined();
const MethodInfo *mi = getCompatibleMethod(name, args, inherit);
if (!mi) throw MethodNotFoundException(name, name_);
return mi->invoke(instance, args);
check_defined();
const MethodInfo *mi = getCompatibleMethod(name, args, inherit);
if (!mi) throw MethodNotFoundException(name, name_);
return mi->invoke(instance, args);
}
void Type::getAllProperties(PropertyInfoList &props) const
{
check_defined();
std::copy(props_.begin(), props_.end(), std::back_inserter(props));
for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i)
{
(*i)->getAllProperties(props);
}
check_defined();
std::copy(props_.begin(), props_.end(), std::back_inserter(props));
for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i)
{
(*i)->getAllProperties(props);
}
}
void Type::getAllMethods(MethodInfoList &methods) const
{
check_defined();
std::copy(methods_.begin(), methods_.end(), std::back_inserter(methods));
for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i)
{
(*i)->getAllMethods(methods);
}
check_defined();
std::copy(methods_.begin(), methods_.end(), std::back_inserter(methods));
for (TypeList::const_iterator i=base_.begin(); i!=base_.end(); ++i)
{
(*i)->getAllMethods(methods);
}
}

View File

@ -10,78 +10,78 @@ using namespace osgIntrospection;
Value Value::convertTo(const Type &outtype) const
{
Value v = tryConvertTo(outtype);
if (v.isEmpty())
throw TypeConversionException(type_->getStdTypeInfo(), outtype.getStdTypeInfo());
return v;
Value v = tryConvertTo(outtype);
if (v.isEmpty())
throw TypeConversionException(type_->getStdTypeInfo(), outtype.getStdTypeInfo());
return v;
}
Value Value::tryConvertTo(const Type &outtype) const
{
check_empty();
check_empty();
if (type_ == &outtype)
return *this;
if (type_ == &outtype)
return *this;
if (type_->isConstPointer() && outtype.isNonConstPointer())
return Value();
if (type_->isConstPointer() && outtype.isNonConstPointer())
return Value();
std::auto_ptr<ReaderWriter::Options> wopt;
std::auto_ptr<ReaderWriter::Options> wopt;
if (type_->isEnum() && (outtype.getQualifiedName() == "int" || outtype.getQualifiedName() == "unsigned int"))
{
wopt.reset(new ReaderWriter::Options);
wopt->setForceNumericOutput(true);
}
if (type_->isEnum() && (outtype.getQualifiedName() == "int" || outtype.getQualifiedName() == "unsigned int"))
{
wopt.reset(new ReaderWriter::Options);
wopt->setForceNumericOutput(true);
}
const ReaderWriter *src_rw = type_->getReaderWriter();
if (src_rw)
{
const ReaderWriter *dst_rw = outtype.getReaderWriter();
if (dst_rw)
{
std::ostringstream oss;
if (src_rw->writeTextValue(oss, *this, wopt.get()))
{
Value v;
std::istringstream iss(oss.str());
if (dst_rw->readTextValue(iss, v))
{
return v;
}
}
}
}
const ReaderWriter *src_rw = type_->getReaderWriter();
if (src_rw)
{
const ReaderWriter *dst_rw = outtype.getReaderWriter();
if (dst_rw)
{
std::ostringstream oss;
if (src_rw->writeTextValue(oss, *this, wopt.get()))
{
Value v;
std::istringstream iss(oss.str());
if (dst_rw->readTextValue(iss, v))
{
return v;
}
}
}
}
return Value();
return Value();
}
std::string Value::toString() const
{
check_empty();
check_empty();
const ReaderWriter *rw = type_->getReaderWriter();
if (rw)
{
std::ostringstream oss;
if (!rw->writeTextValue(oss, *this))
throw StreamWriteErrorException();
return oss.str();
}
throw StreamingNotSupportedException(StreamingNotSupportedException::ANY, type_->getStdTypeInfo());
const ReaderWriter *rw = type_->getReaderWriter();
if (rw)
{
std::ostringstream oss;
if (!rw->writeTextValue(oss, *this))
throw StreamWriteErrorException();
return oss.str();
}
throw StreamingNotSupportedException(StreamingNotSupportedException::ANY, type_->getStdTypeInfo());
}
bool Value::compare(const Value &v1, const Value &v2)
{
if (v1.isEmpty() && v2.isEmpty()) return true;
if (v1.isEmpty() || v2.isEmpty()) return false;
if (v1.type_ == v2.type_) return v1.inbox_->equal(v2);
Value temp(v2.convertTo(v1.getType()));
return compare(v1, temp);
if (v1.isEmpty() && v2.isEmpty()) return true;
if (v1.isEmpty() || v2.isEmpty()) return false;
if (v1.type_ == v2.type_) return v1.inbox_->equal(v2);
Value temp(v2.convertTo(v1.getType()));
return compare(v1, temp);
}
void Value::check_empty() const
{
if (!type_ || !inbox_)
throw EmptyValueException();
if (!type_ || !inbox_)
throw EmptyValueException();
}