From edda97af16eef28a7bd958353e4f54bf67b8cf89 Mon Sep 17 00:00:00 2001 From: Janne Valkealahti Date: Sun, 9 Aug 2015 17:15:03 +0100 Subject: [PATCH] Docs for extended state --- docs/src/reference/asciidoc/appendix.adoc | 4 ++ docs/src/reference/asciidoc/sm.adoc | 42 +++++++++++++++++++ .../docs/DocsConfigurationSampleTests.java | 40 ++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/docs/src/reference/asciidoc/appendix.adoc b/docs/src/reference/asciidoc/appendix.adoc index 55b34403..3c4ae766 100644 --- a/docs/src/reference/asciidoc/appendix.adoc +++ b/docs/src/reference/asciidoc/appendix.adoc @@ -73,6 +73,10 @@ A state models a situation during which some invariant condition holds. State is the main entity of a state machine where state changes are driven by an events. +*Extended State*:: +An extended state is a special set of variables kept in a state +machine to reduce number of needed states. + *Transition*:: A transition is a relationship between a source state and a target state. It may be part of a compound transition, which takes the state diff --git a/docs/src/reference/asciidoc/sm.adoc b/docs/src/reference/asciidoc/sm.adoc index b62cb85c..e22b83c9 100644 --- a/docs/src/reference/asciidoc/sm.adoc +++ b/docs/src/reference/asciidoc/sm.adoc @@ -388,6 +388,48 @@ to return a *Boolean* value to satisfy _Guard_ implementation. This is demonstrated with a _guardExpression()_ function which takes an expression as an argument. +[[sm-extendedstate]] +== Using Extended State +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 dump 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. + +[source,java,indent=0] +---- +include::samples/DocsConfigurationSampleTests.java[tags=snippet7] +---- + +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: + + +[source,java,indent=0] +---- +include::samples/DocsConfigurationSampleTests.java[tags=snippet5] +---- + +Or implement a Spring Application context listeners for +`OnExtendedStateChanged`. Naturally as mentioned in <> +you can also listen all `StateMachineEvent` events. + +[source,java,indent=0] +---- +include::samples/DocsConfigurationSampleTests.java[tags=snippet6] +---- + [[sm-statecontext]] == Using StateContext _StateContext_ is a domain object representing a current status of a diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java index 86349a3a..83173dc1 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java @@ -56,6 +56,7 @@ import org.springframework.statemachine.config.builders.StateMachineStateConfigu import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; import org.springframework.statemachine.config.configurers.StateConfigurer.History; import org.springframework.statemachine.ensemble.StateMachineEnsemble; +import org.springframework.statemachine.event.OnExtendedStateChanged; import org.springframework.statemachine.event.OnStateMachineError; import org.springframework.statemachine.event.StateMachineEvent; import org.springframework.statemachine.guard.Guard; @@ -943,4 +944,43 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests { } // end::snippet4[] +// tag::snippet5[] + public static class ExtendedStateVariableListener + extends StateMachineListenerAdapter { + + @Override + public void extendedStateChanged(Object key, Object value) { + // do something with changed variable + } + } +// end::snippet5[] + +// tag::snippet6[] + public static class ExtendedStateVariableEventListener + implements ApplicationListener { + + @Override + public void onApplicationEvent(OnExtendedStateChanged event) { + // do something with changed variable + } + } +// end::snippet6[] + + public static class ExtendedStateVariableActionSample { + +// tag::snippet7[] + public Action myVariableAction() { + return new Action() { + + @Override + public void execute(StateContext context) { + context.getExtendedState() + .getVariables().put("mykey", "myvalue"); + } + }; + } +// end::snippet7[] + + } + }