From a1bdb96638d9ecd64e80f043973354b7368aab94 Mon Sep 17 00:00:00 2001 From: SerLiunx-ctrl <17689543@qq.com> Date: Fri, 24 Jan 2025 09:43:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=8A=B6=E6=80=81=E6=9C=BA=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=8F=91=E5=B8=83=E3=80=81=E8=AE=A2=E9=98=85=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../machine/AbstractStateMachine.java | 7 +++++++ .../machine/StandardStateMachine.java | 9 +++++++-- .../machine/StateMachineBuilder.java | 16 +++++++++++++++- .../serliunx/statemanagement/MachineTest.java | 13 +++++++++++-- .../statemanagement/support/PrinterEvent.java | 12 ++++++++++++ 5 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 src/test/java/com/serliunx/statemanagement/support/PrinterEvent.java diff --git a/src/main/java/com/serliunx/statemanagement/machine/AbstractStateMachine.java b/src/main/java/com/serliunx/statemanagement/machine/AbstractStateMachine.java index c9db829..eeca464 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/AbstractStateMachine.java +++ b/src/main/java/com/serliunx/statemanagement/machine/AbstractStateMachine.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; +import java.util.function.Consumer; /** * 状态机抽象实现, 实现最基本功能 @@ -31,6 +32,10 @@ public abstract class AbstractStateMachine extends AbstractStateManager im * 交换事件集合 */ protected final Map>> exchangeHandlers; + /** + * 事件注册集合 + */ + protected final Map>>> eventRegistries; /** * 异步执行器 */ @@ -55,6 +60,7 @@ public abstract class AbstractStateMachine extends AbstractStateManager im Map>> entryHandlers, Map>> leaveHandlers, Map>> exchangeHandlers, + Map>>> eventRegistries, Executor executor, Boolean async ) { @@ -64,6 +70,7 @@ public abstract class AbstractStateMachine extends AbstractStateManager im this.exchangeHandlers = exchangeHandlers; this.executor = executor; this.async = async; + this.eventRegistries = eventRegistries; } @Override diff --git a/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java b/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java index 8d1c7d4..f3bd761 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java +++ b/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java @@ -5,6 +5,7 @@ import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; +import java.util.function.Consumer; /** * 状态机的标准实现 @@ -28,14 +29,18 @@ public class StandardStateMachine extends AbstractStateMachine implements Map>> entryHandlers, Map>> leaveHandlers, Map>> exchangeHandlers, + Map>>> eventRegistries, Executor executor, Boolean async ) { - super(stateList, entryHandlers, leaveHandlers, exchangeHandlers, executor, async); + super(stateList, entryHandlers, leaveHandlers, exchangeHandlers, eventRegistries, executor, async); } @Override public void publish(Object event) { - + List>> consumers = eventRegistries.get(event); + if (consumers != null) { + consumers.forEach(consumer -> consumer.accept(this)); + } } } diff --git a/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java b/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java index 420a33f..f64e2d0 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java +++ b/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java @@ -5,6 +5,7 @@ import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper; import java.util.*; import java.util.concurrent.Executor; +import java.util.function.Consumer; /** * 状态机构建 @@ -38,6 +39,7 @@ public final class StateMachineBuilder { private final Map>> entryHandlers = new HashMap<>(64); private final Map>> leaveHandlers = new HashMap<>(64); private final Map>> exchangeHandlers = new HashMap<>(64); + private final Map>>> eventRegistries = new HashMap<>(64); private StateMachineBuilder(List states) { this.stateList = states; @@ -169,6 +171,18 @@ public final class StateMachineBuilder { return whenEntry(state, handler, null); } + /** + * 注册当前状态机感兴趣的事件 + * + * @param event 事件 + * @param logic 切换逻辑 + */ + public StateMachineBuilder whenHappened(Object event, Consumer> logic) { + List>> consumers = eventRegistries.computeIfAbsent(event, k -> new ArrayList<>()); + consumers.add(logic); + return this; + } + /** * 指定状态机的执行器 *

@@ -238,7 +252,7 @@ public final class StateMachineBuilder { } if (type.equals(StateMachineType.STANDARD)) { return (M)new StandardStateMachine<>(stateList, entryHandlers, - leaveHandlers, exchangeHandlers, executor, async); + leaveHandlers, exchangeHandlers, eventRegistries, executor, async); } throw new IllegalArgumentException("未知的状态机类型: " + type); } diff --git a/src/test/java/com/serliunx/statemanagement/MachineTest.java b/src/test/java/com/serliunx/statemanagement/MachineTest.java index 7bf122d..509ca06 100644 --- a/src/test/java/com/serliunx/statemanagement/MachineTest.java +++ b/src/test/java/com/serliunx/statemanagement/MachineTest.java @@ -2,6 +2,7 @@ package com.serliunx.statemanagement; import com.serliunx.statemanagement.machine.StateMachine; import com.serliunx.statemanagement.machine.StateMachineBuilder; +import com.serliunx.statemanagement.support.PrinterEvent; import com.serliunx.statemanagement.support.PrinterState; import lombok.extern.slf4j.Slf4j; import org.junit.Test; @@ -21,7 +22,7 @@ public class MachineTest { @Test public void testStandardStateMachine() throws Exception { StateMachine stateMachine = StateMachineBuilder.from(PrinterState.values()) - .async() + .async(false) .standard() .executor(Executors.newFixedThreadPool(16)) .whenLeave(PrinterState.IDLE, h -> { @@ -33,9 +34,17 @@ public class MachineTest { .whenEntry(PrinterState.STOPPED, h -> { System.out.println(Thread.currentThread().getName() + ": entry STOPPED, from " + h.getFrom()); }) + .whenHappened(PrinterEvent.TURN_ON, m -> { + m.switchTo(PrinterState.SCANNING); + }) + .whenHappened(PrinterEvent.TURN_OFF, m -> { + if (m.switchTo(PrinterState.STOPPING)) + m.switchTo(PrinterState.STOPPED); + }) .build(); - stateMachine.switchNext(false); + stateMachine.publish(PrinterEvent.TURN_ON); + stateMachine.close(); } } diff --git a/src/test/java/com/serliunx/statemanagement/support/PrinterEvent.java b/src/test/java/com/serliunx/statemanagement/support/PrinterEvent.java new file mode 100644 index 0000000..5707ea4 --- /dev/null +++ b/src/test/java/com/serliunx/statemanagement/support/PrinterEvent.java @@ -0,0 +1,12 @@ +package com.serliunx.statemanagement.support; + +/** + * @author SerLiunx + * @since 2025/1/24 + */ +public enum PrinterEvent { + + TURN_ON, + + TURN_OFF, +}