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

71 lines
2.3 KiB
C#

using System.Collections.Generic;
using Syntriax.Engine.Core;
namespace Syntriax.Engine.Systems.StateMachine;
public class State : BaseEntity, IState
{
public Event<IState> OnStateUpdate { get; } = new();
public Event<IState, IState.StateTransitionedFromArguments> OnStateTransitionedFrom { get; } = new();
public Event<IState, IState.StateTransitionedToArguments> OnStateTransitionedTo { get; } = new();
public Event<IState, IState.StateTransitionReadyArguments> OnStateTransitionReady { get; } = new();
public Event<INameable, INameable.NameChangedArguments> OnNameChanged { get; } = new();
private readonly List<StateTransition> transitions = [];
private readonly Dictionary<string, StateTransition> possibleTransitions = [];
private string _name = "Default State Name";
public IReadOnlyList<StateTransition> Transitions => transitions;
public IReadOnlyDictionary<string, StateTransition> PossibleTransitions => possibleTransitions;
public string Name
{
get => _name;
set
{
if (_name.CompareTo(value) == 0)
return;
string previousName = _name;
_name = value;
OnNameChanged?.Invoke(this, new(previousName));
}
}
public void RemoveTransition(string name)
{
if (!possibleTransitions.TryGetValue(name, out StateTransition stateTransition))
return;
transitions.Remove(stateTransition);
possibleTransitions.Remove(name);
}
public void AddTransition(string name, StateTransition stateTransition)
{
if (transitions.Contains(stateTransition))
return;
transitions.Add(stateTransition);
possibleTransitions.Add(name, stateTransition);
}
public void Update()
{
if (GetNextState() is IState transitionState)
OnStateTransitionReady?.Invoke(this, new(transitionState));
OnStateUpdate?.Invoke(this);
}
public void TransitionTo(IState from) => OnStateTransitionedTo?.Invoke(this, new(from));
public void TransitionFrom(IState to) => OnStateTransitionedFrom?.Invoke(this, new(to));
public IState? GetNextState()
{
foreach (StateTransition stateTransition in transitions)
if (stateTransition.CanTransition)
return stateTransition.State;
return null;
}
}