using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using AOT;
using UnityEditor;
using UnityEngine.XR.OpenXR.Features;
#if UNITY_EDITOR
using UnityEditor.XR.OpenXR.Features;
#endif
namespace UnityEngine.XR.OpenXR.Samples.InterceptFeature
{
///
/// Example feature showing how to intercept a single OpenXR function.
///
#if UNITY_EDITOR
[OpenXRFeature(UiName = "Sample: Intercept Create Session",
BuildTargetGroups = new[] {BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android},
Company = "Unity",
Desc = "Example feature extension showing how to intercept a single OpenXR function.",
DocumentationLink = Constants.k_DocumentationURL,
OpenxrExtensionStrings = "XR_test", // this extension doesn't exist, a log message will be printed that it couldn't be enabled
Version = "0.0.1",
FeatureId = featureId)]
#endif
public class InterceptCreateSessionFeature : OpenXRFeature
{
///
/// The feature id string. This is used to give the feature a well known id for reference.
///
public const string featureId = "com.unity.openxr.feature.example.intercept";
///
/// Message to display upon interception.
///
public string message = "Hello from C#!";
///
/// Message received from native as a result of the intercepted xrCreateSession call.
///
public string receivedMessage { get; private set; }
///
protected override IntPtr HookGetInstanceProcAddr(IntPtr func)
{
Debug.Log("EXT: registering our own xrGetInstanceProcAddr");
return intercept_xrCreateSession_xrGetInstanceProcAddr(func);
}
///
protected override bool OnInstanceCreate(ulong xrInstance)
{
Internal_SetCallback(OnMessage);
// Example of sending data set by user down to native.
// this is unsafe! Don't do this. Just an example.
Internal_SetMessage(message);
// here's one way you can grab the instance
Debug.Log($"EXT: Got xrInstance: {xrInstance}");
return true;
}
private delegate void OnMessageDelegate(string message);
[MonoPInvokeCallback(typeof(OnMessageDelegate))]
private static void OnMessage(string message)
{
if (message == null)
return;
Debug.Log(message);
var feature = OpenXRSettings.Instance.GetFeature();
if (null == feature)
return;
feature.receivedMessage = message;
}
///
protected override void OnSessionCreate(ulong xrSession)
{
// here's one way you can grab the session
Debug.Log($"EXT: Got xrSession: {xrSession}");
}
///
protected override void OnSessionBegin(ulong xrSession)
{
Debug.Log($"EXT: xrBeginSession: {xrSession}");
}
///
protected override void OnSessionEnd(ulong xrSession)
{
Debug.Log($"EXT: about to xrEndSession: {xrSession}");
}
private const string ExtLib = "InterceptFeaturePlugin";
[DllImport(ExtLib, EntryPoint = "script_intercept_xrCreateSession_xrGetInstanceProcAddr")]
private static extern IntPtr intercept_xrCreateSession_xrGetInstanceProcAddr(IntPtr func);
[DllImport(ExtLib, EntryPoint = "script_set_message", CharSet = CharSet.Ansi)]
private static extern void Internal_SetMessage(string printString);
internal delegate void ReceiveMessageDelegate(string message);
[DllImport(ExtLib, EntryPoint = "script_set_callback")]
static extern void Internal_SetCallback(ReceiveMessageDelegate callback);
}
}