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