I am currently researching Hierarchical State Machines (UML State Machines, Statecharts, etc.), and the following is unclear to me:
Is pushing events to machine's own event queue during transitions and from states valid, and if it is, is it safely used in practice or should it be avoided? Are there certain implications when doing this (implementation quirks at least, problems when orthogonal regions come into play, or similar)?
I will illustrate the question with two dummy machines:
the following machine would be in state A
waiting for event A_to_B
, after which it'd get into infinite loop by dispatching events as transition actions:
+-----+ +-----+ +-----+
| A | A_to_B / | B | B_to_C / | C |
|-----| dispatch B_to_C |-----| dispatch C_to_A |-----|
O---->| +------------------->| +------------------->| |
| | | | | |
+-----+ +-----+ +-----+
^ C_to_A / |
| dispatch A_to_B |
+-----------------------------------------------------+
the following machine would immediately get into infinite loop by dispatching events as entry actions:
+-------------------+ +-------------------+ +-----+
| A | | B | | C |
|-------------------| A_to_B |-------------------| B_to_C |-----|
O---->| on entry: +---------->| on entry: +---------->| |
| dispatch A_to_B | | dispatch B_to_C | | |
| | | dispatch C_to_A | | |
+-------------------+ +-------------------+ +-----+
^ |
| C_to_A |
+---------------------------------------------------------------+
A state machine has some internal state that can be changed in response to an external event. When a state machine receives an event from the external environment, it changes its state to a new state in accordance with a simple rule. It may also perform an action with significance to the external environment.
State machines are useful if you can define a clear number of states and events that will trigger transitions to them. They might be good for user interfaces or communications protocols. However, when building complex systems, implementation of state machines is not the best option.
State Machines are used in applications where distinguishable states exist. Each state can lead to one or multiple states and can also end the process flow. A State Machine relies on user input or in-state calculation to determine which state to go to next.
For every inch of paper there is a single letter printed on it–either the letter 'a' or the letter 'b'. The circles are “states” that the machine can be in. The arrows are the transitions. So, if you are in state s and read an 'a', you'll transition to state q.
A state machine can post events to self, but this has special purposes, such as to break up longer run to completion (RTC) steps into shorter pieces. You might want to do this to enable scheduling of other state machines in the system (or more generally active objects) in between your otherwise too long RTC step.
Specifically to your examples, I would try to avoid posting events to self in this case. Typically I see people do this when they confuse a statechart with a flowchart. A statechart needs events to transition from state to state. A flowchart transitions from one processing box to another automatically upon completion of the computation specified in the box. Obviously, when you post events to self, you turn a statechart into a flowchart. So, you really need a flowchart and and not a statechart, because you don't really wait for anything. You keep processing at full speed.
You can also view it this way. The purpose of events is to provide new information to the state machine. This is how a state machine "learns". But when you post events to self, you don't acquire any new knowledge. All the knowledge you need is already there delivered by the original "true" event. So, you have enough information to perform all this processing in just one transition instead of spreading it among many "states", which really are stages of this lengthy processing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With