/************************************************************************************************************************/ internal static void Begin(TKey previousKey, TKey nextKey, out KeyChange <TKey> previouslyActiveChange) { previouslyActiveChange = _Current;// In case of recursive calls. _Current = new KeyChange <TKey>(previousKey, nextKey); KeyChangeDebug.AddActiveChange(typeof(TKey)); }
/************************************************************************************************************************/ /// <summary> /// Calls <see cref="IState.OnExitState"/> on the current state then changes to the specified key and /// state and calls <see cref="IState.OnEnterState"/> on it. /// <para></para> /// Note that this method does not check <see cref="IState.CanExitState"/> or /// <see cref="IState.CanEnterState"/>. To do that, you should use /// <see cref="TrySetState(TKey, TState)"/> instead. /// </summary> public void ForceSetState(TKey key, TState state) { KeyChange <TKey> .Begin(CurrentKey, key, out var previouslyActiveChange); try { CurrentKey = key; ForceSetState(state); } finally { KeyChange <TKey> .End(previouslyActiveChange); } }
/************************************************************************************************************************/ /// <summary> /// Attempts to enter the specified `state` and returns true if successful. /// <para></para> /// This method does not check if the `state` is already the <see cref="StateMachine{TState}.CurrentState"/>. /// To do so, use <see cref="TrySetState(TKey, TState)"/> instead. /// </summary> public bool TryResetState(TKey key, TState state) { KeyChange <TKey> .Begin(CurrentKey, key, out var previouslyActiveChange); try { if (!CanSetState(state)) { return(false); } ForceSetState(key, state); return(true); } finally { KeyChange <TKey> .End(previouslyActiveChange); } }
/************************************************************************************************************************/ /// <summary>[<see cref="IDisposable"/>] /// Re-assigns the values of this change (which were the previous values from when it was created) to be the /// currently active change. See the constructor for recommended usage. /// </summary> /// <remarks> /// Usually this will be returning to default values (nulls), but if one state change causes another then the /// second one ending will return to the first which will then return to the defaults. /// </remarks> public void Dispose() { _Current = this; }