#include "stdafx.h" #include "boost/msm/back/state_machine.hpp" #include "boost/msm/front/state_machine_def.hpp" #include "boost/msm/front/functor_row.hpp" namespace msm = boost::msm; namespace mpl = boost::mpl; using namespace boost::msm::front; #include #include namespace test_fsm // Concrete FSM implementation { struct baseEvent { virtual const char * getName() const { return "baseEvent"; }; }; // events struct event1 : public baseEvent { virtual const char * getName() const { return "event1"; }; }; struct event2 : public baseEvent { virtual const char * getName() const { return "event2"; }; }; struct event3 : public baseEvent { virtual const char * getName() const { return "event3"; }; }; struct event4 : public baseEvent { virtual const char * getName() const { return "event4"; }; }; struct event5 : public baseEvent { virtual const char * getName() const { return "event5"; }; }; struct FwdGuard { static bool ret; template bool operator()(EVT const& evt_, FSM& fsm_ , SourceState& src, TargetState& tgt) { std::cout << "FwdGuard: returns:" << ret << ", event: "<< evt_.getName() << std::endl; return ret; } }; bool FwdGuard::ret = true; struct ProcessBaseEvent { template void operator()(EVT const& evt_, FSM& fsm_ , SourceState& src, TargetState& tgt) { std::cout << "Processing BaseEvent Instance(" << evt_.getName() << ")" << std::endl; std::cout << "Setting guard false" << std::endl; FwdGuard::ret = false; } }; struct LogDefer { typedef int deferring_action; template void operator()(EVT const& evt,FSM& fsm,SourceState& src_,TargetState& ) const { std::cout << fsm.m_SmName << " DEFERED: " << evt.getName() << std::endl; fsm.defer_event(evt); } }; struct SM1_ : public msm::front::state_machine_def { typedef int no_exception_thrown; typedef int activate_deferred_events; // The list of FSM states struct Idle : public msm::front::state<> { static const char m_name[]; template void on_entry(Event const& event_, FSM& ms_) {std::cout << ms_.m_SmName << " Entering State: "<< m_name << " by: " << event_.getName() << std::endl;} template void on_exit(Event const& event_, FSM& ms_) {std::cout << ms_.m_SmName << " Leaving State: "<< m_name << " by: " << event_.getName() << std::endl;} }; struct SubRunning : public msm::front::state<> { // typedef ::boost::mpl::vector deferred_events; static const char m_name[]; template void on_entry(Event const& event_, FSM& ms_) {std::cout << ms_.m_SmName << " Entering State: "<< m_name << " by: " << event_.getName() << std::endl;} template void on_exit(Event const& event_, FSM& ms_) {std::cout << ms_.m_SmName << " Leaving State: "<< m_name << " by: " << event_.getName() << std::endl;} }; struct AfterSub : public msm::front::state<> { static const char m_name[]; template void on_entry(Event const& event_, FSM& ms_) {std::cout << ms_.m_SmName << " Entering State: "<< m_name << " by: " << event_.getName() << std::endl;} template void on_exit(Event const& event_, FSM& ms_) {std::cout << ms_.m_SmName << " Leaving State: "<< m_name << " by: " << event_.getName() << std::endl;} }; template void no_transition(Event const& event_ ,FSM&, int state) { std::cout << m_SmName << " no_transition event (" << event_.getName() << ")" << std::endl; } // guard template bool gFwdGuard(const TEvent & event_ ) { msm::front::state<> src; msm::front::state<> dst; FwdGuard myfunctor; return myfunctor(event_, *this, src, dst ); } // action template void aProcessBaseEvent(const TEvent & event_ ) { msm::front::state<> src; msm::front::state<> dst; ProcessBaseEvent myfunctor; myfunctor(event_, *this, src, dst ); } typedef Idle initial_state; // Transition table for SubFsm2 struct transition_table : mpl::vector< // Start Event Next Action Guard // +------------+-----------+------------+------------------+-----------+ _row < Idle , event1 , SubRunning >, _row < SubRunning , event5 , AfterSub >, Row < SubRunning , event4 , none , LogDefer , none >, Row < SubRunning , event3 , none , LogDefer , none >, Row < SubRunning , baseEvent , none , ProcessBaseEvent , FwdGuard > //irow < SubRunning , event4 , &SM1_::aProcessBaseEvent , &SM1_::gFwdGuard >, //irow < SubRunning , event3 , &SM1_::aProcessBaseEvent , &SM1_::gFwdGuard >, //irow < SubRunning , event2 , &SM1_::aProcessBaseEvent , &SM1_::gFwdGuard > // +------------+-----------+------------+------------------+-----------+ > {}; static const char m_SmName[]; }; typedef msm::back::state_machine SM1; } const char test_fsm::SM1_::m_SmName[] = "MS1"; const char test_fsm::SM1_::Idle::m_name[] = "Idle"; const char test_fsm::SM1_::SubRunning::m_name[] = "SubRunning"; const char test_fsm::SM1_::AfterSub::m_name[] = "AfterSub"; int _tmain(int argc, _TCHAR* argv[]) { test_fsm::SM1 sm; sm.start(test_fsm::event1()); sm.process_event(test_fsm::event1()); sm.process_event(test_fsm::event2()); sm.process_event(test_fsm::event3()); sm.process_event(test_fsm::event4()); sm.process_event(test_fsm::event5()); return 0; }