using Engine.Core; using Engine.Core.Serialization; namespace Engine.Systems.StateMachine; public class StateMachine : Behaviour, IUpdate { public Event OnStateChanged { get; } = new(); private readonly Event.EventHandler delegateOnStateTransitionReady = null!; [Serialize] public IState State { get; set { if (field == value) return; IState previousState = field; previousState.OnStateTransitionReady.RemoveListener(delegateOnStateTransitionReady); field = value; previousState.TransitionFrom(value); value.TransitionTo(field); OnStateChanged?.Invoke(this, new(value, previousState)); value.OnStateTransitionReady.AddListener(delegateOnStateTransitionReady); } } = new State(); private void OnStateTransitionReady(IState sender, IState.StateTransitionReadyArguments args) { State = args.ToState; while (State.GetNextState() is IState nextState) State = nextState; } public void Update() { if (State is null) return; while (State.GetNextState() is IState nextState) State = nextState; State.Update(); } public StateMachine() { delegateOnStateTransitionReady = OnStateTransitionReady; } public readonly record struct StateChangedArguments(IState CurrentState, IState PreviousState); }