PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Src/Dependencies/Boost/libs/msm/doc/HTML/examples/iPodEuml.cpp

http://hadesmem.googlecode.com/
C++ | 271 lines | 205 code | 21 blank | 45 comment | 36 complexity | 0fc604d6c12978091f8fc44341d84306 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.0, Apache-2.0, LGPL-3.0
  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 <vector>
  11. #include <set>
  12. #include <string>
  13. #include <iostream>
  14. // we need more than the default 20 states
  15. #define FUSION_MAX_VECTOR_SIZE 20
  16. // we need more than the default 20 transitions
  17. #include "boost/mpl/vector/vector50.hpp"
  18. #include <boost/msm/back/state_machine.hpp>
  19. #include <boost/msm/front/euml/euml.hpp>
  20. using namespace std;
  21. using namespace boost::msm::front::euml;
  22. namespace msm = boost::msm;
  23. // attribute names and types
  24. BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int,m_Selected)
  25. BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int,m_SongIndex)
  26. BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int,m_NumberOfSongs)
  27. #include "ipod_functors.hpp"
  28. namespace // Concrete FSM implementation
  29. {
  30. //flags
  31. BOOST_MSM_EUML_FLAG(MenuActive)
  32. BOOST_MSM_EUML_FLAG(NoFastFwd)
  33. // hardware-generated events
  34. BOOST_MSM_EUML_EVENT(Hold)
  35. BOOST_MSM_EUML_EVENT(NoHold)
  36. BOOST_MSM_EUML_EVENT(SouthPressed)
  37. BOOST_MSM_EUML_EVENT(SouthReleased)
  38. BOOST_MSM_EUML_EVENT(MiddleButton)
  39. BOOST_MSM_EUML_EVENT(EastPressed)
  40. BOOST_MSM_EUML_EVENT(EastReleased)
  41. BOOST_MSM_EUML_EVENT(Off)
  42. BOOST_MSM_EUML_EVENT(MenuButton)
  43. // internally defined events
  44. BOOST_MSM_EUML_EVENT(PlayPause)
  45. BOOST_MSM_EUML_EVENT(EndPlay)
  46. struct CloseMenu_impl : euml_event<CloseMenu_impl>
  47. {
  48. CloseMenu_impl(){}//defined only for stt
  49. template<class EVENT>
  50. CloseMenu_impl(EVENT const &) {}
  51. };
  52. CloseMenu_impl const CloseMenu;
  53. BOOST_MSM_EUML_EVENT(OnOffTimer)
  54. BOOST_MSM_EUML_EVENT(MenuMiddleButton)
  55. BOOST_MSM_EUML_EVENT(SelectSong)
  56. BOOST_MSM_EUML_EVENT(SongFinished)
  57. BOOST_MSM_EUML_ATTRIBUTES((attributes_ << m_Selected ), StartSongAttributes)
  58. BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(StartSong,StartSongAttributes)
  59. BOOST_MSM_EUML_EVENT(PreviousSong)
  60. BOOST_MSM_EUML_EVENT(NextSong)
  61. BOOST_MSM_EUML_EVENT(ForwardTimer)
  62. BOOST_MSM_EUML_EVENT(PlayingMiddleButton)
  63. // Concrete iPod implementation
  64. // The list of iPod states
  65. BOOST_MSM_EUML_STATE(( NotHolding_Entry ),NotHolding)
  66. BOOST_MSM_EUML_INTERRUPT_STATE(( NoHold,Holding_Entry ),Holding)
  67. BOOST_MSM_EUML_STATE(( NotPlaying_Entry ),NotPlaying)
  68. BOOST_MSM_EUML_STATE(( NoMenuMode_Entry ),NoMenuMode)
  69. BOOST_MSM_EUML_STATE(( NoOnOffButton_Entry ),NoOnOffButton)
  70. BOOST_MSM_EUML_STATE(( OffDown_Entry ),OffDown)
  71. BOOST_MSM_EUML_STATE(( PlayerOff_Entry ),PlayerOff)
  72. BOOST_MSM_EUML_STATE(( CheckMiddleButton_Entry ),CheckMiddleButton)
  73. // Concrete PlayingMode_ implementation
  74. // The list of PlayingMode_ states
  75. BOOST_MSM_EUML_STATE(( Playing_Entry ),Playing)
  76. BOOST_MSM_EUML_STATE(( WaitingForNextPrev_Entry ),WaitingForNextPrev)
  77. BOOST_MSM_EUML_STATE(( Paused_Entry ),Paused)
  78. BOOST_MSM_EUML_STATE(( WaitingForEnd_Entry ),WaitingForEnd)
  79. BOOST_MSM_EUML_STATE(( NoForward_Entry ),NoForward)
  80. BOOST_MSM_EUML_STATE(( ForwardPressed_Entry,ForwardPressed_Exit ),ForwardPressed)
  81. BOOST_MSM_EUML_STATE(( FastForward_Entry,FastForward_Exit ),FastForward)
  82. BOOST_MSM_EUML_STATE(( StdDisplay_Entry ),StdDisplay)
  83. BOOST_MSM_EUML_STATE(( SetPosition_Entry ),SetPosition)
  84. BOOST_MSM_EUML_STATE(( SetMark_Entry ),SetMark)
  85. BOOST_MSM_EUML_EXIT_STATE(( EndPlay,PlayingExit_Entry ),PlayingExit)
  86. //stt
  87. BOOST_MSM_EUML_TRANSITION_TABLE((
  88. // +------------------------------------------------------------------------------+
  89. Paused == Playing + PlayPause ,
  90. Paused == Playing + Off ,
  91. Playing == Playing + StartSong
  92. / (if_then_(event_(m_Selected) > Int_<0>() &&
  93. event_(m_Selected) < fsm_(m_NumberOfSongs),
  94. fsm_(m_SongIndex) = event_(m_Selected) ),show_selected_song) ,
  95. Playing == Playing + SongFinished
  96. / (if_then_else_(++fsm_(m_SongIndex) <= fsm_(m_NumberOfSongs), /*if*/
  97. show_playing_song, /*then*/
  98. (fsm_(m_SongIndex)=Int_<1>(),process_(EndPlay))/*else*/ ) ) ,
  99. Playing == Paused + PlayPause ,
  100. Playing == Paused + StartSong
  101. / (if_then_(event_(m_Selected) > Int_<0>() &&
  102. event_(m_Selected) < fsm_(m_NumberOfSongs),
  103. fsm_(m_SongIndex) = event_(m_Selected) ),show_selected_song) ,
  104. WaitingForNextPrev == WaitingForNextPrev+ PreviousSong
  105. /( if_then_else_(--fsm_(m_SongIndex) > Int_<0>(), /*if*/
  106. show_playing_song, /*then*/
  107. (fsm_(m_SongIndex)=Int_<1>(),process_(EndPlay)) /*else*/ ) ) ,
  108. WaitingForNextPrev == WaitingForNextPrev+ NextSong
  109. / (if_then_else_(++fsm_(m_SongIndex) <= fsm_(m_NumberOfSongs), /*if*/
  110. show_playing_song, /*then*/
  111. (fsm_(m_SongIndex)=Int_<1>(),process_(EndPlay)) /*else*/ ) ),
  112. PlayingExit == WaitingForEnd + EndPlay ,
  113. ForwardPressed == NoForward + EastPressed [!is_flag_(NoFastFwd)] ,
  114. NoForward == ForwardPressed + EastReleased / process_(NextSong) ,
  115. FastForward == ForwardPressed + ForwardTimer / do_fast_forward ,
  116. FastForward == FastForward + ForwardTimer / do_fast_forward ,
  117. FastForward == NoForward + EastReleased ,
  118. SetPosition == StdDisplay + PlayingMiddleButton ,
  119. StdDisplay == SetPosition + StartSong ,
  120. SetMark == SetPosition + PlayingMiddleButton ,
  121. StdDisplay == SetMark + PlayingMiddleButton ,
  122. StdDisplay == SetMark + StartSong
  123. // +------------------------------------------------------------------------------+
  124. ),playingmode_transition_table )
  125. BOOST_MSM_EUML_DECLARE_STATE_MACHINE( (playingmode_transition_table, //STT
  126. init_ << Playing << WaitingForNextPrev << WaitingForEnd
  127. << NoForward << StdDisplay, // Init States
  128. fsm_(m_NumberOfSongs)=Int_<5>(), // entry
  129. no_action, // exit
  130. attributes_ << m_SongIndex << m_NumberOfSongs, //attributes
  131. configure_<< NoFastFwd // Flags, Deferred events, configuration
  132. ),PlayingMode_)
  133. // choice of back-end
  134. typedef msm::back::state_machine<PlayingMode_> PlayingMode_type;
  135. PlayingMode_type const PlayingMode;
  136. // Concrete MenuMode_ implementation
  137. // The list of MenuMode_ states
  138. BOOST_MSM_EUML_STATE(( WaitingForSongChoice_Entry ),WaitingForSongChoice)
  139. BOOST_MSM_EUML_STATE(( StartCurrentSong_Entry ),StartCurrentSong)
  140. BOOST_MSM_EUML_EXIT_STATE(( CloseMenu,MenuExit_Entry ),MenuExit)
  141. //stt
  142. BOOST_MSM_EUML_TRANSITION_TABLE((
  143. // +------------------------------------------------------------------------------+
  144. StartCurrentSong == WaitingForSongChoice + MenuMiddleButton ,
  145. MenuExit == StartCurrentSong + SelectSong
  146. // +------------------------------------------------------------------------------+
  147. ),menumode_transition_table )
  148. BOOST_MSM_EUML_DECLARE_STATE_MACHINE( (menumode_transition_table, //STT
  149. init_ << WaitingForSongChoice, // Init States
  150. no_action, // entry
  151. no_action, // exit
  152. attributes_ << no_attributes_, //attributes
  153. configure_<< MenuActive // Flags, Deferred events, configuration
  154. ),MenuMode_)
  155. typedef msm::back::state_machine<MenuMode_> MenuMode_type;
  156. MenuMode_type const MenuMode;
  157. // iPod stt
  158. BOOST_MSM_EUML_TRANSITION_TABLE((
  159. // +------------------------------------------------------------------------------+
  160. Holding == NotHolding + Hold ,
  161. NotHolding == Holding + NoHold ,
  162. PlayingMode == NotPlaying + PlayPause ,
  163. NotPlaying == exit_pt_(PlayingMode,PlayingExit) + EndPlay
  164. / process_(MenuButton) ,
  165. MenuMode == NoMenuMode + MenuButton ,
  166. NoMenuMode == exit_pt_(MenuMode,MenuExit)+ CloseMenu
  167. / process2_(StartSong,Int_<5>()) ,
  168. OffDown == NoOnOffButton + SouthPressed ,
  169. NoOnOffButton == OffDown + SouthReleased
  170. / process_(PlayPause) ,
  171. PlayerOff == OffDown + OnOffTimer
  172. / (show_player_off,process_(Off)) ,
  173. NoOnOffButton == PlayerOff + SouthPressed / show_player_on ,
  174. NoOnOffButton == PlayerOff + NoHold / show_player_on ,
  175. CheckMiddleButton == CheckMiddleButton + MiddleButton
  176. [is_flag_(MenuActive)] / process_(PlayingMiddleButton) ,
  177. CheckMiddleButton == CheckMiddleButton + MiddleButton
  178. [!is_flag_(MenuActive)] / process_(PlayingMiddleButton)
  179. // +------------------------------------------------------------------------------+
  180. ),ipod_transition_table )
  181. BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( ipod_transition_table, //STT
  182. init_ << NotHolding << NotPlaying << NoMenuMode
  183. << NoOnOffButton << CheckMiddleButton
  184. ),
  185. iPod_) //fsm name
  186. typedef msm::back::state_machine<iPod_> iPod;
  187. void test()
  188. {
  189. iPod sm;
  190. sm.start();
  191. // we first press Hold
  192. std::cout << "pressing hold" << std::endl;
  193. sm.process_event(Hold);
  194. // pressing a button is now ignored
  195. std::cout << "pressing a button" << std::endl;
  196. sm.process_event(SouthPressed);
  197. // or even one contained in a submachine
  198. sm.process_event(EastPressed);
  199. // no more holding
  200. std::cout << "no more holding, end interrupt event sent" << std::endl;
  201. sm.process_event(NoHold);
  202. std::cout << "pressing South button a short time" << std::endl;
  203. sm.process_event(SouthPressed);
  204. // we suppose a short pressing leading to playing a song
  205. sm.process_event(SouthReleased);
  206. // we move to the next song
  207. std::cout << "we move to the next song" << std::endl;
  208. sm.process_event(NextSong);
  209. // then back to no song => exit from playing, menu active
  210. std::cout << "we press twice the West button (simulated)=> end of playing" << std::endl;
  211. sm.process_event(PreviousSong);
  212. sm.process_event(PreviousSong);
  213. // even in menu mode, pressing play will start playing the first song
  214. std::cout << "pressing play/pause" << std::endl;
  215. sm.process_event(SouthPressed);
  216. sm.process_event(SouthReleased);
  217. // of course pausing must be possible
  218. std::cout << "pressing play/pause" << std::endl;
  219. sm.process_event(SouthPressed);
  220. sm.process_event(SouthReleased);
  221. std::cout << "pressing play/pause" << std::endl;
  222. sm.process_event(SouthPressed);
  223. sm.process_event(SouthReleased);
  224. // while playing, you can fast forward
  225. std::cout << "pressing East button a long time" << std::endl;
  226. sm.process_event(EastPressed);
  227. // let's suppose the timer just fired
  228. sm.process_event(ForwardTimer);
  229. sm.process_event(ForwardTimer);
  230. // end of fast forwarding
  231. std::cout << "releasing East button" << std::endl;
  232. sm.process_event(EastReleased);
  233. // we now press the middle button to set playing at a given position
  234. std::cout << "pressing Middle button, fast forwarding disabled" << std::endl;
  235. sm.process_event(MiddleButton);
  236. std::cout <<"pressing East button to fast forward" << std::endl;
  237. sm.process_event(EastPressed);
  238. // we switch off and on
  239. std::cout <<"switch off player" << std::endl;
  240. sm.process_event(SouthPressed);
  241. sm.process_event(OnOffTimer);
  242. std::cout <<"switch on player" << std::endl;
  243. sm.process_event(SouthPressed);
  244. }
  245. }
  246. int main()
  247. {
  248. test();
  249. return 0;
  250. }