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