00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00027
00029 #ifndef __THREAD_SAFE_FIELDS_H__
00030 #define __THREAD_SAFE_FIELDS_H__
00031
00032 #include <assert.h>
00033 #include "PeriodicUpdate.h"
00034 #include "Threads.h"
00035
00036 namespace H3D {
00037
00053 template< class BaseField >
00054 class ThreadSafeSField: public PeriodicUpdate< BaseField > {
00055 public:
00057 ThreadSafeSField(): rt_value_changed( false ) {}
00058
00060 inline virtual void setValue( const typename BaseField::value_type &v,
00061 int id = 0 ) {
00062 if( HapticThread::inHapticThread() ) {
00063 rt_value = v;
00064 rt_value_changed = true;
00065 } else {
00066 assert( ThreadBase::inMainThread() );
00067 PeriodicUpdate< BaseField >::setValue( v, id );;
00068 void * param[] = { &this->value, &rt_value };
00069 HapticThread::synchronousHapticCB( transferValue, param );
00070 }
00071 }
00072
00074 inline virtual const typename BaseField::value_type &getValue( int id = 0 ) {
00075 if( HapticThread::inHapticThread() ) {
00076 return rt_value;
00077 } else {
00078 assert( ThreadBase::inMainThread() );
00079 return PeriodicUpdate< BaseField >::getValue( id );
00080 }
00081 }
00082
00085 virtual void upToDate() {
00086 assert( ThreadBase::inMainThread() );
00087
00088 if( rt_value_changed ) {
00089 void * param[] = { &rt_value, &this->value };
00090 HapticThread::synchronousHapticCB( transferValue, param );
00091 this->startEvent();
00092 } else {
00093 PeriodicUpdate< BaseField >::upToDate();
00094 }
00095 }
00096
00097 protected:
00100 static PeriodicThread::CallbackCode transferValue( void * _data ) {
00101 void * * data = static_cast< void * * >( _data );
00102 typename BaseField::value_type *new_value =
00103 static_cast< typename BaseField::value_type * >( data[0] );
00104 typename BaseField::value_type *rt_value =
00105 static_cast< typename BaseField::value_type * >( data[1] );
00106 *rt_value = *new_value;
00107 return PeriodicThread::CALLBACK_DONE;
00108 }
00109
00113 inline virtual void update() {
00114 assert( ThreadBase::inMainThread() );
00115 PeriodicUpdate< BaseField >::update();;
00116 void * param[] = { &this->value, &rt_value };
00117 HapticThread::synchronousHapticCB( transferValue, param );
00118 }
00119
00121 typename BaseField::value_type rt_value;
00122
00125 bool rt_value_changed;
00126 };
00127
00144 template< class BaseField >
00145 class ThreadSafeRefSField: public PeriodicUpdate< BaseField > {
00146 public:
00148 ThreadSafeRefSField(): rt_value_changed( false ) {}
00149
00151 inline virtual void setValue( typename BaseField::value_type v,
00152 int id = 0 ) {
00153 if( HapticThread::inHapticThread() ) {
00154 rt_value.reset( v );
00155 rt_value_changed = true;
00156 } else {
00157 assert( ThreadBase::inMainThread() );
00158 PeriodicUpdate< BaseField >::setValue( v, id );
00159 void * param[] = { v, &rt_value };
00160 HapticThread::synchronousHapticCB( transferValue, param );
00161 }
00162 }
00163
00165 virtual typename BaseField::typed_value_type getValue( int id = 0 ) {
00166 if( HapticThread::inHapticThread() ) {
00167 return static_cast< typename BaseField::typed_value_type >( rt_value.get() );
00168 } else {
00169 assert( ThreadBase::inMainThread() );
00170 return PeriodicUpdate< BaseField >::getValue( id );
00171 }
00172 }
00173
00176 virtual void upToDate() {
00177 assert( ThreadBase::inMainThread() );
00178
00179 if( rt_value_changed ) {
00180 void * param[] = { rt_value.get(), &this->value };
00181 HapticThread::synchronousHapticCB( transferValue, param );
00182 this->startEvent();
00183 } else {
00184 PeriodicUpdate< BaseField >::upToDate();
00185 }
00186 }
00187
00188 protected:
00189 static PeriodicThread::CallbackCode transferValue( void * _data ) {
00190 void * * data = static_cast< void * * >( _data );
00191 typename BaseField::value_type new_value =
00192 static_cast< typename BaseField::value_type >( data[0] );
00193 AutoRef< typename BaseField::class_type > *rt_value =
00194 static_cast< AutoRef< typename BaseField::class_type> * >( data[1] );
00195 rt_value->reset( new_value );
00196 return PeriodicThread::CALLBACK_DONE;
00197 }
00198
00200 virtual void onAdd( typename BaseField::value_type i ) {
00201 assert( ThreadBase::inMainThread() );
00202 PeriodicUpdate< BaseField >::onAdd( i );
00203 void * param[] = { i, &rt_value };
00204 HapticThread::synchronousHapticCB( transferValue, param );
00205 }
00206
00208 AutoRef< typename BaseField::class_type > rt_value;
00209
00212 bool rt_value_changed;
00213 };
00214
00230 template< class BaseField >
00231 class ThreadSafeMField: public PeriodicUpdate< BaseField > {
00232 public:
00234 ThreadSafeMField(): rt_value_changed( false ) {}
00235
00238 inline virtual void setValue(
00239 const vector< typename BaseField::value_type > &v,
00240 int id = 0 ) {
00241 if( HapticThread::inHapticThread() ) {
00242 rt_value = v;
00243 rt_value_changed = true;
00244 } else {
00245 assert( ThreadBase::inMainThread() );
00246 PeriodicUpdate< BaseField >::setValue( v, id );
00247 void * param[] = { &this->value, &rt_value };
00248 HapticThread::synchronousHapticCB( transferValue, param );
00249 }
00250 }
00251
00255 inline virtual void setValue( typename BaseField::size_type i,
00256 const typename BaseField::value_type &t,
00257 int id = 0 ) {
00258 if( HapticThread::inHapticThread() ) {
00259 rt_value[i] = t;
00260 rt_value_changed = true;
00261 } else {
00262
00263 assert( ThreadBase::inMainThread() );
00264 PeriodicUpdate< BaseField >::setValue( i, t, id );
00265 void * param[] = { &this->value, &rt_value };
00266 HapticThread::synchronousHapticCB( transferValue, param );
00267 }
00268 }
00269
00271 inline virtual void swap( typename BaseField::vector_type &x, int id = 0 ) {
00272 if( HapticThread::inHapticThread() ) {
00273 rt_value.swap( x );
00274 rt_value_changed = true;
00275 } else {
00276 assert( ThreadBase::inMainThread() );
00277 PeriodicUpdate< BaseField >::swap( x, id );
00278 void * param[] = { &this->value, &rt_value };
00279 HapticThread::synchronousHapticCB( transferValue, param );
00280 }
00281 }
00282
00284 inline virtual void push_back( const typename BaseField::value_type &x,
00285 int id = 0 ) {
00286 if( HapticThread::inHapticThread() ) {
00287 rt_value.push_back( x );
00288 rt_value_changed = true;
00289 } else {
00290
00291 assert( ThreadBase::inMainThread() );
00292 PeriodicUpdate< BaseField >::push_back( x, id );
00293 void * param[] = { &this->value, &rt_value };
00294 HapticThread::synchronousHapticCB( transferValue, param );
00295 }
00296 }
00297
00299 void pop_back( int id = 0 ) {
00300 if( HapticThread::inHapticThread() ) {
00301 rt_value.pop_back();
00302 rt_value_changed = true;
00303 } else {
00304
00305 assert( ThreadBase::inMainThread() );
00306 PeriodicUpdate< BaseField >::pop_back( id );
00307 void * param[] = { &this->value, &rt_value };
00308 HapticThread::synchronousHapticCB( transferValue, param );
00309 }
00310 }
00311
00313 inline virtual void clear( int id = 0 ) {
00314 if( HapticThread::inHapticThread() ) {
00315 rt_value.clear();
00316 rt_value_changed = true;
00317 } else {
00318 assert( ThreadBase::inMainThread() );
00319 PeriodicUpdate< BaseField >::clear( id );
00320 void * param[] = { &this->value, &rt_value };
00321 HapticThread::synchronousHapticCB( transferValue, param );
00322 }
00323 }
00324
00326 inline virtual typename BaseField::const_iterator begin( int id = 0 ) {
00327 if( HapticThread::inHapticThread() ) {
00328 return rt_value.begin();
00329 } else {
00330 assert( ThreadBase::inMainThread() );
00331 return PeriodicUpdate< BaseField >::begin( id );
00332 }
00333 }
00334
00336 inline virtual typename BaseField::const_iterator end( int id = 0 ) {
00337 if( HapticThread::inHapticThread() ) {
00338 return rt_value.end();
00339 } else {
00340 assert( ThreadBase::inMainThread() );
00341 return PeriodicUpdate< BaseField >::end( id );
00342 }
00343 }
00344
00347 inline virtual typename BaseField::const_reverse_iterator rbegin( int id = 0 ) {
00348 if( HapticThread::inHapticThread() ) {
00349 return rt_value.rbegin();
00350 } else {
00351 assert( ThreadBase::inMainThread() );
00352 return PeriodicUpdate< BaseField >::rbegin( id );
00353 }
00354 }
00357 inline virtual typename BaseField::const_reverse_iterator rend( int id = 0 ) {
00358 if( HapticThread::inHapticThread() ) {
00359 return rt_value.rend();
00360 } else {
00361 assert( ThreadBase::inMainThread() );
00362 return PeriodicUpdate< BaseField >::rend( id );
00363 }
00364 }
00365
00367 inline virtual typename BaseField::size_type size() {
00368 if( HapticThread::inHapticThread() ) {
00369 return rt_value.size();
00370 } else {
00371 assert( ThreadBase::inMainThread() );
00372 return PeriodicUpdate< BaseField >::size();
00373 }
00374 }
00375
00377 inline virtual typename BaseField::size_type max_size() {
00378 if( HapticThread::inHapticThread() ) {
00379 return rt_value.max_size();
00380 } else {
00381 assert( ThreadBase::inMainThread() );
00382 return PeriodicUpdate< BaseField >::max_size();
00383 }
00384 }
00385
00388 inline virtual typename BaseField::size_type capacity() {
00389 if( HapticThread::inHapticThread() ) {
00390 return rt_value.capacity();
00391 } else {
00392 assert( ThreadBase::inMainThread() );
00393 return PeriodicUpdate< BaseField >::capacity();
00394 }
00395 }
00396
00398 inline virtual bool empty() {
00399 if( HapticThread::inHapticThread() ) {
00400 return rt_value.empty();
00401 } else {
00402 assert( ThreadBase::inMainThread() );
00403 return PeriodicUpdate< BaseField >::empty();
00404 }
00405 }
00407 inline virtual typename BaseField::const_reference operator[]( typename BaseField::size_type n ) {
00408 if( HapticThread::inHapticThread() ) {
00409 return rt_value[n];
00410 } else {
00411 assert( ThreadBase::inMainThread() );
00412 return PeriodicUpdate< BaseField >::operator[]( n );
00413 }
00414 }
00415
00417 inline virtual typename BaseField::const_reference front( int id = 0 ) {
00418 if( HapticThread::inHapticThread() ) {
00419 return rt_value.front();
00420 } else {
00421 assert( ThreadBase::inMainThread() );
00422 return PeriodicUpdate< BaseField >::front( id );
00423 }
00424 }
00425
00427 inline virtual typename BaseField::const_reference back( int id = 0 ) {
00428 if( HapticThread::inHapticThread() ) {
00429 return rt_value.back();
00430 } else {
00431 assert( ThreadBase::inMainThread() );
00432 return PeriodicUpdate< BaseField >::back( id );
00433 }
00434 }
00435
00437 inline virtual const typename BaseField::vector_type &getValue( int id = 0 ) {
00438 if( HapticThread::inHapticThread() ) {
00439 return rt_value;
00440 } else {
00441 assert( ThreadBase::inMainThread() );
00442 return PeriodicUpdate< BaseField >::getValue( id );
00443 }
00444 }
00445
00448 virtual void upToDate() {
00449 assert( ThreadBase::inMainThread() );
00450
00451 if( rt_value_changed ) {
00452 void * param[] = { &rt_value, &this->value };
00453 HapticThread::synchronousHapticCB( transferValue, param );
00454 this->startEvent();
00455 } else {
00456 PeriodicUpdate< BaseField >::upToDate();
00457 }
00458 }
00459
00460 protected:
00463 static PeriodicThread::CallbackCode transferValue( void * _data ) {
00464 void * * data = static_cast< void * * >( _data );
00465 typename BaseField::vector_type *new_value =
00466 static_cast< typename BaseField::vector_type * >( data[0] );
00467 typename BaseField::vector_type *rt_value =
00468 static_cast< typename BaseField::vector_type * >( data[1] );
00469 *rt_value = *new_value;
00470 return PeriodicThread::CALLBACK_DONE;
00471 }
00472
00476 inline virtual void update() {
00477 assert( ThreadBase::inMainThread() );
00478 PeriodicUpdate< BaseField >::update();;
00479 void * param[] = { &this->value, &rt_value };
00480 HapticThread::synchronousHapticCB( transferValue, param );
00481 }
00482
00484 typename BaseField::vector_type rt_value;
00485
00488 bool rt_value_changed;
00489 };
00490
00491 }
00492
00493 #endif
00494
00495
00496
00497
00498
00499
00500