DVX_GUI/core/widgetClass.c

86 lines
2.4 KiB
C

#define DVX_WIDGET_IMPL
// widgetClass.c -- Widget class table, API registry, and dynamic registration
//
// widgetClassTable is a stb_ds dynamic array. Widget DXEs call
// wgtRegisterClass() during wgtRegister() to append their class
// definition and receive a runtime type ID. No widget types are
// known at compile time.
//
// The API registry uses an stb_ds string hashmap for O(1) lookup.
// Each widget DXE calls wgtRegisterApi("name", &sApi) during
// wgtRegister(). App/core code calls wgtGetApi("name") to get
// the API pointer, then casts and calls through it.
#include "dvxWidgetPlugin.h"
#include "stb_ds.h"
#include <string.h>
// stb_ds dynamic array of class pointers. Grows on each
// wgtRegisterClass() call. Index = type ID.
const WidgetClassT **widgetClassTable = NULL;
// stb_ds string hashmap: key = widget name, value = API pointer
typedef struct {
char *key; // stb_ds string key (heap-allocated by shput)
const void *value;
} ApiMapEntryT;
static ApiMapEntryT *sApiMap = NULL;
// ============================================================
// wgtGetApi
// ============================================================
//
// Look up a widget API by name. O(1) via stb_ds string hashmap.
// Returns NULL if the widget is not loaded. Callers should still
// cache the result in a static local to skip even the hash.
const void *wgtGetApi(const char *name) {
if (!name) {
return NULL;
}
int32_t idx = shgeti(sApiMap, name);
if (idx < 0) {
return NULL;
}
return sApiMap[idx].value;
}
// ============================================================
// wgtRegisterApi
// ============================================================
//
// Register a widget's public API struct under a name. Called by
// each widget DXE during wgtRegister().
void wgtRegisterApi(const char *name, const void *api) {
if (!name || !api) {
return;
}
shput(sApiMap, name, api);
}
// ============================================================
// wgtRegisterClass
// ============================================================
//
// Appends a class to the table and returns the assigned type ID.
// The ID is simply the array index.
int32_t wgtRegisterClass(const WidgetClassT *wclass) {
if (!wclass) {
return -1;
}
int32_t id = arrlen(widgetClassTable);
arrput(widgetClassTable, wclass);
return id;
}