diff --git a/redo/types.c b/redo/types.c new file mode 100644 index 00000000..4a058160 --- /dev/null +++ b/redo/types.c @@ -0,0 +1,53 @@ +// 17 may 2015 +#include "out/ui.h" +#include "uipriv.h" + +struct typeinfo { + const char *name; + uintmax_t parent; +}; + +static struct ptrArray *types = NULL; + +uintmax_t uiRegisterType(const char *name, uintmax_t parent) +{ + struct typeinfo *ti; + + if (types == NULL) { + types = newPtrArray(); + // reserve ID 0 + ptrArrayAppend(types, NULL); + } + ti = uiNew(struct typeinfo); + ti->name = name; + ti->parent = parent; + ptrArrayAppend(types, ti); + return types->len - 1; +} + +void *uiIsA(void *p, uintmax_t id) +{ + uiTyped *t; + struct typeinfo *ti; + uintmax_t compareTo; + + if (id == 0 || id >= types->len) + complain("invalid type ID given to uiIsA()"); + t = (uiTyped *) p; + compareTo = t->Type; + for (;;) { + if (compareTo == 0 || compareTo >= types->len) + complain("invalid type ID in uiIsA()", t); + if (compareTo == id) + return t; + ti = ptrArrayIndex(types, struct typeinfo *, t->Type); + if (ti->parent == 0) + break; + compareTo = ti->parent; + } + ti = ptrArrayIndex(types, struct typeInfo *, t->Type); + complain("object %p not a %s in uiIsA()", t, ti->name); + return NULL; // make compiler happy +} + +// TODO free type info diff --git a/redo/ui.idl b/redo/ui.idl index 0d4f2afa..e27cb0ec 100644 --- a/redo/ui.idl +++ b/redo/ui.idl @@ -28,6 +28,12 @@ func OnShouldQuit(f *func(data *void) int, data *void); func FreeText(text *char); +func RegisterType(name *const char, parent uintmax_t); +func IsA(p *void, type uintmax_t); +struct uiTyped { + field Type uintmax_t; +}; + raw "typedef struct uiSizingSys uiSizingSys;"; struct Sizing {