mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 23:11:38 +00:00
[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:
parent
4057500acc
commit
13bc38a55b
4 changed files with 53 additions and 21 deletions
|
@ -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
|
||||
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; }
|
||||
|
||||
|
|
|
@ -45,13 +45,16 @@
|
|||
#include "compat.h"
|
||||
#include "evdev/inputlib.h"
|
||||
|
||||
typedef struct {
|
||||
typedef struct devmap_s {
|
||||
struct devmap_s *next;
|
||||
struct devmap_s **prev;
|
||||
device_t *device;
|
||||
int devid;
|
||||
} devmap_t;
|
||||
|
||||
static int evdev_driver_handle = -1;
|
||||
static PR_RESMAP (devmap_t) devmap;
|
||||
static devmap_t *devmap_list;
|
||||
|
||||
static void
|
||||
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);
|
||||
dm->next = devmap_list;
|
||||
dm->prev = &devmap_list;
|
||||
if (devmap_list) {
|
||||
devmap_list->prev = &dm->next;
|
||||
}
|
||||
devmap_list = dm;
|
||||
|
||||
dm->device = dev;
|
||||
dm->devid = IN_AddDevice (evdev_driver_handle, dev, name, id);
|
||||
|
||||
|
@ -144,11 +154,15 @@ device_add (device_t *dev)
|
|||
static void
|
||||
device_remove (device_t *dev)
|
||||
{
|
||||
//Sys_Printf ("in_evdev: remove %s\n", dev->path);
|
||||
for (unsigned i = 0; i < devmap._size; i++) {
|
||||
devmap_t *dm = PR_RESGET (devmap, ~i);
|
||||
for (devmap_t *dm = devmap_list; dm; dm = dm->next) {
|
||||
if (dm->device == dev) {
|
||||
IN_RemoveDevice (dm->devid);
|
||||
|
||||
if (dm->next) {
|
||||
dm->next->prev = dm->prev;
|
||||
}
|
||||
*dm->prev = dm->next;
|
||||
|
||||
PR_RESFREE (devmap, dm);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@ typedef struct obj_list_s {
|
|||
} obj_list;
|
||||
|
||||
typedef struct dtable_s {
|
||||
struct dtable_s *next;
|
||||
struct dtable_s **prev;
|
||||
size_t size;
|
||||
func_t *imp;
|
||||
} dtable_t;
|
||||
|
@ -75,6 +77,7 @@ typedef struct probj_resources_s {
|
|||
obj_list **selector_sels;
|
||||
string_t *selector_names;
|
||||
PR_RESMAP (dtable_t) dtables;
|
||||
dtable_t *dtable_list;
|
||||
func_t obj_forward;
|
||||
pr_sel_t *forward_selector;
|
||||
dstring_t *msg;
|
||||
|
@ -93,7 +96,14 @@ typedef struct probj_resources_s {
|
|||
static dtable_t *
|
||||
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
|
||||
|
@ -2195,14 +2205,8 @@ rua_obj_cleanup (progs_t *pr, void *data)
|
|||
probj->selector_names[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < probj->dtables._size; i++) {
|
||||
/* dtable_get expects a handle, but a handle is the ones-compliment
|
||||
* negative of the index.
|
||||
*/
|
||||
dtable_t *dtable = dtable_get (probj, ~i);
|
||||
if (!dtable->imp) {
|
||||
break;
|
||||
}
|
||||
for (dtable_t *dtable = probj->dtable_list; dtable;
|
||||
dtable = dtable->next) {
|
||||
free (dtable->imp);
|
||||
}
|
||||
dtable_reset (probj);
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
#define always_inline inline __attribute__((__always_inline__))
|
||||
|
||||
typedef struct editbuffer_s {
|
||||
void *freenext; // for PR_RESMAP
|
||||
struct editbuffer_s *next;
|
||||
struct editbuffer_s **prev;
|
||||
txtbuffer_t *txtbuffer;
|
||||
int modified;
|
||||
int tabSize;
|
||||
|
@ -27,17 +28,29 @@ typedef struct editbuffer_s {
|
|||
typedef struct qwaq_ebresources_s {
|
||||
progs_t *pr;
|
||||
PR_RESMAP (editbuffer_t) buffers;
|
||||
editbuffer_t *buffer_list;
|
||||
} qwaq_ebresources_t;
|
||||
|
||||
static editbuffer_t *
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -965,12 +978,10 @@ qwaq_ebresources_clear (progs_t *pr, void *data)
|
|||
{
|
||||
__auto_type res = (qwaq_ebresources_t *) data;
|
||||
|
||||
for (size_t i = 0; i < res->buffers._size; i++) {
|
||||
editbuffer_t *buffer = editbuffer_get (res, ~i);
|
||||
if (buffer->txtbuffer) {
|
||||
TextBuffer_Destroy (buffer->txtbuffer);
|
||||
buffer->txtbuffer = 0;
|
||||
}
|
||||
for (editbuffer_t *buffer = res->buffer_list; buffer;
|
||||
buffer = buffer->next) {
|
||||
TextBuffer_Destroy (buffer->txtbuffer);
|
||||
buffer->txtbuffer = 0;
|
||||
}
|
||||
editbuffer_reset (res);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue