Создание подклассов и модификация QStateMachine

Допустим, у меня есть стая роботов, которые запускают QStateMachine, Все конечные автоматы этих роботов имеют одинаковую базовую структуру:

  • Состояния:
    • Спать
    • Поиск
    • уничтожить
    • Вернуть
  • Переходы (from -> to на 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-сигнал.

Как уже упоминалось, мой план состоял в том, чтобы просто добавить их в качестве подсостояний к штату destroy, но как сигнал next будет не только продолжать подсостояние машины до завершения, но и покинет родительское состояние.

Как я могу избежать этого? или есть другой хороший способ сделать подобное?

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) так что я перепутал source а также target,

После того, как они были созданы таким образом, должно быть легко перенаправить или отключить некоторые из этих переходов при создании подкласса этого объекта.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]