From a1b70c746bb178ab0bdd01295cd185f463c193a3 Mon Sep 17 00:00:00 2001 From: Mateo de Mayo Date: Thu, 11 Mar 2021 16:56:52 -0300 Subject: [PATCH] d/qwerty: Add qwerty_system for driver management --- src/xrt/drivers/qwerty/qwerty_device.c | 76 +++++++++++++++++++++++++- src/xrt/drivers/qwerty/qwerty_device.h | 33 ++++++++++- src/xrt/drivers/qwerty/qwerty_prober.c | 2 + src/xrt/drivers/qwerty/qwerty_sdl.c | 59 ++++++++++---------- 4 files changed, 136 insertions(+), 34 deletions(-) diff --git a/src/xrt/drivers/qwerty/qwerty_device.c b/src/xrt/drivers/qwerty/qwerty_device.c index 84009da03..ad01dedde 100644 --- a/src/xrt/drivers/qwerty/qwerty_device.c +++ b/src/xrt/drivers/qwerty/qwerty_device.c @@ -40,13 +40,27 @@ #define QWERTY_AIM 3 #define QWERTY_VIBRATION 0 +static void +qwerty_system_remove(struct qwerty_system *qs, struct qwerty_device *qd); + +static void +qwerty_system_destroy(struct qwerty_system *qs); + +// Compare any two pointers without verbose casts +static inline bool +eq(void *a, void *b) +{ + return a == b; +} + // xrt_device functions struct qwerty_device * qwerty_device(struct xrt_device *xd) { struct qwerty_device *qd = (struct qwerty_device *)xd; - assert(qd); + bool is_qwerty_device = eq(qd, qd->sys->hmd) || eq(qd, qd->sys->lctrl) || eq(qd, qd->sys->rctrl); + assert(is_qwerty_device); return qd; } @@ -54,7 +68,8 @@ struct qwerty_hmd * qwerty_hmd(struct xrt_device *xd) { struct qwerty_hmd *qh = (struct qwerty_hmd *)xd; - assert(qh); + bool is_qwerty_hmd = eq(qh, qh->base.sys->hmd); + assert(is_qwerty_hmd); return qh; } @@ -62,7 +77,8 @@ struct qwerty_controller * qwerty_controller(struct xrt_device *xd) { struct qwerty_controller *qc = (struct qwerty_controller *)xd; - assert(qc); + bool is_qwerty_controller = eq(qc, qc->base.sys->lctrl) || eq(qc, qc->base.sys->rctrl); + assert(is_qwerty_controller); return qc; } @@ -148,6 +164,8 @@ qwerty_get_view_pose(struct xrt_device *xd, static void qwerty_destroy(struct xrt_device *xd) { + struct qwerty_device *qd = qwerty_device(xd); + qwerty_system_remove(qd->sys, qd); u_device_free(xd); } @@ -243,6 +261,58 @@ qwerty_controller_create(bool is_left, struct qwerty_hmd *qhmd) return qc; } +// System methods + +struct qwerty_system * +qwerty_system_create(struct qwerty_hmd *qhmd, + struct qwerty_controller *qleft, + struct qwerty_controller *qright) +{ + assert(qleft && "Cannot create a qwerty system when Left controller is NULL"); + assert(qright && "Cannot create a qwerty system when Right controller is NULL"); + + struct qwerty_system *qs = U_TYPED_CALLOC(struct qwerty_system); + qs->hmd = qhmd; + qs->lctrl = qleft; + qs->rctrl = qright; + qs->process_keys = true; + + if (qhmd) { + qhmd->base.sys = qs; + } + qleft->base.sys = qs; + qright->base.sys = qs; + + return qs; +} + +static void +qwerty_system_remove(struct qwerty_system *qs, struct qwerty_device *qd) +{ + if (eq(qd, qs->hmd)) { + qs->hmd = NULL; + } else if (eq(qd, qs->lctrl)) { + qs->lctrl = NULL; + } else if (eq(qd, qs->rctrl)) { + qs->rctrl = NULL; + } else { + assert(false && "Trying to remove a device that is not in the qwerty system"); + } + + bool all_devices_clean = !qs->hmd && !qs->lctrl && !qs->rctrl; + if (all_devices_clean) { + qwerty_system_destroy(qs); + } +} + +static void +qwerty_system_destroy(struct qwerty_system *qs) +{ + bool all_devices_clean = !qs->hmd && !qs->lctrl && !qs->rctrl; + assert(all_devices_clean && "Tried to destroy a qwerty_system without destroying its devices before."); + free(qs); +} + // Device methods // clang-format off diff --git a/src/xrt/drivers/qwerty/qwerty_device.h b/src/xrt/drivers/qwerty/qwerty_device.h index ce1cc3387..76a5f641c 100644 --- a/src/xrt/drivers/qwerty/qwerty_device.h +++ b/src/xrt/drivers/qwerty/qwerty_device.h @@ -26,12 +26,22 @@ extern "C" { * @{ */ +//! Container of qwerty devices and driver properties. +struct qwerty_system +{ + struct qwerty_hmd *hmd; //!< Can be NULL + struct qwerty_controller *lctrl; //!< Cannot be NULL + struct qwerty_controller *rctrl; //!< Cannot be NULL + bool process_keys; //!< If false disable keyboard and mouse input +}; + //! Fake device that modifies its tracked pose through its methods. //! @implements xrt_device struct qwerty_device { struct xrt_device base; - struct xrt_pose pose; //!< Internal pose state + struct xrt_pose pose; //!< Internal pose state + struct qwerty_system *sys; //!< Reference to the system this device is in. float movement_speed; //!< In meters per frame bool left_pressed; @@ -48,8 +58,8 @@ struct qwerty_device bool look_down_pressed; bool sprint_pressed; //!< Movement speed boost - float yaw_delta; //!< How much extra yaw to add for the next pose. Then reset to 0. - float pitch_delta; //!< Similar to `yaw_delta` + float yaw_delta; //!< How much extra yaw to add for the next pose. Then reset to 0. + float pitch_delta; //!< Similar to `yaw_delta` }; //! @implements qwerty_device @@ -64,6 +74,23 @@ struct qwerty_controller struct qwerty_device base; }; +/*! + * @name Qwerty System + * @memberof qwerty_system + * qwerty_system public methods + * @{ + */ +//! @public @memberof qwerty_system + +struct qwerty_system * +qwerty_system_create(struct qwerty_hmd *qhmd, + struct qwerty_controller *qleft, + struct qwerty_controller *qright); + +/*! + * @} + */ + /*! * @name Qwerty Device * @memberof qwerty_device diff --git a/src/xrt/drivers/qwerty/qwerty_prober.c b/src/xrt/drivers/qwerty/qwerty_prober.c index 509ceb23f..37b3c28f6 100644 --- a/src/xrt/drivers/qwerty/qwerty_prober.c +++ b/src/xrt/drivers/qwerty/qwerty_prober.c @@ -51,6 +51,8 @@ qwerty_prober_autoprobe(struct xrt_auto_prober *xap, struct qwerty_controller *qleft = qwerty_controller_create(true, qhmd); struct qwerty_controller *qright = qwerty_controller_create(false, qhmd); + qwerty_system_create(qhmd, qleft, qright); + struct xrt_device *xd_hmd = &qhmd->base.base; struct xrt_device *xd_left = &qleft->base.base; struct xrt_device *xd_right = &qright->base.base; diff --git a/src/xrt/drivers/qwerty/qwerty_sdl.c b/src/xrt/drivers/qwerty/qwerty_sdl.c index 44a9090c0..2fc6ebe08 100644 --- a/src/xrt/drivers/qwerty/qwerty_sdl.c +++ b/src/xrt/drivers/qwerty/qwerty_sdl.c @@ -11,44 +11,45 @@ #include "util/u_device.h" #include "xrt/xrt_device.h" #include +#include // Amount of look_speed units a mouse delta of 1px in screen space will rotate the device #define SENSITIVITY 0.1f -static void -find_qwerty_devices(struct xrt_device **xdevs, - size_t num_xdevs, - struct xrt_device **xd_hmd, - struct xrt_device **xd_left, - struct xrt_device **xd_right) +static struct qwerty_system * +find_qwerty_system(struct xrt_device **xdevs, size_t num_xdevs) { + struct xrt_device *xdev = NULL; for (size_t i = 0; i < num_xdevs; i++) { if (xdevs[i] == NULL) { continue; } - - if (strcmp(xdevs[i]->str, QWERTY_HMD_STR) == 0) { - *xd_hmd = xdevs[i]; - } else if (strcmp(xdevs[i]->str, QWERTY_LEFT_STR) == 0) { - *xd_left = xdevs[i]; - } else if (strcmp(xdevs[i]->str, QWERTY_RIGHT_STR) == 0) { - *xd_right = xdevs[i]; + if (strcmp(xdevs[i]->str, QWERTY_HMD_STR) == 0 || strcmp(xdevs[i]->str, QWERTY_LEFT_STR) == 0 || + strcmp(xdevs[i]->str, QWERTY_RIGHT_STR) == 0) { + xdev = xdevs[i]; + break; } } + + assert(xdev != NULL && "There is no device in xdevs with the name of a qwerty device"); + struct qwerty_device *qdev = qwerty_device(xdev); + struct qwerty_system *qsys = qdev->sys; + assert(qsys != NULL && "The qwerty_system of a qwerty_device was null"); + return qsys; } // Determines the default qwerty device based on which devices are in use -struct qwerty_device * -default_qwerty_device(struct xrt_device **xdevs, - size_t num_xdevs, - struct xrt_device *xd_hmd, - struct xrt_device *xd_left, - struct xrt_device *xd_right) +static struct qwerty_device * +default_qwerty_device(struct xrt_device **xdevs, size_t num_xdevs, struct qwerty_system *qsys) { int head, left, right; head = left = right = XRT_DEVICE_ROLE_UNASSIGNED; u_device_assign_xdev_roles(xdevs, num_xdevs, &head, &left, &right); + struct xrt_device *xd_hmd = qsys->hmd ? &qsys->hmd->base.base : NULL; + struct xrt_device *xd_left = &qsys->lctrl->base.base; + struct xrt_device *xd_right = &qsys->rctrl->base.base; + struct qwerty_device *default_qdev = NULL; if (xdevs[head] == xd_hmd) { default_qdev = qwerty_device(xd_hmd); @@ -66,9 +67,7 @@ default_qwerty_device(struct xrt_device **xdevs, void qwerty_process_event(struct xrt_device **xdevs, size_t num_xdevs, SDL_Event event) { - static struct xrt_device *xd_hmd = NULL; - static struct xrt_device *xd_left = NULL; - static struct xrt_device *xd_right = NULL; + static struct qwerty_system *qsys = NULL; static bool alt_pressed = false; static bool ctrl_pressed = false; @@ -79,21 +78,25 @@ qwerty_process_event(struct xrt_device **xdevs, size_t num_xdevs, SDL_Event even // We can cache the devices as they don't get destroyed during runtime static bool cached = false; if (!cached) { - find_qwerty_devices(xdevs, num_xdevs, &xd_hmd, &xd_left, &xd_right); - default_qdev = default_qwerty_device(xdevs, num_xdevs, xd_hmd, xd_left, xd_right); + qsys = find_qwerty_system(xdevs, num_xdevs); + default_qdev = default_qwerty_device(xdevs, num_xdevs, qsys); cached = true; } + if (!qsys->process_keys) { + return; + } + // Initialize different views of the same pointers. - struct qwerty_controller *qleft = qwerty_controller(xd_left); + struct qwerty_controller *qleft = qsys->lctrl; struct qwerty_device *qd_left = &qleft->base; - struct qwerty_controller *qright = qwerty_controller(xd_right); + struct qwerty_controller *qright = qsys->rctrl; struct qwerty_device *qd_right = &qright->base; - bool using_qhmd = xd_hmd != NULL; - struct qwerty_hmd *qhmd = using_qhmd ? qwerty_hmd(xd_hmd) : NULL; + bool using_qhmd = qsys->hmd != NULL; + struct qwerty_hmd *qhmd = using_qhmd ? qsys->hmd : NULL; struct qwerty_device *qd_hmd = using_qhmd ? &qhmd->base : NULL; // clang-format off