TerraLib 4.1
E:/Projetos_Primeiro_Semestre_2012/TerraView/terralib/src/terralib/kernel/TeCommunicator.h
Go to the documentation of this file.
00001 /************************************************************************************
00002 TerraLib - a library for developing GIS applications.
00003 Copyright © 2001-2007 INPE and Tecgraf/PUC-Rio.
00004 
00005 This code is part of the TerraLib library.
00006 This library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Lesser General Public
00008 License as published by the Free Software Foundation; either
00009 version 2.1 of the License, or (at your option) any later version.
00010 
00011 You should have received a copy of the GNU Lesser General Public
00012 License along with this library.
00013 
00014 The authors reassure the license terms regarding the warranties.
00015 They specifically disclaim any warranties, including, but not limited to,
00016 the implied warranties of merchantability and fitness for a particular purpose.
00017 The library provided hereunder is on an "as is" basis, and the authors have no
00018 obligation to provide maintenance, support, updates, enhancements, or modifications.
00019 In no event shall INPE and Tecgraf / PUC-Rio be held liable to any party for direct,
00020 indirect, special, incidental, or consequential damages arising out of the use
00021 of this library and its documentation.
00022 *************************************************************************************/
00028 #ifndef TECOMMUNICATOR_H
00029   #define TECOMMUNICATOR_H
00030   
00031   #include "TeMutex.h"
00032   #include "TeAgnostic.h"
00033 
00034   #include <list>
00035   #include <algorithm>
00036   
00046   #define TECOMMWRAPPER( function_name, param_type, class_name ) \
00047     protected : void function_name( const param_type& x ); \
00048     public : static void function_name( const param_type& x, void* objptr ) \
00049     { \
00050       class_name * casted_ptr = ( class_name * ) objptr; \
00051       casted_ptr->function_name( x ); \
00052     };
00053     
00062   template< typename DataType >
00063   class TeCommunicator 
00064   {
00065     public :
00066     
00073       typedef void (*WrapperFuncPtrT)( const DataType&, void* );
00074             
00083       TeCommunicator( void* host_obj_ptr = 0,
00084         WrapperFuncPtrT wrapper_func_ptr = 0,
00085         bool enabled_flag = true );
00086 
00090       ~TeCommunicator();
00091       
00099       void setHostObj( void* host_obj_ptr = 0, 
00100         WrapperFuncPtrT wrapper_func_ptr = 0 );
00101       
00108       bool connect( TeCommunicator< DataType>& external );
00109       
00113       void disconnect();
00114       
00120       void disconnect( TeCommunicator< DataType>& external );
00121       
00127       void send( const DataType& data ) const;
00128       
00134       void toggle( bool enabled_flag );      
00135       
00140       bool isEnabled();          
00141       
00142     protected :
00143       
00147       typedef TeCommunicator< DataType >* ComPtrT;
00148       
00152       typedef std::list< ComPtrT > ContainerT;
00153       
00157       typedef typename ContainerT::iterator ContItT;      
00158       
00165       void ConnectMe( ComPtrT my_pointer );
00166       
00173       void DisconnectMe( ComPtrT my_pointer );
00174       
00180       inline void Receive( const DataType& data ) const; 
00181       
00182     private :
00183     
00187       bool emission_reception_enabled_;
00188     
00192       WrapperFuncPtrT wrapper_func_ptr_;
00193       
00197       void* host_obj_ptr_;
00198       
00202       mutable ContainerT connections_;
00203       
00205       mutable TeMutex lock_instance_;      
00206       
00210       TeCommunicator( const TeCommunicator< DataType >& ) {};
00211       
00215       const TeCommunicator< DataType >& operator=( 
00216         const TeCommunicator< DataType >& ) {};
00217       
00218   };
00219   
00220 
00221   template< typename DataType >  
00222   TeCommunicator< DataType >::TeCommunicator( void* host_obj_ptr,
00223     WrapperFuncPtrT wrapper_func_ptr, bool enabled_flag )
00224   {
00225     wrapper_func_ptr_ = 0;
00226     host_obj_ptr_ = 0;
00227     emission_reception_enabled_ = enabled_flag;
00228     
00229     setHostObj( host_obj_ptr, wrapper_func_ptr );
00230   }
00231   
00232   
00233   template< typename DataType >  
00234   TeCommunicator< DataType >::~TeCommunicator()
00235   {
00236     disconnect();
00237   }
00238   
00239   
00240   template< typename DataType >  
00241   void TeCommunicator< DataType >::setHostObj( void* host_obj_ptr,
00242     WrapperFuncPtrT wrapper_func_ptr )
00243   {
00244     lock_instance_.lock();
00245     
00246 //   TEAGN_TRUE_OR_THROW( (wrapper_func_ptr != 0), 
00247 //      ( ( wrapper_func_ptr == 0 ) && ( host_obj_ptr == 0 ) ) || 
00248 //      ( ( wrapper_func_ptr != 0 ) && ( host_obj_ptr != 0 ) ) ), 
00249 //      "Invalid receiver_func_ptr/host_obj_ptr parameters" );
00250       
00251     wrapper_func_ptr_ = wrapper_func_ptr;
00252     host_obj_ptr_ = host_obj_ptr;
00253     
00254     lock_instance_.unLock();
00255   }
00256   
00257   
00258   template< typename DataType >
00259   bool TeCommunicator< DataType >::connect( 
00260     TeCommunicator< DataType>& external )
00261   {
00262     lock_instance_.lock();
00263     
00264 //    if( ( wrapper_func_ptr_ == 0 ) || ( host_obj_ptr_ == 0 ) ) {
00265              if( wrapper_func_ptr_ == 0 ) {
00266       lock_instance_.unLock();
00267       
00268       TEAGN_LOGERR( "Connecting a inactive communicator instance" );
00269       
00270       return false;
00271     }
00272     
00273     ContItT it = find( connections_.begin(), connections_.end(),
00274       &external );
00275 
00276     if( it == connections_.end() ) {
00277       connections_.push_back( &external );
00278       external.ConnectMe( this );
00279     }
00280     
00281     lock_instance_.unLock();
00282     
00283     return true;
00284   }
00285   
00286 
00287   template< typename DataType >
00288   void TeCommunicator< DataType >::disconnect()
00289   {
00290     lock_instance_.lock();
00291     
00292     ContItT it = connections_.begin();
00293     ContItT it_end = connections_.end();
00294 
00295     while( it != it_end ) {
00296       (*it)->DisconnectMe( this );
00297       
00298       ++it;
00299     }
00300     
00301     connections_.clear();
00302     
00303     lock_instance_.unLock();
00304   }
00305   
00306   
00307   template< typename DataType >
00308   void TeCommunicator< DataType >::disconnect( 
00309     TeCommunicator< DataType>& external )
00310   {
00311     lock_instance_.lock();
00312     
00313     ContItT it = find( connections_.begin(), connections_.end(),
00314       &external );
00315       
00316     if( it != connections_.end() ) {
00317       (*it)->DisconnectMe( this );
00318       connections_.erase( it );
00319     }
00320     
00321     lock_instance_.unLock();
00322   }
00323 
00324   
00325   template< typename DataType >
00326   void TeCommunicator< DataType >::ConnectMe( 
00327     ComPtrT my_pointer )
00328   {
00329     lock_instance_.lock();
00330     
00331     ContItT it = find( connections_.begin(), connections_.end(),
00332       my_pointer );
00333       
00334     if( it == connections_.end() ) {
00335       connections_.push_back( my_pointer );
00336     }
00337     
00338     lock_instance_.unLock();
00339   }
00340 
00341   
00342   template< typename DataType >
00343   void TeCommunicator< DataType >::DisconnectMe( 
00344     ComPtrT my_pointer )
00345   {
00346     lock_instance_.lock();
00347     
00348     ContItT it = find( connections_.begin(), connections_.end(),
00349       my_pointer );
00350       
00351     if( it != connections_.end() ) {
00352       connections_.erase( it );
00353     }
00354     
00355     lock_instance_.unLock();
00356   }
00357   
00358   
00359   template< typename DataType >
00360   void  TeCommunicator< DataType >::send( const DataType& data ) const
00361   {
00362     if( emission_reception_enabled_ )
00363     {
00364       lock_instance_.lock();
00365       
00366       ContItT it = connections_.begin();
00367       ContItT it_end = connections_.end();
00368       
00369       while( it != it_end ) {
00370         (*it)->Receive( data );
00371         
00372         ++it;  
00373       }
00374       
00375       lock_instance_.unLock();
00376     }
00377   }
00378   
00379   
00380   template< typename DataType >
00381   void  TeCommunicator< DataType >::toggle( bool enabled_flag )
00382   {
00383     emission_reception_enabled_ = enabled_flag;
00384   }
00385   
00386   
00387   template< typename DataType >
00388   bool TeCommunicator< DataType >::isEnabled()
00389   {
00390     return emission_reception_enabled_;
00391   }  
00392 
00393   
00394   template< typename DataType >
00395   inline void  TeCommunicator< DataType >::Receive( 
00396     const DataType& data ) const
00397   {
00398     if( emission_reception_enabled_ && ( wrapper_func_ptr_ != 0 ) ) 
00399     {
00400       lock_instance_.lock();
00401       
00402       wrapper_func_ptr_( data, host_obj_ptr_ );
00403       
00404       lock_instance_.unLock();
00405     }
00406   }
00407     
00408 #endif
00409 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines