EumlSimple.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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 "stdafx.h"
  11. #include <boost/msm/back/state_machine.hpp>
  12. #include <boost/msm/front/state_machine_def.hpp>
  13. #include <boost/msm/front/euml/euml.hpp>
  14. #include <boost/msm/front/euml/stl.hpp>
  15. namespace msm = boost::msm;
  16. namespace mpl = boost::mpl;
  17. using namespace boost::msm::front::euml;
  18. #include <iostream>
  19. #ifdef WIN32
  20. #include "windows.h"
  21. #else
  22. #include <sys/time.h>
  23. #endif
  24. namespace // Concrete FSM implementation
  25. {
  26. // events
  27. BOOST_MSM_EUML_EVENT(play)
  28. BOOST_MSM_EUML_EVENT(end_pause)
  29. BOOST_MSM_EUML_EVENT(stop)
  30. BOOST_MSM_EUML_EVENT(pause)
  31. BOOST_MSM_EUML_EVENT(open_close)
  32. BOOST_MSM_EUML_EVENT(cd_detected)
  33. BOOST_MSM_EUML_ACTION(start_playback)
  34. {
  35. template <class FSM,class EVT,class SourceState,class TargetState>
  36. void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
  37. {
  38. }
  39. };
  40. BOOST_MSM_EUML_ACTION(open_drawer)
  41. {
  42. template <class FSM,class EVT,class SourceState,class TargetState>
  43. void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
  44. {
  45. }
  46. };
  47. BOOST_MSM_EUML_ACTION(close_drawer)
  48. {
  49. template <class FSM,class EVT,class SourceState,class TargetState>
  50. void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
  51. {
  52. }
  53. };
  54. BOOST_MSM_EUML_ACTION(store_cd_info)
  55. {
  56. template <class FSM,class EVT,class SourceState,class TargetState>
  57. void operator()(EVT const&, FSM& fsm ,SourceState& ,TargetState& )
  58. {
  59. }
  60. };
  61. BOOST_MSM_EUML_ACTION(stop_playback)
  62. {
  63. template <class FSM,class EVT,class SourceState,class TargetState>
  64. void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
  65. {
  66. }
  67. };
  68. BOOST_MSM_EUML_ACTION(pause_playback)
  69. {
  70. template <class FSM,class EVT,class SourceState,class TargetState>
  71. void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
  72. {
  73. }
  74. };
  75. BOOST_MSM_EUML_ACTION(resume_playback)
  76. {
  77. template <class FSM,class EVT,class SourceState,class TargetState>
  78. void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
  79. {
  80. }
  81. };
  82. BOOST_MSM_EUML_ACTION(stop_and_open)
  83. {
  84. template <class FSM,class EVT,class SourceState,class TargetState>
  85. void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
  86. {
  87. }
  88. };
  89. BOOST_MSM_EUML_ACTION(stopped_again)
  90. {
  91. template <class FSM,class EVT,class SourceState,class TargetState>
  92. void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
  93. {
  94. }
  95. };
  96. // The list of FSM states
  97. BOOST_MSM_EUML_STATE((),Empty)
  98. BOOST_MSM_EUML_STATE((),Open)
  99. BOOST_MSM_EUML_STATE((),Stopped)
  100. BOOST_MSM_EUML_STATE((),Playing)
  101. BOOST_MSM_EUML_STATE((),Paused)
  102. // replaces the old transition table
  103. BOOST_MSM_EUML_TRANSITION_TABLE((
  104. Playing == Stopped + play / start_playback ,
  105. Playing == Paused + end_pause / resume_playback ,
  106. // +------------------------------------------------------------------------------+
  107. Empty == Open + open_close / close_drawer ,
  108. // +------------------------------------------------------------------------------+
  109. Open == Empty + open_close / open_drawer ,
  110. Open == Paused + open_close / stop_and_open ,
  111. Open == Stopped + open_close / open_drawer ,
  112. Open == Playing + open_close / stop_and_open ,
  113. // +------------------------------------------------------------------------------+
  114. Paused == Playing + pause / pause_playback ,
  115. // +------------------------------------------------------------------------------+
  116. Stopped == Playing + stop / stop_playback ,
  117. Stopped == Paused + stop / stop_playback ,
  118. Stopped == Empty + cd_detected / store_cd_info ,
  119. Stopped == Stopped + stop / stopped_again
  120. // +------------------------------------------------------------------------------+
  121. ),transition_table)
  122. BOOST_MSM_EUML_ACTION(Log_No_Transition)
  123. {
  124. template <class FSM,class Event>
  125. void operator()(Event const& e,FSM&,int state)
  126. {
  127. std::cout << "no transition from state " << state
  128. << " on event " << typeid(e).name() << std::endl;
  129. }
  130. };
  131. // create a state machine "on the fly"
  132. BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT
  133. init_ << Empty, // Init State
  134. no_action, // Entry
  135. no_action, // Exit
  136. attributes_ << no_attributes_, // Attributes
  137. configure_ << no_exception << no_msg_queue, // configuration
  138. Log_No_Transition // no_transition handler
  139. ),
  140. player_) //fsm name
  141. typedef msm::back::state_machine<player_> player;
  142. //
  143. // Testing utilities.
  144. //
  145. static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
  146. void pstate(player const& p)
  147. {
  148. std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
  149. }
  150. }
  151. #ifndef WIN32
  152. long mtime(struct timeval& tv1,struct timeval& tv2)
  153. {
  154. return (tv2.tv_sec-tv1.tv_sec) *1000000 + ((tv2.tv_usec-tv1.tv_usec));
  155. }
  156. #endif
  157. int main()
  158. {
  159. // for timing
  160. #ifdef WIN32
  161. LARGE_INTEGER res;
  162. ::QueryPerformanceFrequency(&res);
  163. LARGE_INTEGER li,li2;
  164. #else
  165. struct timeval tv1,tv2;
  166. gettimeofday(&tv1,NULL);
  167. #endif
  168. player p2;
  169. p2.start();
  170. // for timing
  171. #ifdef WIN32
  172. ::QueryPerformanceCounter(&li);
  173. #else
  174. gettimeofday(&tv1,NULL);
  175. #endif
  176. for (int i=0;i<100;++i)
  177. {
  178. p2.process_event(open_close);
  179. p2.process_event(open_close);
  180. p2.process_event(cd_detected);
  181. p2.process_event(play);
  182. p2.process_event(pause);
  183. // go back to Playing
  184. p2.process_event(end_pause);
  185. p2.process_event(pause);
  186. p2.process_event(stop);
  187. // event leading to the same state
  188. p2.process_event(stop);
  189. p2.process_event(open_close);
  190. p2.process_event(open_close);
  191. }
  192. #ifdef WIN32
  193. ::QueryPerformanceCounter(&li2);
  194. #else
  195. gettimeofday(&tv2,NULL);
  196. #endif
  197. #ifdef WIN32
  198. std::cout << "msm took in s:" << (double)(li2.QuadPart-li.QuadPart)/res.QuadPart <<"\n" <<std::endl;
  199. #else
  200. std::cout << "msm took in us:" << mtime(tv1,tv2) <<"\n" <<std::endl;
  201. #endif
  202. return 0;
  203. }