00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef GLFIELD_H
00020 #define GLFIELD_H
00021
00022 #include <map>
00023 #include <fstream>
00024 #include "referencecounted.h"
00025
00030 namespace GLScene
00031 {
00032
00035 class GLFieldBase
00036 {
00037 std::string* name;
00038
00039 public:
00040
00041 GLFieldBase( std::string* const n = NULL) { name = n; };
00042 virtual ~GLFieldBase() {};
00043
00044 virtual void setName( std::string* const n ) { name = n; };
00045 virtual const char* getName( void ) const { return name->c_str(); }
00046
00047 virtual const std::type_info& getType( ) = 0;
00048 virtual bool isOfType( std::type_info ) = 0;
00049
00050 virtual bool loadFromStream( std::istream& in, std::string compareTo, const char* fieldName = NULL ) = 0;
00051 virtual void saveToStream( std::ostream& out, const char* fieldName = NULL ) = 0;
00052 };
00053
00054
00055 typedef GLFieldBase* FieldBasePtr;
00056
00057
00058 template <class Type, short Size = 1>
00059 class GLField: public GLFieldBase
00060 {
00061 typedef std::pair< short unsigned, Type* > PairType;
00062
00063
00064 PairType* val;
00065
00066
00067 public:
00068
00069 GLField( std::string* const n = NULL)
00070 :GLFieldBase(n), val(NULL)
00071 {
00072 if( Size > 1 )
00073 set( new Type[Size] );
00074 else
00075 set( new Type );
00076 }
00077
00078 GLField( const GLField& fl, std::string* const n = NULL )
00079 :GLFieldBase(n), val(NULL)
00080 {
00081 set(fl);
00082 }
00083
00084 explicit GLField( const Type* t, std::string* const n = NULL )
00085 :GLFieldBase(n), val(NULL)
00086 {
00087 set(t);
00088 }
00089
00090 virtual ~GLField()
00091 {
00092 unref();
00093 }
00094
00095 inline void unref( void )
00096 {
00097 if( !val )
00098 return;
00099
00100 --(val->first);
00101
00102 if( val->first == 0)
00103 {
00104 if( val->second )
00105 {
00106 if( Size > 1 )
00107 delete [] val->second;
00108 else
00109 delete val->second;
00110 }
00111
00112 delete val;
00113 }
00114
00115 val = NULL;
00116 }
00117
00118 inline void ref( void )
00119 {
00120 if( !val )
00121 return;
00122 else
00123 ++(val->first);
00124 }
00125
00126 inline void set( const GLField& fl, std::string* const = NULL )
00127 {
00128 set( fl.val, n );
00129 }
00130
00131 inline void set( const PairType* pt, std::string* const = NULL )
00132 {
00133 if( n != NULL )
00134 setName( n );
00135
00136 if( pt == val )
00137 return;
00138
00139 unref();
00140
00141 val = pt;
00142
00143 ref();
00144 }
00145
00146 inline void set( Type* const t, std::string* const n = NULL )
00147 {
00148 if( n != NULL )
00149 setName( n );
00150
00151 if( val == NULL )
00152 {
00153 if( t == NULL )
00154 return;
00155
00156 val = new PairType;
00157 val->first = 1;
00158 val->second = NULL;
00159 }
00160 else
00161 {
00162 if( val->second != NULL)
00163 {
00164 if( val->second != t )
00165 {
00166 unref();
00167
00168 if( t == NULL )
00169 return;
00170
00171 val = new PairType;
00172 val->first = 1;
00173 val->second = NULL;
00174 }
00175
00176 }
00177 }
00178
00179 val->second = t;
00180 }
00181
00182 inline void set( const Type& t)
00183 {
00184 if( val == NULL )
00185 {
00186 val = new PairType;
00187 val->first = 1;
00188 val->second = new Type(t);
00189 }
00190 else
00191 {
00192 if( val->second != NULL)
00193 {
00194 unref();
00195
00196
00197 val = new PairType;
00198 val->first = 1;
00199 val->second = new Type(t);
00200 }
00201
00202 }
00203 }
00204
00205 inline const Type* get( void ) const
00206 {
00207 if( val )
00208 return val->second;
00209 else
00210 return NULL;
00211 }
00212
00213 inline bool operator == (FieldBasePtr ptr)
00214 {
00215 if( ptr == NULL )
00216 {
00217 if( val == NULL || val->second == NULL )
00218 return true;
00219 }
00220
00221 if( GLField<Type, Size>* cast = dynamic_cast< GLField<Type, Size>* >(ptr) )
00222 {
00223 if( cast->val == val )
00224 return true;
00225 else
00226 return false;
00227 }
00228 else
00229 return false;
00230 }
00231
00232 inline operator Type* (void) const
00233 {
00234 if( val )
00235 return val->second;
00236 else
00237 return NULL;
00238 }
00239
00240 inline operator Type (void) const
00241 {
00242 return *(val->second);
00243 }
00244
00245 inline Type* operator -> (void) const
00246 {
00247 return val->second;
00248 }
00249
00250 inline Type& operator * (void) const
00251 {
00252 return *(val->second);
00253 }
00254
00255 inline const GLField& operator = ( Type* const t )
00256 {
00257 set( t );
00258
00259 return *this;
00260 }
00261
00262 inline const GLField& operator = ( const Type& t )
00263 {
00264 set( t );
00265
00266 return *this;
00267 }
00268
00269 virtual const std::type_info& getType( void )
00270 {
00271 return typeid( Type );
00272 }
00273
00274 virtual bool isOfType( std::type_info t )
00275 {
00276 if( typeid( Type ) == t )
00277 return true;
00278 else
00279 return false;
00280 }
00281
00282 virtual bool loadFromStream( std::istream& in, std::string compareTo, const char* fieldName = NULL)
00283 {
00284 bool match = false;
00285
00286 if( getName() != NULL )
00287 {
00288 if( compareTo.compare( getName() ) == 0 )
00289 match = true;
00290 }
00291 else
00292 if( fieldName != NULL )
00293 {
00294 if( compareTo.compare( fieldName ) == 0)
00295 match = true;
00296 }
00297
00298 if( match )
00299 {
00300 char delim;
00301 in>>delim;
00302
00303 Type* newVal;
00304
00305 if( Size > 1 )
00306 {
00307 newVal = new Type[Size];
00308
00309 for( register short i = 0; i < Size; ++i )
00310 in>>newVal[i];
00311
00312 }
00313 else
00314 {
00315 newVal = new Type;
00316
00317 in>>(*newVal);
00318 }
00319
00320 set( newVal );
00321
00322 return true;
00323 }
00324 else
00325 return false;
00326 }
00327
00328 virtual void saveToStream( std::ostream& out, const char* fieldName = NULL)
00329 {
00330 if( val )
00331 if( val->second )
00332 {
00333 if( getName() != NULL )
00334 out<<getName();
00335 else
00336 out<<fieldName;
00337
00338 out<<" =";
00339
00340 if( Size > 1 )
00341 {
00342 for( register short i = 0; i < Size; ++i )
00343 out<<" "<<val->second[i];
00344 }
00345 else
00346 {
00347 out<<" "<<(*(val->second));
00348 }
00349
00350 out<<std::endl;
00351 }
00352 }
00353
00354 };
00355
00356
00357 class GLFieldHolder
00358 {
00359 public:
00360
00361 GLFieldHolder() {};
00362 virtual ~GLFieldHolder()
00363 {
00364 };
00365
00367 virtual FieldBasePtr getFieldByIndex( short index ) = 0;
00368
00369 virtual FieldBasePtr getField( std::string fieldName )
00370 {
00371 for( register short i = 0; true; ++i )
00372 {
00373 FieldBasePtr temp = getFieldByIndex( i );
00374 if( temp == NULL )
00375 break;
00376
00377 if( fieldName.compare( temp->getName() ) == 0 )
00378 return temp;
00379 };
00380
00381 return NULL;
00382 }
00383
00384 virtual bool loadFieldsFromStream( std::istream& in, std::string compareTo )
00385 {
00386 register short i = 0;
00387
00388 while( FieldBasePtr field = getFieldByIndex( i ) )
00389 {
00390 if( field->loadFromStream( in, compareTo ) )
00391 return true;
00392 ++i;
00393 };
00394
00395 return false;
00396 }
00397
00398 virtual void saveFieldsToStream( std::ostream& out )
00399 {
00400 register short i = 0;
00401
00402 while( FieldBasePtr field = getFieldByIndex( i ) )
00403 {
00404 field->saveToStream( out );
00405 ++i;
00406 };
00407 }
00408 };
00409
00410
00411 }
00412 #endif