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
;
11 using namespace msm::front::euml
;
13 // entry/exit/action/guard logging functors
14 #include "logging_functors.h"
19 struct play_impl
: msm::front::euml::euml_event
<play_impl
> {};
20 struct end_pause_impl
: msm::front::euml::euml_event
<end_pause_impl
>{};
21 struct stop_impl
: msm::front::euml::euml_event
<stop_impl
>{};
22 struct pause_impl
: msm::front::euml::euml_event
<pause_impl
>{};
23 struct open_close_impl
: msm::front::euml::euml_event
<open_close_impl
>{};
24 struct cd_detected_impl
: msm::front::euml::euml_event
<cd_detected_impl
>{};
26 // define some dummy instances for use in the transition table
27 // it is also possible to default-construct them instead:
29 // inside the table: play()
31 end_pause_impl end_pause
;
34 open_close_impl open_close
;
35 cd_detected_impl cd_detected
;
37 // The list of FSM states
38 // they have to be declared outside of the front-end only to make VC happy :(
39 // note: gcc would have no problem
40 struct Empty_impl
: public msm::front::state
<> , public msm::front::euml::euml_state
<Empty_impl
>
42 // every (optional) entry/exit methods get the event passed.
43 template <class Event
,class FSM
>
44 void on_entry(Event
const&,FSM
& ) {std::cout
<< "entering: Empty" << std::endl
;}
45 template <class Event
,class FSM
>
46 void on_exit(Event
const&,FSM
& ) {std::cout
<< "leaving: Empty" << std::endl
;}
48 struct Open_impl
: public msm::front::state
<> , public msm::front::euml::euml_state
<Open_impl
>
50 template <class Event
,class FSM
>
51 void on_entry(Event
const& ,FSM
&) {std::cout
<< "entering: Open" << std::endl
;}
52 template <class Event
,class FSM
>
53 void on_exit(Event
const&,FSM
& ) {std::cout
<< "leaving: Open" << std::endl
;}
56 struct Stopped_impl
: public msm::front::state
<> , public msm::front::euml::euml_state
<Stopped_impl
>
58 template <class Event
,class FSM
>
59 void on_entry(Event
const& ,FSM
&) {std::cout
<< "entering: Stopped" << std::endl
;}
60 template <class Event
,class FSM
>
61 void on_exit(Event
const&,FSM
& ) {std::cout
<< "leaving: Stopped" << std::endl
;}
64 struct Playing_impl
: public msm::front::state
<> , public msm::front::euml::euml_state
<Playing_impl
>
66 template <class Event
,class FSM
>
67 void on_entry(Event
const&,FSM
& ) {std::cout
<< "entering: Playing" << std::endl
;}
68 template <class Event
,class FSM
>
69 void on_exit(Event
const&,FSM
& ) {std::cout
<< "leaving: Playing" << std::endl
;}
72 // state not defining any entry or exit
73 struct Paused_impl
: public msm::front::state
<> , public msm::front::euml::euml_state
<Paused_impl
>
76 //to make the transition table more readable
77 Empty_impl
const Empty
;
79 Stopped_impl
const Stopped
;
80 Playing_impl
const Playing
;
81 Paused_impl
const Paused
;
83 BOOST_MSM_EUML_ACTION(pause_playback2
)
85 template <class FSM
,class EVT
,class SourceState
,class TargetState
>
86 void operator()(EVT
const& evt
,FSM
&,SourceState
& ,TargetState
& )
88 cout
<< "player::pause_playback2" << endl
;
89 std::cout
<< "event type: " << typeid(EVT
).name() << std::endl
;
90 std::cout
<< "pause_playback2 with any event: " << evt
.type().name() << std::endl
;
93 // front-end: define the FSM structure
94 struct player_
: public msm::front::state_machine_def
<player_
>
97 // the initial state of the player SM. Must be defined
98 typedef Empty_impl initial_state
;
100 // Transition table for player
101 // replaces the old transition table
102 BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
103 Stopped
+ play
/ start_playback
== Playing
,
104 Stopped
+ open_close
/ open_drawer
== Open
,
105 Stopped
+ stop
== Stopped
,
106 // +------------------------------------------------------------------------------+
107 Open
+ open_close
/ close_drawer
== Empty
,
108 // +------------------------------------------------------------------------------+
109 Empty
+ open_close
/ open_drawer
== Open
,
110 Empty
+ cd_detected
/(store_cd_info
,
111 msm::front::euml::process_(play
)) == Stopped
,
112 // +------------------------------------------------------------------------------+
113 Playing
+ stop
/ stop_playback
== Stopped
,
114 Playing
+ kleene
/ pause_playback2
== Paused
,
115 Playing
+ open_close
/ stop_and_open
== Open
,
116 // +------------------------------------------------------------------------------+
117 Paused
+ end_pause
/ resume_playback
== Playing
,
118 Paused
+ stop
/ stop_playback
== Stopped
,
119 Paused
+ open_close
/ stop_and_open
== Open
120 // +------------------------------------------------------------------------------+
123 // Replaces the default no-transition response.
124 template <class FSM
,class Event
>
125 void no_transition(Event
const& e
, FSM
&,int state
)
127 std::cout
<< "no transition from state " << state
128 << " on event " << typeid(e
).name() << std::endl
;
132 typedef msm::back::state_machine
<player_
> player
;
135 // Testing utilities.
137 static char const* const state_names
[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
138 void pstate(player
const& p
)
140 std::cout
<< " -> " << state_names
[p
.current_state()[0]] << std::endl
;
146 // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
148 // go to Open, call on_exit on Empty, then action, then on_entry on Open
149 p
.process_event(open_close
); pstate(p
);
150 p
.process_event(open_close
); pstate(p
);
151 p
.process_event(cd_detected
); pstate(p
);
153 // at this point, Play is active
154 p
.process_event(pause
); pstate(p
);
155 // go back to Playing
156 p
.process_event(end_pause
); pstate(p
);
157 p
.process_event(pause
); pstate(p
);
158 p
.process_event(stop
); pstate(p
);
159 // event leading to the same state
160 // no action method called as it is not present in the transition table
161 p
.process_event(stop
); pstate(p
);