00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
00069 typedef std::map<std::string, detail::FunctorFactoryPart<detail::EventHookBase*>* > Hooks;
00070 Hooks mhooks;
00071
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
00126
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