![]() |
TerraLib 4.1
|
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