Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / msm / doc / PDF / examples / SimpleTutorialWithEumlTableKleene.cpp
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 using namespace msm::front::euml;
12
13 // entry/exit/action/guard logging functors
14 #include "logging_functors.h"
15
16 namespace
17 {
18     // events
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>{};
25
26     // define some dummy instances for use in the transition table
27     // it is also possible to default-construct them instead:
28     // struct play {};
29     // inside the table: play()
30     play_impl play;
31     end_pause_impl end_pause;
32     stop_impl stop;
33     pause_impl pause;
34     open_close_impl open_close;
35     cd_detected_impl cd_detected;
36
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>
41     {
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;}
47     };
48     struct Open_impl : public msm::front::state<> , public msm::front::euml::euml_state<Open_impl> 
49     {    
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;}
54     };
55
56     struct Stopped_impl : public msm::front::state<> , public msm::front::euml::euml_state<Stopped_impl> 
57     {    
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;}
62     };
63
64     struct Playing_impl : public msm::front::state<> , public msm::front::euml::euml_state<Playing_impl>
65     {
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;}
70     };
71
72     // state not defining any entry or exit
73     struct Paused_impl : public msm::front::state<> , public msm::front::euml::euml_state<Paused_impl>
74     {
75     };
76     //to make the transition table more readable
77     Empty_impl const Empty;
78     Open_impl const Open;
79     Stopped_impl const Stopped;
80     Playing_impl const Playing;
81     Paused_impl const Paused;
82
83     BOOST_MSM_EUML_ACTION(pause_playback2)
84     {
85         template <class FSM,class EVT,class SourceState,class TargetState>
86         void operator()(EVT const& evt,FSM&,SourceState& ,TargetState& )
87         {
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;
91         }
92     };
93     // front-end: define the FSM structure 
94     struct player_ : public msm::front::state_machine_def<player_>
95     {
96
97         // the initial state of the player SM. Must be defined
98         typedef Empty_impl initial_state;
99
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           //  +------------------------------------------------------------------------------+
121           ),transition_table)
122
123         // Replaces the default no-transition response.
124         template <class FSM,class Event>
125         void no_transition(Event const& e, FSM&,int state)
126         {
127             std::cout << "no transition from state " << state
128                 << " on event " << typeid(e).name() << std::endl;
129         }
130     };
131     // Pick a back-end
132     typedef msm::back::state_machine<player_> player;
133
134     //
135     // Testing utilities.
136     //
137     static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
138     void pstate(player const& p)
139     {
140         std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
141     }
142
143     void test()
144     {        
145                 player p;
146         // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
147         p.start(); 
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);
152
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);
162     }
163 }
164
165 int main()
166 {
167     test();
168     return 0;
169 }