[Qt-interest] QStateMachine API and design?

K. Frank kfrank29.c at gmail.com
Fri Nov 5 16:03:58 CET 2010


Hello Steve -

On Fri, Nov 5, 2010 at 9:40 AM, Stephen Kelly <steveire at gmail.com> wrote:
> K. Frank wrote:
>
>> Hi Steve -
>>
>> I would make a couple of philosophical comments:
>
> Thanks. This is useful too. I'm unsure though if this is mostly a
> philosophical approach or if it comes from experience of trying to meld
> QStateMachine with QML?

No, my comments are not motivated by experience with QML, as I
have none.  (I've played around with the Qt state-machine framework
a little -- nothing serious -- but have never used QML.)

But my philosophy has evolved while implementing substantive
production applications (not Qt, and hand-coded state machines,
rather than a state-machine framework).

>> Similarly, in the state-machine paradigm, you don't really care what state
>> you're in.
>
> I think in this interacting-with-QML case, you do care, because the state
> you are in is part of how QML is used. Even if QStateMachine doesn't make it
> easy, to declare which state you are in or should be in, QML does, so
> interacting with QML in a similar way makes for an interesting way to
> implement serious-business applications in QML.

This could well be the case.  QML may well (not that I know anything about
it) make good use of state machines in ways that would not have occurred
to me.  If it works well, more power to them.

>>
>>> My usecase is to create a state machine and expose it to QML so that I
>>> can change the ui state on change of the application state.
>>> ...
>
> What I currently have is something like this in your pseudo code:
>
> application_state_machine::errorstate::onEntry() {
>  ui_state_machine.setState(errorstate);
> }
> ...
> ui_state_machine::errorstate::onEntry() {
>  errorScreen.setVisible(true);
> }

First of all, it's not my intention to criticize your design.  Good, practical,
real-world code is almost always impure.   (My word, the "discussions"
I've had with the object-oriented crowd...  Do you realize that I don't
implement my state value as an instance of a polymorphic class, a la
Design Patterns?  Neanderthal!  Philistine!  Etc...)

Having said that, a little more philosophy:

Having two state machines that are closely coupled in that they need to
be kept (partially) synchronized with one another strikes me as something
of a yellow flag.  I'm a big fan of using multiple, independent state machines
that communicate with one another (and are thus coupled to one another)
by ending one another events.  (And I consider this to be generally preferable
to using "and" states within a single state machine.)

But the redundancy implied by having two state machines whose states
mirror one another and need to be partially synchronized seems a bit
suspicious to me.

Also having (and using) a "setState" method raises a yellow flag for me.
To me the topology of a state machine (which states -- nodes in a directed
graph -- are connected to one another by transitions -- the directed edges)
is the meat of the code, the "business logic," if you will.  Having a setState
method makes your topology that of a complete graph, that is, every node
connected to every other.

Looked at another way, you can think of the setState method as the "goto"
of state machines, except now you can "goto" any line of code, rather than
just labels that you have explicitly defined.  (I would be more comfortable
if you had just a setErrorState method.  That would be like defining a
specific label in procedural code ("oops_error:") and then using that label
in a goto statement ("goto oops_error;").)

Again, this is not meant to be in any way prescriptive.  (Worthwhile design
advice rarely is -- not that my advice is worthwhile.)  It's just some questions
to be thinking about when you mull over your design.

> So the ui state is dependent on the application state in some way.
>
> All the best,
>
> Steve.

Regards.


K. Frank




More information about the Qt-interest-old mailing list