And finished filling in controls.c. This is gonna be fun to debug...

This commit is contained in:
Pietro Gagliardi 2019-06-08 15:31:40 -04:00
parent 1189877ca5
commit 7aa1b0870d
4 changed files with 65 additions and 0 deletions

View File

@ -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;
}

View File

@ -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)

View File

@ -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)

View File

@ -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)