Let’s assume that we’d need to create a state machine tracking how many times a user is pressing a key on a keyboard and then terminate when keys are pressed 1000 times. Possible but a really naive solution would be to create a new state for each 1000 key presses. Going even worse combinations you might suddenly have astronomical number of states which naturally is not very practical.
This is where extended state variables comes into rescue by not having a necessity to add more states to drive state machine changes, instead a simple variable change can be done during a transition.
StateMachine
has a method getExtendedState()
which returns an
interface ExtendedState
which gives an access to extended state
variables. You can access variables directly via a state machine or
StateContext
during a callback from actions or transitions.
public Action<String, String> myVariableAction() { return new Action<String, String>() { @Override public void execute(StateContext<String, String> context) { context.getExtendedState() .getVariables().put("mykey", "myvalue"); } }; }
If there is a need to get notified for extended state variable
changes, there are two options; either use StateMachineListener
and
listen extendedStateChanged(key, value)
callbacks:
public class ExtendedStateVariableListener extends StateMachineListenerAdapter<String, String> { @Override public void extendedStateChanged(Object key, Object value) { // do something with changed variable } }
Or implement a Spring Application context listeners for
OnExtendedStateChanged
. Naturally as mentioned in Chapter 20, Listening State Machine Events
you can also listen all StateMachineEvent
events.
public class ExtendedStateVariableEventListener implements ApplicationListener<OnExtendedStateChanged> { @Override public void onApplicationEvent(OnExtendedStateChanged event) { // do something with changed variable } }