]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/test/SimpleEuml.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / msm / test / SimpleEuml.cpp
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 <iostream>
12 #include <boost/msm/back/state_machine.hpp>
13 #include <boost/msm/front/euml/euml.hpp>
14
15 #ifndef BOOST_MSM_NONSTANDALONE_TEST
16 #define BOOST_TEST_MODULE MyTest
17 #endif
18 #include <boost/test/unit_test.hpp>
19
20 using namespace std;
21 using namespace boost::msm::front::euml;
22 namespace msm = boost::msm;
23
24 namespace
25 {
26 // A "complicated" event type that carries some data.
27 enum DiskTypeEnum
28 {
29 DISK_CD=0,
30 DISK_DVD=1
31 };
32 // events
33 BOOST_MSM_EUML_EVENT(play)
34 BOOST_MSM_EUML_EVENT(end_pause)
35 BOOST_MSM_EUML_EVENT(stop)
36 BOOST_MSM_EUML_EVENT(pause)
37 BOOST_MSM_EUML_EVENT(open_close)
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 //states
45 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,entry_counter)
46 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,exit_counter)
47
48 BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Empty)
49 BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Open)
50 BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Stopped)
51 BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Playing)
52 BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Paused)
53
54 //fsm
55 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_playback_counter)
56 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,can_close_drawer_counter)
57 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,test_fct_counter)
58 BOOST_MSM_EUML_ACTION(No_Transition)
59 {
60 template <class FSM,class Event>
61 void operator()(Event const&,FSM&,int)
62 {
63 BOOST_FAIL("no_transition called!");
64 }
65 };
66 BOOST_MSM_EUML_ACTION(good_disk_format)
67 {
68 template <class FSM,class EVT,class SourceState,class TargetState>
69 bool operator()(EVT const& evt,FSM&,SourceState& ,TargetState& )
70 {
71 if (evt.get_attribute(cd_type)!=DISK_CD)
72 {
73 return false;
74 }
75 return true;
76 }
77 };
78 BOOST_MSM_EUML_TRANSITION_TABLE((
79 Playing == Stopped + play / (++fsm_(start_playback_counter),++fsm_(test_fct_counter) ),
80 Playing == Paused + end_pause ,
81 // +------------------------------------------------------------------------------+
82 Empty == Open + open_close / ++fsm_(can_close_drawer_counter),
83 // +------------------------------------------------------------------------------+
84 Open == Empty + open_close ,
85 Open == Paused + open_close ,
86 Open == Stopped + open_close ,
87 Open == Playing + open_close ,
88 // +------------------------------------------------------------------------------+
89 Paused == Playing + pause ,
90 // +------------------------------------------------------------------------------+
91 Stopped == Playing + stop ,
92 Stopped == Paused + stop ,
93 Stopped == Empty + cd_detected [good_disk_format ||
94 (event_(cd_type)==Int_<DISK_CD>())] / process_(play) ,
95 Stopped == Stopped + stop
96 // +------------------------------------------------------------------------------+
97 ),transition_table)
98
99 BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT
100 init_ << Empty, // Init State
101 no_action, // Entry
102 no_action, // Exit
103 attributes_ << start_playback_counter
104 << can_close_drawer_counter << test_fct_counter, // Attributes
105 configure_ << no_configure_, // configuration
106 No_Transition // no_transition handler
107 ),
108 player_) //fsm name
109
110 typedef msm::back::state_machine<player_> player;
111
112 // static char const* const state_names[] = { "Stopped", "Paused", "Open", "Empty", "Playing" };
113
114
115 BOOST_AUTO_TEST_CASE( my_test )
116 {
117 player p;
118
119 p.start();
120 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1,
121 "Empty entry not called correctly");
122
123 p.process_event(open_close());
124 BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Open should be active"); //Open
125 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1,
126 "Empty exit not called correctly");
127 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1,
128 "Open entry not called correctly");
129
130 p.process_event(open_close());
131 BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
132 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
133 "Open exit not called correctly");
134 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
135 "Empty entry not called correctly");
136 BOOST_CHECK_MESSAGE(p.get_attribute(can_close_drawer_counter) == 1,"guard not called correctly");
137
138 p.process_event(
139 cd_detected("louie, louie",DISK_DVD));
140 BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
141 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
142 "Open exit not called correctly");
143 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
144 "Empty entry not called correctly");
145
146 p.process_event(
147 cd_detected("louie, louie",DISK_CD));
148 BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
149 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 2,
150 "Empty exit not called correctly");
151 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
152 "Stopped entry not called correctly");
153 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
154 "Stopped exit not called correctly");
155 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 1,
156 "Playing entry not called correctly");
157 BOOST_CHECK_MESSAGE(p.get_attribute(start_playback_counter) == 1,"action not called correctly");
158 BOOST_CHECK_MESSAGE(p.get_attribute(test_fct_counter) == 1,"action not called correctly");
159
160 p.process_event(pause());
161 BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
162 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 1,
163 "Playing exit not called correctly");
164 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
165 "Paused entry not called correctly");
166
167 // go back to Playing
168 p.process_event(end_pause());
169 BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
170 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
171 "Paused exit not called correctly");
172 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 2,
173 "Playing entry not called correctly");
174
175 p.process_event(pause());
176 BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
177 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 2,
178 "Playing exit not called correctly");
179 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
180 "Paused entry not called correctly");
181
182 p.process_event(stop());
183 BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
184 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
185 "Paused exit not called correctly");
186 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
187 "Stopped entry not called correctly");
188
189 p.process_event(stop());
190 BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
191 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
192 "Stopped exit not called correctly");
193 BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
194 "Stopped entry not called correctly");
195 }
196 }
197