INTRODUCTION
Overview
Download and Install
Quick Start
Documentation
Publications

NONFRAMEWORK CODE
Driver Interfaces
Drivers
Libraries
Utilities

FRAMEWORK CODE
Interfaces
Components
Libraries
Utilities

Full Software Listings

DEVELOPER
Tutorials
Examples
Dev Guide
Dashboard

PEOPLE
Contributors
Users

SourceForge.net Logo
Project
Download
Mailing lists

 

         

providerImpl.h

00001 /*
00002  * Orca-Robotics Project: Components for robotics 
00003  *               http://orca-robotics.sf.net/
00004  * Copyright (c) 2004-2009 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 ORCA_PROVIDER_IMPL_H
00012 #define ORCA_PROVIDER_IMPL_H
00013 
00014 #include <memory>
00015 #include <orcaice/context.h>
00016 #include <orcaice/topichandler.h>
00017 #include <orcaice/configutils.h>
00018 #include <orcaice/convertutils.h>
00019 #include <orcaice/iceutils.h>
00020 #include <orcaice/multiiceutils.h>
00021 #include <IceUtil/Mutex.h>
00022 
00023 namespace gbxutilacfr { class Stoppable; }
00024 
00025 namespace orcaifaceimpl {
00026 
00037 // template<class ProviderType, class ProviderPrxType, class ConsumerType, class ConsumerPrxType, class DataType>
00038 template<class ProviderType, class ConsumerType, class DataType>
00039 class ProviderImpl : public IceUtil::Shared
00040 {
00041 typedef typename ProviderType::ProxyType ProviderPrxType;
00042 typedef typename ConsumerType::ProxyType ConsumerPrxType;
00043 
00044 friend class ProviderTypeI;
00045 
00046 public:
00048     ProviderImpl( const std::string& interfaceTag, const orcaice::Context& context ) :
00049         isDataSet_(false),
00050         interfaceName_(orcaice::getProvidedInterface(context,interfaceTag).iface),
00051         context_(context)
00052     {
00053         init();
00054     }
00055 
00057     ProviderImpl( const orcaice::Context& context, const std::string& interfaceName ) :
00058         isDataSet_(false),
00059         interfaceName_(interfaceName),
00060         context_(context)
00061     {
00062         init();
00063     }           
00064 
00065     ~ProviderImpl()
00066     {
00067         orcaice::tryRemoveInterface( context_, interfaceName_ );
00068     }
00069 
00070     // local interface:
00073     void initInterface()
00074     {
00075         topicHandler_->connectToTopic();
00076         orcaice::createInterfaceWithString( context_, ptr_, interfaceName_ );    
00077     }
00079     void initInterface( const DataType& data )
00080     {
00081         // by setting the data first we avoid the possibility of initializing the interface
00082         // but not having the data in it.
00083         localSet( data );
00084 
00085         topicHandler_->connectToTopic();
00086         topicHandler_->publish( data );
00087         orcaice::createInterfaceWithString( context_, ptr_, interfaceName_ );    
00088     }
00089 
00092     void initInterface( gbxutilacfr::Stoppable* activity, const std::string& subsysName="", int retryInterval=2 )
00093     {
00094         topicHandler_->connectToTopic( activity, subsysName, retryInterval );
00095         orcaice::createInterfaceWithString( context_, ptr_, interfaceName_, activity, subsysName, retryInterval );
00096     }
00098     void initInterface( const DataType& data, 
00099                         gbxutilacfr::Stoppable* activity, const std::string& subsysName="", int retryInterval=2 )
00100     {
00101         // by setting the data first we avoid the possibility of initializing the interface
00102         // but not having the data in it.
00103         localSet( data );
00104 
00105         topicHandler_->connectToTopic( activity, subsysName, retryInterval );
00106         topicHandler_->publish( data );
00107         orcaice::createInterfaceWithString( context_, ptr_, interfaceName_, activity, subsysName, retryInterval );
00108     }
00109 
00111     void localSend( const DataType& data )
00112     {
00113         topicHandler_->publish(data);
00114     }
00115 
00117     void localSet( const DataType& data )
00118     {
00119         IceUtil::Mutex::Lock lock(mutex_);
00120         data_ = data;
00121         isDataSet_ = true;
00122     }
00123 
00126     void localSetAndSend( const DataType& data )
00127     {
00128         {
00129             IceUtil::Mutex::Lock lock(mutex_);
00130             data_ = data;
00131             isDataSet_ = true;
00132         }
00133         topicHandler_->publish( data );
00134     }
00135 
00140     void localSetAndSend( const DataType& dataToSet, const DataType& dataToSend )
00141     {
00142         // By sending first, we avoid the possibility that a client
00143         // gets our data on subscription then gets pushed the update.
00144         topicHandler_->publish( dataToSend );
00145         {
00146             IceUtil::Mutex::Lock lock(mutex_);
00147             data_ = dataToSet;
00148             isDataSet_ = true;
00149         }
00150     }
00151 
00152 private:    
00153     //
00154     // This is the implementation of the slice-defined interface
00155     //
00156     class ProviderTypeI : public ProviderType
00157     {
00158     public:
00159         ProviderTypeI( ProviderImpl &impl )
00160             : impl_(impl) {}
00161         DataType getData(const Ice::Current&)
00162             { return impl_.internalGetData(); }
00163         virtual IceStorm::TopicPrx subscribe(const ConsumerPrxType& subscriber, const ::Ice::Current& = ::Ice::Current())
00164             { return impl_.internalSubscribe(subscriber); }
00165     private:
00166         ProviderImpl &impl_;
00167     };
00169 
00170     // Holds the current data
00171     DataType data_;
00172     bool isDataSet_;
00173     // Protects the data_
00174     IceUtil::Mutex mutex_;
00175 
00176     typedef orcaice::TopicHandler<ConsumerPrxType,DataType> TopicHandlerType;
00177     std::auto_ptr<TopicHandlerType> topicHandler_;
00178 
00179     Ice::ObjectPtr ptr_;
00180     const std::string interfaceName_;
00181     orcaice::Context context_;
00182 
00183     void init()
00184     {
00185         ptr_ = new ProviderTypeI( *this );
00186 
00187         topicHandler_.reset( new TopicHandlerType( orcaice::toTopicAsString(context_.name(),interfaceName_), context_ ) );    
00188     }
00189 
00190     // remote call implementations, mimic (but do not inherit) the orca interface
00191     DataType internalGetData() const
00192     {
00193         context_.tracer().debug( "ProviderImpl::internalGetData()", 5 );
00194     
00195         IceUtil::Mutex::Lock lock(mutex_);
00196         if ( !isDataSet_ )
00197         {
00198             std::stringstream ss;
00199             ss << "No data available! (interface="<<interfaceName_<<")";
00200             throw orca::DataNotExistException( ss.str() );
00201         }
00202         return data_;
00203     }
00204 
00205     IceStorm::TopicPrx internalSubscribe(const ConsumerPrxType& subscriber)
00206     {
00207         if ( !topicHandler_.get() ) 
00208         {
00209             throw orca::SubscriptionFailedException("topicHandler_ does not exist.");
00210         }
00211 
00212         // Grab the data in a crit section
00213         DataType data;
00214         bool gotData = false;
00215         {        
00216             IceUtil::Mutex::Lock lock(mutex_);
00217             if ( isDataSet_ )
00218             {
00219                 data = data_;
00220                 gotData = true;
00221             }
00222         }
00223 
00224         // EXPERIMENTAL!
00225         IceStorm::QoS qos;
00226         qos["reliability"] = "ordered";
00227 
00228         // if we have data, send all the information we have to the new subscriber (and to no one else)
00229         if ( gotData )
00230         {
00231             return topicHandler_->subscribe( subscriber, data, qos );
00232         }
00233         else
00234         {
00235             return topicHandler_->subscribe( subscriber, qos );
00236         }
00237     }
00238 };
00239 
00240 }
00241 
00242 #endif
 

Webmaster: Tobias Kaupp (tobasco at users.sourceforge.net)


Generated for Orca Robotics by  doxygen 1.4.5