reflection.h
Go to the documentation of this file.00001 #ifndef CPPTL_REFLECTION_H_INCLUDED
00002 # define CPPTL_REFLECTION_H_INCLUDED
00003
00004 # include <cpptl/conststring.h>
00005 # include <cpptl/enumerator.h>
00006 # include <cpptl/sharedptr.h>
00007 # include <cpptl/any.h>
00008 # include <map>
00009 # include <vector>
00010
00011
00012
00013 namespace CppTL {
00014
00015 typedef std::vector<Any> MethodParameters;
00016
00018 namespace Impl {
00019 class AttributAccessor;
00020 class InvokableBase;
00021
00022 typedef SharedPtr<AttributAccessor> AttributAccessorPtr;
00023 typedef SharedPtr<InvokableBase> InvokableBasePtr;
00024
00025 class MethodCall
00026 {
00027 public:
00028 MethodCall( const Method &method,
00029 const Any &holder,
00030 const MethodParameters &args,
00031 Any &result )
00032 : method_( method )
00033 , holder_( holder )
00034 , args_( args )
00035 , result_( result )
00036 {
00037 }
00038
00039 const Method &method_;
00040 const Any &holder_;
00041 const MethodParameters &args_;
00042 Any &result_;
00043 };
00044
00045
00046 class InvokableBase
00047 {
00048 public:
00049 virtual ~InvokableBase()
00050 {
00051 }
00052
00053 virtual void invoke( MethodCall &call ) const = 0;
00054 };
00055
00056
00057 class Invokable
00058 {
00059 public:
00060 Invokable( const Impl::InvokableBasePtr &invokable );
00061
00062 virtual ~Invokable()
00063 {
00064 }
00065
00066 void invoke( Impl::MethodCall &call ) const;
00067
00068 TypeId returnType_;
00069 std::vector<TypeId> argTypes_;
00070 InvokableBasePtr invokable_;
00071 };
00072
00073
00074 class AttributAccessor
00075 {
00076 public:
00077 virtual ~AttributAccessor()
00078 {
00079 }
00080
00081 virtual TypeId getType() const =0;
00082
00083 virtual Any get( const Any &holder) const = 0;
00084
00085 virtual void set( const Any &holder,
00086 const Any &value ) const = 0;
00087 };
00088
00089
00090 template<class Object, class AttributType>
00091 class AttributAccessorImpl : public AttributAccessor
00092 {
00093 public:
00094 typedef AttributType Object::*Attribut;
00095
00096 AttributAccessorImpl( Attribut attribut )
00097 : attribut_( attribut )
00098 {
00099 }
00100
00101 TypeId getType() const
00102 {
00103 return typeId( Type<AttributType>() );
00104 }
00105
00106 Any get( const Any &holder ) const
00107 {
00108 Object &object = *any_cast( holder, Type<Object *>() );
00109 return makeAny( object.*attribut_ );
00110 }
00111
00112 void set( const Any &holder,
00113 const Any &value ) const
00114 {
00115 Object &object = *any_cast( holder, Type<Object *>() );
00116 object.*attribut_ = any_cast( value, Type<AttributType>() );
00117 }
00118
00119 private:
00120 Attribut attribut_;
00121 };
00122
00123
00124 template<class Object, class TheAttributType>
00125 AttributAccessorPtr makeAccessor( TheAttributType Object::*attribut )
00126 {
00127 return AttributAccessorPtr(
00128 new AttributAccessorImpl<Object
00129 ,TheAttributType>( attribut ) );
00130 }
00131
00132 }
00134
00135
00136 class Attribut
00137 {
00138 public:
00139 Attribut( const ConstString &name,
00140 const Impl::AttributAccessorPtr &accessor );
00141
00142 ConstString getName() const;
00143
00144 TypeId getType() const;
00145
00146 void set( const Any &object,
00147 const Any &value ) const;
00148
00149 Any get( const Any &object ) const;
00150
00151 private:
00152 Class *class_;
00153 ConstString name_;
00154 Impl::AttributAccessorPtr accessor_;
00155 };
00156
00157
00158 class Method
00159 {
00160 public:
00161 Method( const ConstString &name,
00162 const Impl::Invokable &invokable );
00163
00164 Any invoke( const Any &object,
00165 const MethodParameters &args ) const;
00166
00167 ConstString getName() const;
00168
00169 size_type getArgCount() const;
00170
00171 TypeId getArgType( size_type index ) const;
00172
00173 TypeId getReturnType() const;
00174
00175 AnyEnumerator<TypeId> getArgTypes() const;
00176
00177 private:
00178 Class *class_;
00179 ConstString name_;
00180 Impl::Invokable invokable_;
00181 };
00182
00183
00184 class Class
00185 {
00186 public:
00187 static Class &create( const ConstString &name,
00188 TypeId type );
00189
00190 static const Class *findClass( const ConstString &name );
00191
00192 ConstString getName() const;
00193
00194 const Method *findMethod( const ConstString &name ) const;
00195
00196 void addMethod( const ConstString &name,
00197 const Impl::Invokable &invokable );
00198
00199 const Attribut *findAttribut( const ConstString &name ) const;
00200
00201 void addAttribut( const ConstString &name,
00202 const Impl::AttributAccessorPtr &accessor );
00203
00204 private:
00205 typedef SharedPtr<Class> ClassPtr;
00206 typedef SharedPtr<Method> MethodPtr;
00207 typedef SharedPtr<Attribut> AttributPtr;
00208 typedef std::map<ConstString,ClassPtr> ClassesByName;
00209 typedef std::map<ConstString,MethodPtr> MethodsByName;
00210 typedef std::map<ConstString,AttributPtr> AttributsByName;
00211
00212 static ClassesByName ®istry();
00213
00214 Class( const ConstString &name,
00215 TypeId type );
00216
00217 AttributsByName attributsByName_;
00218 MethodsByName methodsByName_;
00219 ConstString name_;
00220 TypeId type_;
00221 };
00222
00223
00224 template<class ClassType>
00225 class AutoRegisterClassReflection
00226 {
00227 public:
00228 AutoRegisterClassReflection()
00229 {
00230 ClassType::registerClassReflection();
00231 }
00232 };
00233
00234
00235 }
00236
00237
00238
00239
00240 # define CPPTL_REFLECT_CLASS_BEGIN( ClassType ) \
00241 typedef ClassType _Reflection_SelfType; \
00242 virtual const ::CppTL::Class *getClass() const \
00243 { \
00244 return ::CppTL::Class::findClass( #ClassType ); \
00245 } \
00246 static void registerClassReflection() \
00247 { \
00248 ::CppTL::Class &class_ = ::CppTL::Class::create( #ClassType, \
00249 ::CppTL::typeId( ::CppTL::Type<ClassType>() ) );
00250
00251
00252 # define CPPTL_REFLECT_METHOD( method ) \
00253 { \
00254 ::CppTL::Impl::Invokable invokable = ::CppTL::Impl::makeInvokable( \
00255 &_Reflection_SelfType::method ); \
00256 class_.addMethod( #method, invokable ); \
00257 }
00258
00259 # define CPPTL_REFLECT_METHOD_WITH_RETURN( method ) \
00260 { \
00261 ::CppTL::Impl::Invokable invokable = ::CppTL::Impl::makeInvokableR( \
00262 &_Reflection_SelfType::method ); \
00263 class_.addMethod( #method, invokable ); \
00264 }
00265
00266 # define CPPTL_REFLECT_RENAMED_ATTRIBUT( attribut, name ) \
00267 { \
00268 ::CppTL::Impl::AttributAccessorPtr accessor = ::CppTL::Impl::makeAccessor( \
00269 &_Reflection_SelfType::attribut ); \
00270 class_.addAttribut( name, accessor ); \
00271 }
00272
00273 # define CPPTL_REFLECT_ATTRIBUT( attribut ) \
00274 CPPTL_REFLECT_RENAMED_ATTRIBUT( attribut, #attribut )
00275
00276 # define CPPTL_REFLECT_CLASS_END() \
00277 }
00278
00279 # define CPPTL_REFLECT_REGISTER_CLASS( ClassType ) \
00280 static ::CppTL::AutoRegisterClassReflection<ClassType> \
00281 CPPTL_MAKE_UNIQUE_NAME(cpptlReflectRegisterClass);
00282
00283
00284 # include <cpptl/reflection.inl>
00285 # include <cpptl/reflectionimpl10.h>
00286
00287 #endif // CPPTL_REFLECTION_H_INCLUDED
00288