summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorDavid Boddie <dboddie@trolltech.com>2009-05-13 12:13:13 (GMT)
committerDavid Boddie <dboddie@trolltech.com>2009-05-13 12:13:13 (GMT)
commit0d5d11e67f0189279f180df71e0b6959935bce42 (patch)
tree1e1cf4a87673a5c5827d0fe3d26c5b964ee1001d /doc
parent145f445b6c7fa5546540c07f3bda493f4f825caf (diff)
parenta82714c6c82f682e02969d9afa551f37f8132653 (diff)
downloadQt-0d5d11e67f0189279f180df71e0b6959935bce42.zip
Qt-0d5d11e67f0189279f180df71e0b6959935bce42.tar.gz
Qt-0d5d11e67f0189279f180df71e0b6959935bce42.tar.bz2
Merge branch 'kinetic-animations' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-animations
Diffstat (limited to 'doc')
-rw-r--r--doc/src/examples.qdoc2
-rw-r--r--doc/src/examples/factorial.qdoc102
-rw-r--r--doc/src/examples/tankgame.qdoc115
-rw-r--r--doc/src/images/factorial-example.pngbin0 -> 4032 bytes
-rw-r--r--doc/src/images/statemachine-customevents2.pngbin0 -> 6713 bytes
-rw-r--r--doc/src/images/tankgame-example.pngbin0 -> 16089 bytes
-rw-r--r--doc/src/statemachine.qdoc45
7 files changed, 259 insertions, 5 deletions
diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc
index 0153252..6603390 100644
--- a/doc/src/examples.qdoc
+++ b/doc/src/examples.qdoc
@@ -312,9 +312,11 @@
\list
\o \l{statemachine/eventtransitions}{Event Transitions}\raisedaster
+ \o \l{statemachine/factorial}{Factorial States}\raisedaster
\o \l{statemachine/pingpong}{Ping Pong States}\raisedaster
\o \l{statemachine/trafficlight}{Traffic Light}\raisedaster
\o \l{statemachine/twowaybutton}{Two-way Button}\raisedaster
+ \o \l{statemachine/tankgame}{Tank Game}\raisedaster
\endlist
\section1 Threads
diff --git a/doc/src/examples/factorial.qdoc b/doc/src/examples/factorial.qdoc
new file mode 100644
index 0000000..2a72e0a
--- /dev/null
+++ b/doc/src/examples/factorial.qdoc
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example statemachine/factorial
+ \title Factorial States Example
+
+ The Factorial States example shows how to use \l{The State Machine
+ Framework} to calculate the factorial of an integer.
+
+ The statechart for calculating the factorial looks as follows:
+
+ \img factorial-example.png
+ \omit
+ \caption This is a caption
+ \endomit
+
+ In other words, the state machine calculates the factorial of 6 and prints
+ the result.
+
+ \snippet examples/statemachine/factorial/main.cpp 0
+
+ The Factorial class is used to hold the data of the computation, \c x and
+ \c fac. It also provides a signal that's emitted whenever the value of \c
+ x changes.
+
+ \snippet examples/statemachine/factorial/main.cpp 1
+
+ The FactorialLoopTransition class implements the guard (\c x > 1) and
+ calculations (\c fac = \c x * \c fac; \c x = \c x - 1) of the factorial
+ loop.
+
+ \snippet examples/statemachine/factorial/main.cpp 2
+
+ The FactorialDoneTransition class implements the guard (\c x <= 1) that
+ terminates the factorial computation. It also prints the final result to
+ standard output.
+
+ \snippet examples/statemachine/factorial/main.cpp 3
+
+ The application's main() function first creates the application object, a
+ Factorial object and a state machine.
+
+ \snippet examples/statemachine/factorial/main.cpp 4
+
+ The \c compute state is created, and the initial values of \c x and \c fac
+ are defined. A FactorialLoopTransition object is created and added to the
+ state.
+
+ \snippet examples/statemachine/factorial/main.cpp 5
+
+ A final state, \c done, is created, and a FactorialDoneTransition object
+ is created with \c done as its target state. The transition is then added
+ to the \c compute state.
+
+ \snippet examples/statemachine/factorial/main.cpp 6
+
+ The machine's initial state is set to be the \c compute state. We connect
+ the QStateMachine::finished() signal to the QCoreApplication::quit() slot,
+ so the application will quit when the state machine's work is
+ done. Finally, the state machine is started, and the application's event
+ loop is entered.
+
+ */
diff --git a/doc/src/examples/tankgame.qdoc b/doc/src/examples/tankgame.qdoc
new file mode 100644
index 0000000..1501a99
--- /dev/null
+++ b/doc/src/examples/tankgame.qdoc
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example statemachine/tankgame
+ \title Tank Game Example
+
+ The Tank Game example is part of the in \l{The State Machine Framework}. It shows how to use
+ parallel states to implement artificial intelligence controllers that run in parallel, and error
+ states to handle run-time errors in parts of the state graph created by external plugins.
+
+ \image tankgame-example.png
+
+ In this example we write a simple game. The application runs a state machine with two main
+ states: A "stopped" state and a "running" state. The user can load plugins from the disk by
+ selecting the "Add tank" menu item.
+
+ When the "Add tank" menu item is selected, the "plugins" subdirectory in the example's
+ directory is searched for compatible plugins. If any are found, they will be listed in a
+ dialog box created using QInputDialog::getItem().
+
+ \snippet examples/statemachine/tankgame/mainwindow.cpp 1
+
+ If the user selects a plugin, the application will construct a TankItem object, which inherits
+ from QGraphicsItem and QObject, and which implements an agreed-upon interface using the
+ meta-object mechanism.
+
+ \snippet examples/statemachine/tankgame/tankitem.h 0
+
+ The tank item will be passed to the plugin's create() function. This will in turn return a
+ QState object which is expected to implement an artificial intelligence which controls the
+ tank and attempts to destroy other tanks it detects.
+
+ \snippet examples/statemachine/tankgame/mainwindow.cpp 2
+
+ Each returned QState object becomes a descendant of a \c region in the "running" state, which is
+ defined as a parallel state. This means that entering the "running" state will cause each of the
+ plugged-in QState objects to be entered simultaneously, allowing the tanks to run independently
+ of each other.
+
+ \snippet examples/statemachine/tankgame/mainwindow.cpp 0
+
+ The maximum number of tanks on the map is four, and when this number is reached, the
+ "Add tank" menu item should be disabled. This is implemented by giving the "stopped" state two
+ children which define whether the map is full or not.
+
+ To make sure that we go into the correct child state when returning from the "running" state
+ (if the "Stop game" menu item is selected while the game is running) we also give the "stopped"
+ state a history state which we make the initial state of "stopped" state.
+
+ \snippet examples/statemachine/tankgame/mainwindow.cpp 3
+
+ Since part of the state graph is defined by external plugins, we have no way of controlling
+ whether they contain errors. By default, run-time errors are handled in the state machine by
+ entering a top level state which prints out an error message and never exits. If we were to
+ use this default behavior, a run-time error in any of the plugins would cause the "running"
+ state to exit, and thus all the other tanks to stop running as well. A better solution would
+ be if the broken plugin was disabled and the rest of the tanks allowed to continue as before.
+
+ This is done by setting the error state of the plugin's top-most state to a special error state
+ defined specifically for the plugin in question.
+
+ \snippet examples/statemachine/tankgame/mainwindow.cpp 4
+
+ If a run-time error occurs in \c pluginState or any of its descendants, the state machine will
+ search the hierarchy of ancestors until it finds a state whose error state is different from
+ \c null. (Note that if we are worried that a plugin could inadvertedly be overriding our
+ error state, we could search the descendants of \c pluginState and verify that their error
+ states are set to \c null before accepting the plugin.)
+
+ The specialized \c errorState sets the "enabled" property of the tank item in question to false,
+ causing it to be painted with a red cross over it to indicate that it is no longer running.
+ Since the error state is a child of the same region in the parallel "running" state as
+ \c pluginState, it will not exit the "running" state, and the other tanks will continue running
+ without disruption.
+
+*/
diff --git a/doc/src/images/factorial-example.png b/doc/src/images/factorial-example.png
new file mode 100644
index 0000000..8fb1cc6
--- /dev/null
+++ b/doc/src/images/factorial-example.png
Binary files differ
diff --git a/doc/src/images/statemachine-customevents2.png b/doc/src/images/statemachine-customevents2.png
new file mode 100644
index 0000000..57b37ef
--- /dev/null
+++ b/doc/src/images/statemachine-customevents2.png
Binary files differ
diff --git a/doc/src/images/tankgame-example.png b/doc/src/images/tankgame-example.png
new file mode 100644
index 0000000..9e17e30
--- /dev/null
+++ b/doc/src/images/tankgame-example.png
Binary files differ
diff --git a/doc/src/statemachine.qdoc b/doc/src/statemachine.qdoc
index 27bd4f8..5a89f4d 100644
--- a/doc/src/statemachine.qdoc
+++ b/doc/src/statemachine.qdoc
@@ -147,6 +147,9 @@
QObject::connect(s3, SIGNAL(exited()), button, SLOT(showMinimized()));
\endcode
+ Custom states can reimplement QAbstractState::onEntry() and
+ QAbstractState::onExit().
+
\section1 State Machines That Finish
The state machine defined in the previous section never finishes. In order
@@ -155,6 +158,9 @@
final state, the machine will emit the QStateMachine::finished() signal and
halt.
+ All you need to do to introduce a final state in the graph is create a
+ QFinalState object and use it as the target of one or more transitions.
+
\section1 Sharing Transitions By Grouping States
Assume we wanted the user to be able to quit the application at any time by
@@ -315,16 +321,32 @@
\section1 Detecting that a Composite State has Finished
A child state can be final (a QFinalState object); when a final child state
- is entered, the parent state emits the QState::finished() signal.
+ is entered, the parent state emits the QState::finished() signal. The
+ following diagram shows a composite state \c s1 which does some processing
+ before entering a final state:
\img statemachine-finished.png
\omit
\caption This is a caption
\endomit
- This is useful when you want to hide the internal details of a state;
- i.e. the only thing the outside world should be able to do is enter the
- state, and get a notification when the state has completed its work.
+ When \c s1 's final state is entered, \c s1 will automatically emit
+ finished(). We use a signal transition to cause this event to trigger a
+ state change:
+
+ \code
+ s1->addTransition(s1, SIGNAL(finished()), s2);
+ \endcode
+
+ Using final states in composite states is useful when you want to hide the
+ internal details of a composite state; i.e. the only thing the outside world
+ should be able to do is enter the state, and get a notification when the
+ state has completed its work. This is a very powerful abstraction and
+ encapsulation mechanism when building complex (deeply nested) state
+ machines. (In the above example, you could of course create a transition
+ directly from \c s1 's \c done state rather than relying on \c s1 's
+ finished() signal, but with the consequence that implementation details of
+ \c s1 are exposed and depended on).
For parallel state groups, the QState::finished() signal is emitted when \e
all the child states have entered final states.
@@ -425,7 +447,20 @@
machine.postEvent(new StringEvent("Hello"));
machine.postEvent(new StringEvent("world"));
\endcode
-
+
+ An event that is not handled by any relevant transition will be silently
+ consumed by the state machine. It can be useful to group states and provide
+ a default handling of such events; for example, as illustrated in the
+ following statechart:
+
+ \img statemachine-customevents2.png
+ \omit
+ \caption This is a caption
+ \endomit
+
+ For deeply nested statecharts, you can add such "fallback" transitions at
+ the level of granularity that's most appropriate.
+
\section1 Using Restore Policy To Automatically Restore Properties
In some state machines it can be useful to focus the attention on assigning properties in states,