--- a/ui/common/context.c Sun Apr 16 10:20:21 2023 +0200 +++ b/ui/common/context.c Tue May 23 11:11:28 2023 +0200 @@ -32,6 +32,10 @@ #include <inttypes.h> #include <stdarg.h> +#include <cx/array_list.h> +#include <cx/compare.h> +#include <cx/basic_mempool.h> + #include "context.h" #include "../ui/window.h" #include "document.h" @@ -40,20 +44,24 @@ static UiContext* global_context; void uic_init_global_context(void) { - UcxMempool *mp = ucx_mempool_new(32); - global_context = uic_context(NULL, mp); + CxMempool *mp = cxBasicMempoolCreate(32); + global_context = uic_context(NULL, mp->allocator); } UiContext* ui_global_context(void) { return global_context; } -UiContext* uic_context(UiObject *toplevel, UcxMempool *mp) { - UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext)); +UiContext* uic_context(UiObject *toplevel, const CxAllocator *a) { + UiContext *ctx = cxMalloc(a, sizeof(UiContext)); memset(ctx, 0, sizeof(UiContext)); - ctx->mempool = mp; + ctx->allocator = a; ctx->obj = toplevel; - ctx->vars = ucx_map_new_a(mp->allocator, 16); + ctx->vars = cxHashMapCreate(a, CX_STORE_POINTERS, 16); + + ctx->documents = cxLinkedListCreate(a, cx_cmp_intptr, CX_STORE_POINTERS); + ctx->group_widgets = cxLinkedListCreate(a, NULL, sizeof(UiGroupWidget)); + ctx->groups = cxArrayListCreate(a, cx_cmp_int, sizeof(int), 32); ctx->attach_document = uic_context_attach_document; ctx->detach_document2 = uic_context_detach_document2; @@ -73,8 +81,8 @@ } void uic_context_attach_document(UiContext *ctx, void *document) { - ctx->documents = ucx_list_append_a(ctx->mempool->allocator, ctx->documents, document); - ctx->document = ctx->documents->data; + cxListAdd(ctx->documents, document); + ctx->document = document; UiContext *doc_ctx = ui_document_context(document); @@ -82,25 +90,17 @@ // as any document variable UiContext *var_ctx = ctx; while(var_ctx) { - if(var_ctx->vars_unbound && var_ctx->vars_unbound->count > 0) { - UcxMapIterator i = ucx_map_iterator(var_ctx->vars_unbound); - UiVar *var; - // rmkeys holds all keys, that shall be removed from vars_unbound - UcxKey *rmkeys = calloc(var_ctx->vars_unbound->count, sizeof(UcxKey)); - size_t numkeys = 0; - UCX_MAP_FOREACH(key, var, i) { - UiVar *docvar = ucx_map_get(doc_ctx->vars, key); + if(var_ctx->vars_unbound && var_ctx->vars_unbound->size > 0) { + CxIterator i = cxMapIterator(var_ctx->vars_unbound); + cx_foreach(CxMapEntry*, entry, i) { + UiVar *var = entry->value; + UiVar *docvar = cxMapGet(doc_ctx->vars, *entry->key); if(docvar) { // bind var to document var uic_copy_binding(var, docvar, TRUE); - rmkeys[numkeys++] = key; // save the key for removal + cxIteratorFlagRemoval(i); } } - // now that we may have bound some vars to the document, - // we can remove them from the unbound map - for(size_t k=0;k<numkeys;k++) { - ucx_map_remove(var_ctx->vars_unbound, rmkeys[k]); - } } var_ctx = ctx->parent; @@ -108,56 +108,63 @@ } static void uic_context_unbind_vars(UiContext *ctx) { - UcxMapIterator i = ucx_map_iterator(ctx->vars); - UiVar *var; - UCX_MAP_FOREACH(key, var, i) { + CxIterator i = cxMapIterator(ctx->vars); + cx_foreach(CxMapEntry*, entry, i) { + UiVar *var = entry->value; if(var->from && var->from_ctx) { uic_save_var2(var); uic_copy_binding(var, var->from, FALSE); - ucx_map_put(var->from_ctx->vars_unbound, key, var->from); + cxMapPut(var->from_ctx->vars_unbound, *entry->key, var->from); var->from_ctx = ctx; } } - UCX_FOREACH(elm, ctx->documents) { - UiContext *subctx = ui_document_context(elm->data); - uic_context_unbind_vars(subctx); + if(ctx->documents) { + i = cxListIterator(ctx->documents); + cx_foreach(void *, doc, i) { + UiContext *subctx = ui_document_context(doc); + uic_context_unbind_vars(subctx); + } } } void uic_context_detach_document2(UiContext *ctx, void *document) { // find the document in the documents list - UcxList *doc = NULL; - UCX_FOREACH(elm, ctx->documents) { - if(elm->data == document) { - doc = elm; - break; - } - } - if(!doc) { - return; // document is not a subdocument of this context + ssize_t docIndex = cxListFind(ctx->documents, document); + if(docIndex < 0) { + return; } - ctx->documents = ucx_list_remove_a(ctx->mempool->allocator, ctx->documents, doc); - ctx->document = ctx->documents ? ctx->documents->data : NULL; + cxListRemove(ctx->documents, docIndex); + ctx->document = cxListAt(ctx->documents, 0); UiContext *docctx = ui_document_context(document); uic_context_unbind_vars(docctx); // unbind all doc/subdoc vars from the parent } void uic_context_detach_all(UiContext *ctx) { - UcxList *ls = ucx_list_clone(ctx->documents, NULL, NULL); - UCX_FOREACH(elm, ls) { - ctx->detach_document2(ctx, elm->data); + // copy list + CxList *ls = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS); + CxIterator i = cxListIterator(ctx->documents); + cx_foreach(void *, doc, i) { + cxListAdd(ls, doc); } - ucx_list_free(ls); + + // detach documents + i = cxListIterator(ls); + cx_foreach(void *, doc, i) { + ctx->detach_document2(ctx, doc); + } + + cxListDestroy(ls); } -static UiVar* ctx_getvar(UiContext *ctx, UcxKey key) { - UiVar *var = ucx_map_get(ctx->vars, key); +static UiVar* ctx_getvar(UiContext *ctx, CxHashKey key) { + UiVar *var = cxMapGet(ctx->vars, key); if(!var) { - UCX_FOREACH(elm, ctx->documents) { - UiContext *subctx = ui_document_context(elm->data); + CxIterator i = cxListIterator(ctx->documents); + cx_foreach(void *, doc, i) { + UiContext *subctx = ui_document_context(doc); var = ctx_getvar(subctx, key); if(var) { break; @@ -168,7 +175,7 @@ } UiVar* uic_get_var(UiContext *ctx, const char *name) { - UcxKey key = ucx_key(name, strlen(name)); + CxHashKey key = cx_hash_key(name, strlen(name)); return ctx_getvar(ctx, key); } @@ -189,9 +196,9 @@ var->from_ctx = ctx; if(!ctx->vars_unbound) { - ctx->vars_unbound = ucx_map_new_a(ctx->mempool->allocator, 16); + ctx->vars_unbound = cxHashMapCreate(ctx->allocator, CX_STORE_POINTERS, 16); } - ucx_map_cstr_put(ctx->vars_unbound, name, var); + cxMapPut(ctx->vars_unbound, name, var); return var; } @@ -358,9 +365,9 @@ var->value = value; var->from = NULL; var->from_ctx = ctx; - size_t oldcount = ctx->vars->count; - ucx_map_cstr_put(ctx->vars, name, var); - if(ctx->vars->count != oldcount + 1) { + size_t oldcount = ctx->vars->size; + cxMapPut(ctx->vars, name, var); + if(ctx->vars->size != oldcount + 1) { fprintf(stderr, "UiError: var '%s' already exists\n", name); } @@ -375,8 +382,7 @@ } void uic_remove_bound_var(UiContext *ctx, UiVar *var) { - // TODO: implement - printf("TODO: implement uic_remove_bound_var\n"); + // TODO } @@ -397,8 +403,8 @@ void ui_set_group(UiContext *ctx, int group) { - if(ucx_list_find(ctx->groups, (void*)(intptr_t)group, NULL, NULL) == -1) { - ctx->groups = ucx_list_append_a(ctx->mempool->allocator, ctx->groups, (void*)(intptr_t)group); + if(cxListFind(ctx->groups, &group) == -1) { + cxListAdd(ctx->groups, &group); } // enable/disable group widgets @@ -406,10 +412,9 @@ } void ui_unset_group(UiContext *ctx, int group) { - int i = ucx_list_find(ctx->groups, (void*)(intptr_t)group, NULL, NULL); + int i = cxListFind(ctx->groups, &group); if(i != -1) { - UcxList *elm = ucx_list_get(ctx->groups, i); - ctx->groups = ucx_list_remove_a(ctx->mempool->allocator, ctx->groups, elm); + cxListRemove(ctx->groups, i); } // enable/disable group widgets @@ -417,28 +422,16 @@ } int* ui_active_groups(UiContext *ctx, int *ngroups) { - if(!ctx->groups) { - return NULL; - } - - int nelm = ucx_list_size(ctx->groups); - int *groups = calloc(sizeof(int), nelm); - - int i = 0; - UCX_FOREACH(elm, ctx->groups) { - groups[i++] = (intptr_t)elm->data; - } - - *ngroups = nelm; - return groups; + *ngroups = ctx->groups->size; + return cxListAt(ctx->groups, 0); } void uic_check_group_widgets(UiContext *ctx) { int ngroups = 0; int *groups = ui_active_groups(ctx, &ngroups); - UCX_FOREACH(elm, ctx->group_widgets) { - UiGroupWidget *gw = elm->data; + CxIterator i = cxListIterator(ctx->group_widgets); + cx_foreach(UiGroupWidget *, gw, i) { char *check = calloc(1, gw->numgroups); for(int i=0;i<ngroups;i++) { @@ -456,64 +449,60 @@ break; } } + free(check); gw->enable(gw->widget, enable); } - - if(groups) { - free(groups); - } } void ui_widget_set_groups(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...) { // get groups - UcxList *groups = NULL; + CxList *groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16); va_list ap; va_start(ap, enable); int group; while((group = va_arg(ap, int)) != -1) { - groups = ucx_list_append(groups, (void*)(intptr_t)group); + cxListAdd(groups, &group); } va_end(ap); uic_add_group_widget(ctx, widget, enable, groups); - ucx_list_free(groups); + cxListDestroy(groups); } -void uic_add_group_widget(UiContext *ctx, void *widget, ui_enablefunc enable, UcxList *groups) { - UcxMempool *mp = ctx->mempool; - UiGroupWidget *gw = ucx_mempool_malloc(mp, sizeof(UiGroupWidget)); +void uic_add_group_widget(UiContext *ctx, void *widget, ui_enablefunc enable, CxList *groups) { + const CxAllocator *a = ctx->allocator; + UiGroupWidget gw; - gw->widget = widget; - gw->enable = enable; - gw->numgroups = ucx_list_size(groups); - gw->groups = ucx_mempool_calloc(mp, gw->numgroups, sizeof(int)); - int i = 0; - UCX_FOREACH(elm, groups) { - gw->groups[i++] = (intptr_t)elm->data; + gw.widget = widget; + gw.enable = enable; + gw.numgroups = groups->size; + gw.groups = cxCalloc(a, gw.numgroups, sizeof(int)); + + // copy groups + int *intgroups = cxListAt(groups, 0); + if(intgroups) { + memcpy(gw.groups, intgroups, gw.numgroups * sizeof(int)); } - ctx->group_widgets = ucx_list_append_a( - mp->allocator, - ctx->group_widgets, - gw); + cxListAdd(ctx->group_widgets, &gw); } void* ui_malloc(UiContext *ctx, size_t size) { - return ctx ? ucx_mempool_malloc(ctx->mempool, size) : NULL; + return ctx ? cxMalloc(ctx->allocator, size) : NULL; } void* ui_calloc(UiContext *ctx, size_t nelem, size_t elsize) { - return ctx ? ucx_mempool_calloc(ctx->mempool, nelem, elsize) : NULL; + return ctx ? cxCalloc(ctx->allocator, nelem, elsize) : NULL; } void ui_free(UiContext *ctx, void *ptr) { if(ctx) { - ucx_mempool_free(ctx->mempool, ptr); + cxFree(ctx->allocator, ptr); } } void* ui_realloc(UiContext *ctx, void *ptr, size_t size) { - return ctx ? ucx_mempool_realloc(ctx->mempool, ptr, size) : NULL; + return ctx ? cxRealloc(ctx->allocator, ptr, size) : NULL; }