using System; using System.Collections.Generic; using UnityEngine.SubsystemsImplementation; using UnityEngine.XR.Management; namespace UnityEngine.XR.ARFoundation.InternalUtils { /// /// A utility class for checking loaded subsystems. /// static class SubsystemUtils { static Dictionary s_SubsystemsByType = new(); static Dictionary s_IntegratedSubsystemsByType = new(); /// /// Returns if there is a loaded of /// type , and outputs it. /// /// The base subsystem type, ie `XRSessionSubsystem`. /// The derived subsystem type to match. /// The loaded subsystem, if this method returns . /// if there exists a loaded of type /// . Otherwise, . internal static bool TryGetLoadedSubsystem(out TSubsystem subsystem) where TSubsystemBase : SubsystemWithProvider, new() where TSubsystem : TSubsystemBase { if (s_SubsystemsByType.TryGetValue(typeof(TSubsystem), out var subsystemWithProvider)) { if (subsystemWithProvider != null) { subsystem = subsystemWithProvider as TSubsystem; return true; } s_SubsystemsByType.Remove(typeof(TSubsystem)); } TryGetLoadedSubsystem(out var baseSubsystem); subsystem = baseSubsystem as TSubsystem; if (subsystem != null) s_SubsystemsByType.Add(typeof(TSubsystem), subsystem); return subsystem != null; } /// /// Returns if there is a loaded of /// type and outputs it. Otherwise, . /// /// This method REQUIRES that `TSubsystemBase` is a base subsystem type, i.e. `XRSessionSubsystem`. /// /// The base subsystem type, ie `XRSessionSubsystem`. /// The loaded subsystem, if this method returns . /// if there exists a loaded . /// Otherwise, . internal static bool TryGetLoadedSubsystem(out TSubsystemBase subsystem) where TSubsystemBase : SubsystemWithProvider, new() { if (XRGeneralSettings.Instance == null || XRGeneralSettings.Instance.Manager == null) { subsystem = null; return false; } var loader = XRGeneralSettings.Instance.Manager.activeLoader; subsystem = loader != null ? loader.GetLoadedSubsystem() : null; return subsystem != null; } /// /// Returns if there is a loaded integrated subsystem of /// type . Otherwise, . /// /// The integrated subsystem type. /// The loaded subsystem, if this method returns . /// if there exists a loaded . /// Otherwise, . internal static bool TryGetLoadedIntegratedSubsystem(out TIntegratedSubsystem subsystem) where TIntegratedSubsystem : IntegratedSubsystem, new() { if (s_IntegratedSubsystemsByType.TryGetValue(typeof(TIntegratedSubsystem), out var baseSubsystem)) { if (baseSubsystem != null) { subsystem = baseSubsystem as TIntegratedSubsystem; return true; } s_IntegratedSubsystemsByType.Remove(typeof(TIntegratedSubsystem)); } if (XRGeneralSettings.Instance == null || XRGeneralSettings.Instance.Manager == null) { subsystem = null; return false; } var loader = XRGeneralSettings.Instance.Manager.activeLoader; subsystem = loader != null ? loader.GetLoadedSubsystem() : null; if (subsystem != null) s_IntegratedSubsystemsByType.Add(typeof(TIntegratedSubsystem), subsystem); return subsystem != null; } } }