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;
}
}
}