diff options
author | David Boddie <dboddie@trolltech.com> | 2009-05-13 12:13:13 (GMT) |
---|---|---|
committer | David Boddie <dboddie@trolltech.com> | 2009-05-13 12:13:13 (GMT) |
commit | 0d5d11e67f0189279f180df71e0b6959935bce42 (patch) | |
tree | 1e1cf4a87673a5c5827d0fe3d26c5b964ee1001d /doc/src | |
parent | 145f445b6c7fa5546540c07f3bda493f4f825caf (diff) | |
parent | a82714c6c82f682e02969d9afa551f37f8132653 (diff) | |
download | Qt-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/src')
-rw-r--r-- | doc/src/examples.qdoc | 2 | ||||
-rw-r--r-- | doc/src/examples/factorial.qdoc | 102 | ||||
-rw-r--r-- | doc/src/examples/tankgame.qdoc | 115 | ||||
-rw-r--r-- | doc/src/images/factorial-example.png | bin | 0 -> 4032 bytes | |||
-rw-r--r-- | doc/src/images/statemachine-customevents2.png | bin | 0 -> 6713 bytes | |||
-rw-r--r-- | doc/src/images/tankgame-example.png | bin | 0 -> 16089 bytes | |||
-rw-r--r-- | doc/src/statemachine.qdoc | 45 |
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 Binary files differnew file mode 100644 index 0000000..8fb1cc6 --- /dev/null +++ b/doc/src/images/factorial-example.png diff --git a/doc/src/images/statemachine-customevents2.png b/doc/src/images/statemachine-customevents2.png Binary files differnew file mode 100644 index 0000000..57b37ef --- /dev/null +++ b/doc/src/images/statemachine-customevents2.png diff --git a/doc/src/images/tankgame-example.png b/doc/src/images/tankgame-example.png Binary files differnew file mode 100644 index 0000000..9e17e30 --- /dev/null +++ b/doc/src/images/tankgame-example.png 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, |