fork download
  1. #include <iostream>
  2. #include <boost/msm/back/state_machine.hpp>
  3. #include <boost/msm/front/functor_row.hpp>
  4. #include <boost/msm/front/state_machine_def.hpp>
  5. #include <boost/static_assert.hpp>
  6.  
  7. namespace {
  8. namespace msm = boost::msm;
  9. namespace msmf = boost::msm::front;
  10. namespace mpl = boost::mpl;
  11.  
  12. // ----- Events
  13. struct Event1 {};
  14. struct Event2 {};
  15. struct Event3 {};
  16.  
  17. // ----- State machine
  18. struct StateSub_:msmf::state_machine_def<StateSub_>
  19. {
  20. struct SubState1:msmf::state<> {
  21. template <class Event,class Fsm>
  22. void on_entry(Event const&, Fsm&) const {
  23. BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, StateSub_>::value));
  24. std::cout << "SubState1::on_entry()" << std::endl;
  25. }
  26. template <class Event,class Fsm>
  27. void on_exit(Event const&, Fsm&) const {
  28. BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, StateSub_>::value));
  29. std::cout << "SubState1::on_exit()" << std::endl;
  30. }
  31. };
  32. struct SubState2:msmf::state<> {
  33. template <class Event,class Fsm>
  34. void on_entry(Event const&, Fsm&) const {
  35. BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, StateSub_>::value));
  36. std::cout << "SubState2::on_entry()" << std::endl;
  37. }
  38. template <class Event,class Fsm>
  39. void on_exit(Event const&, Fsm&) const {
  40. BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, StateSub_>::value));
  41. std::cout << "SubState2::on_exit()" << std::endl;
  42. }
  43. };
  44.  
  45. // Set initial state
  46. typedef mpl::vector<SubState1> initial_state;
  47. // Transition table
  48. struct transition_table:mpl::vector<
  49. // Start Event Next Action Guard
  50. msmf::Row < SubState1, Event2, SubState2, msmf::none, msmf::none >,
  51. msmf::Row < SubState2, Event3, SubState1, msmf::none, msmf::none >
  52. > {};
  53. };
  54. typedef msm::back::state_machine<StateSub_> StateSub;
  55. struct OuterSm_:msmf::state_machine_def<OuterSm_>
  56. {
  57. struct State1_:msmf::state_machine_def<State1_>
  58. {
  59. template <class Event,class Fsm>
  60. void on_entry(Event const&, Fsm&) const {
  61. BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value));
  62. std::cout << "State1::on_entry()" << std::endl;
  63. }
  64. template <class Event,class Fsm>
  65. void on_exit(Event const&, Fsm&) const {
  66. BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value));
  67. std::cout << "State1::on_exit()" << std::endl;
  68. }
  69. struct Sub_:StateSub {};
  70. typedef Sub_ initial_state;
  71. };
  72. // Pick a back-end
  73. typedef msm::back::state_machine<State1_> State1;
  74. struct State2:msmf::state<>
  75. {
  76. template <class Event,class Fsm>
  77. void on_entry(Event const&, Fsm&) const {
  78. BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value));
  79. std::cout << "State2::on_entry()" << std::endl;
  80. }
  81. template <class Event,class Fsm>
  82. void on_exit(Event const&, Fsm&) const {
  83. BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value));
  84. std::cout << "State2::on_exit()" << std::endl;
  85. }
  86. };
  87. // Set initial state
  88. typedef State1 initial_state;
  89. // Transition table
  90. struct transition_table:mpl::vector<
  91. // Start Event Next Action Guard
  92. msmf::Row < State1, Event1, State2, msmf::none, msmf::none >
  93. > {};
  94. };
  95.  
  96. // Pick a back-end
  97. typedef msm::back::state_machine<OuterSm_> Osm;
  98.  
  99. void test()
  100. {
  101. Osm osm;
  102. osm.start();
  103.  
  104. std::cout << "> Send Event2()" << std::endl;
  105. osm.process_event(Event2());
  106. std::cout << "> Send Event1()" << std::endl;
  107. osm.process_event(Event1());
  108. }
  109. }
  110.  
  111. int main()
  112. {
  113. test();
  114. return 0;
  115. }
Success #stdin #stdout 0.01s 5432KB
stdin
Standard input is empty
stdout
State1::on_entry()
SubState1::on_entry()
> Send Event2()
SubState1::on_exit()
SubState2::on_entry()
> Send Event1()
SubState2::on_exit()
State1::on_exit()
State2::on_entry()