1<html><head> 2 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 3 <title>Basic front-end</title><link rel="stylesheet" href="boostbook.css" type="text/css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.75.2"><link rel="home" href="index.html" title="Meta State Machine (MSM)"><link rel="up" href="ch03.html" title="Chapter 3. Tutorial"><link rel="prev" href="ch03.html" title="Chapter 3. Tutorial"><link rel="next" href="ch03s03.html" title="Functor front-end"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Basic front-end</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch03.html">Prev</a> </td><th width="60%" align="center">Chapter 3. Tutorial</th><td width="20%" align="right"> <a accesskey="n" href="ch03s03.html">Next</a></td></tr></table><hr></div><div class="sect1" title="Basic front-end"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e338"></a><span class="command"><strong><a name="basic-front-end"></a></strong></span>Basic front-end</h2></div></div></div><p>This is the historical front-end, inherited from the MPL book. It provides a 4 transition table made of rows of different names and functionality. Actions and 5 guards are defined as methods and referenced through a pointer in the 6 transition. This front-end provides a simple interface making easy state 7 machines easy to define, but more complex state machines a bit harder.</p><div class="sect2" title="A simple example"><div class="titlepage"><div><div><h3 class="title"><a name="d0e344"></a>A simple example</h3></div></div></div><p>Let us have a look at a state machine diagram of the founding 8 example:</p><p><span class="inlinemediaobject"><img src="../images/SimpleTutorial.jpg" width="60%"></span></p><p>We are now going to build it with MSM's basic front-end. An <a class="link" href="examples/SimpleTutorial.cpp" target="_top">implementation</a> is also 9 provided.</p></div><div class="sect2" title="Transition table"><div class="titlepage"><div><div><h3 class="title"><a name="d0e358"></a>Transition table</h3></div></div></div><p>As previously stated, MSM is based on the transition table, so let us 10 define one:</p><pre class="programlisting"> 11struct transition_table : mpl::vector< 12// Start Event Target Action Guard 13// +---------+------------+-----------+---------------------------+----------------------------+ 14a_row< Stopped , play , Playing , &player_::start_playback >, 15a_row< Stopped , open_close , Open , &player_::open_drawer >, 16 _row< Stopped , stop , Stopped >, 17// +---------+------------+-----------+---------------------------+----------------------------+ 18a_row< Open , open_close , Empty , &player_::close_drawer >, 19// +---------+------------+-----------+---------------------------+----------------------------+ 20a_row< Empty , open_close , Open , &player_::open_drawer >, 21 row< Empty , cd_detected, Stopped , &player_::store_cd_info , &player_::good_disk_format >, 22 row< Empty , cd_detected, Playing , &player_::store_cd_info , &player_::auto_start >, 23// +---------+------------+-----------+---------------------------+----------------------------+ 24a_row< Playing , stop , Stopped , &player_::stop_playback >, 25a_row< Playing , pause , Paused , &player_::pause_playback >, 26a_row< Playing , open_close , Open , &player_::stop_and_open >, 27// +---------+------------+-----------+---------------------------+----------------------------+ 28a_row< Paused , end_pause , Playing , &player_::resume_playback >, 29a_row< Paused , stop , Stopped , &player_::stop_playback >, 30a_row< Paused , open_close , Open , &player_::stop_and_open > 31// +---------+------------+-----------+---------------------------+----------------------------+ 32> {}; 33 </pre><p>You will notice that this is almost exactly our founding example. The only 34 change in the transition table is the different types of transitions (rows). 35 The founding example forces one to define an action method and offers no 36 guards. You have 4 basic row types:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><code class="code">row</code> takes 5 arguments: start state, event, target 37 state, action and guard.</p></li><li class="listitem"><p><code class="code">a_row</code> (“a” for action) allows defining only the 38 action and omit the guard condition.</p></li><li class="listitem"><p><code class="code">g_row</code> (“g” for guard) allows omitting the action 39 behavior and defining only the guard.</p></li><li class="listitem"><p><code class="code">_row</code> allows omitting action and guard.</p></li></ul></div><p>The signature for an action methods is void method_name (event 40 const&), for example:</p><pre class="programlisting">void stop_playback(stop const&)</pre><p>Action methods return nothing and take the argument as const reference. Of 41 course nothing forbids you from using the same action for several 42 events:</p><pre class="programlisting">template <class Event> void stop_playback(Eventconst&)</pre><p>Guards have as only difference the return value, which is a 43 boolean:</p><pre class="programlisting">bool good_disk_format(cd_detected const& evt)</pre><p>The transition table is actually a MPL vector (or list), which brings the 44 limitation that the default maximum size of the table is 20. If you need 45 more transitions, overriding this default behavior is necessary, so you need 46 to add before any header:</p><pre class="programlisting">#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS 47#define BOOST_MPL_LIMIT_VECTOR_SIZE 30 //or whatever you need 48#define BOOST_MPL_LIMIT_MAP_SIZE 30 //or whatever you need </pre><p>The other limitation is that the MPL types are defined only up to 50 49 entries. For the moment, the only solution to achieve more is to add headers 50 to the MPL (luckily, this is not very complicated).</p></div><div class="sect2" title="Defining states with entry/exit actions"><div class="titlepage"><div><div><h3 class="title"><a name="d0e406"></a>Defining states with entry/exit actions</h3></div></div></div><p>While states were enums in the MPL book, they now are classes, which 51 allows them to hold data, provide entry, exit behaviors and be reusable (as 52 they do not know anything about the containing state machine). To define a 53 state, inherit from the desired state type. You will mainly use simple 54 states:</p><p>struct Empty : public msm::front::state<> {};</p><p>They can optionally provide entry and exit behaviors:</p><pre class="programlisting"> 55struct Empty : public msm::front::state<> 56{ 57 template <class Event, class Fsm> 58 void on_entry(Event const&, Fsm& ) 59 {std::cout <<"entering: Empty" << std::endl;} 60 template <class Event, class Fsm> 61 void on_exit(Event const&, Fsm& ) 62 {std::cout <<"leaving: Empty" << std::endl;} 63}; 64 </pre><p>Notice how the entry and exit behaviors are templatized on the event and 65 state machine. Being generic facilitates reuse. There are more state types 66 (terminate, interrupt, pseudo states, etc.) corresponding to the UML 67 standard state types. These will be described in details in the next 68 sections.</p></div><div class="sect2" title="What do you actually do inside actions / guards?"><div class="titlepage"><div><div><h3 class="title"><a name="d0e419"></a>What do you actually do inside actions / guards?</h3></div></div></div><p>State machines define a structure and important parts of the complete 69 behavior, but not all. For example if you need to send a rocket to Alpha 70 Centauri, you can have a transition to a state "SendRocketToAlphaCentauri" 71 but no code actually sending the rocket. This is where you need actions. So 72 a simple action could be:</p><pre class="programlisting">template <class Fire> void send_rocket(Fire const&) 73{ 74 fire_rocket(); 75}</pre><p>Ok, this was simple. Now, we might want to give a direction. Let us suppose 76 this information is externally given when needed, it makes sense do use the 77 event for this:</p><pre class="programlisting">// Event 78struct Fire {Direction direction;}; 79template <class Fire> void send_rocket(Fire const& evt) 80{ 81 fire_rocket(evt.direction); 82}</pre><p>We might want to calculate the direction based not only on external data 83 but also on data accumulated during previous work. In this case, you might 84 want to have this data in the state machine itself. As transition actions 85 are members of the front-end, you can directly access the data:</p><pre class="programlisting">// Event 86struct Fire {Direction direction;}; 87//front-end definition, see down 88struct launcher_ : public msm::front::state_machine_def<launcher_>{ 89Data current_calculation; 90template <class Fire> void send_rocket(Fire const& evt) 91{ 92 fire_rocket(evt.direction, current_calculation); 93} 94... 95};</pre><p>Entry and exit actions represent a behavior common to a state, no matter 96 through which transition it is entered or left. States being reusable, it 97 might make sense to locate your data there instead of in the state machine, 98 to maximize reuse and make code more readable. Entry and exit actions have 99 access to the state data (being state members) but also to the event and 100 state machine, like transition actions. This happens through the Event and 101 Fsm template parameters:</p><pre class="programlisting">struct Launching : public msm::front::state<> 102{ 103 template <class Event, class Fsm> 104 void on_entry(Event const& evt, Fsm& fsm) 105 { 106 fire_rocket(evt.direction, fsm.current_calculation); 107 } 108};</pre><p>Exit actions are also ideal for clanup when the state becomes 109 inactive.</p><p>Another possible use of the entry action is to pass data to substates / 110 submachines. Launching is a substate containing a <code class="code">data</code> attribute:</p><pre class="programlisting">struct launcher_ : public msm::front::state_machine_def<launcher_>{ 111Data current_calculation; 112// state machines also have entry/exit actions 113template <class Event, class Fsm> 114void on_entry(Event const& evt, Fsm& fsm) 115{ 116 launcher_::Launching& s = fsm.get_state<launcher_::Launching&>(); 117 s.data = fsm.current_calculation; 118} 119... 120};</pre><p>The <span class="command"><strong><a class="command" href="ch03s05.html#backend-fsm-constructor-args">set_states</a></strong></span> back-end method allows you to replace a complete 121 state.</p><p>The <span class="command"><strong><a class="command" href="ch03s03.html#functor-front-end-actions">functor</a></strong></span> front-end and eUML offer more capabilities.</p><p>However, this basic front-end also has special capabilities using the row2 122 / irow2 transitions.<span class="command"><strong><a class="command" href="ch03s02.html#basic-row2">_row2, a_row2, row2, 123 g_row2, a_irow2, irow2, g_irow2</a></strong></span> let you call an action located 124 in any state of the current fsm or in the front-end itself, thus letting you 125 place useful data anywhere you see fit.</p><p>It is sometimes desirable to generate new events for the state machine 126 inside actions. Since the process_event method belongs to the back end, you 127 first need to gain a reference to it. The back end derives from the front 128 end, so one way of doing this is to use a cast:</p><pre class="programlisting">struct launcher_ : public msm::front::state_machine_def<launcher_>{ 129template <class Fire> void send_rocket(Fire const& evt) 130{ 131 fire_rocket(); 132 msm::back::state_machine<launcher_> &fsm = static_cast<msm::back::state_machine<launcher_> &>(*this); 133 fsm.process_event(rocket_launched()); 134} 135... 136};</pre><p>The same can be implemented inside entry/exit actions. Admittedly, this is 137 a bit awkward. A more natural mechanism is available using the <span class="command"><strong><a class="command" href="ch03s03.html#functor-front-end-actions">functor</a></strong></span> 138 front-end.</p></div><div class="sect2" title="Defining a simple state machine"><div class="titlepage"><div><div><h3 class="title"><a name="d0e471"></a>Defining a simple state machine</h3></div></div></div><p>Declaring a state machine is straightforward and is done with a high 139 signal / noise ratio. In our player example, we declare the state machine 140 as:</p><pre class="programlisting">struct player_ : public msm::front::state_machine_def<player_>{ 141 /* see below */}</pre><p>This declares a state machine using the basic front-end. We now declare 142 inside the state machine structure the initial state:</p><p> 143 </p><pre class="programlisting">typedef Empty initial_state;</pre><p> 144 </p><p>And that is about all of what is absolutely needed. In the example, the 145 states are declared inside the state machine for readability but this is not 146 a requirements, states can be declared wherever you like.</p><p>All what is left to do is to pick a back-end (which is quite simple as 147 there is only one at the moment):</p><p> 148 </p><pre class="programlisting">typedef msm::back::state_machine<player_> player;</pre><p> 149 </p><p>You now have a ready-to-use state machine with entry/exit actions, guards, 150 transition actions, a message queue so that processing an event can generate 151 another event. The state machine also adapted itself to your need and 152 removed almost all features we didn't use in this simple example. Note that 153 this is not per default the fastest possible state machine. See the section 154 "getting more speed" to know how to get the maximum speed. In a nutshell, 155 MSM cannot know about your usage of some features so you will have to 156 explicitly tell it.</p><p>State objects are built automatically with the state machine. They will 157 exist until state machine destruction. MSM is using Boost.Fusion behind the 158 hood. This unfortunately means that if you define more than 10 states, you 159 will need to extend the default:</p><p> 160 </p><pre class="programlisting">#define FUSION_MAX_VECTOR_SIZE 20 // or whatever you need 161 </pre><p> 162 </p><p>When an unexpected event is fired, the <code class="code">no_transition(event, state 163 machine, state id)</code> method of the state machine is called . By 164 default, this method simply asserts when called. It is possible to overwrite 165 the <code class="code">no_transition</code> method to define a different handling:</p><p> 166 </p><pre class="programlisting">template <class Fsm,class Event> 167void no_transition(Event const& e, Fsm& ,int state){...}</pre><p> 168 </p><p><span class="underline">Note</span>: you might have noticed that 169 the tutorial calls <code class="code">start()</code> on the state machine just after 170 creation. The start method will initiate the state machine, meaning it will 171 activate the initial state, which means in turn that the initial state's 172 entry behavior will be called. The reason why we need this will be explained 173 in the <a class="link" href="ch03s05.html#backend-start">back-end part</a>. After a call 174 to start, the state machine is ready to process events. The same way, 175 calling <code class="code">stop()</code> will cause the last exit actions to be called.</p></div><div class="sect2" title="Defining a submachine"><div class="titlepage"><div><div><h3 class="title"><a name="d0e529"></a>Defining a submachine</h3></div></div></div><p>We now want to extend our last state machine by making the Playing state a 176 state machine itself (a submachine).</p><p><span class="inlinemediaobject"><img src="../images/CompositeTutorial.jpg" width="60%"></span></p><p>Again, an <a class="link" href="examples/CompositeTutorial.cpp" target="_top">example</a> 177 is also provided.</p><p>A submachine really is a state machine itself, so we declare Playing as 178 such, choosing a front-end and a back-end:</p><p> 179 </p><pre class="programlisting">struct Playing_ : public msm::front::state_machine_def<Playing_>{...} 180typedef msm::back::state_machine<Playing_> Playing;</pre><p> 181 </p><p>Like for any state machine, one also needs a transition table and an 182 initial state:</p><p> 183 </p><pre class="programlisting"> 184struct transition_table : mpl::vector< 185// Start Event Target Action Guard 186// +--------+---------+--------+---------------------------+------+ 187a_row< Song1 , NextSong, Song2 , &Playing_::start_next_song >, 188a_row< Song2 , NextSong, Song1 , &Playing_::start_prev_song >, 189a_row< Song2 , NextSong, Song3 , &Playing_::start_next_song >, 190a_row< Song3 , NextSong, Song2 , &Playing_::start_prev_song > 191// +--------+---------+--------+---------------------------+------+ 192> {}; 193 </pre><p> 194 </p><p> 195 </p><pre class="programlisting">typedef Song1 initial_state; </pre><p> 196 </p><p>This is about all you need to do. MSM will now automatically recognize 197 Playing as a submachine and all events handled by Playing (NextSong and 198 PreviousSong) will now be automatically forwarded to Playing whenever this 199 state is active. All other state machine features described later are also 200 available. You can even decide to use a state machine sometimes as 201 submachine or sometimes as an independent state machine.</p><p><span class="command"><strong><a name="limitation-submachine"></a></strong></span>There is, however, a limitation for submachines. If a submachine's 202 substate has an entry action which requires a special event property (like a 203 given method), the compiler will require all events entering this submachine 204 to support this property. As this is not practicable, we will need to use 205 <code class="code">boost::enable_if</code> / <code class="code">boost::disable_if</code> to help, 206 for example consider:</p><pre class="programlisting">// define a property for use with enable_if 207BOOST_MPL_HAS_XXX_TRAIT_DEF(some_event_property) 208 209// this event supports some_event_property and a corresponding required method 210struct event1 211{ 212 // the property 213 typedef int some_event_property; 214 // the method required by this property 215 void some_property(){...} 216}; 217// this event does not supports some_event_property 218struct event2 219{ 220}; 221struct some_state : public msm::front::state<> 222{ 223 template <class Event,class Fsm> 224 // enable this version for events supporting some_event_property 225 typename boost::enable_if<typename has_some_event_property<Event>::type,void>::type 226 on_entry(Event const& evt,Fsm& fsm) 227 { 228 evt.some_property(); 229 } 230 // for events not supporting some_event_property 231 template <class Event,class Fsm> 232 typename boost::disable_if<typename has_some_event_property<Event>::type,void>::type 233 on_entry(Event const& ,Fsm& ) 234 { } 235}; </pre><p>Now this state can be used in your submachine.</p></div><div class="sect2" title="Orthogonal regions, terminate state, event deferring"><div class="titlepage"><div><div><h3 class="title"><a name="d0e577"></a>Orthogonal regions, terminate state, event deferring</h3></div></div></div><p>It is a very common problem in many state machines to have to handle 236 errors. It usually involves defining a transition from all the states to a 237 special error state. Translation: not fun. It is also not practical to find 238 from which state the error originated. The following diagram shows an 239 example of what clearly becomes not very readable:</p><p><span class="inlinemediaobject"><img src="../images/error_no_regions.jpg" width="60%"></span></p><p>This is neither very readable nor beautiful. And we do not even have any 240 action on the transitions yet to make it even less readable.</p><p>Luckily, UML provides a helpful concept, orthogonal regions. See them as 241 lightweight state machines running at the same time inside a common state 242 machine and having the capability to influence one another. The effect is 243 that you have several active states at any time. We can therefore keep our 244 state machine from the previous example and just define a new region made of 245 two states, AllOk and ErrorMode. AllOk is most of the time active. But the 246 error_found error event makes the second region move to the new active state 247 ErrorMode. This event does not interest the main region so it will simply be 248 ignored. "<code class="code">no_transition</code>" will be called only if no region at 249 all handles the event. Also, as UML mandates, every region gets a chance of 250 handling the event, in the order as declared by the 251 <code class="code">initial_state</code> type.</p><p>Adding an orthogonal region is easy, one only needs to declare more states 252 in the <code class="code">initial_state</code> typedef. So, adding a new region with 253 AllOk as the region's initial state is:</p><p> 254 </p><pre class="programlisting">typedef mpl::vector<Empty,AllOk> initial_state;</pre><p> 255 </p><p><span class="inlinemediaobject"><img src="../images/Orthogonal-deferred.jpg" width="60%"></span></p><p>Furthermore, when you detect an error, you usually do not want events to 256 be further processed. To achieve this, we use another UML feature, terminate 257 states. When any region moves to a terminate state, the state machine 258 “terminates” (the state machine and all its states stay alive) and all 259 events are ignored. This is of course not mandatory, one can use orthogonal 260 regions without terminate states. MSM also provides a small extension to 261 UML, interrupt states. If you declare ErrorMode (or a Boost.MPL sequence of 262 events, like boost::mpl::vector<ErrorMode, AnotherEvent>) as interrupt 263 state instead of terminate state, the state machine will not handle any 264 event other than the one which ends the interrupt. So it's like a terminate 265 state, with the difference that you are allowed to resume the state machine 266 when a condition (like handling of the original error) is met. </p><p><span class="command"><strong><a name="basic-defer"></a></strong></span>Last but not least, this example also shows 267 here the handling of event deferring. Let's say someone puts a disc and 268 immediately presses play. The event cannot be handled, yet you'd want it to 269 be handled at a later point and not force the user to press play again. The 270 solution is to define it as deferred in the Empty and Open states and get it 271 handled in the first state where the event is not to be deferred. It can 272 then be handled or rejected. In this example, when Stopped becomes active, 273 the event will be handled because only Empty and Open defer the 274 event.</p><p>UML defines event deferring as a state property. To accommodate this, MSM 275 lets you specify this in states by providing a <code class="code">deferred_events</code> 276 type:</p><pre class="programlisting">struct Empty : public msm::front::state<> 277{ 278 // if the play event is fired while in this state, defer it until a state 279 // handles or rejects it 280 typedef mpl::vector<play> deferred_events; 281... 282}; </pre><p>Please have a look at the <a class="link" href="examples/Orthogonal-deferred.cpp" target="_top">complete 283 example</a>.</p><p>While this is wanted by UML and is simple, it is not always practical 284 because one could wish to defer only in certain conditions. One could also 285 want to make this be part of a transition action with the added bonus of a 286 guard for more sophisticated behaviors. It would also be conform to the MSM 287 philosophy to get as much as possible in the transition table, where you 288 have the whole state machine structure. This is also possible but not 289 practical with this front-end so we will need to pick a different row from 290 the functor front-end. For a complete description of the <code class="code">Row</code> 291 type, please have a look at the <span class="command"><strong><a class="command" href="ch03s03.html#functor-front-end">functor front-end.</a></strong></span></p><p>First, as there is no state where MSM can automatically find out the usage 292 of this feature, we need to require deferred events capability explicitly, 293 by adding a type in the state machine definition:</p><pre class="programlisting">struct player_ : public msm::front::state_machine_def<player_> 294{ 295 typedef int activate_deferred_events; 296... 297}; </pre><p>We can now defer an event in any transition of the transition table by 298 using as action the predefined <code class="code">msm::front::Defer</code> functor, for 299 example:</p><p> 300 </p><pre class="programlisting">Row < Empty , play , none , Defer , none ></pre><p> 301 </p><p>This is an internal transition row(see <span class="command"><strong><a class="command" href="ch03s02.html#internal-transitions">internal transitions</a></strong></span>) but 302 you can ignore this for the moment. It just means that we are not leaving 303 the Empty state. What matters is that we use Defer as action. This is 304 roughly equivalent to the previous syntax but has the advantage of giving 305 you all the information in the transition table with the added power of 306 transition behavior.</p><p>The second difference is that as we now have a transition defined, this 307 transition can play in the resolution of <span class="command"><strong><a class="command" href="ch02s02.html#transition-conflict">transition conflicts</a></strong></span>. For 308 example, we could model an "if (condition2) move to Playing else if 309 (condition1) defer play event":</p><p> 310 </p><pre class="programlisting">Row < Empty , play , none , Defer , condition1 >, 311g_row < Empty , play , Playing , &player_::condition2 ></pre><p> 312 </p><p>Please have a look at <a class="link" href="examples/Orthogonal-deferred2.cpp" target="_top">this possible implementation</a>.</p></div><div class="sect2" title="History"><div class="titlepage"><div><div><h3 class="title"><a name="d0e668"></a>History</h3></div></div></div><p>UML defines two types of history, Shallow History and Deep History. In the 313 previous examples, if the player was playing the second song and the user 314 pressed pause, leaving Playing, at the next press on the play button, the 315 Playing state would become active and the first song would play again. Soon 316 would the first client complaints follow. They'd of course demand, that if 317 the player was paused, then it should remember which song was playing. But 318 it the player was stopped, then it should restart from the first song. How 319 can it be done? Of course, you could add a bit of programming logic and 320 generate extra events to make the second song start if coming from Pause. 321 Something like: </p><p> 322 </p><pre class="programlisting">if (Event == end_pause) 323{ 324 for (int i=0;i< song number;++i) {player.process_event(NextSong()); } 325} </pre><p> 326 </p><p>Not much to like in this example, isn't it? To solve this problem, you 327 define what is called a shallow or a deep history. A shallow history 328 reactivates the last active substate of a submachine when this submachine 329 becomes active again. The deep history does the same recursively, so if this 330 last active substate of the submachine was itself a submachine, its last 331 active substate would become active and this will continue recursively until 332 an active state is a normal state. For example, let us have a look at the 333 following UML diagram: </p><p><span class="inlinemediaobject"><img src="../images/HistoryTutorial.jpg" width="60%"></span></p><p>Notice that the main difference compared to previous diagrams is that the 334 initial state is gone and replaced by a History symbol (the H inside a 335 circle).</p><p>As explained in the <span class="command"><strong><a class="command" href="ch02s02.html#uml-history">small UML 336 tutorial</a></strong></span>, History is a good concept with a not completely 337 satisfying specification. MSM kept the concept but not the specification and 338 goes another way by making this a policy and you can add your own history 339 types (the <a class="link" href="re02.html#history-interface">reference</a> explains 340 what needs to be done). Furthermore, History is a backend policy. This 341 allows you to reuse the same state machine definition with different history 342 policies in different contexts.</p><p>Concretely, your frontend stays unchanged:</p><p> 343 </p><pre class="programlisting">struct Playing_ : public msm::front::state_machine_def<Playing_></pre><p> 344 </p><p>You then add the policy to the backend as second parameter:</p><p> 345 </p><pre class="programlisting">typedef msm::back::state_machine<Playing_, 346 msm::back::ShallowHistory<mpl::vector<end_pause> > > Playing;</pre><p> 347 </p><p>This states that a shallow history must be activated if the Playing state 348 machine gets activated by the end_pause event and only this one (or any 349 other event added to the mpl::vector). If the state machine was in the 350 Stopped state and the event play was generated, the history would not be 351 activated and the normal initial state would become active. By default, 352 history is disabled. For your convenience the library provides in addition 353 to ShallowHistory a non-UML standard AlwaysHistory policy (likely to be your 354 main choice) which always activates history, whatever event triggers the 355 submachine activation. Deep history is not available as a policy (but could 356 be added). The reason is that it would conflict with policies which 357 submachines could define. Of course, if for example, Song1 were a state 358 machine itself, it could use the ShallowHistory policy itself thus creating 359 Deep History for itself. An <a class="link" href="examples/History.cpp" target="_top">example</a> is also provided.</p></div><div class="sect2" title="Completion (anonymous) transitions"><div class="titlepage"><div><div><h3 class="title"><a name="d0e713"></a>Completion (anonymous) transitions</h3></div></div></div><p><span class="command"><strong><a name="anonymous-transitions"></a></strong></span>The following diagram shows an 360 example making use of this feature:</p><p><span class="inlinemediaobject"><img src="../images/Anonymous.jpg" width="60%"></span></p><p>Anonymous transitions are transitions without a named event. This means 361 that the transition automatically fires when the predecessor state is 362 entered (to be exact, after the entry action). Otherwise it is a normal 363 transition with actions and guards. Why would you need something like that? 364 A possible case would be if a part of your state machine implements some 365 algorithm, where states are steps of the algorithm implementation. Then, 366 using several anonymous transitions with different guard conditions, you are 367 actually implementing some if/else statement. Another possible use would be 368 a real-time system called at regular intervals and always doing the same 369 thing, meaning implementing the same algorithm. The advantage is that once 370 you know how long a transition takes to execute on the system, by 371 calculating the longest path (the number of transitions from start to end), 372 you can pretty much know how long your algorithm will take in the worst 373 case, which in turns tells you how much of a time frame you are to request 374 from a scheduler. </p><p>If you are using Executable UML (a good book describing it is "Executable 375 UML, a foundation for Model-Driven Architecture"), you will notice that it 376 is common for a state machine to generate an event to itself only to force 377 leaving a state. Anonymous transitions free you from this constraint.</p><p>If you do not use this feature in a concrete state machine, MSM will 378 deactivate it and you will not pay for it. If you use it, there is however a 379 small performance penalty as MSM will try to fire a compound event (the 380 other UML name for anonymous transitions) after every taken transition. This 381 will therefore double the event processing cost, which is not as bad as it 382 sounds as MSM’s execution speed is very high anyway.</p><p>To define such a transition, use “none” as event in the transition table, 383 for example:</p><p> 384 </p><pre class="programlisting">row < State3 , none , State4 , &p::State3ToState4 , &p::always_true ></pre><p> 385 </p><p><a class="link" href="examples/AnonymousTutorial.cpp" target="_top">An implementation</a> 386 of the state machine diagram is also provided.</p></div><div class="sect2" title="Internal transitions"><div class="titlepage"><div><div><h3 class="title"><a name="d0e740"></a><span class="command"><strong><a name="internal-transitions"></a></strong></span>Internal transitions</h3></div></div></div><p>Internal transitions are transitions executing in the scope of the active 387 state, a simple state or a submachine. One can see them as a self-transition 388 of this state, without an entry or exit action called. This is useful when 389 all you want is to execute some code for a given event in a given 390 state.</p><p>Internal transitions are specified as having a higher priority than normal 391 transitions. While it makes sense for a submachine with exit points, it is 392 surprising for a simple state. MSM lets you define the transition priority 393 by setting the transition’s position inside the transition table (see 394 <span class="command"><strong><a class="command" href="ch06.html#run-to-completion">internals</a></strong></span> ). The 395 difference between "normal" and internal transitions is that internal 396 transitions have no target state, therefore we need new row types. We had 397 a_row, g_row, _row and row, we now add a_irow, g_irow, _irow and irow which 398 are like normal transitions but define no target state. For, example an 399 internal transition with a guard condition could be:</p><p> 400 </p><pre class="programlisting">g_irow < Empty /*state*/,cd_detected/*event*/,&p::internal_guard/* guard */></pre><p> 401 </p><p>These new row types can be placed anywhere in the transition table so that 402 you can still have your state machine structure grouped together. The only 403 difference of behavior with the UML standard is the missing notion of higher 404 priority for internal transitions. Please have a look at <a class="link" href="examples/SimpleTutorialInternal.cpp" target="_top">the 405 example</a>.</p><p>It is also possible to do it the UML-conform way by declaring a transition 406 table called <code class="code">internal transition_table</code> inside the state itself 407 and using internal row types. For example:</p><pre class="programlisting">struct Empty : public msm::front::state<> 408{ 409 struct internal_transition_table : mpl::vector< 410 a_internal < cd_detected , Empty, &Empty::internal_action > 411 > {}; 412};</pre><p>This declares an internal transition table called 413 internal_transition_table and reacting on the event cd_detected by calling 414 internal_action on Empty. Let us note a few points:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>internal tables are NOT called transition_table but 415 internal_transition_table</p></li><li class="listitem"><p>they use different but similar row types: a_internal, 416 g_internal, _internal and internal.</p></li><li class="listitem"><p>These types take as first template argument the triggering 417 event and then the action and guard method. Note that the only 418 real difference to classical rows is the extra argument before 419 the function pointer. This is the type on which the function 420 will be called.</p></li><li class="listitem"><p>This also allows you, if you wish, to use actions and guards 421 from another state of the state machine or in the state machine 422 itself.</p></li><li class="listitem"><p>submachines can have an internal transition table and a 423 classical transition table.</p></li></ul></div><p>The <a class="link" href="examples/TestInternal.cpp" target="_top">following example</a> 424 makes use of an a_internal. It also uses functor-based internal transitions 425 which will be explained in <span class="command"><strong><a class="command" href="ch03s03.html#functor-internal-transitions">the functor 426 front-end</a></strong></span>, please ignore them for the moment. Also note that 427 the state-defined internal transitions, having the highest priority (as 428 mandated by the UML standard), are tried before those defined inside the 429 state machine transition table.</p><p>Which method should you use? It depends on what you need:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>the first version (using irow) is simpler and likely to 430 compile faster. It also lets you choose the priority of your 431 internal transition.</p></li><li class="listitem"><p>the second version is more logical from a UML perspective and 432 lets you make states more useful and reusable. It also allows 433 you to call actions and guards on any state of the state 434 machine.</p></li></ul></div><p> 435 <span class="command"><strong><a name="internal-transitions-note"></a></strong></span><span class="underline"><span class="bold"><strong>Note</strong></span></span>: There is an added 436 possibility coming from this feature. The 437 <code class="code">internal_transition_table</code> transitions being added directly 438 inside the main state machine's transition table, it is possible, if it is 439 more to your state, to distribute your state machine definition a bit like 440 Boost.Statechart, leaving to the state machine itself the only task of 441 declaring the states it wants to use using the 442 <code class="code">explicit_creation</code> type definition. While this is not the 443 author's favorite way, it is still possible. A simplified example using only 444 two states will show this possibility:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><a class="link" href="examples/distributed_table/DistributedTable.cpp" target="_top">state machine definition</a></p></li><li class="listitem"><p>Empty <a class="link" href="examples/distributed_table/Empty.hpp" target="_top">header</a> and <a class="link" href="examples/distributed_table/Empty.cpp" target="_top">cpp</a></p></li><li class="listitem"><p>Open <a class="link" href="examples/distributed_table/Open.hpp" target="_top">header</a> and <a class="link" href="examples/distributed_table/Open.cpp" target="_top">cpp</a></p></li><li class="listitem"><p><a class="link" href="examples/distributed_table/Events.hpp" target="_top">events definition</a></p></li></ul></div><p>There is an added bonus offered for submachines, which can have both the 445 standard transition_table and an internal_transition_table (which has a 446 higher priority). This makes it easier if you decide to make a full 447 submachine from a state. It is also slightly faster than the standard 448 alternative, adding orthogonal regions, because event dispatching will, if 449 accepted by the internal table, not continue to the subregions. This gives 450 you a O(1) dispatch instead of O(number of regions). While the example is 451 with eUML, the same is also possible with any front-end.</p></div><div class="sect2" title="more row types"><div class="titlepage"><div><div><h3 class="title"><a name="d0e842"></a><span class="command"><strong><a name="basic-row2"></a></strong></span>more row types</h3></div></div></div><p>It is also possible to write transitions using actions and guards not just 452 from the state machine but also from its contained states. In this case, one 453 must specify not just a method pointer but also the object on which to call 454 it. This transition row is called, not very originally, <code class="code">row2</code>. 455 They come, like normal transitions in four flavors: <code class="code">a_row2, g_row2, 456 _row2 and row2</code>. For example, a transition calling an action from 457 the state Empty could be:</p><p> 458 </p><pre class="programlisting">a_row2<Stopped,open_close,Open,Empty 459 /*action source*/,&Empty::open_drawer/*action*/></pre><p> 460 </p><p>The same capabilities are also available for internal transitions so that 461 we have: <code class="code">a_irow2, g_irow2, _irow2 and row2</code>. For transitions 462 defined as part of the <code class="code">internal_transition_table</code>, you can use 463 the <span class="command"><strong><a class="command" href="ch03s02.html#internal-transitions">a_internal, g_internal, 464 _internal, internal</a></strong></span> row types from the previous 465 sections.</p><p>These row types allow us to distribute the state machine code among 466 states, making them reusable and more useful. Using transition tables inside 467 states also contributes to this possibility. An <a class="link" href="examples/SimpleTutorial2.cpp" target="_top">example</a> of these new 468 rows is also provided.</p></div><div class="sect2" title="Explicit entry / entry and exit pseudo-state / fork"><div class="titlepage"><div><div><h3 class="title"><a name="d0e875"></a>Explicit entry / entry and exit pseudo-state / fork</h3></div></div></div><p>MSM (almost) fully supports these features, described in the <span class="command"><strong><a class="command" href="ch02s02.html#uml-history">small UML tutorial</a></strong></span>. Almost because 469 there are currently two limitations: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>it is only possible to explicitly enter a sub- state of the 470 target but not a sub-sub state.</p></li><li class="listitem"><p>it is not possible to explicitly exit. Exit points must be 471 used.</p></li></ul></div><p>Let us see a concrete example:</p><p><span class="inlinemediaobject"><img src="../images/entrytutorial.jpg" width="60%"></span></p><p>We find in this diagram:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>A “normal” activation of SubFsm2, triggered by event1. In each 472 region, the initial state is activated, i.e. SubState1 and 473 SubState1b.</p></li><li class="listitem"><p>An explicit entry into SubFsm2::SubState2 for region “1” with 474 event2 as trigger, meaning that in region “2” the initial state, 475 SubState1b, activated.</p></li><li class="listitem"><p>A fork into regions “1” and “2” to the explicit entries 476 SubState2 and SubState2b, triggered by event3. Both states 477 become active so no region is default activated (if we had a 478 third one, it would be).</p></li><li class="listitem"><p>A connection of two transitions through an entry pseudo state, 479 SubFsm2::PseudoEntry1, triggered by event4 and triggering also 480 the second transition on the same event (both transitions must 481 be triggered by the same event). Region “2” is default-activated 482 and SubState1b becomes active.</p></li><li class="listitem"><p>An exit from SubFsm2 using an exit pseudo-state, PseudoExit1, 483 triggered by event5 and connecting two transitions using the 484 same event. Again, the event is forwarded to the second 485 transition and both regions are exited, as SubFsm2 becomes 486 inactive. Note that if no transition is defined from 487 PseudoExit1, an error (as defined in the UML standard) will be 488 detected and no_transition called.</p></li></ul></div><p>The example is also <a class="link" href="examples/DirectEntryTutorial.cpp" target="_top">fully implemented</a>.</p><p>This sounds complicated but the syntax is simple.</p><div class="sect3" title="Explicit entry"><div class="titlepage"><div><div><h4 class="title"><a name="d0e921"></a>Explicit entry</h4></div></div></div><p>First, to define that a state is an explicit entry, you have to make 489 it a state and mark it as explicit, giving as template parameters the 490 region id (the region id starts with 0 and corresponds to the first 491 initial state of the initial_state type sequence).</p><p> 492 </p><pre class="programlisting">struct SubFsm2_ : public msm::front::state_machine_def<SubFsm2_> 493{ 494 struct SubState2 : public msm::front::state<> , 495 public msm::front::explicit_entry<0> 496 {...}; 497... 498};</pre><p> 499 </p><p>And define the submachine as:</p><p> 500 </p><pre class="programlisting">typedef msm::back::state_machine<SubFsm2_> SubFsm2;</pre><p> 501 </p><p>You can then use it as target in a transition with State1 as 502 source:</p><p> 503 </p><pre class="programlisting">_row < State1, Event2, SubFsm2::direct< SubFsm2_::SubState2> > //SubFsm2_::SubState2: complete name of SubState2 (defined within SubFsm2_)</pre><p> 504 </p><p>The syntax deserves some explanation. SubFsm2_ is a front end. 505 SubState2 is a nested state, therefore the SubFsm2_::SubState2 syntax. 506 The containing machine (containing State1 and SubFsm2) refers to the 507 backend instance (SubFsm2). SubFsm2::direct states that an explicit 508 entry is desired.</p><p><span class="command"><strong><a name="explicit-entry-no-region-id"></a></strong></span>Thanks to the <span class="command"><strong><a class="command" href="ch03s05.html#backend-compile-time-analysis">mpl_graph</a></strong></span> library you can also omit to provide the region 509 index and let MSM find out for you. The are however two points to note:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>MSM can only find out the region index if the explicit 510 entry state is somehow connected to an initial state through 511 a transition, no matter the direction.</p></li><li class="listitem"><p>There is a compile-time cost for this feature.</p></li></ul></div><p><span class="underline">Note (also valid for forks)</span>: in 512 order to make compile time more bearable for the more standard cases, 513 and unlike initial states, explicit entry states which are also not 514 found in the transition table of the entered submachine (a rare case) do 515 NOT get automatically created. To explicitly create such states, you 516 need to add in the state machine containing the explicit states a simple 517 typedef giving a sequence of states to be explicitly created 518 like:</p><p> 519 </p><pre class="programlisting">typedef mpl::vector<SubState2,SubState2b> explicit_creation;</pre><p> 520 </p><p><span class="underline">Note (also valid for forks)</span>: At 521 the moment, it is not possible to use a submachine as the target of an 522 explicit entry. Please use entry pseudo states for an almost identical 523 effect.</p></div><div class="sect3" title="Fork"><div class="titlepage"><div><div><h4 class="title"><a name="d0e973"></a>Fork</h4></div></div></div><p>Need a fork instead of an explicit entry? As a fork is an explicit 524 entry into states of different regions, we do not change the state 525 definition compared to the explicit entry and specify as target a list 526 of explicit entry states:</p><p> 527 </p><pre class="programlisting">_row < State1, Event3, 528 mpl::vector<SubFsm2::direct<SubFsm2_::SubState2>, 529 SubFsm2::direct <SubFsm2_::SubState2b> 530 ></pre><p> 531 </p><p>With SubState2 defined as before and SubState2b defined as being in 532 the second region (Caution: MSM does not check that the region is 533 correct):</p><p> 534 </p><pre class="programlisting">struct SubState2b : public msm::front::state<> , 535 public msm::front::explicit_entry<1></pre><p> 536 </p></div><div class="sect3" title="Entry pseudo states"><div class="titlepage"><div><div><h4 class="title"><a name="d0e990"></a>Entry pseudo states</h4></div></div></div><p> To define an entry pseudo state, you need derive from the 537 corresponding class and give the region id:</p><p> 538 </p><pre class="programlisting">struct PseudoEntry1 : public msm::front::entry_pseudo_state<0></pre><p> 539 </p><p>And add the corresponding transition in the top-level state machine's 540 transition table:</p><p> 541 </p><pre class="programlisting">_row < State1, Event4, SubFsm2::entry_pt<SubFsm2_::PseudoEntry1> ></pre><p> 542 </p><p>And another in the SubFsm2_ submachine definition (remember that UML 543 defines an entry point as a connection between two transitions), for 544 example this time with an action method:</p><p> 545 </p><pre class="programlisting">_row < PseudoEntry1, Event4, SubState3,&SubFsm2_::entry_action ></pre><p> 546 </p></div><div class="sect3" title="Exit pseudo states"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1014"></a> Exit pseudo states </h4></div></div></div><p>And finally, exit pseudo states are to be used almost the same way, 547 but defined differently: it takes as template argument the event to be 548 forwarded (no region id is necessary):</p><p> 549 </p><pre class="programlisting">struct PseudoExit1 : public exit_pseudo_state<event6></pre><p> 550 </p><p>And you need, like for entry pseudo states, two transitions, one in 551 the submachine:</p><p> 552 </p><pre class="programlisting">_row < SubState3, Event5, PseudoExit1 ></pre><p> 553 </p><p>And one in the containing state machine:</p><p> 554 </p><pre class="programlisting">_row < SubFsm2::exit_pt<SubFsm2_::PseudoExit1>, Event6,State2 ></pre><p> 555 </p><p><span class="underline">Important note 1:</span> UML defines 556 transiting to an entry pseudo state and having either no second 557 transition or one with a guard as an error but defines no error 558 handling. MSM will tolerate this behavior; the entry pseudo state will 559 simply be the newly active state.</p><p><span class="underline">Important note 2</span>: UML defines 560 transiting to an exit pseudo state and having no second transition as an 561 error, and also defines no error handling. Therefore, it was decided to 562 implement exit pseudo state as terminate states and the containing 563 composite not properly exited will stay terminated as it was technically 564 “exited”.</p><p><span class="underline">Important note 3:</span> UML states 565 that for the exit point, the same event must be used in both 566 transitions. MSM relaxes this rule and only wants the event on the 567 inside transition to be convertible to the one of the outside 568 transition. In our case, event6 is convertible from event5. Notice that 569 the forwarded event must be named in the exit point definition. For 570 example, we could define event6 as simply as:</p><p> 571 </p><pre class="programlisting">struct event 572{ 573 event(){} 574 template <class Event> 575 event(Event const&){} 576}; //convertible from any event</pre><p> 577 <span class="underline">Note</span>: There is a current 578 limitation if you need not only convert but also get some data from the 579 original event. Consider:</p><pre class="programlisting">struct event1 580{ 581 event1(int val_):val(val_) {} 582 int val; 583}; // forwarded from exit point 584struct event2 585{ 586 template <class Event> 587 event2(Event const& e):val(e.val){} // compiler will complain about another event not having any val 588 int val; 589}; // what the higher-level fsm wants to get</pre><p>The solution is to provide two constructors:</p><pre class="programlisting">struct event2 590{ 591 template <class Event> 592 event2(Event const& ):val(0){} // will not be used 593 event2(event1 const& e)):val(e.val){} // the conversion constructor 594 int val; 595}; // what the higher-level fsm wants to get</pre></div></div><div class="sect2" title="Flags"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1064"></a>Flags</h3></div></div></div><p>This <a class="link" href="examples/Flags.cpp" target="_top">tutorial</a> is devoted to a 596 concept not defined in UML: flags. It has been added into MSM after proving 597 itself useful on many occasions. Please, do not be frightened as we are not 598 talking about ugly shortcuts made of an improbable collusion of 599 Booleans.</p><p>If you look into the Boost.Statechart documentation you'll find this 600 code:</p><pre class="programlisting">if ( ( state_downcast< const NumLockOff * >() != 0 ) && 601 ( state_downcast< const CapsLockOff * >() != 0 ) && 602 ( state_downcast< const ScrollLockOff * >() != 0 ) ) 603 </pre><p>While correct and found in many UML books, this can be error-prone and a 604 potential time-bomb when your state machine grows and you add new states or 605 orthogonal regions.</p><p>And most of all, it hides the real question, which would be “does my state 606 machine's current state define a special property”? In this special case 607 “are my keys in a lock state”? So let's apply the Fundamental Theorem of 608 Software Engineering and move one level of abstraction higher.</p><p>In our player example, let's say we need to know if the player has a 609 loaded CD. We could do the same:</p><pre class="programlisting">if ( ( state_downcast< const Stopped * >() != 0 ) && 610 ( state_downcast< const Open * >() != 0 ) && 611 ( state_downcast< const Paused * >() != 0 ) && 612 ( state_downcast< const Playing * >() != 0 )) </pre><p>Or flag these 4 states as CDLoaded-able. You add a flag_list type into 613 each flagged state:</p><p> 614 </p><pre class="programlisting">typedef mpl::vector1<CDLoaded> flag_list;</pre><p> 615 </p><p>You can even define a list of flags, for example in Playing:</p><p> 616 </p><pre class="programlisting">typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;</pre><p> 617 </p><p>This means that Playing supports both properties. To check if your player 618 has a loaded CD, check if your flag is active in the current state:</p><p> 619 </p><pre class="programlisting">player p; if (p.is_flag_active<CDLoaded>()) ... </pre><p> 620 </p><p>And what if you have orthogonal regions? How to decide if a state machine 621 is in a flagged state? By default, you keep the same code and the current 622 states will be OR'ed, meaning if one of the active states has the flag, then 623 is_flag_active returns true. Of course, in some cases, you might want that 624 all of the active states are flagged for the state to be active. You can 625 also AND the active states:</p><p> 626 </p><pre class="programlisting">if (p.is_flag_active<CDLoaded,player::Flag_AND>()) ...</pre><p> 627 </p><p> Note. Due to arcane C++ rules, when called inside an action, the correct 628 call is: 629 </p><pre class="programlisting">if (p.<span class="bold"><strong>template</strong></span> is_flag_active<CDLoaded>()) ...</pre><p> 630 </p><p>The following diagram displays the flag situation in the tutorial.</p><p><span class="inlinemediaobject"><img src="../images/FlagsTutorial.jpg" width="60%"></span></p></div><div class="sect2" title="Event Hierarchy"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1126"></a><span class="command"><strong><a name="event-hierarchy"></a></strong></span>Event Hierarchy</h3></div></div></div><p>There are cases where one needs transitions based on categories of events. 631 An example is text parsing. Let's say you want to parse a string and use a 632 state machine to manage your parsing state. You want to parse 4 digits and 633 decide to use a state for every matched digit. Your state machine could look 634 like:</p><p><span class="inlinemediaobject"><img src="../images/ParsingDigits.jpg" width="30%"></span></p><p>But how to detect the digit event? We would like to avoid defining 10 635 transitions on char_0, char_1... between two states as it would force us to 636 write 4 x 10 transitions and the compile-time would suffer. To solve this 637 problem, MSM supports the triggering of a transition on a subclass event. 638 For example, if we define digits as: </p><pre class="programlisting">struct digit {}; 639struct char_0 : public digit {}; </pre><p>And to the same for other digits, we can now fire char_0, char_1 events 640 and this will cause a transition with "digit" as trigger to be taken.</p><p>An <a class="link" href="examples/ParsingDigits.cpp" target="_top">example</a> with 641 performance measurement, taken from the documentation of Boost.Xpressive 642 illustrates this example. You might notice that the performance is actually 643 very good (in this case even better).</p></div><div class="sect2" title="Customizing a state machine / Getting more speed"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1147"></a>Customizing a state machine / Getting more speed</h3></div></div></div><p>MSM is offering many UML features at a high-speed, but sometimes, you just 644 need more speed and are ready to give up some features in exchange. A 645 process_event is handling several tasks: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>checking for terminate/interrupt states</p></li><li class="listitem"><p>handling the message queue (for entry/exit/transition actions 646 generating themselves events)</p></li><li class="listitem"><p>handling deferred events</p></li><li class="listitem"><p>catching exceptions (or not)</p></li><li class="listitem"><p>handling the state switching and action calls</p></li></ul></div><p>Of these tasks, only the last one is absolutely necessary to 647 a state machine (its core job), the other ones are nice-to-haves which cost 648 CPU time. In many cases, it is not so important, but in embedded systems, 649 this can lead to ad-hoc state machine implementations. MSM detects by itself 650 if a concrete state machine makes use of terminate/interrupt states and 651 deferred events and deactivates them if not used. For the other two, if you 652 do not need them, you need to help by indicating it in your implementation. 653 This is done with two simple typedefs:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><code class="code">no_exception_thrown</code> indicates that behaviors will 654 never throw and MSM does not need to catch anything</p></li><li class="listitem"><p><code class="code">no_message_queue</code> indicates that no action will 655 itself generate a new event and MSM can save us the message 656 queue.</p></li></ul></div><p>The third configuration possibility, explained <a class="link" href="ch03s02.html#basic-defer">here</a>, is to manually activate deferred 657 events, using <code class="code">activate_deferred_events</code>. For example, the 658 following state machine sets all three configuration types:</p><pre class="programlisting">struct player_ : public msm::front::state_machine_def<player_> 659{ 660 // no need for exception handling or message queue 661 typedef int no_exception_thrown; 662 typedef int no_message_queue; 663 // also manually enable deferred events 664 typedef int activate_deferred_events 665 ...// rest of implementation 666 };</pre><p><span class="underline">Important note</span>: As exit pseudo 667 states are using the message queue to forward events out of a submachine, 668 the <code class="code">no_message_queue</code> option cannot be used with state machines 669 containing an exit pseudo state.</p></div><div class="sect2" title="Choosing the initial event"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1196"></a>Choosing the initial event</h3></div></div></div><p>A state machine is started using the <code class="code">start</code> method. This 670 causes the initial state's entry behavior to be executed. Like every entry 671 behavior, it becomes as parameter the event causing the state to be entered. 672 But when the machine starts, there was no event triggered. In this case, MSM 673 sends <code class="code">msm::back::state_machine<...>::InitEvent</code>, which might 674 not be the default you'd want. For this special case, MSM provides a 675 configuration mechanism in the form of a typedef. If the state machine's 676 front-end definition provides an initial_event typedef set to another event, 677 this event will be used. For example:</p><pre class="programlisting">struct my_initial_event{}; 678struct player_ : public msm::front::state_machine_def<player_>{ 679... 680typedef my_initial_event initial_event; 681};</pre></div><div class="sect2" title="Containing state machine (deprecated)"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1209"></a> Containing state machine (deprecated)</h3></div></div></div><p>This feature is still supported in MSM for backward compatibility but made 682 obsolete by the fact that every guard/action/entry action/exit action get 683 the state machine passed as argument and might be removed at a later 684 time.</p><p>All of the states defined in the state machine are created upon state 685 machine construction. This has the huge advantage of a reduced syntactic 686 noise. The cost is a small loss of control for the user on the state 687 creation and access. But sometimes you needed a way for a state to get 688 access to its containing state machine. Basically, a state needs to change 689 its declaration to:</p><pre class="programlisting">struct Stopped : public msm::front::state<sm_ptr></pre><p>And to provide a set_sm_ptr function: <code class="code">void set_sm_ptr(player* 690 pl)</code></p><p>to get a pointer to the containing state machine. The same applies to 691 terminate_state / interrupt_state and entry_pseudo_state / 692 exit_pseudo_state. </p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch03.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch03.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch03s03.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 3. Tutorial </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Functor front-end</td></tr></table></div></body></html>