Syntriax 61e2761580 perf!: events refactored throughout all the project to use Event<> class
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
2025-05-31 00:32:58 +03:00

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);
}