reacting to all orthogonal states having finished in Boost.statechart
I'm working on a robot control program that is based on a state machine. While the program uses Qt State Machine Framework, I also attempted to implement it using Boost.statechart (BS) as a theoretical exercise and a way to learn / evaluate the library.
In Qt version I used the following pattern in several places: a compound state has parallel nested sub-graphs, each of which eventually reaches a final state. When all parallel sub-states finish, the parent state emits "finished()" signal, which causes the machine to transit to the next top-level state. E.g. (Beware: pseudo diagram):
Idle -calibRequest-> Calibrate( calibrate_camera | calibrate_arm ) -finished-> Idle
and calibrate_*
states in turn have nested states inside them like S -trigger[calibrated?]-> F
where F
is a final state. When both calibrate_*
states reach their respective F
states finished
signal causes the state machine to transit into Idle
.
Qt's parallel child state are analogous to BS's orthogonal nested states. At first I though "termination" was BS's analogue to final states, but in fact it isn't. It's more like "terminate the state machine unless there is still some orthogonal thing going somewhere" - once you terminate all orthogonal states the parent state terminates as well without any chance to transit. Posting events upon termination doesn't help either since there is no state that these events could be delivered to.
I ended up implementing "final states" which post a notification event when reached and reacting on this event in the parent state - checking if all orthogonal states have reached their final events and transiting then. Which is basically reimplementation of Qt State Machine's approach, but which has to be redone each time I need this pattern. But may be I'm just so used to one way of achieving this effect that开发者_JAVA百科 I don't see an alternative?
精彩评论