OpenSceneGraph/include/osgIntrospection/PropertyInfo

313 lines
12 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_PROPERTYINFO_
#define OSGINTROSPECTION_PROPERTYINFO_
#include <osgIntrospection/Export>
#include <osgIntrospection/Type>
#include <osgIntrospection/MethodInfo>
#include <osgIntrospection/Attributes>
#include <string>
#include <typeinfo>
#include <iosfwd>
#include <vector>
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<int>(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<PropertyTypeAttribute>(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<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 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 removed from the array property.
inline bool canRemove() const
{
return _remm != 0 || isDefined<CustomPropertyRemoveAttribute>(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