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

Generated on Tue May 29 16:45:37 2007 for OpenRTM by  doxygen 1.4.1