Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

PeriodicExecutionContext.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00019 /*
00020  * $Log: PeriodicExecutionContext.h,v $
00021  * Revision 1.4.2.1  2007/07/20 15:59:18  n-ando
00022  * ACE header include was added.
00023  *
00024  * Revision 1.4  2007/04/26 15:30:46  n-ando
00025  * The header include order was modified to define _REENTRANT before
00026  * including ace/config-lite.h in Linux systems.
00027  * In ace 5.4.7 or later, _REENTRANT flag should be defined explicitly.
00028  *
00029  * Revision 1.3  2007/04/13 15:52:34  n-ando
00030  * RTC::OK was changed to RTC::RTC_OK.
00031  * Initialization function was added to make it an external module.
00032  *
00033  * Revision 1.2  2007/01/21 10:27:00  n-ando
00034  * Object reference count related bugs were fixed.
00035  *
00036  * Revision 1.1  2007/01/09 15:29:35  n-ando
00037  * PeriodicExecutionContext class
00038  *
00039  */
00040 
00041 #ifndef PeriodicExecutionContext_h
00042 #define PeriodicExecutionContext_h
00043 
00044 #include <rtm/RTC.h>
00045 #include <rtm/idl/RTCSkel.h>
00046 #include <rtm/idl/OpenRTMSkel.h>
00047 #include <rtm/Manager.h>
00048 #include <rtm/StateMachine.h>
00049 #include <rtm/ExecutionContextBase.h>
00050 
00051 // ACE
00052 #include <ace/Task.h>
00053 #include <ace/OS_NS_unistd.h>
00054 #include <vector>
00055 #include <iostream>
00056 
00057 namespace RTC
00058 {
00059 
00060   class PeriodicExecutionContext
00061     : public virtual ExecutionContextBase,
00062       public ACE_Task<ACE_MT_SYNCH>
00063   {
00064   public:
00065     PeriodicExecutionContext();
00066     PeriodicExecutionContext(DataFlowComponent_ptr owner,
00067                              double rate = 1000.0);
00068     virtual ~PeriodicExecutionContext();
00069     
00070     ExecutionContextService_ptr getRef() {return m_ref;}
00071 
00091     virtual int open(void *args);
00092 
00093 
00110     virtual int svc(void);
00111 
00112 
00131     virtual int close(unsigned long flags);
00132 
00133 
00134     //============================================================
00135     // ExecutionContext
00136     //============================================================
00137     
00138     virtual CORBA::Boolean is_running();
00139 
00140     virtual ReturnCode_t start();
00141     virtual ReturnCode_t stop();
00142 
00143     virtual CORBA::Double get_rate();
00144     virtual ReturnCode_t  set_rate(CORBA::Double rate);
00145 
00146     virtual ReturnCode_t activate_component(LightweightRTObject_ptr comp);
00147     virtual ReturnCode_t deactivate_component(LightweightRTObject_ptr comp);
00148     virtual ReturnCode_t reset_component(LightweightRTObject_ptr comp);
00149 
00150     virtual LifeCycleState get_component_state(LightweightRTObject_ptr comp);
00151     virtual ExecutionKind get_kind();
00152     virtual ReturnCode_t add(LightweightRTObject_ptr comp);
00153     virtual ReturnCode_t remove(LightweightRTObject_ptr comp);
00154 
00155     virtual ExecutionContextProfile* get_profile();
00156 
00157   
00158   protected:
00159     //============================================================
00160     // DFPBase
00161     //============================================================
00162     typedef LifeCycleState ExecContextState;
00163     /*
00164     enum ExecContextState
00165       {
00166         INACTIVE_STATE,
00167         ACTIVE_STATE,
00168         ERROR_STATE,
00169       };
00170     */
00171     typedef StateHolder<ExecContextState> ECStates;
00172     
00173     class DFPBase
00174     {
00175     public:
00176 
00177       DFPBase(UniqueId id)
00178         : ec_id(id), m_sm(3)
00179       {
00180         m_sm.setListener(this);
00181         m_sm.setEntryAction (ACTIVE_STATE,
00182                              &DFPBase::on_activated);
00183         m_sm.setDoAction    (ACTIVE_STATE,
00184                              &DFPBase::on_execute);
00185         m_sm.setPostDoAction(ACTIVE_STATE,
00186                              &DFPBase::on_state_update);
00187         m_sm.setExitAction  (ACTIVE_STATE,
00188                              &DFPBase::on_deactivated);
00189         m_sm.setEntryAction (ERROR_STATE,
00190                              &DFPBase::on_aborting);
00191         m_sm.setDoAction    (ERROR_STATE,
00192                              &DFPBase::on_error);
00193         m_sm.setExitAction  (ERROR_STATE,
00194                              &DFPBase::on_reset);
00195 
00196         ECStates st;
00197         st.prev = INACTIVE_STATE;
00198         st.curr = INACTIVE_STATE;
00199         st.next = INACTIVE_STATE;
00200         m_sm.setStartState(st);
00201         m_sm.goTo(INACTIVE_STATE);
00202       } 
00203       virtual ~DFPBase(){}
00204       virtual ReturnCode_t on_startup() = 0;
00205       virtual ReturnCode_t on_shutdown() = 0;
00206 
00207       virtual ReturnCode_t on_activated(const ECStates& st) = 0;
00208       virtual ReturnCode_t on_deactivated(const ECStates& st) = 0;
00209       virtual ReturnCode_t on_aborting(const ECStates& st) = 0;
00210       virtual ReturnCode_t on_error(const ECStates& st) = 0;
00211       virtual ReturnCode_t on_reset(const ECStates& st) = 0;
00212       virtual ReturnCode_t on_execute(const ECStates& st) = 0;
00213       virtual ReturnCode_t on_state_update(const ECStates& st) = 0;
00214 
00215       virtual ReturnCode_t on_rate_changed() = 0;
00216       virtual ReturnCode_t worker() {return m_sm.worker();}
00217       virtual ExecContextState get_state(){ return m_sm.getState();}
00218       UniqueId ec_id;
00219       StateMachine<ExecContextState, ReturnCode_t, DFPBase> m_sm;
00220     };
00221 
00222 
00223     //============================================================
00224     // DFP
00225     //============================================================
00226     template <class Object>
00227     class DFP
00228       : public DFPBase
00229     {
00230     public:
00231       DFP(Object obj, UniqueId id)
00232         : DFPBase(id), m_obj(obj), m_active(true)
00233       {
00234         
00235       }
00236       ReturnCode_t on_startup()
00237       {
00238         return m_obj->on_startup(ec_id);
00239       }
00240       ReturnCode_t on_shutdown()
00241       {
00242         return m_obj->on_shutdown(ec_id);
00243       }
00244 
00245       ReturnCode_t on_activated(const ECStates& st)
00246       {
00247         if (m_obj->on_activated(ec_id) != RTC::RTC_OK)
00248           {
00249             m_sm.goTo(ERROR_STATE);
00250             return RTC::RTC_ERROR;
00251           }
00252         return RTC::RTC_OK;
00253       }
00254       ReturnCode_t on_deactivated(const ECStates& st)
00255       {
00256         if (m_obj->on_deactivated(ec_id) != RTC::RTC_OK)
00257           {
00258             m_sm.goTo(ERROR_STATE);
00259             return RTC::RTC_ERROR;
00260           }
00261         return RTC::RTC_OK;
00262       }
00263 
00264       ReturnCode_t on_aborting(const ECStates& st)
00265       {
00266         return m_obj->on_aborting(ec_id);
00267       }
00268 
00269       ReturnCode_t on_error(const ECStates& st)
00270       {
00271         return m_obj->on_error(ec_id);
00272       }
00273 
00274       ReturnCode_t on_reset(const ECStates& st)
00275       {
00276         if (m_obj->on_reset(ec_id) != RTC::RTC_OK)
00277           {
00278             m_sm.goTo(ERROR_STATE);
00279             return RTC::RTC_ERROR;
00280           }
00281         return RTC::RTC_OK;
00282       }
00283 
00284       ReturnCode_t on_execute(const ECStates& st)
00285       {
00286         if (m_obj->on_execute(ec_id) != RTC::RTC_OK)
00287           {
00288             m_sm.goTo(ERROR_STATE);
00289             return RTC::RTC_ERROR;
00290           }  
00291         return RTC::RTC_OK;
00292       }
00293 
00294       ReturnCode_t on_state_update(const ECStates& st)
00295       {
00296         if (m_obj->on_state_update(ec_id) != RTC::RTC_OK)
00297           {
00298             m_sm.goTo(ERROR_STATE);
00299             return RTC::RTC_ERROR;
00300           }
00301         return RTC::RTC_OK;
00302       }
00303 
00304       ReturnCode_t on_rate_changed()
00305       {
00306         return m_obj->on_rate_changed(ec_id);
00307       }
00308 
00309       Object m_obj;
00310       bool m_active;
00311     };
00312 
00313     struct Comp
00314     {
00315       Comp(LightweightRTObject_ptr ref, DataFlowComponent_ptr dfp,
00316            UniqueId id)
00317         : _ref(ref), _sm(dfp, id)
00318       {
00319       }
00320       Comp(const Comp& comp)
00321         : _ref(comp._ref), _sm(comp._sm.m_obj, comp._sm.ec_id)
00322       {
00323       }
00324       Comp& operator=(const Comp& comp)
00325       {
00326         _ref = comp._ref;
00327         _sm.m_obj = comp._sm.m_obj;
00328         _sm.ec_id = comp._sm.ec_id;
00329         return *this;
00330       }
00331       LightweightRTObject_var _ref;
00332       DFP<DataFlowComponent_var> _sm;
00333     };
00334 
00335 
00336 
00337     struct find_comp
00338     {
00339       LightweightRTObject_var m_comp;
00340       find_comp(LightweightRTObject_ptr comp) : m_comp(comp) {}
00341       bool operator()(Comp& comp)
00342       {
00343         return comp._ref->_is_equivalent(m_comp);
00344       }
00345     };
00346 
00347 
00348     struct invoke_on_startup
00349     {
00350       void operator()(Comp& comp)
00351       {
00352         comp._sm.on_startup();
00353       }
00354     };
00355 
00356     struct invoke_on_shutdown
00357     {
00358       void operator()(Comp& comp)
00359       {
00360         comp._sm.on_shutdown();
00361       }
00362     };
00363 
00364     struct invoke_on_rate_changed
00365     {
00366       void operator()(Comp& comp)
00367       {
00368         comp._sm.on_rate_changed();
00369       }
00370     };
00371 
00372     struct invoke_worker
00373     {
00374       void operator()(Comp& comp)
00375       {
00376         comp._sm.worker();
00377       }
00378     };
00379 
00380     std::vector<Comp> m_comps;
00381     typedef std::vector<Comp>::iterator CompItr;
00382     bool m_running;
00383     ExecutionContextProfile m_profile;
00384     long int m_usec;
00385     ExecutionContextService_var m_ref;
00386 
00387   
00388   }; // class PeriodicExecutionContext
00389 }; // namespace RTC
00390 
00391 extern "C"
00392 {
00393   void PeriodicExecutionContextInit(RTC::Manager* manager);
00394 };
00395 
00396 #endif

Generated on Mon Jul 23 17:08:14 2007 for OpenRTM by  doxygen 1.4.1