From 729888b9d9ba115cb5993dbe79fd6df039cd8c6c Mon Sep 17 00:00:00 2001 From: Timerix22 Date: Wed, 24 May 2023 08:01:26 +0600 Subject: [PATCH] grid deserialization --- src/TUI/Dtsod/tui_dtsod.c | 25 ++++++--- src/TUI/Dtsod/tui_dtsod.h | 5 +- src/TUI/Grid.c | 115 ++++++++++++++++++++++++++------------ src/TUI/tui.c | 15 +++-- src/TUI/tui.h | 37 ++++++++++-- src/TUI/tui_internal.h | 2 +- view/example.tui.dtsod | 4 +- view/main.tui.dtsod | 4 +- 8 files changed, 146 insertions(+), 61 deletions(-) diff --git a/src/TUI/Dtsod/tui_dtsod.c b/src/TUI/Dtsod/tui_dtsod.c index da6d3c5..1f0f20e 100644 --- a/src/TUI/Dtsod/tui_dtsod.c +++ b/src/TUI/Dtsod/tui_dtsod.c @@ -106,38 +106,45 @@ UI_Maybe UIDtsodParser_constructUIContext(UIDtsodParser* parser){ char* file_namespace; Dtsod_tryGet_cptr(fm.dtsod, "namespace", file_namespace, true); - Hashtable_foreach(fm.dtsod, dtsod_elem, if(cptr_compare(dtsod_elem.key, "ui")) { Autoarr_Unitype* ui_ar=dtsod_elem.value.VoidPtr; Autoarr_foreach(ui_ar, ui_el_dtsod, UI_try(UIElement_deserialize(ui_el_dtsod.VoidPtr),_m_ui,;); UIElement_Ptr new_el=_m_ui.value.VoidPtr; + // kprintf("[UIDtsodParser_constructUIContext] %s : %s\n", new_el->name, new_el->ui_type->type->name); + if(new_el->ui_type->type->id==ktid_ptrName(Grid)){ + UI_try(_Grid_bindContent((Grid*)new_el, parser->context),_15151,;); + } UI_try( UIContext_add(parser->context, file_namespace, new_el), _a76515, ;); ); } ); ); + Autoarr_free(parser->file_models,true); + parser->file_models=Autoarr_create(UIDtsodFileModel, 64, 32); parser->returned_context=true; return SUCCESS(UniHeapPtr(UIContext, parser->context)); } -UI_Maybe _UIContext_get(UIContext* context, char* name, ktid type_id){ +UI_Maybe UIContext_getAny(UIContext* context, char* name){ Unitype val; // check name - if(!Hashtable_tryGet(context->ui_elements, name, &val)){ + if(!Hashtable_tryGet(context->ui_elements, name, &val)) UI_safethrow_msg(cptr_concat("can't get <", name, "> from context"), ;); - } - // check type - UIElement* ptr=val.VoidPtr; - if(val.typeId != type_id) + return SUCCESS(val); +} + +UI_Maybe _UIContext_get(UIContext* context, char* name, ktid type_id){ + UI_try(UIContext_getAny(context, name), _m_ui, ;); + UIElement* ptr=_m_ui.value.VoidPtr; + if(ptr->ui_type->type->id != type_id) UI_safethrow_msg(cptr_concat( "tried to get ",ktDescriptor_get(type_id)->name, " <",name,"> but it is of type ", ptr->ui_type->type->name ), ;); - - return SUCCESS(val); + return _m_ui; } UI_Maybe UIContext_add(UIContext* context, char* namespace, _UIElement_Ptr _new_el){ diff --git a/src/TUI/Dtsod/tui_dtsod.h b/src/TUI/Dtsod/tui_dtsod.h index efe62af..0c7f8c9 100644 --- a/src/TUI/Dtsod/tui_dtsod.h +++ b/src/TUI/Dtsod/tui_dtsod.h @@ -48,11 +48,14 @@ typedef struct UIContext UIContext; void UIContext_destroy(UIContext* u); + +UI_Maybe UIContext_getAny(UIContext* context, char* name); + ///@return UI_Maybe UI_THROWING_FUNC_DECL(_UIContext_get(UIContext* context, char* name, ktid type_id)); #define UIContext_get(CONTEXT, NAMESPACE, NAME, TYPE, FREECALLS_ON_ERROR) \ UI_try( \ - _UIContext_get(CONTEXT, #NAMESPACE "_" #NAME, ktid_name(TYPE)), \ + _UIContext_get(CONTEXT, #NAMESPACE "_" #NAME, ktid_ptrName(TYPE)), \ _m_##NAMESPACE##_##NAME, \ FREECALLS_ON_ERROR); \ TYPE* NAMESPACE##_##NAME=_m_##NAMESPACE##_##NAME.value.VoidPtr; diff --git a/src/TUI/Grid.c b/src/TUI/Grid.c index 6f36488..a1128ae 100644 --- a/src/TUI/Grid.c +++ b/src/TUI/Grid.c @@ -1,29 +1,58 @@ #include "tui_internal.h" -static inline UIElement_Ptr* _Grid_getPtr(Grid* grid, u16 column, u16 row){ - if(row >= grid->rows) - throw(ERR_WRONGINDEX); - if(column >= grid->columns) - throw(ERR_WRONGINDEX); - return grid->content + grid->columns*row + column; +#define grid_validate() \ + if(row >= grid->rows) UI_safethrow(UIError_InvalidY,;); \ + if(column >= grid->columns) UI_safethrow(UIError_InvalidX,;); + +UI_Maybe Grid_set(Grid* grid, u16 column, u16 row, UIElement_Ptr value){ + grid_validate(); + UIElement_Ptr* ptr_ptr = grid->content + grid->columns*row + column; + *ptr_ptr=value; + return MaybeNull; } -UIElement_Ptr Grid_get(Grid* grid, u16 column, u16 row){ - return *_Grid_getPtr(grid, column, row); +UI_Maybe Grid_get(Grid* grid, u16 column, u16 row){ + grid_validate(); + UIElement_Ptr* ptr_ptr = grid->content + grid->columns*row + column; + return SUCCESS(UniHeapPtr(UIElement, *ptr_ptr)); } -void Grid_set(Grid* grid, u16 column, u16 row, UIElement_Ptr value){ - *_Grid_getPtr(grid, column, row)=value; +UI_Maybe _Grid_getName(Grid* grid, u16 column, u16 row) { + grid_validate(); + char** str_ptr = grid->content_names + grid->columns*row + column; + return SUCCESS(UniHeapPtr(char, *str_ptr)); +} + +UI_Maybe _Grid_bindContent(Grid* grid, UIContext* context) { + Autoarr(UIElement_Ptr)* content=Autoarr_create(UIElement_Ptr, 64, 16); + Grid_foreachName(grid, name, + UI_try(UIContext_getAny(context, name), m_uie, Autoarr_freeWithoutMembers(content,true)); + UIElement_Ptr uie=m_uie.value.VoidPtr; + Autoarr_add(content, uie); + ); + free(grid->content_names); + grid->content_names=NULL; + grid->content=Autoarr_toArray(content); + Autoarr_freeWithoutMembers(content, true); + return MaybeNull; } void Grid_freeMembers(void* _self){ Grid* self=(Grid*)_self; - Grid_foreach(self, el, - // if(el==NULL) - // throw(ERR_NULLPTR); - UIElement_destroy(el); - ); + if(self->is_bound){ + for(u16 r = 0; r < self->rows; r++){ + for(u16 c = 0; c < self->columns; c++){ + tryLast(Grid_get(self, c, r), m_el, + free(self->content); + free(self->content_names)); + UIElement_Ptr el=m_el.value.VoidPtr; + UIElement_destroy(el); + } + } + } free(self->content); + if(self->content_names) + free(self->content_names); } UI_Maybe Grid_draw(Renderer* renderer, UIElement_Ptr _self, const DrawingArea area){ @@ -38,30 +67,44 @@ UI_Maybe Grid_draw(Renderer* renderer, UIElement_Ptr _self, const DrawingArea ar UI_Maybe Grid_deserialize(Dtsod* dtsod){ Grid gr; - Autoarr(UIElement_Ptr)* content=Autoarr_create(UIElement_Ptr, 64, 8); + Autoarr(Pointer)* content_names=Autoarr_create(Pointer, 64, 16); u16 columns=0, rows=0; UI_try(UIElement_deserializeBase(dtsod, &gr.base), _91875, ;); - /*Autoarr(Unitype)* _content; - Dtsod_tryGet_Autoarr(dtsod, "content", _content, true, { - Autoarr_foreach(_content, _row, - Autoarr(Unitype)* row=_row.VoidPtr; - Autoarr_foreach(row, _elem_d, - if(!UniCheckTypePtr(_elem_d,Hashtable)) - UI_safethrow_msg( - cptr_concat("expected type 'Hashtable', but have got type id '", - toString_i64(_elem_d.typeId),"'"), - Autoarr_freeWithoutMembers(content, true)); - Dtsod* elem_dtsod=_elem_d.VoidPtr; - UI_try(UIElement_deserialize(elem_dtsod), _m_uie, ;); - Autoarr_add(content, (UIElement_Ptr)_m_uie.value.VoidPtr); - ) - ); - });*/ - gr.content=Autoarr_toArray(content); - Autoarr_freeWithoutMembers(content, true); + Autoarr(Unitype)* _content; + Dtsod_tryGet_Autoarr(dtsod, "content", _content, true); + rows=Autoarr_length(_content); + Autoarr_foreach(_content, _row, + if(!UniCheckTypePtr(_row, Autoarr(Unitype))){ + UI_safethrow_msg( + cptr_concat("expected Autoarr, but has got type id '", + toString_i64(_row.typeId), "'"), + Autoarr_freeWithoutMembers(content_names, true)); + } + Autoarr(Unitype)* row=_row.VoidPtr; + u16 row_len=Autoarr_length(row); + if(columns==0) + columns=row_len; + else if(row_len != columns) + UI_safethrow_msg("wrong grid row size",;); + Autoarr_foreach(row, _elem_d, + if(!UniCheckTypePtr(_elem_d, char)){ + UI_safethrow_msg( + cptr_concat("expected char*, but has got type id '", + toString_i64(_elem_d.typeId),"'"), + Autoarr_freeWithoutMembers(content_names, true)); + } + char* elem_name=_elem_d.VoidPtr; + Autoarr_add(content_names, elem_name); + ) + ); + + gr.content_names=(char**)Autoarr_toArray(content_names); + Autoarr_freeWithoutMembers(content_names, true); gr.columns=columns; gr.rows=rows; + gr.is_bound=false; + gr.content=NULL; Grid* ptr=malloc(sizeof(*ptr)); *ptr=gr; @@ -77,7 +120,9 @@ Grid* Grid_create(char* name, u16 columns, u16 rows, UIElement_Ptr* content){ .base=_UIElement_initBaseDefault(name, &UITDescriptor_Grid), .columns=columns, .rows=rows, - .content=content + .content=content, + .content_names=NULL, + .is_bound=true }; return grid; } diff --git a/src/TUI/tui.c b/src/TUI/tui.c index 667da72..b440c6c 100644 --- a/src/TUI/tui.c +++ b/src/TUI/tui.c @@ -5,14 +5,14 @@ kt_define(DrawingArea, NULL, NULL); kt_define(UIBorder, NULL, NULL); kt_define(UITDescriptor, NULL, NULL); -Hashtable* __uit_hashtable=NULL; +Hashtable* _uit_hashtable=NULL; u32 __kt_id_first=-1; Autoarr(Pointer)* __uit_temp_arr=NULL; UITDescriptor** __uit_descriptors=NULL; /// call this between kt_beginInit() and kt_endInit() void kt_beginInitTUI(){ - __uit_hashtable=Hashtable_create(); + _uit_hashtable=Hashtable_create(); __kt_id_first=ktid_last; __uit_temp_arr=Autoarr_create(Pointer, 32, 32); } @@ -25,12 +25,12 @@ void kt_endInitTUI(){ void kt_freeTUI(){ free(__uit_descriptors); - Hashtable_free(__uit_hashtable); + Hashtable_free(_uit_hashtable); } void __uit_register(ktDescriptor* kt, UITDescriptor* uit){ uit->type=kt; - Hashtable_add(__uit_hashtable, cptr_copy(kt->name), UniStackPtr(UITDescriptor, uit)); + Hashtable_add(_uit_hashtable, cptr_copy(kt->name), UniStackPtr(UITDescriptor, uit)); } UITDescriptor* UITDescriptor_getById(ktid id){ @@ -43,7 +43,12 @@ UITDescriptor* UITDescriptor_getById(ktid id){ ///@return NULL if not found UITDescriptor* UITDescriptor_getByName(char* name){ - Unitype val=Hashtable_get(__uit_hashtable, name); + Unitype val=Hashtable_get(_uit_hashtable, name); + if(Unitype_isUniNull(val)){ + char* name_ptr=cptr_concat(name,"_Ptr"); + val=Hashtable_get(_uit_hashtable, name_ptr); + free(name_ptr); + } return val.VoidPtr; } diff --git a/src/TUI/tui.h b/src/TUI/tui.h index 3c0e027..ce686b2 100644 --- a/src/TUI/tui.h +++ b/src/TUI/tui.h @@ -154,18 +154,43 @@ STRUCT(Grid, UIElement base; u16 columns; u16 rows; + bool is_bound; + char** content_names; UIElement_Ptr* content; /* UIElement[rows][columns] */ ) uit_declare(Grid); Grid* Grid_create(char* name, u16 columns, u16 rows, UIElement_Ptr* content); -UIElement_Ptr Grid_get(Grid* grid, u16 column, u16 row); -void Grid_set(Grid* grid, u16 column, u16 row, UIElement_Ptr value); +///@return Maybe +UI_THROWING_FUNC_DECL( Grid_get(Grid* grid, u16 column, u16 row) ); +///@return maybe +UI_THROWING_FUNC_DECL( Grid_set(Grid* grid, u16 column, u16 row, UIElement_Ptr value)); +///@return Maybe +UI_THROWING_FUNC_DECL( _Grid_getName(Grid* grid, u16 column, u16 row) ); +///@return maybe +UI_THROWING_FUNC_DECL( _Grid_bindContent(Grid* grid, UIContext* context) ); -#define Grid_foreach(GRID_PTR, ELEM_VAR_NAME, CODE...) { \ - for(u16 _g_r = 0; _g_r < GRID_PTR->rows; _g_r++){ \ - for(u16 _g_c = 0; _g_c < GRID_PTR->columns; _g_c++){ \ - UIElement_Ptr ELEM_VAR_NAME = Grid_get(GRID_PTR, _g_c, _g_r); \ +#define Grid_foreach(GRID, ELEM_VAR_NAME, CODE...) { \ + if(!GRID->is_bound) \ + UI_safethrow_msg(cptr_concat("grid '", GRID->base.ui_type->type->name, \ + "' content has not been bound"),;); \ + for(u16 _g_r = 0; _g_r < GRID->rows; _g_r++){ \ + for(u16 _g_c = 0; _g_c < GRID->columns; _g_c++){ \ + UI_try(Grid_get(GRID, _g_c, _g_r), _m_g_el,;); \ + UIElement_Ptr ELEM_VAR_NAME=_m_g_el.value.VoidPtr; \ + { CODE; } \ + } \ + } \ +} + +#define Grid_foreachName(GRID, ELEM_VAR_NAME, CODE...) { \ + if(GRID->is_bound) \ + UI_safethrow_msg(cptr_concat("grid '", GRID->base.ui_type->type->name, \ + "' content has been already bound"),;); \ + for(u16 _g_r = 0; _g_r < GRID->rows; _g_r++){ \ + for(u16 _g_c = 0; _g_c < GRID->columns; _g_c++){ \ + UI_try(_Grid_getName(GRID, _g_c, _g_r), _m_g_nm,;); \ + char* ELEM_VAR_NAME=_m_g_nm.value.VoidPtr; \ { CODE; } \ } \ } \ diff --git a/src/TUI/tui_internal.h b/src/TUI/tui_internal.h index 044645b..1f8880c 100644 --- a/src/TUI/tui_internal.h +++ b/src/TUI/tui_internal.h @@ -22,7 +22,7 @@ extern termchar UIBorder_char_lb[4][4]; /// extended kt_register void __uit_register(ktDescriptor* kt, UITDescriptor* uit); -#define uit_register(TYPE) kt_register(TYPE); __uit_register(&ktDescriptor_##TYPE, &UITDescriptor_##TYPE) +#define uit_register(TYPE) kt_register(TYPE); __uit_register(&ktDescriptor_##TYPE##_Ptr, &UITDescriptor_##TYPE) void UI_enum_tables_init(); diff --git a/view/example.tui.dtsod b/view/example.tui.dtsod index bc5ee51..c3c1b9a 100644 --- a/view/example.tui.dtsod +++ b/view/example.tui.dtsod @@ -26,7 +26,7 @@ $ui: { type: "Grid", content: [ # column - [ "@UIElement" ], # row - [ "@namespace.element1" ], # row + [ "example_textblock" ], # row + [ "example_textblock" ], # row ]; }; diff --git a/view/main.tui.dtsod b/view/main.tui.dtsod index f1e6ca3..13fb061 100644 --- a/view/main.tui.dtsod +++ b/view/main.tui.dtsod @@ -6,7 +6,7 @@ $ui: { type: "Grid", content: [ # column - [ "@namespace.element0" ], # row - [ "@namespace.element1" ], # row +# [ "namespace.element0" ], # row +# [ "namespace.element1" ], # row ]; };