VR4Medical/ICI/Library/PackageCache/com.unity.xr.openxr@3903c1059bcf/Runtime/OpenXRRuntime.cs
2025-07-29 13:45:50 +03:00

276 lines
11 KiB
C#

using System;
using System.Runtime.InteropServices;
namespace UnityEngine.XR.OpenXR
{
/// <summary>
/// OpenXR Runtime access
/// </summary>
public static class OpenXRRuntime
{
/// <summary>
/// Name of the current runtime.
/// </summary>
public static string name =>
Internal_GetRuntimeName(out var runtimeNamePtr) ? Marshal.PtrToStringAnsi(runtimeNamePtr) : "";
/// <summary>
/// Version of the current runtime.
/// </summary>
public static string version =>
Internal_GetRuntimeVersion(out var major, out var minor, out var patch) ? $"{major}.{minor}.{patch}" : "";
/// <summary>
/// Version of the current runtime API.
/// </summary>
public static string apiVersion =>
Internal_GetAPIVersion(out var major, out var minor, out var patch) ? $"{major}.{minor}.{patch}" : "";
/// <summary>
/// Version of the current runtime plug-in.
/// </summary>
public static string pluginVersion =>
Internal_GetPluginVersion(out var pluginVersionPtr) ? Marshal.PtrToStringAnsi(pluginVersionPtr) : "";
/// <summary>
/// Check if current runtime API version is greater than 1.1
/// </summary>
internal static bool isRuntimeAPIVersionGreaterThan1_1()
{
if (Internal_GetAPIVersion(out var major, out var minor, out var patch))
{
if (major >= 1 && minor >= 1)
return true;
}
return false;
}
/// <summary>
/// Describes whether the OpenXR Extension with the given name is enabled.
/// </summary>
/// <param name="extensionName">Name of the extension</param>
/// <returns>True if the extension matching the given name is enabled, false otherwise</returns>
public static bool IsExtensionEnabled(string extensionName) => Internal_IsExtensionEnabled(extensionName);
/// <summary>
/// Returns the version number of the given extension.
/// </summary>
/// <param name="extensionName">Name of the extension</param>
/// <returns>Version number of given extension, or zero if the extension was not found</returns>
public static uint GetExtensionVersion(string extensionName) => Internal_GetExtensionVersion(extensionName);
/// <summary>
/// Returns the list of names of extensions enabled within the OpenXR runtime.
/// </summary>
/// <returns>Array of extension names or an empty array if no extensions are enabled.</returns>
public static string[] GetEnabledExtensions()
{
var extensions = new string[Internal_GetEnabledExtensionCount()];
for (var i = 0; i < extensions.Length; i++)
{
Internal_GetEnabledExtensionName((uint)i, out var extensionName);
extensions[i] = $"{extensionName}";
}
return extensions;
}
/// <summary>
/// Returns the list of names of extensions available within the OpenXR runtime.
/// </summary>
/// <returns>Array of extension names or an empty array if no extensions are available.</returns>
public static string[] GetAvailableExtensions()
{
var extensions = new string[Internal_GetAvailableExtensionCount()];
for (var i = 0; i < extensions.Length; i++)
{
Internal_GetAvailableExtensionName((uint)i, out var extensionName);
extensions[i] = $"{extensionName}";
}
return extensions;
}
/// <summary>
/// This event is raised when OpenXR wants the application to quit.
///
/// Note that this event is raised before Application.wantsToQuit is raised and is generally
/// raised because the Runtime has requested the application quit.
///
/// Return true and the quit process will continue. Return false and the quit process will cancel.
/// </summary>
public static event Func<bool> wantsToQuit;
/// <summary>
/// This event is raised when OpenXR Runtime wants to restart the XR loader by shutting down
/// the loader and reinitializing it.
///
/// Return true and the restart process will continue. Return false and the XR loader will be
/// unloaded and the quit process will begin.
/// </summary>
public static event Func<bool> wantsToRestart;
/// <summary>
/// This bool controls whether or not to retry initialization if the runtime reports a
/// FORM_FACTOR_UNAVAILABLE error during initialization.
/// </summary>
public static bool retryInitializationOnFormFactorErrors
{
get
{
return Internal_GetSoftRestartLoopAtInitialization();
}
set
{
Internal_SetSoftRestartLoopAtInitialization(value);
}
}
/// <summary>
/// Invokes the given event function and returns true if all invocations return true
/// </summary>
/// <param name="func">Event function</param>
/// <returns>True if all event invocations return true</returns>
private static bool InvokeEvent(Func<bool> func)
{
if (func == null)
return true;
foreach (Func<bool> invocation in func.GetInvocationList())
{
try
{
if (!invocation())
return false;
}
catch (Exception exception)
{
Debug.LogException(exception);
}
}
return true;
}
#if UNITY_INCLUDE_TESTS
internal static void ClearEvents()
{
if (wantsToQuit != null)
foreach (Func<bool> f in wantsToQuit.GetInvocationList()) wantsToQuit -= f;
if (wantsToRestart != null)
foreach (Func<bool> f in wantsToRestart.GetInvocationList()) wantsToRestart -= f;
wantsToQuit = null;
wantsToRestart = null;
}
#endif
internal static bool ShouldQuit() => InvokeEvent(wantsToQuit);
internal static bool ShouldRestart() => InvokeEvent(wantsToRestart);
private const string LibraryName = "UnityOpenXR";
[DllImport(LibraryName, EntryPoint = "NativeConfig_GetRuntimeName")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool Internal_GetRuntimeName(out IntPtr runtimeNamePtr);
[DllImport(LibraryName, EntryPoint = "NativeConfig_GetRuntimeVersion")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool Internal_GetRuntimeVersion(out ushort major, out ushort minor, out uint patch);
[DllImport(LibraryName, EntryPoint = "NativeConfig_GetAPIVersion")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool Internal_GetAPIVersion(out ushort major, out ushort minor, out uint patch);
[DllImport(LibraryName, EntryPoint = "NativeConfig_GetPluginVersion")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool Internal_GetPluginVersion(out IntPtr pluginVersionPtr);
[DllImport(LibraryName, EntryPoint = "unity_ext_IsExtensionEnabled")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool Internal_IsExtensionEnabled(string extensionName);
[DllImport(LibraryName, EntryPoint = "unity_ext_GetExtensionVersion")]
private static extern uint Internal_GetExtensionVersion(string extensionName);
[DllImport(LibraryName, EntryPoint = "unity_ext_GetEnabledExtensionCount")]
private static extern uint Internal_GetEnabledExtensionCount();
[DllImport(LibraryName, EntryPoint = "unity_ext_GetEnabledExtensionName", CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool Internal_GetEnabledExtensionNamePtr(uint index, out IntPtr outName);
[DllImport(LibraryName, EntryPoint = "session_SetSoftRestartLoopAtInitialization")]
private static extern void Internal_SetSoftRestartLoopAtInitialization([MarshalAs(UnmanagedType.I1)] bool value);
[DllImport(LibraryName, EntryPoint = "session_GetSoftRestartLoopAtInitialization")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool Internal_GetSoftRestartLoopAtInitialization();
private static bool Internal_GetEnabledExtensionName(uint index, out string extensionName)
{
if (!Internal_GetEnabledExtensionNamePtr(index, out var extensionNamePtr))
{
extensionName = "";
return false;
}
extensionName = Marshal.PtrToStringAnsi(extensionNamePtr);
return true;
}
[DllImport(LibraryName, EntryPoint = "unity_ext_GetAvailableExtensionCount")]
private static extern uint Internal_GetAvailableExtensionCount();
[DllImport(LibraryName, EntryPoint = "unity_ext_GetAvailableExtensionName", CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool Internal_GetAvailableExtensionNamePtr(uint index, out IntPtr extensionName);
private static bool Internal_GetAvailableExtensionName(uint index, out string extensionName)
{
if (!Internal_GetAvailableExtensionNamePtr(index, out var extensionNamePtr))
{
extensionName = "";
return false;
}
extensionName = Marshal.PtrToStringAnsi(extensionNamePtr);
return true;
}
[DllImport(LibraryName, EntryPoint = "session_GetLastError", CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool Internal_GetLastError(out IntPtr error);
/// <summary>
/// Returns the last error message that was issued in the native code
/// </summary>
/// <param name="error">Last error message</param>
/// <returns>True if there was an error message, false if not</returns>
internal static bool GetLastError(out string error)
{
if (!Internal_GetLastError(out var errorPtr))
{
error = "";
return false;
}
error = Marshal.PtrToStringAnsi(errorPtr);
return true;
}
/// <summary>
/// Logs the last error message if there is one to the console
/// </summary>
internal static void LogLastError()
{
if (GetLastError(out var error))
{
Debug.LogError(error);
}
}
}
}