grid deserialization

This commit is contained in:
Timerix22 2023-05-24 08:01:26 +06:00
parent e48f7cd6b5
commit 729888b9d9
8 changed files with 146 additions and 61 deletions

View File

@ -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){

View File

@ -48,11 +48,14 @@ typedef struct UIContext UIContext;
void UIContext_destroy(UIContext* u);
UI_Maybe UIContext_getAny(UIContext* context, char* name);
///@return UI_Maybe<UIElement*>
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;

View File

@ -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<Unitype>, 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;
}

View File

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

View File

@ -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<UIElement*>
UI_THROWING_FUNC_DECL( Grid_get(Grid* grid, u16 column, u16 row) );
///@return maybe<void>
UI_THROWING_FUNC_DECL( Grid_set(Grid* grid, u16 column, u16 row, UIElement_Ptr value));
///@return Maybe<char*>
UI_THROWING_FUNC_DECL( _Grid_getName(Grid* grid, u16 column, u16 row) );
///@return maybe<void>
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; } \
} \
} \

View File

@ -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();

View File

@ -26,7 +26,7 @@ $ui: {
type: "Grid",
content: [
# column
[ "@UIElement" ], # row
[ "@namespace.element1" ], # row
[ "example_textblock" ], # row
[ "example_textblock" ], # row
];
};

View File

@ -6,7 +6,7 @@ $ui: {
type: "Grid",
content: [
# column
[ "@namespace.element0" ], # row
[ "@namespace.element1" ], # row
# [ "namespace.element0" ], # row
# [ "namespace.element1" ], # row
];
};