/* -*-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_PROPERTYINFO_ #define OSGINTROSPECTION_PROPERTYINFO_ #include #include #include #include #include #include #include #include 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), _remm(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/remover methods. PropertyInfo(const Type& decltype, const Type& ptype, const std::string& name, const MethodInfo* getm, const MethodInfo* setm, const MethodInfo* numm, const MethodInfo* addm, const MethodInfo* remm) : CustomAttributeProvider(), _decltype(decltype), _ptype(ptype), _name(name), _getm(getm), _setm(setm), _numm(numm), _addm(addm), _remm(remm), _is_array(true) { } /// Returns the number of indices inline int getNumIndices() const { return static_cast(getIndexParameters().size()); } /// 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 of the reflected property. inline const Type& getPropertyType() const { const PropertyTypeAttribute *pta = getAttribute(false); if (pta) return pta->getPropertyType(); return _ptype; } /// Returns the getter method. inline const MethodInfo* getGetMethod() const { return _getm; } /// Returns the setter method. inline const MethodInfo* getSetMethod() const { return _setm; } /// Returns the counter method. inline const MethodInfo* getCountMethod() const { return _numm; } /// Returns the adder method. inline const MethodInfo* getAddMethod() const { return _addm; } /// Returns the remover method. inline const MethodInfo* getRemoveMethod() const { return _remm; } /// Returns whether the property's value can be retrieved. inline bool canGet() const { return (_getm != 0) || isDefined(false); } /// Returns whether the property's value can be set. inline bool canSet() const { return _setm != 0 || isDefined(false); } /// Returns whether the property's array of values can be counted. inline bool canCount() const { return _numm != 0 || isDefined(false); } /// Returns whether items can be added to the array property. inline bool canAdd() const { return _addm != 0 || isDefined(false); } /// Returns whether items can be removed from the array property. inline bool canRemove() const { return _remm != 0 || isDefined(false); } /// 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 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 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 const 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(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 getter method on the given const 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(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 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 const 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(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 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 remover method on the given instance and removes /// an item from the array property. If a custom remover attribute /// is defined, it will be invoked instead. void removeArrayItem(Value& instance, int i) 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; private: const Type& _decltype; const Type& _ptype; std::string _name; const MethodInfo* _getm; const MethodInfo* _setm; const MethodInfo* _numm; const MethodInfo* _addm; const MethodInfo* _remm; ParameterInfoList _indices; bool _is_array; }; } #endif