SCComposite.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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 NextSong: sc::event< NextSong > {};
  34. struct PreviousSong : sc::event< PreviousSong >{};
  35. struct Empty;
  36. struct Open;
  37. struct Stopped;
  38. struct Playing;
  39. struct Paused;
  40. // SM
  41. struct player : sc::state_machine< player, Empty >
  42. {
  43. void open_drawer(open_close const&) { /*std::cout << "player::open_drawer\n";*/ }
  44. void store_cd_info(cd_detected const& cd) {/*std::cout << "player::store_cd_info\n";*/ }
  45. void close_drawer(open_close const&) { /*std::cout << "player::close_drawer\n";*/ }
  46. void start_playback(play const&) { /*std::cout << "player::start_playback\n";*/ }
  47. void stopped_again(stop const&) {/*std::cout << "player::stopped_again\n";*/}
  48. void stop_playback(stop const&) { /*std::cout << "player::stop_playback\n";*/ }
  49. void pause_playback(pause const&) { /*std::cout << "player::pause_playback\n"; */}
  50. void stop_and_open(open_close const&) { /*std::cout << "player::stop_and_open\n";*/ }
  51. void resume_playback(end_pause const&) { /*std::cout << "player::resume_playback\n";*/ }
  52. };
  53. struct Empty : sc::simple_state< Empty, player >
  54. {
  55. Empty() { /*std::cout << "entering Empty" << std::endl;*/ } // entry
  56. ~Empty() { /*std::cout << "leaving Empty" << std::endl;*/ } // exit
  57. typedef mpl::list<
  58. sc::transition< open_close, Open,
  59. player, &player::open_drawer >,
  60. sc::transition< cd_detected, Stopped,
  61. player, &player::store_cd_info > > reactions;
  62. };
  63. struct Open : sc::simple_state< Open, player >
  64. {
  65. Open() { /*std::cout << "entering Open" << std::endl;*/ } // entry
  66. ~Open() { /*std::cout << "leaving Open" << std::endl;*/ } // exit
  67. typedef sc::transition< open_close, Empty,
  68. player, &player::close_drawer > reactions;
  69. };
  70. struct Stopped : sc::simple_state< Stopped, player >
  71. {
  72. Stopped() { /*std::cout << "entering Stopped" << std::endl;*/ } // entry
  73. ~Stopped() { /*std::cout << "leaving Stopped" << std::endl;*/ } // exit
  74. typedef mpl::list<
  75. sc::transition< play, Playing,
  76. player, &player::start_playback >,
  77. sc::transition< open_close, Open,
  78. player, &player::open_drawer >,
  79. sc::transition< stop, Stopped,
  80. player, &player::stopped_again > > reactions;
  81. };
  82. struct Song1;
  83. struct Playing : sc::simple_state< Playing, player,Song1 >
  84. {
  85. Playing() { /*std::cout << "entering Playing" << std::endl;*/ } // entry
  86. ~Playing() { /*std::cout << "leaving Playing" << std::endl;*/ } // exit
  87. typedef mpl::list<
  88. sc::transition< stop, Stopped,
  89. player, &player::stop_playback >,
  90. sc::transition< pause, Paused,
  91. player, &player::pause_playback >,
  92. sc::transition< open_close, Open,
  93. player, &player::stop_and_open > > reactions;
  94. void start_next_song(NextSong const&) { /*std::cout << "Playing::start_next_song\n";*/ }
  95. void start_prev_song(PreviousSong const&) { /*std::cout << "Playing::start_prev_song\n";*/ }
  96. };
  97. struct Song2;
  98. struct Song1 : sc::simple_state< Song1, Playing >
  99. {
  100. Song1() { /*std::cout << "entering Song1" << std::endl;*/ } // entry
  101. ~Song1() { /*std::cout << "leaving Song1" << std::endl;*/ } // exit
  102. typedef sc::transition< NextSong, Song2,
  103. Playing, &Playing::start_next_song > reactions;
  104. };
  105. struct Song3;
  106. struct Song2 : sc::simple_state< Song2, Playing >
  107. {
  108. Song2() { /*std::cout << "entering Song2" << std::endl;*/ } // entry
  109. ~Song2() { /*std::cout << "leaving Song2" << std::endl;*/ } // exit
  110. typedef mpl::list<
  111. sc::transition< NextSong, Song3,
  112. Playing, &Playing::start_next_song >,
  113. sc::transition< PreviousSong, Song1,
  114. Playing, &Playing::start_prev_song > > reactions;
  115. };
  116. struct Song3 : sc::simple_state< Song3, Playing >
  117. {
  118. Song3() { /*std::cout << "entering Song3" << std::endl;*/ } // entry
  119. ~Song3() { /*std::cout << "leaving Song3" << std::endl;*/ } // exit
  120. typedef sc::transition< PreviousSong, Song2,
  121. Playing, &Playing::start_prev_song > reactions;
  122. };
  123. struct Paused : sc::simple_state< Paused, player >
  124. {
  125. Paused() { /*std::cout << "entering Paused" << std::endl;*/ } // entry
  126. ~Paused() { /*std::cout << "leaving Paused" << std::endl;*/ } // exit
  127. typedef mpl::list<
  128. sc::transition< end_pause, Playing,
  129. player, &player::resume_playback >,
  130. sc::transition< stop, Stopped,
  131. player, &player::stop_playback >,
  132. sc::transition< open_close, Open,
  133. player, &player::stop_and_open > > reactions;
  134. };
  135. }
  136. #ifndef WIN32
  137. long mtime(struct timeval& tv1,struct timeval& tv2)
  138. {
  139. return (tv2.tv_sec-tv1.tv_sec) *1000000 + ((tv2.tv_usec-tv1.tv_usec));
  140. }
  141. #endif
  142. int main()
  143. {
  144. test_sc::player p;
  145. p.initiate();
  146. // for timing
  147. #ifdef WIN32
  148. LARGE_INTEGER res;
  149. ::QueryPerformanceFrequency(&res);
  150. LARGE_INTEGER li,li2;
  151. ::QueryPerformanceCounter(&li);
  152. #else
  153. struct timeval tv1,tv2;
  154. gettimeofday(&tv1,NULL);
  155. #endif
  156. for (int i=0;i<100;++i)
  157. {
  158. p.process_event(test_sc::open_close());
  159. p.process_event(test_sc::open_close());
  160. p.process_event(test_sc::cd_detected());
  161. p.process_event(test_sc::play());
  162. for (int j=0;j<100;++j)
  163. {
  164. p.process_event(test_sc::NextSong());
  165. p.process_event(test_sc::NextSong());
  166. p.process_event(test_sc::PreviousSong());
  167. p.process_event(test_sc::PreviousSong());
  168. }
  169. p.process_event(test_sc::pause());
  170. // go back to Playing
  171. p.process_event(test_sc::end_pause());
  172. p.process_event(test_sc::pause());
  173. p.process_event(test_sc::stop());
  174. // event leading to the same state
  175. p.process_event(test_sc::stop());
  176. p.process_event(test_sc::open_close());
  177. p.process_event(test_sc::open_close());
  178. }
  179. #ifdef WIN32
  180. ::QueryPerformanceCounter(&li2);
  181. #else
  182. gettimeofday(&tv2,NULL);
  183. #endif
  184. #ifdef WIN32
  185. std::cout << "sc took in s:" << (double)(li2.QuadPart-li.QuadPart)/res.QuadPart <<"\n" <<std::endl;
  186. #else
  187. std::cout << "sc took in us:" << mtime(tv1,tv2) <<"\n" <<std::endl;
  188. #endif
  189. return 0;
  190. }