Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/statechart/doc/tutorial.html @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 68.1 KB
Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
3<html>
4<head>
5  <meta http-equiv="Content-Language" content="en-us">
6  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
7  <meta name="GENERATOR" content="Microsoft FrontPage 6.0">
8  <meta name="ProgId" content="FrontPage.Editor.Document">
9  <link rel="stylesheet" type="text/css" href="../../../boost.css">
10
11  <title>The Boost Statechart Library - Tutorial</title>
12</head>
13
14<body link="#0000FF" vlink="#800080">
15  <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
16  "header">
17    <tr>
18      <td valign="top" width="300">
19        <h3><a href="../../../index.htm"><img alt="C++ Boost" src=
20        "../../../boost.png" border="0" width="277" height="86"></a></h3>
21      </td>
22
23      <td valign="top">
24        <h1 align="center">The Boost Statechart Library</h1>
25
26        <h2 align="center">Tutorial</h2>
27      </td>
28    </tr>
29  </table>
30  <hr>
31
32  <p>A Japanese translation of an earlier version of this tutorial can be
33  found at <a href=
34  "http://prdownloads.sourceforge.jp/jyugem/7127/fsm-tutorial-jp.pdf">http://prdownloads.sourceforge.jp/jyugem/7127/fsm-tutorial-jp.pdf</a>.
35  Kindly contributed by Mitsuo Fukasawa.</p>
36
37  <h2>Contents</h2>
38
39  <dl class="page-index">
40    <dt><a href="#Introduction">Introduction</a></dt>
41
42    <dd><a href="#HowToReadThisTutorial">How to read this tutorial</a></dd>
43
44    <dt><a href="#HelloWorld">Hello World!</a></dt>
45
46    <dt><a href="#BasicTopicsAStopWatch">Basic topics: A stop watch</a></dt>
47
48    <dd><a href="#DefiningStatesAndEvents">Defining states and
49    events</a></dd>
50
51    <dd><a href="#AddingReactions">Adding reactions</a></dd>
52
53    <dd><a href="#StateLocalStorage">State-local storage</a></dd>
54
55    <dd><a href="#GettingStateInformationOutOfTheMachine">Getting state
56    information out of the machine</a></dd>
57
58    <dt><a href="#IntermediateTopicsADigitalCamera">Intermediate topics: A
59    digital camera</a></dt>
60
61    <dd><a href=
62    "#SpreadingAStateMachineOverMultipleTranslationUnits">Spreading a state
63    machine over multiple translation units</a></dd>
64
65    <dd><a href="#DeferringEvents">Deferring events</a></dd>
66
67    <dd><a href="#Guards">Guards</a></dd>
68
69    <dd><a href="#InStateReactions">In-state reactions</a></dd>
70
71    <dd><a href="#TransitionActions">Transition actions</a></dd>
72
73    <dt><a href="#AdvancedTopics">Advanced topics</a></dt>
74
75    <dd><a href="#SpecifyingMultipleReactionsForAState">Specifying multiple
76    reactions for a state</a></dd>
77
78    <dd><a href="#PostingEvents">Posting events</a></dd>
79
80    <dd><a href="#History">History</a></dd>
81
82    <dd><a href="#OrthogonalStates">Orthogonal states</a></dd>
83
84    <dd><a href="#StateQueries">State queries</a></dd>
85
86    <dd><a href="#StateTypeInformation">State type information</a></dd>
87
88    <dd><a href="#ExceptionHandling">Exception handling</a></dd>
89
90    <dd><a href="#SubmachinesAndParameterizedStates">Submachines &amp;
91    Parametrized States</a></dd>
92
93    <dd><a href="#AsynchronousStateMachines">Asynchronous state
94    machines</a></dd>
95  </dl>
96  <hr>
97
98  <h2><a name="Introduction" id="Introduction">Introduction</a></h2>
99
100  <p>The Boost Statechart library is a framework that allows you to quickly
101  transform a UML statechart into executable C++ code, <b>without</b> needing
102  to use a code generator. Thanks to support for almost all UML features the
103  transformation is straight-forward and the resulting C++ code is a nearly
104  redundancy-free textual description of the statechart.</p>
105
106  <h3><a name="HowToReadThisTutorial" id="HowToReadThisTutorial">How to read
107  this tutorial</a></h3>
108
109  <p>This tutorial was designed to be read linearly. First time users should
110  start reading right at the beginning and stop as soon as they know enough
111  for the task at hand. Specifically:</p>
112
113  <ul>
114    <li>Small and simple machines with just a handful of states can be
115    implemented reasonably well by using the features described under
116    <a href="#BasicTopicsAStopWatch">Basic topics: A stop watch</a></li>
117
118    <li>For larger machines with up to roughly a dozen states the features
119    described under <a href="#IntermediateTopicsADigitalCamera">Intermediate
120    topics: A digital camera</a> are often helpful</li>
121
122    <li>Finally, users wanting to create even more complex machines and
123    project architects evaluating Boost.Statechart should also read the
124    <a href="#AdvancedTopics">Advanced topics</a> section at the end.
125    Moreover, reading the <a href=
126    "rationale.html#Limitations">Limitations</a> section in the Rationale is
127    strongly suggested</li>
128  </ul>
129
130  <h2><a name="HelloWorld" id="HelloWorld">Hello World!</a></h2>
131
132  <p>We will use the simplest possible program to make our first steps. The
133  statechart ...</p>
134
135  <p><img alt="HelloWorld" src="HelloWorld.gif" border="0" width="379"
136  height="94"></p>
137
138  <p>... is implemented with the following code:</p>
139  <pre>
140#include &lt;boost/statechart/state_machine.hpp&gt;
141#include &lt;boost/statechart/simple_state.hpp&gt;
142#include &lt;iostream&gt;
143
144namespace sc = boost::statechart;
145
146// We are declaring all types as <code>struct</code>s only to avoid having to
147// type <code>public</code>. If you don't mind doing so, you can just as well
148// use <code>class.</code>
149
150// We need to forward-declare the initial state because it can
151// only be defined at a point where the state machine is
152// defined.
153struct Greeting;
154
155// Boost.Statechart makes heavy use of the curiously recurring
156// template pattern. The deriving class must always be passed as
157// the first parameter to all base class templates.
158//
159// The state machine must be informed which state it has to
160// enter when the machine is initiated. That's why Greeting is
161// passed as the second template parameter.
162struct Machine : sc::state_machine&lt; Machine, Greeting &gt; {};
163
164// For each state we need to define which state machine it
165// belongs to and where it is located in the statechart. Both is
166// specified with Context argument that is passed to
167// simple_state&lt;&gt;. For a flat state machine as we have it here,
168// the context is always the state machine. Consequently,
169// Machine must be passed as the second template parameter to
170// Greeting's base (the Context parameter is explained in more
171// detail in the next example).
172struct Greeting : sc::simple_state&lt; Greeting, Machine &gt;
173{
174  // Whenever the state machine enters a state, it creates an
175  // object of the corresponding state class. The object is then
176  // kept alive as long as the machine remains in the state.
177  // Finally, the object is destroyed when the state machine
178  // exits the state. Therefore, a state entry action can be
179  // defined by adding a constructor and a state exit action can
180  // be defined by adding a destructor.
181  Greeting() { std::cout &lt;&lt; "Hello World!\n"; } // entry
182  ~Greeting() { std::cout &lt;&lt; "Bye Bye World!\n"; } // exit
183};
184
185int main()
186{
187  Machine myMachine;
188  // The machine is not yet running after construction. We start
189  // it by calling initiate(). This triggers the construction of
190  // the initial state Greeting
191  myMachine.initiate();
192  // When we leave main(), myMachine is destructed what leads to
193  // the destruction of all currently active states.
194  return 0;
195}
196</pre>
197
198  <p>This prints <code>Hello World!</code> and <code>Bye Bye World!</code>
199  before exiting.</p>
200
201  <h2><a name="BasicTopicsAStopWatch" id="BasicTopicsAStopWatch">Basic
202  topics: A stop watch</a></h2>
203
204  <p>Next we will model a simple mechanical stop watch with a state machine.
205  Such watches typically have two buttons:</p>
206
207  <ul>
208    <li>Start/Stop</li>
209
210    <li>Reset</li>
211  </ul>
212
213  <p>And two states:</p>
214
215  <ul>
216    <li>Stopped: The hands reside in the position where they were last
217    stopped:
218
219      <ul>
220        <li>Pressing the reset button moves the hands back to the 0 position.
221        The watch remains in the Stopped state</li>
222
223        <li>Pressing the start/stop button leads to a transition to the
224        Running state</li>
225      </ul>
226    </li>
227
228    <li>Running: The hands of the watch are in motion and continually show
229    the elapsed time
230
231      <ul>
232        <li>Pressing the reset button moves the hands back to the 0 position
233        and leads to a transition to the Stopped state</li>
234
235        <li>Pressing the start/stop button leads to a transition to the
236        Stopped state</li>
237      </ul>
238    </li>
239  </ul>
240
241  <p>Here is one way to specify this in UML:</p>
242
243  <p><img alt="StopWatch" src="StopWatch.gif" border="0" width="560" height=
244  "184"></p>
245
246  <h3><a name="DefiningStatesAndEvents" id="DefiningStatesAndEvents">Defining
247  states and events</a></h3>
248
249  <p>The two buttons are modeled by two events. Moreover, we also define the
250  necessary states and the initial state. <b>The following code is our
251  starting point, subsequent code snippets must be inserted</b>:</p>
252  <pre>
253#include &lt;boost/statechart/event.hpp&gt;
254#include &lt;boost/statechart/state_machine.hpp&gt;
255#include &lt;boost/statechart/simple_state.hpp&gt;
256
257namespace sc = boost::statechart;
258
259struct EvStartStop : sc::event&lt; EvStartStop &gt; {};
260struct EvReset : sc::event&lt; EvReset &gt; {};
261
262struct Active;
263struct StopWatch : sc::state_machine&lt; StopWatch, Active &gt; {};
264
265struct Stopped;
266
267// The simple_state class template accepts up to four parameters:
268// - The third parameter specifies the inner initial state, if
269//   there is one. Here, only Active has inner states, which is
270//   why it needs to pass its inner initial state Stopped to its
271//   base
272// - The fourth parameter specifies whether and what kind of
273//   history is kept
274
275// Active is the outermost state and therefore needs to pass the
276// state machine class it belongs to
277struct Active : sc::simple_state&lt;
278  Active, StopWatch, Stopped &gt; {};
279
280// Stopped and Running both specify Active as their Context,
281// which makes them nested inside Active
282struct Running : sc::simple_state&lt; Running, Active &gt; {};
283struct Stopped : sc::simple_state&lt; Stopped, Active &gt; {};
284
285// Because the context of a state must be a complete type (i.e.
286// not forward declared), a machine must be defined from
287// "outside to inside". That is, we always start with the state
288// machine, followed by outermost states, followed by the direct
289// inner states of outermost states and so on. We can do so in a
290// breadth-first or depth-first way or employ a mixture of the
291// two.
292
293int main()
294{
295  StopWatch myWatch;
296  myWatch.initiate();
297  return 0;
298}
299</pre>
300
301  <p>This compiles but doesn't do anything observable yet.</p>
302
303  <h3><a name="AddingReactions" id="AddingReactions">Adding
304  reactions</a></h3>
305
306  <p>For the moment we will use only one type of reaction: transitions. We
307  <b>insert</b> the bold parts of the following code:</p>
308  <pre>
309<b>#include &lt;boost/statechart/transition.hpp&gt;
310</b>
311// ...
312
313struct Stopped;
314struct Active : sc::simple_state&lt; Active, StopWatch, Stopped &gt;
315{
316  <b>typedef sc::transition&lt; EvReset, Active &gt; reactions;</b>
317};
318
319struct Running : sc::simple_state&lt; Running, Active &gt;
320{
321  <b>typedef sc::transition&lt; EvStartStop, Stopped &gt; reactions;</b>
322};
323
324struct Stopped : sc::simple_state&lt; Stopped, Active &gt;
325{
326  <b>typedef sc::transition&lt; EvStartStop, Running &gt; reactions;</b>
327};
328
329// A state can define an arbitrary number of reactions. That's
330// why we have to put them into an mpl::list&lt;&gt; as soon as there
331// is more than one of them
332// (see <a href=
333"#SpecifyingMultipleReactionsForAState">Specifying multiple reactions for a state</a>).
334
335int main()
336{
337  StopWatch myWatch;
338  myWatch.initiate();
339  <b>myWatch.process_event( EvStartStop() );
340</b>  <b>myWatch.process_event( EvStartStop() );
341</b>  <b>myWatch.process_event( EvStartStop() );
342</b>  <b>myWatch.process_event( EvReset() );
343</b>  return 0;
344}
345</pre>
346
347  <p>Now we have all the states and all the transitions in place and a number
348  of events are also sent to the stop watch. The machine dutifully makes the
349  transitions we would expect, but no actions are executed yet.</p>
350
351  <h3><a name="StateLocalStorage" id="StateLocalStorage">State-local
352  storage</a></h3>
353
354  <p>Next we'll make the stop watch actually measure time. Depending on the
355  state the stop watch is in, we need different variables:</p>
356
357  <ul>
358    <li>Stopped: One variable holding the elapsed time</li>
359
360    <li>Running: One variable holding the elapsed time <b>and</b> one
361    variable storing the point in time at which the watch was last
362    started.</li>
363  </ul>
364
365  <p>We observe that the elapsed time variable is needed no matter what state
366  the machine is in. Moreover, this variable should be reset to 0 when we
367  send an <code>EvReset</code> event to the machine. The other variable is
368  only needed while the machine is in the Running state. It should be set to
369  the current time of the system clock whenever we enter the Running state.
370  Upon exit we simply subtract the start time from the current system clock
371  time and add the result to the elapsed time.</p>
372  <pre>
373<b>#include &lt;ctime&gt;
374</b>
375// ...
376
377struct Stopped;
378struct Active : sc::simple_state&lt; Active, StopWatch, Stopped &gt;
379{
380  <b>public:</b>
381    typedef sc::transition&lt; EvReset, Active &gt; reactions;
382
383    <b>Active() : elapsedTime_( 0.0 ) {}
384</b>    <b>double ElapsedTime() const { return elapsedTime_; }
385</b>    <b>double &amp; ElapsedTime() { return elapsedTime_; }
386</b>  <b>private:
387</b>    <b>double elapsedTime_;
388</b>};
389
390struct Running : sc::simple_state&lt; Running, Active &gt;
391{
392  <b>public:</b>
393    typedef sc::transition&lt; EvStartStop, Stopped &gt; reactions;
394
395    <b>Running() : startTime_( std::time( 0 ) ) {}
396</b>    <b>~Running()
397</b>    <b>{</b>
398      // Similar to when a derived class object accesses its
399      // base class portion, context&lt;&gt;() is used to gain
400      // access to the direct or indirect context of a state.
401      // This can either be a direct or indirect outer state
402      // or the state machine itself
403      // (e.g. here: context&lt; StopWatch &gt;()).
404      <b>context&lt; Active &gt;().ElapsedTime() +=
405</b>        <b>std::difftime( std::time( 0 ), startTime_ );
406</b>    <b>}
407</b>  <b>private:
408</b>    <b>std::time_t startTime_;
409</b>};
410
411// ...
412</pre>
413
414  <p>The machine now measures the time, but we cannot yet retrieve it from
415  the main program.</p>
416
417  <p>At this point, the advantages of state-local storage (which is still a
418  relatively little-known feature) may not yet have become apparent. The FAQ
419  item "<a href="faq.html#StateLocalStorage">What's so cool about state-local
420  storage?</a>" tries to explain them in more detail by comparing this
421  StopWatch with one that does not make use of state-local storage.</p>
422
423  <h3><a name="GettingStateInformationOutOfTheMachine" id=
424  "GettingStateInformationOutOfTheMachine">Getting state information out of
425  the machine</a></h3>
426
427  <p>To retrieve the measured time, we need a mechanism to get state
428  information out of the machine. With our current machine design there are
429  two ways to do that. For the sake of simplicity we use the less efficient
430  one: <code>state_cast&lt;&gt;()</code> (StopWatch2.cpp shows the slightly
431  more complex alternative). As the name suggests, the semantics are very
432  similar to the ones of <code>dynamic_cast</code>. For example, when we call
433  <code>myWatch.state_cast&lt; const Stopped &amp; &gt;()</code> <b>and</b>
434  the machine is currently in the Stopped state, we get a reference to the
435  <code>Stopped</code> state. Otherwise <code>std::bad_cast</code> is thrown.
436  We can use this functionality to implement a <code>StopWatch</code> member
437  function that returns the elapsed time. However, rather than ask the
438  machine in which state it is and then switch to different calculations for
439  the elapsed time, we put the calculation into the Stopped and Running
440  states and use an interface to retrieve the elapsed time:</p>
441  <pre>
442<b>#include &lt;iostream&gt;
443
444</b>// ...
445
446<b>struct IElapsedTime
447{
448</b>  <b>virtual double ElapsedTime() const = 0;
449};
450
451</b>struct Active;
452struct StopWatch : sc::state_machine&lt; StopWatch, Active &gt;
453{
454  <b>double ElapsedTime() const
455</b>  <b>{
456</b>    <b>return state_cast&lt; const IElapsedTime &amp; &gt;().ElapsedTime();
457</b>  <b>}
458</b>};
459<b>
460</b>// ...
461
462struct Running : <b>IElapsedTime,</b>
463  sc::simple_state&lt; Running, Active &gt;
464{
465  public:
466    typedef sc::transition&lt; EvStartStop, Stopped &gt; reactions;
467
468    Running() : startTime_( std::time( 0 ) ) {}
469    ~Running()
470    {
471      <b>context&lt; Active &gt;().ElapsedTime() = ElapsedTime();
472</b>    }
473<b>
474</b>    <b>virtual double ElapsedTime() const
475</b>    <b>{
476</b>      <b>return context&lt; Active &gt;().ElapsedTime() +
477</b>        <b>std::difftime( std::time( 0 ), startTime_ );
478</b>    <b>}
479</b>  private:
480    std::time_t startTime_;
481};
482
483struct Stopped : <b>IElapsedTime,</b>
484  sc::simple_state&lt; Stopped, Active &gt;
485{
486  typedef sc::transition&lt; EvStartStop, Running &gt; reactions;
487
488  <b>virtual double ElapsedTime() const
489</b>  <b>{
490</b>    <b>return context&lt; Active &gt;().ElapsedTime();
491</b>  <b>}
492</b>};
493
494int main()
495{
496  StopWatch myWatch;
497  myWatch.initiate();
498  <b>std::cout &lt;&lt; myWatch.ElapsedTime() &lt;&lt; "\n";
499</b>  myWatch.process_event( EvStartStop() );
500  <b>std::cout &lt;&lt; myWatch.ElapsedTime() &lt;&lt; "\n";
501</b>  myWatch.process_event( EvStartStop() );
502  <b>std::cout &lt;&lt; myWatch.ElapsedTime() &lt;&lt; "\n";
503</b>  myWatch.process_event( EvStartStop() );
504  <b>std::cout &lt;&lt; myWatch.ElapsedTime() &lt;&lt; "\n";
505</b>  myWatch.process_event( EvReset() );
506  <b>std::cout &lt;&lt; myWatch.ElapsedTime() &lt;&lt; "\n";
507</b>  return 0;
508}
509</pre>
510
511  <p>To actually see time being measured, you might want to single-step
512  through the statements in <code>main()</code>. The StopWatch example
513  extends this program to an interactive console application.</p>
514
515  <h2><a name="IntermediateTopicsADigitalCamera" id=
516  "IntermediateTopicsADigitalCamera">Intermediate topics: A digital
517  camera</a></h2>
518
519  <p>So far so good. However, the approach presented above has a few
520  limitations:</p>
521
522  <ul>
523    <li>Bad scalability: As soon as the compiler reaches the point where
524    <code>state_machine::initiate()</code> is called, a number of template
525    instantiations take place, which can only succeed if the full declaration
526    of each and every state of the machine is known. That is, the whole
527    layout of a state machine must be implemented in one single translation
528    unit (actions can be compiled separately, but this is of no importance
529    here). For bigger (and more real-world) state machines, this leads to the
530    following limitations:
531
532      <ul>
533        <li>At some point compilers reach their internal template
534        instantiation limits and give up. This can happen even for
535        moderately-sized machines. For example, in debug mode one popular
536        compiler refused to compile earlier versions of the BitMachine
537        example for anything above 3 bits. This means that the compiler
538        reached its limits somewhere between 8 states, 24 transitions and 16
539        states, 64 transitions</li>
540
541        <li>Multiple programmers can hardly work on the same state machine
542        simultaneously because every layout change will inevitably lead to a
543        recompilation of the whole state machine</li>
544      </ul>
545    </li>
546
547    <li>Maximum one reaction per event: According to UML a state can have
548    multiple reactions triggered by the same event. This makes sense when all
549    reactions have mutually exclusive guards. The interface we used above
550    only allows for at most one unguarded reaction for each event. Moreover,
551    the UML concepts junction and choice point are not directly
552    supported</li>
553  </ul>
554
555  <p>All these limitations can be overcome with custom reactions. <b>Warning:
556  It is easy to abuse custom reactions up to the point of invoking undefined
557  behavior. Please study the documentation before employing them!</b></p>
558
559  <h3><a name="SpreadingAStateMachineOverMultipleTranslationUnits" id=
560  "SpreadingAStateMachineOverMultipleTranslationUnits">Spreading a state
561  machine over multiple translation units</a></h3>
562
563  <p>Let's say your company would like to develop a digital camera. The
564  camera has the following controls:</p>
565
566  <ul>
567    <li>Shutter button, which can be half-pressed and fully-pressed. The
568    associated events are <code>EvShutterHalf</code>,
569    <code>EvShutterFull</code> and <code>EvShutterReleased</code></li>
570
571    <li>Config button, represented by the <code>EvConfig</code> event</li>
572
573    <li>A number of other buttons that are not of interest here</li>
574  </ul>
575
576  <p>One use case for the camera says that the photographer can half-press
577  the shutter <b>anywhere</b> in the configuration mode and the camera will
578  immediately go into shooting mode. The following statechart is one way to
579  achieve this behavior:</p>
580
581  <p><img alt="Camera" src="Camera.gif" border="0" width="544" height=
582  "317"></p>
583
584  <p>The Configuring and Shooting states will contain numerous nested states
585  while the Idle state is relatively simple. It was therefore decided to
586  build two teams. One will implement the shooting mode while the other will
587  implement the configuration mode. The two teams have already agreed on the
588  interface that the shooting team will use to retrieve the configuration
589  settings. We would like to ensure that the two teams can work with the
590  least possible interference. So, we put the two states in their own
591  translation units so that machine layout changes within the Configuring
592  state will never lead to a recompilation of the inner workings of the
593  Shooting state and vice versa.</p>
594
595  <p><b>Unlike in the previous example, the excerpts presented here often
596  outline different options to achieve the same effect. That's why the code
597  is often not equal to the Camera example code.</b> Comments mark the parts
598  where this is the case.</p>
599
600  <p>Camera.hpp:</p>
601  <pre>
602#ifndef CAMERA_HPP_INCLUDED
603#define CAMERA_HPP_INCLUDED
604
605#include &lt;boost/statechart/event.hpp&gt;
606#include &lt;boost/statechart/state_machine.hpp&gt;
607#include &lt;boost/statechart/simple_state.hpp&gt;
608#include &lt;boost/statechart/custom_reaction.hpp&gt;
609
610namespace sc = boost::statechart;
611
612struct EvShutterHalf : sc::event&lt; EvShutterHalf &gt; {};
613struct EvShutterFull : sc::event&lt; EvShutterFull &gt; {};
614struct EvShutterRelease : sc::event&lt; EvShutterRelease &gt; {};
615struct EvConfig : sc::event&lt; EvConfig &gt; {};
616
617struct NotShooting;
618struct Camera : sc::state_machine&lt; Camera, NotShooting &gt;
619{
620  bool IsMemoryAvailable() const { return true; }
621  bool IsBatteryLow() const { return false; }
622};
623
624struct Idle;
625struct NotShooting : sc::simple_state&lt;
626  NotShooting, Camera, Idle &gt;
627{
628  // With a custom reaction we only specify that we <b>might</b> do
629  // something with a particular event, but the actual reaction
630  // is defined in the react member function, which can be
631  // implemented in the .cpp file.
632  <b>typedef sc::custom_reaction&lt; EvShutterHalf &gt; reactions;</b>
633
634  // ...
635  <b>sc::result react( const EvShutterHalf &amp; );</b>
636};
637
638struct Idle : sc::simple_state&lt; Idle, NotShooting &gt;
639{
640  <b>typedef sc::custom_reaction&lt; EvConfig &gt; reactions;</b>
641
642  // ...
643  <b>sc::result react( const EvConfig &amp; );</b>
644};
645
646#endif
647</pre>
648
649  <p>Camera.cpp:</p>
650  <pre>
651#include "Camera.hpp"
652
653// The following includes are only made here but not in
654// Camera.hpp
655// The Shooting and Configuring states can themselves apply the
656// same pattern to hide their inner implementation, which
657// ensures that the two teams working on the Camera state
658// machine will never need to disturb each other.
659#include "Configuring.hpp"
660#include "Shooting.hpp"
661
662// ...
663
664// not part of the Camera example
665sc::result NotShooting::react( const EvShutterHalf &amp; )
666{
667  return transit&lt; Shooting &gt;();
668}
669
670sc::result Idle::react( const EvConfig &amp; )
671{
672  return transit&lt; Configuring &gt;();
673}
674</pre>
675
676  <p><b><font color="#FF0000">Caution: Any call to
677  <code>simple_state&lt;&gt;::transit&lt;&gt;()</code> or
678  <code>simple_state&lt;&gt;::terminate()</code> (see <a href=
679  "reference.html#transit1">reference</a>) will inevitably destruct the state
680  object (similar to <code>delete this;</code>)! That is, code executed after
681  any of these calls may invoke undefined behavior!</font></b> That's why
682  these functions should only be called as part of a return statement.</p>
683
684  <h3><a name="DeferringEvents" id="DeferringEvents">Deferring
685  events</a></h3>
686
687  <p>The inner workings of the Shooting state could look as follows:</p>
688
689  <p><img alt="Camera2" src="Camera2.gif" border="0" width="427" height=
690  "427"></p>
691
692  <p>When the user half-presses the shutter, Shooting and its inner initial
693  state Focusing are entered. In the Focusing entry action the camera
694  instructs the focusing circuit to bring the subject into focus. The
695  focusing circuit then moves the lenses accordingly and sends the EvInFocus
696  event as soon as it is done. Of course, the user can fully-press the
697  shutter while the lenses are still in motion. Without any precautions, the
698  resulting EvShutterFull event would simply be lost because the Focusing
699  state does not define a reaction for this event. As a result, the user
700  would have to fully-press the shutter again after the camera has finished
701  focusing. To prevent this, the EvShutterFull event is deferred inside the
702  Focusing state. This means that all events of this type are stored in a
703  separate queue, which is emptied into the main queue when the Focusing
704  state is exited.</p>
705  <pre>
706struct Focusing : sc::state&lt; Focusing, Shooting &gt;
707{
708  typedef mpl::list&lt;
709    sc::custom_reaction&lt; EvInFocus &gt;,
710    <b>sc::deferral&lt; EvShutterFull &gt;</b>
711  &gt; reactions;
712
713  Focusing( my_context ctx );
714  sc::result react( const EvInFocus &amp; );
715};
716</pre>
717
718  <h3><a name="Guards" id="Guards">Guards</a></h3>
719
720  <p>Both transitions originating at the Focused state are triggered by the
721  same event but they have mutually exclusive guards. Here is an appropriate
722  custom reaction:</p>
723  <pre>
724// not part of the Camera example
725sc::result Focused::react( const EvShutterFull &amp; )
726{
727  if ( context&lt; Camera &gt;().IsMemoryAvailable() )
728  {
729    return transit&lt; Storing &gt;();
730  }
731  else
732  {
733    // The following is actually a mixture between an in-state
734    // reaction and a transition. See later on how to implement
735    // proper transition actions.
736    std::cout &lt;&lt; "Cache memory full. Please wait...\n";
737    return transit&lt; Focused &gt;();
738  }
739}
740</pre>
741
742  <p>Custom reactions can of course also be implemented directly in the state
743  declaration, which is often preferable for easier browsing.</p>
744
745  <p>Next we will use a guard to prevent a transition and let outer states
746  react to the event if the battery is low:</p>
747
748  <p>Camera.cpp:</p>
749  <pre>
750// ...
751sc::result NotShooting::react( const EvShutterHalf &amp; )
752{
753  if ( context&lt; Camera &gt;().IsBatteryLow() )
754  {
755    // We cannot react to the event ourselves, so we forward it
756    // to our outer state (this is also the default if a state
757    // defines no reaction for a given event).
758    <b>return forward_event();</b>
759  }
760  else
761  {
762    return transit&lt; Shooting &gt;();
763  }
764}
765// ...
766</pre>
767
768  <h3><a name="InStateReactions" id="InStateReactions">In-state
769  reactions</a></h3>
770
771  <p>The self-transition of the Focused state could also be implemented as an
772  <a href="definitions.html#InStateReaction">in-state reaction</a>, which has
773  the same effect as long as Focused does not have any entry or exit
774  actions:</p>
775
776  <p>Shooting.cpp:</p>
777  <pre>
778// ...
779sc::result Focused::react( const EvShutterFull &amp; )
780{
781  if ( context&lt; Camera &gt;().IsMemoryAvailable() )
782  {
783    return transit&lt; Storing &gt;();
784  }
785  else
786  {
787    std::cout &lt;&lt; "Cache memory full. Please wait...\n";
788    // Indicate that the event can be discarded. So, the
789    // dispatch algorithm will stop looking for a reaction
790    // and the machine remains in the Focused state.
791    <b>return discard_event();</b>
792  }
793}
794// ...
795</pre>
796
797  <p>Because the in-state reaction is guarded, we need to employ a
798  <code>custom_reaction&lt;&gt;</code> here. For unguarded in-state reactions
799  <code><a href=
800  "reference.html#ClassTemplatein_state_reaction">in_state_reaction</a>&lt;&gt;</code>
801  should be used for better code-readability.</p>
802
803  <h3><a name="TransitionActions" id="TransitionActions">Transition
804  actions</a></h3>
805
806  <p>As an effect of every transition, actions are executed in the following
807  order:</p>
808
809  <ol>
810    <li>Starting from the innermost active state, all exit actions up to but
811    excluding the <a href="definitions.html#InnermostCommonContext">innermost
812    common context</a></li>
813
814    <li>The transition action (if present)</li>
815
816    <li>Starting from the innermost common context, all entry actions down to
817    the target state followed by the entry actions of the initial states</li>
818  </ol>
819
820  <p>Example:</p>
821
822  <p><img alt="LCA" src="LCA.gif" border="0" width="604" height="304"></p>
823
824  <p>Here the order is as follows: ~D(), ~C(), ~B(), ~A(), t(), X(), Y(),
825  Z(). The transition action t() is therefore executed in the context of the
826  InnermostCommonOuter state because the source state has already been left
827  (destructed) and the target state has not yet been entered
828  (constructed).</p>
829
830  <p>With Boost.Statechart, a transition action can be a member of <b>any</b>
831  common outer context. That is, the transition between Focusing and Focused
832  could be implemented as follows:</p>
833
834  <p>Shooting.hpp:</p>
835  <pre>
836// ...
837struct Focusing;
838struct Shooting : sc::simple_state&lt; Shooting, Camera, Focusing &gt;
839{
840  typedef sc::transition&lt;
841    EvShutterRelease, NotShooting &gt; reactions;
842
843  // ...
844  <b>void DisplayFocused( const EvInFocus &amp; );</b>
845};
846
847// ...
848
849// not part of the Camera example
850struct Focusing : sc::simple_state&lt; Focusing, Shooting &gt;
851{
852  typedef sc::transition&lt; EvInFocus, Focused<b>,</b>
853    <b>Shooting, &amp;Shooting::DisplayFocused</b> &gt; reactions;
854};
855</pre>
856
857  <p><b>Or</b>, the following is also possible (here the state machine itself
858  serves as the outermost context):</p>
859  <pre>
860// not part of the Camera example
861struct Camera : sc::state_machine&lt; Camera, NotShooting &gt;
862{
863  <b>void DisplayFocused( const EvInFocus &amp; );</b>
864};
865</pre>
866  <pre>
867// not part of the Camera example
868struct Focusing : sc::simple_state&lt; Focusing, Shooting &gt;
869{
870  typedef sc::transition&lt; EvInFocus, Focused<b>,</b>
871    <b>Camera, &amp;Camera::DisplayFocused</b> &gt; reactions;
872};
873</pre>
874
875  <p>Naturally, transition actions can also be invoked from custom
876  reactions:</p>
877
878  <p>Shooting.cpp:</p>
879  <pre>
880// ...
881sc::result Focusing::react( const EvInFocus &amp; evt )
882{
883  // We have to manually forward evt
884  return transit&lt; Focused &gt;( <b>&amp;Shooting::DisplayFocused</b>, evt );
885}
886</pre>
887
888  <h2><a name="AdvancedTopics" id="AdvancedTopics">Advanced topics</a></h2>
889
890  <h3><a name="SpecifyingMultipleReactionsForAState" id=
891  "SpecifyingMultipleReactionsForAState">Specifying multiple reactions for a
892  state</a></h3>
893
894  <p>Often a state must define reactions for more than one event. In this
895  case, an <code>mpl::list&lt;&gt;</code> must be used as outlined below:</p>
896  <pre>
897// ...
898
899<b>#include &lt;boost/mpl/list.hpp&gt;
900</b>
901<b>namespace mpl = boost::mpl;
902</b>
903// ...
904
905struct Playing : sc::simple_state&lt; Playing, Mp3Player &gt;
906{
907  typdef <b>mpl::list&lt;</b>
908    sc::custom_reaction&lt; EvFastForward &gt;,
909    sc::transition&lt; EvStop, Stopped &gt; <b>&gt;</b> reactions;
910
911  /* ... */
912};
913</pre>
914
915  <h3><a name="PostingEvents" id="PostingEvents">Posting events</a></h3>
916
917  <p>Non-trivial state machines often need to post internal events. Here's an
918  example of how to do this:</p>
919  <pre>
920Pumping::~Pumping()
921{
922  post_event( EvPumpingFinished() );
923}
924</pre>
925
926  <p>The event is pushed into the main queue. The events in the queue are
927  processed as soon as the current reaction is completed. Events can be
928  posted from inside <code>react</code> functions, entry-, exit- and
929  transition actions. However, posting from inside entry actions is a bit
930  more complicated (see e.g. <code>Focusing::Focusing()</code> in
931  <code>Shooting.cpp</code> in the Camera example):</p>
932  <pre>
933struct Pumping : <b>sc::state</b>&lt; Pumping, Purifier &gt;
934{
935  <b>Pumping( my_context ctx ) : my_base( ctx )</b>
936  {
937    post_event( EvPumpingStarted() );
938  }
939  // ...
940};
941</pre>
942
943  <p>As soon as an entry action of a state needs to contact the "outside
944  world" (here: the event queue in the state machine), the state must derive
945  from <code>state&lt;&gt;</code> rather than from
946  <code>simple_state&lt;&gt;</code> and must implement a forwarding
947  constructor as outlined above (apart from the constructor,
948  <code>state&lt;&gt;</code> offers the same interface as
949  <code>simple_state&lt;&gt;</code>). Hence, this must be done whenever an
950  entry action makes one or more calls to the following functions:</p>
951
952  <ul>
953    <li><code>simple_state&lt;&gt;::post_event()</code></li>
954
955    <li>
956    <code>simple_state&lt;&gt;::clear_shallow_history&lt;&gt;()</code></li>
957
958    <li><code>simple_state&lt;&gt;::clear_deep_history&lt;&gt;()</code></li>
959
960    <li><code>simple_state&lt;&gt;::outermost_context()</code></li>
961
962    <li><code>simple_state&lt;&gt;::context&lt;&gt;()</code></li>
963
964    <li><code>simple_state&lt;&gt;::state_cast&lt;&gt;()</code></li>
965
966    <li><code>simple_state&lt;&gt;::state_downcast&lt;&gt;()</code></li>
967
968    <li><code>simple_state&lt;&gt;::state_begin()</code></li>
969
970    <li><code>simple_state&lt;&gt;::state_end()</code></li>
971  </ul>
972
973  <p>In my experience, these functions are needed only rarely in entry
974  actions so this workaround should not uglify user code too much.</p>
975
976  <h3><a name="History" id="History">History</a></h3>
977
978  <p>Photographers testing beta versions of our <a href=
979  "#SpreadingAStateMachineOverMultipleTranslationUnits">digital camera</a>
980  said that they really liked that half-pressing the shutter anytime (even
981  while the camera is being configured) immediately readies the camera for
982  picture-taking. However, most of them found it unintuitive that the camera
983  always goes into the idle mode after releasing the shutter. They would
984  rather see the camera go back into the state it had before half-pressing
985  the shutter. This way they can easily test the influence of a configuration
986  setting by modifying it, half- and then fully-pressing the shutter to take
987  a picture. Finally, releasing the shutter will bring them back to the
988  screen where they have modified the setting. To implement this behavior
989  we'd change the state chart as follows:</p>
990
991  <p><img alt="CameraWithHistory1" src="CameraWithHistory1.gif" border="0"
992  width="542" height="378"></p>
993
994  <p>As mentioned earlier, the Configuring state contains a fairly complex
995  and deeply nested inner machine. Naturally, we'd like to restore the
996  previous state down to the <a href=
997  "definitions.html#InnermostState">innermost state</a>(s) in Configuring,
998  that's why we use a deep history pseudo state. The associated code looks as
999  follows:</p>
1000  <pre>
1001// not part of the Camera example
1002struct NotShooting : sc::simple_state&lt;
1003  NotShooting, Camera, Idle, <b>sc::has_deep_history</b> &gt;
1004{
1005  // ...
1006};
1007
1008// ...
1009
1010struct Shooting : sc::simple_state&lt; Shooting, Camera, Focusing &gt;
1011{
1012  typedef sc::transition&lt;
1013    EvShutterRelease, <b>sc::deep_history&lt; Idle &gt;</b> &gt; reactions;
1014
1015  // ...
1016};
1017</pre>
1018
1019  <p>History has two phases: Firstly, when the state containing the history
1020  pseudo state is exited, information about the previously active inner state
1021  hierarchy must be saved. Secondly, when a transition to the history pseudo
1022  state is made later, the saved state hierarchy information must be
1023  retrieved and the appropriate states entered. The former is expressed by
1024  passing either <code>has_shallow_history</code>,
1025  <code>has_deep_history</code> or <code>has_full_history</code> (which
1026  combines shallow and deep history) as the last parameter to the
1027  <code>simple_state</code> and <code>state</code> class templates. The
1028  latter is expressed by specifying either
1029  <code>shallow_history&lt;&gt;</code> or <code>deep_history&lt;&gt;</code>
1030  as a transition destination or, as we'll see in an instant, as an inner
1031  initial state. Because it is possible that a state containing a history
1032  pseudo state has never been entered before a transition to history is made,
1033  both class templates demand a parameter specifying the default state to
1034  enter in such situations.</p>
1035
1036  <p>The redundancy necessary for using history is checked for consistency at
1037  compile time. That is, the state machine wouldn't have compiled had we
1038  forgotten to pass <code>has_deep_history</code> to the base of
1039  <code>NotShooting</code>.</p>
1040
1041  <p>Another change request filed by a few beta testers says that they would
1042  like to see the camera go back into the state it had before turning it off
1043  when they turn it back on. Here's the implementation:</p>
1044
1045  <p><img alt="CameraWithHistory2" src="CameraWithHistory2.gif" border="0"
1046  width="468" height="483"></p>
1047  <pre>
1048// ...
1049
1050// not part of the Camera example
1051struct NotShooting : sc::simple_state&lt; NotShooting, Camera,
1052  <b>mpl::list&lt; sc::deep_history&lt; Idle &gt; &gt;</b>,
1053  <b>sc::has_deep_history</b> &gt;
1054{
1055  // ...
1056};
1057
1058// ...
1059</pre>
1060
1061  <p>Unfortunately, there is a small inconvenience due to some
1062  template-related implementation details. When the inner initial state is a
1063  class template instantiation we always have to put it into an
1064  <code>mpl::list&lt;&gt;</code>, although there is only one inner initial
1065  state. Moreover, the current deep history implementation has some <a href=
1066  "rationale.html#Limitations">limitations</a>.</p>
1067
1068  <h3><a name="OrthogonalStates" id="OrthogonalStates">Orthogonal
1069  states</a></h3>
1070
1071  <p><img alt="OrthogonalStates" src="OrthogonalStates.gif" border="0" width=
1072  "633" height="393"></p>
1073
1074  <p>To implement this statechart you simply specify more than one inner
1075  initial state (see the Keyboard example):</p>
1076  <pre>
1077struct Active;
1078struct Keyboard : sc::state_machine&lt; Keyboard, Active &gt; {};
1079
1080struct NumLockOff;
1081struct CapsLockOff;
1082struct ScrollLockOff;
1083struct Active: sc::simple_state&lt; Active, Keyboard,
1084  <b>mpl::list&lt; NumLockOff, CapsLockOff, ScrollLockOff &gt;</b> &gt; {};
1085</pre>
1086
1087  <p>Active's inner states must declare which orthogonal region they belong
1088  to:</p>
1089  <pre>
1090struct EvNumLockPressed : sc::event&lt; EvNumLockPressed &gt; {};
1091struct EvCapsLockPressed : sc::event&lt; EvCapsLockPressed &gt; {};
1092struct EvScrollLockPressed :
1093  sc::event&lt; EvScrollLockPressed &gt; {};
1094
1095struct NumLockOn : sc::simple_state&lt;
1096  NumLockOn, Active<b>::orthogonal&lt; 0 &gt;</b> &gt;
1097{
1098  typedef sc::transition&lt;
1099    EvNumLockPressed, NumLockOff &gt; reactions;
1100};
1101
1102struct NumLockOff : sc::simple_state&lt;
1103  NumLockOff, Active<b>::orthogonal&lt; 0 &gt;</b> &gt;
1104{
1105  typedef sc::transition&lt;
1106    EvNumLockPressed, NumLockOn &gt; reactions;
1107};
1108
1109struct CapsLockOn : sc::simple_state&lt;
1110  CapsLockOn, Active<b>::orthogonal&lt; 1 &gt;</b> &gt;
1111{
1112  typedef sc::transition&lt;
1113    EvCapsLockPressed, CapsLockOff &gt; reactions;
1114};
1115
1116struct CapsLockOff : sc::simple_state&lt;
1117  CapsLockOff, Active<b>::orthogonal&lt; 1 &gt;</b> &gt;
1118{
1119  typedef sc::transition&lt;
1120    EvCapsLockPressed, CapsLockOn &gt; reactions;
1121};
1122
1123struct ScrollLockOn : sc::simple_state&lt;
1124  ScrollLockOn, Active<b>::orthogonal&lt; 2 &gt;</b> &gt;
1125{
1126  typedef sc::transition&lt;
1127    EvScrollLockPressed, ScrollLockOff &gt; reactions;
1128};
1129
1130struct ScrollLockOff : sc::simple_state&lt;
1131  ScrollLockOff, Active<b>::orthogonal&lt; 2 &gt;</b> &gt;
1132{
1133  typedef sc::transition&lt;
1134    EvScrollLockPressed, ScrollLockOn &gt; reactions;
1135};
1136</pre>
1137
1138  <p><code>orthogonal&lt; 0 &gt;</code> is the default, so
1139  <code>NumLockOn</code> and <code>NumLockOff</code> could just as well pass
1140  <code>Active</code> instead of <code>Active::orthogonal&lt; 0 &gt;</code>
1141  to specify their context. The numbers passed to the <code>orthogonal</code>
1142  member template must correspond to the list position in the outer state.
1143  Moreover, the orthogonal position of the source state of a transition must
1144  correspond to the orthogonal position of the target state. Any violations
1145  of these rules lead to compile time errors. Examples:</p>
1146  <pre>
1147// Example 1: does not compile because Active specifies
1148// only 3 orthogonal regions
1149struct WhateverLockOn: sc::simple_state&lt;
1150  WhateverLockOn, Active<b>::</b>orthogonal&lt; <b>3</b> &gt; &gt; {};
1151
1152// Example 2: does not compile because Active specifies
1153// that NumLockOff is part of the "0th" orthogonal region
1154struct NumLockOff : sc::simple_state&lt;
1155  NumLockOff, Active<b>::</b>orthogonal&lt; <b>1</b> &gt; &gt; {};
1156
1157// Example 3: does not compile because a transition between
1158// different orthogonal regions is not permitted
1159struct CapsLockOn : sc::simple_state&lt;
1160  CapsLockOn, Active<b>::</b>orthogonal&lt; <b>1</b> &gt; &gt;
1161{
1162  typedef sc::transition&lt;
1163    EvCapsLockPressed, CapsLockOff &gt; reactions;
1164};
1165
1166struct CapsLockOff : sc::simple_state&lt;
1167  CapsLockOff, Active<b>::</b>orthogonal&lt; <b>2</b> &gt; &gt;
1168{
1169  typedef sc::transition&lt;
1170    EvCapsLockPressed, CapsLockOn &gt; reactions;
1171};
1172</pre>
1173
1174  <h3><a name="StateQueries" id="StateQueries">State queries</a></h3>
1175
1176  <p>Often reactions in a state machine depend on the active state in one or
1177  more orthogonal regions. This is because orthogonal regions are not
1178  completely orthogonal or a certain reaction in an outer state can only take
1179  place if the inner orthogonal regions are in particular states. For this
1180  purpose, the <code>state_cast&lt;&gt;</code> function introduced under
1181  <a href="#GettingStateInformationOutOfTheMachine">Getting state information
1182  out of the machine</a> is also available within states.</p>
1183
1184  <p>As a somewhat far-fetched example, let's assume that our <a href=
1185  "#OrthogonalStates">keyboard</a> also accepts
1186  <code>EvRequestShutdown</code> events, the reception of which makes the
1187  keyboard terminate only if all lock keys are in the off state. We would
1188  then modify the Keyboard state machine as follows:</p>
1189  <pre>
1190struct EvRequestShutdown : sc::event&lt; EvRequestShutdown &gt; {};
1191
1192struct NumLockOff;
1193struct CapsLockOff;
1194struct ScrollLockOff;
1195struct Active: sc::simple_state&lt; Active, Keyboard,
1196  mpl::list&lt; NumLockOff, CapsLockOff, ScrollLockOff &gt; &gt;
1197{
1198  typedef sc::custom_reaction&lt; EvRequestShutdown &gt; reactions;
1199
1200  sc::result react( const EvRequestShutdown &amp; )
1201  {
1202    if ( ( state_downcast&lt; const NumLockOff * &gt;() != 0 ) &amp;&amp;
1203         ( state_downcast&lt; const CapsLockOff * &gt;() != 0 ) &amp;&amp;
1204         ( state_downcast&lt; const ScrollLockOff * &gt;() != 0 ) )
1205    {
1206      return terminate();
1207    }
1208    else
1209    {
1210      return discard_event();
1211    }
1212  }
1213};
1214</pre>
1215
1216  <p>Passing a pointer type instead of reference type results in 0 pointers
1217  being returned instead of <code>std::bad_cast</code> being thrown when the
1218  cast fails. Note also the use of <code>state_downcast&lt;&gt;()</code>
1219  instead of <code>state_cast&lt;&gt;()</code>. Similar to the differences
1220  between <code>boost::polymorphic_downcast&lt;&gt;()</code> and
1221  <code>dynamic_cast</code>, <code>state_downcast&lt;&gt;()</code> is a much
1222  faster variant of <code>state_cast&lt;&gt;()</code> and can only be used
1223  when the passed type is a most-derived type.
1224  <code>state_cast&lt;&gt;()</code> should only be used if you want to query
1225  an additional base.</p>
1226
1227  <h4>Custom state queries</h4>
1228
1229  <p>It is often desirable to find out exactly which state(s) a machine
1230  currently resides in. To some extent this is already possible with
1231  <code>state_cast&lt;&gt;()</code> and <code>state_downcast&lt;&gt;()</code>
1232  but their utility is rather limited because both only return a yes/no
1233  answer to the question "Are you in state X?". It is possible to ask more
1234  sophisticated questions when you pass an additional base class rather than
1235  a state class to <code>state_cast&lt;&gt;()</code> but this involves more
1236  work (all states need to derive from and implement the additional base), is
1237  slow (under the hood <code>state_cast&lt;&gt;()</code> uses
1238  <code>dynamic_cast</code>), forces projects to compile with C++ RTTI turned
1239  on and has a negative impact on state entry/exit speed.</p>
1240
1241  <p>Especially for debugging it would be so much more useful being able to
1242  ask "In which state(s) are you?". For this purpose it is possible to
1243  iterate over all active <b>innermost</b> states with
1244  <code>state_machine&lt;&gt;::state_begin()</code> and
1245  <code>state_machine&lt;&gt;::state_end()</code>. Dereferencing the returned
1246  iterator returns a reference to <code>const
1247  state_machine&lt;&gt;::state_base_type</code>, the common base of all
1248  states. We can thus print the currently active state configuration as
1249  follows (see the Keyboard example for the complete code):</p>
1250  <pre>
1251void DisplayStateConfiguration( const Keyboard &amp; kbd )
1252{
1253  char region = 'a';
1254
1255  for (
1256    Keyboard::state_iterator pLeafState = kbd.state_begin();
1257    pLeafState != kbd.state_end(); ++pLeafState )
1258  {
1259    std::cout &lt;&lt; "Orthogonal region " &lt;&lt; region &lt;&lt; ": ";
1260    // The following use of typeid assumes that
1261    // BOOST_STATECHART_USE_NATIVE_RTTI is defined
1262    std::cout &lt;&lt; typeid( *pLeafState ).name() &lt;&lt; "\n";
1263    ++region;
1264  }
1265}
1266</pre>
1267
1268  <p>If necessary, the outer states can be accessed with
1269  <code>state_machine&lt;&gt;::state_base_type::outer_state_ptr()</code>,
1270  which returns a pointer to <code>const
1271  state_machine&lt;&gt;::state_base_type</code>. When called on an outermost
1272  state this function simply returns 0.</p>
1273
1274  <h3><a name="StateTypeInformation" id="StateTypeInformation">State type
1275  information</a></h3>
1276
1277  <p>To cut down on executable size some applications must be compiled with
1278  C++ RTTI turned off. This would render the ability to iterate over all
1279  active states pretty much useless if it weren't for the following two
1280  functions:</p>
1281
1282  <ul>
1283    <li><code>static <i>unspecified_type</i>
1284    simple_state&lt;&gt;::static_type()</code></li>
1285
1286    <li><code><i>unspecified_type<br></i> &nbsp;
1287    state_machine&lt;&gt;::state_base_type::dynamic_type() const</code></li>
1288  </ul>
1289
1290  <p>Both return a value that is comparable via <code>operator==()</code> and
1291  <code>std::less&lt;&gt;</code>. This alone would be enough to implement the
1292  <code>DisplayStateConfiguration</code> function above without the help of
1293  <code>typeid</code> but it is still somewhat cumbersome as a map must be
1294  used to associate the type information values with the state names.</p>
1295
1296  <h4><a name="CustomStateTypeInformation" id=
1297  "CustomStateTypeInformation">Custom state type information</a></h4>
1298
1299  <p>That's why the following functions are also provided (only available
1300  when <a href=
1301  "configuration.html#ApplicationDefinedMacros">BOOST_STATECHART_USE_NATIVE_RTTI</a>
1302  is <b>not</b> defined):</p>
1303
1304  <ul>
1305    <li><code>template&lt; class T &gt;<br>
1306    static void simple_state&lt;&gt;::custom_static_type_ptr( const T *
1307    );</code></li>
1308
1309    <li><code>template&lt; class T &gt;<br>
1310    static const T *
1311    simple_state&lt;&gt;::custom_static_type_ptr();</code></li>
1312
1313    <li><code>template&lt; class T &gt;<br>
1314    const T * state_machine&lt;&gt;::<br>
1315    &nbsp; state_base_type::custom_dynamic_type_ptr() const;</code></li>
1316  </ul>
1317
1318  <p>These allow us to directly associate arbitrary state type information
1319  with each state ...</p>
1320  <pre>
1321// ...
1322
1323int main()
1324{
1325  NumLockOn::custom_static_type_ptr( "NumLockOn" );
1326  NumLockOff::custom_static_type_ptr( "NumLockOff" );
1327  CapsLockOn::custom_static_type_ptr( "CapsLockOn" );
1328  CapsLockOff::custom_static_type_ptr( "CapsLockOff" );
1329  ScrollLockOn::custom_static_type_ptr( "ScrollLockOn" );
1330  ScrollLockOff::custom_static_type_ptr( "ScrollLockOff" );
1331
1332  // ...
1333}
1334</pre>
1335
1336  <p>... and rewrite the display function as follows:</p>
1337  <pre>
1338void DisplayStateConfiguration( const Keyboard &amp; kbd )
1339{
1340  char region = 'a';
1341
1342  for (
1343    Keyboard::state_iterator pLeafState = kbd.state_begin();
1344    pLeafState != kbd.state_end(); ++pLeafState )
1345  {
1346    std::cout &lt;&lt; "Orthogonal region " &lt;&lt; region &lt;&lt; ": ";
1347    std::cout &lt;&lt;
1348      pLeafState-&gt;custom_dynamic_type_ptr&lt; char &gt;() &lt;&lt; "\n";
1349    ++region;
1350  }
1351}
1352</pre>
1353
1354  <h3><a name="ExceptionHandling" id="ExceptionHandling">Exception
1355  handling</a></h3>
1356
1357  <p>Exceptions can be propagated from all user code except from state
1358  destructors. Out of the box, the state machine framework is configured for
1359  simple exception handling and does not catch any of these exceptions, so
1360  they are immediately propagated to the state machine client. A scope guard
1361  inside the <code>state_machine&lt;&gt;</code> ensures that all state
1362  objects are destructed before the exception is caught by the client. The
1363  scope guard does not attempt to call any <code>exit</code> functions (see
1364  <a href="#TwoStageExit">Two stage exit</a> below) that states might define
1365  as these could themselves throw other exceptions which would mask the
1366  original exception. Consequently, if a state machine should do something
1367  more sensible when exceptions are thrown, it has to catch them before they
1368  are propagated into the Boost.Statechart framework. This exception handling
1369  scheme is often appropriate but it can lead to considerable code
1370  duplication in state machines where many actions can trigger exceptions
1371  that need to be handled inside the state machine (see <a href=
1372  "rationale.html#ErrorHandling">Error handling</a> in the Rationale).<br>
1373  That's why exception handling can be customized through the
1374  <code>ExceptionTranslator</code> parameter of the
1375  <code>state_machine</code> class template. Since the out-of-the box
1376  behavior is to <b>not</b> translate any exceptions, the default argument
1377  for this parameter is <code>null_exception_translator</code>. A
1378  <code>state_machine&lt;&gt;</code> subtype can be configured for advanced
1379  exception handling by specifying the library-supplied
1380  <code>exception_translator&lt;&gt;</code> instead. This way, the following
1381  happens when an exception is propagated from user code:</p>
1382
1383  <ol>
1384    <li>The exception is caught inside the framework</li>
1385
1386    <li>In the catch block, an <code>exception_thrown</code> event is
1387    allocated on the stack</li>
1388
1389    <li>Also in the catch block, an <b>immediate</b> dispatch of the
1390    <code>exception_thrown</code> event is attempted. That is, possibly
1391    remaining events in the queue are dispatched only after the exception has
1392    been handled successfully</li>
1393
1394    <li>If the exception was handled successfully, the state machine returns
1395    to the client normally. If the exception could not be handled
1396    successfully, the original exception is rethrown so that the client of
1397    the state machine can handle the exception</li>
1398  </ol>
1399
1400  <p>On platforms with buggy exception handling implementations users would
1401  probably want to implement their own model of the <a href=
1402  "reference.html#ExceptionTranslator">ExceptionTranslator concept</a> (see
1403  also <a href="#DiscriminatingExceptions">Discriminating
1404  exceptions</a>).</p>
1405
1406  <h4>Successful exception handling</h4>
1407
1408  <p>An exception is considered handled successfully, if:</p>
1409
1410  <ul>
1411    <li>an appropriate reaction for the <code>exception_thrown</code> event
1412    has been found, <b>and</b></li>
1413
1414    <li>the state machine is in a stable state after the reaction has
1415    completed.</li>
1416  </ul>
1417
1418  <p>The second condition is important for scenarios 2 and 3 in the next
1419  section. In these scenarios, the state machine is in the middle of a
1420  transition when the exception is handled. The machine would be left in an
1421  invalid state, should the reaction simply discard the event without doing
1422  anything else. <code>exception_translator&lt;&gt;</code> simply rethrows
1423  the original exception if the exception handling was unsuccessful. Just as
1424  with simple exception handling, in this case a scope guard inside the
1425  <code>state_machine&lt;&gt;</code> ensures that all state objects are
1426  destructed before the exception is caught by the client.</p>
1427
1428  <h4>Which states can react to an <code>exception_thrown</code> event?</h4>
1429
1430  <p>Short answer: If the state machine is stable when the exception is
1431  thrown, the state that caused the exception is first tried for a reaction.
1432  Otherwise the outermost <a href="definitions.html#UnstableState">unstable
1433  state</a> is first tried for a reaction.</p>
1434
1435  <p>Longer answer: There are three scenarios:</p>
1436
1437  <ol>
1438    <li>A <code>react</code> member function propagates an exception
1439    <b>before</b> calling any of the reaction functions or the action
1440    executed during an in-state reaction propagates an exception. The state
1441    that caused the exception is first tried for a reaction, so the following
1442    machine will transit to Defective after receiving an EvStart event:<br>
1443    <br>
1444    <img alt="ThrowingInStateReaction" src="ThrowingInStateReaction.gif"
1445    border="0" width="362" height="182"><br>
1446    <br></li>
1447
1448    <li>A state entry action (constructor) propagates an exception:<br>
1449
1450      <ul>
1451        <li>If there are no orthogonal regions, the direct outer state of the
1452        state that caused the exception is first tried for a reaction, so the
1453        following machine will transit to Defective after trying to enter
1454        Stopped:<br>
1455        <br>
1456        <img alt="ThrowingEntryAction" src="ThrowingEntryAction.gif" border=
1457        "0" width="438" height="241"><br></li>
1458
1459        <li>If there are orthogonal regions, the outermost <a href=
1460        "definitions.html#UnstableState">unstable state</a> is first tried
1461        for a reaction. The outermost unstable state is found by first
1462        selecting the direct outer state of the state that caused the
1463        exception and then moving outward until a state is found that is
1464        unstable but has no direct or indirect outer states that are
1465        unstable. This more complex rule is necessary because only reactions
1466        associated with the outermost unstable state (or any of its direct or
1467        indirect outer states) are able to bring the machine back into a
1468        stable state. Consider the following statechart:<br>
1469        <br>
1470        <img alt="OutermostUnstableState" src="OutermostUnstableState.gif"
1471        border="0" width="467" height="572"><br>
1472        <br>
1473        Whether this state machine will ultimately transition to E or F after
1474        initiation depends on which of the two orthogonal regions is
1475        initiated first. If the upper orthogonal region is initiated first,
1476        the entry sequence is as follows: A, D, B, (exception is thrown).
1477        Both D and B were successfully entered, so B is the outermost
1478        unstable state when the exception is thrown and the machine will
1479        therefore transition to F. However, if the lower orthogonal region is
1480        initiated first, the sequence is as follows: A, B, (exception is
1481        thrown). D was never entered so A is the outermost unstable state
1482        when the exception is thrown and the machine will therefore
1483        transition to E.<br>
1484        In practice these differences rarely matter as top-level error
1485        recovery is adequate for most state machines. However, since the
1486        sequence of initiation is clearly defined (orthogonal region 0 is
1487        always initiated first, then region 1 and so forth), users <b>can</b>
1488        accurately control when and where they want to handle
1489        exceptions<br></li>
1490      </ul>
1491    </li>
1492
1493    <li>A transition action propagates an exception: The innermost common
1494    outer state of the source and the target state is first tried for a
1495    reaction, so the following machine will transit to Defective after
1496    receiving an EvStartStop event:<br>
1497    <br>
1498    <img alt="ThrowingTransitionAction" src="ThrowingTransitionAction.gif"
1499    border="0" width="422" height="362"></li>
1500  </ol>
1501
1502  <p>As with a normal event, the dispatch algorithm will move outward to find
1503  a reaction if the first tried state does not provide one (or if the
1504  reaction explicitly returned <code>forward_event();</code>). However, <b>in
1505  contrast to normal events, it will give up once it has unsuccessfully tried
1506  an outermost state</b>, so the following machine will <b>not</b> transit to
1507  Defective after receiving an EvNumLockPressed event:</p>
1508
1509  <p><img alt="ExceptionsAndOrthStates" src="ExceptionsAndOrthStates.gif"
1510  border="0" width="571" height="331"></p>
1511
1512  <p>Instead, the machine is terminated and the original exception
1513  rethrown.</p>
1514
1515  <h4><a name="DiscriminatingExceptions" id=
1516  "DiscriminatingExceptions">Discriminating exceptions</a></h4>
1517
1518  <p>Because the <code>exception_thrown</code> event is dispatched from
1519  within the catch block, we can rethrow and catch the exception in a custom
1520  reaction:</p>
1521  <pre>
1522struct Defective : sc::simple_state&lt;
1523  Defective, Purifier &gt; {};
1524
1525// Pretend this is a state deeply nested in the Purifier
1526// state machine
1527struct Idle : sc::simple_state&lt; Idle, Purifier &gt;
1528{
1529  typedef mpl::list&lt;
1530    sc::custom_reaction&lt; EvStart &gt;,
1531    sc::custom_reaction&lt; sc::exception_thrown &gt;
1532  &gt; reactions;
1533
1534  sc::result react( const EvStart &amp; )
1535  {
1536    throw std::runtime_error( "" );
1537  }
1538
1539  sc::result react( const sc::exception_thrown &amp; )
1540  {
1541    try
1542    {
1543      <b>throw;</b>
1544    }
1545    catch ( const std::runtime_error &amp; )
1546    {
1547      // only std::runtime_errors will lead to a transition
1548      // to Defective ...
1549      return transit&lt; Defective &gt;();
1550    }
1551    catch ( ... )
1552    {
1553      // ... all other exceptions are forwarded to our outer
1554      // state(s). The state machine is terminated and the
1555      // exception rethrown if the outer state(s) can't
1556      // handle it either...
1557      return forward_event();
1558    }
1559
1560    // Alternatively, if we want to terminate the machine
1561    // immediately, we can also either rethrow or throw
1562    // a different exception.
1563  }
1564};
1565</pre>
1566
1567  <p><b>Unfortunately, this idiom (using <code>throw;</code> inside a
1568  <code>try</code> block nested inside a <code>catch</code> block) does not
1569  work on at least one very popular compiler.</b> If you have to use one of
1570  these platforms, you can pass a customized exception translator class to
1571  the <code>state_machine</code> class template. This will allow you to
1572  generate different events depending on the type of the exception.</p>
1573
1574  <h4><a name="TwoStageExit" id="TwoStageExit">Two stage exit</a></h4>
1575
1576  <p>If a <code>simple_state&lt;&gt;</code> or <code>state&lt;&gt;</code>
1577  subtype declares a public member function with the signature <code>void
1578  exit()</code> then this function is called just before the state object is
1579  destructed. As explained under <a href="rationale.html#ErrorHandling">Error
1580  handling</a> in the Rationale, this is useful for two things that would
1581  otherwise be difficult or cumbersome to achieve with destructors only:</p>
1582
1583  <ol>
1584    <li>To signal a failure in an exit action</li>
1585
1586    <li>To execute certain exit actions <b>only</b> during a transition or a
1587    termination but not when the state machine object is destructed</li>
1588  </ol>
1589
1590  <p>A few points to consider before employing <code>exit()</code>:</p>
1591
1592  <ul>
1593    <li>There is no guarantee that <code>exit()</code> will be called:
1594
1595      <ul>
1596        <li>If the client destructs the state machine object without calling
1597        <code>terminate()</code> beforehand then the currently active states
1598        are destructed without calling <code>exit()</code>. This is necessary
1599        because an exception that is possibly thrown from <code>exit()</code>
1600        could not be propagated on to the state machine client</li>
1601
1602        <li><code>exit()</code> is not called when a previously executed
1603        action propagated an exception and that exception has not (yet) been
1604        handled successfully. This is because a new exception that could
1605        possibly be thrown from <code>exit()</code> would mask the original
1606        exception</li>
1607      </ul>
1608    </li>
1609
1610    <li>A state is considered exited, even if its <code>exit</code> function
1611    propagated an exception. That is, the state object is inevitably
1612    destructed right after calling <code>exit()</code>, regardless of whether
1613    <code>exit()</code> propagated an exception or not. A state machine
1614    configured for advanced exception handling is therefore always unstable
1615    while handling an exception propagated from an <code>exit</code>
1616    function</li>
1617
1618    <li>In a state machine configured for advanced exception handling the
1619    processing rules for an exception event resulting from an exception
1620    propagated from <code>exit()</code> are analogous to the ones defined for
1621    exceptions propagated from state constructors. That is, the outermost
1622    unstable state is first tried for a reaction and the dispatcher then
1623    moves outward until an appropriate reaction is found</li>
1624  </ul>
1625
1626  <h3><a name="SubmachinesAndParameterizedStates" id=
1627  "SubmachinesAndParameterizedStates">Submachines &amp; parameterized
1628  states</a></h3>
1629
1630  <p>Submachines are to event-driven programming what functions are to
1631  procedural programming, reusable building blocks implementing often needed
1632  functionality. The associated UML notation is not entirely clear to me. It
1633  seems to be severely limited (e.g. the same submachine cannot appear in
1634  different orthogonal regions) and does not seem to account for obvious
1635  stuff like e.g. parameters.</p>
1636
1637  <p>Boost.Statechart is completely unaware of submachines but they can be
1638  implemented quite nicely with templates. Here, a submachine is used to
1639  improve the copy-paste implementation of the keyboard machine discussed
1640  under <a href="#OrthogonalStates">Orthogonal states</a>:</p>
1641  <pre>
1642enum LockType
1643{
1644  NUM_LOCK,
1645  CAPS_LOCK,
1646  SCROLL_LOCK
1647};
1648
1649template&lt; LockType lockType &gt;
1650struct Off;
1651struct Active : sc::simple_state&lt;
1652  Active, Keyboard, mpl::list&lt;
1653  Off&lt; NUM_LOCK &gt;, Off&lt; CAPS_LOCK &gt;, Off&lt; SCROLL_LOCK &gt; &gt; &gt; {};
1654
1655template&lt; LockType lockType &gt;
1656struct EvPressed : sc::event&lt; EvPressed&lt; lockType &gt; &gt; {};
1657
1658template&lt; LockType lockType &gt;
1659struct On : sc::simple_state&lt;
1660  On&lt; lockType &gt;, Active::orthogonal&lt; lockType &gt; &gt;
1661{
1662  typedef sc::transition&lt;
1663    EvPressed&lt; lockType &gt;, Off&lt; lockType &gt; &gt; reactions;
1664};
1665
1666template&lt; LockType lockType &gt;
1667struct Off : sc::simple_state&lt;
1668  Off&lt; lockType &gt;, Active::orthogonal&lt; lockType &gt; &gt;
1669{
1670  typedef sc::transition&lt;
1671    EvPressed&lt; lockType &gt;, On&lt; lockType &gt; &gt; reactions;
1672};
1673</pre>
1674
1675  <h3><a name="AsynchronousStateMachines" id=
1676  "AsynchronousStateMachines">Asynchronous state machines</a></h3>
1677
1678  <h4>Why asynchronous state machines are necessary</h4>
1679
1680  <p>As the name suggests, a synchronous state machine processes each event
1681  synchronously. This behavior is implemented by the
1682  <code>state_machine</code> class template, whose <code>process_event</code>
1683  function only returns after having executed all reactions (including the
1684  ones provoked by internal events that actions might have posted). This
1685  function is strictly non-reentrant (just like all other member functions,
1686  so <code>state_machine&lt;&gt;</code> is not thread-safe). This makes it
1687  difficult for two <code>state_machine&lt;&gt;</code> subtype objects to
1688  communicate via events in a bi-directional fashion correctly, <b>even in a
1689  single-threaded program</b>. For example, state machine <code>A</code> is
1690  in the middle of processing an external event. Inside an action, it decides
1691  to send a new event to state machine <code>B</code> (by calling
1692  <code>B::process_event()</code>). It then "waits" for B to send back an
1693  answer via a <code>boost::function&lt;&gt;</code>-like call-back, which
1694  references <code>A::process_event()</code> and was passed as a data member
1695  of the event. However, while <code>A</code> is "waiting" for <code>B</code>
1696  to send back an event, <code>A::process_event()</code> has not yet returned
1697  from processing the external event and as soon as <code>B</code> answers
1698  via the call-back, <code>A::process_event()</code> is <b>unavoidably</b>
1699  reentered. This all really happens in a single thread, that's why "wait" is
1700  in quotes.</p>
1701
1702  <h4>How it works</h4>
1703
1704  <p>The <code>asynchronous_state_machine</code> class template has none of
1705  the member functions the <code>state_machine</code> class template has.
1706  Moreover, <code>asynchronous_state_machine&lt;&gt;</code> subtype objects
1707  cannot even be created or destroyed directly. Instead, all these operations
1708  must be performed through the <code>Scheduler</code> object each
1709  asynchronous state machine is associated with. All these
1710  <code>Scheduler</code> member functions only push an appropriate item into
1711  the schedulers' queue and then return immediately. A dedicated thread will
1712  later pop the items out of the queue to have them processed.</p>
1713
1714  <p>Applications will usually first create a
1715  <code>fifo_scheduler&lt;&gt;</code> object and then call
1716  <code>fifo_scheduler&lt;&gt;::create_processor&lt;&gt;()</code> and
1717  <code>fifo_scheduler&lt;&gt;::initiate_processor()</code> to schedule the
1718  creation and initiation of one or more
1719  <code>asynchronous_state_machine&lt;&gt;</code> subtype objects. Finally,
1720  <code>fifo_scheduler&lt;&gt;::operator()()</code> is either called directly
1721  to let the machine(s) run in the current thread, or, a
1722  <code>boost::function&lt;&gt;</code> object referencing
1723  <code>operator()()</code> is passed to a new <code>boost::thread</code>.
1724  Alternatively, the latter could also be done right after constructing the
1725  <code>fifo_scheduler&lt;&gt;</code> object. In the following code, we are
1726  running one state machine in a new <code>boost::thread</code> and the other
1727  in the main thread (see the PingPong example for the full source code):</p>
1728  <pre>
1729struct Waiting;
1730struct Player :
1731  sc::asynchronous_state_machine&lt; Player, Waiting &gt;
1732{
1733  // ...
1734};
1735
1736// ...
1737
1738int main()
1739{
1740  // Create two schedulers that will wait for new events
1741  // when their event queue runs empty
1742  sc::fifo_scheduler&lt;&gt; scheduler1( true );
1743  sc::fifo_scheduler&lt;&gt; scheduler2( true );
1744
1745  // Each player is serviced by its own scheduler
1746  sc::fifo_scheduler&lt;&gt;::processor_handle player1 =
1747    scheduler1.create_processor&lt; Player &gt;( /* ... */ );
1748  scheduler1.initiate_processor( player1 );
1749  sc::fifo_scheduler&lt;&gt;::processor_handle player2 =
1750    scheduler2.create_processor&lt; Player &gt;( /* ... */ );
1751  scheduler2.initiate_processor( player2 );
1752
1753  // the initial event that will start the game
1754  boost::intrusive_ptr&lt; BallReturned &gt; pInitialBall =
1755    new BallReturned();
1756
1757  // ...
1758
1759  scheduler2.queue_event( player2, pInitialBall );
1760
1761  // ...
1762
1763  // Up until here no state machines exist yet. They
1764  // will be created when operator()() is called
1765
1766  // Run first scheduler in a new thread
1767  boost::thread otherThread( boost::bind(
1768    &amp;sc::fifo_scheduler&lt;&gt;::operator(), &amp;scheduler1, 0 ) );
1769  scheduler2(); // Run second scheduler in this thread
1770  otherThread.join();
1771
1772  return 0;
1773}
1774</pre>
1775
1776  <p>We could just as well use two boost::threads:</p>
1777  <pre>
1778int main()
1779{
1780  // ...
1781
1782  boost::thread thread1( boost::bind(
1783    &amp;sc::fifo_scheduler&lt;&gt;::operator(), &amp;scheduler1, 0 ) );
1784  boost::thread thread2( boost::bind(
1785    &amp;sc::fifo_scheduler&lt;&gt;::operator(), &amp;scheduler2, 0 ) );
1786
1787  // do something else ...
1788
1789  thread1.join();
1790  thread2.join();
1791
1792  return 0;
1793}
1794</pre>
1795
1796  <p>Or, run both machines in the same thread:</p>
1797  <pre>
1798int main()
1799{
1800  sc::fifo_scheduler&lt;&gt; scheduler1( true );
1801
1802  sc::fifo_scheduler&lt;&gt;::processor_handle player1 =
1803    scheduler1.create_processor&lt; Player &gt;( /* ... */ );
1804  sc::fifo_scheduler&lt;&gt;::processor_handle player2 =
1805    scheduler1.create_processor&lt; Player &gt;( /* ... */ );
1806
1807  // ...
1808
1809  scheduler1();
1810
1811  return 0;
1812}
1813</pre>
1814
1815  <p>In all the examples above,
1816  <code>fifo_scheduler&lt;&gt;::operator()()</code> waits on an empty event
1817  queue and will only return after a call to
1818  <code>fifo_scheduler&lt;&gt;::terminate()</code>. The <code>Player</code>
1819  state machine calls this function on its scheduler object right before
1820  terminating.</p>
1821  <hr>
1822
1823  <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
1824  "http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional"
1825  height="31" width="88"></a></p>
1826
1827  <p>Revised
1828  <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->03 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38512" --></p>
1829
1830  <p><i>Copyright &copy; 2003-<!--webbot bot="Timestamp" s-type="EDITED" s-format="%Y" startspan -->2006<!--webbot bot="Timestamp" endspan i-checksum="770" -->
1831  <a href="contact.html">Andreas Huber D&ouml;nni</a></i></p>
1832
1833  <p><i>Distributed under the Boost Software License, Version 1.0. (See
1834  accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
1835  copy at <a href=
1836  "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
1837</body>
1838</html>
Note: See TracBrowser for help on using the repository browser.