All delegate events are refactored to use the Event<TSender> and Event<TSender, TArgument> for performance issues regarding delegate events creating garbage, also this gives us better control on event invocation since C# Delegates did also create unnecessary garbage during Delegate.DynamicInvoke
60 lines
1.6 KiB
C#
60 lines
1.6 KiB
C#
using Syntriax.Engine.Core;
|
|
using Syntriax.Engine.Core.Serialization;
|
|
|
|
namespace Syntriax.Engine.Systems.StateMachine;
|
|
|
|
public class StateMachine : Behaviour
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|