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 __PROPERTYINTERFACE_HPP
00032 #define __PROPERTYINTERFACE_HPP
00033
00034 #include "AssocVector.h"
00035
00036 #include "libecs.hpp"
00037 #include "PropertySlot.hpp"
00038 #include "PropertySlotProxy.hpp"
00039
00040 #define PROPERTY_FIELD "Property__"
00041 #define PROPERTYLIST_FIELD "PropertyList"
00042
00043 namespace libecs
00044 {
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 class PropertyInterfaceBase
00055 {
00056 public:
00057
00058 ~PropertyInterfaceBase()
00059 {
00060 ;
00061 }
00062
00063 protected:
00064
00065 PropertyInterfaceBase()
00066 {
00067 ;
00068 }
00069
00070 static void throwNoSlot( StringCref aClassName, StringCref aPropertyName );
00071
00072 static void throwNotLoadable( PropertiedClassCref aClassName,
00073 StringCref aPropertyName );
00074 static void throwNotSavable( PropertiedClassCref aClassName,
00075 StringCref aPropertyName );
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 };
00098
00099
00100 template
00101 <
00102 class T
00103 >
00104 class PropertyInterface
00105 :
00106 public PropertyInterfaceBase
00107 {
00108
00109 public:
00110
00111 typedef PropertySlot<T> PropertySlot_;
00112 DECLARE_TYPE( PropertySlot_, PropertySlot );
00113
00114 DECLARE_ASSOCVECTOR_TEMPLATE( String, PropertySlotPtr,
00115 std::less<const String>, PropertySlotMap );
00116
00117 PropertyInterface()
00118 {
00119 theInfoMap[ String( PROPERTYLIST_FIELD )] = Polymorph( PolymorphVector() ) ;
00120 T::initializePropertyInterface( Type2Type<T>() );
00121 }
00122
00123 ~PropertyInterface()
00124 {
00125
00126
00127
00128
00129
00130
00131
00132
00133 }
00134
00135
00136
00137
00138
00139
00140 static PolymorphMapCref getInfoMap( void )
00141 {
00142 return theInfoMap;
00143 }
00144
00145
00146
00147
00148
00149
00150 static void setInfoField( StringCref aFieldName, PolymorphCref aValue )
00151 {
00152 theInfoMap[ aFieldName ] = aValue;
00153
00154 }
00155
00156
00157
00158
00159
00160
00161
00162 static void setPropertyInfoField( StringCref aPropertyName, StringCref aTypeString,
00163 Integer setFlag, Integer getFlag,
00164 Integer saveFlag, Integer loadFlag )
00165 {
00166 String PROP_FIELD( PROPERTY_FIELD );
00167 String PROPLIST_FIELD ( PROPERTYLIST_FIELD );
00168
00169 PolymorphVector aPropertyDescriptor;
00170 aPropertyDescriptor.push_back( aTypeString );
00171 aPropertyDescriptor.push_back( setFlag );
00172 aPropertyDescriptor.push_back( getFlag );
00173 aPropertyDescriptor.push_back( saveFlag );
00174 aPropertyDescriptor.push_back( loadFlag );
00175 String aPropertyNameField( aPropertyName );
00176 aPropertyNameField.insert( 0, PROP_FIELD );
00177 setInfoField( aPropertyNameField, aPropertyDescriptor );
00178
00179
00180 PolymorphVector aPolymorphVector( getInfoField( PROPLIST_FIELD ).asPolymorphVector());
00181 aPolymorphVector.push_back( aPropertyName );
00182 setInfoField( PROPLIST_FIELD, Polymorph( aPolymorphVector ) );
00183
00184 }
00185
00186
00187
00188
00189
00190 static PolymorphCref getInfoField( StringCref aFieldName )
00191 {
00192 return theInfoMap[ aFieldName ];
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 static PropertySlotPtr getPropertySlot( StringCref aPropertyName )
00205 {
00206 PropertySlotMapConstIterator i( findPropertySlot( aPropertyName ) );
00207
00208 if( i == thePropertySlotMap.end() )
00209 {
00210 throwNoSlot( "This class", aPropertyName );
00211 }
00212
00213 return i->second;
00214 }
00215
00216 static PropertySlotProxyPtr
00217 createPropertySlotProxy( T& anObject,
00218 StringCref aPropertyName )
00219 {
00220 try
00221 {
00222 PropertySlotPtr aPropertySlot( getPropertySlot( aPropertyName ) );
00223 return new ConcretePropertySlotProxy<T>( anObject, *aPropertySlot );
00224 }
00225 catch( NoSlotCref )
00226 {
00227 throwNoSlot( anObject.getClassName(), aPropertyName );
00228 }
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 static void setProperty( T& anObject, StringCref aPropertyName,
00244 PolymorphCref aValue )
00245 {
00246 PropertySlotMapConstIterator
00247 aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00248
00249 if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00250 {
00251 aPropertySlotMapIterator->second->setPolymorph( anObject, aValue );
00252 }
00253 else
00254 {
00255 anObject.defaultSetProperty( aPropertyName, aValue );
00256 }
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 static const Polymorph getProperty( const T& anObject,
00272 StringCref aPropertyName )
00273 {
00274 PropertySlotMapConstIterator
00275 aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00276
00277 if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00278 {
00279 return aPropertySlotMapIterator->second->getPolymorph( anObject );
00280 }
00281 else
00282 {
00283 return anObject.defaultGetProperty( aPropertyName );
00284 }
00285 }
00286
00287
00288 static void loadProperty( T& anObject, StringCref aPropertyName,
00289 PolymorphCref aValue )
00290 {
00291 PropertySlotMapConstIterator
00292 aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00293
00294 if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00295 {
00296 PropertySlotPtr aPropertySlotPtr( aPropertySlotMapIterator->second );
00297
00298 if( aPropertySlotPtr->isLoadable() )
00299 {
00300 aPropertySlotPtr->loadPolymorph( anObject, aValue );
00301 }
00302 else
00303 {
00304 throwNotLoadable( anObject, aPropertyName );
00305 }
00306 }
00307 else
00308 {
00309 anObject.defaultSetProperty( aPropertyName, aValue );
00310 }
00311 }
00312
00313
00314 static const Polymorph
00315 saveProperty( const T& anObject, StringCref aPropertyName )
00316 {
00317 PropertySlotMapConstIterator
00318 aPropertySlotMapIterator( findPropertySlot( aPropertyName ) );
00319
00320 if( aPropertySlotMapIterator != thePropertySlotMap.end() )
00321 {
00322 PropertySlotPtr aPropertySlotPtr( aPropertySlotMapIterator->second );
00323 if( aPropertySlotPtr->isSavable() )
00324 {
00325 return aPropertySlotPtr->savePolymorph( anObject );
00326 }
00327 else
00328 {
00329 throwNotSavable( anObject, aPropertyName );
00330 }
00331 }
00332 else
00333 {
00334 return anObject.defaultGetProperty( aPropertyName );
00335 }
00336 }
00337
00338 static const Polymorph getPropertyList( const T& anObject )
00339 {
00340 PolymorphVector aVector1, aVector2;
00341
00342
00343 for( PropertySlotMapConstIterator i( thePropertySlotMap.begin() );
00344 i != thePropertySlotMap.end() ; ++i )
00345 {
00346 aVector1.push_back( i->first );
00347 }
00348
00349 aVector2 = anObject.defaultGetPropertyList();
00350
00351 if( aVector2.size() > 0 )
00352 {
00353 for( PolymorphVectorIterator i( aVector2.begin() );
00354 i != aVector2.end(); ++i )
00355 {
00356 aVector1.push_back( i->asString() );
00357 }
00358 }
00359
00360 return aVector1;
00361 }
00362
00363
00364 static void
00365 registerPropertySlot( StringCref aName, PropertySlotPtr aPropertySlotPtr )
00366 {
00367 if( findPropertySlot( aName ) != thePropertySlotMap.end() )
00368 {
00369
00370 delete thePropertySlotMap[ aName ];
00371 thePropertySlotMap.erase( aName );
00372 }
00373
00374
00375 thePropertySlotMap.insert( std::make_pair( aName, aPropertySlotPtr ) );
00376 }
00377
00378
00379 static const Polymorph
00380 getPropertyAttributes( const T& anObject, StringCref aPropertyName )
00381 {
00382 PropertySlotMapConstIterator i( findPropertySlot( aPropertyName ) );
00383
00384 if( i != thePropertySlotMap.end() )
00385 {
00386 PropertySlotBasePtr
00387 aPropertySlotPtr( getPropertySlot( aPropertyName ) );
00388
00389 PolymorphVector aVector;
00390
00391
00392 aVector.push_back
00393 ( static_cast<Integer>( aPropertySlotPtr->isSetable() ) );
00394
00395
00396 aVector.push_back
00397 ( static_cast<Integer>( aPropertySlotPtr->isGetable() ) );
00398
00399
00400 aVector.push_back
00401 ( static_cast<Integer>( aPropertySlotPtr->isLoadable() ) );
00402
00403
00404 aVector.push_back
00405 ( static_cast<Integer>( aPropertySlotPtr->isSavable() ) );
00406
00407 return aVector;
00408 }
00409 else
00410 {
00411 return anObject.defaultGetPropertyAttributes( aPropertyName );
00412 }
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 static PropertySlotMapCref getPropertySlotMap()
00432 {
00433 return thePropertySlotMap;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 private:
00482
00483 static PropertySlotMapConstIterator
00484 findPropertySlot( StringCref aPropertyName )
00485 {
00486 return thePropertySlotMap.find( aPropertyName );
00487 }
00488
00489 private:
00490
00491 static PropertySlotMap thePropertySlotMap;
00492
00493 static PolymorphMap theInfoMap;
00494
00495 };
00496
00497
00498
00499
00500
00501 template< class T > class libecs::PropertyInterface< T>::PropertySlotMap
00502 libecs::PropertyInterface< T>::thePropertySlotMap;
00503 template< class T > class std::map<const String, Polymorph, std::less<const String> > libecs::PropertyInterface< T>::theInfoMap;
00504
00505
00506
00507
00508
00509 }
00510
00511 #endif
00512
00513
00514
00515
00516
00517
00518
00519