60 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			60 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using Engine.Core;
 | 
						|
using Engine.Core.Serialization;
 | 
						|
 | 
						|
namespace Engine.Systems.StateMachine;
 | 
						|
 | 
						|
public class StateMachine : Behaviour, IUpdate
 | 
						|
{
 | 
						|
    public Event<StateMachine, StateChangedArguments> OnStateChanged { get; } = new();
 | 
						|
 | 
						|
    private readonly Event<IState, IState.StateTransitionReadyArguments>.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;
 | 
						|
    }
 | 
						|
 | 
						|
    public void Update()
 | 
						|
    {
 | 
						|
        if (State is null)
 | 
						|
            return;
 | 
						|
 | 
						|
        while (State.GetNextState() is IState nextState)
 | 
						|
            State = nextState;
 | 
						|
 | 
						|
        State.Update();
 | 
						|
    }
 | 
						|
 | 
						|
    public readonly record struct StateChangedArguments(IState CurrentState, IState PreviousState);
 | 
						|
}
 |