OpenSceneGraph/include/osgIntrospection/Attributes

322 lines
12 KiB
Plaintext
Raw Normal View History

2006-07-18 23:21:48 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2005-04-29 18:06:50 +08:00
*
* 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_ATTRIBUTES_
#define OSGINTROSPECTION_ATTRIBUTES_
#include <osgIntrospection/CustomAttribute>
#include <osgIntrospection/Value>
#include <osgIntrospection/Exceptions>
#include <osgIntrospection/Type>
namespace osgIntrospection
{
2005-03-14 17:28:31 +08:00
/// 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; }
2005-03-14 17:28:31 +08:00
private:
Value _v;
2005-03-14 17:28:31 +08:00
};
/// 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(Value& /*instance*/, const ValueList& /*indices*/) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::IGET); }
virtual Value get(Value& /*instance*/) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::GET); }
virtual Value get(Value& /*instance*/, int /*i*/) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::AGET); }
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); }
2005-03-14 17:28:31 +08:00
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) {}
2005-03-14 17:28:31 +08:00
const PropertyGetter* getGetter() const { return _getter; }
2005-03-14 17:28:31 +08:00
~CustomPropertyGetAttribute()
{
delete _getter;
2005-03-14 17:28:31 +08:00
}
private:
const PropertyGetter* _getter;
2005-03-14 17:28:31 +08:00
};
/// 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); }
2005-03-14 17:28:31 +08:00
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) {}
2005-03-14 17:28:31 +08:00
const PropertySetter* getSetter() const { return _setter; }
2005-03-14 17:28:31 +08:00
~CustomPropertySetAttribute()
{
delete _setter;
2005-03-14 17:28:31 +08:00
}
private:
const PropertySetter* _setter;
2005-03-14 17:28:31 +08:00
};
/// 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); }
2005-03-14 17:28:31 +08:00
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) {}
2005-03-14 17:28:31 +08:00
const PropertyCounter* getCounter() const { return _counter; }
2005-03-14 17:28:31 +08:00
~CustomPropertyCountAttribute()
{
delete _counter;
2005-03-14 17:28:31 +08:00
}
private:
const PropertyCounter* _counter;
2005-03-14 17:28:31 +08:00
};
/// 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) {}
2005-03-14 17:28:31 +08:00
const PropertyAdder* getAdder() const { return _adder; }
2005-03-14 17:28:31 +08:00
~CustomPropertyAddAttribute()
{
delete _adder;
2005-03-14 17:28:31 +08:00
}
private:
const PropertyAdder* _adder;
2005-03-14 17:28:31 +08:00
};
From David Callu: " the main problem is the wrapper generation: The PropertyInfo class use MethodInfo class to access to the value. When the property are define with the I_Property* macro, the MethodInfo use by the property to have access to the value are instancied in the I_Property* macro, but there are already instantied by the I_Method* macro before secondary problem: - the function used by the property could no be customized in the genwrapper.conf file - an array property can't insert a value - the std::map reflector (and indexedProperty in general) haven't remove method - about the help in wrapper ... why not ... solution : To use the function define by the I_Method, I add a MethodInfo variable in the I_Method0 macro old macro : #define I_Method0(ret, fn) (\ params.clear(),\ addMethod(new osgIntrospection::TypedMethodIn fo0<reflected_type, ret >(qualifyName(#fn), &reflected_type::fn, params))) new macro : #define I_Method0(ret, fn, signature, briefHelp, detailedHelp) \ params.clear(); \ osgIntrospection::MethodInfo* signature = addMethod(new osgIntrospection::TypedMethodInfo0<reflected_type, ret >(qualifyName(#fn), &reflected_type::fn, params, briefHelp, detailedHelp)); sink(signature) the osgIntrospection::MethodInfo* signature is used by the I_Property macro to define the MethodInfo that it use so for I_Property macro : old macro : #define I_PropertyWithReturnType(t, n, r) \ cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \ I_Method0(t, get##n), \ I_Method1(r, set##n, IN, t, value))) new macro: #define I_SimpleProperty(t, n, get, set) \ get, \ set)) The genwrapper has been modified in this way. The method signature is define by the prototype of the method For example, the "const char* libraryName();" have "__C5_char_P1__libraryName" for signature solution for secondary problem: The genwrapper accept new tokens in the configuration to custumize the property. The new PropertyInserter and the CustomPropertyInsertAttribute class has been defined The PropertyRemover has been added to the StdMapReflector The _briefHelp and _detailedHelp variable has been added in PropertyInfo, MethodInfo and ContructorInfo class modification: I have modify the genwrapper files Configuration.cpp Configuration.h add some tokens to custumize the property Doxyfile.template add the comment in the output xml genwrapper.conf customize some property in osg::Geometry RegistryBuilder.h RegistryBuilder.cpp add the process_help function (to extract help from xml) TypeRegister.cpp TypeRegister.h optimize the property detection TypeDesc.h TypeDesc.cpp modify FunctionDesc and PropertyDesc WrapperGenerator.h WrapperGenerator.cpp modify the output I also modify the fallowing osgIntrospection files: include/osgIntrospection/Attributes add the PropertyInserter and the CustomPropertyInsertAttribute class include/osgIntrospection/ConstructorInfo add the _briefHelp and _detailedHelp variable in the ConstructorInfo class add access function for the two new variables (_briefHelp and _detailedHelp) modify the constructor to define the two new variables (_briefHelp and _detailedHelp) include/osgIntrospection/MethodInfo add the _briefHelp and _detailedHelp variable in the MethodInfo class add access function for the two new variables (_briefHelp and _detailedHelp) modify the constructor to define the two new variables (_briefHelp and _detailedHelp) include/osgIntrospection/PropertyInfo add the _briefHelp and _detailedHelp variable in the PropertyInfo class add access function for the two new variables (_briefHelp and _detailedHelp) modify the constructor to define the two new variables (_briefHelp and _detailedHelp) include/osgIntrospection/ReflectionMacro remove unused I_Property* macro modify all I_Method macro to accept the help string modify all I_Method macro to define a MethodInfo signature include/osgIntrospection/Reflector add the PropertyInserter in StdVectorReflector and StdListReflector add the PropertyRemover in the StdMapReflector include/osgIntrospection/StaticMethodInfo modify all StaticMethodInfo* to accept the help in parameter include/osgIntrospection/TypedMethodInfo modify all TypedMethodInfo* to accept the help in parameter include/osgIntrospection/TypedConstructorInfo modify all TypedConstructorInfo* to accept the help in parameter include/osgIntrospection/Type add the _briefHelp and _detailedHelp variable in the Type class "
2006-10-17 23:17:06 +08:00
/// Base struct for custom array property inserters. Descendants should
/// override the insert() method whose purpose is to insert a new item to
/// an array property.
struct PropertyInserter
{
virtual void insert(Value&, int, const Value&) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::INSERT); }
virtual void insert(Value&, const ValueList&, const Value&) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::INSERT); }
virtual ~PropertyInserter() {}
};
/// By setting an attribute of this class you can specify a custom object
/// that will be used to insert a new item to an array property.
class CustomPropertyInsertAttribute: public CustomAttribute
{
public:
CustomPropertyInsertAttribute(const PropertyInserter* inserter)
: CustomAttribute(), _inserter(inserter) {}
const PropertyInserter* getInserter() const { return _inserter; }
~CustomPropertyInsertAttribute()
{
delete _inserter;
}
private:
const PropertyInserter* _inserter;
};
/// Base struct for custom array property removers. Descendants should
/// override the remove() method whose purpose is to remove an item from
/// an array property.
struct PropertyRemover
{
virtual void remove(Value&, int) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::REMOVE); }
From David Callu: " the main problem is the wrapper generation: The PropertyInfo class use MethodInfo class to access to the value. When the property are define with the I_Property* macro, the MethodInfo use by the property to have access to the value are instancied in the I_Property* macro, but there are already instantied by the I_Method* macro before secondary problem: - the function used by the property could no be customized in the genwrapper.conf file - an array property can't insert a value - the std::map reflector (and indexedProperty in general) haven't remove method - about the help in wrapper ... why not ... solution : To use the function define by the I_Method, I add a MethodInfo variable in the I_Method0 macro old macro : #define I_Method0(ret, fn) (\ params.clear(),\ addMethod(new osgIntrospection::TypedMethodIn fo0<reflected_type, ret >(qualifyName(#fn), &reflected_type::fn, params))) new macro : #define I_Method0(ret, fn, signature, briefHelp, detailedHelp) \ params.clear(); \ osgIntrospection::MethodInfo* signature = addMethod(new osgIntrospection::TypedMethodInfo0<reflected_type, ret >(qualifyName(#fn), &reflected_type::fn, params, briefHelp, detailedHelp)); sink(signature) the osgIntrospection::MethodInfo* signature is used by the I_Property macro to define the MethodInfo that it use so for I_Property macro : old macro : #define I_PropertyWithReturnType(t, n, r) \ cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, \ I_Method0(t, get##n), \ I_Method1(r, set##n, IN, t, value))) new macro: #define I_SimpleProperty(t, n, get, set) \ get, \ set)) The genwrapper has been modified in this way. The method signature is define by the prototype of the method For example, the "const char* libraryName();" have "__C5_char_P1__libraryName" for signature solution for secondary problem: The genwrapper accept new tokens in the configuration to custumize the property. The new PropertyInserter and the CustomPropertyInsertAttribute class has been defined The PropertyRemover has been added to the StdMapReflector The _briefHelp and _detailedHelp variable has been added in PropertyInfo, MethodInfo and ContructorInfo class modification: I have modify the genwrapper files Configuration.cpp Configuration.h add some tokens to custumize the property Doxyfile.template add the comment in the output xml genwrapper.conf customize some property in osg::Geometry RegistryBuilder.h RegistryBuilder.cpp add the process_help function (to extract help from xml) TypeRegister.cpp TypeRegister.h optimize the property detection TypeDesc.h TypeDesc.cpp modify FunctionDesc and PropertyDesc WrapperGenerator.h WrapperGenerator.cpp modify the output I also modify the fallowing osgIntrospection files: include/osgIntrospection/Attributes add the PropertyInserter and the CustomPropertyInsertAttribute class include/osgIntrospection/ConstructorInfo add the _briefHelp and _detailedHelp variable in the ConstructorInfo class add access function for the two new variables (_briefHelp and _detailedHelp) modify the constructor to define the two new variables (_briefHelp and _detailedHelp) include/osgIntrospection/MethodInfo add the _briefHelp and _detailedHelp variable in the MethodInfo class add access function for the two new variables (_briefHelp and _detailedHelp) modify the constructor to define the two new variables (_briefHelp and _detailedHelp) include/osgIntrospection/PropertyInfo add the _briefHelp and _detailedHelp variable in the PropertyInfo class add access function for the two new variables (_briefHelp and _detailedHelp) modify the constructor to define the two new variables (_briefHelp and _detailedHelp) include/osgIntrospection/ReflectionMacro remove unused I_Property* macro modify all I_Method macro to accept the help string modify all I_Method macro to define a MethodInfo signature include/osgIntrospection/Reflector add the PropertyInserter in StdVectorReflector and StdListReflector add the PropertyRemover in the StdMapReflector include/osgIntrospection/StaticMethodInfo modify all StaticMethodInfo* to accept the help in parameter include/osgIntrospection/TypedMethodInfo modify all TypedMethodInfo* to accept the help in parameter include/osgIntrospection/TypedConstructorInfo modify all TypedConstructorInfo* to accept the help in parameter include/osgIntrospection/Type add the _briefHelp and _detailedHelp variable in the Type class "
2006-10-17 23:17:06 +08:00
virtual void remove(Value&, ValueList&) const { throw PropertyAccessException("[n/a inside a custom accessor]", PropertyAccessException::REMOVE); }
virtual ~PropertyRemover() {}
};
/// By setting an attribute of this class you can specify a custom object
/// that will be used to remove an item from an array property.
class CustomPropertyRemoveAttribute: public CustomAttribute
{
public:
CustomPropertyRemoveAttribute(const PropertyRemover* remover)
: CustomAttribute(), _remover(remover) {}
const PropertyRemover* getRemover() const { return _remover; }
~CustomPropertyRemoveAttribute()
{
delete _remover;
}
private:
const PropertyRemover* _remover;
};
2005-03-14 17:28:31 +08:00
/// 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;
2005-03-14 17:28:31 +08:00
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) {}
2005-03-14 17:28:31 +08:00
const IndexInfo* getIndexInfo() const
2005-03-14 17:28:31 +08:00
{
return _ii;
2005-03-14 17:28:31 +08:00
}
~CustomIndexAttribute()
{
delete _ii;
2005-03-14 17:28:31 +08:00
}
private:
const IndexInfo* _ii;
2005-03-14 17:28:31 +08:00
};
/// 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) {}
2005-03-14 17:28:31 +08:00
const Type& getPropertyType() const
2005-03-14 17:28:31 +08:00
{
return _type;
2005-03-14 17:28:31 +08:00
}
private:
const Type& _type;
2005-03-14 17:28:31 +08:00
};
/// 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) {}
2005-03-14 17:28:31 +08:00
int getWhichIndex() const
{
return _wi;
2005-03-14 17:28:31 +08:00
}
const Type& getIndexType() const
2005-03-14 17:28:31 +08:00
{
return _type;
2005-03-14 17:28:31 +08:00
}
private:
int _wi;
const Type& _type;
2005-03-14 17:28:31 +08:00
};
}
#endif