refactored value binding system

Thu, 15 May 2014 15:53:29 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 15 May 2014 15:53:29 +0200
changeset 37
56016468753d
parent 36
e4198fc2ead4
child 38
8ccdde37275b

refactored value binding system

application/main.c file | annotate | diff | comparison | revisions
make/configure_gtk2.sh file | annotate | diff | comparison | revisions
make/configure_gtk2legacy.sh file | annotate | diff | comparison | revisions
make/configure_gtk3.sh file | annotate | diff | comparison | revisions
make/configure_motif.sh file | annotate | diff | comparison | revisions
ui/common/context.c file | annotate | diff | comparison | revisions
ui/common/context.h file | annotate | diff | comparison | revisions
ui/common/document.c file | annotate | diff | comparison | revisions
ui/common/document.h file | annotate | diff | comparison | revisions
ui/ui/toolkit.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Sun May 11 11:35:33 2014 +0200
+++ b/application/main.c	Thu May 15 15:53:29 2014 +0200
@@ -47,7 +47,7 @@
 
 UiList *list;
 
-/*
+///*
 
 void action_new(UiEvent *event, void *data) {
     UiObject *window = ui_window("Mod1", NULL);
@@ -162,7 +162,7 @@
     ui_load_lang_def(NULL, "en_EN");
     //ui_openfilefunc(action_new, NULL);
     
-    /*
+    ///*
     list = ui_list_new();
     ui_list_append(list, "file1.txt");
     ui_list_append(list, "hello.txt");
@@ -209,11 +209,11 @@
     ui_toolbar_add_default("redo");
     //*/
     
-    ui_menu("File");
-    ui_menuitem("New", NULL, NULL);
-    ui_menuitem("Close", NULL, NULL);
-    ui_menu("Edit");
-    ui_menuitem("Preferences", NULL, NULL);
+    //ui_menu("File");
+    //ui_menuitem("New", NULL, NULL);
+    //ui_menuitem("Close", NULL, NULL);
+    //ui_menu("Edit");
+    //ui_menuitem("Preferences", NULL, NULL);
     
     printf("create window\n");
     UiObject *window = ui_window("Mod0", NULL);  
@@ -230,7 +230,7 @@
     ui_set_document(window, doc1);
     
     //ui_button(window, "OK", action_open, NULL);
-    //ui_textarea(window, &wdata->text);
+    ui_textarea(window, &wdata->text);
     
     //ui_window_addint(window, "check1");
     ui_show(window);
--- a/make/configure_gtk2.sh	Sun May 11 11:35:33 2014 +0200
+++ b/make/configure_gtk2.sh	Thu May 15 15:53:29 2014 +0200
@@ -28,7 +28,7 @@
 
 TK_CFLAGS="-DUI_GTK2 `pkg-config --cflags gtk+-2.0 libxml-2.0`"
 
-TK_LDFLAGS=`pkg-config --libs gtk+-2.0 libxml-2.0`
+TK_LDFLAGS=`pkg-config --libs gtk+-2.0 libxml-2.0` -lpthread
 
 cat >> config.mk << __EOF__
 
--- a/make/configure_gtk2legacy.sh	Sun May 11 11:35:33 2014 +0200
+++ b/make/configure_gtk2legacy.sh	Thu May 15 15:53:29 2014 +0200
@@ -29,7 +29,7 @@
 TK_CFLAGS="-DUI_GTK2 -DUI_GTK2LEGACY "
 TK_CFLAGS="$TK_CFLAGS `pkg-config --cflags gtk+-2.0 libxml-2.0`"
 
-TK_LDFLAGS=`pkg-config --libs gtk+-2.0 libxml-2.0`
+TK_LDFLAGS=`pkg-config --libs gtk+-2.0 libxml-2.0` -lpthread
 
 cat >> config.mk << __EOF__
 
--- a/make/configure_gtk3.sh	Sun May 11 11:35:33 2014 +0200
+++ b/make/configure_gtk3.sh	Thu May 15 15:53:29 2014 +0200
@@ -28,7 +28,7 @@
 
 TK_CFLAGS="-DUI_GTK3 `pkg-config --cflags gtk+-3.0 libxml-2.0`"
 
-TK_LDFLAGS=`pkg-config --libs gtk+-3.0 libxml-2.0`
+TK_LDFLAGS="`pkg-config --libs gtk+-3.0 libxml-2.0` -lpthread"
 
 cat >> config.mk << __EOF__
 
--- a/make/configure_motif.sh	Sun May 11 11:35:33 2014 +0200
+++ b/make/configure_motif.sh	Thu May 15 15:53:29 2014 +0200
@@ -26,9 +26,9 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-TK_CFLAGS="-DUI_MOTIF `pkg-config --cflags libxml-2.0`"
+TK_CFLAGS="-DUI_MOTIF "
 
-TK_LDFLAGS="`pkg-config --libs libxml-2.0` -lXm -lXt -lX11"
+TK_LDFLAGS="-lXm -lXt -lX11 -lpthread"
 
 cat >> config.mk << __EOF__
 
--- a/ui/common/context.c	Sun May 11 11:35:33 2014 +0200
+++ b/ui/common/context.c	Thu May 15 15:53:29 2014 +0200
@@ -40,7 +40,7 @@
     UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext));
     ctx->mempool = mp;
     
-    ctx->toplevel = toplevel;
+    ctx->obj = toplevel;
     ctx->vars = ucx_map_new_a(mp->allocator, 16);
     ctx->groups = NULL;
     ctx->group_widgets = NULL;
@@ -53,12 +53,15 @@
     return ctx;
 }
 
-UiVar* uic_getvar(UiContext *ctx, char *name) {
+UiVar* uic_get_var(UiContext *ctx, char *name) {
     // check document variables first
-    UiVar *var = uic_document_getvar(
-            uic_getdocument(ctx->toplevel->document),
-            name);
-    // check window vars
+    UiVar *var = NULL;
+    UiContext *doc_ctx = ui_document_context(ctx->document);
+    if(doc_ctx) {
+        var = uic_get_var(doc_ctx, name);
+    }
+    
+    // check variables of this context
     if(!var) {
         var = ucx_map_cstr_get(ctx->vars, name);
     }
@@ -67,10 +70,10 @@
 }
 
 UiVar* uic_connect_var(UiContext *ctx, char *name, int type) {
-    // TODO: get current map
+    // TODO: get current map (Document Container, Tabbed Pane)
     UcxMap *from = ctx->vars;
     
-    UiVar *var = uic_getvar(ctx, name);
+    UiVar *var = uic_get_var(ctx, name);
     if(var) {
         // the value is registered
         
@@ -103,6 +106,107 @@
     }
 }
 
+void uic_move_var(UiVar *from, UiVar *to, int set) {
+    switch(from->type) {
+        case UI_VAR_INTEGER: {
+            //memcpy(to->value, from->value, sizeof(UiInteger));
+            UiInteger *f = from->value;
+            UiInteger *t = to->value;
+            t->get = f->get;
+            t->set = f->set;
+            t->obj = f->obj; 
+            if(set) {
+                t->set(t, t->value);
+            } else {
+                //t->value = t->get(t);
+                f->value = f->get(f);
+                //t->value = 0;
+            }
+            break;
+        }
+        case UI_VAR_STRING: {
+            // TODO
+            break;
+        }
+        case UI_VAR_TEXT: {
+            UiText *f = from->value;
+            UiText *t = to->value;
+            char *tvalue = t->value;
+            memcpy(t, f, sizeof(UiText));
+            if(set) {
+                t->set(t, tvalue);
+            } else {
+                f->value = f->get(f);
+            }
+            break;
+        }
+        case UI_VAR_LIST: {
+            UiListVar *f = from->value;
+            UiListVar *t = to->value;
+            UiList *list = t->listptr->list;
+            UiObserver *observers = f->listptr->list->observers;
+            t->listptr = f->listptr;
+            if(set) {
+                t->listptr->list = list;
+                list->observers = observers;
+                ui_notify(observers, list);
+            }
+            break;
+        }
+    }
+}
+
+void uic_reg_var(UiContext *ctx, char *name, int type, size_t vs, void *value) {
+    UiVar *newvar = ucx_mempool_malloc(ctx->mempool, sizeof(UiVar));
+    newvar->isextern = 1;
+    newvar->type = type;
+    newvar->value = value;
+    newvar->from = NULL;
+    
+    uic_add_var(ctx, name, newvar, type, vs);
+}
+
+void uic_add_var(
+        UiContext *ctx,
+        char *name,
+        UiVar *newvar,
+        int type,
+        size_t vs)
+{ 
+    // if a parent context has a variable with this name, we remove it and put
+    // it to this context
+    UiVar *var = ctx->obj ? uic_get_var(ctx->obj->ctx, name) : NULL;
+    
+    if(var && var->from != ctx->vars) {
+        // external variables cannot be moved
+        if(var->isextern) {
+            fprintf(
+                    stderr,
+                    "UI Error: external variable %s "
+                    "cannot be moved to the document.\n",
+                    name);
+            return;
+        }
+        
+        // check type
+        if(var->type != type) {
+            fprintf(stderr, "UI Error: var %s has incompatible type.\n", name);
+            return;
+        }
+        
+        // override document var with window context var
+        memcpy(newvar->value, var->value, vs);
+        
+        newvar->from = var->from;
+        
+        // TODO: free var struct
+        ucx_map_cstr_remove(var->from, name);
+    }
+    
+    // finally, add the new variable to the document
+    ucx_map_cstr_put(ctx->vars, name, newvar);
+}
+
 void* uic_create_value(UcxAllocator *a, int type) {
     switch(type) {
         case UI_VAR_INTEGER: {
@@ -138,12 +242,10 @@
     return NULL;
 }
 
-
-
 // public API
 
 int ui_getint(UiObject *obj, char *name) {
-    UiVar *var = uic_getvar(obj->ctx, name);
+    UiVar *var = uic_get_var(obj->ctx, name);
     if(var) {
         if(var->type == UI_VAR_INTEGER) {
             UiInteger *i = var->value;
--- a/ui/common/context.h	Sun May 11 11:35:33 2014 +0200
+++ b/ui/common/context.h	Thu May 15 15:53:29 2014 +0200
@@ -44,9 +44,10 @@
 typedef struct UiGroupWidget UiGroupWidget;
 
 struct UiContext {
-    UiObject      *toplevel;
+    UiObject      *obj;
     UcxMempool    *mempool;
     UcxMap        *vars; // key: char*  value: UiVar*
+    void          *document;
     UcxList       *groups; // int list
     UcxList       *group_widgets; // UiGroupWidget* list
     
@@ -84,8 +85,17 @@
 };
 
 UiContext* uic_context(UiObject *toplevel, UcxMempool *mp);
-UiVar* uic_getvar(UiContext *ctx, char *name);
+UiVar* uic_get_var(UiContext *ctx, char *name);
 UiVar* uic_connect_var(UiContext *ctx, char *name, int type);
+void uic_move_var(UiVar *from, UiVar *to, int set);
+void uic_reg_var(UiContext *ctx, char *name, int type, size_t vs, void *value);
+void uic_add_var(
+        UiContext *ctx,
+        char *name,
+        UiVar *newvar,
+        int type,
+        size_t vs);
+
 void* uic_create_value(UcxAllocator *a, int type);
 
 void uic_check_group_widgets(UiContext *ctx);
--- a/ui/common/document.c	Sun May 11 11:35:33 2014 +0200
+++ b/ui/common/document.c	Thu May 15 15:53:29 2014 +0200
@@ -39,18 +39,19 @@
 }
 
 void ui_set_document(UiObject *obj, void *document) {
-    UiDocument *doc = ucx_map_get(documents, ucx_key(&document, sizeof(void*)));
-    if(!doc) {
+    UiContext *ctx = ucx_map_get(documents, ucx_key(&document, sizeof(void*)));
+    if(!ctx) {
         return;
     }
-    doc->obj = obj;
+    ctx->obj = obj;
     
     if(obj->document) {
         ui_detach_document(obj, obj->document);
     }
     obj->document = document;
+    obj->ctx->document = document;
     
-    UcxMapIterator i = ucx_map_iterator(doc->vars);
+    UcxMapIterator i = ucx_map_iterator(ctx->vars);
     UiVar *var;
     UCX_MAP_FOREACH(key, var, i) {
         UiVar *v = ucx_map_get(obj->ctx->vars, key);
@@ -68,7 +69,7 @@
             }
             
             // copy value
-            uic_var_move(v, var, 1);
+            uic_move_var(v, var, 1);
             var->from = v->from;
             
             // TODO: free var struct
@@ -79,20 +80,27 @@
 }
 
 void ui_detach_document(UiObject *obj, void *document) {
-    UiDocument *doc = ucx_map_get(documents, ucx_key(&document, sizeof(void*)));
-    if(!doc) {
+    UiContext *ctx = ucx_map_get(documents, ucx_key(&document, sizeof(void*)));
+    if(!ctx) {
+        fprintf(
+                stderr,
+                "UiError: ui_detach_document: document is not registered\n");
+        return;
+    }
+    if(obj->document != document) {
+        fprintf(stderr, "UiError: ui_detach_document: wrong document\n");
         return;
     }
     
-    UcxMapIterator i = ucx_map_iterator(doc->vars);
+    UcxMapIterator i = ucx_map_iterator(ctx->vars);
     UiVar *var;
     UCX_MAP_FOREACH(key, var, i) {
-        if(var->from && var->from != doc->vars) {
+        if(var->from && var->from != ctx->vars) {
             // this var is bind to an outer widget, so we move it          
             UcxAllocator *a = var->from->allocator;
             UiVar *newvar = a->malloc(a->pool, sizeof(UiVar));
             newvar->value = uic_create_value(a, var->type);
-            uic_var_move(var, newvar, 0);
+            uic_move_var(var, newvar, 0);
             newvar->type = var->type;
             newvar->from = var->from;
             newvar->isextern = 0;
@@ -103,20 +111,22 @@
         }
     }
     
-    doc->obj->document = NULL;
-    doc->obj = NULL;
+    ctx->obj->document = NULL;
+    ctx->obj->ctx->document = NULL;
+    
+    ctx->obj = NULL;
 }
 
 void* ui_document_new(size_t size) {
     UcxMempool *mp = ucx_mempool_new(256);
-    UiDocument *uidoc = ucx_mempool_malloc(mp, sizeof(UiDocument));
-    uidoc->obj = NULL;
-    uidoc->mempool = mp;
-    uidoc->vars = ucx_map_new_a(mp->allocator, 16);
-    uidoc->subdocument = NULL;
+    UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext));
+    ctx->obj = NULL;
+    ctx->mempool = mp;
+    ctx->vars = ucx_map_new_a(mp->allocator, 16);
+    //uidoc->subdocument = NULL;
     
     void *document = ucx_mempool_calloc(mp, 1, size);
-    ucx_map_put(documents, ucx_key(&document, sizeof(void*)), uidoc);
+    ucx_map_put(documents, ucx_key(&document, sizeof(void*)), ctx);
     return document;
 }
 
@@ -124,158 +134,45 @@
     // TODO
 }
 
+UiContext* ui_document_context(void *doc) {
+    if(doc) {
+        return ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
+    } else {
+        return NULL;
+    }
+}
+
 void* ui_document_malloc(void *doc, size_t size) {
-    UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
+    UiContext *uidoc = ui_document_context(doc);
     return ucx_mempool_malloc(uidoc->mempool, size);
 }
 
 void* ui_document_calloc(void *doc, size_t nelem, size_t elsize) {
-    UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
+    UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
     return ucx_mempool_calloc(uidoc->mempool, nelem, elsize);
 }
 
 void  ui_document_free(void *doc, void *ptr) {
-    UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
+    UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
     ucx_mempool_free(uidoc->mempool, ptr);
 }
 
 void* ui_document_realloc(void *doc, void *ptr, size_t size) {
-    UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
+    UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
     return ucx_mempool_realloc(uidoc->mempool, ptr, size);
 }
 
-UiDocument* uic_getdocument(void *doc) {
-    return doc ? ucx_map_get(documents, ucx_key(&doc, sizeof(void*))) : NULL;
-}
-
-UiVar* uic_document_getvar(UiDocument *doc, char *name) {
-    return doc ? ucx_map_cstr_get(doc->vars, name) : NULL;
-}
-
 void uic_document_addvar(void *doc, char *name, int type, size_t vs) {
-    UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
-    if(!uidoc) {
-        return;
-    }
-    
-    UiVar *newvar = ucx_mempool_malloc(uidoc->mempool, sizeof(UiVar));
-    newvar->isextern = 0;
-    newvar->type = type;
-    newvar->value = ucx_mempool_calloc(uidoc->mempool, 1, vs);
-    newvar->from = NULL;
-    
-    uic_document_addvar_v(uidoc, name, newvar, type, vs);
-}
-
-void uic_document_addvar_v(
-        UiDocument *uidoc,
-        char *name,
-        UiVar *newvar,
-        int type,
-        size_t vs)
-{ 
-    // if the window context has this variable, we remove it and put it to
-    // the document vars
-    UiVar *var = uidoc->obj ?
-            ucx_map_cstr_get(uidoc->obj->ctx->vars, name) : NULL;
-    if(var) {
-        // external variables cannot be moved
-        if(var->isextern) {
-            fprintf(
-                    stderr,
-                    "UI Error: external variable %s "
-                    "cannot be moved to the document.\n",
-                    name);
-            return;
-        }
-        
-        // check type
-        if(var->type != type) {
-            fprintf(stderr, "UI Error: var %s has incompatible type.\n", name);
-            return;
-        }
-        
-        // override document var with window context var
-        memcpy(newvar->value, var->value, vs);
-        
-        newvar->from = var->from;
-        
-        // TODO: free var struct
-        ucx_map_cstr_remove(uidoc->obj->ctx->vars, name);
-    }
-    
-    // finally, add the new variable to the document
-    ucx_map_cstr_put(uidoc->vars, name, newvar);
-}
+    // TODO: remove
+    UiContext *ctx = ui_document_context(doc);
+    if(ctx) {
+        UiVar *newvar = ucx_mempool_malloc(ctx->mempool, sizeof(UiVar));
+        newvar->isextern = 0;
+        newvar->type = type;
+        newvar->value = ucx_mempool_calloc(ctx->mempool, 1, vs);
+        newvar->from = NULL;
 
-void uic_document_regvar(
-        void *doc,
-        char *name, 
-        int type,
-        size_t vs,
-        void *value)
-{
-    UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
-    if(!uidoc) {
-        return;
-    }
-    
-    UiVar *newvar = ucx_mempool_malloc(uidoc->mempool, sizeof(UiVar));
-    newvar->isextern = 1;
-    newvar->type = type;
-    newvar->value = value;
-    newvar->from = NULL;
-    
-    uic_document_addvar_v(uidoc, name, newvar, type, vs);
-}
-
-void uic_var_move(UiVar *from, UiVar *to, int set) {
-    switch(from->type) {
-        case UI_VAR_INTEGER: {
-            //memcpy(to->value, from->value, sizeof(UiInteger));
-            UiInteger *f = from->value;
-            UiInteger *t = to->value;
-            t->get = f->get;
-            t->set = f->set;
-            t->obj = f->obj; 
-            if(set) {
-                t->set(t, t->value);
-            } else {
-                //t->value = t->get(t);
-                f->value = f->get(f);
-                //t->value = 0;
-            }
-            break;
-        }
-        case UI_VAR_STRING: {
-            // TODO
-            break;
-        }
-        case UI_VAR_TEXT: {
-            UiText *f = from->value;
-            UiText *t = to->value;
-            char *tvalue = t->value;
-            memcpy(t, f, sizeof(UiText));
-            if(set) {
-                t->set(t, tvalue);
-            } else {
-                f->value = f->get(f);
-            }
-            break;
-        }
-        case UI_VAR_LIST: {
-            UiListVar *f = from->value;
-            UiListVar *t = to->value;
-            UiList *list = t->listptr->list;
-            UiObserver *observers = f->listptr->list->observers;
-            t->listptr = f->listptr;
-            if(set) {
-                t->listptr->list = list;
-                list->observers = observers;
-                ui_notify(observers, list);
-            }
-            break;
-        }
+        uic_add_var(ctx, name, newvar, type, vs);
     }
 }
 
@@ -283,18 +180,29 @@
     uic_document_addvar(doc, name, UI_VAR_INTEGER, sizeof(UiInteger));
 }
 
+
+
 void ui_document_regint(void *doc, char *name, UiInteger *i) {
-    uic_document_regvar(doc, name, UI_VAR_INTEGER, sizeof(UiInteger), i);
+    UiContext *ctx = ui_document_context(doc);
+    if(ctx) {
+        uic_reg_var(ctx, name, UI_VAR_INTEGER, sizeof(UiInteger), i);
+    }
 }
 
 void ui_document_regtext(void *doc, char *name, UiText *text) {
-    uic_document_regvar(doc, name, UI_VAR_TEXT, sizeof(UiText), text);
+    UiContext *ctx = ui_document_context(doc);
+    if(ctx) {
+        uic_reg_var(doc, name, UI_VAR_TEXT, sizeof(UiText), text);
+    }
 }
 
 void ui_document_reglist(void *doc, char *name, UiList *list) {
-    UiListVar *lv = ui_document_malloc(doc, sizeof(UiListVar));
-    UiListPtr *lp = ui_document_malloc(doc, sizeof(UiListPtr));
-    lv->listptr = lp;
-    lp->list = list;
-    uic_document_regvar(doc, name, UI_VAR_LIST, sizeof(UiListPtr), lv);
+    UiContext *ctx = ui_document_context(doc);
+    if(ctx) {
+        UiListVar *lv = ui_document_malloc(doc, sizeof(UiListVar));
+        UiListPtr *lp = ui_document_malloc(doc, sizeof(UiListPtr));
+        lv->listptr = lp;
+        lp->list = list;
+        uic_reg_var(doc, name, UI_VAR_LIST, sizeof(UiListPtr), lv);
+    }
 }
--- a/ui/common/document.h	Sun May 11 11:35:33 2014 +0200
+++ b/ui/common/document.h	Thu May 15 15:53:29 2014 +0200
@@ -36,33 +36,14 @@
 extern "C" {
 #endif
 
-typedef struct UiDocument UiDocument;
-
-struct UiDocument {
-    UiObject     *obj;
-    UcxMempool   *mempool;
-    UcxMap       *vars; // key: char*  value: UiVar*
-    void         *subdocument;
-};
-
 void uic_docmgr_init();
-UiDocument* uic_getdocument(void *doc);
-UiVar* uic_document_getvar(UiDocument *doc, char *name);
 void uic_document_addvar(void *doc, char *name, int type, size_t vs);
 void uic_document_addvar_v(
-        UiDocument *uidoc,
+        UiContext *uidoc,
         char *name,
         UiVar *newvar,
         int type,
         size_t vs);
-void uic_document_regvar(
-        void *doc,
-        char *name, 
-        int type,
-        size_t vs,
-        void *value);
-
-void uic_var_move(UiVar *from, UiVar *to, int set);
 
 
 
--- a/ui/ui/toolkit.h	Sun May 11 11:35:33 2014 +0200
+++ b/ui/ui/toolkit.h	Thu May 15 15:53:29 2014 +0200
@@ -218,6 +218,8 @@
 void* ui_document_new(size_t size);
 void  ui_document_destroy(void *doc);
 
+UiContext* ui_document_context(void *doc);
+
 void* ui_document_malloc(void *doc, size_t size);
 void* ui_document_calloc(void *doc, size_t nelem, size_t elsize);
 void  ui_document_free(void *doc, void *ptr);

mercurial