
Originally Posted by
daviddrell
it was bad of me to assume that only those already familiar with the paper ( i.e the authors of QStateMachines) would be responding.
If that was the case you would probably be waiting forever 
he describes a notational method for making state transitions in AND-parallel states where the transition (fig-19: beta(G)) is conditioned on the state of the adjacent sub-state-machine
The problem with Qt's state machines is that it is not possible to directly ask the machine about what state it is in so to obtain information whether the sub-machine is in state "G" you need to cheat a bit by asking the machine to toggle an external flag that states whether it is in G state or not. Use a boolean property of some object and make the G state set this property to true and all other states to set it to false. Alternatively use QState::onExit() and QState::onEntry() of the G state to manipulate some external variable in a similar manner. Then you will be able to make some other transition active based on the value of this variable - either by reimplementing QAbstractTransition::eventTest() for the transition to check the variable or by using some higher-level transition class.
To generalise -- you can use QAbstractTransition::eventTest() to implement any transition condition you want. The only problem is to provide an infrastructure for it. In your case you can do something like this:
class InStateTransition : public QSignalTransition {
Q_OBJECT
Q_PROPERTY(bool canTrigger READ canTrigger WRITE setCanTrigger)
public:
InStateTransition(QState * sourceState = 0) : QSignalTransition(sourceState) {
m_canTrigger = false;
}
void setCanTrigger(bool v) { m_canTrigger = v; }
bool canTrigger() const { return m_canTrigger; }
protected:
if(!QSignalTransition::eventTest(e))
return false;
return canTrigger();
}
private:
bool m_canTrigger;
};
class InStateTransition : public QSignalTransition {
Q_OBJECT
Q_PROPERTY(bool canTrigger READ canTrigger WRITE setCanTrigger)
public:
InStateTransition(QState * sourceState = 0) : QSignalTransition(sourceState) {
m_canTrigger = false;
}
void setCanTrigger(bool v) { m_canTrigger = v; }
bool canTrigger() const { return m_canTrigger; }
protected:
bool eventTest(QEvent *e) {
if(!QSignalTransition::eventTest(e))
return false;
return canTrigger();
}
private:
bool m_canTrigger;
};
To copy to clipboard, switch view to plain text mode
Then you can use i.e.:
stateG->assignProperty(someInStateTransition, "canTrigger", true);
stateOtherThanG->assignProperty(someInStateTransition, "canTrigger", false);
stateG->assignProperty(someInStateTransition, "canTrigger", true);
stateOtherThanG->assignProperty(someInStateTransition, "canTrigger", false);
To copy to clipboard, switch view to plain text mode
And the transition will only fire when stateG is active.
Bookmarks