H3D API  2.4.1
ThreadSafeFields.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 //
27 //
29 #ifndef __THREAD_SAFE_FIELDS_H__
30 #define __THREAD_SAFE_FIELDS_H__
31 
32 #include <assert.h>
33 #include <H3D/PeriodicUpdate.h>
34 #include <H3DUtil/Threads.h>
35 
36 namespace H3D {
37 
53  template< class BaseField >
54  class ThreadSafeSField: public PeriodicUpdate< BaseField > {
55  public:
58 
60  inline virtual void setValue( const typename BaseField::value_type &v,
61  int id = 0 ) {
63  rt_value = v;
64  rt_value_changed = true;
65  } else {
68  void * param[] = { &this->value, &rt_value };
70  }
71  }
72 
74  inline virtual const typename BaseField::value_type &getValue( int id = 0 ) {
76  return rt_value;
77  } else {
80  }
81  }
82 
85  virtual void upToDate() {
87 
88  if( rt_value_changed ) {
89  void * param[] = { &rt_value, &this->value };
91  this->startEvent();
92  } else {
94  }
95  }
96 
97  protected:
101  void * * data = static_cast< void * * >( _data );
102  typename BaseField::value_type *new_value =
103  static_cast< typename BaseField::value_type * >( data[0] );
104  typename BaseField::value_type *rt_value =
105  static_cast< typename BaseField::value_type * >( data[1] );
106  *rt_value = *new_value;
108  }
109 
113  inline virtual void update() {
116  void * param[] = { &this->value, &rt_value };
118  }
119 
121  typename BaseField::value_type rt_value;
122 
126  };
127 
144  template< class BaseField >
145  class ThreadSafeRefSField: public PeriodicUpdate< BaseField > {
146  public:
149 
151  inline virtual void setValue( typename BaseField::value_type v,
152  int id = 0 ) {
154  rt_value.reset( v );
155  rt_value_changed = true;
156  } else {
159  void * param[] = { v, &rt_value };
160  H3DUtil::HapticThread::synchronousHapticCB( transferValue, param );
161  }
162  }
163 
165  virtual typename BaseField::typed_value_type getValue( int id = 0 ) {
167  return static_cast< typename BaseField::typed_value_type >( rt_value.get() );
168  } else {
171  }
172  }
173 
176  virtual void upToDate() {
178 
179  if( rt_value_changed ) {
180  void * param[] = { rt_value.get(), &this->value };
181  H3DUtil::HapticThread::synchronousHapticCB( transferValue, param );
182  this->startEvent();
183  } else {
185  }
186  }
187 
188  protected:
189  static H3DUtil::PeriodicThread::CallbackCode transferValue( void * _data ) {
190  void * * data = static_cast< void * * >( _data );
191  typename BaseField::value_type new_value =
192  static_cast< typename BaseField::value_type >( data[0] );
194  static_cast< AutoRef< typename BaseField::class_type> * >( data[1] );
195  rt_value->reset( new_value );
197  }
198 
200  virtual void onAdd( typename BaseField::value_type i ) {
203  void * param[] = { i, &rt_value };
204  H3DUtil::HapticThread::synchronousHapticCB( transferValue, param );
205  }
206 
209 
213  };
214 
230  template< class BaseField >
231  class ThreadSafeMField: public PeriodicUpdate< BaseField > {
232  public:
235 
240  inline virtual void setValue(
241  const vector< typename BaseField::value_type > &v,
242  int id = 0 ) {
244  rt_value = v;
245  rt_value_changed = true;
246  } else {
249  void * param[] = { &this->value, &rt_value };
251  }
252  }
253 
259  inline virtual void setValue( typename BaseField::size_type i,
260  const typename BaseField::value_type &t,
261  int id = 0 ) {
263  rt_value[i] = t;
264  rt_value_changed = true;
265  } else {
268  void * param[] = { &this->value, &rt_value };
270  }
271  }
272 
274  inline virtual void swap( typename BaseField::vector_type &x, int id = 0 ) {
276  rt_value.swap( x );
277  rt_value_changed = true;
278  } else {
281  void * param[] = { &this->value, &rt_value };
283  }
284  }
285 
287  inline virtual void push_back( const typename BaseField::value_type &x,
288  int id = 0 ) {
290  rt_value.push_back( x );
291  rt_value_changed = true;
292  } else {
295  void * param[] = { &this->value, &rt_value };
297  }
298  }
299 
301  void pop_back( int id = 0 ) {
303  rt_value.pop_back();
304  rt_value_changed = true;
305  } else {
308  void * param[] = { &this->value, &rt_value };
310  }
311  }
312 
314  inline virtual void clear( int id = 0 ) {
316  rt_value.clear();
317  rt_value_changed = true;
318  } else {
321  void * param[] = { &this->value, &rt_value };
323  }
324  }
325 
327  inline virtual typename BaseField::const_iterator begin( int id = 0 ) {
329  return rt_value.begin();
330  } else {
333  }
334  }
335 
337  inline virtual typename BaseField::const_iterator end( int id = 0 ) {
339  return rt_value.end();
340  } else {
343  }
344  }
345 
350  inline virtual typename BaseField::const_reverse_iterator rbegin( int id = 0 ) {
352  return rt_value.rbegin();
353  } else {
356  }
357  }
362  inline virtual typename BaseField::const_reverse_iterator rend( int id = 0 ) {
364  return rt_value.rend();
365  } else {
368  }
369  }
370 
372  inline virtual unsigned int size() {
374  return rt_value.size();
375  } else {
378  }
379  }
380 
382  inline virtual typename BaseField::size_type max_size() {
384  return rt_value.max_size();
385  } else {
388  }
389  }
390 
393  inline virtual typename BaseField::size_type capacity() {
395  return rt_value.capacity();
396  } else {
399  }
400  }
401 
403  inline virtual bool empty() {
405  return rt_value.empty();
406  } else {
409  }
410  }
412  inline virtual typename BaseField::const_reference operator[]( typename BaseField::size_type n ) {
414  return rt_value[n];
415  } else {
418  }
419  }
420 
422  inline virtual typename BaseField::const_reference front( int id = 0 ) {
424  return rt_value.front();
425  } else {
428  }
429  }
430 
432  inline virtual typename BaseField::const_reference back( int id = 0 ) {
434  return rt_value.back();
435  } else {
438  }
439  }
440 
442  inline virtual const typename BaseField::vector_type &getValue( int id = 0 ) {
444  return rt_value;
445  } else {
448  }
449  }
450 
453  virtual void upToDate() {
455 
456  if( rt_value_changed ) {
457  void * param[] = { &rt_value, &this->value };
459  this->startEvent();
460  } else {
462  }
463  }
464 
465  protected:
469  void * * data = static_cast< void * * >( _data );
470  typename BaseField::vector_type *new_value =
471  static_cast< typename BaseField::vector_type * >( data[0] );
472  typename BaseField::vector_type *rt_value =
473  static_cast< typename BaseField::vector_type * >( data[1] );
474  *rt_value = *new_value;
476  }
477 
481  inline virtual void update() {
484  void * param[] = { &this->value, &rt_value };
486  }
487 
489  typename BaseField::vector_type rt_value;
490 
494  };
495 
496 }
497 
498 #endif
499 
500 
501 
502 
503 
504 
505 
Header file for PeriodicUpdate, template field modifier.
RefCountedClassType * get() const
void reset(RefCountedClassType *p=0)
static bool inHapticThread()
static void synchronousHapticCB(PeriodicThreadBase::CallbackFunc func, void *data)
static bool inMainThread()
The PeriodicUpdate is a template modifier that changes the way the field is updated.
Definition: PeriodicUpdate.h:74
virtual void upToDate()
upToDate is specialized to record the time of the call to the function in the last_up_to_date member.
Definition: PeriodicUpdate.h:125
<>
Definition: ThreadSafeFields.h:231
virtual unsigned int size()
Returns the size of the vector.
Definition: ThreadSafeFields.h:372
virtual bool empty()
true if the vector's size is 0.
Definition: ThreadSafeFields.h:403
virtual void setValue(const vector< typename BaseField::value_type > &v, int id=0)
Set the value of the field.
Definition: ThreadSafeFields.h:240
virtual BaseField::const_reverse_iterator rbegin(int id=0)
Returns a const_reverse_iterator pointing to the beginning of the reversed vector.
Definition: ThreadSafeFields.h:350
ThreadSafeMField()
Constructor.
Definition: ThreadSafeFields.h:234
BaseField::vector_type rt_value
The copy of the field value to be used in the haptics threads.
Definition: ThreadSafeFields.h:489
virtual void upToDate()
Make sure that the field is up-to-date.
Definition: ThreadSafeFields.h:453
virtual void clear(int id=0)
Erases all of the elements.
Definition: ThreadSafeFields.h:314
bool rt_value_changed
Flag indicating if the rt_value has been changed by a haptics thread.
Definition: ThreadSafeFields.h:493
static H3DUtil::PeriodicThread::CallbackCode transferValue(void *_data)
Callback function to transfer copy a value between two pointers of the same type.
Definition: ThreadSafeFields.h:468
virtual void push_back(const typename BaseField::value_type &x, int id=0)
Inserts a new element at the end.
Definition: ThreadSafeFields.h:287
virtual void setValue(typename BaseField::size_type i, const typename BaseField::value_type &t, int id=0)
Change the value of one element in the MField.
Definition: ThreadSafeFields.h:259
virtual void update()
The update function is specialized to synchronize with the haptics threads and copy the new value of ...
Definition: ThreadSafeFields.h:481
virtual void swap(typename BaseField::vector_type &x, int id=0)
Swaps the contents of two vectors.
Definition: ThreadSafeFields.h:274
virtual BaseField::const_reference operator[](typename BaseField::size_type n)
Returns the n'th element.
Definition: ThreadSafeFields.h:412
virtual BaseField::const_reference back(int id=0)
Returns the last element.
Definition: ThreadSafeFields.h:432
virtual BaseField::const_reference front(int id=0)
Returns the first element.
Definition: ThreadSafeFields.h:422
virtual const BaseField::vector_type & getValue(int id=0)
Gets the value of the field.
Definition: ThreadSafeFields.h:442
virtual BaseField::const_reverse_iterator rend(int id=0)
Returns a const_reverse_iterator pointing to the end of the reversed vector.
Definition: ThreadSafeFields.h:362
virtual BaseField::size_type max_size()
Returns the largest possible size of the vector.
Definition: ThreadSafeFields.h:382
virtual BaseField::const_iterator end(int id=0)
Returns a const_iterator pointing to the end of the vector.
Definition: ThreadSafeFields.h:337
void pop_back(int id=0)
Removed the last element.
Definition: ThreadSafeFields.h:301
virtual BaseField::size_type capacity()
Number of elements for which memory has been allocated.
Definition: ThreadSafeFields.h:393
virtual BaseField::const_iterator begin(int id=0)
Returns a const_iterator pointing to the beginning of the vector.
Definition: ThreadSafeFields.h:327
<>
Definition: ThreadSafeFields.h:145
virtual void onAdd(typename BaseField::value_type i)
onAdd is extended to change the rt_image value in a thread safe way.
Definition: ThreadSafeFields.h:200
ThreadSafeRefSField()
Constructor.
Definition: ThreadSafeFields.h:148
virtual BaseField::typed_value_type getValue(int id=0)
Get the value of the field.
Definition: ThreadSafeFields.h:165
AutoRef< typename BaseField::class_type > rt_value
The reference for the haptics loop.
Definition: ThreadSafeFields.h:208
bool rt_value_changed
Flag indicating if the rt_value has been changed by a haptics thread.
Definition: ThreadSafeFields.h:212
virtual void setValue(typename BaseField::value_type v, int id=0)
Set the value of the field.
Definition: ThreadSafeFields.h:151
virtual void upToDate()
Make sure that the field is up-to-date.
Definition: ThreadSafeFields.h:176
<>
Definition: ThreadSafeFields.h:54
virtual void update()
The update function is specialized to synchronize with the haptics threads and copy the new value of ...
Definition: ThreadSafeFields.h:113
bool rt_value_changed
Flag indicating if the rt_value has been changed by a haptics thread.
Definition: ThreadSafeFields.h:125
virtual const BaseField::value_type & getValue(int id=0)
Get the value of the field.
Definition: ThreadSafeFields.h:74
ThreadSafeSField()
Constructor.
Definition: ThreadSafeFields.h:57
static H3DUtil::PeriodicThread::CallbackCode transferValue(void *_data)
Callback function to transfer copy a value between two pointers of the same type.
Definition: ThreadSafeFields.h:100
virtual void setValue(const typename BaseField::value_type &v, int id=0)
Set the value of the field.
Definition: ThreadSafeFields.h:60
BaseField::value_type rt_value
The copy of the field value to be used in the haptics threads.
Definition: ThreadSafeFields.h:121
virtual void upToDate()
Make sure that the field is up-to-date.
Definition: ThreadSafeFields.h:85
H3DDouble & operator[](int i)
H3DDouble x
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