| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>eUML (experimental)</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) V2.12"><link rel="up" href="ch03.html" title="Chapter 3. 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 (experimental)</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch03s03.html">Prev</a> </td><th width="60%" align="center">Chapter 3. Tutorial</th><td width="20%" align="right"> <a accesskey="n" href="ch03s05.html">Next</a></td></tr></table><hr></div><div class="sect1" title="eUML (experimental)"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e1362"></a><span class="command"><strong><a name="eUML-front-end"></a></strong></span>eUML (experimental)</h2></div></div></div><p><span class="underline">Important note</span>: eUML requires a compiler |
| supporting Boost.Typeof. More generally, eUML has experimental status because |
| most compilers will start crashing when a state machine becomes too big.</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. If it were functional |
| 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 |
| embedded language. It provides grammars which allow the definition of |
| actions/guards directly inside the transition table or entry/exit in the state |
| definition. 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++ >= 4.3).</p><p>Examples will be provided in the next paragraphs. You need to include eUML |
| basic features: </p><p> |
| </p><pre class="programlisting">#include <msm/front/euml/euml.hpp></pre><p> |
| </p><p>To add STL support (at possible cost of longer compilation times), include: </p><p> |
| </p><pre class="programlisting">#include <msm/front/euml/stl.hpp></pre><p> |
| </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="d0e1395"></a>Transition table</h3></div></div></div><p>A transition can be defined using eUML as: </p><p> |
| </p><pre class="programlisting">source + event [guard] / action == target</pre><p> |
| </p><p>or as</p><p> |
| </p><pre class="programlisting">target == source + event [guard] / action</pre><p> |
| </p><p>The first version looks like a drawn transition in a diagram, the second |
| 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 |
| written as:</p><pre class="programlisting">BOOST_MSM_EUML_TRANSITION_TABLE(( |
| Stopped + play [some_guard] / (some_action , start_playback) == Playing , |
| Stopped + open_close/ open_drawer == Open , |
| Stopped + stop == Stopped , |
| Open + open_close / close_drawer == Empty , |
| Empty + open_close / open_drawer == Open , |
| Empty + cd_detected [good_disk_format] / store_cd_info == Stopped |
| ),transition_table) </pre><p>Or, using the alternative notation, it can be:</p><pre class="programlisting">BOOST_MSM_EUML_TRANSITION_TABLE(( |
| Playing == Stopped + play [some_guard] / (some_action , start_playback) , |
| Open == Stopped + open_close/ open_drawer , |
| Stopped == Stopped + stop , |
| Empty == Open + open_close / close_drawer , |
| Open == Empty + open_close / open_drawer , |
| Stopped == Empty + cd_detected [good_disk_format] / store_cd_info |
| ),transition_table) </pre><p>The transition table now looks like a list of (readable) rules with little |
| noise.</p><p>UML defines guards between “[ ]” and actions after a “/”, so the chosen |
| syntax 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, eUML is based on typeof (decltype) which only evaluates the |
| parameters to BOOST_MSM_EUML_TRANSITION_TABLE 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-introduced |
| <span class="command"><strong><a class="command" href="ch03s03.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 && (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 any syntactic noise at all.</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="d0e1436"></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="d0e1439"></a>Events</h4></div></div></div><p>Events must be proto-enabled. To achieve this, they must inherit from |
| a proto terminal (euml_event<event-name>). eUML also provides a macro |
| to make this easier:</p><p> |
| </p><pre class="programlisting">BOOST_MSM_EUML_EVENT(play)</pre><p> |
| </p><p>This declares an event type and an instance of this type called |
| <code class="code">play</code>, which is now ready to use in state or transition |
| behaviors.</p><p>There is a second macro, BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES, which |
| takes as second parameter the attributes an event will contain, using |
| the <span class="command"><strong><a class="command" href="ch03s04.html#eUML-attributes">attribute |
| syntax</a></strong></span>.</p><p><span class="underline">Note</span>: as we now have events |
| defined as instances instead of just types, can we still process an |
| event by creating one on the fly, like: |
| <code class="code">fsm.process_event(play());</code> or do we have to write: |
| <code class="code">fsm.process_event(play);</code></p><p>The answer is you can do both. The second one is easier but unlike |
| other front-ends, the second uses a defined operator(), which creates an |
| event on the fly.</p></div><div class="sect3" title="Actions"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1470"></a>Actions</h4></div></div></div><p>Actions (returning void) and guards (returning a bool) are defined |
| like previous functors, with the difference that they also must be |
| proto-enabled. This can be done by inheriting from euml_action< |
| functor-name >. eUML also provides a macro:</p><pre class="programlisting">BOOST_MSM_EUML_ACTION(some_condition) |
| { |
| template <class Fsm,class Evt,class SourceState,class TargetState> |
| bool operator()(Evt const& ,Fsm& ,SourceState&,TargetState& ) |
| { return true; } |
| }; </pre><p>Like for events, this macro declares a functor type and an instance |
| for use in transition or state behaviors.</p><p>It is possible to use the same action grammar from the transition |
| table to define state entry and exit behaviors. So |
| <code class="code">(action1,action2)</code> is a valid entry or exit behavior |
| executing both actions in turn.</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><pre class="programlisting">BOOST_MSM_EUML_ACTION(Empty_Entry) |
| { |
| template <class Evt,class Fsm,class State> |
| void operator()(Evt const& ,Fsm& ,State& ) { ... } |
| }; </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. |
| The syntax is however slightly less comfortable as we need to pretend |
| creating one on the fly for typeof. For example:</p><pre class="programlisting">struct start_playback |
| { |
| template <class Fsm,class Evt,class SourceState,class TargetState> |
| void operator()(Evt const& ,Fsm&,SourceState& ,TargetState& ) |
| { |
| ... |
| } |
| }; |
| BOOST_MSM_EUML_TRANSITION_TABLE(( |
| Playing == Stopped + play / start_playback() , |
| ... |
| ),transition_table)</pre></div><div class="sect3" title="States"><div class="titlepage"><div><div><h4 class="title"><a name="d0e1493"></a>States</h4></div></div></div><p>There is also a macro for states. This macro has 2 arguments, first |
| the expression defining the state, then the state (instance) |
| name:</p><pre class="programlisting">BOOST_MSM_EUML_STATE((),Paused)</pre><p>This defines a simple state without entry or exit action. You can |
| provide in the expression parameter the state behaviors (entry and exit) |
| using the action grammar, like in the transition table:</p><pre class="programlisting">BOOST_MSM_EUML_STATE(((Empty_Entry,Dummy_Entry)/*2 entryactions*/, |
| Empty_Exit/*1 exit action*/ ), |
| Empty)</pre><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 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 |
| action, defining some attributes (read further on).</p></li><li class="listitem"><p>(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>(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>no_action 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 “/” |
| symbol).</p><p>The BOOST_MSM_EUML_STATE macro will allow you to define most common |
| states, but sometimes you will need more, for example provide in your |
| states some special behavior. In this case, you will have to do the |
| macro's job by hand, which is not very complicated. The state will need |
| to inherit from <code class="code">msm::front::state<></code>, like any state, and |
| from <code class="code">euml_state<state-name></code> to be proto-enabled. You |
| will then need to declare an instance for use in the transition table. |
| For example:</p><pre class="programlisting">struct Empty_impl : public msm::front::state<> , public euml_state<Empty_impl> |
| { |
| void activate_empty() {std::cout << "switching to Empty " << std::endl;} |
| template <class Event,class Fsm> |
| void on_entry(Event const& evt,Fsm&fsm){...} |
| template <class Event,class Fsm> |
| void on_exit(Event const& evt,Fsm&fsm){...} |
| }; |
| //instance for use in the transition table |
| Empty_impl const Empty;</pre><p>Notice also that we defined a method named activate_empty. We would |
| like to call it inside a behavior. This can be done using the |
| 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 |
| could use with the functor front-end, the second is the state method |
| name, the third is the eUML-generated function, the fourth and fifth the |
| return value when used inside a transition or a state behavior. You can |
| 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="Defining a simple state machine"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1549"></a>Defining a simple state machine</h3></div></div></div><p>You can reuse the state machine definition method from the standard |
| front-end and simply replace the transition table by this new one. 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 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 |
| describing the state machine and the state machine name. The expression has |
| 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 |
| table and initial state(s) are defined.</p></li><li class="listitem"><p>(Stt, Init, Expr1): state machine where the transition table, |
| initial state and entry action are defined.</p></li><li class="listitem"><p>(Stt, Init, Expr1, Expr2): state machine where the transition |
| table, initial state, entry and exit actions are defined.</p></li><li class="listitem"><p>(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>(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 <a class="link" href="ch03s04.html#eUML-Configuration">configuration |
| capabilities</a> (no message queue / no exception |
| catching) are added.</p></li><li class="listitem"><p>(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 the <a class="link" href="ch03s05.html#backend-base-state">back-end |
| description</a>) is defined.</p></li></ul></div><p>For example, a minimum state machine could be defined |
| as:</p><pre class="programlisting">BOOST_MSM_EUML_TRANSITION_TABLE(( |
| ),transition_table) </pre><pre class="programlisting">BOOST_MSM_EUML_DECLARE_STATE_MACHINE((transition_table,init_ << Empty ), |
| 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</a> and <a class="link" href="examples/SimpleTutorialEuml.cpp" target="_top">second</a> syntax. The |
| BOOST_MSM_EUML_DECLARE_ATTRIBUTE macro, to which we will get back shortly, |
| declares attributes given to an eUML type (state or event) using the |
| <span class="command"><strong><a class="command" href="ch03s04.html#eUML-attributes">attribute |
| syntax</a></strong></span>.</p></div><div class="sect2" title="Defining a submachine"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1597"></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 |
| 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>Unlike the state or event definition macros, |
| BOOST_MSM_EUML_DECLARE_STATE_MACHINE defines a type, not an instance because |
| a type is what the back-end requires. This means that you will need to |
| declare yourself an instance to reference your submachine into another state |
| machine, for example:</p><pre class="programlisting">BOOST_MSM_EUML_DECLARE_STATE_MACHINE(...,Playing_) |
| typedef msm::back::state_machine<Playing_> Playing_type; |
| Playing_type const Playing;</pre><p>We can now use this instance inside the transition table of the containing |
| 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="d0e1613"></a> |
| <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 |
| very simple action methods, for example ++Counter or Counter > 5 where |
| Counter is usually defined as some attribute of the class containing the |
| state machine. It seems like a waste to write a functor for such a simple |
| action. Furthermore, 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 a BOOST_MSM_EUML_DECLARE_ATTRIBUTE and a BOOST_MSM_EUML_ATTRIBUTES |
| macro. The first one declares possible attributes:</p><pre class="programlisting">BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,cd_name) |
| BOOST_MSM_EUML_DECLARE_ATTRIBUTE(DiskTypeEnum,cd_type)</pre><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 using the second one:</p><pre class="programlisting">BOOST_MSM_EUML_ATTRIBUTES((attributes_ << cd_name << cd_type ), |
| cd_detected_attributes)</pre><p>This declares an attribute list which is not linked to anything in |
| particular yet. It can be attached to a state or an event. For example, if |
| we want the event cd_detected to have these defined attributes we |
| 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 |
| form where one can provide attributes. For example:</p><pre class="programlisting">BOOST_MSM_EUML_STATE((no_action /*entry*/,no_action/*exit*/, |
| attributes_ << cd_detected_attributes), |
| some_state)</pre><p>OK, great, we now have a way 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 |
| reference these attributes directly, at compile-time, in the transition |
| table. For example, in the example, you will find this transition:</p><pre class="programlisting">Stopped==Empty+cd_detected[good_disk_format&&(event_(cd_type)==Int_<DISK_CD>())] </pre><p>Read event_(cd_type) as event_->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_<int value>: a functor representing an int</p></li><li class="listitem"><p>Char_<value>: a functor representing a char</p></li><li class="listitem"><p>Size_t_<value>: a functor representing a size_t</p></li><li class="listitem"><p>String_<mpl::string> (boost >= 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 provide your states with their |
| own methods, which you also want to use inside the transition table. 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><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 |
| front-end. The second is the name of the method to call. The third is the |
| function name for use with eUML, 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 |
| shown generic helpers. We can now use this in a transition, for |
| 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 |
| activate_empty, which is 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="sect2" title="Orthogonal regions, flags, event deferring"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1713"></a>Orthogonal regions, flags, event deferring</h3></div></div></div><p>Defining orthogonal regions really means providing more initial states. To |
| add more initial states, “shift left” some, for example, if we had another |
| initial state named AllOk :</p><pre class="programlisting">BOOST_MSM_EUML_DECLARE_STATE_MACHINE((transition_table, |
| init_ << Empty << AllOk ), |
| 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 |
| after attributes, we can define flags, like in the basic MSM front-end. To |
| do this, we have another "shift-left" grammar, for example:</p><pre class="programlisting">BOOST_MSM_EUML_STATE((no_action,no_action, attributes_ <<no_attributes_, |
| /* flags */ configure_<< PlayingPaused << CDLoaded), |
| Paused)</pre><p>We now defined that Paused will get two flags, PlayingPaused and CDLoaded, |
| 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 |
| Paused:</p><pre class="programlisting">struct Paused : public msm::front::state<> |
| { |
| typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list; |
| };</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 |
| BOOST_MSM_EUML_STATE's expression with 4 arguments, we need to tell eUML |
| that we need no attributes. Similarly to a <code class="code">cout << endl</code>, |
| we need a <code class="code">attributes_ << 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 behaviors. For example, in the <a class="link" href="examples/iPodEuml.cpp" target="_top">iPod implementation with eUML</a>, |
| 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 |
| 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><pre class="programlisting">BOOST_MSM_EUML_STATE((Empty_Entry,Empty_Exit, attributes_ << no_attributes_, |
| /* deferred */ configure_<< play ),Empty) </pre><p>The configure_ left shift is also responsible for deferring events. Shift |
| inside configure_ a flag and the state will get a flag, shift an event and |
| it will get a deferred event. This replaces the basic front-end |
| definition:</p><pre class="programlisting">typedef mpl::vector<play> deferred_events;</pre><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 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 |
| 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><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 |
| we have the same constraints. 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:</p><pre class="programlisting">BOOST_MSM_EUML_DECLARE_STATE_MACHINE((transition_table, |
| init_ << Empty << AllOk, |
| Entry_Action, |
| Exit_Action, |
| attributes_ << no_attributes_, |
| configure_<< deferred_events ), |
| player_)</pre><p>A <a class="link" href="examples/OrthogonalDeferredEuml2.cpp" target="_top">tutorial</a> |
| 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="d0e1825"></a> |
| <span class="command"><strong><a name="eUML-Configuration"></a></strong></span>Customizing a state machine / Getting |
| more speed</h3></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 the other front-ends:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><code class="code">configure_ << no_exception</code>: disables |
| exception handling</p></li><li class="listitem"><p><code class="code">configure_ << no_msg_queue</code> deactivates the |
| message queue</p></li><li class="listitem"><p><code class="code">configure_ << deferred_events</code> manually |
| enables event deferring</p></li></ul></div><p>Deactivating the first two features and not activating the third 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 does this for the best performance.</p><p><span class="underline">Important note</span>: As exit pseudo |
| states are using the message queue to forward events out of a submachine, |
| the <code class="code">no_message_queue</code> option cannot be used with state machines |
| containing an exit pseudo state.</p></div><div class="sect2" title="Completion / Anonymous transitions"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1860"></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 |
| tutorial</a></strong></span>) are transitions without a named event, which are |
| therefore triggered immediately when the source state becomes active, |
| provided a guard allows it. As there is no event, to define such a |
| transition, simply omit the “+” part of the transition (the event), for |
| example: </p><pre class="programlisting">State3 == State4 [always_true] / State3ToState4 |
| State4 [always_true] / State3ToState4 == State3</pre><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="ch03s02.html#anonymous-transitions">previously |
| 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="d0e1878"></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 |
| 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><pre class="programlisting">Open + open_close [internal_guard1] / internal_action1</pre><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><pre class="programlisting">BOOST_MSM_EUML_DECLARE_STATE((Open_Entry,Open_Exit),Open_def) |
| struct Open_impl : public Open_def |
| { |
| BOOST_MSM_EUML_DECLARE_INTERNAL_TRANSITION_TABLE(( |
| open_close [internal_guard1] / internal_action1 |
| )) |
| };</pre><p>Notice how we do not need to repeat that the transition |
| 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 |
| 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="sect2" title="Other state types"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1909"></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> |
| function, which creates a simple state. Likewise, eUML provides other |
| 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 |
| BOOST_MSM_EUML_STATE and defines, well, a terminate |
| state.</p></li><li class="listitem"><p>BOOST_MSM_EUML_INTERRUPT_STATE takes the same arguments as |
| BOOST_MSM_EUML_STATE and defines an interrupt state. However, |
| the expression argument must contain as first element the event |
| ending the interruption, for example: |
| <code class="code">BOOST_MSM_EUML_INTERRUPT_STATE(( end_error /*end |
| interrupt event*/,ErrorMode_Entry,ErrorMode_Exit |
| ),ErrorMode)</code></p></li><li class="listitem"><p>BOOST_MSM_EUML_EXIT_STATE takes the same arguments as |
| BOOST_MSM_EUML_STATE and defines an exit pseudo state. However, |
| the expression argument must contain as first element the event |
| propagated from the exit point: |
| <code class="code">BOOST_MSM_EUML_EXIT_STATE(( event6 /*propagated |
| event*/,PseudoExit1_Entry,PseudoExit1_Exit |
| ),PseudoExit1)</code></p></li><li class="listitem"><p>BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE defines an entry pseudo |
| state. It takes 3 parameters: the region index to be entered is |
| defined as an int argument, followed by the configuration |
| expression like BOOST_MSM_EUML_STATE and the state name, so that |
| <code class="code">BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE(0 /*region |
| index*/,( SubState2_Entry,SubState2_Exit ),SubState2)</code> |
| defines an entry state into the first region of a |
| submachine.</p></li><li class="listitem"><p>BOOST_MSM_EUML_ENTRY_STATE defines an entry pseudo state. It |
| takes 3 parameters: the region index to be entered is defined as |
| an int argument, followed by the configuration expression like |
| BOOST_MSM_EUML_STATE and the state name, so that |
| <code class="code">BOOST_MSM_EUML_ENTRY_STATE(0,( |
| PseudoEntry1_Entry,PseudoEntry1_Exit ),PseudoEntry1)</code> |
| defines a pseudo entry state into the first region of a |
| submachine.</p></li></ul></div><p>To use these states in the transition table, eUML offers the functions |
| <code class="code">explicit_</code>, <code class="code">exit_pt_</code> and |
| <code class="code">entry_pt_</code>. For example, a direct entry into the substate |
| 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 |
| (state1, state2, ...), for example:</p><pre class="programlisting">(explicit_(SubFsm2,SubState2), |
| explicit_(SubFsm2,SubState2b), |
| explicit_(SubFsm2,SubState2c)) == State1 + event3 </pre><p>An entry point is entered using the same syntax as explicit entries: |
| </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 |
| used as source of the transition: |
| </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> |
| is also available with eUML.</p></div><div class="sect2" title="Helper functions"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1973"></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 |
| 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 (deepest-level) state |
| machine processing the transition</p></li><li class="listitem"><p>These objects can also be used as a function and return an |
| attribute, for example event_(cd_name)</p></li><li class="listitem"><p>Int_<int value>: a functor representing an int</p></li><li class="listitem"><p>Char_<value>: a functor representing a char</p></li><li class="listitem"><p>Size_t_<value>: 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_<mpl::string> (boost >= 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_<some predicate>: 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 be quite fun. For example, </p><pre class="programlisting">/( if_then_else_(--fsm_(m_SongIndex) > Int_<0>(),/*if clause*/ |
| show_playing_song, /*then clause*/ |
| (fsm_(m_SongIndex)=Int_<1>(),process_(EndPlay))/*else clause*/ |
| ) |
| )</pre><p>means: if (fsm.SongIndex > 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>, for the |
| 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="d0e2070"></a>Phoenix-like STL support</h3></div></div></div><p>eUML supports most C++ operators (except address-of). For example it is |
| possible to write event_(some_attribute)++ or [source_(some_bool) && |
| 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 further reduce the need for your own functors for |
| the transition table. For almost every algorithm or container method of the |
| STL, a corresponding eUML function is defined. Like Boost.Phoenix, “.” And |
| “->” 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): return 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 <a class="link" href="pt02.html#Reference-begin">reference</a> |
| lists all eUML functions 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 functors for STL algorithms are to be found in:</p><pre class="programlisting">#include <msm/front/euml/algorithm.hpp></pre><p>The algorithms are also divided into sub-headers, matching the phoenix |
| structure for simplicity:</p><pre class="programlisting">#include < msm/front/euml/iteration.hpp> |
| #include < msm/front/euml/transformation.hpp> |
| #include < msm/front/euml/querying.hpp> </pre><p>Container methods can be found in:</p><pre class="programlisting">#include < msm/front/euml/container.hpp></pre><p>Or one can simply include the whole STL support (you will also need to |
| include euml.hpp):</p><pre class="programlisting">#include < msm/front/euml/stl.hpp></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>: |
| the state machine has an attribute m_tgt_container of type |
| std::vector<OneSong> 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="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch03s03.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch03.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch03s05.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Functor front-end </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Back-end</td></tr></table></div></body></html> |