change: 调整状态机代码结构.
This commit is contained in:
@@ -0,0 +1,251 @@
|
|||||||
|
package com.serliunx.statemanagement.machine;
|
||||||
|
|
||||||
|
import com.serliunx.statemanagement.machine.handler.StateHandler;
|
||||||
|
import com.serliunx.statemanagement.machine.handler.StateHandlerProcessParams;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态机抽象实现, 实现最基本功能
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/12/31
|
||||||
|
*/
|
||||||
|
public abstract class AbstractStateMachine<S> extends AbstractStateManager<S> implements StateMachine<S> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进入事件集合
|
||||||
|
*/
|
||||||
|
protected final Map<S, List<StateHandlerWrapper<S>>> entryHandlers;
|
||||||
|
/**
|
||||||
|
* 离开事件集合
|
||||||
|
*/
|
||||||
|
protected final Map<S, List<StateHandlerWrapper<S>>> leaveHandlers;
|
||||||
|
/**
|
||||||
|
* 交换事件集合
|
||||||
|
*/
|
||||||
|
protected final Map<String, List<StateHandlerWrapper<S>>> exchangeHandlers;
|
||||||
|
/**
|
||||||
|
* 异步执行器
|
||||||
|
*/
|
||||||
|
protected final Executor executor;
|
||||||
|
/**
|
||||||
|
* 是否异步执行
|
||||||
|
* <p>
|
||||||
|
* 当具体的执行器没有指定是否异步时, 将根据该值决定是否异步执行.
|
||||||
|
*/
|
||||||
|
protected final Boolean async;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认的构造函数
|
||||||
|
*
|
||||||
|
* @param entryHandlers 进入事件处理器集合
|
||||||
|
* @param leaveHandlers 离开事件处理器集合
|
||||||
|
* @param exchangeHandlers 交换事件处理器集合
|
||||||
|
* @param executor 异步执行器
|
||||||
|
* @param async 是否异步执行
|
||||||
|
*/
|
||||||
|
AbstractStateMachine(List<S> stateList,
|
||||||
|
Map<S, List<StateHandlerWrapper<S>>> entryHandlers,
|
||||||
|
Map<S, List<StateHandlerWrapper<S>>> leaveHandlers,
|
||||||
|
Map<String, List<StateHandlerWrapper<S>>> exchangeHandlers,
|
||||||
|
Executor executor,
|
||||||
|
Boolean async
|
||||||
|
) {
|
||||||
|
super(stateList);
|
||||||
|
this.entryHandlers = entryHandlers;
|
||||||
|
this.leaveHandlers = leaveHandlers;
|
||||||
|
this.exchangeHandlers = exchangeHandlers;
|
||||||
|
this.executor = executor;
|
||||||
|
this.async = async;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
if (executor == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (executor instanceof ExecutorService) {
|
||||||
|
ExecutorService es = (ExecutorService) executor;
|
||||||
|
es.shutdown();
|
||||||
|
} else if (executor instanceof AutoCloseable) {
|
||||||
|
AutoCloseable ac = (AutoCloseable) executor;
|
||||||
|
ac.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public S switchPrevAndGet() {
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
S oldState = get();
|
||||||
|
prev();
|
||||||
|
S newState = get();
|
||||||
|
invokeHandlers(oldState, newState);
|
||||||
|
return newState;
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public S getAndSwitchPrev() {
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
S oldState = get();
|
||||||
|
prev();
|
||||||
|
S newState = get();
|
||||||
|
invokeHandlers(oldState, newState);
|
||||||
|
return oldState;
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void switchPrev() {
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
S oldState = get();
|
||||||
|
prev();
|
||||||
|
S newState = get();
|
||||||
|
invokeHandlers(oldState, newState);
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public S switchNextAndGet() {
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
S oldState = get();
|
||||||
|
next();
|
||||||
|
S newState = get();
|
||||||
|
invokeHandlers(oldState, newState);
|
||||||
|
return newState;
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public S getAndSwitchNext() {
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
S oldState = get();
|
||||||
|
next();
|
||||||
|
S newState = get();
|
||||||
|
invokeHandlers(oldState, newState);
|
||||||
|
return oldState;
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void switchNext() {
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
S oldState = get();
|
||||||
|
next();
|
||||||
|
S newState = get();
|
||||||
|
invokeHandlers(oldState, newState);
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean switchTo(S state) {
|
||||||
|
int i = indexOf(state);
|
||||||
|
if (i == -1 || i == currentIndex()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
// 重新检查
|
||||||
|
if (i == currentIndex()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
S oldState = get();
|
||||||
|
boolean result = super.switchTo(state);
|
||||||
|
if (result) {
|
||||||
|
S newState = get();
|
||||||
|
invokeHandlers(oldState, newState);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
S oldState = get();
|
||||||
|
super.reset();
|
||||||
|
S newState = get();
|
||||||
|
invokeHandlers(oldState, newState);
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 触发处理器
|
||||||
|
*
|
||||||
|
* @param from 源状态
|
||||||
|
* @param to 目的状态
|
||||||
|
*/
|
||||||
|
protected final void invokeHandlers(S from, S to) {
|
||||||
|
// 触发离开处理器
|
||||||
|
doInvokeHandlers(leaveHandlers.get(from), from, to);
|
||||||
|
|
||||||
|
// 触发进入处理器
|
||||||
|
doInvokeHandlers(entryHandlers.get(to), from, to);
|
||||||
|
|
||||||
|
// 触发交换处理器
|
||||||
|
final String key = from.toString() + "-" + to.toString();
|
||||||
|
doInvokeHandlers(exchangeHandlers.get(key), from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 触发
|
||||||
|
*/
|
||||||
|
private void doInvokeHandlers(List<StateHandlerWrapper<S>> handlerWrappers, S from, S to) {
|
||||||
|
if (handlerWrappers == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 全局的异步状态
|
||||||
|
final boolean isGlobalAsync = async != null && async;
|
||||||
|
|
||||||
|
handlerWrappers.forEach(hw -> {
|
||||||
|
final StateHandler<S> stateHandler;
|
||||||
|
if (hw == null ||
|
||||||
|
(stateHandler = hw.getStateHandler()) == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Executor executorToRun = hw.getExecutor() == null ? executor : hw.getExecutor();
|
||||||
|
final boolean runInAsync = hw.getAsync() == null ? isGlobalAsync : hw.getAsync();
|
||||||
|
final StateHandlerProcessParams<S> params = new StateHandlerProcessParams<>(from, to, null);
|
||||||
|
|
||||||
|
if (runInAsync) {
|
||||||
|
if (executorToRun == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
executorToRun.execute(() -> stateHandler.handle(params));
|
||||||
|
} else {
|
||||||
|
stateHandler.handle(params);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
package com.serliunx.statemanagement.machine;
|
package com.serliunx.statemanagement.machine;
|
||||||
|
|
||||||
import com.serliunx.statemanagement.machine.handler.StateHandler;
|
|
||||||
import com.serliunx.statemanagement.machine.handler.StateHandlerProcessParams;
|
|
||||||
import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper;
|
import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper;
|
||||||
import com.serliunx.statemanagement.manager.AbstractStateManager;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -16,39 +13,16 @@ import java.util.concurrent.Executor;
|
|||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
* @since 2024/12/28
|
* @since 2024/12/28
|
||||||
*/
|
*/
|
||||||
public class StandardStateMachine<S> extends AbstractStateManager<S> implements StateMachine<S> {
|
public class StandardStateMachine<S> extends AbstractStateMachine<S> implements StateMachine<S> {
|
||||||
|
|
||||||
/**
|
|
||||||
* 进入事件集合
|
|
||||||
*/
|
|
||||||
private final Map<S, List<StateHandlerWrapper<S>>> entryHandlers;
|
|
||||||
/**
|
|
||||||
* 离开事件集合
|
|
||||||
*/
|
|
||||||
private final Map<S, List<StateHandlerWrapper<S>>> leaveHandlers;
|
|
||||||
/**
|
|
||||||
* 交换事件集合
|
|
||||||
*/
|
|
||||||
private final Map<String, List<StateHandlerWrapper<S>>> exchangeHandlers;
|
|
||||||
/**
|
|
||||||
* 异步执行器
|
|
||||||
*/
|
|
||||||
private final Executor executor;
|
|
||||||
/**
|
|
||||||
* 是否异步执行
|
|
||||||
* <p>
|
|
||||||
* 当具体的执行器没有指定是否异步时, 将根据该值决定是否异步执行.
|
|
||||||
*/
|
|
||||||
private final Boolean async;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认的构造函数
|
* 默认的构造函数
|
||||||
*
|
*
|
||||||
* @param entryHandlers 进入事件处理器集合
|
* @param entryHandlers 进入事件处理器集合
|
||||||
* @param leaveHandlers 离开事件处理器集合
|
* @param leaveHandlers 离开事件处理器集合
|
||||||
* @param exchangeHandlers 交换事件处理器集合
|
* @param exchangeHandlers 交换事件处理器集合
|
||||||
* @param executor 异步执行器
|
* @param executor 异步执行器
|
||||||
* @param async 是否异步执行
|
* @param async 是否异步执行
|
||||||
*/
|
*/
|
||||||
StandardStateMachine(List<S> stateList,
|
StandardStateMachine(List<S> stateList,
|
||||||
Map<S, List<StateHandlerWrapper<S>>> entryHandlers,
|
Map<S, List<StateHandlerWrapper<S>>> entryHandlers,
|
||||||
@@ -57,180 +31,11 @@ public class StandardStateMachine<S> extends AbstractStateManager<S> implements
|
|||||||
Executor executor,
|
Executor executor,
|
||||||
Boolean async
|
Boolean async
|
||||||
) {
|
) {
|
||||||
super(stateList);
|
super(stateList, entryHandlers, leaveHandlers, exchangeHandlers, executor, async);
|
||||||
this.entryHandlers = entryHandlers;
|
|
||||||
this.leaveHandlers = leaveHandlers;
|
|
||||||
this.exchangeHandlers = exchangeHandlers;
|
|
||||||
this.executor = executor;
|
|
||||||
this.async = async;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public S switchPrevAndGet() {
|
public void publish(Object event) {
|
||||||
try {
|
|
||||||
writeLock.lock();
|
|
||||||
S oldState = get();
|
|
||||||
prev();
|
|
||||||
S newState = get();
|
|
||||||
invokeHandlers(oldState, newState);
|
|
||||||
return newState;
|
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public S getAndSwitchPrev() {
|
|
||||||
try {
|
|
||||||
writeLock.lock();
|
|
||||||
S oldState = get();
|
|
||||||
prev();
|
|
||||||
S newState = get();
|
|
||||||
invokeHandlers(oldState, newState);
|
|
||||||
return oldState;
|
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void switchPrev() {
|
|
||||||
try {
|
|
||||||
writeLock.lock();
|
|
||||||
S oldState = get();
|
|
||||||
prev();
|
|
||||||
S newState = get();
|
|
||||||
invokeHandlers(oldState, newState);
|
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public S switchNextAndGet() {
|
|
||||||
try {
|
|
||||||
writeLock.lock();
|
|
||||||
S oldState = get();
|
|
||||||
next();
|
|
||||||
S newState = get();
|
|
||||||
invokeHandlers(oldState, newState);
|
|
||||||
return newState;
|
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public S getAndSwitchNext() {
|
|
||||||
try {
|
|
||||||
writeLock.lock();
|
|
||||||
S oldState = get();
|
|
||||||
next();
|
|
||||||
S newState = get();
|
|
||||||
invokeHandlers(oldState, newState);
|
|
||||||
return oldState;
|
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void switchNext() {
|
|
||||||
try {
|
|
||||||
writeLock.lock();
|
|
||||||
S oldState = get();
|
|
||||||
next();
|
|
||||||
S newState = get();
|
|
||||||
invokeHandlers(oldState, newState);
|
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean switchTo(S state) {
|
|
||||||
int i = indexOf(state);
|
|
||||||
if (i == -1 || i == currentIndex()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
writeLock.lock();
|
|
||||||
// 重新检查
|
|
||||||
if (i == currentIndex()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
S oldState = get();
|
|
||||||
boolean result = super.switchTo(state);
|
|
||||||
if (result) {
|
|
||||||
S newState = get();
|
|
||||||
invokeHandlers(oldState, newState);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
try {
|
|
||||||
writeLock.lock();
|
|
||||||
S oldState = get();
|
|
||||||
super.reset();
|
|
||||||
S newState = get();
|
|
||||||
invokeHandlers(oldState, newState);
|
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 触发处理器
|
|
||||||
*
|
|
||||||
* @param from 源状态
|
|
||||||
* @param to 目的状态
|
|
||||||
*/
|
|
||||||
private void invokeHandlers(S from, S to) {
|
|
||||||
// 触发离开处理器
|
|
||||||
doInvokeHandlers(leaveHandlers.get(from), from, to);
|
|
||||||
|
|
||||||
// 触发进入处理器
|
|
||||||
doInvokeHandlers(entryHandlers.get(to), from, to);
|
|
||||||
|
|
||||||
// 触发交换处理器
|
|
||||||
final String key = from.toString() + "-" + to.toString();
|
|
||||||
doInvokeHandlers(exchangeHandlers.get(key), from, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 触发
|
|
||||||
*/
|
|
||||||
private void doInvokeHandlers(List<StateHandlerWrapper<S>> handlerWrappers, S from, S to) {
|
|
||||||
if (handlerWrappers == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 全局的异步状态
|
|
||||||
final boolean isGlobalAsync = async != null && async;
|
|
||||||
|
|
||||||
handlerWrappers.forEach(hw -> {
|
|
||||||
final StateHandler<S> stateHandler;
|
|
||||||
if (hw == null ||
|
|
||||||
(stateHandler = hw.getStateHandler()) == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Executor executorToRun = hw.getExecutor() == null ? executor : hw.getExecutor();
|
|
||||||
final boolean runInAsync = hw.getAsync() == null ? isGlobalAsync : hw.getAsync();
|
|
||||||
final StateHandlerProcessParams<S> params = new StateHandlerProcessParams<>(from, to, null);
|
|
||||||
|
|
||||||
if (runInAsync) {
|
|
||||||
if (executorToRun == null) {
|
|
||||||
throw new NullPointerException();
|
|
||||||
}
|
|
||||||
executorToRun.execute(() -> stateHandler.handle(params));
|
|
||||||
} else {
|
|
||||||
stateHandler.handle(params);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import com.serliunx.statemanagement.manager.BidirectionalStateManager;
|
|||||||
* <li> 切出指定状态时触发 (离开事件)
|
* <li> 切出指定状态时触发 (离开事件)
|
||||||
* <li> 从A切换到B状态时触发 (交换事件)
|
* <li> 从A切换到B状态时触发 (交换事件)
|
||||||
* <p>
|
* <p>
|
||||||
* 请使用{@link StateMachineBuilder} 来构建状态机.
|
* 请使用 {@link StateMachineBuilder} 来构建状态机.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
@@ -20,10 +20,17 @@ import com.serliunx.statemanagement.manager.BidirectionalStateManager;
|
|||||||
* @see BidirectionalStateManager
|
* @see BidirectionalStateManager
|
||||||
* @see com.serliunx.statemanagement.manager.StateManager
|
* @see com.serliunx.statemanagement.manager.StateManager
|
||||||
*/
|
*/
|
||||||
public interface StateMachine<S> extends BidirectionalStateManager<S> {
|
public interface StateMachine<S> extends BidirectionalStateManager<S>, AutoCloseable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换到指定状态
|
* 发布事件
|
||||||
|
*
|
||||||
|
* @param event 事件
|
||||||
|
*/
|
||||||
|
void publish(Object event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换至指定状态
|
||||||
* <li> 在使用状态机的情况, 仅切换成功才会触发注册的各种事件.
|
* <li> 在使用状态机的情况, 仅切换成功才会触发注册的各种事件.
|
||||||
*
|
*
|
||||||
* @param state 新的状态
|
* @param state 新的状态
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public final class StateMachineBuilder<S> {
|
|||||||
/**
|
/**
|
||||||
* 状态管理器
|
* 状态管理器
|
||||||
*/
|
*/
|
||||||
private List<S> stateList;
|
private final List<S> stateList;
|
||||||
/**
|
/**
|
||||||
* 执行器
|
* 执行器
|
||||||
*/
|
*/
|
||||||
@@ -27,6 +27,10 @@ public final class StateMachineBuilder<S> {
|
|||||||
* 是否异步执行
|
* 是否异步执行
|
||||||
*/
|
*/
|
||||||
private Boolean async;
|
private Boolean async;
|
||||||
|
/**
|
||||||
|
* 状态机类型
|
||||||
|
*/
|
||||||
|
private StateMachineType type = StateMachineType.STANDARD;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 各种事件
|
* 各种事件
|
||||||
@@ -35,8 +39,14 @@ public final class StateMachineBuilder<S> {
|
|||||||
private final Map<S, List<StateHandlerWrapper<S>>> leaveHandlers = new HashMap<>(64);
|
private final Map<S, List<StateHandlerWrapper<S>>> leaveHandlers = new HashMap<>(64);
|
||||||
private final Map<String, List<StateHandlerWrapper<S>>> exchangeHandlers = new HashMap<>(64);
|
private final Map<String, List<StateHandlerWrapper<S>>> exchangeHandlers = new HashMap<>(64);
|
||||||
|
|
||||||
// private-ctor
|
private StateMachineBuilder(List<S> states) {
|
||||||
private StateMachineBuilder() {}
|
this.stateList = states;
|
||||||
|
}
|
||||||
|
|
||||||
|
private StateMachineBuilder(S[] states) {
|
||||||
|
this(Arrays.asList(states));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加交换事件
|
* 添加交换事件
|
||||||
@@ -189,18 +199,33 @@ public final class StateMachineBuilder<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置状态列表
|
* 指定状态机的类型
|
||||||
|
* <li> 状态机并发与否并不影响事件的执行逻辑
|
||||||
|
*
|
||||||
|
* @param type 类型
|
||||||
*/
|
*/
|
||||||
public StateMachineBuilder<S> states(S[] states) {
|
public StateMachineBuilder<S> type(StateMachineType type) {
|
||||||
return states(Arrays.asList(states));
|
if (type == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
this.type = type;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置状态列表
|
* 指定状态机的类型为标准型
|
||||||
|
* <li> 状态机并发与否并不影响事件的执行逻辑
|
||||||
*/
|
*/
|
||||||
public StateMachineBuilder<S> states(List<S> states) {
|
public StateMachineBuilder<S> standard() {
|
||||||
stateList = states;
|
return type(StateMachineType.STANDARD);
|
||||||
return this;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定状态机的类型为并发型
|
||||||
|
* <li> 状态机并发与否并不影响事件的执行逻辑
|
||||||
|
*/
|
||||||
|
public StateMachineBuilder<S> concurrent() {
|
||||||
|
return type(StateMachineType.CONCURRENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -208,19 +233,33 @@ public final class StateMachineBuilder<S> {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <M extends StateMachine<S>> M build() {
|
public <M extends StateMachine<S>> M build() {
|
||||||
return (M) new StandardStateMachine<>(stateList, entryHandlers,
|
if (type == null) {
|
||||||
leaveHandlers, exchangeHandlers, executor, async);
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
if (type.equals(StateMachineType.STANDARD)) {
|
||||||
|
return (M)new StandardStateMachine<>(stateList, entryHandlers,
|
||||||
|
leaveHandlers, exchangeHandlers, executor, async);
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("未知的状态机类型: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态机构建器
|
* 状态机构建器
|
||||||
*
|
*
|
||||||
* @param stateClass 状态类
|
* @param states 状态集合
|
||||||
* @return 状态机构建器实例
|
* @return 状态机构建器实例
|
||||||
* @param <S> 状态类参数
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("all")
|
public static <S> StateMachineBuilder<S> from(S[] states) {
|
||||||
public static <S> StateMachineBuilder<S> from(Class<? extends S> stateClass) {
|
return new StateMachineBuilder<>(states);
|
||||||
return new StateMachineBuilder<>();
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态机构建器
|
||||||
|
*
|
||||||
|
* @param states 状态集合
|
||||||
|
* @return 状态机构建器实例
|
||||||
|
*/
|
||||||
|
public static <S> StateMachineBuilder<S> from(List<S> states) {
|
||||||
|
return new StateMachineBuilder<>(states);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.serliunx.statemanagement.machine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态机类型
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||||
|
* @since 2024/12/31
|
||||||
|
*/
|
||||||
|
public enum StateMachineType {
|
||||||
|
/**
|
||||||
|
* 标准, 切换使用读写锁
|
||||||
|
*/
|
||||||
|
STANDARD,
|
||||||
|
/**
|
||||||
|
* 并发型, 切换使用CAS乐观锁
|
||||||
|
*/
|
||||||
|
CONCURRENT;
|
||||||
|
}
|
||||||
@@ -19,26 +19,30 @@ import java.util.concurrent.Executors;
|
|||||||
public class MachineTest {
|
public class MachineTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStandardStateMachine() {
|
public void testStandardStateMachine() throws Exception {
|
||||||
StateMachine<PrinterState> stateMachine = StateMachineBuilder.from(PrinterState.class)
|
StateMachine<PrinterState> stateMachine = StateMachineBuilder.from(PrinterState.values())
|
||||||
.async(false)
|
.async()
|
||||||
.states(PrinterState.values())
|
.standard()
|
||||||
.executor(Executors.newFixedThreadPool(16))
|
.executor(Executors.newFixedThreadPool(16))
|
||||||
.whenLeave(PrinterState.PRINTING, h -> {
|
.whenLeave(PrinterState.PRINTING, h -> {
|
||||||
System.out.println(Thread.currentThread().getName() + ": leave PRINTING");
|
System.out.println(Thread.currentThread().getName() + ": leave PRINTING");
|
||||||
})
|
})
|
||||||
.whenEntry(PrinterState.SCANNING, h -> {
|
.whenEntry(PrinterState.STOPPING, h -> {
|
||||||
System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo());
|
System.out.println(Thread.currentThread().getName() + ": entry STOPPING, from " + h.getFrom());
|
||||||
})
|
})
|
||||||
.whenEntry(PrinterState.PRINTING, h -> {
|
.whenEntry(PrinterState.STOPPED, h -> {
|
||||||
System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo());
|
System.out.println(Thread.currentThread().getName() + ": entry STOPPED, from " + h.getFrom());
|
||||||
})
|
|
||||||
.exchange(PrinterState.STOPPED, PrinterState.IDLE, h -> {
|
|
||||||
System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo());
|
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
System.out.println(stateMachine.getClass());
|
||||||
|
|
||||||
stateMachine.switchTo(PrinterState.PRINTING);
|
stateMachine.switchTo(PrinterState.PRINTING);
|
||||||
stateMachine.switchNext();
|
stateMachine.switchNext();
|
||||||
|
stateMachine.switchNext();
|
||||||
|
|
||||||
|
System.out.println(stateMachine.current());
|
||||||
|
|
||||||
|
stateMachine.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user