summaryrefslogtreecommitdiffstats
path: root/examples/statemachine
diff options
context:
space:
mode:
Diffstat (limited to 'examples/statemachine')
-rw-r--r--examples/statemachine/README36
-rw-r--r--examples/statemachine/eventtransitions/eventtransitions.pro7
-rw-r--r--examples/statemachine/eventtransitions/main.cpp116
-rw-r--r--examples/statemachine/factorial/factorial.pro11
-rw-r--r--examples/statemachine/factorial/main.cpp182
-rw-r--r--examples/statemachine/pingpong/main.cpp145
-rw-r--r--examples/statemachine/pingpong/pingpong.pro11
-rw-r--r--examples/statemachine/statemachine.pro15
-rw-r--r--examples/statemachine/tankgame/gameitem.cpp129
-rw-r--r--examples/statemachine/tankgame/gameitem.h66
-rw-r--r--examples/statemachine/tankgame/gameovertransition.cpp80
-rw-r--r--examples/statemachine/tankgame/gameovertransition.h63
-rw-r--r--examples/statemachine/tankgame/main.cpp53
-rw-r--r--examples/statemachine/tankgame/mainwindow.cpp342
-rw-r--r--examples/statemachine/tankgame/mainwindow.h93
-rw-r--r--examples/statemachine/tankgame/plugin.h62
-rw-r--r--examples/statemachine/tankgame/rocketitem.cpp101
-rw-r--r--examples/statemachine/tankgame/rocketitem.h66
-rw-r--r--examples/statemachine/tankgame/tankgame.pro19
-rw-r--r--examples/statemachine/tankgame/tankitem.cpp302
-rw-r--r--examples/statemachine/tankgame/tankitem.h109
-rw-r--r--examples/statemachine/tankgameplugins/random_ai/random_ai.pro13
-rw-r--r--examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp79
-rw-r--r--examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h105
-rw-r--r--examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp89
-rw-r--r--examples/statemachine/tankgameplugins/seek_ai/seek_ai.h249
-rw-r--r--examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro13
-rw-r--r--examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp70
-rw-r--r--examples/statemachine/tankgameplugins/spin_ai/spin_ai.h92
-rw-r--r--examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro13
-rw-r--r--examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp70
-rw-r--r--examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h92
-rw-r--r--examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro13
-rw-r--r--examples/statemachine/tankgameplugins/tankgameplugins.pro11
-rw-r--r--examples/statemachine/trafficlight/main.cpp190
-rw-r--r--examples/statemachine/trafficlight/trafficlight.pro7
-rw-r--r--examples/statemachine/twowaybutton/main.cpp86
-rw-r--r--examples/statemachine/twowaybutton/twowaybutton.pro7
38 files changed, 3207 insertions, 0 deletions
diff --git a/examples/statemachine/README b/examples/statemachine/README
new file mode 100644
index 0000000..2879e67
--- /dev/null
+++ b/examples/statemachine/README
@@ -0,0 +1,36 @@
+Qt is provided with a powerful hierchical finite state machine through
+the Qt State Machine classes.
+
+The example launcher provided with Qt can be used to explore each of the
+examples in this directory.
+
+Documentation for these examples can be found via the Tutorial and Examples
+link in the main Qt documentation.
+
+
+Finding the Qt Examples and Demos launcher
+==========================================
+
+On Windows:
+
+The launcher can be accessed via the Windows Start menu. Select the menu
+entry entitled "Qt Examples and Demos" entry in the submenu containing
+the Qt tools.
+
+On Mac OS X:
+
+For the binary distribution, the qtdemo executable is installed in the
+/Developer/Applications/Qt directory. For the source distribution, it is
+installed alongside the other Qt tools on the path specified when Qt is
+configured.
+
+On Unix/Linux:
+
+The qtdemo executable is installed alongside the other Qt tools on the path
+specified when Qt is configured.
+
+On all platforms:
+
+The source code for the launcher can be found in the demos/qtdemo directory
+in the Qt package. This example is built at the same time as the Qt libraries,
+tools, examples, and demonstrations.
diff --git a/examples/statemachine/eventtransitions/eventtransitions.pro b/examples/statemachine/eventtransitions/eventtransitions.pro
new file mode 100644
index 0000000..7e92cf2
--- /dev/null
+++ b/examples/statemachine/eventtransitions/eventtransitions.pro
@@ -0,0 +1,7 @@
+SOURCES = main.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/eventtransitions
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS eventtransitions.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/eventtransitions
+INSTALLS += target sources
diff --git a/examples/statemachine/eventtransitions/main.cpp b/examples/statemachine/eventtransitions/main.cpp
new file mode 100644
index 0000000..aba0c73
--- /dev/null
+++ b/examples/statemachine/eventtransitions/main.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module 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$
+**
+****************************************************************************/
+
+#include <QtGui>
+#ifdef QT_STATEMACHINE_SOLUTION
+#include <qstatemachine.h>
+#include <qstate.h>
+#include <qeventtransition.h>
+#endif
+
+//! [0]
+class Window : public QWidget
+{
+public:
+ Window(QWidget *parent = 0)
+ : QWidget(parent)
+ {
+ QPushButton *button = new QPushButton(this);
+ button->setGeometry(QRect(100, 100, 100, 100));
+//! [0]
+
+//! [1]
+ QStateMachine *machine = new QStateMachine(this);
+
+ QState *s1 = new QState();
+ s1->assignProperty(button, "text", "Outside");
+
+ QState *s2 = new QState();
+ s2->assignProperty(button, "text", "Inside");
+//! [1]
+
+//! [2]
+ QEventTransition *enterTransition = new QEventTransition(button, QEvent::Enter);
+ enterTransition->setTargetState(s2);
+ s1->addTransition(enterTransition);
+//! [2]
+
+//! [3]
+ QEventTransition *leaveTransition = new QEventTransition(button, QEvent::Leave);
+ leaveTransition->setTargetState(s1);
+ s2->addTransition(leaveTransition);
+//! [3]
+
+//! [4]
+ QState *s3 = new QState();
+ s3->assignProperty(button, "text", "Pressing...");
+
+ QEventTransition *pressTransition = new QEventTransition(button, QEvent::MouseButtonPress);
+ pressTransition->setTargetState(s3);
+ s2->addTransition(pressTransition);
+
+ QEventTransition *releaseTransition = new QEventTransition(button, QEvent::MouseButtonRelease);
+ releaseTransition->setTargetState(s2);
+ s3->addTransition(releaseTransition);
+//! [4]
+
+//! [5]
+ machine->addState(s1);
+ machine->addState(s2);
+ machine->addState(s3);
+
+ machine->setInitialState(s1);
+ machine->start();
+ }
+};
+//! [5]
+
+//! [6]
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ Window window;
+ window.resize(300, 300);
+ window.show();
+
+ return app.exec();
+}
+//! [6]
diff --git a/examples/statemachine/factorial/factorial.pro b/examples/statemachine/factorial/factorial.pro
new file mode 100644
index 0000000..14a6833
--- /dev/null
+++ b/examples/statemachine/factorial/factorial.pro
@@ -0,0 +1,11 @@
+QT = core
+win32: CONFIG += console
+mac:CONFIG -= app_bundle
+
+SOURCES += main.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/factorial
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS factorial.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/factorial
+INSTALLS += target sources
diff --git a/examples/statemachine/factorial/main.cpp b/examples/statemachine/factorial/main.cpp
new file mode 100644
index 0000000..1065eb8
--- /dev/null
+++ b/examples/statemachine/factorial/main.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module 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$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <stdio.h>
+#ifdef QT_STATEMACHINE_SOLUTION
+#include <qstatemachine.h>
+#include <qstate.h>
+#include <qsignaltransition.h>
+#include <qfinalstate.h>
+#endif
+
+//! [0]
+class Factorial : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int x READ x WRITE setX)
+ Q_PROPERTY(int fac READ fac WRITE setFac)
+public:
+ Factorial(QObject *parent = 0)
+ : QObject(parent), m_x(-1), m_fac(1)
+ {
+ }
+
+ int x() const
+ {
+ return m_x;
+ }
+
+ void setX(int x)
+ {
+ if (x == m_x)
+ return;
+ m_x = x;
+ emit xChanged(x);
+ }
+
+ int fac() const
+ {
+ return m_fac;
+ }
+
+ void setFac(int fac)
+ {
+ m_fac = fac;
+ }
+
+Q_SIGNALS:
+ void xChanged(int value);
+
+private:
+ int m_x;
+ int m_fac;
+};
+//! [0]
+
+//! [1]
+class FactorialLoopTransition : public QSignalTransition
+{
+public:
+ FactorialLoopTransition(Factorial *fact)
+ : QSignalTransition(fact, SIGNAL(xChanged(int))), m_fact(fact)
+ {}
+
+ virtual bool eventTest(QEvent *e)
+ {
+ if (!QSignalTransition::eventTest(e))
+ return false;
+ QSignalEvent *se = static_cast<QSignalEvent*>(e);
+ return se->arguments().at(0).toInt() > 1;
+ }
+
+ virtual void onTransition(QEvent *e)
+ {
+ QSignalEvent *se = static_cast<QSignalEvent*>(e);
+ int x = se->arguments().at(0).toInt();
+ int fac = m_fact->property("fac").toInt();
+ m_fact->setProperty("fac", x * fac);
+ m_fact->setProperty("x", x - 1);
+ }
+
+private:
+ Factorial *m_fact;
+};
+//! [1]
+
+//! [2]
+class FactorialDoneTransition : public QSignalTransition
+{
+public:
+ FactorialDoneTransition(Factorial *fact)
+ : QSignalTransition(fact, SIGNAL(xChanged(int))), m_fact(fact)
+ {}
+
+ virtual bool eventTest(QEvent *e)
+ {
+ if (!QSignalTransition::eventTest(e))
+ return false;
+ QSignalEvent *se = static_cast<QSignalEvent*>(e);
+ return se->arguments().at(0).toInt() <= 1;
+ }
+
+ virtual void onTransition(QEvent *)
+ {
+ fprintf(stdout, "%d\n", m_fact->property("fac").toInt());
+ }
+
+private:
+ Factorial *m_fact;
+};
+//! [2]
+
+//! [3]
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ Factorial factorial;
+ QStateMachine machine;
+//! [3]
+
+//! [4]
+ QState *compute = new QState(machine.rootState());
+ compute->assignProperty(&factorial, "fac", 1);
+ compute->assignProperty(&factorial, "x", 6);
+ compute->addTransition(new FactorialLoopTransition(&factorial));
+//! [4]
+
+//! [5]
+ QFinalState *done = new QFinalState(machine.rootState());
+ FactorialDoneTransition *doneTransition = new FactorialDoneTransition(&factorial);
+ doneTransition->setTargetState(done);
+ compute->addTransition(doneTransition);
+//! [5]
+
+//! [6]
+ machine.setInitialState(compute);
+ QObject::connect(&machine, SIGNAL(finished()), &app, SLOT(quit()));
+ machine.start();
+
+ return app.exec();
+}
+//! [6]
+
+#include "main.moc"
diff --git a/examples/statemachine/pingpong/main.cpp b/examples/statemachine/pingpong/main.cpp
new file mode 100644
index 0000000..331627e
--- /dev/null
+++ b/examples/statemachine/pingpong/main.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module 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$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <stdio.h>
+#ifdef QT_STATEMACHINE_SOLUTION
+#include <qstate.h>
+#include <qstatemachine.h>
+#include <qabstracttransition.h>
+#endif
+
+//! [0]
+class PingEvent : public QEvent
+{
+public:
+ PingEvent() : QEvent(QEvent::Type(QEvent::User+2))
+ {}
+};
+
+class PongEvent : public QEvent
+{
+public:
+ PongEvent() : QEvent(QEvent::Type(QEvent::User+3))
+ {}
+};
+//! [0]
+
+//! [1]
+class Pinger : public QState
+{
+public:
+ Pinger(QState *parent)
+ : QState(parent) {}
+
+protected:
+ virtual void onEntry(QEvent *)
+ {
+ machine()->postEvent(new PingEvent());
+ fprintf(stdout, "ping?\n");
+ }
+};
+//! [1]
+
+//! [3]
+class PongTransition : public QAbstractTransition
+{
+public:
+ PongTransition() {}
+
+protected:
+ virtual bool eventTest(QEvent *e) {
+ return (e->type() == QEvent::User+3);
+ }
+ virtual void onTransition(QEvent *)
+ {
+ machine()->postEvent(new PingEvent(), 500);
+ fprintf(stdout, "ping?\n");
+ }
+};
+//! [3]
+
+//! [2]
+class PingTransition : public QAbstractTransition
+{
+public:
+ PingTransition() {}
+
+protected:
+ virtual bool eventTest(QEvent *e) {
+ return (e->type() == QEvent::User+2);
+ }
+ virtual void onTransition(QEvent *)
+ {
+ machine()->postEvent(new PongEvent(), 500);
+ fprintf(stdout, "pong!\n");
+ }
+};
+//! [2]
+
+//! [4]
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+
+ QStateMachine machine;
+ QState *group = new QState(QState::ParallelStates);
+ group->setObjectName("group");
+//! [4]
+
+//! [5]
+ Pinger *pinger = new Pinger(group);
+ pinger->setObjectName("pinger");
+ pinger->addTransition(new PongTransition());
+
+ QState *ponger = new QState(group);
+ ponger->setObjectName("ponger");
+ ponger->addTransition(new PingTransition());
+//! [5]
+
+//! [6]
+ machine.addState(group);
+ machine.setInitialState(group);
+ machine.start();
+
+ return app.exec();
+}
+//! [6]
diff --git a/examples/statemachine/pingpong/pingpong.pro b/examples/statemachine/pingpong/pingpong.pro
new file mode 100644
index 0000000..42eab6c
--- /dev/null
+++ b/examples/statemachine/pingpong/pingpong.pro
@@ -0,0 +1,11 @@
+QT = core
+win32: CONFIG += console
+mac:CONFIG -= app_bundle
+
+SOURCES = main.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/pingpong
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS pingpong.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/pingpong
+INSTALLS += target sources
diff --git a/examples/statemachine/statemachine.pro b/examples/statemachine/statemachine.pro
new file mode 100644
index 0000000..5074a3c
--- /dev/null
+++ b/examples/statemachine/statemachine.pro
@@ -0,0 +1,15 @@
+TEMPLATE = subdirs
+SUBDIRS = \
+ eventtransitions \
+ factorial \
+ pingpong \
+ trafficlight \
+ twowaybutton \
+ tankgame \
+ tankgameplugins
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS statemachine.pro README
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine
+INSTALLS += target sources
diff --git a/examples/statemachine/tankgame/gameitem.cpp b/examples/statemachine/tankgame/gameitem.cpp
new file mode 100644
index 0000000..ad8b37c
--- /dev/null
+++ b/examples/statemachine/tankgame/gameitem.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "gameitem.h"
+
+#include <QGraphicsScene>
+#include <QDebug>
+
+GameItem::GameItem(QObject *parent) : QObject(parent)
+{
+}
+
+QPointF GameItem::tryMove(const QPointF &requestedPosition, QLineF *collidedLine,
+ QGraphicsItem **collidedItem) const
+{
+ QLineF movementPath(pos(), requestedPosition);
+
+ qreal cannonLength = 0.0;
+ {
+ QPointF p1 = boundingRect().center();
+ QPointF p2 = QPointF(boundingRect().right() + 10.0, p1.y());
+
+ cannonLength = QLineF(mapToScene(p1), mapToScene(p2)).length();
+ }
+
+ movementPath.setLength(movementPath.length() + cannonLength);
+
+ QRectF boundingRectPath(QPointF(qMin(movementPath.x1(), movementPath.x2()), qMin(movementPath.y1(), movementPath.y2())),
+ QPointF(qMax(movementPath.x1(), movementPath.x2()), qMax(movementPath.y1(), movementPath.y2())));
+
+ QList<QGraphicsItem *> itemsInRect = scene()->items(boundingRectPath, Qt::IntersectsItemBoundingRect);
+
+ QPointF nextPoint = requestedPosition;
+ QRectF sceneRect = scene()->sceneRect();
+
+ foreach (QGraphicsItem *item, itemsInRect) {
+ if (item == static_cast<const QGraphicsItem *>(this))
+ continue;
+
+ QPolygonF mappedBoundingRect = item->mapToScene(item->boundingRect());
+ for (int i=0; i<mappedBoundingRect.size(); ++i) {
+ QPointF p1 = mappedBoundingRect.at(i == 0 ? mappedBoundingRect.size()-1 : i-1);
+ QPointF p2 = mappedBoundingRect.at(i);
+
+ QLineF rectLine(p1, p2);
+ QPointF intersectionPoint;
+ QLineF::IntersectType intersectType = movementPath.intersect(rectLine, &intersectionPoint);
+
+ if (intersectType == QLineF::BoundedIntersection) {
+ movementPath.setP2(intersectionPoint);
+ movementPath.setLength(movementPath.length() - cannonLength);
+ nextPoint = movementPath.p2();
+
+ if (collidedLine != 0)
+ *collidedLine = rectLine;
+
+ if (collidedItem != 0)
+ *collidedItem = item;
+ }
+ }
+ }
+
+
+ // Don't go outside of map
+ if (nextPoint.x() < sceneRect.left()) {
+ nextPoint.rx() = sceneRect.left();
+ if (collidedLine != 0)
+ *collidedLine = QLineF(scene()->sceneRect().topLeft(), scene()->sceneRect().bottomLeft());
+ }
+
+ if (nextPoint.x() > sceneRect.right()) {
+ nextPoint.rx() = sceneRect.right();
+ if (collidedLine != 0)
+ *collidedLine = QLineF(scene()->sceneRect().topRight(), scene()->sceneRect().bottomRight());
+ }
+
+ if (nextPoint.y() < sceneRect.top()) {
+ nextPoint.ry() = sceneRect.top();
+ if (collidedLine != 0)
+ *collidedLine = QLineF(scene()->sceneRect().topLeft(), scene()->sceneRect().topRight());
+ }
+
+ if (nextPoint.y() > sceneRect.bottom()) {
+ nextPoint.ry() = sceneRect.bottom();
+ if (collidedLine != 0)
+ *collidedLine = QLineF(scene()->sceneRect().bottomLeft(), scene()->sceneRect().bottomRight());
+ }
+
+ return nextPoint;
+}
+
diff --git a/examples/statemachine/tankgame/gameitem.h b/examples/statemachine/tankgame/gameitem.h
new file mode 100644
index 0000000..90b0a6c
--- /dev/null
+++ b/examples/statemachine/tankgame/gameitem.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef GAMEITEM_H
+#define GAMEITEM_H
+
+#include <QGraphicsItem>
+
+QT_BEGIN_NAMESPACE
+class QLineF;
+QT_END_NAMESPACE
+class GameItem: public QObject, public QGraphicsItem
+{
+ Q_OBJECT
+public:
+ enum { Type = UserType + 1 };
+ int type() const { return Type; }
+
+ GameItem(QObject *parent = 0);
+
+ virtual void idle(qreal elapsed) = 0;
+
+protected:
+ QPointF tryMove(const QPointF &requestedPosition, QLineF *collidedLine = 0,
+ QGraphicsItem **collidedItem = 0) const;
+};
+
+#endif
diff --git a/examples/statemachine/tankgame/gameovertransition.cpp b/examples/statemachine/tankgame/gameovertransition.cpp
new file mode 100644
index 0000000..360e902
--- /dev/null
+++ b/examples/statemachine/tankgame/gameovertransition.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "gameovertransition.h"
+#include "tankitem.h"
+
+#include <QSignalEvent>
+#include <QSignalMapper>
+
+GameOverTransition::GameOverTransition(QAbstractState *targetState)
+ : QSignalTransition(new QSignalMapper(), SIGNAL(mapped(QObject*)))
+{
+ setTargetState(targetState);
+
+ QSignalMapper *mapper = qobject_cast<QSignalMapper *>(senderObject());
+ mapper->setParent(this);
+}
+
+void GameOverTransition::addTankItem(TankItem *tankItem)
+{
+ m_tankItems.append(tankItem);
+
+ QSignalMapper *mapper = qobject_cast<QSignalMapper *>(senderObject());
+ mapper->setMapping(tankItem, tankItem);
+ connect(tankItem, SIGNAL(aboutToBeDestroyed()), mapper, SLOT(map()));
+}
+
+bool GameOverTransition::eventTest(QEvent *e)
+{
+ bool ret = QSignalTransition::eventTest(e);
+
+ if (ret) {
+ QSignalEvent *signalEvent = static_cast<QSignalEvent *>(e);
+ QObject *sender = qvariant_cast<QObject *>(signalEvent->arguments().at(0));
+ TankItem *tankItem = qobject_cast<TankItem *>(sender);
+ m_tankItems.removeAll(tankItem);
+
+ return m_tankItems.size() <= 1;
+ } else {
+ return false;
+ }
+}
diff --git a/examples/statemachine/tankgame/gameovertransition.h b/examples/statemachine/tankgame/gameovertransition.h
new file mode 100644
index 0000000..5e99a75
--- /dev/null
+++ b/examples/statemachine/tankgame/gameovertransition.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef GAMEOVERTRANSITION_H
+#define GAMEOVERTRANSITION_H
+
+#include <QSignalTransition>
+
+class TankItem;
+class GameOverTransition: public QSignalTransition
+{
+ Q_OBJECT
+public:
+ GameOverTransition(QAbstractState *targetState);
+
+ void addTankItem(TankItem *tankItem);
+
+protected:
+ bool eventTest(QEvent *event);
+
+private:
+ QList<TankItem *> m_tankItems;
+};
+
+#endif
diff --git a/examples/statemachine/tankgame/main.cpp b/examples/statemachine/tankgame/main.cpp
new file mode 100644
index 0000000..185ad68
--- /dev/null
+++ b/examples/statemachine/tankgame/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include "mainwindow.h"
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ MainWindow mainWindow;
+ mainWindow.show();
+
+ return app.exec();
+}
diff --git a/examples/statemachine/tankgame/mainwindow.cpp b/examples/statemachine/tankgame/mainwindow.cpp
new file mode 100644
index 0000000..46e0db3
--- /dev/null
+++ b/examples/statemachine/tankgame/mainwindow.cpp
@@ -0,0 +1,342 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "tankitem.h"
+#include "rocketitem.h"
+#include "plugin.h"
+#include "gameovertransition.h"
+
+#include <QStateMachine>
+#include <QGraphicsView>
+#include <QAction>
+#include <QMenuBar>
+#include <QState>
+#include <QHistoryState>
+#include <QTimer>
+#include <QFileDialog>
+#include <QPluginLoader>
+#include <QApplication>
+#include <QInputDialog>
+#include <QMessageBox>
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent), m_scene(0), m_machine(0), m_runningState(0), m_started(false)
+{
+ init();
+}
+
+MainWindow::~MainWindow()
+{
+}
+
+void MainWindow::addWall(const QRectF &wall)
+{
+ QGraphicsRectItem *item = new QGraphicsRectItem;
+ item->setRect(wall);
+ item->setBrush(Qt::darkGreen);
+ item->setPen(QPen(Qt::black, 0));
+
+ m_scene->addItem(item);
+}
+
+void MainWindow::init()
+{
+ setWindowTitle("Pluggable Tank Game");
+
+ QGraphicsView *view = new QGraphicsView(this);
+ view->setRenderHints(QPainter::Antialiasing);
+ setCentralWidget(view);
+
+ m_scene = new QGraphicsScene(this);
+ view->setScene(m_scene);
+
+ QRectF sceneRect = QRectF(-200.0, -200.0, 400.0, 400.0);
+ m_scene->setSceneRect(sceneRect);
+
+ {
+ TankItem *item = new TankItem(this);
+
+ item->setPos(m_scene->sceneRect().topLeft() + QPointF(30.0, 30.0));
+ item->setDirection(45.0);
+ item->setColor(Qt::red);
+
+ m_spawns.append(item);
+ }
+
+ {
+ TankItem *item = new TankItem(this);
+
+ item->setPos(m_scene->sceneRect().topRight() + QPointF(-30.0, 30.0));
+ item->setDirection(135.0);
+ item->setColor(Qt::green);
+
+ m_spawns.append(item);
+ }
+
+ {
+ TankItem *item = new TankItem(this);
+
+ item->setPos(m_scene->sceneRect().bottomRight() + QPointF(-30.0, -30.0));
+ item->setDirection(225.0);
+ item->setColor(Qt::blue);
+
+ m_spawns.append(item);
+ }
+
+ {
+ TankItem *item = new TankItem(this);
+
+ item->setPos(m_scene->sceneRect().bottomLeft() + QPointF(30.0, -30.0));
+ item->setDirection(315.0);
+ item->setColor(Qt::yellow);
+
+ m_spawns.append(item);
+ }
+
+ QPointF centerOfMap = sceneRect.center();
+
+ addWall(QRectF(centerOfMap + QPointF(-50.0, -60.0), centerOfMap + QPointF(50.0, -50.0)));
+ addWall(QRectF(centerOfMap - QPointF(-50.0, -60.0), centerOfMap - QPointF(50.0, -50.0)));
+ addWall(QRectF(centerOfMap + QPointF(-50.0, -50.0), centerOfMap + QPointF(-40.0, 50.0)));
+ addWall(QRectF(centerOfMap - QPointF(-50.0, -50.0), centerOfMap - QPointF(-40.0, 50.0)));
+
+ addWall(QRectF(sceneRect.topLeft() + QPointF(sceneRect.width() / 2.0 - 5.0, -10.0),
+ sceneRect.topLeft() + QPointF(sceneRect.width() / 2.0 + 5.0, 100.0)));
+ addWall(QRectF(sceneRect.bottomLeft() + QPointF(sceneRect.width() / 2.0 - 5.0, 10.0),
+ sceneRect.bottomLeft() + QPointF(sceneRect.width() / 2.0 + 5.0, -100.0)));
+ addWall(QRectF(sceneRect.topLeft() + QPointF(-10.0, sceneRect.height() / 2.0 - 5.0),
+ sceneRect.topLeft() + QPointF(100.0, sceneRect.height() / 2.0 + 5.0)));
+ addWall(QRectF(sceneRect.topRight() + QPointF(10.0, sceneRect.height() / 2.0 - 5.0),
+ sceneRect.topRight() + QPointF(-100.0, sceneRect.height() / 2.0 + 5.0)));
+
+
+ QAction *addTankAction = menuBar()->addAction("&Add tank");
+ QAction *runGameAction = menuBar()->addAction("&Run game");
+ runGameAction->setObjectName("runGameAction");
+ QAction *stopGameAction = menuBar()->addAction("&Stop game");
+ menuBar()->addSeparator();
+ QAction *quitAction = menuBar()->addAction("&Quit");
+
+ connect(addTankAction, SIGNAL(triggered()), this, SLOT(addTank()));
+ connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
+
+ m_machine = new QStateMachine(this);
+ QState *stoppedState = new QState(m_machine->rootState());
+ stoppedState->setObjectName("stoppedState");
+ stoppedState->assignProperty(runGameAction, "enabled", true);
+ stoppedState->assignProperty(stopGameAction, "enabled", false);
+ stoppedState->assignProperty(this, "started", false);
+ m_machine->setInitialState(stoppedState);
+
+//! [5]
+ QState *spawnsAvailable = new QState(stoppedState);
+ spawnsAvailable->assignProperty(addTankAction, "enabled", true);
+
+ QState *noSpawnsAvailable = new QState(stoppedState);
+ noSpawnsAvailable->assignProperty(addTankAction, "enabled", false);
+//! [5]
+ spawnsAvailable->setObjectName("spawnsAvailable");
+ noSpawnsAvailable->setObjectName("noSpawnsAvailable");
+
+ spawnsAvailable->addTransition(this, SIGNAL(mapFull()), noSpawnsAvailable);
+
+//! [3]
+ QHistoryState *hs = new QHistoryState(stoppedState);
+ hs->setDefaultState(spawnsAvailable);
+//! [3]
+ hs->setObjectName("hs");
+
+ stoppedState->setInitialState(hs);
+
+//! [0]
+ m_runningState = new QState(QState::ParallelStates, m_machine->rootState());
+//! [0]
+ m_runningState->setObjectName("runningState");
+ m_runningState->assignProperty(addTankAction, "enabled", false);
+ m_runningState->assignProperty(runGameAction, "enabled", false);
+ m_runningState->assignProperty(stopGameAction, "enabled", true);
+
+ QState *gameOverState = new QState(m_machine->rootState());
+ gameOverState->setObjectName("gameOverState");
+ gameOverState->assignProperty(stopGameAction, "enabled", false);
+ connect(gameOverState, SIGNAL(entered()), this, SLOT(gameOver()));
+
+ stoppedState->addTransition(runGameAction, SIGNAL(triggered()), m_runningState);
+ m_runningState->addTransition(stopGameAction, SIGNAL(triggered()), stoppedState);
+
+ m_gameOverTransition = new GameOverTransition(gameOverState);
+ m_runningState->addTransition(m_gameOverTransition);
+
+ QTimer *timer = new QTimer(this);
+ timer->setInterval(100);
+ connect(timer, SIGNAL(timeout()), this, SLOT(runStep()));
+ connect(m_runningState, SIGNAL(entered()), timer, SLOT(start()));
+ connect(m_runningState, SIGNAL(exited()), timer, SLOT(stop()));
+
+ m_machine->start();
+ m_time.start();
+}
+
+void MainWindow::runStep()
+{
+ if (!m_started) {
+ m_time.restart();
+ m_started = true;
+ } else {
+ int elapsed = m_time.elapsed();
+ if (elapsed > 0) {
+ m_time.restart();
+ qreal elapsedSecs = elapsed / 1000.0;
+ QList<QGraphicsItem *> items = m_scene->items();
+ foreach (QGraphicsItem *item, items) {
+ if (GameItem *gameItem = qgraphicsitem_cast<GameItem *>(item))
+ gameItem->idle(elapsedSecs);
+ }
+ }
+ }
+}
+
+void MainWindow::gameOver()
+{
+ QList<QGraphicsItem *> items = m_scene->items();
+
+ TankItem *lastTankStanding = 0;
+ foreach (QGraphicsItem *item, items) {
+ if (GameItem *gameItem = qgraphicsitem_cast<GameItem *>(item)) {
+ if ((lastTankStanding = qobject_cast<TankItem *>(gameItem)) != 0)
+ break;
+ }
+ }
+
+ QMessageBox::information(this, "Game over!",
+ QString::fromLatin1("The tank played by '%1' has won!").arg(lastTankStanding->objectName()));
+}
+
+void MainWindow::addRocket()
+{
+ TankItem *tankItem = qobject_cast<TankItem *>(sender());
+ if (tankItem != 0) {
+ RocketItem *rocketItem = new RocketItem;
+
+ QPointF s = tankItem->mapToScene(QPointF(tankItem->boundingRect().right() + 10.0,
+ tankItem->boundingRect().center().y()));
+ rocketItem->setPos(s);
+ rocketItem->setDirection(tankItem->direction());
+ m_scene->addItem(rocketItem);
+ }
+}
+
+void MainWindow::addTank()
+{
+ Q_ASSERT(!m_spawns.isEmpty());
+
+ QDir pluginsDir(qApp->applicationDirPath());
+#if defined(Q_OS_WIN)
+ if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
+ pluginsDir.cdUp();
+#elif defined(Q_OS_MAC)
+ if (pluginsDir.dirName() == "MacOS") {
+ pluginsDir.cdUp();
+ pluginsDir.cdUp();
+ pluginsDir.cdUp();
+ }
+#endif
+
+ pluginsDir.cd("plugins");
+
+ QStringList itemNames;
+ QList<Plugin *> items;
+ foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
+ QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
+ QObject *possiblePlugin = loader.instance();
+ if (Plugin *plugin = qobject_cast<Plugin *>(possiblePlugin)) {
+ QString objectName = possiblePlugin->objectName();
+ if (objectName.isEmpty())
+ objectName = fileName;
+
+ itemNames.append(objectName);
+ items.append(plugin);
+ }
+ }
+
+ if (items.isEmpty()) {
+ QMessageBox::information(this, "No tank types found", "Please build the errorstateplugins directory");
+ return;
+ }
+
+ bool ok;
+//! [1]
+ QString selectedName = QInputDialog::getItem(this, "Select a tank type", "Tank types",
+ itemNames, 0, false, &ok);
+//! [1]
+
+ if (ok && !selectedName.isEmpty()) {
+ int idx = itemNames.indexOf(selectedName);
+ if (Plugin *plugin = idx >= 0 ? items.at(idx) : 0) {
+ TankItem *tankItem = m_spawns.takeLast();
+ tankItem->setObjectName(selectedName);
+ tankItem->setToolTip(selectedName);
+ m_scene->addItem(tankItem);
+ connect(tankItem, SIGNAL(cannonFired()), this, SLOT(addRocket()));
+ if (m_spawns.isEmpty())
+ emit mapFull();
+
+ m_gameOverTransition->addTankItem(tankItem);
+
+ QState *region = new QState(m_runningState);
+ region->setObjectName(QString::fromLatin1("region%1").arg(m_spawns.size()));
+//! [2]
+ QState *pluginState = plugin->create(region, tankItem);
+//! [2]
+ region->setInitialState(pluginState);
+
+ // If the plugin has an error it is disabled
+//! [4]
+ QState *errorState = new QState(region);
+ errorState->setObjectName(QString::fromLatin1("errorState%1").arg(m_spawns.size()));
+ errorState->assignProperty(tankItem, "enabled", false);
+ pluginState->setErrorState(errorState);
+//! [4]
+ }
+ }
+}
+
diff --git a/examples/statemachine/tankgame/mainwindow.h b/examples/statemachine/tankgame/mainwindow.h
new file mode 100644
index 0000000..4ae8f7a
--- /dev/null
+++ b/examples/statemachine/tankgame/mainwindow.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QTime>
+
+QT_BEGIN_NAMESPACE
+class QGraphicsScene;
+class QStateMachine;
+class QState;
+QT_END_NAMESPACE
+class GameOverTransition;
+class TankItem;
+
+class MainWindow: public QMainWindow
+{
+ Q_OBJECT
+ Q_PROPERTY(bool started READ started WRITE setStarted)
+public:
+ MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+ void setStarted(bool b) { m_started = b; }
+ bool started() const { return m_started; }
+
+public slots:
+ void addTank();
+ void addRocket();
+ void runStep();
+ void gameOver();
+
+signals:
+ void mapFull();
+
+private:
+ void init();
+ void addWall(const QRectF &wall);
+
+ QGraphicsScene *m_scene;
+
+ QStateMachine *m_machine;
+ QState *m_runningState;
+ GameOverTransition *m_gameOverTransition;
+
+ QList<TankItem *> m_spawns;
+ QTime m_time;
+
+ bool m_started : 1;
+};
+
+#endif
+
diff --git a/examples/statemachine/tankgame/plugin.h b/examples/statemachine/tankgame/plugin.h
new file mode 100644
index 0000000..ddd10b7
--- /dev/null
+++ b/examples/statemachine/tankgame/plugin.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef PLUGIN_H
+#define PLUGIN_H
+
+#include <QtPlugin>
+
+QT_BEGIN_NAMESPACE
+class QState;
+QT_END_NAMESPACE
+class Plugin
+{
+public:
+ virtual ~Plugin() {}
+
+ virtual QState *create(QState *parentState, QObject *tank) = 0;
+};
+
+QT_BEGIN_NAMESPACE
+Q_DECLARE_INTERFACE(Plugin, "TankPlugin")
+QT_END_NAMESPACE
+
+#endif
diff --git a/examples/statemachine/tankgame/rocketitem.cpp b/examples/statemachine/tankgame/rocketitem.cpp
new file mode 100644
index 0000000..3ace8e8
--- /dev/null
+++ b/examples/statemachine/tankgame/rocketitem.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "rocketitem.h"
+#include "tankitem.h"
+
+#include <QPainter>
+#include <QGraphicsScene>
+
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+RocketItem::RocketItem(QObject *parent)
+ : GameItem(parent), m_direction(0.0), m_distance(300.0)
+{
+}
+
+QRectF RocketItem::boundingRect() const
+{
+ return QRectF(-1.0, -1.0, 2.0, 2.0);
+}
+
+void RocketItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ painter->setBrush(Qt::black);
+ painter->drawEllipse(boundingRect());
+}
+
+void RocketItem::idle(qreal elapsed)
+{
+ qreal dist = elapsed * speed();
+
+ m_distance -= dist;
+ if (m_distance < 0.0) {
+ scene()->removeItem(this);
+ delete this;
+ return;
+ }
+
+ qreal a = m_direction * M_PI / 180.0;
+
+ qreal yd = dist * sin(a);
+ qreal xd = dist * sin(M_PI / 2.0 - a);
+
+ QPointF requestedPosition = pos() + QPointF(xd, yd);
+ QGraphicsItem *collidedItem = 0;
+ QPointF nextPosition = tryMove(requestedPosition, 0, &collidedItem);
+ if (requestedPosition == nextPosition) {
+ setPos(nextPosition);
+ } else {
+ if (GameItem *gameItem = qgraphicsitem_cast<GameItem *>(collidedItem)) {
+ TankItem *tankItem = qobject_cast<TankItem *>(gameItem);
+ if (tankItem != 0)
+ tankItem->hitByRocket();
+ }
+
+ scene()->removeItem(this);
+ delete this;
+ }
+}
diff --git a/examples/statemachine/tankgame/rocketitem.h b/examples/statemachine/tankgame/rocketitem.h
new file mode 100644
index 0000000..31146a6
--- /dev/null
+++ b/examples/statemachine/tankgame/rocketitem.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef ROCKETITEM_H
+#define ROCKETITEM_H
+
+#include "gameitem.h"
+
+class RocketItem: public GameItem
+{
+ Q_OBJECT
+public:
+ RocketItem(QObject *parent = 0);
+
+ virtual void idle(qreal elapsed);
+ qreal speed() const { return 100.0; }
+ void setDirection(qreal direction) { m_direction = direction; }
+
+protected:
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ QRectF boundingRect() const;
+
+private:
+ qreal m_direction;
+ qreal m_distance;
+};
+
+#endif
diff --git a/examples/statemachine/tankgame/tankgame.pro b/examples/statemachine/tankgame/tankgame.pro
new file mode 100644
index 0000000..59415be
--- /dev/null
+++ b/examples/statemachine/tankgame/tankgame.pro
@@ -0,0 +1,19 @@
+HEADERS += mainwindow.h \
+ plugin.h \
+ tankitem.h \
+ rocketitem.h \
+ gameitem.h \
+ gameovertransition.h
+SOURCES += main.cpp \
+ mainwindow.cpp \
+ tankitem.cpp \
+ rocketitem.cpp \
+ gameitem.cpp \
+ gameovertransition.cpp
+CONFIG += console
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS tankgame.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame
+INSTALLS += target sources
diff --git a/examples/statemachine/tankgame/tankitem.cpp b/examples/statemachine/tankgame/tankitem.cpp
new file mode 100644
index 0000000..393d65f
--- /dev/null
+++ b/examples/statemachine/tankgame/tankitem.cpp
@@ -0,0 +1,302 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "tankitem.h"
+
+#include <QPainter>
+#include <QGraphicsScene>
+#include <QDebug>
+
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+class Action
+{
+public:
+ Action(TankItem *item) : m_item(item)
+ {
+ }
+
+ TankItem *item() const { return m_item; }
+ void setItem(TankItem *item) { m_item = item; }
+
+ virtual bool apply(qreal timeDelta) = 0;
+
+private:
+ TankItem *m_item;
+};
+
+class MoveAction: public Action
+{
+public:
+ MoveAction(TankItem *item, qreal distance)
+ : Action(item), m_distance(distance)
+ {
+ m_reverse = m_distance < 0.0;
+ }
+
+ bool apply(qreal timeDelta)
+ {
+ qreal dist = timeDelta * item()->speed() * (m_reverse ? -1.0 : 1.0);
+
+ bool done = false;
+ if (qAbs(m_distance) < qAbs(dist)) {
+ done = true;
+ dist = m_distance;
+ }
+ m_distance -= dist;
+
+ qreal a = item()->direction() * M_PI / 180.0;
+
+ qreal yd = dist * sin(a);
+ qreal xd = dist * sin(M_PI / 2.0 - a);
+
+ item()->setPos(item()->pos() + QPointF(xd, yd));
+ return !done;
+ }
+
+private:
+ qreal m_distance;
+ bool m_reverse;
+};
+
+class TurnAction: public Action
+{
+public:
+ TurnAction(TankItem *item, qreal distance)
+ : Action(item), m_distance(distance)
+ {
+ m_reverse = m_distance < 0.0;
+ }
+
+ bool apply(qreal timeDelta)
+ {
+ qreal dist = timeDelta * item()->angularSpeed() * (m_reverse ? -1.0 : 1.0);
+ bool done = false;
+ if (qAbs(m_distance) < qAbs(dist)) {
+ done = true;
+ dist = m_distance;
+ }
+ m_distance -= dist;
+
+ item()->setDirection(item()->direction() + dist);
+ return !done;
+ }
+
+private:
+ qreal m_distance;
+ bool m_reverse;
+};
+
+TankItem::TankItem(QObject *parent)
+ : GameItem(parent), m_currentAction(0), m_currentDirection(0.0), m_enabled(true)
+{
+ connect(this, SIGNAL(cannonFired()), this, SIGNAL(actionCompleted()));
+}
+
+void TankItem::idle(qreal elapsed)
+{
+ if (m_enabled) {
+ if (m_currentAction != 0) {
+ if (!m_currentAction->apply(elapsed)) {
+ setAction(0);
+ emit actionCompleted();
+ }
+
+ QGraphicsItem *item = 0;
+ qreal distance = distanceToObstacle(&item);
+ if (TankItem *tankItem = qgraphicsitem_cast<TankItem *>(item))
+ emit tankSpotted(tankItem->direction(), distance);
+ }
+ }
+}
+
+void TankItem::hitByRocket()
+{
+ emit aboutToBeDestroyed();
+ deleteLater();
+}
+
+void TankItem::setAction(Action *newAction)
+{
+ if (m_currentAction != 0)
+ delete m_currentAction;
+
+ m_currentAction = newAction;
+}
+
+void TankItem::fireCannon()
+{
+ emit cannonFired();
+}
+
+void TankItem::moveForwards(qreal length)
+{
+ setAction(new MoveAction(this, length));
+}
+
+void TankItem::moveBackwards(qreal length)
+{
+ setAction(new MoveAction(this, -length));
+}
+
+void TankItem::turn(qreal degrees)
+{
+ setAction(new TurnAction(this, degrees));
+}
+
+void TankItem::turnTo(qreal degrees)
+{
+ setAction(new TurnAction(this, degrees - direction()));
+}
+
+void TankItem::stop()
+{
+ setAction(0);
+}
+
+QVariant TankItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemPositionChange && scene()) {
+ QPointF requestedPosition = value.toPointF();
+ QLineF collidedLine;
+ QPointF nextPoint = tryMove(requestedPosition, &collidedLine);
+ if (nextPoint != requestedPosition)
+ emit collision(collidedLine);
+ return nextPoint;
+ } else {
+ return QGraphicsItem::itemChange(change, value);
+ }
+}
+
+
+void TankItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ QRectF brect = boundingRect();
+
+ painter->setBrush(m_color);
+ painter->setPen(Qt::black);
+
+ // body
+ painter->drawRect(brect.adjusted(0.0, 4.0, -2.0, -4.0));
+
+ // cannon
+ QRectF cannonBase = brect.adjusted(10.0, 6.0, -12.0, -6.0);
+ painter->drawEllipse(cannonBase);
+
+ painter->drawRect(QRectF(QPointF(cannonBase.center().x(), cannonBase.center().y() - 2.0),
+ QPointF(brect.right(), cannonBase.center().y() + 2.0)));
+
+ // left track
+ painter->setBrush(QBrush(Qt::black, Qt::VerPattern));
+ QRectF leftTrackRect = QRectF(brect.topLeft(), QPointF(brect.right() - 2.0, brect.top() + 4.0));
+ painter->fillRect(leftTrackRect, Qt::darkYellow);
+ painter->drawRect(leftTrackRect);
+
+ // right track
+ QRectF rightTrackRect = QRectF(QPointF(brect.left(), brect.bottom() - 4.0),
+ QPointF(brect.right() - 2.0, brect.bottom()));
+ painter->fillRect(rightTrackRect, Qt::darkYellow);
+ painter->drawRect(rightTrackRect);
+
+ if (!m_enabled) {
+ painter->setPen(QPen(Qt::red, 5));
+
+ painter->drawEllipse(brect);
+
+ QPainterPath path;
+ path.addEllipse(brect);
+ painter->setClipPath(path);
+ painter->drawLine(brect.topRight(), brect.bottomLeft());
+ }
+}
+
+QRectF TankItem::boundingRect() const
+{
+ return QRectF(-20.0, -10.0, 40.0, 20.0);
+}
+
+qreal TankItem::direction() const
+{
+ return m_currentDirection;
+}
+
+void TankItem::setDirection(qreal newDirection)
+{
+ int fullRotations = int(newDirection) / 360;
+ newDirection -= fullRotations * 360.0;
+
+ qreal diff = newDirection - m_currentDirection;
+ m_currentDirection = newDirection;
+ rotate(diff);
+}
+
+qreal TankItem::distanceToObstacle(QGraphicsItem **obstacle) const
+{
+ qreal dist = sqrt(pow(scene()->sceneRect().width(), 2) + pow(scene()->sceneRect().height(), 2));
+
+ qreal a = m_currentDirection * M_PI / 180.0;
+
+ qreal yd = dist * sin(a);
+ qreal xd = dist * sin(M_PI / 2.0 - a);
+
+ QPointF requestedPosition = pos() + QPointF(xd, yd);
+ QGraphicsItem *collidedItem = 0;
+ QPointF nextPosition = tryMove(requestedPosition, 0, &collidedItem);
+ if (collidedItem != 0) {
+ if (obstacle != 0)
+ *obstacle = collidedItem;
+
+ QPointF d = nextPosition - pos();
+ return sqrt(pow(d.x(), 2) + pow(d.y(), 2));
+ } else {
+ return 0.0;
+ }
+}
+
+qreal TankItem::distanceToObstacle() const
+{
+ return distanceToObstacle(0);
+}
+
diff --git a/examples/statemachine/tankgame/tankitem.h b/examples/statemachine/tankgame/tankitem.h
new file mode 100644
index 0000000..942fca8
--- /dev/null
+++ b/examples/statemachine/tankgame/tankitem.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef TANKITEM_H
+#define TANKITEM_H
+
+#include "gameitem.h"
+
+#include <QColor>
+
+class Action;
+class TankItem: public GameItem
+{
+ Q_OBJECT
+ Q_PROPERTY(bool enabled READ enabled WRITE setEnabled)
+ Q_PROPERTY(qreal direction READ direction WRITE turnTo)
+ Q_PROPERTY(qreal distanceToObstacle READ distanceToObstacle)
+public:
+ TankItem(QObject *parent = 0);
+
+ void setColor(const QColor &color) { m_color = color; }
+ QColor color() const { return m_color; }
+
+ void idle(qreal elapsed);
+ void setDirection(qreal newDirection);
+
+ qreal speed() const { return 90.0; }
+ qreal angularSpeed() const { return 90.0; }
+
+ QRectF boundingRect() const;
+
+ void hitByRocket();
+
+ void setEnabled(bool b) { m_enabled = b; }
+ bool enabled() const { return m_enabled; }
+
+ qreal direction() const;
+ qreal distanceToObstacle() const;
+ qreal distanceToObstacle(QGraphicsItem **item) const;
+
+//! [0]
+signals:
+ void tankSpotted(qreal direction, qreal distance);
+ void collision(const QLineF &collidedLine);
+ void actionCompleted();
+ void cannonFired();
+ void aboutToBeDestroyed();
+
+public slots:
+ void moveForwards(qreal length = 10.0);
+ void moveBackwards(qreal length = 10.0);
+ void turn(qreal degrees = 30.0);
+ void turnTo(qreal degrees = 0.0);
+ void stop();
+ void fireCannon();
+//! [0]
+
+protected:
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);
+
+private:
+ void setAction(Action *newAction);
+
+ Action *m_currentAction;
+ qreal m_currentDirection;
+ QColor m_color;
+ bool m_enabled;
+};
+
+#endif
diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai.pro b/examples/statemachine/tankgameplugins/random_ai/random_ai.pro
new file mode 100644
index 0000000..5bc0b26
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/random_ai/random_ai.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+CONFIG += plugin
+INCLUDEPATH += ../..
+HEADERS = random_ai_plugin.h
+SOURCES = random_ai_plugin.cpp
+TARGET = $$qtLibraryTarget(random_ai)
+DESTDIR = ../../tankgame/plugins
+
+#! [0]
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS random_ai.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/random_ai \ No newline at end of file
diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp
new file mode 100644
index 0000000..d360de9
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "random_ai_plugin.h"
+
+#include <QState>
+#include <QtPlugin>
+
+#include <time.h>
+
+QState *RandomAiPlugin::create(QState *parentState, QObject *tank)
+{
+ qsrand(uint(time(NULL)));
+
+ QState *topLevel = new QState(parentState);
+
+ QState *selectNextActionState = new SelectActionState(topLevel);
+ topLevel->setInitialState(selectNextActionState);
+
+ QState *fireState = new RandomDistanceState(topLevel);
+ connect(fireState, SIGNAL(distanceComputed(qreal)), tank, SLOT(fireCannon()));
+ selectNextActionState->addTransition(selectNextActionState, SIGNAL(fireSelected()), fireState);
+
+ QState *moveForwardsState = new RandomDistanceState(topLevel);
+ connect(moveForwardsState, SIGNAL(distanceComputed(qreal)), tank, SLOT(moveForwards(qreal)));
+ selectNextActionState->addTransition(selectNextActionState, SIGNAL(moveForwardsSelected()), moveForwardsState);
+
+ QState *moveBackwardsState = new RandomDistanceState(topLevel);
+ connect(moveBackwardsState, SIGNAL(distanceComputed(qreal)), tank, SLOT(moveBackwards(qreal)));
+ selectNextActionState->addTransition(selectNextActionState, SIGNAL(moveBackwardsSelected()), moveBackwardsState);
+
+ QState *turnState = new RandomDistanceState(topLevel);
+ connect(turnState, SIGNAL(distanceComputed(qreal)), tank, SLOT(turn(qreal)));
+ selectNextActionState->addTransition(selectNextActionState, SIGNAL(turnSelected()), turnState);
+
+ topLevel->addTransition(tank, SIGNAL(actionCompleted()), selectNextActionState);
+
+ return topLevel;
+}
+
+Q_EXPORT_PLUGIN2(random_ai, RandomAiPlugin)
diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h
new file mode 100644
index 0000000..9faeeac
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef RANDOM_AI_PLUGIN_H
+#define RANDOM_AI_PLUGIN_H
+
+#include <QObject>
+#include <QState>
+
+#include <tankgame/plugin.h>
+
+class SelectActionState: public QState
+{
+ Q_OBJECT
+public:
+ SelectActionState(QState *parent = 0) : QState(parent)
+ {
+ }
+
+signals:
+ void fireSelected();
+ void moveForwardsSelected();
+ void moveBackwardsSelected();
+ void turnSelected();
+
+protected:
+ void onEntry(QEvent *)
+ {
+ int rand = qrand() % 4;
+ switch (rand) {
+ case 0: emit fireSelected(); break;
+ case 1: emit moveForwardsSelected(); break;
+ case 2: emit moveBackwardsSelected(); break;
+ case 3: emit turnSelected(); break;
+ };
+ }
+};
+
+class RandomDistanceState: public QState
+{
+ Q_OBJECT
+public:
+ RandomDistanceState(QState *parent = 0) : QState(parent)
+ {
+ }
+
+signals:
+ void distanceComputed(qreal distance);
+
+protected:
+ void onEntry(QEvent *)
+ {
+ emit distanceComputed(qreal(qrand() % 180));
+ }
+};
+
+class RandomAiPlugin: public QObject, public Plugin
+{
+ Q_OBJECT
+ Q_INTERFACES(Plugin)
+public:
+ RandomAiPlugin() { setObjectName("Random"); }
+
+ virtual QState *create(QState *parentState, QObject *tank);
+};
+
+#endif // RANDOM_AI_PLUGIN_H
diff --git a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp
new file mode 100644
index 0000000..6aae015
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "seek_ai.h"
+
+QState *SeekAi::create(QState *parentState, QObject *tank)
+{
+ QState *topLevel = new QState(parentState);
+ topLevel->setObjectName("topLevel");
+
+ QState *seek = new QState(topLevel);
+ seek->setObjectName("seek");
+ topLevel->setInitialState(seek);
+
+ QState *lookForNearestWall = new SearchState(tank, seek);
+ lookForNearestWall->setObjectName("lookForNearestWall");
+ seek->setInitialState(lookForNearestWall);
+
+ QState *driveToFirstObstacle = new QState(seek);
+ driveToFirstObstacle->setObjectName("driveToFirstObstacle");
+ lookForNearestWall->addTransition(lookForNearestWall, SIGNAL(nearestObstacleStraightAhead()),
+ driveToFirstObstacle);
+
+ QState *drive = new QState(driveToFirstObstacle);
+ drive->setObjectName("drive");
+ driveToFirstObstacle->setInitialState(drive);
+ connect(drive, SIGNAL(entered()), tank, SLOT(moveForwards()));
+ connect(drive, SIGNAL(exited()), tank, SLOT(stop()));
+
+ // Go in loop
+ QState *finishedDriving = new QState(driveToFirstObstacle);
+ finishedDriving->setObjectName("finishedDriving");
+ drive->addTransition(tank, SIGNAL(actionCompleted()), finishedDriving);
+ finishedDriving->addTransition(drive);
+
+ QState *turnTo = new QState(seek);
+ turnTo->setObjectName("turnTo");
+ driveToFirstObstacle->addTransition(new CollisionTransition(tank, turnTo));
+
+ turnTo->addTransition(tank, SIGNAL(actionCompleted()), driveToFirstObstacle);
+
+ ChaseState *chase = new ChaseState(tank, topLevel);
+ chase->setObjectName("chase");
+ seek->addTransition(new TankSpottedTransition(tank, chase));
+ chase->addTransition(chase, SIGNAL(finished()), driveToFirstObstacle);
+ chase->addTransition(new TankSpottedTransition(tank, chase));
+
+ return topLevel;
+}
+
+Q_EXPORT_PLUGIN2(seek_ai, SeekAi)
diff --git a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h
new file mode 100644
index 0000000..e44ad07
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef SEEK_AI_H
+#define SEEK_AI_H
+
+#include <tankgame/plugin.h>
+
+#include <QState>
+#include <QFinalState>
+#include <QSignalTransition>
+#include <QSignalEvent>
+#include <QVariant>
+#include <QLineF>
+#include <QDebug>
+
+class SearchState: public QState
+{
+ Q_OBJECT
+public:
+ SearchState(QObject *tank, QState *parentState = 0)
+ : QState(parentState),
+ m_tank(tank),
+ m_distanceToTurn(360.0),
+ m_nearestDistance(-1.0),
+ m_directionOfNearestObstacle(0.0)
+ {
+ }
+
+public slots:
+ void turnAlittle()
+ {
+ qreal dist = m_tank->property("distanceToObstacle").toDouble();
+
+ if (m_nearestDistance < 0.0 || dist < m_nearestDistance) {
+ m_nearestDistance = dist;
+ m_directionOfNearestObstacle = m_tank->property("direction").toDouble();
+ }
+
+ m_distanceToTurn -= 10.0;
+ if (m_distanceToTurn < 0.0) {
+ disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(turnAlittle()));
+ connect(m_tank, SIGNAL(actionCompleted()), this, SIGNAL(nearestObstacleStraightAhead()));
+ m_tank->setProperty("direction", m_directionOfNearestObstacle);
+ }
+
+ qreal currentDirection = m_tank->property("direction").toDouble();
+ m_tank->setProperty("direction", currentDirection + 10.0);
+ }
+
+signals:
+ void nearestObstacleStraightAhead();
+
+protected:
+ void onEntry(QEvent *)
+ {
+ connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(turnAlittle()));
+ turnAlittle();
+ }
+
+ void onExit(QEvent *)
+ {
+ disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(turnAlittle()));
+ disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(nearestObstacleStraightAhead()));
+ }
+
+private:
+ QObject *m_tank;
+
+ qreal m_distanceToTurn;
+ qreal m_nearestDistance;
+ qreal m_directionOfNearestObstacle;
+};
+
+class CollisionTransition: public QSignalTransition
+{
+public:
+ CollisionTransition(QObject *tank, QState *turnTo)
+ : QSignalTransition(tank, SIGNAL(collision(QLineF))),
+ m_tank(tank),
+ m_turnTo(turnTo)
+ {
+ setTargetState(turnTo);
+ }
+
+protected:
+ bool eventTest(QEvent *event)
+ {
+ bool b = QSignalTransition::eventTest(event);
+ if (b) {
+ QSignalEvent *se = static_cast<QSignalEvent *>(event);
+ m_lastLine = se->arguments().at(0).toLineF();
+ }
+ return b;
+ }
+
+ void onTransition(QEvent *)
+ {
+ qreal angleOfWall = m_lastLine.angle();
+
+ qreal newDirection;
+ if (qrand() % 2 == 0)
+ newDirection = angleOfWall;
+ else
+ newDirection = angleOfWall - 180.0;
+
+ m_turnTo->assignProperty(m_tank, "direction", newDirection);
+ }
+
+private:
+ QLineF m_lastLine;
+ QObject *m_tank;
+ QState *m_turnTo;
+};
+
+class ChaseState: public QState
+{
+ class GoToLocationState: public QState
+ {
+ public:
+ GoToLocationState(QObject *tank, QState *parentState = 0)
+ : QState(parentState), m_tank(tank), m_distance(0.0)
+ {
+ }
+
+ void setDistance(qreal distance) { m_distance = distance; }
+
+ protected:
+ void onEntry()
+ {
+ QMetaObject::invokeMethod(m_tank, "moveForwards", Q_ARG(qreal, m_distance));
+ }
+
+ private:
+ QObject *m_tank;
+ qreal m_distance;
+ };
+
+public:
+ ChaseState(QObject *tank, QState *parentState = 0) : QState(parentState), m_tank(tank)
+ {
+ QState *fireCannon = new QState(this);
+ fireCannon->setObjectName("fireCannon");
+ connect(fireCannon, SIGNAL(entered()), tank, SLOT(fireCannon()));
+ setInitialState(fireCannon);
+
+ m_goToLocation = new GoToLocationState(tank, this);
+ m_goToLocation->setObjectName("goToLocation");
+ fireCannon->addTransition(tank, SIGNAL(actionCompleted()), m_goToLocation);
+
+ m_turnToDirection = new QState(this);
+ m_turnToDirection->setObjectName("turnToDirection");
+ m_goToLocation->addTransition(tank, SIGNAL(actionCompleted()), m_turnToDirection);
+
+ QFinalState *finalState = new QFinalState(this);
+ finalState->setObjectName("finalState");
+ m_turnToDirection->addTransition(tank, SIGNAL(actionCompleted()), finalState);
+ }
+
+ void setDirection(qreal direction)
+ {
+ m_turnToDirection->assignProperty(m_tank, "direction", direction);
+ }
+
+ void setDistance(qreal distance)
+ {
+ m_goToLocation->setDistance(distance);
+ }
+
+private:
+ QObject *m_tank;
+ GoToLocationState *m_goToLocation;
+ QState *m_turnToDirection;
+
+};
+
+class TankSpottedTransition: public QSignalTransition
+{
+public:
+ TankSpottedTransition(QObject *tank, ChaseState *target) : QSignalTransition(tank, SIGNAL(tankSpotted(qreal,qreal))), m_chase(target)
+ {
+ setTargetState(target);
+ }
+
+protected:
+ bool eventTest(QEvent *event)
+ {
+ bool b = QSignalTransition::eventTest(event);
+ if (b) {
+ QSignalEvent *se = static_cast<QSignalEvent *>(event);
+ m_chase->setDirection(se->arguments().at(0).toDouble());
+ m_chase->setDistance(se->arguments().at(1).toDouble());
+ }
+ return b;
+ }
+
+private:
+ ChaseState *m_chase;
+};
+
+class SeekAi: public QObject, public Plugin
+{
+ Q_OBJECT
+ Q_INTERFACES(Plugin)
+public:
+ SeekAi() { setObjectName("Seek and destroy"); }
+
+ virtual QState *create(QState *parentState, QObject *tank);
+};
+
+#endif
diff --git a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro
new file mode 100644
index 0000000..0d8bf2e
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+CONFIG += plugin
+INCLUDEPATH += ../..
+HEADERS = seek_ai.h
+SOURCES = seek_ai.cpp
+TARGET = $$qtLibraryTarget(seek_ai)
+DESTDIR = ../../tankgame/plugins
+
+#! [0]
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS seek_ai.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/seek_ai \ No newline at end of file
diff --git a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp
new file mode 100644
index 0000000..581a6b2
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "spin_ai.h"
+
+#include <QtPlugin>
+
+QState *SpinAi::create(QState *parentState, QObject *tank)
+{
+ QState *topLevel = new QState(parentState);
+ QState *spinState = new SpinState(tank, topLevel);
+ topLevel->setInitialState(spinState);
+
+ // When tank is spotted, fire two times and go back to spin state
+ QState *fireState = new QState(topLevel);
+
+ QState *fireOnce = new QState(fireState);
+ fireState->setInitialState(fireOnce);
+ connect(fireOnce, SIGNAL(entered()), tank, SLOT(fireCannon()));
+
+ QState *fireTwice = new QState(fireState);
+ connect(fireTwice, SIGNAL(entered()), tank, SLOT(fireCannon()));
+
+ fireOnce->addTransition(tank, SIGNAL(actionCompleted()), fireTwice);
+ fireTwice->addTransition(tank, SIGNAL(actionCompleted()), spinState);
+
+ spinState->addTransition(tank, SIGNAL(tankSpotted(qreal,qreal)), fireState);
+
+ return topLevel;
+}
+
+Q_EXPORT_PLUGIN2(spin_ai, SpinAi)
diff --git a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h
new file mode 100644
index 0000000..652e8b8
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef SPIN_AI_H
+#define SPIN_AI_H
+
+#include <tankgame/plugin.h>
+
+#include <QObject>
+#include <QState>
+#include <QVariant>
+
+class SpinState: public QState
+{
+ Q_OBJECT
+public:
+ SpinState(QObject *tank, QState *parent) : QState(parent), m_tank(tank)
+ {
+ }
+
+public slots:
+ void spin()
+ {
+ m_tank->setProperty("direction", m_tank->property("direction").toDouble() + 90.0);
+ }
+
+protected:
+ void onEntry(QEvent *)
+ {
+ connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin()));
+ spin();
+ }
+
+ void onExit(QEvent *)
+ {
+ disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin()));
+ }
+
+private:
+ QObject *m_tank;
+
+};
+
+class SpinAi: public QObject, public Plugin
+{
+ Q_OBJECT
+ Q_INTERFACES(Plugin)
+public:
+ SpinAi() { setObjectName("Spin and destroy"); }
+
+ virtual QState *create(QState *parentState, QObject *tank);
+};
+
+#endif
diff --git a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro
new file mode 100644
index 0000000..8ab4da0
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+CONFIG += plugin
+INCLUDEPATH += ../..
+HEADERS = spin_ai.h
+SOURCES = spin_ai.cpp
+TARGET = $$qtLibraryTarget(spin_ai)
+DESTDIR = ../../tankgame/plugins
+
+#! [0]
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS spin_ai.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/spin_ai \ No newline at end of file
diff --git a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp
new file mode 100644
index 0000000..19137b2
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#include "spin_ai_with_error.h"
+
+#include <QtPlugin>
+
+QState *SpinAiWithError::create(QState *parentState, QObject *tank)
+{
+ QState *topLevel = new QState(parentState);
+ QState *spinState = new SpinState(tank, topLevel);
+ topLevel->setInitialState(spinState);
+
+ // When tank is spotted, fire two times and go back to spin state
+ // (no initial state set for fireState will lead to run-time error in machine)
+ QState *fireState = new QState(topLevel);
+
+ QState *fireOnce = new QState(fireState);
+ connect(fireOnce, SIGNAL(entered()), tank, SLOT(fireCannon()));
+
+ QState *fireTwice = new QState(fireState);
+ connect(fireTwice, SIGNAL(entered()), tank, SLOT(fireCannon()));
+
+ fireOnce->addTransition(tank, SIGNAL(actionCompleted()), fireTwice);
+ fireTwice->addTransition(tank, SIGNAL(actionCompleted()), spinState);
+
+ spinState->addTransition(tank, SIGNAL(tankSpotted(qreal,qreal)), fireState);
+
+ return topLevel;
+}
+
+Q_EXPORT_PLUGIN2(spin_ai_with_error, SpinAiWithError)
diff --git a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h
new file mode 100644
index 0000000..e040bf2
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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$
+**
+****************************************************************************/
+
+#ifndef SPIN_AI_WITH_ERROR_H
+#define SPIN_AI_WITH_ERROR_H
+
+#include <tankgame/plugin.h>
+
+#include <QObject>
+#include <QState>
+#include <QVariant>
+
+class SpinState: public QState
+{
+ Q_OBJECT
+public:
+ SpinState(QObject *tank, QState *parent) : QState(parent), m_tank(tank)
+ {
+ }
+
+public slots:
+ void spin()
+ {
+ m_tank->setProperty("direction", m_tank->property("direction").toDouble() + 90.0);
+ }
+
+protected:
+ void onEntry(QEvent *)
+ {
+ connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin()));
+ spin();
+ }
+
+ void onExit(QEvent *)
+ {
+ disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin()));
+ }
+
+private:
+ QObject *m_tank;
+
+};
+
+class SpinAiWithError: public QObject, public Plugin
+{
+ Q_OBJECT
+ Q_INTERFACES(Plugin)
+public:
+ SpinAiWithError() { setObjectName("Spin and destroy with runtime error in state machine"); }
+
+ virtual QState *create(QState *parentState, QObject *tank);
+};
+
+#endif
diff --git a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro
new file mode 100644
index 0000000..124cf98
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+CONFIG += plugin
+INCLUDEPATH += ../..
+HEADERS = spin_ai_with_error.h
+SOURCES = spin_ai_with_error.cpp
+TARGET = $$qtLibraryTarget(spin_ai_with_error)
+DESTDIR = ../../tankgame/plugins
+
+#! [0]
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS spin_ai_with_error.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/spin_ai_with_error \ No newline at end of file
diff --git a/examples/statemachine/tankgameplugins/tankgameplugins.pro b/examples/statemachine/tankgameplugins/tankgameplugins.pro
new file mode 100644
index 0000000..a098e03
--- /dev/null
+++ b/examples/statemachine/tankgameplugins/tankgameplugins.pro
@@ -0,0 +1,11 @@
+TEMPLATE = subdirs
+SUBDIRS = random_ai \
+ spin_ai_with_error \
+ spin_ai \
+ seek_ai
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS tankgameplugins.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins
+INSTALLS += target sources
diff --git a/examples/statemachine/trafficlight/main.cpp b/examples/statemachine/trafficlight/main.cpp
new file mode 100644
index 0000000..8a46fff
--- /dev/null
+++ b/examples/statemachine/trafficlight/main.cpp
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module 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$
+**
+****************************************************************************/
+
+#include <QtGui>
+#ifdef QT_STATEMACHINE_SOLUTION
+#include <qstate.h>
+#include <qstatemachine.h>
+#include <qfinalstate.h>
+#endif
+
+//! [0]
+class LightWidget : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(bool on READ isOn WRITE setOn)
+public:
+ LightWidget(const QColor &color, QWidget *parent = 0)
+ : QWidget(parent), m_color(color), m_on(false) {}
+
+ bool isOn() const
+ { return m_on; }
+ void setOn(bool on)
+ {
+ if (on == m_on)
+ return;
+ m_on = on;
+ update();
+ }
+
+public slots:
+ void turnOff() { setOn(false); }
+ void turnOn() { setOn(true); }
+
+protected:
+ virtual void paintEvent(QPaintEvent *)
+ {
+ if (!m_on)
+ return;
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setBrush(m_color);
+ painter.drawEllipse(0, 0, width(), height());
+ }
+
+private:
+ QColor m_color;
+ bool m_on;
+};
+//! [0]
+
+//! [1]
+class TrafficLightWidget : public QWidget
+{
+public:
+ TrafficLightWidget(QWidget *parent = 0)
+ : QWidget(parent)
+ {
+ QVBoxLayout *vbox = new QVBoxLayout(this);
+ m_red = new LightWidget(Qt::red);
+ vbox->addWidget(m_red);
+ m_yellow = new LightWidget(Qt::yellow);
+ vbox->addWidget(m_yellow);
+ m_green = new LightWidget(Qt::green);
+ vbox->addWidget(m_green);
+ QPalette pal = palette();
+ pal.setColor(QPalette::Background, Qt::black);
+ setPalette(pal);
+ setAutoFillBackground(true);
+ }
+
+ LightWidget *redLight() const
+ { return m_red; }
+ LightWidget *yellowLight() const
+ { return m_yellow; }
+ LightWidget *greenLight() const
+ { return m_green; }
+
+private:
+ LightWidget *m_red;
+ LightWidget *m_yellow;
+ LightWidget *m_green;
+};
+//! [1]
+
+//! [2]
+QState *createLightState(LightWidget *light, int duration, QState *parent = 0)
+{
+ QState *lightState = new QState(parent);
+ QTimer *timer = new QTimer(lightState);
+ timer->setInterval(duration);
+ timer->setSingleShot(true);
+ QState *timing = new QState(lightState);
+ QObject::connect(timing, SIGNAL(entered()), light, SLOT(turnOn()));
+ QObject::connect(timing, SIGNAL(entered()), timer, SLOT(start()));
+ QObject::connect(timing, SIGNAL(exited()), light, SLOT(turnOff()));
+ QFinalState *done = new QFinalState(lightState);
+ timing->addTransition(timer, SIGNAL(timeout()), done);
+ lightState->setInitialState(timing);
+ return lightState;
+}
+//! [2]
+
+//! [3]
+class TrafficLight : public QWidget
+{
+public:
+ TrafficLight(QWidget *parent = 0)
+ : QWidget(parent)
+ {
+ QVBoxLayout *vbox = new QVBoxLayout(this);
+ TrafficLightWidget *widget = new TrafficLightWidget();
+ vbox->addWidget(widget);
+ vbox->setMargin(0);
+
+ QStateMachine *machine = new QStateMachine(this);
+ QState *redGoingYellow = createLightState(widget->redLight(), 3000);
+ redGoingYellow->setObjectName("redGoingYellow");
+ QState *yellowGoingGreen = createLightState(widget->yellowLight(), 1000);
+ yellowGoingGreen->setObjectName("yellowGoingGreen");
+ redGoingYellow->addTransition(redGoingYellow, SIGNAL(finished()), yellowGoingGreen);
+ QState *greenGoingYellow = createLightState(widget->greenLight(), 3000);
+ greenGoingYellow->setObjectName("greenGoingYellow");
+ yellowGoingGreen->addTransition(yellowGoingGreen, SIGNAL(finished()), greenGoingYellow);
+ QState *yellowGoingRed = createLightState(widget->yellowLight(), 1000);
+ yellowGoingRed->setObjectName("yellowGoingRed");
+ greenGoingYellow->addTransition(greenGoingYellow, SIGNAL(finished()), yellowGoingRed);
+ yellowGoingRed->addTransition(yellowGoingRed, SIGNAL(finished()), redGoingYellow);
+
+ machine->addState(redGoingYellow);
+ machine->addState(yellowGoingGreen);
+ machine->addState(greenGoingYellow);
+ machine->addState(yellowGoingRed);
+ machine->setInitialState(redGoingYellow);
+ machine->start();
+ }
+};
+//! [3]
+
+//! [4]
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ TrafficLight widget;
+ widget.resize(110, 300);
+ widget.show();
+
+ return app.exec();
+}
+//! [4]
+
+#include "main.moc"
diff --git a/examples/statemachine/trafficlight/trafficlight.pro b/examples/statemachine/trafficlight/trafficlight.pro
new file mode 100644
index 0000000..684575a
--- /dev/null
+++ b/examples/statemachine/trafficlight/trafficlight.pro
@@ -0,0 +1,7 @@
+SOURCES = main.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/trafficlight
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS trafficlight.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/trafficlight
+INSTALLS += target sources
diff --git a/examples/statemachine/twowaybutton/main.cpp b/examples/statemachine/twowaybutton/main.cpp
new file mode 100644
index 0000000..a2c6e45
--- /dev/null
+++ b/examples/statemachine/twowaybutton/main.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module 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$
+**
+****************************************************************************/
+
+#include <QtGui>
+#ifdef QT_STATEMACHINE_SOLUTION
+#include <qstate.h>
+#include <qstatemachine.h>
+#endif
+
+//! [0]
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QPushButton button;
+ QStateMachine machine;
+//! [0]
+
+//! [1]
+ QState *off = new QState();
+ off->assignProperty(&button, "text", "Off");
+ off->setObjectName("off");
+
+ QState *on = new QState();
+ on->setObjectName("on");
+ on->assignProperty(&button, "text", "On");
+//! [1]
+
+//! [2]
+ off->addTransition(&button, SIGNAL(clicked()), on);
+ on->addTransition(&button, SIGNAL(clicked()), off);
+//! [2]
+
+//! [3]
+ machine.addState(off);
+ machine.addState(on);
+//! [3]
+
+//! [4]
+ machine.setInitialState(off);
+ machine.start();
+//! [4]
+
+//! [5]
+ button.resize(100, 50);
+ button.show();
+ return app.exec();
+}
+//! [5]
diff --git a/examples/statemachine/twowaybutton/twowaybutton.pro b/examples/statemachine/twowaybutton/twowaybutton.pro
new file mode 100644
index 0000000..f6cbc57
--- /dev/null
+++ b/examples/statemachine/twowaybutton/twowaybutton.pro
@@ -0,0 +1,7 @@
+SOURCES = main.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/twowaybutton
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS twowaybutton.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/twowaybutton
+INSTALLS += target sources