2025-05-30 18:37:35 +03:00

71 lines
2.4 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; init; } = new();
public Event<IState, IState.StateTransitionedFromArguments> OnStateTransitionedFrom { get; init; } = new();
public Event<IState, IState.StateTransitionedToArguments> OnStateTransitionedTo { get; init; } = new();
public Event<IState, IState.StateTransitionReadyArguments> OnStateTransitionReady { get; init; } = new();
public Event<INameable, INameable.NameChangedArguments> OnNameChanged { get; init; } = 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;
}
}