89 lines
2.0 KiB
C
89 lines
2.0 KiB
C
// 17 may 2015
|
|
#include "../ui.h"
|
|
#include "uipriv.h"
|
|
|
|
struct typeinfo {
|
|
const char *name;
|
|
uintmax_t parent;
|
|
size_t size;
|
|
};
|
|
|
|
static struct ptrArray *types = NULL;
|
|
|
|
uintmax_t uiRegisterType(const char *name, uintmax_t parent, size_t size)
|
|
{
|
|
struct typeinfo *ti;
|
|
|
|
if (types == NULL) {
|
|
types = newPtrArray();
|
|
// reserve ID 0
|
|
ptrArrayAppend(types, NULL);
|
|
}
|
|
// TODO prevent our size from being smaller than our parent's
|
|
ti = uiNew(struct typeinfo);
|
|
ti->name = name;
|
|
ti->parent = parent;
|
|
ti->size = size;
|
|
ptrArrayAppend(types, ti);
|
|
return types->len - 1;
|
|
}
|
|
|
|
void *uiIsA(void *p, uintmax_t id, int fail)
|
|
{
|
|
uiTyped *t;
|
|
struct typeinfo *ti, *ti2;
|
|
uintmax_t compareTo;
|
|
|
|
if (id == 0 || id >= types->len)
|
|
complain("invalid type ID given to uiIsA()");
|
|
t = (uiTyped *) p;
|
|
compareTo = t->Type;
|
|
if (compareTo == 0)
|
|
complain("object %p has no type in uiIsA()", t);
|
|
for (;;) {
|
|
if (compareTo >= types->len)
|
|
complain("invalid type ID in uiIsA()", t);
|
|
if (compareTo == id)
|
|
return t;
|
|
ti = ptrArrayIndex(types, struct typeinfo *, compareTo);
|
|
if (ti->parent == 0)
|
|
break;
|
|
compareTo = ti->parent;
|
|
}
|
|
if (fail) {
|
|
ti = ptrArrayIndex(types, struct typeinfo *, id);
|
|
ti2 = ptrArrayIndex(types, struct typeinfo *, t->Type);
|
|
complain("object %p not a %s in uiIsA() (is a %s)", t, ti->name, ti2->name);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void uninitTypes(void)
|
|
{
|
|
struct typeinfo *ti;
|
|
|
|
if (types == NULL) // never initialized; do nothing
|
|
return;
|
|
// the first entry is NULL; get rid of it directly
|
|
ptrArrayDelete(types, 0);
|
|
while (types->len != 0) {
|
|
ti = ptrArrayIndex(types, struct typeinfo *, 0);
|
|
ptrArrayDelete(types, 0);
|
|
uiFree(ti);
|
|
}
|
|
ptrArrayDestroy(types);
|
|
}
|
|
|
|
uiTyped *newTyped(uintmax_t type)
|
|
{
|
|
struct typeinfo *ti;
|
|
uiTyped *instance;
|
|
|
|
if (type == 0 || type >= types->len)
|
|
complain("invalid type ID given to newTyped()");
|
|
ti = ptrArrayIndex(types, struct typeinfo *, type);
|
|
instance = (uiTyped *) uiAlloc(ti->size, ti->name);
|
|
instance->Type = type;
|
|
return instance;
|
|
}
|