PeriodicExecutionContext.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00020 #ifndef PeriodicExecutionContext_h
00021 #define PeriodicExecutionContext_h
00022 
00023 #include <rtm/RTC.h>
00024 #include <rtm/idl/RTCSkel.h>
00025 #include <rtm/idl/OpenRTMSkel.h>
00026 #include <rtm/Manager.h>
00027 #include <rtm/StateMachine.h>
00028 #include <rtm/ExecutionContextBase.h>
00029 
00030 // ACE
00031 #include <ace/Task.h>
00032 #include <ace/OS_NS_unistd.h>
00033 #include <vector>
00034 #include <iostream>
00035 
00036 namespace RTC
00037 {
00058   class PeriodicExecutionContext
00059     : public virtual ExecutionContextBase,
00060       public ACE_Task<ACE_MT_SYNCH>
00061   {
00062   public:
00082     PeriodicExecutionContext();
00083     
00105     PeriodicExecutionContext(DataFlowComponent_ptr owner,
00106                              double rate = 1000.0);
00107     
00121     virtual ~PeriodicExecutionContext();
00122     
00142     ExecutionContextService_ptr getRef() {return m_ref;}
00143     
00168     virtual int open(void *args);
00169     
00189     virtual int svc(void);
00190     
00217     virtual int close(unsigned long flags);
00218     
00219     //============================================================
00220     // ExecutionContext
00221     //============================================================
00246     virtual CORBA::Boolean is_running()
00247       throw (CORBA::SystemException);
00248     
00277     virtual ReturnCode_t start()
00278       throw (CORBA::SystemException);
00279     
00307     virtual ReturnCode_t stop()
00308       throw (CORBA::SystemException);
00309     
00329     virtual CORBA::Double get_rate()
00330       throw (CORBA::SystemException);
00331     
00361     virtual ReturnCode_t  set_rate(CORBA::Double rate)
00362       throw (CORBA::SystemException);
00363     
00398     virtual ReturnCode_t activate_component(LightweightRTObject_ptr comp)
00399       throw (CORBA::SystemException);
00400     
00434     virtual ReturnCode_t deactivate_component(LightweightRTObject_ptr comp)
00435       throw (CORBA::SystemException);
00436     
00469     virtual ReturnCode_t reset_component(LightweightRTObject_ptr comp)
00470       throw (CORBA::SystemException);
00471     
00499     virtual LifeCycleState get_component_state(LightweightRTObject_ptr comp)
00500       throw (CORBA::SystemException);
00501     
00520     virtual ExecutionKind get_kind()
00521       throw (CORBA::SystemException);
00522     
00555     virtual ReturnCode_t add(LightweightRTObject_ptr comp)
00556       throw (CORBA::SystemException);
00557     
00588     virtual ReturnCode_t remove(LightweightRTObject_ptr comp)
00589       throw (CORBA::SystemException);
00590     
00610     virtual ExecutionContextProfile* get_profile()
00611       throw (CORBA::SystemException);
00612     
00613   protected:
00614     //============================================================
00615     // DFPBase
00616     //============================================================
00617     typedef LifeCycleState ExecContextState;
00618     /***
00619         enum ExecContextState
00620         {
00621         INACTIVE_STATE,
00622         ACTIVE_STATE,
00623         ERROR_STATE,
00624         };
00625     */
00626     typedef RTC_Utils::StateHolder<ExecContextState> ECStates;
00627     
00648     class DFPBase
00649     {
00650     public:
00651       
00669       DFPBase(UniqueId id)
00670         : ec_id(id), m_sm(3)
00671       {
00672         m_sm.setListener(this);
00673         m_sm.setEntryAction (ACTIVE_STATE, &DFPBase::on_activated);
00674         m_sm.setDoAction    (ACTIVE_STATE, &DFPBase::on_execute);
00675         m_sm.setPostDoAction(ACTIVE_STATE, &DFPBase::on_state_update);
00676         m_sm.setExitAction  (ACTIVE_STATE, &DFPBase::on_deactivated);
00677         m_sm.setEntryAction (ERROR_STATE,  &DFPBase::on_aborting);
00678         m_sm.setDoAction    (ERROR_STATE,  &DFPBase::on_error);
00679         m_sm.setExitAction  (ERROR_STATE,  &DFPBase::on_reset);
00680         
00681         ECStates st;
00682         st.prev = INACTIVE_STATE;
00683         st.curr = INACTIVE_STATE;
00684         st.next = INACTIVE_STATE;
00685         m_sm.setStartState(st);
00686         m_sm.goTo(INACTIVE_STATE);
00687       } 
00688       
00702       virtual ~DFPBase(){}
00703       
00720       virtual void on_startup() = 0;
00721       
00738       virtual void on_shutdown() = 0;
00739       
00761       virtual void on_activated(const ECStates& st) = 0;
00762       
00784       virtual void on_deactivated(const ECStates& st) = 0;
00785       
00807       virtual void on_aborting(const ECStates& st) = 0;
00808       
00834       virtual void on_error(const ECStates& st) = 0;
00835       
00861       virtual void on_reset(const ECStates& st) = 0;
00862       
00889       virtual void on_execute(const ECStates& st) = 0;
00890       
00917       virtual void on_state_update(const ECStates& st) = 0;
00918       
00936       virtual void on_rate_changed() = 0;
00937       
00956       virtual void worker() {return m_sm.worker();}
00957       
00975       virtual ExecContextState get_state(){ return m_sm.getState();}
00976       
00984       UniqueId ec_id;
00985       
00993       RTC_Utils::StateMachine<ExecContextState, DFPBase> m_sm;
00994     };
00995     
00996     //============================================================
00997     // DFP
00998     //============================================================
01024     template <class Object>
01025     class DFP
01026       : public DFPBase
01027     {
01028     public:
01048       DFP(Object obj, UniqueId id)
01049         : DFPBase(id), m_obj(obj), m_active(true)
01050       {
01051       }
01052       
01068       void on_startup()
01069       {
01070         m_obj->on_startup(ec_id);
01071       }
01072       
01088       void on_shutdown()
01089       {
01090         m_obj->on_shutdown(ec_id);
01091       }
01092       
01115       void on_activated(const ECStates& st)
01116       {
01117         if (m_obj->on_activated(ec_id) != RTC::RTC_OK)
01118           {
01119             m_sm.goTo(ERROR_STATE);
01120             return;
01121           }
01122         return;
01123       }
01124       
01145       void on_deactivated(const ECStates& st)
01146       {
01147         m_obj->on_deactivated(ec_id);
01148       }
01149       
01169       void on_aborting(const ECStates& st)
01170       {
01171         m_obj->on_aborting(ec_id);
01172       }
01173       
01193       void on_error(const ECStates& st)
01194       {
01195         m_obj->on_error(ec_id);
01196       }
01197       
01217       void on_reset(const ECStates& st)
01218       {
01219         if (m_obj->on_reset(ec_id) != RTC::RTC_OK)
01220           {
01221             m_sm.goTo(ERROR_STATE);
01222             return;
01223           }
01224         return;
01225       }
01226       
01252       void on_execute(const ECStates& st)
01253       {
01254         if (m_obj->on_execute(ec_id) != RTC::RTC_OK)
01255           {
01256             m_sm.goTo(ERROR_STATE);
01257             return;
01258           }  
01259         return;
01260       }
01261       
01287       void on_state_update(const ECStates& st)
01288       {
01289         if (m_obj->on_state_update(ec_id) != RTC::RTC_OK)
01290           {
01291             m_sm.goTo(ERROR_STATE);
01292             return;
01293           }
01294         return;
01295       }
01296       
01313       void on_rate_changed()
01314       {
01315         m_obj->on_rate_changed(ec_id);
01316       }
01317       
01325       Object m_obj;
01326       
01334       bool m_active;
01335     };
01336     
01344     struct Comp
01345     {
01346       Comp(LightweightRTObject_ptr ref, DataFlowComponent_ptr dfp,
01347            UniqueId id)
01348         : _ref(ref), _sm(dfp, id)
01349       {
01350       }
01351       Comp(const Comp& comp)
01352         : _ref(comp._ref), _sm(comp._sm.m_obj, comp._sm.ec_id)
01353       {
01354       }
01355       Comp& operator=(const Comp& comp)
01356       {
01357         _ref = comp._ref;
01358         _sm.m_obj = comp._sm.m_obj;
01359         _sm.ec_id = comp._sm.ec_id;
01360         return *this;
01361       }
01362       LightweightRTObject_var _ref;
01363       DFP<DataFlowComponent_var> _sm;
01364     };
01365     
01373     struct find_comp
01374     {
01375       LightweightRTObject_var m_comp;
01376       find_comp(LightweightRTObject_ptr comp) : m_comp(comp) {}
01377       bool operator()(Comp& comp)
01378       {
01379         return comp._ref->_is_equivalent(m_comp);
01380       }
01381     };
01382     
01390     struct invoke_on_startup
01391     {
01392       void operator()(Comp& comp)
01393       {
01394         comp._sm.on_startup();
01395       }
01396     };
01397     
01405     struct invoke_on_shutdown
01406     {
01407       void operator()(Comp& comp)
01408       {
01409         comp._sm.on_shutdown();
01410       }
01411     };
01412     
01420     struct invoke_on_rate_changed
01421     {
01422       void operator()(Comp& comp)
01423       {
01424         comp._sm.on_rate_changed();
01425       }
01426     };
01427     
01435     struct invoke_worker
01436     {
01437       void operator()(Comp& comp)
01438       {
01439         comp._sm.worker();
01440       }
01441     };
01442     
01450     std::vector<Comp> m_comps;
01451     typedef std::vector<Comp>::iterator CompItr;
01452     
01462     bool m_state;
01463 
01471     bool m_running;
01472     
01480     ExecutionContextProfile m_profile;
01481     
01489     long int m_usec;
01490     
01498     ExecutionContextService_var m_ref;
01499     
01508     bool m_nowait;
01509   }; // class PeriodicExecutionContext
01510 }; // namespace RTC
01511 
01512 extern "C"
01513 {
01514   void PeriodicExecutionContextInit(RTC::Manager* manager);
01515 };
01516 
01517 #endif

Generated on Thu May 29 15:03:33 2008 for OpenRTM by  doxygen 1.5.3