]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/msm/doc/HTML/examples/EumlInternalDistributed.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / msm / doc / HTML / examples / EumlInternalDistributed.cpp
CommitLineData
7c673cae
FG
1// Copyright 2010 Christophe Henry
2// henry UNDERSCORE christophe AT hotmail DOT com
3// This is an extended version of the state machine available in the boost::mpl library
4// Distributed under the same license as the original.
5// Copyright for the original version:
6// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
7// under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10
11#include <vector>
12#include <iostream>
13
14#include <boost/msm/back/state_machine.hpp>
15#include <boost/msm/front/euml/euml.hpp>
16
17using namespace std;
18using namespace boost::msm::front::euml;
19using namespace boost::msm::front;
20namespace msm = boost::msm;
21
22// entry/exit/action/guard logging functors
23#include "logging_functors.h"
24
25namespace // Concrete FSM implementation
26{
27 // events
28 // note that unlike the SimpleTutorial, events must derive from euml_event.
29 BOOST_MSM_EUML_EVENT(play)
30 BOOST_MSM_EUML_EVENT(end_pause)
31 BOOST_MSM_EUML_EVENT(stop)
32 BOOST_MSM_EUML_EVENT(pause)
33 BOOST_MSM_EUML_EVENT(open_close)
34 BOOST_MSM_EUML_EVENT(internal_event)
35 BOOST_MSM_EUML_EVENT(next_song)
36 BOOST_MSM_EUML_EVENT(previous_song)
37
38 // A "complicated" event type that carries some data.
39 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,cd_name)
40 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(DiskTypeEnum,cd_type)
41 BOOST_MSM_EUML_ATTRIBUTES((attributes_ << cd_name << cd_type ), cd_detected_attributes)
42 BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(cd_detected,cd_detected_attributes)
43
44 // Concrete FSM implementation
45
46 // The list of FSM states
47 BOOST_MSM_EUML_STATE(( Empty_Entry,Empty_Exit ),Empty)
48
49 // we just declare a state type but do not create any instance as we want to inherit from this type
50 BOOST_MSM_EUML_DECLARE_STATE((Open_Entry,Open_Exit),Open_def)
51 // derive to be able to add an internal transition table
52 struct Open_impl : public Open_def
53 {
54 BOOST_MSM_EUML_DECLARE_INTERNAL_TRANSITION_TABLE((
55 open_close [internal_guard1] / internal_action1 ,
56 open_close [internal_guard2] / internal_action2 ,
57 internal_event / internal_action
58 ))
59 };
60 // declare an instance for the stt as we are manually declaring a state
61 Open_impl const Open;
62 BOOST_MSM_EUML_STATE(( Stopped_Entry,Stopped_Exit ),Stopped)
63
64 // Playing is a state machine itself.
65 // It has 3 substates
66 BOOST_MSM_EUML_STATE(( Song1_Entry,Song1_Exit ),Song1)
67 BOOST_MSM_EUML_STATE(( Song2_Entry,Song2_Exit ),Song2)
68 BOOST_MSM_EUML_STATE(( Song3_Entry,Song3_Exit ),Song3)
69
70 // Playing has a transition table
71 BOOST_MSM_EUML_TRANSITION_TABLE((
72 // +------------------------------------------------------------------------------+
73 Song2 == Song1 + next_song / start_next_song,
74 Song1 == Song2 + previous_song / start_prev_song,
75 Song3 == Song2 + next_song / start_next_song,
76 Song2 == Song3 + previous_song / start_prev_song
77 // +------------------------------------------------------------------------------+
78 ),playing_transition_table )
79
80 BOOST_MSM_EUML_DECLARE_STATE_MACHINE( (playing_transition_table, //STT
81 init_ << Song1 // Init State
82 ),Playing_def)
83
84 // some action for the internal transition
85 BOOST_MSM_EUML_ACTION(playing_internal_action)
86 {
87 template <class FSM,class EVT,class SourceState,class TargetState>
88 void operator()(EVT const&, FSM& ,SourceState& ,TargetState& )
89 {
90 cout << "Playing::internal action" << endl;
91 }
92 };
93 // derive to be able to add an internal transition table
94 struct Playing_ : public Playing_def
95 {
96 BOOST_MSM_EUML_DECLARE_INTERNAL_TRANSITION_TABLE((
97 internal_event / playing_internal_action
98 ))
99 };
100 // choice of back-end
101 typedef msm::back::state_machine<Playing_> Playing_type;
102 Playing_type const Playing;
103
104
105 // state not needing any entry or exit
106 BOOST_MSM_EUML_STATE((),Paused)
107
108 // guard conditions
109 BOOST_MSM_EUML_ACTION(good_disk_format)
110 {
111 template <class FSM,class EVT,class SourceState,class TargetState>
112 bool operator()(EVT const& evt,FSM&,SourceState& ,TargetState& )
113 {
114 // to test a guard condition, let's say we understand only CDs, not DVD
115 if (evt.get_attribute(cd_type)!=DISK_CD)
116 {
117 std::cout << "wrong disk, sorry" << std::endl;
118 // just for logging, does not block any transition
119 return true;
120 }
121 std::cout << "good disk" << std::endl;
122 return true;
123 }
124 };
125 // replaces the old transition table
126 BOOST_MSM_EUML_TRANSITION_TABLE((
127 Stopped + play / start_playback == Playing ,
128 Stopped + open_close / open_drawer == Open ,
129 Stopped + stop == Stopped ,
130 // +------------------------------------------------------------------------------+
131 Open + open_close / close_drawer == Empty ,
132 // +------------------------------------------------------------------------------+
133 Empty + open_close / open_drawer == Open ,
134 Empty + cd_detected
135 [good_disk_format&&(event_(cd_type)==Int_<DISK_CD>())]
136 / (store_cd_info,process_(play))
137 == Stopped ,
138 // +------------------------------------------------------------------------------+
139 Playing + stop / stop_playback == Stopped ,
140 Playing + pause / pause_playback == Paused ,
141 Playing + open_close / stop_and_open == Open ,
142 // +------------------------------------------------------------------------------+
143 Paused + end_pause / resume_playback == Playing ,
144 Paused + stop / stop_playback == Stopped ,
145 Paused + open_close / stop_and_open == Open
146 // +------------------------------------------------------------------------------+
147 ),transition_table)
148
149
150
151 // create a state machine "on the fly"
152 BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT
153 init_ << Empty, // Init State
154 no_action, // Entry
155 no_action, // Exit
156 attributes_ << no_attributes_, // Attributes
157 configure_ << no_configure_, // configuration
158 Log_No_Transition // no_transition handler
159 ),
160 player_) //fsm name
161
162 // choice of back-end
163 typedef msm::back::state_machine<player_> player;
164
165 //
166 // Testing utilities.
167 //
168 static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
169 void pstate(player const& p)
170 {
171 std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
172 }
173
174 void test()
175 {
176 player p;
177 // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
178 p.start();
179 // go to Open, call on_exit on Empty, then action, then on_entry on Open
180 p.process_event(open_close); pstate(p);
181 std::cout << "sending internal event (not rejected)" << std::endl;
182 p.process_event(internal_event);
183 std::cout << "sending open_close event. Conflict with internal transitions (rejecting event)" << std::endl;
184 p.process_event(open_close); pstate(p);
185 // will be rejected, wrong disk type
186 p.process_event(
187 cd_detected("louie, louie",DISK_DVD)); pstate(p);
188 p.process_event(
189 cd_detected("louie, louie",DISK_CD)); pstate(p);
190 // no need to call play as the previous event does it in its action method
191 //p.process_event(play);
192 // at this point, Play is active
193 // make transition happen inside it. Player has no idea about this event but it's ok.
194 p.process_event(next_song);pstate(p); //2nd song active
195 p.process_event(next_song);pstate(p);//3rd song active
196 p.process_event(previous_song);pstate(p);//2nd song active
197 // event handled internally in Playing, without region checking
198 std::cout << "sending internal event (not rejected)" << std::endl;
199 p.process_event(internal_event);
200
201 p.process_event(pause); pstate(p);
202 // go back to Playing
203 p.process_event(end_pause); pstate(p);
204 p.process_event(pause); pstate(p);
205 p.process_event(stop); pstate(p);
206 // event leading to the same state
207 // no action method called as none is defined in the transition table
208 p.process_event(stop); pstate(p);
209 // test call to no_transition
210 p.process_event(pause); pstate(p);
211 }
212}
213
214int main()
215{
216 test();
217 return 0;
218}