Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/backend openxr pollevent #513

Merged
merged 3 commits into from
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}

jackdaus marked this conversation as resolved.
Show resolved Hide resolved
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