using System; namespace UnityEngine.InputSystem.Utilities { /// /// Provides type erasure and an abstraction of a saved state that /// will (must) be restored at a later point. /// internal interface ISavedState { /// /// Dispose current state, should be invoked before RestoreSavedState() /// to dispose the current state before restoring a saved state. /// void StaticDisposeCurrentState(); /// /// Restore previous state, should be invoked after StaticDisposeCurrentState(). /// void RestoreSavedState(); } /// /// Provides functionality to store and support later restoration of a saved /// state. The state is expected to be a value-type. If the state is not restored /// it must be disposed to not leak resources. /// /// The value-type representing the state to be stored. internal sealed class SavedStructState : ISavedState where T : struct { public delegate void TypedRestore(ref T state); /// /// Constructs a SavedStructState. /// /// The value-type state to be saved. /// The action to be carried out to restore state. /// The action to be carried out to dispose current state. May be null. internal SavedStructState(ref T state, TypedRestore restoreAction, Action staticDisposeCurrentState = null) { Debug.Assert(restoreAction != null, "Restore action is required"); m_State = state; // copy m_RestoreAction = restoreAction; m_StaticDisposeCurrentState = staticDisposeCurrentState; } public void StaticDisposeCurrentState() { if (m_StaticDisposeCurrentState != null) { m_StaticDisposeCurrentState(); m_StaticDisposeCurrentState = null; } } public void RestoreSavedState() { Debug.Assert(m_StaticDisposeCurrentState == null, $"Should have been disposed via {nameof(StaticDisposeCurrentState)} before invoking {nameof(RestoreSavedState)}"); Debug.Assert(m_RestoreAction != null, $"Only invoke {nameof(RestoreSavedState)} once "); m_RestoreAction(ref m_State); m_RestoreAction = null; } private T m_State; private TypedRestore m_RestoreAction; private Action m_StaticDisposeCurrentState; } }