summaryrefslogtreecommitdiffstats
path: root/examples/statemachine
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-05-05 16:38:53 +0200
committerEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-05-06 02:23:37 +0200
commita9fd7d6881107b7e06362076c587530124fb1484 (patch)
treed3ef0aab2514d2925b3f8e6fdffc38842749b603 /examples/statemachine
parent7f3b4bdc97e155f84d5294fa822481b8e16e4fc1 (diff)
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 229f83a372..2fb05d431c 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 7d8aa68f1b..34d203ed5e 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