#include #include #include #include namespace { namespace msm = boost::msm; namespace msmf = boost::msm::front; namespace mpl = boost::mpl; // ----- Events struct Event1 {}; struct Event2 { Event2() {} template Event2(Event const&) {} }; struct Event3 {}; // ----- State machine struct Sm1_:public msm::front::state_machine_def { // States struct State1_:public msm::front::state_machine_def { // Entry action template void on_entry(Event const&, Fsm&) const { std::cout << "State1::on_entry()" << std::endl; } // Exit action template void on_exit(Event const&, Fsm&) const { std::cout << "State1::on_exit()" << std::endl; } // States struct State1_1:msm::front::state<> { // Entry action template void on_entry(Event const&, Fsm&) const { std::cout << "State1_1::on_entry()" << std::endl; } // Exit action template void on_exit(Event const&, Fsm&) const { std::cout << "State1_1::on_exit()" << std::endl; } }; struct Exit1:public msm::front::exit_pseudo_state {}; struct Exit2:public msm::front::exit_pseudo_state {}; // Set initial state typedef State1_1 initial_state; // Actions struct Action1 { template void operator()(Event const&, Fsm&, SourceState&, TargetState&) const { std::cout << "Action1" << std::endl; } }; struct Action3 { template void operator()(Event const&, Fsm&, SourceState&, TargetState&) const { std::cout << "Action3" << std::endl; } }; // Transition table struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1_1, Event1, Exit1, Action1, msmf::none >, msmf::Row < State1_1, Event3, Exit2, Action3, msmf::none > > {}; }; // back-end typedef msm::back::state_machine State1; struct State2:msm::front::state<> { // Entry action template void on_entry(Event const&, Fsm&) const { std::cout << "State2::on_entry()" << std::endl; } // Exit action template void on_exit(Event const&, Fsm&) const { std::cout << "State2::on_exit()" << std::endl; } }; struct Choice1:msm::front::state<> {}; // Actions struct Action2 { template void operator()(Event const&, Fsm&, SourceState&, TargetState&) const { std::cout << "Action2" << std::endl; } }; struct Action4 { template void operator()(Event const&, Fsm&, SourceState&, TargetState&) const { std::cout << "Action4" << std::endl; } }; // Guards struct Guard1 { template bool operator()(Event const&, Fsm& fsm, SourceState&, TargetState&) const { return fsm.res > 10; } }; // Set initial state typedef State1 initial_state; // Transition table struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1::exit_pt , Event2, State2, Action2, msmf::none >, msmf::Row < State1::exit_pt , msmf::none, State2, Action4, msmf::none > > {}; // No handled event handler template void no_transition(Event const& e, Fsm& ,int state) { std::cout << "No handled event in State1 " << typeid(e).name() << " on State " << state << std::endl; } }; // back-end typedef msm::back::state_machine Sm1; // No handled event handler template void no_transition(Event const& e, Fsm& ,int state) { std::cout << "No handled event in Sm1 " << typeid(e).name() << " on State " << state << std::endl; } void test() { { std::cout << "=== test case 1 ===" << std::endl; Sm1 sm1; sm1.start(); std::cout << "> Send Event1" << std::endl; sm1.process_event(Event1()); } { std::cout << "=== test case 2 ===" << std::endl; Sm1 sm1; sm1.start(); std::cout << "> Send Event2" << std::endl; sm1.process_event(Event2()); } { std::cout << "=== test case 3 ===" << std::endl; Sm1 sm1; sm1.start(); std::cout << "> Send Event3" << std::endl; sm1.process_event(Event3()); } } } int main() { test(); return 0; } // Output: // // === test case 1 === // State1::on_entry() // State1_1::on_entry() // > Send Event1 // State1_1::on_exit() // Action1 // State1::on_exit() // Action2 // State2::on_entry() // === test case 2 === // State1::on_entry() // State1_1::on_entry() // > Send Event2 // No handled event in State1 struct `anonymous namespace'::Event2 on State 0 // === test case 3 === // State1::on_entry() // State1_1::on_entry() // > Send Event3 // State1_1::on_exit() // Action3 // State1::on_exit() // Action4 // State2::on_entry()