上传YomovSDK
This commit is contained in:
291
Packages/com.unity.xr.openxr/Runtime/OpenXRRestarter.cs
Normal file
291
Packages/com.unity.xr.openxr/Runtime/OpenXRRestarter.cs
Normal file
@@ -0,0 +1,291 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Management;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR
|
||||
{
|
||||
internal class OpenXRRestarter : MonoBehaviour
|
||||
{
|
||||
internal Action onAfterRestart;
|
||||
internal Action onAfterShutdown;
|
||||
internal Action onQuit;
|
||||
internal Action onAfterCoroutine;
|
||||
internal Action onAfterSuccessfulRestart;
|
||||
|
||||
static OpenXRRestarter()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
EditorApplication.playModeStateChanged += (state) =>
|
||||
{
|
||||
if (state == PlayModeStateChange.EnteredPlayMode)
|
||||
m_pauseAndRestartAttempts = 0;
|
||||
};
|
||||
#endif
|
||||
TimeBetweenRestartAttempts = 5.0f;
|
||||
DisableApplicationQuit = false;
|
||||
}
|
||||
|
||||
public void ResetCallbacks()
|
||||
{
|
||||
onAfterRestart = null;
|
||||
onAfterSuccessfulRestart = null;
|
||||
onAfterShutdown = null;
|
||||
onAfterCoroutine = null;
|
||||
onQuit = null;
|
||||
m_pauseAndRestartAttempts = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if the restarter is currently running
|
||||
/// </summary>
|
||||
public bool isRunning => m_Coroutine != null;
|
||||
|
||||
private static OpenXRRestarter s_Instance = null;
|
||||
|
||||
private Coroutine m_Coroutine;
|
||||
|
||||
private static int m_pauseAndRestartCoroutineCount = 0;
|
||||
|
||||
private Object m_PauseAndRestartCoroutineCountLock = new Object();
|
||||
|
||||
private static int m_pauseAndRestartAttempts = 0;
|
||||
|
||||
public static float TimeBetweenRestartAttempts
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public static int PauseAndRestartAttempts
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_pauseAndRestartAttempts;
|
||||
}
|
||||
}
|
||||
|
||||
internal static int PauseAndRestartCoroutineCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_pauseAndRestartCoroutineCount;
|
||||
}
|
||||
}
|
||||
|
||||
public static OpenXRRestarter Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_Instance == null)
|
||||
{
|
||||
var go = GameObject.Find("~oxrestarter");
|
||||
if (go == null)
|
||||
{
|
||||
go = new GameObject("~oxrestarter");
|
||||
go.hideFlags = HideFlags.HideAndDontSave;
|
||||
go.AddComponent<OpenXRRestarter>();
|
||||
}
|
||||
s_Instance = go.GetComponent<OpenXRRestarter>();
|
||||
}
|
||||
return s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, disables the application quitting, even when Quit is called.
|
||||
/// Used in testing, which needs to monitor for Quit to be called.
|
||||
/// </summary>
|
||||
internal static bool DisableApplicationQuit
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shutdown the the OpenXR loader and optionally quit the application
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
if (OpenXRLoader.Instance == null)
|
||||
return;
|
||||
|
||||
if (m_Coroutine != null)
|
||||
{
|
||||
Debug.LogError("Only one shutdown or restart can be executed at a time");
|
||||
return;
|
||||
}
|
||||
|
||||
m_Coroutine = StartCoroutine(RestartCoroutine(false, true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restart the OpenXR loader
|
||||
/// </summary>
|
||||
public void ShutdownAndRestart()
|
||||
{
|
||||
if (OpenXRLoader.Instance == null)
|
||||
return;
|
||||
|
||||
if (m_Coroutine != null)
|
||||
{
|
||||
Debug.LogError("Only one shutdown or restart can be executed at a time");
|
||||
return;
|
||||
}
|
||||
|
||||
m_Coroutine = StartCoroutine(RestartCoroutine(true, true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a coroutine that will pause, then shut xr down, then re-initialize xr.
|
||||
/// </summary>
|
||||
public void PauseAndShutdownAndRestart()
|
||||
{
|
||||
if (OpenXRLoader.Instance == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartCoroutine(PauseAndShutdownAndRestartCoroutine(TimeBetweenRestartAttempts));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a coroutine that will pause, then re-initialize xr if xr hasn't already succeeded.
|
||||
/// </summary>
|
||||
public void PauseAndRetryInitialization()
|
||||
{
|
||||
if (OpenXRLoader.Instance == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartCoroutine(PauseAndRetryInitializationCoroutine(TimeBetweenRestartAttempts));
|
||||
}
|
||||
|
||||
private void IncrementPauseAndRestartCoroutineCount()
|
||||
{
|
||||
lock (m_PauseAndRestartCoroutineCountLock)
|
||||
{
|
||||
m_pauseAndRestartCoroutineCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void DecrementPauseAndRestartCoroutineCount()
|
||||
{
|
||||
lock (m_PauseAndRestartCoroutineCountLock)
|
||||
{
|
||||
m_pauseAndRestartCoroutineCount -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator PauseAndShutdownAndRestartCoroutine(float pauseTimeInSeconds)
|
||||
{
|
||||
IncrementPauseAndRestartCoroutineCount();
|
||||
|
||||
try
|
||||
{
|
||||
// Wait a few seconds to add delay between restart requests in a restart loop.
|
||||
yield return new WaitForSeconds(pauseTimeInSeconds);
|
||||
|
||||
yield return new WaitForRestartFinish();
|
||||
|
||||
m_pauseAndRestartAttempts += 1;
|
||||
m_Coroutine = StartCoroutine(RestartCoroutine(true, true));
|
||||
}
|
||||
finally
|
||||
{
|
||||
onAfterCoroutine?.Invoke();
|
||||
}
|
||||
|
||||
DecrementPauseAndRestartCoroutineCount();
|
||||
}
|
||||
|
||||
private IEnumerator PauseAndRetryInitializationCoroutine(float pauseTimeInSeconds)
|
||||
{
|
||||
IncrementPauseAndRestartCoroutineCount();
|
||||
|
||||
try
|
||||
{
|
||||
// Wait a few seconds to add delay between restart requests in a restart loop.
|
||||
yield return new WaitForSeconds(pauseTimeInSeconds);
|
||||
|
||||
yield return new WaitForRestartFinish();
|
||||
|
||||
bool shouldSkipRestart = XRGeneralSettings.Instance.Manager.activeLoader != null;
|
||||
if (!shouldSkipRestart)
|
||||
{
|
||||
m_pauseAndRestartAttempts += 1;
|
||||
m_Coroutine = StartCoroutine(RestartCoroutine(true, false));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
onAfterCoroutine?.Invoke();
|
||||
}
|
||||
|
||||
DecrementPauseAndRestartCoroutineCount();
|
||||
}
|
||||
|
||||
private IEnumerator RestartCoroutine(bool shouldRestart, bool shouldShutdown)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (shouldShutdown)
|
||||
{
|
||||
Debug.Log("Shutting down OpenXR.");
|
||||
yield return null;
|
||||
|
||||
// Always shutdown the loader
|
||||
XRGeneralSettings.Instance.Manager.DeinitializeLoader();
|
||||
yield return null;
|
||||
|
||||
onAfterShutdown?.Invoke();
|
||||
}
|
||||
|
||||
// Restart?
|
||||
if (shouldRestart && OpenXRRuntime.ShouldRestart())
|
||||
{
|
||||
Debug.Log("Initializing OpenXR.");
|
||||
yield return XRGeneralSettings.Instance.Manager.InitializeLoader();
|
||||
|
||||
XRGeneralSettings.Instance.Manager.StartSubsystems();
|
||||
|
||||
if (XRGeneralSettings.Instance.Manager.activeLoader != null)
|
||||
{
|
||||
m_pauseAndRestartAttempts = 0;
|
||||
onAfterSuccessfulRestart?.Invoke();
|
||||
}
|
||||
|
||||
onAfterRestart?.Invoke();
|
||||
}
|
||||
// Quit?
|
||||
else if (OpenXRRuntime.ShouldQuit())
|
||||
{
|
||||
onQuit?.Invoke();
|
||||
|
||||
if (!DisableApplicationQuit)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (EditorApplication.isPlaying || EditorApplication.isPaused)
|
||||
{
|
||||
EditorApplication.ExitPlaymode();
|
||||
}
|
||||
#else
|
||||
Application.Quit();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_Coroutine = null;
|
||||
onAfterCoroutine?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user