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 | // back-end |
12 | #include <boost/msm/back/state_machine.hpp> |
13 | //front-end |
14 | #include <boost/msm/front/state_machine_def.hpp> |
15 | #include <boost/msm/front/euml/euml.hpp> |
16 | #ifndef BOOST_MSM_NONSTANDALONE_TEST |
17 | #define BOOST_TEST_MODULE MyOrthogonalDeferredEumlTest |
18 | #endif |
19 | #include <boost/test/unit_test.hpp> |
20 | |
21 | namespace msm = boost::msm; |
22 | namespace mpl = boost::mpl; |
23 | using namespace boost::msm::front::euml; |
24 | |
25 | namespace |
26 | { |
27 | // events |
28 | BOOST_MSM_EUML_EVENT(play) |
29 | BOOST_MSM_EUML_EVENT(end_pause) |
30 | BOOST_MSM_EUML_EVENT(stop) |
31 | BOOST_MSM_EUML_EVENT(pause) |
32 | BOOST_MSM_EUML_EVENT(open_close) |
33 | BOOST_MSM_EUML_EVENT(next_song) |
34 | BOOST_MSM_EUML_EVENT(previous_song) |
35 | BOOST_MSM_EUML_EVENT(error_found) |
36 | BOOST_MSM_EUML_EVENT(end_error) |
37 | BOOST_MSM_EUML_EVENT(do_terminate) |
38 | |
39 | // Flags. Allow information about a property of the current state |
40 | BOOST_MSM_EUML_FLAG(PlayingPaused) |
41 | BOOST_MSM_EUML_FLAG(CDLoaded) |
42 | BOOST_MSM_EUML_FLAG(FirstSongPlaying) |
43 | |
44 | // A "complicated" event type that carries some data. |
45 | BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,cd_name) |
46 | BOOST_MSM_EUML_ATTRIBUTES((attributes_ << cd_name ), cd_detected_attributes) |
47 | BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(cd_detected,cd_detected_attributes) |
48 | |
49 | //states |
50 | BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,entry_counter) |
51 | BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,exit_counter) |
52 | |
53 | BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter), |
54 | attributes_ << entry_counter << exit_counter, configure_ << play),Empty) |
55 | BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter), |
56 | attributes_ << entry_counter << exit_counter, configure_<< CDLoaded << play),Open) |
57 | BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter), |
58 | attributes_ << entry_counter << exit_counter, configure_<< CDLoaded),Stopped) |
59 | BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter), |
60 | attributes_ << entry_counter << exit_counter, configure_<< CDLoaded << PlayingPaused),Paused) |
61 | |
62 | BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),AllOk) |
63 | BOOST_MSM_EUML_TERMINATE_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter), |
64 | ErrorTerminate) |
65 | BOOST_MSM_EUML_INTERRUPT_STATE(( end_error,++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter), |
66 | ErrorMode) |
67 | |
68 | // Playing is now a state machine itself. |
69 | BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_next_song_counter) |
70 | BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_prev_song_guard_counter) |
71 | |
72 | BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter), |
73 | attributes_ << entry_counter << exit_counter, configure_<< FirstSongPlaying ),Song1) |
74 | BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Song2) |
75 | BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Song3) |
76 | |
77 | // Playing has a transition table |
78 | BOOST_MSM_EUML_TRANSITION_TABLE(( |
79 | // +------------------------------------------------------------------------------+ |
80 | Song2 == Song1 + next_song , |
81 | Song1 == Song2 + previous_song [True_()] / ++fsm_(start_prev_song_guard_counter) , |
82 | Song3 == Song2 + next_song / ++fsm_(start_next_song_counter) , |
83 | Song2 == Song3 + previous_song [True_()] / ++fsm_(start_prev_song_guard_counter) |
84 | // +------------------------------------------------------------------------------+ |
85 | ),playing_transition_table ) |
86 | |
87 | BOOST_MSM_EUML_DECLARE_STATE_MACHINE( (playing_transition_table, //STT |
88 | init_ << Song1, // Init State |
89 | ++state_(entry_counter), // Entry |
90 | ++state_(exit_counter), // Exit |
91 | attributes_ << entry_counter << exit_counter |
92 | << start_next_song_counter |
93 | << start_prev_song_guard_counter, // Attributes |
94 | configure_<< PlayingPaused << CDLoaded //flags |
95 | ),Playing_) |
96 | |
97 | // back-end |
98 | typedef msm::back::state_machine<Playing_> Playing_type; |
99 | Playing_type const Playing; |
100 | |
101 | //fsm |
102 | BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_playback_counter) |
103 | BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,can_close_drawer_counter) |
104 | BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,report_error_counter) |
105 | BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,report_end_error_counter) |
106 | BOOST_MSM_EUML_ACTION(No_Transition) |
107 | { |
108 | template <class FSM,class Event> |
109 | void operator()(Event const&,FSM&,int) |
110 | { |
111 | BOOST_FAIL("no_transition called!" ); |
112 | } |
113 | }; |
114 | |
115 | BOOST_MSM_EUML_TRANSITION_TABLE(( |
116 | Playing == Stopped + play / ++fsm_(start_playback_counter), |
117 | Playing == Paused + end_pause , |
118 | // +------------------------------------------------------------------------------+ |
119 | Empty == Open + open_close / ++fsm_(can_close_drawer_counter), |
120 | // +------------------------------------------------------------------------------+ |
121 | Open == Empty + open_close , |
122 | Open == Paused + open_close , |
123 | Open == Stopped + open_close , |
124 | Open == Playing + open_close , |
125 | // +------------------------------------------------------------------------------+ |
126 | Paused == Playing + pause , |
127 | // +------------------------------------------------------------------------------+ |
128 | Stopped == Playing + stop , |
129 | Stopped == Paused + stop , |
130 | Stopped == Empty + cd_detected , |
131 | Stopped == Stopped + stop , |
132 | ErrorMode == AllOk + error_found / ++fsm_(report_error_counter), |
133 | AllOk == ErrorMode+ end_error / ++fsm_(report_end_error_counter), |
134 | ErrorTerminate== AllOk +do_terminate |
135 | // +------------------------------------------------------------------------------+ |
136 | ),transition_table) |
137 | |
138 | BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT |
139 | init_ << Empty << AllOk, // Init State |
140 | no_action, // Entry |
141 | no_action, // Exit |
142 | attributes_ << start_playback_counter << can_close_drawer_counter |
143 | << report_error_counter << report_end_error_counter, // Attributes |
144 | configure_ << no_configure_, // configuration |
145 | No_Transition // no_transition handler |
146 | ), |
147 | player_) //fsm name |
148 | |
149 | // Pick a back-end |
150 | typedef msm::back::state_machine<player_> player; |
151 | |
152 | //static char const* const state_names[] = { "Stopped", "Paused","Open", "Empty", "Playing" ,"AllOk","ErrorMode","ErrorTerminate" }; |
153 | |
154 | BOOST_AUTO_TEST_CASE(MyOrthogonalDeferredEumlTest) |
155 | { |
156 | player p; |
157 | // needed to start the highest-level SM. This will call on_entry and mark the start of the SM |
158 | p.start(); |
159 | // test deferred event |
160 | // deferred in Empty and Open, will be handled only after event cd_detected |
161 | p.process_event(evt: play); |
162 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active" ); //Empty |
163 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 0, |
164 | "Open exit not called correctly" ); |
165 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(entry_counter) == 0,"Playing entry not called correctly" ); |
166 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1, |
167 | "Empty entry not called correctly" ); |
168 | //flags |
169 | BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(CDLoaded)>() == false,"CDLoaded should not be active" ); |
170 | |
171 | p.process_event(evt: open_close); |
172 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Open should be active" ); //Open |
173 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1, |
174 | "Empty exit not called correctly" ); |
175 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1, |
176 | "Open entry not called correctly" ); |
177 | |
178 | p.process_event(evt: open_close); |
179 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active" ); //Empty |
180 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1, |
181 | "Open exit not called correctly" ); |
182 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2, |
183 | "Empty entry not called correctly" ); |
184 | BOOST_CHECK_MESSAGE(p.get_attribute(can_close_drawer_counter) == 1,"guard not called correctly" ); |
185 | |
186 | //deferred event should have been processed |
187 | p.process_event(evt: cd_detected("louie, louie" )); |
188 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active" ); //Playing |
189 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 2, |
190 | "Empty exit not called correctly" ); |
191 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1, |
192 | "Stopped entry not called correctly" ); |
193 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1, |
194 | "Stopped exit not called correctly" ); |
195 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(entry_counter) == 1,"Playing entry not called correctly" ); |
196 | BOOST_CHECK_MESSAGE(p.get_attribute(start_playback_counter) == 1,"action not called correctly" ); |
197 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[0] == 0,"Song1 should be active" ); |
198 | BOOST_CHECK_MESSAGE( |
199 | p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song1)&>().get_attribute(entry_counter) == 1, |
200 | "Song1 entry not called correctly" ); |
201 | |
202 | //flags |
203 | BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == true,"PlayingPaused should be active" ); |
204 | BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(FirstSongPlaying)>() == true,"FirstSongPlaying should be active" ); |
205 | |
206 | |
207 | p.process_event(evt: next_song); |
208 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active" ); //Playing |
209 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[0] == 1,"Song2 should be active" ); |
210 | BOOST_CHECK_MESSAGE( |
211 | p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(entry_counter) == 1, |
212 | "Song2 entry not called correctly" ); |
213 | BOOST_CHECK_MESSAGE( |
214 | p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song1)&>().get_attribute(exit_counter) == 1, |
215 | "Song1 exit not called correctly" ); |
216 | BOOST_CHECK_MESSAGE( |
217 | p.get_state<Playing_type&>().get_attribute(start_next_song_counter) == 0, |
218 | "submachine action not called correctly" ); |
219 | |
220 | p.process_event(evt: next_song); |
221 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active" ); //Playing |
222 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[0] == 2,"Song3 should be active" ); |
223 | BOOST_CHECK_MESSAGE( |
224 | p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song3)&>().get_attribute(entry_counter) == 1, |
225 | "Song3 entry not called correctly" ); |
226 | BOOST_CHECK_MESSAGE( |
227 | p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(exit_counter) == 1, |
228 | "Song2 exit not called correctly" ); |
229 | BOOST_CHECK_MESSAGE( |
230 | p.get_state<Playing_type&>().get_attribute(start_next_song_counter) == 1, |
231 | "submachine action not called correctly" ); |
232 | |
233 | p.process_event(evt: previous_song); |
234 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active" ); //Playing |
235 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[0] == 1,"Song2 should be active" ); |
236 | BOOST_CHECK_MESSAGE( |
237 | p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(entry_counter) == 2, |
238 | "Song2 entry not called correctly" ); |
239 | BOOST_CHECK_MESSAGE( |
240 | p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song3)&>().get_attribute(exit_counter) == 1, |
241 | "Song3 exit not called correctly" ); |
242 | BOOST_CHECK_MESSAGE( |
243 | p.get_state<Playing_type&>().get_attribute(start_prev_song_guard_counter) == 1, |
244 | "submachine guard not called correctly" ); |
245 | //flags |
246 | BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == true,"PlayingPaused should be active" ); |
247 | BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(FirstSongPlaying)>() == false,"FirstSongPlaying should not be active" ); |
248 | |
249 | p.process_event(evt: pause()); |
250 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active" ); //Paused |
251 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 1,"Playing exit not called correctly" ); |
252 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1, |
253 | "Paused entry not called correctly" ); |
254 | //flags |
255 | BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == true,"PlayingPaused should be active" ); |
256 | |
257 | // go back to Playing |
258 | p.process_event(evt: end_pause); |
259 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active" ); //Playing |
260 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1, |
261 | "Paused exit not called correctly" ); |
262 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(entry_counter) == 2,"Playing entry not called correctly" ); |
263 | |
264 | p.process_event(evt: pause); |
265 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active" ); //Paused |
266 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly" ); |
267 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2, |
268 | "Paused entry not called correctly" ); |
269 | |
270 | p.process_event(evt: stop); |
271 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active" ); //Stopped |
272 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2, |
273 | "Paused exit not called correctly" ); |
274 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2, |
275 | "Stopped entry not called correctly" ); |
276 | //flags |
277 | BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == false,"PlayingPaused should not be active" ); |
278 | BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(CDLoaded)>() == true,"CDLoaded should be active" ); |
279 | //BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(CDLoaded),player::Flag_AND>() == false,"CDLoaded with AND should not be active"); |
280 | |
281 | p.process_event(evt: stop); |
282 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active" ); //Stopped |
283 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2, |
284 | "Stopped exit not called correctly" ); |
285 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3, |
286 | "Stopped entry not called correctly" ); |
287 | |
288 | //test interrupt |
289 | BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active" ); //AllOk |
290 | p.process_event(evt: error_found); |
291 | BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active" ); //ErrorMode |
292 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(exit_counter) == 1, |
293 | "AllOk exit not called correctly" ); |
294 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(ErrorMode)&>().get_attribute(entry_counter) == 1, |
295 | "ErrorMode entry not called correctly" ); |
296 | |
297 | // try generating more events |
298 | p.process_event(evt: play); |
299 | BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active" ); //ErrorMode |
300 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(exit_counter) == 1, |
301 | "AllOk exit not called correctly" ); |
302 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(ErrorMode)&>().get_attribute(entry_counter) == 1, |
303 | "ErrorMode entry not called correctly" ); |
304 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active" ); //Stopped |
305 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2, |
306 | "Stopped exit not called correctly" ); |
307 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3, |
308 | "Stopped entry not called correctly" ); |
309 | |
310 | p.process_event(evt: end_error); |
311 | BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active" ); //AllOk |
312 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(ErrorMode)&>().get_attribute(exit_counter) == 1, |
313 | "ErrorMode exit not called correctly" ); |
314 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(entry_counter) == 2, |
315 | "AllOk entry not called correctly" ); |
316 | |
317 | p.process_event(evt: play); |
318 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active" ); //Playing |
319 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 3, |
320 | "Stopped exit not called correctly" ); |
321 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(entry_counter) == 3,"Playing entry not called correctly" ); |
322 | |
323 | //test terminate |
324 | BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active" ); //AllOk |
325 | p.process_event(evt: do_terminate); |
326 | BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active" ); //ErrorTerminate |
327 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(exit_counter) == 2, |
328 | "AllOk exit not called correctly" ); |
329 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(ErrorTerminate)&>().get_attribute(entry_counter) == 1, |
330 | "ErrorTerminate entry not called correctly" ); |
331 | |
332 | // try generating more events |
333 | p.process_event(evt: stop); |
334 | BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active" ); //ErrorTerminate |
335 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(ErrorTerminate)&>().get_attribute(exit_counter) == 0, |
336 | "ErrorTerminate exit not called correctly" ); |
337 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active" ); //Playing |
338 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly" ); |
339 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3, |
340 | "Stopped entry not called correctly" ); |
341 | |
342 | p.process_event(evt: end_error()); |
343 | BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active" ); //ErrorTerminate |
344 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active" ); //Playing |
345 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly" ); |
346 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3, |
347 | "Stopped entry not called correctly" ); |
348 | |
349 | p.process_event(evt: stop()); |
350 | BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active" ); //ErrorTerminate |
351 | BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active" ); //Playing |
352 | BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly" ); |
353 | BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3, |
354 | "Stopped entry not called correctly" ); |
355 | |
356 | } |
357 | } |
358 | |
359 | |