]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/doc/PDF/examples/CompositeTutorialWithEumlTable.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / msm / doc / PDF / examples / CompositeTutorialWithEumlTable.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 struct next_song_impl : msm::front::euml::euml_event<next_song_impl>{};
25 struct previous_song_impl : msm::front::euml::euml_event<previous_song_impl>{};
26
27 // define some dummy instances for use in the transition table
28 // it is also possible to default-construct them instead:
29 // struct play {};
30 // inside the table: play()
31 play_impl play;
32 end_pause_impl end_pause;
33 stop_impl stop;
34 pause_impl pause;
35 open_close_impl open_close;
36 cd_detected_impl cd_detected;
37 next_song_impl next_song;
38 previous_song_impl previous_song;
39
40 // The list of FSM states
41 // they have to be declared outside of the front-end only to make VC happy :(
42 // note: gcc would have no problem
43 struct Empty_impl : public msm::front::state<> , public msm::front::euml::euml_state<Empty_impl>
44 {
45 // every (optional) entry/exit methods get the event passed.
46 template <class Event,class FSM>
47 void on_entry(Event const&,FSM& ) {std::cout << "entering: Empty" << std::endl;}
48 template <class Event,class FSM>
49 void on_exit(Event const&,FSM& ) {std::cout << "leaving: Empty" << std::endl;}
50 };
51 struct Open_impl : public msm::front::state<> , public msm::front::euml::euml_state<Open_impl>
52 {
53 template <class Event,class FSM>
54 void on_entry(Event const& ,FSM&) {std::cout << "entering: Open" << std::endl;}
55 template <class Event,class FSM>
56 void on_exit(Event const&,FSM& ) {std::cout << "leaving: Open" << std::endl;}
57 };
58
59 struct Stopped_impl : public msm::front::state<> , public msm::front::euml::euml_state<Stopped_impl>
60 {
61 template <class Event,class FSM>
62 void on_entry(Event const& ,FSM&) {std::cout << "entering: Stopped" << std::endl;}
63 template <class Event,class FSM>
64 void on_exit(Event const&,FSM& ) {std::cout << "leaving: Stopped" << std::endl;}
65 };
66
67 // Playing Submachine front-end
68 struct Playing_ : public msm::front::state_machine_def<Playing_>
69 {
70 template <class Event,class FSM>
71 void on_entry(Event const& ,FSM&) {std::cout << "entering: Playing" << std::endl;}
72 template <class Event,class FSM>
73 void on_exit(Event const&,FSM& ) {std::cout << "leaving: Playing" << std::endl;}
74
75 struct Song1_ : public msm::front::state<> , public msm::front::euml::euml_state<Song1_>
76 {
77 template <class Event,class FSM>
78 void on_entry(Event const& ,FSM&) {std::cout << "entering: Song1" << std::endl;}
79 template <class Event,class FSM>
80 void on_exit(Event const&,FSM& ) {std::cout << "leaving: Song1" << std::endl;}
81 };
82 struct Song2_ : public msm::front::state<> , public msm::front::euml::euml_state<Song2_>
83 {
84 template <class Event,class FSM>
85 void on_entry(Event const& ,FSM&) {std::cout << "entering: Song2" << std::endl;}
86 template <class Event,class FSM>
87 void on_exit(Event const&,FSM& ) {std::cout << "leaving: Song2" << std::endl;}
88 };
89 struct Song3_ : public msm::front::state<> , public msm::front::euml::euml_state<Song3_>
90 {
91 template <class Event,class FSM>
92 void on_entry(Event const& ,FSM&) {std::cout << "entering: Song3" << std::endl;}
93 template <class Event,class FSM>
94 void on_exit(Event const&,FSM& ) {std::cout << "leaving: Song3" << std::endl;}
95 };
96 // to make the transition table more readable
97 // VC seems to need them static
98 static Song1_ Song1;
99 static Song2_ Song2;
100 static Song3_ Song3;
101 typedef Song1_ initial_state;
102
103 // Playing has a transition table
104 BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
105 // +------------------------------------------------------------------------------+
106 Song2 == Song1 + next_song / start_next_song,
107 Song1 == Song2 + previous_song / start_prev_song,
108 Song3 == Song2 + next_song / start_next_song,
109 Song2 == Song3 + previous_song / start_prev_song
110 // +------------------------------------------------------------------------------+
111 ),transition_table )
112
113 };
114 // Playing Submachine back-end
115 typedef boost::msm::back::state_machine<Playing_> Playing_impl;
116
117 // state not defining any entry or exit
118 struct Paused_impl : public msm::front::state<> , public msm::front::euml::euml_state<Paused_impl>
119 {
120 };
121 //to make the transition table more readable
122 Empty_impl const Empty;
123 Open_impl const Open;
124 Stopped_impl const Stopped;
125 Playing_impl const Playing;
126 Paused_impl const Paused;
127
128 // front-end: define the FSM structure
129 struct player_ : public msm::front::state_machine_def<player_>
130 {
131
132 // the initial state of the player SM. Must be defined
133 typedef Empty_impl initial_state;
134
135 // Transition table for player
136 // replaces the old transition table
137 BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
138 Stopped + play / start_playback == Playing ,
139 Stopped + open_close / open_drawer == Open ,
140 Stopped + stop == Stopped ,
141 // +------------------------------------------------------------------------------+
142 Open + open_close / close_drawer == Empty ,
143 // +------------------------------------------------------------------------------+
144 Empty + open_close / open_drawer == Open ,
145 Empty + cd_detected /(store_cd_info,
146 msm::front::euml::process_(play)) == Stopped ,
147 // +------------------------------------------------------------------------------+
148 Playing + stop / stop_playback == Stopped ,
149 Playing + pause / pause_playback == Paused ,
150 Playing + open_close / stop_and_open == Open ,
151 // +------------------------------------------------------------------------------+
152 Paused + end_pause / resume_playback == Playing ,
153 Paused + stop / stop_playback == Stopped ,
154 Paused + open_close / stop_and_open == Open
155 // +------------------------------------------------------------------------------+
156 ),transition_table)
157
158 // Replaces the default no-transition response.
159 template <class FSM,class Event>
160 void no_transition(Event const& e, FSM&,int state)
161 {
162 std::cout << "no transition from state " << state
163 << " on event " << typeid(e).name() << std::endl;
164 }
165 };
166 // Pick a back-end
167 typedef msm::back::state_machine<player_> player;
168
169 //
170 // Testing utilities.
171 //
172 static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
173 void pstate(player const& p)
174 {
175 std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
176 }
177
178 void test()
179 {
180 player p;
181 // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
182 p.start();
183 // go to Open, call on_exit on Empty, then action, then on_entry on Open
184 p.process_event(open_close); pstate(p);
185 p.process_event(open_close); pstate(p);
186 p.process_event(cd_detected); pstate(p);
187
188 // at this point, Play is active
189 // make transition happen inside it. Player has no idea about this event but it's ok.
190 p.process_event(next_song);pstate(p); //2nd song active
191 p.process_event(next_song);pstate(p);//3rd song active
192 p.process_event(previous_song);pstate(p);//2nd song active
193
194 p.process_event(pause); pstate(p);
195 // go back to Playing
196 p.process_event(end_pause); pstate(p);
197 p.process_event(pause); pstate(p);
198 p.process_event(stop); pstate(p);
199 // event leading to the same state
200 // no action method called as it is not present in the transition table
201 p.process_event(stop); pstate(p);
202 }
203 }
204
205 int main()
206 {
207 test();
208 return 0;
209 }