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