Compare commits
No commits in common. "master" and "2.1.1" have entirely different histories.
7
pom.xml
7
pom.xml
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>me.bvn13.fsm</groupId>
|
<groupId>me.bvn13</groupId>
|
||||||
<artifactId>fsm</artifactId>
|
<artifactId>fsm</artifactId>
|
||||||
<version>2.2.1</version>
|
<version>2.1.1</version>
|
||||||
|
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
@ -31,6 +31,9 @@
|
|||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
|
||||||
|
<!-- Versions -->
|
||||||
|
<nexus.url>https://s01.oss.sonatype.org</nexus.url>
|
||||||
|
|
||||||
<!-- Publishing -->
|
<!-- Publishing -->
|
||||||
<nexus.url>https://s01.oss.sonatype.org</nexus.url>
|
<nexus.url>https://s01.oss.sonatype.org</nexus.url>
|
||||||
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
|
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
|
||||||
|
|||||||
25
readme.md
25
readme.md
@ -50,31 +50,6 @@ Simple way to use it - to construct an inherited class specified with the type o
|
|||||||
.create();
|
.create();
|
||||||
```
|
```
|
||||||
|
|
||||||
or since 2.2.1
|
|
||||||
|
|
||||||
```java
|
|
||||||
SimpleFsm<String> simpleFsm = Fsm
|
|
||||||
.<SimpleFsm<String>, String>from(SimpleFsm::new)
|
|
||||||
.withStates()
|
|
||||||
.from("init")
|
|
||||||
.withBeforeHandler(fsm -> initBefore.set(true))
|
|
||||||
.withAfterHandler(fsm -> initAfter.set(true))
|
|
||||||
.withProcessor((fsm, event) -> initProcess.set(true))
|
|
||||||
.withTransition()
|
|
||||||
.to("finish")
|
|
||||||
.checking((fsm, event) -> true)
|
|
||||||
.endTransition()
|
|
||||||
.end()
|
|
||||||
.finish("finish")
|
|
||||||
.withBeforeHandler(fsm -> finishBefore.set(true))
|
|
||||||
.withAfterHandler(fsm -> finishAfter.set(true))
|
|
||||||
.withProcessor((fsm, event) -> finishProcess.set(true))
|
|
||||||
.end()
|
|
||||||
.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## Releasing
|
## Releasing
|
||||||
|
|
||||||
Creating a new release involves the following steps:
|
Creating a new release involves the following steps:
|
||||||
|
|||||||
@ -3,20 +3,12 @@ package me.bvn13.fsm;
|
|||||||
public class ConditionBuilder<T extends Fsm, E> {
|
public class ConditionBuilder<T extends Fsm, E> {
|
||||||
|
|
||||||
private final FsmBuilder<T,E> fsmBuilder;
|
private final FsmBuilder<T,E> fsmBuilder;
|
||||||
private final StateBuilder<T, E> stateBuilder;
|
|
||||||
private String from;
|
private String from;
|
||||||
private String to;
|
private String to;
|
||||||
private Condition<T,E> condition;
|
private Condition<T,E> condition;
|
||||||
|
|
||||||
ConditionBuilder(FsmBuilder<T,E> fsmBuilder) {
|
ConditionBuilder(FsmBuilder<T,E> fsmBuilder) {
|
||||||
this.fsmBuilder = fsmBuilder;
|
this.fsmBuilder = fsmBuilder;
|
||||||
this.stateBuilder = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConditionBuilder(FsmBuilder<T,E> fsmBuilder, StateBuilder<T, E> stateBuilder, String from) {
|
|
||||||
this.fsmBuilder = fsmBuilder;
|
|
||||||
this.stateBuilder = stateBuilder;
|
|
||||||
this.from = from;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConditionBuilder<T,E> from(String from) {
|
public ConditionBuilder<T,E> from(String from) {
|
||||||
@ -39,12 +31,4 @@ public class ConditionBuilder<T extends Fsm, E> {
|
|||||||
return fsmBuilder;
|
return fsmBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StateBuilder<T, E> endTransition() {
|
|
||||||
if (stateBuilder == null) {
|
|
||||||
throw new IllegalStateException("Use '.end()' instead");
|
|
||||||
}
|
|
||||||
end();
|
|
||||||
return stateBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,13 +13,10 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static java.lang.String.format;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* <b>Final State Machine</b>
|
* <b>Final State Machine</b>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* <p>
|
* <p>
|
||||||
* Each state machine must be prepared with:
|
* Each state machine must be prepared with:
|
||||||
* <ol>
|
* <ol>
|
||||||
@ -28,6 +25,7 @@ import static java.lang.String.format;
|
|||||||
* <li>Intermediate states - optionally</li>
|
* <li>Intermediate states - optionally</li>
|
||||||
* <li>All transitions needed</li>
|
* <li>All transitions needed</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Each {@link State} may be specified with handlers:
|
* Each {@link State} may be specified with handlers:
|
||||||
@ -36,6 +34,7 @@ import static java.lang.String.format;
|
|||||||
* <li>After handler - is called right before FSM changes FROM this state to another</li>
|
* <li>After handler - is called right before FSM changes FROM this state to another</li>
|
||||||
* <li>Processor - the method to process events</li>
|
* <li>Processor - the method to process events</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Transition is the Rule providing FSM the possibility to change between states.
|
* Transition is the Rule providing FSM the possibility to change between states.
|
||||||
@ -47,12 +46,12 @@ import static java.lang.String.format;
|
|||||||
* <li>Condition - optionally. If specified, the FSM will check the condition in order to check the possibility
|
* <li>Condition - optionally. If specified, the FSM will check the condition in order to check the possibility
|
||||||
* to change from FROM State into TO State</li>
|
* to change from FROM State into TO State</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Simple way to use it - to construct an inherited class specified with the type of events to be processed
|
* Simple way to use it - to construct an inherited class specified with the type of events to be processed
|
||||||
* during transitions.
|
* during transitions.
|
||||||
*
|
* </p>
|
||||||
* since 2.1.5
|
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
@ -78,66 +77,47 @@ import static java.lang.String.format;
|
|||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* or since 2.2.1
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {@code
|
|
||||||
* SimpleFsm<String> simpleFsm = Fsm
|
|
||||||
* .<SimpleFsm<String>, String>from(SimpleFsm::new)
|
|
||||||
* .withStates()
|
|
||||||
* .from("init")
|
|
||||||
* .withBeforeHandler(fsm -> initBefore.set(true))
|
|
||||||
* .withAfterHandler(fsm -> initAfter.set(true))
|
|
||||||
* .withProcessor((fsm, event) -> initProcess.set(true))
|
|
||||||
* .withTransition()
|
|
||||||
* .to("finish")
|
|
||||||
* .checking((fsm, event) -> true)
|
|
||||||
* .endTransition()
|
|
||||||
* .end()
|
|
||||||
* .finish("finish")
|
|
||||||
* .withBeforeHandler(fsm -> finishBefore.set(true))
|
|
||||||
* .withAfterHandler(fsm -> finishAfter.set(true))
|
|
||||||
* .withProcessor((fsm, event) -> finishProcess.set(true))
|
|
||||||
* .end()
|
|
||||||
* .create();
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* <p>
|
* <p>
|
||||||
* Otherwise you are able to use Old syntax:
|
* Otherwise you are able to use Old syntax:
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
|
* {@code
|
||||||
* NamedFsm namedFsm = new NamedFsm().setName("TEST FSM");
|
* NamedFsm namedFsm = new NamedFsm().setName("TEST FSM");
|
||||||
* namedFsm.initState(new State<String>("init") {
|
* namedFsm.initState(new State<String>("init") {
|
||||||
|
* @Override
|
||||||
* public void process(String event) {
|
* public void process(String event) {
|
||||||
* initStatedProcessed.set(true);
|
* initStatedProcessed.set(true);
|
||||||
* }
|
* }
|
||||||
* });
|
* });
|
||||||
*
|
*
|
||||||
* namedFsm.addTransition("init", new State<String>("first", true) {
|
* namedFsm.addTransition("init", new State<String>("first", true) {
|
||||||
|
* @Override
|
||||||
* public void process(String event) {
|
* public void process(String event) {
|
||||||
* firstStatedProcessed.set(true);
|
* firstStatedProcessed.set(true);
|
||||||
* }
|
* }
|
||||||
* });
|
* });
|
||||||
*
|
*
|
||||||
* namedFsm.addTransition("init", new State<String>("another", true) {
|
* namedFsm.addTransition("init", new State<String>("another", true) {
|
||||||
|
* @Override
|
||||||
* public void process(String event) {
|
* public void process(String event) {
|
||||||
* anotherStatedProcessed.set(true);
|
* anotherStatedProcessed.set(true);
|
||||||
* }
|
* }
|
||||||
* }, (fsm, event) -> false);
|
* }, (fsm, event) -> false);
|
||||||
*
|
*
|
||||||
* namedFsm.init();
|
* namedFsm.init();
|
||||||
* </pre>
|
* }
|
||||||
|
* </pre> *
|
||||||
* {@link SimpleFsm}
|
* {@link SimpleFsm}
|
||||||
*/
|
*/
|
||||||
public class Fsm<T extends Fsm, E> {
|
public class Fsm<T extends Fsm, E> {
|
||||||
|
|
||||||
protected boolean done = false;
|
private boolean done = false;
|
||||||
protected State<E> initialState;
|
private State<E> initialState;
|
||||||
protected State<E> currentState;
|
private State<E> currentState;
|
||||||
protected State<E> previousState;
|
private State<E> previousState;
|
||||||
protected final Map<String, State<E>> states = new HashMap<>();
|
private final Map<String, State<E>> states = new HashMap<>();
|
||||||
protected final Map<String, Map<String, Condition<T, E>>> transitions = new HashMap<>();
|
private final Map<String, Map<String, Condition<T, E>>> transitions = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiate a builder
|
* Initiate a builder
|
||||||
@ -176,9 +156,9 @@ public class Fsm<T extends Fsm, E> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
currentState.process(event);
|
currentState.process(event);
|
||||||
|
currentState.afterEvent();
|
||||||
if (currentState.isFinish()) {
|
if (currentState.isFinish()) {
|
||||||
done = true;
|
done = true;
|
||||||
currentState.afterEvent();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switchToNextState(event);
|
switchToNextState(event);
|
||||||
@ -268,19 +248,6 @@ public class Fsm<T extends Fsm, E> {
|
|||||||
addTransition(fromState, toState.getName(), condition);
|
addTransition(fromState, toState.getName(), condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides a possibility to initialize FSM in custom State
|
|
||||||
* @param name State name (must be added before)
|
|
||||||
*/
|
|
||||||
protected void setCurrentState(String name) {
|
|
||||||
try {
|
|
||||||
this.currentState = this.states.get(name);
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
throw new NotInitializedException(format("Unable to find state '%s'", name), e);
|
|
||||||
}
|
|
||||||
this.done = currentState.isFinish();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void switchToNextState(E event) {
|
private void switchToNextState(E event) {
|
||||||
if (!transitions.containsKey(currentState.getName())) {
|
if (!transitions.containsKey(currentState.getName())) {
|
||||||
throw new TransitionMissedException(currentState.getName());
|
throw new TransitionMissedException(currentState.getName());
|
||||||
@ -305,10 +272,9 @@ public class Fsm<T extends Fsm, E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void nextState(State<E> state, E event) {
|
private void nextState(State<E> state, E event) {
|
||||||
currentState.afterEvent();
|
state.beforeEvent();
|
||||||
previousState = currentState;
|
previousState = currentState;
|
||||||
currentState = state;
|
currentState = state;
|
||||||
currentState.beforeEvent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkStateExist(String name) throws StateAlreadyExistsException {
|
private void checkStateExist(String name) throws StateAlreadyExistsException {
|
||||||
|
|||||||
@ -31,11 +31,6 @@ public class FsmBuilder<T extends Fsm, E> {
|
|||||||
return fsm;
|
return fsm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T startingAt(String name) {
|
|
||||||
fsm.setCurrentState(name);
|
|
||||||
return fsm;
|
|
||||||
}
|
|
||||||
|
|
||||||
T getFsm() {
|
T getFsm() {
|
||||||
return fsm;
|
return fsm;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,8 +56,4 @@ public class StateBuilder<T extends Fsm, E> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConditionBuilder<T,E> withTransition() {
|
|
||||||
return new ConditionBuilder<>(fsmBuilder, this, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,11 +2,11 @@ package me.bvn13.fsm;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* State handler
|
* State handler
|
||||||
* @param <T> class inherited from {@link Fsm}
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface StateHandler<T extends Fsm> {
|
public interface StateHandler<T extends Fsm> {
|
||||||
|
|
||||||
void handle(T fsm);
|
void handle(T fms);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,6 @@ package me.bvn13.fsm;
|
|||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface StateProcessor<T extends Fsm, E> {
|
public interface StateProcessor<T extends Fsm, E> {
|
||||||
|
|
||||||
void process(T fsm, E event);
|
void process(T fms, E event);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import me.bvn13.fsm.StateHandler;
|
|||||||
|
|
||||||
public class DummyHandler<T extends Fsm> implements StateHandler<T> {
|
public class DummyHandler<T extends Fsm> implements StateHandler<T> {
|
||||||
@Override
|
@Override
|
||||||
public void handle(T fsm) {
|
public void handle(T fms) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import me.bvn13.fsm.StateProcessor;
|
|||||||
|
|
||||||
public class DummyProcessor<T extends Fsm,E> implements StateProcessor<T,E> {
|
public class DummyProcessor<T extends Fsm,E> implements StateProcessor<T,E> {
|
||||||
@Override
|
@Override
|
||||||
public void process(T fsm, E event) {
|
public void process(T fms, E event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,8 +2,6 @@ package me.bvn13.fsm.exceptions;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static java.lang.String.format;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* is thrown if there are more than 1 appropriate transition from current state
|
* is thrown if there are more than 1 appropriate transition from current state
|
||||||
*/
|
*/
|
||||||
@ -12,14 +10,11 @@ public class AmbiguousTransitionException extends FsmException {
|
|||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
public AmbiguousTransitionException(String from, List<String> next) {
|
public AmbiguousTransitionException(String from, List<String> next) {
|
||||||
super(format("Ambiguous transition from state %s. Candidates are: %s", from, join(next)));
|
super("");
|
||||||
|
String msg = "";
|
||||||
|
for (String to : next) {
|
||||||
|
msg += (msg.length() > 0 ? ", " : "") + to;
|
||||||
}
|
}
|
||||||
|
this.message = String.format("Ambiguous transition from state %s. Candidates are: %s", from, msg);
|
||||||
private static String join(List<String> list) {
|
|
||||||
StringBuilder msg = new StringBuilder();
|
|
||||||
for (String to : list) {
|
|
||||||
msg.append(msg.length() > 0 ? ", " : "").append(to);
|
|
||||||
}
|
|
||||||
return msg.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package me.bvn13.fsm.exceptions;
|
package me.bvn13.fsm.exceptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* is thrown in case of adding a transition <code>FROM - TO</code>, but it is already defined
|
* is thrown in case of adding a transition <code>FROM->TO</code>, but it is already defined
|
||||||
*/
|
*/
|
||||||
public class ConditionAlreadyExistsException extends FsmException {
|
public class ConditionAlreadyExistsException extends FsmException {
|
||||||
public ConditionAlreadyExistsException(String from, String to) {
|
public ConditionAlreadyExistsException(String from, String to) {
|
||||||
|
|||||||
@ -1,14 +1,23 @@
|
|||||||
package me.bvn13.fsm.exceptions;
|
package me.bvn13.fsm.exceptions;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parent FSM exception class
|
* Parent FSM exception class
|
||||||
*/
|
*/
|
||||||
public class FsmException extends RuntimeException {
|
public class FsmException extends RuntimeException {
|
||||||
|
protected String message;
|
||||||
public FsmException(String message) {
|
public FsmException(String message) {
|
||||||
super(message);
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
protected String getStackTraceString() {
|
||||||
public FsmException(String message, Throwable cause) {
|
StringWriter sw = new StringWriter();
|
||||||
super(message, cause);
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
this.printStackTrace(pw);
|
||||||
|
return sw.toString();
|
||||||
|
}
|
||||||
|
public void printStackTrace() {
|
||||||
|
System.out.println(String.format("FSMException: %s / %s", message, getStackTraceString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,12 +7,7 @@ public class NotInitializedException extends FsmException {
|
|||||||
public NotInitializedException(String message) {
|
public NotInitializedException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotInitializedException(String message, Exception e) {
|
|
||||||
super(message, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NotInitializedException() {
|
public NotInitializedException() {
|
||||||
super("FSM is not initialized");
|
super("FSM is not inited");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import org.junit.Assert;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by bvn13 on 28.12.2017.
|
* Created by bvn13 on 28.12.2017.
|
||||||
@ -93,8 +92,6 @@ public class FsmTest {
|
|||||||
.withAfterHandler(fsm -> initAfter.set(true))
|
.withAfterHandler(fsm -> initAfter.set(true))
|
||||||
.withProcessor((fsm, event) -> initProcess.set(true))
|
.withProcessor((fsm, event) -> initProcess.set(true))
|
||||||
.end()
|
.end()
|
||||||
.state("intermediate")
|
|
||||||
.end()
|
|
||||||
.finish("finish")
|
.finish("finish")
|
||||||
.withBeforeHandler(fsm -> finishBefore.set(true))
|
.withBeforeHandler(fsm -> finishBefore.set(true))
|
||||||
.withAfterHandler(fsm -> finishAfter.set(true))
|
.withAfterHandler(fsm -> finishAfter.set(true))
|
||||||
@ -102,21 +99,17 @@ public class FsmTest {
|
|||||||
.end()
|
.end()
|
||||||
.withTransition()
|
.withTransition()
|
||||||
.from("init")
|
.from("init")
|
||||||
.to("intermediate")
|
|
||||||
.checking((fsm, event) -> true)
|
|
||||||
.end()
|
|
||||||
.withTransition()
|
|
||||||
.from("intermediate")
|
|
||||||
.to("finish")
|
.to("finish")
|
||||||
.checking((fsm, event) -> true)
|
.checking((fsm, event) -> true)
|
||||||
.end()
|
.end()
|
||||||
.create();
|
.create()
|
||||||
|
;
|
||||||
|
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
simpleFsm.process("");
|
|
||||||
simpleFsm.process("");
|
simpleFsm.process("");
|
||||||
|
|
||||||
Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
|
//Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
|
||||||
Assert.assertTrue(initBefore.get());
|
Assert.assertTrue(initBefore.get());
|
||||||
Assert.assertTrue(initProcess.get());
|
Assert.assertTrue(initProcess.get());
|
||||||
Assert.assertTrue(initAfter.get());
|
Assert.assertTrue(initAfter.get());
|
||||||
@ -126,218 +119,4 @@ public class FsmTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void newSyntaxCustomState() {
|
|
||||||
|
|
||||||
AtomicBoolean initBefore = new AtomicBoolean(false);
|
|
||||||
AtomicBoolean initAfter = new AtomicBoolean(false);
|
|
||||||
AtomicBoolean initProcess = new AtomicBoolean(false);
|
|
||||||
AtomicBoolean intermediateBefore = new AtomicBoolean(false);
|
|
||||||
AtomicBoolean intermediateAfter = new AtomicBoolean(false);
|
|
||||||
AtomicBoolean intermediateProcess = new AtomicBoolean(false);
|
|
||||||
AtomicBoolean finishBefore = new AtomicBoolean(false);
|
|
||||||
AtomicBoolean finishAfter = new AtomicBoolean(false);
|
|
||||||
AtomicBoolean finishProcess = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
|
|
||||||
SimpleFsm<String> simpleFsm = Fsm
|
|
||||||
.<SimpleFsm<String>, String>from(SimpleFsm::new)
|
|
||||||
.withStates()
|
|
||||||
.from("init")
|
|
||||||
.withBeforeHandler(fsm -> initBefore.set(true))
|
|
||||||
.withAfterHandler(fsm -> initAfter.set(true))
|
|
||||||
.withProcessor((fsm, event) -> initProcess.set(true))
|
|
||||||
.end()
|
|
||||||
.state("intermediate")
|
|
||||||
.withBeforeHandler(fsm -> intermediateBefore.set(true))
|
|
||||||
.withAfterHandler(fsm -> intermediateAfter.set(true))
|
|
||||||
.withProcessor((fsm, event) -> intermediateProcess.set(true))
|
|
||||||
.end()
|
|
||||||
.finish("finish")
|
|
||||||
.withBeforeHandler(fsm -> finishBefore.set(true))
|
|
||||||
.withAfterHandler(fsm -> finishAfter.set(true))
|
|
||||||
.withProcessor((fsm, event) -> finishProcess.set(true))
|
|
||||||
.end()
|
|
||||||
.withTransition()
|
|
||||||
.from("init")
|
|
||||||
.to("intermediate")
|
|
||||||
.checking((fsm, event) -> true)
|
|
||||||
.end()
|
|
||||||
.withTransition()
|
|
||||||
.from("intermediate")
|
|
||||||
.to("finish")
|
|
||||||
.checking((fsm, event) -> true)
|
|
||||||
.end()
|
|
||||||
.startingAt("intermediate")
|
|
||||||
;
|
|
||||||
|
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
simpleFsm.process("");
|
|
||||||
|
|
||||||
Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
|
|
||||||
Assert.assertFalse(initBefore.get());
|
|
||||||
Assert.assertFalse(initProcess.get());
|
|
||||||
Assert.assertFalse(initAfter.get());
|
|
||||||
Assert.assertFalse(intermediateBefore.get());
|
|
||||||
Assert.assertTrue(intermediateAfter.get());
|
|
||||||
Assert.assertTrue(intermediateProcess.get());
|
|
||||||
Assert.assertTrue(finishBefore.get());
|
|
||||||
Assert.assertFalse(finishProcess.get());
|
|
||||||
Assert.assertFalse(finishAfter.get());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void newSyntaxCountingEveryStep() {
|
|
||||||
|
|
||||||
Counter initCounter = new Counter();
|
|
||||||
Counter firstIntermediateCounter = new Counter();
|
|
||||||
Counter secondIntermediateCounter = new Counter();
|
|
||||||
Counter finishCounter = new Counter();
|
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
|
|
||||||
SimpleFsm<String> simpleFsm = Fsm
|
|
||||||
.<SimpleFsm<String>, String>from(SimpleFsm::new)
|
|
||||||
.withStates()
|
|
||||||
.from("init")
|
|
||||||
.withBeforeHandler(fsm -> initCounter.before.incrementAndGet())
|
|
||||||
.withAfterHandler(fsm -> initCounter.after.incrementAndGet())
|
|
||||||
.withProcessor((fsm, event) -> initCounter.process.incrementAndGet())
|
|
||||||
.end()
|
|
||||||
.state("intermediate-1")
|
|
||||||
.withBeforeHandler(fsm -> firstIntermediateCounter.before.incrementAndGet())
|
|
||||||
.withAfterHandler(fsm -> firstIntermediateCounter.after.incrementAndGet())
|
|
||||||
.withProcessor((fsm, event) -> firstIntermediateCounter.process.incrementAndGet())
|
|
||||||
.end()
|
|
||||||
.state("intermediate-2")
|
|
||||||
.withBeforeHandler(fsm -> secondIntermediateCounter.before.incrementAndGet())
|
|
||||||
.withAfterHandler(fsm -> secondIntermediateCounter.after.incrementAndGet())
|
|
||||||
.withProcessor((fsm, event) -> secondIntermediateCounter.process.incrementAndGet())
|
|
||||||
.end()
|
|
||||||
.finish("finish")
|
|
||||||
.withBeforeHandler(fsm -> finishCounter.before.incrementAndGet())
|
|
||||||
.withAfterHandler(fsm -> finishCounter.after.incrementAndGet())
|
|
||||||
.withProcessor((fsm, event) -> finishCounter.process.incrementAndGet())
|
|
||||||
.end()
|
|
||||||
.withTransition()
|
|
||||||
.from("init")
|
|
||||||
.to("intermediate-1")
|
|
||||||
.checking((fsm, event) -> true)
|
|
||||||
.end()
|
|
||||||
.withTransition()
|
|
||||||
.from("intermediate-1")
|
|
||||||
.to("intermediate-2")
|
|
||||||
.checking((fsm, event) -> true)
|
|
||||||
.end()
|
|
||||||
.withTransition()
|
|
||||||
.from("intermediate-2")
|
|
||||||
.to("finish")
|
|
||||||
.checking((fsm, event) -> true)
|
|
||||||
.end()
|
|
||||||
.create()
|
|
||||||
;
|
|
||||||
|
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
simpleFsm.process("");
|
|
||||||
simpleFsm.process("");
|
|
||||||
simpleFsm.process("");
|
|
||||||
|
|
||||||
Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
|
|
||||||
Assert.assertEquals(1, initCounter.before.get());
|
|
||||||
Assert.assertEquals(1, initCounter.after.get());
|
|
||||||
Assert.assertEquals(1, initCounter.process.get());
|
|
||||||
Assert.assertEquals(1, firstIntermediateCounter.before.get());
|
|
||||||
Assert.assertEquals(1, firstIntermediateCounter.after.get());
|
|
||||||
Assert.assertEquals(1, firstIntermediateCounter.process.get());
|
|
||||||
Assert.assertEquals(1, secondIntermediateCounter.before.get());
|
|
||||||
Assert.assertEquals(1, secondIntermediateCounter.after.get());
|
|
||||||
Assert.assertEquals(1, secondIntermediateCounter.process.get());
|
|
||||||
Assert.assertEquals(1, finishCounter.before.get());
|
|
||||||
Assert.assertEquals(0, finishCounter.after.get());
|
|
||||||
Assert.assertEquals(0, finishCounter.process.get());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void newSyntaxOfTransitions() {
|
|
||||||
|
|
||||||
Counter initCounter = new Counter();
|
|
||||||
Counter firstIntermediateCounter = new Counter();
|
|
||||||
Counter secondIntermediateCounter = new Counter();
|
|
||||||
Counter finishCounter = new Counter();
|
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
|
|
||||||
SimpleFsm<String> simpleFsm = Fsm
|
|
||||||
.<SimpleFsm<String>, String>from(SimpleFsm::new)
|
|
||||||
.withStates()
|
|
||||||
.from("init")
|
|
||||||
.withBeforeHandler(fsm -> initCounter.before.incrementAndGet())
|
|
||||||
.withProcessor((fsm, event) -> initCounter.process.incrementAndGet())
|
|
||||||
.withAfterHandler(fsm -> initCounter.after.incrementAndGet())
|
|
||||||
.withTransition()
|
|
||||||
.to("intermediate-1")
|
|
||||||
.checking((fsm, event) -> true)
|
|
||||||
.endTransition()
|
|
||||||
.end()
|
|
||||||
.state("intermediate-1")
|
|
||||||
.withBeforeHandler(fsm -> firstIntermediateCounter.before.incrementAndGet())
|
|
||||||
.withProcessor((fsm, event) -> firstIntermediateCounter.process.incrementAndGet())
|
|
||||||
.withAfterHandler(fsm -> firstIntermediateCounter.after.incrementAndGet())
|
|
||||||
.withTransition()
|
|
||||||
.from("intermediate-1")
|
|
||||||
.to("intermediate-2")
|
|
||||||
.checking((fsm, event) -> true)
|
|
||||||
.endTransition()
|
|
||||||
.end()
|
|
||||||
.state("intermediate-2")
|
|
||||||
.withBeforeHandler(fsm -> secondIntermediateCounter.before.incrementAndGet())
|
|
||||||
.withProcessor((fsm, event) -> secondIntermediateCounter.process.incrementAndGet())
|
|
||||||
.withAfterHandler(fsm -> secondIntermediateCounter.after.incrementAndGet())
|
|
||||||
.end()
|
|
||||||
.finish("finish")
|
|
||||||
.withBeforeHandler(fsm -> finishCounter.before.incrementAndGet())
|
|
||||||
.withProcessor((fsm, event) -> finishCounter.process.incrementAndGet())
|
|
||||||
.withAfterHandler(fsm -> finishCounter.after.incrementAndGet())
|
|
||||||
.withTransition()
|
|
||||||
.from("intermediate-2")
|
|
||||||
.to("finish")
|
|
||||||
.checking((fsm, event) -> true)
|
|
||||||
.endTransition()
|
|
||||||
.end()
|
|
||||||
.create()
|
|
||||||
;
|
|
||||||
|
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
simpleFsm.process("");
|
|
||||||
simpleFsm.process("");
|
|
||||||
simpleFsm.process("");
|
|
||||||
|
|
||||||
Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
|
|
||||||
Assert.assertEquals(1, initCounter.before.get());
|
|
||||||
Assert.assertEquals(1, initCounter.after.get());
|
|
||||||
Assert.assertEquals(1, initCounter.process.get());
|
|
||||||
Assert.assertEquals(1, firstIntermediateCounter.before.get());
|
|
||||||
Assert.assertEquals(1, firstIntermediateCounter.after.get());
|
|
||||||
Assert.assertEquals(1, firstIntermediateCounter.process.get());
|
|
||||||
Assert.assertEquals(1, secondIntermediateCounter.before.get());
|
|
||||||
Assert.assertEquals(1, secondIntermediateCounter.after.get());
|
|
||||||
Assert.assertEquals(1, secondIntermediateCounter.process.get());
|
|
||||||
Assert.assertEquals(1, finishCounter.before.get());
|
|
||||||
Assert.assertEquals(0, finishCounter.after.get());
|
|
||||||
Assert.assertEquals(0, finishCounter.process.get());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Counter {
|
|
||||||
final AtomicInteger before = new AtomicInteger(0);
|
|
||||||
final AtomicInteger after = new AtomicInteger(0);
|
|
||||||
final AtomicInteger process = new AtomicInteger(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user