init: 仓库初始化.
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package com.serliunx.statemanagement.exception;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public class StateException extends RuntimeException {
|
||||
|
||||
public StateException() {
|
||||
}
|
||||
|
||||
public StateException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public StateException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public StateException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public StateException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 状态机的标准实现
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public class StandardStateMachine<S> extends AbstractStateManager<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 leaveHandlers 离开事件处理器集合
|
||||
* @param exchangeHandlers 交换事件处理器集合
|
||||
* @param executor 异步执行器
|
||||
* @param async 是否异步执行
|
||||
*/
|
||||
StandardStateMachine(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 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) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.serliunx.statemanagement.machine;
|
||||
|
||||
import com.serliunx.statemanagement.manager.BidirectionalStateManager;
|
||||
|
||||
/**
|
||||
* 状态机定义
|
||||
* <p>
|
||||
* 基于双向的状态管理器扩展 {@link BidirectionalStateManager}, 切换逻辑依赖于内置的状态管理器;
|
||||
* 同时可以多种监听事件, 包括:
|
||||
* <li> 切换至指定状态时触发 (进入事件)
|
||||
* <li> 切出指定状态时触发 (离开事件)
|
||||
* <li> 从A切换到B状态时触发 (交换事件)
|
||||
* <p>
|
||||
* 推荐使用{@link StateMachineBuilder} 来构建状态机.
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
* @see StateMachineBuilder
|
||||
* @see BidirectionalStateManager
|
||||
* @see com.serliunx.statemanagement.manager.StateManager
|
||||
*/
|
||||
public interface StateMachine<S> extends BidirectionalStateManager<S> {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
package com.serliunx.statemanagement.machine;
|
||||
|
||||
import com.serliunx.statemanagement.machine.handler.StateHandler;
|
||||
import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper;
|
||||
import com.serliunx.statemanagement.manager.BidirectionalStateManager;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* 状态机构建
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public final class StateMachineBuilder<S> {
|
||||
|
||||
/**
|
||||
* 状态管理器
|
||||
*/
|
||||
private List<S> stateList;
|
||||
/**
|
||||
* 执行器
|
||||
*/
|
||||
private Executor executor;
|
||||
/**
|
||||
* 是否异步执行
|
||||
*/
|
||||
private Boolean async;
|
||||
|
||||
/**
|
||||
* 各种事件
|
||||
*/
|
||||
private final Map<S, List<StateHandlerWrapper<S>>> entryHandlers = 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-ctor
|
||||
private StateMachineBuilder() {}
|
||||
|
||||
/**
|
||||
* 添加交换事件
|
||||
* <li> 从A状态切换至B状态时触发
|
||||
*
|
||||
* @param from 源状态
|
||||
* @param to 目的状态
|
||||
* @param handler 处理器
|
||||
* @param async 是否异步执行
|
||||
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
|
||||
*/
|
||||
public StateMachineBuilder<S> exchange(S from, S to, StateHandler<S> handler, Boolean async, Executor executor) {
|
||||
final String key = from.toString() + "-" + to.toString();
|
||||
final List<StateHandlerWrapper<S>> stateHandlerWrappers = exchangeHandlers.computeIfAbsent(key,
|
||||
k -> new ArrayList<>());
|
||||
stateHandlerWrappers.add(new StateHandlerWrapper<>(handler, executor, async));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加交换事件
|
||||
* <li> 从A状态切换至B状态时触发
|
||||
*
|
||||
* @param from 源状态
|
||||
* @param to 目的状态
|
||||
* @param handler 处理器
|
||||
* @param async 是否异步执行
|
||||
*/
|
||||
public StateMachineBuilder<S> exchange(S from, S to, StateHandler<S> handler, Boolean async) {
|
||||
return exchange(from, to, handler, async, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加交换事件
|
||||
* <li> 从A状态切换至B状态时触发
|
||||
*
|
||||
* @param from 源状态
|
||||
* @param to 目的状态
|
||||
* @param handler 处理器
|
||||
*/
|
||||
public StateMachineBuilder<S> exchange(S from, S to, StateHandler<S> handler) {
|
||||
return exchange(from, to, handler, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加离开事件
|
||||
* <li> 从指定状态切换到别的状态时执行的逻辑
|
||||
*
|
||||
* @param state 状态
|
||||
* @param handler 处理逻辑
|
||||
* @param async 是否异步执行
|
||||
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
|
||||
*/
|
||||
public StateMachineBuilder<S> whenLeave(S state, StateHandler<S> handler, Boolean async, Executor executor) {
|
||||
final List<StateHandlerWrapper<S>> stateHandlerWrappers = leaveHandlers.computeIfAbsent(state,
|
||||
k -> new ArrayList<>());
|
||||
stateHandlerWrappers.add(new StateHandlerWrapper<>(handler, executor, async));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加离开事件
|
||||
* <li> 从指定状态切换到别的状态时执行的逻辑
|
||||
*
|
||||
* @param state 状态
|
||||
* @param handler 处理逻辑
|
||||
* @param async 是否异步执行
|
||||
*/
|
||||
public StateMachineBuilder<S> whenLeave(S state, StateHandler<S> handler, Boolean async) {
|
||||
return whenLeave(state, handler, async, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加离开事件
|
||||
* <li> 从指定状态切换到别的状态时执行的逻辑
|
||||
*
|
||||
* @param state 状态
|
||||
* @param handler 处理逻辑
|
||||
*/
|
||||
public StateMachineBuilder<S> whenLeave(S state, StateHandler<S> handler) {
|
||||
return whenLeave(state, handler, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加进入事件
|
||||
* <li> 切换到了指定状态时执行的逻辑
|
||||
*
|
||||
* @param state 状态
|
||||
* @param handler 处理逻辑
|
||||
* @param async 是否异步执行
|
||||
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
|
||||
*/
|
||||
public StateMachineBuilder<S> whenEntry(S state, StateHandler<S> handler, Boolean async, Executor executor) {
|
||||
final List<StateHandlerWrapper<S>> stateHandlerWrappers = entryHandlers.computeIfAbsent(state,
|
||||
k -> new ArrayList<>());
|
||||
stateHandlerWrappers.add(new StateHandlerWrapper<>(handler, executor, async));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加进入事件
|
||||
* <li> 切换到了指定状态时执行的逻辑
|
||||
*
|
||||
* @param state 状态
|
||||
* @param handler 处理逻辑
|
||||
* @param async 是否异步执行
|
||||
*/
|
||||
public StateMachineBuilder<S> whenEntry(S state, StateHandler<S> handler, Boolean async) {
|
||||
return whenEntry(state, handler, async, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加进入事件
|
||||
* <li> 切换到了指定状态时执行的逻辑
|
||||
*
|
||||
* @param state 状态
|
||||
* @param handler 处理逻辑
|
||||
*/
|
||||
public StateMachineBuilder<S> whenEntry(S state, StateHandler<S> handler) {
|
||||
return whenEntry(state, handler, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定状态机的执行器
|
||||
* <p>
|
||||
* 优先级低于添加事件时指定的执行器
|
||||
*
|
||||
* @param executor 执行器
|
||||
*/
|
||||
public StateMachineBuilder<S> executor(Executor executor) {
|
||||
this.executor = executor;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义状态机是否异步执行
|
||||
*
|
||||
* @param async 是否异步执行
|
||||
*/
|
||||
public StateMachineBuilder<S> async(Boolean async) {
|
||||
this.async = async;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义状态机为异步执行
|
||||
*/
|
||||
public StateMachineBuilder<S> async() {
|
||||
return async(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态列表
|
||||
*/
|
||||
public StateMachineBuilder<S> states(S[] states) {
|
||||
return states(Arrays.asList(states));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态列表
|
||||
*/
|
||||
public StateMachineBuilder<S> states(List<S> states) {
|
||||
stateList = states;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <M extends StateMachine<S>> M build() {
|
||||
return (M) new StandardStateMachine<>(stateList, entryHandlers,
|
||||
leaveHandlers, exchangeHandlers, executor, async);
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态机构建器
|
||||
*
|
||||
* @param stateClass 状态类
|
||||
* @return 状态机构建器实例
|
||||
* @param <S> 状态类参数
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public static <S> StateMachineBuilder<S> from(Class<? extends S> stateClass) {
|
||||
return new StateMachineBuilder<>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.serliunx.statemanagement.machine.handler;
|
||||
|
||||
/**
|
||||
* 状态处理器
|
||||
* <p>
|
||||
* 定义状态进入、离开及切换时执行的逻辑
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface StateHandler<S> {
|
||||
|
||||
/**
|
||||
* 处理
|
||||
*
|
||||
* @param params 参数
|
||||
*/
|
||||
void handle(StateHandlerProcessParams<S> params);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.serliunx.statemanagement.machine.handler;
|
||||
|
||||
import com.serliunx.statemanagement.manager.BidirectionalStateManager;
|
||||
|
||||
/**
|
||||
* 状态处理器入参
|
||||
* <p>
|
||||
* 用于状态机处理事件
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public final class StateHandlerProcessParams<S> {
|
||||
|
||||
/**
|
||||
* 源状态
|
||||
*/
|
||||
private final S from;
|
||||
/**
|
||||
* 目标状态
|
||||
*/
|
||||
private final S to;
|
||||
/**
|
||||
* 附加参数
|
||||
*/
|
||||
private final Object attach;
|
||||
|
||||
/**
|
||||
* @param from 原状态
|
||||
* @param to 目标状态
|
||||
* @param attach 附加参数
|
||||
* @param bidirectionalStateManager 状态机内置的状态管理器
|
||||
*/
|
||||
public StateHandlerProcessParams(S from, S to, Object attach) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.attach = attach;
|
||||
}
|
||||
|
||||
public S getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public S getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
public Object getAttach() {
|
||||
return attach;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.serliunx.statemanagement.machine.handler;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public class StateHandlerRegistry {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.serliunx.statemanagement.machine.handler;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* 处理器封装
|
||||
* <p>
|
||||
* 用于添加处理器时设置处理器的行为
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public final class StateHandlerWrapper<S> {
|
||||
|
||||
/**
|
||||
* 状态处理器
|
||||
*/
|
||||
private final StateHandler<S> stateHandler;
|
||||
/**
|
||||
* 执行器
|
||||
* <li> 用于异步执行处理逻辑
|
||||
*/
|
||||
private final Executor executor;
|
||||
/**
|
||||
* 是否异步执行
|
||||
*/
|
||||
private final Boolean async;
|
||||
|
||||
/**
|
||||
* @param stateHandler 状态处理器
|
||||
* @param executor 执行器
|
||||
* @param async 是否异步执行
|
||||
*/
|
||||
public StateHandlerWrapper(StateHandler<S> stateHandler, Executor executor, Boolean async) {
|
||||
this.stateHandler = stateHandler;
|
||||
this.executor = executor;
|
||||
this.async = async;
|
||||
}
|
||||
|
||||
public StateHandler<S> getStateHandler() {
|
||||
return stateHandler;
|
||||
}
|
||||
|
||||
public Executor getExecutor() {
|
||||
return executor;
|
||||
}
|
||||
|
||||
public Boolean getAsync() {
|
||||
return async;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package com.serliunx.statemanagement.manager;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* 状态管理器的抽象实现
|
||||
* <p>
|
||||
* 提供了最基本功能的实现以及部分供子类使用的参数,如:锁、当前状态的序号等.
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public abstract class AbstractStateManager<S> implements StateManager<S> {
|
||||
|
||||
/**
|
||||
* 状态列表
|
||||
*/
|
||||
private final List<S> stateList;
|
||||
|
||||
/**
|
||||
* 当前状态的序号
|
||||
* <p> 请保证仅在有写锁的情况下去修改
|
||||
*/
|
||||
private volatile int index;
|
||||
|
||||
/**
|
||||
* 锁
|
||||
*/
|
||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
/**
|
||||
* 读锁
|
||||
*/
|
||||
protected final ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
|
||||
/**
|
||||
* 写锁
|
||||
*/
|
||||
protected final ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
|
||||
|
||||
/**
|
||||
* @param stateList 状态列表
|
||||
*/
|
||||
public AbstractStateManager(List<S> stateList) {
|
||||
this.stateList = stateList;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param states 状态数组
|
||||
*/
|
||||
public AbstractStateManager(S[] states) {
|
||||
this(Arrays.asList(states));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留空构造器
|
||||
*/
|
||||
public AbstractStateManager() {
|
||||
this((List<S>) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S current() {
|
||||
try {
|
||||
readLock.lock();
|
||||
return get();
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean switchTo(S state) {
|
||||
int i = indexOf(state);
|
||||
if (i == -1) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
writeLock.lock();
|
||||
index = i;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
try {
|
||||
writeLock.lock();
|
||||
index = getDefault();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将序号移动至下一个
|
||||
* <li> 自动归零
|
||||
* <li> 仅在持有写锁的情况下访问
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
protected void next() {
|
||||
if (++index >= stateList.size())
|
||||
index = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将序号移动至上一个
|
||||
* <li> 自动归零
|
||||
* <li> 仅在持有写锁的情况下访问
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
protected void prev() {
|
||||
if (--index < 0)
|
||||
index = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前状态
|
||||
* <p>
|
||||
* 类及子类访问当前状态时不允许使用{@link #current()},因为会造成死锁
|
||||
*
|
||||
* <li> 仅在持有锁的情况下访问
|
||||
*
|
||||
* @return 当前状态
|
||||
*/
|
||||
protected S get() {
|
||||
return stateList.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定状态在状态列表中的序号
|
||||
*
|
||||
* @param state 状态
|
||||
* @return 序号 {@link List#indexOf(Object)}
|
||||
*/
|
||||
protected int indexOf(S state) {
|
||||
return stateList.indexOf(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前状态是否为状态列表中的最后一个
|
||||
*
|
||||
* @return 是最后一个时返回真, 否则返回假.
|
||||
*/
|
||||
protected boolean isLast() {
|
||||
return index == stateList.size() - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前状态是否为状态列表中的第一个
|
||||
*
|
||||
* @return 是第一个时返回真, 否则返回假.
|
||||
*/
|
||||
protected boolean isFirst() {
|
||||
return index == getDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前状态的序号
|
||||
*
|
||||
* @return 当前状态序号
|
||||
*/
|
||||
protected int currentIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新当前状态的序号
|
||||
*/
|
||||
protected void updateCurrentIndex(int newIndex) {
|
||||
index = newIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态序号默认值(等同于默认状态)
|
||||
*/
|
||||
protected int getDefault() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.serliunx.statemanagement.manager;
|
||||
|
||||
/**
|
||||
* 双向流转的状态管理器
|
||||
* <p>
|
||||
* 基于单向流转的状态管理器{@link UnidirectionalStateManager} 实现, 在其基础上允许了反方向切换状态
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public interface BidirectionalStateManager<S> extends UnidirectionalStateManager<S> {
|
||||
|
||||
/**
|
||||
* 切换至上一个状态并返回切换后的状态
|
||||
*
|
||||
* @return 切换后的状态
|
||||
*/
|
||||
S switchPrevAndGet();
|
||||
|
||||
/**
|
||||
* 获取当前状态并切换至上一个状态
|
||||
*
|
||||
* @return 切换前的状态
|
||||
*/
|
||||
S getAndSwitchPrev();
|
||||
|
||||
/**
|
||||
* 切换至上一个状态
|
||||
*/
|
||||
void switchPrev();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.serliunx.statemanagement.manager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 双向流转的状态管理器的默认实现
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public class DefaultBidirectionalStateManager<S> extends DefaultUnidirectionalStateManager<S>
|
||||
implements BidirectionalStateManager<S> {
|
||||
|
||||
/**
|
||||
* @param stateList 状态列表
|
||||
*/
|
||||
public DefaultBidirectionalStateManager(List<S> stateList) {
|
||||
super(stateList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param states 状态数组
|
||||
*/
|
||||
public DefaultBidirectionalStateManager(S[] states) {
|
||||
super(states);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S switchPrevAndGet() {
|
||||
try {
|
||||
writeLock.lock();
|
||||
prev();
|
||||
return get();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public S getAndSwitchPrev() {
|
||||
try {
|
||||
writeLock.lock();
|
||||
S current = get();
|
||||
prev();
|
||||
return current;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchPrev() {
|
||||
try {
|
||||
writeLock.lock();
|
||||
prev();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean switchTo(S state) {
|
||||
return defaultSwitchTo(state);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.serliunx.statemanagement.manager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 单向流转的状态管理器的默认实现
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public class DefaultUnidirectionalStateManager<S> extends AbstractStateManager<S>
|
||||
implements UnidirectionalStateManager<S> {
|
||||
|
||||
/**
|
||||
* @param stateList 状态列表
|
||||
*/
|
||||
public DefaultUnidirectionalStateManager(List<S> stateList) {
|
||||
super(stateList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param states 状态数组
|
||||
*/
|
||||
public DefaultUnidirectionalStateManager(S[] states) {
|
||||
super(states);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S switchNextAndGet() {
|
||||
try {
|
||||
writeLock.lock();
|
||||
next();
|
||||
return get();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public S getAndSwitchNext() {
|
||||
try {
|
||||
writeLock.lock();
|
||||
S current = get();
|
||||
next();
|
||||
return current;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchNext() {
|
||||
try {
|
||||
writeLock.lock();
|
||||
next();
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean switchTo(S state) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
final int i;
|
||||
if ((i = indexOf(state)) == -1 ||
|
||||
(!isLast() && i < currentIndex()) ||
|
||||
(isLast() && i != getDefault())) {
|
||||
return false;
|
||||
}
|
||||
updateCurrentIndex(i);
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留默认的切换方式供子类使用
|
||||
*/
|
||||
protected boolean defaultSwitchTo(S state) {
|
||||
return super.switchTo(state);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.serliunx.statemanagement.manager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 最简单的状态管理器实现
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public final class StandardStateManager<S> extends AbstractStateManager<S> {
|
||||
|
||||
/**
|
||||
* @param stateList 状态列表
|
||||
*/
|
||||
public StandardStateManager(List<S> stateList) {
|
||||
super(stateList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param states 状态数组
|
||||
*/
|
||||
public StandardStateManager(S[] states) {
|
||||
super(states);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.serliunx.statemanagement.manager;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* 状态管理器
|
||||
* <p>
|
||||
* 将状态集合按照一定的逻辑流转
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public interface StateManager<S> {
|
||||
|
||||
/**
|
||||
* 获取当前状态
|
||||
*
|
||||
* @return 当前最新状态
|
||||
*/
|
||||
S current();
|
||||
|
||||
/**
|
||||
* 切换到指定状态
|
||||
*
|
||||
* @param state 新的状态
|
||||
* @return 切换成功返回真, 否则返回假
|
||||
*/
|
||||
boolean switchTo(S state);
|
||||
|
||||
/**
|
||||
* 重置回默认状态, 一般为状态集合中的第一个
|
||||
*/
|
||||
void reset();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.serliunx.statemanagement.manager;
|
||||
|
||||
/**
|
||||
* 单向流转的状态管理器
|
||||
* <p>
|
||||
* 其基本逻辑等同于 {@link StateManager}, 但存在以下不同:
|
||||
* <li> 状态只能单方向流动(最后一个状态允许切换至第一个状态), 如果有A, B, C, D 四种状态则存在以下几种情况:
|
||||
* <p>
|
||||
* <p>
|
||||
* <li> A -> B 允许直接切换, A -> C 允许直接切换, C -> D 允许直接切换 等等..
|
||||
* <li> B -> A 不允许切换, C -> A 不允许切换, D -> C 不允许切换 等等..
|
||||
* <li> 特例: D -> A 是允许的, 因为D是最后一个状态, 故可以切换至第一个状态.
|
||||
* <p>
|
||||
* 即状态的切换只允许一个方向,不允许向前流动,除非到达最后一个状态!
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public interface UnidirectionalStateManager<S> extends StateManager<S> {
|
||||
|
||||
/**
|
||||
* 切换至下一个状态并返回切换后的状态
|
||||
*
|
||||
* @return 切换后的状态
|
||||
*/
|
||||
S switchNextAndGet();
|
||||
|
||||
/**
|
||||
* 返回并切换至下一个状态
|
||||
*
|
||||
* @return 切换前的状态
|
||||
*/
|
||||
S getAndSwitchNext();
|
||||
|
||||
/**
|
||||
* 切换至下一个状态
|
||||
*/
|
||||
void switchNext();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.serliunx.statemanagement.support;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2024/12/28
|
||||
*/
|
||||
public final class ExecutorUtils {
|
||||
|
||||
private ExecutorUtils() {throw new UnsupportedOperationException();}
|
||||
}
|
||||
Reference in New Issue
Block a user