#ifndef OSGINTROSPECTION_TYPE_ #define OSGINTROSPECTION_TYPE_ #include #include #include #include #include #include #include #include namespace osgIntrospection { // forward declarations class MethodInfo; class PropertyInfo; class ParameterInfo; class ReaderWriter; // typedefs for member info lists typedef std::vector MethodInfoList; typedef std::vector PropertyInfoList; typedef std::vector ParameterInfoList; // typedef for enum label map typedef std::map 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 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 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 ¶ms, 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 friend class Reflector; friend class Reflection; Type(const Type ©): CustomAttributeProvider(copy), ti_(copy.ti_) {} const std::type_info &ti_; std::string name_; std::string namespace_; typedef std::vector 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(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(); } } #endif