From 7aa1b0870d84c82522615ec9c0fc5f4540396493 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sat, 8 Jun 2019 15:31:40 -0400 Subject: [PATCH] And finished filling in controls.c. This is gonna be fun to debug... --- common/controls.c | 37 +++++++++++++++++++++++++++++++++++++ common/events.c | 19 +++++++++++++++++++ common/programmererrors.h | 8 ++++++++ common/uipriv.h | 1 + 4 files changed, 65 insertions(+) diff --git a/common/controls.c b/common/controls.c index be354bdc..00a41423 100644 --- a/common/controls.c +++ b/common/controls.c @@ -128,6 +128,8 @@ void *uiCheckControlType(void *c, uint32_t type) return c; } +#define callVtable(method, ...) ((*(method))(__VA_ARGS__)) + uiControl *uiNewControl(uint32_t type, void *initData) { uiControl *c; @@ -147,16 +149,51 @@ uiControl *uiNewControl(uint32_t type, void *initData) uiprivProgrammerErrorUnknownTypeRequested(type, uiprivFunc); return NULL; } + + c = uiprivNew(uiControl); + c->controlID = controlTypeID; + c->typeID = type; + c->type = ct; + if (ct->implDataSize != 0) + c->implData = uiprivAlloc(ct->implDataSize, "uiControl implementation data"); + if (!callVtable(c->type->vtable.Init, c, c->implData, initData)) { + uiprivProgrammerErrorInvalidControlInitData(ct->name, uiprivFunc); + uiprivFree(c->implData); + uiprivFree(c); + return NULL; + } + return c; } void uiControlFree(uiControl *c) { if (!uiprivCheckInitializedAndThread()) return; + if (c == NULL) { + uiprivProgrammerErrorNullPointer("uiControl", uiprivFunc); + return; + } + if (c->parent != NULL) { + uiprivProgrammerErrorControlHasParent(uiprivFunc); + return; + } + + uiEventFire(uiControlOnFree(), c, NULL); + uiEventInvalidateSender(uiControlOnFree(), c); + + callVtable(c->type->vtable.Free, c, c->implData); + + uiprivFree(c->implData); + uiprivFree(c); } void *uiControlImplData(uiControl *c) { if (!uiprivCheckInitializedAndThread()) return NULL; + if (c == NULL) { + uiprivProgrammerErrorNullPointer("uiControl", uiprivFunc); + return; + } + return c->implData; } diff --git a/common/events.c b/common/events.c index 92addeb5..e6d73090 100644 --- a/common/events.c +++ b/common/events.c @@ -30,6 +30,13 @@ struct uiEvent { uiprivArray unusedIDs; bool firing; }; +#define eventStaticInit(global) { \ + { sizeof (uiEventOptions), global }, \ + true, \ + uiprivArrayStaticInit(struct handler, 32, "uiEvent handlers"), \ + uirpivArrayStaticInit(int, 32, "uiEvent handler unused IDs"), \ + false, \ +} uiEvent *uiNewEvent(const uiEventOptions *options) { @@ -235,3 +242,15 @@ void uiEventInvalidateSender(uiEvent *e, void *sender) h++; } } + +// All built-in events go here. + +#define builtInEvent(name, global) \ + static uiEvent event_ ## name = eventStaticInit(global); \ + uiEvent *name(void) \ + { \ + if (!uiprivCheckInitializedAndThread()) \ + return NULL; \ + return &event_ ## name; \ + } +builtInEvent(uiControlOnFree, false) diff --git a/common/programmererrors.h b/common/programmererrors.h index f58f2d3e..1e6c08c2 100644 --- a/common/programmererrors.h +++ b/common/programmererrors.h @@ -68,3 +68,11 @@ #define uiprivProgrammerErrorCannotCreateBaseControl() \ uiprivProgrammerError("cannot create a uiControl of type uiControl; you must use a specific control type") + +#define uiprivProgrammerErrorInvalidControlInitData(type, func) \ + uiprivProgrammerError("invalid init data for %s in %s()", \ + type, func) + +#define uiprivProgrammerErrorControlHasParent(func) \ + uiprivProgrammerError("control passed to %s() (which requires a control without a parent) has a parent", \ + func) diff --git a/common/uipriv.h b/common/uipriv.h index 0f4ff5db..eef7a725 100644 --- a/common/uipriv.h +++ b/common/uipriv.h @@ -48,6 +48,7 @@ extern bool uiprivSysCheckThread(void); #define sharedbitsPrefix uipriv // TODO determine if we need the ../ or not, and if not, figure out if we should use it everywhere (including ui.h) or not #include "../sharedbits/alloc_header.h" +#define uiprivNew(T) ((T *) sharedbitsPrefix ## Alloc(sizeof (T), #T)) #include "../sharedbits/array_header.h" #define uiprivArrayStaticInit(T, grow, whatstr) { NULL, 0, 0, sizeof (T), grow, whatstr } #define uiprivArrayInit(arr, T, nGrow, what) uiprivArrayInitFull(&(arr), sizeof (T), nGrow, what)