Quick and dirty textual statecharts


Textual Statecharts

    - enter /start_heater();
    - exit  /stop_heater(); 
    - init  >> Toasting.   
    - toast >> Toasting.
    - bake  >> Baking.
    - open  >> Open.
      - enter /arm_timer();
      - exit  /disarm_timer();
      - do [timer elapsed] / eject_toast();
      - enter/set_temp();
      - exit /set_temp();
    - enter /illuminate();
    - exit  /extinguish();
    - close >> Heating.

State names appear first. The outermost initial state appears at the top, and child states are listed "within" their parent state. Other than that the order of states doesn't matter much. In this case ( presumably after you turn the darn toaster oven on ) the first state is "Heating".

Listed underneath each state are all of the events that affect it, preceded by a dash.  The UML reserved labels ( enter, exit, do, include ) appear first ( if they needed). Also, just as in UML, a single forward slash precedes any action that might occur in response to an event. "Heating: enter/start_heater();" indicates that when heating starts, the machine should start the heater.

The "init event" may require some explanation, but basically, in a UML statechart, you must always move to as leaf a state as possible. Heating, here, has two child states, so you can't just be heating: you must also *either* be toasting or baking. This formalism allows you to share what's common in the parent state with what's unique in each child state. The "init" simply says which one you move into by default. In UML, however, there is no such "init" event. Instead, the default flow is represented with an "initial pseudostate" ( a solid black circle, and arrow. ).  Functionally, however, it means the same thing.

Custom events follow the predefined events. "toast" refers to when someone flips the toast switch, "bake" when someone flips the "bake" switch, "open" when they open the toaster door.

The C++ right-shift operator >> indicates the movement from one state to a next. "Heating: init >>Toasting." means the first default child state for Heating is Toasting. "Heating: open>>Open." means if someone opens the toaster's door, move into the "Open" state. All, pretty straight forward.

After the custom events come substates, indented one or more spaces. As you've probably already gathered, state declarations are followed by colons ( eg. "Heating:" ), similar to YAML's associative array of lists, while references to states are terminated with periods.

Finally, any guard conditions that must be met for an event to be processed are in square brackets. In the above example, the reserved event "do" gets polled at a system defined rate, very much like Flash's enter frame event. The guard I added to Samek's chart evaluates whether the timer setup by the Toasting:enter action has finished, and if so, it ejects the toast.

Here's Samek's original statechart:
UML statechart by Miro Samek, licensed under Creative Commons 3.0 Share-Alike

Note: In UML, transitions between sibling states (ex. Heating and Open ) are defined *outside* of both of the states. This reflects how transitions are meant to be processed. Technically, any actions associated with transitions ( though there are none in this example ) are supposed to happen after one state has exited but before the new state has entered. This subtly gets lost in the textual description. 

I will get to regions eventually, though there are none in this example. They will use triple dash (---) separation similar to the "new document" separation that YAML uses.