QStateMachine automatic transitions or mix boost::msm with QObject

258 Views Asked by At

I am pretty new to C++ and Qt and I want to develop a machine control and model the process via state machines. Up until now I separated my code into different QObjects running in different QThreads which communicate via QTs signal/slot concept. Up until now I used the QStatemachine Framework but am suspicious if I am using it the right way. As an example I created a simple StateMachine:

*.h:

class SmTest : public QStateMachine
{
    Q_OBJECT
public:
    explicit SmTest(QObject *parent = nullptr);
private:
    QState* sA;
    QState* sB;
    QState* sC;
    QState* sD;  
signals:
    void DoSomethingA();
    void DoSomethingB();
    void DoSomethingC();
public slots:
    void onA();
    void onB();
    void onC();
    void onD();   
public slots:
};

*.cpp:

SmTest::SmTest(QObject *parent) : QStateMachine(parent)
{
    sA = new QState(this);
    sB = new QState(this);
    sC = new QState(this);
    sD = new QState(this);

    connect(sA, &QState::entered, this, &SmTest::onA);
    connect(sB, &QState::entered, this, &SmTest::onB);
    connect(sC, &QState::entered, this, &SmTest::onC);
    connect(sD, &QState::entered, this, &SmTest::onD);

    sA->addTransition(this, &SmTest::DoSomethingA, sB);
    sB->addTransition(this, &SmTest::DoSomethingB, sC);
    sC->addTransition(this, &SmTest::DoSomethingC, sD);

    this->setInitialState(sA);
}

void SmTest::onA()
{
    qDebug() << "onA entered";
    emit DoSomethingA();
}

void SmTest::onB()
{
    qDebug() << "onB entered";
    double rnd = qrand() % 2;
    if (rnd > 1)
        emit DoSomethingB();
}

void SmTest::onC()
{
    qDebug() << "onC entered";
    emit DoSomethingC();
}

void SmTest::onD()
{
    qDebug() << "onD entered";
}

In this case, I have to declare a signal for each transition and a slot for each state in my FSM and connect those accordingly. This may be okay in small examples like the above but will get messy pretty fast if the FSM may contain >100 states.

  1. Is there a way to use unconditional transitions? For example sA->addTransition(sB) would mean that sA will automatically transition into sB. However, if I try to use this, it breaks my QStateMachine. If this is not possible:
  2. I looked a bit into the Boost MSM Framework and like the syntax and functionality if offers (transition table, "None"-Event, etc). Is there a proper way to embed a boost::msm inside a QObject and being able to emit signals of that QObject inside the on_entry functions of that boost::msm?
0

There are 0 best solutions below