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

SourceForge.net Logo
Project
Download
Mailing lists

 

         

consumerImpl.h

00001 /*
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)


Generated for Orca Robotics by  doxygen 1.4.5