using cache in build_file, ui metaprogram and generating stacks

This commit is contained in:
Krzosa Karol
2025-01-19 21:35:01 +01:00
parent b90656508b
commit 887eb72fa0
14 changed files with 308 additions and 91 deletions

76
src/ui/ui.meta.c Normal file
View File

@@ -0,0 +1,76 @@
void mt_ui(ma_arena_t *arena) {
typedef struct cg_ui_stacks_t cg_ui_stacks_t;
struct cg_ui_stacks_t {
s8_t type;
s8_t name;
b32 skip_box_member;
s8_t stack;
s8_t node;
};
cg_ui_stacks_t stacks[] = {
{s8_lit("ui_id_t") , s8_lit("id") , .skip_box_member = true} ,
{s8_lit("ui_lop_t") , s8_lit("lop") , .skip_box_member = true} ,
{s8_lit("f32") , s8_lit("border_thickness")} ,
{s8_lit("ui_text_align_t") , s8_lit("text_align")} ,
{s8_lit("f32") , s8_lit("required_width")} ,
{s8_lit("f32") , s8_lit("required_height")} ,
{s8_lit("v2f32_t") , s8_lit("padding")} ,
};
///////////////////////////////
// fill stack and node
for (cg_ui_stacks_t *it = stacks; it < stacks + lengthof(stacks); it += 1) {
s8_t core_type = it->type;
if (s8_ends_with(core_type, s8_lit("_t"), false)) core_type = s8_chop(core_type, 2);
it->stack = s8_printf(arena, "%S_stack", it->name);
it->node = s8_printf(arena, "%S_node_t", core_type);
if (!s8_starts_with(it->node, s8_lit("ui_"), false)) it->node = s8_printf(arena, "ui_%S", it->node);
}
sb8_t *h_sb = sb8_serial_begin(arena);
sb8_t *c_sb = sb8_serial_begin(arena);
///////////////////////////////
// generate types
for (cg_ui_stacks_t *it = stacks; it < stacks + lengthof(stacks); it += 1) {
for (cg_ui_stacks_t *jt = it - 1; jt >= stacks; jt -= 1) if (s8_are_equal(it->type, jt->type)) goto type_already_gened;
sb8_stmtf(h_sb, "typedef struct %S %S; struct %S { %S value; %S *next; };", it->node, it->node, it->node, it->type, it->node);
type_already_gened:;
}
sb8_printf(h_sb, "\n");
///////////////////////////////
// generate field embeds
sb8_stmtf(h_sb, "#define UI_DECL_BOX_MEMBERS \\");
for (cg_ui_stacks_t *it = stacks; it < stacks + lengthof(stacks); it += 1) {
if (it->skip_box_member) continue;
sb8_stmtf(h_sb, "%S %S;\\", it->type, it->name);
}
sb8_printf(h_sb, "\n");
sb8_stmtf(h_sb, "#define UI_DECL_STACKS \\");
for (cg_ui_stacks_t *it = stacks; it < stacks + lengthof(stacks); it += 1) {
sb8_stmtf(h_sb, "%S *%S;\\", it->node, it->stack);
}
sb8_printf(h_sb, "\n");
///////////////////////////////
// generate stack functions
for (cg_ui_stacks_t *it = stacks; it < stacks + lengthof(stacks); it += 1) {
sb8_stmtf(c_sb, "fn void ui_push_%S(%S v) { %S *n = ma_push_type(tcx.temp, %S); n->value = v; SLLS_PUSH(ui->%S, n); }", it->name, it->type, it->node, it->node, it->stack);
sb8_stmtf(c_sb, "fn void ui_pop_%S(void) { SLLS_POP(ui->%S); }", it->name, it->stack);
sb8_stmtf(c_sb, "#define ui_set_%S(x) defer_block(ui_push_%S(x), ui_pop_%S())", it->name, it->name, it->name);
}
sb8_stmtf(c_sb, "fn void ui_assert_stacks_are_null(void) {");
for (cg_ui_stacks_t *it = stacks; it < stacks + lengthof(stacks); it += 1) {
sb8_stmtf(c_sb, "assert(ui->%S == NULL);", it->stack);
}
sb8_stmtf(c_sb, "}");
os_write_file(cg_cpath(arena), sb8_serial_end(arena, c_sb));
os_write_file(cg_hpath(arena), sb8_serial_end(arena, h_sb));
}