36 |
36 |
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_document_create(UiObject *obj, size_t size) { |
41 void ui_set_document(UiObject *obj, void *document) { |
|
42 UiDocument *doc = ucx_map_get(documents, ucx_key(&document, sizeof(void*))); |
|
43 if(!doc) { |
|
44 return; |
|
45 } |
|
46 doc->obj = obj; |
|
47 |
|
48 if(obj->document) { |
|
49 ui_detach_document(obj, obj->document); |
|
50 } |
|
51 obj->document = document; |
|
52 |
|
53 UcxMapIterator i = ucx_map_iterator(doc->vars); |
|
54 UiVar *var; |
|
55 UCX_MAP_FOREACH(key, var, i) { |
|
56 UiVar *v = ucx_map_get(obj->ctx->vars, key); |
|
57 if(v) { |
|
58 if(v->isextern) { |
|
59 fprintf( |
|
60 stderr, |
|
61 "UI Error: external variable cannot be moved\n"); |
|
62 return; |
|
63 } |
|
64 // check type |
|
65 if(var->type != v->type) { |
|
66 fprintf(stderr, "UI Error: var has incompatible type.\n"); |
|
67 return; |
|
68 } |
|
69 |
|
70 // copy value |
|
71 uic_var_move(v, var, 1); |
|
72 var->from = v->from; |
|
73 |
|
74 // TODO: free var struct |
|
75 ucx_map_remove(obj->ctx->vars, key); |
|
76 } |
|
77 } |
|
78 |
|
79 } |
|
80 |
|
81 void ui_detach_document(UiObject *obj, void *document) { |
|
82 UiDocument *doc = ucx_map_get(documents, ucx_key(&document, sizeof(void*))); |
|
83 if(!doc) { |
|
84 return; |
|
85 } |
|
86 |
|
87 UcxMapIterator i = ucx_map_iterator(doc->vars); |
|
88 UiVar *var; |
|
89 UCX_MAP_FOREACH(key, var, i) { |
|
90 if(var->from && var->from != doc->vars) { |
|
91 // this var is bind to an outer widget, so we move it |
|
92 UcxAllocator *a = var->from->allocator; |
|
93 UiVar *newvar = a->malloc(a->pool, sizeof(UiVar)); |
|
94 newvar->value = uic_create_value(a, var->type); |
|
95 uic_var_move(var, newvar, 0); |
|
96 newvar->type = var->type; |
|
97 newvar->from = var->from; |
|
98 newvar->isextern = 0; |
|
99 |
|
100 ucx_map_put(var->from, key, newvar); |
|
101 |
|
102 //ucx_map_remove(doc->vars, key); // TODO: dont remove! |
|
103 } |
|
104 } |
|
105 |
|
106 doc->obj->document = NULL; |
|
107 doc->obj = NULL; |
|
108 } |
|
109 |
|
110 void* ui_document_new(size_t size) { |
42 UcxMempool *mp = ucx_mempool_new(256); |
111 UcxMempool *mp = ucx_mempool_new(256); |
43 UiDocument *uidoc = ucx_mempool_malloc(mp, sizeof(UiDocument)); |
112 UiDocument *uidoc = ucx_mempool_malloc(mp, sizeof(UiDocument)); |
44 uidoc->obj = obj; |
113 uidoc->obj = NULL; |
45 uidoc->allocator = ucx_mempool_allocator(mp); |
|
46 uidoc->mempool = mp; |
114 uidoc->mempool = mp; |
47 uidoc->vars = ucx_map_new_a(uidoc->allocator, 16); |
115 uidoc->vars = ucx_map_new_a(mp->allocator, 16); |
|
116 uidoc->subdocument = NULL; |
48 |
117 |
49 void *document = ucx_mempool_calloc(mp, 1, size); |
118 void *document = ucx_mempool_calloc(mp, 1, size); |
50 ucx_map_put(documents, ucx_key(&document, sizeof(void*)), uidoc); |
119 ucx_map_put(documents, ucx_key(&document, sizeof(void*)), uidoc); |
51 return document; |
120 return document; |
52 } |
121 } |
73 void* ui_document_realloc(void *doc, void *ptr, size_t size) { |
142 void* ui_document_realloc(void *doc, void *ptr, size_t size) { |
74 UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); |
143 UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); |
75 return ucx_mempool_realloc(uidoc->mempool, ptr, size); |
144 return ucx_mempool_realloc(uidoc->mempool, ptr, size); |
76 } |
145 } |
77 |
146 |
|
147 UiDocument* uic_getdocument(void *doc) { |
|
148 return doc ? ucx_map_get(documents, ucx_key(&doc, sizeof(void*))) : NULL; |
|
149 } |
78 |
150 |
79 UiVar* uic_document_getvar(UiDocument *doc, char *name) { |
151 UiVar* uic_document_getvar(UiDocument *doc, char *name) { |
80 return ucx_map_cstr_get(doc->vars, 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) { |
|
156 UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); |
|
157 if(!uidoc) { |
|
158 return; |
|
159 } |
|
160 |
|
161 UiVar *newvar = ucx_mempool_malloc(uidoc->mempool, sizeof(UiVar)); |
|
162 newvar->isextern = 0; |
|
163 newvar->type = type; |
|
164 newvar->value = ucx_mempool_calloc(uidoc->mempool, 1, vs); |
|
165 newvar->from = NULL; |
|
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 //t->value = 0; |
|
246 } |
|
247 break; |
|
248 } |
|
249 case UI_VAR_STRING: { |
|
250 break; |
|
251 } |
|
252 } |
81 } |
253 } |
82 |
254 |
83 void ui_document_addint(void *doc, char *name) { |
255 void ui_document_addint(void *doc, char *name) { |
84 UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); |
256 uic_document_addvar(doc, name, UI_VAR_INTEGER, sizeof(UiInteger)); |
85 if(!uidoc) { |
|
86 return; |
|
87 } |
|
88 |
|
89 UiVar *dvar = uic_document_getvar(uidoc, name); |
|
90 UiVar *wvar = uic_getvar(uidoc->obj, name); |
|
91 if(!dvar) { |
|
92 UiVar *var = ucx_mempool_malloc(uidoc->mempool, sizeof(UiVar)); |
|
93 var->isextern = 0; |
|
94 var->type = 1; |
|
95 UiInteger *i = ucx_mempool_calloc(uidoc->mempool, 1, sizeof(UiVar)); |
|
96 if(wvar && !wvar->isextern) { |
|
97 *i = *(UiInteger*)wvar->value; |
|
98 } |
|
99 } |
|
100 |
|
101 if(wvar && wvar->isextern) { |
|
102 fprintf(stderr, "UI Error: window variable moved to document!\n"); |
|
103 } |
|
104 uic_rmvar(uidoc->obj, name); |
|
105 } |
257 } |
106 |
258 |
107 void ui_document_regint(void *doc, char *name, UiInteger *i) { |
259 void ui_document_regint(void *doc, char *name, UiInteger *i) { |
108 |
260 uic_document_regvar(doc, name, UI_VAR_INTEGER, sizeof(UiInteger), i); |
109 } |
261 } |
110 |
262 |
111 void ui_document_setint(void *doc, char *name, int val) { |
|
112 |
|
113 } |
|
114 |
|
115 int ui_document_getint(void *doc, char *name) { |
|
116 |
|
117 } |
|