148 UiVar* uic_create_var(UiContext *ctx, char *name, UiVarType type) { |
148 UiVar* uic_create_var(UiContext *ctx, char *name, UiVarType type) { |
149 // check if this context has a var with this name |
149 // check if this context has a var with this name |
150 // otherweise add it to the bound map |
150 // otherweise add it to the bound map |
151 UiVar *cv = ucx_map_cstr_get(ctx->vars, name); |
151 UiVar *cv = ucx_map_cstr_get(ctx->vars, name); |
152 if(cv) { |
152 if(cv) { |
153 return cv; // I'm not sure if this can actually happen, lol |
153 if(cv->type == type) { |
|
154 return cv; |
|
155 } else { |
|
156 fprintf(stderr, "UiError: var '%s' already exists with different type\n", name); |
|
157 } |
|
158 } |
|
159 |
|
160 UiVar *var; |
|
161 if(ctx->bound) { |
|
162 var = ucx_map_cstr_get(ctx->bound, name); |
|
163 if(var) { |
|
164 if(var->type != type) { |
|
165 fprintf(stderr, "UiError: var '%s' already bound with different type\n", name); |
|
166 } else { |
|
167 return var; |
|
168 } |
|
169 } |
154 } |
170 } |
155 |
171 |
156 // create var and add it to the bound map |
172 // create var and add it to the bound map |
157 // this map contains vars that are created by widgets |
173 // this map contains vars that are created by widgets |
158 // the vars can later be moved to subdocuments |
174 // the vars can later be moved to subdocuments |
159 UiVar *var = ui_malloc(ctx, sizeof(UiVar)); |
175 var = ui_malloc(ctx, sizeof(UiVar)); |
160 var->type = type; |
176 var->type = type; |
161 var->value = uic_create_value(ctx, type); |
177 var->value = uic_create_value(ctx, type); |
162 var->orig_val = NULL; |
178 var->orig_val = NULL; |
163 var->from = NULL; // not connected to a doc var |
179 var->from = NULL; // not connected to a doc var |
164 |
180 |
165 if(!ctx->bound) { |
181 if(!ctx->bound) { |
166 ctx->bound = ucx_map_new_a(ctx->mempool->allocator, 16); |
182 ctx->bound = ucx_map_new_a(ctx->mempool->allocator, 16); |
167 } |
183 } |
168 size_t oldcount = ctx->bound->count; |
|
169 ucx_map_cstr_put(ctx->bound, name, var); |
184 ucx_map_cstr_put(ctx->bound, name, var); |
170 if(ctx->bound->count != oldcount + 1) { |
|
171 fprintf(stderr, "UiError: var '%s' already bound\n", name); |
|
172 } |
|
173 |
185 |
174 // if a subdocument has a variable with this name, we must copy |
186 // if a subdocument has a variable with this name, we must copy |
175 // the binding to the doc var |
187 // the binding to the doc var |
176 UiContext *doc_ctx = ui_document_context(ctx->document); |
188 UiContext *doc_ctx = ui_document_context(ctx->document); |
177 if(doc_ctx) { |
189 if(doc_ctx) { |
232 case UI_VAR_SPECIAL: break; |
244 case UI_VAR_SPECIAL: break; |
233 case UI_VAR_INTEGER: { |
245 case UI_VAR_INTEGER: { |
234 UiInteger *f = from->value; |
246 UiInteger *f = from->value; |
235 UiInteger *t = to->value; |
247 UiInteger *t = to->value; |
236 uic_int_copy(f, t); |
248 uic_int_copy(f, t); |
237 if(t->value != 0) { |
249 t->set(t, t->value); |
238 t->set(t, t->value); |
|
239 } |
|
240 break; |
250 break; |
241 } |
251 } |
242 case UI_VAR_STRING: { |
252 case UI_VAR_STRING: { |
243 UiString *f = from->value; |
253 UiString *f = from->value; |
244 UiString *t = to->value; |
254 UiString *t = to->value; |