0

假设我有一包运行 QStateMachine. 这些机器人的所有状态机都具有相同的基本结构:

  • 状态:
    • 睡觉
    • 搜索
    • 破坏
    • 返回
  • 转换 ( from-> toon signal:
    • 睡眠 -> 搜索“下一步”
    • 搜索 -> 在“下一个”上销毁
    • 销毁 -> 搜索“下一个”
    • 销毁 -> 返回“返回”
    • 搜索 -> 返回“返回”
    • 返回 -> 搜索“下一个”
    • 返回 -> 在“返回”上睡觉

// base.h

#include <QObject>
#include <QState>
#include <QStateMachine>

class Base : public QObject
{
    Q_OBJECT
public:
    Base(QObject* parent = 0);
    ~Base();

signals:
    void next();
    void back();

private:
    QStateMachine m_machine;
    QState* m_sleep;
    QState* m_search;
    QState* m_destroy;
    QState* m_return;
};

// base.cpp

Base::Base(QObject* parent) : QObject(parent)
{
    m_sleep = new QState(&m_machine);
    m_search = new QState(&m_machine);
    m_destroy = new QState(&m_machine);
    m_return = new QState(&m_machine);

    m_machine.setInitialState(m_sleep);

    m_sleep->addTransition(this, &Base::next, m_search);
    m_search->addTransition(this, &Base::next, m_destroy);
    m_search->addTransition(this, &Base::back, m_return);
    m_destroy->addTransition(this, &Base::next, m_search);
    m_destroy->addTransition(this, &Base::back, m_return);
    m_return->addTransition(this, &Base::next, m_search);
    m_return->addTransition(this, &Base::back, m_sleep);

    m_machine.start();
}

现在我想要一个更具体的机器人。假设他在破坏过程中更加详细,具有几个子状态,例如dismantel -> sprayWithAcid -> blowUp -> desintegrate,他在每个next- 信号上继续前进,或者他继续在return-back信号上。

如前所述,我的计划是将它们作为子状态添加到 statedestroy中,但信号next不仅会继续子状态机直到完成,还会离开父状态。

我怎样才能避免这种情况?还是有其他类似的好方法?

4

1 回答 1

0

我现在明白了。

诀窍是显式地创建转换,将它们作为类的成员。您可以像这样设置它们:

m_sleepSearch = new QSignalTransition(this, &Base::next, m_sleep);
m_searchDestroy = new QSignalTransition(this, &Base::next, m_search);
m_searchReturn = new QSignalTransition(this, &Base::back, m_search);
m_destroySearch = new QSignalTransition(this, &Base::next, m_destroy);
m_destroyReturn = new QSignalTransition(this, &Base::back, m_destroy);
m_returnSearch = new QSignalTransition(this, &Base::next, m_return);
m_returnSleep = new QSignalTransition(this, &Base::back, m_return);

m_sleepSearch->setTargetState(m_search);
m_searchDestroy->setTargetState(m_destroy);
m_searchReturn->setTargetState(m_return);
m_destroySearch->setTargetState(m_search);
m_destroyReturn->setTargetState(m_return);
m_returnSearch->setTargetState(m_search);
m_returnSleep->setTargetState(m_sleep);

我首先出错的是QSignalTransition(sender, signal, source_state)构造函数的参数错误,因为它与 的语法太相似了,->addTransition(sender, signal, target_state)所以我混淆了sourcetarget

在像这样创建它们之后,在子类化这个对象时,应该很容易重新路由或禁用其中一些转换。

于 2017-08-17T15:36:20.553 回答