using GFramework.Core.Abstractions.state;
namespace GFramework.Core.state;
///
/// 状态机实现类,用于管理状态的注册、切换和生命周期
///
public class StateMachine : IStateMachine
{
///
/// 存储所有已注册状态的字典,键为状态类型,值为状态实例
///
protected readonly Dictionary States = new();
///
/// 获取当前激活的状态
///
public IState? Current { get; private set; }
///
/// 注册一个状态到状态机中
///
/// 要注册的状态实例
public void Register(IState state)
=> States[state.GetType()] = state;
///
/// 从状态机中注销指定类型的状态
///
/// 要注销的状态类型
public void Unregister() where T : IState
{
var type = typeof(T);
if (!States.TryGetValue(type, out var state)) return;
// 如果当前状态是要注销的状态,则先执行退出逻辑
if (Current == state)
{
Current.OnExit(null);
Current = null;
}
States.Remove(type);
}
///
/// 检查是否可以切换到指定类型的状态
///
/// 目标状态类型
/// 如果可以切换则返回true,否则返回false
public bool CanChangeTo() where T : IState
{
if (!States.TryGetValue(typeof(T), out var target))
return false;
return Current?.CanTransitionTo(target) ?? true;
}
///
/// 切换到指定类型的状态
///
/// 目标状态类型
/// 当目标状态未注册时抛出
public void ChangeTo() where T : IState
{
if (!States.TryGetValue(typeof(T), out var target))
throw new InvalidOperationException("State not registered.");
ChangeInternal(target);
}
///
/// 内部状态切换方法,处理状态切换的核心逻辑
///
/// 下一个状态实例
protected virtual void ChangeInternal(IState next)
{
if (Current == next) return;
if (Current != null && !Current.CanTransitionTo(next)) return;
var old = Current;
old?.OnExit(next);
Current = next;
Current.OnEnter(old);
}
}