On this page, we have implemented the same state machine (the "simple" sample from boost::msm) with various statemachine libraries.
// events struct play {}; struct end_pause {}; struct stop {}; struct pause {}; struct open_close {}; struct cd_detected{}; // Concrete FSM implementation struct player_ : public msm::front::state_machine_def<player_> { // no need for exception handling or message queue typedef int no_exception_thrown; typedef int no_message_queue; // The list of FSM states struct Empty : public msm::front::state<> { // optional entry/exit methods template <class Event,class FSM> void on_entry(Event const&,FSM& ) {/*std::cout << "entering: Empty" << std::endl;*/} template <class Event,class FSM> void on_exit(Event const&,FSM& ) {/*std::cout << "leaving: Empty" << std::endl;*/} }; struct Open : public msm::front::state<> { template <class Event,class FSM> void on_entry(Event const&,FSM& ) {/*std::cout << "entering: Open" << std::endl;*/} template <class Event,class FSM> void on_exit(Event const&,FSM& ) {/*std::cout << "leaving: Open" << std::endl;*/} }; struct Stopped : public msm::front::state<> { template <class Event,class FSM> void on_entry(Event const&,FSM& ) {/*std::cout << "entering: Stopped" << std::endl;*/} template <class Event,class FSM> void on_exit(Event const&,FSM& ) {/*std::cout << "leaving: Stopped" << std::endl;*/} }; struct Playing : public msm::front::state<> { template <class Event,class FSM> void on_entry(Event const&,FSM& ) {/*std::cout << "entering: Playing" << std::endl;*/} template <class Event,class FSM> void on_exit(Event const&,FSM& ) {/*std::cout << "leaving: Playing" << std::endl;*/} }; struct Paused : public msm::front::state<> { template <class Event,class FSM> void on_entry(Event const&,FSM& ) {/*std::cout << "entering: Paused" << std::endl;*/} template <class Event,class FSM> void on_exit(Event const&,FSM& ) {/*std::cout << "leaving: Paused" << std::endl;*/} }; // the initial state of the player SM. Must be defined typedef Empty initial_state; // transition actions void start_playback(play const&) { } void open_drawer(open_close const&) { } void close_drawer(open_close const&) { } void store_cd_info(cd_detected const& cd) { } void stop_playback(stop const&) { } void pause_playback(pause const&) { } void resume_playback(end_pause const&) { } void stop_and_open(open_close const&) { } void stopped_again(stop const&){} // guard conditions typedef player_ p; // makes transition table cleaner // Transition table for player struct transition_table : mpl::vector< // Start Event Next Action Guard // +---------+-------------+---------+---------------------+----------------------+ _row < Stopped , play , Playing >, _row < Stopped , open_close , Open >, _row < Stopped , stop , Stopped >, // +---------+-------------+---------+---------------------+----------------------+ _row < Open , open_close , Empty >, // +---------+-------------+---------+---------------------+----------------------+ _row < Empty , open_close , Open >, _row < Empty , cd_detected , Stopped >, // +---------+-------------+---------+---------------------+----------------------+ _row < Playing , stop , Stopped >, _row < Playing , pause , Paused >, _row < Playing , open_close , Open >, // +---------+-------------+---------+---------------------+----------------------+ _row < Paused , end_pause , Playing >, _row < Paused , stop , Stopped >, _row < Paused , open_close , Open > // +---------+-------------+---------+---------------------+----------------------+ > {}; // Replaces the default no-transition response. template <class FSM,class Event> void no_transition(Event const& e, FSM&,int state) { std::cout << "no transition from state " << state << " on event " << typeid(e).name() << std::endl; } }; typedef msm::back::state_machine<player_> player;
//events struct play : sc::event< play > {}; struct end_pause : sc::event< end_pause > {}; struct stop : sc::event< stop > {}; struct pause : sc::event< pause > {}; struct open_close : sc::event< open_close > {}; struct cd_detected : sc::event< cd_detected > {}; struct Empty; struct Open; struct Stopped; struct Playing; struct Paused; // SM struct player : sc::state_machine< player, Empty > { void open_drawer(open_close const&) { /*std::cout << "player::open_drawer\n";*/ } void store_cd_info(cd_detected const& cd) {/*std::cout << "player::store_cd_info\n";*/ } void close_drawer(open_close const&) { /*std::cout << "player::close_drawer\n";*/ } void start_playback(play const&) { /*std::cout << "player::start_playback\n";*/ } void stopped_again(stop const&) {/*std::cout << "player::stopped_again\n";*/} void stop_playback(stop const&) { /*std::cout << "player::stop_playback\n";*/ } void pause_playback(pause const&) { /*std::cout << "player::pause_playback\n"; */} void stop_and_open(open_close const&) { /*std::cout << "player::stop_and_open\n";*/ } void resume_playback(end_pause const&) { /*std::cout << "player::resume_playback\n";*/ } }; struct Empty : sc::simple_state< Empty, player > { Empty() { /*std::cout << "entering Empty" << std::endl;*/ } // entry ~Empty() { /*std::cout << "leaving Empty" << std::endl;*/ } // exit typedef mpl::list< sc::transition< open_close, Open, player, &player::open_drawer >, sc::transition< cd_detected, Stopped, player, &player::store_cd_info > > reactions; }; struct Open : sc::simple_state< Open, player > { Open() { /*std::cout << "entering Open" << std::endl;*/ } // entry ~Open() { /*std::cout << "leaving Open" << std::endl;*/ } // exit typedef sc::transition< open_close, Empty, player, &player::close_drawer > reactions; }; struct Stopped : sc::simple_state< Stopped, player > { Stopped() { /*std::cout << "entering Stopped" << std::endl;*/ } // entry ~Stopped() { /*std::cout << "leaving Stopped" << std::endl;*/ } // exit typedef mpl::list< sc::transition< play, Playing, player, &player::start_playback >, sc::transition< open_close, Open, player, &player::open_drawer >, sc::transition< stop, Stopped, player, &player::stopped_again > > reactions; }; struct Playing : sc::simple_state< Playing, player > { Playing() { /*std::cout << "entering Playing" << std::endl;*/ } // entry ~Playing() { /*std::cout << "leaving Playing" << std::endl;*/ } // exit typedef mpl::list< sc::transition< stop, Stopped, player, &player::stop_playback >, sc::transition< pause, Paused, player, &player::pause_playback >, sc::transition< open_close, Open, player, &player::stop_and_open > > reactions; }; struct Paused : sc::simple_state< Paused, player > { Paused() { /*std::cout << "entering Paused" << std::endl;*/ } // entry ~Paused() { /*std::cout << "leaving Paused" << std::endl;*/ } // exit typedef mpl::list< sc::transition< end_pause, Playing, player, &player::resume_playback >, sc::transition< stop, Stopped, player, &player::stop_playback >, sc::transition< open_close, Open, player, &player::stop_and_open > > reactions; };
StateMachine sm( State("Empty", initialTag, OnEntry([](){/*std::cout << "entering: Empty" << std::endl;*/}), OnExit([](){/*std::cout << "leaving: Empty" << std::endl;*/}), Transition( OnEvent("open_close"), Target("Open")), Transition( OnEvent("cd_detected"),Target("Stopped")) ), State("Open", OnEntry([](){/*std::cout << "entering: Open" << std::endl;*/}), OnExit([](){/*std::cout << "leaving: Open" << std::endl;*/}), Transition( OnEvent("open_close"), Target("Empty")) ), State("Stopped", OnEntry([](){/*std::cout << "entering: Stopped" << std::endl;*/}), OnExit([](){/*std::cout << "leaving: Stopped" << std::endl;*/}), Transition( OnEvent("play"), Target("Playing")), Transition( OnEvent("open_close"), Target("Open")), Transition( OnEvent("stop"), Target("Stopped")) ), State("Playing", OnEntry([](){/*std::cout << "entering: Playing" << std::endl;*/}), OnExit([](){/*std::cout << "leaving: Playing" << std::endl;*/}), Transition( OnEvent("stop"), Target("Stopped")), Transition( OnEvent("pause"), Target("Paused")), Transition( OnEvent("open_close"), Target("Open")) ), State("Paused", OnEntry([](){/*std::cout << "entering: Paused" << std::endl;*/}), OnExit([](){/*std::cout << "leaving: Paused" << std::endl;*/}), Transition( OnEvent("stop"), Target("Stopped")), Transition( OnEvent("end_pause"), Target("Playing")), Transition( OnEvent("open_close"), Target("Open")) ) );