1<?xml version="1.0" encoding="UTF-8"?> 2<?oxygen RNGSchema="http://www.oasis-open.org/docbook/xml/5.0/rng/docbook.rng" type="xml"?> 3<book xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"> 4 <info> 5 <title>Meta State Machine (MSM)</title> 6 <author> 7 <personname>Christophe Henry</personname> 8 <email>christophe.j.henry@googlemail.com</email> 9 </author> 10 <copyright> 11 <year>2008-2010</year> 12 <holder> 13 <phrase> Distributed under the Boost Software License, Version 1.0. (See 14 accompanying file LICENSE_1_0.txt or copy at <link 15 xlink:href="http://www.boost.org/LICENSE_1_0.txt" 16 >http://www.boost.org/LICENSE_1_0.txt</link> ) </phrase> 17 </holder> 18 </copyright> 19 </info> 20 <preface> 21 <title>Preface</title> 22 <para>MSM is a library allowing you to easily and quickly define state machines of very high 23 performance. From this point, two main questions usually quickly arise, so please allow 24 me to try answering them upfront.</para> 25 <para> 26 <itemizedlist> 27 <listitem> 28 <para>When do I need a state machine?</para> 29 <para>More often that you think. Very often, one defined a state machine 30 informally without even noticing it. For example, one declares inside a 31 class some boolean attribute, say to remember that a task has been 32 completed. Later the boolean actually needs a third value, so it becomes an 33 int. A few weeks, a second attribute is needed. Then a third. Soon, you find 34 yourself writing:</para> 35 <para><code>void incoming_data(data)</code></para> 36 <para><code>{</code></para> 37 <para><code> if (data == packet_3 && flag1 == work_done && flag2 38 > step3)...</code></para> 39 <para><code>}</code></para> 40 <para>This starts to look like event processing (contained inside data) if some 41 stage of the object life has been achieved (but is ugly).</para> 42 <para>This could be a protocol definition and it is a common use case for state 43 machines. Another common one is a user interface. The stage of the user's 44 interaction defines if some button is active, a functionality is available, 45 etc.</para> 46 <para>But there are many more use cases if you start looking. Actually, a whole 47 model-driven development method, Executable UML 48 (http://en.wikipedia.org/wiki/Executable_UML) specifies its complete dynamic 49 behavior using state machines. Class diagram, state machine diagrams, and an 50 action language are all you absolutely need in the Executable UML 51 world.</para> 52 </listitem> 53 <listitem> 54 <para>Another state machine library? What for?</para> 55 <para>True, there are many state machine libraries. This should already be an 56 indication that if you're not using any of them, you might be missing 57 something. Why should you use this one? Unfortunately, when looking for a 58 good state machine library, you usually pretty fast hit one or several of 59 the following snags:<itemizedlist> 60 <listitem> 61 <para>speed: "state machines are slow" is usually the first 62 criticism you might hear. While it is often an excuse not to use 63 any and instead resort to dirty, hand-written implementations (I 64 mean, no, yours are not dirty of course, I'm talking about other 65 developers). MSM removes this often feeble excuse because it is 66 blazingly fast. Most hand-written implementations will be beaten 67 by MSM.</para> 68 </listitem> 69 <listitem> 70 <para>ease of use: good argument. If you used another library, you 71 are probably right. Many state machine definitions will look 72 similar to:</para> 73 <para><code>state s1 = new State; // a state</code></para> 74 <para><code>state s2 = new State; // another state</code></para> 75 <para><code>event e = new Event; // event</code></para> 76 <para><code>s1->addTransition(e,s2); // transition s1 -> 77 s2</code></para> 78 <para>The more transitions you have, the less readable it is. A long 79 time ago, there was not so much Java yet, and many electronic 80 systems were built with a state machine defined by a simple 81 transition table. You could easily see the whole structure and 82 immediately see if you forgot some transitions. Thanks to our 83 new OO techniques, this ease of use was gone. MSM gives you back 84 the transition table and reduces the noise to the 85 minimum.</para> 86 </listitem> 87 <listitem> 88 <para>expressiveness: MSM offers several front-ends and constantly 89 tries to improve state machine definition techniques. For 90 example, you can define a transition with eUML (one of MSM's 91 front-ends) as:</para> 92 <para><code>state1 == state2 + event [condition] / 93 action</code></para> 94 <para>This is not simply syntactic sugar. Such a formalized, 95 readable structure allows easy communication with domain experts 96 of a software to be constructed. Having domain experts 97 understand your code will greatly reduce the number of 98 bugs.</para> 99 </listitem> 100 <listitem> 101 <para>model-driven-development: a common difficulty of a 102 model-driven development is the complexity of making a 103 round-trip (generating code from model and then model from 104 code). This is due to the fact that if a state machine structure 105 is hard for you to read, chances are that your parsing tool will 106 also have a hard time. MSM's syntax will hopefully help tool 107 writers.</para> 108 </listitem> 109 <listitem> 110 <para>features: most developers use only 20% of the richly defined 111 UML standard. Unfortunately, these are never the same 20% for 112 all. And so, very likely, one will need something from the 113 standard which is not implemented. MSM offers a very large part 114 of the standard, with more on the way.</para> 115 </listitem> 116 </itemizedlist></para> 117 <para>Let us not wait any longer, I hope you will enjoy MSM and have fun with 118 it!</para> 119 </listitem> 120 </itemizedlist> 121 </para> 122 </preface> 123 <part> 124 <title>User' guide</title> 125 <chapter> 126 <title>Founding idea</title> 127 <para>Let's start with an example taken from the C++ Template Metaprogramming 128 book:</para> 129 <programlisting>class player : public state_machine<player> 130{ 131 // The list of FSM states enum states { Empty, Open, Stopped, Playing, Paused , initial_state = Empty }; 132 133 // transition actions 134 void start_playback(play const&) { std::cout << "player::start_playback\n"; } 135 void open_drawer(open_close const&) { std::cout << "player::open_drawer\n"; } 136 // more transition actions 137 ... 138 typedef player p; // makes transition table cleaner 139 struct transition_table : mpl::vector11< 140 // Start Event Target Action 141 // +---------+------------+-----------+---------------------------+ 142 row< Stopped , play , Playing , &p::start_playback >, 143 row< Stopped , open_close , Open , &::open_drawer >, 144 // +---------+------------+-----------+---------------------------+ 145 row< Open , open_close , Empty , &p::close_drawer >, 146 // +---------+------------+-----------+---------------------------+ 147 row< Empty , open_close , Open , &p::open_drawer >, 148 row< Empty , cd_detected, Stopped , &p::store_cd_info >, 149 // +---------+------------+-----------+---------------------------+ 150 row< Playing , stop , Stopped , &p::stop_playback >, 151 row< Playing , pause , Paused , &p::pause_playback >, 152 row< Playing , open_close , Open , &p::stop_and_open >, 153 // +---------+------------+-----------+---------------------------+ 154 row< Paused , play , Playing , &p::resume_playback >, 155 row< Paused , stop , Stopped , &p::stop_playback >, 156 row< Paused , open_close , Open , &p::stop_and_open > 157 // +---------+------------+-----------+---------------------------+ 158 > {}; 159 // Replaces the default no-transition response. 160 template <class Event> 161 int no_transition(int state, Event const& e) 162 { 163 std::cout << "no transition from state " << state << " on event " << typeid(e).name() << std::endl; 164 return state; 165 } 166}; </programlisting> 167 <para>This example is the foundation for the idea driving MSM: a descriptive and 168 expressive language based on a transition table with as little syntactic noise as 169 possible, all this while offering as many features from the UML 2.0 standard as 170 possible. MSM also offers several expressive state machine definition syntaxes with 171 different trade-offs.</para> 172 </chapter> 173 <chapter> 174 <title>UML Short Guide</title> 175 <sect1> 176 <title>What are state machines?</title> 177 <para>State machines are the description of a thing's lifeline. They describe the 178 different stages of the lifeline, the events influencing it, and what it does 179 when a particular event is detected at a particular stage. They offer the 180 complete specification of the dynamic behavior of the thing.</para> 181 </sect1> 182 <sect1> 183 <title>Concepts</title> 184 <para>Thinking in terms of state machines is a bit surprising at first, so let us 185 have a quick glance at the concepts.</para> 186 <sect2> 187 <title>State machine, state, transition, event </title> 188 <para>A state machine is a concrete model describing the behavior of a system. 189 It is composed of a finite number of states and transitions.</para> 190 <para> 191 <inlinemediaobject> 192 <imageobject> 193 <imagedata fileref="images/sm.gif"/> 194 </imageobject> 195 </inlinemediaobject></para> 196 <para>A simple state has no sub states. It can have data, entry and exit 197 behaviors and deferred events. One can provide entry and exit behaviors 198 (also called actions) to states (or state machines), which are executed 199 whenever a state is entered or left, no matter how. A state can also have 200 internal transitions which cause no entry or exit behavior to be called. A 201 state can mark events as deferred. This means the event cannot be processed 202 if this state is active, but it must be retained. Next time a state not 203 deferring this event is active, the event will be processed, as if it had 204 just been fired. </para> 205 <para><inlinemediaobject> 206 <imageobject> 207 <imagedata fileref="images/state.gif"/> 208 </imageobject> 209 </inlinemediaobject></para> 210 <para>A transition is the switching between active states, triggered by an 211 event. Actions and guard conditions can be attached to the transition. The 212 action executes when the transition fires, the guard is a Boolean operation 213 executed first and which can prevent the transition from firing by returning 214 false.</para> 215 <para> 216 <inlinemediaobject> 217 <imageobject> 218 <imagedata fileref="images/transition.jpg"/> 219 </imageobject> 220 </inlinemediaobject></para> 221 <para>An initial state marks the first active state of a state machine. It has 222 no real existence and neither has the transition originating from it.</para> 223 <para> 224 <inlinemediaobject> 225 <imageobject> 226 <imagedata fileref="images/init_state.gif"/> 227 </imageobject> 228 </inlinemediaobject></para> 229 </sect2> 230 <sect2> 231 <title>Submachines, orthogonal regions, pseudostates </title> 232 <para>A composite state is a state containing a region or decomposed in two or 233 more regions. A composite state contains its own set of states and regions. </para> 234 <para>A submachine is a state machine inserted as a state in another state 235 machine. The same submachine can be inserted more than once. </para> 236 <para>Orthogonal regions are parts of a composite state or submachine, each 237 having its own set of mutually exclusive set of states and transitions. </para> 238 <para><inlinemediaobject> 239 <imageobject> 240 <imagedata fileref="images/regions.gif" width="60%" scalefit="1"/> 241 </imageobject> 242 </inlinemediaobject></para> 243 <para>UML also defines a number of pseudo states, which are considered important 244 concepts to model, but not enough to make them first-class citizens. The 245 terminate pseudo state terminates the execution of a state machine (MSM 246 handles this slightly differently. The state machine is not destroyed but no 247 further event processing occurs.). </para> 248 <para><inlinemediaobject> 249 <imageobject> 250 <imagedata fileref="images/terminate.gif"/> 251 </imageobject> 252 </inlinemediaobject></para> 253 <para>An exit point pseudo state exits a composite state or a submachine and 254 forces termination of execution in all contained regions.</para> 255 <para><inlinemediaobject> 256 <imageobject> 257 <imagedata fileref="images/exit.gif" width="60%" scalefit="1"/> 258 </imageobject> 259 </inlinemediaobject></para> 260 <para>An entry point pseudo state allows a kind of controlled entry inside a 261 composite. Precisely, it connects a transition outside the composite to a 262 transition inside the composite. An important point is that this mechanism 263 only allows a single region to be entered. In the above diagram, in region1, 264 the initial state would become active. </para> 265 <para><inlinemediaobject> 266 <imageobject> 267 <imagedata fileref="images/entry_point.gif"/> 268 </imageobject> 269 </inlinemediaobject></para> 270 <para>There are also two more ways to enter a submachine (apart the obvious and 271 more common case of a transition terminating on the submachine as shown in 272 the region case). An explicit entry means that an inside state is the target 273 of a transition. Unlike with direct entry, no tentative encapsulation is 274 made, and only one transition is executed. An explicit exit is a transition 275 from an inner state to a state outside the submachine (not supported by 276 MSM). I would not recommend using explicit entry or exit. </para> 277 <para><inlinemediaobject> 278 <imageobject> 279 <imagedata fileref="images/explicit.gif"/> 280 </imageobject> 281 </inlinemediaobject></para> 282 <para>The last entry possibility is using fork. A fork is an explicit entry into 283 one or more regions. Other regions are again activated using their initial 284 state. </para> 285 <para><inlinemediaobject> 286 <imageobject> 287 <imagedata fileref="images/fork.gif" width="70%" scalefit="1"/> 288 </imageobject> 289 </inlinemediaobject></para> 290 </sect2> 291 <sect2> 292 <title> 293 <command xml:id="uml-history"/>History </title> 294 <para>UML defines two kinds of history, shallow history and deep history. 295 Shallow history is a pseudo state representing the most recent substate of a 296 submachine. A submachine can have at most one shallow history. A transition 297 with a history pseudo state as target is equivalent to a transition with the 298 most recent substate as target. And very importantly, only one transition 299 may originate from the history. Deep history is a shallow history 300 recursively reactivating the substates of the most recent substate. It is 301 represented like the shallow history with a star (H* inside a 302 circle).</para> 303 <para> 304 <inlinemediaobject> 305 <imageobject> 306 <imagedata fileref="images/history.gif" width="60%" scalefit="1"/> 307 </imageobject> 308 </inlinemediaobject></para> 309 <para>History is not a completely satisfying concept. First of all, there can be 310 just one history pseudo state and only one transition may originate from it. 311 So they do not mix well with orthogonal regions as only one region can be 312 “remembered”. Deep history is even worse and looks like a last-minute 313 addition. History has to be activated by a transition and only one 314 transition originates from it, so how to model the transition originating 315 from the deep history pseudo state and pointing to the most recent substate 316 of the substate? As a bonus, it is also inflexible and does not accept new 317 types of histories. Let's face it, history sounds great and is useful in 318 theory, but the UML version is not quite making the cut. And therefore, MSM 319 provides a different version of this useful concept. </para> 320 </sect2> 321 <sect2> 322 <title><command xml:id="uml-anonymous"/>Completion transitions / anonymous 323 transitions</title> 324 <para>Completion events (or transitions), also called anonymous transitions, are 325 defined as transitions having no defined event triggering them. This means 326 that such transitions will immediately fire when a state being the source of 327 an anonymous transition becomes active, provided that a guard allows it. 328 They are useful in modeling algorithms as an activity diagram would normally 329 do. In the real-time world, they have the advantage of making it easier to 330 estimate how long a periodically executed action will last. For example, 331 consider the following diagram. </para> 332 <para><inlinemediaobject> 333 <imageobject> 334 <imagedata fileref="images/completion.gif"/> 335 </imageobject> 336 </inlinemediaobject></para> 337 <para>The designer now knows at any time that he will need a maximum of 4 338 transitions. Being able to estimate how long a transition takes, he can 339 estimate how much of a time frame he will need to require (real-time tasks 340 are often executed at regular intervals). If he can also estimate the 341 duration of actions, he can even use graph algorithms to better estimate his 342 timing requirements. </para> 343 </sect2> 344 <sect2> 345 <title><command xml:id="UML-internal-transition"/> Internal transitions </title> 346 <para>Internal transitions are transitions executing in the scope of the active 347 state, being a simple state or a submachine. One can see them as a 348 self-transition of this state, without an entry or exit action 349 called.</para> 350 </sect2> 351 <sect2> 352 <title> 353 <command xml:id="transition-conflict"/>Conflicting transitions </title> 354 <para>If, for a given event, several transitions are enabled, they are said to 355 be in conflict. There are two kinds of conflicts: <itemizedlist> 356 <listitem> 357 <para>For a given source state, several transitions are defined, 358 triggered by the same event. Normally, the guard condition in 359 each transition defines which one is fired.</para> 360 </listitem> 361 <listitem> 362 <para>The source state is a submachine or simple state and the 363 conflict is between a transition internal to this state and a 364 transition triggered by the same event and having as target 365 another state.</para> 366 </listitem> 367 </itemizedlist>The first one is simple; one only needs to define two or more 368 rows in the transition table, with the same source and trigger, with a 369 different guard condition. Beware, however, that the UML standard wants 370 these conditions to be not overlapping. If they do, the standard says 371 nothing except that this is incorrect, so the implementer is free to 372 implement it the way he sees fit. In the case of MSM, the transition 373 appearing last in the transition table gets selected first, if it returns 374 false (meaning disabled), the library tries with the previous one, and so 375 on.</para> 376 <para> 377 <inlinemediaobject> 378 <imageobject> 379 <imagedata fileref="images/conflict1.gif"/> 380 </imageobject> 381 </inlinemediaobject></para> 382 <para>In the second case, UML defines that the most inner transition gets 383 selected first, which makes sense, otherwise no exit point pseudo state 384 would be possible (the inner transition brings us to the exit point, from 385 where the containing state machine can take over). </para> 386 <para><inlinemediaobject> 387 <imageobject> 388 <imagedata fileref="images/conflict2.gif" width="60%" scalefit="1"/> 389 </imageobject> 390 </inlinemediaobject></para> 391 <para>MSM handles both cases itself, so the designer needs only concentrate on 392 its state machine and the UML subtleties (not overlapping conditions), not 393 on implementing this behavior himself. </para> 394 </sect2> 395 </sect1> 396 <sect1> 397 <title>Added concepts</title> 398 <itemizedlist> 399 <listitem> 400 <para>Interrupt states: a terminate state which can be exited if a defined 401 event is triggered.</para> 402 </listitem> 403 <listitem> 404 <para>Kleene (any) event: a transition with a kleene event will accept any 405 event as trigger. Unlike a completion transition, an event must be 406 triggered and the original event is kept accessible in the kleene 407 event.</para> 408 </listitem> 409 </itemizedlist> 410 </sect1> 411 <sect1> 412 <title>State machine glossary</title> 413 <para> 414 <itemizedlist> 415 <listitem> 416 <para>state machine: the life cycle of a thing. It is made of states, 417 regions, transitions and processes incoming events.</para> 418 </listitem> 419 <listitem> 420 <para>state: a stage in the life cycle of a state machine. A state (like 421 a submachine) can have an entry and exit behaviors.</para> 422 </listitem> 423 <listitem> 424 <para>event: an incident provoking (or not) a reaction of the state 425 machine</para> 426 </listitem> 427 <listitem> 428 <para>transition: a specification of how a state machine reacts to an 429 event. It specifies a source state, the event triggering the 430 transition, the target state (which will become the newly active 431 state if the transition is triggered), guard and actions.</para> 432 </listitem> 433 <listitem> 434 <para>action: an operation executed during the triggering of the 435 transition.</para> 436 </listitem> 437 <listitem> 438 <para>guard: a boolean operation being able to prevent the triggering of 439 a transition which would otherwise fire.</para> 440 </listitem> 441 <listitem> 442 <para>transition table: representation of a state machine. A state 443 machine diagram is a graphical, but incomplete representation of the 444 same model. A transition table, on the other hand, is a complete 445 representation.</para> 446 </listitem> 447 <listitem> 448 <para>initial state: The state in which the state machine starts. Having 449 several orthogonal regions means having as many initial 450 states.</para> 451 </listitem> 452 <listitem> 453 <para>submachine: A submachine is a state machine inserted as a state in 454 another state machine and can be found several times in a same state 455 machine.</para> 456 </listitem> 457 <listitem> 458 <para>orthogonal regions: (logical) parallel flow of execution of a 459 state machine. Every region of a state machine gets a chance to 460 process an incoming event.</para> 461 </listitem> 462 <listitem> 463 <para>terminate pseudo-state: when this state becomes active, it 464 terminates the execution of the whole state machine. MSM does not 465 destroy the state machine as required by the UML standard, however, 466 which lets you keep all the state machine's data.</para> 467 </listitem> 468 <listitem> 469 <para>entry/exit pseudo state: defined for submachines and are defined 470 as a connection between a transition outside of the submachine and a 471 transition inside the submachine. It is a way to enter or leave a 472 submachine through a predefined point.</para> 473 </listitem> 474 <listitem> 475 <para>fork: a fork allows explicit entry into several orthogonal regions 476 of a submachine.</para> 477 </listitem> 478 <listitem> 479 <para>history: a history is a way to remember the active state of a 480 submachine so that the submachine can proceed in its last active 481 state next time it becomes active.</para> 482 </listitem> 483 <listitem> 484 <para>completion events (also called completion/anonymous transitions): 485 when a transition has no named event triggering it, it automatically 486 fires when the source state is active, unless a guard forbids 487 it.</para> 488 </listitem> 489 <listitem> 490 <para>transition conflict: a conflict is present if for a given source 491 state and incoming event, several transitions are possible. UML 492 specifies that guard conditions have to solve the conflict.</para> 493 </listitem> 494 <listitem> 495 <para>internal transitions: transition from a state to itself without 496 having exit and entry actions being called.</para> 497 </listitem> 498 </itemizedlist> 499 </para> 500 </sect1> 501 </chapter> 502 <chapter> 503 <title>Tutorial</title> 504 <sect1> 505 <title>Design</title> 506 <para>MSM is divided between front–ends and back-ends. At the moment, there is just 507 one back-end. On the front-end side, you will find three of them which are as 508 many state machine description languages, with many more possible. For potential 509 language writers, this document contains a <link 510 xlink:href="#internals-front-back-interface">description of the interface 511 between front-end and back-end</link>.</para> 512 <para>The first front-end is an adaptation of the example provided in the <link 513 xlink:href="http://boostpro.com/mplbook">MPL book</link> with actions 514 defined as pointers to state or state machine methods. The second one is based 515 on functors. The third, eUML (embedded UML) is an experimental language based on 516 Boost.Proto and Boost.Typeof and hiding most of the metaprogramming to increase 517 readability. Both eUML and the functor front-end also offer a functional library 518 (a bit like Boost.Phoenix) for use as action language (UML defining 519 none).</para> 520 </sect1> 521 <sect1> 522 <title><command xml:id="basic-front-end"/>Basic front-end</title> 523 <para>This is the historical front-end, inherited from the MPL book. It provides a 524 transition table made of rows of different names and functionality. Actions and 525 guards are defined as methods and referenced through a pointer in the 526 transition. This front-end provides a simple interface making easy state 527 machines easy to define, but more complex state machines a bit harder.</para> 528 <sect2> 529 <title>A simple example</title> 530 <para>Let us have a look at a state machine diagram of the founding 531 example:</para> 532 <para><inlinemediaobject> 533 <imageobject> 534 <imagedata fileref="images/SimpleTutorial.jpg" width="60%" 535 scalefit="1"/> 536 </imageobject> 537 </inlinemediaobject></para> 538 <para>We are now going to build it with MSM's basic front-end. An <link 539 xlink:href="examples/SimpleTutorial.cpp">implementation</link> is also 540 provided.</para> 541 </sect2> 542 <sect2> 543 <title>Transition table</title> 544 <para>As previously stated, MSM is based on the transition table, so let us 545 define one:</para> 546 <programlisting> 547struct transition_table : mpl::vector< 548// Start Event Target Action Guard 549// +---------+------------+-----------+---------------------------+----------------------------+ 550a_row< Stopped , play , Playing , &player_::start_playback >, 551a_row< Stopped , open_close , Open , &player_::open_drawer >, 552 _row< Stopped , stop , Stopped >, 553// +---------+------------+-----------+---------------------------+----------------------------+ 554a_row< Open , open_close , Empty , &player_::close_drawer >, 555// +---------+------------+-----------+---------------------------+----------------------------+ 556a_row< Empty , open_close , Open , &player_::open_drawer >, 557 row< Empty , cd_detected, Stopped , &player_::store_cd_info , &player_::good_disk_format >, 558 row< Empty , cd_detected, Playing , &player_::store_cd_info , &player_::auto_start >, 559// +---------+------------+-----------+---------------------------+----------------------------+ 560a_row< Playing , stop , Stopped , &player_::stop_playback >, 561a_row< Playing , pause , Paused , &player_::pause_playback >, 562a_row< Playing , open_close , Open , &player_::stop_and_open >, 563// +---------+------------+-----------+---------------------------+----------------------------+ 564a_row< Paused , end_pause , Playing , &player_::resume_playback >, 565a_row< Paused , stop , Stopped , &player_::stop_playback >, 566a_row< Paused , open_close , Open , &player_::stop_and_open > 567// +---------+------------+-----------+---------------------------+----------------------------+ 568> {}; 569 </programlisting> 570 <para>You will notice that this is almost exactly our founding example. The only 571 change in the transition table is the different types of transitions (rows). 572 The founding example forces one to define an action method and offers no 573 guards. You have 4 basic row types:<itemizedlist> 574 <listitem> 575 <para><code>row</code> takes 5 arguments: start state, event, target 576 state, action and guard.</para> 577 </listitem> 578 <listitem> 579 <para><code>a_row</code> (“a” for action) allows defining only the 580 action and omit the guard condition.</para> 581 </listitem> 582 <listitem> 583 <para><code>g_row</code> (“g” for guard) allows omitting the action 584 behavior and defining only the guard.</para> 585 </listitem> 586 <listitem> 587 <para><code>_row</code> allows omitting action and guard.</para> 588 </listitem> 589 </itemizedlist></para> 590 <para>The signature for an action methods is void method_name (event 591 const&), for example:</para> 592 <programlisting>void stop_playback(stop const&)</programlisting> 593 <para>Action methods return nothing and take the argument as const reference. Of 594 course nothing forbids you from using the same action for several 595 events:</para> 596 <programlisting>template <class Event> void stop_playback(Event const&)</programlisting> 597 <para>Guards have as only difference the return value, which is a 598 boolean:</para> 599 <programlisting>bool good_disk_format(cd_detected const& evt)</programlisting> 600 <para>The transition table is actually a MPL vector (or list), which brings the 601 limitation that the default maximum size of the table is 20. If you need 602 more transitions, overriding this default behavior is necessary, so you need 603 to add before any header:</para> 604 <programlisting>#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS 605#define BOOST_MPL_LIMIT_VECTOR_SIZE 30 //or whatever you need 606#define BOOST_MPL_LIMIT_MAP_SIZE 30 //or whatever you need </programlisting> 607 <para>The other limitation is that the MPL types are defined only up to 50 608 entries. For the moment, the only solution to achieve more is to add headers 609 to the MPL (luckily, this is not very complicated).</para> 610 </sect2> 611 <sect2> 612 <title>Defining states with entry/exit actions</title> 613 <para>While states were enums in the MPL book, they now are classes, which 614 allows them to hold data, provide entry, exit behaviors and be reusable (as 615 they do not know anything about the containing state machine). To define a 616 state, inherit from the desired state type. You will mainly use simple 617 states:</para> 618 <para>struct Empty : public msm::front::state<> {};</para> 619 <para>They can optionally provide entry and exit behaviors:</para> 620 <programlisting language="C++"> 621struct Empty : public msm::front::state<> 622{ 623 template <class Event, class Fsm> 624 void on_entry(Event const&, Fsm& ) 625 {std::cout <<"entering: Empty" << std::endl;} 626 template <class Event, class Fsm> 627 void on_exit(Event const&, Fsm& ) 628 {std::cout <<"leaving: Empty" << std::endl;} 629}; 630 </programlisting> 631 <para>Notice how the entry and exit behaviors are templatized on the event and 632 state machine. Being generic facilitates reuse. There are more state types 633 (terminate, interrupt, pseudo states, etc.) corresponding to the UML 634 standard state types. These will be described in details in the next 635 sections.</para> 636 </sect2> 637 <sect2> 638 <title>What do you actually do inside actions / guards?</title> 639 <para>State machines define a structure and important parts of the complete 640 behavior, but not all. For example if you need to send a rocket to Alpha 641 Centauri, you can have a transition to a state "SendRocketToAlphaCentauri" 642 but no code actually sending the rocket. This is where you need actions. So 643 a simple action could be:</para> 644 <programlisting>template <class Fire> void send_rocket(Fire const&) 645{ 646 fire_rocket(); 647}</programlisting> 648 <para>Ok, this was simple. Now, we might want to give a direction. Let us suppose 649 this information is externally given when needed, it makes sense do use the 650 event for this:</para> 651 <programlisting>// Event 652struct Fire {Direction direction;}; 653template <class Fire> void send_rocket(Fire const& evt) 654{ 655 fire_rocket(evt.direction); 656}</programlisting> 657 <para>We might want to calculate the direction based not only on external data 658 but also on data accumulated during previous work. In this case, you might 659 want to have this data in the state machine itself. As transition actions 660 are members of the front-end, you can directly access the data:</para> 661 <programlisting>// Event 662struct Fire {Direction direction;}; 663//front-end definition, see down 664struct launcher_ : public msm::front::state_machine_def<launcher_>{ 665Data current_calculation; 666template <class Fire> void send_rocket(Fire const& evt) 667{ 668 fire_rocket(evt.direction, current_calculation); 669} 670... 671};</programlisting> 672 <para>Entry and exit actions represent a behavior common to a state, no matter 673 through which transition it is entered or left. States being reusable, it 674 might make sense to locate your data there instead of in the state machine, 675 to maximize reuse and make code more readable. Entry and exit actions have 676 access to the state data (being state members) but also to the event and 677 state machine, like transition actions. This happens through the Event and 678 Fsm template parameters:</para> 679 <programlisting>struct Launching : public msm::front::state<> 680{ 681 template <class Event, class Fsm> 682 void on_entry(Event const& evt, Fsm& fsm) 683 { 684 fire_rocket(evt.direction, fsm.current_calculation); 685 } 686};</programlisting> 687 <para>Exit actions are also ideal for clanup when the state becomes 688 inactive.</para> 689 <para>Another possible use of the entry action is to pass data to substates / 690 submachines. Launching is a substate containing a <code>data</code> attribute:</para> 691 <programlisting>struct launcher_ : public msm::front::state_machine_def<launcher_>{ 692Data current_calculation; 693// state machines also have entry/exit actions 694template <class Event, class Fsm> 695void on_entry(Event const& evt, Fsm& fsm) 696{ 697 launcher_::Launching& s = fsm.get_state<launcher_::Launching&>(); 698 s.data = fsm.current_calculation; 699} 700... 701};</programlisting> 702 <para>The <command xlink:href="#backend-fsm-constructor-args">set_states</command> back-end method allows you to replace a complete 703 state.</para> 704 <para>The <command xlink:href="#functor-front-end-actions">functor</command> front-end and eUML offer more capabilities.</para> 705 <para>However, this basic front-end also has special capabilities using the row2 706 / irow2 transitions.<command xlink:href="#basic-row2">_row2, a_row2, row2, 707 g_row2, a_irow2, irow2, g_irow2</command> let you call an action located 708 in any state of the current fsm or in the front-end itself, thus letting you 709 place useful data anywhere you see fit.</para> 710 <para>It is sometimes desirable to generate new events for the state machine 711 inside actions. Since the process_event method belongs to the back end, you 712 first need to gain a reference to it. The back end derives from the front 713 end, so one way of doing this is to use a cast:</para> 714 <programlisting>struct launcher_ : public msm::front::state_machine_def<launcher_>{ 715template <class Fire> void send_rocket(Fire const& evt) 716{ 717 fire_rocket(); 718 msm::back::state_machine<launcher_> &fsm = static_cast<msm::back::state_machine<launcher_> &>(*this); 719 fsm.process_event(rocket_launched()); 720} 721... 722};</programlisting> 723 <para>The same can be implemented inside entry/exit actions. Admittedly, this is 724 a bit awkward. A more natural mechanism is available using the <command 725 xlink:href="#functor-front-end-actions">functor</command> 726 front-end.</para> 727 </sect2> 728 <sect2> 729 <title>Defining a simple state machine</title> 730 <para>Declaring a state machine is straightforward and is done with a high 731 signal / noise ratio. In our player example, we declare the state machine 732 as:</para> 733 <programlisting>struct player_ : public msm::front::state_machine_def<player_>{ 734 /* see below */}</programlisting> 735 <para>This declares a state machine using the basic front-end. We now declare 736 inside the state machine structure the initial state:</para> 737 <para> 738 <programlisting>typedef Empty initial_state;</programlisting> 739 </para> 740 <para>And that is about all of what is absolutely needed. In the example, the 741 states are declared inside the state machine for readability but this is not 742 a requirements, states can be declared wherever you like.</para> 743 <para>All what is left to do is to pick a back-end (which is quite simple as 744 there is only one at the moment):</para> 745 <para> 746 <programlisting>typedef msm::back::state_machine<player_> player;</programlisting> 747 </para> 748 <para>You now have a ready-to-use state machine with entry/exit actions, guards, 749 transition actions, a message queue so that processing an event can generate 750 another event. The state machine also adapted itself to your need and 751 removed almost all features we didn't use in this simple example. Note that 752 this is not per default the fastest possible state machine. See the section 753 "getting more speed" to know how to get the maximum speed. In a nutshell, 754 MSM cannot know about your usage of some features so you will have to 755 explicitly tell it.</para> 756 <para>State objects are built automatically with the state machine. They will 757 exist until state machine destruction. MSM is using Boost.Fusion behind the 758 hood. This unfortunately means that if you define more than 10 states, you 759 will need to extend the default:</para> 760 <para> 761 <programlisting>#define FUSION_MAX_VECTOR_SIZE 20 // or whatever you need 762 </programlisting> 763 </para> 764 <para>When an unexpected event is fired, the <code>no_transition(event, state 765 machine, state id)</code> method of the state machine is called . By 766 default, this method simply asserts when called. It is possible to overwrite 767 the <code>no_transition</code> method to define a different handling:</para> 768 <para> 769 <programlisting>template <class Fsm,class Event> 770void no_transition(Event const& e, Fsm& ,int state){...}</programlisting> 771 </para> 772 <para><emphasis role="underline">Note</emphasis>: you might have noticed that 773 the tutorial calls <code>start()</code> on the state machine just after 774 creation. The start method will initiate the state machine, meaning it will 775 activate the initial state, which means in turn that the initial state's 776 entry behavior will be called. The reason why we need this will be explained 777 in the <link xlink:href="#backend-start">back-end part</link>. After a call 778 to start, the state machine is ready to process events. The same way, 779 calling <code>stop()</code> will cause the last exit actions to be called.</para> 780 </sect2> 781 <sect2> 782 <title>Defining a submachine</title> 783 <para>We now want to extend our last state machine by making the Playing state a 784 state machine itself (a submachine).</para> 785 <para><inlinemediaobject> 786 <imageobject> 787 <imagedata fileref="images/CompositeTutorial.jpg" width="60%" 788 scalefit="1"/> 789 </imageobject> 790 </inlinemediaobject></para> 791 <para>Again, an <link xlink:href="examples/CompositeTutorial.cpp">example</link> 792 is also provided.</para> 793 <para>A submachine really is a state machine itself, so we declare Playing as 794 such, choosing a front-end and a back-end:</para> 795 <para> 796 <programlisting>struct Playing_ : public msm::front::state_machine_def<Playing_>{...} 797typedef msm::back::state_machine<Playing_> Playing;</programlisting> 798 </para> 799 <para>Like for any state machine, one also needs a transition table and an 800 initial state:</para> 801 <para> 802 <programlisting> 803struct transition_table : mpl::vector< 804// Start Event Target Action Guard 805// +--------+-------------+--------+---------------------------+------+ 806a_row< Song1 , NextSong , Song2 , &Playing_::start_next_song >, 807a_row< Song2 , PreviousSong, Song1 , &Playing_::start_prev_song >, 808a_row< Song2 , NextSong , Song3 , &Playing_::start_next_song >, 809a_row< Song3 , PreviousSong, Song2 , &Playing_::start_prev_song > 810// +--------+-------------+--------+---------------------------+------+ 811> {}; 812 </programlisting> 813 </para> 814 <para> 815 <programlisting>typedef Song1 initial_state; </programlisting> 816 </para> 817 <para>This is about all you need to do. MSM will now automatically recognize 818 Playing as a submachine and all events handled by Playing (NextSong and 819 PreviousSong) will now be automatically forwarded to Playing whenever this 820 state is active. All other state machine features described later are also 821 available. You can even decide to use a state machine sometimes as 822 submachine or sometimes as an independent state machine.</para> 823 <para><command xml:id="limitation-submachine"/>There is, however, a limitation for submachines. If a submachine's 824 substate has an entry action which requires a special event property (like a 825 given method), the compiler will require all events entering this submachine 826 to support this property. As this is not practicable, we will need to use 827 <code>boost::enable_if</code> / <code>boost::disable_if</code> to help, 828 for example consider:</para> 829 <programlisting>// define a property for use with enable_if 830BOOST_MPL_HAS_XXX_TRAIT_DEF(some_event_property) 831 832// this event supports some_event_property and a corresponding required method 833struct event1 834{ 835 // the property 836 typedef int some_event_property; 837 // the method required by this property 838 void some_property(){...} 839}; 840// this event does not supports some_event_property 841struct event2 842{ 843}; 844struct some_state : public msm::front::state<> 845{ 846 template <class Event,class Fsm> 847 // enable this version for events supporting some_event_property 848 typename boost::enable_if<typename has_some_event_property<Event>::type,void>::type 849 on_entry(Event const& evt,Fsm& fsm) 850 { 851 evt.some_property(); 852 } 853 // for events not supporting some_event_property 854 template <class Event,class Fsm> 855 typename boost::disable_if<typename has_some_event_property<Event>::type,void>::type 856 on_entry(Event const& ,Fsm& ) 857 { } 858}; </programlisting> 859 <para>Now this state can be used in your submachine.</para> 860 </sect2> 861 <sect2> 862 <title>Orthogonal regions, terminate state, event deferring</title> 863 <para>It is a very common problem in many state machines to have to handle 864 errors. It usually involves defining a transition from all the states to a 865 special error state. Translation: not fun. It is also not practical to find 866 from which state the error originated. The following diagram shows an 867 example of what clearly becomes not very readable:</para> 868 <para><inlinemediaobject> 869 <imageobject> 870 <imagedata fileref="images/error_no_regions.jpg" width="60%" 871 scalefit="1"/> 872 </imageobject> 873 </inlinemediaobject></para> 874 <para>This is neither very readable nor beautiful. And we do not even have any 875 action on the transitions yet to make it even less readable.</para> 876 <para>Luckily, UML provides a helpful concept, orthogonal regions. See them as 877 lightweight state machines running at the same time inside a common state 878 machine and having the capability to influence one another. The effect is 879 that you have several active states at any time. We can therefore keep our 880 state machine from the previous example and just define a new region made of 881 two states, AllOk and ErrorMode. AllOk is most of the time active. But the 882 error_found error event makes the second region move to the new active state 883 ErrorMode. This event does not interest the main region so it will simply be 884 ignored. "<code>no_transition</code>" will be called only if no region at 885 all handles the event. Also, as UML mandates, every region gets a chance of 886 handling the event, in the order as declared by the 887 <code>initial_state</code> type.</para> 888 <para>Adding an orthogonal region is easy, one only needs to declare more states 889 in the <code>initial_state</code> typedef. So, adding a new region with 890 AllOk as the region's initial state is:</para> 891 <para> 892 <programlisting>typedef mpl::vector<Empty,AllOk> initial_state;</programlisting> 893 </para> 894 <para><inlinemediaobject> 895 <imageobject> 896 <imagedata fileref="images/Orthogonal-deferred.jpg" width="60%" 897 scalefit="1"/> 898 </imageobject> 899 </inlinemediaobject></para> 900 <para>Furthermore, when you detect an error, you usually do not want events to 901 be further processed. To achieve this, we use another UML feature, terminate 902 states. When any region moves to a terminate state, the state machine 903 “terminates” (the state machine and all its states stay alive) and all 904 events are ignored. This is of course not mandatory, one can use orthogonal 905 regions without terminate states. MSM also provides a small extension to 906 UML, interrupt states. If you declare ErrorMode (or a Boost.MPL sequence of 907 events, like boost::mpl::vector<ErrorMode, AnotherEvent>) as interrupt 908 state instead of terminate state, the state machine will not handle any 909 event other than the one which ends the interrupt. So it's like a terminate 910 state, with the difference that you are allowed to resume the state machine 911 when a condition (like handling of the original error) is met. </para> 912 <para><command xml:id="basic-defer"/>Last but not least, this example also shows 913 here the handling of event deferring. Let's say someone puts a disc and 914 immediately presses play. The event cannot be handled, yet you'd want it to 915 be handled at a later point and not force the user to press play again. The 916 solution is to define it as deferred in the Empty and Open states and get it 917 handled in the first state where the event is not to be deferred. It can 918 then be handled or rejected. In this example, when Stopped becomes active, 919 the event will be handled because only Empty and Open defer the 920 event.</para> 921 <para>UML defines event deferring as a state property. To accommodate this, MSM 922 lets you specify this in states by providing a <code>deferred_events</code> 923 type:</para> 924 <programlisting>struct Empty : public msm::front::state<> 925{ 926 // if the play event is fired while in this state, defer it until a state 927 // handles or rejects it 928 typedef mpl::vector<play> deferred_events; 929... 930}; </programlisting> 931 <para>Please have a look at the <link 932 xlink:href="examples/Orthogonal-deferred.cpp">complete 933 example</link>.</para> 934 <para>While this is wanted by UML and is simple, it is not always practical 935 because one could wish to defer only in certain conditions. One could also 936 want to make this be part of a transition action with the added bonus of a 937 guard for more sophisticated behaviors. It would also be conform to the MSM 938 philosophy to get as much as possible in the transition table, where you 939 have the whole state machine structure. This is also possible but not 940 practical with this front-end so we will need to pick a different row from 941 the functor front-end. For a complete description of the <code>Row</code> 942 type, please have a look at the <command xlink:href="#functor-front-end" 943 >functor front-end.</command></para> 944 <para>First, as there is no state where MSM can automatically find out the usage 945 of this feature, we need to require deferred events capability explicitly, 946 by adding a type in the state machine definition:</para> 947 <programlisting>struct player_ : public msm::front::state_machine_def<player_> 948{ 949 typedef int activate_deferred_events; 950... 951}; </programlisting> 952 <para>We can now defer an event in any transition of the transition table by 953 using as action the predefined <code>msm::front::Defer</code> functor, for 954 example:</para> 955 <para> 956 <programlisting>Row < Empty , play , none , Defer , none ></programlisting> 957 </para> 958 <para>This is an internal transition row(see <command 959 xlink:href="#internal-transitions">internal transitions</command>) but 960 you can ignore this for the moment. It just means that we are not leaving 961 the Empty state. What matters is that we use Defer as action. This is 962 roughly equivalent to the previous syntax but has the advantage of giving 963 you all the information in the transition table with the added power of 964 transition behavior.</para> 965 <para>The second difference is that as we now have a transition defined, this 966 transition can play in the resolution of <command 967 xlink:href="#transition-conflict">transition conflicts</command>. For 968 example, we could model an "if (condition2) move to Playing else if 969 (condition1) defer play event":</para> 970 <para> 971 <programlisting>Row < Empty , play , none , Defer , condition1 >, 972g_row < Empty , play , Playing , &player_::condition2 ></programlisting> 973 </para> 974 <para>Please have a look at <link xlink:href="examples/Orthogonal-deferred2.cpp" 975 >this possible implementation</link>.</para> 976 </sect2> 977 <sect2> 978 <title>History</title> 979 <para>UML defines two types of history, Shallow History and Deep History. In the 980 previous examples, if the player was playing the second song and the user 981 pressed pause, leaving Playing, at the next press on the play button, the 982 Playing state would become active and the first song would play again. Soon 983 would the first client complaints follow. They'd of course demand, that if 984 the player was paused, then it should remember which song was playing. But 985 it the player was stopped, then it should restart from the first song. How 986 can it be done? Of course, you could add a bit of programming logic and 987 generate extra events to make the second song start if coming from Pause. 988 Something like: </para> 989 <para> 990 <programlisting>if (Event == end_pause) 991{ 992 for (int i=0;i< song number;++i) {player.process_event(NextSong()); } 993} </programlisting> 994 </para> 995 <para>Not much to like in this example, isn't it? To solve this problem, you 996 define what is called a shallow or a deep history. A shallow history 997 reactivates the last active substate of a submachine when this submachine 998 becomes active again. The deep history does the same recursively, so if this 999 last active substate of the submachine was itself a submachine, its last 1000 active substate would become active and this will continue recursively until 1001 an active state is a normal state. For example, let us have a look at the 1002 following UML diagram: </para> 1003 <para><inlinemediaobject> 1004 <imageobject> 1005 <imagedata fileref="images/HistoryTutorial.jpg" width="60%" 1006 scalefit="1"/> 1007 </imageobject> 1008 </inlinemediaobject></para> 1009 <para>Notice that the main difference compared to previous diagrams is that the 1010 initial state is gone and replaced by a History symbol (the H inside a 1011 circle).</para> 1012 <para>As explained in the <command xlink:href="#uml-history">small UML 1013 tutorial</command>, History is a good concept with a not completely 1014 satisfying specification. MSM kept the concept but not the specification and 1015 goes another way by making this a policy and you can add your own history 1016 types (the <link xlink:href="#history-interface">reference</link> explains 1017 what needs to be done). Furthermore, History is a backend policy. This 1018 allows you to reuse the same state machine definition with different history 1019 policies in different contexts.</para> 1020 <para>Concretely, your frontend stays unchanged:</para> 1021 <para> 1022 <programlisting>struct Playing_ : public msm::front::state_machine_def<Playing_></programlisting> 1023 </para> 1024 <para>You then add the policy to the backend as second parameter:</para> 1025 <para> 1026 <programlisting>typedef msm::back::state_machine<Playing_, 1027 msm::back::ShallowHistory<mpl::vector<end_pause> > > Playing;</programlisting> 1028 </para> 1029 <para>This states that a shallow history must be activated if the Playing state 1030 machine gets activated by the end_pause event and only this one (or any 1031 other event added to the mpl::vector). If the state machine was in the 1032 Stopped state and the event play was generated, the history would not be 1033 activated and the normal initial state would become active. By default, 1034 history is disabled. For your convenience the library provides in addition 1035 to ShallowHistory a non-UML standard AlwaysHistory policy (likely to be your 1036 main choice) which always activates history, whatever event triggers the 1037 submachine activation. Deep history is not available as a policy (but could 1038 be added). The reason is that it would conflict with policies which 1039 submachines could define. Of course, if for example, Song1 were a state 1040 machine itself, it could use the ShallowHistory policy itself thus creating 1041 Deep History for itself. An <link xlink:href="examples/History.cpp" 1042 >example</link> is also provided.</para> 1043 </sect2> 1044 <sect2> 1045 <title>Completion (anonymous) transitions</title> 1046 <para><command xml:id="anonymous-transitions"/>The following diagram shows an 1047 example making use of this feature:</para> 1048 <para><inlinemediaobject> 1049 <imageobject> 1050 <imagedata fileref="images/Anonymous.jpg" width="60%" scalefit="1"/> 1051 </imageobject> 1052 </inlinemediaobject></para> 1053 <para>Anonymous transitions are transitions without a named event. This means 1054 that the transition automatically fires when the predecessor state is 1055 entered (to be exact, after the entry action). Otherwise it is a normal 1056 transition with actions and guards. Why would you need something like that? 1057 A possible case would be if a part of your state machine implements some 1058 algorithm, where states are steps of the algorithm implementation. Then, 1059 using several anonymous transitions with different guard conditions, you are 1060 actually implementing some if/else statement. Another possible use would be 1061 a real-time system called at regular intervals and always doing the same 1062 thing, meaning implementing the same algorithm. The advantage is that once 1063 you know how long a transition takes to execute on the system, by 1064 calculating the longest path (the number of transitions from start to end), 1065 you can pretty much know how long your algorithm will take in the worst 1066 case, which in turns tells you how much of a time frame you are to request 1067 from a scheduler. </para> 1068 <para>If you are using Executable UML (a good book describing it is "Executable 1069 UML, a foundation for Model-Driven Architecture"), you will notice that it 1070 is common for a state machine to generate an event to itself only to force 1071 leaving a state. Anonymous transitions free you from this constraint.</para> 1072 <para>If you do not use this feature in a concrete state machine, MSM will 1073 deactivate it and you will not pay for it. If you use it, there is however a 1074 small performance penalty as MSM will try to fire a compound event (the 1075 other UML name for anonymous transitions) after every taken transition. This 1076 will therefore double the event processing cost, which is not as bad as it 1077 sounds as MSM’s execution speed is very high anyway.</para> 1078 <para>To define such a transition, use “none” as event in the transition table, 1079 for example:</para> 1080 <para> 1081 <programlisting>row < State3 , none , State4 , &p::State3ToState4 , &p::always_true ></programlisting> 1082 </para> 1083 <para><link xlink:href="examples/AnonymousTutorial.cpp">An implementation</link> 1084 of the state machine diagram is also provided.</para> 1085 </sect2> 1086 <sect2> 1087 <title><command xml:id="internal-transitions"/>Internal transitions</title> 1088 <para>Internal transitions are transitions executing in the scope of the active 1089 state, a simple state or a submachine. One can see them as a self-transition 1090 of this state, without an entry or exit action called. This is useful when 1091 all you want is to execute some code for a given event in a given 1092 state.</para> 1093 <para>Internal transitions are specified as having a higher priority than normal 1094 transitions. While it makes sense for a submachine with exit points, it is 1095 surprising for a simple state. MSM lets you define the transition priority 1096 by setting the transition’s position inside the transition table (see 1097 <command xlink:href="#run-to-completion">internals</command> ). The 1098 difference between "normal" and internal transitions is that internal 1099 transitions have no target state, therefore we need new row types. We had 1100 a_row, g_row, _row and row, we now add a_irow, g_irow, _irow and irow which 1101 are like normal transitions but define no target state. For, example an 1102 internal transition with a guard condition could be:</para> 1103 <para> 1104 <programlisting>g_irow < Empty /*state*/,cd_detected/*event*/,&p::internal_guard/* guard */></programlisting> 1105 </para> 1106 <para>These new row types can be placed anywhere in the transition table so that 1107 you can still have your state machine structure grouped together. The only 1108 difference of behavior with the UML standard is the missing notion of higher 1109 priority for internal transitions. Please have a look at <link 1110 xlink:href="examples/SimpleTutorialInternal.cpp">the 1111 example</link>.</para> 1112 <para>It is also possible to do it the UML-conform way by declaring a transition 1113 table called <code>internal transition_table</code> inside the state itself 1114 and using internal row types. For example:</para> 1115 <programlisting>struct Empty : public msm::front::state<> 1116{ 1117 struct internal_transition_table : mpl::vector< 1118 a_internal < cd_detected , Empty, &Empty::internal_action > 1119 > {}; 1120};</programlisting> 1121 <para>This declares an internal transition table called 1122 internal_transition_table and reacting on the event cd_detected by calling 1123 internal_action on Empty. Let us note a few points:<itemizedlist> 1124 <listitem> 1125 <para>internal tables are NOT called transition_table but 1126 internal_transition_table</para> 1127 </listitem> 1128 <listitem> 1129 <para>they use different but similar row types: a_internal, 1130 g_internal, _internal and internal.</para> 1131 </listitem> 1132 <listitem> 1133 <para>These types take as first template argument the triggering 1134 event and then the action and guard method. Note that the only 1135 real difference to classical rows is the extra argument before 1136 the function pointer. This is the type on which the function 1137 will be called.</para> 1138 </listitem> 1139 <listitem> 1140 <para>This also allows you, if you wish, to use actions and guards 1141 from another state of the state machine or in the state machine 1142 itself.</para> 1143 </listitem> 1144 <listitem> 1145 <para>submachines can have an internal transition table and a 1146 classical transition table.</para> 1147 </listitem> 1148 </itemizedlist></para> 1149 <para>The <link xlink:href="examples/TestInternal.cpp">following example</link> 1150 makes use of an a_internal. It also uses functor-based internal transitions 1151 which will be explained in <command 1152 xlink:href="#functor-internal-transitions">the functor 1153 front-end</command>, please ignore them for the moment. Also note that 1154 the state-defined internal transitions, having the highest priority (as 1155 mandated by the UML standard), are tried before those defined inside the 1156 state machine transition table.</para> 1157 <para>Which method should you use? It depends on what you need:<itemizedlist> 1158 <listitem> 1159 <para>the first version (using irow) is simpler and likely to 1160 compile faster. It also lets you choose the priority of your 1161 internal transition.</para> 1162 </listitem> 1163 <listitem> 1164 <para>the second version is more logical from a UML perspective and 1165 lets you make states more useful and reusable. It also allows 1166 you to call actions and guards on any state of the state 1167 machine.</para> 1168 </listitem> 1169 </itemizedlist> 1170 <command xml:id="internal-transitions-note"/><emphasis role="underline" 1171 ><emphasis role="bold">Note</emphasis></emphasis>: There is an added 1172 possibility coming from this feature. The 1173 <code>internal_transition_table</code> transitions being added directly 1174 inside the main state machine's transition table, it is possible, if it is 1175 more to your state, to distribute your state machine definition a bit like 1176 Boost.Statechart, leaving to the state machine itself the only task of 1177 declaring the states it wants to use using the 1178 <code>explicit_creation</code> type definition. While this is not the 1179 author's favorite way, it is still possible. A simplified example using only 1180 two states will show this possibility:<itemizedlist> 1181 <listitem> 1182 <para><link 1183 xlink:href="examples/distributed_table/DistributedTable.cpp" 1184 >state machine definition</link></para> 1185 </listitem> 1186 <listitem> 1187 <para>Empty <link xlink:href="examples/distributed_table/Empty.hpp" 1188 >header</link> and <link 1189 xlink:href="examples/distributed_table/Empty.cpp" 1190 >cpp</link></para> 1191 </listitem> 1192 <listitem> 1193 <para>Open <link xlink:href="examples/distributed_table/Open.hpp" 1194 >header</link> and <link 1195 xlink:href="examples/distributed_table/Open.cpp" 1196 >cpp</link></para> 1197 </listitem> 1198 <listitem> 1199 <para><link xlink:href="examples/distributed_table/Events.hpp" 1200 >events definition</link></para> 1201 </listitem> 1202 </itemizedlist></para> 1203 <para>There is an added bonus offered for submachines, which can have both the 1204 standard transition_table and an internal_transition_table (which has a 1205 higher priority). This makes it easier if you decide to make a full 1206 submachine from a state. It is also slightly faster than the standard 1207 alternative, adding orthogonal regions, because event dispatching will, if 1208 accepted by the internal table, not continue to the subregions. This gives 1209 you a O(1) dispatch instead of O(number of regions). While the example is 1210 with eUML, the same is also possible with any front-end.</para> 1211 </sect2> 1212 <sect2> 1213 <title><command xml:id="basic-row2"/>more row types</title> 1214 <para>It is also possible to write transitions using actions and guards not just 1215 from the state machine but also from its contained states. In this case, one 1216 must specify not just a method pointer but also the object on which to call 1217 it. This transition row is called, not very originally, <code>row2</code>. 1218 They come, like normal transitions in four flavors: <code>a_row2, g_row2, 1219 _row2 and row2</code>. For example, a transition calling an action from 1220 the state Empty could be:</para> 1221 <para> 1222 <programlisting>a_row2<Stopped,open_close,Open,Empty 1223 /*action source*/,&Empty::open_drawer/*action*/></programlisting> 1224 </para> 1225 <para>The same capabilities are also available for internal transitions so that 1226 we have: <code>a_irow2, g_irow2, _irow2 and row2</code>. For transitions 1227 defined as part of the <code>internal_transition_table</code>, you can use 1228 the <command xlink:href="#internal-transitions">a_internal, g_internal, 1229 _internal, internal</command> row types from the previous 1230 sections.</para> 1231 <para>These row types allow us to distribute the state machine code among 1232 states, making them reusable and more useful. Using transition tables inside 1233 states also contributes to this possibility. An <link 1234 xlink:href="examples/SimpleTutorial2.cpp">example</link> of these new 1235 rows is also provided.</para> 1236 </sect2> 1237 <sect2> 1238 <title>Explicit entry / entry and exit pseudo-state / fork</title> 1239 <para>MSM (almost) fully supports these features, described in the <command 1240 xlink:href="#uml-history">small UML tutorial</command>. Almost because 1241 there are currently two limitations: <itemizedlist> 1242 <listitem> 1243 <para>it is only possible to explicitly enter a sub- state of the 1244 target but not a sub-sub state.</para> 1245 </listitem> 1246 <listitem> 1247 <para>it is not possible to explicitly exit. Exit points must be 1248 used.</para> 1249 </listitem> 1250 </itemizedlist></para> 1251 <para>Let us see a concrete example:</para> 1252 <para><inlinemediaobject> 1253 <imageobject> 1254 <imagedata fileref="images/entrytutorial.jpg" width="60%" 1255 scalefit="1"/> 1256 </imageobject> 1257 </inlinemediaobject></para> 1258 <para>We find in this diagram:<itemizedlist> 1259 <listitem> 1260 <para>A “normal” activation of SubFsm2, triggered by event1. In each 1261 region, the initial state is activated, i.e. SubState1 and 1262 SubState1b.</para> 1263 </listitem> 1264 <listitem> 1265 <para>An explicit entry into SubFsm2::SubState2 for region “1” with 1266 event2 as trigger, meaning that in region “2” the initial state, 1267 SubState1b, activated.</para> 1268 </listitem> 1269 <listitem> 1270 <para>A fork into regions “1” and “2” to the explicit entries 1271 SubState2 and SubState2b, triggered by event3. Both states 1272 become active so no region is default activated (if we had a 1273 third one, it would be).</para> 1274 </listitem> 1275 <listitem> 1276 <para>A connection of two transitions through an entry pseudo state, 1277 SubFsm2::PseudoEntry1, triggered by event4 and triggering also 1278 the second transition on the same event (both transitions must 1279 be triggered by the same event). Region “2” is default-activated 1280 and SubState1b becomes active.</para> 1281 </listitem> 1282 <listitem> 1283 <para>An exit from SubFsm2 using an exit pseudo-state, PseudoExit1, 1284 triggered by event5 and connecting two transitions using the 1285 same event. Again, the event is forwarded to the second 1286 transition and both regions are exited, as SubFsm2 becomes 1287 inactive. Note that if no transition is defined from 1288 PseudoExit1, an error (as defined in the UML standard) will be 1289 detected and no_transition called.</para> 1290 </listitem> 1291 </itemizedlist></para> 1292 <para>The example is also <link xlink:href="examples/DirectEntryTutorial.cpp" 1293 >fully implemented</link>.</para> 1294 <para>This sounds complicated but the syntax is simple.</para> 1295 <sect3> 1296 <title>Explicit entry</title> 1297 <para>First, to define that a state is an explicit entry, you have to make 1298 it a state and mark it as explicit, giving as template parameters the 1299 region id (the region id starts with 0 and corresponds to the first 1300 initial state of the initial_state type sequence).</para> 1301 <para> 1302 <programlisting>struct SubFsm2_ : public msm::front::state_machine_def<SubFsm2_> 1303{ 1304 struct SubState2 : public msm::front::state<> , 1305 public msm::front::explicit_entry<0> 1306 {...}; 1307... 1308};</programlisting> 1309 </para> 1310 <para>And define the submachine as:</para> 1311 <para> 1312 <programlisting>typedef msm::back::state_machine<SubFsm2_> SubFsm2;</programlisting> 1313 </para> 1314 <para>You can then use it as target in a transition with State1 as 1315 source:</para> 1316 <para> 1317 <programlisting>_row < State1, Event2, SubFsm2::direct< SubFsm2_::SubState2> > //SubFsm2_::SubState2: complete name of SubState2 (defined within SubFsm2_)</programlisting> 1318 </para> 1319 <para>The syntax deserves some explanation. SubFsm2_ is a front end. 1320 SubState2 is a nested state, therefore the SubFsm2_::SubState2 syntax. 1321 The containing machine (containing State1 and SubFsm2) refers to the 1322 backend instance (SubFsm2). SubFsm2::direct states that an explicit 1323 entry is desired.</para> 1324 <para><command xml:id="explicit-entry-no-region-id"/>Thanks to the <command xlink:href="#backend-compile-time-analysis" 1325 >mpl_graph</command> library you can also omit to provide the region 1326 index and let MSM find out for you. The are however two points to note:<itemizedlist> 1327 <listitem> 1328 <para>MSM can only find out the region index if the explicit 1329 entry state is somehow connected to an initial state through 1330 a transition, no matter the direction.</para> 1331 </listitem> 1332 <listitem> 1333 <para>There is a compile-time cost for this feature.</para> 1334 </listitem> 1335 </itemizedlist></para> 1336 <para><emphasis role="underline">Note (also valid for forks)</emphasis>: in 1337 order to make compile time more bearable for the more standard cases, 1338 and unlike initial states, explicit entry states which are also not 1339 found in the transition table of the entered submachine (a rare case) do 1340 NOT get automatically created. To explicitly create such states, you 1341 need to add in the state machine containing the explicit states a simple 1342 typedef giving a sequence of states to be explicitly created 1343 like:</para> 1344 <para> 1345 <programlisting>typedef mpl::vector<SubState2,SubState2b> explicit_creation;</programlisting> 1346 </para> 1347 <para><emphasis role="underline">Note (also valid for forks)</emphasis>: At 1348 the moment, it is not possible to use a submachine as the target of an 1349 explicit entry. Please use entry pseudo states for an almost identical 1350 effect.</para> 1351 </sect3> 1352 <sect3> 1353 <title>Fork</title> 1354 <para>Need a fork instead of an explicit entry? As a fork is an explicit 1355 entry into states of different regions, we do not change the state 1356 definition compared to the explicit entry and specify as target a list 1357 of explicit entry states:</para> 1358 <para> 1359 <programlisting>_row < State1, Event3, 1360 mpl::vector<SubFsm2::direct<SubFsm2_::SubState2>, 1361 SubFsm2::direct <SubFsm2_::SubState2b> 1362 ></programlisting> 1363 </para> 1364 <para>With SubState2 defined as before and SubState2b defined as being in 1365 the second region (Caution: MSM does not check that the region is 1366 correct):</para> 1367 <para> 1368 <programlisting>struct SubState2b : public msm::front::state<> , 1369 public msm::front::explicit_entry<1></programlisting> 1370 </para> 1371 </sect3> 1372 <sect3> 1373 <title>Entry pseudo states</title> 1374 <para> To define an entry pseudo state, you need derive from the 1375 corresponding class and give the region id:</para> 1376 <para> 1377 <programlisting>struct PseudoEntry1 : public msm::front::entry_pseudo_state<0></programlisting> 1378 </para> 1379 <para>And add the corresponding transition in the top-level state machine's 1380 transition table:</para> 1381 <para> 1382 <programlisting>_row < State1, Event4, SubFsm2::entry_pt<SubFsm2_::PseudoEntry1> ></programlisting> 1383 </para> 1384 <para>And another in the SubFsm2_ submachine definition (remember that UML 1385 defines an entry point as a connection between two transitions), for 1386 example this time with an action method:</para> 1387 <para> 1388 <programlisting>_row < PseudoEntry1, Event4, SubState3,&SubFsm2_::entry_action ></programlisting> 1389 </para> 1390 </sect3> 1391 <sect3> 1392 <title> Exit pseudo states </title> 1393 <para>And finally, exit pseudo states are to be used almost the same way, 1394 but defined differently: it takes as template argument the event to be 1395 forwarded (no region id is necessary):</para> 1396 <para> 1397 <programlisting>struct PseudoExit1 : public exit_pseudo_state<event6></programlisting> 1398 </para> 1399 <para>And you need, like for entry pseudo states, two transitions, one in 1400 the submachine:</para> 1401 <para> 1402 <programlisting>_row < SubState3, Event5, PseudoExit1 ></programlisting> 1403 </para> 1404 <para>And one in the containing state machine:</para> 1405 <para> 1406 <programlisting>_row < SubFsm2::exit_pt<SubFsm2_::PseudoExit1>, Event6,State2 ></programlisting> 1407 </para> 1408 <para><emphasis role="underline">Important note 1:</emphasis> UML defines 1409 transiting to an entry pseudo state and having either no second 1410 transition or one with a guard as an error but defines no error 1411 handling. MSM will tolerate this behavior; the entry pseudo state will 1412 simply be the newly active state.</para> 1413 <para><emphasis role="underline">Important note 2</emphasis>: UML defines 1414 transiting to an exit pseudo state and having no second transition as an 1415 error, and also defines no error handling. Therefore, it was decided to 1416 implement exit pseudo state as terminate states and the containing 1417 composite not properly exited will stay terminated as it was technically 1418 “exited”.</para> 1419 <para><emphasis role="underline">Important note 3:</emphasis> UML states 1420 that for the exit point, the same event must be used in both 1421 transitions. MSM relaxes this rule and only wants the event on the 1422 inside transition to be convertible to the one of the outside 1423 transition. In our case, event6 is convertible from event5. Notice that 1424 the forwarded event must be named in the exit point definition. For 1425 example, we could define event6 as simply as:</para> 1426 <para> 1427 <programlisting>struct event 1428{ 1429 event(){} 1430 template <class Event> 1431 event(Event const&){} 1432}; //convertible from any event</programlisting> 1433 <emphasis role="underline">Note</emphasis>: There is a current 1434 limitation if you need not only convert but also get some data from the 1435 original event. Consider:</para> 1436 <programlisting>struct event1 1437{ 1438 event1(int val_):val(val_) {} 1439 int val; 1440}; // forwarded from exit point 1441struct event2 1442{ 1443 template <class Event> 1444 event2(Event const& e):val(e.val){} // compiler will complain about another event not having any val 1445 int val; 1446}; // what the higher-level fsm wants to get</programlisting> 1447 <para>The solution is to provide two constructors:</para> 1448 <programlisting>struct event2 1449{ 1450 template <class Event> 1451 event2(Event const& ):val(0){} // will not be used 1452 event2(event1 const& e)):val(e.val){} // the conversion constructor 1453 int val; 1454}; // what the higher-level fsm wants to get</programlisting> 1455 </sect3> 1456 </sect2> 1457 <sect2> 1458 <title>Flags</title> 1459 <para>This <link xlink:href="examples/Flags.cpp">tutorial</link> is devoted to a 1460 concept not defined in UML: flags. It has been added into MSM after proving 1461 itself useful on many occasions. Please, do not be frightened as we are not 1462 talking about ugly shortcuts made of an improbable collusion of 1463 Booleans.</para> 1464 <para>If you look into the Boost.Statechart documentation you'll find this 1465 code:</para> 1466 <programlisting>if ( ( state_downcast< const NumLockOff * >() != 0 ) && 1467 ( state_downcast< const CapsLockOff * >() != 0 ) && 1468 ( state_downcast< const ScrollLockOff * >() != 0 ) ) 1469 </programlisting> 1470 <para>While correct and found in many UML books, this can be error-prone and a 1471 potential time-bomb when your state machine grows and you add new states or 1472 orthogonal regions.</para> 1473 <para>And most of all, it hides the real question, which would be “does my state 1474 machine's current state define a special property”? In this special case 1475 “are my keys in a lock state”? So let's apply the Fundamental Theorem of 1476 Software Engineering and move one level of abstraction higher.</para> 1477 <para>In our player example, let's say we need to know if the player has a 1478 loaded CD. We could do the same:</para> 1479 <programlisting>if ( ( state_downcast< const Stopped * >() != 0 ) && 1480 ( state_downcast< const Open * >() != 0 ) && 1481 ( state_downcast< const Paused * >() != 0 ) && 1482 ( state_downcast< const Playing * >() != 0 )) </programlisting> 1483 <para>Or flag these 4 states as CDLoaded-able. You add a flag_list type into 1484 each flagged state:</para> 1485 <para> 1486 <programlisting>typedef mpl::vector1<CDLoaded> flag_list;</programlisting> 1487 </para> 1488 <para>You can even define a list of flags, for example in Playing:</para> 1489 <para> 1490 <programlisting>typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;</programlisting> 1491 </para> 1492 <para>This means that Playing supports both properties. To check if your player 1493 has a loaded CD, check if your flag is active in the current state:</para> 1494 <para> 1495 <programlisting>player p; if (p.is_flag_active<CDLoaded>()) ... </programlisting> 1496 </para> 1497 <para>And what if you have orthogonal regions? How to decide if a state machine 1498 is in a flagged state? By default, you keep the same code and the current 1499 states will be OR'ed, meaning if one of the active states has the flag, then 1500 is_flag_active returns true. Of course, in some cases, you might want that 1501 all of the active states are flagged for the state to be active. You can 1502 also AND the active states:</para> 1503 <para> 1504 <programlisting>if (p.is_flag_active<CDLoaded,player::Flag_AND>()) ...</programlisting> 1505 </para> 1506 <para> Note. Due to arcane C++ rules, when called inside an action, the correct 1507 call is: 1508 <programlisting>if (p.<emphasis role="bold">template</emphasis> is_flag_active<CDLoaded>()) ...</programlisting> 1509 </para> 1510 <para>The following diagram displays the flag situation in the tutorial.</para> 1511 <para><inlinemediaobject> 1512 <imageobject> 1513 <imagedata fileref="images/FlagsTutorial.jpg" width="60%" 1514 scalefit="1"/> 1515 </imageobject> 1516 </inlinemediaobject></para> 1517 </sect2> 1518 <sect2> 1519 <title><command xml:id="event-hierarchy"/>Event Hierarchy</title> 1520 <para>There are cases where one needs transitions based on categories of events. 1521 An example is text parsing. Let's say you want to parse a string and use a 1522 state machine to manage your parsing state. You want to parse 4 digits and 1523 decide to use a state for every matched digit. Your state machine could look 1524 like:</para> 1525 <para><inlinemediaobject> 1526 <imageobject> 1527 <imagedata fileref="images/ParsingDigits.jpg" width="30%" 1528 scalefit="1"/> 1529 </imageobject> 1530 </inlinemediaobject></para> 1531 <para>But how to detect the digit event? We would like to avoid defining 10 1532 transitions on char_0, char_1... between two states as it would force us to 1533 write 4 x 10 transitions and the compile-time would suffer. To solve this 1534 problem, MSM supports the triggering of a transition on a subclass event. 1535 For example, if we define digits as: </para> 1536 <programlisting>struct digit {}; 1537struct char_0 : public digit {}; </programlisting> 1538 <para>And to the same for other digits, we can now fire char_0, char_1 events 1539 and this will cause a transition with "digit" as trigger to be taken.</para> 1540 <para>An <link xlink:href="examples/ParsingDigits.cpp">example</link> with 1541 performance measurement, taken from the documentation of Boost.Xpressive 1542 illustrates this example. You might notice that the performance is actually 1543 very good (in this case even better).</para> 1544 </sect2> 1545 <sect2> 1546 <title>Customizing a state machine / Getting more speed</title> 1547 <para>MSM is offering many UML features at a high-speed, but sometimes, you just 1548 need more speed and are ready to give up some features in exchange. A 1549 process_event is handling several tasks: <itemizedlist> 1550 <listitem> 1551 <para>checking for terminate/interrupt states</para> 1552 </listitem> 1553 <listitem> 1554 <para>handling the message queue (for entry/exit/transition actions 1555 generating themselves events)</para> 1556 </listitem> 1557 <listitem> 1558 <para>handling deferred events</para> 1559 </listitem> 1560 <listitem> 1561 <para>catching exceptions (or not)</para> 1562 </listitem> 1563 <listitem> 1564 <para>handling the state switching and action calls</para> 1565 </listitem> 1566 </itemizedlist>Of these tasks, only the last one is absolutely necessary to 1567 a state machine (its core job), the other ones are nice-to-haves which cost 1568 CPU time. In many cases, it is not so important, but in embedded systems, 1569 this can lead to ad-hoc state machine implementations. MSM detects by itself 1570 if a concrete state machine makes use of terminate/interrupt states and 1571 deferred events and deactivates them if not used. For the other two, if you 1572 do not need them, you need to help by indicating it in your implementation. 1573 This is done with two simple typedefs:<itemizedlist> 1574 <listitem> 1575 <para><code>no_exception_thrown</code> indicates that behaviors will 1576 never throw and MSM does not need to catch anything</para> 1577 </listitem> 1578 <listitem> 1579 <para><code>no_message_queue</code> indicates that no action will 1580 itself generate a new event and MSM can save us the message 1581 queue.</para> 1582 </listitem> 1583 </itemizedlist>The third configuration possibility, explained <link 1584 xlink:href="#basic-defer">here</link>, is to manually activate deferred 1585 events, using <code>activate_deferred_events</code>. For example, the 1586 following state machine sets all three configuration types:</para> 1587 <programlisting>struct player_ : public msm::front::state_machine_def<player_> 1588{ 1589 // no need for exception handling or message queue 1590 typedef int no_exception_thrown; 1591 typedef int no_message_queue; 1592 // also manually enable deferred events 1593 typedef int activate_deferred_events 1594 ...// rest of implementation 1595 };</programlisting> 1596 <para><emphasis role="underline">Important note</emphasis>: As exit pseudo 1597 states are using the message queue to forward events out of a submachine, 1598 the <code>no_message_queue</code> option cannot be used with state machines 1599 containing an exit pseudo state.</para> 1600 </sect2> 1601 <sect2> 1602 <title>Choosing the initial event</title> 1603 <para>A state machine is started using the <code>start</code> method. This 1604 causes the initial state's entry behavior to be executed. Like every entry 1605 behavior, it becomes as parameter the event causing the state to be entered. 1606 But when the machine starts, there was no event triggered. In this case, MSM 1607 sends <code>msm::back::state_machine<...>::InitEvent</code>, which might 1608 not be the default you'd want. For this special case, MSM provides a 1609 configuration mechanism in the form of a typedef. If the state machine's 1610 front-end definition provides an initial_event typedef set to another event, 1611 this event will be used. For example:</para> 1612 <programlisting>struct my_initial_event{}; 1613struct player_ : public msm::front::state_machine_def<player_>{ 1614... 1615typedef my_initial_event initial_event; 1616};</programlisting> 1617 </sect2> 1618 <sect2> 1619 <title> Containing state machine (deprecated)</title> 1620 <para>This feature is still supported in MSM for backward compatibility but made 1621 obsolete by the fact that every guard/action/entry action/exit action get 1622 the state machine passed as argument and might be removed at a later 1623 time.</para> 1624 <para>All of the states defined in the state machine are created upon state 1625 machine construction. This has the huge advantage of a reduced syntactic 1626 noise. The cost is a small loss of control for the user on the state 1627 creation and access. But sometimes you needed a way for a state to get 1628 access to its containing state machine. Basically, a state needs to change 1629 its declaration to:</para> 1630 <programlisting>struct Stopped : public msm::front::state<sm_ptr></programlisting> 1631 <para>And to provide a set_sm_ptr function: <code>void set_sm_ptr(player* 1632 pl)</code></para> 1633 <para>to get a pointer to the containing state machine. The same applies to 1634 terminate_state / interrupt_state and entry_pseudo_state / 1635 exit_pseudo_state. </para> 1636 </sect2> 1637 </sect1> 1638 <sect1> 1639 <title><command xml:id="functor-front-end"/>Functor front-end</title> 1640 <para>The functor front-end is the preferred front-end at the moment. It is more 1641 powerful than the standard front-end and has a more readable transition table. 1642 It also makes it easier to reuse parts of state machines. Like <command 1643 xlink:href="#eUML-front-end">eUML</command>, it also comes with a good deal 1644 of predefined actions. Actually, eUML generates a functor front-end through 1645 Boost.Typeof and Boost.Proto so both offer the same functionality.</para> 1646 <para>The rows which MSM offered in the previous front-end come in different 1647 flavors. We saw the a_row, g_row, _row, row, not counting internal rows. This is 1648 already much to know, so why define new rows? These types have some 1649 disadvantages: <itemizedlist> 1650 <listitem> 1651 <para>They are more typing and information than we would wish. This 1652 means syntactic noise and more to learn.</para> 1653 </listitem> 1654 <listitem> 1655 <para>Function pointers are weird in C++.</para> 1656 </listitem> 1657 <listitem> 1658 <para>The action/guard signature is limited and does not allow for more 1659 variations of parameters (source state, target state, current state 1660 machine, etc.)</para> 1661 </listitem> 1662 <listitem> 1663 <para>It is not easy to reuse action code from a state machine to 1664 another.</para> 1665 </listitem> 1666 </itemizedlist></para> 1667 <sect2> 1668 <title> Transition table </title> 1669 <para>We can change the definition of the simple tutorial's transition table 1670 to:</para> 1671 <programlisting> 1672struct transition_table : mpl::vector< 1673// Start Event Target Action Guard 1674// +---------+------------+-----------+---------------------------+----------------------------+ 1675Row < Stopped , play , Playing , start_playback , none >, 1676Row < Stopped , open_close , Open , open_drawer , none >, 1677Row < Stopped , stop , Stopped , none , none >, 1678// +---------+------------+-----------+---------------------------+----------------------------+ 1679Row < Open , open_close , Empty , close_drawer , none >, 1680// +---------+------------+-----------+---------------------------+----------------------------+ 1681Row < Empty , open_close , Open , open_drawer , none >, 1682Row < Empty , cd_detected, Stopped , store_cd_info , good_disk_format >, 1683g_row< Empty , cd_detected, Playing , &player_::store_cd_info , &player_::auto_start >, 1684// +---------+------------+-----------+---------------------------+----------------------------+ 1685Row < Playing , stop , Stopped , stop_playback , none >, 1686Row < Playing , pause , Paused , pause_playback , none >, 1687Row < Playing , open_close , Open , stop_and_open , none >, 1688// +---------+------------+-----------+---------------------------+----------------------------+ 1689Row < Paused , end_pause , Playing , resume_playback , none >, 1690Row < Paused , stop , Stopped , stop_playback , none >, 1691Row < Paused , open_close , Open , stop_and_open , none > 1692// +---------+------------+-----------+---------------------------+----------------------------+ 1693> {}; 1694 </programlisting> 1695 <para>Transitions are now of type "Row" with exactly 5 template arguments: 1696 source state, event, target state, action and guard. Wherever there is 1697 nothing (for example actions and guards), write "none". Actions and guards 1698 are no more methods but functors getting as arguments the detected event, 1699 the state machine, source and target state:</para> 1700 <programlisting>struct store_cd_info 1701{ 1702 template <class Fsm,class Evt,class SourceState,class TargetState> 1703 void operator()(Evt const&, Fsm& fsm, SourceState&,TargetState& ) 1704 { 1705 cout << "player::store_cd_info" << endl; 1706 fsm.process_event(play()); 1707 } 1708}; </programlisting> 1709 <para>The advantage of functors compared to functions are that functors are 1710 generic and reusable. They also allow passing more parameters than just 1711 events. The guard functors are the same but have an operator() returning a 1712 bool.</para> 1713 <para>It is also possible to mix rows from different front-ends. To show this, a 1714 g_row has been left in the transition table. <emphasis role="underline" 1715 >Note:</emphasis> in case the action functor is used in the transition 1716 table of a state machine contained inside a top-level state machine, the 1717 “fsm” parameter refers to the lowest-level state machine (referencing this 1718 action), not the top-level one.</para> 1719 <para>To illustrate the reusable point, MSM comes with a whole set of predefined 1720 functors. Please refer to eUML for the <link xlink:href="#Reference-begin" 1721 >full list</link>. For example, we are now going to replace the first 1722 action by an action sequence and the guard by a more complex functor.</para> 1723 <para>We decide we now want to execute two actions in the first transition 1724 (Stopped -> Playing). We only need to change the action start_playback to 1725 <programlisting>ActionSequence_< mpl::vector<some_action, start_playback> ></programlisting>and 1726 now will execute some_action and start_playback every time the transition is 1727 taken. ActionSequence_ is a functor calling each action of the mpl::vector 1728 in sequence.</para> 1729 <para>We also want to replace good_disk_format by a condition of the type: 1730 “good_disk_format && (some_condition || some_other_condition)”. We 1731 can achieve this using And_ and Or_ functors: 1732 <programlisting>And_<good_disk_format,Or_< some_condition , some_other_condition> ></programlisting>It 1733 even starts looking like functional programming. MSM ships with functors for 1734 operators, state machine usage, STL algorithms or container methods.</para> 1735 </sect2> 1736 <sect2> 1737 <title>Defining states with entry/exit actions</title> 1738 <para>You probably noticed that we just showed a different transition table and 1739 that we even mixed rows from different front-ends. This means that you can 1740 do this and leave the definitions for states unchanged. Most examples are 1741 doing this as it is the simplest solution. You still enjoy the simplicity of 1742 the first front-end with the extended power of the new transition types. 1743 This <link xlink:href="examples/SimpleWithFunctors.cpp">tutorial</link>, 1744 adapted from the earlier example does just this.</para> 1745 <para>Of course, it is also possible to define states where entry and exit 1746 actions are also provided as functors as these are generated by eUML and 1747 both front-ends are equivalent. For example, we can define a state 1748 as:</para> 1749 <programlisting>struct Empty_Entry 1750{ 1751 template <class Event,class Fsm,class State> 1752 void operator()(Event const&,Fsm&,State&) 1753 { 1754 ... 1755 } 1756}; // same for Empty_Exit 1757struct Empty_tag {}; 1758struct Empty : public msm::front::euml::func_state<Empty_tag,Empty_Entry,Empty_Exit>{};</programlisting> 1759 <para>This also means that you can, like in the transition table, write entry / 1760 exit actions made of more complicated action combinations. The previous 1761 example can therefore <link xlink:href="examples/SimpleWithFunctors2.cpp">be 1762 rewritten</link>.</para> 1763 <para>Usually, however, one will probably use the standard state definition as 1764 it provides the same capabilities as this front-end state definition, unless 1765 one needs some of the shipped predefined functors or is a fan of functional 1766 programming.</para> 1767 </sect2> 1768 <sect2> 1769 <title><command xml:id="functor-front-end-actions"/>What do you actually do inside actions / guards (Part 2)?</title> 1770 <para>Using the basic front-end, we saw how to pass data to actions through the 1771 event, that data common to all states could be stored in the state machine, 1772 state relevant data could be stored in the state and access as template 1773 parameter in the entry / exit actions. What was however missing was the 1774 capability to access relevant state data in the transition action. This is 1775 possible with this front-end. A transition's source and target state are 1776 also given as arguments. If the current calculation's state was to be found 1777 in the transition's source state (whatever it is), we could access 1778 it:</para> 1779 <programlisting>struct send_rocket 1780{ 1781 template <class Fsm,class Evt,class SourceState,class TargetState> 1782 void operator()(Evt const&, Fsm& fsm, SourceState& src,TargetState& ) 1783 { 1784 fire_rocket(evt.direction, src.current_calculation); 1785 } 1786}; </programlisting> 1787 <para>It was a little awkward to generate new events inside actions with the basic 1788 front-end. With the functor front-end it is much cleaner:</para> 1789 <programlisting>struct send_rocket 1790{ 1791 template <class Fsm,class Evt,class SourceState,class TargetState> 1792 void operator()(Evt const& evt, Fsm& fsm, SourceState& src,TargetState&) 1793 { 1794 fire_rocket(evt.direction, src.current_calculation); 1795 fsm.process_event(rocket_launched()); 1796 } 1797}; </programlisting> 1798 </sect2> 1799 <sect2> 1800 <title>Defining a simple state machine</title> 1801 <para>Like states, state machines can be defined using the previous front-end, 1802 as the previous example showed, or with the functor front-end, which allows 1803 you to define a state machine entry and exit functions as functors, as in 1804 <link xlink:href="examples/SimpleWithFunctors2.cpp">this 1805 example</link>.</para> 1806 </sect2> 1807 <sect2> 1808 <title>Anonymous transitions</title> 1809 <para>Anonymous (completion) transitions are transitions without a named event. 1810 We saw how this front-end uses <code>none</code> when no action or guard is 1811 required. We can also use <code>none</code> instead of an event to mark an 1812 anonymous transition. For example, the following transition makes an 1813 immediate transition from State1 to State2:</para> 1814 <programlisting>Row < State1 , none , State2 ></programlisting> 1815 <para>The following transition does the same but calling an action in the 1816 process:</para> 1817 <programlisting>Row < State1 , none , State2 , State1ToState2, none ></programlisting> 1818 <para>The following diagram shows an example and its <link 1819 xlink:href="examples/AnonymousTutorialWithFunctors.cpp" 1820 >implementation</link>:</para> 1821 <para><inlinemediaobject> 1822 <imageobject> 1823 <imagedata fileref="images/Anonymous.jpg" width="70%" scalefit="1"/> 1824 </imageobject> 1825 </inlinemediaobject></para> 1826 </sect2> 1827 <sect2> 1828 <title><command xml:id="functor-internal-transitions"/>Internal 1829 transitions</title> 1830 <para>The <link xlink:href="examples/SimpleTutorialInternalFunctors.cpp" 1831 >following example</link> uses internal transitions with the functor 1832 front-end. As for the simple standard front-end, both methods of defining 1833 internal transitions are supported:<itemizedlist> 1834 <listitem> 1835 <para>providing a <code>Row</code> in the state machine's transition 1836 table with <code>none</code> as target state defines an internal 1837 transition.</para> 1838 </listitem> 1839 <listitem> 1840 <para>providing an <code>internal_transition_table</code> made of 1841 <code>Internal</code> rows inside a state or submachine 1842 defines UML-conform internal transitions with higher 1843 priority.</para> 1844 </listitem> 1845 <listitem> 1846 <para>transitions defined inside 1847 <code>internal_transition_table</code> require no source or 1848 target state as the source state is known (<code>Internal</code> 1849 really are <code>Row</code> without a source or target state) 1850 .</para> 1851 </listitem> 1852 </itemizedlist>Like for the <command xlink:href="#internal-transitions-note" 1853 >standard front-end internal transitions</command>, internal transition 1854 tables are added into the main state machine's table, thus allowing you to 1855 distribute the transition table definition and reuse states.</para> 1856 <para>There is an added bonus offered for submachines, which can have both the 1857 standard transition_table and an internal_transition_table (which has higher 1858 priority). This makes it easier if you decide to make a full submachine from 1859 a state later. It is also slightly faster than the standard alternative, 1860 adding orthogonal regions, because event dispatching will, if accepted by 1861 the internal table, not continue to the subregions. This gives you a O(1) 1862 dispatch instead of O(number of regions). While the example is with eUML, 1863 the same is also possible with this front-end.</para> 1864 </sect2> 1865 <sect2> 1866 <title><command xml:id="any-event"/>Kleene (any) event</title> 1867 <para>Normally, MSM requires an event to fire a transition. But there are cases, 1868 where any event, no matter which one would do:<itemizedlist> 1869 <listitem> 1870 <para>If you want to reduce the number of transitions: any event 1871 would do, possibly will guards decide what happens</para> 1872 </listitem> 1873 <listitem> 1874 <para>Pseudo entry states do not necessarily want to know the event 1875 which caused their activation, or they might want to know only a 1876 property of it.</para> 1877 </listitem> 1878 </itemizedlist></para> 1879 <para>MSM supports a boost::any as an acceptable event. This event will match 1880 any event, meaning that if a transition with boost::any as event originates 1881 from the current state, this transition would fire (provided no guards or 1882 transition with a higher priority fires first). This event is named Kleene, 1883 as reference top the Kleene star used in a regex.</para> 1884 <para>For example, this transition on a state machine instance named fsm:</para> 1885 <programlisting>Row < State1, boost::any, State2></programlisting> 1886 <para>will fire if State1 is active and an event is processed:</para> 1887 <programlisting>fsm.process_event(whatever_event());</programlisting> 1888 <para>At this point, you can use this <emphasis role="italic">any</emphasis> 1889 event in transition actions to get back to the original event by calling for 1890 example<emphasis role="italic"> boost::any::type()</emphasis>.</para> 1891 <para>It is also possible to support your own Kleene events by specializing 1892 boost::msm::is_kleene_event for a given event, for example:</para> 1893 <programlisting>namespace boost { namespace msm{ 1894 template<> 1895 struct is_kleene_event< my_event > 1896 { 1897 typedef boost::mpl::true_ type; 1898 }; 1899}}</programlisting> 1900 <para>The only requirement is that this event must have a copy constructor from 1901 the event originally processed on the state machine.</para> 1902 </sect2> 1903 </sect1> 1904 <sect1> 1905 <title><command xml:id="eUML-front-end"/>eUML</title> 1906 <para><emphasis role="underline">Important note</emphasis>: eUML requires a compiler 1907 supporting Boost.Typeof. Full eUML has experimental status (but not if only the 1908 transition table is written using eUML) because some compilers will start 1909 crashing when a state machine becomes too big (usually when you write huge 1910 actions).</para> 1911 <para>The previous front-ends are simple to write but still force an amount of 1912 noise, mostly MPL types, so it would be nice to write code looking like C++ 1913 (with a C++ action language) directly inside the transition table, like UML 1914 designers like to do on their state machine diagrams. If it were functional 1915 programming, it would be even better. This is what eUML is for.</para> 1916 <para>eUML is a Boost.Proto and Boost.Typeof-based compile-time domain specific 1917 embedded language. It provides grammars which allow the definition of 1918 actions/guards directly inside the transition table or entry/exit in the state 1919 definition. There are grammars for actions, guards, flags, attributes, deferred 1920 events, initial states.</para> 1921 <para>It also relies on Boost.Typeof as a wrapper around the new decltype C++0x 1922 feature to provide a compile-time evaluation of all the grammars. Unfortunately, 1923 all the underlying Boost libraries are not Typeof-enabled, so for the moment, 1924 you will need a compiler where Typeof is supported (like VC9-10, g++ >= 1925 4.3).</para> 1926 <para>Examples will be provided in the next paragraphs. You need to include eUML 1927 basic features: </para> 1928 <para> 1929 <programlisting>#include <msm/front/euml/euml.hpp></programlisting> 1930 </para> 1931 <para>To add STL support (at possible cost of longer compilation times), include: </para> 1932 <para> 1933 <programlisting>#include <msm/front/euml/stl.hpp></programlisting> 1934 </para> 1935 <para>eUML is defined in the namespace <code>msm::front::euml</code>.</para> 1936 <sect2> 1937 <title>Transition table</title> 1938 <para>A transition can be defined using eUML as: </para> 1939 <para> 1940 <programlisting>source + event [guard] / action == target</programlisting> 1941 </para> 1942 <para>or as</para> 1943 <para> 1944 <programlisting>target == source + event [guard] / action</programlisting> 1945 </para> 1946 <para>The first version looks like a drawn transition in a diagram, the second 1947 one seems natural to a C++ developer.</para> 1948 <para>The simple transition table written with the <command 1949 xlink:href="#functor-front-end">functor front-end</command> can now be 1950 written as:</para> 1951 <programlisting>BOOST_MSM_EUML_TRANSITION_TABLE(( 1952Stopped + play [some_guard] / (some_action , start_playback) == Playing , 1953Stopped + open_close/ open_drawer == Open , 1954Stopped + stop == Stopped , 1955Open + open_close / close_drawer == Empty , 1956Empty + open_close / open_drawer == Open , 1957Empty + cd_detected [good_disk_format] / store_cd_info == Stopped 1958),transition_table) </programlisting> 1959 <para>Or, using the alternative notation, it can be:</para> 1960 <programlisting>BOOST_MSM_EUML_TRANSITION_TABLE(( 1961Playing == Stopped + play [some_guard] / (some_action , start_playback) , 1962Open == Stopped + open_close/ open_drawer , 1963Stopped == Stopped + stop , 1964Empty == Open + open_close / close_drawer , 1965Open == Empty + open_close / open_drawer , 1966Stopped == Empty + cd_detected [good_disk_format] / store_cd_info 1967),transition_table) </programlisting> 1968 <para>The transition table now looks like a list of (readable) rules with little 1969 noise.</para> 1970 <para>UML defines guards between “[ ]” and actions after a “/”, so the chosen 1971 syntax is already more readable for UML designers. UML also allows designers 1972 to define several actions sequentially (our previous ActionSequence_) 1973 separated by a comma. The first transition does just this: two actions 1974 separated by a comma and enclosed inside parenthesis to respect C++ operator 1975 precedence.</para> 1976 <para>If this seems to you like it will cost you run-time performance, don't 1977 worry, eUML is based on typeof (or decltype) which only evaluates the 1978 parameters to BOOST_MSM_EUML_TRANSITION_TABLE and no run-time cost occurs. 1979 Actually, eUML is only a metaprogramming layer on top of "standard" MSM 1980 metaprogramming and this first layer generates the previously-introduced 1981 <command xlink:href="#functor-front-end">functor 1982 front-end</command>.</para> 1983 <para>UML also allows designers to define more complicated guards, like 1984 [good_disk_format && (some_condition || some_other_condition)]. This 1985 was possible with our previously defined functors, but using a complicated 1986 template syntax. This syntax is now possible exactly as written, which means 1987 without any syntactic noise at all.</para> 1988 </sect2> 1989 <sect2> 1990 <title>A simple example: rewriting only our transition table </title> 1991 <para>As an introduction to eUML, we will rewrite our tutorial's transition 1992 table using eUML. This will require two or three changes, depending on the compiler:<itemizedlist> 1993 <listitem> 1994 <para>events must inherit from msm::front::euml::euml_event< 1995 event_name ></para> 1996 </listitem> 1997 <listitem> 1998 <para>states must inherit from msm::front::euml::euml_state< 1999 state_name ></para> 2000 </listitem> 2001 <listitem> 2002 <para>with VC, states must be declared before the front-end</para> 2003 </listitem> 2004 </itemizedlist></para> 2005 <para>We now can write the transition table like just shown, using 2006 BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE instead of 2007 BOOST_MSM_EUML_TRANSITION_TABLE. The <link 2008 xlink:href="examples/SimpleTutorialWithEumlTable.cpp" 2009 >implementation</link> is pretty straightforward. The only required 2010 addition is the need to declare a variable for each state or add parenses (a 2011 default-constructor call) in the transition table.</para> 2012 <para>The <link xlink:href="examples/CompositeTutorialWithEumlTable.cpp"> 2013 <command xml:id="eUML-composite-table">composite</command></link> implementation is also natural:</para> 2014 <programlisting>// front-end like always 2015struct sub_front_end : public boost::msm::front::state_machine_def<sub_front_end> 2016{ 2017... 2018}; 2019// back-end like always 2020typedef boost::msm::back::state_machine<sub_front_end> sub_back_end; 2021 2022sub_back_end const sub; // sub can be used in a transition table.</programlisting> 2023 <para>Unfortunately, there is a bug with VC, which appears from time to time and 2024 causes in a stack overflow. If you get a warning that the program is 2025 recursive on all paths, revert to either standard eUML or another front-end 2026 as Microsoft doesn't seem to intend to fix it.</para> 2027 <para>We now have a new, more readable transition table with few changes to our 2028 example. eUML can do much more so please follow the guide.</para> 2029 </sect2> 2030 <sect2> 2031 <title>Defining events, actions and states with entry/exit actions</title> 2032 <sect3> 2033 <title>Events</title> 2034 <para>Events must be proto-enabled. To achieve this, they must inherit from 2035 a proto terminal (euml_event<event-name>). eUML also provides a macro 2036 to make this easier:</para> 2037 <para> 2038 <programlisting>BOOST_MSM_EUML_EVENT(play)</programlisting> 2039 </para> 2040 <para>This declares an event type and an instance of this type called 2041 <code>play</code>, which is now ready to use in state or transition 2042 behaviors.</para> 2043 <para>There is a second macro, BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES, which 2044 takes as second parameter the attributes an event will contain, using 2045 the <command xlink:href="#eUML-attributes">attribute 2046 syntax</command>.</para> 2047 <para><emphasis role="underline">Note</emphasis>: as we now have events 2048 defined as instances instead of just types, can we still process an 2049 event by creating one on the fly, like: 2050 <code>fsm.process_event(play());</code> or do we have to write: 2051 <code>fsm.process_event(play);</code></para> 2052 <para>The answer is you can do both. The second one is easier but unlike 2053 other front-ends, the second uses a defined operator(), which creates an 2054 event on the fly.</para> 2055 </sect3> 2056 <sect3> 2057 <title>Actions</title> 2058 <para>Actions (returning void) and guards (returning a bool) are defined 2059 like previous functors, with the difference that they also must be 2060 proto-enabled. This can be done by inheriting from euml_action< 2061 functor-name >. eUML also provides a macro:</para> 2062 <programlisting>BOOST_MSM_EUML_ACTION(some_condition) 2063{ 2064 template <class Fsm,class Evt,class SourceState,class TargetState> 2065 bool operator()(Evt const& ,Fsm& ,SourceState&,TargetState& ) 2066 { return true; } 2067}; </programlisting> 2068 <para>Like for events, this macro declares a functor type and an instance 2069 for use in transition or state behaviors.</para> 2070 <para>It is possible to use the same action grammar from the transition 2071 table to define state entry and exit behaviors. So 2072 <code>(action1,action2)</code> is a valid entry or exit behavior 2073 executing both actions in turn.</para> 2074 <para>The state functors have a slightly different signature as there is no 2075 source and target state but only a current state (entry/exit actions are 2076 transition-independent), for example:</para> 2077 <programlisting>BOOST_MSM_EUML_ACTION(Empty_Entry) 2078{ 2079 template <class Evt,class Fsm,class State> 2080 void operator()(Evt const& ,Fsm& ,State& ) { ... } 2081 }; </programlisting> 2082 <para><command xml:id="eUML-reuse-functor"/>It is also possible to reuse the functors from the functor front-end. 2083 The syntax is however slightly less comfortable as we need to pretend 2084 creating one on the fly for typeof. For example:</para> 2085 <programlisting>struct start_playback 2086{ 2087 template <class Fsm,class Evt,class SourceState,class TargetState> 2088 void operator()(Evt const& ,Fsm&,SourceState& ,TargetState& ) 2089 { 2090 ... 2091 } 2092}; 2093BOOST_MSM_EUML_TRANSITION_TABLE(( 2094Playing == Stopped + play / start_playback() , 2095... 2096),transition_table)</programlisting> 2097 </sect3> 2098 <sect3> 2099 <title>States</title> 2100 <para>There is also a macro for states. This macro has 2 arguments, first 2101 the expression defining the state, then the state (instance) 2102 name:</para> 2103 <programlisting>BOOST_MSM_EUML_STATE((),Paused)</programlisting> 2104 <para>This defines a simple state without entry or exit action. You can 2105 provide in the expression parameter the state behaviors (entry and exit) 2106 using the action grammar, like in the transition table:</para> 2107 <programlisting>BOOST_MSM_EUML_STATE(((Empty_Entry,Dummy_Entry)/*2 entryactions*/, 2108 Empty_Exit/*1 exit action*/ ), 2109 Empty)</programlisting> 2110 <para>This means that Empty is defined as a state with an entry action made 2111 of two sub-actions, Empty_Entry and Dummy_Entry (enclosed inside 2112 parenthesis), and an exit action, Empty_Exit.</para> 2113 <para>There are several possibilitites for the <command 2114 xml:id="eUML-build-state"/> expression syntax:<itemizedlist> 2115 <listitem> 2116 <para>(): state without entry or exit action.</para> 2117 </listitem> 2118 <listitem> 2119 <para>(Expr1): state with entry but no exit action.</para> 2120 </listitem> 2121 <listitem> 2122 <para>(Expr1,Expr2): state with entry and exit action.</para> 2123 </listitem> 2124 <listitem> 2125 <para>(Expr1,Expr2,Attributes): state with entry and exit 2126 action, defining some attributes (read further on).</para> 2127 </listitem> 2128 <listitem> 2129 <para>(Expr1,Expr2,Attributes,Configure): state with entry and 2130 exit action, defining some attributes (read further on) and 2131 flags (standard MSM flags) or deferred events (standard MSM 2132 deferred events).</para> 2133 </listitem> 2134 <listitem> 2135 <para>(Expr1,Expr2,Attributes,Configure,Base): state with entry 2136 and exit action, defining some attributes (read further on), 2137 flags and deferred events (plain msm deferred events) and a 2138 non-default base state (as defined in standard MSM).</para> 2139 </listitem> 2140 </itemizedlist></para> 2141 <para>no_action is also defined, which does, well, nothing except being a 2142 placeholder (needed for example as entry action if we have no entry but 2143 an exit). Expr1 and Expr2 are a sequence of actions, obeying the same 2144 action grammar as in the transition table (following the “/” 2145 symbol).</para> 2146 <para>The BOOST_MSM_EUML_STATE macro will allow you to define most common 2147 states, but sometimes you will need more, for example provide in your 2148 states some special behavior. In this case, you will have to do the 2149 macro's job by hand, which is not very complicated. The state will need 2150 to inherit from <code>msm::front::state<></code>, like any state, and 2151 from <code>euml_state<state-name></code> to be proto-enabled. You 2152 will then need to declare an instance for use in the transition table. 2153 For example:</para> 2154 <programlisting>struct Empty_impl : public msm::front::state<> , public euml_state<Empty_impl> 2155{ 2156 void activate_empty() {std::cout << "switching to Empty " << std::endl;} 2157 template <class Event,class Fsm> 2158 void on_entry(Event const& evt,Fsm&fsm){...} 2159 template <class Event,class Fsm> 2160 void on_exit(Event const& evt,Fsm&fsm){...} 2161}; 2162//instance for use in the transition table 2163Empty_impl const Empty;</programlisting> 2164 <para>Notice also that we defined a method named activate_empty. We would 2165 like to call it inside a behavior. This can be done using the 2166 BOOST_MSM_EUML_METHOD macro. </para> 2167 <programlisting>BOOST_MSM_EUML_METHOD(ActivateEmpty_,activate_empty,activate_empty_,void,void)</programlisting> 2168 <para>The first parameter is the name of the underlying functor, which you 2169 could use with the functor front-end, the second is the state method 2170 name, the third is the eUML-generated function, the fourth and fifth the 2171 return value when used inside a transition or a state behavior. You can 2172 now use this inside a transition:</para> 2173 <programlisting>Empty == Open + open_close / (close_drawer,activate_empty_(target_))</programlisting> 2174 </sect3> 2175 </sect2> 2176 <sect2> 2177 <title>Wrapping up a simple state machine and first complete examples</title> 2178 <para>You can reuse the state machine definition method from the standard 2179 front-end and simply replace the transition table by this new one. You can 2180 also use eUML to define a state machine "on the fly" (if, for example, you 2181 need to provide an on_entry/on_exit for this state machine as a functor). 2182 For this, there is also a macro, <command xml:id="eUML-build-sm" 2183 />BOOST_MSM_EUML_DECLARE_STATE_MACHINE, which has 2 arguments, an expression 2184 describing the state machine and the state machine name. The expression has 2185 up to 8 arguments:<itemizedlist> 2186 <listitem> 2187 <para>(Stt, Init): simplest state machine where only the transition 2188 table and initial state(s) are defined.</para> 2189 </listitem> 2190 <listitem> 2191 <para>(Stt, Init, Expr1): state machine where the transition table, 2192 initial state and entry action are defined.</para> 2193 </listitem> 2194 <listitem> 2195 <para>(Stt, Init, Expr1, Expr2): state machine where the transition 2196 table, initial state, entry and exit actions are defined.</para> 2197 </listitem> 2198 <listitem> 2199 <para>(Stt, Init, Expr1, Expr2, Attributes): state machine where the 2200 transition table, initial state, entry and exit actions are 2201 defined. Furthermore, some attributes are added (read further 2202 on).</para> 2203 </listitem> 2204 <listitem> 2205 <para>(Stt, Init, Expr1, Expr2, Attributes, Configure): state 2206 machine where the transition table, initial state, entry and 2207 exit actions are defined. Furthermore, some attributes (read 2208 further on), flags, deferred events and <link 2209 xlink:href="#eUML-Configuration">configuration 2210 capabilities</link> (no message queue / no exception 2211 catching) are added.</para> 2212 </listitem> 2213 <listitem> 2214 <para>(Stt, Init, Expr1, Expr2, Attributes, Flags, Deferred , Base): 2215 state machine where the transition table, initial state, entry 2216 and exit actions are defined. Furthermore, attributes (read 2217 further on), flags , deferred events and configuration 2218 capabilities (no message queue / no exception catching) are 2219 added and a non-default base state (see the <link 2220 xlink:href="#backend-base-state">back-end 2221 description</link>) is defined.</para> 2222 </listitem> 2223 </itemizedlist>For example, a minimum state machine could be defined 2224 as:</para> 2225 <programlisting>BOOST_MSM_EUML_TRANSITION_TABLE(( 2226),transition_table) </programlisting> 2227 <programlisting>BOOST_MSM_EUML_DECLARE_STATE_MACHINE((transition_table,init_ << Empty ), 2228 player_)</programlisting> 2229 <para>Please have a look at the player tutorial written using eUML's <link 2230 xlink:href="examples/SimpleTutorialEuml2.cpp">first syntax</link> and 2231 <link xlink:href="examples/SimpleTutorialEuml.cpp">second syntax</link>. 2232 The BOOST_MSM_EUML_DECLARE_ATTRIBUTE macro, to which we will get back 2233 shortly, declares attributes given to an eUML type (state or event) using 2234 the <command xlink:href="#eUML-attributes">attribute 2235 syntax</command>.</para> 2236 </sect2> 2237 <sect2> 2238 <title>Defining a submachine</title> 2239 <para>Defining a submachine (see <link 2240 xlink:href="examples/CompositeTutorialEuml.cpp">tutorial</link>) with 2241 other front-ends simply means using a state which is a state machine in the 2242 transition table of another state machine. This is the same with eUML. One 2243 only needs define a second state machine and reference it in the transition 2244 table of the containing state machine.</para> 2245 <para>Unlike the state or event definition macros, 2246 BOOST_MSM_EUML_DECLARE_STATE_MACHINE defines a type, not an instance because 2247 a type is what the back-end requires. This means that you will need to 2248 declare yourself an instance to reference your submachine into another state 2249 machine, for example:</para> 2250 <programlisting>BOOST_MSM_EUML_DECLARE_STATE_MACHINE(...,Playing_) 2251typedef msm::back::state_machine<Playing_> Playing_type; 2252Playing_type const Playing;</programlisting> 2253 <para>We can now use this instance inside the transition table of the containing 2254 state machine:</para> 2255 <programlisting>Paused == Playing + pause / pause_playback</programlisting> 2256 </sect2> 2257 <sect2> 2258 <title> 2259 <command xml:id="eUML-attributes"/>Attributes / Function call</title> 2260 <para>We now want to make our grammar more useful. Very often, one needs only 2261 very simple action methods, for example ++Counter or Counter > 5 where 2262 Counter is usually defined as some attribute of the class containing the 2263 state machine. It seems like a waste to write a functor for such a simple 2264 action. Furthermore, states within MSM are also classes so they can have 2265 attributes, and we would also like to provide them with attributes. </para> 2266 <para>If you look back at our examples using the <link 2267 xlink:href="examples/SimpleTutorialEuml2.cpp">first</link> and <link 2268 xlink:href="examples/SimpleTutorialEuml.cpp">second</link> syntaxes, you 2269 will find a BOOST_MSM_EUML_DECLARE_ATTRIBUTE and a BOOST_MSM_EUML_ATTRIBUTES 2270 macro. The first one declares possible attributes:</para> 2271 <programlisting>BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,cd_name) 2272BOOST_MSM_EUML_DECLARE_ATTRIBUTE(DiskTypeEnum,cd_type)</programlisting> 2273 <para>This declares two attributes: cd_name of type std::string and cd_type of 2274 type DiskTypeEnum. These attributes are not part of any event or state in 2275 particular, we just declared a name and a type. Now, we can add attributes 2276 to our cd_detected event using the second one:</para> 2277 <programlisting>BOOST_MSM_EUML_ATTRIBUTES((attributes_ << cd_name << cd_type ), 2278 cd_detected_attributes)</programlisting> 2279 <para>This declares an attribute list which is not linked to anything in 2280 particular yet. It can be attached to a state or an event. For example, if 2281 we want the event cd_detected to have these defined attributes we 2282 write:</para> 2283 <programlisting>BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(cd_detected,cd_detected_attributes)</programlisting> 2284 <para>For states, we use the BOOST_MSM_EUML_STATE macro, which has an expression 2285 form where one can provide attributes. For example:</para> 2286 <programlisting>BOOST_MSM_EUML_STATE((no_action /*entry*/,no_action/*exit*/, 2287 attributes_ << cd_detected_attributes), 2288 some_state)</programlisting> 2289 <para>OK, great, we now have a way to add attributes to a class, which we could 2290 have done more easily, so what is the point? The point is that we can now 2291 reference these attributes directly, at compile-time, in the transition 2292 table. For example, in the example, you will find this transition:</para> 2293 <programlisting>Stopped==Empty+cd_detected[good_disk_format&&(event_(cd_type)==Int_<DISK_CD>())] </programlisting> 2294 <para>Read event_(cd_type) as event_->cd_type with event_ a type generic for 2295 events, whatever the concrete event is (in this particular case, it happens 2296 to be a cd_detected as the transition shows).</para> 2297 <para>The main advantage of this feature is that you do not need to define a new 2298 functor and you do not need to look inside the functor to know what it does, 2299 you have all at hand.</para> 2300 <para>MSM provides more generic objects for state machine types:<itemizedlist> 2301 <listitem> 2302 <para>event_ : used inside any action, the event triggering the 2303 transition</para> 2304 </listitem> 2305 <listitem> 2306 <para>state_: used inside entry and exit actions, the entered / 2307 exited state</para> 2308 </listitem> 2309 <listitem> 2310 <para>source_: used inside a transition action, the source 2311 state</para> 2312 </listitem> 2313 <listitem> 2314 <para>target_: used inside a transition action, the target 2315 state</para> 2316 </listitem> 2317 <listitem> 2318 <para>fsm_: used inside any action, the (lowest-level) state machine 2319 processing the transition</para> 2320 </listitem> 2321 <listitem> 2322 <para>Int_<int value>: a functor representing an int</para> 2323 </listitem> 2324 <listitem> 2325 <para>Char_<value>: a functor representing a char</para> 2326 </listitem> 2327 <listitem> 2328 <para>Size_t_<value>: a functor representing a size_t</para> 2329 </listitem> 2330 <listitem> 2331 <para>String_<mpl::string> (boost >= 1.40): a functor 2332 representing a string.</para> 2333 </listitem> 2334 </itemizedlist></para> 2335 <para>These helpers can be used in two different ways:<itemizedlist> 2336 <listitem> 2337 <para>helper(attribute_name) returns the attribute with name 2338 attribute_name</para> 2339 </listitem> 2340 <listitem> 2341 <para>helper returns the state / event type itself.</para> 2342 </listitem> 2343 </itemizedlist></para> 2344 <para>The second form is helpful if you want to provide your states with their 2345 own methods, which you also want to use inside the transition table. In the 2346 <link xlink:href="examples/SimpleTutorialEuml.cpp">above 2347 tutorial</link>, we provide Empty with an activate_empty method. We would 2348 like to create a eUML functor and call it from inside the transition table. 2349 This is done using the MSM_EUML_METHOD / MSM_EUML_FUNCTION macros. The first 2350 creates a functor to a method, the second to a free function. In the 2351 tutorial, we write:</para> 2352 <programlisting>MSM_EUML_METHOD(ActivateEmpty_,activate_empty,activate_empty_,void,void)</programlisting> 2353 <para>The first parameter is the functor name, for use with the functor 2354 front-end. The second is the name of the method to call. The third is the 2355 function name for use with eUML, the fourth is the return type of the 2356 function if used in the context of a transition action, the fifth is the 2357 result type if used in the context of a state entry / exit action (usually 2358 fourth and fifth are the same). We now have a new eUML function calling a 2359 method of "something", and this "something" is one of the five previously 2360 shown generic helpers. We can now use this in a transition, for 2361 example:</para> 2362 <programlisting>Empty == Open + open_close / (close_drawer,activate_empty_(target_))</programlisting> 2363 <para>The action is now defined as a sequence of two actions: close_drawer and 2364 activate_empty, which is called on the target itself. The target being Empty 2365 (the state defined left), this really will call Empty::activate_empty(). 2366 This method could also have an (or several) argument(s), for example the 2367 event, we could then call activate_empty_(target_ , event_).</para> 2368 <para>More examples can be found in the <link 2369 xlink:href="examples/CompilerStressTestEuml.cpp">terrible compiler 2370 stress test</link>, the <link xlink:href="examples/SimpleTimer.cpp" 2371 >timer example</link> or in the <link 2372 xlink:href="examples/iPodSearchEuml.cpp">iPodSearch with eUML</link> 2373 (for String_ and more).</para> 2374 </sect2> 2375 <sect2> 2376 <title>Orthogonal regions, flags, event deferring</title> 2377 <para>Defining orthogonal regions really means providing more initial states. To 2378 add more initial states, “shift left” some, for example, if we had another 2379 initial state named AllOk :</para> 2380 <programlisting>BOOST_MSM_EUML_DECLARE_STATE_MACHINE((transition_table, 2381 init_ << Empty << AllOk ), 2382 player_)</programlisting> 2383 <para>You remember from the <command xlink:href="#eUML-build-state" 2384 >BOOST_MSM_EUML_STATE </command> and <command 2385 xlink:href="#eUML-build-sm" 2386 >BOOST_MSM_EUML_DECLARE_STATE_MACHINE</command> signatures that just 2387 after attributes, we can define flags, like in the basic MSM front-end. To 2388 do this, we have another "shift-left" grammar, for example:</para> 2389 <programlisting>BOOST_MSM_EUML_STATE((no_action,no_action, attributes_ <<no_attributes_, 2390 /* flags */ configure_<< PlayingPaused << CDLoaded), 2391 Paused)</programlisting> 2392 <para>We now defined that Paused will get two flags, PlayingPaused and CDLoaded, 2393 defined, with another macro:</para> 2394 <programlisting>BOOST_MSM_EUML_FLAG(CDLoaded)</programlisting> 2395 <para>This corresponds to the following basic front-end definition of 2396 Paused:</para> 2397 <programlisting>struct Paused : public msm::front::state<> 2398{ 2399 typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list; 2400};</programlisting> 2401 <para>Under the hood, what you get really is a mpl::vector2.</para> 2402 <para><emphasis role="underline">Note</emphasis>: As we use the version of 2403 BOOST_MSM_EUML_STATE's expression with 4 arguments, we need to tell eUML 2404 that we need no attributes. Similarly to a <code>cout << endl</code>, 2405 we need a <code>attributes_ << no_attributes_</code> syntax.</para> 2406 <para>You can use the flag with the is_flag_active method of a state machine. 2407 You can also use the provided helper function is_flag_ (returning a bool) 2408 for state and transition behaviors. For example, in the <link 2409 xlink:href="examples/iPodEuml.cpp">iPod implementation with eUML</link>, 2410 you find the following transition:</para> 2411 <programlisting>ForwardPressed == NoForward + EastPressed[!is_flag_(NoFastFwd)]</programlisting> 2412 <para>The function also has an optional second parameter which is the state 2413 machine on which the function is called. By default, fsm_ is used (the 2414 current state machine) but you could provide a functor returning a reference 2415 to another state machine.</para> 2416 <para>eUML also supports defining deferred events in the state (state machine) 2417 definition. To this aim, we can reuse the flag grammar. For example:</para> 2418 <programlisting>BOOST_MSM_EUML_STATE((Empty_Entry,Empty_Exit, attributes_ << no_attributes_, 2419 /* deferred */ configure_<< play ),Empty) </programlisting> 2420 <para>The configure_ left shift is also responsible for deferring events. Shift 2421 inside configure_ a flag and the state will get a flag, shift an event and 2422 it will get a deferred event. This replaces the basic front-end 2423 definition:</para> 2424 <programlisting>typedef mpl::vector<play> deferred_events;</programlisting> 2425 <para>In <link xlink:href="examples/OrthogonalDeferredEuml.cpp">this 2426 tutorial</link>, player is defining a second orthogonal region with 2427 AllOk as initial state. The <code>Empty</code> and <code>Open</code> states 2428 also defer the event <code>play</code>. <code>Open</code>, 2429 <code>Stopped</code> and <code>Pause</code> also support the flag 2430 <code>CDLoaded</code> using the same left shift into 2431 <code>configure_</code>.</para> 2432 <para>In the functor front-end, we also had the possibility to defer an event 2433 inside a transition, which makes possible conditional deferring. This is 2434 also possible with eUML through the use of the defer_ order, as shown in 2435 <link xlink:href="examples/OrthogonalDeferredEuml.cpp">this 2436 tutorial</link>. You will find the following transition:</para> 2437 <programlisting>Open + play / defer_</programlisting> 2438 <para>This is an <command xlink:href="#eUML-internal">internal 2439 transition</command>. Ignore it for the moment. Interesting is, that 2440 when the event <code>play</code> is fired and <code>Open</code> is active, 2441 the event will be deferred. Now add a guard and you can conditionally defer 2442 the event, for example:</para> 2443 <programlisting>Open + play [ some_condition ] / defer_</programlisting> 2444 <para>This is similar to what we did with the functor front-end. This means that 2445 we have the same constraints. Using defer_ instead of a state declaration, 2446 we need to tell MSM that we have deferred events in this state machine. We 2447 do this (again) using a configure_ declaration in the state machine 2448 definition in which we shift the deferred_events configuration flag:</para> 2449 <programlisting>BOOST_MSM_EUML_DECLARE_STATE_MACHINE((transition_table, 2450 init_ << Empty << AllOk, 2451 Entry_Action, 2452 Exit_Action, 2453 attributes_ << no_attributes_, 2454 configure_<< deferred_events ), 2455 player_)</programlisting> 2456 <para>A <link xlink:href="examples/OrthogonalDeferredEuml2.cpp">tutorial</link> 2457 illustrates this possibility.</para> 2458 </sect2> 2459 <sect2> 2460 <title> 2461 <command xml:id="eUML-Configuration"/>Customizing a state machine / Getting 2462 more speed</title> 2463 <para>We just saw how to use configure_ to define deferred events or flags. We 2464 can also use it to configure our state machine like we did with the other front-ends:<itemizedlist> 2465 <listitem> 2466 <para><code>configure_ << no_exception</code>: disables 2467 exception handling</para> 2468 </listitem> 2469 <listitem> 2470 <para><code>configure_ << no_msg_queue</code> deactivates the 2471 message queue</para> 2472 </listitem> 2473 <listitem> 2474 <para><code>configure_ << deferred_events</code> manually 2475 enables event deferring</para> 2476 </listitem> 2477 </itemizedlist></para> 2478 <para>Deactivating the first two features and not activating the third if not 2479 needed greatly improves the event dispatching speed of your state machine. 2480 Our <link xlink:href="examples/EumlSimple.cpp">speed testing</link> example 2481 with eUML does this for the best performance.</para> 2482 <para><emphasis role="underline">Important note</emphasis>: As exit pseudo 2483 states are using the message queue to forward events out of a submachine, 2484 the <code>no_message_queue</code> option cannot be used with state machines 2485 containing an exit pseudo state.</para> 2486 </sect2> 2487 <sect2> 2488 <title>Completion / Anonymous transitions</title> 2489 <para>Anonymous transitions (See <command xlink:href="#uml-anonymous">UML 2490 tutorial</command>) are transitions without a named event, which are 2491 therefore triggered immediately when the source state becomes active, 2492 provided a guard allows it. As there is no event, to define such a 2493 transition, simply omit the “+” part of the transition (the event), for 2494 example: </para> 2495 <programlisting>State3 == State4 [always_true] / State3ToState4 2496State4 [always_true] / State3ToState4 == State3</programlisting> 2497 <para>Please have a look at <link 2498 xlink:href="examples/AnonymousTutorialEuml.cpp">this example</link>, 2499 which implements the <command xlink:href="#anonymous-transitions">previously 2500 defined</command> state machine with eUML.</para> 2501 </sect2> 2502 <sect2> 2503 <title><command xml:id="eUML-internal"/>Internal transitions</title> 2504 <para>Like both other front-ends, eUML supports two ways of defining internal transitions:<itemizedlist> 2505 <listitem> 2506 <para>in the state machine's transition table. In this case, you 2507 need to specify a source state, event, actions and guards but no 2508 target state, which eUML will interpret as an internal 2509 transition, for example this defines a transition internal to 2510 Open, on the event open_close:</para> 2511 <programlisting>Open + open_close [internal_guard1] / internal_action1</programlisting> 2512 <para><link xlink:href="examples/EumlInternal.cpp">A full 2513 example</link> is also provided.</para> 2514 </listitem> 2515 <listitem> 2516 <para>in a state's <code>internal_transition_table</code>. For 2517 example:</para> 2518 <programlisting>BOOST_MSM_EUML_DECLARE_STATE((Open_Entry,Open_Exit),Open_def) 2519struct Open_impl : public Open_def 2520{ 2521 BOOST_MSM_EUML_DECLARE_INTERNAL_TRANSITION_TABLE(( 2522 open_close [internal_guard1] / internal_action1 2523 )) 2524};</programlisting> 2525 <para>Notice how we do not need to repeat that the transition 2526 originates from Open as we already are in Open's context. </para> 2527 <para>The <link xlink:href="examples/EumlInternalDistributed.cpp" 2528 >implementation</link> also shows the added bonus offered 2529 for submachines, which can have both the standard 2530 transition_table and an internal_transition_table (which has 2531 higher priority). This makes it easier if you decide to make a 2532 full submachine from a state. It is also slightly faster than 2533 the standard alternative, adding orthogonal regions, because 2534 event dispatching will, if accepted by the internal table, not 2535 continue to the subregions. This gives you a O(1) dispatch 2536 instead of O(number of regions).</para> 2537 </listitem> 2538 </itemizedlist></para> 2539 </sect2> 2540 <sect2> 2541 <title><command xml:id="kleene-event"/>Kleene(any) event)</title> 2542 <para>As for the functor front-end, eUML supports the concept of an <emphasis 2543 role="italic"><command xlink:href="#any-event">any</command></emphasis> 2544 event, but boost::any is not an acceptable eUML terminal. If you need an 2545 <emphasis role="italic">any</emphasis> event, use 2546 msm::front::euml::kleene, which inherits boost::any. The same transition as 2547 with boost:any would be: </para> 2548 <programlisting>State1 + kleene == State2</programlisting> 2549 </sect2> 2550 <sect2> 2551 <title>Other state types</title> 2552 <para>We saw the <command xlink:href="#eUML-build-state">build_state</command> 2553 function, which creates a simple state. Likewise, eUML provides other 2554 state-building macros for other types of states:<itemizedlist> 2555 <listitem> 2556 <para>BOOST_MSM_EUML_TERMINATE_STATE takes the same arguments as 2557 BOOST_MSM_EUML_STATE and defines, well, a terminate 2558 state.</para> 2559 </listitem> 2560 <listitem> 2561 <para>BOOST_MSM_EUML_INTERRUPT_STATE takes the same arguments as 2562 BOOST_MSM_EUML_STATE and defines an interrupt state. However, 2563 the expression argument must contain as first element the event 2564 ending the interruption, for example: 2565 <code>BOOST_MSM_EUML_INTERRUPT_STATE(( end_error /*end 2566 interrupt event*/,ErrorMode_Entry,ErrorMode_Exit 2567 ),ErrorMode)</code></para> 2568 </listitem> 2569 <listitem> 2570 <para>BOOST_MSM_EUML_EXIT_STATE takes the same arguments as 2571 BOOST_MSM_EUML_STATE and defines an exit pseudo state. However, 2572 the expression argument must contain as first element the event 2573 propagated from the exit point: 2574 <code>BOOST_MSM_EUML_EXIT_STATE(( event6 /*propagated 2575 event*/,PseudoExit1_Entry,PseudoExit1_Exit 2576 ),PseudoExit1)</code></para> 2577 </listitem> 2578 <listitem> 2579 <para>BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE defines an entry pseudo 2580 state. It takes 3 parameters: the region index to be entered is 2581 defined as an int argument, followed by the configuration 2582 expression like BOOST_MSM_EUML_STATE and the state name, so that 2583 <code>BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE(0 /*region 2584 index*/,( SubState2_Entry,SubState2_Exit ),SubState2)</code> 2585 defines an entry state into the first region of a 2586 submachine.</para> 2587 </listitem> 2588 <listitem> 2589 <para>BOOST_MSM_EUML_ENTRY_STATE defines an entry pseudo state. It 2590 takes 3 parameters: the region index to be entered is defined as 2591 an int argument, followed by the configuration expression like 2592 BOOST_MSM_EUML_STATE and the state name, so that 2593 <code>BOOST_MSM_EUML_ENTRY_STATE(0,( 2594 PseudoEntry1_Entry,PseudoEntry1_Exit ),PseudoEntry1)</code> 2595 defines a pseudo entry state into the first region of a 2596 submachine.</para> 2597 </listitem> 2598 </itemizedlist></para> 2599 <para>To use these states in the transition table, eUML offers the functions 2600 <code>explicit_</code>, <code>exit_pt_</code> and 2601 <code>entry_pt_</code>. For example, a direct entry into the substate 2602 SubState2 from SubFsm2 could be:</para> 2603 <programlisting>explicit_(SubFsm2,SubState2) == State1 + event2</programlisting> 2604 <para>Forks being a list on direct entries, eUML supports a logical syntax 2605 (state1, state2, ...), for example:</para> 2606 <programlisting>(explicit_(SubFsm2,SubState2), 2607 explicit_(SubFsm2,SubState2b), 2608 explicit_(SubFsm2,SubState2c)) == State1 + event3 </programlisting> 2609 <para>An entry point is entered using the same syntax as explicit entries: 2610 <programlisting>entry_pt_(SubFsm2,PseudoEntry1) == State1 + event4</programlisting></para> 2611 <para>For exit points, it is again the same syntax except that exit points are 2612 used as source of the transition: 2613 <programlisting>State2 == exit_pt_(SubFsm2,PseudoExit1) + event6 </programlisting></para> 2614 <para>The <link xlink:href="examples/DirectEntryEuml.cpp">entry tutorial</link> 2615 is also available with eUML.</para> 2616 </sect2> 2617 <sect2> 2618 <title>Helper functions</title> 2619 <para>We saw a few helpers but there are more, so let us have a more complete description:<itemizedlist> 2620 <listitem> 2621 <para>event_ : used inside any action, the event triggering the 2622 transition</para> 2623 </listitem> 2624 <listitem> 2625 <para>state_: used inside entry and exit actions, the entered / 2626 exited state</para> 2627 </listitem> 2628 <listitem> 2629 <para>source_: used inside a transition action, the source 2630 state</para> 2631 </listitem> 2632 <listitem> 2633 <para>target_: used inside a transition action, the target 2634 state</para> 2635 </listitem> 2636 <listitem> 2637 <para>fsm_: used inside any action, the (deepest-level) state 2638 machine processing the transition</para> 2639 </listitem> 2640 <listitem> 2641 <para>These objects can also be used as a function and return an 2642 attribute, for example event_(cd_name)</para> 2643 </listitem> 2644 <listitem> 2645 <para>Int_<int value>: a functor representing an int</para> 2646 </listitem> 2647 <listitem> 2648 <para>Char_<value>: a functor representing a char</para> 2649 </listitem> 2650 <listitem> 2651 <para>Size_t_<value>: a functor representing a size_t</para> 2652 </listitem> 2653 <listitem> 2654 <para>True_ and False_ functors returning true and false 2655 respectively</para> 2656 </listitem> 2657 <listitem> 2658 <para>String_<mpl::string> (boost >= 1.40): a functor 2659 representing a string.</para> 2660 </listitem> 2661 <listitem> 2662 <para>if_then_else_(guard, action, action) where action can be an 2663 action sequence</para> 2664 </listitem> 2665 <listitem> 2666 <para>if_then_(guard, action) where action can be an action 2667 sequence</para> 2668 </listitem> 2669 <listitem> 2670 <para>while_(guard, action) where action can be an action 2671 sequence</para> 2672 </listitem> 2673 <listitem> 2674 <para>do_while_(guard, action) where action can be an action 2675 sequence</para> 2676 </listitem> 2677 <listitem> 2678 <para>for_(action, guard, action, action) where action can be an 2679 action sequence</para> 2680 </listitem> 2681 <listitem> 2682 <para>process_(some_event [, some state machine] [, some state 2683 machine] [, some state machine] [, some state machine]) will 2684 call process_event (some_event) on the current state machine or 2685 on the one(s) passed as 2nd , 3rd, 4th, 5th argument. This allow 2686 sending events to several external machines</para> 2687 </listitem> 2688 <listitem> 2689 <para>process_(event_): reprocesses the event which triggered the 2690 transition</para> 2691 </listitem> 2692 <listitem> 2693 <para>reprocess_(): same as above but shorter to write</para> 2694 </listitem> 2695 <listitem> 2696 <para>process2_(some_event,Value [, some state machine] [, some 2697 state machine] [, some state machine]) will call process_event 2698 (some_event(Value)) on the current state machine or on the 2699 one(s) passed as 3rd, 4th, 5th argument</para> 2700 </listitem> 2701 <listitem> 2702 <para>is_ flag_(some_flag[, some state machine]) will call 2703 is_flag_active on the current state machine or on the one passed 2704 as 2nd argument</para> 2705 </listitem> 2706 <listitem> 2707 <para>Predicate_<some predicate>: Used in STL algorithms. Wraps 2708 unary/binary functions to make them eUML-compatible so that they 2709 can be used in STL algorithms</para> 2710 </listitem> 2711 </itemizedlist></para> 2712 <para>This can be quite fun. For example, </para> 2713 <programlisting>/( if_then_else_(--fsm_(m_SongIndex) > Int_<0>(),/*if clause*/ 2714 show_playing_song, /*then clause*/ 2715 (fsm_(m_SongIndex)=Int_<1>(),process_(EndPlay))/*else clause*/ 2716 ) 2717 )</programlisting> 2718 <para>means: if (fsm.SongIndex > 0, call show_playing_song else 2719 {fsm.SongIndex=1; process EndPlay on fsm;}</para> 2720 <para>A few examples are using these features:<itemizedlist> 2721 <listitem> 2722 <para>the iPod example introduced at the BoostCon09 <link 2723 xlink:href="examples/iPodEuml.cpp">has been rewritten</link> 2724 with eUML (weak compilers please move on...)</para> 2725 </listitem> 2726 <listitem> 2727 <para>the iPodSearch example also introduced at the BoostCon09 <link 2728 xlink:href="examples/iPodSearchEuml.cpp">has been 2729 rewritten</link> with eUML. In this example, you will also 2730 find some examples of STL functor usage.</para> 2731 </listitem> 2732 <listitem> 2733 <para><link xlink:href="examples/SimpleTimer.cpp">A simpler 2734 timer</link> example is a good starting point. </para> 2735 </listitem> 2736 </itemizedlist></para> 2737 <para>There is unfortunately a small catch. Defining a functor using 2738 MSM_EUML_METHOD or MSM_EUML_FUNCTION will create a correct functor. Your own 2739 eUML functors written as described at the beginning of this section will 2740 also work well, <emphasis role="underline">except</emphasis>, for the 2741 moment, with the while_, if_then_, if_then_else_ functions.</para> 2742 </sect2> 2743 <sect2> 2744 <title>Phoenix-like STL support</title> 2745 <para>eUML supports most C++ operators (except address-of). For example it is 2746 possible to write event_(some_attribute)++ or [source_(some_bool) && 2747 fsm_(some_other_bool)]. But a programmer needs more than operators in his 2748 daily programming. The STL is clearly a must have. Therefore, eUML comes in 2749 with a lot of functors to further reduce the need for your own functors for 2750 the transition table. For almost every algorithm or container method of the 2751 STL, a corresponding eUML function is defined. Like Boost.Phoenix, “.” And 2752 “->” of call on objects are replaced by a functional programming paradigm, 2753 for example:<itemizedlist> 2754 <listitem> 2755 <para>begin_(container), end_(container): return iterators of a 2756 container.</para> 2757 </listitem> 2758 <listitem> 2759 <para>empty_(container): returns container.empty()</para> 2760 </listitem> 2761 <listitem> 2762 <para>clear_(container): container.clear()</para> 2763 </listitem> 2764 <listitem> 2765 <para>transform_ : std::transform</para> 2766 </listitem> 2767 </itemizedlist></para> 2768 <para>In a nutshell, almost every STL method or algorithm is matched by a 2769 corresponding functor, which can then be used in the transition table or 2770 state actions. The <link xlink:href="#Reference-begin">reference</link> 2771 lists all eUML functions and the underlying functor (so that this 2772 possibility is not reserved to eUML but also to the functor-based 2773 front-end). The file structure of this Phoenix-like library matches the one 2774 of Boost.Phoenix. All functors for STL algorithms are to be found in:</para> 2775 <programlisting>#include <msm/front/euml/algorithm.hpp></programlisting> 2776 <para>The algorithms are also divided into sub-headers, matching the phoenix 2777 structure for simplicity:</para> 2778 <programlisting>#include < msm/front/euml/iteration.hpp> 2779#include < msm/front/euml/transformation.hpp> 2780#include < msm/front/euml/querying.hpp> </programlisting> 2781 <para>Container methods can be found in:</para> 2782 <programlisting>#include < msm/front/euml/container.hpp></programlisting> 2783 <para>Or one can simply include the whole STL support (you will also need to 2784 include euml.hpp):</para> 2785 <programlisting>#include < msm/front/euml/stl.hpp></programlisting> 2786 <para>A few examples (to be found in <link 2787 xlink:href="examples/iPodSearchEuml.cpp">this tutorial</link>):<itemizedlist> 2788 <listitem> 2789 <para><code>push_back_(fsm_(m_tgt_container),event_(m_song))</code>: 2790 the state machine has an attribute m_tgt_container of type 2791 std::vector<OneSong> and the event has an attribute m_song of 2792 type OneSong. The line therefore pushes m_song at the end of 2793 m_tgt_container</para> 2794 </listitem> 2795 <listitem> 2796 <para><code>if_then_( state_(m_src_it) != 2797 end_(fsm_(m_src_container)), 2798 process2_(OneSong(),*(state_(m_src_it)++)) )</code>: the 2799 current state has an attribute m_src_it (an iterator). If this 2800 iterator != fsm.m_src_container.end(), process OneSong on fsm, 2801 copy-constructed from state.m_src_it which we 2802 post-increment</para> 2803 </listitem> 2804 </itemizedlist></para> 2805 </sect2> 2806 <sect2> 2807 <title><command xml:id="eUML-phoenix"/>Writing actions with Boost.Phoenix (in development)</title> 2808 <para> It is also possible to write actions, guards, state entry and exit 2809 actions using a reduced set of Boost.Phoenix capabilities. This feature 2810 is still in development stage, so you might get here and there some 2811 surprise. Simple cases, however, should work well. What will not work 2812 will be mixing of eUML and Phoenix functors. Writing guards in one 2813 language and actions in another is ok though.</para> 2814 <para>Phoenix also supports a larger syntax than what will ever be possible 2815 with eUML, so you can only use a reduced set of phoenix's grammar. This 2816 is due to the nature of eUML. The run-time transition table definition 2817 is translated to a type using Boost.Typeof. The result is a "normal" MSM 2818 transition table made of functor types. As C++ does not allow mixing 2819 run-time and compile-time constructs, there will be some limit (trying 2820 to instantiate a template class MyTemplateClass<i> where i is an int 2821 will give you an idea). This means following valid Phoenix constructs 2822 will not work:</para> 2823 <para> 2824 <itemizedlist> 2825 <listitem> 2826 <para>literals</para> 2827 </listitem> 2828 <listitem> 2829 <para>function pointers</para> 2830 </listitem> 2831 <listitem> 2832 <para>bind</para> 2833 </listitem> 2834 <listitem> 2835 <para>->*</para> 2836 </listitem> 2837 </itemizedlist> 2838 </para> 2839 <para>MSM also provides placeholders which make more sense in its context 2840 than arg1.. argn:</para> 2841 <para> 2842 <itemizedlist> 2843 <listitem> 2844 <para>_event: the event triggering the transition</para> 2845 </listitem> 2846 <listitem> 2847 <para>_fsm: the state machine processing the event</para> 2848 </listitem> 2849 <listitem> 2850 <para>_source: the source state of the transition</para> 2851 </listitem> 2852 <listitem> 2853 <para>_target: the target state of the transition</para> 2854 </listitem> 2855 <listitem> 2856 <para>_state: for state entry/exit actions, the entry/exit 2857 state</para> 2858 </listitem> 2859 </itemizedlist> 2860 </para> 2861 <para>Future versions of MSM will support Phoenix better. You can contribute 2862 by finding out cases which do not work but should, so that they can be 2863 added.</para> 2864 <para>Phoenix support is not activated by default. To activate it, add 2865 before any MSM header: #define BOOST_MSM_EUML_PHOENIX_SUPPORT.</para> 2866 <para>A <link 2867 xlink:href="examples/SimplePhoenix.cpp">simple example</link> shows some basic capabilities.</para> 2868 </sect2> 2869 </sect1> 2870 <sect1> 2871 <title>Back-end</title> 2872 <para>There is, at the moment, one back-end. This back-end contains the library 2873 engine and defines the performance and functionality trade-offs. The currently 2874 available back-end implements most of the functionality defined by the UML 2.0 2875 standard at very high runtime speed, in exchange for longer compile-time. The 2876 runtime speed is due to a constant-time double-dispatch and self-adapting 2877 capabilities allowing the framework to adapt itself to the features used by a 2878 given concrete state machine. All unneeded features either disable themselves or 2879 can be manually disabled. See section 5.1 for a complete description of the 2880 run-to-completion algorithm.</para> 2881 <sect2> 2882 <title>Creation </title> 2883 <para>MSM being divided between front and back-end, one needs to first define a 2884 front-end. Then, to create a real state machine, the back-end must be 2885 declared: 2886 <programlisting>typedef msm::back::state_machine<my_front_end> my_fsm;</programlisting></para> 2887 <para>We now have a fully functional state machine type. The next sections will 2888 describe what can be done with it.</para> 2889 </sect2> 2890 <sect2> 2891 <title><command xml:id="backend-start"/>Starting and stopping a state 2892 machine</title> 2893 <para>The <code>start()</code> method starts the state machine, meaning it will 2894 activate the initial state, which means in turn that the initial state's 2895 entry behavior will be called. We need the start method because you do not 2896 always want the entry behavior of the initial state to be called immediately 2897 but only when your state machine is ready to process events. A good example 2898 of this is when you use a state machine to write an algorithm and each loop 2899 back to the initial state is an algorithm call. Each call to start will make 2900 the algorithm run once. The <link xlink:href="examples/iPodSearch.cpp" 2901 >iPodSearch</link> example uses this possibility.</para> 2902 <para>The <code>stop()</code> method works the same way. It will cause the exit 2903 actions of the currently active states(s) to be called.</para> 2904 <para>Both methods are actually not an absolute need. Not calling them will 2905 simply cause your first entry or your last exit action not to be 2906 called.</para> 2907 </sect2> 2908 <sect2> 2909 <title>Event dispatching</title> 2910 <para>The main reason to exist for a state machine is to dispatch events. For 2911 MSM, events are objects of a given event type. The object itself can contain 2912 data, but the event type is what decides of the transition to be taken. For 2913 MSM, if some_event is a given type (a simple struct for example) and e1 and 2914 e2 concrete instances of some_event, e1 and e2 are equivalent, from a 2915 transition perspective. Of course, e1 and e2 can have different values and 2916 you can use them inside actions. Events are dispatched as const reference, 2917 so actions cannot modify events for obvious side-effect reasons. To dispatch 2918 an event of type some_event, you can simply create one on the fly or 2919 instantiate if before processing: </para> 2920 <programlisting>my_fsm fsm; fsm.process_event(some_event()); 2921some_event e1; fsm.process_event(e1)</programlisting> 2922 <para>Creating an event on the fly will be optimized by the compiler so the 2923 performance will not degrade.</para> 2924 </sect2> 2925 <sect2> 2926 <title>Active state(s)</title> 2927 <para>The backend also offers a way to know which state is active, though you 2928 will normally only need this for debugging purposes. If what you need simply 2929 is doing something with the active state, <command 2930 xlink:href="#UML-internal-transition">internal transitions</command> or 2931 <command xlink:href="#backend-visitor">visitors</command> are a better 2932 alternative. If you need to know what state is active, const int* 2933 current_state() will return an array of state ids. Please refer to the 2934 <command xlink:href="#internals-state-id">internals section</command> to 2935 know how state ids are generated.</para> 2936 </sect2> 2937 <sect2> 2938 <title><command xml:id="back-end-serialization"/>Serialization</title> 2939 <para>A common need is the ability to save a state machine and restore it at a 2940 different time. MSM supports this feature for the basic and functor 2941 front-ends, and in a more limited manner for eUML. MSM supports 2942 boost::serialization out of the box (by offering a <code>serialize</code> 2943 function). Actually, for basic serialization, you need not do much, a MSM 2944 state machine is serializable almost like any other type. Without any 2945 special work, you can make a state machine remember its state, for 2946 example:</para> 2947 <para> 2948 <programlisting>MyFsm fsm; 2949// write to archive 2950std::ofstream ofs("fsm.txt"); 2951// save fsm to archive 2952{ 2953 boost::archive::text_oarchive oa(ofs); 2954 // write class instance to archive 2955 oa << fsm; 2956} </programlisting> 2957 </para> 2958 <para>Loading back is very similar:</para> 2959 <para> 2960 <programlisting>MyFsm fsm; 2961{ 2962 // create and open an archive for input 2963 std::ifstream ifs("fsm.txt"); 2964 boost::archive::text_iarchive ia(ifs); 2965 // read class state from archive 2966 ia >> fsm; 2967} </programlisting> 2968 </para> 2969 <para>This will (de)serialize the state machine itself but not the concrete 2970 states' data. This can be done on a per-state basis to reduce the amount of 2971 typing necessary. To allow serialization of a concrete state, provide a 2972 do_serialize typedef and implement the serialize function:</para> 2973 <para> 2974 <programlisting>struct Empty : public msm::front::state<> 2975{ 2976 // we want Empty to be serialized. First provide the typedef 2977 typedef int do_serialize; 2978 // then implement serialize 2979 template<class Archive> 2980 void serialize(Archive & ar, const unsigned int /* version */) 2981 { 2982 ar & some_dummy_data; 2983 } 2984 Empty():some_dummy_data(0){} 2985 int some_dummy_data; 2986}; </programlisting> 2987 </para> 2988 <para>You can also serialize data contained in the front-end class. Again, you 2989 need to provide the typedef and implement serialize:</para> 2990 <para> 2991 <programlisting>struct player_ : public msm::front::state_machine_def<player_> 2992{ 2993 //we might want to serialize some data contained by the front-end 2994 int front_end_data; 2995 player_():front_end_data(0){} 2996 // to achieve this, provide the typedef 2997 typedef int do_serialize; 2998 // and implement serialize 2999 template<class Archive> 3000 void serialize(Archive & ar, const unsigned int ) 3001 { 3002 ar & front_end_data; 3003 } 3004... 3005}; </programlisting> 3006 </para> 3007 <para>The saving of the back-end data (the current state(s)) is valid for all 3008 front-ends, so a front-end written using eUML can be serialized. However, to 3009 serialize a concrete state, the macros like 3010 <code>BOOST_MSM_EUML_STATE</code> cannot be used, so the state will have 3011 to be implemented by directly inheriting from 3012 <code>front::euml::euml_state</code>.</para> 3013 <para>The only limitiation is that the event queues cannot be serialized so 3014 serializing must be done in a stable state, when no event is being 3015 processed. You can serialize during event processing only if using no queue 3016 (deferred or event queue).</para> 3017 <para>This <link 3018 xlink:href="examples/Serialize.cpp">example</link> shows a state machine which we serialize after processing an 3019 event. The <code>Empty</code> state also has some data to serialize.</para> 3020 </sect2> 3021 <sect2> 3022 <title><command xml:id="backend-base-state"/>Base state type </title> 3023 <para>Sometimes, one needs to customize states to avoid repetition and provide a 3024 common functionality, for example in the form of a virtual method. You might 3025 also want to make your states polymorphic so that you can call typeid on 3026 them for logging or debugging. It is also useful if you need a visitor, like 3027 the next section will show. You will notice that all front-ends offer the 3028 possibility of adding a base type. Note that all states and state machines 3029 must have the same base state, so this could reduce reuse. For example, 3030 using the basic front end, you need to:<itemizedlist> 3031 <listitem> 3032 <para>Add the non-default base state in your msm::front::state<> 3033 definition, as first template argument (except for 3034 interrupt_states for which it is the second argument, the first 3035 one being the event ending the interrupt), for example, 3036 my_base_state being your new base state for all states in a 3037 given state machine: 3038 <programlisting>struct Empty : public msm::front::state<my_base_state></programlisting> 3039 Now, my_base_state is your new base state. If it has a virtual 3040 function, your states become polymorphic. MSM also provides a 3041 default polymorphic base type, 3042 <code>msm::front::polymorphic_state</code> 3043 </para> 3044 </listitem> 3045 <listitem> 3046 <para>Add the user-defined base state in the state machine frontend 3047 definition, as a second template argument, for example: 3048 <programlisting>struct player_ : public msm::front::state_machine<player_,my_base_state> </programlisting></para> 3049 </listitem> 3050 </itemizedlist></para> 3051 <para>You can also ask for a state with a given id (which you might have gotten 3052 from current_state()) using <code>const base_state* get_state_by_id(int id) 3053 const</code> where base_state is the one you just defined. You can now 3054 do something polymorphically.</para> 3055 </sect2> 3056 <sect2> 3057 <title><command xml:id="backend-visitor"/>Visitor</title> 3058 <para>In some cases, having a pointer-to-base of the currently active states is 3059 not enough. You might want to call non-virtually a method of the currently 3060 active states. It will not be said that MSM forces the virtual keyword down 3061 your throat!</para> 3062 <para>To achieve this goal, MSM provides its own variation of a visitor pattern 3063 using the previously described user-defined state technique. If you add to 3064 your user-defined base state an <code>accept_sig</code> typedef giving the 3065 return value (unused for the moment) and parameters and provide an accept 3066 method with this signature, calling visit_current_states will cause accept 3067 to be called on the currently active states. Typically, you will also want 3068 to provide an empty default accept in your base state in order in order not 3069 to force all your states to implement accept. For example your base state 3070 could be:</para> 3071 <programlisting>struct my_visitable_state 3072{ 3073 // signature of the accept function 3074 typedef args<void> accept_sig; 3075 // we also want polymorphic states 3076 virtual ~my_visitable_state() {} 3077 // default implementation for states who do not need to be visited 3078 void accept() const {} 3079};</programlisting> 3080 <para>This makes your states polymorphic and visitable. In this case, accept is 3081 made const and takes no argument. It could also be:</para> 3082 <programlisting>struct SomeVisitor {…}; 3083struct my_visitable_state 3084{ 3085 // signature of the accept function 3086 typedef args<void,SomeVisitor&> accept_sig; 3087 // we also want polymorphic states 3088 virtual ~my_visitable_state() {} 3089 // default implementation for states who do not need to be visited 3090 void accept(SomeVisitor&) const {} 3091};</programlisting> 3092 <para>And now, <code>accept</code> will take one argument (it could also be 3093 non-const). By default, <code>accept</code> takes up to 2 arguments. To get 3094 more, set #define BOOST_MSM_VISITOR_ARG_SIZE to another value before 3095 including state_machine.hpp. For example:</para> 3096 <programlisting>#define BOOST_MSM_VISITOR_ARG_SIZE 3 3097#include <boost/msm/back/state_machine.hpp></programlisting> 3098 <para>Note that accept will be called on ALL active states <emphasis 3099 role="underline">and also automatically on sub-states of a 3100 submachine</emphasis>.</para> 3101 <para><emphasis role="underline">Important warning</emphasis>: The method 3102 visit_current_states takes its parameter by value, so if the signature of 3103 the accept function is to contain a parameter passed by reference, pass this 3104 parameter with a boost:ref/cref to avoid undesired copies or slicing. So, 3105 for example, in the above case, call:</para> 3106 <programlisting>SomeVisitor vis; sm.visit_current_states(boost::ref(vis));</programlisting> 3107 <para>This <link xlink:href="examples/SM-2Arg.cpp">example</link> uses a 3108 visiting function with 2 arguments.</para> 3109 </sect2> 3110 <sect2> 3111 <title>Flags</title> 3112 <para>Flags is a MSM-only concept, supported by all front-ends, which base 3113 themselves on the functions: </para> 3114 <programlisting>template <class Flag> bool is_flag_active() 3115template <class Flag,class BinaryOp> bool is_flag_active()</programlisting> 3116 <para>These functions return true if the currently active state(s) support the 3117 Flag property. The first variant ORs the result if there are several 3118 orthogonal regions, the second one expects OR or AND, for example:</para> 3119 <programlisting>my_fsm.is_flag_active<MyFlag>() 3120my_fsm.is_flag_active<MyFlag,my_fsm_type::Flag_OR>()</programlisting> 3121 <para>Please refer to the front-ends sections for usage examples.</para> 3122 </sect2> 3123 <sect2> 3124 <title>Getting a state</title> 3125 <para>It is sometimes necessary to have the client code get access to the 3126 states' data. After all, the states are created once for good and hang 3127 around as long as the state machine does so why not use it? You simply just 3128 need sometimes to get information about any state, even inactive ones. An 3129 example is if you want to write a coverage tool and know how many times a 3130 state was visited. To get a state, use the get_state method giving the state 3131 name, for example: </para> 3132 <programlisting>player::Stopped* tempstate = p.get_state<player::Stopped*>();</programlisting> 3133 <para> or </para> 3134 <programlisting>player::Stopped& tempstate2 = p.get_state<player::Stopped&>();</programlisting> 3135 <para>depending on your personal taste. </para> 3136 </sect2> 3137 <sect2> 3138 <title><command xml:id="backend-fsm-constructor-args"/> State machine constructor with arguments </title> 3139 <para>You might want to define a state machine with a non-default constructor. 3140 For example, you might want to write: </para> 3141 <programlisting>struct player_ : public msm::front::state_machine_def<player_> 3142{ 3143 player_(int some_value){…} 3144}; </programlisting> 3145 <para>This is possible, using the back-end as forwarding object: </para> 3146 <programlisting>typedef msm::back::state_machine<player_ > player; player p(3);</programlisting> 3147 <para>The back-end will call the corresponding front-end constructor upon 3148 creation.</para> 3149 <para>You can pass arguments up to the value of the 3150 BOOST_MSM_CONSTRUCTOR_ARG_SIZE macro (currently 5) arguments. Change this 3151 value before including any header if you need to overwrite the default. </para> 3152 <para>You can also pass arguments by reference (or const-reference) using 3153 boost::ref (or boost::cref):</para> 3154 <programlisting>struct player_ : public msm::front::state_machine_def<player_> 3155{ 3156 player_(SomeType& t, int some_value){…} 3157}; 3158 3159typedef msm::back::state_machine<player_ > player; 3160SomeType data; 3161player p(boost::ref(data),3); 3162 </programlisting> 3163 <para>Normally, MSM default-constructs all its states or submachines. There are 3164 however cases where you might not want this. An example is when you use a 3165 state machine as submachine, and this submachine used the above defined 3166 constructors. You can add as first argument of the state machine constructor 3167 an expression where existing states are passed and copied:</para> 3168 <programlisting>player p( back::states_ << state_1 << ... << state_n , boost::ref(data),3);</programlisting> 3169 <para>Where state_1..n are instances of some or all of the states of the state 3170 machine. Submachines being state machines, this can recurse, for example, if 3171 Playing is a submachine containing a state Song1 having itself a constructor 3172 where some data is passed:</para> 3173 <programlisting>player p( back::states_ << Playing(back::states_ << Song1(some_Song1_data)) , 3174 boost::ref(data),3);</programlisting> 3175 <para>It is also possible to replace a given state by a new instance at any time 3176 using <code>set_states()</code> and the same syntax, for example: 3177 <programlisting>p.set_states( back::states_ << state_1 << ... << state_n );</programlisting></para> 3178 <para>An <link xlink:href="examples/Constructor.cpp" 3179 >example</link> making intensive use of this capability is provided.</para> 3180 </sect2> 3181 <sect2> 3182 <title><command xml:id="backend-tradeof-rt-ct"/>Trading run-time speed for 3183 better compile-time / multi-TU compilation</title> 3184 <para>MSM is optimized for run-time speed at the cost of longer compile-time. 3185 This can become a problem with older compilers and big state machines, 3186 especially if you don't really care about run-time speed that much and would 3187 be satisfied by a performance roughly the same as most state machine 3188 libraries. MSM offers a back-end policy to help there. But before you try 3189 it, if you are using a VC compiler, deactivate the /Gm compiler option 3190 (default for debug builds). This option can cause builds to be 3 times 3191 longer... If the compile-time still is a problem, read further. MSM offers a 3192 policy which will speed up compiling in two main cases:<itemizedlist> 3193 <listitem> 3194 <para>many transition conflicts</para> 3195 </listitem> 3196 <listitem> 3197 <para>submachines</para> 3198 </listitem> 3199 </itemizedlist></para> 3200 <para>The back-end <code>msm::back::state_machine</code> has a policy argument 3201 (first is the front-end, then the history policy) defaulting to 3202 <code>favor_runtime_speed</code>. To switch to 3203 <code>favor_compile_time</code>, which is declared in 3204 <code><msm/back/favor_compile_time.hpp></code>, you need to:<itemizedlist> 3205 <listitem> 3206 <para>switch the policy to <code>favor_compile_time</code> for the 3207 main state machine (and possibly submachines)</para> 3208 </listitem> 3209 <listitem> 3210 <para>move the submachine declarations into their own header which 3211 includes 3212 <code><msm/back/favor_compile_time.hpp></code></para> 3213 </listitem> 3214 <listitem> 3215 <para>add for each submachine a cpp file including your header and 3216 calling a macro, which generates helper code, for 3217 example:</para> 3218 <programlisting>#include "mysubmachine.hpp" 3219BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(mysubmachine)</programlisting> 3220 </listitem> 3221 <listitem> 3222 <para>configure your compiler for multi-core compilation</para> 3223 </listitem> 3224 </itemizedlist></para> 3225 <para>You will now compile your state machine on as many cores as you have 3226 submachines, which will greatly speed up the compilation if you factor your 3227 state machine into smaller submachines.</para> 3228 <para>Independently, transition conflicts resolution will also be much 3229 faster.</para> 3230 <para>This policy uses boost.any behind the hood, which means that we will lose 3231 a feature which MSM offers with the default policy, <link 3232 xlink:href="#event-hierarchy">event hierarchy</link>. The following 3233 example takes our iPod example and speeds up compile-time by using this 3234 technique. We have:<itemizedlist> 3235 <listitem> 3236 <para><link xlink:href="examples/iPod_distributed/iPod.cpp">our main 3237 state machine and main function</link></para> 3238 </listitem> 3239 <listitem> 3240 <para><link xlink:href="examples/iPod_distributed/PlayingMode.hpp" 3241 >PlayingMode moved to a separate header</link></para> 3242 </listitem> 3243 <listitem> 3244 <para><link xlink:href="examples/iPod_distributed/PlayingMode.cpp">a 3245 cpp for PlayingMode</link></para> 3246 </listitem> 3247 <listitem> 3248 <para><link xlink:href="examples/iPod_distributed/MenuMode.hpp" 3249 >MenuMode moved to a separate header</link></para> 3250 </listitem> 3251 <listitem> 3252 <para><link xlink:href="examples/iPod_distributed/MenuMode.cpp">a 3253 cpp for MenuMode</link></para> 3254 </listitem> 3255 <listitem> 3256 <para><link xlink:href="examples/iPod_distributed/Events.hpp">events 3257 move to a separate header as all machines use 3258 it</link></para> 3259 </listitem> 3260 </itemizedlist> 3261 </para> 3262 </sect2> 3263 <sect2> 3264 <title><command xml:id="backend-compile-time-analysis"/>Compile-time state machine analysis </title> 3265 <para>A MSM state machine being a metaprogram, it is only logical that cheking 3266 for the validity of a concrete state machine happens compile-time. To this 3267 aim, using the compile-time graph library <link xlink:href="http://www.dynagraph.org/mpl_graph/">mpl_graph</link> (delivered at the moment 3268 with MSM) from Gordon Woodhull, MSM provides several compile-time checks:<itemizedlist> 3269 <listitem> 3270 <para>Check that orthogonal regions ar truly orthogonal.</para> 3271 </listitem> 3272 <listitem> 3273 <para>Check that all states are either reachable from the initial 3274 states or are explicit entries / pseudo-entry states.</para> 3275 </listitem> 3276 </itemizedlist></para> 3277 <para>To make use of this feature, the back-end provides a policy (default is no 3278 analysis), <code>msm::back::mpl_graph_fsm_check</code>. For example:</para> 3279 <programlisting> typedef msm::back::state_machine< player_,msm::back::mpl_graph_fsm_check> player; </programlisting> 3280 <para>As MSM is now using Boost.Parameter to declare policies, the policy choice 3281 can be made at any position after the front-end type (in this case 3282 <code>player_</code>).</para> 3283 <para>In case an error is detected, a compile-time assertion is provoked.</para> 3284 <para>This feature is not enabled by default because it has a non-neglectable 3285 compile-time cost. The algorithm is linear if no explicit or pseudo entry 3286 states are found in the state machine, unfortunately still O(number of 3287 states * number of entry states) otherwise. This will be improved in future 3288 versions of MSM.</para> 3289 <para>The same algorithm is also used in case you want to omit providing the 3290 region index in the <command xlink:href="#explicit-entry-no-region-id">explicit entry / pseudo entry state</command> declaration.</para> 3291 <para>The author's advice is to enable the checks after any state machine 3292 structure change and disable it again after sucessful analysis.</para> 3293 <para>The <link xlink:href="examples/TestErrorOrthogonality.cpp">following example</link> provokes an assertion if one of the first two lines 3294 of the transition table is used.</para> 3295 </sect2> 3296 <sect2> 3297 <title><command xml:id="backend-enqueueing"/> Enqueueing events for later 3298 processing </title> 3299 <para>Calling <code>process_event(Event const&)</code> will immediately 3300 process the event with run-to-completion semantics. You can also enqueue the 3301 events and delay their processing by calling <code>enqueue_event(Event 3302 const&)</code> instead. Calling <code>execute_queued_events()</code> 3303 will then process all enqueued events (in FIFO order). Calling 3304 <code>execute_single_queued_event()</code> will execute the oldest 3305 enqueued event.</para> 3306 <para>You can query the queue size by calling <code>get_message_queue_size()</code>.</para> 3307 </sect2> 3308 <sect2> 3309 <title><command xml:id="backend-queues"/> Customizing the message queues </title> 3310 <para>MSM uses by default a std::deque for its queues (one message queue for 3311 events generated during run-to-completion or with 3312 <code>enqueue_event</code>, one for deferred events). Unfortunately, on some 3313 STL implementations, it is a very expensive container in size and copying 3314 time. Should this be a problem, MSM offers an alternative based on 3315 boost::circular_buffer. The policy is msm::back::queue_container_circular. 3316 To use it, you need to provide it to the back-end definition:</para> 3317 <programlisting> typedef msm::back::state_machine< player_,msm::back::queue_container_circular> player; </programlisting> 3318 <para>You can access the queues with get_message_queue and get_deferred_queue, 3319 both returning a reference or a const reference to the queues themselves. 3320 Boost::circular_buffer is outside of the scope of this documentation. What 3321 you will however need to define is the queue capacity (initially is 0) to 3322 what you think your queue will at most grow, for example (size 1 is 3323 common):</para> 3324 <programlisting> fsm.get_message_queue().set_capacity(1); </programlisting> 3325 </sect2> 3326 <sect2> 3327 <title><command xml:id="backend-boost-parameter"/>Policy definition with Boost.Parameter </title> 3328 <para>MSM uses Boost.Parameter to allow easier definition of 3329 back::state_machine<> policy arguments (all except the front-end). This 3330 allows you to define policy arguments (history, compile-time / run-time, 3331 state machine analysis, container for the queues) at any position, in any 3332 number. For example: </para> 3333 <programlisting> typedef msm::back::state_machine< player_,msm::back::mpl_graph_fsm_check> player; 3334 typedef msm::back::state_machine< player_,msm::back::AlwaysHistory> player; 3335 typedef msm::back::state_machine< player_,msm::back::mpl_graph_fsm_check,msm::back::AlwaysHistory> player; 3336 typedef msm::back::state_machine< player_,msm::back::AlwaysHistory,msm::back::mpl_graph_fsm_check> player; </programlisting> 3337 </sect2> 3338 <sect2> 3339 <title><command xml:id="backend-state-switch"/>Choosing when to switch active 3340 states </title> 3341 <para>The UML Standard is silent about a very important question: when a 3342 transition fires, at which exact point is the target state the new active 3343 state of a state machine? At the end of the transition? After the source 3344 state has been left? What if an exception is thrown? The Standard considers 3345 that run-to-completion means a transition completes in almost no time. But 3346 even this can be in some conditions a very very long time. Consider the 3347 following example. We have a state machine representing a network 3348 connection. We can be <code>Connected</code> and <code>Disconnected</code>. When we move from one 3349 state to another, we send a (Boost) Signal to another entity. By default, 3350 MSM makes the target state as the new state after the transition is 3351 completed. We want to send a signal based on a flag is_connected which is 3352 true when in state Connected.</para> 3353 <para>We are in state <code>Disconnected</code> and receive an event <code>connect</code>. The transition 3354 action will ask the state machine <code>is_flag_active<is_connected></code> and will 3355 get... false because we are still in <code>Disconnected</code>. Hmm, what to do? We could 3356 queue the action and execute it later, but it means an extra queue, more 3357 work and higher run-time.</para> 3358 <para>MSM provides the possibility (in form of a policy) for a front-end to 3359 decide when the target state becomes active. It can be:<itemizedlist> 3360 <listitem> 3361 <para>before the transition fires, if the guard will allow the 3362 transition to fire: 3363 <code>active_state_switch_before_transition</code></para> 3364 </listitem> 3365 <listitem> 3366 <para>after calling the exit action of the source state: 3367 <code>active_state_switch_after_exit</code></para> 3368 </listitem> 3369 <listitem> 3370 <para>after the transition action is executed: 3371 <code>active_state_switch_after_transition_action</code></para> 3372 </listitem> 3373 <listitem> 3374 <para>after the entry action of the target state is executed 3375 (default): <code>active_state_switch_after_entry</code></para> 3376 </listitem> 3377 </itemizedlist>The problem and the solution is shown for the 3378 <link xlink:href="examples/ActiveStateSetBeforeTransition.cpp">functor-front-end</link> 3379 and <link xlink:href="examples/ActivateStateBeforeTransitionEuml.cpp">eUML</link>. Removing <code>active_state_switch_before_transition</code> 3380 will show the default state. </para> 3381 </sect2> 3382 </sect1> 3383 </chapter> 3384 <chapter> 3385 <title> Performance / Compilers</title> 3386 <para>Tests were made on different PCs running Windows XP and Vista and compiled with 3387 VC9 SP1 or Ubuntu and compiled with g++ 4.2 and 4.3. For these tests, the same 3388 player state machine was written using Boost.Statechart, as a <link 3389 xlink:href="examples/SCSimple.cpp">state machine with only simple states</link> 3390 and as a <link xlink:href="examples/SCComposite.cpp">state machine with a composite 3391 state</link>. The same simple and composite state machines are implemented with 3392 MSM with a standard frontend <link xlink:href="examples/MsmSimple.cpp" 3393 >(simple)</link><link xlink:href="examples/MsmComposite.cpp">(composite)</link>, 3394 the simple one also with <link xlink:href="examples/MsmSimpleFunctors.cpp" 3395 >functors</link> and with <link xlink:href="examples/EumlSimple.cpp" 3396 >eUML</link>. As these simple machines need no terminate/interrupt states, no 3397 message queue and have no-throw guarantee on their actions, the MSM state machines 3398 are defined with minimum functionality. Test machine is a Q6600 2.4GHz, Vista 3399 64.</para> 3400 <sect1> 3401 <title>Speed</title> 3402 <para>VC9:<itemizedlist> 3403 <listitem> 3404 <para>The simple test completes 90 times faster with MSM than with 3405 Boost.Statechart</para> 3406 </listitem> 3407 <listitem> 3408 <para>The composite test completes 25 times faster with MSM</para> 3409 </listitem> 3410 </itemizedlist></para> 3411 <para>gcc 4.2.3 (Ubuntu 8.04 in VMWare, same PC):<itemizedlist> 3412 <listitem> 3413 <para>The simple test completes 46 times faster with MSM</para> 3414 </listitem> 3415 <listitem> 3416 <para>The composite test completes 19 times faster with Msm</para> 3417 </listitem> 3418 </itemizedlist></para> 3419 </sect1> 3420 <sect1> 3421 <title>Executable size</title> 3422 <para>There are some worries that MSM generates huge code. Is it true? The 2 3423 compilers I tested disagree with this claim. On VC9, the test state machines 3424 used in the performance section produce executables of 14kB (for simple and 3425 eUML) and 21kB (for the composite). This includes the test code and iostreams. 3426 By comparison, an empty executable with iostreams generated by VC9 has a size of 3427 7kB. Boost.Statechart generates executables of 43kB and 54kB. As a bonus, eUML 3428 comes for “free” in terms of executable size. You even get a speed gain. With 3429 g++ 4.3, it strongly depends on the compiler options (much more than VC). A good 3430 size state machine with –O3 can generate an executable of 600kB, and with eUML 3431 you can get to 1.5MB. Trying with –Os –s I come down to 18kB and 30kB for the 3432 test state machines, while eUML will go down to 1MB (which is still big), so in 3433 this case eUML does not come for free.</para> 3434 </sect1> 3435 <sect1> 3436 <title>Supported compilers</title> 3437 <para>For a current status, have a look at the <link 3438 xlink:href="http://www.boost.org/development/tests/trunk/developer/msm.html" 3439 >regression tests</link>.</para> 3440 <para>MSM was successfully tested with: <itemizedlist> 3441 <listitem> 3442 <para>VC8 (partly), VC9, VC10</para> 3443 </listitem> 3444 <listitem> 3445 <para>g++ 4.0.1 and higher</para> 3446 </listitem> 3447 <listitem> 3448 <para>Intel 10.1 and higher</para> 3449 </listitem> 3450 <listitem> 3451 <para>Clang 2.9</para> 3452 </listitem> 3453 <listitem> 3454 <para>Green Hills Software MULTI for ARM v5.0.5 patch 4416 (Simple and 3455 Composite tutorials)</para> 3456 </listitem> 3457 <listitem> 3458 <para>Partial support for IBM compiler</para> 3459 </listitem> 3460 </itemizedlist></para> 3461 <para>VC8 and to some lesser extent VC9 suffer from a bug. Enabling the option 3462 "Enable Minimal Rebuild" (/Gm) will cause much higher compile-time (up to three 3463 times with VC8!). This option being activated per default in Debug mode, this 3464 can be a big problem.</para> 3465 </sect1> 3466 <sect1> 3467 <title> Limitations </title> 3468 <para> 3469 <itemizedlist> 3470 <listitem> 3471 <para>Compilation times of state machines with > 80 transitions that are 3472 going to make you storm the CFO's office and make sure you get a 3473 shiny octocore with 12GB RAM by next week, unless he's interested in 3474 paying you watch the compiler agonize for hours... (Make sure you 3475 ask for dual 24" as well, it doesn't hurt).</para> 3476 </listitem> 3477 <listitem> 3478 <para>eUML allows very long constructs but will also quickly increase 3479 your compile time on some compilers (VC9, VC10) with buggy decltype 3480 support (I suspect some at least quadratic algorithms there). Even 3481 g++ 4.4 shows some regression compared to 4.3 and will crash if the 3482 constructs become too big.</para> 3483 </listitem> 3484 <listitem> 3485 <para>Need to overwrite the mpl::vector/list default-size-limit of 20 3486 and fusion default vector size of 10 if more than 10 states found in 3487 a state machine</para> 3488 </listitem> 3489 <listitem> 3490 <para><command xlink:href="#limitation-submachine">Limitation for 3491 submachines</command> and entry actions requiring an event 3492 property.</para> 3493 </listitem> 3494 </itemizedlist> 3495 </para> 3496 </sect1> 3497 <sect1> 3498 <title> Compilers corner </title> 3499 <para>Compilers are sometimes full of surprises and such strange errors happened in 3500 the course of the development that I wanted to list the most fun for readers’ 3501 entertainment.</para> 3502 <para><emphasis role="underline">VC8</emphasis>: </para> 3503 <programlisting>template <class StateType> 3504typename ::boost::enable_if< 3505 typename ::boost::mpl::and_< 3506 typename ::boost::mpl::not_< 3507 typename has_exit_pseudo_states<StateType>::type 3508 >::type, 3509 typename ::boost::mpl::not_< 3510 typename is_pseudo_exit<StateType>::type 3511 >::type 3512 >::type, 3513 BaseState*>::type </programlisting> 3514 <para>I get the following error:</para> 3515 <para>error C2770: invalid explicit template argument(s) for '`global 3516 namespace'::boost::enable_if<...>::...' </para> 3517 <para>If I now remove the first “::” in ::boost::mpl , the compiler shuts up. So in 3518 this case, it is not possible to follow Boost’s guidelines.</para> 3519 <para><emphasis role="underline">VC9</emphasis>:<itemizedlist> 3520 <listitem> 3521 <para>This one is my all times’ favorite. Do you know why the exit 3522 pseudo states are referenced in the transition table with a 3523 “submachine::exit_pt” ? Because “exit” will crash the compiler. 3524 “Exit” is not possible either because it will crash the compiler on 3525 one machine, but not on another (the compiler was installed from the 3526 same disk).</para> 3527 </listitem> 3528 <listitem> 3529 <para>Sometimes, removing a policy crashes the compiler, so some 3530 versions are defining a dummy policy called WorkaroundVC9.</para> 3531 </listitem> 3532 <listitem> 3533 <para>Typeof: While g++ and VC9 compile “standard” state machines in 3534 comparable times, Typeof (while in both ways natively supported) 3535 seems to behave in a quadratic complexity with VC9 and VC10.</para> 3536 </listitem> 3537 <listitem> 3538 <para>eUML: in case of a compiler crash, changing the order of state 3539 definitions (first states without entry or exit) sometimes solves 3540 the problem.</para> 3541 </listitem> 3542 </itemizedlist></para> 3543 <para><emphasis role="underline">g++ 4.x</emphasis>: Boring compiler, almost all is 3544 working almost as expected. Being not a language lawyer I am unsure about the 3545 following “Typeof problem”. VC9 and g++ disagree on the question if you can 3546 derive from the BOOST_TYPEOF generated type without first defining a typedef. I 3547 will be thankful for an answer on this. I only found two ways to break the compiler:<itemizedlist> 3548 <listitem> 3549 <para>Add more eUML constructs until something explodes (especially with 3550 g++-4.4) </para> 3551 </listitem> 3552 <listitem> 3553 <para>The build_terminate function uses 2 mpl::push_back instead of 3554 mpl::insert_range because g++ would not accept insert_range.</para> 3555 </listitem> 3556 </itemizedlist></para> 3557 <para>You can test your compiler’s decltype implementation with the <link 3558 xlink:href="examples/CompilerStressTestEuml.cpp">following stress 3559 test</link> and reactivate the commented-out code until the compiler 3560 crashes.</para> 3561 </sect1> 3562 </chapter> 3563 <chapter> 3564 <title>Questions & Answers, tips</title> 3565 <para><emphasis role="underline">Where should I define a state machine?</emphasis>: The 3566 tutorials are implemented in a simple cpp source file for simplicity. I want to 3567 model dynamic behavior of a class as a state machine, how should I define the state 3568 machine?</para> 3569 <para><emphasis role="underline">Answer</emphasis>: Usually you'll want to implement the 3570 state machine as an attribute of the class. Unfortunately, a concrete state machine 3571 is a typedef, which cannot be forward-declared. This leaves you with two 3572 possibilities: <itemizedlist> 3573 <listitem> 3574 <para>Provide the state machine definition inside the header class and 3575 contain an instance as attribute. Simple, but with several drawbacks: 3576 using namespace directives are not advised, and compile-time cost for 3577 all modules including the header.</para> 3578 </listitem> 3579 <listitem> 3580 <para>Keep the state machine as (shared) pointer to void inside the <link 3581 xlink:href="examples/FsmAsPtr.hpp">class definition</link>, and 3582 implement the state machine in the <link 3583 xlink:href="examples/FsmAsPtr.cpp">cpp file</link>. Minimum 3584 compile-time, using directives are okay, but the state machine is now 3585 located inside the heap.</para> 3586 </listitem> 3587 </itemizedlist></para> 3588 <para><emphasis role="underline">Question</emphasis>: on_entry gets as argument, the 3589 sent event. What event do I get when the state becomes default-activated (because it 3590 is an initial state)?</para> 3591 <para> 3592 <emphasis role="underline">Answer</emphasis>: To allow you to know that the state 3593 was default-activated, MSM generates a boost::msm::InitEvent default event. </para> 3594 <para><emphasis role="underline">Question</emphasis>: Why do I see no call to 3595 no_transition in my submachine? </para> 3596 <para><emphasis role="underline">Answer</emphasis>: Because of the priority rule defined 3597 by UML. It says that in case of transition conflict, the most inner state has a 3598 higher priority. So after asking the inner state, the containing composite has to be 3599 also asked to handle the transition and could find a possible transition.</para> 3600 <para><emphasis role="underline">Question</emphasis>: Why do I get a compile error 3601 saying the compiler cannot convert to a function ...Fsm::*(some_event)? </para> 3602 <para><emphasis role="underline">Answer</emphasis>: You probably defined a transition 3603 triggered by the event some_event, but used a guard/action method taking another 3604 event. </para> 3605 <para><emphasis role="underline">Question</emphasis>: Why do I get a compile error 3606 saying something like “too few” or “too many” template arguments? </para> 3607 <para><emphasis role="underline">Answer</emphasis>: You probably defined a transition in 3608 form of a a_row or g_row where you wanted just a _row or the other way around. With 3609 Row, it could mean that you forgot a "none". </para> 3610 <para><emphasis role="underline">Question</emphasis>: Why do I get a very long compile 3611 error when I define more than 20 rows in the transition table? </para> 3612 <para><emphasis role="underline">Answer</emphasis>: MSM uses Boost.MPL under the hood 3613 and this is the default maximum size. Please define the following 3 macros before 3614 including any MSM headers: </para> 3615 <programlisting>#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS 3616#define BOOST_MPL_LIMIT_VECTOR_SIZE 30 // or whatever you need 3617#define BOOST_MPL_LIMIT_MAP_SIZE 30 // or whatever you need </programlisting> 3618 <para><emphasis role="underline">Question</emphasis>: Why do I get this error: ”error 3619 C2977: 'boost::mpl::vector' : too many template arguments”? </para> 3620 <para><emphasis role="underline">Answer</emphasis>: The first possibility is that you 3621 defined a transition table as, say, vector17 and have 18 entries. The second is that 3622 you have 17 entries and have a composite state. Under the hood, MSM adds a row for 3623 every event in the composite transition table. The third one is that you used a 3624 mpl::vector without the number of entries but are close to the MPL default of 50 and 3625 have a composite, thus pushing you above 50. Then you need mpl/vector60/70….hpp and 3626 a mpl/map60/70….hpp </para> 3627 <para><emphasis role="underline">Question</emphasis>: Why do I get a very long compile 3628 error when I define more than 10 states in a state machine? </para> 3629 <para><emphasis role="underline">Answer</emphasis>: MSM uses Boost.Fusion under the hood 3630 and this is the default maximum size. Please define the following macro before 3631 including any MSM headers: </para> 3632 <programlisting>#define FUSION_MAX_VECTOR_SIZE 20 // or whatever you need </programlisting> 3633 </chapter> 3634 <chapter> 3635 <title>Internals</title> 3636 <para>This chapter describes the internal machinery of the back-end, which can be useful 3637 for UML experts but can be safely ignored for most users. For implementers, the 3638 interface between front- and back- end is also described in detail.</para> 3639 <sect1> 3640 <title><command xml:id="run-to-completion"/>Backend: Run To Completion</title> 3641 <para>The back-end implements the following run-to completion algorithm:<itemizedlist> 3642 <listitem> 3643 <para>Check if one region of the concrete state machine is in a 3644 terminate or interrupt state. If yes, event processing is disabled 3645 while the condition lasts (forever for a terminate pseudo-state, 3646 while active for an interrupt pseudo-state).</para> 3647 </listitem> 3648 <listitem> 3649 <para>If the message queue feature is enabled and if the state machine 3650 is already processing an event, push the currently processed event 3651 into the queue and end processing. Otherwise, remember that the 3652 state machine is now processing an event and continue.</para> 3653 </listitem> 3654 <listitem> 3655 <para>If the state machine detected that no deferred event is used, skip 3656 this step. Otherwise, mark the first deferred event from the 3657 deferred queue as active.</para> 3658 </listitem> 3659 <listitem> 3660 <para>Now start the core of event dispatching. If exception handling is 3661 activated, this will happen inside a try/catch block and the 3662 front-end <code>exception_caught</code> is called if an exception 3663 occurs. </para> 3664 </listitem> 3665 <listitem> 3666 <para>The event is now dispatched in turn to every region, in the order 3667 defined by the initial state front-end definition. This will, for 3668 every region, call the corresponding front-end transition definition 3669 (the "row" or "Row" of the transition table).</para> 3670 </listitem> 3671 <listitem> 3672 <para>Without transition conflict, if for a given region a transition is 3673 possible, the guard condition is checked. If it returns 3674 <code>true</code>, the transition processing continues and the 3675 current state's exit action is called, followed by the transition 3676 action behavior and the new active state's entry behavior.</para> 3677 </listitem> 3678 <listitem> 3679 <para>With transition conflicts (several possible transitions, 3680 disambiguated by mutually exclusive guard conditions), the guard 3681 conditions are tried in reverse order of their transition definition 3682 in the transition table. The first one returning <code>true</code> 3683 selects its transition. Note that this is not defined by the UML 3684 standard, which simply specifies that if the guard conditions are 3685 not mutually exclusive, the state machine is ill-formed and the 3686 behaviour undefined. Relying on this implementation-specific 3687 behaviour will make it harder for the developer to support another 3688 state machine framework.</para> 3689 </listitem> 3690 <listitem> 3691 <para>If at least one region processes the event, this event is seen as 3692 having been accepted. If not, the library calls 3693 <code>no_transition</code> on the state machine for every 3694 contained region.</para> 3695 </listitem> 3696 <listitem> 3697 <para>If the currently active state is a submachine, the behaviour is 3698 slightly different. The UML standard specifies that internal 3699 transitions have to be tried first, so the event is first dispatched 3700 to the submachine. Only if the submachine does not accept the event 3701 are other (non internal) transitions tried.</para> 3702 </listitem> 3703 <listitem> 3704 <para>This back-end supports simple states' and submachines' internal 3705 transitions. These are provided in the state's 3706 <code>internal_transition_table</code> type. Transitions defined 3707 in this table are added at the end of the main state machine's 3708 transition table, but with a lesser priority than the submachine's 3709 transitions (defined in <code>transition_table</code>). This means, 3710 for simple states, that these transitions have higher priority than 3711 non-internal transitions, conform to the UML standard which gives 3712 higher priority to deeper-level transitions. For submachines, this 3713 is a non-standard addition which can help make event processing 3714 faster by giving a chance to bypass subregion processing. With 3715 standard UML, one would need to add a subregion only to process 3716 these internal transitions, which would be slower.</para> 3717 </listitem> 3718 <listitem> 3719 <para>After the dispatching itself, the deferred event marked in step 3 3720 (if any) now gets a chance of processing.</para> 3721 </listitem> 3722 <listitem> 3723 <para>Then, events queued in the message queue also get a dispatching 3724 chance</para> 3725 </listitem> 3726 <listitem> 3727 <para>Finally, completion / anonymous transitions, if to be found in the 3728 transition table, also get their dispatching chance.</para> 3729 </listitem> 3730 </itemizedlist></para> 3731 <para>This algorithm illustrates how the back-end configures itself at compile-time 3732 as much as possible. Every feature not found in a given state machine definition 3733 is deactivated and has therefore no runtime cost. Completion events, deferred 3734 events, terminate states, dispatching to several regions, internal transitions 3735 are all deactivated if not used. User configuration is only for exception 3736 handling and message queue necessary.</para> 3737 </sect1> 3738 <sect1> 3739 <title><command xml:id="internals-front-back-interface"/>Frontend / Backend 3740 interface</title> 3741 <para>The design of MSM tries to make front-ends and back-ends (later) to be as 3742 interchangeable as possible. Of course, no back-end will ever implement every 3743 feature defined by any possible front-end and inversely, but the goal is to make 3744 it as easy as possible to extend the current state of the library.</para> 3745 <para>To achieve this, MSM divides the functionality between both sides: the 3746 front-end is a sort of user interface and is descriptive, the back-end 3747 implements the state machine engine.</para> 3748 <para>MSM being based on a transition table, a concrete state machine (or a given 3749 front-end) must provide a transition_table. This transition table must be made 3750 of rows. And each row must tell what kind of transition it is and implement the 3751 calls to the actions and guards. A state machine must also define its regions 3752 (marked by initial states) And that is about the only constraints for 3753 front-ends. How the rows are described is implementer's choice. </para> 3754 <para>Every row must provide:</para> 3755 <itemizedlist> 3756 <listitem> 3757 <para>A <code>Source</code> typedef indicating, well, the type of the source 3758 state.</para> 3759 </listitem> 3760 <listitem> 3761 <para>A <code>Target</code> typedef indicating, well, the type of the target 3762 state.</para> 3763 </listitem> 3764 <listitem> 3765 <para>A <code>Evt</code> typedef indicating the type of the event triggering 3766 the transition.</para> 3767 </listitem> 3768 <listitem> 3769 <para>A <code>row_type_tag</code> typedef indicating the type of the 3770 transition.</para> 3771 </listitem> 3772 <listitem> 3773 <para>Rows having a type requiring transition actions must provide a static 3774 function <code>action_call</code> with the following signature: <code> 3775 template <class Fsm,class SourceState,class TargetState,class 3776 AllStates> </code></para> 3777 <para><code>static void action_call (Fsm& fsm, Event const& evt, 3778 SourceState&, TargetState&, AllStates&) </code></para> 3779 <para>The function gets as parameters the (back-end) state machine, the 3780 event, source and target states and a container (in the current 3781 back-end, a fusion::set) of all the states defined in the state machine. 3782 For example, as the back-end has the front-end as basic class, 3783 <code>action_call</code> is simply defined as 3784 <code>(fsm.*action)(evt)</code>.</para> 3785 </listitem> 3786 <listitem> 3787 <para>Rows having a type requiring a guard must provide a static function 3788 <code>guard_call</code> with the following signature:<code 3789 > </code></para> 3790 <para><code>template <class Fsm,class SourceState,class TargetState,class 3791 AllStates></code></para> 3792 <para><code>static bool guard_call (Fsm&, Event const&, 3793 SourceState&, TargetState&, AllStates&)</code></para> 3794 </listitem> 3795 <listitem> 3796 <para>The possible transition (row) types are:<itemizedlist> 3797 <listitem> 3798 <para>a_row_tag: a transition with actions and no guard</para> 3799 </listitem> 3800 <listitem> 3801 <para>g_row_type: a transition with a guard and no 3802 actions</para> 3803 </listitem> 3804 <listitem> 3805 <para>_row_tag: a transition without actions or guard</para> 3806 </listitem> 3807 <listitem> 3808 <para>row_tag: a transition with guard and actions</para> 3809 </listitem> 3810 <listitem> 3811 <para>a_irow_tag: an internal transition (defined inside the 3812 <code>transition_table</code>) with actions</para> 3813 </listitem> 3814 <listitem> 3815 <para>g_irow_tag: an internal transition (defined inside the 3816 <code>transition_table</code>) with guard</para> 3817 </listitem> 3818 <listitem> 3819 <para>irow_tag: an internal transition (defined inside the 3820 <code>transition_table</code>) with actions and 3821 guards</para> 3822 </listitem> 3823 <listitem> 3824 <para>_irow_tag: an internal transition (defined inside the 3825 <code>transition_table</code>) without action or guard. 3826 Due to higher priority for internal transitions, this is 3827 equivalent to a "ignore event"</para> 3828 </listitem> 3829 <listitem> 3830 <para>sm_a_i_row_tag: an internal transition (defined inside the 3831 <code>internal_transition_table</code>) with 3832 actions</para> 3833 </listitem> 3834 <listitem> 3835 <para>sm_g_i_row_tag: an internal transition (defined inside the 3836 <code>internal_transition_table</code>) with 3837 guard</para> 3838 </listitem> 3839 <listitem> 3840 <para>sm_i_row_tag: an internal transition (defined inside the 3841 <code>internal_transition_table</code>) with actions and 3842 guards</para> 3843 </listitem> 3844 <listitem> 3845 <para>sm__i_row_tag: an internal transition (defined inside the 3846 <code>internal_transition_table</code>) without action 3847 or guard. Due to higher priority for internal transitions, 3848 this is quivalent to a "ignore event"</para> 3849 </listitem> 3850 </itemizedlist></para> 3851 </listitem> 3852 </itemizedlist> 3853 <para>Furthermore, a front-end must provide the definition of states and state 3854 machines. State machine definitions must provide (the implementer is free to 3855 provide it or let it be done by every concrete state machine. Different MSM 3856 front-ends took one or the other approach):<itemizedlist> 3857 <listitem> 3858 <para><code>initial_state</code>: This typedef can be a single state or 3859 a mpl container and provides the initial states defining one or 3860 several orthogonal regions.</para> 3861 </listitem> 3862 <listitem> 3863 <para><code>transition_table</code>: This typedef is a MPL sequence of 3864 transition rows.</para> 3865 </listitem> 3866 <listitem> 3867 <para><code>configuration</code>: this typedef is a MPL sequence of 3868 known types triggering special behavior in the back-end, for example 3869 if a concrete fsm requires a message queue or exception 3870 catching.</para> 3871 </listitem> 3872 </itemizedlist></para> 3873 <para>States and state machines must both provide a (possibly empty) definition of:<itemizedlist> 3874 <listitem> 3875 <para><code>flag_list</code>: the flags being active when this state or 3876 state machine become the current state of the fsm.</para> 3877 </listitem> 3878 <listitem> 3879 <para><code>deferred_events</code>: events being automatically deferred 3880 when the state is the current state of the fsm.</para> 3881 </listitem> 3882 <listitem> 3883 <para><code>internal_transition_table</code>: the internal transitions 3884 of this state.</para> 3885 </listitem> 3886 <listitem> 3887 <para><code>on_entry</code> and <code>on_exit</code> methods.</para> 3888 </listitem> 3889 </itemizedlist></para> 3890 </sect1> 3891 <sect1> 3892 <title><command xml:id="internals-state-id"/> Generated state ids </title> 3893 <para>Normally, one does not need to know the ids are generated for all the states 3894 of a state machine, unless for debugging purposes, like the pstate function does 3895 in the tutorials in order to display the name of the current state. This section 3896 will show how to automatically display typeid-generated names, but these are not 3897 very readable on all platforms, so it can help to know how the ids are 3898 generated. The ids are generated using the transition table, from the “Start” 3899 column up to down, then from the “Next” column, up to down, as shown in the next 3900 image: </para> 3901 <para><inlinemediaobject> 3902 <imageobject> 3903 <imagedata fileref="images/AnnexA.jpg" width="90%" scalefit="1"/> 3904 </imageobject> 3905 </inlinemediaobject></para> 3906 <para>Stopped will get id 0, Open id 1, ErrorMode id 6 and SleepMode (seen only in 3907 the “Next” column) id 7. If you have some implicitly created states, like 3908 transition-less initial states or states created using the explicit_creation 3909 typedef, these will be added as a source at the end of the transition table. If 3910 you have submachine states, a row will be added for them at the end of the 3911 table, after the automatically or explicitly created states, which can change 3912 their id. The next help you will need for debugging would be to call the 3913 current_state method of the state_machine class, then the display_type helper to 3914 generate a readable name from the id. If you do not want to go through the 3915 transition table to fill an array of names, the library provides another helper, 3916 fill_state_names, which, given an array of sufficient size (please see next 3917 section to know how many states are defined in the state machine), will fill it 3918 with typeid-generated names. </para> 3919 </sect1> 3920 <sect1> 3921 <title>Metaprogramming tools</title> 3922 <para>We can find for the transition table more uses than what we have seen so far. 3923 Let's suppose you need to write a coverage tool. A state machine would be 3924 perfect for such a job, if only it could provide some information about its 3925 structure. Thanks to the transition table and Boost.MPL, it does.</para> 3926 <para>What is needed for a coverage tool? You need to know how many states are 3927 defined in the state machine, and how many events can be fired. This way you can 3928 log the fired events and the states visited in the life of a concrete machine 3929 and be able to perform some coverage analysis, like “fired 65% of all possible 3930 events and visited 80% of the states defined in the state machine”. To achieve 3931 this, MSM provides a few useful tools:<itemizedlist> 3932 <listitem> 3933 <para>generate_state_set<transition table>: returns a mpl::set of all 3934 the states defined in the table.</para> 3935 </listitem> 3936 <listitem> 3937 <para>generate_event_set<transition table>: returns a mpl::set of all 3938 the events defined in the table.</para> 3939 </listitem> 3940 <listitem> 3941 <para>using mpl::size<>::value you can get the number of elements in 3942 the set.</para> 3943 </listitem> 3944 <listitem> 3945 <para>display_type defines an operator() sending typeid(Type).name() to 3946 cout.</para> 3947 </listitem> 3948 <listitem> 3949 <para>fill_state_names fills an array of char const* with names of all 3950 states (found by typeid)</para> 3951 </listitem> 3952 <listitem> 3953 <para>using mpl::for_each on the result of generate_state_set and 3954 generate_event_set passing display_type as argument will display all 3955 the states of the state machine.</para> 3956 </listitem> 3957 <listitem> 3958 <para>let's suppose you need to recursively find the states and events 3959 defined in the composite states and thus also having a transition 3960 table. Calling recursive_get_transition_table<Composite> will 3961 return you the transition table of the composite state, recursively 3962 adding the transition tables of all sub-state machines and 3963 sub-sub...-sub-state machines. Then call generate_state_set or 3964 generate_event_set on the result to get the full list of states and 3965 events. </para> 3966 </listitem> 3967 </itemizedlist></para> 3968 <para> An <link xlink:href="examples/BoostCon09Full.cpp">example</link> shows the 3969 tools in action. </para> 3970 </sect1> 3971 </chapter> 3972 <chapter> 3973 <title>Acknowledgements</title> 3974 <para>I am in debt to the following people who helped MSM along the way.</para> 3975 <sect1> 3976 <title>MSM v2</title> 3977 <para> 3978 <itemizedlist> 3979 <listitem> 3980 <para>Thanks to Dave Abrahams for managing the review</para> 3981 </listitem> 3982 <listitem> 3983 <para>Thanks to Eric Niebler for his patience correcting my grammar 3984 errors</para> 3985 </listitem> 3986 <listitem> 3987 <para>Special thanks to Joel de Guzman who gave me very good ideas at 3988 the BoostCon09. These ideas were the starting point of the redesign. 3989 Any time again, Joel ☺</para> 3990 </listitem> 3991 <listitem> 3992 <para>Thanks to Richard O’Hara for making Green Hills bring a patch in 3993 less than 1 week, thus adding one more compiler to the supported 3994 list.</para> 3995 </listitem> 3996 <listitem> 3997 <para>Big thanks to those who took the time to write a review: Franz 3998 Alt, David Bergman, Michael Caisse, Barend Gehrels, Darryl Greene, 3999 Juraj Ivancic, Erik Nelson, Kenny Riddile.</para> 4000 </listitem> 4001 <listitem> 4002 <para>Thanks to Matt Calabrese, Juraj Ivancic, Adam Merz and Joseph Wu 4003 for reporting bugs.</para> 4004 </listitem> 4005 <listitem> 4006 <para>Thanks to Thomas Mistretta for providing an addition to the 4007 section "What do you actually do inside actions / guards".</para> 4008 </listitem> 4009 </itemizedlist> 4010 </para> 4011 </sect1> 4012 <sect1> 4013 <title> MSM v1</title> 4014 <para> 4015 <itemizedlist> 4016 <listitem> 4017 <para>The original version of this framework is based on the brilliant 4018 work of David Abrahams and Aleksey Gurtovoy who laid down the base 4019 and the principles of the framework in their excellent book, “C++ 4020 template Metaprogramming”. The implementation also makes heavy use 4021 of the boost::mpl.</para> 4022 </listitem> 4023 <listitem> 4024 <para>Thanks to Jeff Flinn for his idea of the user-defined base state 4025 and his review which allowed MSM to be presented at the 4026 BoostCon09.</para> 4027 </listitem> 4028 <listitem> 4029 <para>Thanks to my MSM v1 beta testers, Christoph Woskowski and Franz 4030 Alt for using the framework with little documentation and to my 4031 private reviewer, Edouard Alligand</para> 4032 </listitem> 4033 </itemizedlist> 4034 </para> 4035 </sect1> 4036 </chapter> 4037 <chapter> 4038 <title>Version history</title> 4039 <sect1> 4040 <title>From V2.28 to V2.29 (Boost 1.72)</title> 4041 <para> 4042 <itemizedlist> 4043 <listitem> 4044 <para>Merged from develop new implementation of deferred events</para> 4045 </listitem> 4046 <listitem> 4047 <para>Div. bugfixes</para> 4048 </listitem> 4049 </itemizedlist> 4050 </para> 4051 </sect1> 4052 <sect1> 4053 <title>From V2.27 to V2.28 (Boost 1.57)</title> 4054 <para> 4055 <itemizedlist> 4056 <listitem> 4057 <para>Fixed BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES (broken in 4058 1.56).</para> 4059 </listitem> 4060 <listitem> 4061 <para>Fixed execute_queued_events, added 4062 execute_single_queued_event</para> 4063 </listitem> 4064 <listitem> 4065 <para>Fixed warnings for unused variables</para> 4066 </listitem> 4067 </itemizedlist> 4068 </para> 4069 </sect1> 4070 <sect1> 4071 <title>From V2.26 to V2.27 (Boost 1.56)</title> 4072 <para> 4073 <itemizedlist> 4074 <listitem> 4075 <para>Bugfix: no_transition in case of an exception.</para> 4076 </listitem> 4077 <listitem> 4078 <para>Bugfix: Trac 9280</para> 4079 </listitem> 4080 <listitem> 4081 <para>Bugfix: incomplete namespace names in eUML</para> 4082 </listitem> 4083 </itemizedlist> 4084 </para> 4085 </sect1> 4086 <sect1> 4087 <title>From V2.25 to V2.26 (Boost 1.55)</title> 4088 <para> 4089 <itemizedlist> 4090 <listitem> 4091 <para>New feature: interrupt states now support a sequence of events to 4092 end the interruption</para> 4093 </listitem> 4094 <listitem> 4095 <para>Bugfix: Trac 8686.</para> 4096 </listitem> 4097 </itemizedlist> 4098 </para> 4099 </sect1> 4100 <sect1> 4101 <title>From V2.24 to V2.25 (Boost 1.54)</title> 4102 <para> 4103 <itemizedlist> 4104 <listitem> 4105 <para>Bugfix: Exit points broken for the favor_compile_time 4106 policy.</para> 4107 </listitem> 4108 <listitem> 4109 <para>Bugfix: copy breaks exit points of subsubmachines.</para> 4110 </listitem> 4111 <listitem> 4112 <para>Bugfix: Trac 8046.</para> 4113 </listitem> 4114 </itemizedlist> 4115 </para> 4116 </sect1> 4117 <sect1> 4118 <title>From V2.23 to V2.24 (Boost 1.51)</title> 4119 <para> 4120 <itemizedlist> 4121 <listitem> 4122 <para> Support for <command xlink:href="#any-event">boost::any</command> 4123 or <command xlink:href="#kleene-event">kleene</command> as an 4124 acceptable event.</para> 4125 </listitem> 4126 <listitem> 4127 <para>Bugfix: compiler error with fsm internal table and 4128 <code>none</code>(compound) event.</para> 4129 </listitem> 4130 <listitem> 4131 <para>Bugfix: <code>euml::defer_</code> leading to stack overflow.</para> 4132 </listitem> 4133 </itemizedlist> 4134 </para> 4135 </sect1> 4136 <sect1> 4137 <title>From V2.22 to V2.23 (Boost 1.50)</title> 4138 <para> 4139 <itemizedlist> 4140 <listitem> 4141 <para> <command xlink:href="#eUML-composite-table">eUML</command> : better syntax 4142 for front-ends defined with eUML as transititon table only. Caution: 4143 Breaking Change!</para> 4144 </listitem> 4145 <listitem> 4146 <para>Bugfix: graph building was only working if 4147 <code>initial_state</code> defined as a sequence</para> 4148 </listitem> 4149 <listitem> 4150 <para>Bugfix: flags defined for a Terminate or Interrupt state do not 4151 break the blocking function of these states any more.</para> 4152 </listitem> 4153 <listitem> 4154 <para>Bugfix: multiple deferred events from several regions were not 4155 working in every case.</para> 4156 </listitem> 4157 <listitem> 4158 <para>Bugfix: visitor was passed by value to submachines.</para> 4159 </listitem> 4160 <listitem> 4161 <para>Bugfix: <code>no_transition</code> was not called for submachines who send an 4162 event to themselves.</para> 4163 </listitem> 4164 <listitem> 4165 <para>Fixed warnings with gcc</para> 4166 </listitem> 4167 </itemizedlist> 4168 </para> 4169 </sect1> 4170 <sect1> 4171 <title>From V2.21 to V2.22 (Boost 1.48)</title> 4172 <para> 4173 <itemizedlist> 4174 <listitem> 4175 <para>eUML: added easier event reprocessing: 4176 <code>process(event_)</code> and <code>reprocess()</code></para> 4177 </listitem> 4178 <listitem> 4179 <para>Rewrite of internal transition tables. There were a few bugs 4180 (failing recursivity in internal transition tables of sub-sub 4181 machines) and a missing feature (unused internal transition table of 4182 the main state machine).</para> 4183 </listitem> 4184 <listitem> 4185 <para>Bugfixes<itemizedlist> 4186 <listitem> 4187 <para>Reverted favor_compile_time policy to Boost 1.46 4188 state</para> 4189 </listitem> 4190 <listitem> 4191 <para><code>none</code> event now is convertible from any 4192 other event </para> 4193 </listitem> 4194 <listitem> 4195 <para>eUML and pseudo exit states</para> 4196 </listitem> 4197 <listitem> 4198 <para>Fixed not working Flag_AND</para> 4199 </listitem> 4200 <listitem> 4201 <para>Fixed rare bugs causing multiple processing of the 4202 same event in a submachine whose transition table 4203 contains this event and a base event of it.</para> 4204 </listitem> 4205 <listitem> 4206 <para>gcc warnings about unused variables</para> 4207 </listitem> 4208 </itemizedlist></para> 4209 </listitem> 4210 <listitem> 4211 <para>Breaking change: the new internal transition table feature causes 4212 a minor breaking change. In a submachine, the "Fsm" template 4213 parameter for guards / actions of an internal table declared using 4214 <code>internal_transition_table</code> now is the submachine, 4215 not the higher-level state machine. Internal transitions declared 4216 using internal rows in the higher-level state machine keep their 4217 behavior (the "Fsm" parameter is the higher-level state machine). To 4218 sum up, the internal transition "Fsm" parameter is the closest state 4219 machine containing this transition.</para> 4220 </listitem> 4221 </itemizedlist> 4222 </para> 4223 </sect1> 4224 <sect1> 4225 <title>From V2.20 to V2.21 (Boost 1.47)</title> 4226 <para> 4227 <itemizedlist> 4228 <listitem> 4229 <para>Added a <command xlink:href="#backend-start">stop()</command> 4230 method in the back-end.</para> 4231 </listitem> 4232 <listitem> 4233 <para><command xlink:href="#eUML-phoenix">Added partial support for 4234 Boost.Phoenix functors in eUML</command></para> 4235 </listitem> 4236 <listitem> 4237 <para>Added the possibility to choose when <command xlink:href="#backend-state-switch">state switching</command> 4238 occurs.</para> 4239 </listitem> 4240 <listitem> 4241 <para>Bugfixes<itemizedlist> 4242 <listitem> 4243 <para>Trac 5117, 5253, 5533, 5573</para> 4244 </listitem> 4245 <listitem> 4246 <para>gcc warnings about unused variables</para> 4247 </listitem> 4248 <listitem> 4249 <para>better implemenation of favor_compile_time back-end 4250 policy</para> 4251 </listitem> 4252 <listitem> 4253 <para>bug with eUML and state construction</para> 4254 </listitem> 4255 <listitem> 4256 <para>incorrect eUML event and state macros</para> 4257 </listitem> 4258 <listitem> 4259 <para>incorrect event type passed to a direct entry state's 4260 on_entry action</para> 4261 </listitem> 4262 <listitem> 4263 <para>more examples</para> 4264 </listitem> 4265 </itemizedlist></para> 4266 </listitem> 4267 </itemizedlist> 4268 </para> 4269 </sect1> 4270 <sect1> 4271 <title>From V2.12 to V2.20 (Boost 1.46)</title> 4272 <para> 4273 <itemizedlist> 4274 <listitem> 4275 <para>Compile-time state machine analysis using mpl_graph:</para> 4276 <itemizedlist> 4277 <listitem> 4278 <para><command xlink:href="#backend-compile-time-analysis">checking of region orthogonality</command>.</para> 4279 </listitem> 4280 <listitem> 4281 <para><command xlink:href="#backend-compile-time-analysis">search for unreachable states</command>.</para> 4282 </listitem> 4283 <listitem> 4284 <para><command xlink:href="#explicit-entry-no-region-id">automatic region index search for pseudo entry or explicit 4285 entry states</command>.</para> 4286 </listitem> 4287 </itemizedlist> 4288 </listitem> 4289 <listitem> 4290 <para><command xlink:href="#backend-boost-parameter">Boost.Parameter interface definition</command> for 4291 msm::back::state_machine<> template arguments.</para> 4292 </listitem> 4293 <listitem> 4294 <para><command xlink:href="#backend-queues">Possibility to provide a 4295 container</command> for the event and deferred event queues. A 4296 policy implementation based on a more efficient Boost.CircularBuffer 4297 is provided.</para> 4298 </listitem> 4299 <listitem> 4300 <para>msm::back::state_machine<>::is_flag_active method made 4301 const.</para> 4302 </listitem> 4303 <listitem> 4304 <para>added possibility to <command xlink:href="#backend-enqueueing" 4305 >enqueue events</command> for delayed processing.</para> 4306 </listitem> 4307 <listitem> 4308 <para>Bugfixes<itemizedlist> 4309 <listitem> 4310 <para>Trac 4926</para> 4311 </listitem> 4312 <listitem> 4313 <para>stack overflow using the Defer functor</para> 4314 </listitem> 4315 <listitem> 4316 <para>anonymous transition of a submachine not called for 4317 the initial state</para> 4318 </listitem> 4319 </itemizedlist></para> 4320 </listitem> 4321 </itemizedlist> 4322 </para> 4323 </sect1> 4324 <sect1> 4325 <title>From V2.10 to V2.12 (Boost 1.45)</title> 4326 <para> 4327 <itemizedlist> 4328 <listitem> 4329 <para>Support for <command xlink:href="#back-end-serialization">serialization</command></para> 4330 </listitem> 4331 <listitem> 4332 <para><command xlink:href="#eUML-reuse-functor">Possibility to use 4333 normal functors</command> (from functor front-end) in 4334 eUML.</para> 4335 </listitem> 4336 <listitem> 4337 <para><command xlink:href="#backend-fsm-constructor-args">New constructors</command> where substates / submachines can be taken as 4338 arguments. This allows passing arguments to the constructor of a 4339 submachine.</para> 4340 </listitem> 4341 <listitem> 4342 <para>Bugfixes</para> 4343 </listitem> 4344 </itemizedlist> 4345 </para> 4346 </sect1> 4347 <sect1> 4348 <title>From V2.0 to V2.12 (Boost 1.44)</title> 4349 <para> 4350 <itemizedlist> 4351 <listitem> 4352 <para>New documentation</para> 4353 </listitem> 4354 <listitem> 4355 <para>Internal transitions. Either as part of the transition table or 4356 using a state's internal transition table</para> 4357 </listitem> 4358 <listitem> 4359 <para>increased dispatch and copy speed</para> 4360 </listitem> 4361 <listitem> 4362 <para><command xlink:href="#basic-row2">new row types</command> for the 4363 basic front-end</para> 4364 </listitem> 4365 <listitem> 4366 <para>new eUML syntax, better attribute support, macros to ease 4367 developer's life. Even VC8 seems to like it better.</para> 4368 </listitem> 4369 <listitem> 4370 <para>New policy for reduced compile-time at the cost of dispatch 4371 speed</para> 4372 </listitem> 4373 <listitem> 4374 <para>Support for base events</para> 4375 </listitem> 4376 <listitem> 4377 <para>possibility to choose the initial event</para> 4378 </listitem> 4379 </itemizedlist> 4380 </para> 4381 </sect1> 4382 </chapter> 4383 </part> 4384 <part> 4385 <title><command xml:id="Reference-begin"/>Reference</title> 4386 <chapter> 4387 <title>External references to MSM</title> 4388 <para>An interesting mapping UML <-> MSM from Takatoshi Kondo can be found at 4389 <command xlink:href="http://redboltz.wikidot.com/boost-msm-guide" 4390 >Redboltz</command>.</para> 4391 </chapter> 4392 <chapter> 4393 <title>eUML operators and basic helpers</title> 4394 <para>The following table lists the supported operators: </para> 4395 <para> 4396 <table frame="all"> 4397 <title>Operators and state machine helpers</title> 4398 <tgroup cols="3"> 4399 <colspec colname="c1" colnum="1"/> 4400 <colspec colname="c2" colnum="2"/> 4401 <colspec colname="c3" colnum="3"/> 4402 <thead> 4403 <row> 4404 <entry>eUML function / operator</entry> 4405 <entry>Description</entry> 4406 <entry>Functor</entry> 4407 </row> 4408 </thead> 4409 <tbody> 4410 <row> 4411 <entry>&&</entry> 4412 <entry>Calls lazily Action1&& Action2</entry> 4413 <entry>And_</entry> 4414 </row> 4415 <row> 4416 <entry>||</entry> 4417 <entry>Calls lazily Action1|| Action2</entry> 4418 <entry>Or_</entry> 4419 </row> 4420 <row> 4421 <entry>!</entry> 4422 <entry>Calls lazily !Action1</entry> 4423 <entry>Not_</entry> 4424 </row> 4425 <row> 4426 <entry>!=</entry> 4427 <entry>Calls lazily Action1 != Action2</entry> 4428 <entry>NotEqualTo_</entry> 4429 </row> 4430 <row> 4431 <entry>==</entry> 4432 <entry>Calls lazily Action1 == Action2</entry> 4433 <entry>EqualTo_</entry> 4434 </row> 4435 <row> 4436 <entry>></entry> 4437 <entry>Calls lazily Action1 > Action2</entry> 4438 <entry>Greater_</entry> 4439 </row> 4440 <row> 4441 <entry>>=</entry> 4442 <entry>Calls lazily Action1 >= Action2</entry> 4443 <entry>Greater_Equal_</entry> 4444 </row> 4445 <row> 4446 <entry><</entry> 4447 <entry>Calls lazily Action1 < Action2</entry> 4448 <entry>Less_</entry> 4449 </row> 4450 <row> 4451 <entry><=</entry> 4452 <entry>Calls lazily Action1 <= Action2</entry> 4453 <entry>Less_Equal_</entry> 4454 </row> 4455 <row> 4456 <entry>&</entry> 4457 <entry>Calls lazily Action1 & Action2</entry> 4458 <entry>Bitwise_And_</entry> 4459 </row> 4460 <row> 4461 <entry>|</entry> 4462 <entry>Calls lazily Action1 | Action2</entry> 4463 <entry>Bitwise_Or_</entry> 4464 </row> 4465 <row> 4466 <entry>^</entry> 4467 <entry>Calls lazily Action1 ^ Action2</entry> 4468 <entry>Bitwise_Xor_</entry> 4469 </row> 4470 <row> 4471 <entry>--</entry> 4472 <entry>Calls lazily --Action1 / Action1--</entry> 4473 <entry>Pre_Dec_ / Post_Dec_</entry> 4474 </row> 4475 <row> 4476 <entry>++</entry> 4477 <entry>Calls lazily ++Action1 / Action1++</entry> 4478 <entry>Pre_Inc_ / Post_Inc_</entry> 4479 </row> 4480 <row> 4481 <entry>/</entry> 4482 <entry>Calls lazily Action1 / Action2</entry> 4483 <entry>Divides_</entry> 4484 </row> 4485 <row> 4486 <entry>/=</entry> 4487 <entry>Calls lazily Action1 /= Action2</entry> 4488 <entry>Divides_Assign_</entry> 4489 </row> 4490 <row> 4491 <entry>*</entry> 4492 <entry>Calls lazily Action1 * Action2</entry> 4493 <entry>Multiplies_</entry> 4494 </row> 4495 <row> 4496 <entry>*=</entry> 4497 <entry>Calls lazily Action1 *= Action2</entry> 4498 <entry>Multiplies_Assign_</entry> 4499 </row> 4500 <row> 4501 <entry>+ (binary)</entry> 4502 <entry>Calls lazily Action1 + Action2</entry> 4503 <entry>Plus_</entry> 4504 </row> 4505 <row> 4506 <entry>+ (unary)</entry> 4507 <entry>Calls lazily +Action1</entry> 4508 <entry>Unary_Plus_</entry> 4509 </row> 4510 <row> 4511 <entry>+=</entry> 4512 <entry>Calls lazily Action1 += Action2</entry> 4513 <entry>Plus_Assign_</entry> 4514 </row> 4515 <row> 4516 <entry>- (binary)</entry> 4517 <entry>Calls lazily Action1 - Action2</entry> 4518 <entry>Minus_</entry> 4519 </row> 4520 <row> 4521 <entry>- (unary)</entry> 4522 <entry>Calls lazily -Action1</entry> 4523 <entry>Unary_Minus_</entry> 4524 </row> 4525 <row> 4526 <entry>-=</entry> 4527 <entry>Calls lazily Action1 -= Action2</entry> 4528 <entry>Minus_Assign_</entry> 4529 </row> 4530 <row> 4531 <entry>%</entry> 4532 <entry>Calls lazily Action1 % Action2</entry> 4533 <entry>Modulus_</entry> 4534 </row> 4535 <row> 4536 <entry>%=</entry> 4537 <entry>Calls lazily Action1 %= Action2</entry> 4538 <entry>Modulus_Assign_</entry> 4539 </row> 4540 <row> 4541 <entry>>></entry> 4542 <entry>Calls lazily Action1 >> Action2</entry> 4543 <entry>ShiftRight_</entry> 4544 </row> 4545 <row> 4546 <entry>>>=</entry> 4547 <entry>Calls lazily Action1 >>= Action2</entry> 4548 <entry>ShiftRight_Assign_</entry> 4549 </row> 4550 <row> 4551 <entry><<</entry> 4552 <entry>Calls lazily Action1 << Action2</entry> 4553 <entry>ShiftLeft_</entry> 4554 </row> 4555 <row> 4556 <entry><<=</entry> 4557 <entry>Calls lazily Action1 <<= Action2</entry> 4558 <entry>ShiftLeft_Assign_</entry> 4559 </row> 4560 <row> 4561 <entry>[] (works on vector, map, arrays)</entry> 4562 <entry>Calls lazily Action1 [Action2]</entry> 4563 <entry>Subscript_</entry> 4564 </row> 4565 <row> 4566 <entry>if_then_else_(Condition,Action1,Action2)</entry> 4567 <entry>Returns either the result of calling Action1 or the result of 4568 calling Action2</entry> 4569 <entry>If_Else_</entry> 4570 </row> 4571 <row> 4572 <entry>if_then_(Condition,Action)</entry> 4573 <entry>Returns the result of calling Action if Condition</entry> 4574 <entry>If_Then_</entry> 4575 </row> 4576 <row> 4577 <entry>while_(Condition, Body)</entry> 4578 <entry>While Condition(), calls Body(). Returns nothing</entry> 4579 <entry>While_Do_</entry> 4580 </row> 4581 <row> 4582 <entry>do_while_(Condition, Body)</entry> 4583 <entry>Calls Body() while Condition(). Returns nothing</entry> 4584 <entry>Do_While_</entry> 4585 </row> 4586 <row> 4587 <entry>for_(Begin,Stop,EndLoop,Body)</entry> 4588 <entry>Calls for(Begin;Stop;EndLoop){Body;}</entry> 4589 <entry>For_Loop_</entry> 4590 </row> 4591 <row> 4592 <entry>process_(Event [,fsm1] [,fsm2] [,fsm3] [,fsm4])</entry> 4593 <entry>Processes Event on the current state machine (if no fsm 4594 specified) or on up to 4 state machines returned by an 4595 appropriate functor.</entry> 4596 <entry>Process_</entry> 4597 </row> 4598 <row> 4599 <entry>process2_(Event, Data [,fsm1] [,fsm2] [,fsm3])</entry> 4600 <entry>Processes Event on the current state machine (if no fsm 4601 specified) or on up to 2 state machines returned by an 4602 appropriate functor. The event is copy-constructed from what 4603 Data() returns.</entry> 4604 <entry>Process2_</entry> 4605 </row> 4606 <row> 4607 <entry>is_flag_(Flag [,fsm])</entry> 4608 <entry>Calls is_flag_active() on the current state machine or the 4609 one returned by calling fsm.</entry> 4610 <entry>Get_Flag_</entry> 4611 </row> 4612 <row> 4613 <entry>event_ [(attribute name)]</entry> 4614 <entry>Returns the current event (as const reference)</entry> 4615 <entry>GetEvent_</entry> 4616 </row> 4617 <row> 4618 <entry>source_ [(attribute name)]</entry> 4619 <entry>Returns the source state of the currently triggered 4620 transition (as reference). If an attribute name is provided, 4621 returns the attribute by reference.</entry> 4622 <entry>GetSource_</entry> 4623 </row> 4624 <row> 4625 <entry>target_ [(attribute name)]</entry> 4626 <entry>Returns the target state of the currently triggered 4627 transition (as reference). If an attribute name is provided, 4628 returns the attribute by reference.</entry> 4629 <entry>GetTarget_</entry> 4630 </row> 4631 <row> 4632 <entry>state_ [(attribute name)]</entry> 4633 <entry>Returns the source state of the currently active state (as 4634 reference). Valid inside a state entry/exit action. If an 4635 attribute name is provided, returns the attribute by 4636 reference.</entry> 4637 <entry>GetState_</entry> 4638 </row> 4639 <row> 4640 <entry>fsm_ [(attribute name)]</entry> 4641 <entry>Returns the current state machine (as reference). Valid 4642 inside a state entry/exit action or a transition. If an 4643 attribute name is provided, returns the attribute by 4644 reference.</entry> 4645 <entry>GetFsm_</entry> 4646 </row> 4647 <row> 4648 <entry>substate_(state_name [,fsm])</entry> 4649 <entry>Returns (as reference) the state state_name referenced in the 4650 current state machine or the one given as argument.</entry> 4651 <entry>SubState_</entry> 4652 </row> 4653 </tbody> 4654 </tgroup> 4655 </table> 4656 </para> 4657 <para>To use these functions, you need to include: </para> 4658 <para><code>#include <msm/front/euml/euml.hpp></code></para> 4659 </chapter> 4660 <chapter> 4661 <title> 4662 <command xml:id="eUML-STL-all"/>Functional programming </title> 4663 <para>To use these functions, you need to include: </para> 4664 <para><code>#include <msm/front/euml/stl.hpp></code></para> 4665 <para>or the specified header in the following tables.</para> 4666 <para>The following tables list the supported STL algorithms: </para> 4667 <para> 4668 <command xml:id="eUML-STL-querying"/> 4669 <table frame="all"> 4670 <title>STL algorithms</title> 4671 <tgroup cols="2"> 4672 <colspec colname="c2" colnum="1"/> 4673 <colspec colname="c3" colnum="2"/> 4674 <thead> 4675 <row> 4676 <entry>STL algorithms in querying.hpp</entry> 4677 <entry>Functor</entry> 4678 </row> 4679 </thead> 4680 <tbody> 4681 <row> 4682 <entry>find_(first, last, value)</entry> 4683 <entry>Find_</entry> 4684 </row> 4685 <row> 4686 <entry>find_if_(first, last, value)</entry> 4687 <entry>FindIf_</entry> 4688 </row> 4689 <row> 4690 <entry>lower_bound_(first, last, value [,opᵃ])</entry> 4691 <entry>LowerBound_</entry> 4692 </row> 4693 <row> 4694 <entry>upper_bound_(first, last, value [,opᵃ])</entry> 4695 <entry>UpperBound_</entry> 4696 </row> 4697 <row> 4698 <entry>equal_range_(first, last, value [,opᵃ])</entry> 4699 <entry>EqualRange_</entry> 4700 </row> 4701 <row> 4702 <entry>binary_search_(first, last, value [,opᵃ])</entry> 4703 <entry>BinarySearch_</entry> 4704 </row> 4705 <row> 4706 <entry>min_element_(first, last[,opᵃ])</entry> 4707 <entry>MinElement_</entry> 4708 </row> 4709 <row> 4710 <entry>max_element_(first, last[,opᵃ])</entry> 4711 <entry>MaxElement_</entry> 4712 </row> 4713 <row> 4714 <entry>adjacent_find_(first, last[,opᵃ])</entry> 4715 <entry>AdjacentFind_</entry> 4716 </row> 4717 <row> 4718 <entry>find_end_( first1, last1, first2, last2 [,op ᵃ])</entry> 4719 <entry>FindEnd_</entry> 4720 </row> 4721 <row> 4722 <entry>find_first_of_( first1, last1, first2, last2 [,op ᵃ])</entry> 4723 <entry>FindFirstOf_</entry> 4724 </row> 4725 <row> 4726 <entry>equal_( first1, last1, first2 [,op ᵃ])</entry> 4727 <entry>Equal_</entry> 4728 </row> 4729 <row> 4730 <entry>search_( first1, last1, first2, last2 [,op ᵃ])</entry> 4731 <entry>Search_</entry> 4732 </row> 4733 <row> 4734 <entry>includes_( first1, last1, first2, last2 [,op ᵃ])</entry> 4735 <entry>Includes_</entry> 4736 </row> 4737 <row> 4738 <entry>lexicographical_compare_ ( first1, last1, first2, last2 [,op 4739 ᵃ]) </entry> 4740 <entry>LexicographicalCompare_</entry> 4741 </row> 4742 <row> 4743 <entry>count_(first, last, value [,size])</entry> 4744 <entry>Count_</entry> 4745 </row> 4746 <row> 4747 <entry>count_if_(first, last, op ᵃ [,size])</entry> 4748 <entry>CountIf_</entry> 4749 </row> 4750 <row> 4751 <entry>distance_(first, last)</entry> 4752 <entry>Distance_</entry> 4753 </row> 4754 <row> 4755 <entry>mismatch _( first1, last1, first2 [,op ᵃ])</entry> 4756 <entry>Mismatch_</entry> 4757 </row> 4758 </tbody> 4759 </tgroup> 4760 </table> 4761 </para> 4762 <para> 4763 <command xml:id="eUML-STL-iteration"/> 4764 <table frame="all"> 4765 <title>STL algorithms</title> 4766 <tgroup cols="2"> 4767 <colspec colname="c2" colnum="1"/> 4768 <colspec colname="c3" colnum="2"/> 4769 <thead> 4770 <row> 4771 <entry>STL algorithms in iteration.hpp</entry> 4772 <entry>Functor</entry> 4773 </row> 4774 </thead> 4775 <tbody> 4776 <row> 4777 <entry>for_each_(first,last, unary opᵃ)</entry> 4778 <entry>ForEach_</entry> 4779 </row> 4780 <row> 4781 <entry>accumulate_first, last, init [,opᵃ])</entry> 4782 <entry>Accumulate_</entry> 4783 </row> 4784 </tbody> 4785 </tgroup> 4786 </table> 4787 </para> 4788 <para> 4789 <command xml:id="eUML-STL-transformation"/> 4790 <table> 4791 <title>STL algorithms</title> 4792 <tgroup cols="2"> 4793 <colspec colname="c2" colnum="1"/> 4794 <colspec colname="c3" colnum="2"/> 4795 <thead> 4796 <row> 4797 <entry>STL algorithms in transformation.hpp</entry> 4798 <entry>Functor</entry> 4799 </row> 4800 </thead> 4801 <tbody> 4802 <row> 4803 <entry>copy_(first, last, result)</entry> 4804 <entry>Copy_</entry> 4805 </row> 4806 <row> 4807 <entry>copy_backward_(first, last, result)</entry> 4808 <entry>CopyBackward_</entry> 4809 </row> 4810 <row> 4811 <entry>reverse_(first, last)</entry> 4812 <entry>Reverse_</entry> 4813 </row> 4814 <row> 4815 <entry>reverse_copy_(first, last , result)</entry> 4816 <entry>ReverseCopy_</entry> 4817 </row> 4818 <row> 4819 <entry>remove_(first, last, value)</entry> 4820 <entry>Remove_</entry> 4821 </row> 4822 <row> 4823 <entry>remove_if_(first, last , opᵃ)</entry> 4824 <entry>RemoveIf_</entry> 4825 </row> 4826 <row> 4827 <entry>remove_copy_(first, last , output, value)</entry> 4828 <entry>RemoveCopy_</entry> 4829 </row> 4830 <row> 4831 <entry>remove_copy_if_(first, last, output, opᵃ)</entry> 4832 <entry>RemoveCopyIf_</entry> 4833 </row> 4834 <row> 4835 <entry>fill_(first, last, value)</entry> 4836 <entry>Fill_</entry> 4837 </row> 4838 <row> 4839 <entry>fill_n_(first, size, value)ᵇ</entry> 4840 <entry>FillN_</entry> 4841 </row> 4842 <row> 4843 <entry>generate_(first, last, generatorᵃ)</entry> 4844 <entry>Generate_</entry> 4845 </row> 4846 <row> 4847 <entry>generate_(first, size, generatorᵃ)ᵇ</entry> 4848 <entry>GenerateN_</entry> 4849 </row> 4850 <row> 4851 <entry>unique_(first, last [,opᵃ])</entry> 4852 <entry>Unique_</entry> 4853 </row> 4854 <row> 4855 <entry>unique_copy_(first, last, output [,opᵃ])</entry> 4856 <entry>UniqueCopy_</entry> 4857 </row> 4858 <row> 4859 <entry>random_shuffle_(first, last [,opᵃ])</entry> 4860 <entry>RandomShuffle_</entry> 4861 </row> 4862 <row> 4863 <entry>rotate_copy_(first, middle, last, output)</entry> 4864 <entry>RotateCopy_</entry> 4865 </row> 4866 <row> 4867 <entry>partition_ (first, last [,opᵃ])</entry> 4868 <entry>Partition_</entry> 4869 </row> 4870 <row> 4871 <entry>stable_partition_ (first, last [,opᵃ])</entry> 4872 <entry>StablePartition_</entry> 4873 </row> 4874 <row> 4875 <entry>stable_sort_(first, last [,opᵃ])</entry> 4876 <entry>StableSort_</entry> 4877 </row> 4878 <row> 4879 <entry>sort_(first, last [,opᵃ])</entry> 4880 <entry>Sort_</entry> 4881 </row> 4882 <row> 4883 <entry>partial_sort_(first, middle, last [,opᵃ])</entry> 4884 <entry>PartialSort_</entry> 4885 </row> 4886 <row> 4887 <entry>partial_sort_copy_ (first, last, res_first, res_last [,opᵃ]) </entry> 4888 <entry>PartialSortCopy_</entry> 4889 </row> 4890 <row> 4891 <entry>nth_element_(first, nth, last [,opᵃ])</entry> 4892 <entry>NthElement_</entry> 4893 </row> 4894 <row> 4895 <entry>merge_( first1, last1, first2, last2, output [,op ᵃ])</entry> 4896 <entry>Merge_</entry> 4897 </row> 4898 <row> 4899 <entry>inplace_merge_(first, middle, last [,opᵃ])</entry> 4900 <entry>InplaceMerge_</entry> 4901 </row> 4902 <row> 4903 <entry>set_union_(first1, last1, first2, last2, output [,op 4904 ᵃ])</entry> 4905 <entry>SetUnion_</entry> 4906 </row> 4907 <row> 4908 <entry>push_heap_(first, last [,op ᵃ])</entry> 4909 <entry>PushHeap_</entry> 4910 </row> 4911 <row> 4912 <entry>pop_heap_(first, last [,op ᵃ])</entry> 4913 <entry>PopHeap_</entry> 4914 </row> 4915 <row> 4916 <entry>make_heap_(first, last [,op ᵃ])</entry> 4917 <entry>MakeHeap_</entry> 4918 </row> 4919 <row> 4920 <entry>sort_heap_(first, last [,op ᵃ])</entry> 4921 <entry>SortHeap_</entry> 4922 </row> 4923 <row> 4924 <entry>next_permutation_(first, last [,op ᵃ])</entry> 4925 <entry>NextPermutation_</entry> 4926 </row> 4927 <row> 4928 <entry>prev_permutation_(first, last [,op ᵃ])</entry> 4929 <entry>PrevPermutation_</entry> 4930 </row> 4931 <row> 4932 <entry>inner_product_(first1, last1, first2, init [,op1ᵃ] [,op2ᵃ]) </entry> 4933 <entry>InnerProduct_</entry> 4934 </row> 4935 <row> 4936 <entry>partial_sum_(first, last, output [,opᵃ])</entry> 4937 <entry>PartialSum_</entry> 4938 </row> 4939 <row> 4940 <entry>adjacent_difference_(first, last, output [,opᵃ])</entry> 4941 <entry>AdjacentDifference_</entry> 4942 </row> 4943 <row> 4944 <entry>replace_(first, last, old_value, new_value)</entry> 4945 <entry>Replace_</entry> 4946 </row> 4947 <row> 4948 <entry>replace_if_(first, last, opᵃ, new_value)</entry> 4949 <entry>ReplaceIf_</entry> 4950 </row> 4951 <row> 4952 <entry>replace_copy_(first, last, result, old_value, 4953 new_value)</entry> 4954 <entry>ReplaceCopy_</entry> 4955 </row> 4956 <row> 4957 <entry>replace_copy_if_(first, last, result, opᵃ, new_value)</entry> 4958 <entry>ReplaceCopyIf_</entry> 4959 </row> 4960 <row> 4961 <entry>rotate_(first, middle, last)ᵇ</entry> 4962 <entry>Rotate_</entry> 4963 </row> 4964 </tbody> 4965 </tgroup> 4966 </table> 4967 </para> 4968 <para> 4969 <command xml:id="eUML-STL-container"/> 4970 <table> 4971 <title>STL container methods</title> 4972 <tgroup cols="2"> 4973 <colspec colname="c2" colnum="1"/> 4974 <colspec colname="c3" colnum="2"/> 4975 <thead> 4976 <row> 4977 <entry>STL container methods(common) in container.hpp</entry> 4978 <entry>Functor</entry> 4979 </row> 4980 </thead> 4981 <tbody> 4982 <row> 4983 <entry>container::reference front_(container)</entry> 4984 <entry>Front_</entry> 4985 </row> 4986 <row> 4987 <entry>container::reference back_(container)</entry> 4988 <entry>Back_</entry> 4989 </row> 4990 <row> 4991 <entry>container::iterator begin_(container)</entry> 4992 <entry>Begin_</entry> 4993 </row> 4994 <row> 4995 <entry>container::iterator end_(container)</entry> 4996 <entry>End_</entry> 4997 </row> 4998 <row> 4999 <entry>container::reverse_iterator rbegin_(container)</entry> 5000 <entry>RBegin_</entry> 5001 </row> 5002 <row> 5003 <entry>container::reverse_iterator rend_(container)</entry> 5004 <entry>REnd_</entry> 5005 </row> 5006 <row> 5007 <entry>void push_back_(container, value)</entry> 5008 <entry>Push_Back_</entry> 5009 </row> 5010 <row> 5011 <entry>void pop_back_(container, value)</entry> 5012 <entry>Pop_Back_</entry> 5013 </row> 5014 <row> 5015 <entry>void push_front_(container, value)</entry> 5016 <entry>Push_Front_</entry> 5017 </row> 5018 <row> 5019 <entry>void pop_front_(container, value)</entry> 5020 <entry>Pop_Front_</entry> 5021 </row> 5022 <row> 5023 <entry>void clear_(container)</entry> 5024 <entry>Clear_</entry> 5025 </row> 5026 <row> 5027 <entry>size_type capacity_(container)</entry> 5028 <entry>Capacity_</entry> 5029 </row> 5030 <row> 5031 <entry>size_type size_(container)</entry> 5032 <entry>Size_</entry> 5033 </row> 5034 <row> 5035 <entry>size_type max_size_(container)</entry> 5036 <entry>Max_Size_</entry> 5037 </row> 5038 <row> 5039 <entry>void reserve_(container, value)</entry> 5040 <entry>Reserve _</entry> 5041 </row> 5042 <row> 5043 <entry>void resize_(container, value)</entry> 5044 <entry>Resize _</entry> 5045 </row> 5046 <row> 5047 <entry>iterator insert_(container, pos, value)</entry> 5048 <entry>Insert_</entry> 5049 </row> 5050 <row> 5051 <entry>void insert_( container , pos, first, last)</entry> 5052 <entry>Insert_</entry> 5053 </row> 5054 <row> 5055 <entry>void insert_( container , pos, number, value)</entry> 5056 <entry>Insert_</entry> 5057 </row> 5058 <row> 5059 <entry>void swap_( container , other_container)</entry> 5060 <entry>Swap_</entry> 5061 </row> 5062 <row> 5063 <entry>void erase_( container , pos)</entry> 5064 <entry>Erase_</entry> 5065 </row> 5066 <row> 5067 <entry>void erase_( container , first, last) </entry> 5068 <entry>Erase_</entry> 5069 </row> 5070 <row> 5071 <entry>bool empty_( container)</entry> 5072 <entry>Empty_</entry> 5073 </row> 5074 </tbody> 5075 </tgroup> 5076 </table> 5077 </para> 5078 <para> 5079 <table> 5080 <title>STL list methods</title> 5081 <tgroup cols="2"> 5082 <colspec colname="c2" colnum="1"/> 5083 <colspec colname="c3" colnum="2"/> 5084 <thead> 5085 <row> 5086 <entry>std::list methods in container.hpp</entry> 5087 <entry>Functor</entry> 5088 </row> 5089 </thead> 5090 <tbody> 5091 <row> 5092 <entry>void list_remove_(container, value)</entry> 5093 <entry>ListRemove_</entry> 5094 </row> 5095 <row> 5096 <entry>void list_remove_if_(container, opᵃ)</entry> 5097 <entry>ListRemove_If_</entry> 5098 </row> 5099 <row> 5100 <entry>void list_merge_(container, other_list)</entry> 5101 <entry>ListMerge_</entry> 5102 </row> 5103 <row> 5104 <entry>void list_merge_(container, other_list, opᵃ)</entry> 5105 <entry>ListMerge_</entry> 5106 </row> 5107 <row> 5108 <entry>void splice_(container, iterator, other_list)</entry> 5109 <entry>Splice_</entry> 5110 </row> 5111 <row> 5112 <entry>void splice_(container, iterator, other_list, 5113 iterator)</entry> 5114 <entry>Splice_</entry> 5115 </row> 5116 <row> 5117 <entry>void splice_(container, iterator, other_list, first, 5118 last)</entry> 5119 <entry>Splice_</entry> 5120 </row> 5121 <row> 5122 <entry>void list_reverse_(container)</entry> 5123 <entry>ListReverse_</entry> 5124 </row> 5125 <row> 5126 <entry>void list_unique_(container)</entry> 5127 <entry>ListUnique_</entry> 5128 </row> 5129 <row> 5130 <entry>void list_unique_(container, opᵃ)</entry> 5131 <entry>ListUnique_</entry> 5132 </row> 5133 <row> 5134 <entry>void list_sort_(container)</entry> 5135 <entry>ListSort_</entry> 5136 </row> 5137 <row> 5138 <entry>void list_sort_(container, opᵃ)</entry> 5139 <entry>ListSort_</entry> 5140 </row> 5141 </tbody> 5142 </tgroup> 5143 </table> 5144 </para> 5145 <para> 5146 <table> 5147 <title>STL associative container methods </title> 5148 <tgroup cols="2"> 5149 <colspec colname="c2" colnum="1"/> 5150 <colspec colname="c3" colnum="2"/> 5151 <thead> 5152 <row> 5153 <entry>Associative container methods in container.hpp</entry> 5154 <entry>Functor</entry> 5155 </row> 5156 </thead> 5157 <tbody> 5158 <row> 5159 <entry>iterator insert_(container, pos, value)</entry> 5160 <entry>Insert_</entry> 5161 </row> 5162 <row> 5163 <entry>void insert_( container , first, last)</entry> 5164 <entry>Insert_</entry> 5165 </row> 5166 <row> 5167 <entry>pair<iterator, bool> insert_( container , value)</entry> 5168 <entry>Insert_</entry> 5169 </row> 5170 <row> 5171 <entry>void associative_erase_( container , pos)</entry> 5172 <entry>Associative_Erase_</entry> 5173 </row> 5174 <row> 5175 <entry>void associative_erase_( container , first, last)</entry> 5176 <entry>Associative_Erase_</entry> 5177 </row> 5178 <row> 5179 <entry>size_type associative_erase_( container , key)</entry> 5180 <entry>Associative_Erase_</entry> 5181 </row> 5182 <row> 5183 <entry>iterator associative_find_( container , key)</entry> 5184 <entry>Associative_Find_</entry> 5185 </row> 5186 <row> 5187 <entry>size_type associative_count_( container , key)</entry> 5188 <entry>AssociativeCount_</entry> 5189 </row> 5190 <row> 5191 <entry>iterator associative_lower_bound_( container , key)</entry> 5192 <entry>Associative_Lower_Bound_</entry> 5193 </row> 5194 <row> 5195 <entry>iterator associative_upper_bound_( container , key)</entry> 5196 <entry>Associative_Upper_Bound_</entry> 5197 </row> 5198 <row> 5199 <entry>pair<iterator, iterator> associative_equal_range_( 5200 container , key)</entry> 5201 <entry>Associative_Equal_Range_</entry> 5202 </row> 5203 </tbody> 5204 </tgroup> 5205 </table> 5206 </para> 5207 <para> 5208 <table> 5209 <title>STL pair</title> 5210 <tgroup cols="2"> 5211 <colspec colname="c2" colnum="1"/> 5212 <colspec colname="c3" colnum="2"/> 5213 <thead> 5214 <row> 5215 <entry>std::pair in container.hpp</entry> 5216 <entry>Functor</entry> 5217 </row> 5218 </thead> 5219 <tbody> 5220 <row> 5221 <entry>first_type first_(pair<T1, T2>)</entry> 5222 <entry>First_</entry> 5223 </row> 5224 <row> 5225 <entry>second_type second_(pair<T1, T2>)</entry> 5226 <entry>Second_</entry> 5227 </row> 5228 </tbody> 5229 </tgroup> 5230 </table> 5231 </para> 5232 <para> 5233 <table> 5234 <title>STL string</title> 5235 <tgroup cols="3"> 5236 <colspec colname="newCol1" colnum="1"/> 5237 <colspec colname="c2" colnum="2"/> 5238 <colspec colname="c3" colnum="3"/> 5239 <thead> 5240 <row> 5241 <entry>STL string method</entry> 5242 <entry>std::string method in container.hpp</entry> 5243 <entry>Functor</entry> 5244 </row> 5245 </thead> 5246 <tbody> 5247 <row> 5248 <entry>substr (size_type pos, size_type size)</entry> 5249 <entry>string substr_(container, pos, length)</entry> 5250 <entry>Substr_</entry> 5251 </row> 5252 <row> 5253 <entry>int compare(string)</entry> 5254 <entry>int string_compare_(container, another_string)</entry> 5255 <entry>StringCompare_</entry> 5256 </row> 5257 <row> 5258 <entry>int compare(char*)</entry> 5259 <entry>int string_compare_(container, another_string)</entry> 5260 <entry>StringCompare_</entry> 5261 </row> 5262 <row> 5263 <entry>int compare(size_type pos, size_type size, string)</entry> 5264 <entry>int string_compare_(container, pos, size, 5265 another_string)</entry> 5266 <entry>StringCompare_</entry> 5267 </row> 5268 <row> 5269 <entry>int compare (size_type pos, size_type size, string, size_type 5270 length)</entry> 5271 <entry>int string_compare_(container, pos, size, another_string, 5272 length)</entry> 5273 <entry>StringCompare_</entry> 5274 </row> 5275 <row> 5276 <entry>string& append(const string&)</entry> 5277 <entry>string& append_(container, another_string)</entry> 5278 <entry>Append_</entry> 5279 </row> 5280 <row> 5281 <entry>string& append (charT*)</entry> 5282 <entry>string& append_(container, another_string)</entry> 5283 <entry>Append_</entry> 5284 </row> 5285 <row> 5286 <entry>string& append (string , size_type pos, size_type 5287 size)</entry> 5288 <entry>string& append_(container, other_string, pos, 5289 size)</entry> 5290 <entry>Append_</entry> 5291 </row> 5292 <row> 5293 <entry>string& append (charT*, size_type size)</entry> 5294 <entry>string& append_(container, another_string, 5295 length)</entry> 5296 <entry>Append_</entry> 5297 </row> 5298 <row> 5299 <entry>string& append (size_type size, charT)</entry> 5300 <entry>string& append_(container, size, char)</entry> 5301 <entry>Append_</entry> 5302 </row> 5303 <row> 5304 <entry>string& append (iterator begin, iterator end)</entry> 5305 <entry>string& append_(container, begin, end)</entry> 5306 <entry>Append_</entry> 5307 </row> 5308 <row> 5309 <entry>string& insert (size_type pos, charT*)</entry> 5310 <entry>string& string_insert_(container, pos, 5311 other_string)</entry> 5312 <entry>StringInsert_</entry> 5313 </row> 5314 <row> 5315 <entry>string& insert(size_type pos, charT*,size_type n)</entry> 5316 <entry>string& string_insert_(container, pos, other_string, 5317 n)</entry> 5318 <entry>StringInsert_</entry> 5319 </row> 5320 <row> 5321 <entry>string& insert(size_type pos,size_type n, charT 5322 c)</entry> 5323 <entry>string& string_insert_(container, pos, n, c)</entry> 5324 <entry>StringInsert_</entry> 5325 </row> 5326 <row> 5327 <entry>string& insert (size_type pos, const string&)</entry> 5328 <entry>string& string_insert_(container, pos, 5329 other_string)</entry> 5330 <entry>StringInsert_</entry> 5331 </row> 5332 <row> 5333 <entry>string& insert (size_type pos, const string&, 5334 size_type pos1, size_type n)</entry> 5335 <entry>string& string_insert_(container, pos, other_string, 5336 pos1, n)</entry> 5337 <entry>StringInsert_</entry> 5338 </row> 5339 <row> 5340 <entry>string& erase(size_type pos=0, size_type n=npos)</entry> 5341 <entry>string& string_erase_(container, pos, n)</entry> 5342 <entry>StringErase_</entry> 5343 </row> 5344 <row> 5345 <entry>string& assign(const string&)</entry> 5346 <entry>string& string_assign_(container, another_string)</entry> 5347 <entry>StringAssign_</entry> 5348 </row> 5349 <row> 5350 <entry>string& assign(const charT*)</entry> 5351 <entry>string& string_assign_(container, another_string)</entry> 5352 <entry>StringAssign_</entry> 5353 </row> 5354 <row> 5355 <entry>string& assign(const string&, size_type pos, 5356 size_type n)</entry> 5357 <entry>string& string_assign_(container, another_string, pos, 5358 n)</entry> 5359 <entry>StringAssign_</entry> 5360 </row> 5361 <row> 5362 <entry>string& assign(const charT*, size_type n)</entry> 5363 <entry>string& string_assign_(container, another_string, 5364 n)</entry> 5365 <entry>StringAssign_</entry> 5366 </row> 5367 <row> 5368 <entry>string& assign(size_type n, charT c)</entry> 5369 <entry>string& string_assign_(container, n, c)</entry> 5370 <entry>StringAssign_</entry> 5371 </row> 5372 <row> 5373 <entry>string& assign(iterator first, iterator last)</entry> 5374 <entry>string& string_assign_(container, first, last)</entry> 5375 <entry>StringAssign_</entry> 5376 </row> 5377 <row> 5378 <entry>string& replace(size_type pos, size_type n, const 5379 string&)</entry> 5380 <entry>string& string_replace_(container, pos, n, 5381 another_string)</entry> 5382 <entry>StringReplace_</entry> 5383 </row> 5384 <row> 5385 <entry>string& replace(size_type pos, size_type n, const charT*, 5386 size_type n1)</entry> 5387 <entry>string& string_replace_(container, pos, n, 5388 another_string, n1)</entry> 5389 <entry>StringReplace_</entry> 5390 </row> 5391 <row> 5392 <entry>string& replace(size_type pos, size_type n, const 5393 charT*)</entry> 5394 <entry>string& string_replace_(container, pos, n, 5395 another_string)</entry> 5396 <entry>StringReplace_</entry> 5397 </row> 5398 <row> 5399 <entry>string& replace(size_type pos, size_type n, size_type n1, 5400 charT c)</entry> 5401 <entry>string& string_replace_(container, pos, n, n1, c)</entry> 5402 <entry>StringReplace_</entry> 5403 </row> 5404 <row> 5405 <entry>string& replace(iterator first, iterator last, const 5406 string&)</entry> 5407 <entry>string& string_replace_(container, first, last, 5408 another_string)</entry> 5409 <entry>StringReplace_</entry> 5410 </row> 5411 <row> 5412 <entry>string& replace(iterator first, iterator last, const 5413 charT*, size_type n)</entry> 5414 <entry>string& string_replace_(container, first, last, 5415 another_string, n)</entry> 5416 <entry>StringReplace_</entry> 5417 </row> 5418 <row> 5419 <entry>string& replace(iterator first, iterator last, const 5420 charT*)</entry> 5421 <entry>string& string_replace_(container, first, last, 5422 another_string)</entry> 5423 <entry>StringReplace_</entry> 5424 </row> 5425 <row> 5426 <entry>string& replace(iterator first, iterator last, size_type 5427 n, charT c)</entry> 5428 <entry>string& string_replace_(container, first, last, n, 5429 c)</entry> 5430 <entry>StringReplace_</entry> 5431 </row> 5432 <row> 5433 <entry>string& replace(iterator first, iterator last, iterator 5434 f, iterator l)</entry> 5435 <entry>string& string_replace_(container, first, last, f, 5436 l)</entry> 5437 <entry>StringReplace_</entry> 5438 </row> 5439 <row> 5440 <entry>const charT* c_str()</entry> 5441 <entry>const charT* c_str_(container)</entry> 5442 <entry>CStr_</entry> 5443 </row> 5444 <row> 5445 <entry>const charT* data()</entry> 5446 <entry>const charT* string_data_(container)</entry> 5447 <entry>StringData_</entry> 5448 </row> 5449 <row> 5450 <entry>size_type copy(charT* buf, size_type n, size_type pos = 5451 0)</entry> 5452 <entry>size_type string_copy_(container, buf, n, pos); size_type 5453 string_copy_(container, buf, n) </entry> 5454 <entry>StringCopy_</entry> 5455 </row> 5456 <row> 5457 <entry>size_type find(charT* s, size_type pos, size_type n)</entry> 5458 <entry>size_type string_find_(container, s, pos, n)</entry> 5459 <entry>StringFind_</entry> 5460 </row> 5461 <row> 5462 <entry>size_type find(charT* s, size_type pos=0)</entry> 5463 <entry>size_type string_find_(container, s, pos); size_type 5464 string_find_(container, s) </entry> 5465 <entry>StringFind_</entry> 5466 </row> 5467 <row> 5468 <entry>size_type find(const string& s, size_type pos=0)</entry> 5469 <entry>size_type string_find_(container, s, pos) size_type 5470 string_find_(container, s) </entry> 5471 <entry>StringFind_</entry> 5472 </row> 5473 <row> 5474 <entry>size_type find(charT c, size_type pos=0)</entry> 5475 <entry>size_type string_find_(container, c, pos) size_type 5476 string_find_(container, c) </entry> 5477 <entry>StringFind_</entry> 5478 </row> 5479 <row> 5480 <entry>size_type rfind(charT* s, size_type pos, size_type n)</entry> 5481 <entry>size_type string_rfind_(container, s, pos, n)</entry> 5482 <entry>StringRFind_</entry> 5483 </row> 5484 <row> 5485 <entry>size_type rfind(charT* s, size_type pos=npos)</entry> 5486 <entry>size_type string_rfind_(container, s, pos); size_type 5487 string_rfind_(container, s) </entry> 5488 <entry>StringRFind_</entry> 5489 </row> 5490 <row> 5491 <entry>size_type rfind(const string& s, size_type 5492 pos=npos)</entry> 5493 <entry>size_type string_rfind_(container, s, pos); size_type 5494 string_rfind_(container, s) </entry> 5495 <entry>StringRFind_</entry> 5496 </row> 5497 <row> 5498 <entry>size_type rfind(charT c, size_type pos=npos)</entry> 5499 <entry>size_type string_rfind_(container, c, pos) size_type 5500 string_rfind_(container, c) </entry> 5501 <entry>StringRFind_</entry> 5502 </row> 5503 <row> 5504 <entry>size_type find_first_of(charT* s, size_type pos, size_type 5505 n)</entry> 5506 <entry>size_type find_first_of_(container, s, pos, n)</entry> 5507 <entry>StringFindFirstOf_</entry> 5508 </row> 5509 <row> 5510 <entry>size_type find_first_of (charT* s, size_type pos=0)</entry> 5511 <entry>size_type find_first_of_(container, s, pos); size_type 5512 find_first_of_(container, s) </entry> 5513 <entry>StringFindFirstOf_</entry> 5514 </row> 5515 <row> 5516 <entry>size_type find_first_of (const string& s, size_type 5517 pos=0)</entry> 5518 <entry>size_type find_first_of_(container, s, pos); size_type 5519 find_first_of_(container, s) </entry> 5520 <entry>StringFindFirstOf_</entry> 5521 </row> 5522 <row> 5523 <entry>size_type find_first_of (charT c, size_type pos=0)</entry> 5524 <entry>size_type find_first_of_(container, c, pos) size_type 5525 find_first_of_(container, c) </entry> 5526 <entry>StringFindFirstOf_</entry> 5527 </row> 5528 <row> 5529 <entry>size_type find_first_not_of(charT* s, size_type pos, 5530 size_type n)</entry> 5531 <entry>size_type find_first_not_of_(container, s, pos, n)</entry> 5532 <entry>StringFindFirstNotOf_</entry> 5533 </row> 5534 <row> 5535 <entry>size_type find_first_not_of (charT* s, size_type 5536 pos=0)</entry> 5537 <entry>size_type find_first_not_of_(container, s, pos); size_type 5538 find_first_not_of_(container, s) </entry> 5539 <entry>StringFindFirstNotOf_</entry> 5540 </row> 5541 <row> 5542 <entry>size_type find_first_not_of (const string& s, size_type 5543 pos=0)</entry> 5544 <entry>size_type find_first_not_of_(container, s, pos); size_type 5545 find_first_not_of_(container, s) </entry> 5546 <entry>StringFindFirstNotOf_</entry> 5547 </row> 5548 <row> 5549 <entry>size_type find_first_not_of (charT c, size_type 5550 pos=0)</entry> 5551 <entry>size_type find_first_not_of_(container, c, pos); size_type 5552 find_first_not_of_(container, c) </entry> 5553 <entry>StringFindFirstNotOf_</entry> 5554 </row> 5555 <row> 5556 <entry>size_type find_last_of(charT* s, size_type pos, size_type 5557 n)</entry> 5558 <entry>size_type find_last_of_(container, s, pos, n)</entry> 5559 <entry>StringFindLastOf_</entry> 5560 </row> 5561 <row> 5562 <entry>size_type find_last_of (charT* s, size_type pos=npos)</entry> 5563 <entry>size_type find_last_of_(container, s, pos); size_type 5564 find_last_of_(container, s) </entry> 5565 <entry>StringFindLastOf_</entry> 5566 </row> 5567 <row> 5568 <entry>size_type find_last_of (const string& s, size_type 5569 pos=npos)</entry> 5570 <entry>size_type find_last_of_(container, s, pos); size_type 5571 find_last_of_(container, s) </entry> 5572 <entry>StringFindLastOf_</entry> 5573 </row> 5574 <row> 5575 <entry>size_type find_last_of (charT c, size_type pos=npos)</entry> 5576 <entry>size_type find_last_of_(container, c, pos); size_type 5577 find_last_of_(container, c) </entry> 5578 <entry>StringFindLastOf_</entry> 5579 </row> 5580 <row> 5581 <entry>size_type find_last_not_of(charT* s, size_type pos, size_type 5582 n)</entry> 5583 <entry>size_type find_last_not_of_(container, s, pos, n)</entry> 5584 <entry>StringFindLastNotOf_</entry> 5585 </row> 5586 <row> 5587 <entry>size_type find_last_not_of (charT* s, size_type 5588 pos=npos)</entry> 5589 <entry>size_type find_last_not_of_(container, s, pos); size_type 5590 find_last_of_(container, s) </entry> 5591 <entry>StringFindLastNotOf_</entry> 5592 </row> 5593 <row> 5594 <entry>size_type find_last_not_of (const string& s, size_type 5595 pos=npos)</entry> 5596 <entry>size_type find_last_not_of_(container, s, pos); size_type 5597 find_last_not_of_(container, s) </entry> 5598 <entry>StringFindLastNotOf_</entry> 5599 </row> 5600 <row> 5601 <entry>size_type find_last_not_of (charT c, size_type 5602 pos=npos)</entry> 5603 <entry>size_type find_last_not_of_(container, c, pos); size_type 5604 find_last_not_of_(container, c) </entry> 5605 <entry>StringFindLastNotOf_</entry> 5606 </row> 5607 </tbody> 5608 </tgroup> 5609 </table> 5610 </para> 5611 <para><emphasis role="underline">Notes</emphasis>: <itemizedlist> 5612 <listitem> 5613 <para>ᵃ: algorithms requiring a predicate need to make them eUML compatible 5614 by wrapping them inside a Predicate_ functor. For example, 5615 std::less<int> => Predicate_<std::less<int> >()</para> 5616 </listitem> 5617 <listitem> 5618 <para>ᵇ: If using the SGI STL implementation, these functors use the SGI 5619 return value</para> 5620 </listitem> 5621 </itemizedlist> 5622 </para> 5623 </chapter> 5624 <refentry> 5625 <refnamediv> 5626 <refname>Common headers</refname> 5627 <refpurpose>The common types used by front- and back-ends</refpurpose> 5628 </refnamediv> 5629 <refsect1> 5630 <title>msm/common.hpp</title> 5631 <para>This header provides one type, wrap, which is an empty type whose only reason 5632 to exist is to be cheap to construct, so that it can be used with mpl::for_each, 5633 as shown in the Metaprogramming book, chapter 9.</para> 5634 <classsynopsis> 5635 <ooclass> 5636 <classname>template <class Dummy> wrap{};</classname> 5637 </ooclass> 5638 </classsynopsis> 5639 </refsect1> 5640 <refsect1> 5641 <title>msm/row_tags.hpp</title> 5642 <para>This header contains the row type tags which front-ends can support partially 5643 or totally. Please see the <command xlink:href="#internals-front-back-interface" 5644 >Internals</command> section for a description of the different 5645 types.</para> 5646 </refsect1> 5647 </refentry> 5648 <refentry> 5649 <refnamediv> 5650 <refname>Back-end</refname> 5651 <refpurpose>The back-end headers</refpurpose> 5652 </refnamediv> 5653 <refsect1> 5654 <title>msm/back/state_machine.hpp</title> 5655 <para> This header provides one type, state_machine, MSM's state machine engine 5656 implementation.</para> 5657 <classsynopsis> 5658 <ooclass> 5659 <classname>template <class Derived,class HistoryPolicy=NoHistory,class 5660 CompilePolicy=favor_runtime_speed> state_machine</classname> 5661 </ooclass> 5662 </classsynopsis> 5663 <refsect2> 5664 <title> Template arguments </title> 5665 <refsect3> 5666 <title> Derived </title> 5667 <para>The name of the front-end state machine definition. All three 5668 front-ends are possible.</para> 5669 </refsect3> 5670 <refsect3> 5671 <title> HistoryPolicy </title> 5672 <para>The desired history. This can be: AlwaysHistory, NoHistory, 5673 ShallowHistory. Default is NoHistory.</para> 5674 </refsect3> 5675 <refsect3> 5676 <title> CompilePolicy </title> 5677 <para>The trade-off performance / compile-time. There are two predefined 5678 policies, favor_runtime_speed and favor_compile_time. Default is 5679 favor_runtime_speed, best performance, longer compile-time. See <link 5680 xlink:href="#backend-tradeof-rt-ct">the backend</link>.</para> 5681 </refsect3> 5682 </refsect2> 5683 <refsect2> 5684 <title> methods </title> 5685 <refsect3> 5686 <title>start</title> 5687 <para> The start methods must be called before any call to process_event. It 5688 activates the entry action of the initial state(s). This allows you to 5689 choose when a state machine can start. See <link 5690 xlink:href="#backend-start">backend</link>.</para> 5691 <methodsynopsis> 5692 <methodname>void start</methodname> 5693 <methodparam> 5694 <funcparams/> 5695 </methodparam> 5696 </methodsynopsis> 5697 </refsect3> 5698 <refsect3> 5699 <title>process_event</title> 5700 <para>The event processing method implements the double-dispatch. Each call 5701 to this function with a new event type instantiates a new dispatch 5702 algorithm and increases compile-time.</para> 5703 <methodsynopsis> 5704 <methodname>template <class Event> HandledEnum 5705 process_event</methodname> 5706 <methodparam> 5707 <funcparams>Event const&</funcparams> 5708 </methodparam> 5709 </methodsynopsis> 5710 </refsect3> 5711 <refsect3> 5712 <title>current_state</title> 5713 <para>Returns the ids of currently active states. You will typically need it 5714 only for debugging or logging purposes.</para> 5715 <methodsynopsis> 5716 <methodname>const int* current_state const</methodname> 5717 <methodparam> 5718 <funcparams/> 5719 </methodparam> 5720 </methodsynopsis> 5721 </refsect3> 5722 <refsect3> 5723 <title>get_state_by_id</title> 5724 <para>Returns the state whose id is given. As all states of a concrete state 5725 machine share a common base state, the return value is a base state. If 5726 the id corresponds to no state, a null pointer is returned.</para> 5727 <methodsynopsis> 5728 <methodname>const BaseState* get_state_by_id const</methodname> 5729 <methodparam> 5730 <funcparams>int id</funcparams> 5731 </methodparam> 5732 </methodsynopsis> 5733 </refsect3> 5734 <refsect3> 5735 <title>is_contained</title> 5736 <para>Helper returning true if the state machine is contained as a 5737 submachine of another state machine.</para> 5738 <methodsynopsis> 5739 <methodname>bool is_contained const</methodname> 5740 <methodparam> 5741 <funcparams/> 5742 </methodparam> 5743 </methodsynopsis> 5744 </refsect3> 5745 <refsect3> 5746 <title>get_state</title> 5747 <para>Returns the required state of the state machine as a pointer. A 5748 compile error will occur if the state is not to be found in the state 5749 machine.</para> 5750 <methodsynopsis> 5751 <methodname>template <class State> State* get_state</methodname> 5752 <methodparam> 5753 <funcparams/> 5754 </methodparam> 5755 </methodsynopsis> 5756 </refsect3> 5757 <refsect3> 5758 <title>get_state</title> 5759 <para>Returns the required state of the state machine as a reference. A 5760 compile error will occur if the state is not to be found in the state 5761 machine.</para> 5762 <methodsynopsis> 5763 <methodname>template <class State> State& get_state</methodname> 5764 <methodparam> 5765 <funcparams/> 5766 </methodparam> 5767 </methodsynopsis> 5768 </refsect3> 5769 <refsect3> 5770 <title>is_flag_active</title> 5771 <para>Returns true if the given flag is currently active. A flag is active 5772 if the active state of one region is tagged with this flag (using OR as 5773 BinaryOp) or active states of <emphasis role="underline">all</emphasis> 5774 regions (using AND as BinaryOp)</para> 5775 <methodsynopsis> 5776 <methodname>template <class Flag,class BinaryOp> bool 5777 is_flag_active</methodname> 5778 <methodparam> 5779 <funcparams/> 5780 </methodparam> 5781 </methodsynopsis> 5782 </refsect3> 5783 <refsect3> 5784 <title>is_flag_active</title> 5785 <para>Returns true if the given flag is currently active. A flag is active 5786 if the active state of one region is tagged with this flag.</para> 5787 <methodsynopsis> 5788 <methodname>template <class Flag> bool is_flag_active</methodname> 5789 <methodparam> 5790 <funcparams/> 5791 </methodparam> 5792 </methodsynopsis> 5793 </refsect3> 5794 <refsect3> 5795 <title>visit_current_states</title> 5796 <para>Visits all active states and their substates. A state is visited using 5797 the <code>accept</code> method without argument. The base class of all 5798 states must provide an <code>accept_sig</code> type.</para> 5799 <methodsynopsis> 5800 <methodname>void visit_current_states</methodname> 5801 <methodparam> 5802 <funcparams/> 5803 </methodparam> 5804 </methodsynopsis> 5805 </refsect3> 5806 <refsect3> 5807 <title>visit_current_states</title> 5808 <para>Visits all active states and their substates. A state is visited using 5809 the <code>accept</code> method with arguments. The base class of all 5810 states must provide an <code>accept_sig</code> type defining the 5811 signature and thus the number and type of the parameters.</para> 5812 <methodsynopsis> 5813 <methodname>void visit_current_states</methodname> 5814 <methodparam> 5815 <funcparams>any-type param1, any-type param2,...</funcparams> 5816 </methodparam> 5817 </methodsynopsis> 5818 </refsect3> 5819 <refsect3> 5820 <title>defer_event</title> 5821 <para> Defers the provided event. This method can be called only if at least 5822 one state defers an event or if the state machine provides the 5823 <code>activate_deferred_events</code>(see <link 5824 xlink:href="examples/Orthogonal-deferred2.cpp">example</link>) type 5825 either directly or using the deferred_events configuration of eUML 5826 (<code>configure_ << deferred_events</code>)</para> 5827 <methodsynopsis> 5828 <methodname>template <class Event> void defer_event</methodname> 5829 <methodparam> 5830 <funcparams>Event const&</funcparams> 5831 </methodparam> 5832 </methodsynopsis> 5833 </refsect3> 5834 </refsect2> 5835 <refsect2> 5836 <title>Types</title> 5837 <refsect3> 5838 <title>nr_regions </title> 5839 <para>The number of orthogonal regions contained in the state machine</para> 5840 </refsect3> 5841 <refsect3> 5842 <title>entry_pt</title> 5843 <para>This nested type provides the necessary typedef for entry point 5844 pseudostates. 5845 <code>state_machine<...>::entry_pt<state_name></code> is a 5846 transition's valid target inside the containing state machine's 5847 transition table.</para> 5848 <classsynopsis> 5849 <ooclass> 5850 <classname>entry_pt</classname> 5851 </ooclass> 5852 </classsynopsis> 5853 </refsect3> 5854 <refsect3> 5855 <title>exit_pt</title> 5856 <para>This nested type provides the necessary typedef for exit point 5857 pseudostates. <code>state_machine<...>::exit_pt<state_name></code> 5858 is a transition's valid source inside the containing state machine's 5859 transition table.</para> 5860 <classsynopsis> 5861 <ooclass> 5862 <classname>exit_pt</classname> 5863 </ooclass> 5864 </classsynopsis> 5865 </refsect3> 5866 <refsect3> 5867 <title>direct</title> 5868 <para>This nested type provides the necessary typedef for an explicit entry 5869 inside a submachine. 5870 <code>state_machine<...>::direct<state_name></code> is a 5871 transition's valid target inside the containing state machine's 5872 transition table.</para> 5873 <classsynopsis> 5874 <ooclass> 5875 <classname>direct</classname> 5876 </ooclass> 5877 </classsynopsis> 5878 </refsect3> 5879 <refsect3> 5880 <title>stt</title> 5881 <para>Calling state_machine<frontend>::stt returns a mpl::vector 5882 containing the transition table of the state machine. This type can then 5883 be used with generate_state_set or generate_event_set.</para> 5884 </refsect3> 5885 </refsect2> 5886 </refsect1> 5887 <refsect1> 5888 <title>args.hpp</title> 5889 <para>This header provides one type, args. which provides the necessary types for a 5890 visitor implementation.</para> 5891 </refsect1> 5892 <refsect1> 5893 <title><command xml:id="history-interface"/>msm/back/history_policies.hpp</title> 5894 <para>This header provides the out-of-the-box history policies supported by MSM. 5895 There are 3 such policies.</para> 5896 <refsect2> 5897 <title>Every history policy must implement the following methods: </title> 5898 <refsect3> 5899 <title> set_initial_states </title> 5900 <para> This method is called by msm::back::state_machine when constructed. 5901 It gives the policy a chance to save the ids of all initial states 5902 (passed as array).</para> 5903 <funcsynopsis> 5904 <funcprototype> 5905 <funcdef>void set_initial_states</funcdef> 5906 <paramdef> 5907 <funcparams>int* const</funcparams> 5908 </paramdef> 5909 </funcprototype> 5910 </funcsynopsis> 5911 </refsect3> 5912 <refsect3> 5913 <title> history_exit </title> 5914 <para>This method is called by msm::back::state_machine when the submachine 5915 is exited. It gives the policy a chance to remember the ids of the last 5916 active substates of this submachine (passed as array).</para> 5917 <funcsynopsis> 5918 <funcprototype> 5919 <funcdef>void history_exit</funcdef> 5920 <paramdef> 5921 <funcparams>int* const</funcparams> 5922 </paramdef> 5923 </funcprototype> 5924 </funcsynopsis> 5925 </refsect3> 5926 <refsect3> 5927 <title> history_entry </title> 5928 <para>This method is called by msm::back::state_machine when the submachine 5929 is entered. It gives the policy a chance to set the active states 5930 according to the policy's aim. The policy gets as parameter the event 5931 which activated the submachine and returns an array of active states 5932 ids.</para> 5933 <funcsynopsis> 5934 <funcprototype> 5935 <funcdef>template <class Event> int* const history_exit</funcdef> 5936 <paramdef> 5937 <funcparams>Event const&</funcparams> 5938 </paramdef> 5939 </funcprototype> 5940 </funcsynopsis> 5941 </refsect3> 5942 </refsect2> 5943 <refsect2> 5944 <title>Out-of-the-box policies: </title> 5945 <refsect3> 5946 <title>NoHistory</title> 5947 <para>This policy is the default used by state_machine. No active state of a 5948 submachine is remembered and at every new activation of the submachine, 5949 the initial state(s) are activated. </para> 5950 </refsect3> 5951 <refsect3> 5952 <title>AlwaysHistory</title> 5953 <para>This policy is a non-UML-standard extension. The active state(s) of a 5954 submachine is (are) always remembered at every new activation of the 5955 submachine. </para> 5956 </refsect3> 5957 <refsect3> 5958 <title>ShallowHistory</title> 5959 <para>This policy activates the active state(s) of a submachine if the event 5960 is found in the policy's event list. </para> 5961 </refsect3> 5962 </refsect2> 5963 </refsect1> 5964 <refsect1> 5965 <title>msm/back/default_compile_policy.hpp</title> 5966 <para>This header contains the definition of favor_runtime_speed. This policy has 5967 two settings:<itemizedlist> 5968 <listitem> 5969 <para>Submachines dispatch faster because their transitions are added 5970 into their containing machine's transition table instead of simply 5971 forwarding events.</para> 5972 </listitem> 5973 <listitem> 5974 <para>It solves transition conflicts at compile-time</para> 5975 </listitem> 5976 </itemizedlist></para> 5977 </refsect1> 5978 <refsect1> 5979 <title>msm/back/favor_compile_time.hpp</title> 5980 <para>This header contains the definition of favor_compile_time. This policy has two settings:<itemizedlist> 5981 <listitem> 5982 <para>Submachines dispatch is slower because all events, even those with 5983 no dispatch chance, are forwarded to submachines. In exchange, no 5984 row is added into the containing machine's transition table, which 5985 reduces compile-time.</para> 5986 </listitem> 5987 <listitem> 5988 <para>It solves transition conflicts at run-time.</para> 5989 </listitem> 5990 </itemizedlist></para> 5991 </refsect1> 5992 <refsect1> 5993 <title>msm/back/metafunctions.hpp </title> 5994 <para>This header contains metafunctions for use by the library. Three metafunctions 5995 can be useful for the user:<itemizedlist> 5996 <listitem> 5997 <para><code>generate_state_set< stt ></code>: generates the list of 5998 all states referenced by the transition table stt. If stt is a 5999 recursive table (generated by 6000 <code>recursive_get_transition_table</code>), the metafunction 6001 finds recursively all states of the submachines. A non-recursive 6002 table can be obtained with some_backend_fsm::stt.</para> 6003 </listitem> 6004 <listitem> 6005 <para><code>generate_event_set< stt></code>: generates the list of 6006 all events referenced by the transition table stt. If stt is a 6007 recursive table (generated by 6008 <code>recursive_get_transition_table</code>), the metafunction 6009 finds recursively all events of the submachines. A non-recursive 6010 table can be obtained with some_backend_fsm::stt.</para> 6011 </listitem> 6012 <listitem> 6013 <para><code>recursive_get_transition_table<fsm></code>: recursively 6014 extends the transition table of the state machine fsm with tables 6015 from the submachines.</para> 6016 </listitem> 6017 </itemizedlist></para> 6018 </refsect1> 6019 <refsect1> 6020 <title>msm/back/tools.hpp </title> 6021 <para> This header contains a few metaprogramming tools to get some information out 6022 of a state machine.</para> 6023 <refsect2> 6024 <title>fill_state_names </title> 6025 <refsect3> 6026 <title>attributes </title> 6027 <para> fill_state_names has for attribute:<itemizedlist> 6028 <listitem> 6029 <para><code>char const** m_names</code>: an already allocated 6030 array of const char* where the typeid-generated names of a 6031 state machine states will be witten.</para> 6032 </listitem> 6033 </itemizedlist></para> 6034 </refsect3> 6035 <refsect3> 6036 <title>constructor </title> 6037 <constructorsynopsis> 6038 <methodparam> 6039 <funcparams>char const** names_to_fill</funcparams> 6040 </methodparam> 6041 </constructorsynopsis> 6042 </refsect3> 6043 <refsect3> 6044 <title>usage</title> 6045 <para> fill_state_names is made for use in a mpl::for_each iterating on a 6046 state list and writing inside a pre-allocated array the state names. 6047 Example:</para> 6048 <programlisting>typedef some_fsm::stt Stt; 6049typedef msm::back::generate_state_set<Stt>::type all_states; //states 6050static char const* state_names[mpl::size<all_states>::value]; 6051// array to fill with names 6052// fill the names of the states defined in the state machine 6053mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> > 6054 (msm::back::fill_state_names<Stt>(state_names)); 6055// display all active states 6056for (unsigned int i=0;i<some_fsm::nr_regions::value;++i) 6057{ 6058 std::cout << " -> " 6059 << state_names[my_fsm_instance.current_state()[i]] 6060 << std::endl; 6061}</programlisting> 6062 </refsect3> 6063 </refsect2> 6064 <refsect2> 6065 <title>get_state_name </title> 6066 <refsect3> 6067 <title> attributes </title> 6068 <para>get_state_name has for attributes:<itemizedlist> 6069 <listitem> 6070 <para>std::string& m_name: the return value of the 6071 iteration</para> 6072 </listitem> 6073 <listitem> 6074 <para>int m_state_id: the searched state's id</para> 6075 </listitem> 6076 </itemizedlist></para> 6077 </refsect3> 6078 <refsect3> 6079 <title>constructor</title> 6080 <para>The constructor takes as argument a reference to the string to fill 6081 with the state name and the id which must be searched.</para> 6082 <constructorsynopsis> 6083 <methodparam> 6084 <funcparams>string& name_to_fill,int state_id</funcparams> 6085 </methodparam> 6086 </constructorsynopsis> 6087 </refsect3> 6088 <refsect3> 6089 <title> usage</title> 6090 <para>This type is made for the same search as in the previous example, 6091 using a mpl::for_each to iterate on states. After the iteration, the 6092 state name reference has been set.</para> 6093 <programlisting>// we need a fsm's table 6094typedef player::stt Stt; 6095typedef msm::back::generate_state_set<Stt>::type all_states; //all states 6096std::string name_of_open; // id of Open is 1 6097// fill name_of_open for state of id 1 6098boost::mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> > 6099 (msm::back::get_state_name<Stt>(name_of_open,1)); 6100std::cout << "typeid-generated name Open is: " << name_of_open << std::endl;</programlisting> 6101 </refsect3> 6102 </refsect2> 6103 <refsect2> 6104 <title>display_type </title> 6105 <refsect3> 6106 <title> attributes </title> 6107 <para>none</para> 6108 </refsect3> 6109 <refsect3> 6110 <title> usage</title> 6111 <para>Reusing the state list from the previous example, we can output all 6112 state names:</para> 6113 <para><code>mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> 6114 >(msm::back::display_type ());</code></para> 6115 </refsect3> 6116 </refsect2> 6117 </refsect1> 6118 </refentry> 6119 <refentry> 6120 <refnamediv> 6121 <refname>Front-end</refname> 6122 <refpurpose>The front-end headers</refpurpose> 6123 </refnamediv> 6124 <refsect1> 6125 <title>msm/front/common_states.hpp</title> 6126 <para>This header contains the predefined types to serve as base for states or state machines:<itemizedlist> 6127 <listitem> 6128 <para>default_base_state: non-polymorphic empty type.</para> 6129 </listitem> 6130 <listitem> 6131 <para>polymorphic_state: type with a virtual destructor, which makes all 6132 states polymorphic.</para> 6133 </listitem> 6134 </itemizedlist></para> 6135 </refsect1> 6136 <refsect1> 6137 <title>msm/front/completion_event.hpp</title> 6138 <para>This header contains one type, <code>none</code>. This type has several 6139 meanings inside a transition table:<itemizedlist> 6140 <listitem> 6141 <para>as action or guard: that there is no action or guard</para> 6142 </listitem> 6143 <listitem> 6144 <para>as target state: that the transition is an internal 6145 transition</para> 6146 </listitem> 6147 <listitem> 6148 <para>as event: the transition is an anonymous (completion) 6149 transition</para> 6150 </listitem> 6151 </itemizedlist></para> 6152 </refsect1> 6153 <refsect1> 6154 <title>msm/front/functor_row.hpp</title> 6155 <para>This header implements the functor front-end's transitions and helpers.</para> 6156 <refsect2> 6157 <title>Row</title> 6158 <refsect3> 6159 <title>definition</title> 6160 <classsynopsis> 6161 <ooclass> 6162 <classname>template <class Source,class Event,class Target,class 6163 Action,class Guard> Row</classname> 6164 </ooclass> 6165 </classsynopsis> 6166 </refsect3> 6167 <refsect3> 6168 <title>tags</title> 6169 <para>row_type_tag is defined differently for every specialization:<itemizedlist> 6170 <listitem> 6171 <para>all 5 template parameters means a normal transition with 6172 action and guard: <code>typedef row_tag 6173 row_type_tag;</code></para> 6174 </listitem> 6175 <listitem> 6176 <para>Row<Source,Event,Target,none,none> a normal transition 6177 without action or guard: <code>typedef _row_tag 6178 row_type_tag;</code></para> 6179 </listitem> 6180 <listitem> 6181 <para>Row<Source,Event,Target,Action,none> a normal 6182 transition without guard: <code>typedef a_row_tag 6183 row_type_tag;</code></para> 6184 </listitem> 6185 <listitem> 6186 <para>Row<Source,Event,Target,none,Guard> a normal transition 6187 without action: <code>typedef g_row_tag 6188 row_type_tag;</code></para> 6189 </listitem> 6190 <listitem> 6191 <para>Row<Source,Event,none,Action,none> an internal 6192 transition without guard: <code>typedef a_irow_tag 6193 row_type_tag;</code></para> 6194 </listitem> 6195 <listitem> 6196 <para>Row<Source,Event,none,none,Guard> an internal 6197 transition without action: <code>typedef g_irow_tag 6198 row_type_tag;</code></para> 6199 </listitem> 6200 <listitem> 6201 <para>Row<Source,Event,none,none,Guard> an internal 6202 transition with action and guard: <code>typedef irow_tag 6203 row_type_tag;</code></para> 6204 </listitem> 6205 <listitem> 6206 <para>Row<Source,Event,none,none,none> an internal transition 6207 without action or guard: <code>typedef _irow_tag 6208 row_type_tag;</code></para> 6209 </listitem> 6210 </itemizedlist></para> 6211 </refsect3> 6212 <refsect3> 6213 <title>methods</title> 6214 <para>Like any other front-end, Row implements the two necessary static 6215 functions for action and guard call. Each function receives as parameter 6216 the (deepest-level) state machine processsing the event, the event 6217 itself, the source and target states and all the states contained in a 6218 state machine.</para> 6219 <funcsynopsis> 6220 <funcprototype> 6221 <funcdef>template <class Fsm,class SourceState,class TargetState, 6222 class AllStates> static void action_call</funcdef> 6223 <paramdef> 6224 <funcparams>Fsm& fsm,Event const& 6225 evt,SourceState&,TargetState,AllStates&</funcparams> 6226 </paramdef> 6227 </funcprototype> 6228 </funcsynopsis> 6229 <funcsynopsis> 6230 <funcprototype> 6231 <funcdef>template <class Fsm,class SourceState,class TargetState, 6232 class AllStates> static bool guard_call</funcdef> 6233 <paramdef> 6234 <funcparams>Fsm& fsm,Event const& 6235 evt,SourceState&,TargetState,AllStates&</funcparams> 6236 </paramdef> 6237 </funcprototype> 6238 </funcsynopsis> 6239 </refsect3> 6240 </refsect2> 6241 <refsect2> 6242 <title>Internal</title> 6243 <refsect3> 6244 <title>definition</title> 6245 <classsynopsis> 6246 <ooclass> 6247 <classname>template <class Event,class Action,class Guard> 6248 Internal</classname> 6249 </ooclass> 6250 </classsynopsis> 6251 </refsect3> 6252 <refsect3> 6253 <title>tags</title> 6254 <para>row_type_tag is defined differently for every specialization:<itemizedlist> 6255 <listitem> 6256 <para>all 3 template parameters means an internal transition 6257 with action and guard: <code>typedef sm_i_row_tag 6258 row_type_tag;</code></para> 6259 </listitem> 6260 <listitem> 6261 <para>Internal<Event,none,none> an internal transition 6262 without action or guard: <code>typedef sm__i_row_tag 6263 row_type_tag;</code></para> 6264 </listitem> 6265 <listitem> 6266 <para>Internal<Event,Action,none> an internal transition 6267 without guard: <code>typedef sm_a_i_row_tag 6268 row_type_tag;</code></para> 6269 </listitem> 6270 <listitem> 6271 <para>Internal<Event,none,Guard> an internal transition 6272 without action: <code>typedef sm_g_i_row_tag 6273 row_type_tag;</code></para> 6274 </listitem> 6275 </itemizedlist></para> 6276 </refsect3> 6277 <refsect3> 6278 <title>methods</title> 6279 <para>Like any other front-end, Internal implements the two necessary static 6280 functions for action and guard call. Each function receives as parameter 6281 the (deepest-level) state machine processsing the event, the event 6282 itself, the source and target states and all the states contained in a 6283 state machine.</para> 6284 <funcsynopsis> 6285 <funcprototype> 6286 <funcdef>template <class Fsm,class SourceState,class TargetState, 6287 class AllStates> static void action_call</funcdef> 6288 <paramdef> 6289 <funcparams>Fsm& fsm,Event const& 6290 evt,SourceState&,TargetState,AllStates&</funcparams> 6291 </paramdef> 6292 </funcprototype> 6293 </funcsynopsis> 6294 <funcsynopsis> 6295 <funcprototype> 6296 <funcdef>template <class Fsm,class SourceState,class TargetState, 6297 class AllStates> static bool guard_call</funcdef> 6298 <paramdef> 6299 <funcparams>Fsm& fsm,Event const& 6300 evt,SourceState&,TargetState,AllStates&</funcparams> 6301 </paramdef> 6302 </funcprototype> 6303 </funcsynopsis> 6304 </refsect3> 6305 </refsect2> 6306 <refsect2> 6307 <title>ActionSequence_</title> 6308 <para>This functor calls every element of the template Sequence (which are also 6309 callable functors) in turn. It is also the underlying implementation of the 6310 eUML sequence grammar (action1,action2,...).</para> 6311 <refsect3> 6312 <title>definition</title> 6313 <classsynopsis> 6314 <ooclass> 6315 <classname>template <class Sequence> ActionSequence_</classname> 6316 </ooclass> 6317 </classsynopsis> 6318 </refsect3> 6319 <refsect3> 6320 <title>methods</title> 6321 <para>This helper functor is made for use in a transition table and in a 6322 state behavior and therefore implements an operator() with 3 and with 4 6323 arguments:</para> 6324 <para> 6325 <funcsynopsis> 6326 <funcprototype> 6327 <funcdef>template <class Evt,class Fsm,class 6328 SourceState,class TargetState> operator()</funcdef> 6329 <paramdef>Evt const& ,Fsm& ,SourceState& 6330 ,TargetState& </paramdef> 6331 </funcprototype> 6332 </funcsynopsis> 6333 </para> 6334 <para> 6335 <funcsynopsis> 6336 <funcprototype> 6337 <funcdef>template <class Evt,class Fsm,class State> 6338 operator()</funcdef> 6339 <paramdef>Evt const&, Fsm&, State&</paramdef> 6340 </funcprototype> 6341 </funcsynopsis> 6342 </para> 6343 </refsect3> 6344 </refsect2> 6345 <refsect2> 6346 <title>Defer</title> 6347 <refsect3> 6348 <title>definition</title> 6349 <classsynopsis> 6350 <ooclass> 6351 <classname>Defer</classname> 6352 </ooclass> 6353 </classsynopsis> 6354 </refsect3> 6355 <refsect3> 6356 <title>methods</title> 6357 <para>This helper functor is made for use in a transition table and 6358 therefore implements an operator() with 4 arguments:</para> 6359 <funcsynopsis> 6360 <funcprototype> 6361 <funcdef>template <class Evt,class Fsm,class SourceState,class 6362 TargetState> operator()</funcdef> 6363 <paramdef>Evt const&, Fsm& , SourceState&, 6364 TargetState&</paramdef> 6365 </funcprototype> 6366 </funcsynopsis> 6367 </refsect3> 6368 </refsect2> 6369 </refsect1> 6370 <refsect1> 6371 <title>msm/front/internal_row.hpp</title> 6372 <para>This header implements the internal transition rows for use inside an 6373 internal_transition_table. All these row types have no source or target state, 6374 as the backend will recognize internal transitions from this 6375 internal_transition_table.</para> 6376 <refsect2> 6377 <title>methods</title> 6378 <para>Like any other front-end, the following transition row types implements 6379 the two necessary static functions for action and guard call. Each function 6380 receives as parameter the (deepest-level) state machine processsing the 6381 event, the event itself, the source and target states and all the states 6382 contained in a state machine.</para> 6383 <funcsynopsis> 6384 <funcprototype> 6385 <funcdef>template <class Fsm,class SourceState,class TargetState, 6386 class AllStates> static void action_call</funcdef> 6387 <paramdef> 6388 <funcparams>Fsm& fsm,Event const& 6389 evt,SourceState&,TargetState,AllStates&</funcparams> 6390 </paramdef> 6391 </funcprototype> 6392 </funcsynopsis> 6393 <funcsynopsis> 6394 <funcprototype> 6395 <funcdef>template <class Fsm,class SourceState,class TargetState, 6396 class AllStates> static bool guard_call</funcdef> 6397 <paramdef> 6398 <funcparams>Fsm& fsm,Event const& 6399 evt,SourceState&,TargetState,AllStates&</funcparams> 6400 </paramdef> 6401 </funcprototype> 6402 </funcsynopsis> 6403 </refsect2> 6404 <refsect2> 6405 <title>a_internal</title> 6406 <refsect3> 6407 <title>definition</title> 6408 <para>This is an internal transition with an action called during the 6409 transition.</para> 6410 <classsynopsis> 6411 <ooclass> 6412 <classname>template< class Event, class CalledForAction, void 6413 (CalledForAction::*action)(Event const&)> 6414 a_internal</classname> 6415 </ooclass> 6416 </classsynopsis> 6417 </refsect3> 6418 <refsect3> 6419 <title>template parameters</title> 6420 <para> 6421 <itemizedlist> 6422 <listitem> 6423 <para>Event: the event triggering the internal 6424 transition.</para> 6425 </listitem> 6426 <listitem> 6427 <para>CalledForAction: the type on which the action method will 6428 be called. It can be either a state of the containing state 6429 machine or the state machine itself.</para> 6430 </listitem> 6431 <listitem> 6432 <para>action: a pointer to the method which CalledForAction 6433 provides.</para> 6434 </listitem> 6435 </itemizedlist> 6436 </para> 6437 </refsect3> 6438 </refsect2> 6439 <refsect2> 6440 <title>g_internal</title> 6441 <para>This is an internal transition with a guard called before the transition 6442 and allowing the transition if returning true.</para> 6443 <refsect3> 6444 <title>definition</title> 6445 <classsynopsis> 6446 <ooclass> 6447 <classname>template< class Event, class CalledForGuard, bool 6448 (CalledForGuard::*guard)(Event const&)> 6449 g_internal</classname> 6450 </ooclass> 6451 </classsynopsis> 6452 </refsect3> 6453 <refsect3> 6454 <title>template parameters</title> 6455 <para> 6456 <itemizedlist> 6457 <listitem> 6458 <para>Event: the event triggering the internal 6459 transition.</para> 6460 </listitem> 6461 <listitem> 6462 <para>CalledForGuard: the type on which the guard method will be 6463 called. It can be either a state of the containing state 6464 machine or the state machine itself.</para> 6465 </listitem> 6466 <listitem> 6467 <para>guard: a pointer to the method which CalledForGuard 6468 provides.</para> 6469 </listitem> 6470 </itemizedlist> 6471 </para> 6472 </refsect3> 6473 </refsect2> 6474 <refsect2> 6475 <title>internal</title> 6476 <para>This is an internal transition with a guard called before the transition 6477 and allowing the transition if returning true. It also calls an action 6478 called during the transition.</para> 6479 <refsect3> 6480 <title>definition</title> 6481 <classsynopsis> 6482 <ooclass> 6483 <classname>template< class Event, class CalledForAction, void 6484 (CalledForAction::*action)(Event const&), class 6485 CalledForGuard, bool (CalledForGuard::*guard)(Event const&)> 6486 internal</classname> 6487 </ooclass> 6488 </classsynopsis> 6489 </refsect3> 6490 <refsect3> 6491 <title>template parameters</title> 6492 <para> 6493 <itemizedlist> 6494 <listitem> 6495 <para>Event: the event triggering the internal transition</para> 6496 </listitem> 6497 <listitem> 6498 <para>CalledForAction: the type on which the action method will 6499 be called. It can be either a state of the containing state 6500 machine or the state machine itself.</para> 6501 </listitem> 6502 <listitem> 6503 <para>action: a pointer to the method which CalledForAction 6504 provides.</para> 6505 </listitem> 6506 <listitem> 6507 <para>CalledForGuard: the type on which the guard method will be 6508 called. It can be either a state of the containing state 6509 machine or the state machine itself.</para> 6510 </listitem> 6511 <listitem> 6512 <para>guard: a pointer to the method which CalledForGuard 6513 provides.</para> 6514 </listitem> 6515 </itemizedlist> 6516 </para> 6517 </refsect3> 6518 </refsect2> 6519 <refsect2> 6520 <title>_internal</title> 6521 <para>This is an internal transition without action or guard. This is equivalent 6522 to an explicit "ignore event".</para> 6523 <refsect3> 6524 <title>definition</title> 6525 <classsynopsis> 6526 <ooclass> 6527 <classname>template< class Event > _internal</classname> 6528 </ooclass> 6529 </classsynopsis> 6530 </refsect3> 6531 <refsect3> 6532 <title>template parameters</title> 6533 <para> 6534 <itemizedlist> 6535 <listitem> 6536 <para>Event: the event triggering the internal 6537 transition.</para> 6538 </listitem> 6539 </itemizedlist> 6540 </para> 6541 </refsect3> 6542 </refsect2> 6543 </refsect1> 6544 <refsect1> 6545 <title>msm/front/row2.hpp</title> 6546 <para>This header contains the variants of row2, which are an extension of the 6547 standard row transitions for use in the transition table. They offer the 6548 possibility to define action and guard not only in the state machine, but in any 6549 state of the state machine. They can also be used in internal transition tables 6550 through their irow2 variants.</para> 6551 <refsect2> 6552 <title>methods</title> 6553 <para>Like any other front-end, the following transition row types implements 6554 the two necessary static functions for action and guard call. Each function 6555 receives as parameter the (deepest-level) state machine processsing the 6556 event, the event itself, the source and target states and all the states 6557 contained in a state machine.</para> 6558 <funcsynopsis> 6559 <funcprototype> 6560 <funcdef>template <class Fsm,class SourceState,class TargetState, 6561 class AllStates> static void action_call</funcdef> 6562 <paramdef> 6563 <funcparams>Fsm& fsm,Event const& 6564 evt,SourceState&,TargetState,AllStates&</funcparams> 6565 </paramdef> 6566 </funcprototype> 6567 </funcsynopsis> 6568 <funcsynopsis> 6569 <funcprototype> 6570 <funcdef>template <class Fsm,class SourceState,class TargetState, 6571 class AllStates> static bool guard_call</funcdef> 6572 <paramdef> 6573 <funcparams>Fsm& fsm,Event const& 6574 evt,SourceState&,TargetState,AllStates&</funcparams> 6575 </paramdef> 6576 </funcprototype> 6577 </funcsynopsis> 6578 </refsect2> 6579 <refsect2> 6580 <title>_row2</title> 6581 <para>This is a transition without action or guard. The state machine only 6582 changes active state.</para> 6583 <refsect3> 6584 <title>definition</title> 6585 <classsynopsis> 6586 <ooclass> 6587 <classname>template< class Source, class Event, class Target > 6588 _row2</classname> 6589 </ooclass> 6590 </classsynopsis> 6591 </refsect3> 6592 <refsect3> 6593 <title>template parameters</title> 6594 <para> 6595 <itemizedlist> 6596 <listitem> 6597 <para>Event: the event triggering the transition.</para> 6598 </listitem> 6599 <listitem> 6600 <para>Source: the source state of the transition.</para> 6601 </listitem> 6602 <listitem> 6603 <para>Target: the target state of the transition.</para> 6604 </listitem> 6605 </itemizedlist> 6606 </para> 6607 </refsect3> 6608 </refsect2> 6609 <refsect2> 6610 <title>a_row2</title> 6611 <para>This is a transition with action and without guard.</para> 6612 <refsect3> 6613 <title>definition</title> 6614 <classsynopsis> 6615 <ooclass> 6616 <classname>template< class Source, class Event, class Target, 6617 </classname> 6618 </ooclass> 6619 </classsynopsis> 6620 <classsynopsis> 6621 <ooclass> 6622 <classname>class CalledForAction, void 6623 (CalledForAction::*action)(Event const&) > _row2</classname> 6624 </ooclass> 6625 </classsynopsis> 6626 </refsect3> 6627 <refsect3> 6628 <title>template parameters</title> 6629 <para> 6630 <itemizedlist> 6631 <listitem> 6632 <para>Event: the event triggering the transition.</para> 6633 </listitem> 6634 <listitem> 6635 <para>Source: the source state of the transition.</para> 6636 </listitem> 6637 <listitem> 6638 <para>Target: the target state of the transition.</para> 6639 </listitem> 6640 <listitem> 6641 <para>CalledForAction: the type on which the action method will 6642 be called. It can be either a state of the containing state 6643 machine or the state machine itself.</para> 6644 </listitem> 6645 <listitem> 6646 <para>action: a pointer to the method which CalledForAction 6647 provides.</para> 6648 </listitem> 6649 </itemizedlist> 6650 </para> 6651 </refsect3> 6652 </refsect2> 6653 <refsect2> 6654 <title>g_row2</title> 6655 <para>This is a transition with guard and without action.</para> 6656 <refsect3> 6657 <title>definition</title> 6658 <classsynopsis> 6659 <ooclass> 6660 <classname>template< class Source, class Event, class Target, 6661 </classname> 6662 </ooclass> 6663 </classsynopsis> 6664 <classsynopsis> 6665 <ooclass> 6666 <classname>class CalledForGuard, bool (CalledForGuard::*guard)(Event 6667 const&) > _row2</classname> 6668 </ooclass> 6669 </classsynopsis> 6670 </refsect3> 6671 <refsect3> 6672 <title>template parameters</title> 6673 <para> 6674 <itemizedlist> 6675 <listitem> 6676 <para>Event: the event triggering the transition.</para> 6677 </listitem> 6678 <listitem> 6679 <para>Source: the source state of the transition.</para> 6680 </listitem> 6681 <listitem> 6682 <para>Target: the target state of the transition.</para> 6683 </listitem> 6684 <listitem> 6685 <para>CalledForGuard: the type on which the guard method will be 6686 called. It can be either a state of the containing state 6687 machine or the state machine itself.</para> 6688 </listitem> 6689 <listitem> 6690 <para>guard: a pointer to the method which CalledForGuard 6691 provides.</para> 6692 </listitem> 6693 </itemizedlist> 6694 </para> 6695 </refsect3> 6696 </refsect2> 6697 <refsect2> 6698 <title>row2</title> 6699 <para>This is a transition with guard and action.</para> 6700 <refsect3> 6701 <title>definition</title> 6702 <classsynopsis> 6703 <ooclass> 6704 <classname>template< class Source, class Event, class Target, 6705 </classname> 6706 </ooclass> 6707 </classsynopsis> 6708 <classsynopsis> 6709 <ooclass> 6710 <classname>class CalledForAction, void 6711 (CalledForAction::*action)(Event const&), </classname> 6712 </ooclass> 6713 </classsynopsis> 6714 <classsynopsis> 6715 <ooclass> 6716 <classname>class CalledForGuard, bool (CalledForGuard::*guard)(Event 6717 const&) > _row2</classname> 6718 </ooclass> 6719 </classsynopsis> 6720 </refsect3> 6721 <refsect3> 6722 <title>template parameters</title> 6723 <para> 6724 <itemizedlist> 6725 <listitem> 6726 <para>Event: the event triggering the transition.</para> 6727 </listitem> 6728 <listitem> 6729 <para>Source: the source state of the transition.</para> 6730 </listitem> 6731 <listitem> 6732 <para>Target: the target state of the transition.</para> 6733 </listitem> 6734 <listitem> 6735 <para>CalledForAction: the type on which the action method will 6736 be called. It can be either a state of the containing state 6737 machine or the state machine itself.</para> 6738 </listitem> 6739 <listitem> 6740 <para>action: a pointer to the method which CalledForAction 6741 provides.</para> 6742 </listitem> 6743 <listitem> 6744 <para>CalledForGuard: the type on which the guard method will be 6745 called. It can be either a state of the containing state 6746 machine or the state machine itself.</para> 6747 </listitem> 6748 <listitem> 6749 <para>guard: a pointer to the method which CalledForGuard 6750 provides.</para> 6751 </listitem> 6752 </itemizedlist> 6753 </para> 6754 </refsect3> 6755 </refsect2> 6756 <refsect2> 6757 <title>a_irow2</title> 6758 <para>This is an internal transition for use inside a transition table, with 6759 action and without guard.</para> 6760 <refsect3> 6761 <title>definition</title> 6762 <classsynopsis> 6763 <ooclass> 6764 <classname>template< class Source, class Event, </classname> 6765 </ooclass> 6766 </classsynopsis> 6767 <classsynopsis> 6768 <ooclass> 6769 <classname>class CalledForAction, void 6770 (CalledForAction::*action)(Event const&) > _row2</classname> 6771 </ooclass> 6772 </classsynopsis> 6773 </refsect3> 6774 <refsect3> 6775 <title>template parameters</title> 6776 <para> 6777 <itemizedlist> 6778 <listitem> 6779 <para>Event: the event triggering the transition.</para> 6780 </listitem> 6781 <listitem> 6782 <para>Source: the source state of the transition.</para> 6783 </listitem> 6784 <listitem> 6785 <para>CalledForAction: the type on which the action method will 6786 be called. It can be either a state of the containing state 6787 machine or the state machine itself.</para> 6788 </listitem> 6789 <listitem> 6790 <para>action: a pointer to the method which CalledForAction 6791 provides.</para> 6792 </listitem> 6793 </itemizedlist> 6794 </para> 6795 </refsect3> 6796 </refsect2> 6797 <refsect2> 6798 <title>g_irow2</title> 6799 <para>This is an internal transition for use inside a transition table, with 6800 guard and without action.</para> 6801 <refsect3> 6802 <title>definition</title> 6803 <classsynopsis> 6804 <ooclass> 6805 <classname>template< class Source, class Event, </classname> 6806 </ooclass> 6807 </classsynopsis> 6808 <classsynopsis> 6809 <ooclass> 6810 <classname>class CalledForGuard, bool (CalledForGuard::*guard)(Event 6811 const&) > _row2</classname> 6812 </ooclass> 6813 </classsynopsis> 6814 </refsect3> 6815 <refsect3> 6816 <title>template parameters</title> 6817 <para> 6818 <itemizedlist> 6819 <listitem> 6820 <para>Event: the event triggering the transition.</para> 6821 </listitem> 6822 <listitem> 6823 <para>Source: the source state of the transition.</para> 6824 </listitem> 6825 <listitem> 6826 <para>CalledForGuard: the type on which the guard method will be 6827 called. It can be either a state of the containing state 6828 machine or the state machine itself.</para> 6829 </listitem> 6830 <listitem> 6831 <para>guard: a pointer to the method which CalledForGuard 6832 provides.</para> 6833 </listitem> 6834 </itemizedlist> 6835 </para> 6836 </refsect3> 6837 </refsect2> 6838 <refsect2> 6839 <title>irow2</title> 6840 <para>This is an internal transition for use inside a transition table, with 6841 guard and action.</para> 6842 <refsect3> 6843 <title>definition</title> 6844 <classsynopsis> 6845 <ooclass> 6846 <classname>template< class Source, class Event, </classname> 6847 </ooclass> 6848 </classsynopsis> 6849 <classsynopsis> 6850 <ooclass> 6851 <classname>class CalledForAction, void 6852 (CalledForAction::*action)(Event const&), </classname> 6853 </ooclass> 6854 </classsynopsis> 6855 <classsynopsis> 6856 <ooclass> 6857 <classname>class CalledForGuard, bool (CalledForGuard::*guard)(Event 6858 const&) > _row2</classname> 6859 </ooclass> 6860 </classsynopsis> 6861 </refsect3> 6862 <refsect3> 6863 <title>template parameters</title> 6864 <para> 6865 <itemizedlist> 6866 <listitem> 6867 <para>Event: the event triggering the transition.</para> 6868 </listitem> 6869 <listitem> 6870 <para>Source: the source state of the transition.</para> 6871 </listitem> 6872 <listitem> 6873 <para>CalledForAction: the type on which the action method will 6874 be called. It can be either a state of the containing state 6875 machine or the state machine itself.</para> 6876 </listitem> 6877 <listitem> 6878 <para>action: a pointer to the method which CalledForAction 6879 provides.</para> 6880 </listitem> 6881 <listitem> 6882 <para>CalledForGuard: the type on which the guard method will be 6883 called. It can be either a state of the containing state 6884 machine or the state machine itself.</para> 6885 </listitem> 6886 <listitem> 6887 <para>guard: a pointer to the method which CalledForGuard 6888 provides.</para> 6889 </listitem> 6890 </itemizedlist> 6891 </para> 6892 </refsect3> 6893 </refsect2> 6894 </refsect1> 6895 <refsect1> 6896 <title>msm/front/state_machine_def.hpp</title> 6897 <para>This header provides the implementation of the <command 6898 xlink:href="#basic-front-end">basic front-end</command>. It contains one 6899 type, <code>state_machine_def</code></para> 6900 <refsect2> 6901 <title>state_machine_def definition</title> 6902 <para>This type is the basic class for a basic (or possibly any other) 6903 front-end. It provides the standard row types (which includes internal 6904 transitions) and a default implementation of the required methods and 6905 typedefs.</para> 6906 <classsynopsis> 6907 <ooclass> 6908 <classname>template <class Derived,class BaseState = 6909 default_base_state> state_machine_def</classname> 6910 </ooclass> 6911 </classsynopsis> 6912 <refsect3> 6913 <title>typedefs</title> 6914 <para> 6915 <itemizedlist> 6916 <listitem> 6917 <para>flag_list: by default, no flag is set in the state 6918 machine</para> 6919 </listitem> 6920 <listitem> 6921 <para>deferred_events: by default, no event is deferred.</para> 6922 </listitem> 6923 <listitem> 6924 <para>configuration: by default, no configuration customization 6925 is done.</para> 6926 </listitem> 6927 </itemizedlist> 6928 </para> 6929 </refsect3> 6930 <refsect3> 6931 <title>row methods</title> 6932 <para>Like any other front-end, the following transition row types 6933 implements the two necessary static functions for action and guard call. 6934 Each function receives as parameter the (deepest-level) state machine 6935 processsing the event, the event itself, the source and target states 6936 and all the states contained in a state machine (ignored).</para> 6937 <funcsynopsis> 6938 <funcprototype> 6939 <funcdef>template <class Fsm,class SourceState,class TargetState, 6940 class AllStates> static void action_call</funcdef> 6941 <paramdef> 6942 <funcparams>Fsm& fsm,Event const& 6943 evt,SourceState&,TargetState,AllStates&</funcparams> 6944 </paramdef> 6945 </funcprototype> 6946 </funcsynopsis> 6947 <funcsynopsis> 6948 <funcprototype> 6949 <funcdef>template <class Fsm,class SourceState,class TargetState, 6950 class AllStates> static bool guard_call</funcdef> 6951 <paramdef> 6952 <funcparams>Fsm& fsm,Event const& 6953 evt,SourceState&,TargetState,AllStates&</funcparams> 6954 </paramdef> 6955 </funcprototype> 6956 </funcsynopsis> 6957 </refsect3> 6958 <refsect3> 6959 <title>a_row</title> 6960 <para>This is a transition with action and without guard.</para> 6961 <para><ooclass> 6962 <classname>template< class Source, class Event, class Target, 6963 void (Derived::*action)(Event const&) > a_row</classname> 6964 </ooclass><itemizedlist> 6965 <listitem> 6966 <para>Event: the event triggering the transition.</para> 6967 </listitem> 6968 <listitem> 6969 <para>Source: the source state of the transition.</para> 6970 </listitem> 6971 <listitem> 6972 <para>Target: the target state of the transition.</para> 6973 </listitem> 6974 <listitem> 6975 <para>action: a pointer to the method provided by the concrete 6976 front-end (represented by <code>Derived</code>).</para> 6977 </listitem> 6978 </itemizedlist></para> 6979 </refsect3> 6980 <refsect3> 6981 <title>g_row</title> 6982 <para>This is a transition with guard and without action.</para> 6983 <para><ooclass> 6984 <classname>template< class Source, class Event, class Target, 6985 bool (Derived::*guard)(Event const&) > g_row</classname> 6986 </ooclass><itemizedlist> 6987 <listitem> 6988 <para>Event: the event triggering the transition.</para> 6989 </listitem> 6990 <listitem> 6991 <para>Source: the source state of the transition.</para> 6992 </listitem> 6993 <listitem> 6994 <para>Target: the target state of the transition.</para> 6995 </listitem> 6996 <listitem> 6997 <para>guard: a pointer to the method provided by the concrete 6998 front-end (represented by <code>Derived</code>).</para> 6999 </listitem> 7000 </itemizedlist></para> 7001 </refsect3> 7002 <refsect3> 7003 <title>row</title> 7004 <para>This is a transition with guard and action.</para> 7005 <para><ooclass> 7006 <classname>template< class Source, class Event, class Target, 7007 void (Derived::*action)(Event const&), bool 7008 (Derived::*guard)(Event const&) > row</classname> 7009 </ooclass><itemizedlist> 7010 <listitem> 7011 <para>Event: the event triggering the transition.</para> 7012 </listitem> 7013 <listitem> 7014 <para>Source: the source state of the transition.</para> 7015 </listitem> 7016 <listitem> 7017 <para>Target: the target state of the transition.</para> 7018 </listitem> 7019 <listitem> 7020 <para>action: a pointer to the method provided by the concrete 7021 front-end (represented by <code>Derived</code>).</para> 7022 </listitem> 7023 <listitem> 7024 <para>guard: a pointer to the method provided by the concrete 7025 front-end (represented by <code>Derived</code>).</para> 7026 </listitem> 7027 </itemizedlist></para> 7028 </refsect3> 7029 <refsect3> 7030 <title>_row</title> 7031 <para>This is a transition without action or guard. The state machine only 7032 changes active state.</para> 7033 <para><ooclass> 7034 <classname>template< class Source, class Event, class Target > 7035 _row</classname> 7036 </ooclass><itemizedlist> 7037 <listitem> 7038 <para>Event: the event triggering the transition.</para> 7039 </listitem> 7040 <listitem> 7041 <para>Source: the source state of the transition.</para> 7042 </listitem> 7043 <listitem> 7044 <para>Target: the target state of the transition.</para> 7045 </listitem> 7046 </itemizedlist></para> 7047 </refsect3> 7048 <refsect3> 7049 <title>a_irow</title> 7050 <para>This is an internal transition for use inside a transition table, with 7051 action and without guard.</para> 7052 <para><ooclass> 7053 <classname>template< class Source, class Event, void 7054 (Derived::*action)(Event const&) > a_irow</classname> 7055 </ooclass><itemizedlist> 7056 <listitem> 7057 <para>Event: the event triggering the transition.</para> 7058 </listitem> 7059 <listitem> 7060 <para>Source: the source state of the transition.</para> 7061 </listitem> 7062 <listitem> 7063 <para>action: a pointer to the method provided by the concrete 7064 front-end (represented by <code>Derived</code>).</para> 7065 </listitem> 7066 </itemizedlist></para> 7067 </refsect3> 7068 <refsect3> 7069 <title>g_irow</title> 7070 <para>This is an internal transition for use inside a transition table, with 7071 guard and without action.</para> 7072 <para><ooclass> 7073 <classname>template< class Source, class Event, bool 7074 (Derived::*guard)(Event const&) > g_irow</classname> 7075 </ooclass><itemizedlist> 7076 <listitem> 7077 <para>Event: the event triggering the transition.</para> 7078 </listitem> 7079 <listitem> 7080 <para>Source: the source state of the transition.</para> 7081 </listitem> 7082 <listitem> 7083 <para>guard: a pointer to the method provided by the concrete 7084 front-end (represented by <code>Derived</code>).</para> 7085 </listitem> 7086 </itemizedlist></para> 7087 </refsect3> 7088 <refsect3> 7089 <title>irow</title> 7090 <para>This is an internal transition for use inside a transition table, with 7091 guard and action.</para> 7092 <para><ooclass> 7093 <classname>template< class Source, class Event, void 7094 (Derived::*action)(Event const&), bool 7095 (Derived::*guard)(Event const&) > irow</classname> 7096 </ooclass><itemizedlist> 7097 <listitem> 7098 <para>Event: the event triggering the transition.</para> 7099 </listitem> 7100 <listitem> 7101 <para>Source: the source state of the transition.</para> 7102 </listitem> 7103 <listitem> 7104 <para>action: a pointer to the method provided by the concrete 7105 front-end (represented by <code>Derived</code>).</para> 7106 </listitem> 7107 <listitem> 7108 <para>guard: a pointer to the method provided by the concrete 7109 front-end (represented by <code>Derived</code>).</para> 7110 </listitem> 7111 </itemizedlist></para> 7112 </refsect3> 7113 <refsect3> 7114 <title>_irow</title> 7115 <para>This is an internal transition without action or guard. As it does 7116 nothing, it means "ignore event".</para> 7117 <para><ooclass> 7118 <classname>template< class Source, class Event > 7119 _irow</classname> 7120 </ooclass><itemizedlist> 7121 <listitem> 7122 <para>Event: the event triggering the transition.</para> 7123 </listitem> 7124 <listitem> 7125 <para>Source: the source state of the transition.</para> 7126 </listitem> 7127 </itemizedlist></para> 7128 </refsect3> 7129 <refsect3> 7130 <title>methods</title> 7131 <para><code>state_machine_def</code> provides a default implementation in 7132 case of an event which cannot be processed by a state machine (no 7133 transition found). The implementation is using a 7134 <code>BOOST_ASSERT</code> so that the error will only be noticed in 7135 debug mode. Overwrite this method in your implementation to change the 7136 behavior.</para> 7137 <para> 7138 <funcsynopsis> 7139 <funcprototype> 7140 <funcdef>template <class Fsm,class Event> static void 7141 no_transition</funcdef> 7142 <paramdef> 7143 <funcparams>Event const& ,Fsm&, int 7144 state</funcparams> 7145 </paramdef> 7146 </funcprototype> 7147 </funcsynopsis> 7148 </para> 7149 <para><code>state_machine_def</code> provides a default implementation in 7150 case an exception is thrown by a state (entry/exit) or transition 7151 (action/guard) behavior. The implementation is using a 7152 <code>BOOST_ASSERT</code> so that the error will only be noticed in 7153 debug mode. Overwrite this method in your implementation to change the 7154 behavior. This method will be called only if exception handling is not 7155 deactivated (default) by defining 7156 <code>has_no_message_queue</code>.</para> 7157 <para> 7158 <funcsynopsis> 7159 <funcprototype> 7160 <funcdef>template <class Fsm,class Event> static void 7161 exception_caught</funcdef> 7162 <paramdef> 7163 <funcparams>Event const& ,Fsm&, 7164 std::exception&</funcparams> 7165 </paramdef> 7166 </funcprototype> 7167 </funcsynopsis> 7168 </para> 7169 </refsect3> 7170 </refsect2> 7171 </refsect1> 7172 <refsect1> 7173 <title>msm/front/states.hpp </title> 7174 <para>This header provides the different states (except state machines) for the 7175 basic front-end (or mixed with other front-ends).</para> 7176 <refsect2> 7177 <title>types</title> 7178 <para>This header provides the following types:</para> 7179 <refsect3> 7180 <title>no_sm_ptr</title> 7181 <para>deprecated: default policy for states. It means that states do not 7182 need to save a pointer to their containing state machine.</para> 7183 </refsect3> 7184 <refsect3> 7185 <title>sm_ptr</title> 7186 <para>deprecated: state policy. It means that states need to save a pointer 7187 to their containing state machine. When seeing this flag, the back-end 7188 will call set_sm_ptr(fsm*) and give itself as argument.</para> 7189 </refsect3> 7190 <refsect3> 7191 <title>state</title> 7192 <para>Basic type for simple states. Inherit from this type to define a 7193 simple state. The first argument is needed if you want your state (and 7194 all others used in a concrete state machine) to inherit a basic type for 7195 logging or providing a common behavior.</para> 7196 <classsynopsis> 7197 <ooclass> 7198 <classname>template<class Base = default_base_state,class 7199 SMPtrPolicy = no_sm_ptr> state</classname> 7200 </ooclass> 7201 </classsynopsis> 7202 </refsect3> 7203 <refsect3> 7204 <title>terminate_state</title> 7205 <para>Basic type for terminate states. Inherit from this type to define a 7206 terminate state. The first argument is needed if you want your state 7207 (and all others used in a concrete state machine) to inherit a basic 7208 type for logging or providing a common behavior.</para> 7209 <classsynopsis> 7210 <ooclass> 7211 <classname>template<class Base = default_base_state,class 7212 SMPtrPolicy = no_sm_ptr> terminate_state</classname> 7213 </ooclass> 7214 </classsynopsis> 7215 </refsect3> 7216 <refsect3> 7217 <title>interrupt_state</title> 7218 <para>Basic type for interrupt states. Interrupt states prevent any further 7219 event handling until EndInterruptEvent is sent. Inherit from this type 7220 to define a terminate state. The first argument is the name of the event 7221 ending the interrupt. The second argument is needed if you want your 7222 state (and all others used in a concrete state machine) to inherit a 7223 basic type for logging or providing a common behavior.</para> 7224 <para>The EndInterruptEvent can also be a sequence of events: 7225 mpl::vector<EndInterruptEvent,EndInterruptEvent2>.</para> 7226 <classsynopsis> 7227 <ooclass> 7228 <classname>template<class EndInterruptEvent,class Base = 7229 default_base_state,</classname> 7230 </ooclass> 7231 </classsynopsis> 7232 <classsynopsis> 7233 <ooclass> 7234 <classname>class SMPtrPolicy = no_sm_ptr> 7235 interrupt_state</classname> 7236 </ooclass> 7237 </classsynopsis> 7238 </refsect3> 7239 <refsect3> 7240 <title>explicit_entry</title> 7241 <para>Inherit from this type <emphasis role="underline">in 7242 addition</emphasis> to the desired state type to enable this state 7243 for direct entering. The template parameter gives the region id of the 7244 state (regions are numbered in the order of the 7245 <code>initial_state</code> typedef).</para> 7246 <classsynopsis> 7247 <ooclass> 7248 <classname>template <int ZoneIndex=-1> explicit_entry</classname> 7249 </ooclass> 7250 </classsynopsis> 7251 </refsect3> 7252 <refsect3> 7253 <title>entry_pseudo_state</title> 7254 <para>Basic type for entry pseudo states. Entry pseudo states are an 7255 predefined entry into a submachine and connect two transitions. The 7256 first argument is the id of the region entered by this state (regions 7257 are numbered in the order of the <code>initial_state</code> typedef). 7258 The second argument is needed if you want your state (and all others 7259 used in a concrete state machine) to inherit a basic type for logging or 7260 providing a common behavior.</para> 7261 <classsynopsis> 7262 <ooclass> 7263 <classname>template<int RegionIndex=-1,class Base = 7264 default_base_state,</classname> 7265 </ooclass> 7266 </classsynopsis> 7267 <classsynopsis> 7268 <ooclass> 7269 <classname>class SMPtrPolicy = no_sm_ptr> 7270 entry_pseudo_state</classname> 7271 </ooclass> 7272 </classsynopsis> 7273 </refsect3> 7274 <refsect3> 7275 <title>exit_pseudo_state</title> 7276 <para>Basic type for exit pseudo states. Exit pseudo states are an 7277 predefined exit from a submachine and connect two transitions. The first 7278 argument is the name of the event which will be "thrown" out of the exit 7279 point. This event does not need to be the same as the one sent by the 7280 inner region but must be convertible from it. The second argument is 7281 needed if you want your state (and all others used in a concrete state 7282 machine) to inherit a basic type for logging or providing a common 7283 behavior.</para> 7284 <classsynopsis> 7285 <ooclass> 7286 <classname>template<class Event,class Base = 7287 default_base_state,</classname> 7288 </ooclass> 7289 </classsynopsis> 7290 <classsynopsis> 7291 <ooclass> 7292 <classname>class SMPtrPolicy = no_sm_ptr> 7293 exit_pseudo_state</classname> 7294 </ooclass> 7295 </classsynopsis> 7296 </refsect3> 7297 </refsect2> 7298 </refsect1> 7299 <refsect1> 7300 <title>msm/front/euml/euml.hpp</title> 7301 <para>This header includes all of eUML except the STL functors.</para> 7302 </refsect1> 7303 <refsect1> 7304 <title>msm/front/euml/stl.hpp</title> 7305 <para>This header includes all the functors for STL support in eUML. These <command 7306 xlink:href="#eUML-STL-all">tables</command> show a full description.</para> 7307 </refsect1> 7308 <refsect1> 7309 <title>msm/front/euml/algorithm.hpp</title> 7310 <para>This header includes all the functors for STL algorithms support in eUML. 7311 These <command xlink:href="#eUML-STL-all">tables</command> show a full 7312 description.</para> 7313 </refsect1> 7314 <refsect1> 7315 <title>msm/front/euml/iteration.hpp</title> 7316 <para>This header includes iteration functors for STL support in eUML. This <command 7317 xlink:href="#eUML-STL-iteration">tables</command> shows a full 7318 description.</para> 7319 </refsect1> 7320 <refsect1> 7321 <title>msm/front/euml/querying.hpp</title> 7322 <para>This header includes querying functors for STL support in eUML. This <command 7323 xlink:href="#eUML-STL-querying">tables</command> shows a full 7324 description.</para> 7325 </refsect1> 7326 <refsect1> 7327 <title>msm/front/euml/transformation.hpp</title> 7328 <para>This header includes transformation functors for STL support in eUML. This 7329 <command xlink:href="#eUML-STL-transformation">tables</command> shows a full 7330 description.</para> 7331 </refsect1> 7332 <refsect1> 7333 <title>msm/front/euml/container.hpp</title> 7334 <para>This header includes container functors for STL support in eUML (functors 7335 calling container methods). This <command xlink:href="#eUML-STL-container" 7336 >tables</command> shows a full description. It also provides npos for 7337 strings.</para> 7338 <refsect2> 7339 <title>Npos_<container type></title> 7340 <para>Functor returning npos for transition or state behaviors. Like all 7341 constants, only the functor form exists, so parenthesis are necessary. 7342 Example:</para> 7343 <para><code>string_find_(event_(m_song),Char_<'S'>(),Size_t_<0>()) != 7344 Npos_<string>() // compare result of string::find with 7345 npos</code></para> 7346 </refsect2> 7347 </refsect1> 7348 <refsect1> 7349 <title>msm/front/euml/stt_grammar.hpp</title> 7350 <para>This header provides the transition table grammars. This includes internal 7351 transition tables.</para> 7352 <refsect2> 7353 <title>functions</title> 7354 <refsect3> 7355 <title>build_stt</title> 7356 <para>The function build_stt evaluates the grammar-conform expression as 7357 parameter. It returns a transition table, which is a mpl::vector of 7358 transitions (rows) or, if the expression is ill-formed (does not match 7359 the grammar), the type <code>invalid_type</code>, which will lead to a 7360 compile-time static assertion when this transition table is passed to a 7361 state machine. </para> 7362 <funcsynopsis> 7363 <funcprototype> 7364 <funcdef>template<class Expr> [mpl::vector<...> / 7365 msm::front::euml::invalid_type] build_stt</funcdef> 7366 <paramdef>Expr const& expr</paramdef> 7367 </funcprototype> 7368 </funcsynopsis> 7369 </refsect3> 7370 <refsect3> 7371 <title>build_internal_stt</title> 7372 <para>The function build_internal_stt evaluates the grammar-conform 7373 expression as parameter. It returns a transition table, which is a 7374 mpl::vector of transitions (rows) or, if the expression is ill-formed 7375 (does not match the grammar), the type <code>invalid_type</code>, which 7376 will lead to a compile-time static assertion when this transition table 7377 is passed to a state machine. </para> 7378 <funcsynopsis> 7379 <funcprototype> 7380 <funcdef>template<class Expr> [mpl::vector<...> / 7381 msm::front::euml::invalid_type] build_internal_stt</funcdef> 7382 <paramdef>Expr const& expr</paramdef> 7383 </funcprototype> 7384 </funcsynopsis> 7385 </refsect3> 7386 </refsect2> 7387 <refsect2> 7388 <title>grammars</title> 7389 <refsect3> 7390 <title><command xml:id="reference-stt-grammar">transition 7391 table</command></title> 7392 <para>The transition table accepts the following grammar:</para> 7393 <programlisting>Stt := Row | (Stt ',' Stt) 7394Row := (Target '==' (SourcePlusEvent)) /* first syntax*/ 7395 | ( (SourcePlusEvent) '==' Target ) /* second syntax*/ 7396 | (SourcePlusEvent) /* internal transitions */ 7397SourcePlusEvent := (BuildSource '+' BuildEvent)/* standard transition*/ 7398 | (BuildSource) /* anonymous transition */ 7399BuildSource := state_tag | (state_tag '/' Action) | (state_tag '[' Guard ']') 7400 | (state_tag '[' Guard ']' '/' Action) 7401BuildEvent := event_tag | (event_tag '/' Action) | (event_tag '[' Guard ']') 7402 | (event_tag '[' Guard ']' '/' Action)</programlisting> 7403 <para>The grammars Action and Guard are defined in state_grammar.hpp and 7404 guard_grammar.hpp respectively. state_tag and event_tag are inherited 7405 from euml_state (or other state variants) and euml_event respectively. 7406 For example, following declarations are possible:</para> 7407 <programlisting>target == source + event [guard] / action, 7408source + event [guard] / action == target, 7409source + event [guard] / (action1,action2) == target, 7410target == source + event [guard] / (action1,action2), 7411target == source + event, 7412source + event == target, 7413target == source + event [guard], 7414source + event [guard] == target, 7415target == source + event / action, 7416source + event /action == target, 7417source / action == target, /*anonymous transition*/ 7418target == source / action, /*anonymous transition*/ 7419source + event /action, /* internal transition*/</programlisting> 7420 </refsect3> 7421 <refsect3> 7422 <title>internal transition table</title> 7423 <para>The internal transition table accepts the following grammar:</para> 7424 <programlisting>IStt := BuildEvent | (IStt ',' IStt)</programlisting> 7425 <para>BuildEvent being defined for both internal and standard transition 7426 tables.</para> 7427 </refsect3> 7428 </refsect2> 7429 </refsect1> 7430 <refsect1> 7431 <title>msm/front/euml/guard_grammar.hpp</title> 7432 <para>This header contains the <code>Guard</code> grammar used in the previous 7433 section. This grammar is long but pretty simple:</para> 7434 <programlisting>Guard := action_tag | (Guard '&&' Guard) 7435 | (Guard '||' Guard) | ... /* operators*/ 7436 | (if_then_else_(Guard,Guard,Guard)) | (function (Action,...Action))</programlisting> 7437 <para>Most C++ operators are supported (address-of is not). With 7438 <code>function</code> is meant any eUML predefined function or any self-made 7439 (using <code>MSM_EUML_METHOD</code> or <code>MSM_EUML_FUNCTION</code>). Action 7440 is a grammar defined in state_grammar.hpp.</para> 7441 </refsect1> 7442 <refsect1> 7443 <title>msm/front/euml/state_grammar.hpp</title> 7444 <para>This header provides the grammar for actions and the different grammars and 7445 functions to build states using eUML.</para> 7446 <refsect2> 7447 <title>action grammar</title> 7448 <para>Like the guard grammar, this grammar supports relevant C++ operators and 7449 eUML functions:</para> 7450 <programlisting>Action := action_tag | (Action '+' Action) 7451 | ('--' Action) | ... /* operators*/ 7452 | if_then_else_(Guard,Action,Action) | if_then_(Action) 7453 | while_(Guard,Action) 7454 | do_while_(Guard,Action) | for_(Action,Guard,Action,Action) 7455 | (function(Action,...Action)) 7456ActionSequence := Action | (Action ',' Action)</programlisting> 7457 <para>Relevant operators are: ++ (post/pre), -- (post/pre), dereferencing, + 7458 (unary/binary), - (unary/binary), *, /, %, &(bitwise), | (bitwise), 7459 ^(bitwise), +=, -=, *=, /=, %=, <<=, >>=, <<, >>, =, [].</para> 7460 </refsect2> 7461 <refsect2> 7462 <title>attributes</title> 7463 <para>This grammar is used to add attributes to states (or state machines) or 7464 events: It evaluates to a fusion::map. You can use two forms:<itemizedlist> 7465 <listitem> 7466 <para><code>attributes_ << no_attributes_</code></para> 7467 </listitem> 7468 <listitem> 7469 <para><code>attributes_ << attribute_1 << ... << 7470 attribute_n</code></para> 7471 </listitem> 7472 </itemizedlist></para> 7473 <para>Attributes can be of any default-constructible type (fusion 7474 requirement).</para> 7475 </refsect2> 7476 <refsect2> 7477 <title>configure</title> 7478 <para>This grammar also has two forms:<itemizedlist> 7479 <listitem> 7480 <para><code>configure_ << no_configure_</code></para> 7481 </listitem> 7482 <listitem> 7483 <para><code>configure_ << type_1 << ... << 7484 type_n</code></para> 7485 </listitem> 7486 </itemizedlist></para> 7487 <para>This grammar is used to create inside one syntax:<itemizedlist> 7488 <listitem> 7489 <para>flags: <code>configure_ << some_flag</code> where 7490 some_flag inherits from <code>euml_flag<some_flag></code> or 7491 is defined using BOOST_MSM_EUML_FLAG.</para> 7492 </listitem> 7493 <listitem> 7494 <para>deferred events: <code>configure_ << some_event</code> 7495 where some_event inherits from 7496 <code>euml_event<some_event></code> or is defined using 7497 BOOST_MSM_EUML_EVENT or 7498 BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES.</para> 7499 </listitem> 7500 <listitem> 7501 <para>configuration (message queue, manual deferring, exception 7502 handling): <code>configure_ << some_config</code> where 7503 some_config inherits from 7504 <code>euml_config<some_config></code>. At the moment, 7505 three predefined objects exist (in msm//front/euml/common.hpp):<itemizedlist> 7506 <listitem> 7507 <para>no_exception: disable catching exceptions</para> 7508 </listitem> 7509 <listitem> 7510 <para>no_msg_queue: disable message queue</para> 7511 </listitem> 7512 <listitem> 7513 <para>deferred_events: manually enable handling of 7514 deferred events</para> 7515 </listitem> 7516 </itemizedlist></para> 7517 </listitem> 7518 </itemizedlist></para> 7519 </refsect2> 7520 <refsect2> 7521 <title>initial states</title> 7522 <para>The grammar to define initial states for a state machine is: <code>init_ 7523 << state_1 << ... << state_n</code> where 7524 state_1...state_n inherit from euml_state or is defined using 7525 BOOST_MSM_EUML_STATE, BOOST_MSM_EUML_INTERRUPT_STATE, 7526 BOOST_MSM_EUML_TERMINATE_STATE, BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE, 7527 BOOST_MSM_EUML_ENTRY_STATE or BOOST_MSM_EUML_EXIT_STATE.</para> 7528 </refsect2> 7529 <refsect2> 7530 <title>functions</title> 7531 <refsect3> 7532 <title>build_sm</title> 7533 <para>This function has several overloads. The return type is not relevant 7534 to you as only decltype (return type) is what one needs.</para> 7535 <para>Defines a state machine without entry or exit:</para> 7536 <funcsynopsis> 7537 <funcprototype> 7538 <funcdef>template <class StateNameTag,class Stt,class Init> 7539 func_state_machine<...> build_sm</funcdef> 7540 <paramdef>Stt ,Init</paramdef> 7541 </funcprototype> 7542 </funcsynopsis> 7543 <para>Defines a state machine with entry behavior:</para> 7544 <funcsynopsis> 7545 <funcprototype> 7546 <funcdef>template <class StateNameTag,class Stt,class Init,class 7547 Expr1> func_state_machine<...> build_sm</funcdef> 7548 <paramdef>Stt ,Init,Expr1 const&</paramdef> 7549 </funcprototype> 7550 </funcsynopsis> 7551 <para>Defines a state machine with entry and exit behaviors:</para> 7552 <funcsynopsis> 7553 <funcprototype> 7554 <funcdef>template <class StateNameTag,class Stt,class Init,class 7555 Expr1, class Expr2> func_state_machine<...> 7556 build_sm</funcdef> 7557 <paramdef>Stt ,Init,Expr1 const&,Expr2 const&</paramdef> 7558 </funcprototype> 7559 </funcsynopsis> 7560 <para>Defines a state machine with entry, exit behaviors and 7561 attributes:</para> 7562 <funcsynopsis> 7563 <funcprototype> 7564 <funcdef>template <class StateNameTag,class Stt,class Init,class 7565 Expr1, class Expr2, class Attributes> func_state_machine<...> 7566 build_sm</funcdef> 7567 <paramdef>Stt ,Init,Expr1 const&, Expr2 const&, Attributes 7568 const&</paramdef> 7569 </funcprototype> 7570 </funcsynopsis> 7571 <para>Defines a state machine with entry, exit behaviors, attributes and 7572 configuration (deferred events, flags):</para> 7573 <funcsynopsis> 7574 <funcprototype> 7575 <funcdef>template <class StateNameTag,class Stt,class Init,class 7576 Expr1, class Expr2, class Attributes, class Configure> 7577 func_state_machine<...> build_sm</funcdef> 7578 <paramdef>Stt ,Init,Expr1 const&, Expr2 const&, Attributes 7579 const&, Configure const&</paramdef> 7580 </funcprototype> 7581 </funcsynopsis> 7582 <para>Defines a state machine with entry, exit behaviors, attributes, 7583 configuration (deferred events, flags) and a base state:</para> 7584 <funcsynopsis> 7585 <funcprototype> 7586 <funcdef>template <class StateNameTag,class Stt,class Init,class 7587 Expr1, class Expr2, class Attributes, class Configure, class 7588 Base> func_state_machine<...> build_sm</funcdef> 7589 <paramdef>Stt ,Init,Expr1 const&, Expr2 const&, Attributes 7590 const&, Configure const&, Base</paramdef> 7591 </funcprototype> 7592 </funcsynopsis> 7593 <para>Notice that this function requires the extra parameter class 7594 StateNameTag to disambiguate state machines having the same parameters 7595 but still being different.</para> 7596 </refsect3> 7597 <refsect3> 7598 <title>build_state</title> 7599 <para>This function has several overloads. The return type is not relevant 7600 to you as only decltype (return type) is what one needs.</para> 7601 <para>Defines a simple state without entry or exit:</para> 7602 <funcsynopsis> 7603 <funcprototype> 7604 <funcdef>func_state<class StateNameTag,...> build_state</funcdef> 7605 <paramdef/> 7606 </funcprototype> 7607 </funcsynopsis> 7608 <para>Defines a simple state with entry behavior:</para> 7609 <funcsynopsis> 7610 <funcprototype> 7611 <funcdef>template <class StateNameTag,class Expr1> 7612 func_state<...> build_state</funcdef> 7613 <paramdef>Expr1 const&</paramdef> 7614 </funcprototype> 7615 </funcsynopsis> 7616 <para>Defines a simple state with entry and exit behaviors:</para> 7617 <funcsynopsis> 7618 <funcprototype> 7619 <funcdef>template <class StateNameTag,class Expr1, class Expr2> 7620 func_state<...> build_state</funcdef> 7621 <paramdef>Expr1 const&,Expr2 const&</paramdef> 7622 </funcprototype> 7623 </funcsynopsis> 7624 <para>Defines a simple state with entry, exit behaviors and 7625 attributes:</para> 7626 <funcsynopsis> 7627 <funcprototype> 7628 <funcdef>template <class StateNameTag,class Expr1, class Expr2, 7629 class Attributes> func_state<...> build_state</funcdef> 7630 <paramdef>Expr1 const&, Expr2 const&, Attributes 7631 const&</paramdef> 7632 </funcprototype> 7633 </funcsynopsis> 7634 <para>Defines a simple state with entry, exit behaviors, attributes and 7635 configuration (deferred events, flags):</para> 7636 <funcsynopsis> 7637 <funcprototype> 7638 <funcdef>template <class StateNameTag,class Expr1, class Expr2, 7639 class Attributes, class Configure> func_state<...> 7640 build_state</funcdef> 7641 <paramdef>Expr1 const&, Expr2 const&, Attributes const&, 7642 Configure const&</paramdef> 7643 </funcprototype> 7644 </funcsynopsis> 7645 <para>Defines a simple state with entry, exit behaviors, attributes, 7646 configuration (deferred events, flags) and a base state:</para> 7647 <funcsynopsis> 7648 <funcprototype> 7649 <funcdef>template <class StateNameTag,class Expr1, class Expr2, 7650 class Attributes, class Configure, class Base> 7651 func_state<...> build_state</funcdef> 7652 <paramdef>Expr1 const&, Expr2 const&, Attributes const&, 7653 Configure const&, Base</paramdef> 7654 </funcprototype> 7655 </funcsynopsis> 7656 <para>Notice that this function requires the extra parameter class 7657 StateNameTag to disambiguate states having the same parameters but still 7658 being different.</para> 7659 </refsect3> 7660 <refsect3> 7661 <title>build_terminate_state</title> 7662 <para>This function has the same overloads as build_state.</para> 7663 </refsect3> 7664 <refsect3> 7665 <title>build_interrupt_state</title> 7666 <para>This function has several overloads. The return type is not relevant 7667 to you as only decltype (return type) is what one needs.</para> 7668 <para>Defines an interrupt state without entry or exit:</para> 7669 <funcsynopsis> 7670 <funcprototype> 7671 <funcdef>template <class StateNameTag,class EndInterruptEvent> 7672 func_state<...> build_interrupt_state</funcdef> 7673 <paramdef>EndInterruptEvent const&</paramdef> 7674 </funcprototype> 7675 </funcsynopsis> 7676 <para>Defines an interrupt state with entry behavior:</para> 7677 <funcsynopsis> 7678 <funcprototype> 7679 <funcdef>template <class StateNameTag,class 7680 EndInterruptEvent,class Expr1> func_state<...> 7681 build_interrupt_state</funcdef> 7682 <paramdef>EndInterruptEvent const&,Expr1 const&</paramdef> 7683 </funcprototype> 7684 </funcsynopsis> 7685 <para>Defines an interrupt state with entry and exit behaviors:</para> 7686 <funcsynopsis> 7687 <funcprototype> 7688 <funcdef>template <class StateNameTag,class 7689 EndInterruptEvent,class Expr1, class Expr2> func_state<...> 7690 build_interrupt_state</funcdef> 7691 <paramdef>EndInterruptEvent const&,Expr1 const&,Expr2 7692 const&</paramdef> 7693 </funcprototype> 7694 </funcsynopsis> 7695 <para>Defines an interrupt state with entry, exit behaviors and 7696 attributes:</para> 7697 <funcsynopsis> 7698 <funcprototype> 7699 <funcdef>template <class StateNameTag,class 7700 EndInterruptEvent,class Expr1, class Expr2, class Attributes> 7701 func_state<...> build_interrupt_state</funcdef> 7702 <paramdef>EndInterruptEvent const&,Expr1 const&, Expr2 7703 const&, Attributes const&</paramdef> 7704 </funcprototype> 7705 </funcsynopsis> 7706 <para>Defines an interrupt state with entry, exit behaviors, attributes and 7707 configuration (deferred events, flags):</para> 7708 <funcsynopsis> 7709 <funcprototype> 7710 <funcdef>template <class StateNameTag,class 7711 EndInterruptEvent,class Expr1, class Expr2, class Attributes, 7712 class Configure> func_state<...> 7713 build_interrupt_state</funcdef> 7714 <paramdef>EndInterruptEvent const&,Expr1 const&, Expr2 7715 const&, Attributes const&, Configure 7716 const&</paramdef> 7717 </funcprototype> 7718 </funcsynopsis> 7719 <para>Defines an interrupt state with entry, exit behaviors, attributes, 7720 configuration (deferred events, flags) and a base state:</para> 7721 <funcsynopsis> 7722 <funcprototype> 7723 <funcdef>template <class StateNameTag,class 7724 EndInterruptEvent,class Expr1, class Expr2, class Attributes, 7725 class Configure, class Base> func_state<...> 7726 build_interrupt_state</funcdef> 7727 <paramdef>EndInterruptEvent const&,Expr1 const&, Expr2 7728 const&, Attributes const&, Configure const&, 7729 Base</paramdef> 7730 </funcprototype> 7731 </funcsynopsis> 7732 <para>Notice that this function requires the extra parameter class 7733 StateNameTag to disambiguate states having the same parameters but still 7734 being different.</para> 7735 </refsect3> 7736 <refsect3> 7737 <title>build_entry_state</title> 7738 <para>This function has several overloads. The return type is not relevant 7739 to you as only decltype (return type) is what one needs.</para> 7740 <para>Defines an entry pseudo state without entry or exit:</para> 7741 <funcsynopsis> 7742 <funcprototype> 7743 <funcdef>template <class StateNameTag,int RegionIndex> 7744 entry_func_state<...> build_entry_state</funcdef> 7745 <paramdef/> 7746 </funcprototype> 7747 </funcsynopsis> 7748 <para>Defines an entry pseudo state with entry behavior:</para> 7749 <funcsynopsis> 7750 <funcprototype> 7751 <funcdef>template <class StateNameTag,int RegionIndex,class 7752 Expr1> entry_func_state<...> build_entry_state</funcdef> 7753 <paramdef>Expr1 const&</paramdef> 7754 </funcprototype> 7755 </funcsynopsis> 7756 <para>Defines an entry pseudo state with entry and exit behaviors:</para> 7757 <funcsynopsis> 7758 <funcprototype> 7759 <funcdef>template <class StateNameTag,int RegionIndex,class 7760 Expr1, class Expr2> entry_func_state<...> 7761 build_entry_state</funcdef> 7762 <paramdef>Expr1 const&,Expr2 const&</paramdef> 7763 </funcprototype> 7764 </funcsynopsis> 7765 <para>Defines an entry pseudo state with entry, exit behaviors and 7766 attributes:</para> 7767 <funcsynopsis> 7768 <funcprototype> 7769 <funcdef>template <class StateNameTag,int RegionIndex,class 7770 Expr1, class Expr2, class Attributes> entry_func_state<...> 7771 build_entry_state</funcdef> 7772 <paramdef>Expr1 const&, Expr2 const&, Attributes 7773 const&</paramdef> 7774 </funcprototype> 7775 </funcsynopsis> 7776 <para>Defines an entry pseudo state with entry, exit behaviors, attributes 7777 and configuration (deferred events, flags):</para> 7778 <funcsynopsis> 7779 <funcprototype> 7780 <funcdef>template <class StateNameTag,int RegionIndex,class 7781 Expr1, class Expr2, class Attributes, class Configure> 7782 entry_func_state<...> build_entry_state</funcdef> 7783 <paramdef>Expr1 const&, Expr2 const&, Attributes const&, 7784 Configure const&</paramdef> 7785 </funcprototype> 7786 </funcsynopsis> 7787 <para>Defines an entry pseudo state with entry, exit behaviors, attributes, 7788 configuration (deferred events, flags) and a base state:</para> 7789 <funcsynopsis> 7790 <funcprototype> 7791 <funcdef>template <class StateNameTag,int RegionIndex,class 7792 Expr1, class Expr2, class Attributes, class Configure, class 7793 Base> entry_func_state<...> build_entry_state</funcdef> 7794 <paramdef>Expr1 const&, Expr2 const&, Attributes const&, 7795 Configure const&, Base</paramdef> 7796 </funcprototype> 7797 </funcsynopsis> 7798 <para>Notice that this function requires the extra parameter class 7799 StateNameTag to disambiguate states having the same parameters but still 7800 being different.</para> 7801 </refsect3> 7802 <refsect3> 7803 <title>build_exit_state</title> 7804 <para>This function has several overloads. The return type is not relevant 7805 to you as only decltype (return type) is what one needs.</para> 7806 <para>Defines an exit pseudo state without entry or exit:</para> 7807 <funcsynopsis> 7808 <funcprototype> 7809 <funcdef>template <class StateNameTag,class Event> 7810 exit_func_state<...> build_exit_state</funcdef> 7811 <paramdef>Event const&</paramdef> 7812 </funcprototype> 7813 </funcsynopsis> 7814 <para>Defines an exit pseudo state with entry behavior:</para> 7815 <funcsynopsis> 7816 <funcprototype> 7817 <funcdef>template <class StateNameTag,class Event,class Expr1> 7818 exit_func_state<...> build_exit_state</funcdef> 7819 <paramdef>Event const&,Expr1 const&</paramdef> 7820 </funcprototype> 7821 </funcsynopsis> 7822 <para>Defines an exit pseudo state with entry and exit behaviors:</para> 7823 <funcsynopsis> 7824 <funcprototype> 7825 <funcdef>template <class StateNameTag,class Event,class Expr1, 7826 class Expr2> exit_func_state<...> build_exit_state</funcdef> 7827 <paramdef>Event const&,Expr1 const&,Expr2 7828 const&</paramdef> 7829 </funcprototype> 7830 </funcsynopsis> 7831 <para>Defines an exit pseudo state with entry, exit behaviors and 7832 attributes:</para> 7833 <funcsynopsis> 7834 <funcprototype> 7835 <funcdef>template <class StateNameTag,class Event,class Expr1, 7836 class Expr2, class Attributes> exit_func_state<...> 7837 build_exit_state</funcdef> 7838 <paramdef>Event const&,Expr1 const&, Expr2 const&, 7839 Attributes const&</paramdef> 7840 </funcprototype> 7841 </funcsynopsis> 7842 <para>Defines an exit pseudo state with entry, exit behaviors, attributes 7843 and configuration (deferred events, flags):</para> 7844 <funcsynopsis> 7845 <funcprototype> 7846 <funcdef>template <class StateNameTag,class Event,class Expr1, 7847 class Expr2, class Attributes, class Configure> 7848 exit_func_state<...> build_exit_state</funcdef> 7849 <paramdef>Event const&,Expr1 const&, Expr2 const&, 7850 Attributes const&, Configure const&</paramdef> 7851 </funcprototype> 7852 </funcsynopsis> 7853 <para>Defines an exit pseudo state with entry, exit behaviors, attributes, 7854 configuration (deferred events, flags) and a base state:</para> 7855 <funcsynopsis> 7856 <funcprototype> 7857 <funcdef>template <class StateNameTag,class Event,class Expr1, 7858 class Expr2, class Attributes, class Configure, class Base> 7859 exit_func_state<...> build_exit_state</funcdef> 7860 <paramdef>Event const&,Expr1 const&, Expr2 const&, 7861 Attributes const&, Configure const&, Base</paramdef> 7862 </funcprototype> 7863 </funcsynopsis> 7864 <para>Notice that this function requires the extra parameter class 7865 StateNameTag to disambiguate states having the same parameters but still 7866 being different.</para> 7867 </refsect3> 7868 <refsect3> 7869 <title>build_explicit_entry_state</title> 7870 <para>This function has the same overloads as build_entry_state and 7871 explicit_entry_func_state as return type.</para> 7872 </refsect3> 7873 </refsect2> 7874 </refsect1> 7875 <refsect1> 7876 <title>msm/front/euml/common.hpp</title> 7877 <refsect2> 7878 <title>types</title> 7879 <refsect3> 7880 <title>euml_event</title> 7881 <para>The basic type for events with eUML.</para> 7882 <classsynopsis> 7883 <ooclass> 7884 <classname>template <class EventName> euml_event;</classname> 7885 </ooclass> 7886 </classsynopsis> 7887 <programlisting>struct play : euml_event<play>{};</programlisting> 7888 </refsect3> 7889 <refsect3> 7890 <title>euml_state</title> 7891 <para>The basic type for states with eUML. You will usually not use this 7892 type directly as it is easier to use BOOST_MSM_EUML_STATE, 7893 BOOST_MSM_EUML_INTERRUPT_STATE, BOOST_MSM_EUML_TERMINATE_STATE, 7894 BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE, BOOST_MSM_EUML_ENTRY_STATE or 7895 BOOST_MSM_EUML_EXIT_STATE.</para> 7896 <classsynopsis> 7897 <ooclass> 7898 <classname>template <class StateName> euml_state;</classname> 7899 </ooclass> 7900 </classsynopsis> 7901 <para>You can however use this type directly if you want to provide your 7902 state with extra functions or provide entry or exit behaviors without 7903 functors, for example:</para> 7904 <programlisting>struct Empty : public msm::front::state<> , public euml_state<Empty> 7905{ 7906 void foo() {...} 7907 template <class Event,class Fsm> 7908 void on_entry(Event const& evt,Fsm& fsm){...} 7909};</programlisting> 7910 </refsect3> 7911 <refsect3> 7912 <title>euml_flag</title> 7913 <para>The basic type for flags with eUML.</para> 7914 <classsynopsis> 7915 <ooclass> 7916 <classname>template <class FlagName> euml_flag;</classname> 7917 </ooclass> 7918 </classsynopsis> 7919 <programlisting>struct PlayingPaused: euml_flag<PlayingPaused>{};</programlisting> 7920 </refsect3> 7921 <refsect3> 7922 <title>euml_action</title> 7923 <para>The basic type for state or transition behaviors and guards with 7924 eUML.</para> 7925 <classsynopsis> 7926 <ooclass> 7927 <classname>template <class AcionName> euml_action;</classname> 7928 </ooclass> 7929 </classsynopsis> 7930 <programlisting>struct close_drawer : euml_action<close_drawer> 7931{ 7932 template <class Fsm,class Evt,class SourceState,class TargetState> 7933 void operator()(Evt const& , Fsm&, SourceState& ,TargetState& ) {...} 7934};</programlisting> 7935 <para>Or, as state entry or exit behavior:</para> 7936 <programlisting>struct Playing_Entry : euml_action<Playing_Entry> 7937{ 7938 template <class Event,class Fsm,class State> 7939 void operator()(Event const&,Fsm& fsm,State& ){...} 7940};</programlisting> 7941 </refsect3> 7942 <refsect3> 7943 <title>euml_config</title> 7944 <para>The basic type for configuration possibilities with eUML.</para> 7945 <classsynopsis> 7946 <ooclass> 7947 <classname>template <class ConfigName> euml_config;</classname> 7948 </ooclass> 7949 </classsynopsis> 7950 <para>You normally do not use this type directly but instead the instances 7951 of predefined configuration:<itemizedlist> 7952 <listitem> 7953 <para>no_exception: disable catching exceptions</para> 7954 </listitem> 7955 <listitem> 7956 <para>no_msg_queue: disable message queue. The message queue 7957 allows you to send an event for procesing while in an event 7958 processing.</para> 7959 </listitem> 7960 <listitem> 7961 <para>deferred_events: manually enable handling of deferred 7962 events</para> 7963 </listitem> 7964 </itemizedlist></para> 7965 </refsect3> 7966 <refsect3> 7967 <title>invalid_type</title> 7968 <para>Type returned by grammar parsers if the grammar is invalid. Seeing 7969 this type will result in a static assertion.</para> 7970 </refsect3> 7971 <refsect3> 7972 <title>no_action</title> 7973 <para>Placeholder type for use in entry/exit or transition behaviors, which 7974 does absolutely nothing.</para> 7975 </refsect3> 7976 <refsect3> 7977 <title>source_</title> 7978 <para>Generic object or function for the source state of a given transition:<itemizedlist> 7979 <listitem> 7980 <para>as object: returns by reference the source state of a 7981 transition, usually to be used by another function (usually 7982 one created by MSM_EUML_METHOD or MSM_EUML_FUNCTION).</para> 7983 <para>Example: 7984 <programlisting>some_user_function_(source_)</programlisting></para> 7985 </listitem> 7986 <listitem> 7987 <para>as function: returns by reference the attribute passed as 7988 parameter.</para> 7989 <para>Example: 7990 <programlisting>source_(m_counter)++</programlisting></para> 7991 </listitem> 7992 </itemizedlist></para> 7993 </refsect3> 7994 <refsect3> 7995 <title>target_</title> 7996 <para>Generic object or function for the target state of a given transition:<itemizedlist> 7997 <listitem> 7998 <para>as object: returns by reference the target state of a 7999 transition, usually to be used by another function (usually 8000 one created by MSM_EUML_METHOD or MSM_EUML_FUNCTION).</para> 8001 <para>Example: 8002 <programlisting>some_user_function_(target_)</programlisting></para> 8003 </listitem> 8004 <listitem> 8005 <para>as function: returns by reference the attribute passed as 8006 parameter.</para> 8007 <para>Example: 8008 <programlisting>target_(m_counter)++</programlisting></para> 8009 </listitem> 8010 </itemizedlist></para> 8011 </refsect3> 8012 <refsect3> 8013 <title>state_</title> 8014 <para>Generic object or function for the state of a given entry / exit 8015 behavior. state_ means source_ while in the context of an exit behavior 8016 and target_ in the context of an entry behavior:<itemizedlist> 8017 <listitem> 8018 <para>as object: returns by reference the current state, usually 8019 to be used by another function (usually one created by 8020 MSM_EUML_METHOD or MSM_EUML_FUNCTION).</para> 8021 <para>Example: 8022 <programlisting>some_user_function_(state_) // calls some_user_function on the current state</programlisting></para> 8023 </listitem> 8024 <listitem> 8025 <para>as function: returns by reference the attribute passed as 8026 parameter.</para> 8027 <para>Example: 8028 <programlisting>state_(m_counter)++</programlisting></para> 8029 </listitem> 8030 </itemizedlist></para> 8031 </refsect3> 8032 <refsect3> 8033 <title>event_</title> 8034 <para>Generic object or function for the event triggering a given transition 8035 (valid in a transition behavior, as well as in state entry/exit behaviors):<itemizedlist> 8036 <listitem> 8037 <para>as object: returns by reference the event of a transition, 8038 usually to be used by another function (usually one created 8039 by MSM_EUML_METHOD or MSM_EUML_FUNCTION).</para> 8040 <para>Example: 8041 <programlisting>some_user_function_(event_)</programlisting></para> 8042 </listitem> 8043 <listitem> 8044 <para>as function: returns by reference the attribute passed as 8045 parameter.</para> 8046 <para>Example: 8047 <programlisting>event_(m_counter)++</programlisting></para> 8048 </listitem> 8049 </itemizedlist></para> 8050 </refsect3> 8051 <refsect3> 8052 <title>fsm_</title> 8053 <para>Generic object or function for the state machine containing a given transition:<itemizedlist> 8054 <listitem> 8055 <para>as object: returns by reference the event of a transition, 8056 usually to be used by another function (usually one created 8057 by MSM_EUML_METHOD or MSM_EUML_FUNCTION).</para> 8058 <para>Example: 8059 <programlisting>some_user_function_(fsm_)</programlisting></para> 8060 </listitem> 8061 <listitem> 8062 <para>as function: returns by reference the attribute passed as 8063 parameter.</para> 8064 <para>Example: 8065 <programlisting>fsm_(m_counter)++</programlisting></para> 8066 </listitem> 8067 </itemizedlist></para> 8068 </refsect3> 8069 <refsect3> 8070 <title>substate_</title> 8071 <para>Generic object or function returning a state of a given state machine:<itemizedlist> 8072 <listitem> 8073 <para>with 1 parameter: returns by reference the state passed as 8074 parameter, usually to be used by another function (usually 8075 one created by MSM_EUML_METHOD or MSM_EUML_FUNCTION).</para> 8076 <para>Example: 8077 <programlisting>some_user_function_(substate_(my_state))</programlisting></para> 8078 </listitem> 8079 <listitem> 8080 <para>with 2 parameters: returns by reference the state passed 8081 as first parameter from the state machine passed as second 8082 parameter, usually to be used by another function (usually 8083 one created by MSM_EUML_METHOD or MSM_EUML_FUNCTION). This 8084 makes sense when used in combination with attribute_.</para> 8085 <para>Example (equivalent to the previous example): 8086 <programlisting>some_user_function_(substate_(my_state,fsm_))</programlisting></para> 8087 </listitem> 8088 </itemizedlist></para> 8089 </refsect3> 8090 <refsect3> 8091 <title>attribute_</title> 8092 <para>Generic object or function returning the attribute passed (by name) as 8093 second parameter of the thing passed as first (a state, event or state 8094 machine). Example: </para> 8095 <para> 8096 <programlisting>attribute_(substate_(my_state),cd_name_attribute)++</programlisting> 8097 </para> 8098 </refsect3> 8099 <refsect3> 8100 <title>True_</title> 8101 <para>Functor returning true for transition or state behaviors. Like all 8102 constants, only the functor form exists, so parenthesis are necessary. 8103 Example:</para> 8104 <para> 8105 <programlisting>if_then_(True_(),/* some action always called*/)</programlisting> 8106 </para> 8107 </refsect3> 8108 <refsect3> 8109 <title>False_</title> 8110 <para>Functor returning false for transition or state behaviors. Like all 8111 constants, only the functor form exists, so parenthesis are necessary. 8112 Example:</para> 8113 <para> 8114 <programlisting>if_then_(False_(),/* some action never called */)</programlisting> 8115 </para> 8116 </refsect3> 8117 <refsect3> 8118 <title>Int_<int value></title> 8119 <para>Functor returning an integer value for transition or state behaviors. 8120 Like all constants, only the functor form exists, so parenthesis are 8121 necessary. Example:</para> 8122 <para> 8123 <programlisting>target_(m_ringing_cpt) = Int_<RINGING_TIME>() // RINGING_TIME is a constant</programlisting> 8124 </para> 8125 </refsect3> 8126 <refsect3> 8127 <title>Char_<char value></title> 8128 <para>Functor returning a char value for transition or state behaviors. Like 8129 all constants, only the functor form exists, so parenthesis are 8130 necessary. Example:</para> 8131 <para> 8132 <programlisting>// look for 'S' in event.m_song 8133[string_find_(event_(m_song),Char_<'S'>(),Size_t_<0>()) != Npos_<string>()]</programlisting> 8134 </para> 8135 </refsect3> 8136 <refsect3> 8137 <title>Size_t_<size_t value></title> 8138 <para>Functor returning a size_t value for transition or state behaviors. 8139 Like all constants, only the functor form exists, so parenthesis are 8140 necessary. Example:</para> 8141 <para> 8142 <programlisting>substr_(event_(m_song),Size_t_<1>()) // returns a substring of event.m_song</programlisting> 8143 </para> 8144 </refsect3> 8145 <refsect3> 8146 <title>String_ < mpl::string ></title> 8147 <para>Functor returning a string for transition or state behaviors. Like all 8148 constants, only the functor form exists, so parenthesis are necessary. 8149 Requires boost >= 1.40 for mpl::string.</para> 8150 <para>Example:</para> 8151 <para> 8152 <programlisting>// adds "Let it be" to fsm.m_src_container 8153push_back_(fsm_(m_src_container), String_<mpl::string<'Let','it ','be'> >())</programlisting> 8154 </para> 8155 </refsect3> 8156 <refsect3> 8157 <title>Predicate_ < some_stl_compatible_functor ></title> 8158 <para>This functor eUML-enables a STL functor (for use in an algorithm). 8159 This is necessary because all what is in the transition table must be a 8160 eUML terminal.</para> 8161 <para>Example:</para> 8162 <programlisting>//equivalent to: 8163//std::accumulate(fsm.m_vec.begin(),fsm.m_vec.end(),1,std::plus<int>())== 1 8164accumulate_(begin_(fsm_(m_vec)),end_(fsm_(m_vec)),Int_<1>(), 8165 Predicate_<std::plus<int> >()) == Int_<1>())</programlisting> 8166 </refsect3> 8167 <refsect3> 8168 <title>process_</title> 8169 <para>This function sends an event to up to 4 state machines by calling 8170 <code>process_event</code> on them:<itemizedlist> 8171 <listitem> 8172 <para><code>process_(some_event)</code> : processes an event in 8173 the current (containing) state machine.</para> 8174 </listitem> 8175 <listitem> 8176 <para><code>process_(some_event [,fsm1...fsm4] )</code> : 8177 processes the same event in the 1-4 state machines passed as 8178 argument.</para> 8179 </listitem> 8180 </itemizedlist></para> 8181 </refsect3> 8182 <refsect3> 8183 <title>process2_</title> 8184 <para>This function sends an event to up to 3 state machines by calling 8185 <code>process_event</code> on them and copy-constructing the event 8186 from the data passed as second parameter:<itemizedlist> 8187 <listitem> 8188 <para><code>process2_(some_event, some_data)</code> : processes 8189 an event in the current (containing) state machine.</para> 8190 </listitem> 8191 <listitem> 8192 <para><code>process2_(some_event, some_data [,fsm1...fsm3] 8193 )</code> : processes the same event in the 1-3 state 8194 machines passed as argument.</para> 8195 </listitem> 8196 </itemizedlist></para> 8197 <para>Example: </para> 8198 <para> 8199 <programlisting>// processes NotFound on current state machine, 8200// copy-constructed with event.m_song 8201process2_(NotFound,event_(m_song))</programlisting> 8202 </para> 8203 <para>With the following definitions:</para> 8204 <programlisting>BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,m_song)//declaration of m_song 8205NotFound (const string& data) // copy-constructor of NotFound</programlisting> 8206 </refsect3> 8207 <refsect3> 8208 <title>is_flag_</title> 8209 <para>This function tells if a flag is active by calling 8210 <code>is_flag_active</code> on the current state machine or one 8211 passed as parameter:<itemizedlist> 8212 <listitem> 8213 <para><code>is_flag_(some_flag)</code> : calls 8214 <code>is_flag_active</code> on the current (containing) 8215 state machine.</para> 8216 </listitem> 8217 <listitem> 8218 <para><code>is_flag_(some_flag, some_fsm)</code> :calls 8219 <code>is_flag_active</code> on the state machine.passed 8220 as argument.</para> 8221 </listitem> 8222 </itemizedlist></para> 8223 </refsect3> 8224 <refsect3> 8225 <title>defer_</title> 8226 <para>This object defers the current event by calling 8227 <code>defer_event</code> on the current state machine. 8228 Example:</para> 8229 <programlisting>Empty() + play() / defer_</programlisting> 8230 </refsect3> 8231 <refsect3> 8232 <title>explicit_(submachine-name,state-name)</title> 8233 <para>Used as transition's target, causes an explicit entry into the given 8234 state from the given submachine. Several explicit_ as targets, separated 8235 by commas, means a fork. The state must have been declared as such using 8236 BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE.</para> 8237 </refsect3> 8238 <refsect3> 8239 <title>entry_pt_(submachine-name,state-name)</title> 8240 <para>Used as transition's target from a containing state machine, causes 8241 submachine-name to be entered using the given entry pseudo-state. This 8242 state must have been declared as pseudo entry using 8243 BOOST_MSM_EUML_ENTRY_STATE.</para> 8244 </refsect3> 8245 <refsect3> 8246 <title>exit_pt_(submachine-name,state-name)</title> 8247 <para>Used as transition's source from a containing state machine, causes 8248 submachine-name to be left using the given exit pseudo-state. This state 8249 must have been declared as pseudo exit using 8250 BOOST_MSM_EUML_EXIT_STATE.</para> 8251 </refsect3> 8252 <refsect3> 8253 <title>MSM_EUML_FUNCTION</title> 8254 <para>This macro creates a eUML function and a functor for use with the 8255 functor front-end, based on a free function:<itemizedlist> 8256 <listitem> 8257 <para>first parameter: the name of the functor</para> 8258 </listitem> 8259 <listitem> 8260 <para>second parameter: the underlying function</para> 8261 </listitem> 8262 <listitem> 8263 <para>third parameter: the eUML function name</para> 8264 </listitem> 8265 <listitem> 8266 <para>fourth parameter: the return type if used in a transition 8267 behavior</para> 8268 </listitem> 8269 <listitem> 8270 <para>fifth parameter: the return type if used in a state 8271 behavior (entry/exit)</para> 8272 </listitem> 8273 </itemizedlist> Note that the function itself can take up to 5 8274 arguments.</para> 8275 <para>Example:</para> 8276 <para> 8277 <programlisting>MSM_EUML_FUNCTION(BinarySearch_,std::binary_search,binary_search_,bool,bool)</programlisting> 8278 </para> 8279 <para>Can be used like:</para> 8280 <para> 8281 <programlisting>binary_search_(begin_(fsm_(m_var)),end_(fsm_(m_var)),Int_<9>())</programlisting> 8282 </para> 8283 </refsect3> 8284 <refsect3> 8285 <title>MSM_EUML_METHOD</title> 8286 <para>This macro creates a eUML function and a functor for use with the 8287 functor front-end, based on a method:<itemizedlist> 8288 <listitem> 8289 <para>first parameter: the name of the functor</para> 8290 </listitem> 8291 <listitem> 8292 <para>second parameter: the underlying function</para> 8293 </listitem> 8294 <listitem> 8295 <para>third parameter: the eUML function name</para> 8296 </listitem> 8297 <listitem> 8298 <para>fourth parameter: the return type if used in a transition 8299 behavior</para> 8300 </listitem> 8301 <listitem> 8302 <para>fifth parameter: the return type if used in a state 8303 behavior (entry/exit)</para> 8304 </listitem> 8305 </itemizedlist> Note that the method itself can take up to 4 arguments 8306 (5 like for a free function - 1 for the object on which the method is 8307 called).</para> 8308 <para>Example:</para> 8309 <programlisting>struct Empty : public msm::front::state<> , public euml_state<Empty> 8310{ 8311 void activate_empty() {std::cout << "switching to Empty " << std::endl;} 8312... 8313}; 8314MSM_EUML_METHOD(ActivateEmpty_,activate_empty,activate_empty_,void,void)</programlisting> 8315 <para>Can be used like:</para> 8316 <para> 8317 <programlisting>Empty == Open + open_close / (close_drawer , activate_empty_(target_))</programlisting> 8318 </para> 8319 </refsect3> 8320 <refsect3> 8321 <title>BOOST_MSM_EUML_ACTION(action-instance-name)</title> 8322 <para>This macro declares a behavior type and a const instance for use in 8323 state or transition behaviors. The action implementation itself follows 8324 the macro declaration, for example:</para> 8325 <programlisting>BOOST_MSM_EUML_ACTION(good_disk_format) 8326{ 8327 template <class Fsm,class Evt,class SourceState,class TargetState> 8328 void/bool operator()(Evt const& evt,Fsm&,SourceState& ,TargetState& ){...} 8329};</programlisting> 8330 </refsect3> 8331 <refsect3> 8332 <title>BOOST_MSM_EUML_FLAG(flag-instance-name)</title> 8333 <para>This macro declares a flag type and a const instance for use in 8334 behaviors.</para> 8335 </refsect3> 8336 <refsect3> 8337 <title>BOOST_MSM_EUML_FLAG_NAME(flag-instance-name)</title> 8338 <para>This macro returns the name of the flag type generated by 8339 BOOST_MSM_EUML_FLAG. You need this where the type is required (usually 8340 with the back-end method is_flag_active). For example:</para> 8341 <programlisting>fsm.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(CDLoaded)>()</programlisting> 8342 </refsect3> 8343 <refsect3> 8344 <title>BOOST_MSM_EUML_DECLARE_ATTRIBUTE(event-type,event-name)</title> 8345 <para>This macro declares an attribute called event-name of type event-type. 8346 This attribute can then be made part of an attribute list using 8347 BOOST_MSM_EUML_ATTRIBUTES.</para> 8348 </refsect3> 8349 <refsect3> 8350 <title>BOOST_MSM_EUML_ATTRIBUTES(attributes-expression,attributes-name)</title> 8351 <para>This macro declares an attribute list called attributes-name based on 8352 the expression as first argument. These attributes can then be made part 8353 of an event using BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES, of a state as 8354 3rd parameter of BOOST_MSM_EUML_STATE or of a state machine as 5th 8355 parameter of BOOST_MSM_EUML_DECLARE_STATE_MACHINE.</para> 8356 <para>Attributes are added using left-shift, for example:</para> 8357 <programlisting>// m_song is of type std::string 8358BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,m_song) 8359// contains one attribute, m_song 8360BOOST_MSM_EUML_ATTRIBUTES((attributes_ << m_song ), FoundDef)</programlisting> 8361 </refsect3> 8362 <refsect3> 8363 <title>BOOST_MSM_EUML_EVENT(event-instance name)</title> 8364 <para>This macro defines an event type (event-instance-name_helper) and 8365 declares a const instance of this event type called event-instance-name 8366 for use in a transition table or state behaviors.</para> 8367 </refsect3> 8368 <refsect3> 8369 <title>BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(event-instance-name,attributes)</title> 8370 <para>This macro defines an event type (event-instance-name_helper) and 8371 declares a const instance of this event type called event-instance-name 8372 for use in a transition table or state behaviors. The event will have as 8373 attributes the ones passed by the second argument:</para> 8374 <para><code>BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(Found,FoundDef)</code> 8375 </para> 8376 <para>The created event instance supports operator()(attributes) so that 8377 <programlisting>my_back_end.process_event(Found(some_string))</programlisting> 8378 is possible.</para> 8379 </refsect3> 8380 <refsect3> 8381 <title>BOOST_MSM_EUML_EVENT_NAME(event-instance-name)</title> 8382 <para>This macro returns the name of the event type generated by 8383 BOOST_MSM_EUML_EVENT or BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES. You need 8384 this where the type is required (usually inside a back-end definition). 8385 For example:</para> 8386 <para> 8387 <programlisting>typedef msm::back::state_machine<Playing_, 8388msm::back::ShallowHistory<mpl::vector<BOOST_MSM_EUML_EVENT_NAME(end_pause) 8389> > > Playing_type;</programlisting> 8390 </para> 8391 </refsect3> 8392 <refsect3> 8393 <title>BOOST_MSM_EUML_STATE(build-expression,state-instance-name)</title> 8394 <para>This macro defines a state type (state-instance-name_helper) and 8395 declares a const instance of this state type called state-instance-name 8396 for use in a transition table or state behaviors.</para> 8397 <para>There are several possibilitites for the expression syntax:<itemizedlist> 8398 <listitem> 8399 <para>(): state without entry or exit action.</para> 8400 </listitem> 8401 <listitem> 8402 <para>(Expr1): state with entry but no exit action.</para> 8403 </listitem> 8404 <listitem> 8405 <para>(Expr1,Expr2): state with entry and exit action.</para> 8406 </listitem> 8407 <listitem> 8408 <para>(Expr1,Expr2,Attributes): state with entry and exit 8409 action, defining some attributes.</para> 8410 </listitem> 8411 <listitem> 8412 <para>(Expr1,Expr2,Attributes,Configure): state with entry and 8413 exit action, defining some attributes and flags (standard 8414 MSM flags) or deferred events (standard MSM deferred 8415 events).</para> 8416 </listitem> 8417 <listitem> 8418 <para>(Expr1,Expr2,Attributes,Configure,Base): state with entry 8419 and exit action, defining some attributes, flags and 8420 deferred events (plain msm deferred events) and a 8421 non-default base state (as defined in standard MSM).</para> 8422 </listitem> 8423 </itemizedlist></para> 8424 </refsect3> 8425 <refsect3> 8426 <title>BOOST_MSM_EUML_INTERRUPT_STATE(build-expression,state-instance-name)</title> 8427 <para>This macro defines an interrupt state type 8428 (state-instance-name_helper) and declares a const instance of this state 8429 type called state-instance-name for use in a transition table or state 8430 behaviors.</para> 8431 <para>There are several possibilitites for the expression syntax. In all of 8432 them, the first argument is the name of the event (generated by one of 8433 the previous macros) ending the interrupt:<itemizedlist> 8434 <listitem> 8435 <para>(end_interrupt_event): interrupt state without entry or 8436 exit action.</para> 8437 </listitem> 8438 <listitem> 8439 <para>(end_interrupt_event,Expr1): interrupt state with entry 8440 but no exit action.</para> 8441 </listitem> 8442 <listitem> 8443 <para>(end_interrupt_event,Expr1,Expr2): interrupt state with 8444 entry and exit action.</para> 8445 </listitem> 8446 <listitem> 8447 <para>(end_interrupt_event,Expr1,Expr2,Attributes): interrupt 8448 state with entry and exit action, defining some 8449 attributes.</para> 8450 </listitem> 8451 <listitem> 8452 <para>(end_interrupt_event,Expr1,Expr2,Attributes,Configure): 8453 interrupt state with entry and exit action, defining some 8454 attributes and flags (standard MSM flags) or deferred events 8455 (standard MSM deferred events).</para> 8456 </listitem> 8457 <listitem> 8458 <para>(end_interrupt_event,Expr1,Expr2,Attributes,Configure,Base): 8459 interrupt state with entry and exit action, defining some 8460 attributes, flags and deferred events (plain msm deferred 8461 events) and a non-default base state (as defined in standard 8462 MSM).</para> 8463 </listitem> 8464 </itemizedlist></para> 8465 </refsect3> 8466 <refsect3> 8467 <title>BOOST_MSM_EUML_TERMINATE_STATE(build-expression,state-instance-name)</title> 8468 <para>This macro defines a terminate pseudo-state type 8469 (state-instance-name_helper) and declares a const instance of this state 8470 type called state-instance-name for use in a transition table or state 8471 behaviors.</para> 8472 <para>There are several possibilitites for the expression syntax:<itemizedlist> 8473 <listitem> 8474 <para>(): terminate pseudo-state without entry or exit 8475 action.</para> 8476 </listitem> 8477 <listitem> 8478 <para>(Expr1): terminate pseudo-state with entry but no exit 8479 action.</para> 8480 </listitem> 8481 <listitem> 8482 <para>(Expr1,Expr2): terminate pseudo-state with entry and exit 8483 action.</para> 8484 </listitem> 8485 <listitem> 8486 <para>(Expr1,Expr2,Attributes): terminate pseudo-state with 8487 entry and exit action, defining some attributes.</para> 8488 </listitem> 8489 <listitem> 8490 <para>(Expr1,Expr2,Attributes,Configure): terminate pseudo-state 8491 with entry and exit action, defining some attributes and 8492 flags (standard MSM flags) or deferred events (standard MSM 8493 deferred events).</para> 8494 </listitem> 8495 <listitem> 8496 <para>(Expr1,Expr2,Attributes,Configure,Base): terminate 8497 pseudo-state with entry and exit action, defining some 8498 attributes, flags and deferred events (plain msm deferred 8499 events) and a non-default base state (as defined in standard 8500 MSM).</para> 8501 </listitem> 8502 </itemizedlist></para> 8503 </refsect3> 8504 <refsect3> 8505 <title>BOOST_MSM_EUML_EXIT_STATE(build-expression,state-instance-name)</title> 8506 <para>This macro defines an exit pseudo-state type 8507 (state-instance-name_helper) and declares a const instance of this state 8508 type called state-instance-name for use in a transition table or state 8509 behaviors.</para> 8510 <para>There are several possibilitites for the expression syntax:<itemizedlist> 8511 <listitem> 8512 <para>(forwarded_event):exit pseudo-state without entry or exit 8513 action.</para> 8514 </listitem> 8515 <listitem> 8516 <para>(forwarded_event,Expr1): exit pseudo-state with entry but 8517 no exit action.</para> 8518 </listitem> 8519 <listitem> 8520 <para>(forwarded_event,Expr1,Expr2): exit pseudo-state with 8521 entry and exit action.</para> 8522 </listitem> 8523 <listitem> 8524 <para>(forwarded_event,Expr1,Expr2,Attributes): exit 8525 pseudo-state with entry and exit action, defining some 8526 attributes.</para> 8527 </listitem> 8528 <listitem> 8529 <para>(forwarded_event,Expr1,Expr2,Attributes,Configure): exit 8530 pseudo-state with entry and exit action, defining some 8531 attributes and flags (standard MSM flags) or deferred events 8532 (standard MSM deferred events).</para> 8533 </listitem> 8534 <listitem> 8535 <para>(forwarded_event,Expr1,Expr2,Attributes,Configure,Base): 8536 exit pseudo-state with entry and exit action, defining some 8537 attributes, flags and deferred events (plain msm deferred 8538 events) and a non-default base state (as defined in standard 8539 MSM).</para> 8540 </listitem> 8541 </itemizedlist></para> 8542 <para>Note that the forwarded_event must be constructible from the event 8543 sent by the submachine containing the exit point.</para> 8544 </refsect3> 8545 <refsect3> 8546 <title>BOOST_MSM_EUML_ENTRY_STATE(int 8547 region-index,build-expression,state-instance-name)</title> 8548 <para>This macro defines an entry pseudo-state type 8549 (state-instance-name_helper) and declares a const instance of this state 8550 type called state-instance-name for use in a transition table or state 8551 behaviors.</para> 8552 <para>There are several possibilitites for the expression syntax:<itemizedlist> 8553 <listitem> 8554 <para>(): entry pseudo-state without entry or exit 8555 action.</para> 8556 </listitem> 8557 <listitem> 8558 <para>(Expr1): entry pseudo-state with entry but no exit 8559 action.</para> 8560 </listitem> 8561 <listitem> 8562 <para>(Expr1,Expr2): entry pseudo-state with entry and exit 8563 action.</para> 8564 </listitem> 8565 <listitem> 8566 <para>(Expr1,Expr2,Attributes): entry pseudo-state with entry 8567 and exit action, defining some attributes.</para> 8568 </listitem> 8569 <listitem> 8570 <para>(Expr1,Expr2,Attributes,Configure): entry pseudo-state 8571 with entry and exit action, defining some attributes and 8572 flags (standard MSM flags) or deferred events (standard MSM 8573 deferred events).</para> 8574 </listitem> 8575 <listitem> 8576 <para>(Expr1,Expr2,Attributes,Configure,Base): entry 8577 pseudo-state with entry and exit action, defining some 8578 attributes, flags and deferred events (plain msm deferred 8579 events) and a non-default base state (as defined in standard 8580 MSM).</para> 8581 </listitem> 8582 </itemizedlist></para> 8583 </refsect3> 8584 <refsect3> 8585 <title>BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE(int 8586 region-index,build-expression,state-instance-name)</title> 8587 <para>This macro defines a submachine's substate type 8588 (state-instance-name_helper), which can be explicitly entered and also 8589 declares a const instance of this state type called state-instance-name 8590 for use in a transition table or state behaviors.</para> 8591 <para>There are several possibilitites for the expression syntax:<itemizedlist> 8592 <listitem> 8593 <para>(): state without entry or exit action.</para> 8594 </listitem> 8595 <listitem> 8596 <para>(Expr1): state with entry but no exit action.</para> 8597 </listitem> 8598 <listitem> 8599 <para>(Expr1,Expr2): state with entry and exit action.</para> 8600 </listitem> 8601 <listitem> 8602 <para>(Expr1,Expr2,Attributes): state with entry and exit 8603 action, defining some attributes.</para> 8604 </listitem> 8605 <listitem> 8606 <para>(Expr1,Expr2,Attributes,Configure): state with entry and 8607 exit action, defining some attributes and flags (standard 8608 MSM flags) or deferred events (standard MSM deferred 8609 events).</para> 8610 </listitem> 8611 <listitem> 8612 <para>(Expr1,Expr2,Attributes,Configure,Base): state with entry 8613 and exit action, defining some attributes, flags and 8614 deferred events (plain msm deferred events) and a 8615 non-default base state (as defined in standard MSM).</para> 8616 </listitem> 8617 </itemizedlist></para> 8618 </refsect3> 8619 <refsect3> 8620 <title>BOOST_MSM_EUML_STATE_NAME(state-instance-name)</title> 8621 <para>This macro returns the name of the state type generated by 8622 BOOST_MSM_EUML_STATE or other state macros. You need this where the type 8623 is required (usually using a backend function). For example:</para> 8624 <para> 8625 <programlisting>fsm.get_state<BOOST_MSM_EUML_STATE_NAME(StringFind)&>().some_state_function();</programlisting> 8626 </para> 8627 </refsect3> 8628 <refsect3> 8629 <title>BOOST_MSM_EUML_DECLARE_STATE(build-expression,state-instance-name)</title> 8630 <para>Like BOOST_MSM_EUML_STATE but does not provide an instance, simply a 8631 type declaration.</para> 8632 </refsect3> 8633 <refsect3> 8634 <title>BOOST_MSM_EUML_DECLARE_INTERRUPT_STATE(build-expression,state-instance-name)</title> 8635 <para>Like BOOST_MSM_EUML_INTERRUPT_STATE but does not provide an instance, 8636 simply a type declaration.</para> 8637 </refsect3> 8638 <refsect3> 8639 <title>BOOST_MSM_EUML_DECLARE_TERMINATE_STATE(build-expression,state-instance-name)</title> 8640 <para>Like BOOST_MSM_EUML_TERMINATE_STATE but does not provide an instance, 8641 simply a type declaration.</para> 8642 </refsect3> 8643 <refsect3> 8644 <title>BOOST_MSM_EUML_DECLARE_EXIT_STATE(build-expression,state-instance-name)</title> 8645 <para>Like BOOST_MSM_EUML_EXIT_STATE but does not provide an instance, 8646 simply a type declaration.</para> 8647 </refsect3> 8648 <refsect3> 8649 <title>BOOST_MSM_EUML_DECLARE_ENTRY_STATE(int 8650 region-index,build-expression,state-instance-name)</title> 8651 <para>Like BOOST_MSM_EUML_ENTRY_STATE but does not provide an instance, 8652 simply a type declaration.</para> 8653 </refsect3> 8654 <refsect3> 8655 <title>BOOST_MSM_EUML_DECLARE_EXPLICIT_ENTRY_STATE(int 8656 region-index,build-expression,state-instance-name)</title> 8657 <para>Like BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE but does not provide an 8658 instance, simply a type declaration.</para> 8659 </refsect3> 8660 <refsect3> 8661 <title>BOOST_MSM_EUML_TRANSITION_TABLE(expression, 8662 table-instance-name)</title> 8663 <para>This macro declares a transition table type and also declares a const 8664 instance of the table which can then be used in a state machine 8665 declaration (see BOOST_MSM_EUML_DECLARE_STATE_MACHINE).The expression 8666 must follow the <command xlink:href="#reference-stt-grammar">transition 8667 table grammar</command>.</para> 8668 </refsect3> 8669 <refsect3> 8670 <title>BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE(iexpression,table-instance-name)</title> 8671 <para>Like BOOST_MSM_EUML_TRANSITION_TABLE but does not provide an instance, 8672 simply a type declaration.</para> 8673 </refsect3> 8674 <refsect3> 8675 <title>BOOST_MSM_EUML_INTERNAL_TRANSITION_TABLE(expression, 8676 table-instance-name)</title> 8677 <para>This macro declares a transition table type and also declares a const 8678 instance of the table.The expression must follow the <command 8679 xlink:href="#reference-stt-grammar">transition table 8680 grammar</command>. For the moment, this macro is not used.</para> 8681 </refsect3> 8682 <refsect3> 8683 <title>BOOST_MSM_EUML_DECLARE_INTERNAL_TRANSITION_TABLE(iexpression,table-instance-name)</title> 8684 <para>Like BOOST_MSM_EUML_TRANSITION_TABLE but does not provide an instance, 8685 simply a type declaration. This is currently the only way to declare an 8686 internal transition table with eUML. For example:</para> 8687 <programlisting>BOOST_MSM_EUML_DECLARE_STATE((Open_Entry,Open_Exit),Open_def) 8688struct Open_impl : public Open_def 8689{ 8690 BOOST_MSM_EUML_DECLARE_INTERNAL_TRANSITION_TABLE(( 8691 open_close [internal_guard1] / internal_action1 , 8692 open_close [internal_guard2] / internal_action2 8693 )) 8694}; </programlisting> 8695 </refsect3> 8696 </refsect2> 8697 </refsect1> 8698 </refentry> 8699 </part> 8700</book> 8701