2017-08-17 40 views
0

假設我有一包機器人運行QStateMachine。這些機器人的所有狀態機具有相同的基本結構:子類化和修改QStateMachine

  • 國:
    • 睡眠
    • 搜索
    • 銷燬
    • 返回
  • 轉換(from - >tosignal
    • 睡眠 - > 「下一步」
    • 搜索 - > 「下一步」
    • 滅滅 - >搜索 「下一步」
    • 摧毀 - >返回的 「回」
    • 搜索 - >返回的 「回」
    • 返回 - > 「下一步」
    • 迴歸搜索 - >睡眠 「返回」

// 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 -signal繼續前進,或者在back-信號後繼續輸入return

如上所述,我的計劃是將它們作爲子狀態添加到狀態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)語法,所以我混了sourcetarget

在創建它們之後,在對這個對象進行子類化時,應該很容易重新路由或禁用其中一些轉換。