summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/animation/appchooser/main.cpp18
-rw-r--r--examples/animation/moveblocks/main.cpp6
-rw-r--r--examples/animation/sub-attaq/boat_p.h12
-rw-r--r--examples/animation/sub-attaq/qanimationstate.cpp4
-rw-r--r--examples/animation/sub-attaq/qanimationstate.h4
-rw-r--r--examples/animation/sub-attaq/states.cpp16
-rw-r--r--examples/animation/sub-attaq/states.h14
-rw-r--r--examples/animation/sub-attaq/submarine_p.h12
-rw-r--r--examples/statemachine/clockticking/main.cpp6
-rw-r--r--examples/statemachine/errorstate/errorstate.pro2
-rw-r--r--examples/statemachine/errorstate/gameitem.cpp29
-rw-r--r--examples/statemachine/errorstate/gameitem.h9
-rw-r--r--examples/statemachine/errorstate/mainwindow.cpp29
-rw-r--r--examples/statemachine/errorstate/plugin.h5
-rw-r--r--examples/statemachine/errorstate/rocketitem.cpp16
-rw-r--r--examples/statemachine/errorstate/rocketitem.h6
-rw-r--r--examples/statemachine/errorstate/tank.h31
-rw-r--r--examples/statemachine/errorstate/tankitem.cpp94
-rw-r--r--examples/statemachine/errorstate/tankitem.h38
-rw-r--r--examples/statemachine/errorstateplugins/errorstateplugins.pro11
-rw-r--r--examples/statemachine/errorstateplugins/random_ai/random_ai_plugin.cpp4
-rw-r--r--examples/statemachine/errorstateplugins/random_ai/random_ai_plugin.h6
-rw-r--r--examples/statemachine/errorstateplugins/seek_ai/seek_ai.cpp48
-rw-r--r--examples/statemachine/errorstateplugins/seek_ai/seek_ai.h202
-rw-r--r--examples/statemachine/errorstateplugins/seek_ai/seek_ai.pro13
-rw-r--r--examples/statemachine/errorstateplugins/spin_ai/spin_ai.cpp29
-rw-r--r--examples/statemachine/errorstateplugins/spin_ai/spin_ai.h44
-rw-r--r--examples/statemachine/errorstateplugins/spin_ai/spin_ai.pro13
-rw-r--r--examples/statemachine/errorstateplugins/spin_ai_with_error/spin_ai_with_error.cpp29
-rw-r--r--examples/statemachine/errorstateplugins/spin_ai_with_error/spin_ai_with_error.h44
-rw-r--r--examples/statemachine/errorstateplugins/spin_ai_with_error/spin_ai_with_error.pro13
-rw-r--r--examples/statemachine/factorial/main.cpp4
-rw-r--r--examples/statemachine/helloworld/main.cpp2
-rw-r--r--examples/statemachine/pingpong/main.cpp6
-rw-r--r--examples/statemachine/trafficlight/main.cpp3
35 files changed, 668 insertions, 154 deletions
diff --git a/examples/animation/appchooser/main.cpp b/examples/animation/appchooser/main.cpp
index 02302d9..1c63aba 100644
--- a/examples/animation/appchooser/main.cpp
+++ b/examples/animation/appchooser/main.cpp
@@ -90,15 +90,16 @@ void createStates(const QObjectList &objects,
for (int i = 0; i < objects.size(); ++i) {
QState *state = new QState(parent);
state->assignProperty(objects.at(i), "geometry", selectedRect);
- QAbstractTransition *trans = parent->addTransition(objects.at(i), SIGNAL(clicked()), state);
- for (int j = 0; j < objects.size(); ++j) {
- QPropertyAnimation *animation = new QPropertyAnimation(objects.at(j), "geometry");
- animation->setDuration(2000);
- trans->addAnimation(animation);
- }
+ parent->addTransition(objects.at(i), SIGNAL(clicked()), state);
}
}
+void createAnimations(const QObjectList &objects, QStateMachine *machine)
+{
+ for (int i=0; i<objects.size(); ++i)
+ machine->addDefaultAnimation(new QPropertyAnimation(objects.at(i), "geometry"));
+}
+
int main(int argc, char **argv)
{
Q_INIT_RESOURCE(appchooser);
@@ -143,7 +144,10 @@ int main(int argc, char **argv)
QState *idleState = new QState(group);
group->setInitialState(idleState);
- createStates(QObjectList() << p1 << p2 << p3 << p4, selectedRect, group);
+ QObjectList objects;
+ objects << p1 << p2 << p3 << p4;
+ createStates(objects, selectedRect, group);
+ createAnimations(objects, &machine);
machine.setInitialState(group);
machine.start();
diff --git a/examples/animation/moveblocks/main.cpp b/examples/animation/moveblocks/main.cpp
index eb23bd5..06ed3dd 100644
--- a/examples/animation/moveblocks/main.cpp
+++ b/examples/animation/moveblocks/main.cpp
@@ -101,7 +101,7 @@ protected:
&& (static_cast<StateSwitchEvent *>(event)->rand() == m_rand);
}
- virtual void onTransition() {}
+ virtual void onTransition(QEvent *) {}
private:
int m_rand;
@@ -116,7 +116,7 @@ public:
m_stateCount(0), m_lastIndex(0)
{ }
- virtual void onEntry()
+ virtual void onEntry(QEvent *)
{
int n;
while ((n = (qrand() % m_stateCount + 1)) == m_lastIndex)
@@ -124,7 +124,7 @@ public:
m_lastIndex = n;
m_machine->postEvent(new StateSwitchEvent(n));
}
- virtual void onExit() {}
+ virtual void onExit(QEvent *) {}
void addState(QState *state, QAbstractAnimation *animation) {
StateSwitchTransition *trans = new StateSwitchTransition(++m_stateCount);
diff --git a/examples/animation/sub-attaq/boat_p.h b/examples/animation/sub-attaq/boat_p.h
index 855b10f..17fbe5c 100644
--- a/examples/animation/sub-attaq/boat_p.h
+++ b/examples/animation/sub-attaq/boat_p.h
@@ -104,7 +104,7 @@ protected:
return false;
}
- void onTransition()
+ void onTransition(QEvent *)
{
//We decrease the speed if needed
if (key == Qt::Key_Left && boat->currentDirection() == Boat::Right)
@@ -156,7 +156,7 @@ public:
this->boat = boat;
}
protected:
- void onEntry()
+ void onEntry(QEvent *)
{
boat->setCurrentDirection(Boat::Right);
boat->updateBoatMovement();
@@ -174,7 +174,7 @@ public:
this->boat = boat;
}
protected:
- void onEntry()
+ void onEntry(QEvent *)
{
boat->setCurrentDirection(Boat::Left);
boat->updateBoatMovement();
@@ -192,7 +192,7 @@ public:
this->boat = boat;
}
protected:
- void onEntry()
+ void onEntry(QEvent *)
{
boat->setCurrentSpeed(0);
boat->setCurrentDirection(Boat::None);
@@ -211,7 +211,7 @@ public:
this->boat = boat;
}
protected:
- void onEntry()
+ void onEntry(QEvent *)
{
Bomb *b = new Bomb();
b->setPos(boat->x()+boat->size().width(),boat->y());
@@ -233,7 +233,7 @@ public:
this->boat = boat;
}
protected:
- void onEntry()
+ void onEntry(QEvent *)
{
Bomb *b = new Bomb();
b->setPos(boat->x() - b->size().width(), boat->y());
diff --git a/examples/animation/sub-attaq/qanimationstate.cpp b/examples/animation/sub-attaq/qanimationstate.cpp
index 3659657..0f30ac2 100644
--- a/examples/animation/sub-attaq/qanimationstate.cpp
+++ b/examples/animation/sub-attaq/qanimationstate.cpp
@@ -146,7 +146,7 @@ QAbstractAnimation* QAnimationState::animation() const
/*!
\reimp
*/
-void QAnimationState::onEntry()
+void QAnimationState::onEntry(QEvent *)
{
Q_D(QAnimationState);
if (d->animation)
@@ -156,7 +156,7 @@ void QAnimationState::onEntry()
/*!
\reimp
*/
-void QAnimationState::onExit()
+void QAnimationState::onExit(QEvent *)
{
Q_D(QAnimationState);
if (d->animation)
diff --git a/examples/animation/sub-attaq/qanimationstate.h b/examples/animation/sub-attaq/qanimationstate.h
index ddf5681..88c0a6d 100644
--- a/examples/animation/sub-attaq/qanimationstate.h
+++ b/examples/animation/sub-attaq/qanimationstate.h
@@ -74,8 +74,8 @@ Q_SIGNALS:
void animationFinished();
protected:
- void onEntry();
- void onExit();
+ void onEntry(QEvent *);
+ void onExit(QEvent *);
bool event(QEvent *e);
private:
diff --git a/examples/animation/sub-attaq/states.cpp b/examples/animation/sub-attaq/states.cpp
index 0b98016..c6af924 100644
--- a/examples/animation/sub-attaq/states.cpp
+++ b/examples/animation/sub-attaq/states.cpp
@@ -76,7 +76,7 @@ PlayState::~PlayState()
{
}
-void PlayState::onEntry()
+void PlayState::onEntry(QEvent *)
{
//We are now playing?
if (machine) {
@@ -159,7 +159,7 @@ void PlayState::onEntry()
LevelState::LevelState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game)
{
}
-void LevelState::onEntry()
+void LevelState::onEntry(QEvent *)
{
initializeLevel();
}
@@ -202,12 +202,12 @@ void LevelState::initializeLevel()
PauseState::PauseState(GraphicsScene *scene, QState *parent) : QState(parent),scene(scene)
{
}
-void PauseState::onEntry()
+void PauseState::onEntry(QEvent *)
{
AnimationManager::self()->pauseAll();
scene->boat->setEnabled(false);
}
-void PauseState::onExit()
+void PauseState::onExit(QEvent *)
{
AnimationManager::self()->resumeAll();
scene->boat->setEnabled(true);
@@ -219,7 +219,7 @@ LostState::LostState(GraphicsScene *scene, PlayState *game, QState *parent) : QS
{
}
-void LostState::onEntry()
+void LostState::onEntry(QEvent *)
{
//The message to display
QString message = QString("You lose on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score);
@@ -242,7 +242,7 @@ WinState::WinState(GraphicsScene *scene, PlayState *game, QState *parent) : QSta
{
}
-void WinState::onEntry()
+void WinState::onEntry(QEvent *)
{
//We clear the scene
scene->clearScene();
@@ -269,9 +269,9 @@ UpdateScoreState::UpdateScoreState(PlayState *game, QState *parent) : QState(par
{
this->game = game;
}
-void UpdateScoreState::onEntry()
+void UpdateScoreState::onEntry(QEvent *e)
{
- QState::onEntry();
+ QState::onEntry(e);
}
/** Win transition */
diff --git a/examples/animation/sub-attaq/states.h b/examples/animation/sub-attaq/states.h
index ec69ae7..27beb71 100644
--- a/examples/animation/sub-attaq/states.h
+++ b/examples/animation/sub-attaq/states.h
@@ -68,7 +68,7 @@ public:
~PlayState();
protected:
- void onEntry();
+ void onEntry(QEvent *);
private :
GraphicsScene *scene;
@@ -91,7 +91,7 @@ class LevelState : public QState
public:
LevelState(GraphicsScene *scene, PlayState *game, QState *parent = 0);
protected:
- void onEntry();
+ void onEntry(QEvent *);
private :
void initializeLevel();
GraphicsScene *scene;
@@ -104,8 +104,8 @@ public:
PauseState(GraphicsScene *scene, QState *parent = 0);
protected:
- void onEntry();
- void onExit();
+ void onEntry(QEvent *);
+ void onExit(QEvent *);
private :
GraphicsScene *scene;
Boat *boat;
@@ -117,7 +117,7 @@ public:
LostState(GraphicsScene *scene, PlayState *game, QState *parent = 0);
protected:
- void onEntry();
+ void onEntry(QEvent *);
private :
GraphicsScene *scene;
PlayState *game;
@@ -129,7 +129,7 @@ public:
WinState(GraphicsScene *scene, PlayState *game, QState *parent = 0);
protected:
- void onEntry();
+ void onEntry(QEvent *);
private :
GraphicsScene *scene;
PlayState *game;
@@ -140,7 +140,7 @@ class UpdateScoreState : public QState
public:
UpdateScoreState(PlayState *game, QState *parent);
protected:
- void onEntry();
+ void onEntry(QEvent *);
private:
QPropertyAnimation *scoreAnimation;
PlayState *game;
diff --git a/examples/animation/sub-attaq/submarine_p.h b/examples/animation/sub-attaq/submarine_p.h
index 918e7f5..c76d991 100644
--- a/examples/animation/sub-attaq/submarine_p.h
+++ b/examples/animation/sub-attaq/submarine_p.h
@@ -77,7 +77,7 @@ protected slots:
}
protected:
- void onEntry()
+ void onEntry(QEvent *e)
{
if (submarine->currentDirection() == SubMarine::Left) {
movementAnimation->setEndValue(QPointF(0,submarine->y()));
@@ -88,7 +88,7 @@ protected:
movementAnimation->setDuration((submarine->scene()->width()-submarine->size().width()-submarine->x())/submarine->currentSpeed()*12);
}
movementAnimation->setStartValue(submarine->pos());
- QAnimationState::onEntry();
+ QAnimationState::onEntry(e);
}
private:
@@ -109,19 +109,19 @@ public:
}
protected:
- void onEntry()
+ void onEntry(QEvent *e)
{
returnAnimation->stop();
returnAnimation->setStartValue(submarine->yRotation());
returnAnimation->setEndValue(submarine->currentDirection() == SubMarine::Right ? 360. : 180.);
returnAnimation->setDuration(500);
- QAnimationState::onEntry();
+ QAnimationState::onEntry(e);
}
- void onExit()
+ void onExit(QEvent *e)
{
submarine->currentDirection() == SubMarine::Right ? submarine->setCurrentDirection(SubMarine::Left) : submarine->setCurrentDirection(SubMarine::Right);
- QAnimationState::onExit();
+ QAnimationState::onExit(e);
}
private:
diff --git a/examples/statemachine/clockticking/main.cpp b/examples/statemachine/clockticking/main.cpp
index 9b54f29..ea8e692 100644
--- a/examples/statemachine/clockticking/main.cpp
+++ b/examples/statemachine/clockticking/main.cpp
@@ -61,7 +61,7 @@ public:
: QState(parent) {}
protected:
- virtual void onEntry()
+ virtual void onEntry(QEvent *)
{
fprintf(stdout, "ClockState entered; posting the initial tick\n");
machine()->postEvent(new ClockEvent());
@@ -77,7 +77,7 @@ protected:
virtual bool eventTest(QEvent *e) const {
return (e->type() == QEvent::User+2);
}
- virtual void onTransition()
+ virtual void onTransition(QEvent *)
{
fprintf(stdout, "ClockTransition triggered; posting another tick with a delay of 1 second\n");
machine()->postEvent(new ClockEvent(), 1000);
@@ -93,7 +93,7 @@ protected:
virtual bool eventTest(QEvent *e) const {
return (e->type() == QEvent::User+2);
}
- virtual void onTransition()
+ virtual void onTransition(QEvent *)
{
fprintf(stdout, "ClockListener heard a tick!\n");
}
diff --git a/examples/statemachine/errorstate/errorstate.pro b/examples/statemachine/errorstate/errorstate.pro
index c159f94..b93a691 100644
--- a/examples/statemachine/errorstate/errorstate.pro
+++ b/examples/statemachine/errorstate/errorstate.pro
@@ -8,6 +8,6 @@ DEPENDPATH += .
INCLUDEPATH += C:/dev/kinetic/examples/statemachine/errorstate/. .
# Input
-HEADERS += mainwindow.h plugin.h tank.h tankitem.h rocketitem.h gameitem.h
+HEADERS += mainwindow.h plugin.h tankitem.h rocketitem.h gameitem.h
SOURCES += main.cpp mainwindow.cpp tankitem.cpp rocketitem.cpp gameitem.cpp
CONFIG += console
diff --git a/examples/statemachine/errorstate/gameitem.cpp b/examples/statemachine/errorstate/gameitem.cpp
index 786cf51..1a2af71 100644
--- a/examples/statemachine/errorstate/gameitem.cpp
+++ b/examples/statemachine/errorstate/gameitem.cpp
@@ -1,6 +1,11 @@
#include "gameitem.h"
#include <QGraphicsScene>
+#include <QDebug>
+
+GameItem::GameItem(QObject *parent) : QObject(parent)
+{
+}
QPointF GameItem::tryMove(const QPointF &requestedPosition, QLineF *collidedLine,
QGraphicsItem **collidedItem) const
@@ -52,15 +57,31 @@ QPointF GameItem::tryMove(const QPointF &requestedPosition, QLineF *collidedLine
}
}
+
// Don't go outside of map
- if (nextPoint.x() < sceneRect.left())
+ if (nextPoint.x() < sceneRect.left()) {
nextPoint.rx() = sceneRect.left();
- if (nextPoint.x() > sceneRect.right())
+ if (collidedLine != 0)
+ *collidedLine = QLineF(scene()->sceneRect().topLeft(), scene()->sceneRect().bottomLeft());
+ }
+
+ if (nextPoint.x() > sceneRect.right()) {
nextPoint.rx() = sceneRect.right();
- if (nextPoint.y() < sceneRect.top())
+ if (collidedLine != 0)
+ *collidedLine = QLineF(scene()->sceneRect().topRight(), scene()->sceneRect().bottomRight());
+ }
+
+ if (nextPoint.y() < sceneRect.top()) {
nextPoint.ry() = sceneRect.top();
- if (nextPoint.y() > sceneRect.bottom())
+ 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/errorstate/gameitem.h b/examples/statemachine/errorstate/gameitem.h
index 6ca32b7..43b8785 100644
--- a/examples/statemachine/errorstate/gameitem.h
+++ b/examples/statemachine/errorstate/gameitem.h
@@ -4,15 +4,16 @@
#include <QGraphicsItem>
class QLineF;
-class GameItem: public QGraphicsItem
+class GameItem: public QObject, public QGraphicsItem
{
+ Q_OBJECT
public:
enum { Type = UserType + 1 };
-
int type() const { return Type; }
- virtual void idle(qreal elapsed) = 0;
- virtual void hitByRocket() = 0;
+ GameItem(QObject *parent = 0);
+
+ virtual void idle(qreal elapsed) = 0;
protected:
QPointF tryMove(const QPointF &requestedPosition, QLineF *collidedLine = 0,
diff --git a/examples/statemachine/errorstate/mainwindow.cpp b/examples/statemachine/errorstate/mainwindow.cpp
index e04ca94..39b8663 100644
--- a/examples/statemachine/errorstate/mainwindow.cpp
+++ b/examples/statemachine/errorstate/mainwindow.cpp
@@ -88,23 +88,25 @@ void MainWindow::init()
}
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, 0.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, 0.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(0.0, sceneRect.height() / 2.0 - 5.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(0.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");
@@ -112,9 +114,7 @@ void MainWindow::init()
connect(addTankAction, SIGNAL(triggered()), this, SLOT(addTank()));
connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
- m_machine = new QStateMachine(this);
- m_machine->setGlobalRestorePolicy(QStateMachine::RestoreProperties);
-
+ m_machine = new QStateMachine(this);
QState *stoppedState = new QState(m_machine->rootState());
stoppedState->setObjectName("stoppedState");
stoppedState->assignProperty(runGameAction, "enabled", true);
@@ -168,8 +168,7 @@ void MainWindow::runStep()
qreal elapsedSecs = elapsed / 1000.0;
QList<QGraphicsItem *> items = m_scene->items();
foreach (QGraphicsItem *item, items) {
- GameItem *gameItem = qgraphicsitem_cast<GameItem *>(item);
- if (gameItem != 0)
+ if (GameItem *gameItem = qgraphicsitem_cast<GameItem *>(item))
gameItem->idle(elapsedSecs);
}
}
@@ -201,12 +200,18 @@ void MainWindow::addTank()
if (plugin != 0) {
TankItem *tankItem = m_spawns.takeLast();
m_scene->addItem(tankItem);
- connect(tankItem, SIGNAL(fireCannon()), this, SLOT(addRocket()));
+ connect(tankItem, SIGNAL(cannonFired()), this, SLOT(addRocket()));
if (m_spawns.isEmpty())
emit mapFull();
QState *region = new QState(m_runningState);
- region->setInitialState(plugin->create(region, tankItem));
+ QState *pluginState = plugin->create(region, tankItem);
+ region->setInitialState(pluginState);
+
+ // If the plugin has an error it is disabled
+ QState *errorState = new QState(region);
+ errorState->assignProperty(tankItem, "enabled", false);
+ pluginState->setErrorState(errorState);
}
}
diff --git a/examples/statemachine/errorstate/plugin.h b/examples/statemachine/errorstate/plugin.h
index 1ac7e0f..2b48d43 100644
--- a/examples/statemachine/errorstate/plugin.h
+++ b/examples/statemachine/errorstate/plugin.h
@@ -1,14 +1,15 @@
#ifndef PLUGIN_H
#define PLUGIN_H
+#include <QtPlugin>
+
class QState;
-class Tank;
class Plugin
{
public:
virtual ~Plugin() {}
- virtual QState *create(QState *parentState, Tank *tank) = 0;
+ virtual QState *create(QState *parentState, QObject *tank) = 0;
};
Q_DECLARE_INTERFACE(Plugin, "TankPlugin")
diff --git a/examples/statemachine/errorstate/rocketitem.cpp b/examples/statemachine/errorstate/rocketitem.cpp
index de9eef7..c324980 100644
--- a/examples/statemachine/errorstate/rocketitem.cpp
+++ b/examples/statemachine/errorstate/rocketitem.cpp
@@ -1,4 +1,5 @@
#include "rocketitem.h"
+#include "tankitem.h"
#include <QPainter>
#include <QGraphicsScene>
@@ -9,8 +10,8 @@
#define M_PI 3.14159265358979323846
#endif
-RocketItem::RocketItem()
- : m_direction(0.0), m_distance(300.0)
+RocketItem::RocketItem(QObject *parent)
+ : GameItem(parent), m_direction(0.0), m_distance(300.0)
{
}
@@ -25,10 +26,6 @@ void RocketItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWid
painter->drawEllipse(boundingRect());
}
-void RocketItem::hitByRocket()
-{
-}
-
void RocketItem::idle(qreal elapsed)
{
qreal dist = elapsed * speed();
@@ -51,8 +48,11 @@ void RocketItem::idle(qreal elapsed)
if (requestedPosition == nextPosition) {
setPos(nextPosition);
} else {
- if (GameItem *gameItem = qgraphicsitem_cast<GameItem *>(collidedItem))
- gameItem->hitByRocket();
+ 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/errorstate/rocketitem.h b/examples/statemachine/errorstate/rocketitem.h
index 9805a8a..189a1dd 100644
--- a/examples/statemachine/errorstate/rocketitem.h
+++ b/examples/statemachine/errorstate/rocketitem.h
@@ -5,20 +5,18 @@
class RocketItem: public GameItem
{
+ Q_OBJECT
public:
- RocketItem();
+ RocketItem(QObject *parent = 0);
virtual void idle(qreal elapsed);
qreal speed() const { return 100.0; }
void setDirection(qreal direction) { m_direction = direction; }
-
- void hitByRocket();
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QRectF boundingRect() const;
-
private:
qreal m_direction;
qreal m_distance;
diff --git a/examples/statemachine/errorstate/tank.h b/examples/statemachine/errorstate/tank.h
deleted file mode 100644
index 49c5daf..0000000
--- a/examples/statemachine/errorstate/tank.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef TANK_H
-#define TANK_H
-
-#include <QObject>
-#include <QLineF>
-
-class Tank: public QObject
-{
- Q_OBJECT
- Q_PROPERTY(qreal direction READ direction)
- Q_PROPERTY(qreal distanceToObstacle READ distanceToObstacle)
-public:
- Tank(QObject *parent = 0) : QObject(parent) {}
-
- virtual qreal direction() const = 0;
- virtual qreal distanceToObstacle() const = 0;
-
-signals:
- void collision(const QLineF &collidedLine) const;
- void actionCompleted();
- void tankSpotted(qreal otherTankDirection, qreal distance);
-
-public slots:
- virtual void moveForwards(qreal length) = 0;
- virtual void moveBackwards(qreal length) = 0;
- virtual void turn(qreal degrees) = 0;
- virtual void stop() = 0;
- virtual void fireCannon() = 0;
-};
-
-#endif
diff --git a/examples/statemachine/errorstate/tankitem.cpp b/examples/statemachine/errorstate/tankitem.cpp
index 814de2b..5506a7e 100644
--- a/examples/statemachine/errorstate/tankitem.cpp
+++ b/examples/statemachine/errorstate/tankitem.cpp
@@ -2,6 +2,7 @@
#include <QPainter>
#include <QGraphicsScene>
+#include <QDebug>
#include <math.h>
@@ -38,11 +39,12 @@ public:
{
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;
- if (m_reverse && m_distance > 0.0)
- return false;
- else if (m_distance < 0.0)
- return false;
qreal a = item()->direction() * M_PI / 180.0;
@@ -50,7 +52,7 @@ public:
qreal xd = dist * sin(M_PI / 2.0 - a);
item()->setPos(item()->pos() + QPointF(xd, yd));
- return true;
+ return !done;
}
private:
@@ -70,14 +72,15 @@ public:
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;
- if (m_reverse && m_distance > 0.0)
- return false;
- else if (m_distance < 0.0)
- return false;
item()->setDirection(item()->direction() + dist);
- return true;
+ return !done;
}
private:
@@ -85,17 +88,25 @@ private:
bool m_reverse;
};
-TankItem::TankItem(QObject *parent) : Tank(parent), m_currentAction(0), m_currentDirection(0.0)
+TankItem::TankItem(QObject *parent)
+ : GameItem(parent), m_currentAction(0), m_currentDirection(0.0), m_enabled(true)
{
- connect(this, SIGNAL(fireCannon()), this, SIGNAL(actionCompleted()));
+ connect(this, SIGNAL(cannonFired()), this, SIGNAL(actionCompleted()));
}
void TankItem::idle(qreal elapsed)
{
- if (m_currentAction != 0) {
- if (!m_currentAction->apply(elapsed)) {
- setAction(0);
- emit actionCompleted();
+ 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);
}
}
}
@@ -113,6 +124,11 @@ void TankItem::setAction(Action *newAction)
m_currentAction = newAction;
}
+void TankItem::fireCannon()
+{
+ emit cannonFired();
+}
+
void TankItem::moveForwards(qreal length)
{
setAction(new MoveAction(this, length));
@@ -128,6 +144,11 @@ 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);
@@ -176,6 +197,17 @@ void TankItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidge
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
@@ -190,16 +222,40 @@ qreal TankItem::direction() const
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() const
+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;
+ }
+}
- return 0.0;
+qreal TankItem::distanceToObstacle() const
+{
+ return distanceToObstacle(0);
}
diff --git a/examples/statemachine/errorstate/tankitem.h b/examples/statemachine/errorstate/tankitem.h
index c9e0d22..cefed69 100644
--- a/examples/statemachine/errorstate/tankitem.h
+++ b/examples/statemachine/errorstate/tankitem.h
@@ -1,25 +1,20 @@
#ifndef TANKITEM_H
#define TANKITEM_H
-#include "tank.h"
#include "gameitem.h"
#include <QColor>
class Action;
-class TankItem: public Tank, public GameItem
+class TankItem: public GameItem
{
Q_OBJECT
-public:
+ 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);
-
- virtual void moveForwards(qreal length);
- virtual void moveBackwards(qreal length);
- virtual void turn(qreal newDirection);
- virtual void stop();
- virtual qreal direction() const;
- virtual qreal distanceToObstacle() const;
-
+
void setColor(const QColor &color) { m_color = color; }
QColor color() const { return m_color; }
@@ -33,8 +28,26 @@ public:
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;
+
signals:
- virtual void fireCannon();
+ void tankSpotted(qreal direction, qreal distance);
+ void collision(const QLineF &collidedLine);
+ void actionCompleted();
+ void cannonFired();
+
+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();
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
@@ -46,6 +59,7 @@ private:
Action *m_currentAction;
qreal m_currentDirection;
QColor m_color;
+ bool m_enabled;
};
#endif
diff --git a/examples/statemachine/errorstateplugins/errorstateplugins.pro b/examples/statemachine/errorstateplugins/errorstateplugins.pro
new file mode 100644
index 0000000..5b6b758
--- /dev/null
+++ b/examples/statemachine/errorstateplugins/errorstateplugins.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/errorstateplugins
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS errorstateplugins.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/errorstateplugins
+INSTALLS += target sources
diff --git a/examples/statemachine/errorstateplugins/random_ai/random_ai_plugin.cpp b/examples/statemachine/errorstateplugins/random_ai/random_ai_plugin.cpp
index 135c7b6..c196247 100644
--- a/examples/statemachine/errorstateplugins/random_ai/random_ai_plugin.cpp
+++ b/examples/statemachine/errorstateplugins/random_ai/random_ai_plugin.cpp
@@ -1,13 +1,11 @@
#include "random_ai_plugin.h"
-#include <errorstate/tank.h>
-
#include <QState>
#include <QtPlugin>
#include <time.h>
-QState *RandomAiPlugin::create(QState *parentState, Tank *tank)
+QState *RandomAiPlugin::create(QState *parentState, QObject *tank)
{
qsrand(uint(time(NULL)));
diff --git a/examples/statemachine/errorstateplugins/random_ai/random_ai_plugin.h b/examples/statemachine/errorstateplugins/random_ai/random_ai_plugin.h
index 758b3e8..3db464b 100644
--- a/examples/statemachine/errorstateplugins/random_ai/random_ai_plugin.h
+++ b/examples/statemachine/errorstateplugins/random_ai/random_ai_plugin.h
@@ -21,7 +21,7 @@ signals:
void turnSelected();
protected:
- void onEntry()
+ void onEntry(QEvent *)
{
int rand = qrand() % 4;
switch (rand) {
@@ -45,7 +45,7 @@ signals:
void distanceComputed(qreal distance);
protected:
- void onEntry()
+ void onEntry(QEvent *)
{
emit distanceComputed(qreal(qrand() % 180));
}
@@ -56,7 +56,7 @@ class RandomAiPlugin: public QObject, public Plugin
Q_OBJECT
Q_INTERFACES(Plugin)
public:
- virtual QState *create(QState *parentState, Tank *tank);
+ virtual QState *create(QState *parentState, QObject *tank);
};
#endif // RANDOM_AI_PLUGIN_H
diff --git a/examples/statemachine/errorstateplugins/seek_ai/seek_ai.cpp b/examples/statemachine/errorstateplugins/seek_ai/seek_ai.cpp
new file mode 100644
index 0000000..2fb05d4
--- /dev/null
+++ b/examples/statemachine/errorstateplugins/seek_ai/seek_ai.cpp
@@ -0,0 +1,48 @@
+#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/errorstateplugins/seek_ai/seek_ai.h b/examples/statemachine/errorstateplugins/seek_ai/seek_ai.h
new file mode 100644
index 0000000..34d203e
--- /dev/null
+++ b/examples/statemachine/errorstateplugins/seek_ai/seek_ai.h
@@ -0,0 +1,202 @@
+#ifndef SEEK_AI_H
+#define SEEK_AI_H
+
+#include <errorstate/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) const
+ {
+ 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:
+ mutable 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);
+ 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
+ Q_INTERFACES(Plugin)
+public:
+ virtual QState *create(QState *parentState, QObject *tank);
+};
+
+#endif
diff --git a/examples/statemachine/errorstateplugins/seek_ai/seek_ai.pro b/examples/statemachine/errorstateplugins/seek_ai/seek_ai.pro
new file mode 100644
index 0000000..11bd242
--- /dev/null
+++ b/examples/statemachine/errorstateplugins/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 = ../../errorstate/plugins
+
+#! [0]
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/errorstate/plugins
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS seek_ai.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/errorstateplugins/seek_ai \ No newline at end of file
diff --git a/examples/statemachine/errorstateplugins/spin_ai/spin_ai.cpp b/examples/statemachine/errorstateplugins/spin_ai/spin_ai.cpp
new file mode 100644
index 0000000..de95f41
--- /dev/null
+++ b/examples/statemachine/errorstateplugins/spin_ai/spin_ai.cpp
@@ -0,0 +1,29 @@
+#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/errorstateplugins/spin_ai/spin_ai.h b/examples/statemachine/errorstateplugins/spin_ai/spin_ai.h
new file mode 100644
index 0000000..4b4629c
--- /dev/null
+++ b/examples/statemachine/errorstateplugins/spin_ai/spin_ai.h
@@ -0,0 +1,44 @@
+#ifndef SPIN_AI_H
+#define SPIN_AI_H
+
+#include <errorstate/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", 90.0);
+ }
+
+protected:
+ void onEntry(QEvent *)
+ {
+ connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin()));
+ spin();
+ }
+
+private:
+ QObject *m_tank;
+
+};
+
+class SpinAi: public QObject, public Plugin
+{
+ Q_OBJECT
+ Q_INTERFACES(Plugin)
+public:
+ virtual QState *create(QState *parentState, QObject *tank);
+};
+
+#endif
diff --git a/examples/statemachine/errorstateplugins/spin_ai/spin_ai.pro b/examples/statemachine/errorstateplugins/spin_ai/spin_ai.pro
new file mode 100644
index 0000000..c2fd937
--- /dev/null
+++ b/examples/statemachine/errorstateplugins/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 = ../../errorstate/plugins
+
+#! [0]
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/errorstate/plugins
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS spin_ai.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/errorstateplugins/spin_ai \ No newline at end of file
diff --git a/examples/statemachine/errorstateplugins/spin_ai_with_error/spin_ai_with_error.cpp b/examples/statemachine/errorstateplugins/spin_ai_with_error/spin_ai_with_error.cpp
new file mode 100644
index 0000000..5499ba3
--- /dev/null
+++ b/examples/statemachine/errorstateplugins/spin_ai_with_error/spin_ai_with_error.cpp
@@ -0,0 +1,29 @@
+#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/errorstateplugins/spin_ai_with_error/spin_ai_with_error.h b/examples/statemachine/errorstateplugins/spin_ai_with_error/spin_ai_with_error.h
new file mode 100644
index 0000000..9a96a8b
--- /dev/null
+++ b/examples/statemachine/errorstateplugins/spin_ai_with_error/spin_ai_with_error.h
@@ -0,0 +1,44 @@
+#ifndef SPIN_AI_WITH_ERROR_H
+#define SPIN_AI_WITH_ERROR_H
+
+#include <errorstate/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", 90.0);
+ }
+
+protected:
+ void onEntry(QEvent *)
+ {
+ connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin()));
+ spin();
+ }
+
+private:
+ QObject *m_tank;
+
+};
+
+class SpinAiWithError: public QObject, public Plugin
+{
+ Q_OBJECT
+ Q_INTERFACES(Plugin)
+public:
+ virtual QState *create(QState *parentState, QObject *tank);
+};
+
+#endif
diff --git a/examples/statemachine/errorstateplugins/spin_ai_with_error/spin_ai_with_error.pro b/examples/statemachine/errorstateplugins/spin_ai_with_error/spin_ai_with_error.pro
new file mode 100644
index 0000000..31f4c7f
--- /dev/null
+++ b/examples/statemachine/errorstateplugins/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 = ../../errorstate/plugins
+
+#! [0]
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/errorstate/plugins
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS spin_ai_with_error.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/errorstateplugins/spin_ai_with_error \ No newline at end of file
diff --git a/examples/statemachine/factorial/main.cpp b/examples/statemachine/factorial/main.cpp
index 9e39ced..2b63690 100644
--- a/examples/statemachine/factorial/main.cpp
+++ b/examples/statemachine/factorial/main.cpp
@@ -104,7 +104,7 @@ public:
return m_fact->property("x").toInt() > 1;
}
- virtual void onTransition()
+ virtual void onTransition(QEvent *)
{
int x = m_fact->property("x").toInt();
int fac = m_fact->property("fac").toInt();
@@ -128,7 +128,7 @@ public:
return m_fact->property("x").toInt() <= 1;
}
- virtual void onTransition()
+ virtual void onTransition(QEvent *)
{
fprintf(stdout, "%d\n", m_fact->property("fac").toInt());
}
diff --git a/examples/statemachine/helloworld/main.cpp b/examples/statemachine/helloworld/main.cpp
index 13486d4..fbe34b5 100644
--- a/examples/statemachine/helloworld/main.cpp
+++ b/examples/statemachine/helloworld/main.cpp
@@ -52,7 +52,7 @@ public:
S0(QState *parent = 0)
: QState(parent) {}
- virtual void onEntry()
+ virtual void onEntry(QEvent *)
{
fprintf(stdout, "Hello world!\n");
}
diff --git a/examples/statemachine/pingpong/main.cpp b/examples/statemachine/pingpong/main.cpp
index 68f7115..eb8fd5d 100644
--- a/examples/statemachine/pingpong/main.cpp
+++ b/examples/statemachine/pingpong/main.cpp
@@ -68,7 +68,7 @@ public:
: QState(parent) {}
protected:
- virtual void onEntry()
+ virtual void onEntry(QEvent *)
{
machine()->postEvent(new PingEvent());
fprintf(stdout, "ping?\n");
@@ -84,7 +84,7 @@ protected:
virtual bool eventTest(QEvent *e) const {
return (e->type() == QEvent::User+3);
}
- virtual void onTransition()
+ virtual void onTransition(QEvent *)
{
machine()->postEvent(new PingEvent(), 500);
fprintf(stdout, "ping?\n");
@@ -100,7 +100,7 @@ protected:
virtual bool eventTest(QEvent *e) const {
return (e->type() == QEvent::User+2);
}
- virtual void onTransition()
+ virtual void onTransition(QEvent *)
{
machine()->postEvent(new PongEvent(), 500);
fprintf(stdout, "pong!\n");
diff --git a/examples/statemachine/trafficlight/main.cpp b/examples/statemachine/trafficlight/main.cpp
index ed0eeea..3c47a51 100644
--- a/examples/statemachine/trafficlight/main.cpp
+++ b/examples/statemachine/trafficlight/main.cpp
@@ -151,6 +151,7 @@ public:
QVBoxLayout *vbox = new QVBoxLayout(this);
TrafficLightWidget *widget = new TrafficLightWidget();
vbox->addWidget(widget);
+ vbox->setMargin(0);
QStateMachine *machine = new QStateMachine(this);
LightState *redGoingYellow = new LightState(widget->redLight(), 3000);
@@ -182,7 +183,7 @@ int main(int argc, char **argv)
QApplication app(argc, argv);
TrafficLight widget;
- widget.resize(120, 300);
+ widget.resize(110, 300);
widget.show();
return app.exec();