Question

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:

  1. 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     |
             +-----------------------------------------------------+
    
  2. 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      |
             +---------------------------------------------------------------+
    
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top