ThreadSafeFields.h

Go to the documentation of this file.
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 //
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         // TODO: don't copy the entire rt_value vector, just change the current one.
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         // TODO: don't copy the entire rt_value vector, just change the current one.
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         // TODO: don't copy the entire rt_value vector, just change the current one.
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 

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