ui/common/document.c

changeset 37
56016468753d
parent 33
458831c574f4
child 52
25e5390cce41
equal deleted inserted replaced
36:e4198fc2ead4 37:56016468753d
37 void uic_docmgr_init() { 37 void uic_docmgr_init() {
38 documents = ucx_map_new(32); 38 documents = ucx_map_new(32);
39 } 39 }
40 40
41 void ui_set_document(UiObject *obj, void *document) { 41 void ui_set_document(UiObject *obj, void *document) {
42 UiDocument *doc = ucx_map_get(documents, ucx_key(&document, sizeof(void*))); 42 UiContext *ctx = ucx_map_get(documents, ucx_key(&document, sizeof(void*)));
43 if(!doc) { 43 if(!ctx) {
44 return; 44 return;
45 } 45 }
46 doc->obj = obj; 46 ctx->obj = obj;
47 47
48 if(obj->document) { 48 if(obj->document) {
49 ui_detach_document(obj, obj->document); 49 ui_detach_document(obj, obj->document);
50 } 50 }
51 obj->document = document; 51 obj->document = document;
52 52 obj->ctx->document = document;
53 UcxMapIterator i = ucx_map_iterator(doc->vars); 53
54 UcxMapIterator i = ucx_map_iterator(ctx->vars);
54 UiVar *var; 55 UiVar *var;
55 UCX_MAP_FOREACH(key, var, i) { 56 UCX_MAP_FOREACH(key, var, i) {
56 UiVar *v = ucx_map_get(obj->ctx->vars, key); 57 UiVar *v = ucx_map_get(obj->ctx->vars, key);
57 if(v) { 58 if(v) {
58 if(v->isextern) { 59 if(v->isextern) {
66 fprintf(stderr, "UI Error: var has incompatible type.\n"); 67 fprintf(stderr, "UI Error: var has incompatible type.\n");
67 return; 68 return;
68 } 69 }
69 70
70 // copy value 71 // copy value
71 uic_var_move(v, var, 1); 72 uic_move_var(v, var, 1);
72 var->from = v->from; 73 var->from = v->from;
73 74
74 // TODO: free var struct 75 // TODO: free var struct
75 ucx_map_remove(obj->ctx->vars, key); 76 ucx_map_remove(obj->ctx->vars, key);
76 } 77 }
77 } 78 }
78 79
79 } 80 }
80 81
81 void ui_detach_document(UiObject *obj, void *document) { 82 void ui_detach_document(UiObject *obj, void *document) {
82 UiDocument *doc = ucx_map_get(documents, ucx_key(&document, sizeof(void*))); 83 UiContext *ctx = ucx_map_get(documents, ucx_key(&document, sizeof(void*)));
83 if(!doc) { 84 if(!ctx) {
85 fprintf(
86 stderr,
87 "UiError: ui_detach_document: document is not registered\n");
84 return; 88 return;
85 } 89 }
86 90 if(obj->document != document) {
87 UcxMapIterator i = ucx_map_iterator(doc->vars); 91 fprintf(stderr, "UiError: ui_detach_document: wrong document\n");
92 return;
93 }
94
95 UcxMapIterator i = ucx_map_iterator(ctx->vars);
88 UiVar *var; 96 UiVar *var;
89 UCX_MAP_FOREACH(key, var, i) { 97 UCX_MAP_FOREACH(key, var, i) {
90 if(var->from && var->from != doc->vars) { 98 if(var->from && var->from != ctx->vars) {
91 // this var is bind to an outer widget, so we move it 99 // this var is bind to an outer widget, so we move it
92 UcxAllocator *a = var->from->allocator; 100 UcxAllocator *a = var->from->allocator;
93 UiVar *newvar = a->malloc(a->pool, sizeof(UiVar)); 101 UiVar *newvar = a->malloc(a->pool, sizeof(UiVar));
94 newvar->value = uic_create_value(a, var->type); 102 newvar->value = uic_create_value(a, var->type);
95 uic_var_move(var, newvar, 0); 103 uic_move_var(var, newvar, 0);
96 newvar->type = var->type; 104 newvar->type = var->type;
97 newvar->from = var->from; 105 newvar->from = var->from;
98 newvar->isextern = 0; 106 newvar->isextern = 0;
99 107
100 ucx_map_put(var->from, key, newvar); 108 ucx_map_put(var->from, key, newvar);
101 109
102 //ucx_map_remove(doc->vars, key); // TODO: dont remove! 110 //ucx_map_remove(doc->vars, key); // TODO: dont remove!
103 } 111 }
104 } 112 }
105 113
106 doc->obj->document = NULL; 114 ctx->obj->document = NULL;
107 doc->obj = NULL; 115 ctx->obj->ctx->document = NULL;
116
117 ctx->obj = NULL;
108 } 118 }
109 119
110 void* ui_document_new(size_t size) { 120 void* ui_document_new(size_t size) {
111 UcxMempool *mp = ucx_mempool_new(256); 121 UcxMempool *mp = ucx_mempool_new(256);
112 UiDocument *uidoc = ucx_mempool_malloc(mp, sizeof(UiDocument)); 122 UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext));
113 uidoc->obj = NULL; 123 ctx->obj = NULL;
114 uidoc->mempool = mp; 124 ctx->mempool = mp;
115 uidoc->vars = ucx_map_new_a(mp->allocator, 16); 125 ctx->vars = ucx_map_new_a(mp->allocator, 16);
116 uidoc->subdocument = NULL; 126 //uidoc->subdocument = NULL;
117 127
118 void *document = ucx_mempool_calloc(mp, 1, size); 128 void *document = ucx_mempool_calloc(mp, 1, size);
119 ucx_map_put(documents, ucx_key(&document, sizeof(void*)), uidoc); 129 ucx_map_put(documents, ucx_key(&document, sizeof(void*)), ctx);
120 return document; 130 return document;
121 } 131 }
122 132
123 void ui_document_destroy(void *doc) { 133 void ui_document_destroy(void *doc) {
124 // TODO 134 // TODO
125 } 135 }
126 136
137 UiContext* ui_document_context(void *doc) {
138 if(doc) {
139 return ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
140 } else {
141 return NULL;
142 }
143 }
144
127 void* ui_document_malloc(void *doc, size_t size) { 145 void* ui_document_malloc(void *doc, size_t size) {
128 UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); 146 UiContext *uidoc = ui_document_context(doc);
129 return ucx_mempool_malloc(uidoc->mempool, size); 147 return ucx_mempool_malloc(uidoc->mempool, size);
130 } 148 }
131 149
132 void* ui_document_calloc(void *doc, size_t nelem, size_t elsize) { 150 void* ui_document_calloc(void *doc, size_t nelem, size_t elsize) {
133 UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); 151 UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
134 return ucx_mempool_calloc(uidoc->mempool, nelem, elsize); 152 return ucx_mempool_calloc(uidoc->mempool, nelem, elsize);
135 } 153 }
136 154
137 void ui_document_free(void *doc, void *ptr) { 155 void ui_document_free(void *doc, void *ptr) {
138 UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); 156 UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
139 ucx_mempool_free(uidoc->mempool, ptr); 157 ucx_mempool_free(uidoc->mempool, ptr);
140 } 158 }
141 159
142 void* ui_document_realloc(void *doc, void *ptr, size_t size) { 160 void* ui_document_realloc(void *doc, void *ptr, size_t size) {
143 UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); 161 UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
144 return ucx_mempool_realloc(uidoc->mempool, ptr, size); 162 return ucx_mempool_realloc(uidoc->mempool, ptr, size);
145 } 163 }
146 164
147 UiDocument* uic_getdocument(void *doc) {
148 return doc ? ucx_map_get(documents, ucx_key(&doc, sizeof(void*))) : NULL;
149 }
150
151 UiVar* uic_document_getvar(UiDocument *doc, char *name) {
152 return doc ? ucx_map_cstr_get(doc->vars, name) : NULL;
153 }
154
155 void uic_document_addvar(void *doc, char *name, int type, size_t vs) { 165 void uic_document_addvar(void *doc, char *name, int type, size_t vs) {
156 UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); 166 // TODO: remove
157 if(!uidoc) { 167 UiContext *ctx = ui_document_context(doc);
158 return; 168 if(ctx) {
159 } 169 UiVar *newvar = ucx_mempool_malloc(ctx->mempool, sizeof(UiVar));
160 170 newvar->isextern = 0;
161 UiVar *newvar = ucx_mempool_malloc(uidoc->mempool, sizeof(UiVar)); 171 newvar->type = type;
162 newvar->isextern = 0; 172 newvar->value = ucx_mempool_calloc(ctx->mempool, 1, vs);
163 newvar->type = type; 173 newvar->from = NULL;
164 newvar->value = ucx_mempool_calloc(uidoc->mempool, 1, vs); 174
165 newvar->from = NULL; 175 uic_add_var(ctx, name, newvar, type, vs);
166
167 uic_document_addvar_v(uidoc, name, newvar, type, vs);
168 }
169
170 void uic_document_addvar_v(
171 UiDocument *uidoc,
172 char *name,
173 UiVar *newvar,
174 int type,
175 size_t vs)
176 {
177 // if the window context has this variable, we remove it and put it to
178 // the document vars
179 UiVar *var = uidoc->obj ?
180 ucx_map_cstr_get(uidoc->obj->ctx->vars, name) : NULL;
181 if(var) {
182 // external variables cannot be moved
183 if(var->isextern) {
184 fprintf(
185 stderr,
186 "UI Error: external variable %s "
187 "cannot be moved to the document.\n",
188 name);
189 return;
190 }
191
192 // check type
193 if(var->type != type) {
194 fprintf(stderr, "UI Error: var %s has incompatible type.\n", name);
195 return;
196 }
197
198 // override document var with window context var
199 memcpy(newvar->value, var->value, vs);
200
201 newvar->from = var->from;
202
203 // TODO: free var struct
204 ucx_map_cstr_remove(uidoc->obj->ctx->vars, name);
205 }
206
207 // finally, add the new variable to the document
208 ucx_map_cstr_put(uidoc->vars, name, newvar);
209 }
210
211 void uic_document_regvar(
212 void *doc,
213 char *name,
214 int type,
215 size_t vs,
216 void *value)
217 {
218 UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
219 if(!uidoc) {
220 return;
221 }
222
223 UiVar *newvar = ucx_mempool_malloc(uidoc->mempool, sizeof(UiVar));
224 newvar->isextern = 1;
225 newvar->type = type;
226 newvar->value = value;
227 newvar->from = NULL;
228
229 uic_document_addvar_v(uidoc, name, newvar, type, vs);
230 }
231
232 void uic_var_move(UiVar *from, UiVar *to, int set) {
233 switch(from->type) {
234 case UI_VAR_INTEGER: {
235 //memcpy(to->value, from->value, sizeof(UiInteger));
236 UiInteger *f = from->value;
237 UiInteger *t = to->value;
238 t->get = f->get;
239 t->set = f->set;
240 t->obj = f->obj;
241 if(set) {
242 t->set(t, t->value);
243 } else {
244 //t->value = t->get(t);
245 f->value = f->get(f);
246 //t->value = 0;
247 }
248 break;
249 }
250 case UI_VAR_STRING: {
251 // TODO
252 break;
253 }
254 case UI_VAR_TEXT: {
255 UiText *f = from->value;
256 UiText *t = to->value;
257 char *tvalue = t->value;
258 memcpy(t, f, sizeof(UiText));
259 if(set) {
260 t->set(t, tvalue);
261 } else {
262 f->value = f->get(f);
263 }
264 break;
265 }
266 case UI_VAR_LIST: {
267 UiListVar *f = from->value;
268 UiListVar *t = to->value;
269 UiList *list = t->listptr->list;
270 UiObserver *observers = f->listptr->list->observers;
271 t->listptr = f->listptr;
272 if(set) {
273 t->listptr->list = list;
274 list->observers = observers;
275 ui_notify(observers, list);
276 }
277 break;
278 }
279 } 176 }
280 } 177 }
281 178
282 void ui_document_addint(void *doc, char *name) { 179 void ui_document_addint(void *doc, char *name) {
283 uic_document_addvar(doc, name, UI_VAR_INTEGER, sizeof(UiInteger)); 180 uic_document_addvar(doc, name, UI_VAR_INTEGER, sizeof(UiInteger));
284 } 181 }
285 182
183
184
286 void ui_document_regint(void *doc, char *name, UiInteger *i) { 185 void ui_document_regint(void *doc, char *name, UiInteger *i) {
287 uic_document_regvar(doc, name, UI_VAR_INTEGER, sizeof(UiInteger), i); 186 UiContext *ctx = ui_document_context(doc);
187 if(ctx) {
188 uic_reg_var(ctx, name, UI_VAR_INTEGER, sizeof(UiInteger), i);
189 }
288 } 190 }
289 191
290 void ui_document_regtext(void *doc, char *name, UiText *text) { 192 void ui_document_regtext(void *doc, char *name, UiText *text) {
291 uic_document_regvar(doc, name, UI_VAR_TEXT, sizeof(UiText), text); 193 UiContext *ctx = ui_document_context(doc);
194 if(ctx) {
195 uic_reg_var(doc, name, UI_VAR_TEXT, sizeof(UiText), text);
196 }
292 } 197 }
293 198
294 void ui_document_reglist(void *doc, char *name, UiList *list) { 199 void ui_document_reglist(void *doc, char *name, UiList *list) {
295 UiListVar *lv = ui_document_malloc(doc, sizeof(UiListVar)); 200 UiContext *ctx = ui_document_context(doc);
296 UiListPtr *lp = ui_document_malloc(doc, sizeof(UiListPtr)); 201 if(ctx) {
297 lv->listptr = lp; 202 UiListVar *lv = ui_document_malloc(doc, sizeof(UiListVar));
298 lp->list = list; 203 UiListPtr *lp = ui_document_malloc(doc, sizeof(UiListPtr));
299 uic_document_regvar(doc, name, UI_VAR_LIST, sizeof(UiListPtr), lv); 204 lv->listptr = lp;
300 } 205 lp->list = list;
206 uic_reg_var(doc, name, UI_VAR_LIST, sizeof(UiListPtr), lv);
207 }
208 }

mercurial