00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef __PROPERTYSLOT_HPP
00032 #define __PROPERTYSLOT_HPP
00033
00034 #include <functional>
00035
00036 #include "libecs.hpp"
00037
00038 #include "PropertiedClass.hpp"
00039 #include "convertTo.hpp"
00040 #include "Polymorph.hpp"
00041
00042
00043 namespace libecs
00044 {
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 class PropertySlotBase
00067 {
00068
00069 public:
00070
00071 PropertySlotBase()
00072 {
00073 ;
00074 }
00075
00076 ECELL_API virtual ~PropertySlotBase();
00077
00078 virtual const bool isSetable() const = 0;
00079 virtual const bool isGetable() const = 0;
00080
00081 ECELL_API virtual const bool isLoadable() const;
00082 ECELL_API virtual const bool isSavable() const;
00083
00084 };
00085
00086
00087 template
00088 <
00089 class T
00090 >
00091 class PropertySlot
00092 :
00093 public PropertySlotBase
00094 {
00095
00096 public:
00097
00098 typedef void ( T::* SetPolymorphMethodPtr )( PolymorphCref );
00099 typedef const Polymorph ( T::* GetPolymorphMethodPtr )() const;
00100
00101 PropertySlot()
00102 {
00103 ;
00104 }
00105
00106 virtual ~PropertySlot()
00107 {
00108 ;
00109 }
00110
00111
00112 #define _PROPERTYSLOT_SETMETHOD( TYPE )\
00113 virtual void set ## TYPE( T& anObject, Param<TYPE>::type value ) = 0;
00114
00115 #define _PROPERTYSLOT_GETMETHOD( TYPE )\
00116 virtual const TYPE get ## TYPE( const T& anObject ) const = 0;
00117
00118 _PROPERTYSLOT_SETMETHOD( Polymorph );
00119 _PROPERTYSLOT_GETMETHOD( Polymorph );
00120
00121 _PROPERTYSLOT_SETMETHOD( Real );
00122 _PROPERTYSLOT_GETMETHOD( Real );
00123
00124 _PROPERTYSLOT_SETMETHOD( Integer );
00125 _PROPERTYSLOT_GETMETHOD( Integer );
00126
00127 _PROPERTYSLOT_SETMETHOD( String );
00128 _PROPERTYSLOT_GETMETHOD( String );
00129
00130 #undef _PROPERTYSLOT_SETMETHOD
00131 #undef _PROPERTYSLOT_GETMETHOD
00132
00133
00134 virtual void loadPolymorph( T& anObject, Param<Polymorph>::type aValue )
00135 {
00136 setPolymorph( anObject, aValue );
00137 }
00138
00139 virtual const Polymorph savePolymorph( const T& anObject ) const
00140 {
00141 return getPolymorph( anObject );
00142 }
00143
00144 };
00145
00146
00147 template
00148 <
00149 class T,
00150 typename SlotType_
00151 >
00152 class ConcretePropertySlot
00153 :
00154 public PropertySlot<T>
00155 {
00156
00157 public:
00158
00159 DECLARE_TYPE( SlotType_, SlotType );
00160
00161 typedef typename Param<SlotType>::type SetType;
00162 typedef const SlotType GetType;
00163
00164 typedef void ( T::* SetMethodPtr )( SetType );
00165 typedef GetType ( T::* GetMethodPtr )() const;
00166
00167 ConcretePropertySlot( const SetMethodPtr aSetMethodPtr,
00168 const GetMethodPtr aGetMethodPtr )
00169 :
00170 theSetMethodPtr( SetMethod( aSetMethodPtr ) ),
00171 theGetMethodPtr( GetMethod( aGetMethodPtr ) )
00172 {
00173 ;
00174 }
00175
00176 virtual ~ConcretePropertySlot()
00177 {
00178 ;
00179 }
00180
00181
00182 virtual const bool isSetable() const
00183 {
00184 return isSetableMethod( theSetMethodPtr );
00185 }
00186
00187 virtual const bool isGetable() const
00188 {
00189 return isGetableMethod( theGetMethodPtr );
00190 }
00191
00192 #define _PROPERTYSLOT_SETMETHOD( TYPE )\
00193 virtual void set ## TYPE( T& anObject, Param<TYPE>::type aValue )\
00194 {\
00195 setImpl( anObject, aValue );\
00196 }
00197
00198 #define _PROPERTYSLOT_GETMETHOD( TYPE )\
00199 virtual const TYPE get ## TYPE( const T& anObject ) const\
00200 {\
00201 return getImpl<TYPE>( anObject );\
00202 }
00203
00204 _PROPERTYSLOT_SETMETHOD( Polymorph );
00205 _PROPERTYSLOT_GETMETHOD( Polymorph );
00206
00207 _PROPERTYSLOT_SETMETHOD( Real );
00208 _PROPERTYSLOT_GETMETHOD( Real );
00209
00210 _PROPERTYSLOT_SETMETHOD( Integer );
00211 _PROPERTYSLOT_GETMETHOD( Integer );
00212
00213 _PROPERTYSLOT_SETMETHOD( String );
00214 _PROPERTYSLOT_GETMETHOD( String );
00215
00216 #undef _PROPERTYSLOT_SETMETHOD
00217 #undef _PROPERTYSLOT_GETMETHOD
00218
00219
00220 protected:
00221
00222 inline void callSetMethod( T& anObject, SetType aValue )
00223 {
00224 ( anObject.*theSetMethodPtr )( aValue );
00225 }
00226
00227 inline GetType callGetMethod( const T& anObject ) const
00228 {
00229 return ( anObject.*theGetMethodPtr )();
00230 }
00231
00232 template < typename Type >
00233 inline void setImpl( T& anObject, Type aValue )
00234 {
00235 callSetMethod( anObject, convertTo<SlotType>( aValue ) );
00236 }
00237
00238 template < typename Type >
00239 inline const Type getImpl( const T& anObject ) const
00240 {
00241 return convertTo<Type>( callGetMethod( anObject ) );
00242 }
00243
00244
00245 static const bool isSetableMethod( const SetMethodPtr aSetMethodPtr )
00246 {
00247 const SetMethodPtr aNullMethodPtr( &PropertiedClass::nullSet<SlotType> );
00248 return aSetMethodPtr != aNullMethodPtr;
00249 }
00250
00251 static const bool isGetableMethod( const GetMethodPtr aGetMethodPtr )
00252 {
00253 const GetMethodPtr
00254 aNullMethodPtr( &PropertiedClass::nullGet<SlotType> );
00255 return aGetMethodPtr != aNullMethodPtr;
00256 }
00257
00258
00259 static SetMethodPtr SetMethod( SetMethodPtr aSetMethodPtr )
00260 {
00261 if( aSetMethodPtr == NULLPTR )
00262 {
00263 return &PropertiedClass::nullSet<SlotType>;
00264 }
00265 else
00266 {
00267 return aSetMethodPtr;
00268 }
00269 }
00270
00271 static GetMethodPtr GetMethod( GetMethodPtr aGetMethodPtr )
00272 {
00273 if( aGetMethodPtr == NULLPTR )
00274 {
00275 return &PropertiedClass::nullGet<SlotType>;
00276 }
00277 else
00278 {
00279 return aGetMethodPtr;
00280 }
00281 }
00282
00283
00284 protected:
00285
00286 const SetMethodPtr theSetMethodPtr;
00287 const GetMethodPtr theGetMethodPtr;
00288
00289 };
00290
00291 template
00292 <
00293 class T,
00294 typename SlotType_
00295 >
00296 class LoadSaveConcretePropertySlot
00297 :
00298 public ConcretePropertySlot<T,SlotType_>
00299 {
00300
00301 public:
00302
00303 DECLARE_TYPE( SlotType_, SlotType );
00304
00305 typedef ConcretePropertySlot<T,SlotType> ConcretePropertySlot;
00306
00307 typedef typename ConcretePropertySlot::SetType SetType;
00308 typedef typename ConcretePropertySlot::GetType GetType;
00309
00310 typedef typename ConcretePropertySlot::SetMethodPtr SetMethodPtr;
00311 typedef typename ConcretePropertySlot::GetMethodPtr GetMethodPtr;
00312
00313 LoadSaveConcretePropertySlot( const SetMethodPtr aSetMethodPtr,
00314 const GetMethodPtr aGetMethodPtr,
00315 const SetMethodPtr aLoadMethodPtr,
00316 const GetMethodPtr aSaveMethodPtr )
00317 :
00318 ConcretePropertySlot( aSetMethodPtr, aGetMethodPtr ),
00319 theLoadMethodPtr( SetMethod( aLoadMethodPtr ) ),
00320 theSaveMethodPtr( GetMethod( aSaveMethodPtr ) )
00321 {
00322 ;
00323 }
00324
00325 ~LoadSaveConcretePropertySlot()
00326 {
00327 ;
00328 }
00329
00330
00331 virtual const bool isLoadable() const
00332 {
00333 return isSetableMethod( theLoadMethodPtr );
00334 }
00335
00336 virtual const bool isSavable() const
00337 {
00338 return isGetableMethod( theSaveMethodPtr );
00339 }
00340
00341 virtual void loadPolymorph( T& anObject, Param<Polymorph>::type aValue )
00342 {
00343 loadImpl( anObject, aValue );
00344 }
00345
00346 virtual const Polymorph savePolymorph( const T& anObject ) const
00347 {
00348 return saveImpl( anObject );
00349 }
00350
00351
00352 protected:
00353
00354 inline void callLoadMethod( T& anObject, SetType aValue )
00355 {
00356 ( anObject.*theLoadMethodPtr )( aValue );
00357 }
00358
00359 inline GetType callSaveMethod( const T& anObject ) const
00360 {
00361 return ( anObject.*theSaveMethodPtr )();
00362 }
00363
00364 inline void loadImpl( T& anObject, PolymorphCref aValue )
00365 {
00366 callLoadMethod( anObject, convertTo<SlotType>( aValue ) );
00367 }
00368
00369 inline const Polymorph saveImpl( const T& anObject ) const
00370 {
00371 return convertTo<Polymorph>( callSaveMethod( anObject ) );
00372 }
00373
00374 protected:
00375
00376 const SetMethodPtr theLoadMethodPtr;
00377 const GetMethodPtr theSaveMethodPtr;
00378
00379 };
00380
00381
00382
00383 }
00384
00385
00386 #endif