summaryrefslogtreecommitdiffstats
path: root/examples/statemachine
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-05-05 14:38:53 (GMT)
committerEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-05-06 00:23:37 (GMT)
commita9fd7d6881107b7e06362076c587530124fb1484 (patch)
treed3ef0aab2514d2925b3f8e6fdffc38842749b603 /examples/statemachine
parent7f3b4bdc97e155f84d5294fa822481b8e16e4fc1 (diff)
downloadQt-a9fd7d6881107b7e06362076c587530124fb1484.zip
Qt-a9fd7d6881107b7e06362076c587530124fb1484.tar.gz
Qt-a9fd7d6881107b7e06362076c587530124fb1484.tar.bz2
Add chase state and ability to detect and fire at other tanks. This reveals an
assert in the state machine which needs to be debugged.
Diffstat (limited to 'examples/statemachine')
-rw-r--r--examples/statemachine/errorstateplugins/seek_ai/seek_ai.cpp6
-rw-r--r--examples/statemachine/errorstateplugins/seek_ai/seek_ai.h90
2 files changed, 92 insertions, 4 deletions
diff --git a/examples/statemachine/errorstateplugins/seek_ai/seek_ai.cpp b/examples/statemachine/errorstateplugins/seek_ai/seek_ai.cpp
index 229f83a..2fb05d4 100644
--- a/examples/statemachine/errorstateplugins/seek_ai/seek_ai.cpp
+++ b/examples/statemachine/errorstateplugins/seek_ai/seek_ai.cpp
@@ -36,6 +36,12 @@ QState *SeekAi::create(QState *parentState, QObject *tank)
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;
}
diff --git a/examples/statemachine/errorstateplugins/seek_ai/seek_ai.h b/examples/statemachine/errorstateplugins/seek_ai/seek_ai.h
index 7d8aa68..34d203e 100644
--- a/examples/statemachine/errorstateplugins/seek_ai/seek_ai.h
+++ b/examples/statemachine/errorstateplugins/seek_ai/seek_ai.h
@@ -4,6 +4,7 @@
#include <errorstate/plugin.h>
#include <QState>
+#include <QFinalState>
#include <QSignalTransition>
#include <QSignalEvent>
#include <QVariant>
@@ -72,7 +73,7 @@ class CollisionTransition: public QSignalTransition
{
public:
CollisionTransition(QObject *tank, QState *turnTo)
- : QSignalTransition(tank, SIGNAL(collision(QLineF)), turnTo),
+ : QSignalTransition(tank, SIGNAL(collision(QLineF))),
m_tank(tank),
m_turnTo(turnTo)
{
@@ -82,16 +83,16 @@ public:
protected:
bool eventTest(QEvent *event) const
{
- if (event->type() == QEvent::Signal) {
+ bool b = QSignalTransition::eventTest(event);
+ if (b) {
QSignalEvent *se = static_cast<QSignalEvent *>(event);
m_lastLine = se->arguments().at(0).toLineF();
}
- return QSignalTransition::eventTest(event);
+ return b;
}
void onTransition(QEvent *)
{
- qreal currentDirection = m_tank->property("direction").toDouble();
qreal angleOfWall = m_lastLine.angle();
qreal newDirection;
@@ -109,6 +110,87 @@ private:
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);
+ connect(fireCannon, SIGNAL(entered()), tank, SLOT(fireCannon()));
+ setInitialState(fireCannon);
+
+ m_goToLocation = new GoToLocationState(this);
+ fireCannon->addTransition(tank, SIGNAL(actionCompleted()), m_goToLocation);
+
+ m_turnToDirection = new QState(this);
+ m_goToLocation->addTransition(tank, SIGNAL(actionCompleted()), m_turnToDirection);
+
+ QFinalState *finalState = new QFinalState(this);
+ 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) const
+ {
+ 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