Skip to content

Commit

Permalink
Feature/backend openxr pollevent (#513)
Browse files Browse the repository at this point in the history
* Backend OpenXR PollEvent API in C layer

* Backend OpenXR PollEvent API in C# layer

* Add context as first callback argument
  • Loading branch information
jackdaus committed Nov 10, 2022
1 parent 0b73692 commit c2f09f2
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 2 deletions.
2 changes: 2 additions & 0 deletions StereoKit/Native/NativeAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,8 @@ internal static class NativeAPI
[DllImport(dll, CharSet = cSet, CallingConvention = call)] public static extern void backend_openxr_use_minimum_exts(int use_minimum_exts);
[DllImport(dll, CharSet = cSet, CallingConvention = call)] public static extern void backend_openxr_composition_layer(IntPtr XrCompositionLayerBaseHeader, int layer_size, int sort_order);
[DllImport(dll, CharSet = cSet, CallingConvention = call)] public static extern void backend_openxr_add_callback_pre_session_create([MarshalAs(UnmanagedType.FunctionPtr)] XRPreSessionCreateCallback on_pre_session_create, IntPtr context);
[DllImport(dll, CharSet = cSet, CallingConvention = call)] public static extern void backend_openxr_add_callback_poll_event ([MarshalAs(UnmanagedType.FunctionPtr)] XRPollEventCallback on_poll_event, IntPtr context);
[DllImport(dll, CharSet = cSet, CallingConvention = call)] public static extern void backend_openxr_remove_callback_poll_event ([MarshalAs(UnmanagedType.FunctionPtr)] XRPollEventCallback on_poll_event);
[DllImport(dll, CharSet = cSet, CallingConvention = call)] public static extern BackendPlatform backend_platform_get ();
[DllImport(dll, CharSet = cSet, CallingConvention = call)] public static extern IntPtr backend_android_get_java_vm ();
[DllImport(dll, CharSet = cSet, CallingConvention = call)] public static extern IntPtr backend_android_get_activity();
Expand Down
3 changes: 3 additions & 0 deletions StereoKit/Native/NativeTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,9 @@ public Ray Ray
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void XRPreSessionCreateCallback(IntPtr context);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void XRPollEventCallback(IntPtr context, IntPtr XrEventDataBuffer);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void AssetOnLoadCallback(IntPtr asset, IntPtr context);

Expand Down
35 changes: 34 additions & 1 deletion StereoKit/Systems/Backend.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace StereoKit
Expand Down Expand Up @@ -169,6 +170,38 @@ internal static void CleanupInitialize()
_onPreCreateSession = null;
_onPreCreateSessionRegistered = false;
}

private struct XRPollEventCallbackData
{
public Action<IntPtr> action;
public XRPollEventCallback callback;
}

private static List<XRPollEventCallbackData> _xrPollEventCallbacks;

/// <summary>This event gets published each time xrPollEvent results in XR_SUCCESS.</summary>
public static event Action<IntPtr> OnPollEvent
{
add
{
if (_xrPollEventCallbacks == null) _xrPollEventCallbacks = new List<XRPollEventCallbackData>();

XRPollEventCallback callback = (_, XrEventDataBuffer) => { value(XrEventDataBuffer); };
_xrPollEventCallbacks.Add(new XRPollEventCallbackData { action = value, callback = callback });

NativeAPI.backend_openxr_add_callback_poll_event(callback, IntPtr.Zero);
}
remove
{
if (_xrPollEventCallbacks == null) throw new NullReferenceException();

int i = _xrPollEventCallbacks.FindIndex(d => d.action == value);
if (i < 0) throw new KeyNotFoundException();

NativeAPI.backend_openxr_remove_callback_poll_event(_xrPollEventCallbacks[i].callback);
_xrPollEventCallbacks.RemoveAt(i);
}
}
}

/// <summary>This class contains variables that may be useful for
Expand Down
12 changes: 12 additions & 0 deletions StereoKitC/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ void backend_openxr_add_callback_pre_session_create(void (*on_pre_session_create

///////////////////////////////////////////

void backend_openxr_add_callback_poll_event(void (*on_poll_event)(void* context, void* XrEventDataBuffer), void* context) {
log_err(backend_err_wrong_backend);
}

///////////////////////////////////////////

void backend_openxr_remove_callback_poll_event(void (*on_poll_event)(void* context, void* XrEventDataBuffer)) {
log_err(backend_err_wrong_backend);
}

///////////////////////////////////////////

void backend_openxr_composition_layer(void *XrCompositionLayerBaseHeader, int32_t layer_size, int32_t sort_order) {
log_err(backend_err_wrong_backend);
}
Expand Down
2 changes: 2 additions & 0 deletions StereoKitC/stereokit.h
Original file line number Diff line number Diff line change
Expand Up @@ -2005,6 +2005,8 @@ SK_API void backend_openxr_use_minimum_exts (bool32_t use_minimu
SK_API void backend_openxr_composition_layer (void *XrCompositionLayerBaseHeader, int32_t layer_size, int32_t sort_order);

SK_API void backend_openxr_add_callback_pre_session_create(void (*on_pre_session_create)(void* context), void* context);
SK_API void backend_openxr_add_callback_poll_event (void (*on_poll_event)(void* context, void* XrEventDataBuffer), void* context);
SK_API void backend_openxr_remove_callback_poll_event (void (*on_poll_event)(void* context, void* XrEventDataBuffer));

SK_API backend_platform_ backend_platform_get ();
SK_API void *backend_android_get_java_vm ();
Expand Down
40 changes: 39 additions & 1 deletion StereoKitC/xr_backends/openxr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ typedef struct context_callback_t {
void *context;
} context_callback_t;

typedef struct poll_event_callback_t {
void (*callback)(void* context, void* XrEventDataBuffer);
void *context;
} poll_event_callback_t;

XrFormFactor xr_config_form = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
const char *xr_request_layers[] = {
"",
Expand All @@ -71,7 +76,8 @@ array_t<const char*> xr_exts_user = {};
array_t<uint64_t> xr_exts_loaded = {};
bool32_t xr_minimum_exts = false;

array_t<context_callback_t> xr_callbacks_pre_session_create = {};
array_t<context_callback_t> xr_callbacks_pre_session_create = {};
array_t<poll_event_callback_t> xr_callbacks_poll_event = {};

bool xr_has_bounds = false;
vec2 xr_bounds_size = {};
Expand Down Expand Up @@ -697,6 +703,11 @@ void openxr_poll_events() {
break;
default: break;
}

for (int32_t i = 0; i < xr_callbacks_poll_event.count; i++) {
xr_callbacks_poll_event[i].callback(xr_callbacks_poll_event[i].context, &event_buffer);
}

event_buffer = { XR_TYPE_EVENT_DATA_BUFFER };
}
}
Expand Down Expand Up @@ -1016,6 +1027,33 @@ void backend_openxr_add_callback_pre_session_create(void (*on_pre_session_create
xr_callbacks_pre_session_create.add({ on_pre_session_create, context });
}

///////////////////////////////////////////

void backend_openxr_add_callback_poll_event(void (*on_poll_event)(void* context, void* XrEventDataBuffer), void* context) {
if (backend_xr_get_type() != backend_xr_type_openxr) {
log_err("backend_openxr_ functions only work when OpenXR is the backend!");
return;
}

xr_callbacks_poll_event.add({ on_poll_event, context });
}

///////////////////////////////////////////

void backend_openxr_remove_callback_poll_event(void (*on_poll_event)(void* context, void* XrEventDataBuffer)) {
if (backend_xr_get_type() != backend_xr_type_openxr) {
log_err("backend_openxr_ functions only work when OpenXR is the backend!");
return;
}

for (int32_t i = 0; i < xr_callbacks_poll_event.count; i++) {
if (xr_callbacks_poll_event[i].callback == on_poll_event || on_poll_event == nullptr) {
xr_callbacks_poll_event.remove(i);
return;
}
}
}

} // namespace sk

#endif

0 comments on commit c2f09f2

Please sign in to comment.