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 } |