using System;
using System.Collections.Generic;
using UnityEngine.XR.Management;
using UnityEngine.SubsystemsImplementation;
namespace UnityEngine.XR.ARFoundation
{
///
/// A base class for subsystems whose lifetime is managed by a MonoBehaviour.
///
/// The [Subsystem](xref:UnityEngine.Subsystem) which provides this manager data.
/// The [provider](xref:UnityEngine.SubsystemsImplementation.SubsystemProvider) associated with this subsystem.
/// The SubsystemDescriptor required to create the Subsystem.
public class SubsystemLifecycleManager : MonoBehaviour
where TSubsystem : SubsystemWithProvider, new()
where TSubsystemDescriptor : SubsystemDescriptorWithProvider
where TProvider : SubsystemProvider
{
///
/// Get the TSubsystem whose lifetime this component manages.
///
public TSubsystem subsystem { get; private set; }
///
/// The descriptor for the subsystem.
///
///
/// The descriptor for the subsystem.
///
public TSubsystemDescriptor descriptor => subsystem?.subsystemDescriptor;
///
/// Returns the active TSubsystem instance if present, otherwise returns null.
///
/// The active subsystem instance, or `null` if there isn't one.
protected TSubsystem GetActiveSubsystemInstance()
{
TSubsystem activeSubsystem = null;
// Query the currently active loader for the created subsystem, if one exists.
if (XRGeneralSettings.Instance != null && XRGeneralSettings.Instance.Manager != null)
{
XRLoader loader = XRGeneralSettings.Instance.Manager.activeLoader;
if (loader != null)
activeSubsystem = loader.GetLoadedSubsystem();
}
if (activeSubsystem == null)
Debug.LogWarningFormat($"No active {typeof(TSubsystem).FullName} is available. Please ensure that a " +
"valid loader configuration exists in the XR project settings.");
return activeSubsystem;
}
///
/// Called by derived classes to initialize the subsystem is initialized before use
///
protected void EnsureSubsystemInstanceSet()
{
subsystem = GetActiveSubsystemInstance();
}
///
/// Creates the TSubsystem.
///
protected virtual void OnEnable()
{
EnsureSubsystemInstanceSet();
if (subsystem != null)
{
OnBeforeStart();
// The derived class may disable the
// component if it has invalid state
if (enabled)
{
subsystem.Start();
OnAfterStart();
}
}
}
///
/// Stops the TSubsystem.
///
protected virtual void OnDisable()
{
if (subsystem != null)
subsystem.Stop();
}
///
/// Destroys the TSubsystem.
///
protected virtual void OnDestroy()
{
subsystem = null;
}
///
/// Invoked after creating the subsystem and before calling Start on it.
/// The is not null.
///
protected virtual void OnBeforeStart()
{ }
///
/// Invoked after calling Start on it the Subsystem.
/// The is not null.
///
protected virtual void OnAfterStart()
{ }
static List s_SubsystemDescriptors =
new List();
static List s_SubsystemInstances =
new List();
}
}