MField.h

00001 
00002 //    Copyright 2004, SenseGraphics AB
00003 //
00004 //    This file is part of H3D API.
00005 //
00006 //    H3D API is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    H3D API is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with H3D API; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 //
00020 //    A commercial license is also available. Please contact us at 
00021 //    www.sensegraphics.com for more information.
00022 //
00023 //
00024 //
00025 //
00027 #ifndef __MFIELD_H__
00028 #define __MFIELD_H__
00029 
00030 #include <string>
00031 #include <set>
00032 #include <vector>
00033 #include <algorithm>
00034 
00035 #include "TypedField.h"
00036 #include "Node.h"
00037 #include "X3DFieldConversion.h"
00038 
00039 using namespace std;
00040 
00041 namespace H3D {
00042 
00043   class H3DAPI_API MFieldClass {
00044   public:
00045     // Virtual destructor.
00046     virtual ~MFieldClass() {};
00047 
00054     virtual int setValueFromVoidPtr( void *data, unsigned int nr_elements, 
00055                                      unsigned int size, int id = 0 ) = 0;
00056 
00064     virtual int getValueAsVoidPtr( void *data, unsigned int &nr_elements,
00065                                    unsigned int size, int id = 0 ) = 0;
00066 
00068     virtual unsigned int valueTypeSize() = 0;
00069 
00071     virtual unsigned int size() = 0; 
00072   };
00073 
00074 
00084   template< class Type, 
00085             class VectorClass = vector< Type >, 
00086             class BaseField  = ParsableMField > 
00087   class MFieldBase: public TypedField< BaseField,
00088                                        void,
00089                                        AnyNumber< MFieldBase< Type, 
00090                                                               VectorClass, 
00091                                                               BaseField > > >,
00092                     public MFieldClass {
00093   public:
00095     typedef VectorClass vector_type;
00097     typedef typename VectorClass::value_type value_type;
00099     typedef typename VectorClass::pointer pointer;
00101     typedef typename VectorClass::const_reference const_reference;
00103     typedef typename VectorClass::size_type size_type;
00105     typedef typename VectorClass::difference_type difference_type;  
00107     typedef typename VectorClass::const_iterator const_iterator;
00109     typedef typename VectorClass::const_reverse_iterator 
00110     const_reverse_iterator;
00111 
00113     inline const_iterator begin( int id = 0 ) { 
00114       // check that we have the correct access type
00115       this->checkAccessTypeGet( id );
00116       this->upToDate();
00117       return value.begin();
00118     }
00120     inline const_iterator end( int id = 0 ) { 
00121       // check that we have the correct access type
00122       this->checkAccessTypeGet( id );
00123       this->upToDate();
00124       return value.end(); 
00125     }
00128     inline const_reverse_iterator rbegin( int id = 0 ) { 
00129       // check that we have the correct access type
00130       this->checkAccessTypeGet( id );
00131       this->upToDate();
00132       return value.rbegin();
00133     }
00136     inline const_reverse_iterator rend( int id = 0 ) { 
00137       // check that we have the correct access type
00138       this->checkAccessTypeGet( id );
00139       this->upToDate();
00140       return value.rend(); 
00141     }
00142 
00144     inline unsigned int size() { 
00145       this->upToDate();
00146       return value.size(); 
00147     }
00148 
00150     inline size_type max_size() {
00151       this->upToDate();
00152       return value.max_size();
00153     }
00154         
00157     inline size_type capacity() { 
00158       this->upToDate();
00159       return value.capacity(); 
00160     }
00161         
00169     inline void reserve( size_t s ) { 
00170       this->upToDate();
00171       value.reserve( s ); 
00172     }
00173 
00175     inline  void resize( size_t n, Type t = Type(), int id = 0 ) { 
00176       this->checkAccessTypeSet( id );
00177       this->upToDate();
00178       value.resize( n ); 
00179       this->startEvent();
00180     }
00181 
00183     inline  bool empty() { 
00184       this->upToDate();
00185       return value.empty(); 
00186     }
00188     inline  const_reference operator[](size_type n ) {
00189       // check that we have the correct access type
00190       this->checkAccessTypeGet( 0 );
00191       this->upToDate();
00192       return value[n];
00193     }
00194 
00196     inline  const_reference front( int id = 0 ) { 
00197       // check that we have the correct access type
00198       this->checkAccessTypeGet( id );
00199       this->upToDate();
00200       return value.front(); 
00201     }
00202 
00204     inline  const_reference back( int id = 0 ) {
00205       // check that we have the correct access type
00206       this->checkAccessTypeGet( id );
00207       this->upToDate();
00208       return value.back(); 
00209     }
00210 
00212     inline  void swap( VectorClass &x, int id = 0 ) {
00213       // check that we have the correct access type
00214       this->checkAccessTypeSet( id );
00215       this->checkAccessTypeGet( id );
00216       this->upToDate();
00217       this->value.swap( x );
00218       this->startEvent();
00219     }
00220 
00222     inline void push_back( const Type &x, int id = 0 ) {
00223       // check that we have the correct access type
00224       this->checkAccessTypeSet( id );
00225       this->upToDate();    
00226       this->value.push_back( x );
00227       this->startEvent();
00228     }
00229 
00231     void pop_back( int id = 0 ) {
00232       // check that we have the correct access type
00233       this->checkAccessTypeSet( id );
00234       this->upToDate();
00235       value.pop_back();
00236       this->startEvent();
00237     }
00238 
00240     inline  void clear( int id = 0 ) {
00241       // check that we have the correct access type
00242       this->checkAccessTypeSet( id );
00243       this->upToDate();
00244       value.clear();
00245       this->startEvent();
00246     }
00247 
00254     inline virtual int setValueFromVoidPtr( void *data, 
00255                                             unsigned int nr_elements, 
00256                                             unsigned int len, int id = 0 ) {
00257       this->checkAccessTypeSet( id );
00258           
00259       if( len != sizeof( value_type ) * nr_elements )
00260       return -1;
00261       
00262       vector< Type > new_data( nr_elements );
00263       for( unsigned int i = 0; i < nr_elements; i++ ) {
00264         new_data[i] = static_cast< value_type * >( data )[i];
00265       }
00266       this->value.swap( new_data );
00267       this->startEvent();
00268       return 0;
00269     }
00270 
00278     inline virtual int getValueAsVoidPtr( void *data, 
00279                                           unsigned int &nr_elements,
00280                                           unsigned int len, 
00281                                           int id = 0 ) {
00282       unsigned int sz = sizeof( value_type );
00283       nr_elements = this->value.size();
00284       if( len < sz * nr_elements ) {
00285         return -1;
00286       }
00287       
00288       value_type *data_ptr = 
00289         static_cast< value_type * >( data );
00290 
00291       this->upToDate();
00292 
00293       for( unsigned int i = 0; i < nr_elements; i++ ) {
00294         data_ptr[i] = value[i];
00295       }
00296       return sz * nr_elements;
00297     } 
00298 
00300     inline virtual unsigned int valueTypeSize() {
00301       return sizeof( value_type );
00302     }
00303 
00305     MFieldBase() {};
00306 
00308     MFieldBase( size_type sz ) : value( sz ) {};
00309 
00311     static string classTypeName() {
00312       return typeid( MFieldBase< Type, VectorClass, BaseField > ).name();
00313     }
00314 
00315   protected:
00317     VectorClass value;
00318   };
00319 
00325   template< class Type >
00326   class MField: public MFieldBase< Type, 
00327                                    vector< Type >, 
00328                                    ParsableMField > {
00329     typedef MFieldBase< Type, 
00330                         vector< Type >, 
00331                         ParsableMField > BaseMField;
00332      
00333   public:
00335     typedef typename vector< Type >::iterator iterator;
00336 
00339     H3D_VALUE_EXCEPTION( typename BaseMField::size_type, InvalidIndex );
00340 
00342     MField() {}
00343 
00345     MField( typename BaseMField::size_type sz ) : 
00346       BaseMField( sz ) {}
00347         
00349     inline virtual const vector< Type > &getValue( int id = 0 );
00350 
00353     inline virtual typename MField<Type>::const_reference 
00354     getValueByIndex( typename BaseMField::size_type i, int id = 0 ) {
00355 #ifdef DEBUG
00356       Console(1) << "MField(" << name << ")::getValue()" << endl;
00357 #endif
00358       // check that we have the correct access type
00359       this->checkAccessTypeGet( id );
00360       
00361       // check that the field is up-to-date first
00362       this->upToDate();
00363       if( i < 0 || i >= this->value.size() ) {
00364         stringstream s;
00365         s << "Trying to access value outside the bounds of field "
00366           << this->getFullName() << ". Field has size " << this->value.size()
00367           << ". ";
00368         throw InvalidIndex( i, s.str(), H3D_FULL_LOCATION );
00369       }
00370       return this->value[i];    
00371     }
00372 
00375     inline virtual void setValue( const vector< Type > &v, int id = 0  );
00376 
00380     inline virtual void setValue( typename BaseMField::size_type i,
00381                                   const Type &v, int id = 0  ) {
00382 #ifdef DEBUG
00383       Console(1) << "MField< " << typeid( Type ).name() 
00384            << " >(" << this->name << ")::setValue()" << endl;
00385 #endif
00386       // check that we have the correct access type
00387       this->checkAccessTypeSet( id );
00388       this->value[i] = v; //.set( i, v );
00389       // reset the event pointer since we want to ignore any pending
00390       // events when the field is set to a new value.
00391       this->event.ptr = NULL;
00392       // generate an event.
00393       this->startEvent();                                  
00394     }
00395 
00399     inline virtual void setValueFromString( const string &s ) {
00400       vector< Type > v;
00401       X3D::X3DStringToVector< vector< Type > >( s, v ); 
00402       setValue( v );
00403     }
00404 
00406     inline virtual void addElementFromString( const string &s ) {
00407       push_back(  X3D::X3DStringToValue< Type >( s )  );
00408     }
00409 
00412     inline virtual string getValueAsString( const string& separator = " " ) {
00413       stringstream s;
00414       const vector< Type > &v = getValue();
00415       
00416       if( v.size() == 0 )
00417         return "";
00418       unsigned int i;
00419       for( i = 0; i < v.size() - 1; i++ )
00420         s << v[i] << separator;
00421       s << v[i];
00422       return s.str();
00423     }
00424 
00426     inline iterator insert( iterator pos,
00427                      const Type &x, 
00428                      int id = 0 ) {
00429       this->checkAccessTypeSet( id );
00430       this->upToDate();
00431       iterator i = this->value.insert( pos, x );
00432       this->startEvent();
00433       return i;
00434     }
00435         
00437    template <class InputIterator>
00438    void insert(iterator pos,
00439                InputIterator first, 
00440                InputIterator last,
00441                int id = 0 ) {
00442      this->checkAccessTypeSet( id );
00443      this->upToDate();
00444      this->value.insert( pos, first, last );
00445      this->startEvent();
00446    } 
00447             
00449     inline void insert(iterator pos, 
00450                        typename BaseMField::size_type n, const Type &x, int id = 0 ) {
00451       this->checkAccessTypeSet( id );
00452       this->upToDate();
00453       this->value.insert( pos, n, x );
00454       this->startEvent();
00455     }
00456     
00458     inline virtual void erase( iterator pos, int id = 0 ) { 
00459       this->checkAccessTypeSet( id );
00460       this->upToDate();
00461       this->value.erase( pos );
00462       this->startEvent();
00463     }
00464         
00466     inline virtual void erase( iterator first, iterator last, int id = 0 ) {
00467       this->checkAccessTypeSet( id );
00468       this->upToDate();
00469       this->value.erase( first, last );
00470       this->startEvent();
00471     }
00472     
00473     
00475     inline virtual void erase( const Type &a, int id = 0 ) {
00476       iterator i = std::find( this->value.begin(), this->value.end(), a );
00477       if( i != this->value.end() ) {
00478         this->value.erase( i );
00479       }
00480     } 
00481 
00483     virtual string getTypeName() {
00484       return this->classTypeName();
00485     }
00486 
00490     virtual size_t getSize( ) {
00491       const vector< Type > &v = getValue();
00492       return v.size();
00493     }
00494 
00497     inline virtual string getElementAsString( size_t element ) {
00498       stringstream s;
00499       const vector< Type > &v = getValue();
00500       
00501       if( element >= v.size() )
00502         throw InvalidIndex( element, "getElementAsString", H3D_FULL_LOCATION );
00503       
00504       s << v[element];
00505       return s.str();
00506     }
00507 
00508 
00509   protected:
00511     inline virtual void update();
00512   };
00513 
00514   template< class Type  >
00515   void MField< Type >::update() {
00516 #ifdef DEBUG
00517     Console(1) << "MField< " << typeid( Type ).name() 
00518          << " >(" << this->name << ")::update()" << endl;
00519 #endif
00520     if( this->owner )
00521       this->value = 
00522         static_cast< MField<Type>* >
00523         (this->event.ptr)->getValue( this->owner->id );
00524     else 
00525       this->value = 
00526         static_cast< MField<Type>* >(this->event.ptr)->getValue();
00527   }
00528 
00529   template< class Type  >
00530   void MField< Type >::setValue( const vector< Type > &v, int id ) {
00531 #ifdef DEBUG
00532     Console(1) << "MField< " << typeid( Type ).name() 
00533          << " >(" << this->name << ")::setValue()" << endl;
00534 #endif
00535     // check that we have the correct access type
00536     this->checkAccessTypeSet( id );
00537     this->value = v;
00538     // reset the event pointer since we want to ignore any pending
00539     // events when the field is set to a new value.
00540     this->event.ptr = NULL;
00541     // generate an event.
00542     this->startEvent();
00543   }
00544 
00545   template< class Type >
00546   const vector< Type > &MField<Type >::getValue( int id ) {
00547 #ifdef DEBUG
00548     Console(1) << "MField< " << typeid( Type ).name() 
00549          << " >(" << this->name << ")::getValue()" << endl;
00550 #endif
00551     // check that we have the correct access type
00552     this->checkAccessTypeGet( id );
00553 
00554     // check that the field is up-to-date first
00555     this->upToDate();
00556     return this->value;
00557   }
00558     
00559 }
00560 
00561 #endif
00562 

Generated on Thu Aug 24 12:38:33 2006 for H3D API by  doxygen 1.4.5