using System.Collections.Generic; using Syntriax.Engine.Core; namespace Syntriax.Engine.Systems.StateMachine; public class State : BaseEntity, IState { public Event OnStateUpdate { get; } = new(); public Event OnStateTransitionedFrom { get; } = new(); public Event OnStateTransitionedTo { get; } = new(); public Event OnStateTransitionReady { get; } = new(); public Event OnNameChanged { get; } = new(); private readonly List transitions = []; private readonly Dictionary possibleTransitions = []; private string _name = "Default State Name"; public IReadOnlyList Transitions => transitions; public IReadOnlyDictionary 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; } }