00001
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef PeriodicExecutionContext_h
00027 #define PeriodicExecutionContext_h
00028
00029 #include <rtm/idl/RTCSkel.h>
00030 #include <rtm/StateMachine.h>
00031
00032
00033 #include <ace/Task.h>
00034 #include <vector>
00035
00036 namespace RTC
00037 {
00038
00039 class PeriodicExecutionContext
00040 : public virtual POA_RTC::ExecutionContextService,
00041 public virtual PortableServer::RefCountServantBase,
00042 public ACE_Task<ACE_MT_SYNCH>
00043 {
00044 public:
00045 PeriodicExecutionContext(DataFlowComponent_ptr owner, double rate = 0.0);
00046 virtual ~PeriodicExecutionContext();
00047
00048 ExecutionContextService_ptr getRef() {return m_ref;}
00049
00069 virtual int open(void *args);
00070
00071
00088 virtual int svc(void);
00089
00090
00109 virtual int close(unsigned long flags);
00110
00111
00112
00113
00114
00115
00116 virtual CORBA::Boolean is_running();
00117
00118 virtual ReturnCode_t start();
00119 virtual ReturnCode_t stop();
00120
00121 virtual CORBA::Double get_rate();
00122 virtual ReturnCode_t set_rate(CORBA::Double rate);
00123
00124 virtual ReturnCode_t activate_component(LightweightRTObject_ptr comp);
00125 virtual ReturnCode_t deactivate_component(LightweightRTObject_ptr comp);
00126 virtual ReturnCode_t reset_component(LightweightRTObject_ptr comp);
00127
00128 virtual LifeCycleState get_component_state(LightweightRTObject_ptr comp);
00129 virtual ExecutionKind get_kind();
00130 virtual ReturnCode_t add(LightweightRTObject_ptr comp);
00131 virtual ReturnCode_t remove(LightweightRTObject_ptr comp);
00132
00133 virtual ExecutionContextProfile* get_profile();
00134
00135
00136 protected:
00137
00138
00139
00140 typedef LifeCycleState ExecContextState;
00141
00142
00143
00144
00145
00146
00147
00148
00149 typedef StateHolder<ExecContextState> ECStates;
00150
00151 class DFPBase
00152 {
00153 public:
00154
00155 DFPBase(UniqueId id)
00156 : ec_id(id), m_sm(3)
00157 {
00158 m_sm.setListener(this);
00159 m_sm.setEntryAction (ACTIVE_STATE,
00160 &DFPBase::on_activated);
00161 m_sm.setDoAction (ACTIVE_STATE,
00162 &DFPBase::on_execute);
00163 m_sm.setPostDoAction(ACTIVE_STATE,
00164 &DFPBase::on_state_update);
00165 m_sm.setExitAction (ACTIVE_STATE,
00166 &DFPBase::on_deactivated);
00167 m_sm.setEntryAction (ERROR_STATE,
00168 &DFPBase::on_aborting);
00169 m_sm.setDoAction (ERROR_STATE,
00170 &DFPBase::on_error);
00171 m_sm.setExitAction (ERROR_STATE,
00172 &DFPBase::on_reset);
00173
00174 ECStates st;
00175 st.prev = INACTIVE_STATE;
00176 st.curr = INACTIVE_STATE;
00177 st.next = INACTIVE_STATE;
00178 m_sm.setStartState(st);
00179 m_sm.goTo(INACTIVE_STATE);
00180 }
00181 virtual ~DFPBase(){}
00182 virtual ReturnCode_t on_startup() = 0;
00183 virtual ReturnCode_t on_shutdown() = 0;
00184
00185 virtual ReturnCode_t on_activated(const ECStates& st) = 0;
00186 virtual ReturnCode_t on_deactivated(const ECStates& st) = 0;
00187 virtual ReturnCode_t on_aborting(const ECStates& st) = 0;
00188 virtual ReturnCode_t on_error(const ECStates& st) = 0;
00189 virtual ReturnCode_t on_reset(const ECStates& st) = 0;
00190 virtual ReturnCode_t on_execute(const ECStates& st) = 0;
00191 virtual ReturnCode_t on_state_update(const ECStates& st) = 0;
00192
00193 virtual ReturnCode_t on_rate_changed() = 0;
00194 virtual ReturnCode_t worker() {return m_sm.worker();}
00195 virtual ExecContextState get_state(){ return m_sm.getState();}
00196 UniqueId ec_id;
00197 StateMachine<ExecContextState, ReturnCode_t, DFPBase> m_sm;
00198 };
00199
00200
00201
00202
00203
00204 template <class Object>
00205 class DFP
00206 : public DFPBase
00207 {
00208 public:
00209 DFP(Object obj, UniqueId id)
00210 : DFPBase(id), m_obj(obj), m_active(true)
00211 {
00212
00213 }
00214 ReturnCode_t on_startup()
00215 {
00216 return m_obj->on_startup(ec_id);
00217 }
00218 ReturnCode_t on_shutdown()
00219 {
00220 return m_obj->on_shutdown(ec_id);
00221 }
00222
00223 ReturnCode_t on_activated(const ECStates& st)
00224 {
00225 if (m_obj->on_activated(ec_id) != RTC::OK)
00226 {
00227 m_sm.goTo(ERROR_STATE);
00228 return RTC::ERROR;
00229 }
00230 return RTC::OK;
00231 }
00232 ReturnCode_t on_deactivated(const ECStates& st)
00233 {
00234 if (m_obj->on_deactivated(ec_id) != RTC::OK)
00235 {
00236 m_sm.goTo(ERROR_STATE);
00237 return RTC::ERROR;
00238 }
00239 return RTC::OK;
00240 }
00241
00242 ReturnCode_t on_aborting(const ECStates& st)
00243 {
00244 return m_obj->on_aborting(ec_id);
00245 }
00246
00247 ReturnCode_t on_error(const ECStates& st)
00248 {
00249 return m_obj->on_error(ec_id);
00250 }
00251
00252 ReturnCode_t on_reset(const ECStates& st)
00253 {
00254 if (m_obj->on_reset(ec_id) != RTC::OK)
00255 {
00256 m_sm.goTo(ERROR_STATE);
00257 return RTC::ERROR;
00258 }
00259 return RTC::OK;
00260 }
00261
00262 ReturnCode_t on_execute(const ECStates& st)
00263 {
00264 if (m_obj->on_execute(ec_id) != RTC::OK)
00265 {
00266 m_sm.goTo(ERROR_STATE);
00267 return RTC::ERROR;
00268 }
00269 return RTC::OK;
00270 }
00271
00272 ReturnCode_t on_state_update(const ECStates& st)
00273 {
00274 if (m_obj->on_state_update(ec_id) != RTC::OK)
00275 {
00276 m_sm.goTo(ERROR_STATE);
00277 return RTC::ERROR;
00278 }
00279 return RTC::OK;
00280 }
00281
00282 ReturnCode_t on_rate_changed()
00283 {
00284 return m_obj->on_rate_changed(ec_id);
00285 }
00286
00287 Object m_obj;
00288 bool m_active;
00289 };
00290
00291 struct Comp
00292 {
00293 Comp(LightweightRTObject_ptr ref, DataFlowComponent_ptr dfp,
00294 UniqueId id)
00295 : _ref(ref), _sm(dfp, id)
00296 {
00297 }
00298 Comp(const Comp& comp)
00299 : _ref(comp._ref), _sm(comp._sm.m_obj, comp._sm.ec_id)
00300 {
00301 }
00302 Comp& operator=(const Comp& comp)
00303 {
00304 _ref = comp._ref;
00305 _sm.m_obj = comp._sm.m_obj;
00306 _sm.ec_id = comp._sm.ec_id;
00307 return *this;
00308 }
00309 LightweightRTObject_var _ref;
00310 DFP<DataFlowComponent_ptr> _sm;
00311 };
00312
00313
00314
00315 struct find_comp
00316 {
00317 LightweightRTObject_var m_comp;
00318 find_comp(LightweightRTObject_ptr comp) : m_comp(comp) {}
00319 bool operator()(Comp& comp)
00320 {
00321 return m_comp->_is_equivalent(comp._ref);
00322 }
00323 };
00324
00325
00326 struct invoke_on_startup
00327 {
00328 void operator()(Comp& comp)
00329 {
00330 comp._sm.on_startup();
00331 }
00332 };
00333
00334 struct invoke_on_shutdown
00335 {
00336 void operator()(Comp& comp)
00337 {
00338 comp._sm.on_shutdown();
00339 }
00340 };
00341
00342 struct invoke_on_rate_changed
00343 {
00344 void operator()(Comp& comp)
00345 {
00346 comp._sm.on_rate_changed();
00347 }
00348 };
00349
00350 struct invoke_worker
00351 {
00352 void operator()(Comp& comp)
00353 {
00354 comp._sm.worker();
00355 }
00356 };
00357
00358 std::vector<Comp> m_comps;
00359 typedef std::vector<Comp>::iterator CompItr;
00360 bool m_running;
00361 ExecutionContextProfile m_profile;
00362 long int m_usec;
00363 ExecutionContextService_var m_ref;
00364
00365
00366 };
00367 };
00368
00369 #endif