EventService.hpp

00001 /***************************************************************************
00002   tag: Peter Soetens  Wed Jan 18 14:11:40 CET 2006  EventService.hpp
00003 
00004                         EventService.hpp -  description
00005                            -------------------
00006     begin                : Wed January 18 2006
00007     copyright            : (C) 2006 Peter Soetens
00008     email                : peter.soetens@mech.kuleuven.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
00035  *                                                                         *
00036  ***************************************************************************/
00037 
00038 
00039 #ifndef EVENT_SERVICE_HPP
00040 #define EVENT_SERVICE_HPP
00041 
00042 #include "Logger.hpp"
00043 #include "FunctorFactory.hpp"
00044 #include "OperationFactory.hpp"
00045 #include "EventHook.hpp"
00046 #include "Event.hpp"
00047 #include "CompletionProcessor.hpp"
00048 #include "EventC.hpp"
00049 #include "ConnectionC.hpp"
00050 #include "DataSourceArgsEvent.hpp"
00051 #include <boost/static_assert.hpp>
00052 #include <boost/type_traits/function_traits.hpp>
00053 
00054 namespace RTT
00055 {
00056 
00057     class ExecutionEngine;
00058 
00065     class RTT_API EventService
00066         : public OperationFactory< ActionInterface* >
00067     {
00068         // creates event hooks
00069         typedef std::map<std::string, detail::FunctorFactoryPart<detail::EventHookBase*>* > Hooks;
00070         Hooks mhooks;
00071         // creates emittor objects
00072         typedef std::map<std::string, boost::shared_ptr<ActionInterface> > Events;
00073         Events mevents;
00074 
00075         ExecutionEngine* eeproc;
00076         EventProcessor* eproc;
00077     public:
00078         typedef OperationFactory< ActionInterface* > Factory;
00079 
00085         EventService( ExecutionEngine* ee );
00086 
00093         EventService( EventProcessor* ep = 0 );
00094 
00095         ~EventService();
00096 
00097         EventProcessor* getEventProcessor();
00098 
00099         void setEventProcessor(EventProcessor* ep);
00100 
00104         void clear();
00105 
00110         std::vector<std::string> getEvents() const;
00111 
00122         template< class EventT>
00123         bool addEvent( EventT* e ) {
00124             Logger::In in("EventService");
00125             // All addEvent functions below first call this function.
00126             // Hence all these checks are always performed.
00127             std::string ename = e->getName();
00128             if ( ename.empty() || e->ready() == false ) {
00129                 log(Error) << "Can not use addEvent with uninitialised Event: give your event a name upon construction." << endlog();
00130                 return false;
00131             }
00132 
00133             if ( mevents.count(ename) != 0 ) {
00134                 log(Error) << "Can not add Event '"<<ename<<"': name already used." << endlog();
00135                 return false;
00136             }
00137 
00138             mevents[ename] = e->getImplementation();
00139             return true;
00140         }
00141 
00153         template<class Signature>
00154         boost::shared_ptr<ActionInterface> getEvent(const std::string& ename)
00155         {
00156             if ( mevents.count(ename) )
00157                 return mevents[ename];
00158             return boost::shared_ptr<ActionInterface>();
00159         }
00160 
00170         template< class EventT>
00171         bool addEvent( EventT* e, const char* description )
00172         {
00173             BOOST_STATIC_ASSERT( boost::function_traits<typename EventT::Signature>::arity == 0 );
00174 
00175             if ( this->addEvent( e ) == false)
00176                 return false;
00177 
00178             this->add(e->getName(),
00179                       new detail::OperationFactoryPart0<ActionInterface*,
00180                       detail::DataSourceArgsEvent<typename EventT::Signature> >( boost::bind(&EventT::operator(),e), description) );
00181 
00182             this->mhooks[e->getName()]
00183                 = new detail::FunctorFactoryPart0<detail::EventHookBase*, detail::EventHookGenerator<EventT> >( detail::EventHookGenerator<EventT>(e) );
00184 
00185             return true;
00186         }
00187 
00199         template< class EventT>
00200         bool addEvent( EventT* e, const char* description,
00201                        const char* arg1, const char* arg1_description )
00202         {
00203             BOOST_STATIC_ASSERT( boost::function_traits<typename EventT::Signature>::arity == 1 );
00204 
00205             if ( this->addEvent( e ) == false)
00206                 return false;
00207             this->add(e->getName(),
00208                       new detail::OperationFactoryPart1<ActionInterface*,
00209                       detail::DataSourceArgsEvent<typename EventT::Signature> >( boost::bind(&EventT::operator(),e, _1),
00210                       description,
00211                       arg1, arg1_description) );
00212 
00213             this->mhooks[e->getName()]
00214                 = new detail::FunctorFactoryPart1<detail::EventHookBase*, detail::EventHookGenerator<EventT> >( detail::EventHookGenerator<EventT>(e) );
00215 
00216             return true;
00217         }
00218 
00232         template< class EventT>
00233         bool addEvent( EventT* e, const char* description,
00234                        const char* arg1, const char* arg1_description,
00235                        const char* arg2, const char* arg2_description )
00236         {
00237             BOOST_STATIC_ASSERT( boost::function_traits<typename EventT::Signature>::arity == 2 );
00238 
00239             if ( this->addEvent( e ) == false)
00240                 return false;
00241             this->add(e->getName(),
00242                       new detail::OperationFactoryPart2<ActionInterface*,
00243                       detail::DataSourceArgsEvent<typename EventT::Signature> >( boost::bind(&EventT::operator(),e,_1,_2),
00244                       description,
00245                       arg1, arg1_description,
00246                       arg2, arg2_description) );
00247 
00248             this->mhooks[e->getName()]
00249                 = new detail::FunctorFactoryPart2<detail::EventHookBase*, detail::EventHookGenerator<EventT> >( detail::EventHookGenerator<EventT>(e) );
00250 
00251             return true;
00252         }
00253 
00269         template< class EventT>
00270         bool addEvent( EventT* e, const char* description,
00271                        const char* arg1, const char* arg1_description,
00272                        const char* arg2, const char* arg2_description,
00273                        const char* arg3, const char* arg3_description)
00274         {
00275             BOOST_STATIC_ASSERT( boost::function_traits<typename EventT::Signature>::arity == 3 );
00276 
00277             if ( this->addEvent( e ) == false)
00278                 return false;
00279             this->add(e->getName(),
00280                       new detail::OperationFactoryPart3<ActionInterface*,
00281                       detail::DataSourceArgsEvent<typename EventT::Signature> >( boost::bind(&EventT::operator(),e,_1,_2,_3),
00282                       description,
00283                       arg1, arg1_description,
00284                       arg2, arg2_description,
00285                       arg3, arg3_description));
00286 
00287             this->mhooks[e->getName()]
00288                 = new detail::FunctorFactoryPart3<detail::EventHookBase*, detail::EventHookGenerator<EventT> >( detail::EventHookGenerator<EventT>(e) );
00289             return true;
00290         }
00291 
00309         template< class EventT>
00310         bool addEvent( EventT* e, const char* description,
00311                        const char* arg1, const char* arg1_description,
00312                        const char* arg2, const char* arg2_description,
00313                        const char* arg3, const char* arg3_description,
00314                        const char* arg4, const char* arg4_description )
00315         {
00316             BOOST_STATIC_ASSERT( boost::function_traits<typename EventT::Signature>::arity == 4 );
00317 
00318             if ( this->addEvent( e ) == false)
00319                 return false;
00320             this->add(e->getName(),
00321                       new detail::OperationFactoryPart4<ActionInterface*,
00322                       detail::DataSourceArgsEvent<typename EventT::Signature> >( boost::bind(&EventT::operator(),e,_1,_2,_3,_4),
00323                       description,
00324                       arg1, arg1_description,
00325                       arg2, arg2_description,
00326                       arg3, arg3_description,
00327                       arg4, arg4_description));
00328 
00329             this->mhooks[e->getName()]
00330                 = new detail::FunctorFactoryPart4<detail::EventHookBase*, detail::EventHookGenerator<EventT> >( detail::EventHookGenerator<EventT>(e) );
00331             return true;
00332         }
00333 
00334 
00339         bool hasEvent(const std::string& ename) const;
00340 
00346         int arity(const std::string& name) const;
00347 
00351         bool removeEvent( const std::string& ename );
00352 
00369         EventC setupEmit(const std::string& ename) const;
00370 
00385         ConnectionC setupConnection(const std::string& ename) const;
00386 
00396         Handle setupSyn(const std::string& ename,
00397                         boost::function<void(void)> func,
00398                         std::vector<DataSourceBase::shared_ptr> args ) const;
00399 
00414         Handle setupAsyn(const std::string& ename,
00415                          boost::function<void(void)> afunc,
00416                          const std::vector<DataSourceBase::shared_ptr>& args,
00417                          EventProcessor* ep = CompletionProcessor::Instance(),
00418                          EventProcessor::AsynStorageType s_type = EventProcessor::OnlyFirst) const;
00420 
00429         ActionInterface* getEvent(const std::string& ename,const std::vector<DataSourceBase::shared_ptr>& args) const;
00430 
00431     };
00432 
00433 
00434 }
00435 
00436 #endif
Generated on Thu Dec 23 13:22:37 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3