using System; using System.Collections.Generic; namespace UnityEngine.XR.ARSubsystems { /// /// A utility to validate data from certain types of Subsystems. /// /// The managed by the subsystem. /// /// /// public class ValidationUtility where T : struct, ITrackable { /// /// Performs validation checks that ensure a trackable does not exist in multiple lists /// simultaneously (for example, both added and removed). Also ensures that a trackable cannot be /// removed before being added. /// /// A set of changes to trackables (added, updated and removed). public void ValidateAndThrow(TrackableChanges changes) { s_IdSet.Clear(); foreach (var trackable in changes.added) { AddToSetAndThrowIfDuplicate(trackable.trackableId, false, k_AddedAction); m_Trackables.Add(trackable.trackableId); } foreach (var trackable in changes.updated) AddToSetAndThrowIfDuplicate(trackable.trackableId, true, k_UpdatedAction); foreach (var trackableId in changes.removed) { AddToSetAndThrowIfDuplicate(trackableId, true, k_RemovedAction); m_Trackables.Remove(trackableId); } } /// /// Same as but also disposes the . /// /// A set of changes to trackables (added, updated and removed). public void ValidateAndDisposeIfThrown(TrackableChanges changes) { try { using (new ScopedProfiler("ValidateTrackableChanges")) ValidateAndThrow(changes); } catch { changes.Dispose(); throw; } } void AddToSetAndThrowIfDuplicate( TrackableId trackableId, bool shouldBeInDictionary, string action) { if (!s_IdSet.Add(trackableId)) throw new InvalidOperationException( string.Format( "Trackable {0} being {1} this frame has at least one other action associated with it.", trackableId, action)); if (m_Trackables.Contains(trackableId) != shouldBeInDictionary) throw new InvalidOperationException(string.Format( "Trackable {0} is being {1} but is {2} in the list of trackables.", trackableId, action, shouldBeInDictionary ? "not" : "already")); } static HashSet s_IdSet = new (); static readonly string k_AddedAction = "added"; static readonly string k_UpdatedAction = "updated"; static readonly string k_RemovedAction = "removed"; HashSet m_Trackables = new (); } }