]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/doc/PDF/examples/SimpleTutorialWithEumlTable.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / msm / doc / PDF / examples / SimpleTutorialWithEumlTable.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
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>
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;}
46 };
47 struct Open_impl : public msm::front::state<> , public msm::front::euml::euml_state<Open_impl>
48 {
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;}
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>
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;}
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>
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;}
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>
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" };
127 void pstate(player const& p)
128 {
129 std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
130 }
131
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
154 int main()
155 {
156 test();
157 return 0;
158 }