More implementation of uiEvent. Now we'll need to deal with memory allocation.
This commit is contained in:
parent
caa926feeb
commit
bd84da7179
|
@ -29,6 +29,7 @@ static const char *messages[uiprivNumProgrammerErrors] = {
|
||||||
[uiprivProgrammerErrorIndexOutOfRange] = "index %d out of range in %s()",
|
[uiprivProgrammerErrorIndexOutOfRange] = "index %d out of range in %s()",
|
||||||
[uiprivProgrammerErrorNullPointer] = "invalid null pointer for %s passed into %s()",
|
[uiprivProgrammerErrorNullPointer] = "invalid null pointer for %s passed into %s()",
|
||||||
[uiprivProgrammerErrorIntIDNotFound] = "%s identifier %d not found in %s()",
|
[uiprivProgrammerErrorIntIDNotFound] = "%s identifier %d not found in %s()",
|
||||||
|
[uiprivProgrammerErrorBadSenderForEvent] = "attempt to use a %s sender with a %s event in %s()",
|
||||||
[uiprivProgrammerErrorChangingEventDuringFire] = "attempt to change a uiEvent with %s() while it is firing",
|
[uiprivProgrammerErrorChangingEventDuringFire] = "attempt to change a uiEvent with %s() while it is firing",
|
||||||
[uiprivProgrammerErrorRecursiveEventFire] = "attempt to fire a uiEvent while it is already being fired",
|
[uiprivProgrammerErrorRecursiveEventFire] = "attempt to fire a uiEvent while it is already being fired",
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,15 +24,6 @@ static int handlerCmp(const void *a, const void *b)
|
||||||
return 0;
|
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)
|
static void handlerSort(struct handler *handlers, size_t len)
|
||||||
{
|
{
|
||||||
qsort(handlers, len, sizeof (struct handler), handlerCmp);
|
qsort(handlers, len, sizeof (struct handler), handlerCmp);
|
||||||
|
@ -46,8 +37,12 @@ struct uiEvent {
|
||||||
bool firing;
|
bool firing;
|
||||||
};
|
};
|
||||||
|
|
||||||
uiEvent *uiNewEvent(uiEventOptions *options)
|
uiEvent *uiNewEvent(const uiEventOptions *options)
|
||||||
{
|
{
|
||||||
|
if (options == NULL) {
|
||||||
|
uiprivProgrammerError(uiprivProgrammerErrorNullPointer, "uiEventOptions", __func__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define checkEventNonnull(e, ...) if ((e) == NULL) { \
|
#define checkEventNonnull(e, ...) if ((e) == NULL) { \
|
||||||
|
@ -59,10 +54,47 @@ uiEvent *uiNewEvent(uiEventOptions *options)
|
||||||
return __VA_ARGS__; \
|
return __VA_ARGS__; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool checkEventSender(const uiEvent *e, void *sender, const char *func)
|
||||||
|
{
|
||||||
|
if (e->opts.Global && sender != NULL) {
|
||||||
|
uiprivProgrammerError(uiprivProgrammerErrorBadSenderForEvent, "non-NULL", "global", func);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!e->opts.Global && sender == NULL) {
|
||||||
|
uiprivProgrammerError(uiprivProgrammerErrorBadSenderForEvent, "NULL", "non-global", func);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int uiEventAddHandler(uiEvent *e, uiEventHandler handler, void *sender, void *data)
|
int uiEventAddHandler(uiEvent *e, uiEventHandler handler, void *sender, void *data)
|
||||||
{
|
{
|
||||||
checkEventNonnull(e, 0);
|
checkEventNonnull(e, 0);
|
||||||
checkEventNotFiring(e, 0);
|
checkEventNotFiring(e, 0);
|
||||||
|
if (handler == NULL) {
|
||||||
|
uiprivProgrammerError(uiprivProgrammerErrorNullPointer, "uiEventHandler", __func__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!checkEventSender(e, sender, __func__))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct handler *findHandler(const uiEvent *e, int id, const char *func)
|
||||||
|
{
|
||||||
|
struct handler key;
|
||||||
|
struct handler *ret;
|
||||||
|
|
||||||
|
if (e->len == 0)
|
||||||
|
goto notFound;
|
||||||
|
memset(&key, 0, sizeof (struct handler));
|
||||||
|
key.id = id;
|
||||||
|
ret = (struct handler *) bsearch(&key, e->handlers, e->len, sizeof (struct handler), handlerCmp);
|
||||||
|
if (ret != NULL)
|
||||||
|
return ret;
|
||||||
|
// otherwise fall through
|
||||||
|
notFound:
|
||||||
|
uiprivProgrammerError(uiprivProgrammerErrorIntIDNotFound, "uiEvent handler", id, func);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiEventDeleteHandler(uiEvent *e, int id)
|
void uiEventDeleteHandler(uiEvent *e, int id)
|
||||||
|
@ -71,11 +103,9 @@ void uiEventDeleteHandler(uiEvent *e, int id)
|
||||||
|
|
||||||
checkEventNonnull(e);
|
checkEventNonnull(e);
|
||||||
checkEventNotFiring(e);
|
checkEventNotFiring(e);
|
||||||
if (e->len == 0)
|
h = findHandler(e, id, __func__);
|
||||||
TODO
|
|
||||||
h = handlerFind(e->handlers, e->len, id);
|
|
||||||
if (h == NULL)
|
if (h == NULL)
|
||||||
TODO
|
return;
|
||||||
e->len--;
|
e->len--;
|
||||||
memmove(h + 1, h, (e->len - (h - e->handlers)) * sizeof (struct handler));
|
memmove(h + 1, h, (e->len - (h - e->handlers)) * sizeof (struct handler));
|
||||||
}
|
}
|
||||||
|
@ -90,8 +120,9 @@ void uiEventFire(uiEvent *e, void *sender, void *args)
|
||||||
uiprivProgrammerError(uiprivProgrammerErrorRecursiveEventFire);
|
uiprivProgrammerError(uiprivProgrammerErrorRecursiveEventFire);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e->opts.Global && sender != NULL)
|
if (!checkEventSender(e, sender, __func__))
|
||||||
TODO
|
return;
|
||||||
|
|
||||||
e->firing = true;
|
e->firing = true;
|
||||||
h = e->handlers;
|
h = e->handlers;
|
||||||
for (i = 0; i < e->len; i++) {
|
for (i = 0; i < e->len; i++) {
|
||||||
|
@ -104,11 +135,23 @@ void uiEventFire(uiEvent *e, void *sender, void *args)
|
||||||
|
|
||||||
bool uiEventHandlerBlocked(const uiEvent *e, int id)
|
bool uiEventHandlerBlocked(const uiEvent *e, int id)
|
||||||
{
|
{
|
||||||
|
struct handler *h;
|
||||||
|
|
||||||
checkEventNonnull(e, false);
|
checkEventNonnull(e, false);
|
||||||
|
h = findHandler(e, id, __func__);
|
||||||
|
if (h == NULL)
|
||||||
|
return false;
|
||||||
|
return h->blocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiEventSetHandlerBlocked(uiEvent *e, int id, bool blocked)
|
void uiEventSetHandlerBlocked(uiEvent *e, int id, bool blocked)
|
||||||
{
|
{
|
||||||
|
struct handler *h;
|
||||||
|
|
||||||
checkEventNonnull(e);
|
checkEventNonnull(e);
|
||||||
checkEventNotFiring(e);
|
checkEventNotFiring(e);
|
||||||
|
h = findHandler(e, id, __func__);
|
||||||
|
if (h == NULL)
|
||||||
|
return;
|
||||||
|
h->blocked = blocked;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ enum {
|
||||||
uiprivProgrammerErrorNullPointer, // arguments: const char *paramDesc, __func__
|
uiprivProgrammerErrorNullPointer, // arguments: const char *paramDesc, __func__
|
||||||
uiprivProgrammerErrorIntIDNotFound, // arguments: const char *idDesc, int badID, __func__
|
uiprivProgrammerErrorIntIDNotFound, // arguments: const char *idDesc, int badID, __func__
|
||||||
// TODO type mismatch
|
// TODO type mismatch
|
||||||
|
uiprivProgrammerErrorBadSenderForEvent, // arguments: const char *senderDesc, const char *eventDesc, __func__
|
||||||
uiprivProgrammerErrorChangingEventDuringFire, // arguments: __func__
|
uiprivProgrammerErrorChangingEventDuringFire, // arguments: __func__
|
||||||
uiprivProgrammerErrorRecursiveEventFire, // no arguments
|
uiprivProgrammerErrorRecursiveEventFire, // no arguments
|
||||||
uiprivNumProgrammerErrors,
|
uiprivNumProgrammerErrors,
|
||||||
|
|
|
@ -43,7 +43,7 @@ If `Global` is true, the event is "global" — there are no specific senders, an
|
||||||
### `uiNewEvent()`
|
### `uiNewEvent()`
|
||||||
|
|
||||||
```c
|
```c
|
||||||
uiEvent *uiNewEvent(uiEventOptions *options);
|
uiEvent *uiNewEvent(const uiEventOptions *options);
|
||||||
```
|
```
|
||||||
|
|
||||||
`uiNewEvent()` creates a new `uiEvent` with the given options.
|
`uiNewEvent()` creates a new `uiEvent` with the given options.
|
||||||
|
|
2
ui.h
2
ui.h
|
@ -53,7 +53,7 @@ struct uiEventOptions {
|
||||||
bool Global;
|
bool Global;
|
||||||
};
|
};
|
||||||
|
|
||||||
uiprivExtern uiEvent *uiNewEvent(uiEventOptions *options);
|
uiprivExtern uiEvent *uiNewEvent(const uiEventOptions *options);
|
||||||
// TODO uiFreeEvent()
|
// TODO uiFreeEvent()
|
||||||
uiprivExtern int uiEventAddHandler(uiEvent *e, uiEventHandler handler, void *sender, void *data);
|
uiprivExtern int uiEventAddHandler(uiEvent *e, uiEventHandler handler, void *sender, void *data);
|
||||||
uiprivExtern void uiEventDeleteHandler(uiEvent *e, int id);
|
uiprivExtern void uiEventDeleteHandler(uiEvent *e, int id);
|
||||||
|
|
Loading…
Reference in New Issue