Test2RegionsAnonymous.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. // functors
  16. #include <boost/msm/front/functor_row.hpp>
  17. #include <boost/msm/front/euml/common.hpp>
  18. // for And_ operator
  19. #include <boost/msm/front/euml/operator.hpp>
  20. #include <boost/test/unit_test.hpp>
  21. using namespace std;
  22. namespace msm = boost::msm;
  23. namespace mpl = boost::mpl;
  24. using namespace msm::front;
  25. // for And_ operator
  26. using namespace msm::front::euml;
  27. namespace
  28. {
  29. // events
  30. struct event1 {};
  31. struct event2 {};
  32. // front-end: define the FSM structure
  33. struct my_machine_ : public msm::front::state_machine_def<my_machine_>
  34. {
  35. // The list of FSM states
  36. struct State1 : public msm::front::state<>
  37. {
  38. template <class Event,class FSM>
  39. void on_entry(Event const&,FSM& ) {++entry_counter;}
  40. template <class Event,class FSM>
  41. void on_exit(Event const&,FSM& ) {++exit_counter;}
  42. int entry_counter;
  43. int exit_counter;
  44. };
  45. struct State2 : public msm::front::state<>
  46. {
  47. template <class Event,class FSM>
  48. void on_entry(Event const&,FSM& ) {++entry_counter;}
  49. template <class Event,class FSM>
  50. void on_exit(Event const&,FSM& ) {++exit_counter;}
  51. int entry_counter;
  52. int exit_counter;
  53. };
  54. struct State3 : public msm::front::state<>
  55. {
  56. template <class Event,class FSM>
  57. void on_entry(Event const&,FSM& ) {++entry_counter;}
  58. template <class Event,class FSM>
  59. void on_exit(Event const&,FSM& ) {++exit_counter;}
  60. int entry_counter;
  61. int exit_counter;
  62. };
  63. struct State1b : public msm::front::state<>
  64. {
  65. template <class Event,class FSM>
  66. void on_entry(Event const&,FSM& ) {++entry_counter;}
  67. template <class Event,class FSM>
  68. void on_exit(Event const&,FSM& ) {++exit_counter;}
  69. int entry_counter;
  70. int exit_counter;
  71. };
  72. struct State2b : public msm::front::state<>
  73. {
  74. template <class Event,class FSM>
  75. void on_entry(Event const&,FSM& ) {++entry_counter;}
  76. template <class Event,class FSM>
  77. void on_exit(Event const&,FSM& ) {++exit_counter;}
  78. int entry_counter;
  79. int exit_counter;
  80. };
  81. struct always_true
  82. {
  83. template <class EVT,class FSM,class SourceState,class TargetState>
  84. bool operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
  85. {
  86. return true;
  87. }
  88. };
  89. struct always_false
  90. {
  91. template <class EVT,class FSM,class SourceState,class TargetState>
  92. bool operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
  93. {
  94. return false;
  95. }
  96. };
  97. // the initial state of the player SM. Must be defined
  98. typedef boost::mpl::vector2<State1,State1b> initial_state;
  99. // Transition table for player
  100. struct transition_table : boost::mpl::vector<
  101. // Start Event Next Action Guard
  102. // +---------+-------------+---------+---------------------+----------------------+
  103. Row < State1 , event1 , State2 , none , always_true >,
  104. Row < State2 , none , State3 >,
  105. // +---------+-------------+---------+---------------------+----------------------+
  106. Row < State1b , event1 , State2b , none , always_false >
  107. // +---------+-------------+---------+---------------------+----------------------+
  108. > {};
  109. // Replaces the default no-transition response.
  110. template <class FSM,class Event>
  111. void no_transition(Event const&, FSM&,int)
  112. {
  113. BOOST_FAIL("no_transition called!");
  114. }
  115. // init counters
  116. template <class Event,class FSM>
  117. void on_entry(Event const&,FSM& fsm)
  118. {
  119. fsm.template get_state<my_machine_::State1&>().entry_counter=0;
  120. fsm.template get_state<my_machine_::State1&>().exit_counter=0;
  121. fsm.template get_state<my_machine_::State2&>().entry_counter=0;
  122. fsm.template get_state<my_machine_::State2&>().exit_counter=0;
  123. fsm.template get_state<my_machine_::State3&>().entry_counter=0;
  124. fsm.template get_state<my_machine_::State3&>().exit_counter=0;
  125. fsm.template get_state<my_machine_::State1b&>().entry_counter=0;
  126. fsm.template get_state<my_machine_::State1b&>().exit_counter=0;
  127. fsm.template get_state<my_machine_::State2b&>().entry_counter=0;
  128. fsm.template get_state<my_machine_::State2b&>().exit_counter=0;
  129. }
  130. };
  131. // Pick a back-end
  132. typedef msm::back::state_machine<my_machine_> my_machine;
  133. BOOST_AUTO_TEST_CASE( my_test )
  134. {
  135. my_machine p;
  136. p.start();
  137. BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State1 should be active");
  138. BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State1b should be active");
  139. p.process_event(event1());
  140. BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"State3 should be active");
  141. BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State1b should be active");
  142. BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().exit_counter == 1,"State1 exit not called correctly");
  143. BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().entry_counter == 1,"State1 entry not called correctly");
  144. BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().exit_counter == 1,"State2 exit not called correctly");
  145. BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().entry_counter == 1,"State2 entry not called correctly");
  146. BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().exit_counter == 0,"State3 exit not called correctly");
  147. BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().entry_counter == 1,"State3 entry not called correctly");
  148. BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1b&>().entry_counter == 1,"State1b entry not called correctly");
  149. BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1b&>().exit_counter == 0,"State1b exit not called correctly");
  150. BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2b&>().entry_counter == 0,"State2b entry not called correctly");
  151. BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2b&>().exit_counter == 0,"State2b exit not called correctly");
  152. }
  153. }