// Animancer // Copyright 2020 Kybernetik // using System; namespace Animancer.FSM { /// <summary> /// A state that uses delegates to define its behaviour in the <see cref="StateMachine{TState}"/>. /// </summary> public class DelegateState<TState> : IState<TState> where TState : class, IState<TState> { /************************************************************************************************************************/ /// <summary>Determines whether this state can be entered. Null is treated as returning true.</summary> public Func<TState, bool> canEnter; /// <summary>Determines whether this state can be exited. Null is treated as returning true.</summary> public Func<TState, bool> canExit; /// <summary>Called when this state is entered.</summary> public Action onEnter; /// <summary>Called when this state is exited.</summary> public Action onExit; /************************************************************************************************************************/ /// <summary> /// Constructs a new <see cref="DelegateState{TState}"/> with the provided delegates. /// </summary> /// <param name="canEnter">Determines whether this state can be entered. Null is treated as returning true.</param> /// <param name="canExit">Determines whether this state can be exited. Null is treated as returning true.</param> /// <param name="onEnter">Called when this state is entered.</param> /// <param name="onExit">Called when this state is exited.</param> public DelegateState( Func<TState, bool> canEnter = null, Func<TState, bool> canExit = null, Action onEnter = null, Action onExit = null) { this.canEnter = canEnter; this.canExit = canExit; this.onEnter = onEnter; this.onExit = onExit; } /************************************************************************************************************************/ /// <summary>Calls <see cref="canEnter"/> to determine whether this state can be entered.</summary> bool IState<TState>.CanEnterState(TState previousState) { return canEnter == null || canEnter(previousState); } /************************************************************************************************************************/ /// <summary>Calls <see cref="canExit"/> to determine whether this state can be exited.</summary> bool IState<TState>.CanExitState(TState nextState) { return canExit == null || canExit(nextState); } /************************************************************************************************************************/ /// <summary>Calls <see cref="onEnter"/> when this state is entered.</summary> void IState<TState>.OnEnterState() { if (onEnter != null) onEnter(); } /************************************************************************************************************************/ /// <summary>Calls <see cref="onExit"/> when this state is exited.</summary> void IState<TState>.OnExitState() { if (onExit != null) onExit(); } /************************************************************************************************************************/ } }