• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <iostream>
2 // back-end
3 #include <boost/msm/back/state_machine.hpp>
4 //front-end
5 #include <boost/msm/front/state_machine_def.hpp>
6 #include <boost/msm/front/euml/euml.hpp>
7 
8 namespace msm = boost::msm;
9 namespace mpl = boost::mpl;
10 using namespace std;
11 
12 // entry/exit/action/guard logging functors
13 #include "logging_functors.h"
14 
15 namespace
16 {
17     // events
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>{};
24 
25     // define some dummy instances for use in the transition table
26     // it is also possible to default-construct them instead:
27     // struct play {};
28     // inside the table: play()
29     play_impl play;
30     end_pause_impl end_pause;
31     stop_impl stop;
32     pause_impl pause;
33     open_close_impl open_close;
34     cd_detected_impl cd_detected;
35 
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>
40     {
41         // every (optional) entry/exit methods get the event passed.
42         template <class Event,class FSM>
on_entry__anonaf3cad4a0111::Empty_impl43         void on_entry(Event const&,FSM& ) {std::cout << "entering: Empty" << std::endl;}
44         template <class Event,class FSM>
on_exit__anonaf3cad4a0111::Empty_impl45         void on_exit(Event const&,FSM& ) {std::cout << "leaving: Empty" << std::endl;}
46     };
47     struct Open_impl : public msm::front::state<> , public msm::front::euml::euml_state<Open_impl>
48     {
49         template <class Event,class FSM>
on_entry__anonaf3cad4a0111::Open_impl50         void on_entry(Event const& ,FSM&) {std::cout << "entering: Open" << std::endl;}
51         template <class Event,class FSM>
on_exit__anonaf3cad4a0111::Open_impl52         void on_exit(Event const&,FSM& ) {std::cout << "leaving: Open" << std::endl;}
53     };
54 
55     struct Stopped_impl : public msm::front::state<> , public msm::front::euml::euml_state<Stopped_impl>
56     {
57         template <class Event,class FSM>
on_entry__anonaf3cad4a0111::Stopped_impl58         void on_entry(Event const& ,FSM&) {std::cout << "entering: Stopped" << std::endl;}
59         template <class Event,class FSM>
on_exit__anonaf3cad4a0111::Stopped_impl60         void on_exit(Event const&,FSM& ) {std::cout << "leaving: Stopped" << std::endl;}
61     };
62 
63     struct Playing_impl : public msm::front::state<> , public msm::front::euml::euml_state<Playing_impl>
64     {
65         template <class Event,class FSM>
on_entry__anonaf3cad4a0111::Playing_impl66         void on_entry(Event const&,FSM& ) {std::cout << "entering: Playing" << std::endl;}
67         template <class Event,class FSM>
on_exit__anonaf3cad4a0111::Playing_impl68         void on_exit(Event const&,FSM& ) {std::cout << "leaving: Playing" << std::endl;}
69     };
70 
71     // state not defining any entry or exit
72     struct Paused_impl : public msm::front::state<> , public msm::front::euml::euml_state<Paused_impl>
73     {
74     };
75     //to make the transition table more readable
76     Empty_impl const Empty;
77     Open_impl const Open;
78     Stopped_impl const Stopped;
79     Playing_impl const Playing;
80     Paused_impl const Paused;
81 
82     // front-end: define the FSM structure
83     struct player_ : public msm::front::state_machine_def<player_>
84     {
85 
86         // the initial state of the player SM. Must be defined
87         typedef Empty_impl initial_state;
88 
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           //  +------------------------------------------------------------------------------+
110           ),transition_table)
111 
112         // Replaces the default no-transition response.
113         template <class FSM,class Event>
no_transition__anonaf3cad4a0111::player_114         void no_transition(Event const& e, FSM&,int state)
115         {
116             std::cout << "no transition from state " << state
117                 << " on event " << typeid(e).name() << std::endl;
118         }
119     };
120     // Pick a back-end
121     typedef msm::back::state_machine<player_> player;
122 
123     //
124     // Testing utilities.
125     //
126     static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
pstate(player const & p)127     void pstate(player const& p)
128     {
129         std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
130     }
131 
test()132     void test()
133     {
134 		player p;
135         // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
136         p.start();
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);
141 
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);
151     }
152 }
153 
main()154 int main()
155 {
156     test();
157     return 0;
158 }
159