2
0
mirror of https://github.com/boostorg/msm.git synced 2026-02-19 02:22:17 +00:00
Files
msm/doc/HTML/ar01s04.html
Christophe Henry 9f03aaa362 msm added to trunk
[SVN r62129]
2010-05-21 21:15:38 +00:00

1302 lines
144 KiB
HTML

<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>User's Guide</title><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="index.html" title="Meta State Machine (MSM)"><link rel="prev" href="ar01s03.html" title="UML Short Guide"><link rel="next" href="ar01s05.html" title="Performance / Compilers"></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">User's Guide</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ar01s03.html">Prev</a>&nbsp;</td><th width="60%" align="center">&nbsp;</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="ar01s05.html">Next</a></td></tr></table><hr></div><div class="sect1" title="User's Guide"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e402"></a>User's Guide</h2></div></div></div><div class="sect2" title="Design"><div class="titlepage"><div><div><h3 class="title"><a name="d0e405"></a>Design</h3></div></div></div><p>Msm is divided between front&#8211;ends and back-ends. At the moment, there is just one
back-end. On the front-end side, there is more to see. Msm offers several state
machine description languages with many more possible. Now, everybody can build his
own description language (in case one gets bored with the ones provided) without
changes to the library. For who feels like being a language writer this document
adds a description of the interface between front-end and back-end.TODO.</p><p>There are, at the moment, three main front-ends. The basic one is an adaptation of
the example provided in the MPL book (TODO add 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).</p></div><div class="sect2" title="Basic front-end"><div class="titlepage"><div><div><h3 class="title"><a name="d0e412"></a>Basic front-end</h3></div></div></div><p>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 easier to
define, but more complex state machines a bit harder. It also is slightly slower
than the functor and eUML front-ends (about 20%). Not that it does more, it simply
seems that the compiler better optimizes the functor actions.</p><div class="sect3" title="A simple example"><div class="titlepage"><div><div><h4 class="title"><a name="d0e417"></a>A simple example</h4></div></div></div><p>Let us have a look at a state machine diagram of the founding example:</p><p><span class="inlinemediaobject"><img src="../images/SimpleTutorial.jpg"></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">example</a> is also
provided.</p></div><div class="sect3" title="Transition table"><div class="titlepage"><div><div><h4 class="title"><a name="d0e431"></a>Transition table</h4></div></div></div><p>As previously stated, MSM is based on the transition table, so let us define
one:</p><p>struct transition_table : mpl::vector&lt;</p><p>
</p><table frame="void" id="d0e440"><tbody><tr>
<td>//</td>
<td>Start</td>
<td>Event</td>
<td>Next</td>
<td>Action</td>
<td>Guard</td>
<td> </td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>a_row &lt;</td>
<td>Stopped ,</td>
<td>play,</td>
<td>Playing,</td>
<td>&amp;player_::start_playback</td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>a_row &lt;</td>
<td>Stopped ,</td>
<td>open_close,</td>
<td>Open,</td>
<td>&amp;player_::open_drawer</td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>_row &lt;</td>
<td>Stopped ,</td>
<td>stop,</td>
<td>Stopped</td>
<td> </td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>//</td>
<td>+---------</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>a_row &lt;</td>
<td>Open ,</td>
<td>open_close ,</td>
<td>Empty ,</td>
<td>&amp;player_::close_drawer</td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>a_row &lt;</td>
<td>Empty ,</td>
<td>open_close ,</td>
<td>Open ,</td>
<td>&amp;player_::open_drawer</td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>row &lt;</td>
<td>Empty ,</td>
<td>cd_detected ,</td>
<td>Stopped ,</td>
<td>&amp;player_::store_cd_info ,</td>
<td>&amp;player_::good_disk_format</td>
<td>&gt;,</td>
</tr><tr>
<td>row &lt;</td>
<td>Empty ,</td>
<td>cd_detected ,</td>
<td>Playing ,</td>
<td>&amp;player_::store_cd_info ,</td>
<td>&amp;player_::auto_start</td>
<td>&gt;,</td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>a_row &lt;</td>
<td>Playing ,</td>
<td>stop ,</td>
<td>Stopped ,</td>
<td>&amp;player_::stop_playback</td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>a_row &lt;</td>
<td>Playing ,</td>
<td>pause ,</td>
<td>Paused ,</td>
<td>&amp;player_::pause_playback</td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>a_row &lt;</td>
<td>Playing ,</td>
<td>open_close ,</td>
<td>Open ,</td>
<td>&amp;player_::stop_and_open</td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>a_row &lt;</td>
<td> Paused ,</td>
<td>end_pause ,</td>
<td>Playing ,</td>
<td>&amp;player_::resume_playback</td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>a_row &lt;</td>
<td> Paused ,</td>
<td>stop ,</td>
<td>Stopped ,</td>
<td>&amp;player_::stop_playback</td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>a_row &lt;</td>
<td> Paused ,</td>
<td>open_close ,</td>
<td>Open ,</td>
<td>&amp;player_::stop_and_open</td>
<td> </td>
<td>&gt;</td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>&gt; {};</td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr></tbody></table><p>
</p><p>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:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><code class="code">row</code> takes 5 arguments: start state, event, next
state, action and guard.</p></li><li class="listitem"><p><code class="code">a_row</code> (&#8220;a&#8221; for action) allows defining only the
action and omit the guard condition.</p></li><li class="listitem"><p><code class="code">g_row</code> (&#8220;g&#8221; for guard) allows omitting the action
method and defining only the guard.</p></li><li class="listitem"><p><code class="code">_row</code> allows omitting action and guard methods.</p></li></ul></div><p>The signature for action methods is:</p><p><code class="code">void stop_playback(stop const&amp;)</code></p><p>Action methods return nothing and take the argument as const reference. Of
course nothing forbids you from defining an action for several events:</p><p><code class="code">template &lt;class Event&gt; void stop_playback(Event
const&amp;)</code></p><p>Guards have as only difference the return value, which is a boolean:</p><p><code class="code">bool good_disk_format(cd_detected const&amp; evt)</code></p><p>The transition table is actually a MPL vector (or list), which brings a
limitation that the default maximum size of the table is 20. If you need more
transitions, overriding this default behavior is necessary, for example add
before any header:</p><p><code class="code">#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS </code></p><p><code class="code">#define BOOST_MPL_LIMIT_VECTOR_SIZE 30 // or whatever you need
</code></p><p><code class="code">#define BOOST_MPL_LIMIT_MAP_SIZE 30 // or whatever you need
</code></p><p>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).TODO add them</p></div><div class="sect3" title="Defining states with entry/exit actions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e977"></a>Defining states with entry/exit actions</h4></div></div></div><p>While states were enums in the MPL book, they now are structs, which allows
them to hold data, provide entry, exit actions, different behaviors and be
reusable (as they do not know anything about the containing state machine). To
define a state, inherit from the correct state type:</p><p>struct Empty : public msm::front::state&lt;&gt; {};</p><p>They can optionally provide entry and exit behaviors:</p><p><code class="code">struct Empty : public msm::front::state&lt;&gt; {</code></p><p><code class="code">template &lt;class Event, class Fsm&gt; </code></p><p><code class="code">void on_entry(Event const&amp;, Fsm&amp; ) {std::cout &lt;&lt;
"entering: Empty" &lt;&lt; std::endl;} </code></p><p><code class="code">template &lt;class Event, class Fsm&gt; </code></p><p><code class="code">void on_exit(Event const&amp;, Fsm&amp; ) {std::cout &lt;&lt; "leaving:
Empty" &lt;&lt; std::endl;} </code></p><p><code class="code">};</code></p><p>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 pages.</p></div><div class="sect3" title="Defining a simple state machine"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1006"></a>Defining a simple state machine</h4></div></div></div><p>Declaring a state machine is straightforward and is done with a high signal /
noise ratio. In our player example, we declare the state machine as:</p><p><code class="code">struct player_ : public msm::front::state_machine_def&lt;player_&gt;{ /*
see below */}</code></p><p>This declares a state machine using the basic front-end. We now declare inside
the state machine structure the initial state:</p><p><code class="code">typedef Empty initial_state;</code></p><p>And that is about all of what is absolutely needed. In the example, the states
are declared inside the state machine for readability but this is not a
requirements, states can be declared wherever you see fit.</p><p>All what is left to us is to pick a back-end (which is quite simple as there
is only one at the moment):</p><p><code class="code">typedef msm::back::state_machine&lt;player_&gt; player;</code></p><p>You now have a ready-to-use state machine with entry/exit actions, guards,
transition actions, a message queue so that processing an event can generate
another event. The state machine also adapted itself to your need and removed
almost all features we didn't use in this simple example. Note that this is not
per default the faster possible state machine. See the section "getting more
speed" to know how to get the maximum speed. In a nutshell, MSM cannot know
about your usage of some features so you will have to explicitly tell it.</p><p>TODO no_transition TODO start fct</p></div><div class="sect3" title="Defining a submachine"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1030"></a>Defining a submachine</h4></div></div></div><p>We now want to extend our last state machine by making the Playing state a
state machine itself (a submachine).</p><p><span class="inlinemediaobject"><img src="../images/CompositeTutorial.jpg"></span></p><p>Again, an <a class="link" href="examples/CompositeTutorial.cpp" target="_top">example</a> is
also provided.</p><p>A submachine really is a state machine itself, so we declare Playing as such,
choosing a front-end and a back-end:</p><p><code class="code">struct Playing_ : public msm::Front::state_machine_def&lt;Playing_&gt;{...}
</code></p><p><code class="code">typedef msm::back::state_machine&lt;Playing_&gt; Playing;</code></p><p>Like for any state machine, one also needs a transition table and an initial
state:</p><p>struct transition_table : mpl::vector&lt;</p><table id="d0e1056"><tbody><tr>
<td>//</td>
<td>Start</td>
<td>Event</td>
<td>Next</td>
<td>Action</td>
<td>Guard</td>
<td> </td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>------------------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>a_row &lt;</td>
<td>Song1 ,</td>
<td>NextSong,</td>
<td>Song2,</td>
<td>&amp;Playing_::start_next_song </td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>a_row &lt;</td>
<td>Song2 ,</td>
<td>PreviousSong,</td>
<td>Song1,</td>
<td>&amp;Playing_::start_prev_song </td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>a_row &lt;</td>
<td>Song2 ,</td>
<td>NextSong,</td>
<td>Song3,</td>
<td>&amp;Playing_::start_next_song </td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>a_row &lt;</td>
<td>Song3 ,</td>
<td>PreviousSong ,</td>
<td>Song2 ,</td>
<td>&amp;Playing_::start_prev_song </td>
<td> </td>
<td>&gt;</td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>------------------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>&gt; {};</td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr></tbody></table><p><code class="code">typedef Song1 initial_state; </code></p><p>This is about all you need to do. MSM will now automatically recognize Playing
as a submachine and all events handled by Playing (NextSong and PreviousSong)
will now be automatically forwarded to Playing whenever this state is active.
All other state machine features described later are also available.</p></div><div class="sect3" title="Orthogonal regions, terminate state, event deferring"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1247"></a>Orthogonal regions, terminate state, event deferring</h4></div></div></div><p>It is a very common problem in many state machines to have to handle errors.
It usually involves defining a transition from all the states to a special error
state. Translation: not fun. It is also not practical to find from which state
the error originated. The following diagram shows an example of what clearly
becomes not very readable:</p><p><span class="inlinemediaobject"><img src="../images/error_no_regions.jpg"></span></p><p>This is neither very readable nor beautiful, clearly. And we do not even have
any action on the transitions yet.</p><p>Luckily, UML provides a helpful concept, orthogonal regions. See them as
lightweight state machines running at the same time in a same state machine and
having the capability to influence one another. The effect is that you have
several active states at any time. We can therefore keep our state machine from
the previous example and just define a new region made of two states, AllOk and
ErrorMode. AllOk is most of the time active. But the error_found error event
makes the second region move to the new active state ErrorMode. This event does
not interest the main region so it will simply be ignored.
"<code class="code">no_transition</code>" will be called only if no region at all handles
the event. </p><p>Adding an orthogonal region is easy, one only needs to declare more states in
the <code class="code">initial_state</code> typedef. So, adding a new region with AllOk as
the region's initial state is:</p><p><code class="code">typedef mpl::vector&lt;Empty,AllOk&gt; initial_state;</code></p><p><span class="inlinemediaobject"><img src="../images/Orthogonal-deferred.jpg"></span></p><p>Furthermore, when you detect an error, you usually do not want other events to
be handled. To achieve this, we use another UML feature, terminate states. When
any region moves to a terminate state, the state machine &#8220;terminates&#8221; (the state
machine and all its states stay alive) and all further events are ignored. This
is of course not mandatory, one can use orthogonal regions without terminate
states. Also note that, as UML mandates, every region gets a chance of handling
the event, in the order as declared by the <code class="code">initial_state</code> type. MSM
also provides a small extension to UML, interrupt states. If you declare
ErrorMode as interrupt state instead of terminate state, the state machine will
not handle any event other than the one which ends the interrupt. So it's like a
terminate state, with the difference that you are allowed to resume the state
machine when a condition (like handling of the original error) is met. </p><p>Last but not least, this example also shows here the handling of event
deferring. Let's say someone puts a disc and immediately presses play. The event
cannot be handled, yet you'd want it to be handled at a later point and not
force the user to press play again. The solution is to define it as deferred in
the Empty and Open states and get it handled in the first state where the event
is not to be deferred. It can then be handled or rejected. In this example, when
Stopped becomes active, the event will be handled because only Empty and Open
defer the event.</p><p>Notice how UML defines event deferring as a state property. To accomodate
this, MSM lets you specify this in states by providing a
<code class="code">deferred_events</code> type:</p><p><code class="code">struct Empty : public msm::front::state&lt;&gt; </code></p><p><code class="code">{ </code></p><p><code class="code">// if the play event is fired while in this state, defer it until a
state </code></p><p><code class="code">// handles or rejects it</code></p><p><code class="code"> typedef mpl::vector&lt;play&gt; deferred_events;</code></p><p><code class="code">...};</code></p><p>Please have a look at the <a class="link" href="examples/Orthogonal-deferred.cpp" target="_top">complete example</a>.</p><p>While this is wanted by UML and is simple, it is not always practical because
one could wish to defer only in certain conditions. One could also want to make
this be part of a transition action with the added bonus of a guard. It would
also be conform to the MSM philosophy to get as much as possible in the
transition table, where you can have all the important state machine structure
grouped together. This is also possible but not practical with this front-end so
we will need to pick a different row from the functor front-end. For a complete
description of the <code class="code">Row</code> type, please have a look at the <span class="command"><strong><a class="command" href="ar01s04.html#functor-front-end">functor front-end.</a></strong></span></p><p>First, as there is no state where MSM can detect the requirement of this
feature, we need to require deferred events capability explicitly, by adding a
type in the state machine definition:</p><p><code class="code">struct player_ : public
msm::front::state_machine_def&lt;player_&gt;</code></p><p><code class="code">{ </code></p><p><code class="code">typedef int activate_deferred_events;</code></p><p><code class="code">...};</code></p><p>We can now defer an event in any transition of the transition table by using
as action the predefined <code class="code">msm::front::Defer</code> functor, for
example:</p><p><code class="code">Row &lt; Empty , play , none , Defer , none &gt;</code></p><p>This is an internal transition row(see <span class="command"><strong><a class="command" href="ar01s04.html#internal-transitions">internal transitions</a></strong></span>) but you
can ignore this for the moment. It just means that we are not leaving the Empty
state. What matters is that we use Defer as action. This is roughly equivalent
to the previous syntax but has the advantage of giving you all the information
in the transition table.</p><p>The second difference is that as we now have a transition defined, this
transition can play in the resolution of <span class="command"><strong><a class="command" href="ar01s03.html#transition-conflict">transition conflicts</a></strong></span>. For
example, we could model an "if (condition2) move to Playing else if (condition1)
defer play event":</p><p>
<code class="code">Row &lt; Empty , play , none , Defer , condition1 &gt;,</code></p><p><code class="code">g_row &lt; Empty , play , Playing , &amp;player_::condition2
&gt;</code></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="sect3" title="History"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1361"></a>History</h4></div></div></div><p>UML defines two types of history, Shallow History and Deep History. What is it
and when do you need it? In the previous examples, if the player was playing the
second song and the user pressed pause, leaving Playing, at the next press on
the play button, the Playing state would become active and the first song would
play again. Soon would the first client complaints follow. They'd of course
demand, that if the player was paused, then it should remember which song was
playing. But it the player was stopped, then it should restart from the first
song. Now, how can it be done? Of course, you could add a bit of programming
logic and generate extra events to make the second song start if coming from
Pause. Something like: </p><p><code class="code">if (Event == end_pause) { for (int i=0;i&lt; song number;++i) {
player.process_event(NextSong()); } } </code></p><p>Not much to like in this example, isn't it? To solve this problem, you define
what is called a shallow or a deep history. A shallow history reactivates the
last active state of a submachine when this state machine becomes active again.
The deep history does the same recursively, so if this last active state of the
submachine was itself a submachine, its last active state would become active
and this will continue until an active state is a normal state. For example, let
us have a look at the following UML diagram: </p><p><span class="inlinemediaobject"><img src="../images/HistoryTutorial.jpg"></span></p><p>Notice that the main difference compared to previous diagrams is that the
initial state is gone and replaced by a History symbol (the H inside a
circle).</p><p>As explained in the <span class="command"><strong><a class="command" href="ar01s03.html#uml-history">small UML
tutorial</a></strong></span>, History is a good concept with a not completely
satisfying specification. MSM kept the concept but not the specification. Msm
goes another way and makes this a policy so you can define your own history
types. Furthermore, History is a backend policy. This allows you to reuse the
same state machine frontend with different history policies.</p><p>Concretely, your frontend stays unchanged:</p><p><code class="code">struct Playing_ : public
msm::front::state_machine_def&lt;Playing_&gt;</code></p><p>You then add the policy to the backend:</p><p><code class="code">typedef
msm::back::state_machine&lt;Playing_,msm::back::ShallowHistory&lt;mpl::vector&lt;end_pause&gt;
&gt; &gt; Playing;</code></p><p>This states that a shallow history must be activated if the Playing state
machine gets activated by the end_pause event and only this one (or any other
event added to the mpl::vector). If the state machine was in the Stopped state
and the event play was generated, the history would not be activated and the
normal initial state would become active. By default, history is disabled. For
your convenience the library provides in addition to ShallowHistory a non-UML
standard AlwaysHistory policy (likely to be your main choice) which always
activates history, whatever event triggers the submachine activation. Deep
history is not directly available. The reason is that it would conflict with
policies which submachines could define. Of course, if for example, Song1 were a
state machine itself, it could use the ShallowHistory policy itself thus
creating Deep History. </p></div><div class="sect3" title="Anonymous transitions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1394"></a>Anonymous transitions</h4></div></div></div><p><span class="command"><strong><a name="anonymous-transitions"></a></strong></span>The following diagram shows an
example making use of this feature:</p><p><span class="inlinemediaobject"><img src="../images/Anonymous.jpg"></span></p><p>Anonymous transitions are transitions without a named event. This means that
the transition automatically fires when the predecessor state is entered (to be
exact, after the entry action). Otherwise it is a normal transition with actions
and guards. Why would you need something like that? A possible case would be if
a part of your state machine implements some algorithm, where states are steps
of the algorithm implementation. Then, using several anonymous transitions with
different guard conditions, you are actually implementing some if/else
statement. Another possible use would be a real-time system called at regular
intervals and always doing the same thing, meaning implementing the same
algorithm. The advantage is that once you know how long a transition takes to
execute on the system, by calculating the longest path (the number of
transitions from start to end), you can pretty much know how long your algorithm
will take in the worst case, which in turns tells you how big of a time frame
you are to request from a scheduler. </p><p>If you are using Executable UML (a good book describing it is "Executable UML,
a foundation for Model-Driven Architecture"), you will notice that it is common
for a state machine to generate an event to itself only to leave 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
deactivate it and you will not pay for it. If you use it, there is however a
small performance penalty as MSM will try to fire a compound event (the other
UML name for anonymous transitions) after every taken transition. This will
therefore double the event processing cost, which is not as bad as it sounds as
MSM&#8217;s execution speed is very high anyway.</p><p>To define such a transition, use &#8220;none&#8221; as event in the transition table, for
example:</p><p><code class="code">row &lt; State3 , none , State4 , &amp;p::State3ToState4 ,
&amp;p::always_true &gt;</code></p><p><a class="link" href="examples/AnonymousTutorial.cpp" target="_top">An implementation</a> of
the state machine diagram is also provided.</p></div><div class="sect3" title="Internal transitions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1419"></a><span class="command"><strong><a name="internal-transitions"></a></strong></span>Internal transitions</h4></div></div></div><p>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. This is
useful when all you want is to execute some code for a given event in a given
state.</p><p>Internal transitions are specified as having a higher priority than normal
transitions. While it makes sense for a submachine with exit points, it is
surprising for a simple state. MSM lets you define the transition priority by
setting the transition&#8217;s position inside the transition table (see <span class="command"><strong><a class="command" href="ar01s07.html#run-to-completion">internals</a></strong></span> ). The difference
between "normal" and internal transitions is that internal transitions have no
target state, therefore we need new row types. We had a_row, g_row, _row and
row, we now add a_irow, g_irow, _irow and irow which are like normal transitions
but define no target state. For, example an internal transition with a guard
condition could be:</p><p><code class="code">g_irow &lt; Empty /*state*/ , cd_detected
/*event*/,&amp;p::internal_guard /* guard */ &gt;</code></p><p>These new row types can be placed anywhere in the transition table so that you
can still have your state machine structure grouped together. The only
difference of behavior with the UML standard is the missing notion of priority.
Please have a look at <a class="link" href="examples/SimpleTutorialInternal.cpp" target="_top">the
example</a>.</p><p>It is also possible to do it the UML-conform way by declaring a transition
table called <code class="code">internal transition_table</code> inside the state itself and
using internal row types. For example:</p><p><code class="code">struct Empty : public msm::front::state&lt;&gt; {</code></p><p><code class="code">struct internal_transition_table : mpl::vector&lt;</code></p><p><code class="code">a_internal &lt; cd_detected , Empty, &amp;Empty::internal_action
&gt;</code></p><p><code class="code">&gt; {};</code></p><p><code class="code">};</code></p><p>This declares an internal transition table called internal_transition_table
and reacting on the event cd_detected by calling 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
internal_transition_table</p></li><li class="listitem"><p>they use different but similar row types: a_internal, g_internal,
_internal and internal.</p></li><li class="listitem"><p>These types take as first template argument the triggering event
and then the action and guard method. Note that the only real
difference to classical rows is the extra argument before the
function pointer. This is the type on which the function will be
called.</p></li><li class="listitem"><p>This also allows you, if you wish, to define actions and guards in
another state of the state machine or in the state machine
itself.</p></li><li class="listitem"><p>submachines can have an internal transition table and a classical
transition table.</p></li></ul></div><p>The <a class="link" href="examples/TestInternal.cpp" target="_top">following example</a>
makes use of an a_internal. It also uses functor-based internal transitions
which will be explained in <span class="command"><strong><a class="command" href="ar01s04.html#functor-internal-transitions">the functor front-end</a></strong></span>, please ignore them for the moment. Also
note that the state-defined internal transitions, having following the UML
standard the highest priority, are tried before those defined inside the 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 compile
faster. It also lets you choose the priority of your internal
transition.</p></li><li class="listitem"><p>the second version is more logical from a UML perspective and lets
you make states more useful and reusable. It also allows you to call
actions and guards on any state of the state machine</p></li></ul></div><p>
<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
possibility coming from this feature. The <code class="code">internal_transition_table</code>
transitions being added directly inside the main state machine's transition
table, it is possible, if it is more to your state, to distribute your state
machine definition a bit like Boost.Statechart, leaving the state machine itself
the only task of declaring the states it wants to use using the
<code class="code">explicit_creation</code> type definition. While this is not the
author's favorite way, it is still possible. A simplified example using only two
states will make it clearer:</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
standard transition_table and an internal_transition_table (which has higher
priority). This makes it easier if you decide to make a full submachine from a
state. It is also slightly faster than the standard alternative, adding
orthogonal regions, because event dispatching will, if accepted by the internal
table, not continue to the subregions. This gives you a O(1) dispatch instead of
O(number of regions). While the example is with eUML, the same is also possible
with this front-end.</p></div><div class="sect3" title="more row types"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1532"></a>more row types</h4></div></div></div><p>It is also possible to write transitions using actions and guard conditions
not just from the state machine but also from its contained states. In this
case, one must specify not just a method pointer but also the object on which to
call it. This transition row is called, not very originally, <code class="code">row2</code>.
They come, like normal transitions in four flavors: <code class="code">a_row2, g_row2, _row2
and row2</code>. For example, a transition calling an action from the state
Empty could be:</p><p><code class="code">a_row2 &lt; Stopped , open_close , Open , Empty /*action source*/ ,
&amp;Empty::open_drawer /*action*/&gt;</code></p><p>The same capabilities are also available for internal transitions so that we
have: <code class="code">a_irow2, g_irow2, _irow2 and row2</code>. For transitions defined as
part of the <code class="code">internal_transition_table</code>, you can use the <span class="command"><strong><a class="command" href="ar01s04.html#internal-transitions">a_internal, g_internal, _internal,
internal</a></strong></span> row types.</p><p>These row types allow us to distribute the state machine code among states,
making them reusable and more valuable. Using transition tables inside states
also contributes to this possibility. An <a class="link" href="examples/SimpleTutorial2.cpp" target="_top">example</a> of these new tows
is also provided.</p></div><div class="sect3" title="Explicit entry / entry and exit pseudo-state / fork"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1562"></a>Explicit entry / entry and exit pseudo-state / fork</h4></div></div></div><p>MSM (almost) fully supports these features described in the <span class="command"><strong><a class="command" href="ar01s03.html#uml-history">small UML tutorial</a></strong></span>. Almost because 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 target
but not a sub-sub state.</p></li><li class="listitem"><p>it is not possible to explicitly exit. Exit points must be
used.</p></li></ul></div><p>Let us see a concrete example:</p><p><span class="inlinemediaobject"><img src="../images/entry%20tutorial.jpg"></span></p><p>We find in this diagram:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>A &#8220;normal&#8221; entering into SubFsm2 triggered by event1 and back to
State1 using the same event. In each zone is the initial state
activated, i.e. SubState1 and SubState1b.</p></li><li class="listitem"><p>An explicit entry into SubFsm2::SubState2 for zone &#8220;a&#8221; with event2
as trigger, meaning that in region &#8220;b&#8221; the initial state,
SubState1b, activated.</p></li><li class="listitem"><p>A fork into zones &#8220;a&#8221; and &#8220;b&#8221; to the explicit entries SubState2
and SubState2b, triggered by event3. Both states become active so no
zone is default activated (if we had a third zone, it would
be).</p></li><li class="listitem"><p>A connection of two transitions through an entry pseudo state,
SubFsm2::PseudoEntry1, triggered by event4 and triggering also the
second transition on the same event (both transitions must be
triggered by the same event). Zone &#8220;b&#8221; gets default-activated and
SubState1b becomes active.</p></li><li class="listitem"><p>An exit from SubFsm2 using an exit pseudo-state, PseudoExit1,
triggered by event5 and connecting two transitions using the same
event. Again, the event is forwarded to the second transition and
both regions are exited, as SubFsm2 becomes inactive. Note that if
no transition is defined from PseudoExit1, an error (as defined in
the UML standard) will be 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="sect4" title="Explicit entry"><div class="titlepage"><div><div><h5 class="title"><a name="d0e1608"></a>Explicit entry</h5></div></div></div><p>First, to define that a state is an explicit entry, you have to make it a
state and mark it as explicit, giving as template parameters the zone id
(the zone id starts with 0 and corresponds to the first initial state of the
initial_state type sequence).</p><p><code class="code">struct SubState2 : public msm::front::state&lt;&gt; , public
msm::front::explicit_entry&lt;0&gt;</code></p><p>And define the submachine as:</p><p><code class="code">typedef msm::back::state_machine&lt;SubFsm2_&gt; SubFsm2;</code></p><p>You can then use it as target in a transition with State1 as
source:</p><p><code class="code">_row &lt; State1, Event2, SubFsm2::direct&lt; SubFsm2_::SubState2&gt;
&gt;</code></p><p>The syntax deserves some explanation. SubFsm2_ is a front end. SubState2
is a nested state, therefore the SubFsm2_::SubState2 syntax. The containing
machine (containing State1 and SubFsm2) refers to the backend instance
(SubFsm2). SubFsm2::direct states that a direct entry is desired.</p><p><span class="underline">Note (also valid for forks)</span>: in
order to make compile time more bearable for the more standard cases, and
unlike initial states, explicit entry states which are also not found in the
transition table of the entered submachine (a rare case) do NOT get
automatically created. To explicitly create such states, you need to add in
the state machine containing the explicit states a simple typedef giving a
sequence of states to be explicitly created like:</p><p><code class="code">typedef mpl::vector&lt;SubState2,SubState2b&gt;
explicit_creation;</code></p></div><div class="sect4" title="Fork"><div class="titlepage"><div><div><h5 class="title"><a name="d0e1635"></a>Fork</h5></div></div></div><p>Need a fork instead of an explicit entry? Then, as a fork is an explicit
entry into states of different regions, we do not change the state
definition compared to the explicit entry and specify as target a list of
explicit entry states:</p><p><code class="code">_row &lt; State1, Event3, mpl::vector&lt;SubFsm2::direct&lt;
SubFsm2_::SubState2&gt;, SubFsm2::direct &lt;SubFsm2_::SubState2b&gt;
&gt;</code></p><p>With SubState2 defined as before and SubState2b defined as being in the
second region (Caution: MSM does not check that the region is
correct):</p><p><code class="code">struct SubState2b : public msm::front::state&lt;&gt; , public
msm::front::explicit_entry&lt;1&gt;</code></p></div><div class="sect4" title="Entry pseudo states"><div class="titlepage"><div><div><h5 class="title"><a name="d0e1648"></a>Entry pseudo states</h5></div></div></div><p> To define an entry pseudo state, you need derive from the corresponding
class and give the region id:</p><p><code class="code">struct PseudoEntry1 : public
msm::front::entry_pseudo_state&lt;0&gt;</code></p><p>And add the corresponding transition in Fsm's transition table:</p><p><code class="code">_row &lt; State1, Event4,
SubFsm2::entry_pt&lt;SubFsm2_::PseudoEntry1&gt; &gt;</code></p><p>And another in the SubFsm2_ submachine definition (remember that UML
defines an entry point as a connection between two transitions), for example
this time with an action method:</p><p><code class="code">_row &lt; PseudoEntry1, Event4, SubState3,
&amp;SubFsm2_::entry_action &gt;</code></p></div><div class="sect4" title="Exit pseudo states"><div class="titlepage"><div><div><h5 class="title"><a name="d0e1666"></a> Exit pseudo states </h5></div></div></div><p>And finally, exit pseudo states are to be used almost the same way, but
defined differently: it takes as template argument the event to be forwarded
(no region id is necessary):</p><p><code class="code">struct PseudoExit1 : public
exit_pseudo_state&lt;event6&gt;</code></p><p>And you need, as for entry pseudo states, two transitions, one in the
submachine:</p><p><code class="code">_row &lt; SubState3, Event5, PseudoExit1 &gt;</code></p><p>And one in the containing state machine:</p><p><code class="code">_row &lt; SubFsm2::exit_pt&lt;SubFsm2_::PseudoExit1&gt;, Event6, State2
&gt;</code></p><p><span class="underline">Important note 1:</span> UML defines
transiting to an entry pseudo state and having either no second transition
or one with a guard as an error but defines no error handling. MSM will
tolerate this behavior; the entry pseudo state will simply be the newly
active state.</p><p><span class="underline">Important note 2</span>: UML defines
transiting to an exit pseudo state and having no second transition as an
error, and also defines no error handling. Therefore, it was decided to
implement exit pseudo state as terminate states and the containing composite
not properly exited will stay terminated as it was technically
&#8220;exited&#8221;.</p><p><span class="underline">Important note 3:</span> UML states that
for the exit point, the same event must be used in both transitions. MSM
relaxes this rule and only wants the event on the inside transition to be
convertible to the one of the outside transition. In our case, event6 is
convertible from event5. Notice that the forwarded event must be named in
the exit point definition. For example, we could define event6 as simply
as:</p><p><code class="code">struct event6 { event6(){} template &lt;class Event&gt; event6(Event
const&amp;){} };//convertible from any event</code>
</p></div></div><div class="sect3" title="Flags"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1700"></a>Flags</h4></div></div></div><p>This <a class="link" href="examples/Flags.cpp" target="_top">tutorial</a> is devoted to a
concept not defined in UML: flags. It has been added into MSM after proving
itself useful on many occasions. Please, do not be frightened as we are not
talking about ugly shortcuts made of an improbable collusion of Booleans.</p><p>If you look into the Boost.Statechart documentation you'll find some code
like:</p><p><code class="code">if ( ( state_downcast&lt; const NumLockOff * &gt;() != 0 ) &amp;&amp;
</code></p><p><code class="code">( state_downcast&lt; const CapsLockOff * &gt;() != 0 ) &amp;&amp;
</code></p><p><code class="code">( state_downcast&lt; const ScrollLockOff * &gt;() != 0 ) ) </code></p><p>While correct and found in many UML books, this can be error-prone and a
potential time-bomb when your state machine grows and you add new states or
orthogonal regions.</p><p>And most of all, it hides the real question, which would be &#8220;does my state
machine's current state define a special property&#8221;? In this special case &#8220;are my
keys in a lock state&#8221;? So let's apply the Fundamental Theorem of 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 loaded
CD. We could do the same:</p><p><code class="code">if ( ( state_downcast&lt; const Stopped * &gt;() != 0 ) &amp;&amp;
</code></p><p><code class="code">( state_downcast&lt; const Open * &gt;() != 0 ) &amp;&amp; </code></p><p><code class="code">( state_downcast&lt; const Paused * &gt;() != 0 ) &amp;&amp;</code></p><p><code class="code">( state_downcast&lt; const Playing * &gt;() != 0 )</code></p><p><code class="code"> ) </code></p><p>Or flag these 4 states as CDLoaded-able. You add a flag_list type into each
flagged state:</p><p><code class="code">typedef mpl::vector1&lt;CDLoaded&gt; flag_list;</code></p><p>You can even define a list of flags, for example in Playing:</p><p><code class="code">typedef mpl::vector2&lt;PlayingPaused,CDLoaded&gt; flag_list;</code></p><p>This means that Playing supports both properties. Now to check if your player
has a loaded CD, check if your flag is active in the current state:</p><p><code class="code">player p; if (p.is_flag_active&lt;CDLoaded&gt;()) ... </code></p><p>And what if you have orthogonal regions? How to decide if a state machine is
in a flagged state? By default, you keep the same code and the current states
will be OR'ed, meaning if one of the active states has the flag, then
is_flag_active returns true. Of course, in some cases, you might want that all
of the active states are flagged for the state to be active. You can also AND
the active states:</p><p><code class="code">if (p.is_flag_active&lt;CDLoaded,player::Flag_AND&gt;()) ...</code></p><p>The following diagram displays the flag situation in the tutorial.</p><p><span class="inlinemediaobject"><img src="../images/FlagsTutorial.jpg"></span></p></div><div class="sect3" title="Event Hierarchy"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1766"></a>Event Hierarchy</h4></div></div></div><p>There are cases where transitions with many related but different events are
needed. An example is text parsing. Let's say you want to parse a string and use
a state machine to handle you parsing state. You want to parse 4 digits and
decide to use a state for every matched digit. Your state machine could look
like:</p><p><span class="inlinemediaobject"><img src="../images/ParsingDigits.jpg"></span></p><p>But how to detect the digit event? We would like to avoid having to define 10
transitions on char_0, char_1... between two states as it would force us to
write 4 x 10 transitions and the compile-time would suffer. To solve this
problem, MSM supports the triggering of a transition on a subclass event. For
example, if we define digits as: </p><p><code class="code">struct digit {};</code></p><p><code class="code">struct char_0 : public digit {}; </code></p><p>And to the same for other digits, we can now fire char_0, char_1 events and
this will cause a transition with "digit" as trigger to be taken.</p><p>An example with performance measurement, taken from the documentation of
Boost.Xpressive illustrates this example (TODO). You might notice that the
performance is actually very good (better).</p></div><div class="sect3" title="Containing state machine (deprecated)"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1787"></a> Containing state machine (deprecated)</h4></div></div></div><p>This feature is still supported in MSM for backward compatibility but made
obsolete by the fact that every guard/action/entry action/exit action get the
state machine passed as argument and might be removed at a later time.</p><p>All of the states defined in the state machine are created upon state machine
construction. This has the huge advantage of a reduced syntactic noise. The cost
is a small loss of control of the user on the state creation and access. But
sometimes you needed a way for a state to get access to its containing state
machine. Basically, a state needs to change its declaration to:</p><p><code class="code">struct Stopped : public msm::front::state&lt;sm_ptr&gt;</code></p><p>And to provide a set_sm_ptr function: <code class="code">void set_sm_ptr(player*
pl)</code></p><p>to get a pointer to the containing state machine. The same applies to
terminate_state / interrupt_state and entry_pseudo_state / exit_pseudo_state.
</p></div></div><div class="sect2" title="Functor front-end"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1803"></a><span class="command"><strong><a name="functor-front-end"></a></strong></span>Functor front-end</h3></div></div></div><p>The functor front-end is the preferred front-end at the moment. It is more
powerful than the standard front-end, slightly faster and has a more readable
transition table. It also makes it easier to reuse parts of state machines. Like
<span class="command"><strong><a class="command" href="ar01s04.html#eUML-front-end">eUML</a></strong></span>, il also comes with a good
deal of predefined actions. Actually, eUML generates a functor front-end through
Boost.Typeof and Boost.Proto so both offer the same functionality.</p><p>The rows which MSM offers come in different flavors. We saw the a_row, g_row,
_row, row, not counting internal rows. This is already much to know, so why define
new rows? These types have some disadvantages: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>They are more typing and information than we would wish. This means
syntactic noise.</p></li><li class="listitem"><p>Function pointers are weird in C++.</p></li><li class="listitem"><p>The action/guard signature is limited and does not allow for more
variations of parameters (source state, target state, current state
machine, etc.)</p></li><li class="listitem"><p>It is not easy to reuse action code from a state machine to
another.</p></li></ul></div><div class="sect3" title="Transition table"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1827"></a> Transition table </h4></div></div></div><p>We can change the definition of the simple tutorial's transition table
to:</p><p>
</p><table id="d0e1834"><tbody><tr>
<td>//</td>
<td>Start</td>
<td>Event</td>
<td>Next</td>
<td>Action</td>
<td>Guard</td>
<td> </td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>Row &lt;</td>
<td>Stopped ,</td>
<td>play,</td>
<td>Playing,</td>
<td>start_playback</td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>Row &lt;</td>
<td>Stopped ,</td>
<td>open_close,</td>
<td>Open,</td>
<td>open_drawer,</td>
<td> none</td>
<td>&gt;,</td>
</tr><tr>
<td>Row &lt;</td>
<td>Stopped ,</td>
<td>stop,</td>
<td>Stopped,</td>
<td> </td>
<td> none</td>
<td>&gt;,</td>
</tr><tr>
<td>//</td>
<td>+---------</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>Row &lt;</td>
<td>Open ,</td>
<td>open_close ,</td>
<td>Empty ,</td>
<td>close_drawer,</td>
<td> none</td>
<td>&gt;,</td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>Row &lt;</td>
<td>Empty ,</td>
<td>open_close ,</td>
<td>Open ,</td>
<td>open_drawer</td>
<td> </td>
<td>&gt;,</td>
</tr><tr>
<td>Row &lt;</td>
<td>Empty ,</td>
<td>cd_detected ,</td>
<td>Stopped ,</td>
<td>store_cd_info ,</td>
<td>good_disk_format</td>
<td>&gt;,</td>
</tr><tr>
<td>g_row &lt;</td>
<td>Empty ,</td>
<td>cd_detected ,</td>
<td>Playing ,</td>
<td>store_cd_info ,</td>
<td>&amp;player_::auto_start</td>
<td>&gt;,</td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>Row &lt;</td>
<td>Playing ,</td>
<td>stop ,</td>
<td>Stopped ,</td>
<td>stop_playback,</td>
<td> none</td>
<td>&gt;,</td>
</tr><tr>
<td>Row &lt;</td>
<td>Playing ,</td>
<td>pause ,</td>
<td>Paused ,</td>
<td>pause_playback,</td>
<td> none</td>
<td>&gt;,</td>
</tr><tr>
<td>Row &lt;</td>
<td>Playing ,</td>
<td>open_close ,</td>
<td>Open ,</td>
<td>stop_and_open,</td>
<td> none</td>
<td>&gt;,</td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>Row &lt;</td>
<td> Paused ,</td>
<td>end_pause ,</td>
<td>Playing ,</td>
<td>resume_playback,</td>
<td> none</td>
<td>&gt;,</td>
</tr><tr>
<td>Row &lt;</td>
<td> Paused ,</td>
<td>stop ,</td>
<td>Stopped ,</td>
<td>stop_playback,</td>
<td> none</td>
<td>&gt;,</td>
</tr><tr>
<td>Row &lt;</td>
<td> Paused ,</td>
<td>open_close ,</td>
<td>Open ,</td>
<td>stop_and_open,</td>
<td> none</td>
<td>&gt;</td>
</tr><tr>
<td>//</td>
<td>+---------+</td>
<td>-------------+</td>
<td>---------+</td>
<td>---------------------+</td>
<td>----------------------+</td>
<td> </td>
</tr><tr>
<td>&gt; {};</td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr></tbody></table><p>
</p><p>Transitions are now of type "Row" with exactly 5 template arguments: source
state, event, target state, action and guard. Wherever there is nothing (for
example actions and guards), write "none". Actions and guards are no more
methods but functors getting as arguments the detected event, the state machine,
source and target state:</p><p><code class="code">struct store_cd_info { </code></p><p><code class="code">template &lt;class Fsm,class Evt,class SourceState,class TargetState&gt;
</code></p><p><code class="code">void operator()(Evt const&amp;, Fsm&amp; fsm, SourceState&amp;,
TargetState&amp; ) </code></p><p><code class="code"> {</code></p><p><code class="code"> cout &lt;&lt; "player::store_cd_info" &lt;&lt; endl;
fsm.process_event(play()); </code></p><p><code class="code"> } </code></p><p><code class="code">}; </code></p><p>The advantage to functors compared to functions are that they are generic and
reusable. They also allow passing more parameters than just events. The guard
functors are the same but have an operator() returning a bool.</p><p>It is also possible to mix rows from different front-ends. To show this, a
g_row has been left in the transition table. <span class="underline">Note:</span> in case the action functor is used in the transition table
of a state machine contained inside a top-level state machine, the &#8220;fsm&#8221;
parameter refers to the lowest-level state machine (referencing this action),
not the top-level one.</p><p>To illustrate the reusable point, MSM comes with a whole set of predefined
functors. Please refer to eUML for the full list (TODO). For example, we are
going to replace the first action by an action sequence and the guard by a more
complex functor.</p><p>We decide we now want to execute 2 actions in the first transition (Stopped -&gt;
Playing). We only need to change the action start_playback to (TODO)
<code class="code">ActionSequence_&lt; mpl::vector&lt;some_action, start_playback&gt; &gt;
</code> and now will execute some_action and start_playback every time the
transition is taken. ActionSequence_ is a functor callinng each element of the
mpl::vector in sequence.</p><p>We also want to replace good_disk_format by a condition of the type:
&#8220;good_disk_format &amp;&amp; (some_condition || some_other_condition)&#8221;. We can
achieve this using And_ and Or_ functors: <code class="code">And_&lt;good_disk_format,Or_&lt;
some_condition , some_other_condition&gt;</code>. It even starts looking like
functional programming. MSM ships with functors for operators, state machine
usage, STL algorithms or container methods.</p></div><div class="sect3" title="Defining states with entry/exit actions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e2362"></a>Defining states with entry/exit actions</h4></div></div></div><p>You probably noticed that we just showed a different transition table and that
we even mixed rows from different front-ends. This means that you can do this
and leave the definitions for states unchanged. Most examples are doing this as
it is the simplest solution. You still enjoy the simplicity of the first
front-end with the extended power of the new transition types. This <a class="link" href="examples/SimpleWithFunctors.cpp" target="_top">tutorial</a>, adapted from
the earlier example does just this.</p><p>Of course, it is also possible to define states where entry and exit actions
are also provided as functors as these are generated by eUML and both front-ends
are equivalent. For example, we can define a state as:</p><p><code class="code">struct Empty_Entry { </code></p><p><code class="code">template &lt;class Event,class Fsm,class State&gt; </code></p><p><code class="code">void operator()(Event const&amp;,Fsm&amp;,State&amp;) </code></p><p><code class="code"> {</code></p><p><code class="code"> ... </code></p><p><code class="code"> } </code></p><p><code class="code">}; // same for Empty_Exit</code></p><p><code class="code">struct Empty : public
msm::front::euml::func_state&lt;Empty_Entry,Empty_Exit&gt;{};</code></p><p>This also means that you can, like in the transition table, write entry / exit
actions made of more complicated action combinations. The previous example can
therefore <a class="link" href="examples/SimpleWithFunctors2.cpp" target="_top">be
rewritten</a>.</p><p>Usually, however, one will probably use the standard state definition as it
provides the same capabilities as this front-end state definition, unless one
needs some of the shipped predefined functors.</p></div><div class="sect3" title="Defining a simple state machine"><div class="titlepage"><div><div><h4 class="title"><a name="d0e2403"></a>Defining a simple state machine</h4></div></div></div><p>Like states, state machines can be defined using the previous front-end, as
the previous example showed, or with the functor front-end, which allows you to
define a state machine entry and exit functions as functors, as in <a class="link" href="examples/SimpleWithFunctors2.cpp" target="_top">this example</a>.</p></div><div class="sect3" title="Anonymous transitions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e2411"></a>Anonymous transitions</h4></div></div></div><p>Anonymous (compound) transitions are transition withour a named event, taken
automatically. We saw how this front-end uses <code class="code">none</code> when no action
or guard is required. We can also use <code class="code">none</code> instead of an event to
mark an anonymous transition. For example, the following transition makes an
immediate transition from State1 to State2:</p><p>Row &lt; State1 , none , State2 &gt;</p><p>The following transition does the same but calling an action in the
process:</p><p>Row &lt; State1 , none , State2 , State1ToState2, none &gt;</p><p>The following diagram shows an example and its <a class="link" href="examples/AnonymousTutorialWithFunctors.cpp" target="_top">implementation</a>:</p><p><span class="inlinemediaobject"><img src="../images/Anonymous.jpg"></span></p></div><div class="sect3" title="Internal transitions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e2437"></a><span class="command"><strong><a name="functor-internal-transitions"></a></strong></span>Internal transitions</h4></div></div></div><p>The <a class="link" href="examples/SimpleTutorialInternalFunctors.cpp" target="_top">following
example</a> uses internal transitions with the functor front-end. As for
the simple standard front-end, both methods of defining internal transitions are supported:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>defining a <code class="code">Row</code> in the state machine's transition
table with <code class="code">none</code> as target state defines an internal
transition</p></li><li class="listitem"><p>defining an <code class="code">internal_transition_table</code> made of
<code class="code">Internal</code> rows inside a state defines UML-conform
internal transitions with higher priority</p></li><li class="listitem"><p>transitions defined inside <code class="code">internal_transition_table</code>
require no source state either as the source state is known.</p></li></ul></div><p>Like for the <span class="command"><strong><a class="command" href="ar01s04.html#internal-transitions-note">standard front-end internal transitions</a></strong></span>, internal transition
tables are added into the main state machine's table, thus allowing you to
distribute the transition table definition and reuse states.</p><p>There is an added bonus offered for submachines, which can have both the
standard transition_table and an internal_transition_table (which has higher
priority). This makes it easier if you decide to make a full submachine from a
state. It is also slightly faster than the standard alternative, adding
orthogonal regions, because event dispatching will, if accepted by the internal
table, not continue to the subregions. This gives you a O(1) dispatch instead of
O(number of regions). While the example is with eUML, the same is also possible
with this front-end.</p></div></div><div class="sect2" title="eUML (experimental)"><div class="titlepage"><div><div><h3 class="title"><a name="d0e2477"></a><span class="command"><strong><a name="eUML-front-end"></a></strong></span>eUML (experimental)</h3></div></div></div><p><span class="underline">Important note</span>: eUML requires a compiler
supporting the C++0x decltype/typeof feature (from example VC &gt;= 9, g++ &gt;= 4.3. VC8
is partially supported). More generally, eUML has experimental status because most
compilers will start crashing when a state machine becomes too big. Only g++ 4.3
(unfortunately not 4.4 which shows a serious regression) seems perfectly
resilient.</p><p>The previous front-ends are simple to write but still force an amount of noise,
mostly MPL types, so it would be nice to write code looking like C++ (with a C++
action language) directly inside the transition table, like UML designers like to do
on their state machine diagrams. This is what eUML is for.</p><p>eUML is a Boost.Proto-based compile-time domain specific embedded language. It
provides grammars which allow the definition of actions/guards directly inside the
transition table or entry/exit in the state definition. It is defined in the
namespace msm::front::euml. There are grammars for actions, guards, flags,
attributes, deferred events, initial states.</p><p>It also relies on Boost.Typeof as a wrapper around the new decltype C++0x feature
to provide a compile-time evaluation of all the grammars. Unfortunately, all the
underlying Boost libraries are not Typeof-enabled, so for the moment, you will need
a compiler where Typeof is natively implemented (like VC8-9-10, g++ &gt;= 4.3).</p><p>Examples will be provided in the next paragraphs. You need to include eUML basic
features: </p><p><code class="code">#include &lt;msm/front/euml/euml.hpp&gt;</code></p><p>To add STL support (at possible cost of longer compilation times), include: </p><p><code class="code">#include &lt;msm/front/euml/stl.hpp&gt;</code></p><div class="sect3" title="Transition table"><div class="titlepage"><div><div><h4 class="title"><a name="d0e2501"></a>Transition table</h4></div></div></div><p>A transition can be defined using eUML as: </p><p><code class="code">source + event [guard] / action == target</code> or as</p><p><code class="code">target == source + event [guard] / action</code></p><p>The first version looks like a drawn transition in a diagram, the second one
seems natural to a C++ developper.</p><p>The simple transition table written with the <span class="command"><strong><a class="command" href="ar01s04.html#functor-front-end">previous front-end</a></strong></span> can now be
written as:</p><p>
</p><table frame="void" id="d0e2522"><tbody><tr>
<td>typedef BOOST_TYPEOF(build_stt((</td>
<td> </td>
<td> </td>
</tr><tr>
<td>Stopped +</td>
<td>play [DummyGuard] / (TestFct,start_playback)</td>
<td>== Playing</td>
</tr><tr>
<td>Stopped +</td>
<td>open_close/ open_drawer</td>
<td>== Open</td>
</tr><tr>
<td>Stopped +</td>
<td>stop</td>
<td>== Stopped</td>
</tr><tr>
<td>Open +</td>
<td>open_close / close_drawer</td>
<td>== Empty</td>
</tr><tr>
<td>Empty +</td>
<td>open_close / open_drawer </td>
<td>== Open</td>
</tr><tr>
<td>Empty +</td>
<td>cd_detected [good_disk_format] / store_cd_info </td>
<td>== Stopped</td>
</tr><tr>
<td> ) ) ) transition_table;</td>
<td> </td>
<td> </td>
</tr></tbody></table><p>
</p><p>Or, using the alternative notation, it can be:</p><p>
</p><table id="d0e2617"><tbody><tr>
<td>typedef BOOST_TYPEOF(build_stt((</td>
<td> </td>
<td> </td>
</tr><tr>
<td>Playing == </td>
<td>Stopped +</td>
<td>play [DummyGuard] / (TestFct,start_playback)</td>
</tr><tr>
<td>Open ==</td>
<td>Stopped +</td>
<td>open_close/ open_drawer</td>
</tr><tr>
<td>Stopped ==</td>
<td>Stopped +</td>
<td>stop</td>
</tr><tr>
<td>Empty ==</td>
<td>Open +</td>
<td>open_close / close_drawer</td>
</tr><tr>
<td>Open ==</td>
<td>Empty +</td>
<td>open_close / open_drawer</td>
</tr><tr>
<td>Stopped ==</td>
<td>Empty +</td>
<td>cd_detected [good_disk_format] / store_cd_info </td>
</tr><tr>
<td> ) ) ) transition_table;</td>
<td> </td>
<td> </td>
</tr></tbody></table><p>
</p><p>The transition table now looks like a list of (readable) rules with little
noise.</p><p>UML defines guards between &#8220;[ ]&#8221; and actions after a &#8220;/&#8221;, so this is already
more readable for UML designers. UML also allows designers to define several
actions sequentially (our previous ActionSequence) separated by a comma. The
first transition does just this: two actions separated by a comma and enclosed
inside parenthesis to respect C++ operator precedence.</p><p>If this seems to you like it will cost you run-time performance, don't worry,
typeof (decltype) only evaluates the build_stt function and no run-time cost
occurs. Actually, eUML is only a metaprogramming layer on top of "standard" MSM
metaprogramming and this first layer generates the previously-presented <span class="command"><strong><a class="command" href="ar01s04.html#functor-front-end">functor front-end</a></strong></span>.</p><p>UML also allows designers to define more complicated guards, like
[good_disk_format &amp;&amp; (some_condition || some_other_condition)]. This was
possible with our previously defined functors, but using a complicated template
syntax. This syntax is now possible exactly as written, which means without
syntactic noise.</p></div><div class="sect3" title="Defining events, actions and states with entry/exit actions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e2719"></a>Defining events, actions and states with entry/exit actions</h4></div></div></div><p>Events must be proto-enabled. To achieve this, they must inherit from
euml_event:</p><p><code class="code">struct play : euml_event&lt;play&gt;{};</code></p><p>Actions (returning void) and guards (returning a bool) are defined like
previous functors, with the difference that they also must be
proto-enabled:</p><p><code class="code">struct some_condition : euml_action&lt; some_condition &gt;</code></p><p><code class="code">{ </code></p><p><code class="code">template &lt;class Fsm,class Evt,class SourceState,class
TargetState&gt;</code></p><p><code class="code">bool operator()(Evt const&amp; ,Fsm&amp; ,SourceState&amp;
,TargetState&amp; ) { return true; } </code></p><p><code class="code">}; </code></p><p>It is also possible to use the same action grammar as for the transition table
for state entry and exit actions:</p><p><code class="code">typedef BOOST_TYPEOF(euml::build_state( (Empty_Entry,Dummy_Entry)/*2
entry actions*/,Empty_Exit/*1 exit action*/ )) Empty;</code></p><p>This means that Empty is defined as a state with an entry action made of two
sub-actions, Empty_Entry and Dummy_Entry (enclosed inside parenthesis), and an
exit action, Empty_Exit.</p><p>There are several overloads of the <span class="command"><strong><a name="eUML-build-state"></a></strong></span>build_state function:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>build_state(): state without entry or exit action.</p></li><li class="listitem"><p>build_state(Expr1): state with entry but no exit action.</p></li><li class="listitem"><p>build_state(Expr1,Expr2): state with entry and exit action.</p></li><li class="listitem"><p>build_state(Expr1,Expr2,Attributes): state with entry and exit
action, defining some attributes (read further on).</p></li><li class="listitem"><p>build_state(Expr1,Expr2,Attributes,Configure): state with entry
and exit action, defining some attributes (read further on) and
flags (standard MSM flags) or deferred events (standard MSM deferred
events).</p></li><li class="listitem"><p>build_state(Expr1,Expr2,Attributes,Configure,Base): state with
entry and exit action, defining some attributes (read further on),
flags and deferred events (plain msm deferred events) and a
non-default base state (as defined in standard MSM).</p></li></ul></div><p>A NoAction is also defined, which does, well, nothing except being a
placeholder (needed for example as entry action if we have no entry but an
exit). Expr1 and Expr2 are a sequence of actions, obeying the same action
grammar as in the transition table (following the &#8220;/&#8221; symbol).</p><p>The state functors have a slightly different signature as there is no source
and target state but only a current state (entry/exit actions are
transition-independent), for example:</p><p><code class="code">struct Empty_Entry : euml_action&lt; Empty_Entry &gt;</code></p><p><code class="code">{ </code></p><p><code class="code">template &lt;class Evt,class Fsm,class State&gt;</code></p><p><code class="code">void operator()(Evt const&amp; ,Fsm&amp; ,State&amp; ) { ... }
</code></p><p><code class="code">}; </code></p><p>Notice again the euml_action, to make the functor play nice with the grammar.
</p></div><div class="sect3" title="Defining a simple state machine"><div class="titlepage"><div><div><h4 class="title"><a name="d0e2795"></a>Defining a simple state machine</h4></div></div></div><p>Like for a functor front-end, you can reuse the state machine definition
method from the standard front-end. You can also use eUML to define a state
machine "on the fly" (if, for example, you need to provide an on_entry/on_exit
for this state machine as a functor). For this, there is also a function,
<span class="command"><strong><a name="eUML-build-sm"></a></strong></span>build_sm, which has up to 8 arguments:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>build_sm(Stt, Init): simplest state machine where only the
transition table and initial state(s) are defined.</p></li><li class="listitem"><p>build_sm(Stt, Init, Expr1): state machine where the transition
table, initial state and entry action are defined.</p></li><li class="listitem"><p>build_sm(Stt, Init, Expr1, Expr2): state machine where the
transition table, initial state, entry and exit actions are
defined.</p></li><li class="listitem"><p>build_sm(Stt, Init, Expr1, Expr2, Attributes): state machine where
the transition table, initial state, entry and exit actions are
defined. Furthermore, some attributes are added (read further
on).</p></li><li class="listitem"><p>build_sm(Stt, Init, Expr1, Expr2, Attributes, Configure): state
machine where the transition table, initial state, entry and exit
actions are defined. Furthermore, some attributes (read further on),
flags, deferred events and configuration capabilities TODO link (no
message queue / no exception catching) are added.</p></li><li class="listitem"><p>build_sm(Stt, Init, Expr1, Expr2, Attributes, Flags, Deferred ,
Base): state machine where the transition table, initial state,
entry and exit actions are defined. Furthermore, attributes (read
further on), flags , deferred events and configuration capabilities
(no message queue / no exception catching) are added and a
non-default base state (see base state TODO) is defined.</p></li></ul></div><p>For example, a minimum state machine could be defined
like:</p><p>
</p><table id="d0e2824"><tbody><tr>
<td>typedef BOOST_TYPEOF(build_stt((</td>
<td> </td>
<td> </td>
</tr><tr>
<td>... ) ) ) transition_table;</td>
<td> </td>
<td> </td>
</tr></tbody></table><p>
</p><p><code class="code">typedef BOOST_TYPEOF(build_sm( transition_table(),init_ &lt;&lt; Empty
)) player_;</code></p><p><span class="underline">Note for VC9</span>: This defined build_sm
syntax works most of the time. But once in a while, VC9 will display the problem
shown in the next section (not enough heap space). For example, this simple
performance test (TODO link), while really simple, will display the bug. To
correct it, the following solution works: </p><p><code class="code">#ifndef BOOST_MSVC</code></p><p><code class="code">typedef BOOST_TYPEOF(build_sm( transition_table(),init_ &lt;&lt; Empty
&lt;&lt; AllOk )) player_;</code></p><p><code class="code">#else</code></p><p><code class="code">struct player_ : public BOOST_TYPEOF(build_sm( transition_table(),init_
&lt;&lt; Empty &lt;&lt; AllOk )) {};</code></p><p><code class="code">#endif</code></p><p>Please have a look at the player tutorial written using eUML's <a class="link" href="examples/SimpleTutorialEuml2.cpp" target="_top">first</a> and <a class="link" href="examples/SimpleTutorialEuml.cpp" target="_top">second</a> syntax. Please
ignore for the moment the BOOST_MSM_EUML_DECLARE_ATTRIBUTE macros, we come back
to it very soon.</p></div><div class="sect3" title="Defining a submachine"><div class="titlepage"><div><div><h4 class="title"><a name="d0e2879"></a>Defining a submachine</h4></div></div></div><p>Defining a submachine (see <a class="link" href="examples/CompositeTutorialEuml.cpp" target="_top">tutorial</a>) with other
front-ends simply means using a state which is a state machine in the transition
table of another state machine. This is the same with eUML. One only needs
define a second state machine and reference it in the transition table of the
containing state machine.</p><p><span class="underline">Note</span>: the previous #ifdef trick has to
be used for submachine definition because the VC9 bug occurs more often when
submachines are involved.</p></div><div class="sect3" title="Attributes / Function call"><div class="titlepage"><div><div><h4 class="title"><a name="d0e2891"></a> Attributes / Function call</h4></div></div></div><p>We now want to make our grammar more useful. Very often, one needs only very
simple action methods, for example ++Counter or Counter &gt; 5 where Counter is
usually defined as some attribute of the class containing the state machine.
Furthermore, unlike many expensive tools which are on the market, states within
MSM are also classes so they can have attributes, and we would also like to
provide them with attributes. </p><p>If you look back at our examples using the <a class="link" href="examples/SimpleTutorialEuml2.cpp" target="_top">first</a> and <a class="link" href="examples/SimpleTutorialEuml.cpp" target="_top">second</a> syntaxes, you
will find some unexplained BOOST_MSM_EUML_DECLARE_ATTRIBUTE macros. Let us go
back to them. We have:</p><p><code class="code">BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,cd_name)</code></p><p><code class="code">BOOST_MSM_EUML_DECLARE_ATTRIBUTE(DiskTypeEnum,cd_type)</code></p><p>This declares two attributes: cd_name of type std::string and cd_type of type
DiskTypeEnum. These attributes are not part of any event or state in particular,
we just declared a name and a type. Now, we can add attributes to our
cd_detected event:</p><p><code class="code">typedef BOOST_TYPEOF(build_attributes(attributes_ &lt;&lt; cd_name
&lt;&lt; cd_type )) cd_detected_attributes;</code></p><p><code class="code">struct cd_detected : euml_event&lt;cd_detected&gt;,cd_detected_attributes
{</code></p><p><code class="code">cd_detected(std::string name, DiskTypeEnum diskType) {</code></p><p><code class="code">get_attribute(cd_name)=name;get_attribute(cd_type)=diskType;}</code></p><p><code class="code">};</code></p><p>The two left shift of the first line add both attributes into the helper
cd_detected_attributes structure. As cd_detected inherits from the helper, it
now has these two attributes. The function get_attribute returns a reference to
the required attributes so that we can easily write and set them.</p><p>Ok, great, we now have a two liner to add attributes to a class, which we
could have done more easily, so what is the point? The point is that we can now
do what was not possible, reference these attributes directly, at compile-time,
in the transition table. For example, in the example, you will find this
transition:</p><p><code class="code">Stopped == Empty + cd_detected [good_disk_format &amp;&amp;
(event_(cd_type)==Int_&lt;DISK_CD&gt;())] </code></p><p>Read event_(cd_type) as event_-&gt;cd_type with event_ a type generic for events,
whatever the concrete event is (in this particular case, it happens to be a
cd_detected as the transition shows).</p><p>The main advantage of this feature is that you do not need to define a new
functor and you do not need to look inside the functor to know what it does, you
have all at hand.</p><p>MSM provides more generic objects for state machine types:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>event_ : used inside any action, the event triggering the
transition</p></li><li class="listitem"><p>state_: used inside entry and exit actions, the entered / exited
state</p></li><li class="listitem"><p>source_: used inside a transition action, the source state</p></li><li class="listitem"><p>target_: used inside a transition action, the target state</p></li><li class="listitem"><p>fsm_: used inside any action, the (lowest-level) state machine
processing the transition</p></li><li class="listitem"><p>Int_&lt;int value&gt;: a functor representing an int</p></li><li class="listitem"><p>Char_&lt;value&gt;: a functor representing a char</p></li><li class="listitem"><p>Size_t_&lt;value&gt;: a functor representing a size_t</p></li><li class="listitem"><p>String_&lt;mpl::string&gt; (boost &gt;= 1.40): a functor representing a
string.</p></li></ul></div><p>These helpers can be used in two different ways:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>helper(attribute_name) returns the attribute with name
attribute_name</p></li><li class="listitem"><p>helper returns the state / event type itself.</p></li></ul></div><p>The second form is helpful if you want to use states with self-created
functors. In the <a class="link" href="examples/SimpleTutorialEuml.cpp" target="_top">above
tutorial</a>, we provide Empty with an activate_empty method. We would
like to create a eUML functor and call it from inside the transition table. This
is done using the MSM_EUML_METHOD / MSM_EUML_FUNCTION macros. The first creates
a functor to a method, the second to a free function. In the tutorial, we
write:</p><p><code class="code">MSM_EUML_METHOD(ActivateEmpty_ , activate_empty , activate_empty_ , void
, void )</code></p><p>The first parameter is the functor name, for use either directly or with the
functor front-end. The second is the name of the method which will be called.
The third is the function name for use in the transition table, the fourth is
the return type of the function if used in the context of a transition action,
the fifth is the result type if used in the context of a state entry / exit
action (usually fourth and fifth are the same). We now have a new eUML function
calling a method of "something", and this "something" is one of the five
previously explained helpers. We can now use this in a transition, for
example:</p><p><code class="code">Empty == Open + open_close /
(close_drawer,activate_empty_(target_))</code></p><p>The action is now defined as a sequence of two actions: close_drawer and
activate_empty called on the target itself. The target being Empty (the state
defined left), this really will call Empty.activate_empty(). This method could
also have an (or several) argument(s), for example the event, we could then call
activate_empty_(target_ , event_).</p><p>More examples can be found in the <a class="link" href="examples/CompilerStressTestEuml.cpp" target="_top">terrible compiler stress
test</a>, the <a class="link" href="examples/SimpleTimer.cpp" target="_top">timer
example</a> or in the <a class="link" href="examples/iPodSearchEuml.cpp" target="_top">iPodSearch with eUML</a> (for String_ and more).</p></div><div class="sect3" title="Orthogonal regions, flags, event deferring"><div class="titlepage"><div><div><h4 class="title"><a name="d0e3003"></a>Orthogonal regions, flags, event deferring</h4></div></div></div><p>To define orthogonal regions really means defining more initial states. To add
more initial states, &#8220;shift left&#8221; some, for example, if we had another initial
state named AllOk :</p><p><code class="code">typedef BOOST_TYPEOF(build_sm( transition_table(),init_ &lt;&lt; Empty
&lt;&lt; AllOk )) player_;</code></p><p>You remember from the <span class="command"><strong><a class="command" href="ar01s04.html#eUML-build-state">build_state</a></strong></span> and <span class="command"><strong><a class="command" href="ar01s04.html#eUML-build-sm">build_sm</a></strong></span> signatures that just after attributes, we can define
flags, like in the basic MSM frontend. To do this, we have another "shift-left"
grammar, for example:</p><p><code class="code">typedef BOOST_TYPEOF(build_state(NoAction,NoAction, attributes_ &lt;&lt;
no_attributes_, </code></p><p><code class="code">/* flags */ configure_&lt;&lt; PlayingPaused &lt;&lt; CDLoaded ))
Paused; </code></p><p>We now defined that Paused will get two flags, PlayingPaused and CDLoaded,
defined, for example as:</p><p><code class="code">struct CDLoaded : euml_flag&lt;CDLoaded&gt; {};</code></p><p>This corresponds to the following basic front-end definition of Paused:</p><p><code class="code">struct Paused : public msm::front::state&lt;&gt; </code></p><p><code class="code">{ typedef mpl::vector2&lt;PlayingPaused,CDLoaded&gt; flag_list; };
</code></p><p>Under the hood, what you get really is a mpl::vector2.</p><p><span class="underline">Note</span>: As we use the version of
build_state with 4 arguments, we need to tell eUML that we need no attributes.
Similarly to a <code class="code">cout &lt;&lt; endl</code>, we need a <code class="code">attributes_
&lt;&lt; no_attributes_</code> syntax.</p><p>You can use the flag with the is_flag_active method of a state machine. You
can also use the provided helper function is_flag_ (returning a bool) for state
and transition actions. For example, in the iPod implementation with eUML (TODO
link), you find the following transition:</p><p><code class="code">ForwardPressed == NoForward + EastPressed
[!is_flag_(NoFastFwd)]</code></p><p>The function also has an optional second parameter which is the state machine
on which the function is called. by default, fsm_ is used (the current state
machine) but you could provide a functor returning a reference to another state
machine.</p><p>eUML also supports defining deferred events in the state (state machine)
definition. To this aim, we can reuse the flag grammar. For example:</p><p><code class="code">typedef BOOST_TYPEOF(build_state(Empty_Entry,Empty_Exit, attributes_
&lt;&lt; no_attributes_, </code></p><p><code class="code">/* flags */ configure_&lt;&lt; play )) Empty; </code></p><p>The configure_ left shift is also responsible for deferring events. Shit
inside a flag and it will be seen as a flag, shift an event and it will be a
deferred event. This replaces the basic front-end definition:</p><p><code class="code">typedef mpl::vector&lt;play&gt; deferred_events;</code></p><p>In <a class="link" href="examples/OrthogonalDeferredEuml.cpp" target="_top">this
tutorial</a>, player is defining a second orthogonal region with AllOk as
initial state. The <code class="code">Empty</code> and <code class="code">Open</code> states also defer
the event <code class="code">play</code>. <code class="code">Open</code>, <code class="code">Stopped</code> and
<code class="code">Pause</code> also support the flag <code class="code">CDLoaded</code> using the
same left shift into <code class="code">configure_</code>.</p><p>In the functor front_end, we also had the possibility to defer an event inside
a transition, which makes possible conditional deferring. This is also possible
with eUML through the use of the defer_ order, as shown in <a class="link" href="examples/OrthogonalDeferredEuml.cpp" target="_top">this tutorial</a>. You
will find the foillowing transition:</p><p><code class="code">Open + play / defer_</code></p><p>This is an <span class="command"><strong><a class="command" href="ar01s04.html#eUML-internal">internal transition</a></strong></span>.
Ignore it for the moment. Interesting is, that when the event <code class="code">play</code>
is fired and <code class="code">Open</code> is active, the event will be deferred. Now add a
guard and you can conditionally defer the event, for example:</p><p><code class="code">Open + play [ some_condition ] / defer_</code></p><p>This is similar to what we did with the functor front-end. This means that we
have the same limitations. Using defer_ instead of a state declaration, we need
to tell MSM that we have deferred events in this state machine. We do this
(again) using a configure_ declaration in the state machine definition in which
we shift the deferred_events configuration flag using the build_sm
function:</p><p><code class="code">typedef BOOST_TYPEOF(build_sm( transition_table(),init_ &lt;&lt; Empty
&lt;&lt; AllOk,</code></p><p><code class="code">Entry_Action, Exit_Action, attributes_ &lt;&lt; no_attributes_,
configure_&lt;&lt; deferred_events )) player_;</code></p><p>A <a class="link" href="examples/OrthogonalDeferredEuml2.cpp" target="_top">tutorial</a>
illsutrates this possibility.</p></div><div class="sect3" title="Customizing a state machine / Getting more speed"><div class="titlepage"><div><div><h4 class="title"><a name="d0e3134"></a> Customizing a state machine / Getting more speed</h4></div></div></div><p>We just saw how to use configure_ to define deferred events or flags. We can
also use it to configure our state machine like we did with other front-ends
(TODO add in standard):</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>configure_ &lt;&lt; no_exception: disables exception
handling</p></li><li class="listitem"><p>configure_ &lt;&lt; no_msg_queue deactivates the message
queue</p></li></ul></div><p>Deactivating these features if not needed greatly improves the event
dispatching speed of your state machine. Our <a class="link" href="examples/EumlSimple.cpp" target="_top">speed testing</a> example with eUML
use this feature.</p></div><div class="sect3" title="Anonymous transitions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e3151"></a>Anonymous transitions</h4></div></div></div><p>Anonymous transitions (See <span class="command"><strong><a class="command" href="ar01s03.html#uml-anonymous">UML
tutorial</a></strong></span>) are transitions without a named event which are
therefore triggered immediately when the source state becomre active, provided a
guard allows it. As there is no event, to define such a transition, simply omit
the &#8220;+&#8221; part of the transition (the event), for example: </p><p><code class="code">State3 == State4 [always_true] / State3ToState4</code></p><p><code class="code">State4 [always_true] / State3ToState4 == State3</code></p><p>Please have a look at <a class="link" href="examples/AnonymousTutorialEuml.cpp" target="_top">this example</a>, which implements the <span class="command"><strong><a class="command" href="ar01s04.html#anonymous-transitions">previously defined</a></strong></span> state
machine with eUML.</p></div><div class="sect3" title="Internal transitions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e3173"></a><span class="command"><strong><a name="eUML-internal"></a></strong></span>Internal transitions</h4></div></div></div><p>Like both other front-ends, eUML supports two ways of defining internal transitions:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>in the state machine's transition table. In this case, you need to
specify a source state, event, actions and guards but no target
state, which eUML will interpret as an internal transition, for
example this defines a transition internal to Open, on the event
open_close:</p><p><code class="code">Open + open_close [internal_guard1] /
internal_action1</code></p><p><a class="link" href="examples/EumlInternal.cpp" target="_top">A full example</a>
is also provided.</p></li><li class="listitem"><p>in a state's <code class="code">internal_transition_table</code>. For
example:</p><p><code class="code">typedef BOOST_TYPEOF(build_state( Open_Entry(),Open_Exit()
)) Open_def;</code></p><p><code class="code">struct Open : public Open_def {</code></p><p><code class="code">typedef BOOST_TYPEOF(build_internal_stt((</code></p><p><code class="code">open_close [internal_guard1] /
internal_action1</code></p><p><code class="code">) ) ) internal_transition_table;</code></p><p><code class="code">};</code></p><p>Notice how we do not need to repeat that the transition originates
from Open as we already are in the context of Open. </p><p>The <a class="link" href="examples/EumlInternalDistributed.cpp" target="_top">implementation</a> also shows the added bonus offered for
submachines, which can have both the standard transition_table and
an internal_transition_table (which has higher priority). This makes
it easier if you decide to make a full submachine from a state. It
is also slightly faster than the standard alternative, adding
orthogonal regions, because event dispatching will, if accepted by
the internal table, not continue to the subregions. This gives you a
O(1) dispatch instead of O(number of regions).</p></li></ul></div></div><div class="sect3" title="Direct entry / entry and exit pseudo-state / fork"><div class="titlepage"><div><div><h4 class="title"><a name="d0e3221"></a>Direct entry / entry and exit pseudo-state / fork</h4></div></div></div><p>We saw the <span class="command"><strong><a class="command" href="ar01s04.html#eUML-build-state">build_state</a></strong></span>
function, which creates a simple state. Likewise, eUML provides other
state-building functions for other types of states:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>build_terminal_state takes the same arguments as build_state and
defines, well, a terminate state.</p></li><li class="listitem"><p>build_interrupt_state takes the same arguments as build_state and
defines an interrupt state.</p></li><li class="listitem"><p>build_exit_state takes the same arguments as build_state and
defines an exit pseudo state.</p></li><li class="listitem"><p>build_entry_state takes the same arguments as build_state and
defines an interrupt state. The region index to be entered is
defined as an int template argument, so build_entry_state&lt;0&gt;
defines an entry state into the first region of a submachine.</p></li><li class="listitem"><p>build_explicit_entry_state takes the same arguments as build_state
and defines an explicit entry state. The region index to be entered
is defined as an int template argument, so
build_explicit_entry_state&lt;0&gt; defines an explicit entry state
into the first region of a submachine.</p></li></ul></div><p>Using these states in the transition table is like in any other front end
using fsm_name::exit_pt&lt;&gt;, fsm_name::direct&lt;&gt; and fsm_name::entry_pt&lt;&gt;.
For example, a direct entry could be:</p><p><code class="code">SubFsm2::direct&lt;SubState2&gt; == State1 + event2</code></p><p>Forks being a list on direct entries, eUML supports a logical syntax (state1,
state2, ...), for example:</p><p><code class="code">(SubFsm2::direct&lt;SubState2&gt;, SubFsm2::direct&lt;SubState2b&gt;,
SubFsm2::direct&lt;SubState2c&gt;) == State1 + event3</code></p><p>The <a class="link" href="examples/DirectEntryEuml.cpp" target="_top">entry tutorial</a> is
also available with eUML.</p></div><div class="sect3" title="Helper functions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e3260"></a>Helper functions</h4></div></div></div><p>We saw a few helpers but there are more, so let us have a more complete description:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>event_ : used inside any action, the event triggering the
transition</p></li><li class="listitem"><p>state_: used inside entry and exit actions, the entered / exited
state</p></li><li class="listitem"><p>source_: used inside a transition action, the source state</p></li><li class="listitem"><p>target_: used inside a transition action, the target state</p></li><li class="listitem"><p>fsm_: used inside any action, the (lowest-level) state machine
processing the transition</p></li><li class="listitem"><p>The previous objects can also return an attribute, for example
event_(cd_name)</p></li><li class="listitem"><p>Int_&lt;int value&gt;: a functor representing an int</p></li><li class="listitem"><p>Char_&lt;value&gt;: a functor representing a char</p></li><li class="listitem"><p>Size_t_&lt;value&gt;: a functor representing a size_t</p></li><li class="listitem"><p>True_ and False_ functors returning true and false
respectively</p></li><li class="listitem"><p>String_&lt;mpl::string&gt; (boost &gt;= 1.40): a functor representing a
string.</p></li><li class="listitem"><p>if_then_else_(guard, action, action) where action can be an action
sequence</p></li><li class="listitem"><p>if_then_(guard, action) where action can be an action
sequence</p></li><li class="listitem"><p>while_(guard, action) where action can be an action
sequence</p></li><li class="listitem"><p>do_while_(guard, action) where action can be an action
sequence</p></li><li class="listitem"><p>for_(action, guard, action, action) where action can be an action
sequence</p></li><li class="listitem"><p>process_(some_event [, some state machine] [, some state machine]
[, some state machine] [, some state machine]) will call
process_event (some_event) on the current state machine or on the
one(s) passed as 2nd , 3rd, 4th, 5th argument. This allow sending
events to several external machines</p></li><li class="listitem"><p>process2_(some_event,Value [, some state machine] [, some state
machine] [, some state machine]) will call process_event
(some_event(Value)) on the current state machine or on the one(s)
passed as 3rd, 4th, 5th argument</p></li><li class="listitem"><p>is_ flag_(some_flag[, some state machine]) will call
is_flag_active on the current state machine or on the one passed as
2nd argument</p></li><li class="listitem"><p>Predicate_&lt;some predicate&gt;: Used in STL algorithms. Wraps
unary/binary functions to make them eUML-compatible so that they can
be used in STL algorithms</p></li></ul></div><p>This can make for quite some fun. For example, </p><p><code class="code">/( if_then_else_(--fsm_(m_SongIndex) &gt; Int_&lt;0&gt;(),/*if
clause*/</code></p><p><code class="code">show_playing_song(), /*then clause*/</code></p><p><code class="code">(fsm_(m_SongIndex)=Int_&lt;1&gt;(),process_(EndPlay())) /*else clause*/ )
)</code> means:</p><p>if (fsm.SongIndex &gt; 0, call show_playing_song else {fsm.SongIndex=1; process
EndPlay on fsm;}</p><p>A few examples are using these features:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>the iPod example introduced at the BoostCon09 <a class="link" href="examples/iPodEuml.cpp" target="_top">has been rewritten</a>
with eUML (weak compilers please move on...)</p></li><li class="listitem"><p>the iPodSearch example also introduced at the BoostCon09 <a class="link" href="examples/iPodSearchEuml.cpp" target="_top">has been
rewritten</a> with eUML. In this example, you will also find
some examples of STL functor usage.</p></li><li class="listitem"><p><a class="link" href="examples/SimpleTimer.cpp" target="_top">A simpler timer</a>
example is a good starting point. </p></li></ul></div><p>There is unfortunately a small catch. Defining a functor using MSM_EUML_METHOD
or MSM_EUML_FUNCTION will create a correct functor. Your own eUML functors
written as described at the beginning of this section will also work well,
<span class="underline">except</span> with the while_, if_then_,
if_then_else_ functions which will require a bit of writing. TODO macro.</p></div><div class="sect3" title="Phoenix-like STL support"><div class="titlepage"><div><div><h4 class="title"><a name="d0e3365"></a>Phoenix-like STL support</h4></div></div></div><p>As we saw, eUML supports most C++ operators (except address-of). For example
it is possible to write event_(some_attribute)++ or [source_(some_bool)
&amp;&amp; fsm_(some_other_bool)]. But a programmer needs more than operators in
his daily programming. The STL is clearly a must have. Therefore, eUML comes in
with a lot of functors to simplify your day-to-day programming. For almost every
algorithm or container method of the STL, a corresponding eUML function is
defined. Like Boost.Phoenix, &#8220;.&#8221; And &#8220;-&gt;&#8221; of call on objects are replaced by a
functional programming paradigm, for example:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>begin_(container), end_(container): returns iterators of a
container.</p></li><li class="listitem"><p>empty_(container): returns container.empty()</p></li><li class="listitem"><p>clear_(container): container.clear()</p></li><li class="listitem"><p>transform_ : std::transform</p></li></ul></div><p>In a nutshell, almost every STL method or algorithm is matched by a
corresponding functor, which can then be used in the transition table or state
actions. The reference (TODO link) explains in detail the usage and the
underlying functor (so that this possibility is not reserved to eUML but also to
the functor-based front-end). The file structure of this Phoenix-like library
matches the one of Boost.Phoenix. All STL algorithm functors are to be found
in:</p><p><code class="code">#include &lt;msm/front/euml/algorithm.hpp&gt;</code></p><p>The algorithms are also divided into sub-headers, matching the phoenix
structure for simplicity:</p><p><code class="code">#include &lt; msm/front/euml/iteration.hpp&gt; </code></p><p><code class="code">#include &lt; msm/front/euml/transformation.hpp&gt; </code></p><p><code class="code">#include &lt; msm/front/euml/querying.hpp&gt; </code></p><p>Container methods can be found in:</p><p><code class="code">#include &lt; msm/front/euml/container.hpp&gt;</code></p><p>Or one can simply include the whole STL support (you will also need to include
euml.hpp):</p><p><code class="code">#include &lt; msm/front/euml/stl.hpp&gt;</code></p><p>A few examples (to be found in <a class="link" href="examples/iPodSearchEuml.cpp" target="_top">this tutorial</a>):</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><code class="code">push_back_(fsm_(m_tgt_container),event_(m_song))</code>: the
state machine has an attribute m_tgt_container of type
std::vector&lt;OneSong&gt; and the event has an attribute m_song of
type OneSong. The line therefore pushes m_song at the end of
m_tgt_container</p></li><li class="listitem"><p><code class="code">if_then_( state_(m_src_it) != end_(fsm_(m_src_container)),
process2_(OneSong(),*(state_(m_src_it)++)) )</code>: the current
state has an attribute m_src_it (an iterator). If this iterator !=
fsm.m_src_container.end(), process OneSong on fsm, copy-constructed
from state.m_src_it which we post-increment</p></li></ul></div></div></div><div class="sect2" title="Back-end"><div class="titlepage"><div><div><h3 class="title"><a name="d0e3425"></a>Back-end</h3></div></div></div><p>There is, at the moment, one back-end. This back-end contains the library engine
and defines the performance and functionality tradeoffs. The currently available
back-end implements most of the functionality defined by the UML 2.0 standard at
very high runtime speed, in exchange for longer compile-time. The runtime speed is
due to a constant-time double-dispatch and self-adapting capabilities allowing the
framework to adapt itself to the features used by a given concrete state machine.
All unneeded features either disable themselves or can be manually disabled. See
section 5.1 for a complete description of the run-to-completion algorithm.</p><div class="sect3" title="MSM Backend features"><div class="titlepage"><div><div><h4 class="title"><a name="d0e3430"></a> MSM Backend features </h4></div></div></div><p>TODO</p><p></p><div class="sect4" title="Creation"><div class="titlepage"><div><div><h5 class="title"><a name="d0e3436"></a> Creation </h5></div></div></div><p> MSM being divided betwenn front and back-end, one needs to first define a
front-end. Then, to create a real state machine, the back-end must be
created: <code class="code">typedef msm::back::state_machine&lt;my_front_end&gt;
my_fsm;</code>
</p><p>We now have a fully functional state machine. The next sections will
describe what can be done with it.</p></div><div class="sect4" title="Event dispatching"><div class="titlepage"><div><div><h5 class="title"><a name="d0e3446"></a>Event dispatching</h5></div></div></div><p>The main reason to exist for a state machine is to dispatch events. For
MSM, events are objects of a given event type. The object itself can contain
data, but the event type is what decides of the transition to be taken. For
MSM, if some_event is a given type (a simple struct for example) and e1 and
e2 concrete events, e1 and e2 are equivalent, from a transition perspective.
Of course, e1 and e2 can have different values and you can use them inside
actions. Events are dispatched as const reference, so actions cannot modify
events for obvious side-effect reasons. To dispatch an event of type
some_event, you can simply write: </p><p><code class="code">my_fsm fsm; fsm.process_event(some_event());</code></p><p><code class="code">some_event e1; fsm.process_event(e1)</code></p><p>Creating an event on the fly will be optimized by the compiler so the
performance will not degrade.</p></div><div class="sect4" title="Active state(s)"><div class="titlepage"><div><div><h5 class="title"><a name="d0e3459"></a>Active state(s)</h5></div></div></div><p>The backend also offers a way to know which state is active, though you
will normally only need this for debugging purposes. If what you need simply
is doing something with the active state, <span class="command"><strong><a class="command" href="ar01s03.html#UML-internal-transition">internal transitions</a></strong></span> or
<span class="command"><strong><a class="command" href="ar01s04.html#backend-visitor">visitors</a></strong></span> are a better
alternative. If you need to know what state is active, const int*
current_state() will return an array of state ids. Please refer to the
<span class="command"><strong><a class="command" href="ar01s07.html#internals-state-id">internals section</a></strong></span> to
know how state ids are generated.</p></div><div class="sect4" title="Base state type"><div class="titlepage"><div><div><h5 class="title"><a name="d0e3473"></a> Base state type </h5></div></div></div><p>Sometimes, one needs to customize states to avoid repetition and provide a
common functionality, for example in the form of a virtual method. You might
also want to make your states polymorphic so that you can call typeid on
them for logging or debugging. It is also useful if you need a visitor, like
the next section will show. You will notice that all front-ends offer the
possibility of adding a base type. Not that all states and state machines
must have the same base state, so this could reduce reuse. For example,
using the basic front end, you need to:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Add the non-default base state in your msm::front::state&lt;&gt;
definition, as first template argument (except for
interrupt_states for which it is the second argument, the first
one being the event ending the interrupt), for example,
my_base_state being your new base state for all states in a
given state machine: <code class="code">struct Empty : public
msm::front::state&lt;my_base_state&gt;</code> Now,
my_base_state is your new base state. If it has a virtual
function, your states become polymorphic. MSM also provides a
default polymorphic base type for your convenience,
<code class="code">msm::front::polymorphic_state</code>
</p></li><li class="listitem"><p>Add the user-defined base state in the state machine frontend
definition, as a second template argument, for example:
<code class="code">struct player_ : public
msm::front::state_machine&lt;player_,my_base_state&gt;
</code></p></li></ul></div><p>You can also ask for a state with a given id (which you might have gotten
from current_state()) using <code class="code">const base_state* get_state_by_id(int id)
const</code> where base_state is the one you just defined. You can now
do something ploymorphically. For example using the visitor.</p></div><div class="sect4" title="Visitor"><div class="titlepage"><div><div><h5 class="title"><a name="d0e3498"></a><span class="command"><strong><a name="backend-visitor"></a></strong></span>Visitor</h5></div></div></div><p>In some cases, having a pointer-to-base of the currently active states is
not enough. You might want to call non-virtually a method of the currently
active states. It will not be said that MSM forces the virtual keyword down
your throat!</p><p>To achieve this goal, MSM provides its own variation of a visitor pattern
using the previously described user-defined state technique. If you add to
your user-defined base state an <code class="code">accept_sig</code> typedef giving the
return value (unused for the moment) and signature and provide an accept
method with this signature, calling visit_current_states will cause accept
to be called on the currently active states. Typically, you will also want
to provide an empty default accept in your base state in order in order not
to force all your states to implement accept. For example your base state
could be:</p><p><code class="code">struct my_visitable_state{</code></p><p><code class="code">// signature of the accept function</code></p><p><code class="code">typedef args&lt;void&gt; accept_sig;</code></p><p><code class="code">// we also want polymorphic states</code></p><p><code class="code">virtual ~my_visitable_state() {}</code></p><p><code class="code">// default implementation for states who do not need to be
visited</code></p><p><code class="code">void accept() const {}</code></p><p><code class="code">};</code></p><p>This makes your states polymorphic and visitable. In this case, accept is
made const and takes no argument. It could also be:</p><p><code class="code">struct SomeVisitor {&#8230;};</code></p><p><code class="code">struct my_visitable_state{</code></p><p><code class="code">// signature of the accept function</code></p><p><code class="code">typedef args&lt;void,SomeVisitor&amp;&gt; accept_sig;</code></p><p><code class="code">// we also want polymorphic states</code></p><p><code class="code">virtual ~my_visitable_state() {}</code></p><p><code class="code">// default implementation for states who do not need to be
visited</code></p><p><code class="code">void accept(SomeVisitor&amp;) const {}</code></p><p><code class="code">};</code></p><p>And now, accept will take one argument (it could also be non-const). By
default, accept takes up to 2 arguments. To get more, add a #define
BOOST_MSM_VISITOR_ARG_SIZE to another value before including
state_machine.hpp. For example:</p><p><code class="code">#define BOOST_MSM_VISITOR_ARG_SIZE 3</code></p><p><code class="code">#include &lt;boost/msm/back/state_machine.hpp&gt;</code></p><p>Note that accept will be called on ALL active states <span class="underline">and also automatically on sub-states of a
submachine</span>.</p><p><span class="underline">Important warning</span>: The method
visit_current_states takes its parameter by value, so if the signature of
the accept function is to contain a parameter passed by reference, pass this
parameter with a boost:ref/cref to avoid undesired copies or slicing. So,
for example, in the above case, call:</p><p><code class="code">SomeVisitor vis; sm.visit_current_states(boost::ref(vis));
</code></p><p>This <a class="link" href="examples/SM-2Arg.cpp" target="_top">example</a> uses a
visiting function with 2 arguments.</p></div><div class="sect4" title="Flags"><div class="titlepage"><div><div><h5 class="title"><a name="d0e3587"></a>Flags</h5></div></div></div><p>Flags is a MSM-only concept, supported by all front-ends, which base
themselves on the functions: </p><p><code class="code">template &lt;class Flag&gt; bool is_flag_active()</code> and</p><p><code class="code">template &lt;class Flag,class BinaryOp&gt; bool is_flag_active()</code>
</p><p>These functions return true if the currently active state(s) support the
Flag property. The first variant ORs the result if there are several
orthogonal regions, the second one expects OR or AND, for example:</p><p><code class="code">my_fsm.is_flag_active&lt;MyFlag&gt;()</code></p><p><code class="code">my_fsm.is_flag_active&lt;MyFlag,my_fsm_type::Flag_OR&gt;()</code></p><p>Please refer to the front-ends sections for more information.</p></div><div class="sect4" title="Getting a state"><div class="titlepage"><div><div><h5 class="title"><a name="d0e3610"></a>Getting a state</h5></div></div></div><p>It is sometimes necessary to have the client code get access to the
states' data. After all, the states are created once for good and hang
around as long as the state machine does so why not use it? You simply just
need sometimes to get information about any state, even inactive ones. An
example is if you want to write a coverage tool and know how many times a
state was visited. To get a state, use the get_state method giving the state
name, for example: </p><p><code class="code">player::Stopped* tempstate =
p.get_state&lt;player::Stopped*&gt;();</code> or </p><p><code class="code">player::Stopped&amp; tempstate2 =
p.get_state&lt;player::Stopped&amp;&gt;();</code> depending on your
personal taste. </p></div><div class="sect4" title="State machine constructor with arguments"><div class="titlepage"><div><div><h5 class="title"><a name="d0e3623"></a> State machine constructor with arguments </h5></div></div></div><p>You might want to define a state machine with a non-default constructor.
For example, you might want to write: </p><p><code class="code">struct player_ : public msm::front::state_machine_def&lt;player_&gt; {
player_(int some_value){&#8230;} } </code></p><p>This is possible, using the back-end as forwarding object: </p><p><code class="code">typedef msm::back::state_machine&lt;player_ &gt; player; player
p(3);</code> The back-end will call the corresponding front-end
constructor upon creation.</p><p>You can pass arguments up to the value of the
BOOST_MSM_CONSTRUCTOR_ARG_SIZE macro (currently 5) arguments. Change this
value before including any header if you need to change it. </p></div></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ar01s03.html">Prev</a>&nbsp;</td><td width="20%" align="center">&nbsp;</td><td width="40%" align="right">&nbsp;<a accesskey="n" href="ar01s05.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">UML Short Guide&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp; Performance / Compilers</td></tr></table></div></body></html>