QStateMachine’s a state, too

Did a nifty change in QStateMachine yesterday: QStateMachine now inherits QState. QStateMachine::rootState() is gone; the state machine now is the root state. This allowed us to remove a fair amount of code and API from QStateMachine; most importantly, it makes application code nicer, as you can do new QState(machine) to create a top-level state, instead of the old new QState(machine->rootState()) (whee, that's something we've wanted since day one!). Other than that, behavior and source compatibility is preserved.

An interesting question is... What should QState::machine() return when the state is a state machine? Itself?

Nope, it doesn't. We now support embedding state machines within other state machines. If the parent of the state machine is a QState, machine() will return the machine of the parent state.

When a QStateMachine is a child state of another QState, the ancestor state machine will treat the nested machine as an atomic state in the state machine algorithm; effectively, the nested machine is treated as a black box. QStateMachine reimplements QState::onEntry() and calls start(), so that when a nested state machine is entered, it will automatically start running. The nested machine is self-contained; it maintains its own event queue and so on. Of course, you can't have transitions from states in the nested machine to states in the parent machine; you'll have to use e.g. the nested machine's finished() signal to trigger a transition from the nested machine to another state in the parent machine (since the nested machine is a state of the parent machine, and not of itself). Well, that should go without saying.

OK, so we haven't found a use case yet where you'd rather use nested state machines with separate event loops and all instead of just using normal group states within a single machine, where all states can be directly connected by transitions (maybe you can think of a scenario?). But a) it's neat, and b) it works. As always, these qualities take presedence over any purported absence of use cases.

The documentation for QState still says that "the QState class provides a general-purpose state for QStateMachine". Seeing as QStateMachine itself is now a QState, this begs the question: Who is really providing what for whom, to what end, and why?

Blog Topics: