[input,ruamoko,qwaq] Fix incorrect use of PR_RESMAP

I had forgotten that _size was the number of rows in the map, not the
number of objects (1024 objects per row). This fixes the missed device
removal messages. And probably a slew of other bugs I'd yet to encounter
:P
This commit is contained in:
Bill Currie 2021-09-25 15:42:54 +09:00
parent 4057500acc
commit 13bc38a55b
4 changed files with 53 additions and 21 deletions

View file

@ -1539,6 +1539,9 @@ void *PR_Resources_Find (progs_t *pr, const char *name);
\param type The type of the resource. The size must be at least \param type The type of the resource. The size must be at least
as large as \c sizeof(type *). as large as \c sizeof(type *).
\note \a _size is <em>NOT</em> the number of objects in the
map. It is the number of rows in the map array (each row
has multiple objects).
*/ */
#define PR_RESMAP(type) struct { type *_free; type **_map; unsigned _size; } #define PR_RESMAP(type) struct { type *_free; type **_map; unsigned _size; }

View file

@ -45,13 +45,16 @@
#include "compat.h" #include "compat.h"
#include "evdev/inputlib.h" #include "evdev/inputlib.h"
typedef struct { typedef struct devmap_s {
struct devmap_s *next;
struct devmap_s **prev;
device_t *device; device_t *device;
int devid; int devid;
} devmap_t; } devmap_t;
static int evdev_driver_handle = -1; static int evdev_driver_handle = -1;
static PR_RESMAP (devmap_t) devmap; static PR_RESMAP (devmap_t) devmap;
static devmap_t *devmap_list;
static void static void
in_evdev_keydest_callback (keydest_t key_dest, void *data) in_evdev_keydest_callback (keydest_t key_dest, void *data)
@ -119,6 +122,13 @@ device_add (device_t *dev)
} }
devmap_t *dm = PR_RESNEW (devmap); devmap_t *dm = PR_RESNEW (devmap);
dm->next = devmap_list;
dm->prev = &devmap_list;
if (devmap_list) {
devmap_list->prev = &dm->next;
}
devmap_list = dm;
dm->device = dev; dm->device = dev;
dm->devid = IN_AddDevice (evdev_driver_handle, dev, name, id); dm->devid = IN_AddDevice (evdev_driver_handle, dev, name, id);
@ -144,11 +154,15 @@ device_add (device_t *dev)
static void static void
device_remove (device_t *dev) device_remove (device_t *dev)
{ {
//Sys_Printf ("in_evdev: remove %s\n", dev->path); for (devmap_t *dm = devmap_list; dm; dm = dm->next) {
for (unsigned i = 0; i < devmap._size; i++) {
devmap_t *dm = PR_RESGET (devmap, ~i);
if (dm->device == dev) { if (dm->device == dev) {
IN_RemoveDevice (dm->devid); IN_RemoveDevice (dm->devid);
if (dm->next) {
dm->next->prev = dm->prev;
}
*dm->prev = dm->next;
PR_RESFREE (devmap, dm); PR_RESFREE (devmap, dm);
break; break;
} }

View file

@ -64,6 +64,8 @@ typedef struct obj_list_s {
} obj_list; } obj_list;
typedef struct dtable_s { typedef struct dtable_s {
struct dtable_s *next;
struct dtable_s **prev;
size_t size; size_t size;
func_t *imp; func_t *imp;
} dtable_t; } dtable_t;
@ -75,6 +77,7 @@ typedef struct probj_resources_s {
obj_list **selector_sels; obj_list **selector_sels;
string_t *selector_names; string_t *selector_names;
PR_RESMAP (dtable_t) dtables; PR_RESMAP (dtable_t) dtables;
dtable_t *dtable_list;
func_t obj_forward; func_t obj_forward;
pr_sel_t *forward_selector; pr_sel_t *forward_selector;
dstring_t *msg; dstring_t *msg;
@ -93,7 +96,14 @@ typedef struct probj_resources_s {
static dtable_t * static dtable_t *
dtable_new (probj_t *probj) dtable_new (probj_t *probj)
{ {
return PR_RESNEW (probj->dtables); dtable_t *dtable = PR_RESNEW (probj->dtables);
dtable->next = probj->dtable_list;
dtable->prev = &probj->dtable_list;
if (probj->dtable_list) {
probj->dtable_list->prev = &dtable->next;
}
probj->dtable_list = dtable;
return dtable;
} }
static void static void
@ -2195,14 +2205,8 @@ rua_obj_cleanup (progs_t *pr, void *data)
probj->selector_names[i] = 0; probj->selector_names[i] = 0;
} }
for (i = 0; i < probj->dtables._size; i++) { for (dtable_t *dtable = probj->dtable_list; dtable;
/* dtable_get expects a handle, but a handle is the ones-compliment dtable = dtable->next) {
* negative of the index.
*/
dtable_t *dtable = dtable_get (probj, ~i);
if (!dtable->imp) {
break;
}
free (dtable->imp); free (dtable->imp);
} }
dtable_reset (probj); dtable_reset (probj);

View file

@ -18,7 +18,8 @@
#define always_inline inline __attribute__((__always_inline__)) #define always_inline inline __attribute__((__always_inline__))
typedef struct editbuffer_s { typedef struct editbuffer_s {
void *freenext; // for PR_RESMAP struct editbuffer_s *next;
struct editbuffer_s **prev;
txtbuffer_t *txtbuffer; txtbuffer_t *txtbuffer;
int modified; int modified;
int tabSize; int tabSize;
@ -27,17 +28,29 @@ typedef struct editbuffer_s {
typedef struct qwaq_ebresources_s { typedef struct qwaq_ebresources_s {
progs_t *pr; progs_t *pr;
PR_RESMAP (editbuffer_t) buffers; PR_RESMAP (editbuffer_t) buffers;
editbuffer_t *buffer_list;
} qwaq_ebresources_t; } qwaq_ebresources_t;
static editbuffer_t * static editbuffer_t *
editbuffer_new (qwaq_ebresources_t *res) editbuffer_new (qwaq_ebresources_t *res)
{ {
return PR_RESNEW (res->buffers); editbuffer_t *buffer = PR_RESNEW (res->buffers);
buffer->next = res->buffer_list;
buffer->prev = &res->buffer_list;
if (res->buffer_list) {
res->buffer_list->prev = &buffer->next;
}
res->buffer_list = buffer;
return buffer;
} }
static void static void
editbuffer_free (qwaq_ebresources_t *res, editbuffer_t *buffer) editbuffer_free (qwaq_ebresources_t *res, editbuffer_t *buffer)
{ {
if (buffer->next) {
buffer->next->prev = buffer->prev;
}
*buffer->prev = buffer->next;
PR_RESFREE (res->buffers, buffer); PR_RESFREE (res->buffers, buffer);
} }
@ -965,13 +978,11 @@ qwaq_ebresources_clear (progs_t *pr, void *data)
{ {
__auto_type res = (qwaq_ebresources_t *) data; __auto_type res = (qwaq_ebresources_t *) data;
for (size_t i = 0; i < res->buffers._size; i++) { for (editbuffer_t *buffer = res->buffer_list; buffer;
editbuffer_t *buffer = editbuffer_get (res, ~i); buffer = buffer->next) {
if (buffer->txtbuffer) {
TextBuffer_Destroy (buffer->txtbuffer); TextBuffer_Destroy (buffer->txtbuffer);
buffer->txtbuffer = 0; buffer->txtbuffer = 0;
} }
}
editbuffer_reset (res); editbuffer_reset (res);
} }