From 50000c0d6bbd627febf41da628217dd8389738a6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 23 Jan 2025 11:39:55 -0800 Subject: [PATCH] adjust metagen to support correctly-escaped multiline string generations; sketch out setting schemas; eliminate old settings hack, move to using cfg tree & settings schema --- src/lib_rdi_format/rdi_format.h | 2 +- src/metagen/metagen.c | 26 +- src/metagen/metagen_base/metagen_base_arena.c | 77 +- src/metagen/metagen_base/metagen_base_arena.h | 19 +- .../metagen_base/metagen_base_command_line.c | 24 +- .../metagen_base/metagen_base_command_line.h | 2 + .../metagen_base_context_cracking.h | 6 +- src/metagen/metagen_base/metagen_base_core.c | 114 ++- src/metagen/metagen_base/metagen_base_core.h | 160 ++++- .../metagen_base/metagen_base_entry_point.c | 78 ++- .../metagen_base/metagen_base_entry_point.h | 4 +- src/metagen/metagen_base/metagen_base_inc.c | 5 +- src/metagen/metagen_base/metagen_base_inc.h | 1 + src/metagen/metagen_base/metagen_base_log.c | 2 +- src/metagen/metagen_base/metagen_base_math.c | 61 +- src/metagen/metagen_base/metagen_base_math.h | 26 + src/metagen/metagen_base/metagen_base_meta.c | 422 +++++++++++ src/metagen/metagen_base/metagen_base_meta.h | 298 ++++++++ .../metagen_base/metagen_base_profile.h | 50 +- .../metagen_base/metagen_base_strings.c | 661 +++++++++++++++--- .../metagen_base/metagen_base_strings.h | 39 +- .../metagen_base_thread_context.h | 2 +- src/metagen/metagen_main.c | 18 +- .../core/win32/metagen_os_core_win32.c | 2 +- src/raddbg/generated/raddbg.meta.c | 124 +--- src/raddbg/generated/raddbg.meta.h | 31 +- src/raddbg/raddbg.mdesk | 167 +++-- src/raddbg/raddbg_core.c | 152 ++-- src/raddbg/raddbg_core.h | 11 +- src/raddbg/raddbg_views.c | 6 +- src/raddbg/raddbg_widgets.c | 14 +- src/rdi_format/rdi_format.mdesk | 2 +- 32 files changed, 2014 insertions(+), 592 deletions(-) create mode 100644 src/metagen/metagen_base/metagen_base_meta.c create mode 100644 src/metagen/metagen_base/metagen_base_meta.h diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index f440f03c..65f75c1e 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -50,7 +50,7 @@ typedef int64_t RDI_S64; //////////////////////////////////////////////////////////////// //~ Format Constants -// \"raddbg\0\0\" +// "raddbg\0\0" #define RDI_MAGIC_CONSTANT 0x0000676264646172 #define RDI_ENCODING_VERSION 10 diff --git a/src/metagen/metagen.c b/src/metagen/metagen.c index 4d68bf5a..33c4daa7 100644 --- a/src/metagen/metagen.c +++ b/src/metagen/metagen.c @@ -686,8 +686,8 @@ mg_string_from_row_desc_idx(MD_Node *row_parent, MG_ColumnDescArray descs, U64 i cell_idx -= 1; } } - MD_Node *node = md_child_from_index(row_parent, cell_idx); - result = node->string; + MD_Node *node = md_child_from_index(row_parent, cell_idx); + result = node->string; }break; case MG_ColumnKind_CheckForTag: @@ -828,8 +828,8 @@ mg_eval_table_expand_expr__string(Arena *arena, MG_StrExpr *expr, MG_TableExpand }break; case MG_StrExprOp_Null: - { - str8_list_push(arena, out, expr->node->string); + { + str8_list_push(arena, out, expr->node->string); }break; case MG_StrExprOp_Dot: @@ -900,7 +900,14 @@ mg_eval_table_expand_expr__string(Arena *arena, MG_StrExpr *expr, MG_TableExpand } // rjf: push lookup string - { + { + B32 is_multiline = (str8_find_needle(lookup_string, 0, str8_lit("\n"), 0) < lookup_string.size); + if(is_multiline) + { + lookup_string = indented_from_string(mg_arena, lookup_string); + lookup_string = escaped_from_raw_str8(mg_arena, lookup_string); + lookup_string = escaped_from_raw_str8(mg_arena, lookup_string); + } str8_list_push(arena, out, lookup_string); } }break; @@ -1010,9 +1017,10 @@ mg_loop_table_column_expansion(Arena *arena, String8 strexpr, MG_TableExpandInfo char_idx += 1; } } - String8 expansion_str = str8_list_join(arena, &expansion_strs, 0); + String8 expansion_str = str8_list_join(arena, &expansion_strs, 0); if(expansion_str.size != 0) - { + { + expansion_str = raw_from_escaped_str8(mg_arena, expansion_str); str8_list_push(arena, out, expansion_str); } } @@ -1028,7 +1036,7 @@ mg_string_list_from_table_gen(Arena *arena, MG_Map grid_name_map, MG_Map grid_co Temp scratch = scratch_begin(&arena, 1); if(md_node_is_nil(gen->first) && gen->string.size != 0) { - str8_list_push(arena, &result, gen->string); + str8_list_push(arena, &result, raw_from_escaped_str8(arena, gen->string)); str8_list_push(arena, &result, str8_lit("\n")); } else for MD_EachNode(strexpr_node, gen->first) @@ -1080,7 +1088,7 @@ mg_string_list_from_table_gen(Arena *arena, MG_Map grid_name_map, MG_Map grid_co } else { - str8_list_push(arena, &result, strexpr_node->string); + str8_list_push(arena, &result, raw_from_escaped_str8(arena, strexpr_node->string)); } } } diff --git a/src/metagen/metagen_base/metagen_base_arena.c b/src/metagen/metagen_base/metagen_base_arena.c index 28eb6e83..68ad2544 100644 --- a/src/metagen/metagen_base/metagen_base_arena.c +++ b/src/metagen/metagen_base/metagen_base_arena.c @@ -52,12 +52,16 @@ arena_alloc_(ArenaParams *params) Arena *arena = (Arena *)base; arena->current = arena; arena->flags = params->flags; - arena->cmt_size = (U32)params->commit_size; + arena->cmt_size = params->commit_size; arena->res_size = params->reserve_size; arena->base_pos = 0; arena->pos = ARENA_HEADER_SIZE; arena->cmt = commit_size; arena->res = reserve_size; +#if ARENA_FREE_LIST + arena->free_size = 0; + arena->free_last = 0; +#endif AsanPoisonMemoryRegion(base, commit_size); AsanUnpoisonMemoryRegion(base, ARENA_HEADER_SIZE); return arena; @@ -85,30 +89,67 @@ arena_push(Arena *arena, U64 size, U64 align) // rjf: chain, if needed if(current->res < pos_pst && !(arena->flags & ArenaFlag_NoChain)) { - U64 res_size = current->res_size; - U64 cmt_size = current->cmt_size; - if(size + ARENA_HEADER_SIZE > res_size) + Arena *new_block = 0; + +#if ARENA_FREE_LIST + Arena *prev_block; + for(new_block = arena->free_last, prev_block = 0; new_block != 0; prev_block = new_block, new_block = new_block->prev) { - res_size = size + ARENA_HEADER_SIZE; - cmt_size = size + ARENA_HEADER_SIZE; + if(new_block->res >= AlignPow2(size, align)) + { + if(prev_block) + { + prev_block->prev = new_block->prev; + } + else + { + arena->free_last = new_block->prev; + } + arena->free_size -= new_block->res_size; + AsanUnpoisonMemoryRegion((U8*)new_block + ARENA_HEADER_SIZE, new_block->res_size - ARENA_HEADER_SIZE); + break; + } } - Arena *new_block = arena_alloc(.reserve_size = res_size, - .commit_size = cmt_size, - .flags = current->flags); +#endif + + if(new_block == 0) + { + U64 res_size = current->res_size; + U64 cmt_size = current->cmt_size; + if(size + ARENA_HEADER_SIZE > res_size) + { + res_size = AlignPow2(size + ARENA_HEADER_SIZE, align); + cmt_size = AlignPow2(size + ARENA_HEADER_SIZE, align); + } + new_block = arena_alloc(.reserve_size = res_size, + .commit_size = cmt_size, + .flags = current->flags); + } + new_block->base_pos = current->base_pos + current->res; SLLStackPush_N(arena->current, new_block, prev); + current = new_block; pos_pre = AlignPow2(current->pos, align); pos_pst = pos_pre + size; } // rjf: commit new pages, if needed - if(current->cmt < pos_pst && !(current->flags & ArenaFlag_LargePages)) + if(current->cmt < pos_pst) { - U64 cmt_pst_aligned = AlignPow2(pos_pst, current->cmt_size); + U64 cmt_pst_aligned = pos_pst + current->cmt_size-1; + cmt_pst_aligned -= cmt_pst_aligned%current->cmt_size; U64 cmt_pst_clamped = ClampTop(cmt_pst_aligned, current->res); U64 cmt_size = cmt_pst_clamped - current->cmt; - os_commit((U8 *)current + current->cmt, cmt_size); + U8 *cmt_ptr = (U8 *)current + current->cmt; + if(current->flags & ArenaFlag_LargePages) + { + os_commit_large(cmt_ptr, cmt_size); + } + else + { + os_commit(cmt_ptr, cmt_size); + } current->cmt = cmt_pst_clamped; } @@ -146,11 +187,23 @@ arena_pop_to(Arena *arena, U64 pos) { U64 big_pos = ClampBot(ARENA_HEADER_SIZE, pos); Arena *current = arena->current; + +#if ARENA_FREE_LIST + for(Arena *prev = 0; current->base_pos >= big_pos; current = prev) + { + prev = current->prev; + current->pos = ARENA_HEADER_SIZE; + arena->free_size += current->res_size; + SLLStackPush_N(arena->free_last, current, prev); + AsanPoisonMemoryRegion((U8*)current + ARENA_HEADER_SIZE, current->res_size - ARENA_HEADER_SIZE); + } +#else for(Arena *prev = 0; current->base_pos >= big_pos; current = prev) { prev = current->prev; os_release(current, current->res); } +#endif arena->current = current; U64 new_pos = big_pos - current->base_pos; AssertAlways(new_pos <= current->pos); diff --git a/src/metagen/metagen_base/metagen_base_arena.h b/src/metagen/metagen_base/metagen_base_arena.h index f941bcd7..8696f49f 100644 --- a/src/metagen/metagen_base/metagen_base_arena.h +++ b/src/metagen/metagen_base/metagen_base_arena.h @@ -7,12 +7,12 @@ //////////////////////////////// //~ rjf: Constants -#define ARENA_HEADER_SIZE 64 +#define ARENA_HEADER_SIZE 128 //////////////////////////////// //~ rjf: Types -typedef U32 ArenaFlags; +typedef U64 ArenaFlags; enum { ArenaFlag_NoChain = (1<<0), @@ -34,12 +34,16 @@ struct Arena Arena *prev; // previous arena in chain Arena *current; // current arena in chain ArenaFlags flags; - U32 cmt_size; + U64 cmt_size; U64 res_size; U64 base_pos; U64 pos; U64 cmt; U64 res; +#if ARENA_FREE_LIST + U64 free_size; + Arena *free_last; +#endif }; StaticAssert(sizeof(Arena) <= ARENA_HEADER_SIZE, arena_header_size_check); @@ -50,12 +54,19 @@ struct Temp U64 pos; }; +//////////////////////////////// +//~ rjf: Global Defaults + +global U64 arena_default_reserve_size = MB(64); +global U64 arena_default_commit_size = KB(64); +global ArenaFlags arena_default_flags = 0; + //////////////////////////////// //~ rjf: Arena Functions //- rjf: arena creation/destruction internal Arena *arena_alloc_(ArenaParams *params); -#define arena_alloc(...) arena_alloc_(&(ArenaParams){.reserve_size = MB(64), .commit_size = KB(64), __VA_ARGS__}) +#define arena_alloc(...) arena_alloc_(&(ArenaParams){.reserve_size = arena_default_reserve_size, .commit_size = arena_default_commit_size, .flags = arena_default_flags, __VA_ARGS__}) internal void arena_release(Arena *arena); //- rjf: arena push/pop/pos core functions diff --git a/src/metagen/metagen_base/metagen_base_command_line.c b/src/metagen/metagen_base/metagen_base_command_line.c index ecf23745..ec726752 100644 --- a/src/metagen/metagen_base/metagen_base_command_line.c +++ b/src/metagen/metagen_base/metagen_base_command_line.c @@ -98,9 +98,10 @@ cmd_line_from_string_list(Arena *arena, String8List command_line) next = node->next; String8 option_name = node->string; - // NOTE(rjf): Look at -- or - at the start of an argument to determine if it's - // a flag option. All arguments after a single "--" (with no trailing string - // on the command line will be considered as input files. + // NOTE(rjf): Look at --, -, or / (only on Windows) at the start of an + // argument to determine if it's a flag option. All arguments after a + // single "--" (with no trailing string on the command line will be + // considered as input files. B32 is_option = 1; if(after_passthrough_option == 0) { @@ -117,6 +118,11 @@ cmd_line_from_string_list(Arena *arena, String8List command_line) { option_name = str8_skip(option_name, 1); } + else if(operating_system_from_context() == OperatingSystem_Windows && + str8_match(str8_prefix(node->string, 1), str8_lit("/"), 0)) + { + option_name = str8_skip(option_name, 1); + } else { is_option = 0; @@ -184,6 +190,18 @@ cmd_line_from_string_list(Arena *arena, String8List command_line) } } + // rjf: fill argc/argv + parsed.argc = command_line.node_count; + parsed.argv = push_array(arena, char *, parsed.argc); + { + U64 idx = 0; + for(String8Node *n = command_line.first; n != 0; n = n->next) + { + parsed.argv[idx] = (char *)push_str8_copy(arena, n->string).str; + idx += 1; + } + } + return parsed; } diff --git a/src/metagen/metagen_base/metagen_base_command_line.h b/src/metagen/metagen_base/metagen_base_command_line.h index c37f91dc..acd7f17b 100644 --- a/src/metagen/metagen_base/metagen_base_command_line.h +++ b/src/metagen/metagen_base/metagen_base_command_line.h @@ -34,6 +34,8 @@ struct CmdLine String8List inputs; U64 option_table_size; CmdLineOpt **option_table; + U64 argc; + char **argv; }; //////////////////////////////// diff --git a/src/metagen/metagen_base/metagen_base_context_cracking.h b/src/metagen/metagen_base/metagen_base_context_cracking.h index 040c0004..bac701dd 100644 --- a/src/metagen/metagen_base/metagen_base_context_cracking.h +++ b/src/metagen/metagen_base/metagen_base_context_cracking.h @@ -155,11 +155,11 @@ #endif #if !defined(BUILD_VERSION_MINOR) -# define BUILD_VERSION_MINOR 0 +# define BUILD_VERSION_MINOR 9 #endif #if !defined(BUILD_VERSION_PATCH) -# define BUILD_VERSION_PATCH 0 +# define BUILD_VERSION_PATCH 14 #endif #define BUILD_VERSION_STRING_LITERAL Stringify(BUILD_VERSION_MAJOR) "." Stringify(BUILD_VERSION_MINOR) "." Stringify(BUILD_VERSION_PATCH) @@ -183,7 +183,7 @@ #endif #if !defined(BUILD_ISSUES_LINK_STRING_LITERAL) -# define BUILD_ISSUES_LINK_STRING_LITERAL "https://github.com/EpicGames/raddebugger/issues" +# define BUILD_ISSUES_LINK_STRING_LITERAL "https://github.com/EpicGamesExt/raddebugger/issues" #endif #define BUILD_TITLE_STRING_LITERAL BUILD_TITLE " (" BUILD_VERSION_STRING_LITERAL " " BUILD_RELEASE_PHASE_STRING_LITERAL ") - " __DATE__ "" BUILD_GIT_HASH_STRING_LITERAL_APPEND BUILD_MODE_STRING_LITERAL_APPEND diff --git a/src/metagen/metagen_base/metagen_base_core.c b/src/metagen/metagen_base/metagen_base_core.c index 877dcb4e..b392e4a0 100644 --- a/src/metagen/metagen_base/metagen_base_core.c +++ b/src/metagen/metagen_base/metagen_base_core.c @@ -143,12 +143,6 @@ bswap_u64(U64 x) #if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS) -internal U64 -count_bits_set16(U16 val) -{ - return __popcnt16(val); -} - internal U64 count_bits_set32(U32 val) { @@ -195,46 +189,40 @@ clz64(U64 mask) #elif COMPILER_CLANG || COMPILER_GCC -internal U64 -count_bits_set16(U16 val) -{ - NotImplemented; - return 0; -} - internal U64 count_bits_set32(U32 val) { - NotImplemented; - return 0; + return __builtin_popcount(val); } internal U64 count_bits_set64(U64 val) { - NotImplemented; - return 0; + return __builtin_popcountll(val); } internal U64 ctz32(U32 val) { - NotImplemented; - return 0; + return __builtin_ctz(val); } internal U64 clz32(U32 val) { - NotImplemented; - return 0; + return __builtin_clz(val); +} + +internal U64 +ctz64(U64 val) +{ + return __builtin_ctzll(val); } internal U64 clz64(U64 val) { - NotImplemented; - return 0; + return __builtin_clzll(val); } #else @@ -399,23 +387,23 @@ txt_rng_contains(TxtRng r, TxtPt pt) //~ rjf: Toolchain/Environment Enum Functions internal U64 -bit_size_from_arch(Architecture arch) +bit_size_from_arch(Arch arch) { // TODO(rjf): metacode U64 arch_bitsize = 0; switch(arch) { - case Architecture_x64: arch_bitsize = 64; break; - case Architecture_x86: arch_bitsize = 32; break; - case Architecture_arm64: arch_bitsize = 64; break; - case Architecture_arm32: arch_bitsize = 32; break; + case Arch_x64: arch_bitsize = 64; break; + case Arch_x86: arch_bitsize = 32; break; + case Arch_arm64: arch_bitsize = 64; break; + case Arch_arm32: arch_bitsize = 32; break; default: break; } return arch_bitsize; } internal U64 -max_instruction_size_from_arch(Architecture arch) +max_instruction_size_from_arch(Arch arch) { // TODO(rjf): make this real return 64; @@ -434,17 +422,17 @@ operating_system_from_context(void){ return os; } -internal Architecture -architecture_from_context(void){ - Architecture arch = Architecture_Null; +internal Arch +arch_from_context(void){ + Arch arch = Arch_Null; #if ARCH_X64 - arch = Architecture_x64; + arch = Arch_x64; #elif ARCH_X86 - arch = Architecture_x86; + arch = Arch_x86; #elif ARCH_ARM64 - arch = Architecture_arm64; + arch = Arch_arm64; #elif ARCH_ARM32 - arch = Architecture_arm32; + arch = Arch_arm32; #endif return arch; } @@ -526,6 +514,60 @@ date_time_from_micro_seconds(U64 time){ return(result); } +internal DateTime +date_time_from_unix_time(U64 unix_time) +{ + DateTime date = {0}; + date.year = 1970; + date.day = 1 + (unix_time / 86400); + date.sec = (U32)unix_time % 60; + date.min = (U32)(unix_time / 60) % 60; + date.hour = (U32)(unix_time / 3600) % 24; + + for(;;) + { + for(date.month = 0; date.month < 12; ++date.month) + { + U64 c = 0; + switch(date.month) + { + case Month_Jan: c = 31; break; + case Month_Feb: + { + if((date.year % 4 == 0) && ((date.year % 100) != 0 || (date.year % 400) == 0)) + { + c = 29; + } + else + { + c = 28; + } + } break; + case Month_Mar: c = 31; break; + case Month_Apr: c = 30; break; + case Month_May: c = 31; break; + case Month_Jun: c = 30; break; + case Month_Jul: c = 31; break; + case Month_Aug: c = 31; break; + case Month_Sep: c = 30; break; + case Month_Oct: c = 31; break; + case Month_Nov: c = 30; break; + case Month_Dec: c = 31; break; + default: InvalidPath; + } + if(date.day <= c) + { + goto exit; + } + date.day -= c; + } + ++date.year; + } + exit:; + + return date; +} + //////////////////////////////// //~ rjf: Non-Fancy Ring Buffer Reads/Writes diff --git a/src/metagen/metagen_base/metagen_base_core.h b/src/metagen/metagen_base/metagen_base_core.h index b2483870..191e1e7f 100644 --- a/src/metagen/metagen_base/metagen_base_core.h +++ b/src/metagen/metagen_base/metagen_base_core.h @@ -40,6 +40,12 @@ # define thread_static __thread #endif +#if COMPILER_MSVC +# define force_inline __forceinline +#elif COMPILER_CLANG || COMPILER_GCC +# define force_inline __attribute__((always_inline)) +#endif + //////////////////////////////// //~ rjf: Linkage Keyword Macros @@ -118,8 +124,10 @@ #define DeferLoop(begin, end) for(int _i_ = ((begin), 0); !_i_; _i_ += 1, (end)) #define DeferLoopChecked(begin, end) for(int _i_ = 2 * !(begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end)) -#define EachEnumVal(type, it) type it = (type)0; it < type##_COUNT; it = (type)(it+1) -#define EachNonZeroEnumVal(type, it) type it = (type)1; it < type##_COUNT; it = (type)(it+1) +#define EachIndex(it, count) (U64 it = 0; it < (count); it += 1) +#define EachElement(it, array) (U64 it = 0; it < ArrayCount(array); it += 1) +#define EachEnumVal(type, it) (type it = (type)0; it < type##_COUNT; it = (type)(it+1)) +#define EachNonZeroEnumVal(type, it) (type it = (type)1; it < type##_COUNT; it = (type)(it+1)) //////////////////////////////// //~ rjf: Memory Operation Macros @@ -170,33 +178,49 @@ //////////////////////////////// //~ rjf: Atomic Operations -#if OS_WINDOWS -# include -# include -# include +#if COMPILER_MSVC # include # if ARCH_X64 -# define ins_atomic_u64_eval(x) InterlockedAdd64((volatile __int64 *)(x), 0) -# define ins_atomic_u64_inc_eval(x) InterlockedIncrement64((volatile __int64 *)(x)) -# define ins_atomic_u64_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x)) -# define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x),(c)) -# define ins_atomic_u64_add_eval(x,c) InterlockedAdd64((volatile __int64 *)(x), c) +# define ins_atomic_u64_eval(x) *((volatile U64 *)(x)) +# define ins_atomic_u64_inc_eval(x) InterlockedIncrement64((volatile __int64 *)(x)) +# define ins_atomic_u64_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x)) +# define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x),(c)) +# define ins_atomic_u64_add_eval(x,c) InterlockedAdd64((volatile __int64 *)(x), c) # define ins_atomic_u64_eval_cond_assign(x,k,c) InterlockedCompareExchange64((volatile __int64 *)(x),(k),(c)) -# define ins_atomic_u32_eval(x,c) InterlockedAdd((volatile LONG *)(x), 0) -# define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x),(c)) +# define ins_atomic_u32_eval(x) *((volatile U32 *)(x)) +# define ins_atomic_u32_inc_eval(x) InterlockedIncrement((volatile LONG *)x) +# define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x),(c)) # define ins_atomic_u32_eval_cond_assign(x,k,c) InterlockedCompareExchange((volatile LONG *)(x),(k),(c)) -# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u64_eval_assign((volatile __int64 *)(x), (__int64)(c)) +# define ins_atomic_u32_add_eval(x,c) InterlockedAdd((volatile LONG *)(x), c) # else -# error Atomic intrinsics not defined for this operating system / architecture combination. -# endif -#elif OS_LINUX -# if ARCH_X64 -# define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1) -# else -# error Atomic intrinsics not defined for this operating system / architecture combination. +# error Atomic intrinsics not defined for this compiler / architecture combination. # endif +#elif COMPILER_CLANG || COMPILER_GCC +# define ins_atomic_u64_eval(x) __atomic_load_n(x, __ATOMIC_SEQ_CST) +# define ins_atomic_u64_inc_eval(x) (__atomic_fetch_add((volatile U64 *)(x), 1, __ATOMIC_SEQ_CST) + 1) +# define ins_atomic_u64_dec_eval(x) (__atomic_fetch_sub((volatile U64 *)(x), 1, __ATOMIC_SEQ_CST) - 1) +# define ins_atomic_u64_eval_assign(x,c) __atomic_exchange_n(x, c, __ATOMIC_SEQ_CST) +# define ins_atomic_u64_add_eval(x,c) (__atomic_fetch_add((volatile U64 *)(x), c, __ATOMIC_SEQ_CST) + (c)) +# define ins_atomic_u64_eval_cond_assign(x,k,c) ({ U64 _new = (c); __atomic_compare_exchange_n((volatile U64 *)(x),&_new,(k),0,__ATOMIC_SEQ_CST,__ATOMIC_SEQ_CST); _new; }) +# define ins_atomic_u32_eval(x) __atomic_load_n(x, __ATOMIC_SEQ_CST) +# define ins_atomic_u32_inc_eval(x) (__atomic_fetch_add((volatile U32 *)(x), 1, __ATOMIC_SEQ_CST) + 1) +# define ins_atomic_u32_add_eval(x,c) (__atomic_fetch_add((volatile U32 *)(x), c, __ATOMIC_SEQ_CST) + (c)) +# define ins_atomic_u32_eval_assign(x,c) __atomic_exchange_n(x, c, __ATOMIC_SEQ_CST) +# define ins_atomic_u32_eval_cond_assign(x,k,c) ({ U32 _new = (c); __atomic_compare_exchange_n((volatile U32 *)(x),&_new,(k),0,__ATOMIC_SEQ_CST,__ATOMIC_SEQ_CST); _new; }) #else -# error Atomic intrinsics not defined for this operating system. +# error Atomic intrinsics not defined for this compiler / architecture. +#endif + +#if ARCH_64BIT +# define ins_atomic_ptr_eval_cond_assign(x,k,c) (void*)ins_atomic_u64_eval_cond_assign((volatile U64 *)(x), (U64)(k), (U64)(c)) +# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u64_eval_assign((volatile U64 *)(x), (U64)(c)) +# define ins_atomic_ptr_eval(x) (void*)ins_atomic_u64_eval((volatile U64 *)x) +#elif ARCH_32BIT +# define ins_atomic_ptr_eval_cond_assign(x,k,c) (void*)ins_atomic_u32_eval_cond_assign((volatile U32 *)(x), (U32)(k), (U32)(c)) +# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u32_eval_assign((volatile U32 *)(x), (U32)(c)) +# define ins_atomic_ptr_eval(x) (void*)ins_atomic_u32_eval((volatile U32 *)x) +#else +# error Atomic intrinsics for pointers not defined for this architecture. #endif //////////////////////////////// @@ -430,16 +454,25 @@ typedef enum OperatingSystem } OperatingSystem; -typedef enum Architecture +typedef enum ImageType { - Architecture_Null, - Architecture_x64, - Architecture_x86, - Architecture_arm64, - Architecture_arm32, - Architecture_COUNT, + Image_Null, + Image_CoffPe, + Image_Elf32, + Image_Elf64, + Image_Macho +} ImageType; + +typedef enum Arch +{ + Arch_Null, + Arch_x64, + Arch_x86, + Arch_arm64, + Arch_arm32, + Arch_COUNT, } -Architecture; +Arch; typedef enum Compiler { @@ -468,6 +501,51 @@ struct TxtRng TxtPt max; }; +//////////////////////////////// +//~ Globally Unique Ids + +typedef union Guid Guid; +union Guid +{ + struct + { + U32 data1; + U16 data2; + U16 data3; + U8 data4[8]; + }; + U8 v[16]; +}; +StaticAssert(sizeof(Guid) == 16, g_guid_size_check); + +//////////////////////////////// +//~ Arrays + +typedef struct U16Array U16Array; +struct U16Array +{ + U64 count; + U16 *v; +}; +typedef struct U32Array U32Array; +struct U32Array +{ + U64 count; + U32 *v; +}; +typedef struct U64Array U64Array; +struct U64Array +{ + U64 count; + U64 *v; +}; +typedef struct U128Array U128Array; +struct U128Array +{ + U64 count; + U128 *v; +}; + //////////////////////////////// //~ NOTE(allen): Constants @@ -734,7 +812,16 @@ internal U16 bswap_u16(U16 x); internal U32 bswap_u32(U32 x); internal U64 bswap_u64(U64 x); -internal U64 count_bits_set16(U16 val); +#if ARCH_LITTLE_ENDIAN +# define from_be_u16(x) bswap_u16(x) +# define from_be_u32(x) bswap_u32(x) +# define from_be_u64(x) bswap_u64(x) +#else +# define from_be_u16(x) (x) +# define from_be_u32(x) (x) +# define from_be_u64(x) (x) +#endif + internal U64 count_bits_set32(U32 val); internal U64 count_bits_set64(U64 val); @@ -770,19 +857,20 @@ internal B32 txt_rng_contains(TxtRng r, TxtPt pt); //////////////////////////////// //~ rjf: Toolchain/Environment Enum Functions -internal U64 bit_size_from_arch(Architecture arch); -internal U64 max_instruction_size_from_arch(Architecture arch); +internal U64 bit_size_from_arch(Arch arch); +internal U64 max_instruction_size_from_arch(Arch arch); internal OperatingSystem operating_system_from_context(void); -internal Architecture architecture_from_context(void); +internal Arch arch_from_context(void); internal Compiler compiler_from_context(void); //////////////////////////////// //~ rjf: Time Functions internal DenseTime dense_time_from_date_time(DateTime date_time); -internal DateTime date_time_from_dense_time(DenseTime time); -internal DateTime date_time_from_micro_seconds(U64 time); +internal DateTime date_time_from_dense_time(DenseTime time); +internal DateTime date_time_from_micro_seconds(U64 time); +internal DateTime date_time_from_unix_time(U64 unix_time); //////////////////////////////// //~ rjf: Non-Fancy Ring Buffer Reads/Writes diff --git a/src/metagen/metagen_base/metagen_base_entry_point.c b/src/metagen/metagen_base/metagen_base_entry_point.c index 498ec0b5..21bbc363 100644 --- a/src/metagen/metagen_base/metagen_base_entry_point.c +++ b/src/metagen/metagen_base/metagen_base_entry_point.c @@ -1,26 +1,43 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +global U64 global_update_tick_idx = 0; + internal void -main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **arguments, U64 arguments_count) +main_thread_base_entry_point(int arguments_count, char **arguments) { + Temp scratch = scratch_begin(0, 0); + ThreadNameF("[main thread]"); + + //- rjf: set up telemetry #if PROFILE_TELEMETRY - local_persist U8 tm_data[MB(64)]; + local_persist char tm_data[MB(64)]; tmLoadLibrary(TM_RELEASE); tmSetMaxThreadCount(256); - tmInitialize(sizeof(tm_data), (char *)tm_data); + tmInitialize(sizeof(tm_data), tm_data); #endif - ThreadNameF("[main thread]"); - Temp scratch = scratch_begin(0, 0); - String8List command_line_argument_strings = os_string_list_from_argcv(scratch.arena, (int)arguments_count, arguments); + + //- rjf: parse command line + String8List command_line_argument_strings = os_string_list_from_argcv(scratch.arena, arguments_count, arguments); CmdLine cmdline = cmd_line_from_string_list(scratch.arena, command_line_argument_strings); + + //- rjf: begin captures B32 capture = cmd_line_has_flag(&cmdline, str8_lit("capture")); if(capture) { ProfBeginCapture(arguments[0]); } -#if defined(TASK_SYSTEM_H) && !defined(TS_INIT_MANUAL) - ts_init(); + +#if PROFILE_TELEMETRY + tmMessage(0, TMMF_ICON_NOTE, BUILD_TITLE); +#endif + + //- rjf: initialize all included layers +#if defined(ASYNC_H) && !defined(ASYNC_INIT_MANUAL) + async_init(&cmdline); +#endif +#if defined(RDI_FROM_PDB_H) && !defined(P2R_INIT_MANUAL) + p2r_init(); #endif #if defined(HASH_STORE_H) && !defined(HS_INIT_MANUAL) hs_init(); @@ -37,19 +54,16 @@ main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **argum #if defined(DASM_CACHE_H) && !defined(DASM_INIT_MANUAL) dasm_init(); #endif -#if defined(DI_H) && !defined(DI_INIT_MANUAL) +#if defined(DBGI_H) && !defined(DI_INIT_MANUAL) di_init(); #endif -#if defined(FUZZY_SEARCH_H) && !defined(FZY_INIT_MANUAL) - fzy_init(); -#endif #if defined(DEMON_CORE_H) && !defined(DMN_INIT_MANUAL) dmn_init(); #endif #if defined(CTRL_CORE_H) && !defined(CTRL_INIT_MANUAL) ctrl_init(); #endif -#if defined(OS_GRAPHICAL_H) && !defined(OS_GFX_INIT_MANUAL) +#if defined(OS_GFX_H) && !defined(OS_GFX_INIT_MANUAL) os_gfx_init(); #endif #if defined(FONT_PROVIDER_H) && !defined(FP_INIT_MANUAL) @@ -64,21 +78,25 @@ main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **argum #if defined(GEO_CACHE_H) && !defined(GEO_INIT_MANUAL) geo_init(); #endif -#if defined(FONT_CACHE_H) && !defined(F_INIT_MANUAL) - f_init(); +#if defined(FONT_CACHE_H) && !defined(FNT_INIT_MANUAL) + fnt_init(); #endif -#if defined(DF_CORE_H) && !defined(DF_INIT_MANUAL) - DF_StateDeltaHistory *hist = df_state_delta_history_alloc(); - df_core_init(&cmdline, hist); +#if defined(DBG_ENGINE_CORE_H) && !defined(D_INIT_MANUAL) + d_init(); #endif -#if defined(DF_GFX_H) && !defined(DF_GFX_INIT_MANUAL) - df_gfx_init(update_and_render, df_state_delta_history()); +#if defined(RADDBG_CORE_H) && !defined(RD_INIT_MANUAL) + rd_init(&cmdline); #endif + + //- rjf: call into entry point entry_point(&cmdline); + + //- rjf: end captures if(capture) { ProfEndCapture(); } + scratch_end(scratch); } @@ -90,3 +108,23 @@ supplement_thread_base_entry_point(void (*entry_point)(void *params), void *para entry_point(params); tctx_release(); } + +internal U64 +update_tick_idx(void) +{ + U64 result = ins_atomic_u64_eval(&global_update_tick_idx); + return result; +} + +internal B32 +update(void) +{ + ProfTick(0); + ins_atomic_u64_inc_eval(&global_update_tick_idx); +#if OS_FEATURE_GRAPHICAL + B32 result = frame(); +#else + B32 result = 0; +#endif + return result; +} diff --git a/src/metagen/metagen_base/metagen_base_entry_point.h b/src/metagen/metagen_base/metagen_base_entry_point.h index 560bdcc7..318f8d9f 100644 --- a/src/metagen/metagen_base/metagen_base_entry_point.h +++ b/src/metagen/metagen_base/metagen_base_entry_point.h @@ -4,7 +4,9 @@ #ifndef BASE_ENTRY_POINT_H #define BASE_ENTRY_POINT_H -internal void main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **arguments, U64 arguments_count); +internal void main_thread_base_entry_point(int argc, char **argv); internal void supplement_thread_base_entry_point(void (*entry_point)(void *params), void *params); +internal U64 update_tick_idx(void); +internal B32 update(void); #endif // BASE_ENTRY_POINT_H diff --git a/src/metagen/metagen_base/metagen_base_inc.c b/src/metagen/metagen_base/metagen_base_inc.c index 74dcfe02..57aa2113 100644 --- a/src/metagen/metagen_base/metagen_base_inc.c +++ b/src/metagen/metagen_base/metagen_base_inc.c @@ -4,8 +4,8 @@ //////////////////////////////// //~ rjf: Base Includes -#undef RADDBG_LAYER_COLOR -#define RADDBG_LAYER_COLOR 0.20f, 0.60f, 0.80f +#undef MARKUP_LAYER_COLOR +#define MARKUP_LAYER_COLOR 0.20f, 0.60f, 0.80f #include "metagen_base_core.c" #include "metagen_base_profile.c" @@ -15,5 +15,6 @@ #include "metagen_base_thread_context.c" #include "metagen_base_command_line.c" #include "metagen_base_markup.c" +#include "metagen_base_meta.c" #include "metagen_base_log.c" #include "metagen_base_entry_point.c" diff --git a/src/metagen/metagen_base/metagen_base_inc.h b/src/metagen/metagen_base/metagen_base_inc.h index 88aa65f7..55e2ebe7 100644 --- a/src/metagen/metagen_base/metagen_base_inc.h +++ b/src/metagen/metagen_base/metagen_base_inc.h @@ -17,6 +17,7 @@ #include "metagen_base_thread_context.h" #include "metagen_base_command_line.h" #include "metagen_base_markup.h" +#include "metagen_base_meta.h" #include "metagen_base_log.h" #include "metagen_base_entry_point.h" diff --git a/src/metagen/metagen_base/metagen_base_log.c b/src/metagen/metagen_base/metagen_base_log.c index 418b29ff..1c2a05f8 100644 --- a/src/metagen/metagen_base/metagen_base_log.c +++ b/src/metagen/metagen_base/metagen_base_log.c @@ -88,7 +88,7 @@ log_scope_end(Arena *arena) SLLStackPop(log_active->top_scope); if(arena != 0) { - for(EachEnumVal(LogMsgKind, kind)) + for EachEnumVal(LogMsgKind, kind) { Temp scratch = scratch_begin(&arena, 1); String8 result_unindented = str8_list_join(scratch.arena, &scope->strings[kind], 0); diff --git a/src/metagen/metagen_base/metagen_base_math.c b/src/metagen/metagen_base/metagen_base_math.c index 465d342d..2c6201f3 100644 --- a/src/metagen/metagen_base/metagen_base_math.c +++ b/src/metagen/metagen_base/metagen_base_math.c @@ -394,7 +394,7 @@ internal Rng1U32 shift_1u32(Rng1U32 r, U32 x) {r.min += x; r.m internal Rng1U32 pad_1u32(Rng1U32 r, U32 x) {r.min -= x; r.max += x; return r;} internal U32 center_1u32(Rng1U32 r) {U32 c = (r.min+r.max)/2; return c;} internal B32 contains_1u32(Rng1U32 r, U32 x) {B32 c = (r.min <= x && x < r.max); return c;} -internal U32 dim_1u32(Rng1U32 r) {U32 c = r.max-r.min; return c;} +internal U32 dim_1u32(Rng1U32 r) {U32 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;} internal Rng1U32 union_1u32(Rng1U32 a, Rng1U32 b) {Rng1U32 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;} internal Rng1U32 intersect_1u32(Rng1U32 a, Rng1U32 b) {Rng1U32 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;} internal U32 clamp_1u32(Rng1U32 r, U32 v) {v = Clamp(r.min, v, r.max); return v;} @@ -404,7 +404,7 @@ internal Rng1S32 shift_1s32(Rng1S32 r, S32 x) {r.min += x; r.m internal Rng1S32 pad_1s32(Rng1S32 r, S32 x) {r.min -= x; r.max += x; return r;} internal S32 center_1s32(Rng1S32 r) {S32 c = (r.min+r.max)/2; return c;} internal B32 contains_1s32(Rng1S32 r, S32 x) {B32 c = (r.min <= x && x < r.max); return c;} -internal S32 dim_1s32(Rng1S32 r) {S32 c = r.max-r.min; return c;} +internal S32 dim_1s32(Rng1S32 r) {S32 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;} internal Rng1S32 union_1s32(Rng1S32 a, Rng1S32 b) {Rng1S32 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;} internal Rng1S32 intersect_1s32(Rng1S32 a, Rng1S32 b) {Rng1S32 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;} internal S32 clamp_1s32(Rng1S32 r, S32 v) {v = Clamp(r.min, v, r.max); return v;} @@ -414,7 +414,7 @@ internal Rng1U64 shift_1u64(Rng1U64 r, U64 x) {r.min += x; r.m internal Rng1U64 pad_1u64(Rng1U64 r, U64 x) {r.min -= x; r.max += x; return r;} internal U64 center_1u64(Rng1U64 r) {U64 c = (r.min+r.max)/2; return c;} internal B32 contains_1u64(Rng1U64 r, U64 x) {B32 c = (r.min <= x && x < r.max); return c;} -internal U64 dim_1u64(Rng1U64 r) {U64 c = r.max-r.min; return c;} +internal U64 dim_1u64(Rng1U64 r) {U64 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;} internal Rng1U64 union_1u64(Rng1U64 a, Rng1U64 b) {Rng1U64 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;} internal Rng1U64 intersect_1u64(Rng1U64 a, Rng1U64 b) {Rng1U64 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;} internal U64 clamp_1u64(Rng1U64 r, U64 v) {v = Clamp(r.min, v, r.max); return v;} @@ -424,7 +424,7 @@ internal Rng1S64 shift_1s64(Rng1S64 r, S64 x) {r.min += x; r.m internal Rng1S64 pad_1s64(Rng1S64 r, S64 x) {r.min -= x; r.max += x; return r;} internal S64 center_1s64(Rng1S64 r) {S64 c = (r.min+r.max)/2; return c;} internal B32 contains_1s64(Rng1S64 r, S64 x) {B32 c = (r.min <= x && x < r.max); return c;} -internal S64 dim_1s64(Rng1S64 r) {S64 c = r.max-r.min; return c;} +internal S64 dim_1s64(Rng1S64 r) {S64 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;} internal Rng1S64 union_1s64(Rng1S64 a, Rng1S64 b) {Rng1S64 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;} internal Rng1S64 intersect_1s64(Rng1S64 a, Rng1S64 b) {Rng1S64 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;} internal S64 clamp_1s64(Rng1S64 r, S64 v) {v = Clamp(r.min, v, r.max); return v;} @@ -434,7 +434,7 @@ internal Rng1F32 shift_1f32(Rng1F32 r, F32 x) {r.min += x; r.m internal Rng1F32 pad_1f32(Rng1F32 r, F32 x) {r.min -= x; r.max += x; return r;} internal F32 center_1f32(Rng1F32 r) {F32 c = (r.min+r.max)/2; return c;} internal B32 contains_1f32(Rng1F32 r, F32 x) {B32 c = (r.min <= x && x < r.max); return c;} -internal F32 dim_1f32(Rng1F32 r) {F32 c = r.max-r.min; return c;} +internal F32 dim_1f32(Rng1F32 r) {F32 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;} internal Rng1F32 union_1f32(Rng1F32 a, Rng1F32 b) {Rng1F32 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;} internal Rng1F32 intersect_1f32(Rng1F32 a, Rng1F32 b) {Rng1F32 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;} internal F32 clamp_1f32(Rng1F32 r, F32 v) {v = Clamp(r.min, v, r.max); return v;} @@ -444,7 +444,7 @@ internal Rng2S16 shift_2s16(Rng2S16 r, Vec2S16 x) {r.min = add_2s1 internal Rng2S16 pad_2s16(Rng2S16 r, S16 x) {Vec2S16 xv = {x, x}; r.min = sub_2s16(r.min, xv); r.max = add_2s16(r.max, xv); return r;} internal Vec2S16 center_2s16(Rng2S16 r) {Vec2S16 c = {(S16)((r.min.x+r.max.x)/2), (S16)((r.min.y+r.max.y)/2)}; return c;} internal B32 contains_2s16(Rng2S16 r, Vec2S16 x) {B32 c = (r.min.x <= x.x && x.x < r.max.x && r.min.y <= x.y && x.y < r.max.y); return c;} -internal Vec2S16 dim_2s16(Rng2S16 r) {Vec2S16 dim = {(S16)(r.max.x-r.min.x), (S16)(r.max.y-r.min.y)}; return dim;} +internal Vec2S16 dim_2s16(Rng2S16 r) {Vec2S16 dim = {(S16)(((r.max.x > r.min.x) ? (r.max.x - r.min.x) : 0)), (S16)(((r.max.y > r.min.y) ? (r.max.y - r.min.y) : 0))}; return dim;} internal Rng2S16 union_2s16(Rng2S16 a, Rng2S16 b) {Rng2S16 c; c.p0.x = Min(a.min.x, b.min.x); c.p0.y = Min(a.min.y, b.min.y); c.p1.x = Max(a.max.x, b.max.x); c.p1.y = Max(a.max.y, b.max.y); return c;} internal Rng2S16 intersect_2s16(Rng2S16 a, Rng2S16 b) {Rng2S16 c; c.p0.x = Max(a.min.x, b.min.x); c.p0.y = Max(a.min.y, b.min.y); c.p1.x = Min(a.max.x, b.max.x); c.p1.y = Min(a.max.y, b.max.y); return c;} internal Vec2S16 clamp_2s16(Rng2S16 r, Vec2S16 v) {v.x = Clamp(r.min.x, v.x, r.max.x); v.y = Clamp(r.min.y, v.y, r.max.y); return v;} @@ -454,7 +454,7 @@ internal Rng2S32 shift_2s32(Rng2S32 r, Vec2S32 x) {r.min = add_2s3 internal Rng2S32 pad_2s32(Rng2S32 r, S32 x) {Vec2S32 xv = {x, x}; r.min = sub_2s32(r.min, xv); r.max = add_2s32(r.max, xv); return r;} internal Vec2S32 center_2s32(Rng2S32 r) {Vec2S32 c = {(r.min.x+r.max.x)/2, (r.min.y+r.max.y)/2}; return c;} internal B32 contains_2s32(Rng2S32 r, Vec2S32 x) {B32 c = (r.min.x <= x.x && x.x < r.max.x && r.min.y <= x.y && x.y < r.max.y); return c;} -internal Vec2S32 dim_2s32(Rng2S32 r) {Vec2S32 dim = {r.max.x-r.min.x, r.max.y-r.min.y}; return dim;} +internal Vec2S32 dim_2s32(Rng2S32 r) {Vec2S32 dim = {((r.max.x > r.min.x) ? (r.max.x - r.min.x) : 0), ((r.max.y > r.min.y) ? (r.max.y - r.min.y) : 0)}; return dim;} internal Rng2S32 union_2s32(Rng2S32 a, Rng2S32 b) {Rng2S32 c; c.p0.x = Min(a.min.x, b.min.x); c.p0.y = Min(a.min.y, b.min.y); c.p1.x = Max(a.max.x, b.max.x); c.p1.y = Max(a.max.y, b.max.y); return c;} internal Rng2S32 intersect_2s32(Rng2S32 a, Rng2S32 b) {Rng2S32 c; c.p0.x = Max(a.min.x, b.min.x); c.p0.y = Max(a.min.y, b.min.y); c.p1.x = Min(a.max.x, b.max.x); c.p1.y = Min(a.max.y, b.max.y); return c;} internal Vec2S32 clamp_2s32(Rng2S32 r, Vec2S32 v) {v.x = Clamp(r.min.x, v.x, r.max.x); v.y = Clamp(r.min.y, v.y, r.max.y); return v;} @@ -464,7 +464,7 @@ internal Rng2S64 shift_2s64(Rng2S64 r, Vec2S64 x) {r.min = add_2s6 internal Rng2S64 pad_2s64(Rng2S64 r, S64 x) {Vec2S64 xv = {x, x}; r.min = sub_2s64(r.min, xv); r.max = add_2s64(r.max, xv); return r;} internal Vec2S64 center_2s64(Rng2S64 r) {Vec2S64 c = {(r.min.x+r.max.x)/2, (r.min.y+r.max.y)/2}; return c;} internal B32 contains_2s64(Rng2S64 r, Vec2S64 x) {B32 c = (r.min.x <= x.x && x.x < r.max.x && r.min.y <= x.y && x.y < r.max.y); return c;} -internal Vec2S64 dim_2s64(Rng2S64 r) {Vec2S64 dim = {r.max.x-r.min.x, r.max.y-r.min.y}; return dim;} +internal Vec2S64 dim_2s64(Rng2S64 r) {Vec2S64 dim = {((r.max.x > r.min.x) ? (r.max.x - r.min.x) : 0), ((r.max.y > r.min.y) ? (r.max.y - r.min.y) : 0)}; return dim;} internal Rng2S64 union_2s64(Rng2S64 a, Rng2S64 b) {Rng2S64 c; c.p0.x = Min(a.min.x, b.min.x); c.p0.y = Min(a.min.y, b.min.y); c.p1.x = Max(a.max.x, b.max.x); c.p1.y = Max(a.max.y, b.max.y); return c;} internal Rng2S64 intersect_2s64(Rng2S64 a, Rng2S64 b) {Rng2S64 c; c.p0.x = Max(a.min.x, b.min.x); c.p0.y = Max(a.min.y, b.min.y); c.p1.x = Min(a.max.x, b.max.x); c.p1.y = Min(a.max.y, b.max.y); return c;} internal Vec2S64 clamp_2s64(Rng2S64 r, Vec2S64 v) {v.x = Clamp(r.min.x, v.x, r.max.x); v.y = Clamp(r.min.y, v.y, r.max.y); return v;} @@ -474,7 +474,7 @@ internal Rng2F32 shift_2f32(Rng2F32 r, Vec2F32 x) {r.min = add_2f3 internal Rng2F32 pad_2f32(Rng2F32 r, F32 x) {Vec2F32 xv = {x, x}; r.min = sub_2f32(r.min, xv); r.max = add_2f32(r.max, xv); return r;} internal Vec2F32 center_2f32(Rng2F32 r) {Vec2F32 c = {(r.min.x+r.max.x)/2, (r.min.y+r.max.y)/2}; return c;} internal B32 contains_2f32(Rng2F32 r, Vec2F32 x) {B32 c = (r.min.x <= x.x && x.x < r.max.x && r.min.y <= x.y && x.y < r.max.y); return c;} -internal Vec2F32 dim_2f32(Rng2F32 r) {Vec2F32 dim = {r.max.x-r.min.x, r.max.y-r.min.y}; return dim;} +internal Vec2F32 dim_2f32(Rng2F32 r) {Vec2F32 dim = {((r.max.x > r.min.x) ? (r.max.x - r.min.x) : 0), ((r.max.y > r.min.y) ? (r.max.y - r.min.y) : 0)}; return dim;} internal Rng2F32 union_2f32(Rng2F32 a, Rng2F32 b) {Rng2F32 c; c.p0.x = Min(a.min.x, b.min.x); c.p0.y = Min(a.min.y, b.min.y); c.p1.x = Max(a.max.x, b.max.x); c.p1.y = Max(a.max.y, b.max.y); return c;} internal Rng2F32 intersect_2f32(Rng2F32 a, Rng2F32 b) {Rng2F32 c; c.p0.x = Max(a.min.x, b.min.x); c.p0.y = Max(a.min.y, b.min.y); c.p1.x = Min(a.max.x, b.max.x); c.p1.y = Min(a.max.y, b.max.y); return c;} internal Vec2F32 clamp_2f32(Rng2F32 r, Vec2F32 v) {v.x = Clamp(r.min.x, v.x, r.max.x); v.y = Clamp(r.min.y, v.y, r.max.y); return v;} @@ -591,6 +591,49 @@ u32_from_rgba(Vec4F32 rgba) //////////////////////////////// //~ rjf: List Type Functions +internal void +rng1u64_list_push(Arena *arena, Rng1U64List *list, Rng1U64 rng) +{ + Rng1U64Node *n = push_array(arena, Rng1U64Node, 1); + MemoryCopyStruct(&n->v, &rng); + SLLQueuePush(list->first, list->last, n); + list->count += 1; +} + +internal void +rng1u64_list_concat(Rng1U64List *list, Rng1U64List *to_concat) +{ + if(to_concat->first) + { + if(list->first) + { + list->last->next = to_concat->first; + list->last = to_concat->last; + } + else + { + list->first = to_concat->first; + list->last = to_concat->last; + } + MemoryZeroStruct(to_concat); + } +} + +internal Rng1U64Array +rng1u64_array_from_list(Arena *arena, Rng1U64List *list) +{ + Rng1U64Array arr = {0}; + arr.count = list->count; + arr.v = push_array_no_zero(arena, Rng1U64, arr.count); + U64 idx = 0; + for(Rng1U64Node *n = list->first; n != 0; n = n->next) + { + arr.v[idx] = n->v; + idx += 1; + } + return arr; +} + internal void rng1s64_list_push(Arena *arena, Rng1S64List *list, Rng1S64 rng) { diff --git a/src/metagen/metagen_base/metagen_base_math.h b/src/metagen/metagen_base/metagen_base_math.h index 645a6d31..b6063ad5 100644 --- a/src/metagen/metagen_base/metagen_base_math.h +++ b/src/metagen/metagen_base/metagen_base_math.h @@ -329,6 +329,28 @@ union Rng2S64 //////////////////////////////// //~ rjf: List Types +typedef struct Rng1U64Node Rng1U64Node; +struct Rng1U64Node +{ + Rng1U64Node *next; + Rng1U64 v; +}; + +typedef struct Rng1U64List Rng1U64List; +struct Rng1U64List +{ + U64 count; + Rng1U64Node *first; + Rng1U64Node *last; +}; + +typedef struct Rng1U64Array Rng1U64Array; +struct Rng1U64Array +{ + Rng1U64 *v; + U64 count; +}; + typedef struct Rng1S64Node Rng1S64Node; struct Rng1S64Node { @@ -643,6 +665,10 @@ internal U32 u32_from_rgba(Vec4F32 rgba); //////////////////////////////// //~ rjf: List Type Functions +internal void rng1u64_list_push(Arena *arena, Rng1U64List *list, Rng1U64 rng); +internal void rng1u64_list_concat(Rng1U64List *list, Rng1U64List *to_concat); +internal Rng1U64Array rng1u64_array_from_list(Arena *arena, Rng1U64List *list); + internal void rng1s64_list_push(Arena *arena, Rng1S64List *list, Rng1S64 rng); internal Rng1S64Array rng1s64_array_from_list(Arena *arena, Rng1S64List *list); diff --git a/src/metagen/metagen_base/metagen_base_meta.c b/src/metagen/metagen_base/metagen_base_meta.c new file mode 100644 index 00000000..c60dc237 --- /dev/null +++ b/src/metagen/metagen_base/metagen_base_meta.c @@ -0,0 +1,422 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: Type Info Lookups + +internal Member * +member_from_name(Type *type, String8 name) +{ + Member *member = &member_nil; + if(type->members != 0 && name.size != 0) + { + for(U64 idx = 0; idx < type->count; idx += 1) + { + if(str8_match(type->members[idx].name, name, 0)) + { + member = &type->members[idx]; + break; + } + } + } + return member; +} + +//////////////////////////////// +//~ rjf: Type Info * Instance Operations + +internal void +typed_data_rebase_ptrs(Type *type, String8 data, void *base_ptr) +{ + Temp scratch = scratch_begin(0, 0); + typedef struct RebaseTypeTask RebaseTypeTask; + struct RebaseTypeTask + { + RebaseTypeTask *next; + Type *type; + U8 *ptr; + }; + RebaseTypeTask start_task = {0, type, data.str}; + RebaseTypeTask *first_task = &start_task; + RebaseTypeTask *last_task = first_task; + for(RebaseTypeTask *t = first_task; t != 0; t = t->next) + { + switch(t->type->kind) + { + default:{}break; + case TypeKind_Ptr: + if(!(t->type->flags & TypeFlag_IsExternal)) + { + *(U64 *)t->ptr = ((U64)(*(U8 **)t->ptr - (U8 *)base_ptr)); + }break; + case TypeKind_Array: + { + for(U64 idx = 0; idx < t->type->count; idx += 1) + { + RebaseTypeTask *task = push_array(scratch.arena, RebaseTypeTask, 1); + task->type = t->type->direct; + task->ptr = t->ptr + t->type->direct->size * idx; + SLLQueuePush(first_task, last_task, task); + } + }break; + case TypeKind_Struct: + { + for(U64 idx = 0; idx < t->type->count; idx += 1) + { + Member *member = &t->type->members[idx]; + RebaseTypeTask *task = push_array(scratch.arena, RebaseTypeTask, 1); + task->type = member->type; + task->ptr = t->ptr + member->value; + SLLQueuePush(first_task, last_task, task); + } + }break; + } + } + scratch_end(scratch); +} + +internal String8 +serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List strings = {0}; + str8_serial_begin(scratch.arena, &strings); + { + typedef struct SerializeTypeTask SerializeTypeTask; + struct SerializeTypeTask + { + SerializeTypeTask *next; + Type *type; + U64 count; + U8 *src; + Type *containing_type; + U8 *containing_ptr; + B32 is_post_header; + }; + SerializeTypeTask start_task = {0, type, 1, data.str}; + SerializeTypeTask *first_task = &start_task; + SerializeTypeTask *last_task = first_task; + for(SerializeTypeTask *t = first_task; t != 0; t = t->next) + { + switch(t->type->kind) + { + //- rjf: leaf -> just copy the data directly + default: + if(TypeKind_FirstLeaf <= t->type->kind && t->type->kind <= TypeKind_LastLeaf) + { + str8_serial_push_string(scratch.arena, &strings, str8(t->src, t->type->size*t->count)); + }break; + + //- rjf: pointers -> try to interpret/understand pointer & read/write, otherwise just write as plain data + case TypeKind_Ptr: + { + // rjf: unpack info about this pointer + TypeSerializePtrRefInfo *ptr_ref_info = 0; + for(U64 idx = 0; idx < params->ptr_ref_infos_count; idx += 1) + { + if(params->ptr_ref_infos[idx].type == t->type->direct) + { + ptr_ref_info = ¶ms->ptr_ref_infos[idx]; + break; + } + } + + // rjf: indexification -> subtract base, divide direct size, write index + if(ptr_ref_info != 0 && ptr_ref_info->indexify_base != 0) + { + U64 ptr_value = 0; + MemoryCopy(&ptr_value, t->src, sizeof(ptr_value)); + U64 ptr_write_value = ((U64)((U8 *)ptr_value - (U8 *)ptr_ref_info->indexify_base)/t->type->direct->size); + str8_serial_push_struct(scratch.arena, &strings, &ptr_write_value); + } + + // rjf: offsetification -> subtract base, write offsets + else if(ptr_ref_info != 0 && ptr_ref_info->offsetify_base != 0) + { + U64 ptr_value = 0; + MemoryCopy(&ptr_value, t->src, sizeof(ptr_value)); + U64 ptr_write_value = (U64)((U8 *)ptr_value - (U8 *)ptr_ref_info->offsetify_base); + str8_serial_push_struct(scratch.arena, &strings, &ptr_write_value); + } + + // rjf: size-by-member (pre-header): still potentially dependent on other members which + // delimit our size, so push a new post-header task for pointer. + else if(t->type->count_delimiter_name.size != 0 && !t->is_post_header) + { + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); + task->type = t->type; + task->count = t->count; + task->src = t->src; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + task->is_post_header = 1; + SLLQueuePush(first_task, last_task, task); + } + + // rjf: size-by-member (post-header): all flat parts of containing struct have been + // iterated, so now we can read the size, & descend to new task to read pointer + // destination contents + else if(t->type->count_delimiter_name.size != 0 && t->is_post_header) + { + // rjf: determine count of this pointer + U64 count = 0; + { + Member *count_member = member_from_name(t->containing_type, t->type->count_delimiter_name); + MemoryCopy(&count, t->containing_ptr + count_member->value, count_member->type->size); + } + + // rjf: push task + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); + task->type = t->type->direct; + task->count = count; + task->src = *(void **)t->src; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + } + + // rjf: catch-all: write pointer value + else + { + str8_serial_push_string(scratch.arena, &strings, str8(t->src, t->type->size*t->count)); + } + }break; + + //- rjf: arrays -> descend to underlying type, + count + case TypeKind_Array: + { + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); + task->type = t->type->direct; + task->count = t->type->count; + task->src = t->src; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + }break; + + //- rjf: struct -> descend to members + case TypeKind_Struct: + { + U64 off = 0; + for(U64 idx = 0; idx < t->count; idx += 1) + { + for(U64 member_idx = 0; member_idx < t->type->count; member_idx += 1) + { + if(t->type->members[member_idx].flags & MemberFlag_DoNotSerialize) + { + continue; + } + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); + task->type = t->type->members[member_idx].type; + task->count = 1; + task->src = t->src + idx*t->type->size + t->type->members[member_idx].value; + task->containing_type = t->type; + task->containing_ptr = t->src; + SLLQueuePush(first_task, last_task, task); + } + } + }break; + + //- rjf: enum -> descend to basic type interpretation + case TypeKind_Enum: + { + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); + task->type = t->type->direct; + task->count = t->count; + task->src = t->src; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + }break; + } + } + } + String8 result = str8_serial_end(arena, &strings); + scratch_end(scratch); + return result; +} + +internal String8 +deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params) +{ + String8 result = {0}; + result.size = type->size; + result.str = push_array(arena, U8, result.size); + { + Temp scratch = scratch_begin(&arena, 1); + typedef struct DeserializeTypeTask DeserializeTypeTask; + struct DeserializeTypeTask + { + DeserializeTypeTask *next; + Type *type; + U64 count; + U8 *dst; + Type *containing_type; + U8 *containing_ptr; + B32 is_post_header; + }; + U64 read_off = 0; + DeserializeTypeTask start_task = {0, type, 1, result.str}; + DeserializeTypeTask *first_task = &start_task; + DeserializeTypeTask *last_task = first_task; + for(DeserializeTypeTask *t = first_task; t != 0; t = t->next) + { + U8 *t_src = data.str + read_off; + switch(t->type->kind) + { + //- rjf: leaf -> copy the data directly + default: + if(TypeKind_FirstLeaf <= t->type->kind && t->type->kind <= TypeKind_LastLeaf) + { + MemoryCopy(t->dst, t_src, t->type->size*t->count); + read_off += t->type->size*t->count; + }break; + + //- rjf: pointers -> try to interpret/understand pointer & read/write, otherwise skip + case TypeKind_Ptr: + { + // rjf: unpack info about this pointer + TypeSerializePtrRefInfo *ptr_ref_info = 0; + for(U64 idx = 0; idx < params->ptr_ref_infos_count; idx += 1) + { + if(params->ptr_ref_infos[idx].type == t->type->direct) + { + ptr_ref_info = ¶ms->ptr_ref_infos[idx]; + break; + } + } + + // rjf: indexification -> add base, multiply direct size + if(ptr_ref_info != 0 && ptr_ref_info->indexify_base != 0) + { + U64 ptr_value = 0; + MemoryCopy(&ptr_value, t_src, sizeof(ptr_value)); + U64 ptr_write_value = (ptr_value + (U64)ptr_ref_info->indexify_base) * t->type->direct->size; + MemoryCopy(t->dst, &ptr_write_value, sizeof(ptr_write_value)); + read_off += sizeof(ptr_value); + } + + // rjf: offsetification -> subtract base, write offsets + else if(ptr_ref_info != 0 && ptr_ref_info->offsetify_base != 0) + { + U64 ptr_value = 0; + MemoryCopy(&ptr_value, t_src, sizeof(ptr_value)); + U64 ptr_write_value = ptr_value + (U64)ptr_ref_info->offsetify_base; + MemoryCopy(t->dst, &ptr_write_value, sizeof(ptr_write_value)); + read_off += sizeof(ptr_value); + } + + // rjf: size-by-member (pre-header): still potentially dependent on other members which + // delimit our size, so push a new post-header task for pointer. + else if(t->type->count_delimiter_name.size != 0 && !t->is_post_header) + { + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); + task->type = t->type; + task->count = t->count; + task->dst = t->dst; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + task->is_post_header = 1; + SLLQueuePush(first_task, last_task, task); + } + + // rjf: size-by-member (post-header): all flat parts of containing struct have been + // iterated, so now we can read the size, & descend to new task to read pointer + // destination contents + else if(t->type->count_delimiter_name.size != 0 && t->is_post_header) + { + // rjf: determine count of this pointer + U64 count = 0; + { + Member *count_member = member_from_name(t->containing_type, t->type->count_delimiter_name); + MemoryCopy(&count, t->containing_ptr + count_member->value, count_member->type->size); + } + + // rjf: allocate buffer for pointer destination; write address into pointer value slot + U64 ptr_dest_buffer_size = (count+1)*t->type->direct->size; + U8 *ptr_dest_buffer = push_array(arena, U8, ptr_dest_buffer_size); + MemoryCopy(t->dst, &ptr_dest_buffer, sizeof(ptr_dest_buffer)); + + // rjf: push task + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); + task->type = t->type->direct; + task->count = count; + task->dst = ptr_dest_buffer; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + } + + // rjf: catch-all: read pointer value + else + { + MemoryCopy(t->dst, t_src, t->type->size*t->count); + read_off += t->type->size*t->count; + } + }break; + + //- rjf: arrays -> descend to underlying type, + count + case TypeKind_Array: + { + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); + task->type = t->type->direct; + task->count = t->type->count; + task->dst = t->dst; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + }break; + + //- rjf: struct -> descend to members + case TypeKind_Struct: + { + for(U64 idx = 0; idx < t->count; idx += 1) + { + for(U64 member_idx = 0; member_idx < t->type->count; member_idx += 1) + { + if(t->type->members[member_idx].flags & MemberFlag_DoNotSerialize) + { + continue; + } + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); + task->type = t->type->members[member_idx].type; + task->count = 1; + task->dst = t->dst + idx*t->type->size + t->type->members[member_idx].value; + task->containing_type = t->type; + task->containing_ptr = t->dst; + SLLQueuePush(first_task, last_task, task); + } + } + }break; + + //- rjf: enum -> descend to basic type interpretation + case TypeKind_Enum: + { + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); + task->type = t->type->direct; + task->count = t->count; + task->dst = t->dst; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + }break; + } + } + if(params->advance_out != 0) + { + params->advance_out[0] = read_off; + } + scratch_end(scratch); + } + return result; +} + +internal String8 +deep_copy_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params) +{ + Temp scratch = scratch_begin(&arena, 1); + String8 data_srlz = serialized_from_typed_data(scratch.arena, type, data, params); + String8 data_copy = deserialized_from_typed_data(arena, type, data_srlz, params); + scratch_end(scratch); + return data_copy; +} diff --git a/src/metagen/metagen_base/metagen_base_meta.h b/src/metagen/metagen_base/metagen_base_meta.h new file mode 100644 index 00000000..45d01e72 --- /dev/null +++ b/src/metagen/metagen_base/metagen_base_meta.h @@ -0,0 +1,298 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef BASE_META_H +#define BASE_META_H + +//////////////////////////////// +//~ rjf: Meta Markup Features + +#define EmbedFile(name, path) +#define TweakB32(name, default) (TWEAK_##name) +#define TweakF32(name, default, min, max) (TWEAK_##name) + +//////////////////////////////// +//~ rjf: Tweak Info Tables + +typedef struct TweakB32Info TweakB32Info; +struct TweakB32Info +{ + String8 name; + B32 default_value; + B32 *value_ptr; +}; + +typedef struct TweakF32Info TweakF32Info; +struct TweakF32Info +{ + String8 name; + F32 default_value; + Rng1F32 value_range; + F32 *value_ptr; +}; + +typedef struct TweakB32InfoTable TweakB32InfoTable; +struct TweakB32InfoTable +{ + TweakB32Info *v; + U64 count; +}; + +typedef struct TweakF32InfoTable TweakF32InfoTable; +struct TweakF32InfoTable +{ + TweakF32Info *v; + U64 count; +}; + +typedef struct EmbedInfo EmbedInfo; +struct EmbedInfo +{ + String8 name; + String8 *data; + U128 *hash; +}; + +typedef struct EmbedInfoTable EmbedInfoTable; +struct EmbedInfoTable +{ + EmbedInfo *v; + U64 count; +}; + +//////////////////////////////// +//~ rjf: Type Info Types + +typedef enum TypeKind +{ + TypeKind_Null, + + // rjf: leaves + TypeKind_Void, TypeKind_FirstLeaf = TypeKind_Void, + TypeKind_U8, + TypeKind_U16, + TypeKind_U32, + TypeKind_U64, + TypeKind_S8, + TypeKind_S16, + TypeKind_S32, + TypeKind_S64, + TypeKind_B8, + TypeKind_B16, + TypeKind_B32, + TypeKind_B64, + TypeKind_F32, + TypeKind_F64, TypeKind_LastLeaf = TypeKind_F64, + + // rjf: operators + TypeKind_Ptr, + TypeKind_Array, + + // rjf: user-defined-types + TypeKind_Struct, + TypeKind_Union, + TypeKind_Enum, + + TypeKind_COUNT +} +TypeKind; + +typedef U32 TypeFlags; +enum +{ + TypeFlag_IsExternal = (1<<0), + TypeFlag_IsPlainText = (1<<1), + TypeFlag_IsCodeText = (1<<2), + TypeFlag_IsPathText = (1<<3), +}; + +typedef U32 MemberFlags; +enum +{ + MemberFlag_DoNotSerialize = (1<<0), +}; + +typedef struct Type Type; +typedef struct Member Member; +struct Member +{ + String8 name; + String8 pretty_name; + Type *type; + U64 value; + MemberFlags flags; +}; + +typedef struct Type Type; +struct Type +{ + TypeKind kind; + TypeFlags flags; + U64 size; + Type *direct; + String8 name; + String8 count_delimiter_name; // gathered from surrounding members, turns *->[1] into *->[N] + U64 count; + Member *members; +}; + +//////////////////////////////// +//~ rjf: Type Serialization Parameters + +typedef struct TypeSerializePtrRefInfo TypeSerializePtrRefInfo; +struct TypeSerializePtrRefInfo +{ + Type *type; // pointers to this + void *indexify_base; // can be indexified using this + void *offsetify_base; // can be offsetified using this + void *nil_ptr; // is terminal if matching 0 or this +}; + +typedef struct TypeSerializeParams TypeSerializeParams; +struct TypeSerializeParams +{ + U64 *advance_out; + TypeSerializePtrRefInfo *ptr_ref_infos; + U64 ptr_ref_infos_count; +}; + +//////////////////////////////// +//~ rjf: Type Name -> Type Info + +#define type(T) (&T##__type) + +//////////////////////////////// +//~ rjf: Type Info Table Initializer Helpers + +#define member_lit_comp(S, ti, m, ...) {str8_lit_comp(#m), {0}, (ti), OffsetOf(S, m), __VA_ARGS__} +#define struct_members(S) read_only global Member S##__members[] = +#define struct_type(S, ...) read_only global Type S##__type = {TypeKind_Struct, 0, sizeof(S), &type_nil, str8_lit_comp(#S), {0}, ArrayCount(S##__members), S##__members, __VA_ARGS__} +#define named_struct_type(name, S, ...) read_only global Type name##__type = {TypeKind_Struct, 0, sizeof(S), &type_nil, str8_lit_comp(#name), {0}, ArrayCount(name##__members), name##__members, __VA_ARGS__} +#define ptr_type(name, ti, ...) read_only global Type name = {TypeKind_Ptr, 0, sizeof(void *), (ti), __VA_ARGS__} + +//////////////////////////////// +//~ rjf: Globals + +read_only global Type type_nil = {TypeKind_Null, 0, 0, &type_nil}; +read_only global Member member_nil = {{0}, {0}, &type_nil}; + +//////////////////////////////// +//~ rjf: Built-In Types + +//- rjf: leaves +read_only global Type void__type = {TypeKind_Void, 0, 0, &type_nil, str8_lit_comp("void")}; +read_only global Type U8__type = {TypeKind_U8, 0, sizeof(U8), &type_nil, str8_lit_comp("U8")}; +read_only global Type U16__type = {TypeKind_U16, 0, sizeof(U16), &type_nil, str8_lit_comp("U16")}; +read_only global Type U32__type = {TypeKind_U32, 0, sizeof(U32), &type_nil, str8_lit_comp("U32")}; +read_only global Type U64__type = {TypeKind_U64, 0, sizeof(U64), &type_nil, str8_lit_comp("U64")}; +read_only global Type S8__type = {TypeKind_S8, 0, sizeof(S8), &type_nil, str8_lit_comp("S8")}; +read_only global Type S16__type = {TypeKind_S16, 0, sizeof(S16), &type_nil, str8_lit_comp("S16")}; +read_only global Type S32__type = {TypeKind_S32, 0, sizeof(S32), &type_nil, str8_lit_comp("S32")}; +read_only global Type S64__type = {TypeKind_S64, 0, sizeof(S64), &type_nil, str8_lit_comp("S64")}; +read_only global Type B8__type = {TypeKind_B8, 0, sizeof(B8), &type_nil, str8_lit_comp("B8")}; +read_only global Type B16__type = {TypeKind_B16, 0, sizeof(B16), &type_nil, str8_lit_comp("B16")}; +read_only global Type B32__type = {TypeKind_B32, 0, sizeof(B32), &type_nil, str8_lit_comp("B32")}; +read_only global Type B64__type = {TypeKind_B64, 0, sizeof(B64), &type_nil, str8_lit_comp("B64")}; +read_only global Type F32__type = {TypeKind_F32, 0, sizeof(F32), &type_nil, str8_lit_comp("F32")}; +read_only global Type F64__type = {TypeKind_F64, 0, sizeof(F64), &type_nil, str8_lit_comp("F64")}; +read_only global Type *type_kind_type_table[] = +{ + &type_nil, + type(void), + type(U8), + type(U16), + type(U32), + type(U64), + type(S8), + type(S16), + type(S32), + type(S64), + type(B8), + type(B16), + type(B32), + type(B64), + type(F32), + type(F64), + &type_nil, + &type_nil, + &type_nil, + &type_nil, + &type_nil, +}; + +//- rjf: Rng1U64 +struct_members(Rng1U64) +{ + member_lit_comp(Rng1U64, type(U64), min), + member_lit_comp(Rng1U64, type(U64), max), +}; +struct_type(Rng1U64); + +//- rjf: String8 +ptr_type(String8__str_ptr_type, type(U8), str8_lit_comp("size")); +struct_members(String8) +{ + member_lit_comp(String8, &String8__str_ptr_type, str), + member_lit_comp(String8, type(U64), size), +}; +struct_type(String8); + +//- rjf: String8Node +extern Type String8Node__type; +Type String8Node__ptr_type = {TypeKind_Ptr, 0, sizeof(void *), &String8Node__type}; +Member String8Node__members[] = +{ + {str8_lit_comp("next"), {0}, &String8Node__ptr_type, OffsetOf(String8Node, next)}, + {str8_lit_comp("string"), {0}, type(String8), OffsetOf(String8Node, string)}, +}; +Type String8Node__type = +{ + TypeKind_Struct, + 0, + sizeof(String8Node), + &type_nil, + str8_lit_comp("String8Node"), + {0}, + ArrayCount(String8Node__members), + String8Node__members, +}; + +//- rjf: String8List +Member String8List__members[] = +{ + {str8_lit_comp("first"), {0}, &String8Node__ptr_type, OffsetOf(String8List, first)}, + {str8_lit_comp("last"), {0}, &String8Node__ptr_type, OffsetOf(String8List, last), MemberFlag_DoNotSerialize}, + {str8_lit_comp("node_count"), {0}, type(U64), OffsetOf(String8List, node_count)}, + {str8_lit_comp("total_size"), {0}, type(U64), OffsetOf(String8List, total_size)}, +}; +Type String8List__type = +{ + TypeKind_Struct, + 0, + sizeof(String8List), + &type_nil, + str8_lit_comp("String8List"), + {0}, + ArrayCount(String8List__members), + String8List__members, +}; + +//////////////////////////////// +//~ rjf: Type Info Lookups + +internal Member *member_from_name(Type *type, String8 name); +#define EachMember(T, it) (Member *it = (type(T))->members; it != 0 && it < (type(T))->members + (type(T))->count; it += 1) + +//////////////////////////////// +//~ rjf: Type Info * Instance Operations + +internal void typed_data_rebase_ptrs(Type *type, String8 data, void *base_ptr); +internal String8 serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params); +internal String8 deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params); +internal String8 deep_copy_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params); +#define struct_rebase_ptrs(T, ptr, base) typed_data_rebase_ptrs(type(T), str8_struct(ptr), (base)) +#define serialized_from_struct(arena, T, ptr, ...) serialized_from_typed_data((arena), type(T), str8_struct(ptr), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}) +#define struct_from_serialized(arena, T, string, ...) (T *)deserialized_from_typed_data((arena), type(T), (string), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}).str +#define deep_copy_from_struct(arena, T, ptr, ...) (T *)deep_copy_from_typed_data((arena), type(T), str8_struct(ptr), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}).str + +#endif // BASE_META_H diff --git a/src/metagen/metagen_base/metagen_base_profile.h b/src/metagen/metagen_base/metagen_base_profile.h index fa67b823..098270f4 100644 --- a/src/metagen/metagen_base/metagen_base_profile.h +++ b/src/metagen/metagen_base/metagen_base_profile.h @@ -43,26 +43,48 @@ # define ProfLockTake(...) tmAcquiredLock(0, 0, __VA_ARGS__) # define ProfLockDrop(...) tmReleasedLock(0, __VA_ARGS__) # define ProfColor(color) tmZoneColorSticky(color) +# define ProfBeginV(...) \ + if (TM_API_PTR) { \ + static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \ + Temp scratch = scratch_begin(0,0); \ + String8 string = push_str8f(scratch.arena, __VA_ARGS__); \ + tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \ + hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \ + TM_API_PTR->_tmEnterZoneFast_Core(0, 0, file_id, __LINE__, hash); \ + scratch_end(scratch); \ + } +# define ProfNoteV(...) \ + if (TM_API_PTR) { \ + static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \ + Temp scratch = scratch_begin(0,0); \ + String8 string = push_str8f(scratch.arena, __VA_ARGS__); \ + tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \ + hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \ + TM_API_PTR->_tmMessageFast_Core(0, TMMF_ICON_NOTE, file_id, __LINE__, hash); \ + scratch_end(scratch); \ + } #endif //////////////////////////////// //~ rjf: Zeroify Undefined Defines #if !defined(ProfBegin) -# define ProfBegin(...) (0) -# define ProfBeginDynamic(...) (0) -# define ProfEnd(...) (0) -# define ProfTick(...) (0) -# define ProfIsCapturing(...) (0) -# define ProfBeginCapture(...) (0) -# define ProfEndCapture(...) (0) -# define ProfThreadName(...) (0) -# define ProfMsg(...) (0) -# define ProfBeginLockWait(...) (0) -# define ProfEndLockWait(...) (0) -# define ProfLockTake(...) (0) -# define ProfLockDrop(...) (0) -# define ProfColor(...) (0) +# define ProfBegin(...) (0) +# define ProfBeginDynamic(...) (0) +# define ProfEnd(...) (0) +# define ProfTick(...) (0) +# define ProfIsCapturing(...) (0) +# define ProfBeginCapture(...) (0) +# define ProfEndCapture(...) (0) +# define ProfThreadName(...) (0) +# define ProfMsg(...) (0) +# define ProfBeginLockWait(...) (0) +# define ProfEndLockWait(...) (0) +# define ProfLockTake(...) (0) +# define ProfLockDrop(...) (0) +# define ProfColor(...) (0) +# define ProfBeginV(...) (0) +# define ProfNoteV(...) (0) #endif //////////////////////////////// diff --git a/src/metagen/metagen_base/metagen_base_strings.c b/src/metagen/metagen_base/metagen_base_strings.c index 91a47562..9e42e0cd 100644 --- a/src/metagen/metagen_base/metagen_base_strings.c +++ b/src/metagen/metagen_base/metagen_base_strings.c @@ -215,12 +215,42 @@ str32_cstring(U32 *c){ internal String8 str8_cstring_capped(void *cstr, void *cap) { - char *ptr = (char*)cstr; - char *opl = (char*)cap; + char *ptr = (char *)cstr; + char *opl = (char *)cap; for (;ptr < opl && *ptr != 0; ptr += 1); U64 size = (U64)(ptr - (char *)cstr); - String8 result = {(U8*)cstr, size}; - return(result); + String8 result = str8((U8*)cstr, size); + return result; +} + +internal String16 +str16_cstring_capped(void *cstr, void *cap) +{ + U16 *ptr = (U16 *)cstr; + U16 *opl = (U16 *)cap; + for (;ptr < opl && *ptr != 0; ptr += 1); + U64 size = (U64)(ptr - (U16 *)cstr); + String16 result = str16(cstr, size); + return result; +} + +internal String8 +str8_cstring_capped_reverse(void *raw_start, void *raw_cap) +{ + U8 *start = raw_start; + U8 *ptr = raw_cap; + for(; ptr > start; ) + { + ptr -= 1; + + if (*ptr == '\0') + { + break; + } + } + U64 size = (U64)(ptr - start); + String8 result = str8(start, size); + return result; } //////////////////////////////// @@ -263,31 +293,41 @@ backslashed_from_str8(Arena *arena, String8 string) //~ rjf: String Matching internal B32 -str8_match(String8 a, String8 b, StringMatchFlags flags){ +str8_match(String8 a, String8 b, StringMatchFlags flags) +{ B32 result = 0; - if (a.size == b.size || (flags & StringMatchFlag_RightSideSloppy)){ - B32 case_insensitive = (flags & StringMatchFlag_CaseInsensitive); + if(a.size == b.size && flags == 0) + { + result = MemoryMatch(a.str, b.str, b.size); + } + else if(a.size == b.size || (flags & StringMatchFlag_RightSideSloppy)) + { + B32 case_insensitive = (flags & StringMatchFlag_CaseInsensitive); B32 slash_insensitive = (flags & StringMatchFlag_SlashInsensitive); - U64 size = Min(a.size, b.size); + U64 size = Min(a.size, b.size); result = 1; - for (U64 i = 0; i < size; i += 1){ + for(U64 i = 0; i < size; i += 1) + { U8 at = a.str[i]; U8 bt = b.str[i]; - if (case_insensitive){ + if(case_insensitive) + { at = char_to_upper(at); bt = char_to_upper(bt); } - if (slash_insensitive){ + if(slash_insensitive) + { at = char_to_correct_slash(at); bt = char_to_correct_slash(bt); } - if (at != bt){ + if(at != bt) + { result = 0; break; } } } - return(result); + return result; } internal U64 @@ -322,6 +362,22 @@ str8_find_needle(String8 string, U64 start_pos, String8 needle, StringMatchFlags return(result); } +internal U64 +str8_find_needle_reverse(String8 string, U64 start_pos, String8 needle, StringMatchFlags flags) +{ + U64 result = 0; + for(S64 i = string.size - start_pos - needle.size; i >= 0; --i) + { + String8 haystack = str8_substr(string, rng_1u64(i, i + needle.size)); + if(str8_match(haystack, needle, flags)) + { + result = (U64)i + needle.size; + break; + } + } + return result; +} + internal B32 str8_ends_with(String8 string, String8 end, StringMatchFlags flags){ String8 postfix = str8_postfix(string, end.size); @@ -500,6 +556,22 @@ s64_from_str8(String8 string, U32 radix){ return(x); } +internal U32 +u32_from_str8(String8 string, U32 radix) +{ + U64 x64 = u64_from_str8(string, radix); + U32 x32 = safe_cast_u32(x64); + return x32; +} + +internal S32 +s32_from_str8(String8 string, U32 radix) +{ + S64 x64 = s64_from_str8(string, radix); + S32 x32 = safe_cast_s32(x64); + return x32; +} + internal B32 try_u64_from_str8_c_rules(String8 string, U64 *x){ B32 is_integer = 0; @@ -544,21 +616,121 @@ try_s64_from_str8_c_rules(String8 string, S64 *x){ //- rjf: integer -> string internal String8 -str8_from_memory_size(Arena *arena, U64 z){ - String8 result = {0}; - if (z < KB(1)){ - result = push_str8f(arena, "%llu b", z); +str8_from_memory_size(Arena *arena, U64 size) +{ + String8 result; + + if(size < KB(1)) + { + result = push_str8f(arena, "%llu Bytes", size); } - else if (z < MB(1)){ - result = push_str8f(arena, "%llu.%02llu Kb", z/KB(1), ((100*z)/KB(1))%100); + else if(size < MB(1)) + { + result = push_str8f(arena, "%llu.%02llu KiB", size / KB(1), ((size * 100) / KB(1)) % 100); } - else if (z < GB(1)){ - result = push_str8f(arena, "%llu.%02llu Mb", z/MB(1), ((100*z)/MB(1))%100); + else if(size < GB(1)) + { + result = push_str8f(arena, "%llu.%02llu MiB", size / MB(1), ((size * 100) / MB(1)) % 100); } - else{ - result = push_str8f(arena, "%llu.%02llu Gb", z/GB(1), ((100*z)/GB(1))%100); + else if(size < TB(1)) + { + result = push_str8f(arena, "%llu.%02llu GiB", size / GB(1), ((size * 100) / GB(1)) % 100); } - return(result); + else + { + result = push_str8f(arena, "%llu.%02llu TiB", size / TB(1), ((size * 100) / TB(1)) % 100); + } + + return result; +} + +internal String8 +str8_from_count(Arena *arena, U64 count) +{ + String8 result; + + if(count < 1 * 1000) + { + result = push_str8f(arena, "%llu", count); + } + else if(count < 1000000) + { + U64 frac = ((count * 100) / 1000) % 100; + if(frac > 0) + { + result = push_str8f(arena, "%llu.%02lluK", count / 1000, frac); + } + else + { + result = push_str8f(arena, "%lluK", count / 1000); + } + } + else if(count < 1000000000) + { + U64 frac = ((count * 100) / 1000000) % 100; + if(frac > 0) + { + result = push_str8f(arena, "%llu.%02lluM", count / 1000000, frac); + } + else + { + result = push_str8f(arena, "%lluM", count / 1000000); + } + } + else + { + U64 frac = ((count * 100) * 1000000000) % 100; + if(frac > 0) + { + result = push_str8f(arena, "%llu.%02lluB", count / 1000000000, frac); + } + else + { + result = push_str8f(arena, "%lluB", count / 1000000000, frac); + } + } + + return result; +} + +internal String8 +str8_from_bits_u32(Arena *arena, U32 x) +{ + U8 c0 = 'a' + ((x >> 28) & 0xf); + U8 c1 = 'a' + ((x >> 24) & 0xf); + U8 c2 = 'a' + ((x >> 20) & 0xf); + U8 c3 = 'a' + ((x >> 16) & 0xf); + U8 c4 = 'a' + ((x >> 12) & 0xf); + U8 c5 = 'a' + ((x >> 8) & 0xf); + U8 c6 = 'a' + ((x >> 4) & 0xf); + U8 c7 = 'a' + ((x >> 0) & 0xf); + String8 result = push_str8f(arena, "%c%c%c%c%c%c%c%c", c0, c1, c2, c3, c4, c5, c6, c7); + return result; +} + +internal String8 +str8_from_bits_u64(Arena *arena, U64 x) +{ + U8 c0 = 'a' + ((x >> 60) & 0xf); + U8 c1 = 'a' + ((x >> 56) & 0xf); + U8 c2 = 'a' + ((x >> 52) & 0xf); + U8 c3 = 'a' + ((x >> 48) & 0xf); + U8 c4 = 'a' + ((x >> 44) & 0xf); + U8 c5 = 'a' + ((x >> 40) & 0xf); + U8 c6 = 'a' + ((x >> 36) & 0xf); + U8 c7 = 'a' + ((x >> 32) & 0xf); + U8 c8 = 'a' + ((x >> 28) & 0xf); + U8 c9 = 'a' + ((x >> 24) & 0xf); + U8 ca = 'a' + ((x >> 20) & 0xf); + U8 cb = 'a' + ((x >> 16) & 0xf); + U8 cc = 'a' + ((x >> 12) & 0xf); + U8 cd = 'a' + ((x >> 8) & 0xf); + U8 ce = 'a' + ((x >> 4) & 0xf); + U8 cf = 'a' + ((x >> 0) & 0xf); + String8 result = push_str8f(arena, + "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf); + return result; } internal String8 @@ -685,27 +857,28 @@ f64_from_str8(String8 string) { // rjf: find starting pos of numeric string, as well as sign F64 sign = +1.0; - //U64 first_numeric = 0; if(string.str[0] == '-') { - //first_numeric = 1; sign = -1.0; } else if(string.str[0] == '+') { - //first_numeric = 1; sign = 1.0; } // rjf: gather numerics U64 num_valid_chars = 0; char buffer[64]; + B32 exp = 0; for(U64 idx = 0; idx < string.size && num_valid_chars < sizeof(buffer)-1; idx += 1) { - if(char_is_digit(string.str[idx], 10) || string.str[idx] == '.') + if(char_is_digit(string.str[idx], 10) || string.str[idx] == '.' || string.str[idx] == 'e' || + (exp && (string.str[idx] == '+' || string.str[idx] == '-'))) { buffer[num_valid_chars] = string.str[idx]; num_valid_chars += 1; + exp = 0; + exp = (string.str[idx] == 'e'); } } @@ -1138,7 +1311,9 @@ str8_path_list_resolve_dots_in_place(String8List *path, PathStyle style){ internal String8 str8_path_list_join_by_style(Arena *arena, String8List *path, PathStyle style){ StringJoin params = {0}; - switch (style){ + switch(style) + { + case PathStyle_Null:{}break; case PathStyle_Relative: case PathStyle_WindowsAbsolute: { @@ -1151,9 +1326,8 @@ str8_path_list_join_by_style(Arena *arena, String8List *path, PathStyle style){ params.sep = str8_lit("/"); }break; } - String8 result = str8_list_join(arena, path, ¶ms); - return(result); + return result; } internal String8TxtPtPair @@ -1346,70 +1520,127 @@ utf8_from_utf32_single(U8 *buffer, U32 character){ //~ rjf: Unicode String Conversions internal String8 -str8_from_16(Arena *arena, String16 in){ - U64 cap = in.size*3; - U8 *str = push_array_no_zero(arena, U8, cap + 1); - U16 *ptr = in.str; - U16 *opl = ptr + in.size; - U64 size = 0; - UnicodeDecode consume; - for (;ptr < opl; ptr += consume.inc){ - consume = utf16_decode(ptr, opl - ptr); - size += utf8_encode(str + size, consume.codepoint); +str8_from_16(Arena *arena, String16 in) +{ + String8 result = str8_zero(); + if(in.size) + { + U64 cap = in.size*3; + U8 *str = push_array_no_zero(arena, U8, cap + 1); + U16 *ptr = in.str; + U16 *opl = ptr + in.size; + U64 size = 0; + UnicodeDecode consume; + for(;ptr < opl; ptr += consume.inc) + { + consume = utf16_decode(ptr, opl - ptr); + size += utf8_encode(str + size, consume.codepoint); + } + str[size] = 0; + arena_pop(arena, (cap - size)); + result = str8(str, size); } - str[size] = 0; - arena_pop(arena, (cap - size)); - return(str8(str, size)); + return result; } internal String16 -str16_from_8(Arena *arena, String8 in){ - U64 cap = in.size*2; - U16 *str = push_array_no_zero(arena, U16, cap + 1); - U8 *ptr = in.str; - U8 *opl = ptr + in.size; - U64 size = 0; - UnicodeDecode consume; - for (;ptr < opl; ptr += consume.inc){ - consume = utf8_decode(ptr, opl - ptr); - size += utf16_encode(str + size, consume.codepoint); +str16_from_8(Arena *arena, String8 in) +{ + String16 result = str16_zero(); + if(in.size) + { + U64 cap = in.size*2; + U16 *str = push_array_no_zero(arena, U16, cap + 1); + U8 *ptr = in.str; + U8 *opl = ptr + in.size; + U64 size = 0; + UnicodeDecode consume; + for(;ptr < opl; ptr += consume.inc) + { + consume = utf8_decode(ptr, opl - ptr); + size += utf16_encode(str + size, consume.codepoint); + } + str[size] = 0; + arena_pop(arena, (cap - size)*2); + result = str16(str, size); } - str[size] = 0; - arena_pop(arena, (cap - size)*2); - return(str16(str, size)); + return result; } internal String8 -str8_from_32(Arena *arena, String32 in){ - U64 cap = in.size*4; - U8 *str = push_array_no_zero(arena, U8, cap + 1); - U32 *ptr = in.str; - U32 *opl = ptr + in.size; - U64 size = 0; - for (;ptr < opl; ptr += 1){ - size += utf8_encode(str + size, *ptr); +str8_from_32(Arena *arena, String32 in) +{ + String8 result = str8_zero(); + if(in.size) + { + U64 cap = in.size*4; + U8 *str = push_array_no_zero(arena, U8, cap + 1); + U32 *ptr = in.str; + U32 *opl = ptr + in.size; + U64 size = 0; + for(;ptr < opl; ptr += 1) + { + size += utf8_encode(str + size, *ptr); + } + str[size] = 0; + arena_pop(arena, (cap - size)); + result = str8(str, size); } - str[size] = 0; - arena_pop(arena, (cap - size)); - return(str8(str, size)); + return result; } internal String32 -str32_from_8(Arena *arena, String8 in){ - U64 cap = in.size; - U32 *str = push_array_no_zero(arena, U32, cap + 1); - U8 *ptr = in.str; - U8 *opl = ptr + in.size; - U64 size = 0; - UnicodeDecode consume; - for (;ptr < opl; ptr += consume.inc){ - consume = utf8_decode(ptr, opl - ptr); - str[size] = consume.codepoint; - size += 1; +str32_from_8(Arena *arena, String8 in) +{ + String32 result = str32_zero(); + if(in.size) + { + U64 cap = in.size; + U32 *str = push_array_no_zero(arena, U32, cap + 1); + U8 *ptr = in.str; + U8 *opl = ptr + in.size; + U64 size = 0; + UnicodeDecode consume; + for(;ptr < opl; ptr += consume.inc) + { + consume = utf8_decode(ptr, opl - ptr); + str[size] = consume.codepoint; + size += 1; + } + str[size] = 0; + arena_pop(arena, (cap - size)*4); + result = str32(str, size); } - str[size] = 0; - arena_pop(arena, (cap - size)*4); - return(str32(str, size)); + return result; +} + +//////////////////////////////// +//~ String -> Enum Conversions + +read_only global struct +{ + String8 string; + OperatingSystem os; +} g_os_enum_map[] = +{ + { str8_lit_comp(""), OperatingSystem_Null }, + { str8_lit_comp("Windows"), OperatingSystem_Windows, }, + { str8_lit_comp("Linux"), OperatingSystem_Linux, }, + { str8_lit_comp("Mac"), OperatingSystem_Mac, }, +}; +StaticAssert(ArrayCount(g_os_enum_map) == OperatingSystem_COUNT, g_os_enum_map_count_check); + +internal OperatingSystem +operating_system_from_string(String8 string) +{ + for(U64 i = 0; i < ArrayCount(g_os_enum_map); ++i) + { + if(str8_match(g_os_enum_map[i].string, string, StringMatchFlag_CaseInsensitive)) + { + return g_os_enum_map[i].os; + } + } + return OperatingSystem_Null; } //////////////////////////////// @@ -1444,22 +1675,18 @@ string_from_side(Side side){ } internal String8 -string_from_operating_system(OperatingSystem os){ - local_persist String8 strings[] = { - str8_lit_comp("Null"), - str8_lit_comp("Windows"), - str8_lit_comp("Linux"), - str8_lit_comp("Mac"), - }; - String8 result = str8_lit("error"); - if (os < OperatingSystem_COUNT){ - result = strings[os]; +string_from_operating_system(OperatingSystem os) +{ + String8 result = g_os_enum_map[OperatingSystem_Null].string; + if(os < ArrayCount(g_os_enum_map)) + { + result = g_os_enum_map[os].string; } - return(result); + return result; } internal String8 -string_from_architecture(Architecture arch){ +string_from_arch(Arch arch){ local_persist String8 strings[] = { str8_lit_comp("Null"), str8_lit_comp("x64"), @@ -1468,7 +1695,7 @@ string_from_architecture(Architecture arch){ str8_lit_comp("arm32"), }; String8 result = str8_lit("error"); - if (arch < Architecture_COUNT){ + if (arch < Arch_COUNT){ result = strings[arch]; } return(result); @@ -1565,6 +1792,78 @@ string_from_elapsed_time(Arena *arena, DateTime dt){ return(result); } +//////////////////////////////// +//~ Globally UNique Ids + +internal String8 +string_from_guid(Arena *arena, Guid guid) +{ + String8 result = push_str8f(arena, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + guid.data1, + guid.data2, + guid.data3, + guid.data4[0], + guid.data4[1], + guid.data4[2], + guid.data4[3], + guid.data4[4], + guid.data4[5], + guid.data4[6], + guid.data4[7]); + return result; +} + +internal B32 +try_guid_from_string(String8 string, Guid *guid_out) +{ + Temp scratch = scratch_begin(0,0); + B32 is_parsed = 0; + String8List list = str8_split_by_string_chars(scratch.arena, string, str8_lit("-"), StringSplitFlag_KeepEmpties); + if(list.node_count == 5) + { + String8 data1_str = list.first->string; + String8 data2_str = list.first->next->string; + String8 data3_str = list.first->next->next->string; + String8 data4_hi_str = list.first->next->next->next->string; + String8 data4_lo_str = list.first->next->next->next->next->string; + if(str8_is_integer(data1_str, 16) && + str8_is_integer(data2_str, 16) && + str8_is_integer(data3_str, 16) && + str8_is_integer(data4_hi_str, 16) && + str8_is_integer(data4_lo_str, 16)) + { + U64 data1 = u64_from_str8(data1_str, 16); + U64 data2 = u64_from_str8(data2_str, 16); + U64 data3 = u64_from_str8(data3_str, 16); + U64 data4_hi = u64_from_str8(data4_hi_str, 16); + U64 data4_lo = u64_from_str8(data4_lo_str, 16); + if(data1 <= max_U32 && + data2 <= max_U16 && + data3 <= max_U16 && + data4_hi <= max_U16 && + data4_lo <= 0xffffffffffff) + { + guid_out->data1 = (U32)data1; + guid_out->data2 = (U16)data2; + guid_out->data3 = (U16)data3; + U64 data4 = (data4_hi << 48) | data4_lo; + MemoryCopy(&guid_out->data4[0], &data4, sizeof(data4)); + is_parsed = 1; + } + } + } + scratch_end(scratch); + return is_parsed; +} + +internal Guid +guid_from_string(String8 string) +{ + Guid guid = {0}; + try_guid_from_string(string, &guid); + return guid; +} + //////////////////////////////// //~ rjf: Basic Text Indentation @@ -1593,6 +1892,10 @@ indented_from_string(Arena *arena, String8 string) { str8_list_pushf(scratch.arena, &indented_strings, "%.*s%S\n", (int)depth*2, indentation_bytes, line); } + if(line.size == 0 && indented_strings.node_count != 0 && off < string.size) + { + str8_list_pushf(scratch.arena, &indented_strings, "\n"); + } line_begin_off = off+1; depth = next_depth; }break; @@ -1603,6 +1906,100 @@ indented_from_string(Arena *arena, String8 string) return result; } +//////////////////////////////// +//~ rjf: Text Escaping + +internal String8 +escaped_from_raw_str8(Arena *arena, String8 string) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List parts = {0}; + U64 start_split_idx = 0; + for(U64 idx = 0; idx <= string.size; idx += 1) + { + U8 byte = (idx < string.size) ? string.str[idx] : 0; + B32 split = 1; + String8 separator_replace = {0}; + switch(byte) + { + default:{split = 0;}break; + case 0: {}break; + case '\a': {separator_replace = str8_lit("\\a");}break; + case '\b': {separator_replace = str8_lit("\\b");}break; + case '\f': {separator_replace = str8_lit("\\f");}break; + case '\n': {separator_replace = str8_lit("\\n");}break; + case '\r': {separator_replace = str8_lit("\\r");}break; + case '\t': {separator_replace = str8_lit("\\t");}break; + case '\v': {separator_replace = str8_lit("\\v");}break; + case '\\': {separator_replace = str8_lit("\\\\");}break; + case '"': {separator_replace = str8_lit("\\\"");}break; + case '?': {separator_replace = str8_lit("\\?");}break; + } + if(split) + { + String8 substr = str8_substr(string, r1u64(start_split_idx, idx)); + start_split_idx = idx+1; + str8_list_push(scratch.arena, &parts, substr); + if(separator_replace.size != 0) + { + str8_list_push(scratch.arena, &parts, separator_replace); + } + } + } + StringJoin join = {0}; + String8 result = str8_list_join(arena, &parts, &join); + scratch_end(scratch); + return result; +} + +internal String8 +raw_from_escaped_str8(Arena *arena, String8 string) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List strs = {0}; + U64 start = 0; + for(U64 idx = 0; idx <= string.size; idx += 1) + { + if(idx == string.size || string.str[idx] == '\\' || string.str[idx] == '\r') + { + String8 str = str8_substr(string, r1u64(start, idx)); + if(str.size != 0) + { + str8_list_push(scratch.arena, &strs, str); + } + start = idx+1; + } + if(idx < string.size && string.str[idx] == '\\') + { + U8 next_char = string.str[idx+1]; + U8 replace_byte = 0; + switch(next_char) + { + default:{}break; + case 'a': replace_byte = 0x07; break; + case 'b': replace_byte = 0x08; break; + case 'e': replace_byte = 0x1b; break; + case 'f': replace_byte = 0x0c; break; + case 'n': replace_byte = 0x0a; break; + case 'r': replace_byte = 0x0d; break; + case 't': replace_byte = 0x09; break; + case 'v': replace_byte = 0x0b; break; + case '\\':replace_byte = '\\'; break; + case '\'':replace_byte = '\''; break; + case '"': replace_byte = '"'; break; + case '?': replace_byte = '?'; break; + } + String8 replace_string = push_str8_copy(scratch.arena, str8(&replace_byte, 1)); + str8_list_push(scratch.arena, &strs, replace_string); + idx += 1; + start += 1; + } + } + String8 result = str8_list_join(arena, &strs, 0); + scratch_end(scratch); + return result; +} + //////////////////////////////// //~ rjf: Text Wrapping @@ -1973,3 +2370,77 @@ str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out) *block_out = str8_substr(string, range); return block_out->size; } + +internal U64 +str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out) +{ + U64 value = 0; + U64 shift = 0; + U64 cursor = off; + for(;;) + { + U8 byte = 0; + U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); + + if(bytes_read != sizeof(byte)) + { + break; + } + + U8 val = byte & 0x7fu; + value |= ((U64)val) << shift; + + cursor += bytes_read; + shift += 7u; + + if((byte & 0x80u) == 0) + { + break; + } + } + if(value_out != 0) + { + *value_out = value; + } + U64 bytes_read = cursor - off; + return bytes_read; +} + +internal U64 +str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out) +{ + U64 value = 0; + U64 shift = 0; + U64 cursor = off; + for(;;) + { + U8 byte; + U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); + if(bytes_read != sizeof(byte)) + { + break; + } + + U8 val = byte & 0x7fu; + value |= ((U64)val) << shift; + + cursor += bytes_read; + shift += 7u; + + if((byte & 0x80u) == 0) + { + if(shift < sizeof(value) * 8 && (byte & 0x40u) != 0) + { + value |= -(S64)(1ull << shift); + } + break; + } + } + if(value_out != 0) + { + *value_out = value; + } + U64 bytes_read = cursor - off; + return bytes_read; +} + diff --git a/src/metagen/metagen_base/metagen_base_strings.h b/src/metagen/metagen_base/metagen_base_strings.h index c68bdff6..fc946dd8 100644 --- a/src/metagen/metagen_base/metagen_base_strings.h +++ b/src/metagen/metagen_base/metagen_base_strings.h @@ -86,6 +86,7 @@ enum typedef enum PathStyle { + PathStyle_Null, PathStyle_Relative, PathStyle_WindowsAbsolute, PathStyle_UnixAbsolute, @@ -192,6 +193,8 @@ internal String8 str8_cstring(char *c); internal String16 str16_cstring(U16 *c); internal String32 str32_cstring(U32 *c); internal String8 str8_cstring_capped(void *cstr, void *cap); +internal String16 str16_cstring_capped(void *cstr, void *cap); +internal String8 str8_cstring_capped_reverse(void *raw_start, void *raw_cap); //////////////////////////////// //~ rjf: String Stylization @@ -205,6 +208,7 @@ internal String8 backslashed_from_str8(Arena *arena, String8 string); internal B32 str8_match(String8 a, String8 b, StringMatchFlags flags); internal U64 str8_find_needle(String8 string, U64 start_pos, String8 needle, StringMatchFlags flags); +internal U64 str8_find_needle_reverse(String8 string, U64 start_pos, String8 needle, StringMatchFlags flags); internal B32 str8_ends_with(String8 string, String8 end, StringMatchFlags flags); //////////////////////////////// @@ -231,13 +235,19 @@ internal String8 push_str8f(Arena *arena, char *fmt, ...); //- rjf: string -> integer internal S64 sign_from_str8(String8 string, String8 *string_tail); internal B32 str8_is_integer(String8 string, U32 radix); + internal U64 u64_from_str8(String8 string, U32 radix); internal S64 s64_from_str8(String8 string, U32 radix); +internal U32 u32_from_str8(String8 string, U32 radix); +internal S32 s32_from_str8(String8 string, U32 radix); internal B32 try_u64_from_str8_c_rules(String8 string, U64 *x); internal B32 try_s64_from_str8_c_rules(String8 string, S64 *x); //- rjf: integer -> string -internal String8 str8_from_memory_size(Arena *arena, U64 z); +internal String8 str8_from_memory_size(Arena *arena, U64 size); +internal String8 str8_from_count(Arena *arena, U64 count); +internal String8 str8_from_bits_u32(Arena *arena, U32 x); +internal String8 str8_from_bits_u64(Arena *arena, U64 x); internal String8 str8_from_u64(Arena *arena, U64 u64, U32 radix, U8 min_digits, U8 digit_group_separator); internal String8 str8_from_s64(Arena *arena, S64 s64, U32 radix, U8 min_digits, U8 digit_group_separator); @@ -309,13 +319,18 @@ internal String16 str16_from_8(Arena *arena, String8 in); internal String8 str8_from_32(Arena *arena, String32 in); internal String32 str32_from_8(Arena *arena, String8 in); +//////////////////////////////// +//~ String -> Enum Conversions + +internal OperatingSystem operating_system_from_string(String8 string); + //////////////////////////////// //~ rjf: Basic Types & Space Enum -> String Conversions internal String8 string_from_dimension(Dimension dimension); internal String8 string_from_side(Side side); internal String8 string_from_operating_system(OperatingSystem os); -internal String8 string_from_architecture(Architecture arch); +internal String8 string_from_arch(Arch arch); //////////////////////////////// //~ rjf: Time Types -> String @@ -326,11 +341,24 @@ internal String8 push_date_time_string(Arena *arena, DateTime *date_time); internal String8 push_file_name_date_time_string(Arena *arena, DateTime *date_time); internal String8 string_from_elapsed_time(Arena *arena, DateTime dt); +//////////////////////////////// +//~ Globally Unique Ids + +internal String8 string_from_guid(Arena *arena, Guid guid); +internal B32 try_guid_from_string(String8 string, Guid *guid_out); +internal Guid guid_from_string(String8 string); + //////////////////////////////// //~ rjf: Basic Text Indentation internal String8 indented_from_string(Arena *arena, String8 string); +//////////////////////////////// +//~ rjf: Text Escaping + +internal String8 escaped_from_raw_str8(Arena *arena, String8 string); +internal String8 raw_from_escaped_str8(Arena *arena, String8 string); + //////////////////////////////// //~ rjf: Text Wrapping @@ -372,10 +400,13 @@ internal void str8_serial_push_string(Arena *arena, String8List *srl, String8 internal U64 str8_deserial_read(String8 string, U64 off, void *read_dst, U64 read_size, U64 granularity); internal U64 str8_deserial_find_first_match(String8 string, U64 off, U16 scan_val); -internal void * str8_deserial_get_raw_ptr(String8 string, U64 off, U64 size);internal U64 str8_deserial_read_cstr(String8 string, U64 off, String8 *cstr_out); +internal void * str8_deserial_get_raw_ptr(String8 string, U64 off, U64 size); +internal U64 str8_deserial_read_cstr(String8 string, U64 off, String8 *cstr_out); internal U64 str8_deserial_read_windows_utf16_string16(String8 string, U64 off, String16 *str_out); internal U64 str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out); +internal U64 str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out); +internal U64 str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out); #define str8_deserial_read_array(string, off, ptr, count) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr))*(count), sizeof(*(ptr))) -#define str8_deserial_read_struct(string, off, ptr) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr)), sizeof(*(ptr))) +#define str8_deserial_read_struct(string, off, ptr) str8_deserial_read_array(string, off, ptr, 1) #endif // BASE_STRINGS_H diff --git a/src/metagen/metagen_base/metagen_base_thread_context.h b/src/metagen/metagen_base/metagen_base_thread_context.h index 90a396fe..b2515c93 100644 --- a/src/metagen/metagen_base/metagen_base_thread_context.h +++ b/src/metagen/metagen_base/metagen_base_thread_context.h @@ -26,7 +26,7 @@ internal void tctx_init_and_equip(TCTX *tctx); internal void tctx_release(void); internal TCTX* tctx_get_equipped(void); -internal Arena* tctx_get_scratch(Arena **conflicts, U64 count); +internal Arena* tctx_get_scratch(Arena **conflicts, U64 countt); internal void tctx_set_thread_name(String8 name); internal String8 tctx_get_thread_name(void); diff --git a/src/metagen/metagen_main.c b/src/metagen/metagen_main.c index 2323a6d9..24c645b1 100644 --- a/src/metagen/metagen_main.c +++ b/src/metagen/metagen_main.c @@ -246,8 +246,7 @@ entry_point(CmdLine *cmdline) } for(String8Node *n = gen_strings.first; n != 0; n = n->next) { - String8 escaped = mg_escaped_from_str8(mg_arena, n->string); - str8_list_pushf(mg_arena, &layer->enums, "%S_%S,\n", enum_member_prefix, escaped); + str8_list_pushf(mg_arena, &layer->enums, "%S_%S,\n", enum_member_prefix, n->string); } if(enum_base_type_name.size == 0) { @@ -278,8 +277,7 @@ entry_point(CmdLine *cmdline) str8_list_pushf(mg_arena, &layer->enums, "#define %S \\\n", node->string); for(String8Node *n = gen_strings.first; n != 0; n = n->next) { - String8 escaped = mg_escaped_from_str8(mg_arena, n->string); - str8_list_pushf(mg_arena, &layer->enums, "X(%S)\\\n", escaped); + str8_list_pushf(mg_arena, &layer->enums, "X(%S)\\\n", n->string); } str8_list_push(mg_arena, &layer->enums, str8_lit("\n")); } @@ -303,8 +301,7 @@ entry_point(CmdLine *cmdline) str8_list_pushf(mg_arena, &layer->structs, "struct %S\n{\n", node->string); for(String8Node *n = gen_strings.first; n != 0; n = n->next) { - String8 escaped = mg_escaped_from_str8(mg_arena, n->string); - str8_list_pushf(mg_arena, &layer->structs, "%S;\n", escaped); + str8_list_pushf(mg_arena, &layer->structs, "%S;\n", n->string); } str8_list_pushf(mg_arena, &layer->structs, "};\n\n"); } @@ -333,8 +330,7 @@ entry_point(CmdLine *cmdline) str8_list_pushf(mg_arena, &layer->c_tables, "%S %S[%I64u] =\n{\n", element_type, node->string, gen_strings.node_count); for(String8Node *n = gen_strings.first; n != 0; n = n->next) { - String8 escaped = mg_escaped_from_str8(mg_arena, n->string); - str8_list_pushf(mg_arena, &layer->c_tables, "%S,\n", escaped); + str8_list_pushf(mg_arena, &layer->c_tables, "%S,\n", n->string); } str8_list_push(mg_arena, &layer->c_tables, str8_lit("};\n\n")); } @@ -364,8 +360,7 @@ entry_point(CmdLine *cmdline) str8_list_pushf(mg_arena, &layer->c_functions, "default:{}break;\n"); for(String8Node *n = gen_strings.first; n != 0; n = n->next) { - String8 escaped = mg_escaped_from_str8(mg_arena, n->string); - str8_list_pushf(mg_arena, &layer->c_functions, "%S;\n", escaped); + str8_list_pushf(mg_arena, &layer->c_functions, "%S;\n", n->string); } str8_list_pushf(mg_arena, &layer->c_functions, "}\n"); str8_list_pushf(mg_arena, &layer->c_functions, "return result;\n"); @@ -398,8 +393,7 @@ entry_point(CmdLine *cmdline) for(String8Node *n = gen_strings.first; n != 0; n = n->next) { String8 trimmed = str8_skip_chop_whitespace(n->string); - String8 escaped = mg_escaped_from_str8(mg_arena, trimmed); - str8_list_push(mg_arena, out, escaped); + str8_list_push(mg_arena, out, trimmed); str8_list_push(mg_arena, out, str8_lit("\n")); } } diff --git a/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c b/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c index 37e02710..876f0d91 100644 --- a/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c +++ b/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c @@ -1628,7 +1628,7 @@ w32_entry_point_caller(int argc, WCHAR **wargv) } //- rjf: call into "real" entry point - main_thread_base_entry_point(entry_point, argv, (U64)argc); + main_thread_base_entry_point(argc, argv); } #if BUILD_CONSOLE_INTERFACE diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index c628a0ff..e9c96ee3 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -73,11 +73,12 @@ RD_VocabularyInfo rd_vocabulary_info_table[41] = {str8_lit_comp("label"), str8_lit_comp("labels"), str8_lit_comp("Label"), str8_lit_comp("Labels"), RD_IconKind_Null}, }; -RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[5] = +RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6] = { -{str8_lit_comp("target"), str8_lit_comp("x:{'label':code_string, 'exe':path, 'args':string, 'working_directory':path, 'entry_point':code_string, 'stdout_path':path, 'stderr_path':path, 'stdin_path':path, 'debug_subprocesses':bool}")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("x:{'label':code_string, 'condition':code_string, 'location':location, 'hit_count':u64, 'enabled':bool}")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("x:{'expression':code_string, 'view_rule':code_string, 'location':location}")}, +{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'exe': path,\n 'args': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'condition': code_string,\n 'location': location,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("x:\n{\n 'expression':code_string,\n 'view_rule':code_string,\n 'location':location,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("x:{'source':code_string, 'dest':code_string}")}, }; @@ -1897,120 +1898,5 @@ str8_lit_comp("breakpoint"), str8_lit_comp("cache_line_boundary"), }; -String8 rd_setting_code_display_string_table[19] = -{ -str8_lit_comp("Hover Animations"), -str8_lit_comp("Press Animations"), -str8_lit_comp("Focus Animations"), -str8_lit_comp("Tooltip Animations"), -str8_lit_comp("Menu Animations"), -str8_lit_comp("Scrolling Animations"), -str8_lit_comp("Background Blur"), -str8_lit_comp("Thread Lines"), -str8_lit_comp("Breakpoint Lines"), -str8_lit_comp("Thread Glow"), -str8_lit_comp("Breakpoint Glow"), -str8_lit_comp("Opaque Backgrounds"), -str8_lit_comp("Tab Width"), -str8_lit_comp("Main Font Size"), -str8_lit_comp("Code Font Size"), -str8_lit_comp("Smooth UI Text"), -str8_lit_comp("Smooth Code Text"), -str8_lit_comp("Hint UI Text"), -str8_lit_comp("Hint Code Text"), -}; - -String8 rd_setting_code_lower_string_table[19] = -{ -str8_lit_comp("hover_animations"), -str8_lit_comp("press_animations"), -str8_lit_comp("focus_animations"), -str8_lit_comp("tooltip_animations"), -str8_lit_comp("menu_animations"), -str8_lit_comp("scrolling_animations"), -str8_lit_comp("background_blur"), -str8_lit_comp("thread_lines"), -str8_lit_comp("breakpoint_lines"), -str8_lit_comp("thread_glow"), -str8_lit_comp("breakpoint_glow"), -str8_lit_comp("opaque_backgrounds"), -str8_lit_comp("tab_width"), -str8_lit_comp("main_font_size"), -str8_lit_comp("code_font_size"), -str8_lit_comp("smooth_ui_text"), -str8_lit_comp("smooth_code_text"), -str8_lit_comp("hint_ui_text"), -str8_lit_comp("hint_code_text"), -}; - -B8 rd_setting_code_default_is_per_window_table[19] = -{ -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -1, -1, -1, -1, -1, -}; - -RD_SettingVal rd_setting_code_default_val_table[19] = -{ -{1, 1}, -{1, 1}, -{1, 0}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 0}, -{1, 4}, -{1, 11}, -{1, 11}, -{1, 1}, -{1, 0}, -{1, 1}, -{1, 1}, -}; - -Rng1S32 rd_setting_code_s32_range_table[19] = -{ -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{1, 32}, -{6, 72}, -{6, 72}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -}; - C_LINKAGE_END diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index ca29430a..897039d7 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -512,30 +512,6 @@ RD_ThemePreset_FarManager, RD_ThemePreset_COUNT, } RD_ThemePreset; -typedef enum RD_SettingCode -{ -RD_SettingCode_HoverAnimations, -RD_SettingCode_PressAnimations, -RD_SettingCode_FocusAnimations, -RD_SettingCode_TooltipAnimations, -RD_SettingCode_MenuAnimations, -RD_SettingCode_ScrollingAnimations, -RD_SettingCode_BackgroundBlur, -RD_SettingCode_ThreadLines, -RD_SettingCode_BreakpointLines, -RD_SettingCode_ThreadGlow, -RD_SettingCode_BreakpointGlow, -RD_SettingCode_OpaqueBackgrounds, -RD_SettingCode_TabWidth, -RD_SettingCode_MainFontSize, -RD_SettingCode_CodeFontSize, -RD_SettingCode_SmoothUIText, -RD_SettingCode_SmoothCodeText, -RD_SettingCode_HintUIText, -RD_SettingCode_HintCodeText, -RD_SettingCode_COUNT, -} RD_SettingCode; - typedef struct RD_VocabularyInfo RD_VocabularyInfo; struct RD_VocabularyInfo { @@ -781,7 +757,7 @@ extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; extern RD_VocabularyInfo rd_vocabulary_info_table[41]; -extern RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[5]; +extern RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6]; extern String8 d_entity_kind_display_string_table[27]; extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; @@ -817,11 +793,6 @@ extern Vec4F32 rd_theme_preset_colors__far_manager[76]; extern Vec4F32* rd_theme_preset_colors_table[9]; extern String8 rd_theme_color_display_string_table[76]; extern String8 rd_theme_color_cfg_string_table[76]; -extern String8 rd_setting_code_display_string_table[19]; -extern String8 rd_setting_code_lower_string_table[19]; -extern B8 rd_setting_code_default_is_per_window_table[19]; -extern RD_SettingVal rd_setting_code_default_val_table[19]; -extern Rng1S32 rd_setting_code_s32_range_table[19]; read_only global U8 rd_icon_font_bytes__data[] = { 0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x44,0x49,0xa0,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0x2a,0x09,0xe2,0xc2,0x00,0x00,0x01,0xb0,0x00,0x00,0x05,0xec,0x63,0x76,0x74,0x20, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index e27f2929..3b6bac8d 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -111,42 +111,91 @@ RD_VocabularyMap: //////////////////////////////// //~ rjf: Configuration Tree Schemas -/* +@table(name schema) RD_CfgSchemaTable: +{ + //- rjf: settings { - top_level, + settings, ```x: { - 'hover_animations': bool, - 'press_animations': bool, - 'focus_animations': bool, - 'tooltip_animations': bool, - 'menu_animations': bool, - 'scrolling_animations': bool, - 'background_blur': bool, - 'thread_lines': bool, - 'breakpoint_lines': bool, - 'thread_glow': bool, - 'breakpoint_glow': bool, - 'opaque_backgrounds': bool, - 'smooth_main_text': bool, - 'smooth_code_text': bool, - 'hint_main_text': bool, - 'hint_code_text': bool, - 'tab_width': @range[1, 32] u64, - 'main_font_size': @range[6, 72] u64, - 'code_font_size': @range[1, 32] u64, + @default(1) 'hover_animations': bool, + @default(1) 'press_animations': bool, + @default(0) 'focus_animations': bool, + @default(1) 'tooltip_animations': bool, + @default(1) 'menu_animations': bool, + @default(1) 'scrolling_animations': bool, + @default(1) 'background_blur': bool, + @default(1) 'thread_lines': bool, + @default(1) 'breakpoint_lines': bool, + @default(1) 'thread_glow': bool, + @default(1) 'breakpoint_glow': bool, + @default(0) 'opaque_backgrounds': bool, + @default(1) 'smooth_main_text': bool, + @default(0) 'smooth_code_text': bool, + @default(1) 'hint_main_text': bool, + @default(1) 'hint_code_text': bool, + @default(2) 'tab_width': @range[1, 32] u64, + @can_be_per_window 'main_font_size': @range[6, 72] u64, + @can_be_per_window 'code_font_size': @range[1, 32] u64, } ``` } -*/ - -@table(name schema) RD_CfgSchemaTable: -{ - {target "x:{'label':code_string, 'exe':path, 'args':string, 'working_directory':path, 'entry_point':code_string, 'stdout_path':path, 'stderr_path':path, 'stdin_path':path, 'debug_subprocesses':bool}"} - {breakpoint "x:{'label':code_string, 'condition':code_string, 'location':location, 'hit_count':u64, 'enabled':bool}"} - {watch_pin "x:{'expression':code_string, 'view_rule':code_string, 'location':location}"} - {file_path_map "x:{'source':path, 'dest':path}"} - {auto_view_rule "x:{'source':code_string, 'dest':code_string}"} + + //- rjf: targets + { + target, + ```x: + { + 'label': code_string, + 'exe': path, + 'args': string, + 'working_directory': path, + 'entry_point': code_string, + 'stdout_path': path, + 'stderr_path': path, + 'stdin_path': path, + 'debug_subprocesses': bool, + } + ``` + } + + //- rjf: breakpoints + { + breakpoint, + ```x: + { + 'label': code_string, + 'condition': code_string, + 'location': location, + 'hit_count': u64, + 'disabled': bool, + } + ``` + } + + //- rjf: watch pins + { + watch_pin, + ```x: + { + 'expression':code_string, + 'view_rule':code_string, + 'location':location, + } + ``` + } + + //- rjf: file path maps + { + file_path_map, + ```x:{'source':path, 'dest':path}``` + } + + //- rjf: auto view rules + { + auto_view_rule, + ```x:{'source':code_string, 'dest':code_string}``` + } } @struct RD_CfgNameSchemaPair: @@ -1290,64 +1339,6 @@ RD_ThemeColorVersionRemapTable: @expand(RD_ThemeColorTable a) `str8_lit_comp("$(a.name_lower)")` } -//////////////////////////////// -//~ rjf: Settings - -@table(name name_lower display_string default_per_window default_s32 s32_min s32_max) -RD_SettingTable: -{ - {HoverAnimations hover_animations "Hover Animations" 0 1 0 1 } - {PressAnimations press_animations "Press Animations" 0 1 0 1 } - {FocusAnimations focus_animations "Focus Animations" 0 0 0 1 } - {TooltipAnimations tooltip_animations "Tooltip Animations" 0 1 0 1 } - {MenuAnimations menu_animations "Menu Animations" 0 1 0 1 } - {ScrollingAnimations scrolling_animations "Scrolling Animations" 0 1 0 1 } - {BackgroundBlur background_blur "Background Blur" 0 1 0 1 } - {ThreadLines thread_lines "Thread Lines" 0 1 0 1 } - {BreakpointLines breakpoint_lines "Breakpoint Lines" 0 1 0 1 } - {ThreadGlow thread_glow "Thread Glow" 0 1 0 1 } - {BreakpointGlow breakpoint_glow "Breakpoint Glow" 0 1 0 1 } - {OpaqueBackgrounds opaque_backgrounds "Opaque Backgrounds" 0 0 0 1 } - {TabWidth tab_width "Tab Width" 0 4 1 32 } - {MainFontSize main_font_size "Main Font Size" 1 11 6 72 } - {CodeFontSize code_font_size "Code Font Size" 1 11 6 72 } - {SmoothUIText smooth_ui_text "Smooth UI Text" 1 1 0 1 } - {SmoothCodeText smooth_code_text "Smooth Code Text" 1 0 0 1 } - {HintUIText hint_ui_text "Hint UI Text" 1 1 0 1 } - {HintCodeText hint_code_text "Hint Code Text" 1 1 0 1 } -} - -@enum RD_SettingCode: -{ - @expand(RD_SettingTable a) `$(a.name)`, - COUNT -} - -@data(String8) rd_setting_code_display_string_table: -{ - @expand(RD_SettingTable a) `str8_lit_comp("$(a.display_string)")` -} - -@data(String8) rd_setting_code_lower_string_table: -{ - @expand(RD_SettingTable a) `str8_lit_comp("$(a.name_lower)")` -} - -@data(B8) rd_setting_code_default_is_per_window_table: -{ - @expand(RD_SettingTable a) `$(a.default_per_window)` -} - -@data(RD_SettingVal) rd_setting_code_default_val_table: -{ - @expand(RD_SettingTable a) `{1, $(a.default_s32)}` -} - -@data(Rng1S32) rd_setting_code_s32_range_table: -{ - @expand(RD_SettingTable a) `{$(a.s32_min), $(a.s32_max)}` -} - //////////////////////////////// //~ rjf: Help/Docs/README diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ac7f2240..ac0168b3 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1479,6 +1479,49 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 return result; } +internal String8 +rd_setting_from_key(String8 key) +{ + String8 result = {0}; + { + // rjf: find most-granular config scope to begin looking for the setting + RD_Cfg *start_cfg = rd_cfg_from_handle(rd_regs()->view); + if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->panel); } + if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->window); } + + // rjf: scan upwards the config tree until we find the setting + RD_Cfg *setting = &rd_nil_cfg; + for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && setting == &rd_nil_cfg; cfg = cfg->parent) + { + setting = rd_cfg_child_from_string(cfg, key); + } + + // rjf: return resultant child string stored under this key + result = setting->first->string; + + // rjf: no result -> look for default in settings schema + if(result.size == 0) ProfScope("default setting schema lookup") + { + Temp scratch = scratch_begin(0, 0); + String8 schema_string = {0}; + for EachElement(idx, rd_cfg_name_schema_pair_table) + { + if(str8_match(rd_cfg_name_schema_pair_table[idx].name, str8_lit("settings"), 0)) + { + schema_string = rd_cfg_name_schema_pair_table[idx].schema; + break; + } + } + MD_Node *schema = md_tree_from_string(scratch.arena, schema_string)->first; + MD_Node *setting = md_child_from_string(schema, key, 0); + MD_Node *default_tag = md_tag_from_string(setting, str8_lit("default"), 0); + result = default_tag->first->string; + scratch_end(scratch); + } + } + return result; +} + //////////////////////////////// //~ rjf: Entity State Functions @@ -3415,17 +3458,6 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->drop_completion_arena = arena_alloc(); ws->hover_eval_arena = arena_alloc(); ws->last_dpi = os_dpi_from_window(ws->os); - for EachEnumVal(RD_SettingCode, code) - { - if(rd_setting_code_default_is_per_window_table[code]) - { - ws->setting_vals[code] = rd_setting_code_default_val_table[code]; - } - } - ws->setting_vals[RD_SettingCode_MainFontSize].s32 = ws->setting_vals[RD_SettingCode_MainFontSize].s32 * (ws->last_dpi / 96.f); - ws->setting_vals[RD_SettingCode_CodeFontSize].s32 = ws->setting_vals[RD_SettingCode_CodeFontSize].s32 * (ws->last_dpi / 96.f); - ws->setting_vals[RD_SettingCode_MainFontSize].s32 = ClampBot(ws->setting_vals[RD_SettingCode_MainFontSize].s32, rd_setting_code_default_val_table[RD_SettingCode_MainFontSize].s32); - ws->setting_vals[RD_SettingCode_CodeFontSize].s32 = ClampBot(ws->setting_vals[RD_SettingCode_CodeFontSize].s32, rd_setting_code_default_val_table[RD_SettingCode_CodeFontSize].s32); OS_Handle zero_monitor = {0}; if(!os_handle_match(zero_monitor, preferred_monitor)) { @@ -3616,7 +3648,7 @@ rd_window_frame(void) ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text = current->colors[RD_ThemeColor_DropSiteOverlay]; ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text_weak = current->colors[RD_ThemeColor_DropSiteOverlay]; ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].border = current->colors[RD_ThemeColor_DropSiteOverlay]; - if(rd_setting_val_from_code(RD_SettingCode_OpaqueBackgrounds).s32) + if(rd_setting_b32_from_key(str8_lit("opaque_backgrounds"))) { for EachEnumVal(RD_PaletteCode, code) { @@ -3703,12 +3735,12 @@ rd_window_frame(void) // rjf: build animation info UI_AnimationInfo animation_info = {0}; { - if(rd_setting_val_from_code(RD_SettingCode_HoverAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_HotAnimations;} - if(rd_setting_val_from_code(RD_SettingCode_PressAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_ActiveAnimations;} - if(rd_setting_val_from_code(RD_SettingCode_FocusAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_FocusAnimations;} - if(rd_setting_val_from_code(RD_SettingCode_TooltipAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_TooltipAnimations;} - if(rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_ContextMenuAnimations;} - if(rd_setting_val_from_code(RD_SettingCode_ScrollingAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_ScrollingAnimations;} + if(rd_setting_b32_from_key(str8_lit("hover_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_HotAnimations;} + if(rd_setting_b32_from_key(str8_lit("press_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ActiveAnimations;} + if(rd_setting_b32_from_key(str8_lit("focus_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_FocusAnimations;} + if(rd_setting_b32_from_key(str8_lit("tooltip_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_TooltipAnimations;} + if(rd_setting_b32_from_key(str8_lit("menu_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ContextMenuAnimations;} + if(rd_setting_b32_from_key(str8_lit("scrolling_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ScrollingAnimations;} } // rjf: begin & push initial stack values @@ -3721,8 +3753,8 @@ rd_window_frame(void) ui_push_palette(rd_palette_from_code(RD_PaletteCode_Base)); ui_push_blur_size(10.f); FNT_RasterFlags text_raster_flags = 0; - if(rd_setting_val_from_code(RD_SettingCode_SmoothUIText).s32) {text_raster_flags |= FNT_RasterFlag_Smooth;} - if(rd_setting_val_from_code(RD_SettingCode_HintUIText).s32) {text_raster_flags |= FNT_RasterFlag_Hinted;} + if(rd_setting_b32_from_key(str8_lit("smooth_main_text"))) {text_raster_flags |= FNT_RasterFlag_Smooth;} + if(rd_setting_b32_from_key(str8_lit("hint_main_text"))) {text_raster_flags |= FNT_RasterFlag_Hinted;} ui_push_text_raster_flags(text_raster_flags); } @@ -6322,11 +6354,13 @@ rd_window_frame(void) //- rjf: animate { + B32 do_menu_animations = rd_setting_b32_from_key(str8_lit("menu_animations")); + F32 rate = do_menu_animations ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; + // rjf: animate height { - F32 fish_rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; F32 hover_eval_container_height_target = row_height * Min(30, block_tree.total_row_count); - ws->hover_eval_num_visible_rows_t += (hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) * fish_rate; + ws->hover_eval_num_visible_rows_t += (hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) * rate; if(abs_f32(hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) > 0.5f) { rd_request_frame(); @@ -6339,9 +6373,8 @@ rd_window_frame(void) // rjf: animate open { - F32 fish_rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; F32 diff = 1.f - ws->hover_eval_open_t; - ws->hover_eval_open_t += diff*fish_rate; + ws->hover_eval_open_t += diff*rate; if(abs_f32(diff) < 0.01f) { ws->hover_eval_open_t = 1.f; @@ -7885,6 +7918,9 @@ rd_window_frame(void) { Temp scratch = scratch_begin(0, 0); + //- rjf: unpack settings + B32 do_background_blur = rd_setting_b32_from_key(str8_lit("background_blur")); + //- rjf: set up heatmap buckets F32 heatmap_bucket_size = 32.f; U64 *heatmap_buckets = 0; @@ -7959,7 +7995,7 @@ rd_window_frame(void) } // rjf: blur background - if(box->flags & UI_BoxFlag_DrawBackgroundBlur && rd_setting_val_from_code(RD_SettingCode_BackgroundBlur).s32) + if(box->flags & UI_BoxFlag_DrawBackgroundBlur && do_background_blur) { R_PassParams_Blur *params = dr_blur(pad_2f32(box->rect, 1.f), box->blur_size*(1-box->transparency), 0); MemoryCopyArray(params->corner_radii, box->corner_radii); @@ -10672,7 +10708,6 @@ rd_font_from_slot(RD_FontSlot slot) internal F32 rd_font_size_from_slot(RD_FontSlot slot) { - B32 explicit_config_found = 0; F32 result = 9.f; // rjf: determine config key based on slot @@ -10685,32 +10720,23 @@ rd_font_size_from_slot(RD_FontSlot slot) case RD_FontSlot_Code:{key = str8_lit("code_font_size");}break; } - // rjf: find most-granular config scope to begin looking for the setting - RD_Cfg *start_cfg = rd_cfg_from_handle(rd_regs()->view); - if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->panel); } - if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->window); } + // rjf: given key, find setting string + String8 setting_string = rd_setting_from_key(key); - // rjf: scan upwards the config tree until we find the setting - for(RD_Cfg *parent = start_cfg; parent != &rd_nil_cfg; parent = parent->parent) - { - RD_Cfg *child = rd_cfg_child_from_string(parent, key); - if(child != &rd_nil_cfg) - { - result = (F32)f64_from_str8(child->first->string); - explicit_config_found = 1; - break; - } - } - - // rjf: if we haven't found any explicit config, then use the window's monitor's DPI + // rjf: if found, map setting string -> f64; otherwise use the window's monitor's DPI // based on some default size. - if(explicit_config_found == 0) + if(setting_string.size) + { + result = (F32)f64_from_str8(setting_string); + } + else { RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); F32 dpi = os_dpi_from_window(ws->os); - result *= (dpi / 96.f); + result = 9.f * (dpi / 96.f); } + return result; } @@ -10722,38 +10748,12 @@ rd_raster_flags_from_slot(RD_FontSlot slot) { default:{}break; case RD_FontSlot_Icons:{flags = FNT_RasterFlag_Smooth;}break; - case RD_FontSlot_Main: {flags = (!!rd_setting_val_from_code(RD_SettingCode_SmoothUIText).s32*FNT_RasterFlag_Smooth)|(!!rd_setting_val_from_code(RD_SettingCode_HintUIText).s32*FNT_RasterFlag_Hinted);}break; - case RD_FontSlot_Code: {flags = (!!rd_setting_val_from_code(RD_SettingCode_SmoothCodeText).s32*FNT_RasterFlag_Smooth)|(!!rd_setting_val_from_code(RD_SettingCode_HintCodeText).s32*FNT_RasterFlag_Hinted);}break; + case RD_FontSlot_Main: {flags = (rd_setting_b32_from_key(str8_lit("smooth_main_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_key(str8_lit("hint_main_text"))*FNT_RasterFlag_Hinted);}break; + case RD_FontSlot_Code: {flags = (rd_setting_b32_from_key(str8_lit("smooth_code_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_key(str8_lit("hint_code_text"))*FNT_RasterFlag_Hinted);}break; } return flags; } -//- rjf: settings - -internal RD_SettingVal -rd_setting_val_from_code(RD_SettingCode code) -{ - RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(wcfg); - RD_SettingVal result = {0}; - if(ws != 0) - { - result = ws->setting_vals[code]; - } - if(result.set == 0) - { - for EachEnumVal(RD_CfgSrc, src) - { - if(rd_state->cfg_setting_vals[src][code].set) - { - result = rd_state->cfg_setting_vals[src][code]; - break; - } - } - } - return result; -} - //- rjf: config serialization internal int @@ -13316,7 +13316,7 @@ rd_frame(void) case RD_CmdKind_IncCodeFontScale: { fnt_reset(); - F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); + F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Code); F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); @@ -13326,7 +13326,7 @@ rd_frame(void) case RD_CmdKind_DecCodeFontScale: { fnt_reset(); - F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); + F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Code); F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); @@ -16610,7 +16610,7 @@ X(getting_started) //- rjf: animate confirmation // { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-10.f * rd_state->frame_dt)) : 1.f; + F32 rate = rd_setting_b32_from_key(str8_lit("menu_animations")) ? 1 - pow_f32(2, (-10.f * rd_state->frame_dt)) : 1.f; B32 popup_open = rd_state->popup_active; rd_state->popup_t += rate * ((F32)!!popup_open-rd_state->popup_t); if(abs_f32(rd_state->popup_t - (F32)!!popup_open) > 0.005f) diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index f1da382d..2398512a 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -652,7 +652,6 @@ struct RD_WindowState B32 window_temporarily_focused_ipc; // rjf: config/settings - RD_SettingVal setting_vals[RD_SettingCode_COUNT]; UI_Palette cfg_palettes[RD_PaletteCode_COUNT]; // derivative from theme // rjf: dev interface state @@ -936,9 +935,6 @@ struct RD_State String8 bind_change_cmd_name; RD_Binding bind_change_binding; - // rjf: global settings - RD_SettingVal cfg_setting_vals[RD_CfgSrc_COUNT][RD_SettingCode_COUNT]; - //- // TODO(rjf): TO BE ELIMINATED OR REPLACED ^^^^^^^^^^^^^^^^^^ //- @@ -1148,6 +1144,10 @@ internal String8 rd_expr_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); internal DR_FancyStringList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size); +internal String8 rd_setting_from_key(String8 key); +#define rd_setting_b32_from_key(key) (str8_match(rd_setting_from_key(key), str8_lit("1"), 0)) +#define rd_setting_u64_from_key(key) (u64_from_str8(rd_setting_from_key(key), 10)) + //////////////////////////////// //~ rjf: Entity Stateful Functions @@ -1352,9 +1352,6 @@ internal FNT_Tag rd_font_from_slot(RD_FontSlot slot); internal F32 rd_font_size_from_slot(RD_FontSlot slot); internal FNT_RasterFlags rd_raster_flags_from_slot(RD_FontSlot slot); -//- rjf: settings -internal RD_SettingVal rd_setting_val_from_code(RD_SettingCode code); - //- rjf: config serialization internal int rd_qsort_compare__cfg_string_bindings(RD_StringBindingPair *a, RD_StringBindingPair *b); internal String8List rd_cfg_strings_from_gfx(Arena *arena, String8 root_path, RD_CfgSrc source); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index d614ef07..8fd17d62 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -35,7 +35,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // FNT_Tag code_font = rd_font_from_slot(RD_FontSlot_Code); F32 code_font_size = rd_font_size_from_slot(RD_FontSlot_Code); - F32 code_tab_size = fnt_column_size_from_tag_size(code_font, code_font_size)*rd_setting_val_from_code(RD_SettingCode_TabWidth).s32; + F32 code_tab_size = fnt_column_size_from_tag_size(code_font, code_font_size)*rd_setting_u64_from_key(str8_lit("tab_width")); FNT_Metrics code_font_metrics = fnt_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(fnt_line_height_from_metrics(&code_font_metrics) * 1.5f); F32 big_glyph_advance = fnt_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; @@ -1268,7 +1268,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo DI_Scope *di_scope = di_scope_open(); Temp scratch = scratch_begin(0, 0); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - F32 entity_hover_t_rate = rd_setting_val_from_code(RD_SettingCode_HoverAnimations).s32 ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; + F32 entity_hover_t_rate = rd_setting_b32_from_key(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; ////////////////////////////// //- rjf: unpack arguments @@ -6053,6 +6053,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(geo3d) //////////////////////////////// //~ rjf: settings @view_hook_impl +#if 0 // TODO(rjf): @cfg typedef enum RD_SettingsItemKind { RD_SettingsItemKind_CategoryHeader, @@ -6123,6 +6124,7 @@ rd_qsort_compare_settings_item(RD_SettingsItem *a, RD_SettingsItem *b) } return result; } +#endif RD_VIEW_RULE_UI_FUNCTION_DEF(settings) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index ce58c58e..3ae666d8 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -614,7 +614,11 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe margin_contents_palette->background = v4f32(0, 0, 0, 0); F32 line_num_padding_px = ui_top_font_size()*1.f; F32 entity_alive_t_rate = (1 - pow_f32(2, (-30.f * rd_state->frame_dt))); - F32 entity_hover_t_rate = rd_setting_val_from_code(RD_SettingCode_HoverAnimations).s32 ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; + F32 entity_hover_t_rate = rd_setting_b32_from_key(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; + B32 do_thread_lines = rd_setting_b32_from_key(str8_lit("thread_lines")); + B32 do_thread_glow = rd_setting_b32_from_key(str8_lit("thread_glow")); + B32 do_bp_lines = rd_setting_b32_from_key(str8_lit("breakpoint_lines")); + B32 do_bp_glow = rd_setting_b32_from_key(str8_lit("breakpoint_glow")); ////////////////////////////// //- rjf: build top-level container @@ -755,8 +759,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe u->hover_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_hover_t_%p", thread), (F32)!!is_hovering, .rate = entity_hover_t_rate); u->is_selected = (thread == selected_thread); u->is_frozen = !!thread->is_frozen; - u->do_lines = rd_setting_val_from_code(RD_SettingCode_ThreadLines).s32; - u->do_glow = rd_setting_val_from_code(RD_SettingCode_ThreadGlow).s32; + u->do_lines = do_thread_lines; + u->do_glow = do_thread_glow; ui_box_equip_custom_draw(thread_box, rd_thread_box_draw_extensions, u); // rjf: fill out progress t (progress into range of current line's @@ -974,8 +978,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe bp_draw->color = bp_rgba; bp_draw->alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_alive_t_%p", bp), 1.f, .rate = entity_alive_t_rate); bp_draw->hover_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_hover_t_%p", bp), (F32)!!is_hovering, .rate = entity_hover_t_rate); - bp_draw->do_lines = rd_setting_val_from_code(RD_SettingCode_BreakpointLines).s32; - bp_draw->do_glow = rd_setting_val_from_code(RD_SettingCode_BreakpointGlow).s32; + bp_draw->do_lines = do_bp_lines; + bp_draw->do_glow = do_bp_glow; if(params->line_vaddrs[line_idx] == 0) { D_LineList *lines = ¶ms->line_infos[line_idx]; diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 2a515898..c0534cdf 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -60,7 +60,7 @@ "////////////////////////////////////////////////////////////////"; "//~ Format Constants"; ""; - "// \"raddbg\0\0\""; + "// \"raddbg\\0\\0\""; "#define RDI_MAGIC_CONSTANT 0x0000676264646172"; "#define RDI_ENCODING_VERSION 10"; "";