• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html><head>
2      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
3   <title>eUML</title><link rel="stylesheet" href="boostbook.css" type="text/css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.75.2"><link rel="home" href="index.html" title="Meta State Machine (MSM)"><link rel="up" href="ch03.html" title="Chapter&nbsp;3.&nbsp;Tutorial"><link rel="prev" href="ch03s03.html" title="Functor front-end"><link rel="next" href="ch03s05.html" title="Back-end"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">eUML</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch03s03.html">Prev</a>&nbsp;</td><th width="60%" align="center">Chapter&nbsp;3.&nbsp;Tutorial</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="ch03s05.html">Next</a></td></tr></table><hr></div><div class="sect1" title="eUML"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e1429"></a><span class="command"><strong><a name="eUML-front-end"></a></strong></span>eUML</h2></div></div></div><p><span class="underline">Important note</span>: eUML requires a compiler
4                    supporting Boost.Typeof. Full eUML has experimental status (but not if only the
5                    transition table is written using eUML) because some compilers will start
6                    crashing when a state machine becomes too big (usually when you write huge
7                    actions).</p><p>The previous front-ends are simple to write but still force an amount of
8                    noise, mostly MPL types, so it would be nice to write code looking like C++
9                    (with a C++ action language) directly inside the transition table, like UML
10                    designers like to do on their state machine diagrams. If it were functional
11                    programming, it would be even better. This is what eUML is for.</p><p>eUML is a Boost.Proto and Boost.Typeof-based compile-time domain specific
12                    embedded language. It provides grammars which allow the definition of
13                    actions/guards directly inside the transition table or entry/exit in the state
14                    definition. There are grammars for actions, guards, flags, attributes, deferred
15                    events, initial states.</p><p>It also relies on Boost.Typeof as a wrapper around the new decltype C++0x
16                    feature to provide a compile-time evaluation of all the grammars. Unfortunately,
17                    all the underlying Boost libraries are not Typeof-enabled, so for the moment,
18                    you will need a compiler where Typeof is supported (like VC9-10, g++ &gt;=
19                    4.3).</p><p>Examples will be provided in the next paragraphs. You need to include eUML
20                    basic features: </p><p>
21                    </p><pre class="programlisting">#include &lt;msm/front/euml/euml.hpp&gt;</pre><p>
22                </p><p>To add STL support (at possible cost of longer compilation times), include: </p><p>
23                    </p><pre class="programlisting">#include &lt;msm/front/euml/stl.hpp&gt;</pre><p>
24                </p><p>eUML is defined in the namespace <code class="code">msm::front::euml</code>.</p><div class="sect2" title="Transition table"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1462"></a>Transition table</h3></div></div></div><p>A transition can be defined using eUML as: </p><p>
25                        </p><pre class="programlisting">source + event [guard] / action == target</pre><p>
26                    </p><p>or as</p><p>
27                        </p><pre class="programlisting">target == source + event [guard] / action</pre><p>
28                    </p><p>The first version looks like a drawn transition in a diagram, the second
29                        one seems natural to a C++ developer.</p><p>The simple transition table written with the <span class="command"><strong><a class="command" href="ch03s03.html#functor-front-end">functor front-end</a></strong></span> can now be
30                        written as:</p><pre class="programlisting">BOOST_MSM_EUML_TRANSITION_TABLE((
31Stopped + play [some_guard] / (some_action , start_playback)  == Playing ,
32Stopped + open_close/ open_drawer                             == Open    ,
33Stopped + stop                                                == Stopped ,
34Open    + open_close / close_drawer                           == Empty   ,
35Empty   + open_close / open_drawer                            == Open    ,
36Empty   + cd_detected [good_disk_format] / store_cd_info      == Stopped
37),transition_table)                       </pre><p>Or, using the alternative notation, it can be:</p><pre class="programlisting">BOOST_MSM_EUML_TRANSITION_TABLE((
38Playing  == Stopped + play [some_guard] / (some_action , start_playback) ,
39Open     == Stopped + open_close/ open_drawer                            ,
40Stopped  == Stopped + stop                                               ,
41Empty    == Open    + open_close / close_drawer                          ,
42Open     == Empty   + open_close / open_drawer                           ,
43Stopped  == Empty   + cd_detected [good_disk_format] / store_cd_info
44),transition_table)           </pre><p>The transition table now looks like a list of (readable) rules with little
45                        noise.</p><p>UML defines guards between &#8220;[ ]&#8221; and actions after a &#8220;/&#8221;, so the chosen
46                        syntax is already more readable for UML designers. UML also allows designers
47                        to define several actions sequentially (our previous ActionSequence_)
48                        separated by a comma. The first transition does just this: two actions
49                        separated by a comma and enclosed inside parenthesis to respect C++ operator
50                        precedence.</p><p>If this seems to you like it will cost you run-time performance, don't
51                        worry, eUML is based on typeof (or decltype) which only evaluates the
52                        parameters to BOOST_MSM_EUML_TRANSITION_TABLE and no run-time cost occurs.
53                        Actually, eUML is only a metaprogramming layer on top of "standard" MSM
54                        metaprogramming and this first layer generates the previously-introduced
55                            <span class="command"><strong><a class="command" href="ch03s03.html#functor-front-end">functor
56                        front-end</a></strong></span>.</p><p>UML also allows designers to define more complicated guards, like
57                        [good_disk_format &amp;&amp; (some_condition || some_other_condition)]. This
58                        was possible with our previously defined functors, but using a complicated
59                        template syntax. This syntax is now possible exactly as written, which means
60                        without any syntactic noise at all.</p></div><div class="sect2" title="A simple example: rewriting only our transition table"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1503"></a>A simple example: rewriting only our transition table </h3></div></div></div><p>As an introduction to eUML, we will rewrite our tutorial's transition
61                        table using eUML. This will require two or three changes, depending on the compiler:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>events must inherit from msm::front::euml::euml_event&lt;
62                                    event_name &gt;</p></li><li class="listitem"><p>states must inherit from msm::front::euml::euml_state&lt;
63                                    state_name &gt;</p></li><li class="listitem"><p>with VC, states must be declared before the front-end</p></li></ul></div><p>We now can write the transition table like just shown, using
64                        BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE instead of
65                        BOOST_MSM_EUML_TRANSITION_TABLE. The <a class="link" href="examples/SimpleTutorialWithEumlTable.cpp" target="_top">implementation</a> is pretty straightforward. The only required
66                        addition is the need to declare a variable for each state or add parenses (a
67                        default-constructor call) in the transition table.</p><p>The <a class="link" href="examples/CompositeTutorialWithEumlTable.cpp" target="_top">
68                      <span class="command"><strong></strong></span></a><a name="eUML-composite-table"></a><a class="link" href="examples/CompositeTutorialWithEumlTable.cpp" target="_top"><span class="command"><strong>composite</strong></span></a> implementation is also natural:</p><pre class="programlisting">// front-end like always
69struct sub_front_end : public boost::msm::front::state_machine_def&lt;sub_front_end&gt;
70{
71...
72};
73// back-end like always
74typedef boost::msm::back::state_machine&lt;sub_front_end&gt; sub_back_end;
75
76sub_back_end const sub; // sub can be used in a transition table.</pre><p>Unfortunately, there is a bug with VC, which appears from time to time and
77                        causes in a stack overflow. If you get a warning that the program is
78                        recursive on all paths, revert to either standard eUML or another front-end
79                        as Microsoft doesn't seem to intend to fix it.</p><p>We now have a new, more readable transition table with few changes to our
80                        example. eUML can do much more so please follow the guide.</p></div><div class="sect2" title="Defining events, actions and states with entry/exit actions"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1536"></a>Defining events, actions and states with entry/exit actions</h3></div></div></div><div class="sect3" title="Events"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1539"></a>Events</h4></div></div></div><p>Events must be proto-enabled. To achieve this, they must inherit from
81                            a proto terminal (euml_event&lt;event-name&gt;). eUML also provides a macro
82                            to make this easier:</p><p>
83                            </p><pre class="programlisting">BOOST_MSM_EUML_EVENT(play)</pre><p>
84                        </p><p>This declares an event type and an instance of this type called
85                                <code class="code">play</code>, which is now ready to use in state or transition
86                            behaviors.</p><p>There is a second macro, BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES, which
87                            takes as second parameter the attributes an event will contain, using
88                            the <span class="command"><strong><a class="command" href="ch03s04.html#eUML-attributes">attribute
89                            syntax</a></strong></span>.</p><p><span class="underline">Note</span>: as we now have events
90                            defined as instances instead of just types, can we still process an
91                            event by creating one on the fly, like:
92                                <code class="code">fsm.process_event(play());</code> or do we have to write:
93                                <code class="code">fsm.process_event(play);</code></p><p>The answer is you can do both. The second one is easier but unlike
94                            other front-ends, the second uses a defined operator(), which creates an
95                            event on the fly.</p></div><div class="sect3" title="Actions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1570"></a>Actions</h4></div></div></div><p>Actions (returning void) and guards (returning a bool) are defined
96                            like previous functors, with the difference that they also must be
97                            proto-enabled. This can be done by inheriting from euml_action&lt;
98                            functor-name &gt;. eUML also provides a macro:</p><pre class="programlisting">BOOST_MSM_EUML_ACTION(some_condition)
99{
100    template &lt;class Fsm,class Evt,class SourceState,class TargetState&gt;
101    bool operator()(Evt const&amp; ,Fsm&amp; ,SourceState&amp;,TargetState&amp; )
102    { return true; }
103}; </pre><p>Like for events, this macro declares a functor type and an instance
104                            for use in transition or state behaviors.</p><p>It is possible to use the same action grammar from the transition
105                            table to define state entry and exit behaviors. So
106                                <code class="code">(action1,action2)</code> is a valid entry or exit behavior
107                            executing both actions in turn.</p><p>The state functors have a slightly different signature as there is no
108                            source and target state but only a current state (entry/exit actions are
109                            transition-independent), for example:</p><pre class="programlisting">BOOST_MSM_EUML_ACTION(Empty_Entry)
110{
111    template &lt;class Evt,class Fsm,class State&gt;
112    void operator()(Evt const&amp; ,Fsm&amp; ,State&amp; ) { ... }
113    }; </pre><p><span class="command"><strong><a name="eUML-reuse-functor"></a></strong></span>It is also possible to reuse the functors from the functor front-end.
114                            The syntax is however slightly less comfortable as we need to pretend
115                            creating one on the fly for typeof. For example:</p><pre class="programlisting">struct start_playback
116{
117        template &lt;class Fsm,class Evt,class SourceState,class TargetState&gt;
118        void operator()(Evt const&amp; ,Fsm&amp;,SourceState&amp; ,TargetState&amp; )
119        {
120         ...
121        }
122};
123BOOST_MSM_EUML_TRANSITION_TABLE((
124Playing   == Stopped  + play        / start_playback() ,
125...
126),transition_table)</pre></div><div class="sect3" title="States"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1593"></a>States</h4></div></div></div><p>There is also a macro for states. This macro has 2 arguments, first
127                            the expression defining the state, then the state (instance)
128                            name:</p><pre class="programlisting">BOOST_MSM_EUML_STATE((),Paused)</pre><p>This defines a simple state without entry or exit action. You can
129                            provide in the expression parameter the state behaviors (entry and exit)
130                            using the action grammar, like in the transition table:</p><pre class="programlisting">BOOST_MSM_EUML_STATE(((Empty_Entry,Dummy_Entry)/*2 entryactions*/,
131                       Empty_Exit/*1 exit action*/ ),
132                     Empty)</pre><p>This means that Empty is defined as a state with an entry action made
133                            of two sub-actions, Empty_Entry and Dummy_Entry (enclosed inside
134                            parenthesis), and an exit action, Empty_Exit.</p><p>There are several possibilitites for the <span class="command"><strong><a name="eUML-build-state"></a></strong></span> expression syntax:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>(): state without entry or exit action.</p></li><li class="listitem"><p>(Expr1): state with entry but no exit action.</p></li><li class="listitem"><p>(Expr1,Expr2): state with entry and exit action.</p></li><li class="listitem"><p>(Expr1,Expr2,Attributes): state with entry and exit
135                                        action, defining some attributes (read further on).</p></li><li class="listitem"><p>(Expr1,Expr2,Attributes,Configure): state with entry and
136                                        exit action, defining some attributes (read further on) and
137                                        flags (standard MSM flags) or deferred events (standard MSM
138                                        deferred events).</p></li><li class="listitem"><p>(Expr1,Expr2,Attributes,Configure,Base): state with entry
139                                        and exit action, defining some attributes (read further on),
140                                        flags and deferred events (plain msm deferred events) and a
141                                        non-default base state (as defined in standard MSM).</p></li></ul></div><p>no_action is also defined, which does, well, nothing except being a
142                            placeholder (needed for example as entry action if we have no entry but
143                            an exit). Expr1 and Expr2 are a sequence of actions, obeying the same
144                            action grammar as in the transition table (following the &#8220;/&#8221;
145                            symbol).</p><p>The BOOST_MSM_EUML_STATE macro will allow you to define most common
146                            states, but sometimes you will need more, for example provide in your
147                            states some special behavior. In this case, you will have to do the
148                            macro's job by hand, which is not very complicated. The state will need
149                            to inherit from <code class="code">msm::front::state&lt;&gt;</code>, like any state, and
150                            from <code class="code">euml_state&lt;state-name&gt;</code> to be proto-enabled. You
151                            will then need to declare an instance for use in the transition table.
152                            For example:</p><pre class="programlisting">struct Empty_impl : public msm::front::state&lt;&gt; , public euml_state&lt;Empty_impl&gt;
153{
154   void activate_empty() {std::cout &lt;&lt; "switching to Empty " &lt;&lt; std::endl;}
155   template &lt;class Event,class Fsm&gt;
156   void on_entry(Event const&amp; evt,Fsm&amp;fsm){...}
157   template &lt;class Event,class Fsm&gt;
158   void on_exit(Event const&amp; evt,Fsm&amp;fsm){...}
159};
160//instance for use in the transition table
161Empty_impl const Empty;</pre><p>Notice also that we defined a method named activate_empty. We would
162                            like to call it inside a behavior. This can be done using the
163                            BOOST_MSM_EUML_METHOD macro. </p><pre class="programlisting">BOOST_MSM_EUML_METHOD(ActivateEmpty_,activate_empty,activate_empty_,void,void)</pre><p>The first parameter is the name of the underlying functor, which you
164                            could use with the functor front-end, the second is the state method
165                            name, the third is the eUML-generated function, the fourth and fifth the
166                            return value when used inside a transition or a state behavior. You can
167                            now use this inside a transition:</p><pre class="programlisting">Empty == Open + open_close / (close_drawer,activate_empty_(target_))</pre></div></div><div class="sect2" title="Wrapping up a simple state machine and first complete examples"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1649"></a>Wrapping up a simple state machine and first complete examples</h3></div></div></div><p>You can reuse the state machine definition method from the standard
168                        front-end and simply replace the transition table by this new one. You can
169                        also use eUML to define a state machine "on the fly" (if, for example, you
170                        need to provide an on_entry/on_exit for this state machine as a functor).
171                        For this, there is also a macro, <span class="command"><strong><a name="eUML-build-sm"></a></strong></span>BOOST_MSM_EUML_DECLARE_STATE_MACHINE, which has 2 arguments, an expression
172                        describing the state machine and the state machine name. The expression has
173                        up to 8 arguments:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>(Stt, Init): simplest state machine where only the transition
174                                    table and initial state(s) are defined.</p></li><li class="listitem"><p>(Stt, Init, Expr1): state machine where the transition table,
175                                    initial state and entry action are defined.</p></li><li class="listitem"><p>(Stt, Init, Expr1, Expr2): state machine where the transition
176                                    table, initial state, entry and exit actions are defined.</p></li><li class="listitem"><p>(Stt, Init, Expr1, Expr2, Attributes): state machine where the
177                                    transition table, initial state, entry and exit actions are
178                                    defined. Furthermore, some attributes are added (read further
179                                    on).</p></li><li class="listitem"><p>(Stt, Init, Expr1, Expr2, Attributes, Configure): state
180                                    machine where the transition table, initial state, entry and
181                                    exit actions are defined. Furthermore, some attributes (read
182                                    further on), flags, deferred events and <a class="link" href="ch03s04.html#eUML-Configuration">configuration
183                                        capabilities</a> (no message queue / no exception
184                                    catching) are added.</p></li><li class="listitem"><p>(Stt, Init, Expr1, Expr2, Attributes, Flags, Deferred , Base):
185                                    state machine where the transition table, initial state, entry
186                                    and exit actions are defined. Furthermore, attributes (read
187                                    further on), flags , deferred events and configuration
188                                    capabilities (no message queue / no exception catching) are
189                                    added and a non-default base state (see the <a class="link" href="ch03s05.html#backend-base-state">back-end
190                                    description</a>) is defined.</p></li></ul></div><p>For example, a minimum state machine could be defined
191                        as:</p><pre class="programlisting">BOOST_MSM_EUML_TRANSITION_TABLE((
192),transition_table)                       </pre><pre class="programlisting">BOOST_MSM_EUML_DECLARE_STATE_MACHINE((transition_table,init_ &lt;&lt; Empty ),
193                                     player_)</pre><p>Please have a look at the player tutorial written using eUML's <a class="link" href="examples/SimpleTutorialEuml2.cpp" target="_top">first syntax</a> and
194                            <a class="link" href="examples/SimpleTutorialEuml.cpp" target="_top">second syntax</a>.
195                        The BOOST_MSM_EUML_DECLARE_ATTRIBUTE macro, to which we will get back
196                        shortly, declares attributes given to an eUML type (state or event) using
197                        the <span class="command"><strong><a class="command" href="ch03s04.html#eUML-attributes">attribute
198                        syntax</a></strong></span>.</p></div><div class="sect2" title="Defining a submachine"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1697"></a>Defining a submachine</h3></div></div></div><p>Defining a submachine (see <a class="link" href="examples/CompositeTutorialEuml.cpp" target="_top">tutorial</a>) with
199                        other front-ends simply means using a state which is a state machine in the
200                        transition table of another state machine. This is the same with eUML. One
201                        only needs define a second state machine and reference it in the transition
202                        table of the containing state machine.</p><p>Unlike the state or event definition macros,
203                        BOOST_MSM_EUML_DECLARE_STATE_MACHINE defines a type, not an instance because
204                        a type is what the back-end requires. This means that you will need to
205                        declare yourself an instance to reference your submachine into another state
206                        machine, for example:</p><pre class="programlisting">BOOST_MSM_EUML_DECLARE_STATE_MACHINE(...,Playing_)
207typedef msm::back::state_machine&lt;Playing_&gt; Playing_type;
208Playing_type const Playing;</pre><p>We can now use this instance inside the transition table of the containing
209                        state machine:</p><pre class="programlisting">Paused == Playing + pause / pause_playback</pre></div><div class="sect2" title="Attributes / Function call"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1713"></a>
210                        <span class="command"><strong><a name="eUML-attributes"></a></strong></span>Attributes / Function call</h3></div></div></div><p>We now want to make our grammar more useful. Very often, one needs only
211                        very simple action methods, for example ++Counter or Counter &gt; 5 where
212                        Counter is usually defined as some attribute of the class containing the
213                        state machine. It seems like a waste to write a functor for such a simple
214                        action. Furthermore, states within MSM are also classes so they can have
215                        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
216                        will find a BOOST_MSM_EUML_DECLARE_ATTRIBUTE and a BOOST_MSM_EUML_ATTRIBUTES
217                        macro. The first one declares possible attributes:</p><pre class="programlisting">BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,cd_name)
218BOOST_MSM_EUML_DECLARE_ATTRIBUTE(DiskTypeEnum,cd_type)</pre><p>This declares two attributes: cd_name of type std::string and cd_type of
219                        type DiskTypeEnum. These attributes are not part of any event or state in
220                        particular, we just declared a name and a type. Now, we can add attributes
221                        to our cd_detected event using the second one:</p><pre class="programlisting">BOOST_MSM_EUML_ATTRIBUTES((attributes_ &lt;&lt; cd_name &lt;&lt; cd_type ),
222                          cd_detected_attributes)</pre><p>This declares an attribute list which is not linked to anything in
223                        particular yet. It can be attached to a state or an event. For example, if
224                        we want the event cd_detected to have these defined attributes we
225                        write:</p><pre class="programlisting">BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(cd_detected,cd_detected_attributes)</pre><p>For states, we use the BOOST_MSM_EUML_STATE macro, which has an expression
226                        form where one can provide attributes. For example:</p><pre class="programlisting">BOOST_MSM_EUML_STATE((no_action /*entry*/,no_action/*exit*/,
227                      attributes_ &lt;&lt; cd_detected_attributes),
228                     some_state)</pre><p>OK, great, we now have a way to add attributes to a class, which we could
229                        have done more easily, so what is the point? The point is that we can now
230                        reference these attributes directly, at compile-time, in the transition
231                        table. For example, in the example, you will find this transition:</p><pre class="programlisting">Stopped==Empty+cd_detected[good_disk_format&amp;&amp;(event_(cd_type)==Int_&lt;DISK_CD&gt;())] </pre><p>Read event_(cd_type) as event_-&gt;cd_type with event_ a type generic for
232                        events, whatever the concrete event is (in this particular case, it happens
233                        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
234                        functor and you do not need to look inside the functor to know what it does,
235                        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
236                                    transition</p></li><li class="listitem"><p>state_: used inside entry and exit actions, the entered /
237                                    exited state</p></li><li class="listitem"><p>source_: used inside a transition action, the source
238                                    state</p></li><li class="listitem"><p>target_: used inside a transition action, the target
239                                    state</p></li><li class="listitem"><p>fsm_: used inside any action, the (lowest-level) state machine
240                                    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
241                                    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
242                                    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 provide your states with their
243                        own methods, which you also want to use inside the transition table. In the
244                            <a class="link" href="examples/SimpleTutorialEuml.cpp" target="_top">above
245                        tutorial</a>, we provide Empty with an activate_empty method. We would
246                        like to create a eUML functor and call it from inside the transition table.
247                        This is done using the MSM_EUML_METHOD / MSM_EUML_FUNCTION macros. The first
248                        creates a functor to a method, the second to a free function. In the
249                        tutorial, we write:</p><pre class="programlisting">MSM_EUML_METHOD(ActivateEmpty_,activate_empty,activate_empty_,void,void)</pre><p>The first parameter is the functor name, for use with the functor
250                        front-end. The second is the name of the method to call. The third is the
251                        function name for use with eUML, the fourth is the return type of the
252                        function if used in the context of a transition action, the fifth is the
253                        result type if used in the context of a state entry / exit action (usually
254                        fourth and fifth are the same). We now have a new eUML function calling a
255                        method of "something", and this "something" is one of the five previously
256                        shown generic helpers. We can now use this in a transition, for
257                        example:</p><pre class="programlisting">Empty == Open + open_close / (close_drawer,activate_empty_(target_))</pre><p>The action is now defined as a sequence of two actions: close_drawer and
258                        activate_empty, which is called on the target itself. The target being Empty
259                        (the state defined left), this really will call Empty::activate_empty().
260                        This method could also have an (or several) argument(s), for example the
261                        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
262                            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>
263                        (for String_ and more).</p></div><div class="sect2" title="Orthogonal regions, flags, event deferring"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1813"></a>Orthogonal regions, flags, event deferring</h3></div></div></div><p>Defining orthogonal regions really means providing more initial states. To
264                        add more initial states, &#8220;shift left&#8221; some, for example, if we had another
265                        initial state named AllOk :</p><pre class="programlisting">BOOST_MSM_EUML_DECLARE_STATE_MACHINE((transition_table,
266                                     init_ &lt;&lt; Empty &lt;&lt; AllOk ),
267                                    player_)</pre><p>You remember from the <span class="command"><strong><a class="command" href="ch03s04.html#eUML-build-state">BOOST_MSM_EUML_STATE </a></strong></span> and <span class="command"><strong><a class="command" href="ch03s04.html#eUML-build-sm">BOOST_MSM_EUML_DECLARE_STATE_MACHINE</a></strong></span> signatures that just
268                        after attributes, we can define flags, like in the basic MSM front-end. To
269                        do this, we have another "shift-left" grammar, for example:</p><pre class="programlisting">BOOST_MSM_EUML_STATE((no_action,no_action, attributes_ &lt;&lt;no_attributes_,
270                      /* flags */ configure_&lt;&lt; PlayingPaused &lt;&lt; CDLoaded),
271                    Paused)</pre><p>We now defined that Paused will get two flags, PlayingPaused and CDLoaded,
272                        defined, with another macro:</p><pre class="programlisting">BOOST_MSM_EUML_FLAG(CDLoaded)</pre><p>This corresponds to the following basic front-end definition of
273                        Paused:</p><pre class="programlisting">struct Paused : public msm::front::state&lt;&gt;
274{
275   typedef mpl::vector2&lt;PlayingPaused,CDLoaded&gt; flag_list;
276};</pre><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
277                        BOOST_MSM_EUML_STATE's expression with 4 arguments, we need to tell eUML
278                        that we need no attributes. Similarly to a <code class="code">cout &lt;&lt; endl</code>,
279                        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.
280                        You can also use the provided helper function is_flag_ (returning a bool)
281                        for state and transition behaviors. For example, in the <a class="link" href="examples/iPodEuml.cpp" target="_top">iPod implementation with eUML</a>,
282                        you find the following transition:</p><pre class="programlisting">ForwardPressed == NoForward + EastPressed[!is_flag_(NoFastFwd)]</pre><p>The function also has an optional second parameter which is the state
283                        machine on which the function is called. By default, fsm_ is used (the
284                        current state machine) but you could provide a functor returning a reference
285                        to another state machine.</p><p>eUML also supports defining deferred events in the state (state machine)
286                        definition. To this aim, we can reuse the flag grammar. For example:</p><pre class="programlisting">BOOST_MSM_EUML_STATE((Empty_Entry,Empty_Exit, attributes_ &lt;&lt; no_attributes_,
287                      /* deferred */ configure_&lt;&lt; play ),Empty) </pre><p>The configure_ left shift is also responsible for deferring events. Shift
288                        inside configure_ a flag and the state will get a flag, shift an event and
289                        it will get a deferred event. This replaces the basic front-end
290                        definition:</p><pre class="programlisting">typedef mpl::vector&lt;play&gt; deferred_events;</pre><p>In <a class="link" href="examples/OrthogonalDeferredEuml.cpp" target="_top">this
291                            tutorial</a>, player is defining a second orthogonal region with
292                        AllOk as initial state. The <code class="code">Empty</code> and <code class="code">Open</code> states
293                        also defer the event <code class="code">play</code>. <code class="code">Open</code>,
294                            <code class="code">Stopped</code> and <code class="code">Pause</code> also support the flag
295                            <code class="code">CDLoaded</code> using the same left shift into
296                            <code class="code">configure_</code>.</p><p>In the functor front-end, we also had the possibility to defer an event
297                        inside a transition, which makes possible conditional deferring. This is
298                        also possible with eUML through the use of the defer_ order, as shown in
299                            <a class="link" href="examples/OrthogonalDeferredEuml.cpp" target="_top">this
300                            tutorial</a>. You will find the following transition:</p><pre class="programlisting">Open + play / defer_</pre><p>This is an <span class="command"><strong><a class="command" href="ch03s04.html#eUML-internal">internal
301                            transition</a></strong></span>. Ignore it for the moment. Interesting is, that
302                        when the event <code class="code">play</code> is fired and <code class="code">Open</code> is active,
303                        the event will be deferred. Now add a guard and you can conditionally defer
304                        the event, for example:</p><pre class="programlisting">Open + play [ some_condition ] / defer_</pre><p>This is similar to what we did with the functor front-end. This means that
305                        we have the same constraints. Using defer_ instead of a state declaration,
306                        we need to tell MSM that we have deferred events in this state machine. We
307                        do this (again) using a configure_ declaration in the state machine
308                        definition in which we shift the deferred_events configuration flag:</p><pre class="programlisting">BOOST_MSM_EUML_DECLARE_STATE_MACHINE((transition_table,
309                                      init_ &lt;&lt; Empty &lt;&lt; AllOk,
310                                      Entry_Action,
311                                      Exit_Action,
312                                      attributes_ &lt;&lt; no_attributes_,
313                                      configure_&lt;&lt; deferred_events ),
314                                    player_)</pre><p>A <a class="link" href="examples/OrthogonalDeferredEuml2.cpp" target="_top">tutorial</a>
315                        illustrates this possibility.</p></div><div class="sect2" title="Customizing a state machine / Getting more speed"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1925"></a>
316                        <span class="command"><strong><a name="eUML-Configuration"></a></strong></span>Customizing a state machine / Getting
317                        more speed</h3></div></div></div><p>We just saw how to use configure_ to define deferred events or flags. We
318                        can also use it to configure our state machine like we did with the other front-ends:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><code class="code">configure_ &lt;&lt; no_exception</code>: disables
319                                    exception handling</p></li><li class="listitem"><p><code class="code">configure_ &lt;&lt; no_msg_queue</code> deactivates the
320                                    message queue</p></li><li class="listitem"><p><code class="code">configure_ &lt;&lt; deferred_events</code> manually
321                                    enables event deferring</p></li></ul></div><p>Deactivating the first two features and not activating the third if not
322                        needed greatly improves the event dispatching speed of your state machine.
323                        Our <a class="link" href="examples/EumlSimple.cpp" target="_top">speed testing</a> example
324                        with eUML does this for the best performance.</p><p><span class="underline">Important note</span>: As exit pseudo
325                        states are using the message queue to forward events out of a submachine,
326                        the <code class="code">no_message_queue</code> option cannot be used with state machines
327                        containing an exit pseudo state.</p></div><div class="sect2" title="Completion / Anonymous transitions"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1960"></a>Completion / Anonymous transitions</h3></div></div></div><p>Anonymous transitions (See <span class="command"><strong><a class="command" href="ch02s02.html#uml-anonymous">UML
328                            tutorial</a></strong></span>) are transitions without a named event, which are
329                        therefore triggered immediately when the source state becomes active,
330                        provided a guard allows it. As there is no event, to define such a
331                        transition, simply omit the &#8220;+&#8221; part of the transition (the event), for
332                        example: </p><pre class="programlisting">State3 == State4 [always_true] / State3ToState4
333State4 [always_true] / State3ToState4 == State3</pre><p>Please have a look at <a class="link" href="examples/AnonymousTutorialEuml.cpp" target="_top">this example</a>,
334                        which implements the <span class="command"><strong><a class="command" href="ch03s02.html#anonymous-transitions">previously
335                            defined</a></strong></span> state machine with eUML.</p></div><div class="sect2" title="Internal transitions"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1978"></a><span class="command"><strong><a name="eUML-internal"></a></strong></span>Internal transitions</h3></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
336                                    need to specify a source state, event, actions and guards but no
337                                    target state, which eUML will interpret as an internal
338                                    transition, for example this defines a transition internal to
339                                    Open, on the event open_close:</p><pre class="programlisting">Open + open_close [internal_guard1] / internal_action1</pre><p><a class="link" href="examples/EumlInternal.cpp" target="_top">A full
340                                        example</a> is also provided.</p></li><li class="listitem"><p>in a state's <code class="code">internal_transition_table</code>. For
341                                    example:</p><pre class="programlisting">BOOST_MSM_EUML_DECLARE_STATE((Open_Entry,Open_Exit),Open_def)
342struct Open_impl : public Open_def
343{
344   BOOST_MSM_EUML_DECLARE_INTERNAL_TRANSITION_TABLE((
345        open_close [internal_guard1] / internal_action1
346   ))
347};</pre><p>Notice how we do not need to repeat that the transition
348                                    originates from Open as we already are in Open's context. </p><p>The <a class="link" href="examples/EumlInternalDistributed.cpp" target="_top">implementation</a> also shows the added bonus offered
349                                    for submachines, which can have both the standard
350                                    transition_table and an internal_transition_table (which has
351                                    higher priority). This makes it easier if you decide to make a
352                                    full submachine from a state. It is also slightly faster than
353                                    the standard alternative, adding orthogonal regions, because
354                                    event dispatching will, if accepted by the internal table, not
355                                    continue to the subregions. This gives you a O(1) dispatch
356                                    instead of O(number of regions).</p></li></ul></div></div><div class="sect2" title="Kleene(any) event)"><div class="titlepage"><div><div><h3 class="title"><a name="d0e2009"></a><span class="command"><strong><a name="kleene-event"></a></strong></span>Kleene(any) event)</h3></div></div></div><p>As for the functor front-end, eUML supports the concept of an <span class="italic"><span class="command"><strong><a class="command" href="ch03s03.html#any-event">any</a></strong></span></span>
357                        event, but boost::any is not an acceptable eUML terminal. If you need an
358                            <span class="italic">any</span> event, use
359                        msm::front::euml::kleene, which inherits boost::any. The same transition as
360                        with boost:any would be: </p><pre class="programlisting">State1 + kleene == State2</pre></div><div class="sect2" title="Other state types"><div class="titlepage"><div><div><h3 class="title"><a name="d0e2024"></a>Other state types</h3></div></div></div><p>We saw the <span class="command"><strong><a class="command" href="ch03s04.html#eUML-build-state">build_state</a></strong></span>
361                        function, which creates a simple state. Likewise, eUML provides other
362                        state-building macros for other types of states:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>BOOST_MSM_EUML_TERMINATE_STATE takes the same arguments as
363                                    BOOST_MSM_EUML_STATE and defines, well, a terminate
364                                    state.</p></li><li class="listitem"><p>BOOST_MSM_EUML_INTERRUPT_STATE takes the same arguments as
365                                    BOOST_MSM_EUML_STATE and defines an interrupt state. However,
366                                    the expression argument must contain as first element the event
367                                    ending the interruption, for example:
368                                        <code class="code">BOOST_MSM_EUML_INTERRUPT_STATE(( end_error /*end
369                                        interrupt event*/,ErrorMode_Entry,ErrorMode_Exit
370                                        ),ErrorMode)</code></p></li><li class="listitem"><p>BOOST_MSM_EUML_EXIT_STATE takes the same arguments as
371                                    BOOST_MSM_EUML_STATE and defines an exit pseudo state. However,
372                                    the expression argument must contain as first element the event
373                                    propagated from the exit point:
374                                        <code class="code">BOOST_MSM_EUML_EXIT_STATE(( event6 /*propagated
375                                        event*/,PseudoExit1_Entry,PseudoExit1_Exit
376                                        ),PseudoExit1)</code></p></li><li class="listitem"><p>BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE defines an entry pseudo
377                                    state. It takes 3 parameters: the region index to be entered is
378                                    defined as an int argument, followed by the configuration
379                                    expression like BOOST_MSM_EUML_STATE and the state name, so that
380                                        <code class="code">BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE(0 /*region
381                                        index*/,( SubState2_Entry,SubState2_Exit ),SubState2)</code>
382                                    defines an entry state into the first region of a
383                                    submachine.</p></li><li class="listitem"><p>BOOST_MSM_EUML_ENTRY_STATE defines an entry pseudo state. It
384                                    takes 3 parameters: the region index to be entered is defined as
385                                    an int argument, followed by the configuration expression like
386                                    BOOST_MSM_EUML_STATE and the state name, so that
387                                        <code class="code">BOOST_MSM_EUML_ENTRY_STATE(0,(
388                                        PseudoEntry1_Entry,PseudoEntry1_Exit ),PseudoEntry1)</code>
389                                    defines a pseudo entry state into the first region of a
390                                    submachine.</p></li></ul></div><p>To use these states in the transition table, eUML offers the functions
391                            <code class="code">explicit_</code>, <code class="code">exit_pt_</code> and
392                        <code class="code">entry_pt_</code>. For example, a direct entry into the substate
393                        SubState2 from SubFsm2 could be:</p><pre class="programlisting">explicit_(SubFsm2,SubState2) == State1 + event2</pre><p>Forks being a list on direct entries, eUML supports a logical syntax
394                        (state1, state2, ...), for example:</p><pre class="programlisting">(explicit_(SubFsm2,SubState2),
395 explicit_(SubFsm2,SubState2b),
396 explicit_(SubFsm2,SubState2c)) == State1 + event3 </pre><p>An entry point is entered using the same syntax as explicit entries:
397                        </p><pre class="programlisting">entry_pt_(SubFsm2,PseudoEntry1) == State1 + event4</pre><p>For exit points, it is again the same syntax except that exit points are
398                        used as source of the transition:
399                        </p><pre class="programlisting">State2 == exit_pt_(SubFsm2,PseudoExit1) + event6 </pre><p>The <a class="link" href="examples/DirectEntryEuml.cpp" target="_top">entry tutorial</a>
400                        is also available with eUML.</p></div><div class="sect2" title="Helper functions"><div class="titlepage"><div><div><h3 class="title"><a name="d0e2088"></a>Helper functions</h3></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
401                                    transition</p></li><li class="listitem"><p>state_: used inside entry and exit actions, the entered /
402                                    exited state</p></li><li class="listitem"><p>source_: used inside a transition action, the source
403                                    state</p></li><li class="listitem"><p>target_: used inside a transition action, the target
404                                    state</p></li><li class="listitem"><p>fsm_: used inside any action, the (deepest-level) state
405                                    machine processing the transition</p></li><li class="listitem"><p>These objects can also be used as a function and return an
406                                    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
407                                    respectively</p></li><li class="listitem"><p>String_&lt;mpl::string&gt; (boost &gt;= 1.40): a functor
408                                    representing a string.</p></li><li class="listitem"><p>if_then_else_(guard, action, action) where action can be an
409                                    action sequence</p></li><li class="listitem"><p>if_then_(guard, action) where action can be an action
410                                    sequence</p></li><li class="listitem"><p>while_(guard, action) where action can be an action
411                                    sequence</p></li><li class="listitem"><p>do_while_(guard, action) where action can be an action
412                                    sequence</p></li><li class="listitem"><p>for_(action, guard, action, action) where action can be an
413                                    action sequence</p></li><li class="listitem"><p>process_(some_event [, some state machine] [, some state
414                                    machine] [, some state machine] [, some state machine]) will
415                                    call process_event (some_event) on the current state machine or
416                                    on the one(s) passed as 2nd , 3rd, 4th, 5th argument. This allow
417                                    sending events to several external machines</p></li><li class="listitem"><p>process_(event_): reprocesses the event which triggered the
418                                    transition</p></li><li class="listitem"><p>reprocess_(): same as above but shorter to write</p></li><li class="listitem"><p>process2_(some_event,Value [, some state machine] [, some
419                                    state machine] [, some state machine]) will call process_event
420                                    (some_event(Value)) on the current state machine or on the
421                                    one(s) passed as 3rd, 4th, 5th argument</p></li><li class="listitem"><p>is_ flag_(some_flag[, some state machine]) will call
422                                    is_flag_active on the current state machine or on the one passed
423                                    as 2nd argument</p></li><li class="listitem"><p>Predicate_&lt;some predicate&gt;: Used in STL algorithms. Wraps
424                                    unary/binary functions to make them eUML-compatible so that they
425                                    can be used in STL algorithms</p></li></ul></div><p>This can be quite fun. For example, </p><pre class="programlisting">/( if_then_else_(--fsm_(m_SongIndex) &gt; Int_&lt;0&gt;(),/*if clause*/
426                 show_playing_song, /*then clause*/
427                 (fsm_(m_SongIndex)=Int_&lt;1&gt;(),process_(EndPlay))/*else clause*/
428                 )
429  )</pre><p>means: if (fsm.SongIndex &gt; 0, call show_playing_song else
430                        {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>
431                                    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
432                                        rewritten</a> with eUML. In this example, you will also
433                                    find some examples of STL functor usage.</p></li><li class="listitem"><p><a class="link" href="examples/SimpleTimer.cpp" target="_top">A simpler
434                                        timer</a> example is a good starting point. </p></li></ul></div><p>There is unfortunately a small catch. Defining a functor using
435                        MSM_EUML_METHOD or MSM_EUML_FUNCTION will create a correct functor. Your own
436                        eUML functors written as described at the beginning of this section will
437                        also work well, <span class="underline">except</span>, for the
438                        moment, with the while_, if_then_, if_then_else_ functions.</p></div><div class="sect2" title="Phoenix-like STL support"><div class="titlepage"><div><div><h3 class="title"><a name="d0e2191"></a>Phoenix-like STL support</h3></div></div></div><p>eUML supports most C++ operators (except address-of). For example it is
439                        possible to write event_(some_attribute)++ or [source_(some_bool) &amp;&amp;
440                        fsm_(some_other_bool)]. But a programmer needs more than operators in his
441                        daily programming. The STL is clearly a must have. Therefore, eUML comes in
442                        with a lot of functors to further reduce the need for your own functors for
443                        the transition table. For almost every algorithm or container method of the
444                        STL, a corresponding eUML function is defined. Like Boost.Phoenix, &#8220;.&#8221; And
445                        &#8220;-&gt;&#8221; of call on objects are replaced by a functional programming paradigm,
446                        for example:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>begin_(container), end_(container): return iterators of a
447                                    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
448                        corresponding functor, which can then be used in the transition table or
449                        state actions. The <a class="link" href="pt02.html#Reference-begin">reference</a>
450                        lists all eUML functions and the underlying functor (so that this
451                        possibility is not reserved to eUML but also to the functor-based
452                        front-end). The file structure of this Phoenix-like library matches the one
453                        of Boost.Phoenix. All functors for STL algorithms are to be found in:</p><pre class="programlisting">#include &lt;msm/front/euml/algorithm.hpp&gt;</pre><p>The algorithms are also divided into sub-headers, matching the phoenix
454                        structure for simplicity:</p><pre class="programlisting">#include &lt; msm/front/euml/iteration.hpp&gt;
455#include &lt; msm/front/euml/transformation.hpp&gt;
456#include &lt; msm/front/euml/querying.hpp&gt; </pre><p>Container methods can be found in:</p><pre class="programlisting">#include &lt; msm/front/euml/container.hpp&gt;</pre><p>Or one can simply include the whole STL support (you will also need to
457                        include euml.hpp):</p><pre class="programlisting">#include &lt; msm/front/euml/stl.hpp&gt;</pre><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>:
458                                    the state machine has an attribute m_tgt_container of type
459                                    std::vector&lt;OneSong&gt; and the event has an attribute m_song of
460                                    type OneSong. The line therefore pushes m_song at the end of
461                                    m_tgt_container</p></li><li class="listitem"><p><code class="code">if_then_( state_(m_src_it) !=
462                                        end_(fsm_(m_src_container)),
463                                        process2_(OneSong(),*(state_(m_src_it)++)) )</code>: the
464                                    current state has an attribute m_src_it (an iterator). If this
465                                    iterator != fsm.m_src_container.end(), process OneSong on fsm,
466                                    copy-constructed from state.m_src_it which we
467                                    post-increment</p></li></ul></div></div><div class="sect2" title="Writing actions with Boost.Phoenix (in development)"><div class="titlepage"><div><div><h3 class="title"><a name="d0e2244"></a><span class="command"><strong><a name="eUML-phoenix"></a></strong></span>Writing actions with Boost.Phoenix (in development)</h3></div></div></div><p> It is also possible to write actions, guards, state entry and exit
468                        actions using a reduced set of Boost.Phoenix capabilities. This feature
469                        is still in development stage, so you might get here and there some
470                        surprise. Simple cases, however, should work well. What will not work
471                        will be mixing of eUML and Phoenix functors. Writing guards in one
472                        language and actions in another is ok though.</p><p>Phoenix also supports a larger syntax than what will ever be possible
473                        with eUML, so you can only use a reduced set of phoenix's grammar. This
474                        is due to the nature of eUML. The run-time transition table definition
475                        is translated to a type using Boost.Typeof. The result is a "normal" MSM
476                        transition table made of functor types. As C++ does not allow mixing
477                        run-time and compile-time constructs, there will be some limit (trying
478                        to instantiate a template class MyTemplateClass&lt;i&gt; where i is an int
479                        will give you an idea). This means following valid Phoenix constructs
480                        will not work:</p><p>
481                        </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>literals</p></li><li class="listitem"><p>function pointers</p></li><li class="listitem"><p>bind</p></li><li class="listitem"><p>-&gt;*</p></li></ul></div><p>
482                    </p><p>MSM also provides placeholders which make more sense in its context
483                        than arg1.. argn:</p><p>
484                        </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>_event: the event triggering the transition</p></li><li class="listitem"><p>_fsm: the state machine processing the event</p></li><li class="listitem"><p>_source: the source state of the transition</p></li><li class="listitem"><p>_target: the target state of the transition</p></li><li class="listitem"><p>_state: for state entry/exit actions, the entry/exit
485                                    state</p></li></ul></div><p>
486                    </p><p>Future versions of MSM will support Phoenix better. You can contribute
487                        by finding out cases which do not work but should, so that they can be
488                        added.</p><p>Phoenix support is not activated by default. To activate it, add
489                        before any MSM header: #define BOOST_MSM_EUML_PHOENIX_SUPPORT.</p><p>A <a class="link" href="examples/SimplePhoenix.cpp" target="_top">simple example</a> shows some basic capabilities.</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch03s03.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="ch03.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="ch03s05.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Functor front-end&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;Back-end</td></tr></table></div></body></html>