ui/common/context.c

branch
newapi
changeset 178
7c3ff86ee9d4
parent 174
0358f1d9c506
child 187
24ce2c326d85
--- 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;
 }
 

mercurial