TestDeferIn2Regions.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // Copyright 2010 Christophe Henry
  2. // henry UNDERSCORE christophe AT hotmail DOT com
  3. // This is an extended version of the state machine available in the boost::mpl library
  4. // Distributed under the same license as the original.
  5. // Copyright for the original version:
  6. // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
  7. // under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #include <iostream>
  11. // back-end
  12. #include <boost/msm/back/state_machine.hpp>
  13. //front-end
  14. #include <boost/msm/front/state_machine_def.hpp>
  15. #include <boost/msm/front/functor_row.hpp>
  16. #include <boost/test/unit_test.hpp>
  17. namespace msm = boost::msm;
  18. namespace mpl = boost::mpl;
  19. using namespace boost::msm::front;
  20. namespace
  21. {
  22. // events
  23. struct event1 {};
  24. struct event2 {};
  25. struct event3 {};
  26. struct eventd {};
  27. // front-end: define the FSM structure
  28. struct player_ : public msm::front::state_machine_def<player_>
  29. {
  30. // The list of FSM states
  31. struct State11 : public msm::front::state<>
  32. {
  33. template <class Event,class FSM>
  34. void on_entry(Event const&,FSM& ) {++entry_counter;}
  35. template <class Event,class FSM>
  36. void on_exit(Event const&,FSM& ) {++exit_counter;}
  37. int entry_counter;
  38. int exit_counter;
  39. };
  40. struct State12 : public msm::front::state<>
  41. {
  42. typedef mpl::vector<eventd> deferred_events;
  43. template <class Event,class FSM>
  44. void on_entry(Event const&,FSM& ) {++entry_counter;}
  45. template <class Event,class FSM>
  46. void on_exit(Event const&,FSM& ) {++exit_counter;}
  47. int entry_counter;
  48. int exit_counter;
  49. };
  50. struct State13 : public msm::front::state<>
  51. {
  52. template <class Event,class FSM>
  53. void on_entry(Event const&,FSM& ) {++entry_counter;}
  54. template <class Event,class FSM>
  55. void on_exit(Event const&,FSM& ) {++exit_counter;}
  56. int entry_counter;
  57. int exit_counter;
  58. };
  59. struct State21 : public msm::front::state<>
  60. {
  61. template <class Event,class FSM>
  62. void on_entry(Event const&,FSM& ) {++entry_counter;}
  63. template <class Event,class FSM>
  64. void on_exit(Event const&,FSM& ) {++exit_counter;}
  65. int entry_counter;
  66. int exit_counter;
  67. };
  68. struct State22 : public msm::front::state<>
  69. {
  70. template <class Event,class FSM>
  71. void on_entry(Event const&,FSM& ) {++entry_counter;}
  72. template <class Event,class FSM>
  73. void on_exit(Event const&,FSM& ) {++exit_counter;}
  74. int entry_counter;
  75. int exit_counter;
  76. };
  77. // the initial state of the player SM. Must be defined
  78. typedef mpl::vector<State11,State21> initial_state;
  79. // Transition table for player
  80. struct transition_table : mpl::vector<
  81. // Start Event Next Action Guard
  82. // +---------+-------------+---------+---------------------+----------------------+
  83. Row < State11 , event1 , State12 >,
  84. Row < State12 , event2 , State13 >,
  85. Row < State21 , event3 , State22 >,
  86. Row < State22 , eventd , State21 >
  87. // +---------+-------------+---------+---------------------+----------------------+
  88. > {};
  89. // Replaces the default no-transition response.
  90. template <class FSM,class Event>
  91. void no_transition(Event const& , FSM&,int )
  92. {
  93. BOOST_FAIL("no_transition called!");
  94. }
  95. // init counters
  96. template <class Event,class FSM>
  97. void on_entry(Event const&,FSM& fsm)
  98. {
  99. fsm.template get_state<player_::State11&>().entry_counter=0;
  100. fsm.template get_state<player_::State11&>().exit_counter=0;
  101. fsm.template get_state<player_::State12&>().entry_counter=0;
  102. fsm.template get_state<player_::State12&>().exit_counter=0;
  103. fsm.template get_state<player_::State13&>().entry_counter=0;
  104. fsm.template get_state<player_::State13&>().exit_counter=0;
  105. fsm.template get_state<player_::State21&>().entry_counter=0;
  106. fsm.template get_state<player_::State22&>().exit_counter=0;
  107. }
  108. };
  109. // Pick a back-end
  110. typedef msm::back::state_machine<player_> player;
  111. BOOST_AUTO_TEST_CASE( TestDeferIn2Regions )
  112. {
  113. player p;
  114. // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
  115. p.start();
  116. p.process_event(event1());
  117. BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"State12 should be active");
  118. BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
  119. BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
  120. BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
  121. BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
  122. // deferred
  123. p.process_event(eventd());
  124. BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"State12 should be active");
  125. BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
  126. BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
  127. BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
  128. BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
  129. BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().exit_counter == 0,"State12 exit not called correctly");
  130. BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().exit_counter == 0,"State21 exit not called correctly");
  131. BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().entry_counter == 1,"State21 entry not called correctly");
  132. BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().exit_counter == 0,"State22 exit not called correctly");
  133. BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().entry_counter == 0,"State22 entry not called correctly");
  134. p.process_event(event3());
  135. BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"State12 should be active");
  136. BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
  137. BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().exit_counter == 1,"State21 exit not called correctly");
  138. BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().entry_counter == 2,"State21 entry not called correctly");
  139. BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().exit_counter == 1,"State22 exit not called correctly");
  140. BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().entry_counter == 1,"State22 entry not called correctly");
  141. BOOST_CHECK_MESSAGE(p.get_deferred_queue().size() == 1,"Deferred queue should have one element");
  142. p.clear_deferred_queue();
  143. p.process_event(event2());
  144. BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"State13 should be active");
  145. BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
  146. BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().exit_counter == 1,"State21 exit not called correctly");
  147. BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().entry_counter == 2,"State21 entry not called correctly");
  148. BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().exit_counter == 1,"State22 exit not called correctly");
  149. BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().entry_counter == 1,"State22 entry not called correctly");
  150. BOOST_CHECK_MESSAGE(p.get_deferred_queue().size() == 0,"Deferred queue should have no element");
  151. }
  152. }