Changed the type system so that memory is allocated as-is. This means that uiControls are destroyed by controlBaseDestroy(). There's a system for specifying uiControl subclasses directly in the source code too.

This commit is contained in:
Pietro Gagliardi 2015-05-29 14:43:44 -04:00
parent f0302d6a3e
commit c0cd20683a
6 changed files with 101 additions and 8 deletions

View File

@ -18,7 +18,7 @@ static void controlBaseDestroy(uiControl *c)
complain("attempt to destroy uiControl %p while it has a parent", c);
uiControlCommitDestroy(c);
uiFree(cb);
// TODO free c?
uiFree(c);
}
static uiControl *controlBaseParent(uiControl *c)
@ -119,9 +119,11 @@ static void controlBaseContainerUpdateState(uiControl *c)
// by default not a container; do nothing
}
void uiMakeControl(uiControl *c, uintmax_t type)
uiControl *uiNewControl(uintmax_t type)
{
uiTyped(c)->Type = type;
uiControl *c;
c = uiControl(newTyped(type));
uiControl(c)->Internal = uiNew(struct controlBase);
uiControl(c)->Destroy = controlBaseDestroy;
uiControl(c)->Parent = controlBaseParent;
@ -135,4 +137,5 @@ void uiMakeControl(uiControl *c, uintmax_t type)
uiControl(c)->Disable = controlBaseDisable;
uiControl(c)->UpdateState = controlBaseUpdateState;
uiControl(c)->ContainerUpdateState = controlBaseContainerUpdateState;
return uiControl(c);
}

73
redo/objimpl/types.c Normal file
View File

@ -0,0 +1,73 @@
// 17 may 2015
#include "out/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);
}
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;
}
// TODO free type info
uiTyped *newTyped(uintmax_t type)
{
struct typeinfo *ti;
uiTyped *instance;
if (type == 0 || id >= 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;
}

View File

@ -28,7 +28,7 @@ func OnShouldQuit(f *func(data *void) int, data *void);
func FreeText(text *char);
func RegisterType(name *const char, parent uintmax_t) uintmax_t;
func RegisterType(name *const char, parent uintmax_t, size size_t) uintmax_t;
func IsA(p *void, type uintmax_t, fail int) *void;
struct Typed {
field Type uintmax_t;
@ -74,6 +74,17 @@ interface Control {
func ContainerUpdateState(void);
};
func NewControl(type uintmax_t) *Control;
raw "#define uiDefineControlType(typename, funcname, realtype) \";
raw " static uintmax_t type_ ## typename = 0; \";
raw " uintmax_t funcname(void) \";
raw " { \";
raw " if (type_ ## typename == 0) \";
raw " type_ ## typename = uiRegisterType(#typename, uiTypeControl(), sizeof (realtype)); \";
raw " return type_ ## typename; \";
raw " }";
func FreeSizing(d *Sizing);
func MakeContainer(c *Control);

View File

@ -18,7 +18,7 @@ _UI_EXTERN void uiWIndowsUtilEnable(HWND hwnd);
_UI_EXTERN void uiWindowsUtilDisable(HWND hwnd);
_UI_EXTERN void uiWindowsUtilSysFunc(HWND hwnd, uiControlSysFuncParams *p);
_UI_EXTERN void uiWindowsUtilStartZOrder(HWND hwnd, uiControlSysFuncParams *p);
_UI_EXTERN void uiWindowsMakeSingleHWNDControl(uiControl *c, uintmax_t type);
_UI_EXTERN uiControl *uiWindowsNewSingleHWNDControl(uintmax_t type);
// This contains the Windows-specific parts of the uiSizing structure.
// BaseX and BaseY are the dialog base units.

View File

@ -31,4 +31,7 @@ void ptrArrayDelete(struct ptrArray *, uintmax_t);
#define ptrArrayIndex(p, T, i) ((T) ((p)->ptrs[(i)]))
// shouldquit.c
int shouldQuit(void);
extern int shouldQuit(void);
// types.c
extern uiTyped *newTyped(uintmax_t type);

View File

@ -144,9 +144,11 @@ static void singleHWNDStartZOrder(uiControl *c, uiControlSysFuncParams *p)
uiWindowsUtilStartZOrder(HWND(c), p);
}
void uiWindowsMakeSingleHWNDControl(uiControl *c, uintmax_t type)
uiControl *uiWindowsNewSingleHWNDControl(uintmax_t type)
{
uiMakeControl(c, type);
uiControl *c;
c = uiNewControl(type);
uiControl(c)->CommitDestroy = singleHWNDCommitDestroy;
uiControl(c)->CommitSetParent = singleHWNDCommitSetParent;
uiControl(c)->Resize = singleHWNDResize;
@ -157,4 +159,5 @@ void uiWindowsMakeSingleHWNDControl(uiControl *c, uintmax_t type)
uiControl(c)->CommitDisable = singleHWNDCommitDisable;
uiControl(c)->SysFunc = singleHWNDSysFunc;
uiControl(c)->StartZOrder = singleHWNDStartZOrder;
return c;
}