3 #include <boost/msm/back/state_machine.hpp>
5 #include <boost/msm/front/state_machine_def.hpp>
6 #include <boost/msm/front/euml/euml.hpp>
8 namespace msm
= boost::msm
;
9 namespace mpl
= boost::mpl
;
12 // entry/exit/action/guard logging functors
13 #include "logging_functors.h"
18 struct play_impl
: msm::front::euml::euml_event
<play_impl
> {};
19 struct end_pause_impl
: msm::front::euml::euml_event
<end_pause_impl
>{};
20 struct stop_impl
: msm::front::euml::euml_event
<stop_impl
>{};
21 struct pause_impl
: msm::front::euml::euml_event
<pause_impl
>{};
22 struct open_close_impl
: msm::front::euml::euml_event
<open_close_impl
>{};
23 struct cd_detected_impl
: msm::front::euml::euml_event
<cd_detected_impl
>{};
25 // define some dummy instances for use in the transition table
26 // it is also possible to default-construct them instead:
28 // inside the table: play()
30 end_pause_impl end_pause
;
33 open_close_impl open_close
;
34 cd_detected_impl cd_detected
;
36 // The list of FSM states
37 // they have to be declared outside of the front-end only to make VC happy :(
38 // note: gcc would have no problem
39 struct Empty_impl
: public msm::front::state
<> , public msm::front::euml::euml_state
<Empty_impl
>
41 // every (optional) entry/exit methods get the event passed.
42 template <class Event
,class FSM
>
43 void on_entry(Event
const&,FSM
& ) {std::cout
<< "entering: Empty" << std::endl
;}
44 template <class Event
,class FSM
>
45 void on_exit(Event
const&,FSM
& ) {std::cout
<< "leaving: Empty" << std::endl
;}
47 struct Open_impl
: public msm::front::state
<> , public msm::front::euml::euml_state
<Open_impl
>
49 template <class Event
,class FSM
>
50 void on_entry(Event
const& ,FSM
&) {std::cout
<< "entering: Open" << std::endl
;}
51 template <class Event
,class FSM
>
52 void on_exit(Event
const&,FSM
& ) {std::cout
<< "leaving: Open" << std::endl
;}
55 struct Stopped_impl
: public msm::front::state
<> , public msm::front::euml::euml_state
<Stopped_impl
>
57 template <class Event
,class FSM
>
58 void on_entry(Event
const& ,FSM
&) {std::cout
<< "entering: Stopped" << std::endl
;}
59 template <class Event
,class FSM
>
60 void on_exit(Event
const&,FSM
& ) {std::cout
<< "leaving: Stopped" << std::endl
;}
63 struct Playing_impl
: public msm::front::state
<> , public msm::front::euml::euml_state
<Playing_impl
>
65 template <class Event
,class FSM
>
66 void on_entry(Event
const&,FSM
& ) {std::cout
<< "entering: Playing" << std::endl
;}
67 template <class Event
,class FSM
>
68 void on_exit(Event
const&,FSM
& ) {std::cout
<< "leaving: Playing" << std::endl
;}
71 // state not defining any entry or exit
72 struct Paused_impl
: public msm::front::state
<> , public msm::front::euml::euml_state
<Paused_impl
>
75 //to make the transition table more readable
76 Empty_impl
const Empty
;
78 Stopped_impl
const Stopped
;
79 Playing_impl
const Playing
;
80 Paused_impl
const Paused
;
82 // front-end: define the FSM structure
83 struct player_
: public msm::front::state_machine_def
<player_
>
86 // the initial state of the player SM. Must be defined
87 typedef Empty_impl initial_state
;
89 // Transition table for player
90 // replaces the old transition table
91 BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
92 Stopped
+ play
/ start_playback
== Playing
,
93 Stopped
+ open_close
/ open_drawer
== Open
,
94 Stopped
+ stop
== Stopped
,
95 // +------------------------------------------------------------------------------+
96 Open
+ open_close
/ close_drawer
== Empty
,
97 // +------------------------------------------------------------------------------+
98 Empty
+ open_close
/ open_drawer
== Open
,
99 Empty
+ cd_detected
/(store_cd_info
,
100 msm::front::euml::process_(play
)) == Stopped
,
101 // +------------------------------------------------------------------------------+
102 Playing
+ stop
/ stop_playback
== Stopped
,
103 Playing
+ pause
/ pause_playback
== Paused
,
104 Playing
+ open_close
/ stop_and_open
== Open
,
105 // +------------------------------------------------------------------------------+
106 Paused
+ end_pause
/ resume_playback
== Playing
,
107 Paused
+ stop
/ stop_playback
== Stopped
,
108 Paused
+ open_close
/ stop_and_open
== Open
109 // +------------------------------------------------------------------------------+
112 // Replaces the default no-transition response.
113 template <class FSM
,class Event
>
114 void no_transition(Event
const& e
, FSM
&,int state
)
116 std::cout
<< "no transition from state " << state
117 << " on event " << typeid(e
).name() << std::endl
;
121 typedef msm::back::state_machine
<player_
> player
;
124 // Testing utilities.
126 static char const* const state_names
[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
127 void pstate(player
const& p
)
129 std::cout
<< " -> " << state_names
[p
.current_state()[0]] << std::endl
;
135 // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
137 // go to Open, call on_exit on Empty, then action, then on_entry on Open
138 p
.process_event(open_close
); pstate(p
);
139 p
.process_event(open_close
); pstate(p
);
140 p
.process_event(cd_detected
); pstate(p
);
142 // at this point, Play is active
143 p
.process_event(pause
); pstate(p
);
144 // go back to Playing
145 p
.process_event(end_pause
); pstate(p
);
146 p
.process_event(pause
); pstate(p
);
147 p
.process_event(stop
); pstate(p
);
148 // event leading to the same state
149 // no action method called as it is not present in the transition table
150 p
.process_event(stop
); pstate(p
);