H3D API  2.4.1
MField.h
Go to the documentation of this file.
1 // Copyright 2004-2019, SenseGraphics AB
3 //
4 // This file is part of H3D API.
5 //
6 // H3D API is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // H3D API is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with H3D API; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 //
20 // A commercial license is also available. Please contact us at
21 // www.sensegraphics.com for more information.
22 //
23 //
26 //
28 #ifndef __MFIELD_H__
29 #define __MFIELD_H__
30 
31 #include <string>
32 #include <set>
33 #include <vector>
34 #include <algorithm>
35 
36 #include <H3D/TypedField.h>
37 #include <H3D/Node.h>
38 #include <H3D/X3DFieldConversion.h>
39 
40 namespace H3D {
41 
44  class H3DAPI_API MFieldClass {
45  public:
47  virtual ~MFieldClass() {};
48 
50  DEPRECATED( "int setValueFromVoidPtr( const void *data, unsigned int nr_elements, unsigned int size, int id = 0 )", )
52 
54  virtual int setValueFromVoidPtr( void *data, unsigned int nr_elements,
55  unsigned int size, int id = 0 ) {
56  return setValueFromVoidPtr( (const void*)data, nr_elements, size, id );
57  }
58 
67  virtual int getValueAsVoidPtr( void *data, unsigned int &nr_elements,
68  unsigned int size, int id = 0 ) = 0;
69 
71  virtual unsigned int valueTypeSize() = 0;
72 
74  virtual unsigned int size() = 0;
75 
83  virtual int setValueFromVoidPtr( const void *data, unsigned int nr_elements,
84  unsigned int size, int id = 0 ) = 0;
85  };
86 
87 
97  template< class Type,
98  class VectorClass = std::vector< Type >,
99  class BaseField = ParsableMField >
100  class MFieldBase: public TypedField< BaseField,
101  void,
102  AnyNumber< MFieldBase< Type,
103  VectorClass,
104  BaseField > > >,
105  public MFieldClass {
106  public:
108  typedef VectorClass vector_type;
110  typedef VectorClass vector_return_type;
112  typedef typename VectorClass::value_type value_type;
114  typedef typename VectorClass::pointer pointer;
116  typedef typename VectorClass::const_reference const_reference;
118  typedef typename VectorClass::size_type size_type;
120  typedef typename VectorClass::difference_type difference_type;
122  typedef typename VectorClass::const_iterator const_iterator;
124  typedef typename VectorClass::const_reverse_iterator
126 
128  inline const_iterator begin( int id = 0 ) {
129  // check that we have the correct access type
130  this->checkAccessTypeGet( id );
131  this->upToDate();
132  return value.begin();
133  }
134 
136  inline const_iterator end( int id = 0 ) {
137  // check that we have the correct access type
138  this->checkAccessTypeGet( id );
139  this->upToDate();
140  return value.end();
141  }
142 
147  inline const_reverse_iterator rbegin( int id = 0 ) {
148  // check that we have the correct access type
149  this->checkAccessTypeGet( id );
150  this->upToDate();
151  return value.rbegin();
152  }
153 
158  inline const_reverse_iterator rend( int id = 0 ) {
159  // check that we have the correct access type
160  this->checkAccessTypeGet( id );
161  this->upToDate();
162  return value.rend();
163  }
164 
166  inline unsigned int size() {
167  this->upToDate();
168  return (unsigned int)value.size();
169  }
170 
172  inline size_type max_size() {
173  this->upToDate();
174  return value.max_size();
175  }
176 
179  inline size_type capacity() {
180  this->upToDate();
181  return value.capacity();
182  }
183 
191  inline void reserve( size_type s ) {
192  this->upToDate();
193  value.reserve( s );
194  }
195 
197  inline void resize( size_type n, Type t = Type(), int id = 0 ) {
198  this->checkAccessTypeSet( id );
199  this->upToDate();
200  value.resize( n, t );
201  this->startEvent();
202  }
203 
205  inline bool empty() {
206  this->upToDate();
207  return value.empty();
208  }
209 
211  inline const_reference operator[](size_type n ) {
212  // check that we have the correct access type
213  this->checkAccessTypeGet( 0 );
214  this->upToDate();
215  return value[n];
216  }
217 
219  inline const_reference front( int id = 0 ) {
220  // check that we have the correct access type
221  this->checkAccessTypeGet( id );
222  this->upToDate();
223  return value.front();
224  }
225 
227  inline const_reference back( int id = 0 ) {
228  // check that we have the correct access type
229  this->checkAccessTypeGet( id );
230  this->upToDate();
231  return value.back();
232  }
233 
235  inline void swap( VectorClass &x, int id = 0 ) {
236  // check that we have the correct access type
237  this->checkAccessTypeSet( id );
238  this->checkAccessTypeGet( id );
239  this->upToDate();
240  this->value.swap( x );
241  this->startEvent();
242  }
243 
245  inline void push_back( const Type &x, int id = 0 ) {
246  // check that we have the correct access type
247  this->checkAccessTypeSet( id );
248  this->upToDate();
249  this->value.push_back( x );
250  this->startEvent();
251  }
252 
254  void pop_back( int id = 0 ) {
255  // check that we have the correct access type
256  this->checkAccessTypeSet( id );
257  this->upToDate();
258  value.pop_back();
259  this->startEvent();
260  }
261 
263  inline void clear( int id = 0 ) {
264  // check that we have the correct access type
265  this->checkAccessTypeSet( id );
266  value.clear();
267  this->startEvent();
268  }
269 
278  inline virtual int setValueFromVoidPtr( const void *data,
279  unsigned int nr_elements,
280  unsigned int len, int id = 0 ) {
281  this->checkAccessTypeSet( id );
282 
283  if( len != sizeof( value_type ) * nr_elements )
284  return -1;
285 
286  std::vector< Type > new_data( nr_elements );
287  for( unsigned int i = 0; i < nr_elements; ++i ) {
288  new_data[i] = static_cast< const value_type * >( data )[i];
289  }
290  this->value.swap( new_data );
291  this->startEvent();
292  return 0;
293  }
294 
295 H3D_PUSH_WARNINGS()
296 H3D_DISABLE_UNUSED_PARAMETER_WARNING()
306  inline virtual int getValueAsVoidPtr( void *data,
307  unsigned int &nr_elements,
308  unsigned int len,
309  int id = 0 ) {
310  unsigned int sz = sizeof( value_type );
311  nr_elements = (unsigned int) this->value.size();
312  if( len < sz * nr_elements ) {
313  return -1;
314  }
315 
316  value_type *data_ptr =
317  static_cast< value_type * >( data );
318 
319  this->upToDate();
320 
321  for( unsigned int i = 0; i < nr_elements; ++i ) {
322  data_ptr[i] = value[i];
323  }
324  return sz * nr_elements;
325  }
326 H3D_POP_WARNINGS()
327 
328 
329  inline virtual unsigned int valueTypeSize() {
330  return sizeof( value_type );
331  }
332 
335 
337  MFieldBase( size_type sz ) : value( sz ) {};
338 
340  static string classTypeName() {
342  }
343 
344  protected:
346  VectorClass value;
347  };
348 
354  template< class Type >
355  class MField: public MFieldBase< Type,
356  std::vector< Type >,
357  ParsableMField > {
358  typedef MFieldBase< Type,
359  std::vector< Type >,
361 
362  public:
364  typedef typename std::vector< Type >::iterator iterator;
365 
369 
371  MField() {}
372 
374  MField( typename BaseMField::size_type sz ) :
375  BaseMField( sz ) {}
376 
378  inline virtual const std::vector< Type > &getValue( int id = 0 );
379 
384  inline virtual typename std::vector<Type>::const_reference
385  getValueByIndex( typename BaseMField::size_type i, int id = 0 ) {
386 #ifdef DEBUG
387  Console(LogLevel::Debug) << "MField(" << this->name << ")::getValue()" << endl;
388 #endif
389  // check that we have the correct access type
390  this->checkAccessTypeGet( id );
391 
392  // check that the field is up-to-date first
393  this->upToDate();
394  // i < 0 is never true..
395  if( /*i < 0 || */ i >= this->value.size() ) {
396  stringstream s;
397  s << "Trying to access value outside the bounds of field "
398  << this->getFullName() << ". Field has size " << this->value.size()
399  << ". ";
400  throw InvalidIndex( i, s.str(), H3D_FULL_LOCATION );
401  }
402  return this->value[i];
403  }
404 
409  inline virtual void setValue( const std::vector< Type > &v, int id = 0 );
410 
416  inline virtual void setValue( typename BaseMField::size_type i,
417  const Type &v, int id = 0 ) {
418 #ifdef DEBUG
419  Console(LogLevel::Debug) << "MField< " << typeid( Type ).name()
420  << " >(" << this->name << ")::setValue()" << endl;
421 #endif
422  // check that we have the correct access type
423  this->checkAccessTypeSet( id );
424  this->value[i] = v; //.set( i, v );
425  // reset the event pointer since we want to ignore any pending
426  // events when the field is set to a new value.
427  this->event.ptr = NULL;
428  // generate an event.
429  this->startEvent();
430  }
431 
435  inline virtual void setValueFromString( const string &s ) {
436  std::vector< Type > v;
437  X3D::X3DStringToVector< std::vector< Type > >( s, v );
438  setValue( v );
439  }
440 
442  inline virtual void addElementFromString( const string &s ) {
443  this->push_back( X3D::X3DStringToValue< Type >( s ) );
444  }
445 
448  inline virtual string getValueAsString( const string& separator = " " ) {
449  stringstream s;
450  const std::vector< Type > &v = getValue();
451 
452  if( v.size() == 0 )
453  return "";
454  unsigned int i;
455  for( i = 0; i < v.size() - 1; ++i )
456  s << v[i] << separator;
457  s << v[i];
458  return s.str();
459  }
460 
463  const Type &x,
464  int id = 0 ) {
465  this->checkAccessTypeSet( id );
466  this->upToDate();
467  iterator i = this->value.insert( this->iteratorFromConst ( pos ), x );
468  this->startEvent();
469  return i;
470  }
471 
473  template <class InputIterator>
475  InputIterator first,
476  InputIterator last,
477  int id = 0 ) {
478  this->checkAccessTypeSet( id );
479  this->upToDate();
480  this->value.insert( this->iteratorFromConst ( pos ), first, last );
481  this->startEvent();
482  }
483 
485  inline void insert(typename MField<Type>::const_iterator pos,
486  typename BaseMField::size_type n, const Type &x, int id = 0 ) {
487  this->checkAccessTypeSet( id );
488  this->upToDate();
489  this->value.insert( this->iteratorFromConst ( pos ), n, x );
490  this->startEvent();
491  }
492 
494  inline virtual void erase( typename MField<Type>::const_iterator pos, int id = 0 ) {
495  this->checkAccessTypeSet( id );
496  this->upToDate();
497  this->value.erase( this->iteratorFromConst ( pos ) );
498  this->startEvent();
499  }
500 
502  inline virtual void erase( typename MField<Type>::const_iterator first,
503  typename MField<Type>::const_iterator last, int id = 0 ) {
504  this->checkAccessTypeSet( id );
505  this->upToDate();
506  this->value.erase(
507  this->iteratorFromConst ( first ),
508  this->iteratorFromConst ( last ) );
509  this->startEvent();
510  }
511 
512 
514  inline virtual void erase( const Type &a, int /*id*/ = 0 ) {
515  iterator i = std::find( this->value.begin(), this->value.end(), a );
516  if( i != this->value.end() ) {
517  this->value.erase( i );
518  }
519  }
520 
522  virtual string getTypeName() {
523  return this->classTypeName();
524  }
525 
529  virtual size_t getSize( ) {
530  const std::vector< Type > &v = getValue();
531  return v.size();
532  }
533 
535  inline virtual string getElementAsString( size_t element ) {
536  stringstream s;
537  const std::vector< Type > &v = getValue();
538 
539  if( element >= v.size() )
540  throw InvalidIndex( element, "getElementAsString", H3D_FULL_LOCATION );
541 
542  s << v[element];
543  return s.str();
544  }
545 
546 
547  protected:
549  inline virtual void update();
550 
553  return this->value.begin()+(pos-this->value.begin());
554  }
555  };
556 
557  template< class Type >
559 #ifdef DEBUG
560  Console(LogLevel::Debug) << "MField< " << typeid( Type ).name()
561  << " >(" << this->name << ")::update()" << endl;
562 #endif
563  if( this->owner )
564  this->value =
565  static_cast< MField<Type>* >
566  (this->event.ptr)->getValue( this->owner->id );
567  else
568  this->value =
569  static_cast< MField<Type>* >(this->event.ptr)->getValue();
570  }
571 
572  template< class Type >
573  void MField< Type >::setValue( const std::vector< Type > &v, int id ) {
574 #ifdef DEBUG
575  Console(LogLevel::Debug) << "MField< " << typeid( Type ).name()
576  << " >(" << this->name << ")::setValue()" << endl;
577 #endif
578  // check that we have the correct access type
579  this->checkAccessTypeSet( id );
580  this->value = v;
581  // reset the event pointer since we want to ignore any pending
582  // events when the field is set to a new value.
583  this->event.ptr = NULL;
584  // generate an event.
585  this->startEvent();
586  }
587 
588  template< class Type >
589  const std::vector< Type > &MField<Type >::getValue( int id ) {
590 #ifdef DEBUG
591  Console(LogLevel::Debug) << "MField< " << typeid( Type ).name()
592  << " >(" << this->name << ")::getValue()" << endl;
593 #endif
594  // check that we have the correct access type
595  this->checkAccessTypeGet( id );
596 
597  // check that the field is up-to-date first
598  this->upToDate();
599  return this->value;
600  }
601 
602 }
603 
604 #endif
605 
#define H3D_FULL_LOCATION
Node base class.
Contains the TypedField template class.
This file contains functions for convertion from a string to a value of an X3D field type.
string getFullName()
Get the full name of the field including the name of the owner node if it exists (ownername....
Definition: Field.cpp:406
virtual void startEvent()
Start a new event from this field.
Definition: Field.cpp:349
virtual void upToDate()
Check that the field is up-to-date, if not update() is called to make it up-to-date.
Definition: Field.cpp:388
void checkAccessTypeGet(int id)
Check the access type is valid for getting the value of a field.
Definition: Field.cpp:160
void checkAccessTypeSet(int id)
Check the access type is valid for changing the value of a field.
Definition: Field.cpp:185
string name
The name of the field.
Definition: Field.h:312
The common base class for MField types and MFNode.
Definition: MField.h:105
MFieldBase(size_type sz)
Creates a MField with space reserved for n elements.
Definition: MField.h:337
VectorClass::const_reference const_reference
Const reference to Type.
Definition: MField.h:116
void pop_back(int id=0)
Removed the last element.
Definition: MField.h:254
const_iterator end(int id=0)
Returns a const_iterator pointing to the end of the vector.
Definition: MField.h:136
bool empty()
true if the vector's size is 0.
Definition: MField.h:205
size_type max_size()
Returns the largest possible size of the vector.
Definition: MField.h:172
unsigned int size()
Returns the size of the vector.
Definition: MField.h:166
const_reverse_iterator rend(int id=0)
Returns a const_reverse_iterator pointing to the end of the reversed vector.
Definition: MField.h:158
VectorClass vector_return_type
The return type of functions that return the value of the field.
Definition: MField.h:110
const_reverse_iterator rbegin(int id=0)
Returns a const_reverse_iterator pointing to the beginning of the reversed vector.
Definition: MField.h:147
VectorClass value
The encapsulated vector.
Definition: MField.h:346
const_reference operator[](size_type n)
Returns the n'th element.
Definition: MField.h:211
static string classTypeName()
Returns a string name for this field type e.g. MFInt32.
Definition: MField.h:340
const_reference front(int id=0)
Returns the first element.
Definition: MField.h:219
virtual int getValueAsVoidPtr(void *data, unsigned int &nr_elements, unsigned int len, int id=0)
Get the value of the data copied into a memory buffer.
Definition: MField.h:306
const_iterator begin(int id=0)
Returns a const_iterator pointing to the beginning of the vector.
Definition: MField.h:128
void push_back(const Type &x, int id=0)
Inserts a new element at the end.
Definition: MField.h:245
virtual unsigned int valueTypeSize()
Returns the size in bytes of the value type the mfield encapsulates.
Definition: MField.h:329
VectorClass::const_iterator const_iterator
Const iterator used to iterate through a vector.
Definition: MField.h:122
MFieldBase()
Default constructor. Creates an empty MField.
Definition: MField.h:334
VectorClass::difference_type difference_type
A signed integral type.
Definition: MField.h:120
VectorClass::pointer pointer
Pointer to Type.
Definition: MField.h:114
void swap(VectorClass &x, int id=0)
Swaps the contents of two vectors.
Definition: MField.h:235
virtual int setValueFromVoidPtr(const void *data, unsigned int nr_elements, unsigned int len, int id=0)
Set the value of the field given a pointer to where the value of the field is.
Definition: MField.h:278
VectorClass vector_type
The type of the value member.
Definition: MField.h:108
size_type capacity()
Number of elements for which memory has been allocated.
Definition: MField.h:179
void reserve(size_type s)
A request for allocation of additional memory.
Definition: MField.h:191
VectorClass::const_reverse_iterator const_reverse_iterator
Const iterator used to iterate backwards through a vector.
Definition: MField.h:125
void clear(int id=0)
Erases all of the elements.
Definition: MField.h:263
VectorClass::value_type value_type
The type of the values stored in the vector.
Definition: MField.h:112
const_reference back(int id=0)
Returns the last element.
Definition: MField.h:227
VectorClass::size_type size_type
An unsigned integral type.
Definition: MField.h:118
void resize(size_type n, Type t=Type(), int id=0)
Inserts or erases elements at the end such that the size becomes n.
Definition: MField.h:197
Base class for all fields created with the MField template.
Definition: MField.h:44
virtual unsigned int valueTypeSize()=0
Returns the size in bytes of the value type the mfield encapsulates.
virtual int setValueFromVoidPtr(const void *data, unsigned int nr_elements, unsigned int size, int id=0)=0
Set the value of the field given a pointer to where the value of the field is.
virtual ~MFieldClass()
Virtual destructor.
Definition: MField.h:47
virtual unsigned int size()=0
Returns the number of values that is stored in the mfield.
virtual int getValueAsVoidPtr(void *data, unsigned int &nr_elements, unsigned int size, int id=0)=0
Get the value of the data copied into a memory buffer.
Thrown if the index given to getValueByIndex() is outside the boundaries.
Definition: MField.h:368
Template class that adds the Field mechanism to a vector of values.
Definition: MField.h:357
virtual void setValue(const std::vector< Type > &v, int id=0)
Set the value of the field.
Definition: MField.h:573
virtual string getElementAsString(size_t element)
Get the value of an element of the field as a string.
Definition: MField.h:535
virtual void erase(typename MField< Type >::const_iterator pos, int id=0)
Erases the element at position pos.
Definition: MField.h:494
virtual void addElementFromString(const string &s)
Add a new element to an MField from a string value.
Definition: MField.h:442
virtual void setValueFromString(const string &s)
Set the value of the field given a string.
Definition: MField.h:435
iterator iteratorFromConst(typename MField< Type >::const_iterator pos)
Helper function to get an iterator from a const_iterator.
Definition: MField.h:552
MField()
Default constructor. Creates an empty MField.
Definition: MField.h:371
virtual void setValue(typename BaseMField::size_type i, const Type &v, int id=0)
Change the value of one element in the MField.
Definition: MField.h:416
void insert(typename MField< Type >::const_iterator pos, typename BaseMField::size_type n, const Type &x, int id=0)
Inserts n copies of x before pos.
Definition: MField.h:485
MField< Type >::const_iterator insert(typename MField< Type >::const_iterator pos, const Type &x, int id=0)
Inserts x before pos.
Definition: MField.h:462
std::vector< Type >::iterator iterator
iterator used to iterate through a vector.
Definition: MField.h:364
MField(typename BaseMField::size_type sz)
Creates an MField with space reserved for size nodes.
Definition: MField.h:374
virtual void update()
Make the field up to date given that an event has occured.
Definition: MField.h:558
virtual const std::vector< Type > & getValue(int id=0)
Get the value of the MField.
Definition: MField.h:589
void insert(typename MField< Type >::const_iterator pos, InputIterator first, InputIterator last, int id=0)
Inserts the range [first, last) before pos.
Definition: MField.h:474
virtual std::vector< Type >::const_reference getValueByIndex(typename BaseMField::size_type i, int id=0)
Get the value of an element of the MField.
Definition: MField.h:385
virtual string getTypeName()
Returns a string name for this field type e.g. MFInt32.
Definition: MField.h:522
virtual void erase(const Type &a, int=0)
Erase the first element equal to a.
Definition: MField.h:514
virtual string getValueAsString(const string &separator=" ")
Get the value of the field as a string.
Definition: MField.h:448
virtual size_t getSize()
Set the value of the field given a string.
Definition: MField.h:529
virtual void erase(typename MField< Type >::const_iterator first, typename MField< Type >::const_iterator last, int id=0)
Erases the range [first, last)
Definition: MField.h:502
This is a field which value can be set by a string from the X3D parser.
Definition: Field.h:371
A template modifier class for adding type checking on the routes to any Field class.
Definition: TypedField.h:84
H3DDouble x
H3D_VALUE_EXCEPTION(string, InvalidType)
An exception thrown when a field is of the wrong type when it is checked.
Type getValue(const char *s, const char *&rest)
Function that reads characters from a char * and converts them to a given type.
Definition: X3DFieldConversion.h:134
H3D API namespace.
Definition: Anchor.h:38