ピンポン状態

Ping Pong States の例では、Qt State Machine Framework で並列状態をカスタムイベントやトランジションと共に使用する方法を示します。

この例では、2つの状態がステートマシンにイベントをポストすることで通信するステートチャートを実装しています。ステートチャートは以下のようになります:

pingerponger の状態は並列状態です。つまり、同時に入力され、互いに独立して遷移します。

pinger 、最初のping イベントがポストされる。pongerpong イベントがポストされ、pingerping イベントがポストされる。

class PingEvent : public QEvent
{
public:
    PingEvent() : QEvent(PingEventType) { }
};

class PongEvent : public QEvent
{
public:
    PongEvent() : QEvent(PongEventType) { }
};

PingEventPongEvent の2つのカスタムイベントが定義されています。

class Pinger : public QState
{
public:
    explicit Pinger(QState *parent) : QState(parent) { }

protected:
    void onEntry(QEvent *) override
    {
        machine()->postEvent(new PingEvent);
        qInfo() << "ping?";
    }
};

Pinger クラスは、ステートに入るとステートマシンにPingEvent をポストするステートを定義する。

class PingTransition : public QAbstractTransition
{
public:
    PingTransition() {}

protected:
    bool eventTest(QEvent *e) override { return e->type() == PingEventType; }

    void onTransition(QEvent *) override
    {
        machine()->postDelayedEvent(new PongEvent, 500);
        qInfo() << "pong!";
    }
};

PingTransition クラスは、PingEvent タイプのイベントによってトリガーされる遷移を定義し、遷移がトリガーされると、PongEvent (500 ミリ秒の遅延付き)をステートマシンにポストします。

class PongTransition : public QAbstractTransition
{
public:
    PongTransition() {}

protected:
    bool eventTest(QEvent *e) override { return (e->type() == PingEventType); }

    void onTransition(QEvent *) override
    {
        machine()->postDelayedEvent(new PingEvent, 500);
        qInfo() << "ping?";
    }
};

PongTransition クラスは、PongEvent タイプのイベントによってトリガーされるトランジションを定義し、トランジションがトリガーされると、PingEvent (500 ミリ秒の遅延)をステートマシンにポストします。

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    QStateMachine machine;
    auto group = new QState(QState::ParallelStates);
    group->setObjectName("group");

main()関数は、まずステートマシンと並列ステートグループを作成する。

    auto pinger = new Pinger(group);
    pinger->setObjectName("pinger");
    pinger->addTransition(new PongTransition);

    auto ponger = new QState(group);
    ponger->setObjectName("ponger");
    ponger->addTransition(new PingTransition);

次に、並列状態グループを親状態として、pingerponger 状態が作成される。遷移にはターゲットがないことに注意。このような遷移がトリガーされると、ソース状態が終了して再入力されることはありません。遷移のonTransition()関数だけが呼び出され、ステートマシンのコンフィギュレーションは変わりません。

    machine.addState(group);
    machine.setInitialState(group);
    machine.start();

    return app.exec();
}

最後に、グループがステートマシンに追加され、マシンが開始され、アプリケーションのイベントループに入ります。

プロジェクト例 @ code.qt.io

©2024 The Qt Company Ltd. 本書に含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。