From b8f8e1c4f708108c72ad93349a09a52d7be8ced0 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sun, 2 Jun 2019 20:47:27 -0400 Subject: [PATCH] Started writing out uiControl's documentation. This new design is going to be rather interesting. --- doc/controls.md | 31 +++++++++++++++++++++++++++++++ doc/events.md | 2 +- ui.h | 7 +++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/doc/controls.md b/doc/controls.md index 7fbe19ce..4e5ac83a 100644 --- a/doc/controls.md +++ b/doc/controls.md @@ -21,3 +21,34 @@ uint32_t uiControlType(void); `uiControl()` is a conversion macro for casting a pointer of a specific control type (or a `void *`) to `uiControl` while also checking for errors. `uiControlType()` is the type identifier of a `uiControl` as passed to `uiControlCheckType()`. You rarely need to call this directly; the `uiControl()` conversion macro does this for you. + +### `uiControlVtable` + +```c +typedef struct uiControlVtable uiControlVtable; +struct uiControlVtable { + void (*Free)(uiControl *c, void *implData); +}; +``` + +`uiControlVtable` describes the set of functions that control implementations need to implement. When registering your control type, you pass this in as part of the OS-specific counterpart vtable. Each method here is required. + +Each method takes at least two parameters. The first, `c`, is the `uiControl` itself. The second, `implData`, is the implementation data pointer; it is the same as the pointer returned by `uiControlImplData(c)`, and is provided here as a convenience. + +Each method is named for the `uiControl` function that it implements. As such, details on how to implement these methods are documented alongside those functions. For instance, instructions on implementing `Free()` are given under the documentation for `uiControlFree()`. + +### `uiControlFree()` + +```c +void uiControlFree(uiControl *c); +``` + +`uiControlFree()` frees the given control. + +If `c` has children, those children are also freed. It is a programmer error to free a control that is itself a child of another control. + +If `c` has any registered events, those event handlers will be set to be no longer run via `uiEventInvalidateSender()`. The registered handlers themselves will not be removed, to avoid the scenario of another `uiControl` being created with the same pointer value later triggering your handler unexpectedly. + +It is a programmer error to specify `NULL` for `c`. + +**For control implementations**: This function calls your vtable's `Free()` method. Parameter validity checks are already performed, `uiControlEventOnFree()` handlers have been called, and `uiControl`-specific events have been invalidated. Your `Free()` should invalidate any events that are specific to your controls, call `uiControlFree()` on all the children of this control, and free dynamically allocated memory that is part of your implementation data. Once your `Free()` method returns, libui will take care of freeing the implementation data memory block itself. diff --git a/doc/events.md b/doc/events.md index 27279d17..1bbfd084 100644 --- a/doc/events.md +++ b/doc/events.md @@ -58,7 +58,7 @@ uiprivExtern void uiFreeEvent(uiEvent *e); Frees the given event. The event must not be a libui-provided event, and must not have any handlers registered to it. -It is a programmer error to pass `NULL` for the given event, or to pass in an event that is currently firing. +It is a programmer error to pass `NULL` for `e`. It is also a programmer error to call `uiFreeEvent()` on an event while that event is being fired. ### `uiEventAddHandler()` diff --git a/ui.h b/ui.h index 276dd358..f2441453 100644 --- a/ui.h +++ b/ui.h @@ -62,10 +62,17 @@ uiprivExtern bool uiEventHandlerBlocked(const uiEvent *e, int id); uiprivExtern void uiEventSetHandlerBlocked(uiEvent *e, int id, bool blocked); typedef struct uiControl uiControl; +typedef struct uiControlVtable uiControlVtable; uiprivExtern uint32_t uiControlType(void); #define uiControl(obj) ((uiControl *) uiCheckControlType((obj), uiControlType())) +struct uiControlVtable { + void (*Free)(uiControl *c, void *implData); +}; + +uiprivExtern void uiControlFree(uiControl *c); + #ifdef __cplusplus } #endif