using UnityEngine.XR.Interaction.Toolkit.Utilities.Internal; namespace UnityEngine.XR.Interaction.Toolkit.Utilities { /// /// A cache for a Unity Object reference that is used to avoid the overhead of the Unity Object alive check /// every time the reference is accessed after the first time. /// /// The type of the serialized field. class UnityObjectReferenceCache where T : Object { T m_CapturedField; T m_FieldOrNull; /// /// A fast but unsafe method for getting the field without doing a Unity Object alive check after the first time. /// The purpose is to avoid the overhead of the Unity Object alive check when it is known that the reference is alive, /// but does not have the rigor of detecting when the Object is deleted or destroyed after the first check, which should be very rare. /// This will handle the user modifying the field in the Inspector window by invalidating the cached version. /// /// The serialized field to get. /// The Unity Object or actual . /// Returns if the reference is not null. Otherwise, returns . public bool TryGet(T field, out T fieldOrNull) { if (ReferenceEquals(m_CapturedField, field)) { fieldOrNull = m_FieldOrNull; #pragma warning disable UNT0029 // bypass Unity Object alive check return m_FieldOrNull is not null; #pragma warning restore UNT0029 } m_CapturedField = field; if (field != null) { m_FieldOrNull = field; fieldOrNull = field; return true; } m_FieldOrNull = null; fieldOrNull = null; return false; } } /// /// A cache for a serialized Unity Object reference that represents an interface type. /// /// Interface that the reference Unity Object should implement. /// Serialized field type, usually Unity . /// class UnityObjectReferenceCache where TInterface : class where TObject : Object { TObject m_CapturedObject; TInterface m_Interface; /// /// Gets the interface-typed Object reference. /// /// The serialized field to get. /// Returns the interface-typed Object reference, which may be . public TInterface Get(TObject field) { if (ReferenceEquals(m_CapturedObject, field)) return m_Interface; m_CapturedObject = field; m_Interface = field as TInterface; return m_Interface; } /// /// Sets the Object reference to the interface-typed reference. /// /// The serialized field to set. /// The interface-typed value. // ReSharper disable once RedundantAssignment -- ref field is used to update the serialized field with the new value public void Set(ref TObject field, TInterface value) { field = value as TObject; m_CapturedObject = field; m_Interface = value; } } }