Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members

glfield.h

00001 /***************************************************************************
00002                           glfield.h  -  description
00003                              -------------------
00004     begin                : Wed Oct 29 2003
00005     copyright            : (C) 2003 by Jacques Gasselin de Richebourg
00006     email                : jacquesgasselin@hotmail.com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU Lesser General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
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    //typedef RCPointer<GLFieldBase> FieldBasePtr;
00055    typedef GLFieldBase* FieldBasePtr;
00056 
00057    // fields implement a simple reference count that is very small and quick
00058    template <class Type, short Size = 1>
00059    class GLField: public GLFieldBase
00060    {
00061       typedef std::pair< short unsigned, Type* > PairType;
00062 
00063       //Type* val;
00064       PairType* val;
00065 //      Type* val;
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; // no need to double copy
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          { // they have the same value type
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;//remove the " = "
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

Generated on Wed Feb 4 23:11:33 2004 by doxygen 1.3.3