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