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
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
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
00115 this->checkAccessTypeGet( id );
00116 this->upToDate();
00117 return value.begin();
00118 }
00120 inline const_iterator end( int id = 0 ) {
00121
00122 this->checkAccessTypeGet( id );
00123 this->upToDate();
00124 return value.end();
00125 }
00128 inline const_reverse_iterator rbegin( int id = 0 ) {
00129
00130 this->checkAccessTypeGet( id );
00131 this->upToDate();
00132 return value.rbegin();
00133 }
00136 inline const_reverse_iterator rend( int id = 0 ) {
00137
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
00190 this->checkAccessTypeGet( 0 );
00191 this->upToDate();
00192 return value[n];
00193 }
00194
00196 inline const_reference front( int id = 0 ) {
00197
00198 this->checkAccessTypeGet( id );
00199 this->upToDate();
00200 return value.front();
00201 }
00202
00204 inline const_reference back( int id = 0 ) {
00205
00206 this->checkAccessTypeGet( id );
00207 this->upToDate();
00208 return value.back();
00209 }
00210
00212 inline void swap( VectorClass &x, int id = 0 ) {
00213
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
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
00233 this->checkAccessTypeSet( id );
00234 this->upToDate();
00235 value.pop_back();
00236 this->startEvent();
00237 }
00238
00240 inline void clear( int id = 0 ) {
00241
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
00359 this->checkAccessTypeGet( id );
00360
00361
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
00387 this->checkAccessTypeSet( id );
00388 this->value[i] = v;
00389
00390
00391 this->event.ptr = NULL;
00392
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
00536 this->checkAccessTypeSet( id );
00537 this->value = v;
00538
00539
00540 this->event.ptr = NULL;
00541
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
00552 this->checkAccessTypeGet( id );
00553
00554
00555 this->upToDate();
00556 return this->value;
00557 }
00558
00559 }
00560
00561 #endif
00562