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 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</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"><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++ >= 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 <msm/front/euml/euml.hpp></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 <msm/front/euml/stl.hpp></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 “[ ]” and actions after a “/”, 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 && (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< 62 event_name ></p></li><li class="listitem"><p>states must inherit from msm::front::euml::euml_state< 63 state_name ></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<sub_front_end> 70{ 71... 72}; 73// back-end like always 74typedef boost::msm::back::state_machine<sub_front_end> 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<event-name>). 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< 98 functor-name >. eUML also provides a macro:</p><pre class="programlisting">BOOST_MSM_EUML_ACTION(some_condition) 99{ 100 template <class Fsm,class Evt,class SourceState,class TargetState> 101 bool operator()(Evt const& ,Fsm& ,SourceState&,TargetState& ) 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 <class Evt,class Fsm,class State> 112 void operator()(Evt const& ,Fsm& ,State& ) { ... } 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 <class Fsm,class Evt,class SourceState,class TargetState> 118 void operator()(Evt const& ,Fsm&,SourceState& ,TargetState& ) 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 “/” 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<></code>, like any state, and 150 from <code class="code">euml_state<state-name></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<> , public euml_state<Empty_impl> 153{ 154 void activate_empty() {std::cout << "switching to Empty " << std::endl;} 155 template <class Event,class Fsm> 156 void on_entry(Event const& evt,Fsm&fsm){...} 157 template <class Event,class Fsm> 158 void on_exit(Event const& evt,Fsm&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_ << 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<Playing_> 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 > 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_ << cd_name << 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_ << 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&&(event_(cd_type)==Int_<DISK_CD>())] </pre><p>Read event_(cd_type) as event_->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_<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 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, “shift left” 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_ << Empty << 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_ <<no_attributes_, 270 /* flags */ configure_<< PlayingPaused << 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<> 274{ 275 typedef mpl::vector2<PlayingPaused,CDLoaded> 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 << endl</code>, 279 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. 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_ << no_attributes_, 287 /* deferred */ configure_<< 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<play> 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_ << Empty << AllOk, 310 Entry_Action, 311 Exit_Action, 312 attributes_ << no_attributes_, 313 configure_<< 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_ << no_exception</code>: disables 319 exception handling</p></li><li class="listitem"><p><code class="code">configure_ << no_msg_queue</code> deactivates the 320 message queue</p></li><li class="listitem"><p><code class="code">configure_ << 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 “+” 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_<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 407 respectively</p></li><li class="listitem"><p>String_<mpl::string> (boost >= 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_<some predicate>: 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) > Int_<0>(),/*if clause*/ 426 show_playing_song, /*then clause*/ 427 (fsm_(m_SongIndex)=Int_<1>(),process_(EndPlay))/*else clause*/ 428 ) 429 )</pre><p>means: if (fsm.SongIndex > 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) && 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, “.” And 445 “->” 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 <msm/front/euml/algorithm.hpp></pre><p>The algorithms are also divided into sub-headers, matching the phoenix 454 structure for simplicity:</p><pre class="programlisting">#include < msm/front/euml/iteration.hpp> 455#include < msm/front/euml/transformation.hpp> 456#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 457 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>: 458 the state machine has an attribute m_tgt_container of type 459 std::vector<OneSong> 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<i> 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>->*</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> </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>