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 delegateOnStateTransitionReady = null!; private IState _state = new State(); public StateMachine() { delegateOnStateTransitionReady = OnStateTransitionReady; } [Serialize] public IState State { get => _state; set { if (_state == value) return; IState previousState = _state; previousState.OnStateTransitionReady.RemoveListener(delegateOnStateTransitionReady); _state = value; previousState.TransitionFrom(value); value.TransitionTo(_state); OnStateChanged?.Invoke(this, new(value, previousState)); value.OnStateTransitionReady.AddListener(delegateOnStateTransitionReady); } } private void OnStateTransitionReady(IState sender, IState.StateTransitionReadyArguments args) { State = args.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); }