// Composite_Sate_explicit_entry.cpp : Defines the entry point for the console application. // #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 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 { event4 () : baseEvent() { } event4 (const event3& evt_) : 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 = false; struct ProcessBaseEvent { template void operator()(EVT const& evt_, FSM& fsm_ , SourceState& src, TargetState& tgt) { std::cout << "Processing BaseEvent" << std::endl; } }; // Concrete FSM implementation struct SM1_ : public msm::front::state_machine_def { // no need for exception handling or message queue typedef int no_exception_thrown; typedef int activate_deferred_events; // The list of FSM states struct Idle : public msm::front::state<> { // optional entry/exit methods template void on_entry(Event const&,FSM& ms_) {std::cout << "entering: Idle " << ms_.m_SmName << std::endl;} template void on_exit(Event const&,FSM& ) {std::cout << "leaving: Idle" << std::endl;} }; struct RunningStateMachine_ : public msm::front::state_machine_def { // no need for exception handling or message queue typedef int no_exception_thrown; typedef int activate_deferred_events; // optional entry/exit methods template void on_entry(Event const&,FSM& ms_) {std::cout << "entering: RunningStateMachine " << ms_.m_SmName << std::endl;} template void on_exit(Event const&,FSM& ) {std::cout << "leaving: RunningStateMachine" << std::endl;} // The list of FSM states struct InitialState : public msm::front::state<> { // optional entry/exit methods template void on_entry(Event const&,FSM& ) {std::cout << "entering: InitialState" << std::endl;} template void on_exit(Event const&,FSM& ) {std::cout << "leaving: InitialState" << std::endl;} }; struct PseudoExit1 : public msm::front::exit_pseudo_state { template void on_entry(Event const&,FSM& ) {std::cout << "entering: RunningStateMachine::PseudoExit1" << std::endl;} template void on_exit(Event const&,FSM& ) {std::cout << "leaving: RunningStateMachine::PseudoExit1" << std::endl;} }; struct PseudoEntry1 : public msm::front::entry_pseudo_state<0> { template void on_entry(Event const&,FSM& ) {std::cout << "entering: RunningStateMachine::PseudoEntry1" << std::endl;} template void on_exit(Event const&,FSM& ) {std::cout << "leaving: RunningStateMachine::PseudoEntry1" << std::endl;} }; struct Inner1_ : public msm::front::state_machine_def { // no need for exception handling or message queue typedef int no_exception_thrown; typedef int activate_deferred_events; // optional entry/exit methods template void on_entry(Event const&,FSM& ms_) { std::cout << "entering: Inner1 " << ms_.m_SmName << std::endl; } template void on_exit(Event const&,FSM& ) {std::cout << "leaving: Inner1" << std::endl;} // The list of FSM states struct InnerState11 : public msm::front::state<> , public msm::front::explicit_entry<0> { // optional entry/exit methods template void on_entry(Event const&,FSM& fsm_ ) { std::cout << "entering: InnerState11" << std::endl; //std::cout << "sending event5" << std::endl; //fsm_.process_event(event5()); //std::cout << "sending event5 sent" << std::endl; } template void on_exit(Event const&,FSM& ) {std::cout << "leaving: InnerState11" << std::endl;} }; struct InnerState12 : public msm::front::state<> { // optional entry/exit methods template void on_entry(Event const&,FSM& ) {std::cout << "entering: InnerState12" << std::endl;} template void on_exit(Event const&,FSM& ) {std::cout << "leaving: InnerState12" << std::endl;} }; // the initial state of the player SM. Must be defined typedef InnerState11 initial_state; // transition actions void onEvent2(event2 const&) { std::cout << "Action: Inner1::onEvent2" << std::endl; } struct transition_table : mpl::vector1< // Start Event Next Action Guard // +---------+-------------+---------+---------------------+----------------------+ a_row < InnerState11 , event2 , InnerState12 , &Inner1_::onEvent2 > // +---------+-------------+---------+---------------------+----------------------+ > {}; static const char m_SmName[]; }; typedef msm::back::state_machine Inner1; // the initial state of the player SM. Must be defined typedef InitialState initial_state; typedef int activate_deferred_events; // transition actions void onEvent4(event4 const&) { std::cout << "Action: RunningStateMachine::onEvent4" << std::endl; } struct transition_table : mpl::vector< // Start Event Next Action Guard // +---------+-------------+---------+---------------------+----------------------+ a_row < InitialState , event4 , InitialState , &RunningStateMachine_::onEvent4 >, //_row < PseudoEntry1 , event1 , Inner1::direct >, _row < PseudoEntry1 , event1 , Inner1 >, _row < Inner1 , event3 , PseudoExit1 >, Row < Inner1 , baseEvent , none , ProcessBaseEvent , FwdGuard > //_row < PseudoEntry1 , event2 , Inner2 > // +---------+-------------+---------+---------------------+----------------------+ > {}; static const char m_SmName[]; }; typedef msm::back::state_machine RunningStateMachine; // the initial state of the player SM. Must be defined typedef Idle initial_state; // transition actions void onEvent1(event1 const&) { std::cout << "Action: MS1::onEvent1" << std::endl; } // transition actions void onEvent2(event2 const&) { std::cout << "Action: MS1::onEvent1" << std::endl; } void onEvent5(event5 const&) { std::cout << "Action: MS1::onEvent5" << std::endl; } // Transition table for SubFsm2 struct transition_table : mpl::vector< // Start Event Next Action Guard // +--------------+-------------+------------+------------------------+----------------------+ _row < RunningStateMachine::exit_pt< RunningStateMachine::PseudoExit1 > , event4 , Idle >, //a_irow < RunningStateMachine , event5 ,&SM1_::onEvent5 >, Row < RunningStateMachine, event5 , none , Defer, none >, a_row < Idle , event1 , RunningStateMachine::entry_pt ,&SM1_::onEvent1 > //a_row < Idle , event2 , RunningStateMachine::entry_pt ,&SM1_::onEvent2 > // +--------------+-------------+------------+------------------------+----------------------+ > {}; static const char m_SmName[]; }; typedef msm::back::state_machine SM1; } const char test_fsm::SM1_::m_SmName[] = "MS1_"; const char test_fsm::SM1_::RunningStateMachine_::m_SmName[] = "RunningStateMachine_"; const char test_fsm::SM1_::RunningStateMachine_::Inner1_::m_SmName[] = "Inner1_"; int _tmain(int argc, _TCHAR* argv[]) { test_fsm::SM1 sm; sm.start(); sm.process_event(test_fsm::event1()); sm.process_event(test_fsm::event5()); sm.process_event(test_fsm::event1()); sm.process_event(test_fsm::event1()); sm.process_event(test_fsm::event1()); return 0; }