diff --git a/src/main/java/com/serliunx/statemanagement/machine/AbstractStateMachine.java b/src/main/java/com/serliunx/statemanagement/machine/AbstractStateMachine.java index 2df3eec..2715ad0 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/AbstractStateMachine.java +++ b/src/main/java/com/serliunx/statemanagement/machine/AbstractStateMachine.java @@ -6,7 +6,6 @@ import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper; import com.serliunx.statemanagement.manager.AbstractStateManager; import java.util.List; -import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; @@ -29,22 +28,15 @@ public abstract class AbstractStateMachine extends AbstractStateManager im /** * 默认的构造函数 * - * @param entryHandlers 进入事件处理器集合 - * @param leaveHandlers 离开事件处理器集合 - * @param exchangeHandlers 交换事件处理器集合 - * @param executor 异步执行器 - * @param async 是否异步执行 + * @param stateList 状态列表 + * @param context 状态机上下文 */ - AbstractStateMachine(List stateList, - Map>> entryHandlers, - Map>> leaveHandlers, - Map>> exchangeHandlers, - Map>>> eventRegistries, - Executor executor, - Boolean async - ) { + public AbstractStateMachine(List stateList, StateMachineContext context) { super(stateList); - context = new StateMachineContext<>(entryHandlers, leaveHandlers, exchangeHandlers, eventRegistries, executor, async); + this.context = context; + + // 设置初始状态 + tryInitialState(); } @Override @@ -303,4 +295,13 @@ public abstract class AbstractStateMachine extends AbstractStateManager im stateHandler.handle(params); }); } + + /** + * 尝试设置初始状态(如果有指定的话) + */ + private void tryInitialState() { + if (context.initialState != null) { + switchTo(context.initialState, false); + } + } } diff --git a/src/main/java/com/serliunx/statemanagement/machine/DefaultConcurrentStateMachine.java b/src/main/java/com/serliunx/statemanagement/machine/DefaultConcurrentStateMachine.java index 4e80863..a10ad7f 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/DefaultConcurrentStateMachine.java +++ b/src/main/java/com/serliunx/statemanagement/machine/DefaultConcurrentStateMachine.java @@ -23,13 +23,15 @@ public class DefaultConcurrentStateMachine extends AbstractStateMachine im private final AtomicInteger index = new AtomicInteger(0); DefaultConcurrentStateMachine(List stateList, - Map>> entryHandlers, - Map>> leaveHandlers, - Map>> exchangeHandlers, - Map>>> eventRegistries, - Executor executor, - Boolean async) { - super(stateList, entryHandlers, leaveHandlers, exchangeHandlers, eventRegistries, executor, async); + Map>> entryHandlers, + Map>> leaveHandlers, + Map>> exchangeHandlers, + Map>>> eventRegistries, + Executor executor, + Boolean async, + S initialState + ) { + super(stateList, new StateMachineContext<>(entryHandlers, leaveHandlers, exchangeHandlers, eventRegistries, executor, async, initialState)); } @Override diff --git a/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java b/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java index 143a201..59e1d50 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java +++ b/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java @@ -31,8 +31,10 @@ public class StandardStateMachine extends AbstractStateMachine implements Map>> exchangeHandlers, Map>>> eventRegistries, Executor executor, - Boolean async + Boolean async, + S initialState ) { - super(stateList, entryHandlers, leaveHandlers, exchangeHandlers, eventRegistries, executor, async); + super(stateList, new StateMachineContext<>(entryHandlers, leaveHandlers, exchangeHandlers, eventRegistries, + executor, async, initialState)); } } diff --git a/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java b/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java index 087a4cf..257027f 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java +++ b/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java @@ -32,6 +32,10 @@ public final class StateMachineBuilder { * 状态机类型 */ private StateMachineType type = StateMachineType.STANDARD; + /** + * 初始化状态 + */ + private S initialState; /** * 各种事件 @@ -49,6 +53,15 @@ public final class StateMachineBuilder { this(Arrays.asList(states)); } + /** + * 定义初始状态 + * + * @param initialState 初始状态 + */ + public StateMachineBuilder withInitial(S initialState) { + this.initialState = initialState; + return this; + } /** * 添加交换事件 @@ -252,10 +265,10 @@ public final class StateMachineBuilder { } if (type.equals(StateMachineType.STANDARD)) { return (M)new StandardStateMachine<>(stateList, entryHandlers, - leaveHandlers, exchangeHandlers, eventRegistries, executor, async); + leaveHandlers, exchangeHandlers, eventRegistries, executor, async, initialState); } else if (type.equals(StateMachineType.CONCURRENT)) { return (M)new DefaultConcurrentStateMachine<>(stateList, entryHandlers, - leaveHandlers, exchangeHandlers, eventRegistries, executor, async); + leaveHandlers, exchangeHandlers, eventRegistries, executor, async, initialState); } throw new IllegalArgumentException("未知的状态机类型: " + type); } diff --git a/src/main/java/com/serliunx/statemanagement/machine/StateMachineContext.java b/src/main/java/com/serliunx/statemanagement/machine/StateMachineContext.java index 20bf5ea..0756da3 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/StateMachineContext.java +++ b/src/main/java/com/serliunx/statemanagement/machine/StateMachineContext.java @@ -7,9 +7,6 @@ import com.serliunx.statemanagement.support.ExecutorUtils; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; /** @@ -47,13 +44,18 @@ public final class StateMachineContext { * 当具体的执行器没有指定是否异步时, 将根据该值决定是否异步执行. */ final Boolean async; + /** + * 初始化状态 + */ + final S initialState; - StateMachineContext(Map>> entryHandlers, - Map>> leaveHandlers, - Map>> exchangeHandlers, - Map>>> eventRegistries, - Executor executor, - Boolean async + public StateMachineContext(Map>> entryHandlers, + Map>> leaveHandlers, + Map>> exchangeHandlers, + Map>>> eventRegistries, + Executor executor, + Boolean async, + S initialState ) { this.entryHandlers = entryHandlers; this.leaveHandlers = leaveHandlers; @@ -61,6 +63,17 @@ public final class StateMachineContext { this.executor = executorAutoConfiguration(executor); this.async = async; this.eventRegistries = eventRegistries; + this.initialState = initialState; + } + + public StateMachineContext(Map>> entryHandlers, + Map>> leaveHandlers, + Map>> exchangeHandlers, + Map>>> eventRegistries, + Executor executor, + Boolean async + ) { + this(entryHandlers, leaveHandlers, exchangeHandlers, eventRegistries, executor, async, null); } /** diff --git a/src/main/java/com/serliunx/statemanagement/manager/AbstractStateManager.java b/src/main/java/com/serliunx/statemanagement/manager/AbstractStateManager.java index b96615c..1187316 100644 --- a/src/main/java/com/serliunx/statemanagement/manager/AbstractStateManager.java +++ b/src/main/java/com/serliunx/statemanagement/manager/AbstractStateManager.java @@ -26,6 +26,11 @@ public abstract class AbstractStateManager implements StateManager { */ private volatile int index; + /** + * 默认状态序号 + */ + private int defaultIndex = 0; + /** * 锁 */ @@ -180,7 +185,7 @@ public abstract class AbstractStateManager implements StateManager { * @return 是第一个时返回真, 否则返回假. */ protected boolean isFirst() { - return index == getDefault(); + return index == 0; } /** @@ -203,6 +208,15 @@ public abstract class AbstractStateManager implements StateManager { * 状态序号默认值(等同于默认状态) */ protected int getDefault() { - return 0; + return defaultIndex; + } + + /** + * 设置默认值 + * + * @param defaultIndex 默认值 + */ + protected void setDefault(int defaultIndex) { + this.defaultIndex = defaultIndex; } } diff --git a/src/test/java/com/serliunx/statemanagement/MachineTest.java b/src/test/java/com/serliunx/statemanagement/MachineTest.java index 73a58e8..949ed3b 100644 --- a/src/test/java/com/serliunx/statemanagement/MachineTest.java +++ b/src/test/java/com/serliunx/statemanagement/MachineTest.java @@ -7,8 +7,6 @@ import com.serliunx.statemanagement.support.PrinterEvent; import com.serliunx.statemanagement.support.PrinterState; import org.junit.Test; -import java.util.concurrent.Executors; - /** * 状态机测试 * @@ -21,23 +19,12 @@ public class MachineTest { @Test public void testStandardStateMachine() throws Exception { StateMachine stateMachine = StateMachineBuilder.from(PrinterState.values()) - .async(false) + .async(true) .standard() - .exchange(PrinterState.IDLE, PrinterState.SCANNING, h -> { - System.out.println("hello~"); - }) - .whenLeave(PrinterState.IDLE, h -> { - System.out.println(Thread.currentThread().getName() + ": leave IDLE"); - }) - .whenEntry(PrinterState.STOPPING, h -> { - System.out.println(Thread.currentThread().getName() + ": entry STOPPING, from " + h.getFrom()); - }) - .whenEntry(PrinterState.STOPPED, h -> { - System.out.println(Thread.currentThread().getName() + ": entry STOPPED, from " + h.getFrom()); - }) + .withInitial(PrinterState.STOPPING) .build(); - stateMachine.switchTo(PrinterState.SCANNING); + System.out.println(stateMachine.current()); } @Test