using System; using System.Collections.Concurrent; 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 IMicroStateMachine { T CurrentState { get; } event Action OnStateChanged; T TransitionState() where TState : T; T TransitionState(T state); } public interface IStateMachine:IMicroStateMachine where T:IState { bool Enabled { get; set; } event Action OnStateRegistered; event Action OnStateUnRegistered; IDictionary StateDictionary { get; } void Initialize(); void UpdateState(float deltaTime); void DisposeState(); void Register(T newState) => throw new NotImplementedException("未实现的接口"); void UnRegister(T newState) => throw new NotImplementedException("未实现的接口"); void InvokeOnStateRegistered(T state){} void InvokeOnStateUnRegistered(T state){} } public class MicroStateMachine : IMicroStateMachine { public T CurrentState { get; private set; } public event Action OnStateChanged; private readonly ConcurrentDictionary _stateDictionary=new(); public T TransitionState() where TState : T { var state = _stateDictionary.GetOrAdd(typeof(TState), Activator.CreateInstance()); return TransitionState(state); } public T TransitionState(T state) { _stateDictionary.TryAdd(state.GetType(), state); if (Equals(state, CurrentState)) return default; var currentState = CurrentState; CurrentState = state; OnStateChanged?.Invoke(currentState, state); return state; } } public abstract class StateAsync:IStateAsync { public virtual bool Enabled { get; set; } public virtual void Initialize() { } public virtual void OnStateEntry(IState old) { } public virtual void OnStateUpdate(float deltaTime) { } public virtual void OnStateExit(IState old, IState newState) { } public virtual int Identifier { get; set; } public virtual UniTask InitializeAsync() { return UniTask.CompletedTask; } public virtual UniTask OnStateEntryAsync(IState old) { return UniTask.CompletedTask; } public virtual UniTask OnStateUpdateAsync(float deltaTime) { return UniTask.CompletedTask; } public virtual UniTask OnStateExitAsync(IState old, IState newState) { return UniTask.CompletedTask; } } 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); } } }