orca-robotics INTRODUCTION Overview Download and Install Quick Start Documentation Publications REPOSITORY Interfaces Components Libraries Utilities Software Map DEVELOPER Tutorials Examples Dev Guide Dashboard Wiki login/pass: orca/orca PEOPLE Contributors Users Project Download Mailing lists
|
consumerImpl.h00001 /* 00002 * Orca-Robotics Project: Components for robotics 00003 * http://orca-robotics.sf.net/ 00004 * Copyright (c) 2004-2008 Alex Brooks, Alexei Makarenko, Tobias Kaupp 00005 * 00006 * This copy of Orca is licensed to you under the terms described in 00007 * the LICENSE file included in this distribution. 00008 * 00009 */ 00010 00011 #ifndef ORCAIFACEIMPL_CONSUMER_IMPL_H 00012 #define ORCAIFACEIMPL_CONSUMER_IMPL_H 00013 00014 #include <orcaice/context.h> 00015 #include <orcaice/multiconnectutils.h> 00016 #include <gbxsickacfr/gbxiceutilacfr/safethread.h> 00017 00018 namespace orcaifaceimpl 00019 { 00020 00021 // detail class. 00022 // Functionality which ConsumerI needs to know about when talking to ConsumerImpl class. 00023 template<class ObjectType> 00024 class ConsumerDataHandler 00025 { 00026 public: 00027 virtual ~ConsumerDataHandler() {}; 00028 virtual void internalSetData( const ObjectType &data )=0; 00029 }; 00030 00031 // generic consumerI. 00032 // implements any consumer interface whose set method is called "setData". 00033 // this is a "detail" class, not used directly by the end user. 00034 template<class ConsumerType, class ObjectType> 00035 class ConsumerI : public ConsumerType 00036 { 00037 public: 00038 ConsumerI( ConsumerDataHandler<ObjectType> &handler ) 00039 : handler_(handler) {} 00040 00041 virtual ~ConsumerI() {}; 00042 00043 // implementation of remote call defined in all *Consumer interfaces 00044 // this implementation redirects to the implementation class 00045 virtual void setData( const ObjectType& data, const Ice::Current& ) 00046 { 00047 handler_.internalSetData( data ); 00048 } 00049 00050 private: 00051 ConsumerDataHandler<ObjectType> &handler_; 00052 }; 00053 00057 class ConsumerSubscriber 00058 { 00059 public: 00060 virtual ~ConsumerSubscriber() {}; 00061 00065 virtual void subscribeWithString( const std::string& proxyString )=0; 00066 00070 virtual void unsubscribeWithString( const std::string& proxyString )=0; 00071 00073 virtual void subscribeWithTag( const std::string& interfaceTag )=0; 00074 00076 virtual void unsubscribeWithTag( const std::string& interfaceTag )=0; 00077 00083 virtual void subscribeWithString( const std::string& proxyString, 00084 gbxsickacfr::gbxiceutilacfr::Thread* thread, const std::string& subsysName="", 00085 int retryInterval=2, int retryNumber=-1 )=0; 00086 00089 virtual void subscribeWithTag( const std::string& interfaceTag, 00090 gbxsickacfr::gbxiceutilacfr::Thread* thread, const std::string& subsysName="", 00091 int retryInterval=2, int retryNumber=-1 )=0; 00092 }; 00093 00099 // Note: inheriting from IceUtil::Shared allows us to use Ice smart 00100 // pointers with these things. 00101 template<class ProviderPrxType, class ConsumerType, class ConsumerPrxType, class ObjectType> 00102 class ConsumerImpl : public ConsumerDataHandler<ObjectType>, 00103 public ConsumerSubscriber, 00104 public IceUtil::Shared 00105 { 00106 friend class ConsumerI<ConsumerType,ObjectType>; 00107 00108 public: 00110 ConsumerImpl( const orcaice::Context &context ) 00111 : context_(context), 00112 ptr_(new ConsumerI<ConsumerType,ObjectType>(*this)), 00113 // this function does not throw 00114 prx_(orcaice::createConsumerInterface<ConsumerPrxType>(context,ptr_)) 00115 {} 00116 // no doxytags, these functions are already documented above. 00117 virtual ~ConsumerImpl() 00118 { 00119 try { 00120 context_.adapter()->remove( prx_->ice_getIdentity() ); 00121 } 00122 // This can fail if the adapter is shutting down. We don't care. 00123 catch ( ... ) {} 00124 } 00125 00126 virtual void subscribeWithString( const std::string& proxyString ) 00127 { 00128 ProviderPrxType providerPrx; 00129 orcaice::connectToInterfaceWithString<ProviderPrxType>( context_, providerPrx, proxyString ); 00130 00131 providerPrx->subscribe( prx_ ); 00132 std::stringstream ss; 00133 ss << "Subscribed to " << proxyString; 00134 context_.tracer().debug( ss.str() ); 00135 } 00136 00137 virtual void subscribeWithTag( const std::string& interfaceTag ) 00138 { 00139 // this may throw ConfigFileException, we don't catch it, let the user catch it at the component level 00140 std::string proxyString = orcaice::getRequiredInterfaceAsString( context_, interfaceTag ); 00141 00142 // now that we have the stingified proxy, use the function above. 00143 subscribeWithString( proxyString ); 00144 } 00145 00146 virtual void unsubscribeWithString( const std::string& proxyString ) 00147 { 00148 ProviderPrxType providerPrx; 00149 orcaice::connectToInterfaceWithString<ProviderPrxType>( context_, providerPrx, proxyString ); 00150 00151 providerPrx->unsubscribe( prx_ ); 00152 std::stringstream ss; 00153 ss << "unsubscribed to " << proxyString; 00154 context_.tracer().debug( ss.str() ); 00155 } 00156 00157 virtual void unsubscribeWithTag( const std::string& interfaceTag ) 00158 { 00159 // this may throw ConfigFileException, we don't catch it, let the user catch it at the component level 00160 std::string proxyString = orcaice::getRequiredInterfaceAsString( context_, interfaceTag ); 00161 00162 // now that we have the stingified proxy, use the function above. 00163 unsubscribeWithString( proxyString ); 00164 } 00165 00166 virtual void subscribeWithString( const std::string& proxyString, 00167 gbxsickacfr::gbxiceutilacfr::Thread* thread, const std::string& subsysName="", 00168 int retryInterval=2, int retryNumber=-1 ) 00169 { 00170 ProviderPrxType providerPrx; 00171 // multi-try 00172 orcaice::connectToInterfaceWithString<ProviderPrxType>( 00173 context_, providerPrx, proxyString, thread, subsysName, retryInterval, retryNumber ); 00174 00175 int count = 0; 00176 while ( !thread->isStopping() && ( retryNumber<0 || count<retryNumber) ) 00177 { 00178 try { 00179 providerPrx->subscribe( prx_ ); 00180 std::stringstream ss; 00181 ss << "Subscribed to " << proxyString; 00182 context_.tracer().debug( ss.str() ); 00183 break; 00184 } 00185 catch ( const Ice::Exception &e ) 00186 { 00187 std::stringstream ss; 00188 ss << "Failed to subscribe: " << e << std::endl 00189 <<"Will retry in "<<retryInterval<<"s."; 00190 context_.tracer().warning( ss.str() ); 00191 } 00192 catch ( const std::exception &e ) 00193 { 00194 std::stringstream ss; 00195 ss << "Failed to subscribe: " << e.what() << std::endl 00196 <<"Will retry in "<<retryInterval<<"s."; 00197 context_.tracer().warning( ss.str() ); 00198 } 00199 catch ( ... ) 00200 { 00201 std::stringstream ss; 00202 ss << "Failed to subscribe for unknown reason. " 00203 <<"Will retry in "<<retryInterval<<"s."; 00204 context_.tracer().warning( ss.str() ); 00205 } 00206 ++count; 00207 IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(retryInterval)); 00208 } 00209 00210 } 00211 00212 virtual void subscribeWithTag( const std::string& interfaceTag, 00213 gbxsickacfr::gbxiceutilacfr::Thread* thread, const std::string& subsysName="", 00214 int retryInterval=2, int retryNumber=-1 ) 00215 { 00216 // this may throw ConfigFileException, we don't catch it, let the user catch it at the component level 00217 std::string proxyString = orcaice::getRequiredInterfaceAsString( context_, interfaceTag ); 00218 00219 // now that we have the stingified proxy, use the function above. 00220 subscribeWithString( proxyString, thread, subsysName, retryInterval, retryNumber ); 00221 } 00222 00224 ConsumerPrxType consumerPrx() const { return prx_; } 00225 00226 protected: 00228 virtual void handleData( const ObjectType &data )=0; 00229 00231 orcaice::Context context_; 00232 00233 private: 00234 // from ConsumerDataHandler 00235 virtual void internalSetData( const ObjectType &data ) 00236 { 00237 // callback implemented in derived classes. 00238 handleData( data ); 00239 } 00240 00241 // Hang onto this so we can remove from the adapter and control when things get deleted 00242 Ice::ObjectPtr ptr_; 00243 // proxy to the internal consumer interface implementation 00244 ConsumerPrxType prx_; 00245 }; 00246 00247 } // namespace 00248 00249 #endif |
Webmaster: Tobias Kaupp (tobasco at users.sourceforge.net)