// Animancer // Copyright 2020 Kybernetik // using UnityEngine; namespace Animancer.FSM { public partial class StateMachine { /// /// A simple buffer that remembers any failed calls to /// so that it can retry them each time you it until the expires. /// public class InputBuffer { /************************************************************************************************************************/ /// The this buffer is feeding input to. public StateMachine StateMachine { get; set; } /// The this buffer is currently attempting to enter. public TState BufferedState { get; set; } /// The amount of time left before the is cleared. public float TimeOut { get; set; } /// /// If true, the will be updated using . /// Otherwise it will use . /// public bool UseUnscaledTime { get; set; } /************************************************************************************************************************/ /// Indicates whether there is currently a . public bool IsBufferActive { get { return BufferedState != null; } } /************************************************************************************************************************/ /// /// Constructs a new targeting the specified `stateMachine`. /// public InputBuffer(StateMachine stateMachine) { StateMachine = stateMachine; } /************************************************************************************************************************/ /// /// Attempts to enter the specified state and returns true if successful. /// Otherwise the state is remembered and attempted again every time is called. /// public bool TrySetState(TState state, float timeOut) { BufferedState = state; TimeOut = timeOut; // If you can enter that state immediately, clear the buffer. if (TryEnterBufferedState()) { Clear(); return true; } else { return false; } } /************************************************************************************************************************/ /// /// Attempts to enter the and returns true if successful. /// protected virtual bool TryEnterBufferedState() { return StateMachine.TryResetState(BufferedState); } /************************************************************************************************************************/ /// /// Attempts to enter the if there is one and returns true if successful. /// Otherwise the is decreased by and the /// is forgotten after it reaches 0. /// /// If is true, it will use instead. /// public bool Update() { return Update(UseUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime); } /// /// Attempts to enter the if there is one and returns true if successful. /// Otherwise the is decreased by `deltaTime` and the is /// forgotten after it reaches 0. /// public bool Update(float deltaTime) { if (IsBufferActive) { if (TryEnterBufferedState()) { Clear(); return true; } else { TimeOut -= deltaTime; if (TimeOut <= 0) Clear(); } } return false; } /************************************************************************************************************************/ /// /// Attempts to enter the if there is one and returns true if successful. /// /// Unlike , this method doesn't update the . /// public bool CheckBuffer() { if (IsBufferActive && TryEnterBufferedState()) { Clear(); return true; } return false; } /************************************************************************************************************************/ /// Clears the buffer. public void Clear() { BufferedState = null; } /************************************************************************************************************************/ } } }