Imagine a part of your state machine looks like this:
How do you properly implement the choice part in Qt? I know there are guarded transitions, but that would mean that I need to:
std::function<bool()> and a flag which determines if the transition happens when that boolean result is true, or when it is falseS1 using these two instances.That approach seems kind of clumsy and error prone for something as simple as a choice. Is there a more maintainable approach to implement this?
License Notice:
Alternatively to the default StackOverflow license you are hereby allowed to use this code through the MIT License.
I've created a BooleanChoiceTransition class with a constructor like this (might contain errors, the code is not on this machine, so I typed it by heart):
BooleanChoiceTransition::BooleanChoiceTransition(std::function<bool()> choiceFunc, QState* targetForTrueCase, QState* targetForFalseCase)
: QState{}
{
this->addTransition(this, &BooleanChoiceTransition::transitionToTrueTarget, targetForTrueCase);
this->addTransition(this, &BooleanChoiceTransition::transitionToFalseTarget, targetForFalseCase);
(void)QObject::connect(this, &QAbstractState::entered, [this]() {
if(choiceFunc())
{
emit transitionToTrueTarget();
}
else
{
emit transitionToFalseTarget();
}
});
}
with transitionToTrueTarget and transitionToFalseTarget being signals of course.
For the case of the example in the question, the class can be used like so:
auto choiceState = new BooleanChoiceTransition([this](){ return _someConditionFullfilled; }, s2, s3);
s1->addTransition(this, &MyClass::someTrigger, choiceState);
Since BooleanChoiceTransition is a QState, this can even be nested easily:
auto outerChoiceState = new BooleanChoiceTransition([this](){ return _someOtherConditionFullfilled; }, s4, choiceState);