Comprehensive#
Here is a statechart you can play with. Click on the diagram to see a bigger version of it.
It hasn’t been instrumented, but write statements have been placed all over
its HSM so you can see when events activate its different parts.
The code to interact with this design can be found here, and to run it, type:
python comprehensive_no_instrumentation.py
foo = 0;s-ENTRY;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
:C s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
:C s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
:G s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
:E s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
:D s1-D;foo = 1;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
:D s11-D;foo = 0;s11-EXIT;s1-INIT;s11-ENTRY;
:T
Terminating
Comprehensive with Instrumentation#
It’s inconvenient to leave write statements all over your code while you
troubleshoot it, so miros comes with two different types of instrumentation
built in. The instrumentation allows you to query the chart as if the write
statements were written on every transition and hook.
To enable this instrumentation, you place the spy_on decorator above your
state call back functions.
Here is another design (click on it to see a bigger version of it), containing
the same comprehensive chart described in the previous section, but with an
additional M signal. The M signal causes the chart to switch from
normal to trace to spy and back to normal mode.
In normal mode, the write statements work as they did in the previous
un-instrumented design. In trace mode the trace instrumentation is shown
after your chart reacts to an event and the write methods are muted, so
nothing is printed to the screen. In spy mode the write methods write
their contents into the spy stream then the full spy instrumentation is
shown after the chart reacts to an event.
The design was also adjusted to include the T, terminate event within the
model_control statemachine managing the instrumentation mode of the chart.
At any time you can terminate the program by sending a T event.
The code to interact with this design can be found here, and to run it, type:
python comprehensive.py
foo = 0;s-ENTRY;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
n:C s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
n:D s1-D;foo = 1;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
n:D s11-D;foo = 0;s11-EXIT;s1-INIT;s11-ENTRY;
n:M
t:C [2019-02-26 07:05:02.937057] [me] e->C() s11->s211
t:C [2019-02-26 07:05:04.933100] [me] e->C() s211->s11
t:M
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
M:s11
M:s1
M:s
write('s-M')
M:s:HOOK
<- Queued:(0) Deferred:(0)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
s:I
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
I:s11
I:s1
I:s
write('s-I')
I:s:HOOK
<- Queued:(0) Deferred:(0)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
s:T Terminating
Note
Mode changes are highlighted.
The design uses the orthogonal component pattern to build an HSM within an HSM;
the mode_control is built in the entry condition of the s state, and its
events are dispatched to it using the M and T hooks of the s state.
The post_action method of the HsmTester thread is controlled by the
mode_control state, as is the write method of the ExampleStateChart.
The I event is an example of the ultimate hook pattern, and pay special
attention to how D behaves while in the s11 state.