450 lines
14 KiB
C++
450 lines
14 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
|
|
*
|
|
* This library is open source and may be redistributed and/or modified under
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* OpenSceneGraph Public License for more details.
|
|
*/
|
|
//osgIntrospection - Copyright (C) 2005 Marco Jez
|
|
#ifndef OSGINTROSPECTION_TYPE
|
|
#define OSGINTROSPECTION_TYPE
|
|
|
|
#include <osgIntrospection/Export>
|
|
#include <osgIntrospection/Exceptions>
|
|
#include <osgIntrospection/Value>
|
|
#include <osgIntrospection/CustomAttributeProvider>
|
|
|
|
#include <string>
|
|
#include <typeinfo>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <algorithm>
|
|
|
|
namespace osgIntrospection
|
|
{
|
|
|
|
// forward declarations
|
|
class MethodInfo;
|
|
class PropertyInfo;
|
|
class ParameterInfo;
|
|
class ReaderWriter;
|
|
class ConstructorInfo;
|
|
struct Comparator;
|
|
|
|
// typedefs for member info lists
|
|
typedef std::vector<const MethodInfo* > MethodInfoList;
|
|
typedef std::vector<const PropertyInfo* > PropertyInfoList;
|
|
typedef std::vector<const ParameterInfo* > ParameterInfoList;
|
|
typedef std::vector<const ConstructorInfo* > ConstructorInfoList;
|
|
|
|
// typedef for enum label map
|
|
typedef std::map<int, std::string> EnumLabelMap;
|
|
|
|
|
|
/// 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 true if either the fully-qualified name or one of the
|
|
/// name aliases match the given argument
|
|
inline bool matchesName(const std::string& name) 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 the number of type name aliases.
|
|
inline int getNumAliases() const;
|
|
|
|
/// Returns the i-th name alias
|
|
const std::string& getAlias(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 constructors defined for this type.
|
|
inline const ConstructorInfoList& getConstructors() 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 constructor that can be called with the given list
|
|
/// of arguments without raising type conversion errors. If more than
|
|
/// one constructors are suitable for calling, the best match is
|
|
/// returned.
|
|
const ConstructorInfo* getCompatibleConstructor(const ValueList& values) const;
|
|
|
|
/// Searches for a constructor whose parameters match exactly the given
|
|
/// list of parameter descriptions.
|
|
const ConstructorInfo* getConstructor(const ParameterInfoList& params) 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;
|
|
|
|
/// Returns the instance of the comparator object assigned to
|
|
/// this type, if any. Otherwise it returns the null pointer.
|
|
inline const Comparator* getComparator() 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.
|
|
Value createInstance(ValueList& args) const;
|
|
inline Value createInstance() const;
|
|
|
|
protected:
|
|
Type(const std::type_info& ti)
|
|
: _ti(ti),
|
|
_is_const(false),
|
|
_is_abstract(false),
|
|
_pointed_type(0),
|
|
_is_defined(false),
|
|
_rw(0),
|
|
_cmp(0)
|
|
{
|
|
}
|
|
|
|
// throws an exception if the type is not defined.
|
|
void check_defined() const;
|
|
|
|
virtual void getInheritedProviders(CustomAttributeProviderList& providers) const;
|
|
|
|
private:
|
|
template<typename C> friend class Reflector;
|
|
template<typename C> friend struct TypeNameAliasProxy;
|
|
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;
|
|
bool _is_abstract;
|
|
const Type* _pointed_type;
|
|
|
|
ConstructorInfoList _cons;
|
|
PropertyInfoList _props;
|
|
MethodInfoList _methods;
|
|
|
|
EnumLabelMap _labels;
|
|
bool _is_defined;
|
|
|
|
const ReaderWriter* _rw;
|
|
const Comparator* _cmp;
|
|
|
|
typedef std::vector<std::string> AliasList;
|
|
AliasList _aliases;
|
|
};
|
|
|
|
// 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 _is_abstract;
|
|
}
|
|
|
|
inline bool Type::isAtomic() const
|
|
{
|
|
check_defined();
|
|
return _rw != 0;
|
|
}
|
|
|
|
inline const PropertyInfoList& Type::getProperties() const
|
|
{
|
|
check_defined();
|
|
return _props;
|
|
}
|
|
|
|
inline const ConstructorInfoList& Type::getConstructors() const
|
|
{
|
|
check_defined();
|
|
return _cons;
|
|
}
|
|
|
|
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 Comparator* Type::getComparator() const
|
|
{
|
|
check_defined();
|
|
return _cmp;
|
|
}
|
|
|
|
inline const Type& Type::getBaseType(int i) const
|
|
{
|
|
check_defined();
|
|
return *_base.at(i);
|
|
}
|
|
|
|
inline Value Type::createInstance() const
|
|
{
|
|
ValueList args;
|
|
return createInstance(args);
|
|
}
|
|
|
|
inline int Type::getNumAliases() const
|
|
{
|
|
return static_cast<int>(_aliases.size());
|
|
}
|
|
|
|
inline const std::string& Type::getAlias(int i) const
|
|
{
|
|
return _aliases[i];
|
|
}
|
|
|
|
inline bool Type::matchesName(const std::string& name) const
|
|
{
|
|
if (getQualifiedName() == name)
|
|
return true;
|
|
if (std::find(_aliases.begin(), _aliases.end(), name) != _aliases.end())
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|