d/qwerty: Add qwerty_system for driver management

This commit is contained in:
Mateo de Mayo 2021-03-11 16:56:52 -03:00
parent f8f14a1d9e
commit a1b70c746b
4 changed files with 136 additions and 34 deletions

View file

@ -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

View file

@ -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 <!-- Trick for doxygen -->
struct qwerty_system *
qwerty_system_create(struct qwerty_hmd *qhmd,
struct qwerty_controller *qleft,
struct qwerty_controller *qright);
/*!
* @}
*/
/*!
* @name Qwerty Device
* @memberof qwerty_device

View file

@ -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;

View file

@ -11,44 +11,45 @@
#include "util/u_device.h"
#include "xrt/xrt_device.h"
#include <SDL2/SDL.h>
#include <assert.h>
// 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