Software Architecture with (Q)state machine
I'm working on an embedded software under Linux with the help of Qt. I have some experience on this, but this time I try to manage the state machine with QStateMachine api.
My software is based on model / view architecture, and I divide the software on module and submodule. More or less a module contains models and another views. I put the state on a third module, and I believe that the state module should be independant from the views and models. Having I look on the Qt state api, I have some question because with my architecture I can't use the QEventTransition and the QSignalTransition as those two classes seem to be deeply dependant of the event sender. Am I right? So I have to create my own transition class from the QAbstractTransition...
My questions are:
- do you agree with my point of view or do you think a QStateMachine should be deeply linked to the rest of the software or did I miss something?
- How do you use the QStateMachine api yourself?
[quote author="ngrosjean" date="1282759541"]* do you agree with my point of view or do you think a QStateMachine should be deeply linked to the rest of the software or did I miss something?[/quote]
Note that this isn't deeply linked. All you know is something about an object (and nearly everything is an object in Qt). It does make sense to me that if something happens, it is triggered by an object of sorts. However it is always possible to create your own derivative of QAbstractTransition.
Thanks for your reply. I see your point of view and I'm agree you only need a QObject pointer (like for signal / slot), but :
where did you contruct your QEventTransition? Is it correct to think it is on the state machine itself?...
...then in this case you should give a reference (even as QObject) of all potentiel "state event sender"!
Perhaps I'm just wrong to mix Qt Model / View with Qt StateMachine Api...
I'm planning to do some work with the API, but haven't done much so far (lots of other stuff to do). So all I say is based on the docs.
It seems to me however that given the current API, you would have some sort of wrapper around your state machine that allows you to register classes. This would allow you to implement the state machine differently (the old fashioned enum way for example) without having to adapt your interface.
It doesn't seem logical to me to have a GUI element managing a state machine unless it works on that particular GUI element only (animations).
To be able to use the event transition you would have to know the pointer to the state machine however; the application wouldn't know where to send it otherwise.
My state machine will only be managed by the way of Event. I made a minimum subclasse of QAbstractTransition :
@class CSubTransition : public QAbstractTransition
CSubTransition(QState* pStartState, const QEvent::Type eventID);
protected : virtual bool eventTest(QEvent *e) ; virtual void onTransition(QEvent *e); private: const QEvent::Type a_EVENT_ID;
with on .cpp file:
@bool CSubTransition::eventTest(QEvent *e)
return (a_EVENT_ID == e->type());
... and then just listing my "state event" from my UML Diagram into a header and create all transitions instance on my main state machine.
Now, as you said, somewhere far away in my code I should have something like @pMyStateMachine->PostEvent(MY_EVENT)@... that means a pointer to the state machine base class.
[offtopic]I found bug. While you dont select "MY EVENT" code, it show incorrect in Firefox, without "_" character.[/offtopic]