1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- pingpong.qdoc -->
<title>Qt 4.8: Ping Pong States Example</title>
<link rel="stylesheet" type="text/css" href="style/offline.css" />
</head>
<body>
<div class="header" id="qtdocheader">
<div class="content">
<a href="index.html" class="qtref"><span>Qt Reference Documentation</span></a>
</div>
<div class="breadcrumb toolblock">
<ul>
<li class="first"><a href="index.html">Home</a></li>
<!-- Breadcrumbs go here -->
<li><a href="all-examples.html">Examples</a></li>
<li>Ping Pong States Example</li>
</ul>
</div>
</div>
<div class="content mainContent">
<h1 class="title">Ping Pong States Example</h1>
<span class="subtitle"></span>
<!-- $$$statemachine/pingpong-description -->
<div class="descr"> <a name="details"></a>
<p>Files:</p>
<ul>
<li><a href="statemachine-pingpong-main-cpp.html">statemachine/pingpong/main.cpp</a></li>
<li><a href="statemachine-pingpong-pingpong-pro.html">statemachine/pingpong/pingpong.pro</a></li>
</ul>
<p>The Ping Pong States example shows how to use parallel states together with custom events and transitions in <a href="statemachine-api.html">The State Machine Framework</a>.<p>This example implements a statechart where two states communicate by posting events to the state machine. The state chart looks as follows:</p>
<p class="centerAlign"><img src="images/pingpong-example.png" alt="" /></p><p>The <tt>pinger</tt> and <tt>ponger</tt> states are parallel states, i.e. they are entered simultaneously and will take transitions independently of eachother.</p>
<p>The <tt>pinger</tt> state will post the first <tt>ping</tt> event upon entry; the <tt>ponger</tt> state will respond by posting a <tt>pong</tt> event; this will cause the <tt>pinger</tt> state to post a new <tt>ping</tt> event; and so on.</p>
<pre class="cpp"> <span class="keyword">class</span> PingEvent : <span class="keyword">public</span> <span class="type"><a href="qevent.html">QEvent</a></span>
{
<span class="keyword">public</span>:
PingEvent() : <span class="type"><a href="qevent.html">QEvent</a></span>(<span class="type"><a href="qevent.html">QEvent</a></span><span class="operator">::</span>Type(<span class="type"><a href="qevent.html">QEvent</a></span><span class="operator">::</span>User<span class="operator">+</span><span class="number">2</span>))
{}
};
<span class="keyword">class</span> PongEvent : <span class="keyword">public</span> <span class="type"><a href="qevent.html">QEvent</a></span>
{
<span class="keyword">public</span>:
PongEvent() : <span class="type"><a href="qevent.html">QEvent</a></span>(<span class="type"><a href="qevent.html">QEvent</a></span><span class="operator">::</span>Type(<span class="type"><a href="qevent.html">QEvent</a></span><span class="operator">::</span>User<span class="operator">+</span><span class="number">3</span>))
{}
};</pre>
<p>Two custom events are defined, <tt>PingEvent</tt> and <tt>PongEvent</tt>.</p>
<pre class="cpp"> <span class="keyword">class</span> Pinger : <span class="keyword">public</span> <span class="type"><a href="qstate.html">QState</a></span>
{
<span class="keyword">public</span>:
Pinger(<span class="type"><a href="qstate.html">QState</a></span> <span class="operator">*</span>parent)
: <span class="type"><a href="qstate.html">QState</a></span>(parent) {}
<span class="keyword">protected</span>:
<span class="keyword">virtual</span> <span class="type">void</span> onEntry(<span class="type"><a href="qevent.html">QEvent</a></span> <span class="operator">*</span>)
{
machine()<span class="operator">-</span><span class="operator">></span>postEvent(<span class="keyword">new</span> PingEvent());
fprintf(stdout<span class="operator">,</span> <span class="string">"ping?\n"</span>);
}
};</pre>
<p>The <tt>Pinger</tt> class defines a state that posts a <tt>PingEvent</tt> to the state machine when the state is entered.</p>
<pre class="cpp"> <span class="keyword">class</span> PingTransition : <span class="keyword">public</span> <span class="type"><a href="qabstracttransition.html">QAbstractTransition</a></span>
{
<span class="keyword">public</span>:
PingTransition() {}
<span class="keyword">protected</span>:
<span class="keyword">virtual</span> <span class="type">bool</span> eventTest(<span class="type"><a href="qevent.html">QEvent</a></span> <span class="operator">*</span>e) {
<span class="keyword">return</span> (e<span class="operator">-</span><span class="operator">></span>type() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="qevent.html">QEvent</a></span><span class="operator">::</span>User<span class="operator">+</span><span class="number">2</span>);
}
<span class="keyword">virtual</span> <span class="type">void</span> onTransition(<span class="type"><a href="qevent.html">QEvent</a></span> <span class="operator">*</span>)
{
machine()<span class="operator">-</span><span class="operator">></span>postDelayedEvent(<span class="keyword">new</span> PongEvent()<span class="operator">,</span> <span class="number">500</span>);
fprintf(stdout<span class="operator">,</span> <span class="string">"pong!\n"</span>);
}
};</pre>
<p>The <tt>PingTransition</tt> class defines a transition that is triggered by events of type <tt>PingEvent</tt>, and that posts a <tt>PongEvent</tt> (with a delay of 500 milliseconds) to the state machine when the transition is triggered.</p>
<pre class="cpp"> <span class="keyword">class</span> PongTransition : <span class="keyword">public</span> <span class="type"><a href="qabstracttransition.html">QAbstractTransition</a></span>
{
<span class="keyword">public</span>:
PongTransition() {}
<span class="keyword">protected</span>:
<span class="keyword">virtual</span> <span class="type">bool</span> eventTest(<span class="type"><a href="qevent.html">QEvent</a></span> <span class="operator">*</span>e) {
<span class="keyword">return</span> (e<span class="operator">-</span><span class="operator">></span>type() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="qevent.html">QEvent</a></span><span class="operator">::</span>User<span class="operator">+</span><span class="number">3</span>);
}
<span class="keyword">virtual</span> <span class="type">void</span> onTransition(<span class="type"><a href="qevent.html">QEvent</a></span> <span class="operator">*</span>)
{
machine()<span class="operator">-</span><span class="operator">></span>postDelayedEvent(<span class="keyword">new</span> PingEvent()<span class="operator">,</span> <span class="number">500</span>);
fprintf(stdout<span class="operator">,</span> <span class="string">"ping?\n"</span>);
}
};</pre>
<p>The <tt>PongTransition</tt> class defines a transition that is triggered by events of type <tt>PongEvent</tt>, and that posts a <tt>PingEvent</tt> (with a delay of 500 milliseconds) to the state machine when the transition is triggered.</p>
<pre class="cpp"> <span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span><span class="operator">*</span>argv)
{
<span class="type"><a href="qcoreapplication.html">QCoreApplication</a></span> app(argc<span class="operator">,</span> argv);
<span class="type"><a href="qstatemachine.html">QStateMachine</a></span> machine;
<span class="type"><a href="qstate.html">QState</a></span> <span class="operator">*</span>group <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qstate.html">QState</a></span>(<span class="type"><a href="qstate.html">QState</a></span><span class="operator">::</span>ParallelStates);
group<span class="operator">-</span><span class="operator">></span>setObjectName(<span class="string">"group"</span>);</pre>
<p>The main() function begins by creating a state machine and a parallel state group.</p>
<pre class="cpp"> Pinger <span class="operator">*</span>pinger <span class="operator">=</span> <span class="keyword">new</span> Pinger(group);
pinger<span class="operator">-</span><span class="operator">></span>setObjectName(<span class="string">"pinger"</span>);
pinger<span class="operator">-</span><span class="operator">></span>addTransition(<span class="keyword">new</span> PongTransition());
<span class="type"><a href="qstate.html">QState</a></span> <span class="operator">*</span>ponger <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qstate.html">QState</a></span>(group);
ponger<span class="operator">-</span><span class="operator">></span>setObjectName(<span class="string">"ponger"</span>);
ponger<span class="operator">-</span><span class="operator">></span>addTransition(<span class="keyword">new</span> PingTransition());</pre>
<p>Next, the <tt>pinger</tt> and <tt>ponger</tt> states are created, with the parallel state group as their parent state. Note that the transitions are <i>targetless</i>. When such a transition is triggered, the source state won't be exited and re-entered; only the transition's onTransition() function will be called, and the state machine's configuration will remain the same, which is precisely what we want in this case.</p>
<pre class="cpp"> machine<span class="operator">.</span>addState(group);
machine<span class="operator">.</span>setInitialState(group);
machine<span class="operator">.</span>start();
<span class="keyword">return</span> app<span class="operator">.</span>exec();
}</pre>
<p>Finally, the group is added to the state machine, the machine is started, and the application event loop is entered.</p>
</div>
<!-- @@@statemachine/pingpong -->
<div class="ft">
<span></span>
</div>
</div>
<div class="footer">
<p>
<acronym title="Copyright">©</acronym> 2012 Nokia Corporation and/or its
subsidiaries. Documentation contributions included herein are the copyrights of
their respective owners.</p>
<br />
<p>
The documentation provided herein is licensed under the terms of the
<a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation
License version 1.3</a> as published by the Free Software Foundation.</p>
<p>
Documentation sources may be obtained from <a href="http://www.qt-project.org">
www.qt-project.org</a>.</p>
<br />
<p>
Nokia, Qt and their respective logos are trademarks of Nokia Corporation
in Finland and/or other countries worldwide. All other trademarks are property
of their respective owners. <a title="Privacy Policy"
href="http://en.gitorious.org/privacy_policy/">Privacy Policy</a></p>
</div>
</body>
</html>
|