Started implementing events.
This commit is contained in:
parent
101df7a469
commit
55a7e3e56e
|
@ -0,0 +1,101 @@
|
|||
// 15 may 2019
|
||||
#include <stdlib.h>
|
||||
#include "ui.h"
|
||||
#include "uipriv.h"
|
||||
|
||||
struct handler {
|
||||
int id;
|
||||
uiHandlerFunc f;
|
||||
void *sender;
|
||||
void *data;
|
||||
bool blocked;
|
||||
};
|
||||
|
||||
static int handlerCmp(const void *a, const void *b)
|
||||
{
|
||||
const struct handler *ha = (const struct handler *) a;
|
||||
const struct handler *hb = (const struct handler *) b;
|
||||
|
||||
// This could be ha->id - hb->id, but let's do it the explicit way to avoid integer overflow/underflow.
|
||||
if (ha->id < hb->id)
|
||||
return -1;
|
||||
if (ha->id > hb->id)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct handler *handlerFind(struct handler *handlers, size_t len, int id)
|
||||
{
|
||||
struct handler key;
|
||||
|
||||
memset(&key, 0, sizeof (struct handler));
|
||||
key.id = id;
|
||||
return (struct handler *) bsearch(&key, handlers, len, sizeof (struct handler), handlerCmp);
|
||||
}
|
||||
|
||||
static void handlerSort(struct handler *handlers, size_t len)
|
||||
{
|
||||
qsort(handlers, len, sizeof (struct handler), handlerCmp);
|
||||
}
|
||||
|
||||
struct uiEvent {
|
||||
uiEventOptions opts;
|
||||
struct handler *handlers;
|
||||
size_t len;
|
||||
size_t cap;
|
||||
bool firing;
|
||||
};
|
||||
|
||||
uiEvent *uiNewEvent(uiEventOptions *options)
|
||||
{
|
||||
}
|
||||
|
||||
int uiEventAddHandler(uiEvent *e, uiEventHandler handler, void *sender, void *data)
|
||||
{
|
||||
}
|
||||
|
||||
void uiEventDeleteHandler(uiEvent *e, int id)
|
||||
{
|
||||
struct handler *h;
|
||||
|
||||
if (e == NULL)
|
||||
TODO
|
||||
if (e->firing)
|
||||
TODO
|
||||
if (e->len == 0)
|
||||
TODO
|
||||
h = handlerFind(e->handlers, e->len, id);
|
||||
if (h == NULL)
|
||||
TODO
|
||||
e->len--;
|
||||
memmove(h + 1, h, (e->len - (h - e->handlers)) * sizeof (struct handler));
|
||||
}
|
||||
|
||||
void uiEventFire(uiEvent *e, void *sender, void *args)
|
||||
{
|
||||
struct handler *h;
|
||||
size_t i;
|
||||
|
||||
if (e == NULL)
|
||||
TODO
|
||||
if (e->firing)
|
||||
TODO
|
||||
if (e->opts.Global && sender != NULL)
|
||||
TODO
|
||||
e->firing = true;
|
||||
h = e->handlers;
|
||||
for (i = 0; i < e->len; i++) {
|
||||
if (h->sender == sender && !h->blocked)
|
||||
(*(h->f))(sender, args, h->data);
|
||||
h++;
|
||||
}
|
||||
e->firing = false;
|
||||
}
|
||||
|
||||
bool uiEventHandlerBlocked(const uiEvent *e, int id)
|
||||
{
|
||||
}
|
||||
|
||||
void uiEventSetHandlerBlocked(uiEvent *e, int id, bool blocked)
|
||||
{
|
||||
}
|
|
@ -2,5 +2,6 @@
|
|||
|
||||
libui_sources += [
|
||||
'common/errors.c',
|
||||
'common/events.c',
|
||||
'common/init.c',
|
||||
]
|
||||
|
|
|
@ -72,6 +72,8 @@ It is a programmer error to specify `NULL` for `e` or `handler`. It is also a pr
|
|||
void uiEventDeleteHandler(uiEvent *e, int id);
|
||||
```
|
||||
|
||||
`uiEventDeleteHandler()` removes an event handler registration; you specify which handler to unregister by passing in the ID returned from `uiEventAddHandler()`.
|
||||
|
||||
It is a programmer error to specify `NULL` for `e` or a currently unregistered value for `id`. It is also a programmer error to call `uiEventDeleteHandler()` on an event while that event is being fired.
|
||||
|
||||
### `uiEventFire()`
|
||||
|
|
18
ui.h
18
ui.h
|
@ -43,6 +43,24 @@ uiprivExtern void uiMain(void);
|
|||
uiprivExtern void uiQuit(void);
|
||||
uiprivExtern void uiQueueMain(void (*f)(void *data), void *data);
|
||||
|
||||
typedef struct uiEvent uiEvent;
|
||||
typedef struct uiEventOptions uiEventOptions;
|
||||
|
||||
typedef void (*uiEventHandler)(void *sender, void *args, void *data);
|
||||
|
||||
struct uiEventOptions {
|
||||
size_t Size;
|
||||
bool Global;
|
||||
};
|
||||
|
||||
uiprivExtern uiEvent *uiNewEvent(uiEventOptions *options);
|
||||
// TODO uiFreeEvent()
|
||||
uiprivExtern int uiEventAddHandler(uiEvent *e, uiEventHandler handler, void *sender, void *data);
|
||||
uiprivExtern void uiEventDeleteHandler(uiEvent *e, int id);
|
||||
uiprivExtern void uiEventFire(uiEvent *e, void *sender, void *args);
|
||||
uiprivExtern bool uiEventHandlerBlocked(const uiEvent *e, int id);
|
||||
uiprivExtern void uiEventSetHandlerBlocked(uiEvent *e, int id, bool blocked);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue