0
0
Fork 0
mirror of https://git.code.sf.net/p/quake/quakeforge synced 2025-03-21 18:01:15 +00:00

[input] Use a single select call for all drivers

For drivers that support it. Polling is still supported and forces the
select timeout to 0 if any driver requires polling. For now, the default
timeout when all drivers use select is 10ms.
This commit is contained in:
Bill Currie 2021-09-26 15:11:07 +09:00
parent 940d824be0
commit 7f408351b9
6 changed files with 91 additions and 30 deletions
include
libs/input
ruamoko/qwaq/builtins

View file

@ -45,6 +45,9 @@ typedef struct in_buttoninfo_s {
} in_buttoninfo_t;
#ifndef __QFCC__
#include <sys/select.h>
typedef struct {
vec3_t angles;
vec3_t position;
@ -53,7 +56,14 @@ typedef struct {
typedef struct in_driver_s {
void (*init) (void *data);
void (*shutdown) (void *data);
// The driver must provide either both or none of add_select and
// chec_select.
void (*add_select) (fd_set *fdset, int *maxfd, void *data);
void (*check_select) (fd_set *fdset, void *data);
// Generally musually exclusive with add_select/check_select
void (*process_events) (void *data);
void (*clear_states) (void *data);
void (*grab_input) (void *data, int grab);

View file

@ -44,6 +44,8 @@ typedef struct device_s {
void (*button_event) (button_t *button, void *data);
} device_t;
void inputlib_add_select (fd_set *fdset, int *maxfd);
void inputlib_check_select (fd_set *fdset);
int inputlib_check_input (void);
void inputlib_close (void);
int inputlib_init (void (*dev_add) (device_t *), void (*dev_rem) (device_t *));

View file

@ -309,6 +309,37 @@ read_device_input (device_t *dev)
}
}
void
inputlib_add_select (fd_set *fdset, int *maxfd)
{
inputlib_hotplug_add_select (fdset, maxfd);
for (device_t *dev = devices; dev; dev = dev->next) {
if (dev->fd < 0) {
continue;
}
FD_SET (dev->fd, fdset);
if (dev->fd > *maxfd) {
*maxfd = dev->fd;
}
}
}
void
inputlib_check_select (fd_set *fdset)
{
inputlib_hotplug_check_select (fdset);
for (device_t *dev = devices; dev; dev = dev->next) {
if (dev->fd < 0) {
continue;
}
if (FD_ISSET (dev->fd, fdset)) {
read_device_input (dev);
}
}
}
int
inputlib_check_input (void)
{
@ -317,24 +348,13 @@ inputlib_check_input (void)
struct timeval *timeout = &_timeout;
int res;
int maxfd = -1;
device_t *dev;
_timeout.tv_sec = 0;
_timeout.tv_usec = 0;
FD_ZERO (&fdset);
inputlib_hotplug_add_select (&fdset, &maxfd);
for (dev = devices; dev; dev = dev->next) {
if (dev->fd < 0) {
continue;
}
FD_SET (dev->fd, &fdset);
if (dev->fd > maxfd) {
maxfd = dev->fd;
}
}
inputlib_add_select (&fdset, &maxfd);
if (maxfd < 0) {
return 0;
}
@ -343,16 +363,7 @@ inputlib_check_input (void)
return 0;
}
inputlib_hotplug_check_select (&fdset);
for (dev = devices; dev; dev = dev->next) {
if (dev->fd < 0) {
continue;
}
if (FD_ISSET (dev->fd, &fdset)) {
read_device_input (dev);
}
}
inputlib_check_select (&fdset);
return 1;
}

View file

@ -77,6 +77,7 @@ cvar_t *in_mouse_amp;
cvar_t *in_mouse_pre_amp;
cvar_t *lookstrafe;
int64_t in_timeout = 10000;//10ms default timeout
kbutton_t in_mlook, in_klook;
kbutton_t in_strafe;
kbutton_t in_speed;
@ -265,9 +266,29 @@ IN_UpdateGrab (cvar_t *var) // called from context_*.c
void
IN_ProcessEvents (void)
{
fd_set fdset;
int maxfd = -1;
int64_t timeout = in_timeout;
FD_ZERO (&fdset);
for (size_t i = 0; i < in_drivers.size; i++) {
in_regdriver_t *rd = &in_drivers.a[i];
rd->driver.process_events (rd->data);
if (rd->driver.add_select) {
rd->driver.add_select (&fdset, &maxfd, rd->data);
}
if (rd->driver.process_events) {
rd->driver.process_events (rd->data);
// if a driver can't use select, then we can't block in select
timeout = 0;
}
}
if (maxfd >= 0 && Sys_Select (maxfd, &fdset, timeout) > 0) {
for (size_t i = 0; i < in_drivers.size; i++) {
in_regdriver_t *rd = &in_drivers.a[i];
if (rd->driver.check_select) {
rd->driver.check_select (&fdset, rd->data);
}
}
}
}

View file

@ -62,10 +62,15 @@ in_evdev_keydest_callback (keydest_t key_dest, void *data)
}
static void
in_evdev_process_events (void *data)
in_evdev_add_select (fd_set *fdset, int *maxfd, void *data)
{
if (inputlib_check_input ()) {
}
inputlib_add_select (fdset, maxfd);
}
static void
in_evdev_check_select (fd_set *fdset, void *data)
{
inputlib_check_select (fdset);
}
static void
@ -223,7 +228,8 @@ in_evdev_button_info (void *data, void *device, in_buttoninfo_t *buttons,
static in_driver_t in_evdev_driver = {
.init = in_evdev_init,
.shutdown = in_evdev_shutdown,
.process_events = in_evdev_process_events,
.add_select = in_evdev_add_select,
.check_select = in_evdev_check_select,
.clear_states = in_evdev_clear_states,
.axis_info = in_evdev_axis_info,

View file

@ -464,8 +464,18 @@ term_shutdown (void *_res)
{
}
#define FD 0
static void
term_process_events (void *_res)
term_add_select (fd_set *fdset, int *maxfd, void *_res)
{
FD_SET (FD, fdset);
if (*maxfd < FD) {
*maxfd = FD;
}
}
static void
term_check_select (fd_set *fdset, void *_res)
{
qwaq_input_resources_t *res = _res;
char buf[256];
@ -482,7 +492,7 @@ term_process_events (void *_res)
resize_event (res);
}
#endif
while (Sys_CheckInput (1, -1)) {
if (FD_ISSET (FD, fdset)) {
len = read(0, buf, sizeof (buf));
for (int i = 0; i < len; i++) {
process_char (res, buf[i]);
@ -493,7 +503,8 @@ term_process_events (void *_res)
static in_driver_t term_driver = {
.init = term_init,
.shutdown = term_shutdown,
.process_events = term_process_events,
.add_select = term_add_select,
.check_select = term_check_select,
};
static int term_driver_handle;