This commit is contained in:
2025-05-30 16:05:49 +03:00
committed by Syntriax
parent 846aa75dd5
commit b5140a94de
57 changed files with 437 additions and 462 deletions

View File

@@ -4,10 +4,10 @@ namespace Syntriax.Engine.Systems.StateMachine;
public interface IState : IEntity, INameable
{
event StateUpdateEventHandler? OnStateUpdate;
event StateTransitionedFromEventHandler? OnStateTransitionedFrom;
event StateTransitionedToEventHandler? OnStateTransitionedTo;
event StateTransitionReadyEventHandler? OnStateTransitionReady;
Event<IState> OnStateUpdate { get; }
Event<IState, StateTransitionedFromArguments> OnStateTransitionedFrom { get; }
Event<IState, StateTransitionedToArguments> OnStateTransitionedTo { get; }
Event<IState, StateTransitionReadyArguments> OnStateTransitionReady { get; }
IState? GetNextState();
@@ -15,8 +15,7 @@ public interface IState : IEntity, INameable
void TransitionTo(IState from);
void TransitionFrom(IState to);
delegate void StateUpdateEventHandler(IState sender);
delegate void StateTransitionedFromEventHandler(IState sender, IState toState);
delegate void StateTransitionedToEventHandler(IState sender, IState fromState);
delegate void StateTransitionReadyEventHandler(IState sender, IState toState);
readonly record struct StateTransitionedFromArguments(IState ToState);
readonly record struct StateTransitionedToArguments(IState FromState);
readonly record struct StateTransitionReadyArguments(IState ToState);
}

View File

@@ -6,11 +6,11 @@ namespace Syntriax.Engine.Systems.StateMachine;
public class State : BaseEntity, IState
{
public event IState.StateUpdateEventHandler? OnStateUpdate = null;
public event IState.StateTransitionedFromEventHandler? OnStateTransitionedFrom = null;
public event IState.StateTransitionedToEventHandler? OnStateTransitionedTo = null;
public event IState.StateTransitionReadyEventHandler? OnStateTransitionReady = null;
public Event<INameable, string> OnNameChanged { get; private set; } = new();
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 = [];
@@ -28,7 +28,7 @@ public class State : BaseEntity, IState
string previousName = _name;
_name = value;
OnNameChanged?.Invoke(this, previousName);
OnNameChanged?.Invoke(this, new(previousName));
}
}
@@ -53,12 +53,12 @@ public class State : BaseEntity, IState
public void Update()
{
if (GetNextState() is IState transitionState)
OnStateTransitionReady?.Invoke(this, transitionState);
OnStateTransitionReady?.Invoke(this, new(transitionState));
OnStateUpdate?.Invoke(this);
}
public void TransitionTo(IState from) => OnStateTransitionedTo?.Invoke(this, from);
public void TransitionFrom(IState to) => OnStateTransitionedFrom?.Invoke(this, to);
public void TransitionTo(IState from) => OnStateTransitionedTo?.Invoke(this, new(from));
public void TransitionFrom(IState to) => OnStateTransitionedFrom?.Invoke(this, new(to));
public IState? GetNextState()
{

View File

@@ -4,13 +4,11 @@ namespace Syntriax.Engine.Systems.StateMachine;
public abstract class StateBehaviourBase : Behaviour, IState
{
public event IState.StateUpdateEventHandler? OnStateUpdate = null;
public event IState.StateTransitionedFromEventHandler? OnStateTransitionedFrom = null;
public event IState.StateTransitionedToEventHandler? OnStateTransitionedTo = null;
public Event<INameable, string> OnNameChanged { get; private set; } = new();
public abstract event IState.StateTransitionReadyEventHandler? OnStateTransitionReady;
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 string _name = string.Empty;
public string Name
@@ -23,7 +21,7 @@ public abstract class StateBehaviourBase : Behaviour, IState
string previousName = _name;
_name = value;
OnNameChanged?.Invoke(this, previousName);
OnNameChanged?.Invoke(this, new(previousName));
}
}
@@ -38,14 +36,14 @@ public abstract class StateBehaviourBase : Behaviour, IState
public void TransitionTo(IState from)
{
OnTransitionedToState(from);
OnStateTransitionedTo?.Invoke(this, from);
OnStateTransitionedTo?.Invoke(this, new(from));
}
protected virtual void OnTransitionedFromState(IState to) { }
public void TransitionFrom(IState to)
{
OnTransitionedFromState(to);
OnStateTransitionedFrom?.Invoke(this, to);
OnStateTransitionedFrom?.Invoke(this, new(to));
}
public abstract IState? GetNextState();

View File

@@ -5,9 +5,17 @@ namespace Syntriax.Engine.Systems.StateMachine;
public class StateMachine : Behaviour
{
public event StateChangedEventHandler? OnStateChanged = null;
public Event<StateMachine, StateChangedArguments> OnStateChanged { get; init; } = new();
private readonly Event<IState, IState.StateTransitionReadyArguments>.EventHandler cachedOnStateTransitionReady = null!;
private IState _state = new State();
public StateMachine()
{
cachedOnStateTransitionReady = OnStateTransitionReady;
}
[Serialize]
public IState State
{
@@ -18,20 +26,20 @@ public class StateMachine : Behaviour
return;
IState previousState = _state;
previousState.OnStateTransitionReady -= OnStateTransitionReady;
previousState.OnStateTransitionReady.RemoveListener(cachedOnStateTransitionReady);
_state = value;
previousState.TransitionFrom(value);
value.TransitionTo(_state);
OnStateChanged?.Invoke(this, previousState, value);
OnStateChanged?.Invoke(this, new(value, previousState));
value.OnStateTransitionReady += OnStateTransitionReady;
value.OnStateTransitionReady.AddListener(cachedOnStateTransitionReady);
}
}
private void OnStateTransitionReady(IState sender, IState toState)
private void OnStateTransitionReady(IState sender, IState.StateTransitionReadyArguments arguments)
{
State = toState;
State = arguments.ToState;
while (State.GetNextState() is IState nextState)
State = nextState;
}
@@ -47,5 +55,5 @@ public class StateMachine : Behaviour
State.Update();
}
public delegate void StateChangedEventHandler(StateMachine sender, IState previousState, IState newState);
public readonly record struct StateChangedArguments(IState CurrentState, IState PreviousState);
}