diff --git a/VisualStudio/osgIntrospection/osgIntrospection.dsp b/VisualStudio/osgIntrospection/osgIntrospection.dsp index 0c08075e0..c1af38b4c 100644 --- a/VisualStudio/osgIntrospection/osgIntrospection.dsp +++ b/VisualStudio/osgIntrospection/osgIntrospection.dsp @@ -187,6 +187,10 @@ SOURCE=..\..\include\osgIntrospection\PropertyInfo # End Source File # Begin Source File +SOURCE=..\..\include\osgIntrospection\PublicMemberAccessor +# End Source File +# Begin Source File + SOURCE=..\..\include\osgIntrospection\ReaderWriter # End Source File # Begin Source File diff --git a/include/osgIntrospection/PublicMemberAccessor b/include/osgIntrospection/PublicMemberAccessor new file mode 100644 index 000000000..cec962318 --- /dev/null +++ b/include/osgIntrospection/PublicMemberAccessor @@ -0,0 +1,59 @@ +/* -*-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) 2006 David Callu + +#ifndef OSGINTROSPECTION_PUBLICMEMBERACCESSOR_ +#define OSGINTROSPECTION_PUBLICMEMBERACCESSOR_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace osgIntrospection +{ + template < typename C, typename P > + struct PublicMemberAccessor: public PropertyGetter, public PropertySetter + { + typedef P C::*MemberType; + + PublicMemberAccessor(MemberType m) + : _m(m) + {} + + virtual Value get(Value& instance) const + { + return getInstance(instance).*_m; + } + + virtual Value get(const Value& instance) const + { + return getInstance(instance).*_m; + } + + virtual void set(Value& instance, const Value& v) const + { + getInstance(instance).*_m = variant_cast(v); + } + + P C::*_m; + }; +} + +#endif diff --git a/include/osgIntrospection/ReaderWriter b/include/osgIntrospection/ReaderWriter index 518938a60..bb83c4f6f 100644 --- a/include/osgIntrospection/ReaderWriter +++ b/include/osgIntrospection/ReaderWriter @@ -26,6 +26,7 @@ #include #include +#include namespace osgIntrospection @@ -61,6 +62,12 @@ namespace osgIntrospection /// Reads a textual representation of the value's content from a stream. virtual std::istream &readTextValue(std::istream &, Value& v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::TEXT_READ, v.getType().getStdTypeInfo()); } + /// Writes a textual representation of the value's content to a stream. + virtual std::wostream &writeTextValue(std::wostream & wos, const Value& v, const Options* op = 0) const { std::ostringstream os; writeTextValue(os, v, op); wos << os; return (wos);} + + /// Reads a textual representation of the value's content from a stream. + virtual std::wistream &readTextValue(std::wistream& , Value& v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::TEXT_READ, v.getType().getStdTypeInfo()); } + /// Writes a binary representation of the value's content to a stream. virtual std::ostream &writeBinaryValue(std::ostream &, const Value& v, const Options* = 0) const { throw StreamingNotSupportedException(StreamingNotSupportedException::BINARY_WRITE, v.getType().getStdTypeInfo()); } @@ -107,6 +114,34 @@ namespace osgIntrospection }; + template + class StdWReaderWriter: public ReaderWriter + { + public: + virtual std::wostream &writeTextValue(std::wostream &wos, const Value& v, const Options * = 0) const + { + return (wos << variant_cast(v)); + } + + virtual std::wistream &readTextValue(std::wistream &wis, Value& v, const Options * = 0) const + { + if (v.isEmpty()) v = Value(T()); + return (wis >> variant_cast(v)); + } + + virtual std::ostream &writeBinaryValue(std::ostream &os, const Value& v, const Options * = 0) const + { + return os.write(reinterpret_cast(extract_raw_data(v)), sizeof(T)); + } + + virtual std::istream &readBinaryValue(std::istream &is, Value& v, const Options * = 0) const + { + if (v.isEmpty()) v = Value(T()); + return is.read(reinterpret_cast(extract_raw_data(v)), sizeof(T)); + } + + }; + /// This ReaderWriter can be used to read and write enumeration values. /// The textual representation will be the enum label, if found, or the /// numerical value. The binary representation doesn't take label names diff --git a/include/osgIntrospection/ReflectionMacros b/include/osgIntrospection/ReflectionMacros index b6fdd4d2b..567eae363 100644 --- a/include/osgIntrospection/ReflectionMacros +++ b/include/osgIntrospection/ReflectionMacros @@ -20,6 +20,7 @@ #include #include #include +#include namespace osgIntrospection { @@ -85,6 +86,9 @@ namespace osgIntrospection #define ATOMIC_VALUE_REFLECTOR(t) \ namespace { osgIntrospection::AtomicValueReflector OSG_RM_LINEID(reflector) (#t); } +#define WATOMIC_VALUE_REFLECTOR(t) \ + namespace { osgIntrospection::WAtomicValueReflector OSG_RM_LINEID(reflector) (#t); } + #define STD_PAIR_REFLECTOR(t) \ namespace { osgIntrospection::StdPairReflector OSG_RM_LINEID(reflector) (#t); } @@ -212,6 +216,20 @@ struct BaseTypeConverters #define I_EnumLabel(x) addEnumLabel(x, #x, true); + + + + +// -------------------------------------------------------------------------- +// PUBLIC MEMBER PROPERTIES +// -------------------------------------------------------------------------- + +#define I_PublicMemberProperty(t, n) \ + cap=addProperty(new osgIntrospection::PropertyInfo(osgIntrospection::Reflection::getType(typeid(reflected_type)), osgIntrospection::Reflection::getType(typeid(t)), #n, 0, 0)); \ + cap->addAttribute(new osgIntrospection::CustomPropertyGetAttribute(new osgIntrospection::PublicMemberAccessor(&reflected_type::n))); \ + cap->addAttribute(new osgIntrospection::CustomPropertySetAttribute(new osgIntrospection::PublicMemberAccessor(&reflected_type::n))); + + // -------------------------------------------------------------------------- // SIMPLE PROPERTIES // -------------------------------------------------------------------------- diff --git a/include/osgIntrospection/Reflector b/include/osgIntrospection/Reflector index 46e13c8ae..10a274bfa 100644 --- a/include/osgIntrospection/Reflector +++ b/include/osgIntrospection/Reflector @@ -226,6 +226,28 @@ namespace osgIntrospection } }; + template + struct WAtomicValueReflector: ValueReflector + { + typedef typename ValueReflector::instance_creator_type instance_creator_type; + + WAtomicValueReflector(const std::string& name, const std::string& ns) + : ValueReflector(name, ns) + { + setReaderWriter(new StdWReaderWriter); + setComparator(new PartialOrderComparator); + addConstructor(new TypedConstructorInfo0(ParameterInfoList())); + } + + WAtomicValueReflector(const std::string& qname) + : ValueReflector(qname) + { + setReaderWriter(new StdWReaderWriter); + setComparator(new PartialOrderComparator); + addConstructor(new TypedConstructorInfo0(ParameterInfoList())); + } + }; + /// This reflector is a ValueReflector that should be used to define /// enumerations. It assigns an EnumReaderWriter by default. diff --git a/include/osgIntrospection/Type b/include/osgIntrospection/Type index 59125c07b..0952bd77a 100644 --- a/include/osgIntrospection/Type +++ b/include/osgIntrospection/Type @@ -37,14 +37,20 @@ namespace osgIntrospection struct Comparator; // typedefs for member info lists - typedef std::vector MethodInfoList; - typedef std::vector PropertyInfoList; + typedef std::vector MethodInfoList; + typedef std::vector PropertyInfoList; typedef std::vector ParameterInfoList; typedef std::vector ConstructorInfoList; + // typedefs for member info map + typedef std::map PropertyInfoMap; + typedef std::map MethodInfoMap; + // typedef for enum label map typedef std::map EnumLabelMap; + // typedef for base type + typedef std::vector TypeList; /// Objects of class Type are used to maintain information about /// reflected types. They also provide a number of services, like @@ -92,9 +98,12 @@ namespace osgIntrospection /// Returns the i-th base type. inline const Type& getBaseType(int i) const; + /// Returns the base type list. + inline const TypeList& getBaseTypeList() 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; @@ -133,7 +142,11 @@ namespace osgIntrospection /// Fills a list of properties that are either defined in this Type /// or in inherited types. void getAllProperties(PropertyInfoList& props) const; - + + /// Fills a map of "type <-> propertyInfoList" that are either defined in this Type + /// or in inherited types. + void getPropertiesMap(PropertyInfoMap& props) const; + /// Returns the list of constructors defined for this type. inline const ConstructorInfoList& getConstructors() const; @@ -145,6 +158,10 @@ namespace osgIntrospection /// or in inherited types. void getAllMethods(MethodInfoList& methods) const; + /// Fills a map of "type <-> MethodInfoList" that are either defined in this Type + /// or in inherited types. + void getMethodsMap(MethodInfoMap& 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; @@ -154,7 +171,7 @@ namespace osgIntrospection /// 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; @@ -186,7 +203,7 @@ namespace osgIntrospection /// 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; @@ -226,7 +243,6 @@ namespace osgIntrospection std::string _name; std::string _namespace; - typedef std::vector TypeList; TypeList _base; bool _is_const; @@ -242,7 +258,7 @@ namespace osgIntrospection const ReaderWriter* _rw; const Comparator* _cmp; - + typedef std::vector AliasList; AliasList _aliases; }; @@ -352,7 +368,7 @@ namespace osgIntrospection check_defined(); return _props; } - + inline const ConstructorInfoList& Type::getConstructors() const { check_defined(); @@ -419,22 +435,28 @@ namespace osgIntrospection return *_base.at(i); } + inline const TypeList& Type::getBaseTypeList() const + { + check_defined(); + return _base; + } + inline Value Type::createInstance() const { ValueList args; return createInstance(args); } - + inline int Type::getNumAliases() const { return static_cast(_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) diff --git a/include/osgIntrospection/Value b/include/osgIntrospection/Value index dbf5013bb..b7dd7aff5 100644 --- a/include/osgIntrospection/Value +++ b/include/osgIntrospection/Value @@ -146,6 +146,7 @@ namespace osgIntrospection /// associated to it. If the conversion can't be completed, an /// exception is thrown. std::string toString() const; + std::wstring toWString() const; /// Swaps the content of this Value with another Value void swap(Value& v); diff --git a/src/osgIntrospection/DefaultReflectors.cpp b/src/osgIntrospection/DefaultReflectors.cpp index 14eb1b6f2..f4225565e 100644 --- a/src/osgIntrospection/DefaultReflectors.cpp +++ b/src/osgIntrospection/DefaultReflectors.cpp @@ -22,6 +22,7 @@ ABSTRACT_OBJECT_REFLECTOR(void) ATOMIC_VALUE_REFLECTOR(char) +WATOMIC_VALUE_REFLECTOR(wchar_t) ATOMIC_VALUE_REFLECTOR(signed char) ATOMIC_VALUE_REFLECTOR(unsigned char) diff --git a/src/osgIntrospection/Type.cpp b/src/osgIntrospection/Type.cpp index e8e62d289..e83630ccc 100644 --- a/src/osgIntrospection/Type.cpp +++ b/src/osgIntrospection/Type.cpp @@ -207,6 +207,16 @@ void Type::getAllProperties(PropertyInfoList& props) const } } +void Type::getPropertiesMap(PropertyInfoMap& props) const +{ + check_defined(); + props[this] = _props; + for (TypeList::const_iterator i=_base.begin(); i!=_base.end(); ++i) + { + (*i)->getPropertiesMap(props); + } +} + void Type::getAllMethods(MethodInfoList& methods) const { check_defined(); @@ -217,6 +227,16 @@ void Type::getAllMethods(MethodInfoList& methods) const } } +void Type::getMethodsMap(MethodInfoMap& methods) const +{ + check_defined(); + methods[this] = _methods; + for (TypeList::const_iterator i=_base.begin(); i!=_base.end(); ++i) + { + (*i)->getMethodsMap(methods); + } +} + Value Type::createInstance(ValueList& args) const { if (isAbstract()) diff --git a/src/osgIntrospection/Value.cpp b/src/osgIntrospection/Value.cpp index c063cd154..53e1a74b1 100644 --- a/src/osgIntrospection/Value.cpp +++ b/src/osgIntrospection/Value.cpp @@ -82,7 +82,7 @@ Value Value::tryConvertTo(const Type& outtype) const std::string Value::toString() const { - check_empty(); + check_empty(); const ReaderWriter* rw = _type->getReaderWriter(); if (rw) @@ -90,7 +90,22 @@ std::string Value::toString() const std::ostringstream oss; if (!rw->writeTextValue(oss, *this)) throw StreamWriteErrorException(); - return oss.str(); + return oss.str(); + } + throw StreamingNotSupportedException(StreamingNotSupportedException::ANY, _type->getStdTypeInfo()); + } + +std::wstring Value::toWString() const +{ + check_empty(); + + const ReaderWriter* rw = _type->getReaderWriter(); + if (rw) + { + std::wostringstream woss; + if (!rw->writeTextValue(woss, *this)) + throw StreamWriteErrorException(); + return woss.str(); } throw StreamingNotSupportedException(StreamingNotSupportedException::ANY, _type->getStdTypeInfo()); }