This files are part of the ‘symplehfsm’ package.
This is a full blown example. It uses all features of the symplehfsm framework (entry-, exit- and transition-actions, guards). There are also tests for each transition. This example shows the usage of different actions implementations applied to the same state machine (one for testing, one for the interactive demo).
It’s all about:
making a statemachine testable based on: http://accu.org/index.php/journals/1548
------------------------------------------------------------------------------
Statechart used to test the SympleHFSM
based on
[Samek] Miro Samek, Practical Statecharts in C/C++, CMP Books 2002.
There's a companion website with additional information: http://www.quantum-leaps.com
taken from: http://accu.org/index.php/journals/252
see also: http://en.wikipedia.org/wiki/UML_state_machine#Local_versus_external_transitions
making a statemachine testable based on: http://accu.org/index.php/journals/1548
+-------------------------------------------------------------------------------------+
*--init-->| s0 |
+-------------------------------------------------------------------------------------+
| entry/ |
| exit/ |
| +-------------------------+ +------------------------------------------+ |
| *-->| s1 | | s2 | |
| +-------------------------+ +------------------------------------------+ |
| | entry/ |-c->| entry/ +-----------------+ | |
|<--d---| exit/ | | exit/ | h[!foo]/ foo=1; | | |
| | +---------------+ |<-c-| +----------------------------+ | | |
| | *-->| s11 | | | *-->| s21 |<--+ | |
| | +---------------+ | | +----------------------------+ | |
| +--| | entry/ | | | | entry/ | | |
| a| | | exit/ |<---f---| | exit/ | | |
| +->| | h[foo]/ foo=0;| | | | +--------------+ | | |
| | | | | | | *-->| s211 | | | |
| |--b->| | | | | +--------------+ | | |
| | | | |--------f--------->| entry/ | | | |
| | | | | | | | exit/ |--------g------>|
| | | |----------g----------->| | | | |
| | | | | | |--b--->| |<-------e-------|
| | | | | | |<---d--| | | | |
| | | | | | | +--------------+ | | |
| | +---------------+ | | +----------------------------+ | |--exit-->O
| | | | | |
| +-------------------------+ +------------------------------------------+ |
| |
+-------------------------------------------------------------------------------------+
As far as I understand it, current_state always points to either s11 or s211 (one of the leaf states).
Also for the transitions triggered by an event I assume it works as follows:
event| from -> to | transition actions
init: s0 -> s11: s0.entry, s1.entry, s11.entry
exit:s211 -> s0: s211.exit, s21.exit, s2.exit, s0.exit
s11 -> s0: s11.exit, s1.exit, s0.exit
a: s1 -> s1: s11.exit, s1.exit, s1.entry, s11.entry
b: s1 -> s11: s11.exit, s11.entry
s21 -> s211: s211.exit, s211.entry
c: s1 -> s2: s11.exit, s1.exit, s2.entry, s21.entry, s211.entry
s2 -> s1: s211.exit, s21.exit, s2.exit, s1.entry, s11.entry
d: s1 -> s0: s11.exit, s1.exit, s1.entry, s11.entry
s211 -> s21: s211.exit, s211.entry
e: s0 -> s211: s11.exit, s1.exit, s2.entry, s21.entry, s211.entry
s211.exit, s21.exit, s2.exit, s2.entry, s21.entry, s211.entry
f: s2 -> s11: s211.exit, s21.exit, s2.exit, s1.entry, s11.entry
s1 -> s211: s11.exit, s1.exit, s2.entry, s21.entry, s211.entry
g: s11 -> s211: s11.exit, s1.exit, s2.entry, s21.entry, s211.entry
s211 -> s0: s211.exit, s21.exit, s2.exit, s1.entry, s11.entry
h: s11 foo==True: actions.unset_foo
s11 foo==False: do nothing
s21 foo==False: s211.exit, s21.exit, actions.set_foo, s21.entry, s211.entry
s21 foo==True: do nothing
Actions:
set_foo() => foo = 1
unset_foo() => foo = 0
The action specifications shown are:
*
The transition from s21 to itself (a self-transition). This is an example of a transition
that has a guard (in brackets []) and an associated action (after the slash /). The guard
is a condition that must evaluate to true to enable the transition. If it evaluates to false,
the transition is not taken and none of the actions are executed. A self-transition exits and
reenters the state, hence the associated exit and entry actions are executed.
*
The internal transition inside s11 is not drawn with an arrow. It merely specifies an action
that is to be taken when a certain event occurs, but no transition to another state occurs,
and no exit or entry actions are performed. In our case the internal transition has a guard,
so the associated action (foo = 0) is only executed when the h key is pressed while foo
evaluates to true.
..todo: loop action back to event -> queue?
Bases: object
The Actions the statemachine can execute.
Bases: object
Event identifiers of the statemachine (the events it can handle).
Bases: object
Bases: symplehfsm.BaseHFSMTests
Testcases for MyStateMachine using the BaseHFSMTests as base.
Bases: examples.TestHFSM.symplehfsm_demo.Actions
Test Actions for testing, captures all actions for comparison
Bases: object
Define an ‘enum’ to have comparable values for each action