diff --git a/GFramework.Core.Abstractions/state/IStateMachine.cs b/GFramework.Core.Abstractions/state/IStateMachine.cs
index f0b6d61..f7ddf1e 100644
--- a/GFramework.Core.Abstractions/state/IStateMachine.cs
+++ b/GFramework.Core.Abstractions/state/IStateMachine.cs
@@ -1,4 +1,7 @@
-namespace GFramework.Core.Abstractions.state;
+using System;
+using System.Collections.Generic;
+
+namespace GFramework.Core.Abstractions.state;
///
/// 状态机接口,用于管理状态的注册、切换和验证
@@ -34,4 +37,47 @@ public interface IStateMachine
///
/// 要切换到的状态类型,必须实现IState接口
void ChangeTo() where T : IState;
+
+ ///
+ /// 检查指定类型的状态是否已注册
+ ///
+ /// 要检查的状态类型
+ /// 如果状态已注册则返回true,否则返回false
+ bool IsRegistered() where T : IState;
+
+ ///
+ /// 获取指定类型的已注册状态实例
+ ///
+ /// 要获取的状态类型
+ /// 如果状态存在则返回对应实例,否则返回null
+ T? GetState() where T : class, IState;
+
+ ///
+ /// 获取所有已注册状态的类型集合
+ ///
+ /// 包含所有已注册状态类型的枚举器
+ IEnumerable GetRegisteredStateTypes();
+
+ ///
+ /// 获取上一个状态
+ ///
+ /// 如果历史记录存在则返回上一个状态,否则返回null
+ IState? GetPreviousState();
+
+ ///
+ /// 获取状态历史记录
+ ///
+ /// 状态历史记录的只读副本
+ IReadOnlyList GetStateHistory();
+
+ ///
+ /// 回退到上一个状态
+ ///
+ /// 如果成功回退则返回true,否则返回false
+ bool GoBack();
+
+ ///
+ /// 清空状态历史记录
+ ///
+ void ClearHistory();
}
\ No newline at end of file
diff --git a/GFramework.Core.Tests/tests/SyncArchitectureTests.cs b/GFramework.Core.Tests/tests/SyncArchitectureTests.cs
index 5fe0ed1..3216d38 100644
--- a/GFramework.Core.Tests/tests/SyncArchitectureTests.cs
+++ b/GFramework.Core.Tests/tests/SyncArchitectureTests.cs
@@ -1,4 +1,5 @@
-using GFramework.Core.Abstractions.enums;
+using System;
+using GFramework.Core.Abstractions.enums;
using GFramework.Core.architecture;
using GFramework.Core.Tests.architecture;
using GFramework.Core.Tests.events;
diff --git a/GFramework.Core/state/ContextAwareStateMachine.cs b/GFramework.Core/state/ContextAwareStateMachine.cs
index 606cc0b..c385502 100644
--- a/GFramework.Core/state/ContextAwareStateMachine.cs
+++ b/GFramework.Core/state/ContextAwareStateMachine.cs
@@ -61,6 +61,20 @@ public class ContextAwareStateMachine : StateMachine, ISystem
///
public virtual void Destroy()
{
+ // 退出当前状态
+ if (Current != null)
+ {
+ Current.OnExit(null);
+ Current = null;
+ }
+
+ // 清理所有状态
+ foreach (var state in States.Values.OfType())
+ {
+ state.Dispose();
+ }
+
+ States.Clear();
}
///
diff --git a/GFramework.Core/state/StateMachine.cs b/GFramework.Core/state/StateMachine.cs
index c845340..08e3b24 100644
--- a/GFramework.Core/state/StateMachine.cs
+++ b/GFramework.Core/state/StateMachine.cs
@@ -5,8 +5,11 @@ namespace GFramework.Core.state;
///
/// 状态机实现类,用于管理状态的注册、切换和生命周期
///
-public class StateMachine : IStateMachine
+public class StateMachine(int maxHistorySize = 10) : IStateMachine
{
+ private readonly object _lock = new();
+ private readonly Stack _stateHistory = new();
+
///
/// 存储所有已注册状态的字典,键为状态类型,值为状态实例
///
@@ -15,14 +18,19 @@ public class StateMachine : IStateMachine
///
/// 获取当前激活的状态
///
- public IState? Current { get; private set; }
+ public IState? Current { get; protected set; }
///
/// 注册一个状态到状态机中
///
/// 要注册的状态实例
public void Register(IState state)
- => States[state.GetType()] = state;
+ {
+ lock (_lock)
+ {
+ States[state.GetType()] = state;
+ }
+ }
///
/// 从状态机中注销指定类型的状态
@@ -30,17 +38,28 @@ public class StateMachine : IStateMachine
/// 要注销的状态类型
public void Unregister() where T : IState
{
- var type = typeof(T);
- if (!States.TryGetValue(type, out var state)) return;
-
- // 如果当前状态是要注销的状态,则先执行退出逻辑
- if (Current == state)
+ lock (_lock)
{
- Current.OnExit(null);
- Current = null;
- }
+ var type = typeof(T);
+ if (!States.TryGetValue(type, out var state)) return;
- States.Remove(type);
+ // 如果当前状态是要注销的状态,则先执行退出逻辑
+ if (Current == state)
+ {
+ Current.OnExit(null);
+ Current = null;
+ }
+
+ // 从历史记录中移除该状态的所有引用
+ var tempStack = new Stack(_stateHistory.Reverse());
+ _stateHistory.Clear();
+ foreach (var historyState in tempStack.Where(s => s != state))
+ {
+ _stateHistory.Push(historyState);
+ }
+
+ States.Remove(type);
+ }
}
///
@@ -63,10 +82,117 @@ public class StateMachine : IStateMachine
/// 当目标状态未注册时抛出
public void ChangeTo() where T : IState
{
- if (!States.TryGetValue(typeof(T), out var target))
- throw new InvalidOperationException("State not registered.");
+ lock (_lock)
+ {
+ // 检查目标状态是否已注册
+ if (!States.TryGetValue(typeof(T), out var target))
+ throw new InvalidOperationException("State not registered.");
- ChangeInternal(target);
+ // 验证当前状态是否可以转换到目标状态
+ if (Current != null && !Current.CanTransitionTo(target))
+ throw new InvalidOperationException(
+ $"Cannot transition from {Current.GetType().Name} to {typeof(T).Name}");
+
+ ChangeInternal(target);
+ }
+ }
+
+ ///
+ /// 检查指定类型的状态是否已注册
+ ///
+ /// 要检查的状态类型
+ /// 如果状态已注册则返回true,否则返回false
+ public bool IsRegistered() where T : IState => States.ContainsKey(typeof(T));
+
+ ///
+ /// 获取指定类型的已注册状态实例
+ ///
+ /// 要获取的状态类型
+ /// 如果状态存在则返回对应实例,否则返回null
+ public T? GetState() where T : class, IState => States.TryGetValue(typeof(T), out var state) ? state as T : null;
+
+ ///
+ /// 获取所有已注册状态的类型集合
+ ///
+ /// 包含所有已注册状态类型的枚举器
+ public IEnumerable GetRegisteredStateTypes() => 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()
+ {
+ lock (_lock)
+ {
+ if (_stateHistory.Count == 0) return false;
+
+ var previousState = _stateHistory.Pop();
+
+ // 检查上一个状态是否仍然注册
+ if (!States.ContainsValue(previousState))
+ {
+ // 如果状态已被注销,继续尝试更早的状态
+ return GoBack();
+ }
+
+ // 回退时不添加到历史记录
+ ChangeInternalWithoutHistory(previousState);
+ return true;
+ }
+ }
+
+ ///
+ /// 清空状态历史记录
+ ///
+ public void ClearHistory()
+ {
+ lock (_lock)
+ {
+ _stateHistory.Clear();
+ }
+ }
+
+ ///
+ /// 内部状态切换方法(不记录历史),用于回退操作
+ ///
+ /// 下一个状态实例
+ 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);
}
///
@@ -75,13 +201,68 @@ public class StateMachine : IStateMachine
/// 下一个状态实例
protected virtual void ChangeInternal(IState next)
{
+ // 检查是否为相同状态,避免不必要的切换
if (Current == next) return;
- if (Current != null && !Current.CanTransitionTo(next)) return;
+
+ // 验证当前状态是否允许切换到目标状态
+ if (Current != null && !Current.CanTransitionTo(next))
+ {
+ OnTransitionRejected(Current, next);
+ return;
+ }
var old = Current;
- old?.OnExit(next);
+ OnStateChanging(old, next);
+ // 将当前状态添加到历史记录
+ if (Current != null)
+ {
+ _stateHistory.Push(Current);
+
+ // 限制历史记录大小
+ if (_stateHistory.Count > maxHistorySize)
+ {
+ // 移除最旧的记录(栈底元素)
+ var tempStack = new Stack(_stateHistory.Reverse().Skip(1));
+ _stateHistory.Clear();
+ foreach (var state in tempStack.Reverse())
+ {
+ _stateHistory.Push(state);
+ }
+ }
+ }
+
+ old?.OnExit(next);
Current = next;
Current.OnEnter(old);
+
+ OnStateChanged(old, Current);
+ }
+
+ ///
+ /// 当状态转换被拒绝时的回调方法
+ ///
+ /// 源状态
+ /// 目标状态
+ protected virtual void OnTransitionRejected(IState from, IState to)
+ {
+ }
+
+ ///
+ /// 当状态即将发生改变时的回调方法
+ ///
+ /// 源状态
+ /// 目标状态
+ protected virtual void OnStateChanging(IState? from, IState to)
+ {
+ }
+
+ ///
+ /// 当状态改变完成后的回调方法
+ ///
+ /// 源状态
+ /// 目标状态
+ protected virtual void OnStateChanged(IState? from, IState? to)
+ {
}
}
\ No newline at end of file