]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/doc/HTML/examples/SimpleTutorialWithEumlTableKleene.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / msm / doc / HTML / 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 }