UNPKG

boost-react-native-bundle

Version:

Boost library as in https://sourceforge.net/projects/boost/files/boost/1.57.0/

731 lines (730 loc) 568 kB
<?xml version="1.0" encoding="UTF-8"?> <?oxygen RNGSchema="http://www.oasis-open.org/docbook/xml/5.0/rng/docbook.rng" type="xml"?> <book xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"> <info> <title>Meta State Machine (MSM)</title> <author> <personname>Christophe Henry</personname> <email>christophe.j.henry@googlemail.com</email> </author> <copyright> <year>2008-2010</year> <holder> <phrase> Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at <link xlink:href="http://www.boost.org/LICENSE_1_0.txt" >http://www.boost.org/LICENSE_1_0.txt</link> ) </phrase> </holder> </copyright> </info> <preface> <title>Preface</title> <para>MSM is a library allowing you to easily and quickly define state machines of very high performance. From this point, two main questions usually quickly arise, so please allow me to try answering them upfront.</para> <para> <itemizedlist> <listitem> <para>When do I need a state machine?</para> <para>More often that you think. Very often, one defined a state machine informally without even noticing it. For example, one declares inside a class some boolean attribute, say to remember that a task has been completed. Later the boolean actually needs a third value, so it becomes an int. A few weeks, a second attribute is needed. Then a third. Soon, you find yourself writing:</para> <para><code>void incoming_data(data)</code></para> <para><code>{</code></para> <para><code> if (data == packet_3 &amp;&amp; flag1 == work_done &amp;&amp; flag2 > step3)...</code></para> <para><code>}</code></para> <para>This starts to look like event processing (contained inside data) if some stage of the object life has been achieved (but is ugly).</para> <para>This could be a protocol definition and it is a common use case for state machines. Another common one is a user interface. The stage of the user's interaction defines if some button is active, a functionality is available, etc.</para> <para>But there are many more use cases if you start looking. Actually, a whole model-driven development method, Executable UML (http://en.wikipedia.org/wiki/Executable_UML) specifies its complete dynamic behavior using state machines. Class diagram, state machine diagrams, and an action language are all you absolutely need in the Executable UML world.</para> </listitem> <listitem> <para>Another state machine library? What for?</para> <para>True, there are many state machine libraries. This should already be an indication that if you're not using any of them, you might be missing something. Why should you use this one? Unfortunately, when looking for a good state machine library, you usually pretty fast hit one or several of the following snags:<itemizedlist> <listitem> <para>speed: "state machines are slow" is usually the first criticism you might hear. While it is often an excuse not to use any and instead resort to dirty, hand-written implementations (I mean, no, yours are not dirty of course, I'm talking about other developers). MSM removes this often feeble excuse because it is blazingly fast. Most hand-written implementations will be beaten by MSM.</para> </listitem> <listitem> <para>ease of use: good argument. If you used another library, you are probably right. Many state machine definitions will look similar to:</para> <para><code>state s1 = new State; // a state</code></para> <para><code>state s2 = new State; // another state</code></para> <para><code>event e = new Event; // event</code></para> <para><code>s1->addTransition(e,s2); // transition s1 -> s2</code></para> <para>The more transitions you have, the less readable it is. A long time ago, there was not so much Java yet, and many electronic systems were built with a state machine defined by a simple transition table. You could easily see the whole structure and immediately see if you forgot some transitions. Thanks to our new OO techniques, this ease of use was gone. MSM gives you back the transition table and reduces the noise to the minimum.</para> </listitem> <listitem> <para>expressiveness: MSM offers several front-ends and constantly tries to improve state machine definition techniques. For example, you can define a transition with eUML (one of MSM's front-ends) as:</para> <para><code>state1 == state2 + event [condition] / action</code></para> <para>This is not simply syntactic sugar. Such a formalized, readable structure allows easy communication with domain experts of a software to be constructed. Having domain experts understand your code will greatly reduce the number of bugs.</para> </listitem> <listitem> <para>model-driven-development: a common difficulty of a model-driven development is the complexity of making a round-trip (generating code from model and then model from code). This is due to the fact that if a state machine structure is hard for you to read, chances are that your parsing tool will also have a hard time. MSM's syntax will hopefully help tool writers.</para> </listitem> <listitem> <para>features: most developers use only 20% of the richly defined UML standard. Unfortunately, these are never the same 20% for all. And so, very likely, one will need something from the standard which is not implemented. MSM offers a very large part of the standard, with more on the way.</para> </listitem> </itemizedlist></para> <para>Let us not wait any longer, I hope you will enjoy MSM and have fun with it!</para> </listitem> </itemizedlist> </para> </preface> <part> <title>User' guide</title> <chapter> <title>Founding idea</title> <para>Let's start with an example taken from the C++ Template Metaprogramming book:</para> <programlisting>class player : public state_machine&lt;player> { // The list of FSM states enum states { Empty, Open, Stopped, Playing, Paused , initial_state = Empty }; // transition actions void start_playback(play const&amp;) { std::cout &lt;&lt; "player::start_playback\n"; } void open_drawer(open_close const&amp;) { std::cout &lt;&lt; "player::open_drawer\n"; } // more transition actions ... typedef player p; // makes transition table cleaner struct transition_table : mpl::vector11&lt; // Start Event Target Action // +---------+------------+-----------+---------------------------+ row&lt; Stopped , play , Playing , &amp;p::start_playback >, row&lt; Stopped , open_close , Open , &amp;::open_drawer >, // +---------+------------+-----------+---------------------------+ row&lt; Open , open_close , Empty , &amp;p::close_drawer >, // +---------+------------+-----------+---------------------------+ row&lt; Empty , open_close , Open , &amp;p::open_drawer >, row&lt; Empty , cd_detected, Stopped , &amp;p::store_cd_info >, // +---------+------------+-----------+---------------------------+ row&lt; Playing , stop , Stopped , &amp;p::stop_playback >, row&lt; Playing , pause , Paused , &amp;p::pause_playback >, row&lt; Playing , open_close , Open , &amp;p::stop_and_open >, // +---------+------------+-----------+---------------------------+ row&lt; Paused , play , Playing , &amp;p::resume_playback >, row&lt; Paused , stop , Stopped , &amp;p::stop_playback >, row&lt; Paused , open_close , Open , &amp;p::stop_and_open > // +---------+------------+-----------+---------------------------+ > {}; // Replaces the default no-transition response. template &lt;class Event> int no_transition(int state, Event const&amp; e) { std::cout &lt;&lt; "no transition from state " &lt;&lt; state &lt;&lt; " on event " &lt;&lt; typeid(e).name() &lt;&lt; std::endl; return state; } }; </programlisting> <para>This example is the foundation for the idea driving MSM: a descriptive and expressive language based on a transition table with as little syntactic noise as possible, all this while offering as many features from the UML 2.0 standard as possible. MSM also offers several expressive state machine definition syntaxes with different trade-offs.</para> </chapter> <chapter> <title>UML Short Guide</title> <sect1> <title>What are state machines?</title> <para>State machines are the description of a thing's lifeline. They describe the different stages of the lifeline, the events influencing it, and what it does when a particular event is detected at a particular stage. They offer the complete specification of the dynamic behavior of the thing.</para> </sect1> <sect1> <title>Concepts</title> <para>Thinking in terms of state machines is a bit surprising at first, so let us have a quick glance at the concepts.</para> <sect2> <title>State machine, state, transition, event </title> <para>A state machine is a concrete model describing the behavior of a system. It is composed of a finite number of states and transitions.</para> <para> <inlinemediaobject> <imageobject> <imagedata fileref="images/sm.gif"/> </imageobject> </inlinemediaobject></para> <para>A simple state has no sub states. It can have data, entry and exit behaviors and deferred events. One can provide entry and exit behaviors (also called actions) to states (or state machines), which are executed whenever a state is entered or left, no matter how. A state can also have internal transitions which cause no entry or exit behavior to be called. A state can mark events as deferred. This means the event cannot be processed if this state is active, but it must be retained. Next time a state not deferring this event is active, the event will be processed, as if it had just been fired. </para> <para><inlinemediaobject> <imageobject> <imagedata fileref="images/state.gif"/> </imageobject> </inlinemediaobject></para> <para>A transition is the switching between active states, triggered by an event. Actions and guard conditions can be attached to the transition. The action executes when the transition fires, the guard is a Boolean operation executed first and which can prevent the transition from firing by returning false.</para> <para> <inlinemediaobject> <imageobject> <imagedata fileref="images/transition.jpg"/> </imageobject> </inlinemediaobject></para> <para>An initial state marks the first active state of a state machine. It has no real existence and neither has the transition originating from it.</para> <para> <inlinemediaobject> <imageobject> <imagedata fileref="images/init_state.gif"/> </imageobject> </inlinemediaobject></para> </sect2> <sect2> <title>Submachines, orthogonal regions, pseudostates </title> <para>A composite state is a state containing a region or decomposed in two or more regions. A composite state contains its own set of states and regions. </para> <para>A submachine is a state machine inserted as a state in another state machine. The same submachine can be inserted more than once. </para> <para>Orthogonal regions are parts of a composite state or submachine, each having its own set of mutually exclusive set of states and transitions. </para> <para><inlinemediaobject> <imageobject> <imagedata fileref="images/regions.gif" width="60%" scalefit="1"/> </imageobject> </inlinemediaobject></para> <para>UML also defines a number of pseudo states, which are considered important concepts to model, but not enough to make them first-class citizens. The terminate pseudo state terminates the execution of a state machine (MSM handles this slightly differently. The state machine is not destroyed but no further event processing occurs.). </para> <para><inlinemediaobject> <imageobject> <imagedata fileref="images/terminate.gif"/> </imageobject> </inlinemediaobject></para> <para>An exit point pseudo state exits a composite state or a submachine and forces termination of execution in all contained regions.</para> <para><inlinemediaobject> <imageobject> <imagedata fileref="images/exit.gif" width="60%" scalefit="1"/> </imageobject> </inlinemediaobject></para> <para>An entry point pseudo state allows a kind of controlled entry inside a composite. Precisely, it connects a transition outside the composite to a transition inside the composite. An important point is that this mechanism only allows a single region to be entered. In the above diagram, in region1, the initial state would become active. </para> <para><inlinemediaobject> <imageobject> <imagedata fileref="images/entry_point.gif"/> </imageobject> </inlinemediaobject></para> <para>There are also two more ways to enter a submachine (apart the obvious and more common case of a transition terminating on the submachine as shown in the region case). An explicit entry means that an inside state is the target of a transition. Unlike with direct entry, no tentative encapsulation is made, and only one transition is executed. An explicit exit is a transition from an inner state to a state outside the submachine (not supported by MSM). I would not recommend using explicit entry or exit. </para> <para><inlinemediaobject> <imageobject> <imagedata fileref="images/explicit.gif"/> </imageobject> </inlinemediaobject></para> <para>The last entry possibility is using fork. A fork is an explicit entry into one or more regions. Other regions are again activated using their initial state. </para> <para><inlinemediaobject> <imageobject> <imagedata fileref="images/fork.gif" width="70%" scalefit="1"/> </imageobject> </inlinemediaobject></para> </sect2> <sect2> <title> <command xml:id="uml-history"/>History </title> <para>UML defines two kinds of history, shallow history and deep history. Shallow history is a pseudo state representing the most recent substate of a submachine. A submachine can have at most one shallow history. A transition with a history pseudo state as target is equivalent to a transition with the most recent substate as target. And very importantly, only one transition may originate from the history. Deep history is a shallow history recursively reactivating the substates of the most recent substate. It is represented like the shallow history with a star (H* inside a circle).</para> <para> <inlinemediaobject> <imageobject> <imagedata fileref="images/history.gif" width="60%" scalefit="1"/> </imageobject> </inlinemediaobject></para> <para>History is not a completely satisfying concept. First of all, there can be just one history pseudo state and only one transition may originate from it. So they do not mix well with orthogonal regions as only one region can be “remembered”. Deep history is even worse and looks like a last-minute addition. History has to be activated by a transition and only one transition originates from it, so how to model the transition originating from the deep history pseudo state and pointing to the most recent substate of the substate? As a bonus, it is also inflexible and does not accept new types of histories. Let's face it, history sounds great and is useful in theory, but the UML version is not quite making the cut. And therefore, MSM provides a different version of this useful concept. </para> </sect2> <sect2> <title><command xml:id="uml-anonymous"/>Completion transitions / anonymous transitions</title> <para>Completion events (or transitions), also called anonymous transitions, are defined as transitions having no defined event triggering them. This means that such transitions will immediately fire when a state being the source of an anonymous transition becomes active, provided that a guard allows it. They are useful in modeling algorithms as an activity diagram would normally do. In the real-time world, they have the advantage of making it easier to estimate how long a periodically executed action will last. For example, consider the following diagram. </para> <para><inlinemediaobject> <imageobject> <imagedata fileref="images/completion.gif"/> </imageobject> </inlinemediaobject></para> <para>The designer now knows at any time that he will need a maximum of 4 transitions. Being able to estimate how long a transition takes, he can estimate how much of a time frame he will need to require (real-time tasks are often executed at regular intervals). If he can also estimate the duration of actions, he can even use graph algorithms to better estimate his timing requirements. </para> </sect2> <sect2> <title><command xml:id="UML-internal-transition"/> Internal transitions </title> <para>Internal transitions are transitions executing in the scope of the active state, being a simple state or a submachine. One can see them as a self-transition of this state, without an entry or exit action called.</para> </sect2> <sect2> <title> <command xml:id="transition-conflict"/>Conflicting transitions </title> <para>If, for a given event, several transitions are enabled, they are said to be in conflict. There are two kinds of conflicts: <itemizedlist> <listitem> <para>For a given source state, several transitions are defined, triggered by the same event. Normally, the guard condition in each transition defines which one is fired.</para> </listitem> <listitem> <para>The source state is a submachine or simple state and the conflict is between a transition internal to this state and a transition triggered by the same event and having as target another state.</para> </listitem> </itemizedlist>The first one is simple; one only needs to define two or more rows in the transition table, with the same source and trigger, with a different guard condition. Beware, however, that the UML standard wants these conditions to be not overlapping. If they do, the standard says nothing except that this is incorrect, so the implementer is free to implement it the way he sees fit. In the case of MSM, the transition appearing last in the transition table gets selected first, if it returns false (meaning disabled), the library tries with the previous one, and so on.</para> <para> <inlinemediaobject> <imageobject> <imagedata fileref="images/conflict1.gif"/> </imageobject> </inlinemediaobject></para> <para>In the second case, UML defines that the most inner transition gets selected first, which makes sense, otherwise no exit point pseudo state would be possible (the inner transition brings us to the exit point, from where the containing state machine can take over). </para> <para><inlinemediaobject> <imageobject> <imagedata fileref="images/conflict2.gif" width="60%" scalefit="1"/> </imageobject> </inlinemediaobject></para> <para>MSM handles both cases itself, so the designer needs only concentrate on its state machine and the UML subtleties (not overlapping conditions), not on implementing this behavior himself. </para> </sect2> </sect1> <sect1> <title>Added concepts</title> <itemizedlist> <listitem> <para>Interrupt states: a terminate state which can be exited if a defined event is triggered.</para> </listitem> <listitem> <para>Kleene (any) event: a transition with a kleene event will accept any event as trigger. Unlike a completion transition, an event must be triggered and the original event is kept accessible in the kleene event.</para> </listitem> </itemizedlist> </sect1> <sect1> <title>State machine glossary</title> <para> <itemizedlist> <listitem> <para>state machine: the life cycle of a thing. It is made of states, regions, transitions and processes incoming events.</para> </listitem> <listitem> <para>state: a stage in the life cycle of a state machine. A state (like a submachine) can have an entry and exit behaviors.</para> </listitem> <listitem> <para>event: an incident provoking (or not) a reaction of the state machine</para> </listitem> <listitem> <para>transition: a specification of how a state machine reacts to an event. It specifies a source state, the event triggering the transition, the target state (which will become the newly active state if the transition is triggered), guard and actions.</para> </listitem> <listitem> <para>action: an operation executed during the triggering of the transition.</para> </listitem> <listitem> <para>guard: a boolean operation being able to prevent the triggering of a transition which would otherwise fire.</para> </listitem> <listitem> <para>transition table: representation of a state machine. A state machine diagram is a graphical, but incomplete representation of the same model. A transition table, on the other hand, is a complete representation.</para> </listitem> <listitem> <para>initial state: The state in which the state machine starts. Having several orthogonal regions means having as many initial states.</para> </listitem> <listitem> <para>submachine: A submachine is a state machine inserted as a state in another state machine and can be found several times in a same state machine.</para> </listitem> <listitem> <para>orthogonal regions: (logical) parallel flow of execution of a state machine. Every region of a state machine gets a chance to process an incoming event.</para> </listitem> <listitem> <para>terminate pseudo-state: when this state becomes active, it terminates the execution of the whole state machine. MSM does not destroy the state machine as required by the UML standard, however, which lets you keep all the state machine's data.</para> </listitem> <listitem> <para>entry/exit pseudo state: defined for submachines and are defined as a connection between a transition outside of the submachine and a transition inside the submachine. It is a way to enter or leave a submachine through a predefined point.</para> </listitem> <listitem> <para>fork: a fork allows explicit entry into several orthogonal regions of a submachine.</para> </listitem> <listitem> <para>history: a history is a way to remember the active state of a submachine so that the submachine can proceed in its last active state next time it becomes active.</para> </listitem> <listitem> <para>completion events (also called completion/anonymous transitions): when a transition has no named event triggering it, it automatically fires when the source state is active, unless a guard forbids it.</para> </listitem> <listitem> <para>transition conflict: a conflict is present if for a given source state and incoming event, several transitions are possible. UML specifies that guard conditions have to solve the conflict.</para> </listitem> <listitem> <para>internal transitions: transition from a state to itself without having exit and entry actions being called.</para> </listitem> </itemizedlist> </para> </sect1> </chapter> <chapter> <title>Tutorial</title> <sect1> <title>Design</title> <para>MSM is divided between front–ends and back-ends. At the moment, there is just one back-end. On the front-end side, you will find three of them which are as many state machine description languages, with many more possible. For potential language writers, this document contains a <link xlink:href="#internals-front-back-interface">description of the interface between front-end and back-end</link>.</para> <para>The first front-end is an adaptation of the example provided in the <link xlink:href="http://boostpro.com/mplbook">MPL book</link> with actions defined as pointers to state or state machine methods. The second one is based on functors. The third, eUML (embedded UML) is an experimental language based on Boost.Proto and Boost.Typeof and hiding most of the metaprogramming to increase readability. Both eUML and the functor front-end also offer a functional library (a bit like Boost.Phoenix) for use as action language (UML defining none).</para> </sect1> <sect1> <title><command xml:id="basic-front-end"/>Basic front-end</title> <para>This is the historical front-end, inherited from the MPL book. It provides a transition table made of rows of different names and functionality. Actions and guards are defined as methods and referenced through a pointer in the transition. This front-end provides a simple interface making easy state machines easy to define, but more complex state machines a bit harder.</para> <sect2> <title>A simple example</title> <para>Let us have a look at a state machine diagram of the founding example:</para> <para><inlinemediaobject> <imageobject> <imagedata fileref="images/SimpleTutorial.jpg" width="60%" scalefit="1"/> </imageobject> </inlinemediaobject></para> <para>We are now going to build it with MSM's basic front-end. An <link xlink:href="examples/SimpleTutorial.cpp">implementation</link> is also provided.</para> </sect2> <sect2> <title>Transition table</title> <para>As previously stated, MSM is based on the transition table, so let us define one:</para> <programlisting> struct transition_table : mpl::vector&lt; // Start Event Target Action Guard // +---------+------------+-----------+---------------------------+----------------------------+ a_row&lt; Stopped , play , Playing , &amp;player_::start_playback >, a_row&lt; Stopped , open_close , Open , &amp;player_::open_drawer >, _row&lt; Stopped , stop , Stopped >, // +---------+------------+-----------+---------------------------+----------------------------+ a_row&lt; Open , open_close , Empty , &amp;player_::close_drawer >, // +---------+------------+-----------+---------------------------+----------------------------+ a_row&lt; Empty , open_close , Open , &amp;player_::open_drawer >, row&lt; Empty , cd_detected, Stopped , &amp;player_::store_cd_info , &amp;player_::good_disk_format >, row&lt; Empty , cd_detected, Playing , &amp;player_::store_cd_info , &amp;player_::auto_start >, // +---------+------------+-----------+---------------------------+----------------------------+ a_row&lt; Playing , stop , Stopped , &amp;player_::stop_playback >, a_row&lt; Playing , pause , Paused , &amp;player_::pause_playback >, a_row&lt; Playing , open_close , Open , &amp;player_::stop_and_open >, // +---------+------------+-----------+---------------------------+----------------------------+ a_row&lt; Paused , end_pause , Playing , &amp;player_::resume_playback >, a_row&lt; Paused , stop , Stopped , &amp;player_::stop_playback >, a_row&lt; Paused , open_close , Open , &amp;player_::stop_and_open > // +---------+------------+-----------+---------------------------+----------------------------+ > {}; </programlisting> <para>You will notice that this is almost exactly our founding example. The only change in the transition table is the different types of transitions (rows). The founding example forces one to define an action method and offers no guards. You have 4 basic row types:<itemizedlist> <listitem> <para><code>row</code> takes 5 arguments: start state, event, target state, action and guard.</para> </listitem> <listitem> <para><code>a_row</code> (“a” for action) allows defining only the action and omit the guard condition.</para> </listitem> <listitem> <para><code>g_row</code> (“g” for guard) allows omitting the action behavior and defining only the guard.</para> </listitem> <listitem> <para><code>_row</code> allows omitting action and guard.</para> </listitem> </itemizedlist></para> <para>The signature for an action methods is void method_name (event const&amp;), for example:</para> <programlisting>void stop_playback(stop const&amp;)</programlisting> <para>Action methods return nothing and take the argument as const reference. Of course nothing forbids you from using the same action for several events:</para> <programlisting>template &lt;class Event> void stop_playback(Eventconst&amp;)</programlisting> <para>Guards have as only difference the return value, which is a boolean:</para> <programlisting>bool good_disk_format(cd_detected const&amp; evt)</programlisting> <para>The transition table is actually a MPL vector (or list), which brings the limitation that the default maximum size of the table is 20. If you need more transitions, overriding this default behavior is necessary, so you need to add before any header:</para> <programlisting>#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #define BOOST_MPL_LIMIT_VECTOR_SIZE 30 //or whatever you need #define BOOST_MPL_LIMIT_MAP_SIZE 30 //or whatever you need </programlisting> <para>The other limitation is that the MPL types are defined only up to 50 entries. For the moment, the only solution to achieve more is to add headers to the MPL (luckily, this is not very complicated).</para> </sect2> <sect2> <title>Defining states with entry/exit actions</title> <para>While states were enums in the MPL book, they now are classes, which allows them to hold data, provide entry, exit behaviors and be reusable (as they do not know anything about the containing state machine). To define a state, inherit from the desired state type. You will mainly use simple states:</para> <para>struct Empty : public msm::front::state&lt;> {};</para> <para>They can optionally provide entry and exit behaviors:</para> <programlisting language="C++"> struct Empty : public msm::front::state&lt;> { template &lt;class Event, class Fsm> void on_entry(Event const&amp;, Fsm&amp; ) {std::cout &lt;&lt;"entering: Empty" &lt;&lt; std::endl;} template &lt;class Event, class Fsm> void on_exit(Event const&amp;, Fsm&amp; ) {std::cout &lt;&lt;"leaving: Empty" &lt;&lt; std::endl;} }; </programlisting> <para>Notice how the entry and exit behaviors are templatized on the event and state machine. Being generic facilitates reuse. There are more state types (terminate, interrupt, pseudo states, etc.) corresponding to the UML standard state types. These will be described in details in the next sections.</para> </sect2> <sect2> <title>What do you actually do inside actions / guards?</title> <para>State machines define a structure and important parts of the complete behavior, but not all. For example if you need to send a rocket to Alpha Centauri, you can have a transition to a state "SendRocketToAlphaCentauri" but no code actually sending the rocket. This is where you need actions. So a simple action could be:</para> <programlisting>template &lt;class Fire> void send_rocket(Fire const&amp;) { fire_rocket(); }</programlisting> <para>Ok, this was simple. Now, we might want to give a direction. Let us suppose this information is externally given when needed, it makes sense do use the event for this:</para> <programlisting>// Event struct Fire {Direction direction;}; template &lt;class Fire> void send_rocket(Fire const&amp; evt) { fire_rocket(evt.direction); }</programlisting> <para>We might want to calculate the direction based not only on external data but also on data accumulated during previous work. In this case, you might want to have this data in the state machine itself. As transition actions are members of the front-end, you can directly access the data:</para> <programlisting>// Event struct Fire {Direction direction;}; //front-end definition, see down struct launcher_ : public msm::front::state_machine_def&lt;launcher_>{ Data current_calculation; template &lt;class Fire> void send_rocket(Fire const&amp; evt) { fire_rocket(evt.direction, current_calculation); } ... };</programlisting> <para>Entry and exit actions represent a behavior common to a state, no matter through which transition it is entered or left. States being reusable, it might make sense to locate your data there instead of in the state machine, to maximize reuse and make code more readable. Entry and exit actions have access to the state data (being state members) but also to the event and state machine, like transition actions. This happens through the Event and Fsm template parameters:</para> <programlisting>struct Launching : public msm::front::state&lt;> { template &lt;class Event, class Fsm> void on_entry(Event const&amp; evt, Fsm&amp; fsm) { fire_rocket(evt.direction, fsm.current_calculation); } };</programlisting> <para>Exit actions are also ideal for clanup when the state becomes inactive.</para> <para>Another possible use of the entry action is to pass data to substates / submachines. Launching is a substate containing a <code>data</code> attribute:</para> <programlisting>struct launcher_ : public msm::front::state_machine_def&lt;launcher_>{ Data current_calculation; // state machines also have entry/exit actions template &lt;class Event, class Fsm> void on_entry(Event const&amp; evt, Fsm&amp; fsm) { launcher_::Launching&amp; s = fsm.get_state&lt;launcher_::Launching&amp;>(); s.data = fsm.current_calculation; } ... };</programlisting> <para>The <command xlink:href="#backend-fsm-constructor-args">set_states</command> back-end method allows you to replace a complete state.</para> <para>The <command xlink:href="#functor-front-end-actions">functor</command> front-end and eUML offer more capabilities.</para> <para>However, this basic front-end also has special capabilities using the row2 / irow2 transitions.<command xlink:href="#basic-row2">_row2, a_row2, row2, g_row2, a_irow2, irow2, g_irow2</command> let you call an action located in any state of the current fsm or in the front-end itself, thus letting you place useful data anywhere you see fit.</para> <para>It is sometimes desirable to generate new events for the state machine inside actions. Since the process_event method belongs to the back end, you first need to gain a reference to it. The back end derives from the front end, so one way of doing this is to use a cast:</para> <programlisting>struct launcher_ : public msm::front::state_machine_def&lt;launcher_>{ template &lt;class Fire> void send_rocket(Fire const&amp; evt) { fire_rocket(); msm::back::state_machine&lt;launcher_> &amp;fsm = static_cast&lt;msm::back::state_machine&lt;launcher_> &amp;>(*this); fsm.process_event(rocket_launched()); } ... };</programlisting> <para>The same can be implemented inside entry/exit actions. Admittedly, this is a bit awkward. A more natural mechanism is available using the <command xlink:href="#functor-front-end-actions">functor</command> front-end.</para> </sect2> <sect2> <title>Defining a simple state machine</title> <para>Declaring a state machine is straightforward and is done with a high signal / noise ratio. In our player e