using GFramework.Core.Abstractions.state;
namespace GFramework.Core.state;
///
/// 状态机实现类,用于管理状态的注册、切换和生命周期
/// 同时支持同步状态(IState)和异步状态(IAsyncState)
///
public class StateMachine(int maxHistorySize = 10) : IStateMachine
{
private readonly object _lock = new();
private readonly HashSet _registeredStates = new(); // 优化:用于快速检查状态是否注册
private readonly Stack _stateHistory = new();
///
/// 存储所有已注册状态的字典,键为状态类型,值为状态实例
///
protected readonly Dictionary States = new();
///
/// 获取当前激活的状态
///
public IState? Current { get; protected set; }
///
/// 注册一个状态到状态机中
///
/// 要注册的状态实例
public IStateMachine Register(IState state)
{
lock (_lock)
{
States[state.GetType()] = state;
_registeredStates.Add(state);
}
return this;
}
///
/// 从状态机中注销指定类型的状态
///
/// 要注销的状态类型
public IStateMachine Unregister() where T : IState
{
var stateToUnregister = PrepareUnregister(out var isCurrentState);
if (stateToUnregister == null) return this;
// 如果是当前状态,执行同步退出
if (isCurrentState)
{
Current!.OnExit(null);
Current = null;
}
CompleteUnregister(stateToUnregister);
return this;
}
///
/// 异步注销指定类型的状态
///
/// 要注销的状态类型
public async Task UnregisterAsync() where T : IState
{
var stateToUnregister = PrepareUnregister(out var isCurrentState);
if (stateToUnregister == null) return this;
// 如果是当前状态,执行异步退出
if (isCurrentState)
{
await ExecuteExitAsync(Current!, null);
Current = null;
}
CompleteUnregister(stateToUnregister);
return this;
}
///
/// 检查是否可以切换到指定类型的状态
///
/// 目标状态类型
/// 如果可以切换则返回true,否则返回false
public bool CanChangeTo() where T : IState
{
if (!States.TryGetValue(typeof(T), out var target))
return false;
return Current?.CanTransitionTo(target) ?? true;
}
///
/// 异步检查是否可以切换到指定类型的状态
///
/// 目标状态类型
/// 如果可以切换则返回true,否则返回false
public async Task CanChangeToAsync() where T : IState
{
if (!States.TryGetValue(typeof(T), out var target))
return false;
if (Current == null) return true;
return await CanTransitionToAsync(Current, target);
}
///
/// 切换到指定类型的状态
///
/// 目标状态类型
/// 如果成功切换则返回true,否则返回false
/// 当目标状态未注册时抛出
public bool ChangeTo() where T : IState
{
lock (_lock)
{
if (!States.TryGetValue(typeof(T), out var target))
throw new InvalidOperationException($"State {typeof(T).Name} not registered.");
if (Current != null && !Current.CanTransitionTo(target))
{
OnTransitionRejected(Current, target);
return false;
}
ChangeInternal(target);
return true;
}
}
///
/// 异步切换到指定类型的状态
///
/// 目标状态类型
/// 如果成功切换则返回true,否则返回false
/// 当目标状态未注册时抛出
public async Task ChangeToAsync() where T : IState
{
IState target;
IState? currentSnapshot;
lock (_lock)
{
if (!States.TryGetValue(typeof(T), out target!))
throw new InvalidOperationException($"State {typeof(T).Name} not registered.");
currentSnapshot = Current; // 在锁内获取当前状态的快照
}
// 验证转换(在锁外执行异步操作)
if (currentSnapshot != null)
{
var canTransition = await CanTransitionToAsync(currentSnapshot, target);
if (!canTransition)
{
await OnTransitionRejectedAsync(currentSnapshot, target);
return false;
}
}
await ChangeInternalAsync(target);
return true;
}
///
/// 检查指定类型的状态是否已注册
///
/// 要检查的状态类型
/// 如果状态已注册则返回true,否则返回false
public bool IsRegistered() where T : IState
{
return States.ContainsKey(typeof(T));
}
///
/// 获取指定类型的已注册状态实例
///
/// 要获取的状态类型
/// 如果状态存在则返回对应实例,否则返回null
public T? GetState() where T : class, IState
{
return States.TryGetValue(typeof(T), out var state) ? state as T : null;
}
///
/// 获取所有已注册状态的类型集合
///
/// 包含所有已注册状态类型的枚举器
public IEnumerable GetRegisteredStateTypes()
{
return States.Keys;
}
///
/// 获取上一个状态
///
/// 如果历史记录存在则返回上一个状态,否则返回null
public IState? GetPreviousState()
{
lock (_lock)
{
return _stateHistory.Count > 0 ? _stateHistory.Peek() : null;
}
}
///
/// 获取状态历史记录
///
/// 状态历史记录的只读副本,从最近到最远排序
public IReadOnlyList GetStateHistory()
{
lock (_lock)
{
return _stateHistory.ToList().AsReadOnly();
}
}
///
/// 回退到上一个状态
///
/// 如果成功回退则返回true,否则返回false
public bool GoBack()
{
var previousState = FindValidPreviousState();
if (previousState == null) return false;
ChangeInternalWithoutHistory(previousState);
return true;
}
///
/// 异步回退到上一个状态
///
/// 如果成功回退则返回true,否则返回false
public async Task GoBackAsync()
{
var previousState = FindValidPreviousState();
if (previousState == null) return false;
await ChangeInternalWithoutHistoryAsync(previousState);
return true;
}
///
/// 清空状态历史记录
///
public void ClearHistory()
{
lock (_lock)
{
_stateHistory.Clear();
}
}
///
/// 准备注销操作,返回要注销的状态
///
private IState? PrepareUnregister(out bool isCurrentState) where T : IState
{
lock (_lock)
{
var type = typeof(T);
if (!States.TryGetValue(type, out var state))
{
isCurrentState = false;
return null;
}
isCurrentState = Current == state;
return state;
}
}
///
/// 完成注销操作,清理历史记录和状态字典
///
private void CompleteUnregister(IState stateToUnregister)
{
lock (_lock)
{
// 从历史记录中移除该状态的所有引用
var tempStack = new Stack(_stateHistory.Reverse());
_stateHistory.Clear();
foreach (var historyState in tempStack.Where(s => s != stateToUnregister))
_stateHistory.Push(historyState);
States.Remove(stateToUnregister.GetType());
_registeredStates.Remove(stateToUnregister);
}
}
///
/// 查找有效的上一个状态(跳过已注销的状态)
///
private IState? FindValidPreviousState()
{
lock (_lock)
{
while (_stateHistory.Count > 0)
{
var candidate = _stateHistory.Pop();
// 使用 HashSet 快速检查,O(1) 复杂度
if (_registeredStates.Contains(candidate))
return candidate;
}
return null;
}
}
///
/// 内部状态切换方法(不记录历史),用于回退操作
///
/// 下一个状态实例
protected virtual void ChangeInternalWithoutHistory(IState next)
{
if (Current == next) return;
var old = Current;
OnStateChanging(old, next);
old?.OnExit(next);
Current = next;
Current.OnEnter(old);
OnStateChanged(old, Current);
}
///
/// 异步内部状态切换方法(不记录历史),用于回退操作
///
/// 下一个状态实例
protected virtual async Task ChangeInternalWithoutHistoryAsync(IState next)
{
if (Current == next) return;
var old = Current;
await OnStateChangingAsync(old, next);
await ExecuteExitAsync(old, next);
Current = next;
await ExecuteEnterAsync(Current, old);
await OnStateChangedAsync(old, Current);
}
///
/// 内部状态切换方法,处理状态切换的核心逻辑
///
/// 下一个状态实例
protected virtual void ChangeInternal(IState next)
{
if (Current == next) return;
if (Current != null && !Current.CanTransitionTo(next))
{
OnTransitionRejected(Current, next);
return;
}
var old = Current;
OnStateChanging(old, next);
AddToHistory(Current);
old?.OnExit(next);
Current = next;
Current.OnEnter(old);
OnStateChanged(old, Current);
}
///
/// 异步内部状态切换方法,处理状态切换的核心逻辑
///
/// 下一个状态实例
protected virtual async Task ChangeInternalAsync(IState next)
{
if (Current == next) return;
var old = Current;
await OnStateChangingAsync(old, next);
AddToHistory(Current);
await ExecuteExitAsync(old, next);
Current = next;
await ExecuteEnterAsync(Current, old);
await OnStateChangedAsync(old, Current);
}
///
/// 将状态添加到历史记录
///
private void AddToHistory(IState? state)
{
if (state == null) return;
lock (_lock)
{
_stateHistory.Push(state);
// 限制历史记录大小
if (_stateHistory.Count > maxHistorySize)
{
var tempStack = new Stack(_stateHistory.Reverse().Skip(1));
_stateHistory.Clear();
foreach (var s in tempStack.Reverse())
_stateHistory.Push(s);
}
}
}
///
/// 执行状态进入逻辑(智能判断同步/异步)
///
private static async Task ExecuteEnterAsync(IState? state, IState? from)
{
if (state == null) return;
if (state is IAsyncState asyncState)
await asyncState.OnEnterAsync(from);
else
state.OnEnter(from);
}
///
/// 执行状态退出逻辑(智能判断同步/异步)
///
private static async Task ExecuteExitAsync(IState? state, IState? to)
{
if (state == null) return;
if (state is IAsyncState asyncState)
await asyncState.OnExitAsync(to);
else
state.OnExit(to);
}
///
/// 检查是否可以转换到目标状态(智能判断同步/异步)
///
private static async Task CanTransitionToAsync(IState current, IState target)
{
if (current is IAsyncState asyncState)
return await asyncState.CanTransitionToAsync(target);
return current.CanTransitionTo(target);
}
///
/// 当状态转换被拒绝时的回调方法
///
/// 源状态
/// 目标状态
protected virtual void OnTransitionRejected(IState from, IState to)
{
}
///
/// 当状态转换被拒绝时的异步回调方法
///
/// 源状态
/// 目标状态
protected virtual Task OnTransitionRejectedAsync(IState from, IState to)
{
OnTransitionRejected(from, to);
return Task.CompletedTask;
}
///
/// 当状态即将发生改变时的回调方法
///
/// 源状态
/// 目标状态
protected virtual void OnStateChanging(IState? from, IState to)
{
}
///
/// 当状态即将发生改变时的异步回调方法
///
/// 源状态
/// 目标状态
protected virtual Task OnStateChangingAsync(IState? from, IState to)
{
OnStateChanging(from, to);
return Task.CompletedTask;
}
///
/// 当状态改变完成后的回调方法
///
/// 源状态
/// 目标状态
protected virtual void OnStateChanged(IState? from, IState? to)
{
}
///
/// 当状态改变完成后的异步回调方法
///
/// 源状态
/// 目标状态
protected virtual Task OnStateChangedAsync(IState? from, IState? to)
{
OnStateChanged(from, to);
return Task.CompletedTask;
}
}