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