using System; using System.Collections.Generic; using Cysharp.Threading.Tasks; namespace BITKit.StateMachine { public struct EmptyState:IState { public bool Enabled { get; set; } public void Initialize() { } public void OnStateEntry(IState old) { } public void OnStateUpdate(float deltaTime) { } public void OnStateExit(IState old, IState newState) { } } public interface IState { bool Enabled { get; set; } void Initialize(); void OnStateEntry(IState old); void OnStateUpdate(float deltaTime); void OnStateExit(IState old, IState newState); } public interface IStateAsync:IState { /// /// 识别符,用于识别多个相同状态但不同用途的状态机 /// int Identifier { get; set; } UniTask InitializeAsync(); UniTask OnStateEntryAsync(IState old); UniTask OnStateUpdateAsync(float deltaTime); UniTask OnStateExitAsync(IState old, IState newState); } public interface IStateMachine where T:IState { bool Enabled { get; set; } T CurrentState { get; } event Action OnStateChanged; event Action OnStateRegistered; event Action OnStateUnRegistered; IDictionary StateDictionary { get; } void Initialize(); void UpdateState(float deltaTime); void DisposeState(); T TransitionState() where TState : T; T TransitionState(T state); void Register(T newState) => throw new NotImplementedException("未实现的接口"); void UnRegister(T newState) => throw new NotImplementedException("未实现的接口"); void InvokeOnStateRegistered(T state){} void InvokeOnStateUnRegistered(T state){} } public static class StateMachineUtils { public static void Register(this IStateMachine stateMachine, T newState) where T : IState { if (stateMachine.StateDictionary.ContainsKey(newState.GetType())) { throw new ArgumentException($"State {newState.GetType().Name} already registered"); } stateMachine.StateDictionary.Add(newState.GetType(), newState); newState.Initialize(); stateMachine.InvokeOnStateRegistered(newState); } public static void UnRegister(this IStateMachine stateMachine, T newState) where T : IState { if (!stateMachine.StateDictionary.ContainsKey(newState.GetType())) return; stateMachine.StateDictionary.Remove(newState.GetType()); stateMachine.InvokeOnStateUnRegistered(newState); } } }