SCSimple.cpp 5.9 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 <boost/statechart/event.hpp>
  11. #include <boost/statechart/state_machine.hpp>
  12. #include <boost/statechart/simple_state.hpp>
  13. #include <boost/statechart/transition.hpp>
  14. #include "boost/mpl/list.hpp"
  15. #include <vector>
  16. #include <iostream>
  17. #ifdef WIN32
  18. #include "windows.h"
  19. #else
  20. #include <sys/time.h>
  21. #endif
  22. namespace sc = boost::statechart;
  23. namespace mpl = boost::mpl;
  24. namespace test_sc
  25. {
  26. //events
  27. struct play : sc::event< play > {};
  28. struct end_pause : sc::event< end_pause > {};
  29. struct stop : sc::event< stop > {};
  30. struct pause : sc::event< pause > {};
  31. struct open_close : sc::event< open_close > {};
  32. struct cd_detected : sc::event< cd_detected > {};
  33. struct Empty;
  34. struct Open;
  35. struct Stopped;
  36. struct Playing;
  37. struct Paused;
  38. // SM
  39. struct player : sc::state_machine< player, Empty >
  40. {
  41. void open_drawer(open_close const&) { /*std::cout << "player::open_drawer\n";*/ }
  42. void store_cd_info(cd_detected const& cd) {/*std::cout << "player::store_cd_info\n";*/ }
  43. void close_drawer(open_close const&) { /*std::cout << "player::close_drawer\n";*/ }
  44. void start_playback(play const&) { /*std::cout << "player::start_playback\n";*/ }
  45. void stopped_again(stop const&) {/*std::cout << "player::stopped_again\n";*/}
  46. void stop_playback(stop const&) { /*std::cout << "player::stop_playback\n";*/ }
  47. void pause_playback(pause const&) { /*std::cout << "player::pause_playback\n"; */}
  48. void stop_and_open(open_close const&) { /*std::cout << "player::stop_and_open\n";*/ }
  49. void resume_playback(end_pause const&) { /*std::cout << "player::resume_playback\n";*/ }
  50. };
  51. struct Empty : sc::simple_state< Empty, player >
  52. {
  53. Empty() { /*std::cout << "entering Empty" << std::endl;*/ } // entry
  54. ~Empty() { /*std::cout << "leaving Empty" << std::endl;*/ } // exit
  55. typedef mpl::list<
  56. sc::transition< open_close, Open,
  57. player, &player::open_drawer >,
  58. sc::transition< cd_detected, Stopped,
  59. player, &player::store_cd_info > > reactions;
  60. };
  61. struct Open : sc::simple_state< Open, player >
  62. {
  63. Open() { /*std::cout << "entering Open" << std::endl;*/ } // entry
  64. ~Open() { /*std::cout << "leaving Open" << std::endl;*/ } // exit
  65. typedef sc::transition< open_close, Empty,
  66. player, &player::close_drawer > reactions;
  67. };
  68. struct Stopped : sc::simple_state< Stopped, player >
  69. {
  70. Stopped() { /*std::cout << "entering Stopped" << std::endl;*/ } // entry
  71. ~Stopped() { /*std::cout << "leaving Stopped" << std::endl;*/ } // exit
  72. typedef mpl::list<
  73. sc::transition< play, Playing,
  74. player, &player::start_playback >,
  75. sc::transition< open_close, Open,
  76. player, &player::open_drawer >,
  77. sc::transition< stop, Stopped,
  78. player, &player::stopped_again > > reactions;
  79. };
  80. struct Playing : sc::simple_state< Playing, player >
  81. {
  82. Playing() { /*std::cout << "entering Playing" << std::endl;*/ } // entry
  83. ~Playing() { /*std::cout << "leaving Playing" << std::endl;*/ } // exit
  84. typedef mpl::list<
  85. sc::transition< stop, Stopped,
  86. player, &player::stop_playback >,
  87. sc::transition< pause, Paused,
  88. player, &player::pause_playback >,
  89. sc::transition< open_close, Open,
  90. player, &player::stop_and_open > > reactions;
  91. };
  92. struct Paused : sc::simple_state< Paused, player >
  93. {
  94. Paused() { /*std::cout << "entering Paused" << std::endl;*/ } // entry
  95. ~Paused() { /*std::cout << "leaving Paused" << std::endl;*/ } // exit
  96. typedef mpl::list<
  97. sc::transition< end_pause, Playing,
  98. player, &player::resume_playback >,
  99. sc::transition< stop, Stopped,
  100. player, &player::stop_playback >,
  101. sc::transition< open_close, Open,
  102. player, &player::stop_and_open > > reactions;
  103. };
  104. }
  105. #ifndef WIN32
  106. long mtime(struct timeval& tv1,struct timeval& tv2)
  107. {
  108. return (tv2.tv_sec-tv1.tv_sec) *1000000 + ((tv2.tv_usec-tv1.tv_usec));
  109. }
  110. #endif
  111. int main()
  112. {
  113. test_sc::player p;
  114. p.initiate();
  115. // for timing
  116. #ifdef WIN32
  117. LARGE_INTEGER res;
  118. ::QueryPerformanceFrequency(&res);
  119. LARGE_INTEGER li,li2;
  120. ::QueryPerformanceCounter(&li);
  121. #else
  122. struct timeval tv1,tv2;
  123. gettimeofday(&tv1,NULL);
  124. #endif
  125. for (int i=0;i<100;++i)
  126. {
  127. p.process_event(test_sc::open_close());
  128. p.process_event(test_sc::open_close());
  129. p.process_event(test_sc::cd_detected());
  130. p.process_event(test_sc::play());
  131. p.process_event(test_sc::pause());
  132. // go back to Playing
  133. p.process_event(test_sc::end_pause());
  134. p.process_event(test_sc::pause());
  135. p.process_event(test_sc::stop());
  136. // event leading to the same state
  137. p.process_event(test_sc::stop());
  138. p.process_event(test_sc::open_close());
  139. p.process_event(test_sc::open_close());
  140. }
  141. #ifdef WIN32
  142. ::QueryPerformanceCounter(&li2);
  143. #else
  144. gettimeofday(&tv2,NULL);
  145. #endif
  146. #ifdef WIN32
  147. std::cout << "sc took in s:" << (double)(li2.QuadPart-li.QuadPart)/res.QuadPart <<"\n" <<std::endl;
  148. #else
  149. std::cout << "sc took in us:" << mtime(tv1,tv2) <<"\n" <<std::endl;
  150. #endif
  151. return 0;
  152. }