71 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System.Collections.Generic;
 | 
						|
 | 
						|
using Engine.Core;
 | 
						|
 | 
						|
namespace 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;
 | 
						|
    }
 | 
						|
}
 |