#include #include #include #include #include namespace msm = boost::msm; namespace mpl = boost::mpl; struct cmd_t { cmd_t(int id) : id_(id) {} virtual ~cmd_t() {} int id_; }; struct test_machine_front_t : public msm::front::state_machine_def { struct ev_connected {}; struct ev_disconnected {}; // internal connected state events struct ev_async_send_simple_cmd { ev_async_send_simple_cmd(boost::shared_ptr op) : op_(op) {} boost::shared_ptr op_; }; struct ev_async_send_cmd_with_reply { ev_async_send_cmd_with_reply(boost::shared_ptr op) : op_(op) {} boost::shared_ptr op_; }; struct ev_async_got_reply {}; // disconnected state struct st_disconnected : public msm::front::state<> {}; // connected state is submachine // front-end st_connected_ struct st_connected_ : public msm::front::state_machine_def { struct st_ready : public msm::front::state<> {}; struct st_busy : public msm::front::state<> { typedef mpl::vector deferred_events; }; // the initial state of st_connected_ typedef st_ready initial_state; void on_simple_cmd( const ev_async_send_simple_cmd& ev ) { std::cout << "On simple cmd: " << ev.op_ << std::endl; op_ = ev.op_; } void on_cmd_with_reply( const ev_async_send_cmd_with_reply& ev ) { std::cout << "On cmd with reply: " << ev.op_->id_ << std::endl; op_ = ev.op_; } void on_got_reply( const ev_async_got_reply& ) { // std::cout << "On got reply" << std::endl; op_.reset(); } template void on_exit(Event const&, Fsm&) { std::cout << "On exit" << std::endl; op_.reset(); } typedef st_connected_ m; // transition table for st_connected_ struct transition_table : mpl::vector< // Start Event Next Action Guard // +---------+-----------------------------+---------+----------------------+----------------+ a_row < st_ready, ev_async_send_cmd_with_reply, st_busy , &m::on_cmd_with_reply>, a_row < st_ready, ev_async_send_simple_cmd , st_ready, &m::on_simple_cmd >, a_row < st_busy , ev_async_got_reply , st_ready, &m::on_got_reply > // +---------+-----------------------------+---------+----------------------+----------------+ > {}; typedef int no_message_queue; typedef int no_exception_thrown; boost::shared_ptr op_; }; // back-end st_connected_ typedef msm::back::state_machine st_connected; // the initial state of machine_ typedef st_disconnected initial_state; // transition table for machine_ struct transition_table : mpl::vector< // Start Event Next Action Guard // +---------------+----------------+-----------------+--------------------+----------------------+ _row < st_disconnected, ev_connected , st_connected >, _row < st_connected , ev_disconnected, st_disconnected > // +---------------+----------------+-----------------+--------------------+----------------------+ > {}; // replaces the default no-transition response. template void no_transition(Event const&, FSM&, int) { assert("Client FSM no_transition"); } typedef int no_message_queue; typedef int no_exception_thrown; }; struct test_machine_t : public msm::back::state_machine > > {}; int main(int argc, char* argv[]) { test_machine_t machine; machine.process_event(test_machine_front_t::ev_connected()); machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr(new cmd_t(0)))); machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr(new cmd_t(1)))); machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr(new cmd_t(2)))); machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr(new cmd_t(3)))); machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr(new cmd_t(4)))); machine.process_event(test_machine_front_t::ev_disconnected()); machine.process_event(test_machine_front_t::ev_connected()); machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr(new cmd_t(5)))); machine.process_event(test_machine_front_t::ev_async_got_reply()); return 0; }