diff --git a/data/icons.ttf b/data/icons.ttf index 86db4361..c2be53be 100644 Binary files a/data/icons.ttf and b/data/icons.ttf differ diff --git a/project.4coder b/project.4coder index 0be9237b..6e727228 100644 --- a/project.4coder +++ b/project.4coder @@ -46,9 +46,10 @@ load_paths = commands = { //- rjf: fkey command slots (change locally but do not commit) - .f1 = { .win = "build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "build textperf release telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "pushd build && textperf.exe --capture && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/base/base_context_cracking.h b/src/base/base_context_cracking.h index ba452a5a..62a6881f 100644 --- a/src/base/base_context_cracking.h +++ b/src/base/base_context_cracking.h @@ -159,7 +159,7 @@ #endif #if !defined(BUILD_VERSION_PATCH) -# define BUILD_VERSION_PATCH 15 +# define BUILD_VERSION_PATCH 16 #endif #define BUILD_VERSION_STRING_LITERAL Stringify(BUILD_VERSION_MAJOR) "." Stringify(BUILD_VERSION_MINOR) "." Stringify(BUILD_VERSION_PATCH) diff --git a/src/base/base_math.c b/src/base/base_math.c index b0a85bfe..4f5903c5 100644 --- a/src/base/base_math.c +++ b/src/base/base_math.c @@ -480,7 +480,9 @@ internal Rng2F32 intersect_2f32(Rng2F32 a, Rng2F32 b) {Rng2F32 c; c.p0 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;} //////////////////////////////// -//~ rjf: Miscellaneous Ops +//~ rjf: Color Operations + +//- rjf: hsv <-> rgb internal Vec3F32 hsv_from_rgb(Vec3F32 rgb) @@ -567,16 +569,102 @@ rgba_from_hsva(Vec4F32 hsva) return rgba; } -internal Vec4F32 -rgba_from_u32(U32 hex) +//- rjf: srgb <-> linear + +internal Vec3F32 +linear_from_srgb(Vec3F32 srgb) { - Vec4F32 result = v4f32(((hex&0xff000000)>>24)/255.f, - ((hex&0x00ff0000)>>16)/255.f, - ((hex&0x0000ff00)>> 8)/255.f, - ((hex&0x000000ff)>> 0)/255.f); + Vec3F32 result; + for EachElement(idx, srgb.v) + { + result.v[idx] = (srgb.v[idx] < 0.0404482362771082f ? srgb.v[idx] / 12.92f : pow_f32((srgb.v[idx] + 0.055f) / 1.055f, 2.4f)); + } return result; } +internal Vec3F32 +srgb_from_linear(Vec3F32 linear) +{ + Vec3F32 result; + for EachElement(idx, linear.v) + { + result.v[idx] = (0 <= linear.v[idx] && linear.v[idx] < 0.00313066844250063) ? linear.v[idx]*12.92f : 1.05f * pow_f32(linear.v[idx], 1.f/2.4f) - 0.055f; + } + return result; +} + +internal Vec4F32 +linear_from_srgba(Vec4F32 srgba) +{ + Vec4F32 result; + result.xyz = linear_from_srgb(srgba.xyz); + result.w = srgba.w; + return result; +} + +internal Vec4F32 +srgba_from_linear(Vec4F32 linear) +{ + Vec4F32 result; + result.xyz = srgb_from_linear(linear.xyz); + result.w = linear.w; + return result; +} + +//- rjf: oklab <-> linear + +internal Vec3F32 +oklab_from_linear(Vec3F32 linear) +{ + F32 l = (0.4122214708f * linear.x + 0.5363325363f * linear.y + 0.0514459929f * linear.z); + F32 m = (0.2119034982f * linear.x + 0.6806995451f * linear.y + 0.1073969566f * linear.z); + F32 s = (0.0883024619f * linear.x + 0.2817188376f * linear.y + 0.6299787005f * linear.z); + F32 l_ = cbrt_f32(l); + F32 m_ = cbrt_f32(m); + F32 s_ = cbrt_f32(s); + Vec3F32 result; + result.x = 0.2104542553f*l_ + 0.7936177850f*m_ - 0.0040720468f*s_; + result.y = 1.9779984951f*l_ - 2.4285922050f*m_ + 0.4505937099f*s_; + result.z = 0.0259040371f*l_ + 0.7827717662f*m_ - 0.8086757660f*s_; + return result; +} + +internal Vec3F32 +linear_from_oklab(Vec3F32 oklab) +{ + F32 l_ = oklab.x + 0.3963377774f * oklab.y + 0.2158037573f * oklab.z; + F32 m_ = oklab.x - 0.1055613458f * oklab.y - 0.0638541728f * oklab.z; + F32 s_ = oklab.x - 0.0894841775f * oklab.y - 1.2914855480f * oklab.z; + F32 l = l_*l_*l_; + F32 m = m_*m_*m_; + F32 s = s_*s_*s_; + Vec3F32 result; + result.x = +4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s; + result.y = -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s; + result.z = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s; + return result; +} + +internal Vec4F32 +oklab_from_lineara(Vec4F32 lineara) +{ + Vec4F32 result; + result.xyz = oklab_from_linear(lineara.xyz); + result.w = lineara.w; + return result; +} + +internal Vec4F32 +lineara_from_oklab(Vec4F32 oklab) +{ + Vec4F32 result; + result.xyz = linear_from_oklab(oklab.xyz); + result.w = oklab.w; + return result; +} + +//- rjf: rgba <-> u32 + internal U32 u32_from_rgba(Vec4F32 rgba) { @@ -588,6 +676,16 @@ u32_from_rgba(Vec4F32 rgba) return result; } +internal Vec4F32 +rgba_from_u32(U32 hex) +{ + Vec4F32 result = v4f32(((hex&0xff000000)>>24)/255.f, + ((hex&0x00ff0000)>>16)/255.f, + ((hex&0x0000ff00)>> 8)/255.f, + ((hex&0x000000ff)>> 0)/255.f); + return result; +} + //////////////////////////////// //~ rjf: List Type Functions diff --git a/src/base/base_math.h b/src/base/base_math.h index d13adbf4..21e238bf 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -379,6 +379,7 @@ struct Rng1S64Array #define abs_s64(v) (S64)llabs(v) #define sqrt_f32(v) sqrtf(v) +#define cbrt_f32(v) cbrtf(v) #define mod_f32(a, b) fmodf((a), (b)) #define pow_f32(b, e) powf((b), (e)) #define ceil_f32(v) ceilf(v) @@ -396,6 +397,7 @@ struct Rng1S64Array #define tan_f32(v) tanf(radians_from_turns_f32(v)) #define sqrt_f64(v) sqrt(v) +#define cbrt_f64(v) cbrt(v) #define mod_f64(a, b) fmod((a), (b)) #define pow_f64(b, e) pow((b), (e)) #define ceil_f64(v) ceil(v) @@ -651,15 +653,29 @@ internal Rng2F32 intersect_2f32(Rng2F32 a, Rng2F32 b); internal Vec2F32 clamp_2f32(Rng2F32 r, Vec2F32 v); //////////////////////////////// -//~ rjf: Miscellaneous Ops +//~ rjf: Color Operations +//- rjf: hsv <-> rgb internal Vec3F32 hsv_from_rgb(Vec3F32 rgb); internal Vec3F32 rgb_from_hsv(Vec3F32 hsv); internal Vec4F32 hsva_from_rgba(Vec4F32 rgba); internal Vec4F32 rgba_from_hsva(Vec4F32 hsva); -internal Vec4F32 rgba_from_u32(U32 hex); -internal U32 u32_from_rgba(Vec4F32 rgba); +//- rjf: srgb <-> linear +internal Vec3F32 linear_from_srgb(Vec3F32 srgb); +internal Vec3F32 srgb_from_linear(Vec3F32 linear); +internal Vec4F32 linear_from_srgba(Vec4F32 srgba); +internal Vec4F32 srgba_from_linear(Vec4F32 linear); + +//- rjf: oklab <-> linear +internal Vec3F32 oklab_from_linear(Vec3F32 linear); +internal Vec3F32 linear_from_oklab(Vec3F32 oklab); +internal Vec4F32 oklab_from_lineara(Vec4F32 lineara); +internal Vec4F32 lineara_from_oklab(Vec4F32 oklab); + +//- rjf: rgba <-> u32 +internal U32 u32_from_rgba(Vec4F32 rgba); +internal Vec4F32 rgba_from_u32(U32 hex); #define rgba_from_u32_lit_comp(h) { (((h)&0xff000000)>>24)/255.f, (((h)&0x00ff0000)>>16)/255.f, (((h)&0x0000ff00)>> 8)/255.f, (((h)&0x000000ff)>> 0)/255.f } //////////////////////////////// diff --git a/src/base/base_strings.c b/src/base/base_strings.c index dcdc2a4d..e8b620dc 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -242,7 +242,7 @@ str8_cstring_capped_reverse(void *raw_start, void *raw_cap) for(; ptr > start; ) { ptr -= 1; - + if (*ptr == '\0') { break; @@ -427,23 +427,53 @@ str8_chop(String8 str, U64 amt){ } internal String8 -str8_skip_chop_whitespace(String8 string){ +str8_skip_chop_whitespace(String8 string) +{ U8 *first = string.str; U8 *opl = first + string.size; - for (;first < opl; first += 1){ - if (!char_is_space(*first)){ + for(;first < opl; first += 1) + { + if(!char_is_space(*first)) + { break; } } - for (;opl > first;){ + for(;opl > first;) + { opl -= 1; - if (!char_is_space(*opl)){ + if(!char_is_space(*opl)) + { opl += 1; break; } } String8 result = str8_range(first, opl); - return(result); + return result; +} + +internal String8 +str8_skip_chop_slashes(String8 string) +{ + U8 *first = string.str; + U8 *opl = first + string.size; + for(;first < opl; first += 1) + { + if(!char_is_slash(*first)) + { + break; + } + } + for(;opl > first;) + { + opl -= 1; + if(!char_is_slash(*opl)) + { + opl += 1; + break; + } + } + String8 result = str8_range(first, opl); + return result; } //////////////////////////////// @@ -619,7 +649,7 @@ internal String8 str8_from_memory_size(Arena *arena, U64 size) { String8 result; - + if(size < KB(1)) { result = push_str8f(arena, "%llu Bytes", size); @@ -640,7 +670,7 @@ str8_from_memory_size(Arena *arena, U64 size) { result = push_str8f(arena, "%llu.%02llu TiB", size / TB(1), ((size * 100) / TB(1)) % 100); } - + return result; } @@ -648,7 +678,7 @@ internal String8 str8_from_count(Arena *arena, U64 count) { String8 result; - + if(count < 1 * 1000) { result = push_str8f(arena, "%llu", count); @@ -689,7 +719,7 @@ str8_from_count(Arena *arena, U64 count) result = push_str8f(arena, "%lluB", count / 1000000000, frac); } } - + return result; } @@ -1114,6 +1144,13 @@ str8_list_from_flags(Arena *arena, String8List *list, //////////////////////////////// //~ rjf; String Arrays +internal String8Array +str8_array_zero(void) +{ + String8Array result = {0}; + return result; +} + internal String8Array str8_array_from_list(Arena *arena, String8List *list) { @@ -1827,10 +1864,10 @@ try_guid_from_string(String8 string, Guid *guid_out) 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)) + 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); @@ -1838,10 +1875,10 @@ try_guid_from_string(String8 string, Guid *guid_out) 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) + data2 <= max_U16 && + data3 <= max_U16 && + data4_hi <= max_U16 && + data4_lo <= 0xffffffffffff) { guid_out->data1 = (U32)data1; guid_out->data2 = (U16)data2; @@ -2370,4 +2407,3 @@ str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out) *block_out = str8_substr(string, range); return block_out->size; } - diff --git a/src/base/base_strings.h b/src/base/base_strings.h index 0d456cac..9e5878f0 100644 --- a/src/base/base_strings.h +++ b/src/base/base_strings.h @@ -223,6 +223,7 @@ internal String8 str8_skip(String8 str, U64 amt); internal String8 str8_postfix(String8 str, U64 size); internal String8 str8_chop(String8 str, U64 amt); internal String8 str8_skip_chop_whitespace(String8 string); +internal String8 str8_skip_chop_slashes(String8 string); //////////////////////////////// //~ rjf: String Formatting & Copying @@ -287,6 +288,7 @@ internal void str8_list_from_flags(Arena *arena, String8List *list, U32 //////////////////////////////// //~ rjf; String Arrays +internal String8Array str8_array_zero(void); internal String8Array str8_array_from_list(Arena *arena, String8List *list); internal String8Array str8_array_reserve(Arena *arena, U64 count); diff --git a/src/ctrl/ctrl.mdesk b/src/ctrl/ctrl.mdesk index abc3401d..98a97412 100644 --- a/src/ctrl/ctrl.mdesk +++ b/src/ctrl/ctrl.mdesk @@ -4,17 +4,17 @@ //////////////////////////////// //~ rjf: Entity Kinds -@table(name display_string) +@table(name code_name display_string) CTRL_EntityKindTable: { - {Root "Root" } - {Machine "Machine" } - {Process "Process" } - {Thread "Thread" } - {Module "Module" } - {EntryPoint "Entry Point" } - {DebugInfoPath "Debug Info Path" } - {PendingThreadName "Pending Thread Name" } + {Root root "Root" } + {Machine machine "Machine" } + {Process process "Process" } + {Thread thread "Thread" } + {Module module "Module" } + {EntryPoint entry_point "Entry Point" } + {DebugInfoPath debug_info_path "Debug Info Path" } + {PendingThreadName pending_thread_name "Pending Thread Name" } } @enum CTRL_EntityKind: @@ -24,6 +24,12 @@ CTRL_EntityKindTable: COUNT, } +@data(String8) ctrl_entity_kind_code_name_table: +{ + `{0}`, + @expand(CTRL_EntityKindTable a) `str8_lit_comp("$(a.code_name)")` +} + @data(String8) ctrl_entity_kind_display_string_table: { `{0}`, diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 17433604..2cb579f4 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -43,6 +43,21 @@ ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind) return cause; } +internal CTRL_ExceptionKind +ctrl_exception_kind_from_dmn(DMN_ExceptionKind kind) +{ + CTRL_ExceptionKind result = CTRL_ExceptionKind_Null; + switch(kind) + { + default:{}break; + case DMN_ExceptionKind_MemoryRead: {result = CTRL_ExceptionKind_MemoryRead;}break; + case DMN_ExceptionKind_MemoryWrite: {result = CTRL_ExceptionKind_MemoryWrite;}break; + case DMN_ExceptionKind_MemoryExecute: {result = CTRL_ExceptionKind_MemoryExecute;}break; + case DMN_ExceptionKind_CppThrow: {result = CTRL_ExceptionKind_CppThrow;}break; + } + return result; +} + internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind) { @@ -91,6 +106,21 @@ ctrl_string_from_msg_kind(CTRL_MsgKind kind) return result; } +internal CTRL_EntityKind +ctrl_entity_kind_from_string(String8 string) +{ + CTRL_EntityKind result = CTRL_EntityKind_Null; + for EachNonZeroEnumVal(CTRL_EntityKind, k) + { + if(str8_match(ctrl_entity_kind_code_name_table[k], string, 0)) + { + result = k; + break; + } + } + return result; +} + //////////////////////////////// //~ rjf: Machine/Handle Pair Type Functions @@ -136,6 +166,37 @@ ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src) return dst; } +internal String8 +ctrl_string_from_handle(Arena *arena, CTRL_Handle handle) +{ + String8 result = push_str8f(arena, "$0x%I64x$0x%I64x", handle.machine_id, handle.dmn_handle.u64[0]); + return result; +} + +internal CTRL_Handle +ctrl_handle_from_string(String8 string) +{ + CTRL_Handle handle = {0}; + { + Temp scratch = scratch_begin(0, 0); + U8 split = '$'; + String8List parts = str8_split(scratch.arena, string, &split, 1, 0); + if(parts.first && parts.first->next) + { + CTRL_MachineID machine_id = 0; + DMN_Handle dmn_handle = {0}; + if(try_u64_from_str8_c_rules(parts.first->string, &machine_id) && + try_u64_from_str8_c_rules(parts.first->next->string, &dmn_handle.u64[0])) + { + handle.machine_id = machine_id; + handle.dmn_handle = dmn_handle; + } + } + scratch_end(scratch); + } + return handle; +} + //////////////////////////////// //~ rjf: Trap Type Functions @@ -201,7 +262,6 @@ ctrl_msg_deep_copy(Arena *arena, CTRL_Msg *dst, CTRL_Msg *src) dst->env_string_list = str8_list_copy(arena, &src->env_string_list); dst->traps = ctrl_trap_list_copy(arena, &src->traps); dst->user_bps = ctrl_user_breakpoint_list_copy(arena, &src->user_bps); - dst->meta_evals = *deep_copy_from_struct(arena, CTRL_MetaEvalArray, &src->meta_evals); } //- rjf: list building @@ -332,10 +392,6 @@ ctrl_serialized_string_from_msg_list(Arena *arena, CTRL_MsgList *msgs) str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->condition.size); str8_serial_push_data(scratch.arena, &msgs_srlzed, bp->condition.str, bp->condition.size); } - - // rjf: write meta-eval-info array - String8 meta_evals_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEvalArray, &msg->meta_evals); - str8_serial_push_string(scratch.arena, &msgs_srlzed, meta_evals_srlzed); } } String8 string = str8_serial_end(arena, &msgs_srlzed); @@ -459,12 +515,6 @@ ctrl_msg_list_from_serialized_string(Arena *arena, String8 string) bp->condition.str = push_array_no_zero(arena, U8, bp->condition.size); read_off += str8_deserial_read(string, read_off, bp->condition.str, bp->condition.size, 1); } - - // rjf: read meta-eval-info array - String8 meta_evals_data = str8_skip(string, read_off); - U64 meta_evals_size = 0; - msg->meta_evals = *struct_from_serialized(arena, CTRL_MetaEvalArray, meta_evals_data, .advance_out = &meta_evals_size); - read_off += meta_evals_size; } } return msgs; @@ -639,95 +689,100 @@ ctrl_entity_store_release(CTRL_EntityStore *cache) //- rjf: string allocation/deletion internal U64 -ctrl_name_bucket_idx_from_string_size(U64 size) +ctrl_name_bucket_num_from_string_size(U64 size) { - U64 size_rounded = u64_up_to_pow2(size+1); - size_rounded = ClampBot((1<<4), size_rounded); - U64 bucket_idx = 0; - switch(size_rounded) + U64 bucket_num = 0; + if(size > 0) { - case 1<<4: {bucket_idx = 0;}break; - case 1<<5: {bucket_idx = 1;}break; - case 1<<6: {bucket_idx = 2;}break; - case 1<<7: {bucket_idx = 3;}break; - case 1<<8: {bucket_idx = 4;}break; - case 1<<9: {bucket_idx = 5;}break; - case 1<<10:{bucket_idx = 6;}break; - default:{bucket_idx = ArrayCount(((CTRL_EntityStore *)0)->free_string_chunks)-1;}break; + for EachElement(idx, ctrl_entity_string_bucket_chunk_sizes) + { + if(size <= ctrl_entity_string_bucket_chunk_sizes[idx]) + { + bucket_num = idx+1; + break; + } + } } - return bucket_idx; + return bucket_num; } internal String8 ctrl_entity_string_alloc(CTRL_EntityStore *store, String8 string) { - if(string.size == 0) {return str8_zero();} - U64 bucket_idx = ctrl_name_bucket_idx_from_string_size(string.size); - CTRL_EntityStringChunkNode *node = store->free_string_chunks[bucket_idx]; - - // rjf: pull from bucket free list - if(node != 0) + //- rjf: allocate node + CTRL_EntityStringChunkNode *node = 0; { - if(bucket_idx == ArrayCount(store->free_string_chunks)-1) + U64 bucket_num = ctrl_name_bucket_num_from_string_size(string.size); + if(bucket_num == ArrayCount(ctrl_entity_string_bucket_chunk_sizes)) { - node = 0; - CTRL_EntityStringChunkNode *prev = 0; - for(CTRL_EntityStringChunkNode *n = store->free_string_chunks[bucket_idx]; - n != 0; - prev = n, n = n->next) + CTRL_EntityStringChunkNode *best_node = 0; + CTRL_EntityStringChunkNode *best_node_prev = 0; + U64 best_node_size = max_U64; { - if(n->size >= string.size) + for(CTRL_EntityStringChunkNode *n = store->free_string_chunks[bucket_num-1], *prev = 0; n != 0; (prev = n, n = n->next)) { - if(prev == 0) + if(n->size >= string.size && n->size < best_node_size) { - store->free_string_chunks[bucket_idx] = n->next; + best_node = n; + best_node_prev = prev; + best_node_size = n->size; } - else - { - prev->next = n->next; - } - node = n; - break; } } + if(best_node != 0) + { + node = best_node; + if(best_node_prev) + { + best_node_prev->next = best_node->next; + } + else + { + store->free_string_chunks[bucket_num-1] = best_node->next; + } + } + else + { + U64 chunk_size = u64_up_to_pow2(string.size); + node = (CTRL_EntityStringChunkNode *)push_array(store->arena, U8, chunk_size); + } } - else + else if(bucket_num != 0) { - SLLStackPop(store->free_string_chunks[bucket_idx]); + node = store->free_string_chunks[bucket_num-1]; + if(node != 0) + { + SLLStackPop(store->free_string_chunks[bucket_num-1]); + } + else + { + node = (CTRL_EntityStringChunkNode *)push_array(store->arena, U8, ctrl_entity_string_bucket_chunk_sizes[bucket_num-1]); + } } } - // rjf: no found node -> allocate new - if(node == 0) + //- rjf: fill node + String8 result = {0}; + if(node != 0) { - U64 chunk_size = 0; - if(bucket_idx < ArrayCount(store->free_string_chunks)-1) - { - chunk_size = 1<<(bucket_idx+4); - } - else - { - chunk_size = u64_up_to_pow2(string.size); - } - U8 *chunk_memory = push_array(store->arena, U8, chunk_size); - node = (CTRL_EntityStringChunkNode *)chunk_memory; - node->size = chunk_size; + result.str = (U8 *)node; + result.size = string.size; + MemoryCopy(result.str, string.str, result.size); } - - // rjf: fill string & return - String8 allocated_string = str8((U8 *)node, string.size); - MemoryCopy((U8 *)node, string.str, string.size); - return allocated_string; + return result; } internal void ctrl_entity_string_release(CTRL_EntityStore *store, String8 string) { - if(string.size == 0) {return;} - U64 bucket_idx = ctrl_name_bucket_idx_from_string_size(string.size); - CTRL_EntityStringChunkNode *node = (CTRL_EntityStringChunkNode *)string.str; - node->size = u64_up_to_pow2(string.size); - SLLStackPush(store->free_string_chunks[bucket_idx], node); + U64 bucket_num = ctrl_name_bucket_num_from_string_size(string.size); + if(1 <= bucket_num && bucket_num <= ArrayCount(rd_name_bucket_chunk_sizes)) + { + U64 bucket_idx = bucket_num-1; + CTRL_EntityStringChunkNode *node = (CTRL_EntityStringChunkNode *)string.str; + SLLStackPush(store->free_string_chunks[bucket_idx], node); + node->size = u64_up_to_pow2(string.size); + } } //- rjf: entity construction/deletion @@ -1305,7 +1360,6 @@ ctrl_init(void) ctrl_state->ctrl_thread_entity_store = ctrl_entity_store_alloc(); ctrl_state->dmn_event_arena = arena_alloc(); ctrl_state->user_entry_point_arena = arena_alloc(); - ctrl_state->user_meta_eval_arena = arena_alloc(); ctrl_state->dbg_dir_arena = arena_alloc(); for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)0; k < CTRL_ExceptionCodeKind_COUNT; k = (CTRL_ExceptionCodeKind)(k+1)) { @@ -1370,6 +1424,7 @@ ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B3 //- rjf: try to read from cache B32 is_good = 0; + B32 process_node_exists = 0; B32 is_stale = 1; OS_MutexScopeR(process_stripe->rw_mutex) { @@ -1377,6 +1432,7 @@ ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B3 { if(ctrl_handle_match(n->handle, process)) { + process_node_exists = 1; U64 range_slot_idx = range_hash%n->range_hash_slots_count; CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx]; for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next) @@ -1395,7 +1451,7 @@ ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B3 } //- rjf: not good -> create process cache node if necessary - if(!is_good) + if(!is_good && !process_node_exists) { OS_MutexScopeW(process_stripe->rw_mutex) { @@ -2994,44 +3050,118 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa internal CTRL_CallStack ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *process, CTRL_Unwind *base_unwind) { + Temp scratch = scratch_begin(&arena, 1); Arch arch = process->arch; CTRL_CallStack result = {0}; - result.concrete_frame_count = base_unwind->frames.count; - result.total_frame_count = result.concrete_frame_count; - result.frames = push_array(arena, CTRL_CallStackFrame, result.concrete_frame_count); - for(U64 idx = 0; idx < result.concrete_frame_count; idx += 1) { - CTRL_UnwindFrame *src = &base_unwind->frames.v[idx]; - CTRL_CallStackFrame *dst = &result.frames[idx]; - U64 rip_vaddr = regs_rip_from_arch_block(arch, src->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); - U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); - RDI_Scope *scope = rdi_scope_from_voff(rdi, rip_voff); - - // rjf: fill concrete frame info - dst->regs = src->regs; - dst->rdi = rdi; - dst->procedure = rdi_element_from_name_idx(rdi, Procedures, scope->proc_idx); - - // rjf: push inline frames - for(RDI_Scope *s = scope; - s->inline_site_idx != 0; - s = rdi_element_from_name_idx(rdi, Scopes, s->parent_scope_idx)) + typedef struct FrameNode FrameNode; + struct FrameNode { - RDI_InlineSite *site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); - CTRL_CallStackInlineFrame *inline_frame = push_array(arena, CTRL_CallStackInlineFrame, 1); - DLLPushFront(dst->first_inline_frame, dst->last_inline_frame, inline_frame); - inline_frame->inline_site = site; - dst->inline_frame_count += 1; - result.inline_frame_count += 1; - result.total_frame_count += 1; + FrameNode *next; + CTRL_CallStackFrame v; + }; + + //- rjf: gather all frames + FrameNode *first_frame = 0; + FrameNode *last_frame = 0; + U64 frame_count = 0; + for(U64 base_frame_idx = 0; base_frame_idx < base_unwind->frames.count; base_frame_idx += 1) + { + // rjf: unpack + CTRL_UnwindFrame *src = &base_unwind->frames.v[base_frame_idx]; + U64 rip_vaddr = regs_rip_from_arch_block(arch, src->regs); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); + U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); + RDI_Scope *scope = rdi_scope_from_voff(rdi, rip_voff); + + // rjf: build inline frames (minus parent & inline depth) + FrameNode *first_inline_frame = 0; + FrameNode *last_inline_frame = 0; + U64 inline_frame_count = 0; + for(RDI_Scope *s = scope; + s->inline_site_idx != 0; + s = rdi_element_from_name_idx(rdi, Scopes, s->parent_scope_idx)) + { + FrameNode *dst_inline = push_array(scratch.arena, FrameNode, 1); + if(first_inline_frame == 0) + { + first_inline_frame = dst_inline; + } + last_inline_frame = dst_inline; + SLLQueuePush(first_frame, last_frame, dst_inline); + dst_inline->v.unwind_count = base_frame_idx; + dst_inline->v.regs = src->regs; + dst_inline->v.rdi = rdi; + dst_inline->v.inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); + frame_count += 1; + inline_frame_count += 1; + } + + // rjf: build concrete frame + FrameNode *dst_base = push_array(scratch.arena, FrameNode, 1); + SLLQueuePush(first_frame, last_frame, dst_base); + dst_base->v.unwind_count = base_frame_idx; + dst_base->v.regs = src->regs; + dst_base->v.rdi = rdi; + dst_base->v.procedure = rdi_element_from_name_idx(rdi, Procedures, scope->proc_idx); + frame_count += 1; + + // rjf: hook up inline frames to point to concrete frame, and to account for inline depth + U64 inline_frame_idx = 0; + for(FrameNode *inline_frame = first_inline_frame; inline_frame != 0; inline_frame = inline_frame->next, inline_frame_idx += 1) + { + inline_frame->v.parent_num = frame_count; + inline_frame->v.inline_depth = inline_frame_count - inline_frame_idx; + if(inline_frame == last_inline_frame) + { + break; + } + } + } + + //- rjf: package + result.count = frame_count; + result.frames = push_array(arena, CTRL_CallStackFrame, result.count); + { + U64 idx = 0; + for(FrameNode *n = first_frame; n != 0; n = n->next, idx += 1) + { + MemoryCopyStruct(&result.frames[idx], &n->v); + } } } + scratch_end(scratch); return result; } +internal CTRL_CallStackFrame * +ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U64 unwind_count, U64 inline_depth) +{ + CTRL_CallStackFrame *f = 0; + { + U64 base_frame_idx = 0; + for(U64 idx = 0; idx < call_stack->count; idx += 1) + { + if(call_stack->frames[idx].parent_num == 0) + { + if(base_frame_idx == unwind_count) + { + f = &call_stack->frames[idx]; + break; + } + base_frame_idx += 1; + } + } + if(f != 0 && call_stack->frames + inline_depth < f) + { + f -= inline_depth; + } + } + return f; +} + //////////////////////////////// //~ rjf: Halting All Attached Processes @@ -3242,8 +3372,6 @@ ctrl_thread__entry_point(void *p) //- rjf: unpack per-message parameterizations & store { MemoryCopyArray(ctrl_state->exception_code_filters, msg->exception_code_filters); - arena_clear(ctrl_state->user_meta_eval_arena); - ctrl_state->user_meta_evals = *deep_copy_from_struct(ctrl_state->user_meta_eval_arena, CTRL_MetaEvalArray, &msg->meta_evals); } //- rjf: process message @@ -3331,11 +3459,11 @@ ctrl_thread__entry_point(void *p) //- rjf: breakpoint resolution internal void -ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out) +ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out) { if(user_bps->first == 0) { return; } Temp scratch = scratch_begin(&arena, 1); - DI_Scope *di_scope = di_scope_open(); + DI_Scope *di_scope = eval_scope->di_scope; CTRL_Entity *module_entity = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, module); CTRL_Entity *debug_info_path_entity = ctrl_entity_child_from_kind(module_entity, CTRL_EntityKind_DebugInfoPath); DI_Key dbgi_key = {debug_info_path_entity->string, debug_info_path_entity->timestamp}; @@ -3399,45 +3527,37 @@ ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_Handle proc } }break; - //- rjf: symbol:voff-based breakpoints - case CTRL_UserBreakpointKind_SymbolNameAndOffset: + //- rjf: expression-based breakpoints + case CTRL_UserBreakpointKind_Expression: { - String8 symbol_name = bp->string; - U64 voff = bp->u64; - RDI_NameMap *mapptr = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); - RDI_ParsedNameMap map = {0}; - rdi_parsed_from_name_map(rdi, mapptr, &map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &map, symbol_name.str, symbol_name.size); - if(node != 0) + String8 expr = bp->string; + E_Value value = e_value_from_string(expr); + if(value.u64 != 0) { - U32 id_count = 0; - U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count); - for(U32 match_i = 0; match_i < id_count; match_i += 1) - { - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, ids[match_i]); - U64 proc_voff = rdi_first_voff_from_procedure(rdi, procedure); - U64 proc_vaddr = proc_voff + base_vaddr; - DMN_Trap trap = {process.dmn_handle, proc_vaddr + voff, (U64)bp}; - dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); - } + DMN_Trap trap = {process.dmn_handle, value.u64, (U64)bp}; + dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); } }break; } } - di_scope_close(di_scope); scratch_end(scratch); } internal void -ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out) +ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out) { for(CTRL_UserBreakpointNode *n = user_bps->first; n != 0; n = n->next) { CTRL_UserBreakpoint *bp = &n->v; - if(bp->kind == CTRL_UserBreakpointKind_VirtualAddress) + if(bp->kind == CTRL_UserBreakpointKind_Expression) { - DMN_Trap trap = {process.dmn_handle, bp->u64, (U64)bp}; - dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); + String8 expr = bp->string; + E_Value value = e_value_from_string(expr); + if(value.u64 != 0) + { + DMN_Trap trap = {process.dmn_handle, value.u64, (U64)bp}; + dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); + } } } } @@ -4404,42 +4524,134 @@ ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) //- rjf: meta evaluations case CTRL_EvalSpaceKind_Meta: { - Temp scratch = scratch_begin(0, 0); - U64 meta_eval_idx = space.u64s[0]; - if(meta_eval_idx < ctrl_state->user_meta_evals.count) - { - CTRL_MetaEval *meval = &ctrl_state->user_meta_evals.v[meta_eval_idx]; - - // rjf: copy meta evaluation to scratch arena, to form range of legal reads - arena_push(scratch.arena, 0, 64); - String8 meval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, meval); - U64 pos_min = arena_pos(scratch.arena); - CTRL_MetaEval *meval_read = struct_from_serialized(scratch.arena, CTRL_MetaEval, meval_srlzed); - U64 pos_opl = arena_pos(scratch.arena); - - // rjf: rebase all pointer values in meta evaluation to be relative to base pointer - struct_rebase_ptrs(CTRL_MetaEval, meval_read, meval_read); - - // rjf: perform actual read - Rng1U64 legal_range = r1u64(0, pos_opl-pos_min); - if(contains_1u64(legal_range, range.min)) - { - result = 1; - U64 range_dim = dim_1u64(range); - U64 bytes_to_read = Min(range_dim, (legal_range.max - range.min)); - MemoryCopy(out, ((U8 *)meval_read) + range.min, bytes_to_read); - if(bytes_to_read < range_dim) - { - MemoryZero((U8 *)out + bytes_to_read, range_dim - bytes_to_read); - } - } - } - scratch_end(scratch); + }break; } return result; } +//- rjf: control thread eval scopes + +internal CTRL_EvalScope * +ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) +{ + CTRL_EvalScope *scope = push_array(arena, CTRL_EvalScope, 1); + scope->di_scope = di_scope_open(); + + // rjf: unpack thread + Arch arch = thread->arch; + U64 thread_rip_vaddr = dmn_rip_from_thread(thread->handle.dmn_handle); + CTRL_Entity *process = ctrl_process_from_entity(thread); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); + U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); + + // rjf: gather evaluation modules + U64 eval_modules_count = Max(1, ctrl_state->ctrl_thread_entity_store->entity_kind_counts[CTRL_EntityKind_Module]); + E_Module *eval_modules = push_array(arena, E_Module, eval_modules_count); + E_Module *eval_modules_primary = &eval_modules[0]; + eval_modules_primary->rdi = &di_rdi_parsed_nil; + eval_modules_primary->vaddr_range = r1u64(0, max_U64); + { + U64 eval_module_idx = 0; + for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; + machine != &ctrl_entity_nil; + machine = machine->next) + { + if(machine->kind != CTRL_EntityKind_Machine) { continue; } + for(CTRL_Entity *process = machine->first; + process != &ctrl_entity_nil; + process = process->next) + { + if(process->kind != CTRL_EntityKind_Process) { continue; } + for(CTRL_Entity *mod = process->first; + mod != &ctrl_entity_nil; + mod = mod->next) + { + if(mod->kind != CTRL_EntityKind_Module) { continue; } + CTRL_Entity *dbg_path = ctrl_entity_child_from_kind(mod, CTRL_EntityKind_DebugInfoPath); + DI_Key dbgi_key = {dbg_path->string, dbg_path->timestamp}; + eval_modules[eval_module_idx].arch = arch; + eval_modules[eval_module_idx].rdi = di_rdi_from_key(scope->di_scope, &dbgi_key, max_U64); + eval_modules[eval_module_idx].vaddr_range = mod->vaddr_range; + eval_modules[eval_module_idx].space = e_space_make(CTRL_EvalSpaceKind_Entity); + eval_modules[eval_module_idx].space.u64_0 = (U64)process; + if(mod == module) + { + eval_modules_primary = &eval_modules[eval_module_idx]; + } + eval_module_idx += 1; + } + } + } + } + + // rjf: build eval type context + { + E_TypeCtx *ctx = &scope->type_ctx; + ctx->ip_vaddr = thread_rip_vaddr; + ctx->ip_voff = thread_rip_voff; + ctx->modules = eval_modules; + ctx->modules_count = eval_modules_count; + ctx->primary_module = eval_modules_primary; + } + e_select_type_ctx(&scope->type_ctx); + + // rjf: build eval parse context + ProfScope("build eval parse context") + { + E_ParseCtx *ctx = &scope->parse_ctx; + ctx->ip_vaddr = thread_rip_vaddr; + ctx->ip_voff = thread_rip_voff; + ctx->ip_thread_space = e_space_make(CTRL_EvalSpaceKind_Entity); + ctx->ip_thread_space.u64_0 = (U64)thread; + ctx->modules = eval_modules; + ctx->modules_count = eval_modules_count; + ctx->primary_module = eval_modules_primary; + ctx->regs_map = ctrl_string2reg_from_arch(arch); + ctx->reg_alias_map = ctrl_string2alias_from_arch(arch); + ctx->locals_map = e_push_locals_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); + ctx->member_map = e_push_member_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); + } + e_select_parse_ctx(&scope->parse_ctx); + + // rjf: build eval IR context + { + E_IRCtx *ctx = &scope->ir_ctx; + ctx->macro_map = push_array(arena, E_String2ExprMap, 1); + ctx->macro_map[0] = e_string2expr_map_make(arena, 512); + ctx->lookup_rule_map = push_array(arena, E_LookupRuleMap, 1); + ctx->lookup_rule_map[0] = e_lookup_rule_map_make(arena, 512); + ctx->irgen_rule_map = push_array(arena, E_IRGenRuleMap, 1); + ctx->irgen_rule_map[0] = e_irgen_rule_map_make(arena, 512); + ctx->auto_hook_map = push_array(arena, E_AutoHookMap, 1); + ctx->auto_hook_map[0] = e_auto_hook_map_make(arena, 512); + } + e_select_ir_ctx(&scope->ir_ctx); + + // rjf: build eval interpretation context + { + E_InterpretCtx *ctx = &scope->interpret_ctx; + ctx->space_rw_user_data = ctrl_state->ctrl_thread_entity_store; + ctx->space_read = ctrl_eval_space_read; + ctx->primary_space = eval_modules_primary->space; + ctx->reg_arch = eval_modules_primary->arch; + ctx->reg_space = e_space_make(CTRL_EvalSpaceKind_Entity); + ctx->reg_space.u64_0 = (U64)thread; + ctx->module_base = push_array(arena, U64, 1); + ctx->module_base[0]= module->vaddr_range.min; + ctx->tls_base = push_array(arena, U64, 1); + } + e_select_interpret_ctx(&scope->interpret_ctx); + + return scope; +} + +internal void +ctrl_thread__eval_scope_end(CTRL_EvalScope *scope) +{ + di_scope_close(scope->di_scope); +} + //- rjf: log flusher internal void @@ -4771,25 +4983,30 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) //- rjf: gather all initial breakpoints // DMN_TrapChunkList user_traps = {0}; - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; - machine != &ctrl_entity_nil; - machine = machine->next) { - if(machine->kind != CTRL_EntityKind_Machine) { continue; } - for(CTRL_Entity *process = machine->first; process != &ctrl_entity_nil; process = process->next) + CTRL_Entity *thread = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, target_thread); + CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(scratch.arena, thread); + for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; + machine != &ctrl_entity_nil; + machine = machine->next) { - if(process->kind != CTRL_EntityKind_Process) { continue; } - - // rjf: resolve module-dependent user bps - for(CTRL_Entity *module = process->first; module != &ctrl_entity_nil; module = module->next) + if(machine->kind != CTRL_EntityKind_Machine) { continue; } + for(CTRL_Entity *process = machine->first; process != &ctrl_entity_nil; process = process->next) { - if(module->kind != CTRL_EntityKind_Module) { continue; } - ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, process->handle, module->handle, &msg->user_bps, &user_traps); + if(process->kind != CTRL_EntityKind_Process) { continue; } + + // rjf: resolve module-dependent user bps + for(CTRL_Entity *module = process->first; module != &ctrl_entity_nil; module = module->next) + { + if(module->kind != CTRL_EntityKind_Module) { continue; } + ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, eval_scope, process->handle, module->handle, &msg->user_bps, &user_traps); + } + + // rjf: push virtual-address user breakpoints per-process + ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, eval_scope, process->handle, &msg->user_bps, &user_traps); } - - // rjf: push virtual-address user breakpoints per-process - ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, process->handle, &msg->user_bps, &user_traps); } + ctrl_thread__eval_scope_end(eval_scope); } ////////////////////////////// @@ -5053,39 +5270,48 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) }break; case DMN_EventKind_CreateProcess: { - DMN_TrapChunkList new_traps = {0}; - ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, ctrl_handle_make(CTRL_MachineID_Local, event->process), &msg->user_bps, &new_traps); - log_infof("step_rule: create_process -> resolve traps\n"); - log_infof("new_traps:\n{\n"); - for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next) + CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(scratch.arena, &ctrl_entity_nil); { - for(U64 idx = 0; idx < n->count; idx += 1) + DMN_TrapChunkList new_traps = {0}; + ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, eval_scope, ctrl_handle_make(CTRL_MachineID_Local, event->process), &msg->user_bps, &new_traps); + log_infof("step_rule: create_process -> resolve traps\n"); + log_infof("new_traps:\n{\n"); + for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next) { - DMN_Trap *trap = &n->v[idx]; - log_infof("{process:[0x%I64x], vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr); + for(U64 idx = 0; idx < n->count; idx += 1) + { + DMN_Trap *trap = &n->v[idx]; + log_infof("{process:[0x%I64x], vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr); + } } + log_infof("}\n\n"); + dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps); + dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps); } - log_infof("}\n\n"); - dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps); - dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps); + ctrl_thread__eval_scope_end(eval_scope); }break; case DMN_EventKind_LoadModule: { - DMN_TrapChunkList new_traps = {0}; - ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, ctrl_handle_make(CTRL_MachineID_Local, event->process), ctrl_handle_make(CTRL_MachineID_Local, event->module), &msg->user_bps, &new_traps); - log_infof("step_rule: load_module -> resolve traps\n"); - log_infof("new_traps:\n{\n"); - for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next) + CTRL_Entity *thread = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, event->thread)); + CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(scratch.arena, thread); { - for(U64 idx = 0; idx < n->count; idx += 1) + DMN_TrapChunkList new_traps = {0}; + ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, eval_scope, ctrl_handle_make(CTRL_MachineID_Local, event->process), ctrl_handle_make(CTRL_MachineID_Local, event->module), &msg->user_bps, &new_traps); + log_infof("step_rule: load_module -> resolve traps\n"); + log_infof("new_traps:\n{\n"); + for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next) { - DMN_Trap *trap = &n->v[idx]; - log_infof("{process:[0x%I64x], vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr); + for(U64 idx = 0; idx < n->count; idx += 1) + { + DMN_Trap *trap = &n->v[idx]; + log_infof("{process:[0x%I64x], vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr); + } } + log_infof("}\n\n"); + dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps); + dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps); } - log_infof("}\n\n"); - dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps); - dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps); + ctrl_thread__eval_scope_end(eval_scope); }break; } @@ -5406,118 +5632,9 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) // rjf: evaluate hit stop conditions if(conditions.node_count != 0) ProfScope("evaluate hit stop conditions") { - DI_Scope *di_scope = di_scope_open(); - - // rjf: gather evaluation modules - U64 eval_modules_count = Max(1, ctrl_state->ctrl_thread_entity_store->entity_kind_counts[CTRL_EntityKind_Module]); - E_Module *eval_modules = push_array(temp.arena, E_Module, eval_modules_count); - E_Module *eval_modules_primary = &eval_modules[0]; - eval_modules_primary->rdi = &di_rdi_parsed_nil; - eval_modules_primary->vaddr_range = r1u64(0, max_U64); - { - U64 eval_module_idx = 0; - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; - machine != &ctrl_entity_nil; - machine = machine->next) - { - if(machine->kind != CTRL_EntityKind_Machine) { continue; } - for(CTRL_Entity *process = machine->first; - process != &ctrl_entity_nil; - process = process->next) - { - if(process->kind != CTRL_EntityKind_Process) { continue; } - for(CTRL_Entity *mod = process->first; - mod != &ctrl_entity_nil; - mod = mod->next) - { - if(mod->kind != CTRL_EntityKind_Module) { continue; } - CTRL_Entity *dbg_path = ctrl_entity_child_from_kind(mod, CTRL_EntityKind_DebugInfoPath); - DI_Key dbgi_key = {dbg_path->string, dbg_path->timestamp}; - eval_modules[eval_module_idx].arch = arch; - eval_modules[eval_module_idx].rdi = di_rdi_from_key(di_scope, &dbgi_key, max_U64); - eval_modules[eval_module_idx].vaddr_range = mod->vaddr_range; - eval_modules[eval_module_idx].space = e_space_make(CTRL_EvalSpaceKind_Entity); - eval_modules[eval_module_idx].space.u64_0 = (U64)process; - if(mod == module) - { - eval_modules_primary = &eval_modules[eval_module_idx]; - } - eval_module_idx += 1; - } - } - } - } - - // rjf: loop through all conditions, check all + CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(temp.arena, thread); for(String8Node *condition_n = conditions.first; condition_n != 0; condition_n = condition_n->next) { - // rjf: build eval type context - E_TypeCtx type_ctx = zero_struct; - { - E_TypeCtx *ctx = &type_ctx; - ctx->ip_vaddr = thread_rip_vaddr; - ctx->ip_voff = thread_rip_voff; - ctx->modules = eval_modules; - ctx->modules_count = eval_modules_count; - ctx->primary_module = eval_modules_primary; - } - e_select_type_ctx(&type_ctx); - - // rjf: build eval parse context - E_ParseCtx parse_ctx = zero_struct; - ProfScope("build eval parse context") - { - E_ParseCtx *ctx = &parse_ctx; - ctx->ip_vaddr = thread_rip_vaddr; - ctx->ip_voff = thread_rip_voff; - ctx->ip_thread_space = e_space_make(CTRL_EvalSpaceKind_Entity); - ctx->ip_thread_space.u64_0 = (U64)thread; - ctx->modules = eval_modules; - ctx->modules_count = eval_modules_count; - ctx->primary_module = eval_modules_primary; - ctx->regs_map = ctrl_string2reg_from_arch(arch); - ctx->reg_alias_map = ctrl_string2alias_from_arch(arch); - ctx->locals_map = e_push_locals_map_from_rdi_voff(temp.arena, eval_modules_primary->rdi, thread_rip_voff); - ctx->member_map = e_push_member_map_from_rdi_voff(temp.arena, eval_modules_primary->rdi, thread_rip_voff); - } - e_select_parse_ctx(&parse_ctx); - - // rjf: build eval IR context - E_IRCtx ir_ctx = zero_struct; - { - E_IRCtx *ctx = &ir_ctx; - ctx->macro_map = push_array(temp.arena, E_String2ExprMap, 1); - ctx->macro_map[0] = e_string2expr_map_make(temp.arena, 512); - E_TypeKey meval_type_key = e_type_key_cons_base(type(CTRL_MetaEval)); - for EachIndex(idx, ctrl_state->user_meta_evals.count) - { - E_Space space = e_space_make(CTRL_EvalSpaceKind_Meta); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->space = space; - expr->mode = E_Mode_Offset; - expr->type_key = meval_type_key; - e_string2expr_map_insert(temp.arena, ctx->macro_map, ctrl_state->user_meta_evals.v[idx].label, expr); - } - } - e_select_ir_ctx(&ir_ctx); - - // rjf: build eval interpretation context - E_InterpretCtx interpret_ctx = zero_struct; - { - E_InterpretCtx *ctx = &interpret_ctx; - ctx->space_rw_user_data = ctrl_state->ctrl_thread_entity_store; - ctx->space_read = ctrl_eval_space_read; - ctx->primary_space = eval_modules_primary->space; - ctx->reg_arch = eval_modules_primary->arch; - ctx->reg_space = e_space_make(CTRL_EvalSpaceKind_Entity); - ctx->reg_space.u64_0 = (U64)thread; - ctx->module_base = push_array(temp.arena, U64, 1); - ctx->module_base[0]= module->vaddr_range.min; - ctx->frame_base = push_array(temp.arena, U64, 1); - ctx->tls_base = push_array(temp.arena, U64, 1); - } - e_select_interpret_ctx(&interpret_ctx, type_ctx.primary_module->rdi, type_ctx.ip_voff); - // rjf: evaluate E_Eval eval = zero_struct; ProfScope("evaluate expression") @@ -5540,7 +5657,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) break; } } - di_scope_close(di_scope); + ctrl_thread__eval_scope_end(eval_scope); } // rjf: gather trap net hits @@ -5848,6 +5965,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) event->entity = ctrl_handle_make(CTRL_MachineID_Local, stop_event->thread); event->parent = ctrl_handle_make(CTRL_MachineID_Local, stop_event->process); event->exception_code = stop_event->code; + event->exception_kind = ctrl_exception_kind_from_dmn(stop_event->exception_kind); event->vaddr_rng = r1u64(stop_event->address, stop_event->address); event->rip_vaddr = stop_event->instruction_pointer; ctrl_c2u_push_events(&evts); @@ -5922,6 +6040,7 @@ ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) event->entity = ctrl_handle_make(CTRL_MachineID_Local, stop_event->thread); event->parent = ctrl_handle_make(CTRL_MachineID_Local, stop_event->process); event->exception_code = stop_event->code; + event->exception_kind = ctrl_exception_kind_from_dmn(stop_event->exception_kind); event->vaddr_rng = r1u64(stop_event->address, stop_event->address); event->rip_vaddr = stop_event->instruction_pointer; } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 3540e87f..92541b1c 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -12,229 +12,6 @@ typedef U64 CTRL_MachineID; #define CTRL_MachineID_Local (1) -//////////////////////////////// -//~ rjf: Meta Evaluation Types - -//- rjf: auto-checkbox b32s - -typedef struct CTRL_CheckB32 CTRL_CheckB32; -struct CTRL_CheckB32 -{ - B32 b32; -}; - -struct_members(CTRL_CheckB32) -{ - member_lit_comp(CTRL_CheckB32, type(B32), b32), -}; -struct_type(CTRL_CheckB32); - -//- rjf: styled string types - -ptr_type(CTRL_PlainString8__str_ptr_type, type(U8), .flags = TypeFlag_IsPlainText,.count_delimiter_name = str8_lit_comp("size")); -ptr_type(CTRL_CodeString8__str_ptr_type, type(U8), .flags = TypeFlag_IsCodeText, .count_delimiter_name = str8_lit_comp("size")); -ptr_type(CTRL_PathString8__str_ptr_type, type(U8), .flags = TypeFlag_IsPathText, .count_delimiter_name = str8_lit_comp("size")); -Member CTRL_PlainString8__members[] = -{ - member_lit_comp(String8, &CTRL_PlainString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")), - member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")), -}; -Member CTRL_CodeString8__members[] = -{ - member_lit_comp(String8, &CTRL_CodeString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")), - member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")), -}; -Member CTRL_PathString8__members[] = -{ - member_lit_comp(String8, &CTRL_PathString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")), - member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")), -}; -named_struct_type(CTRL_PlainString8, String8, .name = str8_lit_comp("string")); -named_struct_type(CTRL_CodeString8, String8, .name = str8_lit_comp("string")); -named_struct_type(CTRL_PathString8, String8, .name = str8_lit_comp("string")); - -//- rjf: meta evaluation callstack types - -typedef struct CTRL_MetaEvalFrame CTRL_MetaEvalFrame; -struct CTRL_MetaEvalFrame -{ - U64 vaddr; - U64 inline_depth; -}; -ptr_type(CTRL_MetaEvalFrame__vaddr_type, type(void), .flags = TypeFlag_IsExternal, .size = sizeof(U64)); -struct_members(CTRL_MetaEvalFrame) -{ - member_lit_comp(CTRL_MetaEvalFrame, &CTRL_MetaEvalFrame__vaddr_type, vaddr), - member_lit_comp(CTRL_MetaEvalFrame, type(U64), inline_depth), -}; -struct_type(CTRL_MetaEvalFrame, .name = str8_lit_comp("callstack_frame")); -typedef struct CTRL_MetaEvalFrameArray CTRL_MetaEvalFrameArray; -struct CTRL_MetaEvalFrameArray -{ - U64 count; - CTRL_MetaEvalFrame *v; -}; -ptr_type(CTRL_MetaEvalFrameArray__v_ptr_type, type(CTRL_MetaEvalFrame), .count_delimiter_name = str8_lit_comp("count")); -struct_members(CTRL_MetaEvalFrameArray) -{ - member_lit_comp(CTRL_MetaEvalFrameArray, type(U64), count, .pretty_name = str8_lit_comp("Frame Count")), - {str8_lit_comp("v"), str8_lit_comp("Frame Addresses"), &CTRL_MetaEvalFrameArray__v_ptr_type, OffsetOf(CTRL_MetaEvalFrameArray, v)}, -}; -struct_type(CTRL_MetaEvalFrameArray, .name = str8_lit_comp("callstack_frames")); - -//- rjf: meta evaluation instance types - -typedef struct CTRL_MetaEval CTRL_MetaEval; -struct CTRL_MetaEval -{ -#define CTRL_MetaEval_MemberXList \ -X(B32, enabled, "Enabled")\ -X(B32, frozen, "Frozen")\ -X(U64, hit_count, "Hit Count")\ -X(U64, id, "ID")\ -X(Rng1U64, vaddr_range, "Address Range")\ -X(U32, color, "Color")\ -X(CTRL_CheckB32, debug_subprocesses,"Debug Subprocesses")\ -Y(String8, type(CTRL_CodeString8), label, "Label")\ -Y(String8, type(CTRL_PathString8), exe, "Executable Path")\ -Y(String8, type(CTRL_PathString8), dbg, "Debug Info Path")\ -Y(String8, type(CTRL_PlainString8), args, "Arguments")\ -Y(String8, type(CTRL_PathString8), working_directory, "Working Directory")\ -Y(String8, type(CTRL_CodeString8), entry_point, "Custom Entry Point")\ -Y(String8, type(CTRL_PathString8), stdout_path, "Standard Output Path")\ -Y(String8, type(CTRL_PathString8), stderr_path, "Standard Error Path")\ -Y(String8, type(CTRL_PathString8), stdin_path, "Standard Input Path")\ -Y(String8, type(CTRL_PathString8), source_location, "Source Location")\ -Y(String8, type(CTRL_CodeString8), function_location, "Function Location")\ -Y(String8, type(CTRL_CodeString8), address_location, "Address Location")\ -Y(String8, type(CTRL_PathString8), source_path, "Source Path")\ -Y(String8, type(CTRL_PathString8), destination_path, "Destination Path")\ -Y(String8, type(CTRL_CodeString8), type, "Type")\ -Y(String8, type(CTRL_CodeString8), view_rule, "View Rule")\ -Y(String8, type(CTRL_CodeString8), condition, "Condition")\ -X(CTRL_MetaEvalFrameArray, callstack, "Call Stack") -#define X(T, name, pretty_name) T name; -#define Y(T, ti, name, pretty_name) T name; - CTRL_MetaEval_MemberXList -#undef X -#undef Y -}; -struct_members(CTRL_MetaEval) -{ -#define X(T, name, pretty_name_) member_lit_comp(CTRL_MetaEval, type(T), name, .pretty_name = str8_lit_comp(pretty_name_)), -#define Y(T, ti, name, pretty_name_) member_lit_comp(CTRL_MetaEval, (ti), name, .pretty_name = str8_lit_comp(pretty_name_)), - CTRL_MetaEval_MemberXList -#undef X -#undef Y -}; -struct_type(CTRL_MetaEval); - -//- rjf: filters on main meta evaluation bundle - -struct_members(CTRL_BreakpointMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(B32), enabled, .pretty_name = str8_lit_comp("Enabled")), - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(U64), hit_count, .pretty_name = str8_lit_comp("Hit Count")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Label")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), condition, .pretty_name = str8_lit_comp("Condition")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_location, .pretty_name = str8_lit_comp("Source Location")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), function_location, .pretty_name = str8_lit_comp("Function Location")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), address_location, .pretty_name = str8_lit_comp("Address Location")), -}; - -struct_members(CTRL_TargetMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Label")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), exe, .pretty_name = str8_lit_comp("Executable")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PlainString8),args, .pretty_name = str8_lit_comp("Arguments")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), working_directory, .pretty_name = str8_lit_comp("Working Directory")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), entry_point, .pretty_name = str8_lit_comp("Custom Entry Point")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stdout_path, .pretty_name = str8_lit_comp("Standard Output Path")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stderr_path, .pretty_name = str8_lit_comp("Standard Error Path")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stdin_path, .pretty_name = str8_lit_comp("Standard Input Path")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CheckB32), debug_subprocesses, .pretty_name = str8_lit_comp("Debug Subprocesses")), -}; - -struct_members(CTRL_PinMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Expression")), - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_location, .pretty_name = str8_lit_comp("Source Location")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), address_location, .pretty_name = str8_lit_comp("Address Location")), -}; - -struct_members(CTRL_FilePathMapMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_path, .pretty_name = str8_lit_comp("Source Path")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), destination_path, .pretty_name = str8_lit_comp("Destination Path")), -}; - -struct_members(CTRL_AutoViewRuleMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), type, .pretty_name = str8_lit_comp("Type")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), view_rule, .pretty_name = str8_lit_comp("View Rule")), -}; - -struct_members(CTRL_MachineMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")), - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")), -}; - -struct_members(CTRL_ProcessMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")), - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")), - member_lit_comp(CTRL_MetaEval, type(U64), id, .pretty_name = str8_lit_comp("ID")), -}; - -struct_members(CTRL_ModuleMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), exe, .pretty_name = str8_lit_comp("Executable Path")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), dbg, .pretty_name = str8_lit_comp("Debug Info Path")), - member_lit_comp(CTRL_MetaEval, type(Rng1U64), vaddr_range, .pretty_name = str8_lit_comp("Address Range")), -}; - -struct_members(CTRL_ThreadMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")), - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")), - member_lit_comp(CTRL_MetaEval, type(U64), id, .pretty_name = str8_lit_comp("ID")), - member_lit_comp(CTRL_MetaEval, type(CTRL_MetaEvalFrameArray), callstack, .pretty_name = str8_lit_comp("Call Stack")), -}; - -named_struct_type(CTRL_BreakpointMetaEval, CTRL_MetaEval, .name = str8_lit_comp("breakpoint")); -named_struct_type(CTRL_TargetMetaEval, CTRL_MetaEval, .name = str8_lit_comp("target")); -named_struct_type(CTRL_PinMetaEval, CTRL_MetaEval, .name = str8_lit_comp("pin")); -named_struct_type(CTRL_FilePathMapMetaEval, CTRL_MetaEval, .name = str8_lit_comp("file_path_map")); -named_struct_type(CTRL_AutoViewRuleMetaEval,CTRL_MetaEval, .name = str8_lit_comp("auto_view_rule")); -named_struct_type(CTRL_MachineMetaEval, CTRL_MetaEval, .name = str8_lit_comp("machine")); -named_struct_type(CTRL_ProcessMetaEval, CTRL_MetaEval, .name = str8_lit_comp("process")); -named_struct_type(CTRL_ModuleMetaEval, CTRL_MetaEval, .name = str8_lit_comp("module")); -named_struct_type(CTRL_ThreadMetaEval, CTRL_MetaEval, .name = str8_lit_comp("thread")); - -//- rjf: meta evaluation array - -typedef struct CTRL_MetaEvalArray CTRL_MetaEvalArray; -struct CTRL_MetaEvalArray -{ - CTRL_MetaEval *v; - U64 count; -}; -ptr_type(CTRL_MetaEvalArray__v_ptr_type, type(CTRL_BreakpointMetaEval), .count_delimiter_name = str8_lit_comp("count")); -struct_members(CTRL_MetaEvalArray) -{ - {str8_lit_comp("v"), {0}, &CTRL_MetaEvalArray__v_ptr_type, OffsetOf(CTRL_MetaEvalArray, v)}, - member_lit_comp(CTRL_MetaEvalArray, type(U64), count), -}; -struct_type(CTRL_MetaEvalArray); - //////////////////////////////// //~ rjf: Entity Handle Types @@ -340,6 +117,18 @@ struct CTRL_EntityStringChunkNode U64 size; }; +read_only global U64 ctrl_entity_string_bucket_chunk_sizes[] = +{ + 16, + 64, + 256, + 1024, + 4096, + 16384, + 65536, + 0xffffffffffffffffull, +}; + typedef struct CTRL_EntityStore CTRL_EntityStore; struct CTRL_EntityStore { @@ -349,7 +138,7 @@ struct CTRL_EntityStore CTRL_EntityHashSlot *hash_slots; CTRL_EntityHashNode *hash_node_free; U64 hash_slots_count; - CTRL_EntityStringChunkNode *free_string_chunks[8]; + CTRL_EntityStringChunkNode *free_string_chunks[ArrayCount(ctrl_entity_string_bucket_chunk_sizes)]; U64 entity_kind_counts[CTRL_EntityKind_COUNT]; Arena *entity_kind_lists_arenas[CTRL_EntityKind_COUNT]; U64 entity_kind_lists_gens[CTRL_EntityKind_COUNT]; @@ -404,32 +193,23 @@ struct CTRL_Unwind //////////////////////////////// //~ rjf: Call Stack Types -typedef struct CTRL_CallStackInlineFrame CTRL_CallStackInlineFrame; -struct CTRL_CallStackInlineFrame -{ - CTRL_CallStackInlineFrame *next; - CTRL_CallStackInlineFrame *prev; - RDI_InlineSite *inline_site; -}; - typedef struct CTRL_CallStackFrame CTRL_CallStackFrame; struct CTRL_CallStackFrame { - CTRL_CallStackInlineFrame *first_inline_frame; - CTRL_CallStackInlineFrame *last_inline_frame; - U64 inline_frame_count; + U64 parent_num; + U64 unwind_count; + U64 inline_depth; void *regs; RDI_Parsed *rdi; RDI_Procedure *procedure; + RDI_InlineSite *inline_site; }; typedef struct CTRL_CallStack CTRL_CallStack; struct CTRL_CallStack { CTRL_CallStackFrame *frames; - U64 concrete_frame_count; - U64 inline_frame_count; - U64 total_frame_count; + U64 count; }; //////////////////////////////// @@ -483,8 +263,7 @@ typedef enum CTRL_UserBreakpointKind { CTRL_UserBreakpointKind_Null, CTRL_UserBreakpointKind_FileNameAndLineColNumber, - CTRL_UserBreakpointKind_SymbolNameAndOffset, - CTRL_UserBreakpointKind_VirtualAddress, + CTRL_UserBreakpointKind_Expression, CTRL_UserBreakpointKind_COUNT } CTRL_UserBreakpointKind; @@ -573,7 +352,6 @@ struct CTRL_Msg String8 stdin_path; CTRL_TrapList traps; CTRL_UserBreakpointList user_bps; - CTRL_MetaEvalArray meta_evals; }; typedef struct CTRL_MsgNode CTRL_MsgNode; @@ -857,6 +635,19 @@ struct CTRL_DbgDirNode U64 module_direct_count; }; +//////////////////////////////// +//~ rjf: Control Thread Evaluation Scopes + +typedef struct CTRL_EvalScope CTRL_EvalScope; +struct CTRL_EvalScope +{ + DI_Scope *di_scope; + E_TypeCtx type_ctx; + E_ParseCtx parse_ctx; + E_IRCtx ir_ctx; + E_InterpretCtx interpret_ctx; +}; + //////////////////////////////// //~ rjf: Wakeup Hook Function Types @@ -909,8 +700,6 @@ struct CTRL_State DMN_EventNode *free_dmn_event_node; Arena *user_entry_point_arena; String8List user_entry_points; - Arena *user_meta_eval_arena; - CTRL_MetaEvalArray user_meta_evals; U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]; U64 process_counter; Arena *dbg_dir_arena; @@ -949,8 +738,10 @@ read_only global CTRL_Entity ctrl_entity_nil = internal U64 ctrl_hash_from_string(String8 string); internal U64 ctrl_hash_from_handle(CTRL_Handle handle); internal CTRL_EventCause ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind); +internal CTRL_ExceptionKind ctrl_exception_kind_from_dmn(DMN_ExceptionKind kind); internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind); internal String8 ctrl_string_from_msg_kind(CTRL_MsgKind kind); +internal CTRL_EntityKind ctrl_entity_kind_from_string(String8 string); //////////////////////////////// //~ rjf: Handle Type Functions @@ -960,6 +751,7 @@ internal CTRL_Handle ctrl_handle_make(CTRL_MachineID machine_id, DMN_Handle dmn_ internal B32 ctrl_handle_match(CTRL_Handle a, CTRL_Handle b); internal void ctrl_handle_list_push(Arena *arena, CTRL_HandleList *list, CTRL_Handle *pair); internal CTRL_HandleList ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src); +internal String8 ctrl_string_from_handle(Arena *arena, CTRL_Handle handle); //////////////////////////////// //~ rjf: Trap Type Functions @@ -1015,7 +807,7 @@ internal CTRL_EntityStore *ctrl_entity_store_alloc(void); internal void ctrl_entity_store_release(CTRL_EntityStore *store); //- rjf: string allocation/deletion -internal U64 ctrl_name_bucket_idx_from_string_size(U64 size); +internal U64 ctrl_name_bucket_num_from_string_size(U64 size); internal String8 ctrl_entity_string_alloc(CTRL_EntityStore *store, String8 string); internal void ctrl_entity_string_release(CTRL_EntityStore *store, String8 string); @@ -1120,6 +912,7 @@ internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *sto //~ rjf: Call Stack Building Functions internal CTRL_CallStack ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *process, CTRL_Unwind *base_unwind); +internal CTRL_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U64 unwind_count, U64 inline_depth); //////////////////////////////// //~ rjf: Halting All Attached Processes @@ -1153,8 +946,8 @@ internal CTRL_EventList ctrl_c2u_pop_events(Arena *arena); internal void ctrl_thread__entry_point(void *p); //- rjf: breakpoint resolution -internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); -internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); +internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); +internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); //- rjf: module lifetime open/close work internal void ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path); @@ -1166,6 +959,10 @@ internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ //- rjf: eval helpers internal B32 ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 vaddr_range); +//- rjf: control thread eval scopes +internal CTRL_EvalScope *ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread); +internal void ctrl_thread__eval_scope_end(CTRL_EvalScope *scope); + //- rjf: log flusher internal void ctrl_thread__flush_info_log(String8 string); internal void ctrl_thread__end_and_flush_info_log(void); diff --git a/src/ctrl/generated/ctrl.meta.c b/src/ctrl/generated/ctrl.meta.c index 019fde09..4b45ed27 100644 --- a/src/ctrl/generated/ctrl.meta.c +++ b/src/ctrl/generated/ctrl.meta.c @@ -4,6 +4,19 @@ //- GENERATED CODE C_LINKAGE_BEGIN +String8 ctrl_entity_kind_code_name_table[9] = +{ +{0}, +str8_lit_comp("root"), +str8_lit_comp("machine"), +str8_lit_comp("process"), +str8_lit_comp("thread"), +str8_lit_comp("module"), +str8_lit_comp("entry_point"), +str8_lit_comp("debug_info_path"), +str8_lit_comp("pending_thread_name"), +}; + String8 ctrl_entity_kind_display_string_table[9] = { {0}, diff --git a/src/ctrl/generated/ctrl.meta.h b/src/ctrl/generated/ctrl.meta.h index 9192b4de..8c5e9a3a 100644 --- a/src/ctrl/generated/ctrl.meta.h +++ b/src/ctrl/generated/ctrl.meta.h @@ -64,6 +64,7 @@ CTRL_ExceptionCodeKind_COUNT, } CTRL_ExceptionCodeKind; C_LINKAGE_BEGIN +extern String8 ctrl_entity_kind_code_name_table[9]; extern String8 ctrl_entity_kind_display_string_table[9]; extern U32 ctrl_exception_code_kind_code_table[38]; extern String8 ctrl_exception_code_kind_display_string_table[38]; diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index 8dc7469c..cef6e19f 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -4,53 +4,52 @@ //////////////////////////////// //~ rjf: Built-In Command Tables -@table(name ui_vis ipc_docs_vis q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ) -// / | | | \___ _________________________________/ | | | | | -// / | | | \ / | | | | | -D_CmdTable: // | | | | | | | | | | +@table(name ui_vis ipc_docs_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_floating q_required canonical_icon string display_name desc search_tags ctx_filter) +// / | | | | \___ _________________________________/ | | | | | | +// / | | | | \ / | | | | | | +D_CmdTable: // | | | | | | | | | | | | { //- rjf: low-level target control operations - {LaunchAndRun 1 1 Entity null Target Null 0 0 0 0 0 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" } - {LaunchAndInit 1 1 Entity null Target Null 0 0 0 0 0 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" } - {Kill 1 1 Process null Nil Process 0 0 0 0 0 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" } - {KillAll 1 1 Null null Nil Null 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" } - {Detach 1 1 Process null Nil Process 0 0 0 0 0 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" } - {Continue 1 1 Null null Nil Null 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" } - {StepIntoInst 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" } - {StepOverInst 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" } - {StepIntoLine 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" } - {StepOverLine 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" } - {StepOut 1 1 Null null Nil Null 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" } - {Halt 1 1 Null null Nil Null 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" } - {SoftHaltRefresh 1 1 Null null Nil Null 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" } - {SetThreadIP 0 1 Vaddr null Nil Null 0 0 0 0 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" } + {LaunchAndRun 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" } + {LaunchAndStepInto 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 PlayStepForward "launch_and_step_into" "Launch and Step Into" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } + {Kill 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" "" } + {KillAll 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" "" } + {Detach 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" "" } + {Continue 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" "" } + {StepIntoInst 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" "" } + {StepOverInst 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" "" } + {StepIntoLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" "" } + {StepOverLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" "" } + {StepOut 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" "" } + {Halt 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" "" } + {SoftHaltRefresh 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" "" } + {SetThreadIP 0 1 "" Vaddr null Nil Null 0 0 0 0 1 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" "" } //- rjf: high-level composite target control operations - {RunToLine 0 1 Null null Nil Null 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" } - {RunToAddress 1 1 Vaddr null Nil Null 0 0 0 0 1 1 PlayStepForward "run_to_address" "Run To Address" "Runs until a particular address is hit." "" } - {Run 1 1 Null null Nil Null 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" } - {Restart 1 1 Null null Nil Null 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" } - {StepInto 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" } - {StepOver 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" } + {RunToLine 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," } + {Run 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" "" } + {Restart 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" "" } + {StepInto 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" "" } + {StepOver 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" "" } //- rjf: debug control context management operations - {FreezeThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" } - {ThawThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" } - {FreezeProcess 1 1 Process null Nil Process 0 0 0 0 0 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" } - {ThawProcess 1 1 Process null Nil Process 0 0 0 0 0 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" } - {FreezeMachine 0 1 Machine null Nil Machine 0 0 0 0 0 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" } - {ThawMachine 0 1 Machine null Nil Machine 0 0 0 0 0 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" } - {FreezeLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" } - {ThawLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" } - {FreezeEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "freeze_entity" "Freeze Entity" "Freezes an entity." "" } - {ThawEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "thaw_entity" "Thaw Entity" "Thaws an entity." "" } + {FreezeThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" "" } + {ThawThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" "" } + {FreezeProcess 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" "" } + {ThawProcess 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" "" } + {FreezeMachine 0 1 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" "" } + {ThawMachine 0 1 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" "" } + {FreezeLocalMachine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" "" } + {ThawLocalMachine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" "" } + {FreezeEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Unlocked "freeze_entity" "Freeze Entity" "Freezes an entity." "" "" } + {ThawEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Locked "thaw_entity" "Thaw Entity" "Thaws an entity." "" "" } //- rjf: entity decoration - {SetEntityColor 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" } - {SetEntityName 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" } + {SetEntityColor 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" "" } + {SetEntityName 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" "" } //- rjf: attaching - {Attach 1 1 PID null Nil Null 0 0 0 0 0 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" } + {Attach 1 1 "query:unattached_processes" PID null Nil Null 0 0 0 0 0 1 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" "" } } @enum D_CmdKind: @@ -114,7 +113,6 @@ D_DevToggleTable: {eval_compiler_tooltips} {eval_watch_key_tooltips} {cmd_context_tooltips} - {scratch_mouse_draw} {updating_indicator} } diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index ff307b28..b61e3c6d 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -12,14 +12,16 @@ //////////////////////////////// //~ rjf: Basic Helpers +#if !defined(XXH_IMPLEMENTATION) +# define XXH_IMPLEMENTATION +# define XXH_STATIC_LINKING_ONLY +# include "third_party/xxHash/xxhash.h" +#endif + internal U64 d_hash_from_seed_string(U64 seed, String8 string) { - U64 result = seed; - for(U64 i = 0; i < string.size; i += 1) - { - result = ((result << 5) + result) + string.str[i]; - } + U64 result = XXH3_64bits_withSeed(string.str, string.size, seed); return result; } @@ -59,7 +61,7 @@ d_breakpoint_array_copy(Arena *arena, D_BreakpointArray *src) for(U64 idx = 0; idx < dst.count; idx += 1) { dst.v[idx].file_path = push_str8_copy(arena, dst.v[idx].file_path); - dst.v[idx].symbol_name = push_str8_copy(arena, dst.v[idx].symbol_name); + dst.v[idx].vaddr_expr = push_str8_copy(arena, dst.v[idx].vaddr_expr); dst.v[idx].condition = push_str8_copy(arena, dst.v[idx].condition); } return dst; @@ -667,35 +669,102 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) //- rjf: symbol lookups internal String8 -d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 decorated) +d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, U64 depth, B32 decorated) { String8 result = {0}; { Temp scratch = scratch_begin(&arena, 1); DI_Scope *scope = di_scope_open(); RDI_Parsed *rdi = di_rdi_from_key(scope, dbgi_key, 0); + + //- rjf: try scopes if(result.size == 0) { + // rjf: voff -> scope U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - U64 proc_idx = scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); - E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); - if(decorated && procedure->type_idx != 0) + + // rjf: scope -> # of max possible inline depth + U64 inline_site_count = 0; + for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) { - String8List list = {0}; - e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); - str8_list_push(scratch.arena, &list, name); - e_type_rhs_string_from_key(scratch.arena, type, &list, 0); - result = str8_list_join(arena, &list, 0); + RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); + s_idx_next = s->parent_scope_idx; + if(s->inline_site_idx != 0) + { + inline_site_count += 1; + } + else + { + break; + } } + + // rjf: depth in [1, max]? -> form name from inline site + if(0 < depth && depth <= inline_site_count) + { + RDI_InlineSite *inline_site = 0; + U64 s_inline_depth = inline_site_count; + for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) + { + RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); + s_idx_next = s->parent_scope_idx; + if(s_inline_depth == depth) + { + inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); + break; + } + s_inline_depth -= 1; + if(s_inline_depth == 0) + { + break; + } + } + if(inline_site != 0) + { + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, inline_site->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); + if(decorated && inline_site->type_idx != 0) + { + String8List list = {0}; + str8_list_pushf(scratch.arena, &list, "[inlined] "); + e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); + str8_list_push(scratch.arena, &list, name); + e_type_rhs_string_from_key(scratch.arena, type, &list, 0); + result = str8_list_join(arena, &list, 0); + } + else + { + result = push_str8_copy(arena, name); + } + } + } + + // rjf: depth == 0 or depth >= max? -> form name from scope procedure else { - result = push_str8_copy(arena, name); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + U64 proc_idx = scope->proc_idx; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); + if(decorated && procedure->type_idx != 0) + { + String8List list = {0}; + e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); + str8_list_push(scratch.arena, &list, name); + e_type_rhs_string_from_key(scratch.arena, type, &list, 0); + result = str8_list_join(arena, &list, 0); + } + else + { + result = push_str8_copy(arena, name); + } } } + + //- rjf: try global variables if(result.size == 0) { U64 global_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_GlobalVMap, voff); @@ -704,6 +773,7 @@ d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 d U8 *name_ptr = rdi_string_from_idx(rdi, global_var->name_string_idx, &name_size); result = push_str8_copy(arena, str8(name_ptr, name_size)); } + di_scope_close(scope); scratch_end(scratch); } @@ -711,7 +781,7 @@ d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 d } internal String8 -d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, B32 decorated) +d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, U64 depth, B32 decorated) { ProfBeginFunction(); String8 result = {0}; @@ -719,7 +789,7 @@ d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); U64 voff = ctrl_voff_from_vaddr(module, vaddr); - result = d_symbol_name_from_dbgi_key_voff(arena, &dbgi_key, voff, decorated); + result = d_symbol_name_from_dbgi_key_voff(arena, &dbgi_key, voff, depth, decorated); } ProfEnd(); return result; @@ -1595,6 +1665,7 @@ d_init(void) d_state->arena = arena; d_state->cmds_arena = arena_alloc(); d_state->output_log_key = hs_hash_from_data(str8_lit("output_log_key")); + hs_submit_data(d_state->output_log_key, 0, str8_zero()); d_state->ctrl_entity_store = ctrl_entity_store_alloc(); d_state->ctrl_stop_arena = arena_alloc(); d_state->view_rule_spec_table_size = 1024; @@ -1628,13 +1699,12 @@ d_init(void) } internal D_EventList -d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64], CTRL_MetaEvalArray *meta_evals) +d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); D_EventList result = {0}; d_state->frame_index += 1; - d_state->frame_eval_memread_endt_us = os_now_microseconds() + 1000; ////////////////////////////// //- rjf: sync with ctrl thread @@ -1831,8 +1901,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P D_Breakpoint *bp = &breakpoints->v[idx]; str8_list_push(scratch.arena, &strings, bp->file_path); str8_list_push(scratch.arena, &strings, str8_struct(&bp->pt)); - str8_list_push(scratch.arena, &strings, bp->symbol_name); - str8_list_push(scratch.arena, &strings, str8_struct(&bp->vaddr)); + str8_list_push(scratch.arena, &strings, bp->vaddr_expr); str8_list_push(scratch.arena, &strings, bp->condition); } } @@ -1872,35 +1941,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P } } - ////////////////////////////// - //- rjf: sync with di parsers - // - ProfScope("sync with di parsers") - { - DI_EventList events = di_p2u_pop_events(scratch.arena, 0); - for(DI_EventNode *n = events.first; n != 0; n = n->next) - { - DI_Event *event = &n->v; - switch(event->kind) - { - default:{}break; - case DI_EventKind_ConversionStarted: - { - RD_Entity *task = rd_entity_alloc(rd_entity_root(), RD_EntityKind_ConversionTask); - rd_entity_equip_name(task, event->string); - }break; - case DI_EventKind_ConversionEnded: - { - RD_Entity *task = rd_entity_from_name_and_kind(event->string, RD_EntityKind_ConversionTask); - if(!rd_entity_is_nil(task)) - { - rd_entity_mark_for_deletion(task); - } - }break; - } - } - } - ////////////////////////////// //- rjf: process top-level commands // @@ -1927,7 +1967,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P //- rjf: low-level target control operations case D_CmdKind_LaunchAndRun: - case D_CmdKind_LaunchAndInit: + case D_CmdKind_LaunchAndStepInto: { // rjf: get list of targets to launch D_TargetArray *targets_to_launch = ¶ms->targets; @@ -1998,7 +2038,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->debug_subprocesses = target->debug_subprocesses; msg->env_inherit = 1; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); str8_list_push(scratch.arena, &msg->entry_points, custom_entry_point_name); msg->env_string_list = env; } @@ -2008,7 +2047,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P need_run = 1; run_kind = D_RunKind_Run; run_thread = &ctrl_entity_nil; - run_flags = (cmd->kind == D_CmdKind_LaunchAndInit) ? CTRL_RunFlag_StopOnEntryPoint : 0; + run_flags = (cmd->kind == D_CmdKind_LaunchAndStepInto) ? CTRL_RunFlag_StopOnEntryPoint : 0; } // rjf: no targets -> error @@ -2031,7 +2070,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->exit_code = 1; msg->entity = process->handle; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); } }break; case D_CmdKind_KillAll: @@ -2040,7 +2078,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->kind = CTRL_MsgKind_KillAll; msg->exit_code = 1; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); }break; case D_CmdKind_Detach: { @@ -2055,7 +2092,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->kind = CTRL_MsgKind_Detach; msg->entity = process->handle; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); } }break; case D_CmdKind_Continue: @@ -2203,15 +2239,15 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P { run_extra_bps.count = 1; run_extra_bps.v = push_array(scratch.arena, D_Breakpoint, 1); - run_extra_bps.v[0].file_path = params->file_path; - run_extra_bps.v[0].pt = params->cursor; - d_cmd(D_CmdKind_Run); - }break; - case D_CmdKind_RunToAddress: - { - run_extra_bps.count = 1; - run_extra_bps.v = push_array(scratch.arena, D_Breakpoint, 1); - run_extra_bps.v[0].vaddr = params->vaddr; + if(params->file_path.size != 0) + { + run_extra_bps.v[0].file_path = params->file_path; + run_extra_bps.v[0].pt = params->cursor; + } + else if(params->vaddr != 0) + { + run_extra_bps.v[0].vaddr_expr = push_str8f(scratch.arena, "0x%I64x", params->vaddr); + } d_cmd(D_CmdKind_Run); }break; case D_CmdKind_Run: @@ -2255,7 +2291,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P } else if(!d_ctrl_targets_running()) { - d_cmd(D_CmdKind_LaunchAndInit, .targets = *targets); + d_cmd(D_CmdKind_LaunchAndStepInto, .targets = *targets); } }break; @@ -2331,7 +2367,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->kind = CTRL_MsgKind_Attach; msg->entity_id = pid; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); } }break; } @@ -2353,7 +2388,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->entity = run_thread->handle; msg->parent = process->handle; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); MemoryCopyStruct(&msg->traps, &run_traps); D_BreakpointArray *bp_batches[] = { @@ -2382,20 +2416,11 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P } } - // rjf: virtual address location -> add breakpoint for address - else if(bp->vaddr != 0) + // rjf: virtual address expression -> add expression breakpoint + else if(bp->vaddr_expr.size != 0) { - CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_VirtualAddress}; - ctrl_user_bp.u64 = bp->vaddr; - ctrl_user_bp.condition = bp->condition; - ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp); - } - - // rjf: symbol name location -> add breakpoint for symbol name - else if(bp->symbol_name.size != 0) - { - CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_SymbolNameAndOffset}; - ctrl_user_bp.string = bp->symbol_name; + CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_Expression}; + ctrl_user_bp.string = bp->vaddr_expr; ctrl_user_bp.condition = bp->condition; ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp); } diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index f39bbde7..cabaca1d 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -33,8 +33,7 @@ struct D_Breakpoint { String8 file_path; TxtPt pt; - String8 symbol_name; - U64 vaddr; + String8 vaddr_expr; String8 condition; }; @@ -331,7 +330,6 @@ struct D_State // rjf: top-level state Arena *arena; U64 frame_index; - U64 frame_eval_memread_endt_us; // rjf: commands Arena *cmds_arena; @@ -433,8 +431,8 @@ internal CTRL_TrapList d_trap_net_from_thread__step_into_line(Arena *arena, CTRL //~ rjf: Debug Info Lookups //- rjf: voff|vaddr -> symbol lookups -internal String8 d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 decorated); -internal String8 d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, B32 decorated); +internal String8 d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, U64 depth, B32 decorated); +internal String8 d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, U64 depth, B32 decorated); //- rjf: symbol -> voff lookups internal U64 d_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name); @@ -495,6 +493,6 @@ internal B32 d_next_cmd(D_Cmd **cmd); //~ rjf: Main Layer Top-Level Calls internal void d_init(void); -internal D_EventList d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64], CTRL_MetaEvalArray *meta_evals); +internal D_EventList d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]); #endif // DBG_ENGINE_CORE_H diff --git a/src/dbg_engine/generated/dbg_engine.meta.h b/src/dbg_engine/generated/dbg_engine.meta.h index d129e3d2..9efa15b8 100644 --- a/src/dbg_engine/generated/dbg_engine.meta.h +++ b/src/dbg_engine/generated/dbg_engine.meta.h @@ -10,7 +10,7 @@ typedef enum D_CmdKind { D_CmdKind_Null, D_CmdKind_LaunchAndRun, -D_CmdKind_LaunchAndInit, +D_CmdKind_LaunchAndStepInto, D_CmdKind_Kill, D_CmdKind_KillAll, D_CmdKind_Detach, @@ -24,7 +24,6 @@ D_CmdKind_Halt, D_CmdKind_SoftHaltRefresh, D_CmdKind_SetThreadIP, D_CmdKind_RunToLine, -D_CmdKind_RunToAddress, D_CmdKind_Run, D_CmdKind_Restart, D_CmdKind_StepInto, @@ -78,7 +77,6 @@ global B32 DEV_draw_ui_box_heatmap = 0; global B32 DEV_eval_compiler_tooltips = 0; global B32 DEV_eval_watch_key_tooltips = 0; global B32 DEV_cmd_context_tooltips = 0; -global B32 DEV_scratch_mouse_draw = 0; global B32 DEV_updating_indicator = 0; struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] = { @@ -89,7 +87,6 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] = {&DEV_eval_compiler_tooltips, str8_lit_comp("eval_compiler_tooltips")}, {&DEV_eval_watch_key_tooltips, str8_lit_comp("eval_watch_key_tooltips")}, {&DEV_cmd_context_tooltips, str8_lit_comp("cmd_context_tooltips")}, -{&DEV_scratch_mouse_draw, str8_lit_comp("scratch_mouse_draw")}, {&DEV_updating_indicator, str8_lit_comp("updating_indicator")}, }; #endif // DBG_ENGINE_META_H diff --git a/src/dbgi/dbgi.c b/src/dbgi/dbgi.c index 063be596..a3fbccaf 100644 --- a/src/dbgi/dbgi.c +++ b/src/dbgi/dbgi.c @@ -262,12 +262,14 @@ di_scope_open(void) scope = push_array_no_zero(di_tctx->arena, DI_Scope, 1); } MemoryZeroStruct(scope); + DLLPushBack(di_tctx->first_scope, di_tctx->last_scope, scope); return scope; } internal void di_scope_close(DI_Scope *scope) { + DLLRemove(di_tctx->first_scope, di_tctx->last_scope, scope); for(DI_Touch *t = scope->first_touch, *next = 0; t != 0; t = next) { next = t->next; @@ -1349,7 +1351,6 @@ di_search_thread__entry_point(void *p) for(;;) { Temp scratch = scratch_begin(0, 0); - DI_Scope *di_scope = di_scope_open(); //- rjf: get next key, unpack U128 key = di_u2s_dequeue_req(thread_idx); @@ -1380,6 +1381,9 @@ di_search_thread__entry_point(void *p) } } + //- rjf: begin debug info scope + DI_Scope *di_scope = di_scope_open(); + //- rjf: get all rdis U64 rdis_count = params.dbgi_keys.count; RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); @@ -1428,6 +1432,9 @@ di_search_thread__entry_point(void *p) cancelled = (cancelled || out->cancelled); } + //- rjf: end debug info scope + di_scope_close(di_scope); + //- rjf: list -> array DI_SearchItemArray items = {0}; if(arena != 0 && !cancelled) @@ -1496,7 +1503,6 @@ di_search_thread__entry_point(void *p) } } - di_scope_close(di_scope); scratch_end(scratch); } } diff --git a/src/dbgi/dbgi.h b/src/dbgi/dbgi.h index 3b3b23ea..76754bd4 100644 --- a/src/dbgi/dbgi.h +++ b/src/dbgi/dbgi.h @@ -225,6 +225,7 @@ typedef struct DI_Scope DI_Scope; struct DI_Scope { DI_Scope *next; + DI_Scope *prev; DI_Touch *first_touch; DI_Touch *last_touch; }; @@ -233,6 +234,8 @@ typedef struct DI_TCTX DI_TCTX; struct DI_TCTX { Arena *arena; + DI_Scope *first_scope; + DI_Scope *last_scope; DI_Scope *free_scope; DI_Touch *free_touch; }; diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 1ac146b0..0e79ad16 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1229,6 +1229,75 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) cmd = str8_list_join(scratch.arena, &args, &join_params); } + //- rjf: determine if process needs a console + B32 needs_console = 1; + { + String8 exe_path = params->cmd_line.first->string; + OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, exe_path); + + // rjf: find PE offset + U32 pe_offset = 0; + { + U64 dos_magic_off = 0; + U16 dos_magic = 0; + os_file_read_struct(file, dos_magic_off, &dos_magic); + if(dos_magic == PE_DOS_MAGIC) + { + U64 pe_offset_off = OffsetOf(PE_DosHeader, coff_file_offset); + os_file_read_struct(file, pe_offset_off, &pe_offset); + } + } + + // rjf: get COFF header + B32 got_coff_header = 0; + U64 coff_header_off = 0; + COFF_Header coff_header = {0}; + if(pe_offset > 0) + { + U64 pe_magic_off = pe_offset; + U32 pe_magic = 0; + os_file_read_struct(file, pe_magic_off, &pe_magic); + if(pe_magic == PE_MAGIC) + { + coff_header_off = pe_magic_off + sizeof(pe_magic); + if(os_file_read_struct(file, coff_header_off, &coff_header)) + { + got_coff_header = 1; + } + } + } + + // rjf: get subsystem from PE header following COFF header + PE_WindowsSubsystem subsystem = 0; + { + U64 opt_header_off = coff_header_off + sizeof(coff_header); + switch(coff_header.machine) + { + default:{}break; + case COFF_MachineType_X64: + { + PE_OptionalHeader32Plus hdr = {0}; + os_file_read_struct(file, opt_header_off, &hdr); + subsystem = hdr.subsystem; + }break; + case COFF_MachineType_X86: + { + PE_OptionalHeader32 hdr = {0}; + os_file_read_struct(file, opt_header_off, &hdr); + subsystem = hdr.subsystem; + }break; + } + } + + // rjf: determine if we need a console depending on the subsystem + if(subsystem == PE_WindowsSubsystem_WINDOWS_GUI) + { + needs_console = 0; + } + + os_file_close(file); + } + //- rjf: produce environment strings String8 env = {0}; { @@ -1291,7 +1360,10 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) inherit_handles = 1; } PROCESS_INFORMATION process_info = {0}; - AllocConsole(); + if(needs_console) + { + AllocConsole(); + } if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 1, creation_flags, (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info)) { // check if we are 32-bit app, and just close it immediately @@ -1315,7 +1387,10 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) { MessageBox(0, "Error starting process.", "Process error", MB_OK|MB_ICONSTOP); } - FreeConsole(); + if(needs_console) + { + FreeConsole(); + } //- rjf: eliminate all handles which have stuck around from the AllocConsole { diff --git a/src/draw/draw.c b/src/draw/draw.c index 272571b3..24b39995 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -45,9 +45,9 @@ dr_hash_from_string(String8 string) //~ rjf: Fancy String Type Functions internal void -dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString *str) +dr_fstrs_push(Arena *arena, DR_FStrList *list, DR_FStr *str) { - DR_FancyStringNode *n = push_array_no_zero(arena, DR_FancyStringNode, 1); + DR_FStrNode *n = push_array_no_zero(arena, DR_FStrNode, 1); MemoryCopyStruct(&n->v, str); SLLQueuePush(list->first, list->last, n); list->node_count += 1; @@ -55,7 +55,38 @@ dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString } internal void -dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList *to_push) +dr_fstrs_push_new_(Arena *arena, DR_FStrList *list, DR_FStrParams *params, DR_FStrParams *overrides, String8 string) +{ + DR_FStr fstr = {string, *params}; + if(!fnt_tag_match(fnt_tag_zero(), overrides->font)) + { + fstr.params.font = overrides->font; + } + if(overrides->raster_flags != 0) + { + fstr.params.raster_flags = overrides->raster_flags; + } + if(overrides->color.x != 0 || overrides->color.y != 0 || overrides->color.z != 0 || overrides->color.w != 0) + { + fstr.params.color = overrides->color; + } + if(overrides->size != 0) + { + fstr.params.size = overrides->size; + } + if(overrides->underline_thickness != 0) + { + fstr.params.underline_thickness = overrides->underline_thickness; + } + if(overrides->strikethrough_thickness != 0) + { + fstr.params.strikethrough_thickness = overrides->strikethrough_thickness; + } + dr_fstrs_push(arena, list, &fstr); +} + +internal void +dr_fstrs_concat_in_place(DR_FStrList *dst, DR_FStrList *to_push) { if(dst->last != 0 && to_push->first != 0) { @@ -71,34 +102,51 @@ dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList MemoryZeroStruct(to_push); } +internal DR_FStrList +dr_fstrs_copy(Arena *arena, DR_FStrList *src) +{ + DR_FStrList dst = {0}; + for(DR_FStrNode *src_n = src->first; src_n != 0; src_n = src_n->next) + { + DR_FStr fstr = src_n->v; + fstr.string = push_str8_copy(arena, fstr.string); + dr_fstrs_push(arena, &dst, &fstr); + } + return dst; +} + internal String8 -dr_string_from_fancy_string_list(Arena *arena, DR_FancyStringList *list) +dr_string_from_fstrs(Arena *arena, DR_FStrList *list) { String8 result = {0}; result.size = list->total_size; result.str = push_array_no_zero(arena, U8, result.size); U64 idx = 0; - for(DR_FancyStringNode *n = list->first; n != 0; n = n->next) + for(DR_FStrNode *n = list->first; n != 0; n = n->next) { - MemoryCopy(result.str+idx, n->v.string.str, n->v.string.size); - idx += n->v.string.size; + if(!fnt_tag_match(n->v.params.font, dr_thread_ctx->icon_font)) + { + MemoryCopy(result.str+idx, n->v.string.str, n->v.string.size); + idx += n->v.string.size; + } } return result; } -internal DR_FancyRunList -dr_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, FNT_RasterFlags flags, DR_FancyStringList *strs) +internal DR_FRunList +dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs) { ProfBeginFunction(); - DR_FancyRunList run_list = {0}; + DR_FRunList run_list = {0}; F32 base_align_px = 0; - for(DR_FancyStringNode *n = strs->first; n != 0; n = n->next) + for(DR_FStrNode *n = strs->first; n != 0; n = n->next) { - DR_FancyRunNode *dst_n = push_array(arena, DR_FancyRunNode, 1); - dst_n->v.run = fnt_push_run_from_string(arena, n->v.font, n->v.size, base_align_px, tab_size_px, flags, n->v.string); - dst_n->v.color = n->v.color; - dst_n->v.underline_thickness = n->v.underline_thickness; - dst_n->v.strikethrough_thickness = n->v.strikethrough_thickness; + DR_FRunNode *dst_n = push_array(arena, DR_FRunNode, 1); + dst_n->v.run = fnt_push_run_from_string(arena, n->v.params.font, n->v.params.size, base_align_px, tab_size_px, n->v.params.raster_flags, n->v.string); + dst_n->v.color = n->v.params.color; + dst_n->v.underline_thickness = n->v.params.underline_thickness; + dst_n->v.strikethrough_thickness = n->v.params.strikethrough_thickness; + dst_n->v.icon = (fnt_tag_match(n->v.params.font, dr_thread_ctx->icon_font)); SLLQueuePush(run_list.first, run_list.last, dst_n); run_list.node_count += 1; run_list.dim.x += dst_n->v.run.dim.x; @@ -109,20 +157,14 @@ dr_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, FNT_Rast return run_list; } -internal DR_FancyRunList -dr_fancy_run_list_copy(Arena *arena, DR_FancyRunList *src) +internal Vec2F32 +dr_dim_from_fstrs(DR_FStrList *fstrs) { - DR_FancyRunList dst = {0}; - for(DR_FancyRunNode *src_n = src->first; src_n != 0; src_n = src_n->next) - { - DR_FancyRunNode *dst_n = push_array(arena, DR_FancyRunNode, 1); - SLLQueuePush(dst.first, dst.last, dst_n); - MemoryCopyStruct(&dst_n->v, &src_n->v); - dst_n->v.run.pieces = fnt_piece_array_copy(arena, &src_n->v.run.pieces); - dst.node_count += 1; - } - dst.dim = src->dim; - return dst; + Temp scratch = scratch_begin(0, 0); + DR_FRunList fruns = dr_fruns_from_fstrs(scratch.arena, 0, fstrs); + Vec2F32 dim = fruns.dim; + scratch_end(scratch); + return dim; } //////////////////////////////// @@ -131,7 +173,7 @@ dr_fancy_run_list_copy(Arena *arena, DR_FancyRunList *src) // (Frame boundaries) internal void -dr_begin_frame(void) +dr_begin_frame(FNT_Tag icon_font) { if(dr_thread_ctx == 0) { @@ -143,6 +185,7 @@ dr_begin_frame(void) arena_pop_to(dr_thread_ctx->arena, dr_thread_ctx->arena_frame_start_pos); dr_thread_ctx->free_bucket_selection = 0; dr_thread_ctx->top_bucket = 0; + dr_thread_ctx->icon_font = icon_font; } internal void @@ -455,7 +498,7 @@ dr_sub_bucket(DR_Bucket *bucket) //- rjf: text internal void -dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run trailer_run) +dr_truncated_fancy_run_list(Vec2F32 p, DR_FRunList *list, F32 max_x, FNT_Run trailer_run) { ProfBeginFunction(); @@ -467,9 +510,9 @@ dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run B32 trailer_found = 0; Vec4F32 last_color = {0}; U64 byte_off = 0; - for(DR_FancyRunNode *n = list->first; n != 0; n = n->next) + for(DR_FRunNode *n = list->first; n != 0; n = n->next) { - DR_FancyRun *fr = &n->v; + DR_FRun *fr = &n->v; Rng1F32 pixel_range = {0}; { pixel_range.min = 100000; @@ -558,7 +601,7 @@ dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run } internal void -dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color) +dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color) { for(FuzzyMatchRangeNode *match_n = ranges->first; match_n != 0; match_n = match_n->next) { @@ -573,9 +616,9 @@ dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x F32 advance = 0; F32 ascent = 0; F32 descent = 0; - for(DR_FancyRunNode *fr_n = list->first; fr_n != 0; fr_n = fr_n->next) + for(DR_FRunNode *fr_n = list->first; fr_n != 0; fr_n = fr_n->next) { - DR_FancyRun *fr = &fr_n->v; + DR_FRun *fr = &fr_n->v; FNT_Run *run = &fr->run; ascent = run->ascent; descent = run->descent; @@ -589,7 +632,10 @@ dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x pixel_range.min = Min(pre_advance, pixel_range.min); pixel_range.max = Max(post_advance, pixel_range.max); } - byte_off += piece->decode_size; + if(!fr->icon) + { + byte_off += piece->decode_size; + } advance += piece->advance; } } diff --git a/src/draw/draw.h b/src/draw/draw.h index 1efb2bed..d905818f 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -7,54 +7,62 @@ //////////////////////////////// //~ rjf: Fancy String Types -typedef struct DR_FancyString DR_FancyString; -struct DR_FancyString +typedef struct DR_FStrParams DR_FStrParams; +struct DR_FStrParams { FNT_Tag font; - String8 string; + FNT_RasterFlags raster_flags; Vec4F32 color; F32 size; F32 underline_thickness; F32 strikethrough_thickness; }; -typedef struct DR_FancyStringNode DR_FancyStringNode; -struct DR_FancyStringNode +typedef struct DR_FStr DR_FStr; +struct DR_FStr { - DR_FancyStringNode *next; - DR_FancyString v; + String8 string; + DR_FStrParams params; }; -typedef struct DR_FancyStringList DR_FancyStringList; -struct DR_FancyStringList +typedef struct DR_FStrNode DR_FStrNode; +struct DR_FStrNode { - DR_FancyStringNode *first; - DR_FancyStringNode *last; + DR_FStrNode *next; + DR_FStr v; +}; + +typedef struct DR_FStrList DR_FStrList; +struct DR_FStrList +{ + DR_FStrNode *first; + DR_FStrNode *last; U64 node_count; U64 total_size; }; -typedef struct DR_FancyRun DR_FancyRun; -struct DR_FancyRun +typedef struct DR_FRun DR_FRun; +struct DR_FRun { FNT_Run run; Vec4F32 color; F32 underline_thickness; F32 strikethrough_thickness; + B32 icon; }; -typedef struct DR_FancyRunNode DR_FancyRunNode; -struct DR_FancyRunNode +typedef struct DR_FRunNode DR_FRunNode; +struct DR_FRunNode { - DR_FancyRunNode *next; - DR_FancyRun v; + DR_FRunNode *next; + DR_FRun v; }; -typedef struct DR_FancyRunList DR_FancyRunList; -struct DR_FancyRunList +typedef struct DR_FRunList DR_FRunList; +struct DR_FRunList { - DR_FancyRunNode *first; - DR_FancyRunNode *last; + DR_FRunNode *first; + DR_FRunNode *last; U64 node_count; Vec2F32 dim; }; @@ -91,6 +99,7 @@ struct DR_ThreadCtx { Arena *arena; U64 arena_frame_start_pos; + FNT_Tag icon_font; DR_BucketSelectionNode *top_bucket; DR_BucketSelectionNode *free_bucket_selection; }; @@ -108,19 +117,21 @@ internal U64 dr_hash_from_string(String8 string); //////////////////////////////// //~ rjf: Fancy String Type Functions -internal void dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString *str); -#define dr_fancy_string_list_push_new(arena, list, font_, size_, color_, string_, ...) dr_fancy_string_list_push((arena), (list), &(DR_FancyString){.font = (font_), .string = (string_), .color = (color_), .size = (size_), __VA_ARGS__}) -internal void dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList *to_push); -internal String8 dr_string_from_fancy_string_list(Arena *arena, DR_FancyStringList *list); -internal DR_FancyRunList dr_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, FNT_RasterFlags flags, DR_FancyStringList *strs); -internal DR_FancyRunList dr_fancy_run_list_copy(Arena *arena, DR_FancyRunList *src); +internal void dr_fstrs_push(Arena *arena, DR_FStrList *list, DR_FStr *str); +internal void dr_fstrs_push_new_(Arena *arena, DR_FStrList *list, DR_FStrParams *params, DR_FStrParams *overrides, String8 string); +#define dr_fstrs_push_new(arena, list, params, string, ...) dr_fstrs_push_new_((arena), (list), (params), &(DR_FStrParams){.size = 0, __VA_ARGS__}, (string)) +internal void dr_fstrs_concat_in_place(DR_FStrList *dst, DR_FStrList *to_push); +internal DR_FStrList dr_fstrs_copy(Arena *arena, DR_FStrList *src); +internal String8 dr_string_from_fstrs(Arena *arena, DR_FStrList *list); +internal DR_FRunList dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs); +internal Vec2F32 dr_dim_from_fstrs(DR_FStrList *fstrs); //////////////////////////////// //~ rjf: Top-Level API // // (Frame boundaries & bucket submission) -internal void dr_begin_frame(void); +internal void dr_begin_frame(FNT_Tag icon_font); internal void dr_submit_bucket(OS_Handle os_window, R_Handle r_window, DR_Bucket *bucket); //////////////////////////////// @@ -184,8 +195,8 @@ internal void dr_sub_bucket(DR_Bucket *bucket); //~ rjf: Draw Call Helpers //- rjf: text -internal void dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run trailer_run); -internal void dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color); +internal void dr_truncated_fancy_run_list(Vec2F32 p, DR_FRunList *list, F32 max_x, FNT_Run trailer_run); +internal void dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color); internal void dr_text_run(Vec2F32 p, Vec4F32 color, FNT_Run run); internal void dr_text(FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, Vec2F32 p, Vec4F32 color, String8 string); diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index f6de6560..4f281812 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -71,7 +71,7 @@ E_TypeKindTable: {IncompleteEnum "enum" 0 } {Bitfield "bitfield" 0 } {Variadic "variadic" 0 } - {Collection "collection" 0 } + {Set "set" 0 } } @table(name op_kind precedence string op_pre op_sep op_pos) @@ -116,6 +116,8 @@ E_ExprKindTable: { Ternary Null 0 "? " "" "?" ":"} + { Call Null 0 "()" "(" "," ")"} + { LeafBytecode Null 0 "bytecode" "" "" "" } { LeafMember Null 0 "member" "" "" "" } { LeafStringLiteral Null 0 "string_literal" "" "" "" } @@ -125,6 +127,7 @@ E_ExprKindTable: { LeafF32 Null 0 "F32" "" "" "" } { LeafIdent Null 0 "leaf_ident" "" "" "" } { LeafOffset Null 0 "leaf_offset" "" "" "" } + { LeafValue Null 0 "leaf_value" "" "" "" } { LeafFilePath Null 0 "leaf_filepath" "" "" "" } { TypeIdent Null 0 "type_ident" "" "" "" } @@ -133,6 +136,8 @@ E_ExprKindTable: { Func Null 0 "function" "" "" "" } { Define Binary 13 "=" "" "=" "" } + + { Tag Null 0 "=>" "=>" "," "" } } @table(name display_string) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 5cdf357c..11c8e68a 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -7,26 +7,35 @@ internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr) { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); - E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - E_Interpretation interp = e_interpret(bytecode); - E_Space zero_space = {0}; - E_Space space = (MemoryMatchStruct(&zero_space, &irtree.space) ? e_interpret_ctx->primary_space : irtree.space); + E_ExprChain exprs = {expr, expr}; + E_Eval result = e_eval_from_exprs(arena, exprs); + return result; +} + +internal E_Eval +e_eval_from_exprs(Arena *arena, E_ExprChain exprs) +{ + ProfBeginFunction(); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, exprs.last); + E_LookupRuleTagPair lookup = e_lookup_rule_tag_pair_from_expr_irtree(exprs.last, &irtree); + E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + E_Interpretation interp = e_interpret(bytecode); E_Eval eval = { - .value = interp.value, - .mode = irtree.mode, - .space = space, - .expr = expr, - .type_key = irtree.type_key, - .code = interp.code, + .value = interp.value, + .space = interp.space, + .exprs = exprs, + .irtree = irtree, + .lookup_rule_tag = lookup, + .code = interp.code, }; e_msg_list_concat_in_place(&eval.msgs, &irtree.msgs); if(E_InterpretationCode_Good < eval.code && eval.code < E_InterpretationCode_COUNT) { e_msg(arena, &eval.msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[eval.code]); } + ProfEnd(); return eval; } @@ -35,26 +44,39 @@ e_eval_from_string(Arena *arena, String8 string) { E_TokenArray tokens = e_token_array_from_text(arena, string); E_Parse parse = e_parse_expr_from_text_tokens(arena, string, &tokens); - E_Eval eval = e_eval_from_expr(arena, parse.expr); + E_Eval eval = e_eval_from_exprs(arena, parse.exprs); e_msg_list_concat_in_place(&eval.msgs, &parse.msgs); return eval; } +internal E_Eval +e_eval_from_stringf(Arena *arena, char *fmt, ...) +{ + Temp scratch = scratch_begin(&arena, 1); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + E_Eval eval = e_eval_from_string(arena, string); + va_end(args); + scratch_end(scratch); + return eval; +} + internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval) { - if(e_parse_ctx && + if(e_parse_state && e_interpret_ctx && - e_parse_ctx->modules_count > 0 && + e_parse_state->ctx->modules_count > 0 && e_interpret_ctx->module_base != 0 && - (e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_S64)) || - e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_U64)) || - e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_S32)) || - e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_U32)))) + (e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_S64)) || + e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_U64)) || + e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_S32)) || + e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_U32)))) { U64 vaddr = eval.value.u64; U64 voff = vaddr - e_interpret_ctx->module_base[0]; - RDI_Parsed *rdi = e_parse_ctx->primary_module->rdi; + RDI_Parsed *rdi = e_parse_state->ctx->primary_module->rdi; RDI_Scope *scope = rdi_scope_from_voff(rdi, voff); RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, voff); RDI_GlobalVariable *gvar = rdi_global_variable_from_voff(rdi, voff); @@ -63,7 +85,7 @@ e_autoresolved_eval_from_eval(E_Eval eval) if(string_idx == 0) { string_idx = gvar->name_string_idx; } if(string_idx != 0) { - eval.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_Void), 0); + eval.irtree.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_Void), 1, 0); } } return eval; @@ -72,7 +94,7 @@ e_autoresolved_eval_from_eval(E_Eval eval) internal E_Eval e_dynamically_typed_eval_from_eval(E_Eval eval) { - E_TypeKey type_key = eval.type_key; + E_TypeKey type_key = eval.irtree.type_key; E_TypeKind type_kind = e_type_kind_from_key(type_key); if(e_type_state != 0 && e_interpret_ctx != 0 && @@ -85,7 +107,7 @@ e_dynamically_typed_eval_from_eval(E_Eval eval) E_TypeKind ptee_type_kind = e_type_kind_from_key(ptee_type_key); if(ptee_type_kind == E_TypeKind_Struct || ptee_type_kind == E_TypeKind_Class) { - E_Type *ptee_type = e_type_from_key(scratch.arena, ptee_type_key); + E_Type *ptee_type = e_type_from_key__cached(ptee_type_key); B32 has_vtable = 0; for(U64 idx = 0; idx < ptee_type->count; idx += 1) { @@ -129,8 +151,8 @@ e_dynamically_typed_eval_from_eval(E_Eval eval) RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, global_var->container_idx); RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, rdi_idx); - E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 0); - eval.type_key = ptr_to_derived_type_key; + E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 1, 0); + eval.irtree.type_key = ptr_to_derived_type_key; } } } @@ -145,13 +167,13 @@ internal E_Eval e_value_eval_from_eval(E_Eval eval) { ProfBeginFunction(); - if(eval.mode == E_Mode_Offset) + if(eval.irtree.mode == E_Mode_Offset) { - E_TypeKey type_key = e_type_unwrap(eval.type_key); + E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); E_TypeKind type_kind = e_type_kind_from_key(type_key); if(type_kind == E_TypeKind_Array) { - eval.mode = E_Mode_Value; + eval.irtree.mode = E_Mode_Value; } else { @@ -162,13 +184,13 @@ e_value_eval_from_eval(E_Eval eval) type_byte_size <= sizeof(E_Value) && e_space_read(eval.space, &eval.value, value_vaddr_range)) { - eval.mode = E_Mode_Value; + eval.irtree.mode = E_Mode_Value; // rjf: mask&shift, for bitfields if(type_kind == E_TypeKind_Bitfield && type_byte_size <= sizeof(U64)) { Temp scratch = scratch_begin(0, 0); - E_Type *type = e_type_from_key(scratch.arena, type_key); + E_Type *type = e_type_from_key__cached(type_key); U64 valid_bits_mask = 0; for(U64 idx = 0; idx < type->count; idx += 1) { @@ -176,7 +198,7 @@ e_value_eval_from_eval(E_Eval eval) } eval.value.u64 = eval.value.u64 >> type->off; eval.value.u64 = eval.value.u64 & valid_bits_mask; - eval.type_key = type->direct_type_key; + eval.irtree.type_key = type->direct_type_key; scratch_end(scratch); } @@ -198,65 +220,37 @@ e_value_eval_from_eval(E_Eval eval) return eval; } -internal E_Eval -e_element_eval_from_array_eval_index(E_Eval eval, U64 index) +internal E_Value +e_value_from_string(String8 string) { - E_Eval result = {0}; - result.mode = eval.mode; - result.space = eval.space; - result.type_key = e_type_direct_from_key(eval.type_key); - result.code = eval.code; - result.msgs = eval.msgs; - U64 element_size = e_type_byte_size_from_key(result.type_key); - switch(eval.mode) - { - default:{}break; - case E_Mode_Value: - if(element_size <= sizeof(E_Value) && - index < sizeof(E_Value)/element_size) - { - MemoryCopy((U8 *)(&result.value.u512[0]), - (U8 *)(&eval.value.u512[0]) + index*element_size, - element_size); - }break; - case E_Mode_Offset: - { - result.value.u64 = eval.value.u64 + element_size*index; - }break; - } + Temp scratch = scratch_begin(0, 0); + E_Eval eval = e_eval_from_string(scratch.arena, string); + E_Eval value_eval = e_value_eval_from_eval(eval); + E_Value result = value_eval.value; + scratch_end(scratch); return result; } -internal E_Eval -e_member_eval_from_eval_member_name(E_Eval eval, String8 member_name) +internal E_Value +e_value_from_stringf(char *fmt, ...) { - E_Eval result = {0}; - { - E_Member member = e_type_member_from_key_name__cached(eval.type_key, member_name); - if(member.kind != E_MemberKind_Null) - { - result.mode = eval.mode; - result.space = eval.space; - result.type_key = member.type_key; - result.code = eval.code; - result.msgs = eval.msgs; - switch(eval.mode) - { - default:{}break; - case E_Mode_Value: - if(member.off < sizeof(eval.value)) - { - U64 member_size = e_type_byte_size_from_key(member.type_key); - MemoryCopy((U8 *)(&result.value.u512[0]), - (U8 *)(&eval.value.u512[0]) + member.off, - Min(member_size, sizeof(eval.value) - member.off)); - }break; - case E_Mode_Offset: - { - result.value.u64 = eval.value.u64 + member.off; - }break; - } - } - } + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + E_Value result = e_value_from_string(string); + va_end(args); + scratch_end(scratch); return result; } + +internal E_Value +e_value_from_expr(E_Expr *expr) +{ + Temp scratch = scratch_begin(0, 0); + E_Eval eval = e_eval_from_expr(scratch.arena, expr); + E_Eval value_eval = e_value_eval_from_eval(eval); + E_Value result = value_eval.value; + scratch_end(scratch); + return result; +} \ No newline at end of file diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index 957ff123..311a752e 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -11,10 +11,10 @@ typedef struct E_Eval E_Eval; struct E_Eval { E_Value value; - E_Mode mode; E_Space space; - E_Expr *expr; - E_TypeKey type_key; + E_ExprChain exprs; + E_IRTreeAndType irtree; + E_LookupRuleTagPair lookup_rule_tag; E_InterpretationCode code; E_MsgList msgs; }; @@ -23,11 +23,14 @@ struct E_Eval //~ rjf: Bundled Evaluation Functions internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr); +internal E_Eval e_eval_from_exprs(Arena *arena, E_ExprChain exprs); internal E_Eval e_eval_from_string(Arena *arena, String8 string); +internal E_Eval e_eval_from_stringf(Arena *arena, char *fmt, ...); internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval); internal E_Eval e_dynamically_typed_eval_from_eval(E_Eval eval); internal E_Eval e_value_eval_from_eval(E_Eval eval); -internal E_Eval e_element_eval_from_array_eval_index(E_Eval eval, U64 index); -internal E_Eval e_member_eval_from_eval_member_name(E_Eval eval, String8 member_name); +internal E_Value e_value_from_string(String8 string); +internal E_Value e_value_from_stringf(char *fmt, ...); +internal E_Value e_value_from_expr(E_Expr *expr); #endif // EVAL_BUNDLES_H diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 0acb895e..ada7177d 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -9,14 +9,16 @@ //////////////////////////////// //~ rjf: Basic Helper Functions +#if !defined(XXH_IMPLEMENTATION) +# define XXH_IMPLEMENTATION +# define XXH_STATIC_LINKING_ONLY +# include "third_party/xxHash/xxhash.h" +#endif + internal U64 e_hash_from_string(U64 seed, String8 string) { - U64 result = seed; - for(U64 i = 0; i < string.size; i += 1) - { - result = ((result << 5) + result) + string.str[i]; - } + U64 result = XXH3_64bits_withSeed(string.str, string.size, seed); return result; } diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 29579d20..650597b8 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -93,7 +93,9 @@ typedef U64 E_SpaceKind; enum { E_SpaceKind_Null, + E_SpaceKind_File, E_SpaceKind_FileSystem, + E_SpaceKind_HashStoreKey, E_SpaceKind_FirstUserDefined, }; diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index 9af391ad..0ebd1ed1 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -99,7 +99,11 @@ e_interpret(String8 bytecode) U64 stack_cap = 128; // TODO(rjf): scan bytecode; determine maximum stack depth E_Value *stack = push_array_no_zero(scratch.arena, E_Value, stack_cap); U64 stack_count = 0; - E_Space selected_space = e_interpret_ctx->primary_space; + E_Space selected_space = {0}; + if(bytecode.size != 0) + { + selected_space = e_interpret_ctx->primary_space; + } //- rjf: iterate bytecode & perform ops U8 *ptr = bytecode.str; @@ -115,7 +119,7 @@ e_interpret(String8 bytecode) } else switch(op) { - case E_IRExtKind_SetSpace:{ctrlbits = RDI_EVAL_CTRLBITS(32, 0, 0);}break; + case E_IRExtKind_SetSpace: {ctrlbits = RDI_EVAL_CTRLBITS(32, 0, 0);}break; default: { result.code = E_InterpretationCode_BadOp; @@ -853,6 +857,7 @@ e_interpret(String8 bytecode) { result.value = stack[0]; } + result.space = selected_space; scratch_end(scratch); return result; } diff --git a/src/eval/eval_interpret.h b/src/eval/eval_interpret.h index f91cc7e2..8d1c1449 100644 --- a/src/eval/eval_interpret.h +++ b/src/eval/eval_interpret.h @@ -11,6 +11,7 @@ typedef struct E_Interpretation E_Interpretation; struct E_Interpretation { E_Value value; + E_Space space; E_InterpretationCode code; }; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 9c08b133..a20e36e9 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -61,13 +61,1436 @@ e_expr_kind_is_comparison(E_ExprKind kind) internal E_IRCtx * e_selected_ir_ctx(void) { - return e_ir_ctx; + return e_ir_state->ctx; } internal void e_select_ir_ctx(E_IRCtx *ctx) { - e_ir_ctx = ctx; + if(e_ir_state == 0) + { + Arena *arena = arena_alloc(); + e_ir_state = push_array(arena, E_IRState, 1); + e_ir_state->arena = arena; + e_ir_state->arena_eval_start_pos = arena_pos(arena); + } + arena_pop_to(e_ir_state->arena, e_ir_state->arena_eval_start_pos); + e_ir_state->ctx = ctx; + e_ir_state->used_tag_map = push_array(e_ir_state->arena, E_UsedTagMap, 1); + e_ir_state->used_tag_map->slots_count = 64; + e_ir_state->used_tag_map->slots = push_array(e_ir_state->arena, E_UsedTagSlot, e_ir_state->used_tag_map->slots_count); + e_ir_state->type_auto_hook_cache_map = push_array(e_ir_state->arena, E_TypeAutoHookCacheMap, 1); + e_ir_state->type_auto_hook_cache_map->slots_count = 256; + e_ir_state->type_auto_hook_cache_map->slots = push_array(e_ir_state->arena, E_TypeAutoHookCacheSlot, e_ir_state->type_auto_hook_cache_map->slots_count); + e_ir_state->irtree_and_type_cache_slots_count = 1024; + e_ir_state->irtree_and_type_cache_slots = push_array(e_ir_state->arena, E_IRTreeAndTypeCacheSlot, e_ir_state->irtree_and_type_cache_slots_count); + e_ir_state->string_id_gen = 0; + e_ir_state->string_id_map = push_array(e_ir_state->arena, E_StringIDMap, 1); + e_ir_state->string_id_map->id_slots_count = 1024; + e_ir_state->string_id_map->id_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->id_slots_count); + e_ir_state->string_id_map->hash_slots_count = 1024; + e_ir_state->string_id_map->hash_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->hash_slots_count); +} + +//////////////////////////////// +//~ rjf: File System Lookup Rules + +typedef struct E_FolderAccel E_FolderAccel; +struct E_FolderAccel +{ + String8 folder_path; + String8Array folders; + String8Array files; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(folder) +{ + E_LookupInfo info = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: evaluate lhs file path ID + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + E_Value lhs_value = lhs_interp.value; + U64 lhs_string_id = lhs_value.u64; + String8 folder_path = e_string_from_id(lhs_string_id); + + //- rjf: compute filter - omit common prefixes (common parent paths) + String8 local_filter = filter; + { + U64 folder_pos_in_filter = str8_find_needle(filter, 0, folder_path, StringMatchFlag_CaseInsensitive|StringMatchFlag_SlashInsensitive); + if(folder_pos_in_filter < filter.size) + { + local_filter = str8_skip(local_filter, folder_pos_in_filter+folder_path.size); + local_filter = str8_skip_chop_slashes(local_filter); + } + else + { + MemoryZeroStruct(&local_filter); + } + } + + //- rjf: gather & filter files in this folder + String8List folder_paths = {0}; + String8List file_paths = {0}; + { + OS_FileIter *iter = os_file_iter_begin(scratch.arena, folder_path, 0); + for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, iter, &info);) + { + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, local_filter, info.name); + if(matches.count == matches.needle_part_count) + { + if(info.props.flags & FilePropertyFlag_IsFolder) + { + str8_list_push(scratch.arena, &folder_paths, push_str8_copy(arena, info.name)); + } + else + { + str8_list_push(scratch.arena, &file_paths, push_str8_copy(arena, info.name)); + } + } + } + os_file_iter_end(iter); + } + + //- rjf: build accelerator + E_FolderAccel *accel = push_array(arena, E_FolderAccel, 1); + accel->folder_path = push_str8_copy(arena, folder_path); + accel->folders = str8_array_from_list(arena, &folder_paths); + accel->files = str8_array_from_list(arena, &file_paths); + info.user_data = accel; + info.idxed_expr_count = accel->folders.count + accel->files.count; + scratch_end(scratch); + } + return info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(folder) +{ + E_FolderAccel *accel = (E_FolderAccel *)user_data; + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + Temp scratch = scratch_begin(&arena, 1); + E_Expr *expr = &e_expr_nil; + String8 expr_string = {0}; + if(0 <= idx && idx < accel->folders.count) + { + String8 folder_name = accel->folders.v[idx - 0]; + String8 folder_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", folder_name); + expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); + expr->space = e_space_make(E_SpaceKind_FileSystem); + expr->value.u64 = e_id_from_string(folder_path); + expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, folder_name)); + } + else if(accel->folders.count <= idx && idx < accel->folders.count + accel->files.count) + { + String8 file_name = accel->files.v[idx - accel->folders.count]; + String8 file_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", file_name); + expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); + expr->space = e_space_make(E_SpaceKind_FileSystem); + expr->value.u64 = e_id_from_string(file_path); + expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, file_name)); + } + exprs[out_idx] = expr; + exprs_strings[out_idx] = expr_string; + scratch_end(scratch); + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(folder) +{ + U64 id = 0; + E_FolderAccel *accel = (E_FolderAccel *)user_data; + String8 name = {0}; + if(0 < num && num <= accel->folders.count) + { + name = accel->folders.v[num-1]; + } + else if(accel->folders.count < num && num <= accel->folders.count+accel->files.count) + { + name = accel->files.v[num-accel->folders.count-1]; + } + id = e_hash_from_string(5381, name); + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(folder) +{ + U64 num = 0; + E_FolderAccel *accel = (E_FolderAccel *)user_data; + for(U64 idx = 0; idx < accel->folders.count+accel->files.count; idx += 1) + { + String8 name = {0}; + if(0 <= idx && idx < accel->folders.count) + { + name = accel->folders.v[idx]; + } + else if(accel->folders.count <= idx && idx < accel->folders.count+accel->files.count) + { + name = accel->files.v[idx-accel->folders.count]; + } + U64 hash = e_hash_from_string(5381, name); + if(hash == id) + { + num = idx+1; + break; + } + } + return num; +} + +typedef struct E_FileAccel E_FileAccel; +struct E_FileAccel +{ + String8 file_path; + FileProperties props; + String8Array fields; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(file) +{ + E_FileAccel *accel = push_array(arena, E_FileAccel, 1); + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: evaluate lhs file path ID + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + E_Value lhs_value = lhs_interp.value; + U64 lhs_string_id = lhs_value.u64; + + //- rjf: get file path + String8 file_path = e_string_from_id(lhs_string_id); + + //- rjf: build field list + String8List fields = {0}; + str8_list_pushf(arena, &fields, "size"); + str8_list_pushf(arena, &fields, "last_modified_time"); + str8_list_pushf(arena, &fields, "creation_time"); + str8_list_pushf(arena, &fields, "data"); + + //- rjf: fill accel + accel->file_path = push_str8_copy(arena, file_path); + accel->props = os_properties_from_file_path(file_path); + accel->fields = str8_array_from_list(arena, &fields); + + scratch_end(scratch); + } + E_LookupInfo info = {accel, accel->fields.count}; + return info; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(file) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_MemberAccess) + { + E_FileAccel *accel = (E_FileAccel *)user_data; + String8 member_name = rhs->string; + if(str8_match(member_name, str8_lit("size"), 0)) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + space.u64_0 = e_id_from_string(accel->file_path); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.size)); + result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); + result.irtree_and_type.mode = E_Mode_Value; + } + else if(str8_match(member_name, str8_lit("last_modified_time"), 0)) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + space.u64_0 = e_id_from_string(accel->file_path); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.modified)); + result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); + result.irtree_and_type.mode = E_Mode_Value; + } + else if(str8_match(member_name, str8_lit("creation_time"), 0)) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + space.u64_0 = e_id_from_string(accel->file_path); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.created)); + result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); + result.irtree_and_type.mode = E_Mode_Value; + } + else if(str8_match(member_name, str8_lit("data"), 0)) + { + E_Space space = e_space_make(E_SpaceKind_File); + space.u64_0 = e_id_from_string(accel->file_path); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), accel->props.size, 0); + result.irtree_and_type.mode = E_Mode_Offset; + } + } + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(file) +{ + E_FileAccel *accel = (E_FileAccel *)user_data; + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + E_Expr *expr = &e_expr_nil; + String8 string = {0}; + if(0 <= idx && idx < accel->fields.count) + { + String8 name = accel->fields.v[idx]; + expr = e_push_expr(arena, E_ExprKind_MemberAccess, 0); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0); + rhs->string = push_str8_copy(arena, name); + e_expr_push_child(expr, e_expr_ref(arena, lhs)); + e_expr_push_child(expr, rhs); + } + exprs[out_idx] = expr; + exprs_strings[out_idx] = string; + } +} + +//////////////////////////////// +//~ rjf: Slice Lookup Rules + +typedef struct E_SliceAccel E_SliceAccel; +struct E_SliceAccel +{ + Arch arch; + U64 count; + U64 base_ptr_vaddr; + E_TypeKey element_type_key; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(slice) +{ + E_LookupInfo info = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + // rjf: unpack struct type + E_TypeKey struct_type_key = e_type_unwrap(lhs->type_key); + for(;;) + { + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(struct_type_key))) + { + struct_type_key = e_type_unwrap(e_type_direct_from_key(struct_type_key)); + } + else + { + break; + } + } + + // rjf: build info from struct type + E_TypeKind type_kind = e_type_kind_from_key(struct_type_key); + if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class) + { + // rjf: unpack members + E_MemberArray members = e_type_data_members_from_key__cached(struct_type_key); + + // rjf: choose base pointer & count members + E_Member *base_ptr_member = 0; + E_Member *opl_ptr_member = 0; + E_Member *count_member = 0; + for(U64 idx = 0; idx < members.count; idx += 1) + { + E_Member *member = &members.v[idx]; + E_TypeKey member_type = e_type_unwrap(member->type_key); + E_TypeKind member_type_kind = e_type_kind_from_key(member_type); + if(count_member == 0 && e_type_kind_is_integer(member_type_kind)) + { + count_member = member; + } + if(base_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) + { + base_ptr_member = &members.v[idx]; + } + else if(base_ptr_member != 0 && opl_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) + { + opl_ptr_member = &members.v[idx]; + } + if(count_member != 0 && base_ptr_member != 0) + { + break; + } + else if(base_ptr_member != 0 && opl_ptr_member != 0) + { + break; + } + } + + // rjf: determine architecture + Arch arch = e_type_state->ctx->primary_module->arch; + if(base_ptr_member != 0) + { + E_Type *type = e_type_from_key__cached(base_ptr_member->type_key); + arch = type->arch; + } + + // rjf: evaluate count member, determine count + U64 count = 0; + if(count_member != 0) + { + E_Expr *count_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, count_member->name); + E_Value count_member_value = e_value_from_expr(count_member_expr); + count = count_member_value.u64; + } + + // rjf: evaluate base ptr member, determine base address + U64 base_ptr_vaddr = 0; + if(base_ptr_member != 0) + { + E_Expr *base_ptr_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, base_ptr_member->name); + E_Value base_ptr_member_value = e_value_from_expr(base_ptr_member_expr); + base_ptr_vaddr = base_ptr_member_value.u64; + } + + // rjf: evaluate opl ptr member, determine opl address + U64 opl_ptr_vaddr = 0; + if(count_member == 0 && opl_ptr_member != 0) + { + E_Expr *opl_ptr_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, opl_ptr_member->name); + E_Value opl_ptr_member_value = e_value_from_expr(opl_ptr_member_expr); + opl_ptr_vaddr = opl_ptr_member_value.u64; + } + + // rjf: determine element type + E_TypeKey element_type_key = zero_struct; + if(base_ptr_member != 0) + { + element_type_key = e_type_direct_from_key(base_ptr_member->type_key); + } + + // rjf: if no count, but base/opl, swap base/opl if needed, and measure count + if(count_member == 0 && opl_ptr_member != 0 && base_ptr_member != 0) + { + U64 min_vaddr = Min(base_ptr_vaddr, opl_ptr_vaddr); + U64 max_vaddr = Max(base_ptr_vaddr, opl_ptr_vaddr); + base_ptr_vaddr = min_vaddr; + opl_ptr_vaddr = max_vaddr; + count = (opl_ptr_vaddr - base_ptr_vaddr) / e_type_byte_size_from_key(element_type_key); + } + + // rjf: fill + if((count_member || opl_ptr_member) && base_ptr_member) + { + E_SliceAccel *accel = push_array(arena, E_SliceAccel, 1); + accel->arch = arch; + accel->count = count; + accel->base_ptr_vaddr = base_ptr_vaddr; + accel->element_type_key = element_type_key; + info.user_data = accel; + info.idxed_expr_count = accel->count; + } + + // rjf: fall back to default + else + { + info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, tag, filter); + } + } + scratch_end(scratch); + } + return info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(slice) +{ + if(user_data == 0) + { + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, tag, filter, idx_range, exprs, exprs_strings, user_data); + } + else + { + E_SliceAccel *accel = (E_SliceAccel *)user_data; + U64 out_idx = 0; + U64 element_type_size = e_type_byte_size_from_key(accel->element_type_key); + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr->value.u64 = accel->base_ptr_vaddr + idx*element_type_size; + expr->type_key = accel->element_type_key; + exprs[out_idx] = expr; + exprs_strings[out_idx] = push_str8f(arena, "[%I64u]", idx); + } + } +} + +E_LOOKUP_INFO_FUNCTION_DEF(default) +{ + E_LookupInfo lookup_info = {0}; + { + E_TypeKey lhs_type_key = e_type_unwrap(lhs->type_key); + E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); + if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + { + E_Type *type = e_type_from_key__cached(lhs_type_key); + lookup_info.idxed_expr_count = type->count; + if(type->count == 1) + { + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Union) + { + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(direct_type_key, filter); + lookup_info.named_expr_count = data_members.count; + } + else if(direct_type_kind == E_TypeKind_Enum) + { + E_Type *direct_type = e_type_from_key__cached(direct_type_key); + lookup_info.named_expr_count = direct_type->count; + } + } + } + else if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Class || + lhs_type_kind == E_TypeKind_Union) + { + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(lhs_type_key, filter); + lookup_info.named_expr_count = data_members.count; + } + else if(lhs_type_kind == E_TypeKind_Enum) + { + E_Type *direct_type = e_type_from_key__cached(lhs_type_key); + lookup_info.named_expr_count = direct_type->count; + } + else if(lhs_type_kind == E_TypeKind_Array) + { + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + lookup_info.idxed_expr_count = lhs_type->count; + } + } + return lookup_info; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(default) +{ + // + // TODO(rjf): need to define what it means to access a set expression + // whose type *does not* define its IR generation rules, BUT it does + // define specific child expressions. so e.g. `watches`, does not + // define `watches[0]`, because it has defined that `watches[0]` + // maps to another expression, which is whatever the first watch + // expression is (e.g. `basics`). so, in that case, we can just use + // the lookup-range rule, grab the Nth expression, and IR-ify *that*. + // + E_LookupAccess result = {{&e_irnode_nil}}; + switch(kind) + { + default:{}break; + + //- rjf: member accessing + case E_ExprKind_MemberAccess: + { + // rjf: unpack left/right expressions + E_Expr *exprl = lhs; + E_Expr *exprr = rhs; + E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); + E_TypeKey l_restype = e_type_unwrap(l.type_key); + E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); + E_TypeKey check_type_key = l_restype; + E_TypeKind check_type_kind = l_restype_kind; + if(l_restype_kind == E_TypeKind_Ptr || + l_restype_kind == E_TypeKind_LRef || + l_restype_kind == E_TypeKind_RRef) + { + check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); + check_type_kind = e_type_kind_from_key(check_type_key); + } + e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &l.msgs); + + // rjf: look up member + E_Member member = zero_struct; + B32 r_found = 0; + E_TypeKey r_type = zero_struct; + U64 r_value = 0; + String8 r_query_name = {0}; + B32 r_is_constant_value = 0; + { + Temp scratch = scratch_begin(&arena, 1); + E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string); + member = match; + if(match.kind != E_MemberKind_Null) + { + r_found = 1; + r_type = match.type_key; + r_value = match.off; + } + if(match.kind == E_MemberKind_Query) + { + r_query_name = exprr->string; + } + if(match.kind == E_MemberKind_Null) + { + E_Type *type = e_type_from_key__cached(check_type_key); + if(type->enum_vals != 0) + { + String8 lookup_string = exprr->string; + String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string); + String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string); + E_EnumVal *enum_val_match = 0; + for EachIndex(idx, type->count) + { + if(str8_match(type->enum_vals[idx].name, lookup_string, 0) || + str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) || + str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0)) + { + enum_val_match = &type->enum_vals[idx]; + break; + } + } + if(enum_val_match != 0) + { + r_found = 1; + r_type = check_type_key; + r_value = enum_val_match->val; + r_is_constant_value = 1; + } + } + } + scratch_end(scratch); + } + + // rjf: bad conditions? -> error if applicable, exit + if(e_type_key_match(e_type_key_zero(), check_type_key)) + { + break; + } + else if(exprr->kind != E_ExprKind_LeafMember) + { + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); + break; + } + else if(!r_found) + { + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); + break; + } + else if(check_type_kind != E_TypeKind_Struct && + check_type_kind != E_TypeKind_Class && + check_type_kind != E_TypeKind_Union && + check_type_kind != E_TypeKind_Enum) + { + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); + break; + } + + // rjf: generate + { + // rjf: build tree + E_IRNode *new_tree = l.root; + E_TypeKey new_tree_type = r_type; + E_Mode mode = l.mode; + if(l_restype_kind == E_TypeKind_Ptr || + l_restype_kind == E_TypeKind_LRef || + l_restype_kind == E_TypeKind_RRef) + { + new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype); + mode = E_Mode_Offset; + } + if(r_value != 0 && !r_is_constant_value) + { + E_IRNode *const_tree = e_irtree_const_u(arena, r_value); + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree); + } + else if(r_is_constant_value) + { + new_tree = e_irtree_const_u(arena, r_value); + mode = E_Mode_Value; + } + + // rjf: fill + result.irtree_and_type.root = new_tree; + result.irtree_and_type.type_key = r_type; + result.irtree_and_type.member = member; + result.irtree_and_type.mode = mode; + } + }break; + + //- rjf: array indexing + case E_ExprKind_ArrayIndex: + { + // rjf: unpack left/right expressions + E_Expr *exprl = lhs; + E_Expr *exprr = rhs; + E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); + E_IRTreeAndType r = e_irtree_and_type_from_expr(arena, exprr); + E_TypeKey l_restype = e_type_unwrap(l.type_key); + E_TypeKey r_restype = e_type_unwrap(r.type_key); + E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); + E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype); + if(e_type_kind_is_basic_or_enum(r_restype_kind)) + { + r_restype = e_type_unwrap_enum(r_restype); + r_restype_kind = e_type_kind_from_key(r_restype); + } + E_TypeKey direct_type = e_type_unwrap(l_restype); + direct_type = e_type_direct_from_key(direct_type); + direct_type = e_type_unwrap(direct_type); + U64 direct_type_size = e_type_byte_size_from_key(direct_type); + e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &l.msgs); + e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &r.msgs); + + // rjf: bad conditions? -> error if applicable, exit + if(r.root->op == 0) + { + break; + } + else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array) + { + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type."); + break; + } + else if(!e_type_kind_is_integer(r_restype_kind)) + { + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type."); + break; + } + else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0) + { + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); + break; + } + else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0) + { + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types."); + break; + } + + // rjf: generate + E_IRNode *new_tree = &e_irnode_nil; + E_Mode mode = l.mode; + { + // rjf: reading from an array value -> read from stack value + if(l.mode == E_Mode_Value && l_restype_kind == E_TypeKind_Array) + { + // rjf: ops to compute the offset + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); + if(direct_type_size > 1) + { + E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + } + + // rjf: ops to push stack value, push offset, + read from stack value + new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead); + new_tree->value.u64 = direct_type_size; + e_irnode_push_child(new_tree, offset_tree); + e_irnode_push_child(new_tree, l.root); + } + + // rjf: all other cases -> read from base offset + else + { + // rjf: ops to compute the offset + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); + if(direct_type_size > 1) + { + E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + } + + // rjf: ops to compute the base offset (resolve to value if addr-of-pointer) + E_IRNode *base_tree = l.root; + if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value) + { + base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype); + } + + // rjf: ops to compute the final address + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); + } + } + + // rjf: fill + result.irtree_and_type.root = new_tree; + result.irtree_and_type.type_key = direct_type; + result.irtree_and_type.mode = mode; + }break; + } + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(default) +{ + Temp scratch = scratch_begin(&arena, 1); + { + //- rjf: unpack type of expression + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_TypeKey lhs_type_key = lhs_irtree.type_key; + E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + + //- rjf: pull out specific kinds of types + B32 do_struct_range = 0; + B32 do_enum_range = 0; + B32 do_index_range = 0; + E_TypeKey enum_type_key = zero_struct; + E_TypeKey struct_type_key = zero_struct; + E_TypeKind struct_type_kind = E_TypeKind_Null; + if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + { + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + if(lhs_type->count == 1 && + (direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Union || + direct_type_kind == E_TypeKind_Class)) + { + struct_type_key = direct_type_key; + struct_type_kind = direct_type_kind; + do_struct_range = 1; + } + else if(lhs_type->count == 1 && direct_type_kind == E_TypeKind_Enum) + { + do_enum_range = 1; + enum_type_key = direct_type_key; + } + else + { + do_index_range = 1; + } + } + else if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Union || + lhs_type_kind == E_TypeKind_Class) + { + struct_type_key = lhs_type_key; + struct_type_kind = lhs_type_kind; + do_struct_range = 1; + } + else if(lhs_type_kind == E_TypeKind_Enum) + { + enum_type_key = lhs_type_key; + do_enum_range = 1; + } + else if(lhs_type_kind == E_TypeKind_Set) + { + do_index_range = 1; + } + else if(lhs_type_kind == E_TypeKind_Array) + { + do_index_range = 1; + } + + //- rjf: struct case -> the lookup-range will return a range of members + if(do_struct_range) + { + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(struct_type_key, filter); + Rng1U64 legal_idx_range = r1u64(0, data_members.count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 member_idx = idx + read_range.min; + String8 member_name = data_members.v[member_idx].name; + exprs[idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, member_name); + } + } + + //- rjf: enum case -> the lookup-range will return a range of enum constants + else if(do_enum_range) + { + E_Type *type = e_type_from_key__cached(enum_type_key); + Rng1U64 legal_idx_range = r1u64(0, type->count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 member_idx = idx + read_range.min; + String8 member_name = type->enum_vals[member_idx].name; + exprs[idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, member_name); + } + } + + //- rjf: ptr case -> the lookup-range will return a range of dereferences + else if(do_index_range) + { + U64 read_range_count = dim_1u64(idx_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + exprs[idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, idx_range.min + idx); + } + } + } + scratch_end(scratch); +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default) +{ + return num; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default) +{ + return id; +} + +//////////////////////////////// +//~ rjf: Member Filtering Lookup Rules + +typedef struct E_MemberFilterAccel E_MemberFilterAccel; +struct E_MemberFilterAccel +{ + E_MemberArray members; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(only) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupInfo lookup_info = {0}; + { + //- rjf: extract struct type + E_TypeKey struct_type_key = zero_struct; + { + E_TypeKey lhs_type_key = e_type_unwrap(lhs->type_key); + E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); + if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + { + E_Type *type = e_type_from_key__cached(lhs_type_key); + if(type->count == 1) + { + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Union) + { + struct_type_key = direct_type_key; + } + } + } + else if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Class || + lhs_type_kind == E_TypeKind_Union) + { + struct_type_key = lhs_type_key; + } + } + + //- rjf: not struct -> fall back on default + if(e_type_key_match(struct_type_key, e_type_key_zero())) + { + lookup_info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, tag, filter); + } + + //- struct -> filter + else + { + E_MemberArray data_members = e_type_data_members_from_key__cached(struct_type_key); + E_MemberList data_members_list__filtered = {0}; + for EachIndex(idx, data_members.count) + { + B32 fits_filter = 0; + for(E_Expr *name = tag->first->next; name != &e_expr_nil; name = name->next) + { + if(str8_match(name->string, data_members.v[idx].name, 0)) + { + fits_filter = 1; + break; + } + } + if(fits_filter) + { + e_member_list_push(scratch.arena, &data_members_list__filtered, &data_members.v[idx]); + } + } + E_MemberFilterAccel *accel = push_array(arena, E_MemberFilterAccel, 1); + accel->members = e_member_array_from_list(arena, &data_members_list__filtered); + lookup_info.user_data = accel; + lookup_info.named_expr_count = accel->members.count; + } + } + scratch_end(scratch); + return lookup_info; +} + +E_LOOKUP_INFO_FUNCTION_DEF(omit) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupInfo lookup_info = {0}; + { + //- rjf: extract struct type + E_TypeKey struct_type_key = zero_struct; + { + E_TypeKey lhs_type_key = e_type_unwrap(lhs->type_key); + E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); + if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + { + E_Type *type = e_type_from_key__cached(lhs_type_key); + if(type->count == 1) + { + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Union) + { + struct_type_key = direct_type_key; + } + } + } + else if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Class || + lhs_type_kind == E_TypeKind_Union) + { + struct_type_key = lhs_type_key; + } + } + + //- rjf: not struct -> fall back on default + if(e_type_key_match(struct_type_key, e_type_key_zero())) + { + lookup_info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, tag, filter); + } + + //- struct -> filter + else + { + E_MemberArray data_members = e_type_data_members_from_key__cached(struct_type_key); + E_MemberList data_members_list__filtered = {0}; + for EachIndex(idx, data_members.count) + { + B32 fits_filter = 1; + for(E_Expr *name = tag->first->next; name != &e_expr_nil; name = name->next) + { + if(str8_match(name->string, data_members.v[idx].name, 0)) + { + fits_filter = 0; + break; + } + } + if(fits_filter) + { + e_member_list_push(scratch.arena, &data_members_list__filtered, &data_members.v[idx]); + } + } + E_MemberFilterAccel *accel = push_array(arena, E_MemberFilterAccel, 1); + accel->members = e_member_array_from_list(arena, &data_members_list__filtered); + lookup_info.user_data = accel; + lookup_info.named_expr_count = accel->members.count; + } + } + scratch_end(scratch); + return lookup_info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(only_and_omit) +{ + if(user_data == 0) + { + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, tag, filter, idx_range, exprs, exprs_strings, user_data); + } + else + { + Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_MemberFilterAccel *accel = (E_MemberFilterAccel *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->members.count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 member_idx = idx + read_range.min; + String8 member_name = accel->members.v[member_idx].name; + exprs[idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, member_name); + } + scratch_end(scratch); + } +} + +//////////////////////////////// +//~ rjf: Lookups + +internal E_LookupRuleMap +e_lookup_rule_map_make(Arena *arena, U64 slots_count) +{ + E_LookupRuleMap map = {0}; + map.slots_count = slots_count; + map.slots = push_array(arena, E_LookupRuleSlot, map.slots_count); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("default"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(default), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(default), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("folder"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(folder), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(folder), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(folder), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(folder)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("file"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(file), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(file), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(file)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("slice"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(slice), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(slice)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("only"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(only), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(only_and_omit)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("omit"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(omit), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(only_and_omit)); + return map; +} + +internal void +e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule) +{ + U64 hash = e_hash_from_string(5381, rule->name); + U64 slot_idx = hash%map->slots_count; + E_LookupRuleNode *n = push_array(arena, E_LookupRuleNode, 1); + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); + MemoryCopyStruct(&n->v, rule); + if(n->v.info == 0) { n->v.info = E_LOOKUP_INFO_FUNCTION_NAME(default); } + if(n->v.access == 0) { n->v.access = E_LOOKUP_ACCESS_FUNCTION_NAME(default); } + if(n->v.range == 0) { n->v.range = E_LOOKUP_RANGE_FUNCTION_NAME(default); } + if(n->v.id_from_num == 0){ n->v.id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default); } + if(n->v.num_from_id == 0){ n->v.num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default); } + n->v.name = push_str8_copy(arena, n->v.name); +} + +internal E_LookupRule * +e_lookup_rule_from_string(String8 string) +{ + E_LookupRule *result = &e_lookup_rule__nil; + if(e_ir_state->ctx->lookup_rule_map != 0 && e_ir_state->ctx->lookup_rule_map->slots_count != 0) + { + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%e_ir_state->ctx->lookup_rule_map->slots_count; + for(E_LookupRuleNode *n = e_ir_state->ctx->lookup_rule_map->slots[slot_idx].first; + n != 0; + n = n->next) + { + if(str8_match(n->v.name, string, 0)) + { + result = &n->v; + break; + } + } + } + return result; +} + +//////////////////////////////// +//~ rjf: IR Gen Rules + +E_IRGEN_FUNCTION_DEF(cast) +{ + E_Expr *type_expr = tag->first->next; + E_TypeKey type_key = e_type_from_expr(type_expr); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); + E_IRTreeAndType result = {irtree.root, type_key, irtree.member, irtree.mode, irtree.msgs}; + return result; +} + +E_IRGEN_FUNCTION_DEF(bswap) +{ + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); + E_IRNode *root = e_push_irnode(arena, RDI_EvalOp_ByteSwap); + e_irnode_push_child(root, irtree.root); + E_IRTreeAndType result = {root, irtree.type_key, irtree.member, irtree.mode, irtree.msgs}; + return result; +} + +E_IRGEN_FUNCTION_DEF(array) +{ + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); + E_TypeKey type_key = irtree.type_key; + E_TypeKind type_kind = e_type_kind_from_key(type_key); + if(e_type_kind_is_pointer_or_ref(type_kind)) + { + E_Value count_value = e_value_from_expr(tag->first->next); + E_TypeKey element_type_key = e_type_ptee_from_key(type_key); + E_TypeKey ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, element_type_key, count_value.u64, 0); + irtree.type_key = ptr_type_key; + } + return irtree; +} + +E_IRGEN_FUNCTION_DEF(wrap) +{ + Temp scratch = scratch_begin(&arena, 1); + E_Expr *expr_to_irify = expr; + E_Expr *wrap_expr_src = tag->first->next; + if(wrap_expr_src != &e_expr_nil) + { + expr_to_irify = e_expr_copy(scratch.arena, wrap_expr_src); + typedef struct Task Task; + struct Task + { + Task *next; + E_Expr *parent; + E_Expr *expr; + }; + Task start_task = {0, &e_expr_nil, expr_to_irify}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + if(t->expr->kind == E_ExprKind_LeafIdent && str8_match(t->expr->string, str8_lit("$expr"), 0)) + { + E_Expr *original_expr_ref = e_expr_ref(arena, expr); + if(t->parent != &e_expr_nil) + { + e_expr_insert_child(t->parent, t->expr, original_expr_ref); + e_expr_remove_child(t->parent, t->expr); + } + } + else for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + SLLQueuePush(first_task, last_task, task); + task->parent = t->expr; + task->expr = child; + } + } + } + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr_to_irify); + scratch_end(scratch); + return irtree; +} + +internal E_IRGenRuleMap +e_irgen_rule_map_make(Arena *arena, U64 slots_count) +{ + E_IRGenRuleMap map = {0}; + map.slots_count = slots_count; + map.slots = push_array(arena, E_IRGenRuleSlot, map.slots_count); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("default"), .irgen = E_IRGEN_FUNCTION_NAME(default)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("cast"), .irgen = E_IRGEN_FUNCTION_NAME(cast)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("bswap"), .irgen = E_IRGEN_FUNCTION_NAME(bswap)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("array"), .irgen = E_IRGEN_FUNCTION_NAME(array)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("wrap"), .irgen = E_IRGEN_FUNCTION_NAME(wrap)); + return map; +} + +internal void +e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule) +{ + U64 hash = e_hash_from_string(5381, rule->name); + U64 slot_idx = hash%map->slots_count; + E_IRGenRuleNode *n = push_array(arena, E_IRGenRuleNode, 1); + MemoryCopyStruct(&n->v, rule); + n->v.name = push_str8_copy(arena, n->v.name); + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); +} + +internal E_IRGenRule * +e_irgen_rule_from_string(String8 string) +{ + E_IRGenRule *rule = &e_irgen_rule__default; + if(e_ir_state != 0 && e_ir_state->ctx != 0 && e_ir_state->ctx->irgen_rule_map != 0 && e_ir_state->ctx->irgen_rule_map->slots_count != 0) + { + E_IRGenRuleMap *map = e_ir_state->ctx->irgen_rule_map; + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + for(E_IRGenRuleNode *n = map->slots[slot_idx].first; n != 0; n = n->next) + { + if(str8_match(string, n->v.name, 0)) + { + rule = &n->v; + break; + } + } + } + return rule; +} + +//////////////////////////////// +//~ rjf: Auto Hooks + +internal E_AutoHookMap +e_auto_hook_map_make(Arena *arena, U64 slots_count) +{ + E_AutoHookMap map = {0}; + map.slots_count = slots_count; + map.slots = push_array(arena, E_AutoHookSlot, map.slots_count); + return map; +} + +internal void +e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params) +{ + Temp scratch = scratch_begin(&arena, 1); + E_TypeKey type_key = params->type_key; + if(params->type_pattern.size != 0) + { + E_TokenArray tokens = e_token_array_from_text(scratch.arena, params->type_pattern); + E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, params->type_pattern, &tokens); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.last); + type_key = irtree.type_key; + } + E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1); + node->type_key = type_key; + U8 pattern_split = '?'; + node->type_pattern_parts = str8_split(arena, params->type_pattern, &pattern_split, 1, StringSplitFlag_KeepEmpties); + node->tag_exprs = e_parse_expr_from_text(arena, push_str8_copy(arena, params->tag_expr_string)).exprs; + if(!e_type_key_match(e_type_key_zero(), type_key)) + { + U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); + U64 slot_idx = hash%map->slots_count; + SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); + } + else + { + SLLQueuePush_N(map->first_pattern, map->last_pattern, node, pattern_order_next); + } + scratch_end(scratch); +} + +internal E_ExprList +e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) +{ + ProfBeginFunction(); + E_ExprList exprs = {0}; + if(e_ir_state != 0 && e_ir_state->ctx != 0) + { + Temp scratch = scratch_begin(&arena, 1); + E_AutoHookMap *map = e_ir_state->ctx->auto_hook_map; + + //- rjf: gather exact-type-key-matches from the map + if(map != 0 && map->slots_count != 0) + { + U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); + U64 slot_idx = hash%map->slots_count; + for(E_AutoHookNode *n = map->slots[slot_idx].first; n != 0; n = n->hash_next) + { + if(e_type_key_match(n->type_key, type_key)) + { + for(E_Expr *e = n->tag_exprs.first; e != &e_expr_nil; e = e->next) + { + e_expr_list_push(arena, &exprs, e); + } + } + } + } + + //- rjf: gather fuzzy matches from all patterns in the map + if(map != 0 && map->first_pattern != 0) + { + String8 type_string = str8_skip_chop_whitespace(e_type_string_from_key(scratch.arena, type_key)); + for(E_AutoHookNode *auto_hook_node = map->first_pattern; + auto_hook_node != 0; + auto_hook_node = auto_hook_node->pattern_order_next) + { + B32 fits_this_type_string = 1; + U64 scan_pos = 0; + for(String8Node *n = auto_hook_node->type_pattern_parts.first; n != 0; n = n->next) + { + if(n->string.size == 0) + { + continue; + } + U64 pattern_part_pos = str8_find_needle(type_string, scan_pos, n->string, 0); + if(pattern_part_pos >= type_string.size) + { + fits_this_type_string = 0; + break; + } + scan_pos = pattern_part_pos + n->string.size; + } + if(fits_this_type_string) + { + for(E_Expr *e = auto_hook_node->tag_exprs.first; e != &e_expr_nil; e = e->next) + { + e_expr_list_push(arena, &exprs, e); + } + } + } + } + + scratch_end(scratch); + } + ProfEnd(); + return exprs; +} + +internal E_ExprList +e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key) +{ + E_ExprList exprs = {0}; + if(e_ir_state != 0 && e_ir_state->ctx != 0 && e_ir_state->type_auto_hook_cache_map != 0 && e_ir_state->type_auto_hook_cache_map->slots_count != 0) + { + U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); + U64 slot_idx = hash%e_ir_state->type_auto_hook_cache_map->slots_count; + E_TypeAutoHookCacheNode *node = 0; + for(E_TypeAutoHookCacheNode *n = e_ir_state->type_auto_hook_cache_map->slots[slot_idx].first; + n != 0; + n = n->next) + { + if(e_type_key_match(n->key, type_key)) + { + node = n; + } + } + if(node == 0) + { + node = push_array(e_ir_state->arena, E_TypeAutoHookCacheNode, 1); + SLLQueuePush(e_ir_state->type_auto_hook_cache_map->slots[slot_idx].first, e_ir_state->type_auto_hook_cache_map->slots[slot_idx].last, node); + node->key = type_key; + node->exprs = e_auto_hook_tag_exprs_from_type_key(e_type_state->arena, type_key); + } + exprs = node->exprs; + } + return exprs; +} + +//////////////////////////////// +//~ rjf: Evaluated String IDs + +internal U64 +e_id_from_string(String8 string) +{ + U64 hash = e_hash_from_string(5381, string); + U64 hash_slot_idx = hash%e_ir_state->string_id_map->hash_slots_count; + E_StringIDNode *node = 0; + for(E_StringIDNode *n = e_ir_state->string_id_map->hash_slots[hash_slot_idx].first; n != 0; n = n->hash_next) + { + if(str8_match(n->string, string, 0)) + { + node = n; + break; + } + } + if(node == 0) + { + e_ir_state->string_id_gen += 1; + U64 id = e_ir_state->string_id_gen; + U64 id_slot_idx = id%e_ir_state->string_id_map->id_slots_count; + node = push_array(e_ir_state->arena, E_StringIDNode, 1); + SLLQueuePush_N(e_ir_state->string_id_map->hash_slots[hash_slot_idx].first, e_ir_state->string_id_map->hash_slots[hash_slot_idx].last, node, hash_next); + SLLQueuePush_N(e_ir_state->string_id_map->id_slots[id_slot_idx].first, e_ir_state->string_id_map->hash_slots[id_slot_idx].last, node, id_next); + node->id = id; + node->string = push_str8_copy(e_ir_state->arena, string); + } + U64 result = node->id; + return result; +} + +internal String8 +e_string_from_id(U64 id) +{ + U64 id_slot_idx = id%e_ir_state->string_id_map->id_slots_count; + E_StringIDNode *node = 0; + for(E_StringIDNode *n = e_ir_state->string_id_map->id_slots[id_slot_idx].first; n != 0; n = n->id_next) + { + if(n->id == id) + { + node = n; + break; + } + } + String8 result = {0}; + if(node != 0) + { + result = node->string; + } + return result; } //////////////////////////////// @@ -211,6 +1634,14 @@ e_irtree_const_u(Arena *arena, U64 v) return n; } +internal E_IRNode * +e_irtree_leaf_u128(Arena *arena, U128 u128) +{ + E_IRNode *n = e_push_irnode(arena, RDI_EvalOp_ConstU128); + n->value.u128 = u128; + return n; +} + internal E_IRNode * e_irtree_unary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *c) { @@ -274,7 +1705,7 @@ e_irtree_set_space(Arena *arena, E_Space space, E_IRNode *c) } internal E_IRNode * -e_irtree_mem_read_type(Arena *arena, E_Space space, E_IRNode *c, E_TypeKey type_key) +e_irtree_mem_read_type(Arena *arena, E_IRNode *c, E_TypeKey type_key) { E_IRNode *result = &e_irnode_nil; U64 byte_size = e_type_byte_size_from_key(type_key); @@ -296,11 +1727,8 @@ e_irtree_mem_read_type(Arena *arena, E_Space space, E_IRNode *c, E_TypeKey type_ e_irnode_push_child(with_trunc, read_node); } - // rjf: set space for this mem read - E_IRNode *set_space_node = e_irtree_set_space(arena, space, with_trunc); - // rjf: fill - result = set_space_node; + result = with_trunc; return result; } @@ -358,20 +1786,63 @@ e_irtree_convert_hi(Arena *arena, E_IRNode *c, E_TypeKey out, E_TypeKey in) } internal E_IRNode * -e_irtree_resolve_to_value(Arena *arena, E_Space from_space, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key) +e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key) { E_IRNode *result = tree; if(from_mode == E_Mode_Offset) { - result = e_irtree_mem_read_type(arena, from_space, tree, type_key); + result = e_irtree_mem_read_type(arena, tree, type_key); } return result; } +//- rjf: rule tag poison checking + +internal B32 +e_tag_is_poisoned(E_Expr *tag) +{ + B32 tag_is_poisoned = 0; + U64 hash = e_hash_from_string(5381, str8_struct(&tag)); + U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; + for(E_UsedTagNode *n = e_ir_state->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) + { + if(n->tag == tag) + { + tag_is_poisoned = 1; + break; + } + } + return tag_is_poisoned; +} + +internal void +e_tag_poison(E_Expr *tag) +{ + U64 hash = e_hash_from_string(5381, str8_struct(&tag)); + U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; + E_UsedTagNode *n = push_array(e_ir_state->arena, E_UsedTagNode, 1); + n->tag = tag; + DLLPushBack(e_ir_state->used_tag_map->slots[slot_idx].first, e_ir_state->used_tag_map->slots[slot_idx].last, n); +} + +internal void +e_tag_unpoison(E_Expr *tag) +{ + U64 hash = e_hash_from_string(5381, str8_struct(&tag)); + U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; + for(E_UsedTagNode *n = e_ir_state->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) + { + if(n->tag == tag) + { + DLLRemove(e_ir_state->used_tag_map->slots[slot_idx].first, e_ir_state->used_tag_map->slots[slot_idx].last, n); + break; + } + } +} + //- rjf: top-level irtree/type extraction -internal E_IRTreeAndType -e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) +E_IRGEN_FUNCTION_DEF(default) { E_IRTreeAndType result = {&e_irnode_nil}; E_ExprKind kind = expr->kind; @@ -379,236 +1850,24 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { default:{}break; - //- rjf: references -> just descend to sub-expr - case E_ExprKind_Ref: - { - result = e_irtree_and_type_from_expr(arena, expr->ref); - }break; - - //- rjf: array indices + //- rjf: accesses + case E_ExprKind_MemberAccess: case E_ExprKind_ArrayIndex: { - // rjf: unpack left/right expressions - E_Expr *exprl = expr->first; - E_Expr *exprr = exprl->next; - E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); - E_IRTreeAndType r = e_irtree_and_type_from_expr(arena, exprr); - E_TypeKey l_restype = e_type_unwrap(l.type_key); - E_TypeKey r_restype = e_type_unwrap(r.type_key); - E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); - E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype); - if(e_type_kind_is_basic_or_enum(r_restype_kind)) + Temp scratch = scratch_begin(&arena, 1); + E_Expr *lhs = expr->first; + E_Expr *rhs = lhs->next; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_LookupRuleTagPair lhs_lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(lhs, &lhs_irtree); + ProfScope("lookup via rule '%.*s'", str8_varg(lhs_lookup_rule_and_tag.rule->name)) { - r_restype = e_type_unwrap_enum(r_restype); - r_restype_kind = e_type_kind_from_key(r_restype); - } - E_TypeKey direct_type = e_type_unwrap(l_restype); - direct_type = e_type_direct_from_key(direct_type); - direct_type = e_type_unwrap(direct_type); - U64 direct_type_size = e_type_byte_size_from_key(direct_type); - e_msg_list_concat_in_place(&result.msgs, &l.msgs); - e_msg_list_concat_in_place(&result.msgs, &r.msgs); - - // rjf: bad conditions? -> error if applicable, exit - if(r.root->op == 0) - { - break; - } - else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type."); - break; - } - else if(!e_type_kind_is_integer(r_restype_kind)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type."); - break; - } - else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); - break; - } - else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types."); - break; - } - - // rjf: generate - E_IRNode *new_tree = &e_irnode_nil; - { - switch(l.mode) - { - // rjf: offsets -> read from base offset - default: - case E_Mode_Null: - case E_Mode_Offset: - { - // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.space, r.mode, r.root, r_restype); - if(direct_type_size > 1) - { - E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); - } - - // rjf: ops to compute the base offset (resolve to value if addr-of-pointer) - E_IRNode *base_tree = l.root; - if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value) - { - base_tree = e_irtree_resolve_to_value(arena, l.space, l.mode, base_tree, l_restype); - } - - // rjf: ops to compute the final address - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); - }break; - - // rjf: values -> read from stack value - case E_Mode_Value: - { - // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.space, r.mode, r.root, r_restype); - if(direct_type_size > 1) - { - E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); - } - - // rjf: ops to push stack value, push offset, + read from stack value - new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead); - new_tree->value.u64 = direct_type_size; - e_irnode_push_child(new_tree, offset_tree); - e_irnode_push_child(new_tree, l.root); - }break; - } - } - - // rjf: fill - result.root = new_tree; - result.type_key = direct_type; - result.mode = l.mode; - result.space = l.space; - }break; - - //- rjf: member accesses - case E_ExprKind_MemberAccess: - { - // rjf: unpack left/right expressions - E_Expr *exprl = expr->first; - E_Expr *exprr = exprl->next; - E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); - E_TypeKey l_restype = e_type_unwrap(l.type_key); - E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); - E_TypeKey check_type_key = l_restype; - E_TypeKind check_type_kind = l_restype_kind; - if(l_restype_kind == E_TypeKind_Ptr || - l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef) - { - check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); - check_type_kind = e_type_kind_from_key(check_type_key); - } - e_msg_list_concat_in_place(&result.msgs, &l.msgs); - - // rjf: look up member - B32 r_found = 0; - E_TypeKey r_type = zero_struct; - U64 r_value = 0; - B32 r_is_constant_value = 0; - { - Temp scratch = scratch_begin(&arena, 1); - E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string); - if(match.kind != E_MemberKind_Null) - { - r_found = 1; - r_type = match.type_key; - r_value = match.off; - } - if(match.kind == E_MemberKind_Null) - { - E_Type *type = e_type_from_key(scratch.arena, check_type_key); - if(type->enum_vals != 0) - { - String8 lookup_string = exprr->string; - String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string); - String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string); - E_EnumVal *enum_val_match = 0; - for EachIndex(idx, type->count) - { - if(str8_match(type->enum_vals[idx].name, lookup_string, 0) || - str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) || - str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0)) - { - enum_val_match = &type->enum_vals[idx]; - break; - } - } - if(enum_val_match != 0) - { - r_found = 1; - r_type = check_type_key; - r_value = enum_val_match->val; - r_is_constant_value = 1; - } - } - } - scratch_end(scratch); - } - - // rjf: bad conditions? -> error if applicable, exit - if(e_type_key_match(e_type_key_zero(), check_type_key)) - { - break; - } - else if(exprr->kind != E_ExprKind_LeafMember) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); - break; - } - else if(!r_found) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); - break; - } - else if(check_type_kind != E_TypeKind_Struct && - check_type_kind != E_TypeKind_Class && - check_type_kind != E_TypeKind_Union && - check_type_kind != E_TypeKind_Enum) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); - break; - } - - // rjf: generate - { - // rjf: build tree - E_IRNode *new_tree = l.root; - E_Mode mode = l.mode; - if(l_restype_kind == E_TypeKind_Ptr || - l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef) - { - new_tree = e_irtree_resolve_to_value(arena, l.space, l.mode, new_tree, l_restype); - mode = E_Mode_Offset; - } - if(r_value != 0 && !r_is_constant_value) - { - E_IRNode *const_tree = e_irtree_const_u(arena, r_value); - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree); - } - else if(r_is_constant_value) - { - new_tree = e_irtree_const_u(arena, r_value); - mode = E_Mode_Value; - } - - // rjf: fill - result.root = new_tree; - result.type_key = r_type; - result.mode = mode; - result.space = l.space; + e_tag_poison(lhs_lookup_rule_and_tag.tag); + E_LookupInfo lookup_info = lhs_lookup_rule_and_tag.rule->info(arena, &lhs_irtree, lhs_lookup_rule_and_tag.tag, str8_zero()); + E_LookupAccess lookup_access = lhs_lookup_rule_and_tag.rule->access(arena, expr->kind, lhs, rhs, lhs_lookup_rule_and_tag.tag, lookup_info.user_data); + result = lookup_access.irtree_and_type; + e_tag_unpoison(lhs_lookup_rule_and_tag.tag); } + scratch_end(scratch); }break; //- rjf: dereference @@ -658,12 +1917,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) r_type_kind == E_TypeKind_LRef || r_type_kind == E_TypeKind_RRef)) { - new_tree = e_irtree_resolve_to_value(arena, r_tree.space, r_tree.mode, r_tree.root, r_type); + new_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); } result.root = new_tree; result.type_key = r_type_direct; result.mode = E_Mode_Offset; - result.space = r_tree.space; } }break; @@ -690,9 +1948,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: generate result.root = r_tree.root; - result.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, r_type_unwrapped, 0); + result.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, r_type_unwrapped, 1, 0); result.mode = E_Mode_Value; - result.space = r_tree.space; }break; //- rjf: cast @@ -736,7 +1993,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: generate { - E_IRNode *in_tree = e_irtree_resolve_to_value(arena, casted_tree.space, casted_tree.mode, casted_tree.root, casted_type); + E_IRNode *in_tree = e_irtree_resolve_to_value(arena, casted_tree.mode, casted_tree.root, casted_type); E_IRNode *new_tree = in_tree; if(conversion_rule == RDI_EvalConversionKind_Legal) { @@ -749,7 +2006,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = new_tree; result.type_key = cast_type; result.mode = E_Mode_Value; - result.space = casted_tree.space; } }break; @@ -774,7 +2030,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); r_type = r_tree.type_key; - space = r_tree.space; }break; } @@ -794,7 +2049,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = e_irtree_const_u(arena, r_type_byte_size); result.type_key = e_type_key_basic(E_TypeKind_U64); result.mode = E_Mode_Value; - result.space = space; } }break; @@ -810,7 +2064,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = e_irtree_const_u(arena, 0); result.type_key = r_tree.type_key; result.mode = E_Mode_Null; - result.space = r_tree.space; }break; //- rjf: byteswap @@ -823,7 +2076,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_TypeKey r_type = e_type_unwrap(r_tree.type_key); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); U64 r_type_size = e_type_byte_size_from_key(r_type); - E_Space space = r_tree.space; // rjf: bad conditions? -> error if applicable, exit if(!e_type_kind_is_integer(r_type_kind) || (r_type_size != 8 && r_type_size != 4 && r_type_size != 2)) @@ -835,12 +2087,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: generate { E_IRNode *node = e_push_irnode(arena, RDI_EvalOp_ByteSwap); - E_IRNode *rhs = e_irtree_resolve_to_value(arena, space, r_tree.mode, r_tree.root, r_type); + E_IRNode *rhs = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); e_irnode_push_child(node, rhs); node->value.u64 = r_type_size; result.root = node; result.mode = E_Mode_Value; - result.space = space; result.type_key = r_type; } }break; @@ -851,7 +2102,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result = e_irtree_and_type_from_expr(arena, expr->first); }break; case E_ExprKind_Neg: - case E_ExprKind_LogNot: case E_ExprKind_BitNot: { // rjf: unpack operand @@ -877,13 +2127,45 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: generate { - E_IRNode *in_tree = e_irtree_resolve_to_value(arena, r_tree.space, r_tree.mode, r_tree.root, r_type); + E_IRNode *in_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); + in_tree = e_irtree_convert_hi(arena, in_tree, r_type_promoted, r_type); + E_IRNode *new_tree = e_irtree_unary_op(arena, op, r_type_group, in_tree); + result.root = new_tree; + result.type_key = r_type_promoted; + result.mode = E_Mode_Value; + } + }break; + case E_ExprKind_LogNot: + { + // rjf: unpack operand + E_Expr *r_expr = expr->first; + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKind r_type_kind = e_type_kind_from_key(r_type); + RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); + E_TypeKey r_type_promoted = e_type_key_basic(E_TypeKind_Bool); + RDI_EvalOp op = e_opcode_from_expr_kind(kind); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + + // rjf: bad conditions? -> error if applicable, exit + if(r_tree.root->op == 0) + { + break; + } + else if(!rdi_eval_op_typegroup_are_compatible(op, r_type_group)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Cannot use this operator on this type."); + break; + } + + // rjf: generate + { + E_IRNode *in_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); in_tree = e_irtree_convert_hi(arena, in_tree, r_type_promoted, r_type); E_IRNode *new_tree = e_irtree_unary_op(arena, op, r_type_group, in_tree); result.root = new_tree; result.type_key = r_type_promoted; result.mode = E_Mode_Value; - result.space = r_tree.space; } }break; @@ -1011,20 +2293,14 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: generate { E_TypeKey final_type_key = is_comparison ? e_type_key_basic(E_TypeKind_Bool) : l_type; - E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.space, l_tree.mode, l_tree.root, l_type); - E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.space, r_tree.mode, r_tree.root, r_type); + E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.mode, l_tree.root, l_type); + E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); l_value_tree = e_irtree_convert_hi(arena, l_value_tree, l_type, l_type); r_value_tree = e_irtree_convert_hi(arena, r_value_tree, l_type, r_type); E_IRNode *new_tree = e_irtree_binary_op(arena, op, l_type_group, l_value_tree, r_value_tree); result.root = new_tree; result.type_key = final_type_key; result.mode = E_Mode_Value; - result.space = l_tree.space; - E_Space zero_space = {0}; - if(MemoryMatchStruct(&result.space, &zero_space)) - { - result.space = r_tree.space; - } } }break; @@ -1051,10 +2327,10 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_IRNode *ptr_root = ptr_tree->root; if(!ptr_is_decay) { - ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->space, ptr_tree->mode, ptr_root, ptr_tree->type_key); + ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->mode, ptr_root, ptr_tree->type_key); } E_IRNode *int_root = int_tree->root; - int_root = e_irtree_resolve_to_value(arena, int_tree->space, int_tree->mode, int_root, int_tree->type_key); + int_root = e_irtree_resolve_to_value(arena, int_tree->mode, int_root, int_tree->type_key); if(direct_type_size > 1) { E_IRNode *const_root = e_irtree_const_u(arena, direct_type_size); @@ -1063,18 +2339,12 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_TypeKey ptr_type = ptr_tree->type_key; if(ptr_is_decay) { - ptr_type = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, direct_type, 0); + ptr_type = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, direct_type, 1, 0); } E_IRNode *new_root = e_irtree_binary_op_u(arena, op, ptr_root, int_root); result.root = new_root; result.type_key = ptr_type; result.mode = E_Mode_Value; - result.space = l_tree.space; - E_Space zero_space = {0}; - if(MemoryMatchStruct(&result.space, &zero_space)) - { - result.space = r_tree.space; - } } }break; @@ -1090,11 +2360,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_IRNode *r_root = r_tree.root; if(!l_is_decay) { - l_root = e_irtree_resolve_to_value(arena, l_tree.space, l_tree.mode, l_root, l_type); + l_root = e_irtree_resolve_to_value(arena, l_tree.mode, l_root, l_type); } if(!r_is_decay) { - r_root = e_irtree_resolve_to_value(arena, r_tree.space, r_tree.mode, r_root, r_type); + r_root = e_irtree_resolve_to_value(arena, r_tree.mode, r_root, r_type); } E_IRNode *op_tree = e_irtree_binary_op_u(arena, op, l_root, r_root); E_IRNode *new_tree = op_tree; @@ -1106,12 +2376,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = new_tree; result.type_key = e_type_key_basic(E_TypeKind_U64); result.mode = E_Mode_Value; - result.space = l_tree.space; - E_Space zero_space = {0}; - if(MemoryMatchStruct(&result.space, &zero_space)) - { - result.space = r_tree.space; - } }break; //- rjf: pointer array comparison @@ -1133,22 +2397,16 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_IRNode *arr_root = arr_tree->root; if(!ptr_is_decay) { - ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->space, ptr_tree->mode, ptr_tree->root, ptr_tree->type_key); + ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->mode, ptr_tree->root, ptr_tree->type_key); } // rjf: read from pointer into value, to compare with array - E_IRNode *mem_root = e_irtree_mem_read_type(arena, ptr_tree->space, ptr_root, arr_tree->type_key); + E_IRNode *mem_root = e_irtree_mem_read_type(arena, ptr_root, arr_tree->type_key); // rjf: generate result.root = e_irtree_binary_op(arena, op, RDI_EvalTypeGroup_Other, mem_root, arr_root); result.type_key = e_type_key_basic(E_TypeKind_Bool); result.mode = E_Mode_Value; - result.space = ptr_tree->space; - E_Space zero_space = {0}; - if(MemoryMatchStruct(&result.space, &zero_space)) - { - result.space = arr_tree->space; - } }break; } }break; @@ -1190,21 +2448,15 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: generate { - E_IRNode *c_value_tree = e_irtree_resolve_to_value(arena, c_tree.space, c_tree.mode, c_tree.root, c_type); - E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.space, l_tree.mode, l_tree.root, l_type); - E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.space, r_tree.mode, r_tree.root, r_type); + E_IRNode *c_value_tree = e_irtree_resolve_to_value(arena, c_tree.mode, c_tree.root, c_type); + E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.mode, l_tree.root, l_type); + E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); l_value_tree = e_irtree_convert_hi(arena, l_value_tree, result_type, l_type); r_value_tree = e_irtree_convert_hi(arena, r_value_tree, result_type, r_type); E_IRNode *new_tree = e_irtree_conditional(arena, c_value_tree, l_value_tree, r_value_tree); result.root = new_tree; result.type_key = result_type; result.mode = E_Mode_Value; - result.space = l_expr->space; - E_Space zero_space = {0}; - if(MemoryMatchStruct(&result.space, &zero_space)) - { - result.space = r_expr->space; - } } }break; @@ -1212,11 +2464,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) case E_ExprKind_LeafBytecode: { E_IRNode *new_tree = e_irtree_bytecode_no_copy(arena, expr->bytecode); + new_tree->space = expr->space; E_TypeKey final_type_key = expr->type_key; result.root = new_tree; result.type_key = final_type_key; result.mode = expr->mode; - result.space = expr->space; }break; //- rjf: (unexpected) leaf member @@ -1229,7 +2481,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) case E_ExprKind_LeafStringLiteral: { String8 string = expr->string; - E_TypeKey type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_UChar8), string.size); + E_TypeKey type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_UChar8), string.size, 0); E_IRNode *new_tree = e_irtree_string_literal(arena, string); result.root = new_tree; result.type_key = type_key; @@ -1282,16 +2534,16 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) //- rjf: leaf identifiers case E_ExprKind_LeafIdent: { - E_Expr *macro_expr = e_string2expr_lookup(e_ir_ctx->macro_map, expr->string); + E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, expr->string); if(macro_expr == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->location, "`%S` could not be found.", expr->string); } else { - e_string2expr_map_inc_poison(e_ir_ctx->macro_map, expr->string); + e_string2expr_map_inc_poison(e_ir_state->ctx->macro_map, expr->string); result = e_irtree_and_type_from_expr(arena, macro_expr); - e_string2expr_map_dec_poison(e_ir_ctx->macro_map, expr->string); + e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, expr->string); } }break; @@ -1299,34 +2551,59 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) case E_ExprKind_LeafOffset: { E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU64); - new_tree->value.u64 = expr->value.u64; + new_tree->value = expr->value; + new_tree->space = expr->space; result.root = new_tree; result.type_key = expr->type_key; result.mode = E_Mode_Offset; - result.space = expr->space; + }break; + + //- rjf: leaf values + case E_ExprKind_LeafValue: + { + E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU128); + new_tree->value = expr->value; + new_tree->space = expr->space; + result.root = new_tree; + result.type_key = expr->type_key; + result.mode = E_Mode_Value; }break; //- rjf: leaf file paths case E_ExprKind_LeafFilePath: { - U128 key = fs_key_from_path_range(expr->string, r1u64(0, max_U64)); - E_Space space = {E_SpaceKind_FileSystem, .u128 = key}; - U64 size = fs_size_from_path(expr->string); - E_IRNode *base_offset = e_irtree_const_u(arena, 0); - E_IRNode *set_space = e_irtree_set_space(arena, space, base_offset); - result.root = set_space; - result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), size); - result.mode = E_Mode_Offset; - result.space = space; + Temp scratch = scratch_begin(&arena, 1); + String8 file_path = expr->string; + FileProperties props = os_properties_from_file_path(file_path); + if(!str8_match(expr->qualifier, str8_lit("folder"), 0) && !(props.flags & FilePropertyFlag_IsFolder) && file_path.size != 0) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); + result.mode = E_Mode_Value; + } + else + { + String8 folder_path = str8_chop_last_slash(file_path); + props = os_properties_from_file_path(folder_path); + if(props.flags & FilePropertyFlag_IsFolder || folder_path.size == 0 || str8_match(folder_path, str8_lit("/"), StringMatchFlag_SlashInsensitive)) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(folder_path))); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); + result.mode = E_Mode_Value; + } + } + scratch_end(scratch); }break; //- rjf: types case E_ExprKind_TypeIdent: { result.root = e_irtree_const_u(arena, 0); + result.root->space = expr->space; result.type_key = expr->type_key; result.mode = E_Mode_Null; - result.space = expr->space; }break; //- rjf: (unexpected) type expressions @@ -1348,18 +2625,116 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); } }break; - + } + return result; +} + +internal E_IRTreeAndType +e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) +{ + ProfBeginFunction(); + Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType result = {&e_irnode_nil}; + if(expr->kind == E_ExprKind_Ref) + { + expr = expr->ref; } + //- rjf: pick the ir-generation rule from explicitly-stored expressions + E_IRGenRule *explicit_irgen_rule = &e_irgen_rule__default; + E_Expr *explicit_irgen_rule_tag = &e_expr_nil; + for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) + { + String8 name = tag->string; + E_IRGenRule *irgen_rule_candidate = e_irgen_rule_from_string(name); + if(irgen_rule_candidate != &e_irgen_rule__default) + { + B32 tag_is_poisoned = e_tag_is_poisoned(tag); + if(!tag_is_poisoned) + { + explicit_irgen_rule = irgen_rule_candidate; + explicit_irgen_rule_tag = tag; + } + } + } + + //- rjf: apply all ir-generation steps + typedef struct Task Task; + struct Task + { + Task *next; + E_IRGenRule *rule; + E_Expr *tag; + }; + Task start_task = {0, explicit_irgen_rule, explicit_irgen_rule_tag}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + // rjf: poison the tag we are about to use, so we don't recursively use it + e_tag_poison(t->tag); + + // rjf: do this rule's generation + ProfScope("irgen rule '%.*s'", str8_varg(t->rule->name)) + { + result = t->rule->irgen(arena, expr, t->tag); + if(result.root == &e_irnode_nil && t->rule != &e_irgen_rule__default) + { + result = e_irgen_rule__default.irgen(arena, expr, &e_expr_nil); + } + } + + // rjf: find any auto hooks according to this generation's type + { + E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key__cached(result.type_key); + for(E_ExprNode *n = exprs.first; n != 0; n = n->next) + { + for(E_Expr *tag = n->v; tag != &e_expr_nil; tag = tag->next) + { + B32 tag_is_poisoned = e_tag_is_poisoned(tag); + if(!tag_is_poisoned) + { + E_IRGenRule *rule = e_irgen_rule_from_string(tag->string); + if(rule != &e_irgen_rule__default) + { + Task *task = push_array(scratch.arena, Task, 1); + SLLQueuePush(first_task, last_task, task); + task->rule = rule; + task->tag = tag; + break; + } + } + } + } + } + } + + //- rjf: unpoison the tags we used + for(Task *t = first_task; t != 0; t = t->next) + { + e_tag_unpoison(t->tag); + } + + scratch_end(scratch); + ProfEnd(); return result; } //- rjf: irtree -> linear ops/bytecode internal void -e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out) +e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out) { U32 op = root->op; + { + E_Space zero_space = zero_struct; + if(!MemoryMatchStruct(&root->space, &zero_space) && + !MemoryMatchStruct(&root->space, current_space)) + { + *current_space = root->space; + e_oplist_push_set_space(arena, out, root->space); + } + } switch(op) { case RDI_EvalOp_Stop: @@ -1382,9 +2757,8 @@ e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out) child != &e_irnode_nil; child = child->next) { - e_append_oplist_from_irtree(arena, child, out); + e_append_oplist_from_irtree(arena, child, current_space, out); } - }break; case RDI_EvalOp_Cond: @@ -1434,7 +2808,7 @@ e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out) child != &e_irnode_nil && idx < child_count; child = child->next, idx += 1) { - e_append_oplist_from_irtree(arena, child, out); + e_append_oplist_from_irtree(arena, child, current_space, out); } // rjf: emit op to compute this node @@ -1448,7 +2822,8 @@ internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root) { E_OpList ops = {0}; - e_append_oplist_from_irtree(arena, root, &ops); + E_Space space = e_interpret_ctx->primary_space; + e_append_oplist_from_irtree(arena, root, &space, &ops); return ops; } @@ -1537,3 +2912,167 @@ e_bytecode_from_oplist(Arena *arena, E_OpList *oplist) result.str = str; return result; } + +//- rjf: leaf-bytecode expression extensions + +internal E_Expr * +e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, String8 member_name) +{ + E_Expr *root = e_push_expr(arena, E_ExprKind_MemberAccess, 0); + E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->location); + E_OpList lhs_oplist = e_oplist_from_irtree(arena, lhs_irtree->root); + lhs_bytecode->string = e_string_from_expr(arena, lhs); + lhs_bytecode->qualifier = lhs->qualifier; + lhs_bytecode->space = lhs->space; + lhs_bytecode->mode = lhs_irtree->mode; + lhs_bytecode->type_key = lhs_irtree->type_key; + lhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &lhs_oplist); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0); + rhs->string = push_str8_copy(arena, member_name); + e_expr_push_child(root, lhs_bytecode); + e_expr_push_child(root, rhs); + return root; +} + +internal E_Expr * +e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, U64 index) +{ + E_Expr *root = e_push_expr(arena, E_ExprKind_ArrayIndex, 0); + E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->location); + E_OpList lhs_oplist = e_oplist_from_irtree(arena, lhs_irtree->root); + lhs_bytecode->string = e_string_from_expr(arena, lhs); + lhs_bytecode->qualifier = lhs->qualifier; + lhs_bytecode->space = lhs->space; + lhs_bytecode->mode = lhs_irtree->mode; + lhs_bytecode->type_key = lhs_irtree->type_key; + lhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &lhs_oplist); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafU64, 0); + rhs->value.u64 = index; + e_expr_push_child(root, lhs_bytecode); + e_expr_push_child(root, rhs); + return root; +} + +internal E_Expr * +e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree) +{ + E_Expr *root = e_push_expr(arena, E_ExprKind_Deref, 0); + E_Expr *rhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, rhs->location); + E_OpList rhs_oplist = e_oplist_from_irtree(arena, rhs_irtree->root); + rhs_bytecode->string = e_string_from_expr(arena, rhs); + rhs_bytecode->space = rhs->space; + rhs_bytecode->mode = rhs_irtree->mode; + rhs_bytecode->type_key = rhs_irtree->type_key; + rhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &rhs_oplist); + e_expr_push_child(root, rhs_bytecode); + return root; +} + +internal E_Expr * +e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key) +{ + E_Expr *root = e_push_expr(arena, E_ExprKind_Cast, 0); + E_Expr *rhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, rhs->location); + E_OpList rhs_oplist = e_oplist_from_irtree(arena, rhs_irtree->root); + rhs_bytecode->string = e_string_from_expr(arena, rhs); + rhs_bytecode->space = rhs->space; + rhs_bytecode->mode = rhs_irtree->mode; + rhs_bytecode->type_key = rhs_irtree->type_key; + rhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &rhs_oplist); + E_Expr *lhs = e_push_expr(arena, E_ExprKind_TypeIdent, 0); + lhs->type_key = type_key; + e_expr_push_child(root, lhs); + e_expr_push_child(root, rhs_bytecode); + return root; +} + +//////////////////////////////// +//~ rjf: IRified Expression Cache + +internal E_IRTreeAndType +e_irtree_and_type_from_expr__cached(E_Expr *expr) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + { + U64 hash = e_hash_from_string(5381, str8_struct(&expr)); + U64 slot_idx = hash%e_ir_state->irtree_and_type_cache_slots_count; + E_IRTreeAndTypeCacheNode *node = 0; + for(E_IRTreeAndTypeCacheNode *n = e_ir_state->irtree_and_type_cache_slots[slot_idx].first; n != 0; n = n->next) + { + if(n->expr == expr) + { + node = n; + break; + } + } + if(node == 0) + { + node = push_array(e_ir_state->arena, E_IRTreeAndTypeCacheNode, 1); + SLLQueuePush(e_ir_state->irtree_and_type_cache_slots[slot_idx].first, e_ir_state->irtree_and_type_cache_slots[slot_idx].last, node); + node->irtree_and_type = e_irtree_and_type_from_expr(e_ir_state->arena, expr); + } + if(node != 0) + { + result = node->irtree_and_type; + } + } + return result; +} + +//////////////////////////////// +//~ rjf: Expression & IR-Tree => Lookup Rule + +internal E_LookupRuleTagPair +e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) +{ + E_LookupRuleTagPair result = {&e_lookup_rule__default, &e_expr_nil}; + { + // rjf: first try explicitly-stored tags + if(result.rule == &e_lookup_rule__default) + { + for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) + { + if(e_tag_is_poisoned(tag)) { continue; } + E_LookupRule *candidate = e_lookup_rule_from_string(tag->string); + if(candidate != &e_lookup_rule__nil) + { + result.rule = candidate; + result.tag = tag; + } + } + } + + // rjf: next try implicit set name -> rule mapping + if(result.rule == &e_lookup_rule__default) + { + E_TypeKind type_kind = e_type_kind_from_key(irtree->type_key); + if(type_kind == E_TypeKind_Set) + { + E_Type *type = e_type_from_key__cached(irtree->type_key); + String8 name = type->name; + E_LookupRule *candidate = e_lookup_rule_from_string(name); + if(candidate != &e_lookup_rule__nil) + { + result.rule = candidate; + } + } + } + + // rjf: next try auto hook map + if(result.rule == &e_lookup_rule__default) + { + E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree->type_key); + for(E_ExprNode *n = tags.first; n != 0; n = n->next) + { + if(e_tag_is_poisoned(n->v)) { continue; } + E_LookupRule *candidate = e_lookup_rule_from_string(n->v->string); + if(candidate != &e_lookup_rule__nil) + { + result.rule = candidate; + result.tag = n->v; + } + } + } + } + return result; +} diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index d5485c1f..d06cb232 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -42,6 +42,7 @@ struct E_IRNode E_IRNode *last; E_IRNode *next; RDI_EvalOp op; + E_Space space; String8 string; E_Value value; }; @@ -51,25 +52,325 @@ struct E_IRTreeAndType { E_IRNode *root; E_TypeKey type_key; + E_Member member; E_Mode mode; - E_Space space; E_MsgList msgs; }; //////////////////////////////// -//~ rjf: Parse Context +//~ rjf: Member/Index Lookup Hooks + +typedef struct E_LookupInfo E_LookupInfo; +struct E_LookupInfo +{ + void *user_data; + U64 named_expr_count; + U64 idxed_expr_count; +}; + +typedef struct E_LookupAccess E_LookupAccess; +struct E_LookupAccess +{ + E_IRTreeAndType irtree_and_type; +}; + +#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_IRTreeAndType *lhs, E_Expr *tag, String8 filter) +#define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name +#define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name)) +typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType); +E_LOOKUP_INFO_FUNCTION_DEF(default); + +#define E_LOOKUP_ACCESS_FUNCTION_SIG(name) E_LookupAccess name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, E_Expr *tag, void *user_data) +#define E_LOOKUP_ACCESS_FUNCTION_NAME(name) e_lookup_access_##name +#define E_LOOKUP_ACCESS_FUNCTION_DEF(name) internal E_LOOKUP_ACCESS_FUNCTION_SIG(E_LOOKUP_ACCESS_FUNCTION_NAME(name)) +typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType); +E_LOOKUP_ACCESS_FUNCTION_DEF(default); + +#define E_LOOKUP_RANGE_FUNCTION_SIG(name) void name(Arena *arena, E_Expr *lhs, E_Expr *tag, String8 filter, Rng1U64 idx_range, E_Expr **exprs, String8 *exprs_strings, void *user_data) +#define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name +#define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name)) +typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType); +E_LOOKUP_RANGE_FUNCTION_DEF(default); + +#define E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data) +#define E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name) e_lookup_id_from_num_##name +#define E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(name) internal E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name)) +typedef E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LookupIDFromNumFunctionType); +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default); + +#define E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data) +#define E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name) e_lookup_num_from_id_##name +#define E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(name) internal E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name)) +typedef E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LookupNumFromIDFunctionType); +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default); + +typedef struct E_LookupRule E_LookupRule; +struct E_LookupRule +{ + String8 name; + E_LookupInfoFunctionType *info; + E_LookupAccessFunctionType *access; + E_LookupRangeFunctionType *range; + E_LookupIDFromNumFunctionType *id_from_num; + E_LookupNumFromIDFunctionType *num_from_id; +}; + +typedef struct E_LookupRuleNode E_LookupRuleNode; +struct E_LookupRuleNode +{ + E_LookupRuleNode *next; + E_LookupRule v; +}; + +typedef struct E_LookupRuleSlot E_LookupRuleSlot; +struct E_LookupRuleSlot +{ + E_LookupRuleNode *first; + E_LookupRuleNode *last; +}; + +typedef struct E_LookupRuleMap E_LookupRuleMap; +struct E_LookupRuleMap +{ + E_LookupRuleSlot *slots; + U64 slots_count; +}; + +typedef struct E_LookupRuleTagPair E_LookupRuleTagPair; +struct E_LookupRuleTagPair +{ + E_LookupRule *rule; + E_Expr *tag; +}; + +//////////////////////////////// +//~ rjf: IR Generation Hooks + +#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_Expr *tag) +#define E_IRGEN_FUNCTION_NAME(name) e_irgen_##name +#define E_IRGEN_FUNCTION_DEF(name) internal E_IRGEN_FUNCTION_SIG(E_IRGEN_FUNCTION_NAME(name)) +typedef E_IRGEN_FUNCTION_SIG(E_IRGenFunctionType); +E_IRGEN_FUNCTION_DEF(default); + +typedef struct E_IRGenRule E_IRGenRule; +struct E_IRGenRule +{ + String8 name; + E_IRGenFunctionType *irgen; +}; + +typedef struct E_IRGenRuleNode E_IRGenRuleNode; +struct E_IRGenRuleNode +{ + E_IRGenRuleNode *next; + E_IRGenRule v; +}; + +typedef struct E_IRGenRuleSlot E_IRGenRuleSlot; +struct E_IRGenRuleSlot +{ + E_IRGenRuleNode *first; + E_IRGenRuleNode *last; +}; + +typedef struct E_IRGenRuleMap E_IRGenRuleMap; +struct E_IRGenRuleMap +{ + U64 slots_count; + E_IRGenRuleSlot *slots; +}; + +//////////////////////////////// +//~ rjf: Type Pattern -> Hook Key Data Structure (Auto View Rules) + +typedef struct E_AutoHookNode E_AutoHookNode; +struct E_AutoHookNode +{ + E_AutoHookNode *hash_next; + E_AutoHookNode *pattern_order_next; + E_TypeKey type_key; + String8List type_pattern_parts; + E_ExprChain tag_exprs; +}; + +typedef struct E_AutoHookSlot E_AutoHookSlot; +struct E_AutoHookSlot +{ + E_AutoHookNode *first; + E_AutoHookNode *last; +}; + +typedef struct E_AutoHookMap E_AutoHookMap; +struct E_AutoHookMap +{ + U64 slots_count; + E_AutoHookSlot *slots; + E_AutoHookNode *first_pattern; + E_AutoHookNode *last_pattern; +}; + +typedef struct E_AutoHookParams E_AutoHookParams; +struct E_AutoHookParams +{ + E_TypeKey type_key; + String8 type_pattern; + String8 tag_expr_string; +}; + +//////////////////////////////// +//~ rjf: Used Tag Map Data Structure + +typedef struct E_UsedTagNode E_UsedTagNode; +struct E_UsedTagNode +{ + E_UsedTagNode *next; + E_UsedTagNode *prev; + E_Expr *tag; +}; + +typedef struct E_UsedTagSlot E_UsedTagSlot; +struct E_UsedTagSlot +{ + E_UsedTagNode *first; + E_UsedTagNode *last; +}; + +typedef struct E_UsedTagMap E_UsedTagMap; +struct E_UsedTagMap +{ + U64 slots_count; + E_UsedTagSlot *slots; +}; + +//////////////////////////////// +//~ rjf: Type Key -> Auto Hook Expr List Cache + +typedef struct E_TypeAutoHookCacheNode E_TypeAutoHookCacheNode; +struct E_TypeAutoHookCacheNode +{ + E_TypeAutoHookCacheNode *next; + E_TypeKey key; + E_ExprList exprs; +}; + +typedef struct E_TypeAutoHookCacheSlot E_TypeAutoHookCacheSlot; +struct E_TypeAutoHookCacheSlot +{ + E_TypeAutoHookCacheNode *first; + E_TypeAutoHookCacheNode *last; +}; + +typedef struct E_TypeAutoHookCacheMap E_TypeAutoHookCacheMap; +struct E_TypeAutoHookCacheMap +{ + U64 slots_count; + E_TypeAutoHookCacheSlot *slots; +}; + +//////////////////////////////// +//~ rjf: Evaluated String ID Map + +typedef struct E_StringIDNode E_StringIDNode; +struct E_StringIDNode +{ + E_StringIDNode *hash_next; + E_StringIDNode *id_next; + U64 id; + String8 string; +}; + +typedef struct E_StringIDSlot E_StringIDSlot; +struct E_StringIDSlot +{ + E_StringIDNode *first; + E_StringIDNode *last; +}; + +typedef struct E_StringIDMap E_StringIDMap; +struct E_StringIDMap +{ + U64 id_slots_count; + E_StringIDSlot *id_slots; + U64 hash_slots_count; + E_StringIDSlot *hash_slots; +}; + +//////////////////////////////// +//~ rjf: IR Context typedef struct E_IRCtx E_IRCtx; struct E_IRCtx { E_String2ExprMap *macro_map; + E_LookupRuleMap *lookup_rule_map; + E_IRGenRuleMap *irgen_rule_map; + E_AutoHookMap *auto_hook_map; +}; + +//////////////////////////////// +//~ rjf: IR State + +typedef struct E_IRTreeAndTypeCacheNode E_IRTreeAndTypeCacheNode; +struct E_IRTreeAndTypeCacheNode +{ + E_IRTreeAndTypeCacheNode *next; + E_Expr *expr; + E_IRTreeAndType irtree_and_type; +}; + +typedef struct E_IRTreeAndTypeCacheSlot E_IRTreeAndTypeCacheSlot; +struct E_IRTreeAndTypeCacheSlot +{ + E_IRTreeAndTypeCacheNode *first; + E_IRTreeAndTypeCacheNode *last; +}; + +typedef struct E_IRState E_IRState; +struct E_IRState +{ + Arena *arena; + U64 arena_eval_start_pos; + + // rjf: ir context + E_IRCtx *ctx; + + // rjf: caches + E_UsedTagMap *used_tag_map; + E_TypeAutoHookCacheMap *type_auto_hook_cache_map; + U64 irtree_and_type_cache_slots_count; + E_IRTreeAndTypeCacheSlot *irtree_and_type_cache_slots; + U64 string_id_gen; + E_StringIDMap *string_id_map; }; //////////////////////////////// //~ rjf: Globals +local_persist read_only E_LookupRule e_lookup_rule__nil = +{ + str8_lit_comp("nil"), + E_LOOKUP_INFO_FUNCTION_NAME(default), + E_LOOKUP_ACCESS_FUNCTION_NAME(default), + E_LOOKUP_RANGE_FUNCTION_NAME(default), + E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), + E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default), +}; +local_persist read_only E_LookupRule e_lookup_rule__default = +{ + str8_lit_comp("default"), + E_LOOKUP_INFO_FUNCTION_NAME(default), + E_LOOKUP_ACCESS_FUNCTION_NAME(default), + E_LOOKUP_RANGE_FUNCTION_NAME(default), + E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), + E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default), +}; +local_persist read_only E_IRGenRule e_irgen_rule__default = +{ + str8_lit_comp("default"), + E_IRGEN_FUNCTION_NAME(default), +}; global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; -thread_static E_IRCtx *e_ir_ctx = 0; +thread_static E_IRState *e_ir_state = 0; //////////////////////////////// //~ rjf: Expr Kind Enum Functions @@ -83,6 +384,39 @@ internal B32 e_expr_kind_is_comparison(E_ExprKind kind); internal E_IRCtx *e_selected_ir_ctx(void); internal void e_select_ir_ctx(E_IRCtx *ctx); +//////////////////////////////// +//~ rjf: Lookups + +internal E_LookupRuleMap e_lookup_rule_map_make(Arena *arena, U64 slots_count); +internal void e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule); +#define e_lookup_rule_map_insert_new(arena, map, name_, ...) e_lookup_rule_map_insert((arena), (map), &(E_LookupRule){.name = (name_), __VA_ARGS__}) + +internal E_LookupRule *e_lookup_rule_from_string(String8 string); + +//////////////////////////////// +//~ rjf: IR Gen Rules + +internal E_IRGenRuleMap e_irgen_rule_map_make(Arena *arena, U64 slots_count); +internal void e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule); +#define e_irgen_rule_map_insert_new(arena, map, name_, ...) e_irgen_rule_map_insert((arena), (map), &(E_IRGenRule){.name = (name_), __VA_ARGS__}) + +internal E_IRGenRule *e_irgen_rule_from_string(String8 string); + +//////////////////////////////// +//~ rjf: Auto Hooks + +internal E_AutoHookMap e_auto_hook_map_make(Arena *arena, U64 slots_count); +internal void e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params); +#define e_auto_hook_map_insert_new(arena, map, ...) e_auto_hook_map_insert_new_((arena), (map), &(E_AutoHookParams){.type_key = zero_struct, __VA_ARGS__}) +internal E_ExprList e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key); +internal E_ExprList e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key); + +//////////////////////////////// +//~ rjf: Evaluated String IDs + +internal U64 e_id_from_string(String8 string); +internal String8 e_string_from_id(U64 id); + //////////////////////////////// //~ rjf: IR-ization Functions @@ -101,6 +435,7 @@ internal void e_irnode_push_child(E_IRNode *parent, E_IRNode *child); //- rjf: ir subtree building helpers internal E_IRNode *e_irtree_const_u(Arena *arena, U64 v); +internal E_IRNode *e_irtree_leaf_u128(Arena *arena, U128 u128); internal E_IRNode *e_irtree_unary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *c); internal E_IRNode *e_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *l, E_IRNode *r); internal E_IRNode *e_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, E_IRNode *l, E_IRNode *r); @@ -108,18 +443,39 @@ internal E_IRNode *e_irtree_conditional(Arena *arena, E_IRNode *c, E_IRNode *l, internal E_IRNode *e_irtree_bytecode_no_copy(Arena *arena, String8 bytecode); internal E_IRNode *e_irtree_string_literal(Arena *arena, String8 string); internal E_IRNode *e_irtree_set_space(Arena *arena, E_Space space, E_IRNode *c); -internal E_IRNode *e_irtree_mem_read_type(Arena *arena, E_Space space, E_IRNode *c, E_TypeKey type_key); +internal E_IRNode *e_irtree_mem_read_type(Arena *arena, E_IRNode *c, E_TypeKey type_key); internal E_IRNode *e_irtree_convert_lo(Arena *arena, E_IRNode *c, RDI_EvalTypeGroup out, RDI_EvalTypeGroup in); internal E_IRNode *e_irtree_trunc(Arena *arena, E_IRNode *c, E_TypeKey type_key); internal E_IRNode *e_irtree_convert_hi(Arena *arena, E_IRNode *c, E_TypeKey out, E_TypeKey in); -internal E_IRNode *e_irtree_resolve_to_value(Arena *arena, E_Space from_space, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key); +internal E_IRNode *e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key); + +//- rjf: rule tag poison checking +internal B32 e_tag_is_poisoned(E_Expr *tag); +internal void e_tag_poison(E_Expr *tag); +internal void e_tag_unpoison(E_Expr *tag); //- rjf: top-level irtree/type extraction internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); //- rjf: irtree -> linear ops/bytecode -internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out); +internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out); internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root); internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist); +//- rjf: leaf-bytecode expression extensions +internal E_Expr *e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, String8 member_name); +internal E_Expr *e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, U64 index); +internal E_Expr *e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree); +internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key); + +//////////////////////////////// +//~ rjf: IRified Expression Cache + +internal E_IRTreeAndType e_irtree_and_type_from_expr__cached(E_Expr *expr); + +//////////////////////////////// +//~ rjf: Expression & IR-Tree => Lookup Rule + +internal E_LookupRuleTagPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); + #endif // EVAL_IR_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 60f31be4..9ab30a5c 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -15,6 +15,7 @@ global read_only String8 e_multichar_symbol_strings[] = str8_lit_comp("!="), str8_lit_comp("&&"), str8_lit_comp("||"), + str8_lit_comp("=>"), }; global read_only S64 e_max_precedence = 15; @@ -151,8 +152,8 @@ e_string2expr_map_insert(Arena *arena, E_String2ExprMap *map, String8 string, E_ SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); node->string = push_str8_copy(arena, string); existing_node = node; + existing_node->expr = expr; } - existing_node->expr = expr; } internal void @@ -618,22 +619,32 @@ e_token_array_make_first_opl(E_Token *first, E_Token *opl) internal E_ParseCtx * e_selected_parse_ctx(void) { - return e_parse_ctx; + return e_parse_state->ctx; } internal void e_select_parse_ctx(E_ParseCtx *ctx) { - e_parse_ctx = ctx; + if(e_parse_state == 0) + { + Arena *arena = arena_alloc(); + e_parse_state = push_array(arena, E_ParseState, 1); + e_parse_state->arena = arena; + e_parse_state->arena_eval_start_pos = arena_pos(arena); + } + arena_pop_to(e_parse_state->arena, e_parse_state->arena_eval_start_pos); + e_parse_state->ctx = ctx; + e_parse_state->parse_cache_slots_count = 1024; + e_parse_state->parse_cache_slots = push_array(e_parse_state->arena, E_ParseCacheSlot, e_parse_state->parse_cache_slots_count); } internal U32 e_parse_ctx_module_idx_from_rdi(RDI_Parsed *rdi) { U32 result = 0; - for(U64 idx = 0; idx < e_parse_ctx->modules_count; idx += 1) + for(U64 idx = 0; idx < e_parse_state->ctx->modules_count; idx += 1) { - if(e_parse_ctx->modules[idx].rdi == rdi) + if(e_parse_state->ctx->modules[idx].rdi == rdi) { result = (U32)idx; break; @@ -649,7 +660,7 @@ internal E_Expr * e_push_expr(Arena *arena, E_ExprKind kind, void *location) { E_Expr *e = push_array(arena, E_Expr, 1); - e->first = e->last = e->next = e->ref = &e_expr_nil; + e->first = e->last = e->next = e->prev = e->ref = e->first_tag = e->last_tag = &e_expr_nil; e->location = location; e->kind = kind; return e; @@ -673,6 +684,12 @@ e_expr_remove_child(E_Expr *parent, E_Expr *child) DLLRemove_NPZ(&e_expr_nil, parent->first, parent->last, child, next, prev); } +internal void +e_expr_push_tag(E_Expr *parent, E_Expr *child) +{ + DLLPushBack_NPZ(&e_expr_nil, parent->first_tag, parent->last_tag, child, next, prev); +} + internal E_Expr * e_expr_ref(Arena *arena, E_Expr *ref) { @@ -681,39 +698,6 @@ e_expr_ref(Arena *arena, E_Expr *ref) return expr; } -internal E_Expr * -e_expr_ref_addr(Arena *arena, E_Expr *rhs) -{ - E_Expr *expr = e_push_expr(arena, E_ExprKind_Address, 0); - E_Expr *rhs_ref = e_expr_ref(arena, rhs); - e_expr_push_child(expr, rhs_ref); - return expr; -} - -internal E_Expr * -e_expr_ref_member_access(Arena *arena, E_Expr *lhs, String8 member_name) -{ - E_Expr *root = e_push_expr(arena, E_ExprKind_MemberAccess, 0); - E_Expr *lhs_ref = e_expr_ref(arena, lhs); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0); - rhs->string = push_str8_copy(arena, member_name); - e_expr_push_child(root, lhs_ref); - e_expr_push_child(root, rhs); - return root; -} - -internal E_Expr * -e_expr_ref_array_index(Arena *arena, E_Expr *lhs, U64 index) -{ - E_Expr *root = e_push_expr(arena, E_ExprKind_ArrayIndex, 0); - E_Expr *lhs_ref = e_expr_ref(arena, lhs); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafU64, 0); - rhs->value.u64 = index; - e_expr_push_child(root, lhs_ref); - e_expr_push_child(root, rhs); - return root; -} - internal E_Expr * e_expr_ref_deref(Arena *arena, E_Expr *rhs) { @@ -736,12 +720,86 @@ e_expr_ref_cast(Arena *arena, E_TypeKey type_key, E_Expr *rhs) } internal E_Expr * -e_expr_ref_bswap(Arena *arena, E_Expr *rhs) +e_expr_copy(Arena *arena, E_Expr *src) { - E_Expr *root = e_push_expr(arena, E_ExprKind_ByteSwap, 0); - E_Expr *rhs_ref = e_expr_ref(arena, rhs); - e_expr_push_child(root, rhs_ref); - return root; + E_Expr *result = &e_expr_nil; + Temp scratch = scratch_begin(&arena, 1); + if(src != &e_expr_nil) + { + typedef struct Task Task; + struct Task + { + Task *next; + E_Expr *dst_parent; + E_Expr *src; + B32 is_ref; + B32 is_tag; + }; + Task start_task = {0, &e_expr_nil, src}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + E_Expr *dst = e_push_expr(arena, t->src->kind, t->src->location); + dst->mode = t->src->mode; + dst->space = t->src->space; + dst->type_key = t->src->type_key; + dst->value = t->src->value; + dst->string = push_str8_copy(arena, t->src->string); + dst->bytecode = push_str8_copy(arena, t->src->bytecode); + dst->qualifier = push_str8_copy(arena, t->src->qualifier); + if(t->dst_parent == &e_expr_nil) + { + result = dst; + } + else if(t->is_ref) + { + t->dst_parent->ref = dst; + } + else if(t->is_tag) + { + e_expr_push_tag(t->dst_parent, dst); + } + else + { + e_expr_push_child(t->dst_parent, dst); + } + if(t->src->ref != &e_expr_nil) + { + Task *task = push_array(scratch.arena, Task, 1); + task->dst_parent = dst; + task->src = t->src->ref; + task->is_ref = 1; + SLLQueuePush(first_task, last_task, task); + } + for(E_Expr *src_child = t->src->first; src_child != &e_expr_nil; src_child = src_child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->dst_parent = dst; + task->src = src_child; + SLLQueuePush(first_task, last_task, task); + } + for(E_Expr *src_child = t->src->first_tag; src_child != &e_expr_nil; src_child = src_child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->dst_parent = dst; + task->src = src_child; + task->is_tag = 1; + SLLQueuePush(first_task, last_task, task); + } + } + } + scratch_end(scratch); + return result; +} + +internal void +e_expr_list_push(Arena *arena, E_ExprList *list, E_Expr *expr) +{ + E_ExprNode *n = push_array(arena, E_ExprNode, 1); + n->v = expr; + SLLQueuePush(list->first, list->last, n); + list->count +=1; } //////////////////////////////// @@ -761,12 +819,20 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) op_info->sep, op_info->post, }; - U64 idx = 0; - for(E_Expr *child = expr->first;; child = child->next, idx += 1) + U64 sep_idx = 0; + for(E_Expr *child = expr->first;; child = child->next) { - if(seps[idx].size != 0) + if(seps[sep_idx].size != 0) { - str8_list_push(arena, out, seps[idx]); + if(sep_idx == 1 && child == &e_expr_nil) + { + sep_idx += 1; + } + str8_list_push(arena, out, seps[sep_idx]); + if(sep_idx == 0) + { + sep_idx += 1; + } } if(child == &e_expr_nil) { @@ -845,9 +911,9 @@ e_leaf_type_from_name(String8 name) { E_TypeKey key = zero_struct; B32 found = 0; - for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1) + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) { - RDI_Parsed *rdi = e_parse_ctx->modules[module_idx].rdi; + RDI_Parsed *rdi = e_parse_state->ctx->modules[module_idx].rdi; RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types); RDI_ParsedNameMap parsed_name_map = {0}; rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); @@ -962,13 +1028,13 @@ e_type_from_expr(E_Expr *expr) case E_ExprKind_Ptr: { E_TypeKey direct_type_key = e_type_from_expr(expr->first); - result = e_type_key_cons_ptr(e_parse_ctx->primary_module->arch, direct_type_key, 0); + result = e_type_key_cons_ptr(e_parse_state->ctx->primary_module->arch, direct_type_key, 1, 0); }break; case E_ExprKind_Array: { E_Expr *child_expr = expr->first; E_TypeKey direct_type_key = e_type_from_expr(child_expr); - result = e_type_key_cons_array(direct_type_key, expr->value.u64); + result = e_type_key_cons_array(direct_type_key, expr->value.u64, 0); }break; } return result; @@ -1001,7 +1067,7 @@ e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) { - E_Parse parse = {0, &e_expr_nil}; + E_Parse parse = {0, &e_expr_nil, &e_expr_nil}; E_Token *token_it = tokens->v; //- rjf: parse unsigned marker @@ -1053,14 +1119,14 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) } // rjf: construct leaf type - parse.expr = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); - parse.expr->type_key = type_key; + parse.exprs.first = parse.exprs.last = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); + parse.exprs.first->type_key = type_key; } } } //- rjf: parse extensions - if(parse.expr != &e_expr_nil) + if(parse.exprs.first != &e_expr_nil) { for(;;) { @@ -1073,9 +1139,9 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) if(str8_match(token_string, str8_lit("*"), 0)) { token_it += 1; - E_Expr *ptee = parse.expr; - parse.expr = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); - e_expr_push_child(parse.expr, ptee); + E_Expr *ptee = parse.exprs.first; + parse.exprs.first = parse.exprs.last = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); + e_expr_push_child(parse.exprs.first, ptee); } else { @@ -1090,1018 +1156,1126 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) } internal E_Parse -e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence) +e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence, U64 max_chain_count) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); E_Token *it = tokens->v; E_Token *it_opl = tokens->v + tokens->count; - E_Parse result = {0, &e_expr_nil}; + E_Parse result = {0, &e_expr_nil, &e_expr_nil}; - //- rjf: parse prefix unaries - typedef struct PrefixUnaryNode PrefixUnaryNode; - struct PrefixUnaryNode + //- rjf: parse chain of expressions + for(U64 chain_count = 0; it < it_opl && chain_count < max_chain_count;) { - PrefixUnaryNode *next; - E_ExprKind kind; - E_Expr *cast_expr; - void *location; - }; - PrefixUnaryNode *first_prefix_unary = 0; - PrefixUnaryNode *last_prefix_unary = 0; - { - for(;it < it_opl;) + //- rjf: exit on symbols callers may be waiting on { - E_Token *start_it = it; E_Token token = e_token_at_it(it, tokens); String8 token_string = str8_substr(text, token.range); - S64 prefix_unary_precedence = 0; - E_ExprKind prefix_unary_kind = 0; - E_Expr *cast_expr = &e_expr_nil; - void *location = 0; - - // rjf: try op table - for EachNonZeroEnumVal(E_ExprKind, k) + if(token.kind == E_TokenKind_Symbol && + (str8_match(token_string, str8_lit(")"), 0) || + str8_match(token_string, str8_lit("]"), 0) || + str8_match(token_string, str8_lit(":"), 0) || + str8_match(token_string, str8_lit("?"), 0))) { - E_OpInfo *op_info = &e_expr_kind_op_info_table[k]; - if(op_info->kind == E_OpKind_UnaryPrefix && str8_match(op_info->pre, token_string, 0)) + break; + } + } + + //- rjf: skip commas, semicolons, etc. + for(;it < it_opl;) + { + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_Symbol && + (str8_match(token_string, str8_lit(","), 0) || + str8_match(token_string, str8_lit(";"), 0))) + { + it += 1; + } + else + { + break; + } + } + + //- rjf: parse prefix unaries + typedef struct PrefixUnaryNode PrefixUnaryNode; + struct PrefixUnaryNode + { + PrefixUnaryNode *next; + E_ExprKind kind; + E_Expr *cast_expr; + void *location; + }; + PrefixUnaryNode *first_prefix_unary = 0; + PrefixUnaryNode *last_prefix_unary = 0; + { + for(;it < it_opl;) + { + E_Token *start_it = it; + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + S64 prefix_unary_precedence = 0; + E_ExprKind prefix_unary_kind = 0; + E_Expr *cast_expr = &e_expr_nil; + void *location = 0; + + // rjf: try op table + for EachNonZeroEnumVal(E_ExprKind, k) + { + E_OpInfo *op_info = &e_expr_kind_op_info_table[k]; + if(op_info->kind == E_OpKind_UnaryPrefix && str8_match(op_info->pre, token_string, 0)) + { + prefix_unary_precedence = op_info->precedence; + prefix_unary_kind = k; + break; + } + } + + // rjf: consume valid op + if(prefix_unary_precedence != 0) + { + location = token_string.str; + it += 1; + } + + // rjf: try casting expression + if(prefix_unary_precedence == 0 && str8_match(token_string, str8_lit("("), 0)) + { + E_Token some_type_identifier_maybe = e_token_at_it(it+1, tokens); + String8 some_type_identifier_maybe_string = str8_substr(text, some_type_identifier_maybe.range); + if(some_type_identifier_maybe.kind == E_TokenKind_Identifier) + { + E_TypeKey type_key = e_leaf_type_from_name(some_type_identifier_maybe_string); + if(!e_type_key_match(type_key, e_type_key_zero()) || str8_match(some_type_identifier_maybe_string, str8_lit("unsigned"), 0)) + { + // rjf: move past open paren + it += 1; + + // rjf: parse type expr + E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); + E_Expr *type = type_parse.exprs.last; + e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); + it = type_parse.last_token; + location = token_string.str; + + // rjf: expect ) + E_Token close_paren_maybe = e_token_at_it(it, tokens); + String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); + if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `)`."); + } + + // rjf: consume ) + else + { + it += 1; + } + + // rjf: fill + prefix_unary_precedence = 2; + prefix_unary_kind = E_ExprKind_Cast; + cast_expr = type; + } + } + } + + // rjf: break if we got no operators + if(prefix_unary_precedence == 0) { - prefix_unary_precedence = op_info->precedence; - prefix_unary_kind = k; break; } - } - - // rjf: consume valid op - if(prefix_unary_precedence != 0) - { - location = token_string.str; - it += 1; - } - - // rjf: try casting expression - if(prefix_unary_precedence == 0 && str8_match(token_string, str8_lit("("), 0)) - { - E_Token some_type_identifier_maybe = e_token_at_it(it+1, tokens); - String8 some_type_identifier_maybe_string = str8_substr(text, some_type_identifier_maybe.range); - if(some_type_identifier_maybe.kind == E_TokenKind_Identifier) + + // rjf: break if the token node iterator has not changed + if(it == start_it) { - E_TypeKey type_key = e_leaf_type_from_name(some_type_identifier_maybe_string); - if(!e_type_key_match(type_key, e_type_key_zero()) || str8_match(some_type_identifier_maybe_string, str8_lit("unsigned"), 0)) - { - // rjf: move past open paren - it += 1; - - // rjf: parse type expr - E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); - E_Expr *type = type_parse.expr; - e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); - it = type_parse.last_token; - location = token_string.str; - - // rjf: expect ) - E_Token close_paren_maybe = e_token_at_it(it, tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `)`."); - } - - // rjf: consume ) - else - { - it += 1; - } - - // rjf: fill - prefix_unary_precedence = 2; - prefix_unary_kind = E_ExprKind_Cast; - cast_expr = type; - } + break; + } + + // rjf: push prefix unary if we got one + { + PrefixUnaryNode *op_n = push_array(scratch.arena, PrefixUnaryNode, 1); + op_n->kind = prefix_unary_kind; + op_n->cast_expr = cast_expr; + op_n->location = location; + SLLQueuePushFront(first_prefix_unary, last_prefix_unary, op_n); + } + } + } + + //- rjf: parse atom + E_Expr *atom = &e_expr_nil; + String8 atom_implicit_member_name = {0}; + if(it < it_opl) + { + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + + //- rjf: gather resolution qualifier + String8 resolution_qualifier = {0}; + if(token.kind == E_TokenKind_Identifier) + { + E_Token next_token = e_token_at_it(it+1, tokens); + String8 next_token_string = str8_substr(text, next_token.range); + if(next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) + { + it += 2; + resolution_qualifier = token_string; + token = e_token_at_it(it, tokens); + token_string = str8_substr(text, token.range); } } - // rjf: break if we got no operators - if(prefix_unary_precedence == 0) - { - break; - } - - // rjf: break if the token node iterator has not changed - if(it == start_it) - { - break; - } - - // rjf: push prefix unary if we got one - { - PrefixUnaryNode *op_n = push_array(scratch.arena, PrefixUnaryNode, 1); - op_n->kind = prefix_unary_kind; - op_n->cast_expr = cast_expr; - op_n->location = location; - SLLQueuePushFront(first_prefix_unary, last_prefix_unary, op_n); - } - } - } - - //- rjf: parse atom - E_Expr *atom = &e_expr_nil; - String8 atom_implicit_member_name = {0}; - if(it < it_opl) - { - E_Token token = e_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - - //- rjf: gather resolution qualifier - String8 resolution_qualifier = {0}; - if(token.kind == E_TokenKind_Identifier) - { - E_Token next_token = e_token_at_it(it+1, tokens); - String8 next_token_string = str8_substr(text, next_token.range); - if(next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) - { - it += 2; - resolution_qualifier = token_string; - token = e_token_at_it(it, tokens); - token_string = str8_substr(text, token.range); - } - } - - //- rjf: descent to nested expression - if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) - { - // rjf: skip ( - it += 1; - - // rjf: parse () contents - E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence); - e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.expr; - it = nested_parse.last_token; - - // rjf: expect ) - E_Token close_paren_maybe = e_token_at_it(it, tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `)`."); - } - - // rjf: consume ) - else + //- rjf: descent to nested expression + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) { + // rjf: skip ( it += 1; - } - } - - //- rjf: descent to assembly-style dereference sub-expression - else if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) - { - // rjf: skip [ - it += 1; - - // rjf: parse [] contents - E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence); - e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.expr; - it = nested_parse.last_token; - - // rjf: build cast-to-U64*, and dereference operators - if(nested_parse.expr == &e_expr_nil) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression following `[`."); - } - else - { - E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); - type->type_key = e_type_key_cons_ptr(e_parse_ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 0); - E_Expr *casted = atom; - E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token_string.str); - e_expr_push_child(cast, type); - e_expr_push_child(cast, casted); - atom = e_push_expr(arena, E_ExprKind_Deref, token_string.str); - e_expr_push_child(atom, cast); - } - - // rjf: expect ] - E_Token close_paren_maybe = e_token_at_it(it, tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit("]"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `]`."); - } - - // rjf: consume ) - else - { - it += 1; - } - } - - //- rjf: leaf (identifier, literal) - else if(token.kind != E_TokenKind_Symbol) - { - switch(token.kind) - { - //- rjf: identifier => name resolution - default: - case E_TokenKind_Identifier: + + // rjf: parse () contents + E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence, 1); + e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); + atom = nested_parse.exprs.last; + it = nested_parse.last_token; + + // rjf: expect ) + E_Token close_paren_maybe = e_token_at_it(it, tokens); + String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); + if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { - B32 mapped_identifier = 0; - B32 identifier_is_constant_value = 0; - B32 identifier_type_is_possibly_dynamically_overridden = 0; - B32 identifier_looks_like_type_expr = 0; - RDI_LocationKind loc_kind = RDI_LocationKind_NULL; - RDI_LocationReg loc_reg = {0}; - RDI_LocationRegPlusU16 loc_reg_u16 = {0}; - String8 loc_bytecode = {0}; - U64 constant_value = 0; - REGS_RegCode reg_code = 0; - REGS_AliasCode alias_code = 0; - E_TypeKey type_key = zero_struct; - String8 local_lookup_string = token_string; - E_Space space = {0}; - Arch arch = Arch_Null; - - //- rjf: identifiers surrounded by ``s should have those `s stripped - if(local_lookup_string.size >= 2 && - local_lookup_string.str[0] == '`' && - local_lookup_string.str[local_lookup_string.size-1] == '`') + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `)`."); + } + + // rjf: consume ) + else + { + it += 1; + } + } + + //- rjf: descent to assembly-style dereference sub-expression + else if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) + { + // rjf: skip [ + it += 1; + + // rjf: parse [] contents + E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence, 1); + e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); + atom = nested_parse.exprs.last; + it = nested_parse.last_token; + + // rjf: build cast-to-U64*, and dereference operators + if(nested_parse.exprs.last == &e_expr_nil) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression following `[`."); + } + else + { + E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); + type->type_key = e_type_key_cons_ptr(e_parse_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0); + E_Expr *casted = atom; + E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token_string.str); + e_expr_push_child(cast, type); + e_expr_push_child(cast, casted); + atom = e_push_expr(arena, E_ExprKind_Deref, token_string.str); + e_expr_push_child(atom, cast); + } + + // rjf: expect ] + E_Token close_paren_maybe = e_token_at_it(it, tokens); + String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); + if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit("]"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `]`."); + } + + // rjf: consume ) + else + { + it += 1; + } + } + + //- rjf: leaf (identifier, literal) + else if(token.kind != E_TokenKind_Symbol) + { + switch(token.kind) + { + //- rjf: identifier => name resolution + default: + case E_TokenKind_Identifier: { - token_string = local_lookup_string = str8_substr(local_lookup_string, r1u64(1, local_lookup_string.size-1)); - } - - //- rjf: form namespaceified fallback versions of this lookup string - String8List namespaceified_token_strings = {0}; - { - E_Module *module = e_parse_ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_ctx->ip_voff); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - U64 proc_idx = scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); - U64 name_size = 0; - U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 containing_procedure_name = str8(name_ptr, name_size); - U64 last_past_scope_resolution_pos = 0; - for(;;) + B32 mapped_identifier = 0; + B32 identifier_is_constant_value = 0; + B32 identifier_type_is_possibly_dynamically_overridden = 0; + B32 identifier_looks_like_type_expr = 0; + RDI_LocationKind loc_kind = RDI_LocationKind_NULL; + RDI_LocationReg loc_reg = {0}; + RDI_LocationRegPlusU16 loc_reg_u16 = {0}; + String8 loc_bytecode = {0}; + U64 constant_value = 0; + REGS_RegCode reg_code = 0; + REGS_AliasCode alias_code = 0; + E_TypeKey type_key = zero_struct; + String8 local_lookup_string = token_string; + E_Space space = {0}; + Arch arch = Arch_Null; + + //- rjf: identifiers surrounded by ``s should have those `s stripped + if(local_lookup_string.size >= 2 && + local_lookup_string.str[0] == '`' && + local_lookup_string.str[local_lookup_string.size-1] == '`') { - U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; - U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; - U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); - if(past_next_scope_resolution_pos >= containing_procedure_name.size) - { - break; - } - String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); - String8 namespaceified_token_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, token_string); - str8_list_push_front(scratch.arena, &namespaceified_token_strings, namespaceified_token_string); - last_past_scope_resolution_pos = past_next_scope_resolution_pos; + token_string = local_lookup_string = str8_substr(local_lookup_string, r1u64(1, local_lookup_string.size-1)); } - } - - //- rjf: try members - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("member"), 0))) ProfScope("try to map name as member") - { - U64 data_member_num = e_num_from_string(e_parse_ctx->member_map, token_string); - if(data_member_num != 0) + + //- rjf: form namespaceified fallback versions of this lookup string + String8List namespaceified_token_strings = {0}; { - atom_implicit_member_name = token_string; - local_lookup_string = str8_lit("this"); - } - } - - //- rjf: try locals - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("local"), 0))) ProfScope("try to map name as local") - { - E_Module *module = e_parse_ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - U64 local_num = e_num_from_string(e_parse_ctx->locals_map, local_lookup_string); - if(local_num != 0) - { - identifier_type_is_possibly_dynamically_overridden = 1; - RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_num-1); - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local_var->type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_ctx->modules)); - - // rjf: grab location info - for(U32 loc_block_idx = local_var->location_first; - loc_block_idx < local_var->location_opl; - loc_block_idx += 1) + E_Module *module = e_parse_state->ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_state->ctx->ip_voff); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + U64 proc_idx = scope->proc_idx; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); + U64 name_size = 0; + U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); + String8 containing_procedure_name = str8(name_ptr, name_size); + U64 last_past_scope_resolution_pos = 0; + for(;;) { - RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); - if(block->scope_off_first <= e_parse_ctx->ip_voff && e_parse_ctx->ip_voff < block->scope_off_opl) + U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; + U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; + U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); + if(past_next_scope_resolution_pos >= containing_procedure_name.size) { - mapped_identifier = 1; - space = module->space; - arch = module->arch; - U64 all_location_data_size = 0; - U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); - loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); - switch(loc_kind) + break; + } + String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); + String8 namespaceified_token_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, token_string); + str8_list_push_front(scratch.arena, &namespaceified_token_strings, namespaceified_token_string); + last_past_scope_resolution_pos = past_next_scope_resolution_pos; + } + } + + //- rjf: try members + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("member"), 0))) ProfScope("try to map name as member") + { + U64 data_member_num = e_num_from_string(e_parse_state->ctx->member_map, token_string); + if(data_member_num != 0) + { + atom_implicit_member_name = token_string; + local_lookup_string = str8_lit("this"); + } + } + + //- rjf: try locals + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("local"), 0))) ProfScope("try to map name as local") + { + E_Module *module = e_parse_state->ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, local_lookup_string); + if(local_num != 0) + { + identifier_type_is_possibly_dynamically_overridden = 1; + RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_num-1); + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local_var->type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_state->ctx->modules)); + + // rjf: grab location info + for(U32 loc_block_idx = local_var->location_first; + loc_block_idx < local_var->location_opl; + loc_block_idx += 1) + { + RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); + if(block->scope_off_first <= e_parse_state->ctx->ip_voff && e_parse_state->ctx->ip_voff < block->scope_off_opl) { - default:{mapped_identifier = 0;}break; - case RDI_LocationKind_ValBytecodeStream: goto bytecode_stream; - case RDI_LocationKind_AddrBytecodeStream: goto bytecode_stream; - bytecode_stream:; + mapped_identifier = 1; + space = module->space; + arch = module->arch; + U64 all_location_data_size = 0; + U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); + loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); + switch(loc_kind) { - U64 bytecode_size = 0; - U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); - U64 off_opl = all_location_data_size; - for(U64 off = off_first, next_off = off_opl; - off < all_location_data_size; - off = next_off) + default:{mapped_identifier = 0;}break; + case RDI_LocationKind_ValBytecodeStream: goto bytecode_stream; + case RDI_LocationKind_AddrBytecodeStream: goto bytecode_stream; + bytecode_stream:; { - next_off = off_opl; - U8 op = all_location_data[off]; - if(op == 0) + U64 bytecode_size = 0; + U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); + U64 off_opl = all_location_data_size; + for(U64 off = off_first, next_off = off_opl; + off < all_location_data_size; + off = next_off) { - break; + next_off = off_opl; + U8 op = all_location_data[off]; + if(op == 0) + { + break; + } + U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; + U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); + bytecode_size += (1 + p_size); + next_off = (off + 1 + p_size); } - U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; - U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - bytecode_size += (1 + p_size); - next_off = (off + 1 + p_size); - } - loc_bytecode = str8(all_location_data + off_first, bytecode_size); - }break; - case RDI_LocationKind_AddrRegPlusU16: - case RDI_LocationKind_AddrAddrRegPlusU16: - { - MemoryCopy(&loc_reg_u16, (all_location_data + block->location_data_off), sizeof(loc_reg_u16)); - }break; - case RDI_LocationKind_ValReg: - { - MemoryCopy(&loc_reg, (all_location_data + block->location_data_off), sizeof(loc_reg)); - }break; + loc_bytecode = str8(all_location_data + off_first, bytecode_size); + }break; + case RDI_LocationKind_AddrRegPlusU16: + case RDI_LocationKind_AddrAddrRegPlusU16: + { + MemoryCopy(&loc_reg_u16, (all_location_data + block->location_data_off), sizeof(loc_reg_u16)); + }break; + case RDI_LocationKind_ValReg: + { + MemoryCopy(&loc_reg, (all_location_data + block->location_data_off), sizeof(loc_reg)); + }break; + } } } } } - } - - //- rjf: try registers - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register") - { - U64 reg_num = e_num_from_string(e_parse_ctx->regs_map, token_string); - if(reg_num != 0) - { - reg_code = reg_num; - type_key = e_type_key_reg(e_parse_ctx->primary_module->arch, reg_code); - mapped_identifier = 1; - space = e_parse_ctx->ip_thread_space; - arch = e_parse_ctx->primary_module->arch; - } - } - - //- rjf: try register aliases - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register alias") - { - U64 alias_num = e_num_from_string(e_parse_ctx->reg_alias_map, token_string); - if(alias_num != 0) - { - alias_code = (REGS_AliasCode)alias_num; - type_key = e_type_key_reg_alias(e_parse_ctx->primary_module->arch, alias_code); - mapped_identifier = 1; - space = e_parse_ctx->ip_thread_space; - arch = e_parse_ctx->primary_module->arch; - } - } - - //- rjf: try global variables - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("global"), 0))) ProfScope("try to map name as global variable") - { - for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - // NOTE(rjf): apparently, PDBs can be produced such that they - // also keep stale *GLOBAL VARIABLE SYMBOLS* around too. I - // don't know of a magic hash table fixup path in PDBs, so - // in this case, I'm going to prefer the latest-added global. - U32 match_idx = matches[matches_count-1]; - RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = global_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try thread variables - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("thread_variable"), 0))) ProfScope("try to map name as thread variable") - { - for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = thread_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try procedures - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("procedure"), 0))) ProfScope("try to map name as procedure") - { - for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - loc_kind = RDI_LocationKind_ValBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try types - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("type"), 0))) ProfScope("try to map name as type") - { - type_key = e_leaf_type_from_name(token_string); - if(!e_type_key_match(e_type_key_zero(), type_key)) - { - mapped_identifier = 1; - identifier_looks_like_type_expr = 1; - MemoryZeroStruct(&space); - arch = e_parse_ctx->primary_module->arch; - } - } - - //- rjf: try basic constants - if(mapped_identifier == 0 && str8_match(token_string, str8_lit("true"), 0)) - { - mapped_identifier = 1; - identifier_is_constant_value = 1; - type_key = e_type_key_basic(E_TypeKind_Bool); - constant_value = 1; - } - if(mapped_identifier == 0 && str8_match(token_string, str8_lit("false"), 0)) - { - mapped_identifier = 1; - identifier_is_constant_value = 1; - type_key = e_type_key_basic(E_TypeKind_Bool); - constant_value = 0; - } - - //- rjf: attach on map - if(mapped_identifier != 0) ProfScope("attach on map") - { - it += 1; - // rjf: build atom - switch(loc_kind) + //- rjf: try registers + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register") { - default: + U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, token_string); + if(reg_num != 0) { - if(identifier_is_constant_value) + reg_code = reg_num; + type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_code); + mapped_identifier = 1; + space = e_parse_state->ctx->ip_thread_space; + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try register aliases + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register alias") + { + U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, token_string); + if(alias_num != 0) + { + alias_code = (REGS_AliasCode)alias_num; + type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_code); + mapped_identifier = 1; + space = e_parse_state->ctx->ip_thread_space; + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try global variables + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("global"), 0))) ProfScope("try to map name as global variable") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) { - atom = e_push_expr(arena, E_ExprKind_LeafBool, token_string.str); - atom->value.u64 = constant_value; - atom->type_key = type_key; + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); } - else if(identifier_looks_like_type_expr) + if(matches_count != 0) { - E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it-1, it_opl); - E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); - E_Expr *type = type_parse.expr; - e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); - it = type_parse.last_token; - atom = type; - } - else if(reg_code != 0) - { - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_ctx->primary_module->arch)[reg_code]; + // NOTE(rjf): apparently, PDBs can be produced such that they + // also keep stale *GLOBAL VARIABLE SYMBOLS* around too. I + // don't know of a magic hash table fixup path in PDBs, so + // in this case, I'm going to prefer the latest-added global. + U32 match_idx = matches[matches_count-1]; + RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); + loc_kind = RDI_LocationKind_AddrBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = global_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try thread variables + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("thread_variable"), 0))) ProfScope("try to map name as thread variable") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[0]; + RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); + loc_kind = RDI_LocationKind_AddrBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = thread_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try procedures + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("procedure"), 0))) ProfScope("try to map name as procedure") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[0]; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + loc_kind = RDI_LocationKind_ValBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try types + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("type"), 0))) ProfScope("try to map name as type") + { + type_key = e_leaf_type_from_name(token_string); + if(!e_type_key_match(e_type_key_zero(), type_key)) + { + mapped_identifier = 1; + identifier_looks_like_type_expr = 1; + MemoryZeroStruct(&space); + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try basic constants + if(mapped_identifier == 0 && str8_match(token_string, str8_lit("true"), 0)) + { + mapped_identifier = 1; + identifier_is_constant_value = 1; + type_key = e_type_key_basic(E_TypeKind_Bool); + constant_value = 1; + } + if(mapped_identifier == 0 && str8_match(token_string, str8_lit("false"), 0)) + { + mapped_identifier = 1; + identifier_is_constant_value = 1; + type_key = e_type_key_basic(E_TypeKind_Bool); + constant_value = 0; + } + + //- rjf: attach on map + if(mapped_identifier != 0) ProfScope("attach on map") + { + it += 1; + + // rjf: build atom + switch(loc_kind) + { + default: + { + if(identifier_is_constant_value) + { + atom = e_push_expr(arena, E_ExprKind_LeafBool, token_string.str); + atom->value.u64 = constant_value; + atom->type_key = type_key; + } + else if(identifier_looks_like_type_expr) + { + E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it-1, it_opl); + E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); + E_Expr *type = type_parse.exprs.last; + e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); + it = type_parse.last_token; + atom = type; + } + else if(reg_code != 0) + { + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_code]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + } + else if(alias_code != 0) + { + REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_code]; + REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_slice.code]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MissingInfo, token_string.str, "Missing location information for `%S`.", token_string); + } + }break; + case RDI_LocationKind_AddrBytecodeStream: + { + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = loc_bytecode; + }break; + case RDI_LocationKind_ValBytecodeStream: + { + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Value; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = loc_bytecode; + }break; + case RDI_LocationKind_AddrRegPlusU16: + { + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); atom->mode = E_Mode_Offset; atom->space = space; atom->type_key = type_key; atom->string = token_string; atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - } - else if(alias_code != 0) + }break; + case RDI_LocationKind_AddrAddrRegPlusU16: { - REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_ctx->primary_module->arch)[alias_code]; - REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_ctx->primary_module->arch)[alias_slice.code]; E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); atom->mode = E_Mode_Offset; atom->space = space; atom->type_key = type_key; atom->string = token_string; atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - } - else + }break; + case RDI_LocationKind_ValReg: { - e_msgf(arena, &result.msgs, E_MsgKind_MissingInfo, token_string.str, "Missing location information for `%S`.", token_string); - } - }break; - case RDI_LocationKind_AddrBytecodeStream: + REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc_reg.reg_code); + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; + E_OpList oplist = {0}; + U64 byte_size = (U64)reg_rng.byte_size; + U64 byte_pos = 0; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg.reg_code, byte_size, byte_pos); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Value; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + }break; + } + + // rjf: implicit local lookup -> attach member access node + if(atom_implicit_member_name.size != 0 && atom != &e_expr_nil) { - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = loc_bytecode; - }break; - case RDI_LocationKind_ValBytecodeStream: - { - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Value; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = loc_bytecode; - }break; - case RDI_LocationKind_AddrRegPlusU16: - { - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - case RDI_LocationKind_AddrAddrRegPlusU16: - { - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - case RDI_LocationKind_ValReg: - { - REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc_reg.reg_code); - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; - E_OpList oplist = {0}; - U64 byte_size = (U64)reg_rng.byte_size; - U64 byte_pos = 0; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg.reg_code, byte_size, byte_pos); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Value; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; + E_Expr *member_container = atom; + E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, atom_implicit_member_name.str); + member_expr->string = atom_implicit_member_name; + atom = e_push_expr(arena, E_ExprKind_MemberAccess, atom_implicit_member_name.str); + atom->space = space; + e_expr_push_child(atom, member_container); + e_expr_push_child(atom, member_expr); + } } - // rjf: implicit local lookup -> attach member access node - if(atom_implicit_member_name.size != 0 && atom != &e_expr_nil) + //- rjf: map failure -> attach as leaf identifier, to be resolved later + if(!mapped_identifier) { - E_Expr *member_container = atom; - E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, atom_implicit_member_name.str); - member_expr->string = atom_implicit_member_name; - atom = e_push_expr(arena, E_ExprKind_MemberAccess, atom_implicit_member_name.str); - atom->space = space; - e_expr_push_child(atom, member_container); - e_expr_push_child(atom, member_expr); + atom = e_push_expr(arena, E_ExprKind_LeafIdent, token_string.str); + atom->string = token_string; + it += 1; } - } + }break; - //- rjf: map failure -> attach as leaf identifier, to be resolved later - if(!mapped_identifier) + //- rjf: numeric => directly extract value + case E_TokenKind_Numeric: { - atom = e_push_expr(arena, E_ExprKind_LeafIdent, token_string.str); - atom->string = token_string; + U64 dot_pos = str8_find_needle(token_string, 0, str8_lit("."), 0); it += 1; - } - }break; - - //- rjf: numeric => directly extract value - case E_TokenKind_Numeric: - { - U64 dot_pos = str8_find_needle(token_string, 0, str8_lit("."), 0); - it += 1; - - // rjf: no . => integral - if(dot_pos == token_string.size) - { - U64 val = 0; - try_u64_from_str8_c_rules(token_string, &val); - atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); - atom->value.u64 = val; - break; - } - - // rjf: presence of . => double or float - if(dot_pos < token_string.size) - { - F64 val = f64_from_str8(token_string); - U64 f_pos = str8_find_needle(token_string, 0, str8_lit("f"), StringMatchFlag_CaseInsensitive); - // rjf: presence of f after . => f32 - if(f_pos < token_string.size) + // rjf: no . => integral + if(dot_pos == token_string.size) { - atom = e_push_expr(arena, E_ExprKind_LeafF32, token_string.str); - atom->value.f32 = val; + U64 val = 0; + try_u64_from_str8_c_rules(token_string, &val); + atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); + atom->value.u64 = val; + break; } - // rjf: no f => f64 + // rjf: presence of . => double or float + if(dot_pos < token_string.size) + { + F64 val = f64_from_str8(token_string); + U64 f_pos = str8_find_needle(token_string, 0, str8_lit("f"), StringMatchFlag_CaseInsensitive); + + // rjf: presence of f after . => f32 + if(f_pos < token_string.size) + { + atom = e_push_expr(arena, E_ExprKind_LeafF32, token_string.str); + atom->value.f32 = val; + } + + // rjf: no f => f64 + else + { + atom = e_push_expr(arena, E_ExprKind_LeafF64, token_string.str); + atom->value.f64 = val; + } + } + }break; + + //- rjf: char => extract char value + case E_TokenKind_CharLiteral: + { + it += 1; + if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') + { + String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); + String8 char_literal_raw = raw_from_escaped_str8(scratch.arena, char_literal_escaped); + U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; + atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); + atom->value.u64 = (U64)char_val; + } else { - atom = e_push_expr(arena, E_ExprKind_LeafF64, token_string.str); - atom->value.f64 = val; + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Malformed character literal."); + } + }break; + + //- rjf: string => leaf string literal, or file path + case E_TokenKind_StringLiteral: + { + if(str8_match(resolution_qualifier, str8_lit("file"), 0) || + str8_match(resolution_qualifier, str8_lit("folder"), 0)) + { + String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); + String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); + atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token_string.str); + atom->string = string_value_raw; + it += 1; + } + else + { + String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); + String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); + atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token_string.str); + atom->string = string_value_raw; + it += 1; + } + }break; + } + + //- rjf: upgrade atom w/ qualifier + if(atom != &e_expr_nil && resolution_qualifier.size != 0) + { + atom->qualifier = resolution_qualifier; + } + } + } + + //- rjf: upgrade atom w/ postfix unaries + if(atom != &e_expr_nil) for(;it < it_opl;) + { + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + B32 is_postfix_unary = 0; + + // rjf: dot/arrow operator + if(token.kind == E_TokenKind_Symbol && + (str8_match(token_string, str8_lit("."), 0) || + str8_match(token_string, str8_lit("->"), 0))) + { + is_postfix_unary = 1; + + // rjf: advance past operator + it += 1; + + // rjf: expect member name + String8 member_name = {0}; + B32 good_member_name = 0; + { + E_Token member_name_maybe = e_token_at_it(it, tokens); + String8 member_name_maybe_string = str8_substr(text, member_name_maybe.range); + if(member_name_maybe.kind != E_TokenKind_Identifier) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected member name after `%S`.", token_string); + } + else + { + member_name = member_name_maybe_string; + good_member_name = 1; + } + } + + // rjf: produce lookup member expr + if(good_member_name) + { + E_Expr *member_container = atom; + E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, member_name.str); + member_expr->string = member_name; + atom = e_push_expr(arena, E_ExprKind_MemberAccess, token_string.str); + e_expr_push_child(atom, member_container); + e_expr_push_child(atom, member_expr); + } + + // rjf: increment past good member names + if(good_member_name) + { + it += 1; + } + } + + // rjf: array index + if(token.kind == E_TokenKind_Symbol && + str8_match(token_string, str8_lit("["), 0)) + { + is_postfix_unary = 1; + + // rjf: advance past [ + it += 1; + + // rjf: parse indexing expression + E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse idx_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence, 1); + e_msg_list_concat_in_place(&result.msgs, &idx_expr_parse.msgs); + it = idx_expr_parse.last_token; + + // rjf: valid indexing expression => produce index expr + if(idx_expr_parse.exprs.last != &e_expr_nil) + { + E_Expr *array_expr = atom; + E_Expr *index_expr = idx_expr_parse.exprs.last; + atom = e_push_expr(arena, E_ExprKind_ArrayIndex, token_string.str); + e_expr_push_child(atom, array_expr); + e_expr_push_child(atom, index_expr); + } + + // rjf: expect ] + { + E_Token close_brace_maybe = e_token_at_it(it, tokens); + String8 close_brace_maybe_string = str8_substr(text, close_brace_maybe.range); + if(close_brace_maybe.kind != E_TokenKind_Symbol || !str8_match(close_brace_maybe_string, str8_lit("]"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Unclosed `[`."); + } + else + { + it += 1; + } + } + } + + // rjf: calls + if(token.kind == E_TokenKind_Symbol && + str8_match(token_string, str8_lit("("), 0)) + { + // rjf: skip ( + it += 1; + + // rjf: parse all argument expressions + E_Expr *callee_expr = atom; + E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str); + call_expr->string = callee_expr->string; + e_expr_push_child(call_expr, callee_expr); + E_TokenArray args_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse args_parse = e_parse_expr_from_text_tokens__prec(arena, text, &args_parse_tokens, e_max_precedence, max_U64); + e_msg_list_concat_in_place(&result.msgs, &args_parse.msgs); + it = args_parse.last_token; + if(args_parse.exprs.first != &e_expr_nil) + { + call_expr->last->next = args_parse.exprs.first; + args_parse.exprs.first->prev = call_expr->last; + call_expr->last = args_parse.exprs.last; + } + atom = call_expr; + + // rjf: expect ) + { + E_Token close_paren_maybe = e_token_at_it(it, tokens); + String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); + if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Unclosed `(`."); + } + else + { + it += 1; + } + } + } + + // rjf: quit if this doesn't look like any patterns of postfix unary we know + if(!is_postfix_unary) + { + break; + } + } + + //- rjf: upgrade atom w/ previously parsed prefix unaries + if(atom == &e_expr_nil && first_prefix_unary != 0 && first_prefix_unary->cast_expr != &e_expr_nil) + { + atom = first_prefix_unary->cast_expr; + for(PrefixUnaryNode *prefix_unary = first_prefix_unary->next; + prefix_unary != 0; + prefix_unary = prefix_unary->next) + { + E_Expr *rhs = atom; + atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); + if(prefix_unary->cast_expr != &e_expr_nil) + { + e_expr_push_child(atom, prefix_unary->cast_expr); + } + e_expr_push_child(atom, rhs); + } + } + else if(atom == &e_expr_nil && first_prefix_unary != 0) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, last_prefix_unary->location, "Missing expression."); + } + else + { + for(PrefixUnaryNode *prefix_unary = first_prefix_unary; + prefix_unary != 0; + prefix_unary = prefix_unary->next) + { + E_Expr *rhs = atom; + atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); + if(prefix_unary->cast_expr != &e_expr_nil) + { + e_expr_push_child(atom, prefix_unary->cast_expr); + } + e_expr_push_child(atom, rhs); + } + } + + //- rjf: parse complex operators + if(atom != &e_expr_nil) for(;it < it_opl;) + { + E_Token *start_it = it; + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + + //- rjf: parse binaries + { + // rjf: first try to find a matching binary operator + S64 binary_precedence = 0; + E_ExprKind binary_kind = 0; + for EachNonZeroEnumVal(E_ExprKind, k) + { + E_OpInfo *op_info = &e_expr_kind_op_info_table[k]; + if(op_info->kind == E_OpKind_Binary && str8_match(op_info->sep, token_string, 0)) + { + binary_precedence = op_info->precedence; + binary_kind = k; + break; + } + } + + // rjf: if we got a valid binary precedence, and it's not to be handled by + // a caller, then we need to parse the right-hand-side with a tighter + // precedence + if(binary_precedence != 0 && binary_precedence <= max_precedence) + { + E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it+1, it_opl); + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, binary_precedence-1, 1); + e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); + E_Expr *rhs = rhs_expr_parse.exprs.last; + it = rhs_expr_parse.last_token; + if(rhs == &e_expr_nil) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing right-hand-side of `%S`.", token_string); + } + else + { + E_Expr *lhs = atom; + atom = e_push_expr(arena, binary_kind, token_string.str); + e_expr_push_child(atom, lhs); + e_expr_push_child(atom, rhs); + } + } + } + + //- rjf: parse ternaries + { + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("?"), 0) && 13 <= max_precedence) + { + it += 1; + + // rjf: parse middle expression + E_TokenArray middle_expr_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &middle_expr_tokens, e_max_precedence, 1); + it = middle_expr_parse.last_token; + E_Expr *middle_expr = middle_expr_parse.exprs.last; + e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); + if(middle_expr_parse.exprs.last == &e_expr_nil) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression after `?`."); + } + + // rjf: expect : + B32 got_colon = 0; + E_Token colon_token = zero_struct; + String8 colon_token_string = {0}; + { + E_Token colon_token_maybe = e_token_at_it(it, tokens); + String8 colon_token_maybe_string = str8_substr(text, colon_token_maybe.range); + if(colon_token_maybe.kind != E_TokenKind_Symbol || !str8_match(colon_token_maybe_string, str8_lit(":"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected `:` after `?`."); + } + else + { + got_colon = 1; + colon_token = colon_token_maybe; + colon_token_string = colon_token_maybe_string; + it += 1; } } - }break; - - //- rjf: char => extract char value - case E_TokenKind_CharLiteral: + + // rjf: parse rhs + E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, e_max_precedence, 1); + if(got_colon) + { + it = rhs_expr_parse.last_token; + e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); + if(rhs_expr_parse.exprs.last == &e_expr_nil) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, colon_token_string.str, "Expected expression after `:`."); + } + } + + // rjf: build ternary + if(atom != &e_expr_nil && + middle_expr_parse.exprs.last != &e_expr_nil && + rhs_expr_parse.exprs.last != &e_expr_nil) + { + E_Expr *lhs = atom; + E_Expr *mhs = middle_expr_parse.exprs.last; + E_Expr *rhs = rhs_expr_parse.exprs.last; + atom = e_push_expr(arena, E_ExprKind_Ternary, token_string.str); + e_expr_push_child(atom, lhs); + e_expr_push_child(atom, mhs); + e_expr_push_child(atom, rhs); + } + } + } + + //- rjf: parse tags + { + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("=>"), 0)) { it += 1; - if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') + E_TokenArray tags_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse tags_parse = e_parse_expr_from_text_tokens__prec(arena, text, &tags_tokens, e_max_precedence, max_U64); + e_msg_list_concat_in_place(&result.msgs, &tags_parse.msgs); + it = tags_parse.last_token; + for(E_Expr *tag = tags_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) { - String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); - String8 char_literal_raw = raw_from_escaped_str8(scratch.arena, char_literal_escaped); - U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; - atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); - atom->value.u64 = (U64)char_val; + next = tag->next; + e_expr_push_tag(atom, tag); } - else - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Malformed character literal."); - } - }break; - - // rjf: string => leaf string literal, or file path - case E_TokenKind_StringLiteral: - { - if(str8_match(resolution_qualifier, str8_lit("file"), 0)) - { - String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); - String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token_string.str); - atom->string = string_value_raw; - it += 1; - } - else - { - String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); - String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token_string.str); - atom->string = string_value_raw; - it += 1; - } - }break; - - } - } - } - - //- rjf: upgrade atom w/ postfix unaries - if(atom != &e_expr_nil) for(;it < it_opl;) - { - E_Token token = e_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - B32 is_postfix_unary = 0; - - // rjf: dot/arrow operator - if(token.kind == E_TokenKind_Symbol && - (str8_match(token_string, str8_lit("."), 0) || - str8_match(token_string, str8_lit("->"), 0))) - { - is_postfix_unary = 1; - - // rjf: advance past operator - it += 1; - - // rjf: expect member name - String8 member_name = {0}; - B32 good_member_name = 0; - { - E_Token member_name_maybe = e_token_at_it(it, tokens); - String8 member_name_maybe_string = str8_substr(text, member_name_maybe.range); - if(member_name_maybe.kind != E_TokenKind_Identifier) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected member name after `%S`.", token_string); - } - else - { - member_name = member_name_maybe_string; - good_member_name = 1; } } - // rjf: produce lookup member expr - if(good_member_name) + // rjf: if we parsed nothing successfully, we're done + if(it == start_it) { - E_Expr *member_container = atom; - E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, member_name.str); - member_expr->string = member_name; - atom = e_push_expr(arena, E_ExprKind_MemberAccess, token_string.str); - e_expr_push_child(atom, member_container); - e_expr_push_child(atom, member_expr); - } - - // rjf: increment past good member names - if(good_member_name) - { - it += 1; + break; } } - // rjf: array index - if(token.kind == E_TokenKind_Symbol && - str8_match(token_string, str8_lit("["), 0)) + //- rjf: store parsed atom to expression chain - if we didn't get an expression, break + if(atom != &e_expr_nil) { - is_postfix_unary = 1; - - // rjf: advance past [ - it += 1; - - // rjf: parse indexing expression - E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse idx_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence); - e_msg_list_concat_in_place(&result.msgs, &idx_expr_parse.msgs); - it = idx_expr_parse.last_token; - - // rjf: valid indexing expression => produce index expr - if(idx_expr_parse.expr != &e_expr_nil) - { - E_Expr *array_expr = atom; - E_Expr *index_expr = idx_expr_parse.expr; - atom = e_push_expr(arena, E_ExprKind_ArrayIndex, token_string.str); - e_expr_push_child(atom, array_expr); - e_expr_push_child(atom, index_expr); - } - - // rjf: expect ] - { - E_Token close_brace_maybe = e_token_at_it(it, tokens); - String8 close_brace_maybe_string = str8_substr(text, close_brace_maybe.range); - if(close_brace_maybe.kind != E_TokenKind_Symbol || !str8_match(close_brace_maybe_string, str8_lit("]"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Unclosed `[`."); - } - else - { - it += 1; - } - } + DLLPushBack_NPZ(&e_expr_nil, result.exprs.first, result.exprs.last, atom, next, prev); + chain_count += 1; } - - // rjf: quit if this doesn't look like any patterns of postfix unary we know - if(!is_postfix_unary) - { - break; - } - } - - //- rjf: upgrade atom w/ previously parsed prefix unaries - if(atom == &e_expr_nil && first_prefix_unary != 0 && first_prefix_unary->cast_expr != &e_expr_nil) - { - atom = first_prefix_unary->cast_expr; - for(PrefixUnaryNode *prefix_unary = first_prefix_unary->next; - prefix_unary != 0; - prefix_unary = prefix_unary->next) - { - E_Expr *rhs = atom; - atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); - if(prefix_unary->cast_expr != &e_expr_nil) - { - e_expr_push_child(atom, prefix_unary->cast_expr); - } - e_expr_push_child(atom, rhs); - } - } - else if(atom == &e_expr_nil && first_prefix_unary != 0) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, last_prefix_unary->location, "Missing expression."); - } - else - { - for(PrefixUnaryNode *prefix_unary = first_prefix_unary; - prefix_unary != 0; - prefix_unary = prefix_unary->next) - { - E_Expr *rhs = atom; - atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); - if(prefix_unary->cast_expr != &e_expr_nil) - { - e_expr_push_child(atom, prefix_unary->cast_expr); - } - e_expr_push_child(atom, rhs); - } - } - - //- rjf: parse complex operators - if(atom != &e_expr_nil) for(;it < it_opl;) - { - E_Token *start_it = it; - E_Token token = e_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - - //- rjf: parse binaries - { - // rjf: first try to find a matching binary operator - S64 binary_precedence = 0; - E_ExprKind binary_kind = 0; - for EachNonZeroEnumVal(E_ExprKind, k) - { - E_OpInfo *op_info = &e_expr_kind_op_info_table[k]; - if(op_info->kind == E_OpKind_Binary && str8_match(op_info->sep, token_string, 0)) - { - binary_precedence = op_info->precedence; - binary_kind = k; - break; - } - } - - // rjf: if we got a valid binary precedence, and it's not to be handled by - // a caller, then we need to parse the right-hand-side with a tighter - // precedence - if(binary_precedence != 0 && binary_precedence <= max_precedence) - { - E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it+1, it_opl); - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, binary_precedence-1); - e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - E_Expr *rhs = rhs_expr_parse.expr; - it = rhs_expr_parse.last_token; - if(rhs == &e_expr_nil) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing right-hand-side of `%S`.", token_string); - } - else - { - E_Expr *lhs = atom; - atom = e_push_expr(arena, binary_kind, token_string.str); - e_expr_push_child(atom, lhs); - e_expr_push_child(atom, rhs); - } - } - } - - //- rjf: parse ternaries - { - if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("?"), 0) && 13 <= max_precedence) - { - it += 1; - - // rjf: parse middle expression - E_TokenArray middle_expr_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &middle_expr_tokens, e_max_precedence); - it = middle_expr_parse.last_token; - E_Expr *middle_expr = middle_expr_parse.expr; - e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); - if(middle_expr_parse.expr == &e_expr_nil) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression after `?`."); - } - - // rjf: expect : - B32 got_colon = 0; - E_Token colon_token = zero_struct; - String8 colon_token_string = {0}; - { - E_Token colon_token_maybe = e_token_at_it(it, tokens); - String8 colon_token_maybe_string = str8_substr(text, colon_token_maybe.range); - if(colon_token_maybe.kind != E_TokenKind_Symbol || !str8_match(colon_token_maybe_string, str8_lit(":"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected `:` after `?`."); - } - else - { - got_colon = 1; - colon_token = colon_token_maybe; - colon_token_string = colon_token_maybe_string; - it += 1; - } - } - - // rjf: parse rhs - E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, e_max_precedence); - if(got_colon) - { - it = rhs_expr_parse.last_token; - e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - if(rhs_expr_parse.expr == &e_expr_nil) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, colon_token_string.str, "Expected expression after `:`."); - } - } - - // rjf: build ternary - if(atom != &e_expr_nil && - middle_expr_parse.expr != &e_expr_nil && - rhs_expr_parse.expr != &e_expr_nil) - { - E_Expr *lhs = atom; - E_Expr *mhs = middle_expr_parse.expr; - E_Expr *rhs = rhs_expr_parse.expr; - atom = e_push_expr(arena, E_ExprKind_Ternary, token_string.str); - e_expr_push_child(atom, lhs); - e_expr_push_child(atom, mhs); - e_expr_push_child(atom, rhs); - } - } - } - - // rjf: if we parsed nothing successfully, we're done - if(it == start_it) + else { break; } @@ -2109,7 +2283,6 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: fill result & return result.last_token = it; - result.expr = atom; scratch_end(scratch); ProfEnd(); return result; @@ -2119,17 +2292,49 @@ internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) { ProfBegin("parse '%.*s'", str8_varg(text)); - E_Parse parse = e_parse_expr_from_text_tokens__prec(arena, text, tokens, e_max_precedence); + E_Parse parse = e_parse_expr_from_text_tokens__prec(arena, text, tokens, e_max_precedence, max_U64); ProfEnd(); return parse; } -internal E_Expr * +internal E_Parse e_parse_expr_from_text(Arena *arena, String8 text) { Temp scratch = scratch_begin(&arena, 1); E_TokenArray tokens = e_token_array_from_text(scratch.arena, text); E_Parse parse = e_parse_expr_from_text_tokens(arena, text, &tokens); scratch_end(scratch); - return parse.expr; + return parse; +} + +internal E_Parse +e_parse_expr_from_text__cached(String8 text) +{ + E_Parse parse = {0, &e_expr_nil}; + U64 hash = e_hash_from_string(5381, str8_struct(&text)); + U64 slot_idx = hash%e_parse_state->parse_cache_slots_count; + E_ParseCacheNode *node = 0; + for(E_ParseCacheNode *n = e_parse_state->parse_cache_slots[slot_idx].first; n != 0; n = n->next) + { + if(str8_match(n->string, text, 0)) + { + node = n; + break; + } + } + if(node == 0) + { + Temp scratch = scratch_begin(0, 0); + node = push_array(e_parse_state->arena, E_ParseCacheNode, 1); + SLLQueuePush(e_parse_state->parse_cache_slots[slot_idx].first, e_parse_state->parse_cache_slots[slot_idx].last, node); + node->string = push_str8_copy(e_parse_state->arena, text); + E_TokenArray tokens = e_token_array_from_text(scratch.arena, text); + node->parse = e_parse_expr_from_text_tokens(e_parse_state->arena, node->string, &tokens); + scratch_end(scratch); + } + if(node != 0) + { + parse = node->parse; + } + return parse; } diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 9f46e6f7..37343f2e 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -52,6 +52,8 @@ struct E_Expr { E_Expr *first; E_Expr *last; + E_Expr *first_tag; + E_Expr *last_tag; E_Expr *next; E_Expr *prev; E_Expr *ref; @@ -62,9 +64,32 @@ struct E_Expr E_TypeKey type_key; E_Value value; String8 string; + String8 qualifier; String8 bytecode; }; +typedef struct E_ExprChain E_ExprChain; +struct E_ExprChain +{ + E_Expr *first; + E_Expr *last; +}; + +typedef struct E_ExprNode E_ExprNode; +struct E_ExprNode +{ + E_ExprNode *next; + E_Expr *v; +}; + +typedef struct E_ExprList E_ExprList; +struct E_ExprList +{ + E_ExprNode *first; + E_ExprNode *last; + U64 count; +}; + //////////////////////////////// //~ rjf: Map Types @@ -128,6 +153,17 @@ struct E_String2ExprMap E_String2ExprMapSlot *slots; }; +//////////////////////////////// +//~ rjf: Parse Results + +typedef struct E_Parse E_Parse; +struct E_Parse +{ + E_Token *last_token; + E_ExprChain exprs; + E_MsgList msgs; +}; + //////////////////////////////// //~ rjf: Parse Context @@ -152,14 +188,33 @@ struct E_ParseCtx }; //////////////////////////////// -//~ rjf: Parse Results +//~ rjf: Parse State (stateful thread-local caching mechanisms, not provided by user) -typedef struct E_Parse E_Parse; -struct E_Parse +typedef struct E_ParseCacheNode E_ParseCacheNode; +struct E_ParseCacheNode { - E_Token *last_token; - E_Expr *expr; - E_MsgList msgs; + E_ParseCacheNode *next; + String8 string; + E_Parse parse; +}; + +typedef struct E_ParseCacheSlot E_ParseCacheSlot; +struct E_ParseCacheSlot +{ + E_ParseCacheNode *first; + E_ParseCacheNode *last; +}; + +typedef struct E_ParseState E_ParseState; +struct E_ParseState +{ + Arena *arena; + U64 arena_eval_start_pos; + E_ParseCtx *ctx; + + // rjf: string -> parse cache + E_ParseCacheSlot *parse_cache_slots; + U64 parse_cache_slots_count; }; //////////////////////////////// @@ -167,8 +222,8 @@ struct E_Parse global read_only E_String2NumMap e_string2num_map_nil = {0}; global read_only E_String2ExprMap e_string2expr_map_nil = {0}; -global read_only E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil}; -thread_static E_ParseCtx *e_parse_ctx = 0; +global read_only E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil}; +thread_static E_ParseState *e_parse_state = 0; //////////////////////////////// //~ rjf: Basic Map Functions @@ -218,13 +273,12 @@ internal E_Expr *e_push_expr(Arena *arena, E_ExprKind kind, void *location); internal void e_expr_insert_child(E_Expr *parent, E_Expr *prev, E_Expr *child); internal void e_expr_push_child(E_Expr *parent, E_Expr *child); internal void e_expr_remove_child(E_Expr *parent, E_Expr *child); +internal void e_expr_push_tag(E_Expr *parent, E_Expr *child); internal E_Expr *e_expr_ref(Arena *arena, E_Expr *ref); -internal E_Expr *e_expr_ref_addr(Arena *arena, E_Expr *rhs); -internal E_Expr *e_expr_ref_member_access(Arena *arena, E_Expr *lhs, String8 member_name); -internal E_Expr *e_expr_ref_array_index(Arena *arena, E_Expr *lhs, U64 index); internal E_Expr *e_expr_ref_deref(Arena *arena, E_Expr *rhs); internal E_Expr *e_expr_ref_cast(Arena *arena, E_TypeKey type_key, E_Expr *rhs); -internal E_Expr *e_expr_ref_bswap(Arena *arena, E_Expr *rhs); +internal E_Expr *e_expr_copy(Arena *arena, E_Expr *src); +internal void e_expr_list_push(Arena *arena, E_ExprList *list, E_Expr *expr); //////////////////////////////// //~ rjf: Expression Tree -> String Conversions @@ -239,8 +293,9 @@ internal E_TypeKey e_leaf_type_from_name(String8 name); internal E_TypeKey e_type_from_expr(E_Expr *expr); internal void e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, E_Expr *expr); internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); -internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence); +internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence, U64 max_chain_count); internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); -internal E_Expr *e_parse_expr_from_text(Arena *arena, String8 text); +internal E_Parse e_parse_expr_from_text(Arena *arena, String8 text); +internal E_Parse e_parse_expr_from_text__cached(String8 text); #endif // EVAL_PARSE_H diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 57706489..25527892 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -250,6 +250,8 @@ e_select_type_ctx(E_TypeCtx *ctx) e_type_state->cons_key_slots = push_array(e_type_state->arena, E_ConsTypeSlot, e_type_state->cons_key_slots_count); e_type_state->member_cache_slots_count = 256; e_type_state->member_cache_slots = push_array(e_type_state->arena, E_MemberCacheSlot, e_type_state->member_cache_slots_count); + e_type_state->type_cache_slots_count = 1024; + e_type_state->type_cache_slots = push_array(e_type_state->arena, E_TypeCacheSlot, e_type_state->type_cache_slots_count); } //////////////////////////////// @@ -321,6 +323,8 @@ e_hash_from_cons_type_params(E_ConsTypeParams *params) params->direct_key.u32[2], (U32)((params->count & 0x00000000ffffffffull)>> 0), (U32)((params->count & 0xffffffff00000000ull)>> 32), + (U32)((params->depth & 0x00000000ffffffffull)>> 0), + (U32)((params->depth & 0xffffffff00000000ull)>> 32), }; U64 hash = e_hash_from_string(5381, str8((U8 *)buffer, sizeof(buffer))); hash = e_hash_from_string(hash, params->name); @@ -334,7 +338,8 @@ e_cons_type_params_match(E_ConsTypeParams *l, E_ConsTypeParams *r) l->flags == r->flags && str8_match(l->name, r->name, 0) && e_type_key_match(l->direct_key, r->direct_key) && - l->count == r->count); + l->count == r->count && + l->depth == r->depth); if(result && l->members != 0 && r->members != 0) { for(U64 idx = 0; idx < l->count; idx += 1) @@ -445,16 +450,16 @@ e_type_key_cons_(E_ConsTypeParams *params) //- rjf: constructed type helpers internal E_TypeKey -e_type_key_cons_array(E_TypeKey element_type_key, U64 count) +e_type_key_cons_array(E_TypeKey element_type_key, U64 count, E_TypeFlags flags) { - E_TypeKey key = e_type_key_cons(.kind = E_TypeKind_Array, .direct_key = element_type_key, .count = count); + E_TypeKey key = e_type_key_cons(.kind = E_TypeKind_Array, .direct_key = element_type_key, .count = count, .flags = flags); return key; } internal E_TypeKey -e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, E_TypeFlags flags) +e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, U64 count, E_TypeFlags flags) { - E_TypeKey key = e_type_key_cons(.arch = arch, .kind = E_TypeKind_Ptr, .flags = flags, .direct_key = element_type_key); + E_TypeKey key = e_type_key_cons(.arch = arch, .kind = E_TypeKind_Ptr, .flags = flags, .direct_key = element_type_key, .count = count); return key; } @@ -478,12 +483,12 @@ e_type_key_cons_base(Type *type) if(type->flags & TypeFlag_IsPlainText){ flags |= E_TypeFlag_IsPlainText; } if(type->flags & TypeFlag_IsCodeText) { flags |= E_TypeFlag_IsCodeText; } if(type->flags & TypeFlag_IsPathText) { flags |= E_TypeFlag_IsPathText; } - result = e_type_key_cons_ptr(arch_from_context(), direct_type, flags); + result = e_type_key_cons_ptr(arch_from_context(), direct_type, 1, flags); }break; case TypeKind_Array: { E_TypeKey direct_type = e_type_key_cons_base(type->direct); - result = e_type_key_cons_array(direct_type, type->count); + result = e_type_key_cons_array(direct_type, type->count, 0); }break; case TypeKind_Struct: { @@ -492,7 +497,7 @@ e_type_key_cons_base(Type *type) for(U64 idx = 0; idx < type->count; idx += 1) { E_TypeKey member_type_key = e_type_key_cons_base(type->members[idx].type); - e_member_list_push_new(scratch.arena, &members, .name = type->members[idx].name, .off = type->members[idx].value, .type_key = member_type_key, .pretty_name = type->members[idx].pretty_name); + e_member_list_push_new(scratch.arena, &members, .name = type->members[idx].name, .off = type->members[idx].value, .type_key = member_type_key); } E_MemberArray members_array = e_member_array_from_list(scratch.arena, &members); result = e_type_key_cons(.arch = arch_from_context(), @@ -518,13 +523,12 @@ e_type_key_match(E_TypeKey l, E_TypeKey r) //- rjf: key -> info extraction internal U64 -e_hash_from_type_key(E_TypeKey key) +e_hash_from_type(E_Type *type) { U64 hash = 0; - if(!e_type_key_match(e_type_key_zero(), key)) + if(type != &e_type_nil) { Temp scratch = scratch_begin(0, 0); - E_Type *type = e_type_from_key(scratch.arena, key); String8List strings = {0}; str8_serial_begin(scratch.arena, &strings); str8_serial_push_struct(scratch.arena, &strings, &type->kind); @@ -623,9 +627,12 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, node->params.name); type->direct_type_key = node->params.direct_key; type->count = node->params.count; + type->depth = node->params.depth; + type->arch = node->params.arch; type->byte_size = node->byte_size; switch(type->kind) { + default:{}break; case E_TypeKind_Struct: case E_TypeKind_Union: case E_TypeKind_Class: @@ -700,6 +707,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = (U64)rdi_type->byte_size; type->count = members_count; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; type->members = members; } @@ -744,6 +752,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = (U64)rdi_type->byte_size; type->count = enum_vals_count; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; type->enum_vals = enum_vals; type->direct_type_key = direct_type_key; } @@ -783,6 +792,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->byte_size = direct_type_byte_size; type->flags = flags; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Ptr: case RDI_TypeKind_LRef: @@ -792,6 +802,8 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->kind = kind; type->direct_type_key = direct_type_key; type->byte_size = bit_size_from_arch(e_type_state->ctx->modules[rdi_idx].arch)/8; + type->count = 1; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Array: @@ -801,6 +813,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->count = rdi_type->constructed.count; type->byte_size = direct_type_byte_size * type->count; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Function: { @@ -816,6 +829,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->count = count; type->param_type_keys = push_array_no_zero(arena, E_TypeKey, type->count); + type->arch = e_type_state->ctx->modules[rdi_idx].arch; for(U32 idx = 0; idx < type->count; idx += 1) { U32 param_type_idx = idx_run[idx]; @@ -849,6 +863,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->owner_type_key = direct_type_key; type->count = count; type->param_type_keys = push_array_no_zero(arena, E_TypeKey, type->count); + type->arch = e_type_state->ctx->modules[rdi_idx].arch; for(U32 idx = 0; idx < type->count; idx += 1) { U32 param_type_idx = idx_run[idx]; @@ -886,6 +901,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->byte_size = bit_size_from_arch(e_type_state->ctx->modules[rdi_idx].arch)/8; type->owner_type_key = owner_type_key; type->direct_type_key = direct_type_key; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; } } @@ -914,6 +930,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = direct_type_byte_size; type->direct_type_key = direct_type_key; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; } //- rjf: bitfields @@ -937,6 +954,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->off = (U32)rdi_type->bitfield.off; type->count = (U64)rdi_type->bitfield.size; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; } //- rjf: incomplete types @@ -950,6 +968,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type = push_array(arena, E_Type, 1); type->kind = kind; type->name = push_str8_copy(arena, name); + type->arch = e_type_state->ctx->modules[rdi_idx].arch; } } @@ -977,6 +996,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->kind = E_TypeKind_Union; type->name = push_str8f(arena, "reg_%I64u_bit", reg_byte_count*8); type->byte_size = (U64)reg_byte_count; + type->arch = (Arch)key.u32[0]; // rjf: build register type members E_MemberList members = {0}; @@ -1045,7 +1065,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("u128s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U128), reg_byte_count/16); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U128), reg_byte_count/16, 0); } if(type->byte_size > 8 && type->byte_size%8 == 0) { @@ -1055,7 +1075,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("u64s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U64), reg_byte_count/8); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U64), reg_byte_count/8, 0); } if(type->byte_size > 4 && type->byte_size%4 == 0) { @@ -1065,7 +1085,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("u32s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U32), reg_byte_count/4); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U32), reg_byte_count/4, 0); } if(type->byte_size > 2 && type->byte_size%2 == 0) { @@ -1075,7 +1095,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("u16s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U16), reg_byte_count/2); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U16), reg_byte_count/2, 0); } if(type->byte_size > 1) { @@ -1085,7 +1105,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("u8s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), reg_byte_count); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), reg_byte_count, 0); } if(type->byte_size > 4 && type->byte_size%4 == 0) { @@ -1095,7 +1115,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("f32s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_F32), reg_byte_count/4); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_F32), reg_byte_count/4, 0); } if(type->byte_size > 8 && type->byte_size%8 == 0) { @@ -1105,7 +1125,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("f64s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_F64), reg_byte_count/8); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_F64), reg_byte_count/8, 0); } } } @@ -1179,10 +1199,8 @@ e_type_direct_from_key(E_TypeKey key) case E_TypeKeyKind_Ext: case E_TypeKeyKind_Cons: { - Temp scratch = scratch_begin(0, 0); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); result = type->direct_type_key; - scratch_end(scratch); }break; } return result; @@ -1198,10 +1216,8 @@ e_type_owner_from_key(E_TypeKey key) case E_TypeKeyKind_Ext: case E_TypeKeyKind_Cons: { - Temp scratch = scratch_begin(0, 0); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); result = type->owner_type_key; - scratch_end(scratch); }break; } return result; @@ -1340,21 +1356,18 @@ e_type_match(E_TypeKey l, E_TypeKey r) case E_TypeKind_Array: { - Temp scratch = scratch_begin(0, 0); - E_Type *lt = e_type_from_key(scratch.arena, l); - E_Type *rt = e_type_from_key(scratch.arena, r); + E_Type *lt = e_type_from_key__cached(l); + E_Type *rt = e_type_from_key__cached(r); if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key)) { result = 1; } - scratch_end(scratch); }break; case E_TypeKind_Function: { - Temp scratch = scratch_begin(0, 0); - E_Type *lt = e_type_from_key(scratch.arena, l); - E_Type *rt = e_type_from_key(scratch.arena, r); + E_Type *lt = e_type_from_key__cached(l); + E_Type *rt = e_type_from_key__cached(r); if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key)) { B32 params_match = 1; @@ -1371,14 +1384,12 @@ e_type_match(E_TypeKey l, E_TypeKey r) } result = params_match; } - scratch_end(scratch); }break; case E_TypeKind_Method: { - Temp scratch = scratch_begin(0, 0); - E_Type *lt = e_type_from_key(scratch.arena, l); - E_Type *rt = e_type_from_key(scratch.arena, r); + E_Type *lt = e_type_from_key__cached(l); + E_Type *rt = e_type_from_key__cached(r); if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key) && e_type_match(lt->owner_type_key, rt->owner_type_key)) @@ -1397,7 +1408,6 @@ e_type_match(E_TypeKey l, E_TypeKey r) } result = params_match; } - scratch_end(scratch); }break; } } @@ -1412,7 +1422,6 @@ e_type_member_copy(Arena *arena, E_Member *src) E_Member *dst = push_array(arena, E_Member, 1); MemoryCopyStruct(dst, src); dst->name = push_str8_copy(arena, src->name); - dst->pretty_name = push_str8_copy(arena, src->pretty_name); dst->inheritance_key_chain = e_type_key_list_copy(arena, &src->inheritance_key_chain); return dst; } @@ -1442,7 +1451,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) E_MemberList members_list = {0}; B32 members_need_offset_sort = 0; { - E_Type *root_type = e_type_from_key(scratch.arena, key); + E_Type *root_type = e_type_from_key__cached(key); typedef struct Task Task; struct Task { @@ -1481,7 +1490,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) t->inheritance_chain = e_type_key_list_copy(scratch.arena, &task->inheritance_chain); e_type_key_list_push(scratch.arena, &t->inheritance_chain, type->members[member_idx].type_key); t->type_key = type->members[member_idx].type_key; - t->type = e_type_from_key(scratch.arena, type->members[member_idx].type_key); + t->type = e_type_from_key__cached(type->members[member_idx].type_key); SLLQueuePush(first_task, last_task, t); members_need_offset_sort = 1; } @@ -1564,7 +1573,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) E_Member *padding_member = &new_members.v[n->prev_member_idx+padding_idx+1]; MemoryZeroStruct(padding_member); padding_member->kind = E_MemberKind_Padding; - padding_member->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), n->size); + padding_member->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), n->size, 0); padding_member->off = n->off; padding_member->name = push_str8f(arena, "[padding %I64u]", padding_idx); padding_idx += 1; @@ -1602,26 +1611,21 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr { default: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); str8_list_push(arena, out, push_str8_copy(arena, type->name)); str8_list_push(arena, out, str8_lit(" ")); - scratch_end(scratch); }break; case E_TypeKind_Bitfield: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); e_type_lhs_string_from_key(arena, type->direct_type_key, out, prec, skip_return); str8_list_pushf(arena, out, ": %I64u", type->count); - scratch_end(scratch); }break; case E_TypeKind_Modifier: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); E_TypeKey direct = type->direct_type_key; e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); if(type->flags & E_TypeFlag_Const) @@ -1632,7 +1636,6 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr { str8_list_push(arena, out, str8_lit("volatile ")); } - scratch_end(scratch); }break; case E_TypeKind_Variadic: @@ -1646,11 +1649,9 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Class: case E_TypeKind_Alias: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); str8_list_push(arena, out, push_str8_copy(arena, type->name)); str8_list_push(arena, out, str8_lit(" ")); - scratch_end(scratch); }break; case E_TypeKind_IncompleteStruct: keyword = str8_lit("struct"); goto fwd_udt; @@ -1659,13 +1660,11 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_IncompleteClass: keyword = str8_lit("class"); goto fwd_udt; fwd_udt:; { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); str8_list_push(arena, out, keyword); str8_list_push(arena, out, str8_lit(" ")); str8_list_push(arena, out, push_str8_copy(arena, type->name)); str8_list_push(arena, out, str8_lit(" ")); - scratch_end(scratch); }break; case E_TypeKind_Array: @@ -1696,6 +1695,11 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr E_TypeKey direct = e_type_direct_from_key(key); e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); str8_list_push(arena, out, str8_lit("*")); + E_Type *type = e_type_from_key__cached(key); + if(type->count != 1) + { + str8_list_pushf(arena, out, ".%I64u", type->count); + } }break; case E_TypeKind_LRef: @@ -1714,11 +1718,10 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_MemberPtr: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); E_TypeKey direct = type->direct_type_key; e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); - E_Type *container = e_type_from_key(scratch.arena, type->owner_type_key); + E_Type *container = e_type_from_key__cached(type->owner_type_key); if(container->kind != E_TypeKind_Null) { str8_list_push(arena, out, push_str8_copy(arena, container->name)); @@ -1728,7 +1731,6 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr str8_list_push(arena, out, str8_lit("")); } str8_list_push(arena, out, str8_lit("::*")); - scratch_end(scratch); }break; } } @@ -1759,8 +1761,7 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Array: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); if(prec == 1) { str8_list_push(arena, out, str8_lit(")")); @@ -1771,13 +1772,11 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr str8_list_push(arena, out, str8_lit("]")); E_TypeKey direct = e_type_direct_from_key(key); e_type_rhs_string_from_key(arena, direct, out, 2); - scratch_end(scratch); }break; case E_TypeKind_Function: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); if(prec == 1) { str8_list_push(arena, out, str8_lit(")")); @@ -1806,7 +1805,6 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr } E_TypeKey direct = e_type_direct_from_key(key); e_type_rhs_string_from_key(arena, direct, out, 2); - scratch_end(scratch); }break; } } @@ -1846,9 +1844,74 @@ e_type_key_list_copy(Arena *arena, E_TypeKeyList *src) return dst; } +internal E_String2TypeKeyMap +e_string2typekey_map_make(Arena *arena, U64 slots_count) +{ + E_String2TypeKeyMap map = {0}; + map.slots_count = slots_count; + map.slots = push_array(arena, E_String2TypeKeySlot, map.slots_count); + return map; +} + +internal void +e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key) +{ + E_String2TypeKeyNode *n = push_array(arena, E_String2TypeKeyNode, 1); + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); + n->string = push_str8_copy(arena, string); + n->key = key; +} + +internal E_TypeKey +e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string) +{ + E_TypeKey key = zero_struct; + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + for(E_String2TypeKeyNode *n = map->slots[slot_idx].first; n != 0; n = n->next) + { + if(str8_match(n->string, string, 0)) + { + key = n->key; + break; + } + } + return key; +} + //////////////////////////////// //~ rjf: Cache Lookups +internal E_Type * +e_type_from_key__cached(E_TypeKey key) +{ + E_Type *type = &e_type_nil; + { + U64 hash = e_hash_from_string(5381, str8_struct(&key)); + U64 slot_idx = hash%e_type_state->type_cache_slots_count; + E_TypeCacheNode *node = 0; + for(E_TypeCacheNode *n = e_type_state->type_cache_slots[slot_idx].first; n != 0; n = n->next) + { + if(e_type_key_match(key, n->key)) + { + node = n; + break; + } + } + if(node == 0) + { + node = push_array(e_type_state->arena, E_TypeCacheNode, 1); + node->key = key; + node->type = e_type_from_key(e_type_state->arena, key); + SLLQueuePush(e_type_state->type_cache_slots[slot_idx].first, e_type_state->type_cache_slots[slot_idx].last, node); + } + type = node->type; + } + return type; +} + internal E_MemberCacheNode * e_member_cache_node_from_type_key(E_TypeKey key) { @@ -1872,6 +1935,8 @@ e_member_cache_node_from_type_key(E_TypeKey key) node->members = e_type_data_members_from_key(e_type_state->arena, key); node->member_hash_slots_count = node->members.count; node->member_hash_slots = push_array(e_type_state->arena, E_MemberHashSlot, node->member_hash_slots_count); + node->member_filter_slots_count = 16; + node->member_filter_slots = push_array(e_type_state->arena, E_MemberFilterSlot, node->member_filter_slots_count); for EachIndex(idx, node->members.count) { U64 hash = e_hash_from_string(5381, node->members.v[idx].name); @@ -1884,6 +1949,55 @@ e_member_cache_node_from_type_key(E_TypeKey key) return node; } +internal E_MemberArray +e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter) +{ + E_MemberArray members = {0}; + E_MemberCacheNode *node = e_member_cache_node_from_type_key(key); + if(node != 0) + { + if(filter.size == 0) + { + members = node->members; + } + else + { + U64 hash = e_hash_from_string(5381, filter); + U64 slot_idx = hash%node->member_filter_slots_count; + E_MemberFilterSlot *slot = &node->member_filter_slots[slot_idx]; + E_MemberFilterNode *filter_node = 0; + for(E_MemberFilterNode *n = slot->first; n != 0; n = n->next) + { + if(str8_match(n->filter, filter, 0)) + { + filter_node = n; + break; + } + } + if(filter_node == 0) + { + Temp scratch = scratch_begin(0, 0); + filter_node = push_array(e_type_state->arena, E_MemberFilterNode, 1); + filter_node->filter = push_str8_copy(e_type_state->arena, filter); + E_MemberList member_list__filtered = {0}; + for EachIndex(idx, node->members.count) + { + E_Member *member = &node->members.v[idx]; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, member->name); + if(matches.count == matches.needle_part_count) + { + e_member_list_push(scratch.arena, &member_list__filtered, member); + } + } + filter_node->members_filtered = e_member_array_from_list(e_type_state->arena, &member_list__filtered); + scratch_end(scratch); + } + members = filter_node->members_filtered; + } + } + return members; +} + internal E_MemberArray e_type_data_members_from_key__cached(E_TypeKey key) { diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index ee4da7ba..38c5c7aa 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -59,6 +59,7 @@ typedef enum E_MemberKind E_MemberKind_VirtualBase, E_MemberKind_NestedType, E_MemberKind_Padding, + E_MemberKind_Query, E_MemberKind_COUNT } E_MemberKind; @@ -66,12 +67,13 @@ E_MemberKind; typedef U32 E_TypeFlags; enum { - E_TypeFlag_Const = (1<<0), - E_TypeFlag_Volatile = (1<<1), - E_TypeFlag_External = (1<<2), - E_TypeFlag_IsPlainText= (1<<3), - E_TypeFlag_IsCodeText = (1<<4), - E_TypeFlag_IsPathText = (1<<5), + E_TypeFlag_Const = (1<<0), + E_TypeFlag_Volatile = (1<<1), + E_TypeFlag_External = (1<<2), + E_TypeFlag_IsPlainText = (1<<3), + E_TypeFlag_IsCodeText = (1<<4), + E_TypeFlag_IsPathText = (1<<5), + E_TypeFlag_EditableChildren = (1<<6), }; typedef struct E_Member E_Member; @@ -80,7 +82,6 @@ struct E_Member E_MemberKind kind; E_TypeKey type_key; String8 name; - String8 pretty_name; U64 off; E_TypeKeyList inheritance_key_chain; }; @@ -129,7 +130,9 @@ struct E_Type String8 name; U64 byte_size; U64 count; + U64 depth; U32 off; + Arch arch; E_TypeKey direct_type_key; E_TypeKey owner_type_key; E_TypeKey *param_type_keys; @@ -137,6 +140,31 @@ struct E_Type E_EnumVal *enum_vals; }; +//////////////////////////////// +//~ rjf: String -> Type Key Map Data Structure + +typedef struct E_String2TypeKeyNode E_String2TypeKeyNode; +struct E_String2TypeKeyNode +{ + E_String2TypeKeyNode *next; + String8 string; + E_TypeKey key; +}; + +typedef struct E_String2TypeKeySlot E_String2TypeKeySlot; +struct E_String2TypeKeySlot +{ + E_String2TypeKeyNode *first; + E_String2TypeKeyNode *last; +}; + +typedef struct E_String2TypeKeyMap E_String2TypeKeyMap; +struct E_String2TypeKeyMap +{ + U64 slots_count; + E_String2TypeKeySlot *slots; +}; + //////////////////////////////// //~ rjf: Evaluation Context @@ -151,6 +179,7 @@ struct E_ConsTypeParams String8 name; E_TypeKey direct_key; U64 count; + U64 depth; E_Member *members; E_EnumVal *enum_vals; }; @@ -172,6 +201,23 @@ struct E_ConsTypeSlot E_ConsTypeNode *last; }; +//- rjf: unpacked type cache + +typedef struct E_TypeCacheNode E_TypeCacheNode; +struct E_TypeCacheNode +{ + E_TypeCacheNode *next; + E_TypeKey key; + E_Type *type; +}; + +typedef struct E_TypeCacheSlot E_TypeCacheSlot; +struct E_TypeCacheSlot +{ + E_TypeCacheNode *first; + E_TypeCacheNode *last; +}; + //- rjf: member lookup cache types typedef struct E_MemberHashNode E_MemberHashNode; @@ -188,6 +234,21 @@ struct E_MemberHashSlot E_MemberHashNode *last; }; +typedef struct E_MemberFilterNode E_MemberFilterNode; +struct E_MemberFilterNode +{ + E_MemberFilterNode *next; + String8 filter; + E_MemberArray members_filtered; +}; + +typedef struct E_MemberFilterSlot E_MemberFilterSlot; +struct E_MemberFilterSlot +{ + E_MemberFilterNode *first; + E_MemberFilterNode *last; +}; + typedef struct E_MemberCacheNode E_MemberCacheNode; struct E_MemberCacheNode { @@ -196,6 +257,8 @@ struct E_MemberCacheNode E_MemberArray members; U64 member_hash_slots_count; E_MemberHashSlot *member_hash_slots; + U64 member_filter_slots_count; + E_MemberFilterSlot *member_filter_slots; }; typedef struct E_MemberCacheSlot E_MemberCacheSlot; @@ -241,6 +304,10 @@ struct E_TypeState // rjf: member cache table U64 member_cache_slots_count; E_MemberCacheSlot *member_cache_slots; + + // rjf: unpacked type cache + U64 type_cache_slots_count; + E_TypeCacheSlot *type_cache_slots; }; //////////////////////////////// @@ -292,15 +359,15 @@ internal E_TypeKey e_type_key_cons_(E_ConsTypeParams *params); #define e_type_key_cons(...) e_type_key_cons_(&(E_ConsTypeParams){.kind = E_TypeKind_Null, __VA_ARGS__}) //- rjf: constructed type construction helpers -internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count); -internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, E_TypeFlags flags); +internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count, E_TypeFlags flags); +internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, U64 count, E_TypeFlags flags); internal E_TypeKey e_type_key_cons_base(Type *type); //- rjf: basic type key functions internal B32 e_type_key_match(E_TypeKey l, E_TypeKey r); //- rjf: key -> info extraction -internal U64 e_hash_from_type_key(E_TypeKey key); +internal U64 e_hash_from_type(E_Type *type); internal E_TypeKind e_type_kind_from_key(E_TypeKey key); internal U64 e_type_byte_size_from_key(E_TypeKey key); internal E_Type *e_type_from_key(Arena *arena, E_TypeKey key); @@ -322,11 +389,16 @@ internal String8 e_type_string_from_key(Arena *arena, E_TypeKey key); //- rjf: type key data structures internal void e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key); internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src); +internal E_String2TypeKeyMap e_string2typekey_map_make(Arena *arena, U64 slots_count); +internal void e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key); +internal E_TypeKey e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string); //////////////////////////////// //~ rjf: Cache Lookups +internal E_Type *e_type_from_key__cached(E_TypeKey key); internal E_MemberCacheNode *e_member_cache_node_from_type_key(E_TypeKey key); +internal E_MemberArray e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter); internal E_MemberArray e_type_data_members_from_key__cached(E_TypeKey key); internal E_Member e_type_member_from_key_name__cached(E_TypeKey key, String8 name); diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 35b65640..770eb9c2 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_expr_kind_strings[48] = +String8 e_expr_kind_strings[51] = { str8_lit_comp("Nil"), str8_lit_comp("Ref"), @@ -49,6 +49,7 @@ str8_lit_comp("BitOr"), str8_lit_comp("LogAnd"), str8_lit_comp("LogOr"), str8_lit_comp("Ternary"), +str8_lit_comp("Call"), str8_lit_comp("LeafBytecode"), str8_lit_comp("LeafMember"), str8_lit_comp("LeafStringLiteral"), @@ -58,12 +59,14 @@ str8_lit_comp("LeafF64"), str8_lit_comp("LeafF32"), str8_lit_comp("LeafIdent"), str8_lit_comp("LeafOffset"), +str8_lit_comp("LeafValue"), str8_lit_comp("LeafFilePath"), str8_lit_comp("TypeIdent"), str8_lit_comp("Ptr"), str8_lit_comp("Array"), str8_lit_comp("Func"), str8_lit_comp("Define"), +str8_lit_comp("Tag"), }; String8 e_interpretation_code_display_strings[11] = @@ -81,7 +84,7 @@ str8_lit_comp("Insufficient evaluation machine stack space."), str8_lit_comp("Malformed bytecode."), }; -E_OpInfo e_expr_kind_op_info_table[48] = +E_OpInfo e_expr_kind_op_info_table[51] = { { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, @@ -116,6 +119,8 @@ E_OpInfo e_expr_kind_op_info_table[48] = { E_OpKind_Binary, 11, str8_lit_comp(""), str8_lit_comp("&&"), str8_lit_comp("") }, { E_OpKind_Binary, 12, str8_lit_comp(""), str8_lit_comp("||"), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("?"), str8_lit_comp(":") }, +{ E_OpKind_Null, 0, str8_lit_comp("("), str8_lit_comp(","), str8_lit_comp(")") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, @@ -131,6 +136,7 @@ E_OpInfo e_expr_kind_op_info_table[48] = { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") }, }; U8 e_kind_basic_byte_size_table[56] = @@ -250,7 +256,7 @@ str8_lit_comp("class"), str8_lit_comp("enum"), str8_lit_comp("bitfield"), str8_lit_comp("variadic"), -str8_lit_comp("collection"), +str8_lit_comp("set"), }; C_LINKAGE_END diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 2a6200ba..3288fa6c 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -74,7 +74,7 @@ E_TypeKind_IncompleteClass, E_TypeKind_IncompleteEnum, E_TypeKind_Bitfield, E_TypeKind_Variadic, -E_TypeKind_Collection, +E_TypeKind_Set, E_TypeKind_COUNT, E_TypeKind_FirstBasic = E_TypeKind_Void, E_TypeKind_LastBasic = E_TypeKind_ComplexF128, @@ -124,6 +124,7 @@ E_ExprKind_BitOr, E_ExprKind_LogAnd, E_ExprKind_LogOr, E_ExprKind_Ternary, +E_ExprKind_Call, E_ExprKind_LeafBytecode, E_ExprKind_LeafMember, E_ExprKind_LeafStringLiteral, @@ -133,12 +134,14 @@ E_ExprKind_LeafF64, E_ExprKind_LeafF32, E_ExprKind_LeafIdent, E_ExprKind_LeafOffset, +E_ExprKind_LeafValue, E_ExprKind_LeafFilePath, E_ExprKind_TypeIdent, E_ExprKind_Ptr, E_ExprKind_Array, E_ExprKind_Func, E_ExprKind_Define, +E_ExprKind_Tag, E_ExprKind_COUNT, } E_ExprKindEnum; @@ -160,9 +163,9 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; -extern String8 e_expr_kind_strings[48]; +extern String8 e_expr_kind_strings[51]; extern String8 e_interpretation_code_display_strings[11]; -extern E_OpInfo e_expr_kind_op_info_table[48]; +extern E_OpInfo e_expr_kind_op_info_table[51]; extern U8 e_kind_basic_byte_size_table[56]; extern String8 e_kind_basic_string_table[56]; diff --git a/src/eval_visualization/eval_visualization.mdesk b/src/eval_visualization/eval_visualization.mdesk index 3fa5a06a..493c64a0 100644 --- a/src/eval_visualization/eval_visualization.mdesk +++ b/src/eval_visualization/eval_visualization.mdesk @@ -91,7 +91,6 @@ @table(coverage_check name name_lower string ih ex xr xe display_name docs schema description) EV_ViewRuleTable: { - {x Default default "default" - - - x "Default" - "" "" } {x Array array "array" - - x - "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." } {x List list "list" - - - x "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." } {x Slice slice "slice" - - x - "Slice" x "" "Specifies that a pointer within a struct, also containing an integer, points to the number of elements encoded by the integer." } @@ -106,22 +105,3 @@ EV_ViewRuleTable: {x Hex hex "hex" x - - - "Display In Hexadecimal" x "" "Specifies that all numeric values should be shown in base 16 (hexadecimal)." } {x NoAddress no_addr "no_addr" x - - - "Omit Addresses" x "" "Specifies that addresses should be omitted from visualizations, if possible." } } - -@enum EV_ViewRuleKind: -{ - @expand(EV_ViewRuleTable a) `$(a.name)`, - COUNT, -} - -@gen -{ - @expand(EV_ViewRuleTable a) `$(a.xr == "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(" .. a.name_lower .. ");")`; - @expand(EV_ViewRuleTable a) `$(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`; - @expand(EV_ViewRuleTable a) `$(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`; -} - -@data(EV_ViewRuleInfo) @c_file ev_builtin_view_rule_info_table: -{ - @expand(EV_ViewRuleTable a) - ```{str8_lit_comp("$(a.string)"), (EV_ViewRuleInfoFlag_Inherited*$(a.ih == "x"))|(EV_ViewRuleInfoFlag_Expandable*$(a.ex == "x")), $(a.xr == "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME("..a.name_lower..")") $(a.xr != "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity)"), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil)"), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil)"), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }```; -} diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.c b/src/eval_visualization/eval_visualization_builtin_view_rules.c deleted file mode 100644 index ab4628dd..00000000 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.c +++ /dev/null @@ -1,557 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: View Rule Tree Info Extraction Helpers - -internal U64 -ev_base_offset_from_eval(E_Eval eval) -{ - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(eval.type_key))) - { - eval = e_value_eval_from_eval(eval); - } - return eval.value.u64; -} - -internal E_Value -ev_value_from_params(MD_Node *params) -{ - Temp scratch = scratch_begin(0, 0); - String8 expr = md_string_from_children(scratch.arena, params); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - scratch_end(scratch); - return value_eval.value; -} - -internal E_TypeKey -ev_type_key_from_params(MD_Node *params) -{ - Temp scratch = scratch_begin(0, 0); - String8 expr = md_string_from_children(scratch.arena, params); - E_TokenArray tokens = e_token_array_from_text(scratch.arena, expr); - E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, expr, &tokens); - E_TypeKey type_key = e_type_from_expr(parse.expr); - scratch_end(scratch); - return type_key; -} - -internal E_Value -ev_value_from_params_key(MD_Node *params, String8 key) -{ - Temp scratch = scratch_begin(0, 0); - MD_Node *key_node = md_child_from_string(params, key, 0); - String8 expr = md_string_from_children(scratch.arena, key_node); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - scratch_end(scratch); - return value_eval.value; -} - -internal Rng1U64 -ev_range_from_eval_params(E_Eval eval, MD_Node *params) -{ - Temp scratch = scratch_begin(0, 0); - U64 size = ev_value_from_params_key(params, str8_lit("size")).u64; - E_TypeKey type_key = e_type_unwrap(eval.type_key); - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.type_key))); - } - if(size == 0 && eval.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Union || - type_kind == E_TypeKind_Class || - type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(e_type_unwrap(eval.type_key)); - } - if(size == 0) - { - size = 16384; - } - Rng1U64 result = {0}; - result.min = ev_base_offset_from_eval(eval); - result.max = result.min + size; - scratch_end(scratch); - return result; -} - -internal Arch -ev_arch_from_eval_params(E_Eval eval, MD_Node *params) -{ - Arch arch = Arch_Null; - MD_Node *arch_node = md_child_from_string(params, str8_lit("arch"), 0); - String8 arch_kind_string = arch_node->first->string; - if(str8_match(arch_kind_string, str8_lit("x64"), StringMatchFlag_CaseInsensitive)) - { - arch = Arch_x64; - } - return arch; -} - -//////////////////////////////// -//~ rjf: default - -typedef struct EV_DefaultExpandAccel EV_DefaultExpandAccel; -struct EV_DefaultExpandAccel -{ - E_MemberArray members; - E_EnumValArray enum_vals; - U64 array_count; - B32 array_need_extra_deref; - B32 is_ptr2ptr; -}; - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(default) -{ - Temp scratch = scratch_begin(&arena, 1); - U64 total_row_count = 0; - EV_DefaultExpandAccel *accel = push_array(arena, EV_DefaultExpandAccel, 1); - - //////////////////////////// - //- rjf: unpack expression type info - // - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_TypeKey type_key = e_type_unwrap(irtree.type_key); - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - - //////////////////////////// - //- rjf: structs/unions/classes -> expansions generate rows for all members - // - if((type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Union || - type_kind == E_TypeKind_Class) || - (e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class))) - { - E_TypeKey struct_type_key = e_type_kind_is_pointer_or_ref(type_kind) ? direct_type_key : type_key; - accel->members = e_type_data_members_from_key__cached(struct_type_key); - total_row_count = accel->members.count; - } - - //////////////////////////// - //- rjf: enums -> expansions generate rows for all members - // - else if(type_kind == E_TypeKind_Enum || - (e_type_kind_is_pointer_or_ref(type_kind) && direct_type_kind == E_TypeKind_Enum)) - { - E_Type *type = e_type_from_key(arena, e_type_kind_is_pointer_or_ref(type_kind) ? direct_type_key : type_key); - accel->enum_vals.v = type->enum_vals; - accel->enum_vals.count = type->count; - total_row_count = accel->enum_vals.count; - } - - //////////////////////////// - //- rjf: arrays -> expansions generate rows for all elements - // - else if(type_kind == E_TypeKind_Array || - (e_type_kind_is_pointer_or_ref(type_kind) && direct_type_kind == E_TypeKind_Array)) - { - B32 need_extra_deref = e_type_kind_is_pointer_or_ref(type_kind); - E_Expr *array_expr = need_extra_deref ? e_expr_ref_deref(arena, expr) : expr; - E_Type *type = e_type_from_key(arena, need_extra_deref ? direct_type_key : type_key); - total_row_count = type->count; - accel->array_count = type->count; - accel->array_need_extra_deref = need_extra_deref; - } - - //////////////////////////// - //- rjf: pointer-to-pointer -> expansions generate dereference - // - else if(e_type_kind_is_pointer_or_ref(type_kind) && e_type_kind_is_pointer_or_ref(direct_type_kind)) - { - total_row_count = 1; - accel->is_ptr2ptr = 1; - } - - //////////////////////////// - //- rjf: package result - // - EV_ExpandInfo result = {0}; - { - result.user_data = accel; - result.row_count = total_row_count; - } - - scratch_end(scratch); - return result; -} - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(default) -{ - EV_DefaultExpandAccel *accel = (EV_DefaultExpandAccel *)user_data; - EV_ExpandRangeInfo result = {0}; - U64 needed_row_count = dim_1u64(idx_range); - - //////////////////////////// - //- rjf: fill with members - // - if(accel->members.count != 0) - { - E_MemberArray *members = &accel->members; - result.row_exprs_count = Min(needed_row_count, members->count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - E_Member *member = &members->v[idx_range.min + row_expr_idx]; - result.row_exprs[row_expr_idx] = e_expr_ref_member_access(arena, expr, member->name); - result.row_members[row_expr_idx] = member; - } - } - - //////////////////////////// - //- rjf: fill with enum vals - // - else if(accel->enum_vals.count != 0) - { - E_EnumValArray *enumvals = &accel->enum_vals; - result.row_exprs_count = Min(needed_row_count, enumvals->count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - E_EnumVal *enumval = &enumvals->v[idx_range.min + row_expr_idx]; - result.row_exprs[row_expr_idx] = e_expr_ref_member_access(arena, expr, enumval->name); - result.row_members[row_expr_idx] = &e_member_nil; - } - } - - //////////////////////////// - //- rjf: fill with array indices - // - else if(accel->array_count != 0) - { - E_Expr *array_expr = accel->array_need_extra_deref ? e_expr_ref_deref(arena, expr) : expr; - result.row_exprs_count = Min(needed_row_count, accel->array_count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - result.row_exprs[row_expr_idx] = e_expr_ref_array_index(arena, array_expr, idx_range.min + row_expr_idx); - result.row_members[row_expr_idx] = &e_member_nil; - } - } - - //////////////////////////// - //- rjf: fill with ptr-to-ptr deref - // - else if(accel->is_ptr2ptr) - { - result.row_exprs_count = 1; - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - result.row_exprs[0] = e_expr_ref_deref(arena, expr); - result.row_members[0] = &e_member_nil; - } - - return result; -} - -//////////////////////////////// -//~ rjf: "array" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(array) -{ - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_TypeKey type_key = irtree.type_key; - E_TypeKind type_kind = e_type_kind_from_key(type_key); - if(e_type_kind_is_pointer_or_ref(type_kind)) - { - E_Value count = ev_value_from_params(params); - E_TypeKey element_type_key = e_type_ptee_from_key(type_key); - E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count.u64); - E_TypeKey ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0); - expr = e_expr_ref_cast(arena, ptr_type_key, expr); - } - scratch_end(scratch); - return expr; -} - -//////////////////////////////// -//~ rjf: "list" - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(list) -{ - EV_ExpandInfo info = {0}; - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(list) -{ - EV_ExpandRangeInfo info = {0}; - return info; -} - -//////////////////////////////// -//~ rjf: "slice" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(slice) -{ - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_TypeKind type_kind = e_type_kind_from_key(irtree.type_key); - if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class) - { - // rjf: unpack members - E_MemberArray members = e_type_data_members_from_key__cached(irtree.type_key); - - // rjf: choose base pointer & count members - E_Member *base_ptr_member = 0; - E_Member *count_member = 0; - for(U64 idx = 0; idx < members.count; idx += 1) - { - E_Member *member = &members.v[idx]; - E_TypeKey member_type = e_type_unwrap(member->type_key); - E_TypeKind member_type_kind = e_type_kind_from_key(member_type); - if(count_member == 0 && e_type_kind_is_integer(member_type_kind)) - { - count_member = member; - } - if(base_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) - { - base_ptr_member = &members.v[idx]; - } - if(count_member != 0 && base_ptr_member != 0) - { - break; - } - } - - // rjf: evaluate count member, determine count - U64 count = 0; - if(count_member != 0) - { - E_Expr *count_member_expr = e_expr_ref_member_access(scratch.arena, expr, count_member->name); - E_Eval count_member_eval = e_eval_from_expr(scratch.arena, count_member_expr); - E_Eval count_member_value_eval = e_value_eval_from_eval(count_member_eval); - count = count_member_value_eval.value.u64; - } - - // rjf: generate new struct slice type - E_TypeKey slice_type_key = zero_struct; - if(base_ptr_member != 0 && count_member != 0) - { - String8 struct_name = e_type_string_from_key(scratch.arena, irtree.type_key); - E_TypeKey element_type_key = e_type_ptee_from_key(base_ptr_member->type_key); - E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count); - E_TypeKey sized_base_ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0); - E_MemberList slice_type_members = {0}; - e_member_list_push(scratch.arena, &slice_type_members, count_member); - e_member_list_push(scratch.arena, &slice_type_members, &(E_Member){.kind = E_MemberKind_DataField, .type_key = sized_base_ptr_type_key, .name = base_ptr_member->name, .pretty_name = base_ptr_member->pretty_name, .off = base_ptr_member->off}); - E_MemberArray slice_type_members_array = e_member_array_from_list(scratch.arena, &slice_type_members); - slice_type_key = e_type_key_cons(.arch = e_type_state->ctx->primary_module->arch, - .kind = E_TypeKind_Struct, - .name = struct_name, - .members = slice_type_members_array.v, - .count = slice_type_members_array.count); - } - - // rjf: generate new expression tree - addr of struct, cast-to-ptr, deref - if(base_ptr_member != 0 && count_member != 0) - { - expr = e_expr_ref_addr(arena, expr); - expr = e_expr_ref_cast(arena, e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, slice_type_key, 0), expr); - expr = e_expr_ref_deref(arena, expr); - } - } - scratch_end(scratch); - return expr; -} - -//////////////////////////////// -//~ rjf: "bswap" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(bswap) -{ - expr = e_expr_ref_bswap(arena, expr); - return expr; -} - -//////////////////////////////// -//~ rjf: "cast" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(cast) -{ - E_TypeKey type_key = ev_type_key_from_params(params); - expr = e_expr_ref_cast(arena, type_key, expr); - return expr; -} - -//////////////////////////////// -//~ rjf: "wrap" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(wrap) -{ - String8 wrap_string = md_string_from_children(arena, params); - E_Expr *wrap_expr = e_parse_expr_from_text(arena, wrap_string); - E_Expr *new_root_expr = wrap_expr; - if(wrap_expr != &e_expr_nil) - { - Temp scratch = scratch_begin(&arena, 1); - typedef struct Task Task; - struct Task - { - Task *next; - E_Expr *parent; - E_Expr *expr; - }; - Task start_task = {0, &e_expr_nil, wrap_expr}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - if(t->expr->kind == E_ExprKind_LeafIdent && str8_match(t->expr->string, str8_lit("$expr"), 0)) - { - E_Expr *original_expr_ref = e_expr_ref(arena, expr); - if(t->parent != &e_expr_nil) - { - e_expr_insert_child(t->parent, t->expr, original_expr_ref); - e_expr_remove_child(t->parent, t->expr); - } - else - { - new_root_expr = original_expr_ref; - } - } - else for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - SLLQueuePush(first_task, last_task, task); - task->parent = t->expr; - task->expr = child; - } - } - scratch_end(scratch); - } - return new_root_expr; -} - -//////////////////////////////// -//~ rjf: "only" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(only) -{ - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_TypeKey type_key = irtree.type_key; - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_direct_from_key(type_key); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - B32 is_ptr = e_type_kind_is_pointer_or_ref(type_kind); - E_TypeKey struct_type_key = is_ptr ? direct_type_key : type_key; - E_TypeKind struct_type_kind = is_ptr ? direct_type_kind : type_kind; - if(struct_type_kind == E_TypeKind_Struct || - struct_type_kind == E_TypeKind_Union || - struct_type_kind == E_TypeKind_Class) - { - E_MemberArray current_members = e_type_data_members_from_key__cached(struct_type_key); - E_MemberList new_members = {0}; - for MD_EachNode(node, params->first) - { - for EachIndex(idx, current_members.count) - { - if(str8_match(node->string, current_members.v[idx].name, 0)) - { - e_member_list_push(scratch.arena, &new_members, ¤t_members.v[idx]); - break; - } - } - } - E_MemberArray new_members_array = e_member_array_from_list(scratch.arena, &new_members); - E_TypeKey new_type = {0}; - if(new_members_array.count == 1 && new_members_array.v[0].off == 0) - { - new_type = new_members_array.v[0].type_key; - } - else - { - String8 struct_name = e_type_string_from_key(scratch.arena, struct_type_key); - new_type = e_type_key_cons(.kind = E_TypeKind_Struct, .name = struct_name, .members = new_members_array.v, .count = new_members_array.count); - } - if(!is_ptr) - { - expr = e_expr_ref_addr(arena, expr); - } - expr = e_expr_ref_cast(arena, e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, new_type, 0), expr); - if(!is_ptr) - { - expr = e_expr_ref_deref(arena, expr); - } - } - scratch_end(scratch); - return expr; -} - -//////////////////////////////// -//~ rjf: "omit" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(omit) -{ - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_TypeKey type_key = irtree.type_key; - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_direct_from_key(type_key); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - B32 is_ptr = e_type_kind_is_pointer_or_ref(type_kind); - E_TypeKey struct_type_key = is_ptr ? direct_type_key : type_key; - E_TypeKind struct_type_kind = is_ptr ? direct_type_kind : type_kind; - if(struct_type_kind == E_TypeKind_Struct || - struct_type_kind == E_TypeKind_Union || - struct_type_kind == E_TypeKind_Class) - { - E_MemberArray current_members = e_type_data_members_from_key__cached(struct_type_key); - E_MemberList new_members = {0}; - for EachIndex(idx, current_members.count) - { - B32 include = 1; - for MD_EachNode(node, params->first) - { - if(str8_match(node->string, current_members.v[idx].name, 0)) - { - include = 0; - break; - } - } - if(include) - { - e_member_list_push(scratch.arena, &new_members, ¤t_members.v[idx]); - } - } - E_MemberArray new_members_array = e_member_array_from_list(scratch.arena, &new_members); - E_TypeKey new_type = {0}; - String8 struct_name = e_type_string_from_key(scratch.arena, struct_type_key); - new_type = e_type_key_cons(.kind = E_TypeKind_Struct, .name = struct_name, .members = new_members_array.v, .count = new_members_array.count); - if(!is_ptr) - { - expr = e_expr_ref_addr(arena, expr); - } - expr = e_expr_ref_cast(arena, e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, new_type, 0), expr); - if(!is_ptr) - { - expr = e_expr_ref_deref(arena, expr); - } - } - scratch_end(scratch); - return expr; -} diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.h b/src/eval_visualization/eval_visualization_builtin_view_rules.h deleted file mode 100644 index 1eb1312c..00000000 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef EVAL_VISUALIZATION_BUILTIN_VIEW_RULES_H -#define EVAL_VISUALIZATION_BUILTIN_VIEW_RULES_H - -//////////////////////////////// -//~ rjf: View Rule Tree Info Extraction Helpers - -internal U64 ev_base_offset_from_eval(E_Eval eval); -internal E_Value ev_value_from_params(MD_Node *params); -internal E_TypeKey ev_type_key_from_params(MD_Node *params); -internal E_Value ev_value_from_params_key(MD_Node *params, String8 key); -internal Rng1U64 ev_range_from_eval_params(E_Eval eval, MD_Node *params); -internal Arch ev_arch_from_eval_params(E_Eval eval, MD_Node *params); - -#endif // EVAL_VISUALIZATION_BUILTIN_VIEW_RULES_H diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index dfaf7e46..7383b24d 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -9,33 +9,12 @@ //////////////////////////////// //~ rjf: Nil/Identity View Rule Hooks -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(identity) -{ - return expr; -} - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(nil) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(nil) { EV_ExpandInfo info = {0}; return info; } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(nil) -{ - EV_ExpandRangeInfo info = {0}; - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity) -{ - return num; -} - -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) -{ - return id; -} - //////////////////////////////// //~ rjf: Key Functions @@ -115,10 +94,19 @@ ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) kind == E_TypeKind_Union || kind == E_TypeKind_Class || kind == E_TypeKind_Array || + kind == E_TypeKind_Set || (kind == E_TypeKind_Enum && mode == E_Mode_Null)) { result = 1; } + if(kind == E_TypeKind_Ptr) + { + E_Type *type = e_type_from_key__cached(t); + if(type->count > 1) + { + result = 1; + } + } } return result; } @@ -130,6 +118,29 @@ ev_type_key_is_editable(E_TypeKey type_key) for(E_TypeKey t = type_key; !result; t = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t)))) { E_TypeKind kind = e_type_kind_from_key(t); + if(kind == E_TypeKind_Array) + { + E_TypeKind element_kind = e_type_kind_from_key(e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t)))); + if(element_kind != E_TypeKind_U8 && + element_kind != E_TypeKind_U16 && + element_kind != E_TypeKind_U32 && + element_kind != E_TypeKind_S8 && + element_kind != E_TypeKind_S16 && + element_kind != E_TypeKind_S32 && + element_kind != E_TypeKind_UChar8 && + element_kind != E_TypeKind_UChar16 && + element_kind != E_TypeKind_UChar32 && + element_kind != E_TypeKind_Char8 && + element_kind != E_TypeKind_Char16 && + element_kind != E_TypeKind_Char32) + { + break; + } + else + { + result = 1; + } + } if(kind == E_TypeKind_Null || kind == E_TypeKind_Function) { break; @@ -337,260 +348,60 @@ ev_key_set_view_rule(EV_View *view, EV_Key key, String8 view_rule_string) //~ rjf: View Rule Info Table Building / Selection / Lookups internal void -ev_view_rule_info_table_push(Arena *arena, EV_ViewRuleInfoTable *table, EV_ViewRuleInfo *info) +ev_expand_rule_table_push(Arena *arena, EV_ExpandRuleTable *table, EV_ExpandRule *info) { if(table->slots_count == 0) { table->slots_count = 512; - table->slots = push_array(arena, EV_ViewRuleInfoSlot, table->slots_count); + table->slots = push_array(arena, EV_ExpandRuleSlot, table->slots_count); } U64 hash = ev_hash_from_seed_string(5381, info->string); U64 slot_idx = hash%table->slots_count; - EV_ViewRuleInfoSlot *slot = &table->slots[slot_idx]; - EV_ViewRuleInfoNode *n = push_array(arena, EV_ViewRuleInfoNode, 1); + EV_ExpandRuleSlot *slot = &table->slots[slot_idx]; + EV_ExpandRuleNode *n = push_array(arena, EV_ExpandRuleNode, 1); SLLQueuePush(slot->first, slot->last, n); MemoryCopyStruct(&n->v, info); n->v.string = push_str8_copy(arena, n->v.string); } internal void -ev_view_rule_info_table_push_builtins(Arena *arena, EV_ViewRuleInfoTable *table) -{ - for EachEnumVal(EV_ViewRuleKind, kind) - { - ev_view_rule_info_table_push(arena, table, &ev_builtin_view_rule_info_table[kind]); - } -} - -internal void -ev_select_view_rule_info_table(EV_ViewRuleInfoTable *table) +ev_select_expand_rule_table(EV_ExpandRuleTable *table) { ev_view_rule_info_table = table; } -internal EV_ViewRuleInfo * -ev_view_rule_info_from_string(String8 string) +internal EV_ExpandRule * +ev_expand_rule_from_string(String8 string) { - EV_ViewRuleInfo *info = &ev_nil_view_rule_info; - U64 hash = ev_hash_from_seed_string(5381, string); - U64 slot_idx = hash%ev_view_rule_info_table->slots_count; - EV_ViewRuleInfoSlot *slot = &ev_view_rule_info_table->slots[slot_idx]; - EV_ViewRuleInfoNode *node = 0; - for(EV_ViewRuleInfoNode *n = slot->first; n != 0; n = n->next) + EV_ExpandRule *info = &ev_nil_expand_rule; + if(ev_view_rule_info_table != 0 && ev_view_rule_info_table->slots_count != 0) { - if(str8_match(n->v.string, string, 0)) + U64 hash = ev_hash_from_seed_string(5381, string); + U64 slot_idx = hash%ev_view_rule_info_table->slots_count; + EV_ExpandRuleSlot *slot = &ev_view_rule_info_table->slots[slot_idx]; + EV_ExpandRuleNode *node = 0; + for(EV_ExpandRuleNode *n = slot->first; n != 0; n = n->next) { - node = n; - break; + if(str8_match(n->v.string, string, 0)) + { + node = n; + break; + } + } + if(node != 0) + { + info = &node->v; } - } - if(node != 0) - { - info = &node->v; } return info; } -//////////////////////////////// -//~ rjf: Automatic Type -> View Rule Table Building / Selection / Lookups - -internal void -ev_auto_view_rule_table_push_new(Arena *arena, EV_AutoViewRuleTable *table, E_TypeKey type_key, String8 view_rule, B32 is_required) -{ - if(table->slots_count == 0) - { - table->slots_count = 4096; - table->slots = push_array(arena, EV_AutoViewRuleSlot, table->slots_count); - } - U64 hash = e_hash_from_type_key(type_key); - U64 slot_idx = hash%table->slots_count; - EV_AutoViewRuleSlot *slot = &table->slots[slot_idx]; - EV_AutoViewRuleNode *node = 0; - for(EV_AutoViewRuleNode *n = slot->first; n != 0; n = n->next) - { - if(e_type_match(n->key, type_key)) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(arena, EV_AutoViewRuleNode, 1); - node->key = type_key; - node->view_rule = push_str8_copy(arena, view_rule); - node->is_required = is_required; - SLLQueuePush(slot->first, slot->last, node); - } -} - -internal void -ev_select_auto_view_rule_table(EV_AutoViewRuleTable *table) -{ - ev_auto_view_rule_table = table; -} - -internal EV_ViewRuleList * -ev_auto_view_rules_from_type_key(Arena *arena, E_TypeKey type_key, B32 gather_required, B32 gather_optional) -{ - EV_ViewRuleList *result = &ev_nil_view_rule_list; - if(ev_auto_view_rule_table != 0 && ev_auto_view_rule_table->slots_count != 0) - { - U64 hash = e_hash_from_type_key(type_key); - U64 slot_idx = hash%ev_auto_view_rule_table->slots_count; - EV_AutoViewRuleSlot *slot = &ev_auto_view_rule_table->slots[slot_idx]; - EV_AutoViewRuleNode *node = 0; - for(EV_AutoViewRuleNode *n = slot->first; n != 0; n = n->next) - { - if(e_type_match(n->key, type_key) && ((n->is_required && gather_required) || (!n->is_required && gather_optional))) - { - if(result == &ev_nil_view_rule_list) - { - result = push_array(arena, EV_ViewRuleList, 1); - } - ev_view_rule_list_push_string(arena, result, n->view_rule); - } - } - } - return result; -} - -//////////////////////////////// -//~ rjf: View Rule Instance List Building - -internal void -ev_view_rule_list_push_tree(Arena *arena, EV_ViewRuleList *list, MD_Node *root) -{ - EV_ViewRuleNode *n = push_array(arena, EV_ViewRuleNode, 1); - n->v.root = root; - SLLQueuePush(list->first, list->last, n); - list->count += 1; -} - -internal void -ev_view_rule_list_push_string(Arena *arena, EV_ViewRuleList *list, String8 string) -{ - if(string.size != 0) - { - MD_Node *root = md_tree_from_string(arena, string); - for MD_EachNode(tln, root->first) - { - ev_view_rule_list_push_tree(arena, list, tln); - } - } -} - -internal EV_ViewRuleList * -ev_view_rule_list_from_string(Arena *arena, String8 string) -{ - EV_ViewRuleList *dst = push_array(arena, EV_ViewRuleList, 1); - ev_view_rule_list_push_string(arena, dst, string); - return dst; -} - -internal EV_ViewRuleList * -ev_view_rule_list_from_expr_fastpaths(Arena *arena, String8 string) -{ - Temp scratch = scratch_begin(&arena, 1); - - // rjf: parse expression - E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); - - // rjf: extract view rules, encoded via fastpaths in expression string - String8List fastpath_view_rules = {0}; - { - U64 parse_opl = (parse.last_token >= tokens.v + tokens.count ? string.size : parse.last_token->range.min); - U64 comma_pos = str8_find_needle(string, parse_opl, str8_lit(","), 0); - U64 passthrough_pos = str8_find_needle(string, 0, str8_lit("--"), 0); - if(comma_pos < string.size && comma_pos < passthrough_pos) - { - String8 comma_extension = str8_skip_chop_whitespace(str8_substr(string, r1u64(comma_pos+1, passthrough_pos))); - if(str8_match(comma_extension, str8_lit("x"), StringMatchFlag_CaseInsensitive)) - { - str8_list_pushf(scratch.arena, &fastpath_view_rules, "hex"); - } - else if(str8_match(comma_extension, str8_lit("b"), StringMatchFlag_CaseInsensitive)) - { - str8_list_pushf(scratch.arena, &fastpath_view_rules, "bin"); - } - else if(str8_match(comma_extension, str8_lit("o"), StringMatchFlag_CaseInsensitive)) - { - str8_list_pushf(scratch.arena, &fastpath_view_rules, "oct"); - } - else if(comma_extension.size != 0) - { - str8_list_pushf(scratch.arena, &fastpath_view_rules, "array:{%S}", comma_extension); - } - } - if(passthrough_pos < string.size) - { - String8 passthrough_view_rule = str8_skip_chop_whitespace(str8_skip(string, passthrough_pos+2)); - if(passthrough_view_rule.size != 0) - { - str8_list_push(scratch.arena, &fastpath_view_rules, passthrough_view_rule); - } - } - } - - // rjf: convert strings to parsed view rules - EV_ViewRuleList *view_rule_list = push_array(arena, EV_ViewRuleList, 1); - for(String8Node *n = fastpath_view_rules.first; n != 0; n = n->next) - { - ev_view_rule_list_push_string(arena, view_rule_list, push_str8_copy(arena, n->string)); - } - - scratch_end(scratch); - return view_rule_list; -} - -internal EV_ViewRuleList * -ev_view_rule_list_from_inheritance(Arena *arena, EV_ViewRuleList *src) -{ - EV_ViewRuleList *dst = push_array(arena, EV_ViewRuleList, 1); - for(EV_ViewRuleNode *n = src->first; n != 0; n = n->next) - { - EV_ViewRuleInfo *info = ev_view_rule_info_from_string(n->v.root->string); - if(info->flags & EV_ViewRuleInfoFlag_Inherited) - { - ev_view_rule_list_push_tree(arena, dst, n->v.root); - } - } - return dst; -} - -internal EV_ViewRuleList * -ev_view_rule_list_copy(Arena *arena, EV_ViewRuleList *src) -{ - EV_ViewRuleList *dst = push_array(arena, EV_ViewRuleList, 1); - for(EV_ViewRuleNode *n = src->first; n != 0; n = n->next) - { - ev_view_rule_list_push_tree(arena, dst, n->v.root); - } - return dst; -} - -internal void -ev_view_rule_list_concat_in_place(EV_ViewRuleList *dst, EV_ViewRuleList **src) -{ - if(dst->first && src[0] != &ev_nil_view_rule_list && src[0]->first) - { - dst->last->next = src[0]->first; - dst->last = src[0]->last; - dst->count += src[0]->count; - } - else if(!dst->first) - { - MemoryCopyStruct(dst, *src); - } - *src = &ev_nil_view_rule_list; -} - //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) +#if 0 // TODO(rjf): @cfg (dynamic type resolution) internal E_Expr * -ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules) +ev_resolved_from_expr(Arena *arena, E_Expr *expr) { ProfBeginFunction(); { @@ -602,7 +413,7 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules) E_TypeKind ptee_type_kind = e_type_kind_from_key(ptee_type_key); if(ptee_type_kind == E_TypeKind_Struct || ptee_type_kind == E_TypeKind_Class) { - E_Type *ptee_type = e_type_from_key(scratch.arena, ptee_type_key); + E_Type *ptee_type = e_type_from_key__cached(ptee_type_key); B32 has_vtable = 0; for(U64 idx = 0; idx < ptee_type->count; idx += 1) { @@ -646,8 +457,8 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules) RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, global_var->container_idx); RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, rdi_idx); - E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 0); - expr = e_expr_ref_cast(arena, ptr_to_derived_type_key, expr); + E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 1, 0); + expr = e_expr_irext_cast(arena, ptr_to_derived_type_key); } } } @@ -655,45 +466,92 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules) } scratch_end(scratch); } - for(EV_ViewRuleNode *n = view_rules->first; n != 0; n = n->next) - { - EV_ViewRuleInfo *info = ev_view_rule_info_from_string(n->v.root->string); - if(info->expr_resolution != 0) - { - expr = info->expr_resolution(arena, expr, n->v.root); - } - } ProfEnd(); return expr; } +#endif + +//////////////////////////////// +//~ rjf: Upgrading Expressions w/ Tags From All Sources + +internal void +ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr) +{ + Temp scratch = scratch_begin(&arena, 1); + if(expr != &e_expr_nil) + { + // rjf: push inherited tags first (we want these to be found first, since tags are applied + // in order, and explicit ones should always be strongest) + { + for(E_Expr *src_tag = block->expr->first_tag; src_tag != &e_expr_nil; src_tag = src_tag->next) + { + B32 is_inherited = 0; + // TODO(rjf): table-drive this + if(str8_match(src_tag->string, str8_lit("hex"), 0) || + str8_match(src_tag->string, str8_lit("oct"), 0) || + str8_match(src_tag->string, str8_lit("bin"), 0) || + str8_match(src_tag->string, str8_lit("dec"), 0) || + str8_match(src_tag->string, str8_lit("no_addr"), 0) || + str8_match(src_tag->string, str8_lit("digits"), 0) || + str8_match(src_tag->string, str8_lit("no_string"), 0) || + str8_match(src_tag->string, str8_lit("only"), 0) || + str8_match(src_tag->string, str8_lit("omit"), 0)) + { + is_inherited = 1; + } + if(is_inherited) + { + e_expr_push_tag(expr, e_expr_copy(arena, src_tag)); + } + } + } + + // rjf: push tags inferred from the type + { + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); + E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree.type_key); + for(E_ExprNode *n = tags.first; n != 0; n = n->next) + { + e_expr_push_tag(expr, e_expr_copy(arena, n->v)); + } + } + + // rjf: push explicitly-attached tags (via key) next + String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); + E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); + E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); + for(E_Expr *tag = tag_expr_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) + { + next = tag->next; + e_expr_push_tag(expr, tag); + } + } + scratch_end(scratch); +} //////////////////////////////// //~ rjf: Block Building internal EV_BlockTree -ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules) +ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChain exprs) { ProfBeginFunction(); EV_BlockTree tree = {&ev_nil_block}; { Temp scratch = scratch_begin(&arena, 1); - EV_ViewRuleInfo *default_expand_view_rule_info = ev_view_rule_info_from_string(str8_lit("default")); - //- rjf: form complete set of view rules - EV_ViewRuleList *top_level_view_rules = ev_view_rule_list_copy(arena, view_rules); - { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - EV_ViewRuleList *auto_view_rules = ev_auto_view_rules_from_type_key(arena, irtree.type_key, 1, 1); - ev_view_rule_list_concat_in_place(top_level_view_rules, &auto_view_rules); - } + //- rjf: generate root expression + EV_Key root_key = ev_key_root(); + EV_Key root_row_key = ev_key_make(ev_hash_from_key(root_key), 1); + E_Expr *root_expr = e_expr_copy(arena, exprs.last); + ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_row_key, root_expr); //- rjf: generate root block tree.root = push_array(arena, EV_Block, 1); MemoryCopyStruct(tree.root, &ev_nil_block); - tree.root->key = ev_key_root(); - tree.root->string = string; - tree.root->expr = ev_resolved_from_expr(arena, expr, top_level_view_rules); - tree.root->view_rules = top_level_view_rules; + tree.root->key = root_key; + tree.root->string = str8_zero(); + tree.root->expr = root_expr; tree.root->row_count = 1; tree.total_row_count += 1; tree.total_item_count += 1; @@ -706,11 +564,10 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str EV_Block *parent_block; E_Expr *expr; U64 child_id; - EV_ViewRuleList *view_rules; U64 split_relative_idx; B32 default_expanded; }; - Task start_task = {0, tree.root, tree.root->expr, 1, top_level_view_rules, 0}; + Task start_task = {0, tree.root, tree.root->expr, 1, 0}; Task *first_task = &start_task; Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) @@ -732,25 +589,47 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str continue; } - // rjf: get expansion view rule info - EV_ViewRuleInfo *expand_view_rule_info = default_expand_view_rule_info; - MD_Node *expand_params = &md_nil_node; - for(EV_ViewRuleNode *n = t->view_rules->first; n != 0; n = n->next) + // rjf: unpack expr + E_IRTreeAndType expr_irtree = e_irtree_and_type_from_expr(scratch.arena, t->expr); + + // rjf: get expr's expansion rule + EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); + EV_ExpandRule *expand_rule = expand_rule_and_tag.rule; + E_Expr *expand_rule_tag = expand_rule_and_tag.tag; + + // rjf: skip if no expansion rule, & type info disallows expansion + if(expand_rule == &ev_nil_expand_rule && !ev_type_key_and_mode_is_expandable(expr_irtree.type_key, expr_irtree.mode)) { - EV_ViewRuleInfo *info = ev_view_rule_info_from_string(n->v.root->string); - if(info->expr_expand_info != 0 && info->expr_expand_info != EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil)) - { - expand_view_rule_info = info; - expand_params = n->v.root; - } + continue; } - // rjf: get expansion info - EV_ExpandInfo expand_info = expand_view_rule_info->expr_expand_info(arena, view, filter, t->expr, expand_params); + // rjf: get expr's lookup rule + E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); + E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; + E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; + + // rjf: get top-level lookup/expansion info + E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, lookup_rule_and_tag.tag, filter); + EV_ExpandInfo expand_info = expand_rule->info(arena, view, filter, t->expr, expand_rule_tag); + + // rjf: determine expansion info + U64 expansion_row_count = lookup_info.named_expr_count ? lookup_info.named_expr_count : lookup_info.idxed_expr_count; + if(expand_rule != &ev_nil_expand_rule) + { + expansion_row_count = expand_info.row_count; + } + + // rjf: determine if this expansion supports child expansions + B32 allow_child_expansions = 1; + if(expand_info.single_item) + { + // NOTE(rjf): for now, just plugging in the heuristic of "is this a single row (a.k.a. visualizer)?" + allow_child_expansions = 0; + } // rjf: generate block for expansion EV_Block *expansion_block = &ev_nil_block; - if(expand_info.row_count != 0) + if(expansion_row_count != 0) { expansion_block = push_array(arena, EV_Block, 1); MemoryCopyStruct(expansion_block, &ev_nil_block); @@ -759,22 +638,24 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str expansion_block->key = key; expansion_block->split_relative_idx = t->split_relative_idx; expansion_block->expr = t->expr; - expansion_block->view_rules = t->view_rules; - expansion_block->expand_view_rule_info = expand_view_rule_info; - expansion_block->expand_view_rule_params = expand_params; - expansion_block->expand_view_rule_info_user_data = expand_info.user_data; - expansion_block->row_count = expand_info.row_count; + expansion_block->lookup_tag = lookup_rule_tag; + expansion_block->expand_tag = expand_rule_tag; + expansion_block->lookup_rule = lookup_rule; + expansion_block->expand_rule = expand_rule; + expansion_block->lookup_rule_user_data = lookup_info.user_data; + expansion_block->expand_rule_user_data = expand_info.user_data; + expansion_block->row_count = expansion_row_count; expansion_block->single_item = expand_info.single_item; expansion_block->rows_default_expanded = expand_info.rows_default_expanded; - tree.total_row_count += expand_info.row_count; - tree.total_item_count += expand_info.single_item ? 1 : expand_info.row_count; + tree.total_row_count += expansion_row_count; + tree.total_item_count += expand_info.single_item ? 1 : expansion_row_count; } // rjf: gather children expansions from expansion state U64 child_count = 0; EV_Key *child_keys = 0; U64 *child_nums = 0; - if(!child_count && !expand_info.rows_default_expanded && expand_node != 0 && expand_info.row_count != 0 && expand_view_rule_info->expr_expand_range_info) + if(allow_child_expansions && !child_count && !expand_info.rows_default_expanded && expand_node != 0 && expansion_row_count != 0) { // rjf: count children for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, child_count += 1){} @@ -788,7 +669,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, idx += 1) { child_keys[idx] = child->key; - child_nums[idx] = expand_view_rule_info->expr_expand_num_from_id(child->key.child_id, expand_info.user_data); + child_nums[idx] = lookup_rule->num_from_id(child->key.child_id, lookup_info.user_data); if(child_nums[idx] != child_keys[idx].child_id) { needs_sort = 1; @@ -821,14 +702,14 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str } // rjf: gather children expansions from inverse of expansion state - if(!child_count && (expand_info.rows_default_expanded || (expand_node == 0 && !expand_info.rows_default_expanded))) + if(allow_child_expansions && !child_count && (expand_info.rows_default_expanded || (expand_node == 0 && !expand_info.rows_default_expanded))) { child_count = expand_info.row_count; child_keys = push_array(scratch.arena, EV_Key, child_count); child_nums = push_array(scratch.arena, U64, child_count); for(U64 idx = 0; idx < child_count; idx += 1) { - U64 child_id = expand_view_rule_info->expr_expand_id_from_num(idx+1, expand_info.user_data); + U64 child_id = lookup_rule->id_from_num(idx+1, lookup_info.user_data); child_keys[idx] = ev_key_make(ev_hash_from_key(key), child_id); child_nums[idx] = idx+1; } @@ -839,39 +720,25 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str { U64 split_num = child_nums[idx]; U64 split_relative_idx = split_num - 1; - if(split_relative_idx >= expand_info.row_count) + if(split_relative_idx >= expansion_row_count) { continue; } if(expand_info.rows_default_expanded || ev_expansion_from_key(view, child_keys[idx])) { - EV_ExpandRangeInfo child_expand = expand_view_rule_info->expr_expand_range_info(arena, view, filter, t->expr, expand_params, r1u64(split_relative_idx, split_relative_idx+1), expand_info.user_data); - if(child_expand.row_exprs_count > 0) + Rng1U64 child_range = r1u64(split_relative_idx, split_relative_idx+1); + E_Expr *child_expr = &e_expr_nil; + String8 child_string = {0}; + lookup_rule->range(arena, t->expr, lookup_rule_tag, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string, lookup_info.user_data); + if(child_expr != &e_expr_nil) { EV_Key child_key = child_keys[idx]; - E_Expr *child_expr = child_expand.row_exprs[0]; - EV_ViewRuleList *child_view_rules = ev_view_rule_list_from_inheritance(arena, t->view_rules); - String8 child_view_rule_string = ev_view_rule_from_key(view, child_key); - ev_view_rule_list_push_string(arena, child_view_rules, child_view_rule_string); - if(child_expand.row_strings[0].size != 0) - { - EV_ViewRuleList *fastpath_view_rules = ev_view_rule_list_from_expr_fastpaths(arena, child_expand.row_strings[0]); - ev_view_rule_list_concat_in_place(child_view_rules, &fastpath_view_rules); - } - { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType child_irtree = e_irtree_and_type_from_expr(scratch.arena, child_expr); - EV_ViewRuleList *child_auto_view_rules = ev_auto_view_rules_from_type_key(arena, child_irtree.type_key, 1, child_view_rule_string.size == 0); - ev_view_rule_list_concat_in_place(child_view_rules, &child_auto_view_rules); - scratch_end(scratch); - } - E_Expr *child_expr__resolved = ev_resolved_from_expr(arena, child_expr, child_view_rules); + ev_keyed_expr_push_tags(arena, view, expansion_block, child_key, child_expr); Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->parent_block = expansion_block; - task->expr = child_expr__resolved; + task->expr = child_expr; task->child_id = child_key.child_id; - task->view_rules = child_view_rules; task->split_relative_idx = split_relative_idx; task->default_expanded = expand_info.rows_default_expanded; } @@ -884,25 +751,6 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str return tree; } -internal EV_BlockTree -ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules) -{ - ProfBeginFunction(); - EV_BlockTree tree = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(arena, string, &tokens); - EV_ViewRuleList *fastpath_view_rules = ev_view_rule_list_from_expr_fastpaths(arena, string); - EV_ViewRuleList *all_view_rules = ev_view_rule_list_copy(arena, view_rules); - ev_view_rule_list_concat_in_place(all_view_rules, &fastpath_view_rules); - tree = ev_block_tree_from_expr(arena, view, filter, string, parse.expr, all_view_rules); - } - scratch_end(scratch); - ProfEnd(); - return tree; -} - internal U64 ev_depth_from_block(EV_Block *block) { @@ -985,7 +833,7 @@ internal EV_BlockRange ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num) { EV_BlockRange result = {&ev_nil_block}; - U64 base_num = 0; + U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { U64 range_size = n->v.block->single_item ? 1 : dim_1u64(n->v.range); @@ -1008,7 +856,7 @@ ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num) { key = ev_key_make(ev_hash_from_key(ev_key_root()), 1); } - U64 base_num = 0; + U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { U64 range_size = n->v.block->single_item ? 1 : dim_1u64(n->v.range); @@ -1016,7 +864,7 @@ ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num) if(contains_1u64(global_range, num)) { U64 relative_num = (num - base_num) + n->v.range.min + 1; - U64 child_id = n->v.block->expand_view_rule_info->expr_expand_id_from_num(relative_num, n->v.block->expand_view_rule_info_user_data); + U64 child_id = n->v.block->lookup_rule->id_from_num(relative_num, n->v.block->lookup_rule_user_data); EV_Key block_key = n->v.block->key; key = ev_key_make(ev_hash_from_key(block_key), child_id); break; @@ -1030,13 +878,13 @@ internal U64 ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key) { U64 result = 0; - U64 base_num = 0; + U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { U64 hash = ev_hash_from_key(n->v.block->key); if(hash == key.parent_hash) { - U64 relative_num = n->v.block->expand_view_rule_info->expr_expand_num_from_id(key.child_id, n->v.block->expand_view_rule_info_user_data); + U64 relative_num = n->v.block->lookup_rule->num_from_id(key.child_id, n->v.block->lookup_rule_user_data); Rng1U64 num_range = r1u64(n->v.range.min, n->v.block->single_item ? (n->v.range.min+1) : n->v.range.max); if(contains_1u64(num_range, relative_num-1)) { @@ -1049,34 +897,84 @@ ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key) return result; } +internal U64 +ev_vnum_from_num(EV_BlockRangeList *block_ranges, U64 num) +{ + U64 vnum = 0; + { + U64 base_vnum = 1; + U64 base_num = 1; + for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) + { + U64 next_base_num = base_num + (n->v.block->single_item ? 1 : dim_1u64(n->v.range)); + if(base_num <= num && num < next_base_num) + { + U64 relative_vnum = (n->v.block->single_item ? 0 : (num - base_num)); + vnum = base_vnum + relative_vnum; + break; + } + base_num = next_base_num; + base_vnum += dim_1u64(n->v.range); + } + if(vnum == 0) + { + vnum = base_vnum; + } + } + return vnum; +} + +internal U64 +ev_num_from_vnum(EV_BlockRangeList *block_ranges, U64 vnum) +{ + U64 num = 0; + { + U64 base_vnum = 1; + U64 base_num = 1; + for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) + { + U64 next_base_vnum = base_vnum + dim_1u64(n->v.range); + if(base_vnum <= vnum && vnum < next_base_vnum) + { + U64 relative_num = (n->v.block->single_item ? 0 : (vnum - base_vnum)); + num = base_num + relative_num; + break; + } + base_vnum = next_base_vnum; + base_num += (n->v.block->single_item ? 1 : dim_1u64(n->v.range)); + } + } + return num; +} + //////////////////////////////// //~ rjf: Row Building internal EV_WindowedRowList -ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 visible_range) +ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 vnum_range) { EV_WindowedRowList rows = {0}; { - U64 visual_idx_off = 0; + U64 base_vnum = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { // rjf: unpack this block/range pair Rng1U64 block_relative_range = n->v.range; U64 block_num_visual_rows = dim_1u64(block_relative_range); - Rng1U64 block_global_range = r1u64(visual_idx_off, visual_idx_off + block_num_visual_rows); + Rng1U64 block_global_range = r1u64(base_vnum, base_vnum + block_num_visual_rows); // rjf: get skip/chop of global range U64 num_skipped = 0; U64 num_chopped = 0; { - if(visible_range.min > block_global_range.min) + if(vnum_range.min > block_global_range.min) { - num_skipped = (visible_range.min - block_global_range.min); + num_skipped = (vnum_range.min - block_global_range.min); num_skipped = Min(num_skipped, block_num_visual_rows); } - if(visible_range.max < block_global_range.max) + if(vnum_range.max < block_global_range.max) { - num_chopped = (block_global_range.max - visible_range.max); + num_chopped = (block_global_range.max - vnum_range.max); num_chopped = Min(num_chopped, block_num_visual_rows); } } @@ -1086,7 +984,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 block_relative_range.max - num_chopped); // rjf: sum & advance - visual_idx_off += block_num_visual_rows; + base_vnum += block_num_visual_rows; rows.count_before_visual += num_skipped; if(block_num_visual_rows != 0 && num_skipped != 0) { @@ -1107,97 +1005,57 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 if(block_relative_range__windowed.max > block_relative_range__windowed.min) { // rjf: get info about expansion range - EV_ExpandRangeInfo expand_range_info = n->v.block->expand_view_rule_info->expr_expand_range_info(arena, view, filter, n->v.block->expr, n->v.block->expand_view_rule_params, block_relative_range__windowed, n->v.block->expand_view_rule_info_user_data); + B32 is_root = 0; + U64 range_exprs_count = dim_1u64(block_relative_range__windowed); + E_Expr **range_exprs = push_array(arena, E_Expr *, range_exprs_count); + String8 *range_exprs_strings = push_array(arena, String8 ,range_exprs_count); + for EachIndex(idx, range_exprs_count) + { + range_exprs[idx] = &e_expr_nil; + } + if(n->v.block->lookup_rule == &e_lookup_rule__nil || + n->v.block->single_item) + { + is_root = 1; + } + else + { + n->v.block->lookup_rule->range(arena, n->v.block->expr, n->v.block->lookup_tag, filter, block_relative_range__windowed, range_exprs, range_exprs_strings, n->v.block->lookup_rule_user_data); + } // rjf: no expansion operator applied -> push row for block expression; pass through block info - if(expand_range_info.row_exprs_count == 0) + if(is_root) { - E_Member *member = &e_member_nil; - if(n->v.block->expr->kind == E_ExprKind_MemberAccess) - { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, n->v.block->expr->first); - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_Member expr_member = e_type_member_from_key_name__cached(lhs_type_key, n->v.block->expr->last->string); - if(expr_member.kind != E_MemberKind_Null) - { - member = push_array(arena, E_Member, 1); - MemoryCopyStruct(member, &expr_member); - } - scratch_end(scratch); - } - EV_Row *row = push_array(arena, EV_Row, 1); - SLLQueuePush(rows.first, rows.last, row); + EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); + SLLQueuePush(rows.first, rows.last, row_node); rows.count += 1; - row->block = n->v.block; - row->key = ev_key_make(ev_hash_from_key(row->block->key), 1); - row->visual_size = n->v.block->single_item ? (n->v.block->row_count - (num_skipped + num_chopped)) : 1; - row->visual_size_skipped = num_skipped; - row->visual_size_chopped = num_chopped; - row->string = n->v.block->string; - row->expr = n->v.block->expr; - row->member = member; - row->view_rules = n->v.block->view_rules; + row_node->visual_size_skipped = num_skipped; + row_node->visual_size_chopped = num_chopped; + EV_Row *row = &row_node->row; + row->block = n->v.block; + row->key = ev_key_make(ev_hash_from_key(row->block->key), 1); + row->visual_size = n->v.block->single_item ? (n->v.block->row_count - (num_skipped + num_chopped)) : 1; + row->string = n->v.block->string; + row->expr = n->v.block->expr; } // rjf: expansion operator applied -> call, and add rows for all expressions in the viewable range - else + else for EachIndex(idx, range_exprs_count) { - for EachIndex(idx, expand_range_info.row_exprs_count) - { - U64 child_num = block_relative_range.min + num_skipped + idx + 1; - U64 child_id = n->v.block->expand_view_rule_info->expr_expand_id_from_num(child_num, n->v.block->expand_view_rule_info_user_data); - EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); - E_Expr *row_expr = expand_range_info.row_exprs[idx]; - EV_ViewRuleList *row_view_rules = ev_view_rule_list_from_inheritance(arena, n->v.block->view_rules); - String8 row_view_rule_string = ev_view_rule_from_key(view, row_key); - ev_view_rule_list_push_string(arena, row_view_rules, row_view_rule_string); - if(expand_range_info.row_strings[idx].size != 0) - { - EV_ViewRuleList *fastpath_view_rules = ev_view_rule_list_from_expr_fastpaths(arena, expand_range_info.row_strings[idx]); - ev_view_rule_list_concat_in_place(row_view_rules, &fastpath_view_rules); - } - { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType row_irtree = e_irtree_and_type_from_expr(scratch.arena, row_expr); - EV_ViewRuleList *row_auto_view_rules = ev_auto_view_rules_from_type_key(arena, row_irtree.type_key, 1, row_view_rule_string.size == 0); - ev_view_rule_list_concat_in_place(row_view_rules, &row_auto_view_rules); - scratch_end(scratch); - } - E_Expr *row_expr__resolved = ev_resolved_from_expr(arena, row_expr, row_view_rules); - EV_Row *row = push_array(arena, EV_Row, 1); - SLLQueuePush(rows.first, rows.last, row); - rows.count += 1; - row->block = n->v.block; - row->key = row_key; - row->visual_size = 1; - row->visual_size_skipped = 0; - row->visual_size_chopped = 0; - row->string = expand_range_info.row_strings[idx]; - row->expr = row_expr__resolved; - row->member = expand_range_info.row_members[idx]; - row->view_rules = row_view_rules; - if(row->member == &e_member_nil || row->member == 0) - { - if(row->expr->kind == E_ExprKind_MemberAccess) - { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr->first); - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_Member expr_member = e_type_member_from_key_name__cached(lhs_type_key, row->expr->last->string); - if(expr_member.kind != E_MemberKind_Null) - { - row->member = push_array(arena, E_Member, 1); - MemoryCopyStruct(row->member, &expr_member); - } - scratch_end(scratch); - } - } - if(expand_range_info.row_view_rules[idx].size != 0) - { - ev_key_set_view_rule(view, row->key, expand_range_info.row_view_rules[idx]); - } - } + U64 child_num = block_relative_range.min + num_skipped + idx + 1; + U64 child_id = n->v.block->lookup_rule->id_from_num(child_num, n->v.block->lookup_rule_user_data); + EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); + E_Expr *row_expr = range_exprs[idx]; + ev_keyed_expr_push_tags(arena, view, n->v.block, row_key, row_expr); + EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); + SLLQueuePush(rows.first, rows.last, row_node); + rows.count += 1; + EV_Row *row = &row_node->row; + row->block = n->v.block; + row->key = row_key; + row->visual_size = 1; + row->string = range_exprs_strings[idx]; + row->expr = row_expr; } } } @@ -1205,6 +1063,33 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 return rows; } +internal EV_Row * +ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, U64 num) +{ + U64 vidx = ev_vnum_from_num(block_ranges, num); + EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, filter, block_ranges, r1u64(vidx, vidx+1)); + EV_Row *result = 0; + if(rows.first != 0) + { + result = &rows.first->row; + } + else + { + result = push_array(arena, EV_Row, 1); + result->block = &ev_nil_block; + result->expr = &e_expr_nil; + } + return result; +} + +internal EV_WindowedRowList +ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 num_range) +{ + Rng1U64 vnum_range = r1u64(ev_vnum_from_num(block_ranges, num_range.min), ev_vnum_from_num(block_ranges, num_range.max)+1); + EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, filter, block_ranges, vnum_range); + return rows; +} + internal String8 ev_expr_string_from_row(Arena *arena, EV_Row *row, EV_StringFlags flags) { @@ -1239,14 +1124,7 @@ ev_expr_string_from_row(Arena *arena, EV_Row *row, EV_StringFlags flags) }break; case E_ExprKind_MemberAccess: { - if(flags & EV_StringFlag_PrettyNames && row->member->pretty_name.size != 0) - { - result = push_str8_copy(arena, row->member->pretty_name); - } - else - { - result = push_str8f(arena, ".%S", e_string_from_expr(arena, notable_expr->last)); - } + result = push_str8f(arena, ".%S", e_string_from_expr(arena, notable_expr->last)); }break; } return result; @@ -1256,29 +1134,28 @@ internal B32 ev_row_is_expandable(EV_Row *row) { B32 result = 0; + if(!ev_key_match(ev_key_root(), row->block->key)) { + Temp scratch = scratch_begin(0, 0); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr); + // rjf: determine if view rules force expandability if(!result) { - for(EV_ViewRuleNode *n = row->view_rules->first; n != 0; n = n->next) + EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(row->expr, &irtree); + if(expand_rule_and_tag.rule != &ev_nil_expand_rule) { - EV_ViewRuleInfo *info = ev_view_rule_info_from_string(n->v.root->string); - if(info->flags & EV_ViewRuleInfoFlag_Expandable) - { - result = 1; - break; - } + result = 1; } } // rjf: determine if type info force expandability if(!result) { - Temp scratch = scratch_begin(0, 0); E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr); result = ev_type_key_and_mode_is_expandable(irtree.type_key, irtree.mode); - scratch_end(scratch); } + scratch_end(scratch); } return result; } @@ -1482,7 +1359,7 @@ internal String8 ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, U32 min_digits, E_Eval eval) { String8 result = {0}; - E_TypeKey type_key = e_type_unwrap(eval.type_key); + E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); E_TypeKind type_kind = e_type_kind_from_key(type_key); U64 type_byte_size = e_type_byte_size_from_key(type_key); U8 digit_group_separator = 0; @@ -1614,7 +1491,7 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, case E_TypeKind_Enum: { Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, type_key); + E_Type *type = e_type_from_key__cached(type_key); String8 constant_name = {0}; for(U64 val_idx = 0; val_idx < type->count; val_idx += 1) { @@ -1692,3 +1569,45 @@ ev_escaped_from_raw_string(Arena *arena, String8 raw) scratch_end(scratch); return result; } + +//////////////////////////////// +//~ rjf: Expression & IR-Tree => Expand Rule + +internal EV_ExpandRuleTagPair +ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) +{ + EV_ExpandRuleTagPair result = {&ev_nil_expand_rule, &e_expr_nil}; + { + // rjf: first try explicitly-stored tags + if(result.rule == &ev_nil_expand_rule) + { + for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) + { + EV_ExpandRule *candidate = ev_expand_rule_from_string(tag->string); + if(candidate != &ev_nil_expand_rule) + { + result.rule = candidate; + result.tag = tag; + break; + } + } + } + + // rjf: next try auto hook map + if(result.rule == &ev_nil_expand_rule) + { + E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree->type_key); + for(E_ExprNode *n = tags.first; n != 0; n = n->next) + { + EV_ExpandRule *candidate = ev_expand_rule_from_string(n->v->string); + if(candidate != &ev_nil_expand_rule) + { + result.rule = candidate; + result.tag = n->v; + break; + } + } + } + } + return result; +} diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 41b9d403..57e24759 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -75,31 +75,7 @@ struct EV_View }; //////////////////////////////// -//~ rjf: View Rule Instance Types - -typedef struct EV_ViewRule EV_ViewRule; -struct EV_ViewRule -{ - MD_Node *root; -}; - -typedef struct EV_ViewRuleNode EV_ViewRuleNode; -struct EV_ViewRuleNode -{ - EV_ViewRuleNode *next; - EV_ViewRule v; -}; - -typedef struct EV_ViewRuleList EV_ViewRuleList; -struct EV_ViewRuleList -{ - EV_ViewRuleNode *first; - EV_ViewRuleNode *last; - U64 count; -}; - -//////////////////////////////// -//~ rjf: View Rule Info Types +//~ rjf: Expansion Rule Types typedef struct EV_ExpandInfo EV_ExpandInfo; struct EV_ExpandInfo @@ -111,82 +87,46 @@ struct EV_ExpandInfo B32 rows_default_expanded; }; -typedef struct EV_ExpandRangeInfo EV_ExpandRangeInfo; -struct EV_ExpandRangeInfo -{ - U64 row_exprs_count; - String8 *row_strings; - String8 *row_view_rules; - E_Expr **row_exprs; - E_Member **row_members; -}; +#define EV_EXPAND_RULE_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, E_Expr *tag) +#define EV_EXPAND_RULE_INFO_FUNCTION_NAME(name) ev_expand_rule_info__##name +#define EV_EXPAND_RULE_INFO_FUNCTION_DEF(name) internal EV_EXPAND_RULE_INFO_FUNCTION_SIG(EV_EXPAND_RULE_INFO_FUNCTION_NAME(name)) +typedef EV_EXPAND_RULE_INFO_FUNCTION_SIG(EV_ExpandRuleInfoHookFunctionType); -#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(name) E_Expr *name(Arena *arena, E_Expr *expr, MD_Node *params) -#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(name) ev_view_rule_expr_resolution__##name -#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(name)) - -#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params) -#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name) ev_view_rule_expr_expand_info__##name -#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name)) - -#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(name) EV_ExpandRangeInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data) -#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(name) ev_view_rule_expr_expand_range_info__##name -#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(name)) - -#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data) -#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(name) ev_view_rule_expr_expand_id_from_num_##name -#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(name)) - -#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data) -#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name) ev_view_rule_expr_expand_num_from_id_##name -#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name)) - -typedef EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(EV_ViewRuleExprResolutionHookFunctionType); -typedef EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_ViewRuleExprExpandInfoHookFunctionType); -typedef EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(EV_ViewRuleExprExpandRangeInfoHookFunctionType); -typedef EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(EV_ViewRuleExprExpandIDFromNumHookFunctionType); -typedef EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(EV_ViewRuleExprExpandNumFromIDHookFunctionType); - -typedef U32 EV_ViewRuleInfoFlags; // NOTE(rjf): see @view_rule_info -enum -{ - EV_ViewRuleInfoFlag_Inherited = (1<<0), - EV_ViewRuleInfoFlag_Expandable = (1<<1), -}; - -typedef struct EV_ViewRuleInfo EV_ViewRuleInfo; -struct EV_ViewRuleInfo +typedef struct EV_ExpandRule EV_ExpandRule; +struct EV_ExpandRule { String8 string; - EV_ViewRuleInfoFlags flags; - EV_ViewRuleExprResolutionHookFunctionType *expr_resolution; - EV_ViewRuleExprExpandInfoHookFunctionType *expr_expand_info; - EV_ViewRuleExprExpandRangeInfoHookFunctionType *expr_expand_range_info; - EV_ViewRuleExprExpandIDFromNumHookFunctionType *expr_expand_id_from_num; - EV_ViewRuleExprExpandIDFromNumHookFunctionType *expr_expand_num_from_id; + EV_ExpandRuleInfoHookFunctionType *info; }; -typedef struct EV_ViewRuleInfoNode EV_ViewRuleInfoNode; -struct EV_ViewRuleInfoNode +typedef struct EV_ExpandRuleNode EV_ExpandRuleNode; +struct EV_ExpandRuleNode { - EV_ViewRuleInfoNode *next; - EV_ViewRuleInfo v; + EV_ExpandRuleNode *next; + EV_ExpandRule v; }; -typedef struct EV_ViewRuleInfoSlot EV_ViewRuleInfoSlot; -struct EV_ViewRuleInfoSlot +typedef struct EV_ExpandRuleSlot EV_ExpandRuleSlot; +struct EV_ExpandRuleSlot { - EV_ViewRuleInfoNode *first; - EV_ViewRuleInfoNode *last; + EV_ExpandRuleNode *first; + EV_ExpandRuleNode *last; }; -typedef struct EV_ViewRuleInfoTable EV_ViewRuleInfoTable; -struct EV_ViewRuleInfoTable +typedef struct EV_ExpandRuleTable EV_ExpandRuleTable; +struct EV_ExpandRuleTable { - EV_ViewRuleInfoSlot *slots; + EV_ExpandRuleSlot *slots; U64 slots_count; }; +typedef struct EV_ExpandRuleTagPair EV_ExpandRuleTagPair; +struct EV_ExpandRuleTagPair +{ + EV_ExpandRule *rule; + E_Expr *tag; +}; + //////////////////////////////// //~ rjf: Blocks @@ -209,10 +149,12 @@ struct EV_Block // rjf: expression / visualization info String8 string; E_Expr *expr; - EV_ViewRuleList *view_rules; - EV_ViewRuleInfo *expand_view_rule_info; - MD_Node *expand_view_rule_params; - void *expand_view_rule_info_user_data; + E_Expr *lookup_tag; + E_Expr *expand_tag; + E_LookupRule *lookup_rule; + EV_ExpandRule *expand_rule; + void *lookup_rule_user_data; + void *expand_rule_user_data; // rjf: expansion info U64 row_count; @@ -256,29 +198,27 @@ struct EV_BlockRangeList typedef struct EV_Row EV_Row; struct EV_Row { - EV_Row *next; - - // rjf: block hierarchy info EV_Block *block; EV_Key key; - - // rjf: row size/scroll info U64 visual_size; - U64 visual_size_skipped; - U64 visual_size_chopped; - - // rjf: expression / visualization info String8 string; E_Expr *expr; - E_Member *member; - EV_ViewRuleList *view_rules; +}; + +typedef struct EV_WindowedRowNode EV_WindowedRowNode; +struct EV_WindowedRowNode +{ + EV_WindowedRowNode *next; + U64 visual_size_skipped; + U64 visual_size_chopped; + EV_Row row; }; typedef struct EV_WindowedRowList EV_WindowedRowList; struct EV_WindowedRowList { - EV_Row *first; - EV_Row *last; + EV_WindowedRowNode *first; + EV_WindowedRowNode *last; U64 count; U64 count_before_visual; U64 count_before_semantic; @@ -329,29 +269,19 @@ enum //////////////////////////////// //~ rjf: Nil/Identity View Rule Hooks -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(identity); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(nil); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(nil); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(nil); //////////////////////////////// //~ rjf: Globals -global read_only EV_ViewRuleInfo ev_nil_view_rule_info = +global read_only EV_ExpandRule ev_nil_expand_rule = { {0}, - 0, - EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), - EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), - EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), - EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), - EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity), + EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), }; -thread_static EV_ViewRuleInfoTable *ev_view_rule_info_table = 0; -global read_only EV_ViewRuleList ev_nil_view_rule_list = {0}; +thread_static EV_ExpandRuleTable *ev_view_rule_info_table = 0; thread_static EV_AutoViewRuleTable *ev_auto_view_rule_table = 0; -global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &ev_nil_view_rule_list, &ev_nil_view_rule_info}; +global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_lookup_rule__nil, &ev_nil_expand_rule}; //////////////////////////////// //~ rjf: Key Functions @@ -387,39 +317,27 @@ internal void ev_key_set_view_rule(EV_View *view, EV_Key key, String8 view_rule_ //////////////////////////////// //~ rjf: View Rule Info Table Building / Selection / Lookups -internal void ev_view_rule_info_table_push(Arena *arena, EV_ViewRuleInfoTable *table, EV_ViewRuleInfo *info); -internal void ev_view_rule_info_table_push_builtins(Arena *arena, EV_ViewRuleInfoTable *table); -internal void ev_select_view_rule_info_table(EV_ViewRuleInfoTable *table); -internal EV_ViewRuleInfo *ev_view_rule_info_from_string(String8 string); - -//////////////////////////////// -//~ rjf: Automatic Type -> View Rule Table Building / Selection / Lookups - -internal void ev_auto_view_rule_table_push_new(Arena *arena, EV_AutoViewRuleTable *table, E_TypeKey type_key, String8 view_rule, B32 is_required); -internal void ev_select_auto_view_rule_table(EV_AutoViewRuleTable *table); -internal EV_ViewRuleList *ev_auto_view_rules_from_type_key(Arena *arena, E_TypeKey type_key, B32 gather_required, B32 gather_optional); - -//////////////////////////////// -//~ rjf: View Rule Instance List Building - -internal void ev_view_rule_list_push_tree(Arena *arena, EV_ViewRuleList *list, MD_Node *root); -internal void ev_view_rule_list_push_string(Arena *arena, EV_ViewRuleList *list, String8 string); -internal EV_ViewRuleList *ev_view_rule_list_from_string(Arena *arena, String8 string); -internal EV_ViewRuleList *ev_view_rule_list_from_expr_fastpaths(Arena *arena, String8 string); -internal EV_ViewRuleList *ev_view_rule_list_from_inheritance(Arena *arena, EV_ViewRuleList *src); -internal EV_ViewRuleList *ev_view_rule_list_copy(Arena *arena, EV_ViewRuleList *src); -internal void ev_view_rule_list_concat_in_place(EV_ViewRuleList *dst, EV_ViewRuleList **src); +internal void ev_expand_rule_table_push(Arena *arena, EV_ExpandRuleTable *table, EV_ExpandRule *info); +#define ev_expand_rule_table_push_new(arena, table, ...) ev_expand_rule_table_push((arena), (table), &(EV_ExpandRule){__VA_ARGS__}) +internal void ev_select_expand_rule_table(EV_ExpandRuleTable *table); +internal EV_ExpandRule *ev_expand_rule_from_string(String8 string); //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) -internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules); +#if 0 // TODO(rjf): @cfg (dynamic type resolution) +internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr); +#endif + +//////////////////////////////// +//~ rjf: Upgrading Expressions w/ Tags From All Sources + +internal void ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr); //////////////////////////////// //~ rjf: Block Building -internal EV_BlockTree ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules); -internal EV_BlockTree ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules); +internal EV_BlockTree ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChain exprs); internal U64 ev_depth_from_block(EV_Block *block); //////////////////////////////// @@ -429,11 +347,15 @@ internal EV_BlockRangeList ev_block_range_list_from_tree(Arena *arena, EV_BlockT internal EV_BlockRange ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num); internal EV_Key ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num); internal U64 ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key); +internal U64 ev_vnum_from_num(EV_BlockRangeList *block_ranges, U64 num); +internal U64 ev_num_from_vnum(EV_BlockRangeList *block_ranges, U64 vidx); //////////////////////////////// //~ rjf: Row Building -internal EV_WindowedRowList ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 visible_range); +internal EV_WindowedRowList ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 vnum_range); +internal EV_Row *ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, U64 num); +internal EV_WindowedRowList ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 num_range); internal String8 ev_expr_string_from_row(Arena *arena, EV_Row *row, EV_StringFlags flags); internal B32 ev_row_is_expandable(EV_Row *row); internal B32 ev_row_is_editable(EV_Row *row); @@ -448,4 +370,9 @@ internal String8 ev_string_from_hresult_code(U32 code); internal String8 ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, U32 min_digits, E_Eval eval); internal String8 ev_escaped_from_raw_string(Arena *arena, String8 raw); +//////////////////////////////// +//~ rjf: Expression & IR-Tree => Expand Rule + +internal EV_ExpandRuleTagPair ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); + #endif // EVAL_VISUALIZATION_CORE_H diff --git a/src/eval_visualization/eval_visualization_inc.c b/src/eval_visualization/eval_visualization_inc.c index 44e7f6cb..d944d937 100644 --- a/src/eval_visualization/eval_visualization_inc.c +++ b/src/eval_visualization/eval_visualization_inc.c @@ -2,4 +2,3 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) #include "eval_visualization_core.c" -#include "eval_visualization_builtin_view_rules.c" diff --git a/src/eval_visualization/eval_visualization_inc.h b/src/eval_visualization/eval_visualization_inc.h index 2e01e21a..11c9b212 100644 --- a/src/eval_visualization/eval_visualization_inc.h +++ b/src/eval_visualization/eval_visualization_inc.h @@ -5,6 +5,5 @@ #define EVAL_VISUALIZATION_INC_H #include "eval_visualization_core.h" -#include "eval_visualization_builtin_view_rules.h" #endif // EVAL_VISUALIZATION_INC_H diff --git a/src/eval_visualization/generated/eval_visualization.meta.c b/src/eval_visualization/generated/eval_visualization.meta.c index ad7776d0..3d32a4c2 100644 --- a/src/eval_visualization/generated/eval_visualization.meta.c +++ b/src/eval_visualization/generated/eval_visualization.meta.c @@ -3,24 +3,3 @@ //- GENERATED CODE -C_LINKAGE_BEGIN -EV_ViewRuleInfo ev_builtin_view_rule_info_table[14] = -{ -{str8_lit_comp("default"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(default) , EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(default) , EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("array"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(array) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("list"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(list) , EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(list) , EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("slice"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(slice) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("bswap"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(bswap) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("cast"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(cast) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("wrap"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(wrap) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("only"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(only) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("omit"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(omit) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("bin"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("oct"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("dec"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("hex"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("no_addr"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -}; - -C_LINKAGE_END - diff --git a/src/eval_visualization/generated/eval_visualization.meta.h b/src/eval_visualization/generated/eval_visualization.meta.h index da13d9b4..efcc2c2a 100644 --- a/src/eval_visualization/generated/eval_visualization.meta.h +++ b/src/eval_visualization/generated/eval_visualization.meta.h @@ -6,34 +6,4 @@ #ifndef EVAL_VISUALIZATION_META_H #define EVAL_VISUALIZATION_META_H -typedef enum EV_ViewRuleKind -{ -EV_ViewRuleKind_Default, -EV_ViewRuleKind_Array, -EV_ViewRuleKind_List, -EV_ViewRuleKind_Slice, -EV_ViewRuleKind_ByteSwap, -EV_ViewRuleKind_Cast, -EV_ViewRuleKind_Wrap, -EV_ViewRuleKind_Only, -EV_ViewRuleKind_Omit, -EV_ViewRuleKind_Bin, -EV_ViewRuleKind_Oct, -EV_ViewRuleKind_Dec, -EV_ViewRuleKind_Hex, -EV_ViewRuleKind_NoAddress, -EV_ViewRuleKind_COUNT, -} EV_ViewRuleKind; - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(array); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(slice); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(bswap); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(cast); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(wrap); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(only); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(omit); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(default); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(list); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(default); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(list); #endif // EVAL_VISUALIZATION_META_H diff --git a/src/file_stream/file_stream.c b/src/file_stream/file_stream.c index cd161dd8..792bc6d7 100644 --- a/src/file_stream/file_stream.c +++ b/src/file_stream/file_stream.c @@ -189,11 +189,11 @@ fs_key_from_path_range(String8 path, Rng1U64 range) return key; } -internal U64 -fs_timestamp_from_path(String8 path) +internal FileProperties +fs_properties_from_path(String8 path) { Temp scratch = scratch_begin(0, 0); - U64 result = 0; + FileProperties result = {0}; path = path_normalized_from_string(scratch.arena, path); U64 path_hash = fs_little_hash_from_string(path); U64 slot_idx = path_hash%fs_shared->slots_count; @@ -206,33 +206,7 @@ fs_timestamp_from_path(String8 path) { if(str8_match(path, n->path, 0)) { - result = n->timestamp; - break; - } - } - } - scratch_end(scratch); - return result; -} - -internal U64 -fs_size_from_path(String8 path) -{ - Temp scratch = scratch_begin(0, 0); - U64 result = 0; - path = path_normalized_from_string(scratch.arena, path); - U64 path_hash = fs_little_hash_from_string(path); - U64 slot_idx = path_hash%fs_shared->slots_count; - U64 stripe_idx = slot_idx%fs_shared->stripes_count; - FS_Slot *slot = &fs_shared->slots[slot_idx]; - FS_Stripe *stripe = &fs_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) - { - for(FS_Node *n = slot->first; n != 0; n = n->next) - { - if(str8_match(path, n->path, 0)) - { - result = n->size; + result = n->props; break; } } @@ -314,8 +288,9 @@ ASYNC_WORK_DEF(fs_stream_work) ProfBegin("load \"%.*s\"", str8_varg(path)); FileProperties pre_props = os_properties_from_file_path(path); U64 range_size = dim_1u64(range); - U64 read_size = Min(pre_props.size, range_size); + U64 read_size = Min(pre_props.size - range.min, range_size); OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, path); + B32 file_handle_is_valid = !os_handle_match(os_handle_zero(), file); U64 data_arena_size = read_size+ARENA_HEADER_SIZE; data_arena_size += KB(4)-1; data_arena_size -= data_arena_size%KB(4); @@ -328,8 +303,12 @@ ASYNC_WORK_DEF(fs_stream_work) os_file_close(file); FileProperties post_props = os_properties_from_file_path(path); - //- rjf: abort if modification timestamps differ - we did not successfully read the file - if(pre_props.modified != post_props.modified) + //- rjf: abort if modification timestamps or sizes differ - we did not successfully read the file + B32 read_good = (pre_props.modified == post_props.modified && + pre_props.size == post_props.size && + read_size == data.size && + (file_handle_is_valid || pre_props.flags & FilePropertyFlag_IsFolder)); + if(!read_good) { ProfScope("abort") { @@ -360,29 +339,13 @@ ASYNC_WORK_DEF(fs_stream_work) break; } } - if(node != 0) + if(node != 0 && read_good) { - if(node->timestamp != 0) + if(node->props.modified != 0) { ins_atomic_u64_inc_eval(&fs_shared->change_gen); } - if(post_props.modified == pre_props.modified) - { - node->timestamp = post_props.modified; - node->size = post_props.size; - } - U64 range_hash = fs_little_hash_from_string(str8_struct(&range)); - U64 range_slot_idx = range_hash%node->slots_count; - FS_RangeSlot *range_slot = &node->slots[range_slot_idx]; - FS_RangeNode *range_node = 0; - for(FS_RangeNode *n = range_slot->first; n != 0; n = n->next) - { - if(MemoryMatchStruct(&n->range, &range)) - { - range_node = n; - break; - } - } + node->props = post_props; } } os_condition_variable_broadcast(path_stripe->cv); @@ -413,7 +376,7 @@ fs_detector_thread__entry_point(void *p) for(FS_Node *n = slot->first; n != 0; n = n->next) { FileProperties props = os_properties_from_file_path(n->path); - if(props.modified != n->timestamp) + if(props.modified != n->props.modified) { for(U64 range_slot_idx = 0; range_slot_idx < n->slots_count; range_slot_idx += 1) { diff --git a/src/file_stream/file_stream.h b/src/file_stream/file_stream.h index 80b1e34a..d1ec870b 100644 --- a/src/file_stream/file_stream.h +++ b/src/file_stream/file_stream.h @@ -31,8 +31,7 @@ struct FS_Node // rjf: file metadata String8 path; - U64 timestamp; - U64 size; + FileProperties props; // rjf: sub-table of per-requested-file-range info U64 slots_count; @@ -108,8 +107,7 @@ internal U64 fs_change_gen(void); internal U128 fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us); internal U128 fs_key_from_path_range(String8 path, Rng1U64 range); -internal U64 fs_timestamp_from_path(String8 path); -internal U64 fs_size_from_path(String8 path); +internal FileProperties fs_properties_from_path(String8 path); //////////////////////////////// //~ rjf: Streaming Work diff --git a/src/font_cache/font_cache.c b/src/font_cache/font_cache.c index f302dd22..52c4aa3a 100644 --- a/src/font_cache/font_cache.c +++ b/src/font_cache/font_cache.c @@ -555,8 +555,8 @@ fnt_hash2style_from_tag_size_flags(FNT_Tag tag, F32 size, FNT_RasterFlags flags) hash2style_node = push_array(f_state->raster_arena, FNT_Hash2StyleRasterCacheNode, 1); DLLPushBack_NP(slot->first, slot->last, hash2style_node, hash_next, hash_prev); hash2style_node->style_hash = style_hash; - hash2style_node->ascent = metrics.ascent; - hash2style_node->descent= metrics.descent; + hash2style_node->ascent = metrics.ascent; + hash2style_node->descent = metrics.descent; hash2style_node->utf8_class1_direct_map = push_array_no_zero(f_state->raster_arena, F_RasterCacheInfo, 256); hash2style_node->hash2info_slots_count = 1024; hash2style_node->hash2info_slots = push_array(f_state->raster_arena, FNT_Hash2InfoRasterCacheSlot, hash2style_node->hash2info_slots_count); diff --git a/src/font_provider/dwrite/font_provider_dwrite.c b/src/font_provider/dwrite/font_provider_dwrite.c index 4bfbddb2..4770ebba 100644 --- a/src/font_provider/dwrite/font_provider_dwrite.c +++ b/src/font_provider/dwrite/font_provider_dwrite.c @@ -191,6 +191,7 @@ fp_init(void) //- rjf: make sharp-hinted rendering params { FLOAT gamma = IDWriteRenderingParams_GetGamma(fp_dwrite_state->base_rendering_params); + gamma = 1.f; FLOAT enhanced_contrast = IDWriteRenderingParams_GetEnhancedContrast(fp_dwrite_state->base_rendering_params); if(fp_dwrite_state->dwrite2_is_supported) { @@ -219,6 +220,7 @@ fp_init(void) //- rjf: make sharp-unhinted rendering params { FLOAT gamma = IDWriteRenderingParams_GetGamma(fp_dwrite_state->base_rendering_params); + gamma = 1.f; FLOAT enhanced_contrast = IDWriteRenderingParams_GetEnhancedContrast(fp_dwrite_state->base_rendering_params); if(fp_dwrite_state->dwrite2_is_supported) { @@ -247,6 +249,7 @@ fp_init(void) //- rjf: make smooth-hinted rendering params { FLOAT gamma = IDWriteRenderingParams_GetGamma(fp_dwrite_state->base_rendering_params); + gamma = 1.f; FLOAT enhanced_contrast = IDWriteRenderingParams_GetEnhancedContrast(fp_dwrite_state->base_rendering_params); if(fp_dwrite_state->dwrite2_is_supported) { @@ -432,7 +435,7 @@ fp_raster(Arena *arena, FP_Handle font_handle, F32 size, FP_RasterFlags flags, S F32 right_side_bearing = 0; if(font.face != 0) { - atlas_dim.y = (S16)ceil_f32((96.f/72.f) * size * (font_metrics.ascent + font_metrics.descent) / design_units_per_em) + 1; + atlas_dim.y = (S16)round_f32((96.f/72.f) * size * (font_metrics.ascent + font_metrics.descent + font_metrics.lineGap) / design_units_per_em) + 1; for(U64 idx = 0; idx < glyphs_count; idx += 1) { DWRITE_GLYPH_METRICS *glyph_metrics = glyphs_metrics + idx; @@ -476,11 +479,14 @@ fp_raster(Arena *arena, FP_Handle font_handle, F32 size, FP_RasterFlags flags, S } //- rjf: draw glyph run - Vec2F32 draw_p = {0, (F32)atlas_dim.y}; + Vec2F32 draw_p = {0, (F32)atlas_dim.y - 1}; if(font.face != 0) { F32 descent = round_f32((96.f/72.f)*size * font_metrics.descent / design_units_per_em); + F32 line_gap = round_f32((96.f/72.f)*size * font_metrics.lineGap / design_units_per_em); draw_p.y -= descent; + draw_p.y -= line_gap; + draw_p.y += 1; } DWRITE_GLYPH_RUN glyph_run = {0}; if(font.face != 0) diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index 82e84617..587a45c0 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -108,7 +108,10 @@ hs_submit_data(U128 key, Arena **data_arena, String8 data) node = push_array(stripe->arena, HS_Node, 1); } node->hash = hash; - node->arena = *data_arena; + if(data_arena != 0) + { + node->arena = *data_arena; + } node->data = data; node->scope_ref_count = 0; node->key_ref_count = 1; @@ -117,9 +120,15 @@ hs_submit_data(U128 key, Arena **data_arena, String8 data) else { existing_node->key_ref_count += 1; - arena_release(*data_arena); + if(data_arena != 0) + { + arena_release(*data_arena); + } + } + if(data_arena != 0) + { + *data_arena = 0; } - *data_arena = 0; } //- rjf: commit this hash to key cache @@ -143,17 +152,17 @@ hs_submit_data(U128 key, Arena **data_arena, String8 data) } if(key_node) { - if(key_node->hash_history_gen >= ArrayCount(key_node->hash_history)) + if(key_node->hash_history_gen >= HS_KEY_HASH_HISTORY_STRONG_REF_COUNT) { - key_expired_hash = key_node->hash_history[key_node->hash_history_gen%ArrayCount(key_node->hash_history)]; + key_expired_hash = key_node->hash_history[(key_node->hash_history_gen-HS_KEY_HASH_HISTORY_STRONG_REF_COUNT)%ArrayCount(key_node->hash_history)]; } key_node->hash_history[key_node->hash_history_gen%ArrayCount(key_node->hash_history)] = hash; key_node->hash_history_gen += 1; } } - //- rjf: if this key's history cache was full, dec key ref count of oldest hash - ProfScope("if this key's history cache was full, dec key ref count of oldest hash") + //- rjf: decrement key ref count of expired hash + ProfScope("decrement key ref count of expired hash") if(!u128_match(key_expired_hash, u128_zero())) { U64 old_hash_slot_idx = key_expired_hash.u64[1]%hs_shared->slots_count; @@ -241,6 +250,49 @@ hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node) SLLStackPush(scope->top_touch, touch); } +//////////////////////////////// +//~ rjf: Downstream Accesses + +internal void +hs_hash_downstream_inc(U128 hash) +{ + U64 slot_idx = hash.u64[1]%hs_shared->slots_count; + U64 stripe_idx = slot_idx%hs_shared->stripes_count; + HS_Slot *slot = &hs_shared->slots[slot_idx]; + HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; + OS_MutexScopeR(stripe->rw_mutex) + { + for(HS_Node *n = slot->first; n != 0; n = n->next) + { + if(u128_match(hash, n->hash)) + { + ins_atomic_u64_inc_eval(&n->downstream_ref_count); + break; + } + } + } +} + +internal void +hs_hash_downstream_dec(U128 hash) +{ + U64 slot_idx = hash.u64[1]%hs_shared->slots_count; + U64 stripe_idx = slot_idx%hs_shared->stripes_count; + HS_Slot *slot = &hs_shared->slots[slot_idx]; + HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; + OS_MutexScopeR(stripe->rw_mutex) + { + for(HS_Node *n = slot->first; n != 0; n = n->next) + { + if(u128_match(hash, n->hash)) + { + ins_atomic_u64_dec_eval(&n->downstream_ref_count); + break; + } + } + } +} + //////////////////////////////// //~ rjf: Cache Lookup @@ -312,7 +364,8 @@ hs_evictor_thread__entry_point(void *p) { U64 key_ref_count = ins_atomic_u64_eval(&n->key_ref_count); U64 scope_ref_count = ins_atomic_u64_eval(&n->scope_ref_count); - if(key_ref_count == 0 && scope_ref_count == 0) + U64 downstream_ref_count = ins_atomic_u64_eval(&n->downstream_ref_count); + if(key_ref_count == 0 && scope_ref_count == 0 && downstream_ref_count == 0) { slot_has_work = 1; break; @@ -326,11 +379,15 @@ hs_evictor_thread__entry_point(void *p) next = n->next; U64 key_ref_count = ins_atomic_u64_eval(&n->key_ref_count); U64 scope_ref_count = ins_atomic_u64_eval(&n->scope_ref_count); - if(key_ref_count == 0 && scope_ref_count == 0) + U64 downstream_ref_count = ins_atomic_u64_eval(&n->downstream_ref_count); + if(key_ref_count == 0 && scope_ref_count == 0 && downstream_ref_count == 0) { DLLRemove(slot->first, slot->last, n); SLLStackPush(hs_shared->stripes_free_nodes[stripe_idx], n); - arena_release(n->arena); + if(n->arena != 0) + { + arena_release(n->arena); + } } } } diff --git a/src/hash_store/hash_store.h b/src/hash_store/hash_store.h index ff886e79..784a9203 100644 --- a/src/hash_store/hash_store.h +++ b/src/hash_store/hash_store.h @@ -8,6 +8,7 @@ //~ rjf: Cache Types #define HS_KEY_HASH_HISTORY_COUNT 64 +#define HS_KEY_HASH_HISTORY_STRONG_REF_COUNT 2 typedef struct HS_KeyNode HS_KeyNode; struct HS_KeyNode @@ -35,6 +36,7 @@ struct HS_Node String8 data; U64 scope_ref_count; U64 key_ref_count; + U64 downstream_ref_count; }; typedef struct HS_Slot HS_Slot; @@ -138,6 +140,12 @@ internal HS_Scope *hs_scope_open(void); internal void hs_scope_close(HS_Scope *scope); internal void hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node); +//////////////////////////////// +//~ rjf: Downstream Accesses + +internal void hs_hash_downstream_inc(U128 hash); +internal void hs_hash_downstream_dec(U128 hash); + //////////////////////////////// //~ rjf: Cache Lookups diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index 365d1f7d..5237ad55 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 11 diff --git a/src/mdesk/mdesk.c b/src/mdesk/mdesk.c index 92c9bcff..a1888673 100644 --- a/src/mdesk/mdesk.c +++ b/src/mdesk/mdesk.c @@ -968,7 +968,10 @@ if(work_top == 0) {work_top = &broken_work;}\ String8 tag_name = md_content_string_from_token_flags_str8(token[1].flags, tag_name_raw); MD_Node *node = md_push_node(arena, MD_NodeKind_Tag, md_node_flags_from_token_flags(token[1].flags), tag_name, tag_name_raw, token[0].range.min); DLLPushBack_NPZ(&md_nil_node, work_top->first_gathered_tag, work_top->last_gathered_tag, node, next, prev); - if(token+2 < tokens_opl && token[2].flags & MD_TokenFlag_Reserved && str8_match(str8_substr(text, token[2].range), str8_lit("("), 0)) + if(token+2 < tokens_opl && token[2].flags & MD_TokenFlag_Reserved && + (str8_match(str8_substr(text, token[2].range), str8_lit("("), 0) || + str8_match(str8_substr(text, token[2].range), str8_lit("["), 0) || + str8_match(str8_substr(text, token[2].range), str8_lit("{"), 0))) { token += 3; MD_ParseWorkPush(MD_ParseWorkKind_Main, node); @@ -1052,10 +1055,13 @@ if(work_top == 0) {work_top = &broken_work;}\ goto end_consume; } - //- rjf: [main_implicit] newline -> pop + //- rjf: [main_implicit] newline -> pop *all* current implicit work tasks if(work_top->kind == MD_ParseWorkKind_MainImplicit && token->flags & MD_TokenFlag_Newline) { - MD_ParseWorkPop(); + for(;work_top->kind == MD_ParseWorkKind_MainImplicit;) + { + MD_ParseWorkPop(); + } token += 1; goto end_consume; } 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/os/core/linux/os_core_linux.c b/src/os/core/linux/os_core_linux.c index 3b2c73b1..5acd5cf8 100644 --- a/src/os/core/linux/os_core_linux.c +++ b/src/os/core/linux/os_core_linux.c @@ -443,6 +443,12 @@ os_copy_file_path(String8 dst, String8 src) return result; } +internal B32 +os_move_file_path(String8 dst, String8 src) +{ + // TODO(rjf) +} + internal String8 os_full_path_from_path(Arena *arena, String8 path) { diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index 96cf3b52..e3a02048 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -202,6 +202,7 @@ internal void os_abort(S32 exit_code); internal OS_Handle os_file_open(OS_AccessFlags flags, String8 path); internal void os_file_close(OS_Handle file); internal U64 os_file_read(OS_Handle file, Rng1U64 rng, void *out_data); +#define os_file_read_struct(f, off, ptr) os_file_read((f), r1u64((off), (off)+sizeof(*(ptr))), (ptr)) internal U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data); internal B32 os_file_set_times(OS_Handle file, DateTime time); internal FileProperties os_properties_from_file(OS_Handle file); @@ -209,6 +210,7 @@ internal OS_FileID os_id_from_file(OS_Handle file); internal B32 os_file_reserve_size(OS_Handle file, U64 size); internal B32 os_delete_file_at_path(String8 path); internal B32 os_copy_file_path(String8 dst, String8 src); +internal B32 os_move_file_path(String8 dst, String8 src); internal String8 os_full_path_from_path(Arena *arena, String8 path); internal B32 os_file_path_exists(String8 path); internal B32 os_folder_path_exists(String8 path); diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index 90b1277c..bfd12c55 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -503,6 +503,17 @@ os_copy_file_path(String8 dst, String8 src) return result; } +internal B32 +os_move_file_path(String8 dst, String8 src) +{ + Temp scratch = scratch_begin(0, 0); + String16 dst16 = str16_from_8(scratch.arena, dst); + String16 src16 = str16_from_8(scratch.arena, src); + B32 result = MoveFileW((WCHAR*)src16.str, (WCHAR*)dst16.str); + scratch_end(scratch); + return result; +} + internal String8 os_full_path_from_path(Arena *arena, String8 path) { @@ -560,6 +571,28 @@ os_properties_from_file_path(String8 path) os_w32_dense_time_from_file_time(&props.modified, &find_data.ftLastWriteTime); props.flags = os_w32_file_property_flags_from_dwFileAttributes(find_data.dwFileAttributes); } + else + { + Temp scratch = scratch_begin(0, 0); + WCHAR buffer[512] = {0}; + DWORD length = GetLogicalDriveStringsW(sizeof(buffer), buffer); + U64 last_slash_pos = 0; + for(;last_slash_pos < path.size; last_slash_pos = str8_find_needle(path, last_slash_pos+1, str8_lit("/"), StringMatchFlag_SlashInsensitive)); + String8 path_trimmed = str8_prefix(path, last_slash_pos); + for(U64 off = 0; off < (U64)length;) + { + String16 next_drive_string_16 = str16_cstring((U16 *)buffer+off); + off += next_drive_string_16.size+1; + String8 next_drive_string = str8_from_16(scratch.arena, next_drive_string_16); + next_drive_string = str8_chop_last_slash(next_drive_string); + if(str8_match(path_trimmed, next_drive_string, StringMatchFlag_CaseInsensitive)) + { + props.flags |= FilePropertyFlag_IsFolder; + break; + } + } + scratch_end(scratch); + } FindClose(handle); scratch_end(scratch); return props; diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index 11da04b8..be83091f 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -71,8 +71,10 @@ os_get_clipboard_text(Arena *arena) //~ rjf: @os_hooks Windows (Implemented Per-OS) internal OS_Handle -os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title) +os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title) { + Vec2F32 resolution = dim_2f32(rect); + //- rjf: allocate window OS_LNX_Window *w = os_lnx_gfx_state->free_window; if(w) @@ -283,6 +285,12 @@ os_dim_from_monitor(OS_Handle monitor) return v2f32(0, 0); } +internal F32 +os_dpi_from_monitor(OS_Handle monitor) +{ + return 96.f; +} + //////////////////////////////// //~ rjf: @os_hooks Events (Implemented Per-OS) diff --git a/src/os/gfx/os_gfx.h b/src/os/gfx/os_gfx.h index f2a860d7..9c50c5d3 100644 --- a/src/os/gfx/os_gfx.h +++ b/src/os/gfx/os_gfx.h @@ -21,7 +21,8 @@ struct OS_GfxInfo typedef U32 OS_WindowFlags; enum { - OS_WindowFlag_CustomBorder = (1<<0), + OS_WindowFlag_CustomBorder = (1<<0), + OS_WindowFlag_UseDefaultPosition = (1<<1), }; //////////////////////////////// @@ -139,7 +140,7 @@ internal String8 os_get_clipboard_text(Arena *arena); //////////////////////////////// //~ rjf: @os_hooks Windows (Implemented Per-OS) -internal OS_Handle os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title); +internal OS_Handle os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title); internal void os_window_close(OS_Handle window); internal void os_window_first_paint(OS_Handle window); internal void os_window_focus(OS_Handle window); @@ -168,6 +169,7 @@ internal OS_Handle os_primary_monitor(void); internal OS_Handle os_monitor_from_window(OS_Handle window); internal String8 os_name_from_monitor(Arena *arena, OS_Handle monitor); internal Vec2F32 os_dim_from_monitor(OS_Handle monitor); +internal F32 os_dpi_from_monitor(OS_Handle monitor); //////////////////////////////// //~ rjf: @os_hooks Events (Implemented Per-OS) diff --git a/src/os/gfx/stub/os_gfx_stub.c b/src/os/gfx/stub/os_gfx_stub.c index 34fd08c9..66b3f898 100644 --- a/src/os/gfx/stub/os_gfx_stub.c +++ b/src/os/gfx/stub/os_gfx_stub.c @@ -34,7 +34,7 @@ os_get_clipboard_text(Arena *arena) //~ rjf: @os_hooks Windows (Implemented Per-OS) internal OS_Handle -os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title) +os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title) { OS_Handle handle = {1}; return handle; @@ -181,6 +181,12 @@ os_dim_from_monitor(OS_Handle monitor) return v; } +internal F32 +os_dpi_from_monitor(OS_Handle monitor) +{ + return 96.f; +} + //////////////////////////////// //~ rjf: @os_hooks Events (Implemented Per-OS) diff --git a/src/os/gfx/win32/os_gfx_win32.c b/src/os/gfx/win32/os_gfx_win32.c index 33ee2a9f..4e8daab1 100644 --- a/src/os/gfx/win32/os_gfx_win32.c +++ b/src/os/gfx/win32/os_gfx_win32.c @@ -8,9 +8,11 @@ typedef BOOL w32_SetProcessDpiAwarenessContext_Type(void* value); typedef UINT w32_GetDpiForWindow_Type(HWND hwnd); +typedef HRESULT w32_GetDpiForMonitor_Type(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT *dpiX, UINT *dpiY); typedef int w32_GetSystemMetricsForDpi_Type(int nIndex, UINT dpi); #define w32_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((void*)-4) global w32_GetDpiForWindow_Type *w32_GetDpiForWindow_func = 0; +global w32_GetDpiForMonitor_Type *w32_GetDpiForMonitor_func = 0; global w32_GetSystemMetricsForDpi_Type *w32_GetSystemMetricsForDpi_func = 0; //////////////////////////////// @@ -713,9 +715,10 @@ os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // of the top hit area so manually checking that. F32 dpi = w32_GetDpiForWindow_func ? (F32)w32_GetDpiForWindow_func(hwnd) : 96.f; S32 frame_y = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CYFRAME, dpi) : GetSystemMetrics(SM_CYFRAME); - S32 padding = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CXPADDEDBORDER, dpi) : GetSystemMetrics(SM_CXPADDEDBORDER); + // NOTE(rjf): it seems incorrect to apply this padding here... + // S32 padding = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CXPADDEDBORDER, dpi) : GetSystemMetrics(SM_CXPADDEDBORDER); - B32 is_over_top_resize = pos_client.y >= 0 && pos_client.y < frame_y + padding; + B32 is_over_top_resize = pos_client.y >= 0 && pos_client.y < frame_y; // + padding; B32 is_over_title_bar = pos_client.y >= 0 && pos_client.y < window->custom_border_title_thickness; //- rjf: check against title bar client areas @@ -811,6 +814,7 @@ os_gfx_init(void) (w32_SetProcessDpiAwarenessContext_Type*)GetProcAddress(module, "SetProcessDpiAwarenessContext"); w32_GetDpiForWindow_func = (w32_GetDpiForWindow_Type*)GetProcAddress(module, "GetDpiForWindow"); + w32_GetDpiForMonitor_func = (w32_GetDpiForMonitor_Type *)GetProcAddress(module, "GetDpiForMonitor"); w32_GetSystemMetricsForDpi_func = (w32_GetSystemMetricsForDpi_Type *)GetProcAddress(module, "GetSystemMetricsForDpi"); FreeLibrary(module); } @@ -1011,9 +1015,12 @@ os_get_clipboard_text(Arena *arena) //~ rjf: @os_hooks Windows (Implemented Per-OS) internal OS_Handle -os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title) +os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title) { B32 custom_border = !!(flags & OS_WindowFlag_CustomBorder); + B32 use_default_position = !!(flags & OS_WindowFlag_UseDefaultPosition); + Vec2F32 pos = rect.p0; + Vec2F32 dim = dim_2f32(rect); //- rjf: make hwnd HWND hwnd = 0; @@ -1025,9 +1032,10 @@ os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title) L"graphical-window", (WCHAR*)title16.str, WS_OVERLAPPEDWINDOW | WS_SIZEBOX, - CW_USEDEFAULT, CW_USEDEFAULT, - (int)resolution.x, - (int)resolution.y, + use_default_position ? CW_USEDEFAULT : (S32)pos.x, + use_default_position ? CW_USEDEFAULT : (S32)pos.y, + (S32)dim.x, + (S32)dim.y, 0, 0, os_w32_gfx_state->hInstance, 0); @@ -1385,6 +1393,21 @@ os_dim_from_monitor(OS_Handle monitor) return result; } +internal F32 +os_dpi_from_monitor(OS_Handle monitor) +{ + F32 result = 96.f; + HMONITOR monitor_handle = (HMONITOR)monitor.u64[0]; + if(w32_GetDpiForMonitor_func != 0) + { + UINT dpi_x = 0; + UINT dpi_y = 0; + HRESULT hr = w32_GetDpiForMonitor_func(monitor_handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y); + result = (F32)dpi_x; + } + return result; +} + //////////////////////////////// //~ rjf: @os_hooks Events (Implemented Per-OS) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7594e916..580643ca 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,194 +4,339 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 rd_cfg_src_string_table[4] = +RD_VocabInfo rd_vocab_info_table[308] = { -str8_lit_comp("user"), -str8_lit_comp("project"), -str8_lit_comp("command_line"), -str8_lit_comp("transient"), +{str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, +{str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, +{str8_lit_comp("watch_pin"), str8_lit_comp("watch_pins"), str8_lit_comp("Watch Pin"), str8_lit_comp("Watch Pins"), RD_IconKind_Pin}, +{str8_lit_comp("watch"), str8_lit_comp("watches"), str8_lit_comp("Watch"), str8_lit_comp("Watches"), RD_IconKind_Binoculars}, +{str8_lit_comp("view_rule"), str8_lit_comp("view_rules"), str8_lit_comp("View Rule"), str8_lit_comp("View Rules"), RD_IconKind_Binoculars}, +{str8_lit_comp("breakpoint"), str8_lit_comp("breakpoints"), str8_lit_comp("Breakpoint"), str8_lit_comp("Breakpoints"), RD_IconKind_CircleFilled}, +{str8_lit_comp("condition"), str8_lit_comp("conditions"), str8_lit_comp("Condition"), str8_lit_comp("Conditions"), RD_IconKind_Null}, +{str8_lit_comp("location"), str8_lit_comp("locations"), str8_lit_comp("Location"), str8_lit_comp("Locations"), RD_IconKind_Null}, +{str8_lit_comp("source_location"), str8_lit_comp("source_locations"), str8_lit_comp("Source Location"), str8_lit_comp("Source Locations"), RD_IconKind_Null}, +{str8_lit_comp("address_location"), str8_lit_comp("address_locations"), str8_lit_comp("Address Location"), str8_lit_comp("Address Locations"), RD_IconKind_Null}, +{str8_lit_comp("target"), str8_lit_comp("targets"), str8_lit_comp("Target"), str8_lit_comp("Targets"), RD_IconKind_Target}, +{str8_lit_comp("executable"), str8_lit_comp("executables"), str8_lit_comp("Executable"), str8_lit_comp("Executables"), RD_IconKind_Module}, +{str8_lit_comp("arguments"), str8_lit_comp("arguments"), str8_lit_comp("Arguments"), str8_lit_comp("Arguments"), RD_IconKind_Null}, +{str8_lit_comp("exe"), str8_lit_comp("exes"), str8_lit_comp("Executable"), str8_lit_comp("Executables"), RD_IconKind_Module}, +{str8_lit_comp("dbg"), str8_lit_comp("dbgs"), str8_lit_comp("Debug Info Path"), str8_lit_comp("Debug Info Paths"), RD_IconKind_Module}, +{str8_lit_comp("vaddr_range"), str8_lit_comp("vaddr_ranges"), str8_lit_comp("Virtual Address Range"), str8_lit_comp("Virtual Address Ranges"), RD_IconKind_Null}, +{str8_lit_comp("min"), str8_lit_comp("mins"), str8_lit_comp("Minimum"), str8_lit_comp("Minimums"), RD_IconKind_Null}, +{str8_lit_comp("max"), str8_lit_comp("maxs"), str8_lit_comp("Maximum"), str8_lit_comp("Maximums"), RD_IconKind_Null}, +{str8_lit_comp("working_directory"), str8_lit_comp("working_directories"), str8_lit_comp("Working Directory"), str8_lit_comp("Working Directories"), RD_IconKind_FolderClosedFilled}, +{str8_lit_comp("entry_point"), str8_lit_comp("entry_points"), str8_lit_comp("Entry Point"), str8_lit_comp("Entry Points"), RD_IconKind_Null}, +{str8_lit_comp("stdout_path"), str8_lit_comp("stdout_paths"), str8_lit_comp("Standard Output Path"), str8_lit_comp("Standard Output Paths"), RD_IconKind_Null}, +{str8_lit_comp("stderr_path"), str8_lit_comp("stderr_paths"), str8_lit_comp("Standard Error Path"), str8_lit_comp("Standard Error Paths"), RD_IconKind_Null}, +{str8_lit_comp("stdin_path"), str8_lit_comp("stdin_paths"), str8_lit_comp("Standard Input Path"), str8_lit_comp("Standard Input Paths"), RD_IconKind_Null}, +{str8_lit_comp("window"), str8_lit_comp("windows"), str8_lit_comp("Window"), str8_lit_comp("Windows"), RD_IconKind_Window}, +{str8_lit_comp("panel"), str8_lit_comp("panels"), str8_lit_comp("Panel"), str8_lit_comp("Panels"), RD_IconKind_Null}, +{str8_lit_comp("view"), str8_lit_comp("views"), str8_lit_comp("View"), str8_lit_comp("Views"), RD_IconKind_Null}, +{str8_lit_comp("tab"), str8_lit_comp("tabs"), str8_lit_comp("Tab"), str8_lit_comp("Tabs"), RD_IconKind_Null}, +{str8_lit_comp("recent_project"), str8_lit_comp("recent_projects"), str8_lit_comp("Recent Project"), str8_lit_comp("Recent Projects"), RD_IconKind_Briefcase}, +{str8_lit_comp("recent_file"), str8_lit_comp("recent_files"), str8_lit_comp("Recent File"), str8_lit_comp("Recent Files"), RD_IconKind_FileOutline}, +{str8_lit_comp("src"), str8_lit_comp("srcs"), str8_lit_comp("Source"), str8_lit_comp("Sources"), RD_IconKind_Null}, +{str8_lit_comp("dst"), str8_lit_comp("dsts"), str8_lit_comp("Destination"), str8_lit_comp("Destinations"), RD_IconKind_Null}, +{str8_lit_comp("conversion_task"), str8_lit_comp("conversion_tasks"), str8_lit_comp("Conversion Task"), str8_lit_comp("Conversion Tasks"), RD_IconKind_Null}, +{str8_lit_comp("conversion_fail"), str8_lit_comp("conversion_fails"), str8_lit_comp("Conversion Fail"), str8_lit_comp("Conversion Fails"), RD_IconKind_Null}, +{str8_lit_comp("lang"), str8_lit_comp("langs"), str8_lit_comp("Language"), str8_lit_comp("Languages"), RD_IconKind_Null}, +{str8_lit_comp("arch"), str8_lit_comp("archs"), str8_lit_comp("Architecture"), str8_lit_comp("Architectures"), RD_IconKind_Null}, +{str8_lit_comp("expr"), str8_lit_comp("exprs"), str8_lit_comp("Expression"), str8_lit_comp("Expressions"), RD_IconKind_Null}, +{str8_lit_comp("expression"), str8_lit_comp("expressions"), str8_lit_comp("Expression"), str8_lit_comp("Expressions"), RD_IconKind_Null}, +{str8_lit_comp("size"), str8_lit_comp("sizes"), str8_lit_comp("Size"), str8_lit_comp("Sizes"), RD_IconKind_Null}, +{str8_lit_comp("count"), str8_lit_comp("counts"), str8_lit_comp("Count"), str8_lit_comp("Counts"), RD_IconKind_Null}, +{str8_lit_comp("bool"), str8_lit_comp("bools"), str8_lit_comp("Boolean"), str8_lit_comp("Booleans"), RD_IconKind_Null}, +{str8_lit_comp("w"), str8_lit_comp("ws"), str8_lit_comp("Width"), str8_lit_comp("Widths"), RD_IconKind_Null}, +{str8_lit_comp("h"), str8_lit_comp("hs"), str8_lit_comp("Height"), str8_lit_comp("Heights"), RD_IconKind_Null}, +{str8_lit_comp("fmt"), str8_lit_comp("fmts"), str8_lit_comp("Format"), str8_lit_comp("Formats"), RD_IconKind_Null}, +{str8_lit_comp("addresses"), str8_lit_comp("addresses"), str8_lit_comp("Addresses"), str8_lit_comp("Addresses"), RD_IconKind_Null}, +{str8_lit_comp("code_bytes"), str8_lit_comp("code_bytes"), str8_lit_comp("Code Bytes"), str8_lit_comp("Code Bytes"), RD_IconKind_Null}, +{str8_lit_comp("vtx"), str8_lit_comp("vtxs"), str8_lit_comp("Vertex Buffer"), str8_lit_comp("Vertex Buffers"), RD_IconKind_Null}, +{str8_lit_comp("vtx_size"), str8_lit_comp("vtx_sizes"), str8_lit_comp("Vertex Buffer Size"), str8_lit_comp("Vertex Buffer Sizes"), RD_IconKind_Null}, +{str8_lit_comp("label"), str8_lit_comp("labels"), str8_lit_comp("Label"), str8_lit_comp("Labels"), RD_IconKind_Null}, +{str8_lit_comp("thread"), str8_lit_comp("threads"), str8_lit_comp("Thread"), str8_lit_comp("Threads"), RD_IconKind_Thread}, +{str8_lit_comp("threads"), str8_lit_comp(""), str8_lit_comp("Threads"), str8_lit_comp(""), RD_IconKind_Threads}, +{str8_lit_comp("process"), str8_lit_comp("processes"), str8_lit_comp("Process"), str8_lit_comp("Processes"), RD_IconKind_Scheduler}, +{str8_lit_comp("processes"), str8_lit_comp(""), str8_lit_comp("Processes"), str8_lit_comp(""), RD_IconKind_Scheduler}, +{str8_lit_comp("machine"), str8_lit_comp("machines"), str8_lit_comp("Machine"), str8_lit_comp("Machines"), RD_IconKind_Machine}, +{str8_lit_comp("module"), str8_lit_comp("modules"), str8_lit_comp("Module"), str8_lit_comp("Modules"), RD_IconKind_Module}, +{str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark}, +{str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, +{str8_lit_comp("text"), str8_lit_comp(""), str8_lit_comp("Text"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("type"), str8_lit_comp("types"), str8_lit_comp("Type"), str8_lit_comp("Types"), RD_IconKind_Null}, +{str8_lit_comp("procedure"), str8_lit_comp("procedures"), str8_lit_comp("Procedure"), str8_lit_comp("Procedures"), RD_IconKind_Null}, +{str8_lit_comp("global_variable"), str8_lit_comp("global_variables"), str8_lit_comp("Global Variable"), str8_lit_comp("Global Variables"), RD_IconKind_Null}, +{str8_lit_comp("global"), str8_lit_comp("globals"), str8_lit_comp("Global"), str8_lit_comp("Globals"), RD_IconKind_Null}, +{str8_lit_comp("thread_variable"), str8_lit_comp("thread_variables"), str8_lit_comp("Thread Variable"), str8_lit_comp("Thread Variables"), RD_IconKind_Null}, +{str8_lit_comp("thread_local"), str8_lit_comp("thread_locals"), str8_lit_comp("Thread Local"), str8_lit_comp("Thread Locals"), RD_IconKind_Null}, +{str8_lit_comp("call_stack"), str8_lit_comp("call_stacks"), str8_lit_comp("Call Stack"), str8_lit_comp("Call Stacks"), RD_IconKind_Thread}, +{str8_lit_comp("output"), str8_lit_comp("outputs"), str8_lit_comp("Output"), str8_lit_comp("Outputs"), RD_IconKind_List}, +{str8_lit_comp("scheduler"), str8_lit_comp("schedulers"), str8_lit_comp("Scheduler"), str8_lit_comp("Schedulers"), RD_IconKind_Scheduler}, +{str8_lit_comp("register"), str8_lit_comp("registers"), str8_lit_comp("Register"), str8_lit_comp("Registers"), RD_IconKind_Null}, +{str8_lit_comp("local"), str8_lit_comp("locals"), str8_lit_comp("Local"), str8_lit_comp("Locals"), RD_IconKind_Null}, +{str8_lit_comp("memory"), str8_lit_comp("memories"), str8_lit_comp("Memory"), str8_lit_comp("Memories"), RD_IconKind_Grid}, +{str8_lit_comp("hit_count"), str8_lit_comp("hit_counts"), str8_lit_comp("Hit Count"), str8_lit_comp("Hit Counts"), RD_IconKind_Null}, +{str8_lit_comp("enabled"), str8_lit_comp(""), str8_lit_comp("Enabled"), str8_lit_comp("Enabled"), RD_IconKind_Null}, +{str8_lit_comp("disabled"), str8_lit_comp(""), str8_lit_comp("Disabled"), str8_lit_comp("Disabled"), RD_IconKind_Null}, +{str8_lit_comp("debug_subprocesses"), str8_lit_comp(""), str8_lit_comp("Debug Subprocesses"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("environment"), str8_lit_comp("environments"), str8_lit_comp("Environment"), str8_lit_comp("Environments"), RD_IconKind_Null}, +{str8_lit_comp("frozen"), str8_lit_comp(""), str8_lit_comp("Frozen"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("id"), str8_lit_comp("ids"), str8_lit_comp("ID"), str8_lit_comp("IDs"), RD_IconKind_Null}, +{str8_lit_comp("last_modified_time"), str8_lit_comp("last_modified_times"), str8_lit_comp("Last Modified Time"), str8_lit_comp("Last Modified Times"), RD_IconKind_Null}, +{str8_lit_comp("creation_time"), str8_lit_comp("creation_times"), str8_lit_comp("Creation Time"), str8_lit_comp("Creation Times"), RD_IconKind_Null}, +{str8_lit_comp("data"), str8_lit_comp("datas"), str8_lit_comp("Data"), str8_lit_comp("Datas"), RD_IconKind_Null}, +{str8_lit_comp("unattached_processes"), str8_lit_comp(""), str8_lit_comp("Unattached Processes"), str8_lit_comp(""), RD_IconKind_Scheduler}, +{str8_lit_comp("user"), str8_lit_comp("users"), str8_lit_comp("User"), str8_lit_comp("Users"), RD_IconKind_Person}, +{str8_lit_comp("project"), str8_lit_comp("projects"), str8_lit_comp("Project"), str8_lit_comp("Projects"), RD_IconKind_Briefcase}, +{str8_lit_comp("recent_project"), str8_lit_comp("recent_projects"), str8_lit_comp("Recent Project"), str8_lit_comp("Recent Projects"), RD_IconKind_Briefcase}, +{str8_lit_comp("recent_file"), str8_lit_comp("recent_files"), str8_lit_comp("Recent File"), str8_lit_comp("Recent Files"), RD_IconKind_FileOutline}, +{str8_lit_comp("show_addresses"), str8_lit_comp(""), str8_lit_comp("Show Addresses"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("show_code_bytes"), str8_lit_comp(""), str8_lit_comp("Show Code Bytes"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("show_source_lines"), str8_lit_comp(""), str8_lit_comp("Show Source Lines"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("show_symbol_names"), str8_lit_comp(""), str8_lit_comp("Show Symbol Names"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("show_line_numbers"), str8_lit_comp(""), str8_lit_comp("Show Line Numbers"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("syntax"), str8_lit_comp("syntaxes"), str8_lit_comp("Syntax"), str8_lit_comp("Syntaxes"), RD_IconKind_Null}, +{str8_lit_comp("num_columns"), str8_lit_comp(""), str8_lit_comp("Number of Columns"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("bitmap"), str8_lit_comp("bitmaps"), str8_lit_comp("Bitmap"), str8_lit_comp("Bitmaps"), RD_IconKind_Bitmap}, +{str8_lit_comp("geo3d"), str8_lit_comp(""), str8_lit_comp("Geometry (3D)"), str8_lit_comp(""), RD_IconKind_Cube}, +{str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, +{str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, +{str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, +{str8_lit_comp("kill_all"), str8_lit_comp(""), str8_lit_comp("Kill All"), str8_lit_comp(""), RD_IconKind_Stop}, +{str8_lit_comp("detach"), str8_lit_comp(""), str8_lit_comp("Detach"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("continue"), str8_lit_comp(""), str8_lit_comp("Continue"), str8_lit_comp(""), RD_IconKind_Play}, +{str8_lit_comp("step_into_inst"), str8_lit_comp(""), str8_lit_comp("Step Into (Assembly)"), str8_lit_comp(""), RD_IconKind_StepInto}, +{str8_lit_comp("step_over_inst"), str8_lit_comp(""), str8_lit_comp("Step Over (Assembly)"), str8_lit_comp(""), RD_IconKind_StepOver}, +{str8_lit_comp("step_into_line"), str8_lit_comp(""), str8_lit_comp("Step Into (Line)"), str8_lit_comp(""), RD_IconKind_StepInto}, +{str8_lit_comp("step_over_line"), str8_lit_comp(""), str8_lit_comp("Step Over (Line)"), str8_lit_comp(""), RD_IconKind_StepOver}, +{str8_lit_comp("step_out"), str8_lit_comp(""), str8_lit_comp("Step Out"), str8_lit_comp(""), RD_IconKind_StepOut}, +{str8_lit_comp("halt"), str8_lit_comp(""), str8_lit_comp("Halt"), str8_lit_comp(""), RD_IconKind_Pause}, +{str8_lit_comp("soft_halt_refresh"), str8_lit_comp(""), str8_lit_comp("Soft Halt Refresh"), str8_lit_comp(""), RD_IconKind_Refresh}, +{str8_lit_comp("set_thread_ip"), str8_lit_comp(""), str8_lit_comp("Set Thread IP"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("run_to_line"), str8_lit_comp(""), str8_lit_comp("Run To Line"), str8_lit_comp(""), RD_IconKind_Play}, +{str8_lit_comp("run"), str8_lit_comp(""), str8_lit_comp("Run"), str8_lit_comp(""), RD_IconKind_Play}, +{str8_lit_comp("restart"), str8_lit_comp(""), str8_lit_comp("Restart"), str8_lit_comp(""), RD_IconKind_Redo}, +{str8_lit_comp("step_into"), str8_lit_comp(""), str8_lit_comp("Step Into"), str8_lit_comp(""), RD_IconKind_StepInto}, +{str8_lit_comp("step_over"), str8_lit_comp(""), str8_lit_comp("Step Over"), str8_lit_comp(""), RD_IconKind_StepOver}, +{str8_lit_comp("freeze_thread"), str8_lit_comp(""), str8_lit_comp("Freeze Thread"), str8_lit_comp(""), RD_IconKind_Locked}, +{str8_lit_comp("thaw_thread"), str8_lit_comp(""), str8_lit_comp("Thaw Thread"), str8_lit_comp(""), RD_IconKind_Unlocked}, +{str8_lit_comp("freeze_process"), str8_lit_comp(""), str8_lit_comp("Freeze Process"), str8_lit_comp(""), RD_IconKind_Locked}, +{str8_lit_comp("thaw_process"), str8_lit_comp(""), str8_lit_comp("Thaw Process"), str8_lit_comp(""), RD_IconKind_Unlocked}, +{str8_lit_comp("freeze_machine"), str8_lit_comp(""), str8_lit_comp("Freeze Machine"), str8_lit_comp(""), RD_IconKind_Locked}, +{str8_lit_comp("thaw_machine"), str8_lit_comp(""), str8_lit_comp("Thaw Machine"), str8_lit_comp(""), RD_IconKind_Unlocked}, +{str8_lit_comp("freeze_local_machine"), str8_lit_comp(""), str8_lit_comp("Freeze Local Machine"), str8_lit_comp(""), RD_IconKind_Machine}, +{str8_lit_comp("thaw_local_machine"), str8_lit_comp(""), str8_lit_comp("Thaw Local Machine"), str8_lit_comp(""), RD_IconKind_Machine}, +{str8_lit_comp("freeze_entity"), str8_lit_comp(""), str8_lit_comp("Freeze Entity"), str8_lit_comp(""), RD_IconKind_Unlocked}, +{str8_lit_comp("thaw_entity"), str8_lit_comp(""), str8_lit_comp("Thaw Entity"), str8_lit_comp(""), RD_IconKind_Locked}, +{str8_lit_comp("set_entity_color"), str8_lit_comp(""), str8_lit_comp("Set Entity Color"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("set_entity_name"), str8_lit_comp(""), str8_lit_comp("Set Entity Name"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("attach"), str8_lit_comp(""), str8_lit_comp("Attach"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("exit"), str8_lit_comp(""), str8_lit_comp("Exit"), str8_lit_comp(""), RD_IconKind_X}, +{str8_lit_comp("open_lister"), str8_lit_comp(""), str8_lit_comp("Open Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("run_command"), str8_lit_comp(""), str8_lit_comp("Run Command"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp("OS Event"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("select_thread"), str8_lit_comp(""), str8_lit_comp("Select Thread"), str8_lit_comp(""), RD_IconKind_Thread}, +{str8_lit_comp("select_unwind"), str8_lit_comp(""), str8_lit_comp("Select Unwind"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("up_one_frame"), str8_lit_comp(""), str8_lit_comp("Up One Frame"), str8_lit_comp(""), RD_IconKind_UpArrow}, +{str8_lit_comp("down_one_frame"), str8_lit_comp(""), str8_lit_comp("Down One Frame"), str8_lit_comp(""), RD_IconKind_DownArrow}, +{str8_lit_comp("select_entity"), str8_lit_comp(""), str8_lit_comp("Select Entity"), str8_lit_comp(""), RD_IconKind_RadioHollow}, +{str8_lit_comp("deselect_entity"), str8_lit_comp(""), str8_lit_comp("Deselect Entity"), str8_lit_comp(""), RD_IconKind_RadioFilled}, +{str8_lit_comp("inc_ui_font_scale"), str8_lit_comp(""), str8_lit_comp("Increase UI Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("dec_ui_font_scale"), str8_lit_comp(""), str8_lit_comp("Decrease UI Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("inc_code_font_scale"), str8_lit_comp(""), str8_lit_comp("Increase Code Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("dec_code_font_scale"), str8_lit_comp(""), str8_lit_comp("Decrease Code Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("open_window"), str8_lit_comp(""), str8_lit_comp("Open New Window"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("close_window"), str8_lit_comp(""), str8_lit_comp("Close Window"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("toggle_fullscreen"), str8_lit_comp(""), str8_lit_comp("Toggle Fullscreen"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("bring_to_front"), str8_lit_comp(""), str8_lit_comp("Bring To Front"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("popup_accept"), str8_lit_comp(""), str8_lit_comp("Popup Accept"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("popup_cancel"), str8_lit_comp(""), str8_lit_comp("Popup Cancel"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("reset_to_default_panels"), str8_lit_comp(""), str8_lit_comp("Reset To Default Panel Layout"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("reset_to_compact_panels"), str8_lit_comp(""), str8_lit_comp("Reset To Compact Panel Layout"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("reset_to_simple_panels"), str8_lit_comp(""), str8_lit_comp("Reset To Simple Panel Layout"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("new_panel_left"), str8_lit_comp(""), str8_lit_comp("Split Panel Left"), str8_lit_comp(""), RD_IconKind_XSplit}, +{str8_lit_comp("new_panel_up"), str8_lit_comp(""), str8_lit_comp("Split Panel Up"), str8_lit_comp(""), RD_IconKind_YSplit}, +{str8_lit_comp("new_panel_right"), str8_lit_comp(""), str8_lit_comp("Split Panel Right"), str8_lit_comp(""), RD_IconKind_XSplit}, +{str8_lit_comp("new_panel_down"), str8_lit_comp(""), str8_lit_comp("Split Panel Down"), str8_lit_comp(""), RD_IconKind_YSplit}, +{str8_lit_comp("split_panel"), str8_lit_comp(""), str8_lit_comp("Split Panel"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("rotate_panel_columns"), str8_lit_comp(""), str8_lit_comp("Rotate Panel Columns"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("next_panel"), str8_lit_comp(""), str8_lit_comp("Focus Next Panel"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("prev_panel"), str8_lit_comp(""), str8_lit_comp("Focus Previous Panel"), str8_lit_comp(""), RD_IconKind_LeftArrow}, +{str8_lit_comp("focus_panel"), str8_lit_comp(""), str8_lit_comp("Focus Panel"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("focus_panel_right"), str8_lit_comp(""), str8_lit_comp("Focus Panel Right"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("focus_panel_left"), str8_lit_comp(""), str8_lit_comp("Focus Panel Left"), str8_lit_comp(""), RD_IconKind_LeftArrow}, +{str8_lit_comp("focus_panel_up"), str8_lit_comp(""), str8_lit_comp("Focus Panel Up"), str8_lit_comp(""), RD_IconKind_UpArrow}, +{str8_lit_comp("focus_panel_down"), str8_lit_comp(""), str8_lit_comp("Focus Panel Down"), str8_lit_comp(""), RD_IconKind_DownArrow}, +{str8_lit_comp("undo"), str8_lit_comp(""), str8_lit_comp("Undo"), str8_lit_comp(""), RD_IconKind_Undo}, +{str8_lit_comp("redo"), str8_lit_comp(""), str8_lit_comp("Redo"), str8_lit_comp(""), RD_IconKind_Redo}, +{str8_lit_comp("go_back"), str8_lit_comp(""), str8_lit_comp("Go Back"), str8_lit_comp(""), RD_IconKind_LeftArrow}, +{str8_lit_comp("go_forward"), str8_lit_comp(""), str8_lit_comp("Go Forward"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("close_panel"), str8_lit_comp(""), str8_lit_comp("Close Panel"), str8_lit_comp(""), RD_IconKind_ClosePanel}, +{str8_lit_comp("focus_tab"), str8_lit_comp(""), str8_lit_comp("Focus Tab"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("next_tab"), str8_lit_comp(""), str8_lit_comp("Focus Next Tab"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("prev_tab"), str8_lit_comp(""), str8_lit_comp("Focus Previous Tab"), str8_lit_comp(""), RD_IconKind_LeftArrow}, +{str8_lit_comp("move_tab_right"), str8_lit_comp(""), str8_lit_comp("Move Tab Right"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("move_tab_left"), str8_lit_comp(""), str8_lit_comp("Move Tab Left"), str8_lit_comp(""), RD_IconKind_LeftArrow}, +{str8_lit_comp("open_tab"), str8_lit_comp(""), str8_lit_comp("Open Tab"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("close_tab"), str8_lit_comp(""), str8_lit_comp("Close Tab"), str8_lit_comp(""), RD_IconKind_X}, +{str8_lit_comp("move_tab"), str8_lit_comp(""), str8_lit_comp("Move Tab"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("tab_bar_top"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Top"), str8_lit_comp(""), RD_IconKind_UpArrow}, +{str8_lit_comp("tab_bar_bottom"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Bottom"), str8_lit_comp(""), RD_IconKind_DownArrow}, +{str8_lit_comp("set_current_path"), str8_lit_comp(""), str8_lit_comp("Set Current Path"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("open"), str8_lit_comp(""), str8_lit_comp("Open"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("switch"), str8_lit_comp(""), str8_lit_comp("Switch"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("switch_to_partner_file"), str8_lit_comp(""), str8_lit_comp("Switch To Partner File"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("record_file_in_project"), str8_lit_comp(""), str8_lit_comp("Record File In Project"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("show_file_in_explorer"), str8_lit_comp(""), str8_lit_comp("Show File In Explorer"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("go_to_disassembly"), str8_lit_comp(""), str8_lit_comp("Go To Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, +{str8_lit_comp("go_to_source"), str8_lit_comp(""), str8_lit_comp("Go To Source"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("set_file_replacement_path"), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("open_user"), str8_lit_comp(""), str8_lit_comp("Open User"), str8_lit_comp(""), RD_IconKind_Person}, +{str8_lit_comp("open_project"), str8_lit_comp(""), str8_lit_comp("Open Project"), str8_lit_comp(""), RD_IconKind_Briefcase}, +{str8_lit_comp("open_recent_project"), str8_lit_comp(""), str8_lit_comp("Open Recent Project"), str8_lit_comp(""), RD_IconKind_Briefcase}, +{str8_lit_comp("write_user_data"), str8_lit_comp(""), str8_lit_comp("Write User Data"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("write_project_data"), str8_lit_comp(""), str8_lit_comp("Write Project Data"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("edit"), str8_lit_comp(""), str8_lit_comp("Edit"), str8_lit_comp(""), RD_IconKind_Pencil}, +{str8_lit_comp("accept"), str8_lit_comp(""), str8_lit_comp("Accept"), str8_lit_comp(""), RD_IconKind_CheckFilled}, +{str8_lit_comp("cancel"), str8_lit_comp(""), str8_lit_comp("Cancel"), str8_lit_comp(""), RD_IconKind_X}, +{str8_lit_comp("move_left"), str8_lit_comp(""), str8_lit_comp("Move Left"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_right"), str8_lit_comp(""), str8_lit_comp("Move Right"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up"), str8_lit_comp(""), str8_lit_comp("Move Up"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down"), str8_lit_comp(""), str8_lit_comp("Move Down"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_left_select"), str8_lit_comp(""), str8_lit_comp("Move Left Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_right_select"), str8_lit_comp(""), str8_lit_comp("Move Right Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_select"), str8_lit_comp(""), str8_lit_comp("Move Up Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_select"), str8_lit_comp(""), str8_lit_comp("Move Down Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_left_chunk"), str8_lit_comp(""), str8_lit_comp("Move Left Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_right_chunk"), str8_lit_comp(""), str8_lit_comp("Move Right Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_chunk"), str8_lit_comp(""), str8_lit_comp("Move Up Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_chunk"), str8_lit_comp(""), str8_lit_comp("Move Down Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_page"), str8_lit_comp(""), str8_lit_comp("Move Up Page"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_page"), str8_lit_comp(""), str8_lit_comp("Move Down Page"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_whole"), str8_lit_comp(""), str8_lit_comp("Move Up Whole"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_whole"), str8_lit_comp(""), str8_lit_comp("Move Down Whole"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_left_chunk_select"), str8_lit_comp(""), str8_lit_comp("Move Left Chunk Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_right_chunk_select"), str8_lit_comp(""), str8_lit_comp("Move Right Chunk Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_chunk_select"), str8_lit_comp(""), str8_lit_comp("Move Up Chunk Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_chunk_select"), str8_lit_comp(""), str8_lit_comp("Move Down Chunk Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_page_select"), str8_lit_comp(""), str8_lit_comp("Move Up Page Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_page_select"), str8_lit_comp(""), str8_lit_comp("Move Down Page Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_whole_select"), str8_lit_comp(""), str8_lit_comp("Move Up Whole Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_whole_select"), str8_lit_comp(""), str8_lit_comp("Move Down Whole Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_reorder"), str8_lit_comp(""), str8_lit_comp("Move Up Reorder"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_reorder"), str8_lit_comp(""), str8_lit_comp("Move Down Reorder"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_home"), str8_lit_comp(""), str8_lit_comp("Move Home"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_end"), str8_lit_comp(""), str8_lit_comp("Move End"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_home_select"), str8_lit_comp(""), str8_lit_comp("Move Home Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_end_select"), str8_lit_comp(""), str8_lit_comp("Move End Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("select_all"), str8_lit_comp(""), str8_lit_comp("Select All"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("delete_single"), str8_lit_comp(""), str8_lit_comp("Delete Single"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("delete_chunk"), str8_lit_comp(""), str8_lit_comp("Delete Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("backspace_single"), str8_lit_comp(""), str8_lit_comp("Backspace Single"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("backspace_chunk"), str8_lit_comp(""), str8_lit_comp("Backspace Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("copy"), str8_lit_comp(""), str8_lit_comp("Copy"), str8_lit_comp(""), RD_IconKind_Clipboard}, +{str8_lit_comp("cut"), str8_lit_comp(""), str8_lit_comp("Cut"), str8_lit_comp(""), RD_IconKind_Clipboard}, +{str8_lit_comp("paste"), str8_lit_comp(""), str8_lit_comp("Paste"), str8_lit_comp(""), RD_IconKind_Clipboard}, +{str8_lit_comp("insert_text"), str8_lit_comp(""), str8_lit_comp("Insert Text"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("goto_line"), str8_lit_comp(""), str8_lit_comp("Go To Line"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("goto_address"), str8_lit_comp(""), str8_lit_comp("Go To Address"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("center_cursor"), str8_lit_comp(""), str8_lit_comp("Center Cursor"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("contain_cursor"), str8_lit_comp(""), str8_lit_comp("Contain Cursor"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("find_text_forward"), str8_lit_comp(""), str8_lit_comp("Find Text (Forward)"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("find_text_backward"), str8_lit_comp(""), str8_lit_comp("Find Text (Backwards)"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("find_next"), str8_lit_comp(""), str8_lit_comp("Find Next"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("find_prev"), str8_lit_comp(""), str8_lit_comp("Find Previous"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("find_thread"), str8_lit_comp(""), str8_lit_comp("Find Thread"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("find_selected_thread"), str8_lit_comp(""), str8_lit_comp("Find Selected Thread"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("goto_name"), str8_lit_comp(""), str8_lit_comp("Go To Name"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("goto_name_at_cursor"), str8_lit_comp(""), str8_lit_comp("Go To Name At Cursor"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("toggle_watch_expr"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Cursor"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Mouse"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("set_columns"), str8_lit_comp(""), str8_lit_comp("Set Columns"), str8_lit_comp(""), RD_IconKind_Thumbnails}, +{str8_lit_comp("toggle_address_visibility"), str8_lit_comp(""), str8_lit_comp("Toggle Address Visibility"), str8_lit_comp(""), RD_IconKind_Thumbnails}, +{str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp(""), str8_lit_comp("Toggle Code Bytes Visibility"), str8_lit_comp(""), RD_IconKind_Thumbnails}, +{str8_lit_comp("enable_cfg"), str8_lit_comp(""), str8_lit_comp("Enable Config Tree"), str8_lit_comp(""), RD_IconKind_CheckHollow}, +{str8_lit_comp("disable_cfg"), str8_lit_comp(""), str8_lit_comp("Disable Config Tree"), str8_lit_comp(""), RD_IconKind_CheckFilled}, +{str8_lit_comp("select_cfg"), str8_lit_comp(""), str8_lit_comp("Select Config Tree"), str8_lit_comp(""), RD_IconKind_RadioHollow}, +{str8_lit_comp("deselect_cfg"), str8_lit_comp(""), str8_lit_comp("Deselect Config Tree"), str8_lit_comp(""), RD_IconKind_RadioFilled}, +{str8_lit_comp("remove_cfg"), str8_lit_comp(""), str8_lit_comp("Remove Config Tree"), str8_lit_comp(""), RD_IconKind_Trash}, +{str8_lit_comp("name_cfg"), str8_lit_comp(""), str8_lit_comp("Name Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("condition_cfg"), str8_lit_comp(""), str8_lit_comp("Condition Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("duplicate_cfg"), str8_lit_comp(""), str8_lit_comp("Duplicate Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("relocate_cfg"), str8_lit_comp(""), str8_lit_comp("Relocate Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("add_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("add_address_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Address Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("add_function_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Function Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("toggle_breakpoint"), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("enable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckFilled}, +{str8_lit_comp("disable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckHollow}, +{str8_lit_comp("add_watch_pin"), str8_lit_comp(""), str8_lit_comp("Add Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, +{str8_lit_comp("toggle_watch_pin"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("add_auto_view_rule"), str8_lit_comp(""), str8_lit_comp("Add Auto View Rule"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("set_next_statement"), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("add_target"), str8_lit_comp(""), str8_lit_comp("Add Target"), str8_lit_comp(""), RD_IconKind_Target}, +{str8_lit_comp("select_target"), str8_lit_comp(""), str8_lit_comp("Select Target"), str8_lit_comp(""), RD_IconKind_Target}, +{str8_lit_comp("enable_target"), str8_lit_comp(""), str8_lit_comp("Enable Target"), str8_lit_comp(""), RD_IconKind_CheckFilled}, +{str8_lit_comp("disable_target"), str8_lit_comp(""), str8_lit_comp("Disable Target"), str8_lit_comp(""), RD_IconKind_CheckHollow}, +{str8_lit_comp("register_as_jit_debugger"), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("find_code_location"), str8_lit_comp(""), str8_lit_comp("Find Code Location"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("search"), str8_lit_comp(""), str8_lit_comp("Search"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("search_backwards"), str8_lit_comp(""), str8_lit_comp("Search Backwards"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark}, +{str8_lit_comp("commands"), str8_lit_comp(""), str8_lit_comp("Commands"), str8_lit_comp(""), RD_IconKind_List}, +{str8_lit_comp("targets"), str8_lit_comp(""), str8_lit_comp("Targets"), str8_lit_comp(""), RD_IconKind_Target}, +{str8_lit_comp("file_path_map"), str8_lit_comp(""), str8_lit_comp("File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("auto_view_rules"), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("breakpoints"), str8_lit_comp(""), str8_lit_comp("Breakpoints"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("watch_pins"), str8_lit_comp(""), str8_lit_comp("Watch Pins"), str8_lit_comp(""), RD_IconKind_Pin}, +{str8_lit_comp("scheduler"), str8_lit_comp(""), str8_lit_comp("Scheduler"), str8_lit_comp(""), RD_IconKind_Scheduler}, +{str8_lit_comp("call_stack"), str8_lit_comp(""), str8_lit_comp("Call Stack"), str8_lit_comp(""), RD_IconKind_Thread}, +{str8_lit_comp("modules"), str8_lit_comp(""), str8_lit_comp("Modules"), str8_lit_comp(""), RD_IconKind_Module}, +{str8_lit_comp("watch"), str8_lit_comp(""), str8_lit_comp("Watch"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("locals"), str8_lit_comp(""), str8_lit_comp("Locals"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("registers"), str8_lit_comp(""), str8_lit_comp("Registers"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("globals"), str8_lit_comp(""), str8_lit_comp("Globals"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("thread_locals"), str8_lit_comp(""), str8_lit_comp("Thread Locals"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("types"), str8_lit_comp(""), str8_lit_comp("Types"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("procedures"), str8_lit_comp(""), str8_lit_comp("Procedures"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("pending_file"), str8_lit_comp(""), str8_lit_comp("Pending File"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, +{str8_lit_comp("output"), str8_lit_comp(""), str8_lit_comp("Output"), str8_lit_comp(""), RD_IconKind_List}, +{str8_lit_comp("memory"), str8_lit_comp(""), str8_lit_comp("Memory"), str8_lit_comp(""), RD_IconKind_Grid}, +{str8_lit_comp("settings"), str8_lit_comp(""), str8_lit_comp("Settings"), str8_lit_comp(""), RD_IconKind_Gear}, +{str8_lit_comp("pick_file"), str8_lit_comp(""), str8_lit_comp("Pick File"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("pick_folder"), str8_lit_comp(""), str8_lit_comp("Pick Folder"), str8_lit_comp(""), RD_IconKind_FolderOpenFilled}, +{str8_lit_comp("pick_file_or_folder"), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("push_lister"), str8_lit_comp(""), str8_lit_comp("Push Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("complete_lister"), str8_lit_comp(""), str8_lit_comp("Complete Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("cancel_lister"), str8_lit_comp(""), str8_lit_comp("Cancel Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("update_lister"), str8_lit_comp(""), str8_lit_comp("Update Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("toggle_dev_menu"), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, }; -RD_CmdKind rd_cfg_src_load_cmd_kind_table[4] = +RD_NameSchemaInfo rd_name_schema_info_table[16] = { -RD_CmdKind_OpenUser, -RD_CmdKind_OpenProject, -RD_CmdKind_Null, -RD_CmdKind_Null, +{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("text"), str8_lit_comp("x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n 'w': code_string,\n 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, +{str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, +{str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, +{str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, +{str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, +{str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, @no_expand 'active':bool, 'unattached_processes':query, 'processes':query}")}, +{str8_lit_comp("process"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'modules':query, 'threads':query}")}, +{str8_lit_comp("module"), str8_lit_comp("x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}")}, +{str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':query}")}, }; -RD_CmdKind rd_cfg_src_write_cmd_kind_table[4] = -{ -RD_CmdKind_WriteUserData, -RD_CmdKind_WriteProjectData, -RD_CmdKind_Null, -RD_CmdKind_Null, -}; - -RD_CmdKind rd_cfg_src_apply_cmd_kind_table[4] = -{ -RD_CmdKind_ApplyUserData, -RD_CmdKind_ApplyProjectData, -RD_CmdKind_Null, -RD_CmdKind_Null, -}; - -String8 d_entity_kind_display_string_table[27] = -{ -str8_lit_comp("Nil"), -str8_lit_comp("Root"), -str8_lit_comp("Auto View Rule"), -str8_lit_comp("File Path Map"), -str8_lit_comp("Watch Pin"), -str8_lit_comp("Watch"), -str8_lit_comp("View Rule"), -str8_lit_comp("Breakpoint"), -str8_lit_comp("Condition"), -str8_lit_comp("Location"), -str8_lit_comp("Target"), -str8_lit_comp("Executable"), -str8_lit_comp("Arguments"), -str8_lit_comp("Working Directory"), -str8_lit_comp("Entry Point"), -str8_lit_comp("Standard Output Path"), -str8_lit_comp("Standard Error Path"), -str8_lit_comp("Standard Input Path"), -str8_lit_comp("Window"), -str8_lit_comp("Panel"), -str8_lit_comp("View"), -str8_lit_comp("Recent Project"), -str8_lit_comp("Recent File"), -str8_lit_comp("Source"), -str8_lit_comp("Destination"), -str8_lit_comp("Conversion Task"), -str8_lit_comp("Conversion Failure"), -}; - -String8 d_entity_kind_name_lower_table[27] = -{ -str8_lit_comp("nil"), -str8_lit_comp("root"), -str8_lit_comp("auto_view_rule"), -str8_lit_comp("file_path_map"), -str8_lit_comp("watch_pin"), -str8_lit_comp("watch"), -str8_lit_comp("view_rule"), -str8_lit_comp("breakpoint"), -str8_lit_comp("condition"), -str8_lit_comp("location"), -str8_lit_comp("target"), -str8_lit_comp("executable"), -str8_lit_comp("arguments"), -str8_lit_comp("working_directory"), -str8_lit_comp("entry_point"), -str8_lit_comp("stdout_path"), -str8_lit_comp("stderr_path"), -str8_lit_comp("stdin_path"), -str8_lit_comp("window"), -str8_lit_comp("panel"), -str8_lit_comp("view"), -str8_lit_comp("recent_project"), -str8_lit_comp("recent_file"), -str8_lit_comp("source"), -str8_lit_comp("dest"), -str8_lit_comp("conversion_task"), -str8_lit_comp("conversion_fail"), -}; - -String8 d_entity_kind_name_lower_plural_table[27] = -{ -str8_lit_comp("nils"), -str8_lit_comp("roots"), -str8_lit_comp("auto_view_rules"), -str8_lit_comp("file_path_maps"), -str8_lit_comp("watch_pins"), -str8_lit_comp("watches"), -str8_lit_comp("view_rules"), -str8_lit_comp("breakpoints"), -str8_lit_comp("conditions"), -str8_lit_comp("locations"), -str8_lit_comp("targets"), -str8_lit_comp("executables"), -str8_lit_comp("argumentses"), -str8_lit_comp("working_directories"), -str8_lit_comp("entry_points"), -str8_lit_comp("stdout_paths"), -str8_lit_comp("stderr_paths"), -str8_lit_comp("stdin_paths"), -str8_lit_comp("windows"), -str8_lit_comp("panels"), -str8_lit_comp("views"), -str8_lit_comp("recent_projects"), -str8_lit_comp("recent_files"), -str8_lit_comp("sources"), -str8_lit_comp("dests"), -str8_lit_comp("conversion_tasks"), -str8_lit_comp("conversion_fails"), -}; - -String8 d_entity_kind_name_label_table[27] = -{ -str8_lit_comp("Label"), -str8_lit_comp("Label"), -str8_lit_comp("Label"), -str8_lit_comp("Label"), -str8_lit_comp("Expression"), -str8_lit_comp("Expression"), -str8_lit_comp("Expression"), -str8_lit_comp("Label"), -str8_lit_comp("Expression"), -str8_lit_comp("Location"), -str8_lit_comp("Label"), -str8_lit_comp("Executable"), -str8_lit_comp("Arguments"), -str8_lit_comp("Path"), -str8_lit_comp("Symbol Name"), -str8_lit_comp("Path"), -str8_lit_comp("Path"), -str8_lit_comp("Path"), -str8_lit_comp("Label"), -str8_lit_comp("Label"), -str8_lit_comp("Label"), -str8_lit_comp("Path"), -str8_lit_comp("Path"), -str8_lit_comp("Path"), -str8_lit_comp("Path"), -str8_lit_comp("Label"), -str8_lit_comp("Label"), -}; - -RD_EntityKindFlags rd_entity_kind_flags_table[27] = -{ -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (1*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (1*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (1*RD_EntityKindFlag_CanEnable) | (1*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (1*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (1*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -}; - -Rng1U64 rd_reg_slot_range_table[34] = +Rng1U64 rd_reg_slot_range_table[42] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -199,13 +344,13 @@ Rng1U64 rd_reg_slot_range_table[34] = {OffsetOf(RD_Regs, process), OffsetOf(RD_Regs, process) + sizeof(CTRL_Handle)}, {OffsetOf(RD_Regs, thread), OffsetOf(RD_Regs, thread) + sizeof(CTRL_Handle)}, {OffsetOf(RD_Regs, ctrl_entity), OffsetOf(RD_Regs, ctrl_entity) + sizeof(CTRL_Handle)}, -{OffsetOf(RD_Regs, window), OffsetOf(RD_Regs, window) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, panel), OffsetOf(RD_Regs, panel) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, view), OffsetOf(RD_Regs, view) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, prev_view), OffsetOf(RD_Regs, prev_view) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, dst_panel), OffsetOf(RD_Regs, dst_panel) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, entity), OffsetOf(RD_Regs, entity) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, entity_list), OffsetOf(RD_Regs, entity_list) + sizeof(RD_HandleList)}, +{OffsetOf(RD_Regs, window), OffsetOf(RD_Regs, window) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, panel), OffsetOf(RD_Regs, panel) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, view), OffsetOf(RD_Regs, view) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, prev_view), OffsetOf(RD_Regs, prev_view) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, dst_panel), OffsetOf(RD_Regs, dst_panel) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, cfg), OffsetOf(RD_Regs, cfg) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, cfg_list), OffsetOf(RD_Regs, cfg_list) + sizeof(RD_CfgIDList)}, {OffsetOf(RD_Regs, unwind_count), OffsetOf(RD_Regs, unwind_count) + sizeof(U64)}, {OffsetOf(RD_Regs, inline_depth), OffsetOf(RD_Regs, inline_depth) + sizeof(U64)}, {OffsetOf(RD_Regs, file_path), OffsetOf(RD_Regs, file_path) + sizeof(String8)}, @@ -219,9 +364,17 @@ Rng1U64 rd_reg_slot_range_table[34] = {OffsetOf(RD_Regs, voff), OffsetOf(RD_Regs, voff) + sizeof(U64)}, {OffsetOf(RD_Regs, vaddr_range), OffsetOf(RD_Regs, vaddr_range) + sizeof(Rng1U64)}, {OffsetOf(RD_Regs, voff_range), OffsetOf(RD_Regs, voff_range) + sizeof(Rng1U64)}, +{OffsetOf(RD_Regs, expr), OffsetOf(RD_Regs, expr) + sizeof(String8)}, +{OffsetOf(RD_Regs, view_rule), OffsetOf(RD_Regs, view_rule) + sizeof(String8)}, +{OffsetOf(RD_Regs, ui_key), OffsetOf(RD_Regs, ui_key) + sizeof(UI_Key)}, +{OffsetOf(RD_Regs, off_px), OffsetOf(RD_Regs, off_px) + sizeof(Vec2F32)}, +{OffsetOf(RD_Regs, lister_flags), OffsetOf(RD_Regs, lister_flags) + sizeof(RD_ListerFlags)}, +{OffsetOf(RD_Regs, reg_slot), OffsetOf(RD_Regs, reg_slot) + sizeof(RD_RegSlot)}, {OffsetOf(RD_Regs, pid), OffsetOf(RD_Regs, pid) + sizeof(U32)}, {OffsetOf(RD_Regs, force_confirm), OffsetOf(RD_Regs, force_confirm) + sizeof(B32)}, {OffsetOf(RD_Regs, prefer_disasm), OffsetOf(RD_Regs, prefer_disasm) + sizeof(B32)}, +{OffsetOf(RD_Regs, no_rich_tooltip), OffsetOf(RD_Regs, no_rich_tooltip) + sizeof(B32)}, +{OffsetOf(RD_Regs, do_implicit_root), OffsetOf(RD_Regs, do_implicit_root) + sizeof(B32)}, {OffsetOf(RD_Regs, dir2), OffsetOf(RD_Regs, dir2) + sizeof(Dir2)}, {OffsetOf(RD_Regs, string), OffsetOf(RD_Regs, string) + sizeof(String8)}, {OffsetOf(RD_Regs, cmd_name), OffsetOf(RD_Regs, cmd_name) + sizeof(String8)}, @@ -229,224 +382,227 @@ Rng1U64 rd_reg_slot_range_table[34] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[213] = +RD_CmdKindInfo rd_cmd_kind_info_table[216] = { {0}, -{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp("Launch and Initialize"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp("Kill"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp("Kill All"), RD_IconKind_Stop, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp("Detach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp("Continue"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp("Step Into (Assembly)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp("Step Over (Assembly)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp("Step Into (Line)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp("Step Over (Line)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp("Step Out"), RD_IconKind_StepOut, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp("Halt"), RD_IconKind_Pause, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp("Soft Halt Refresh"), RD_IconKind_Refresh, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp("Set Thread IP"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("Run To Line"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_address"), str8_lit_comp("Runs until a particular address is hit."), str8_lit_comp(""), str8_lit_comp("Run To Address"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp("Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp("Restart"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp("Step Into"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp("Step Over"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp("Freeze Thread"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp("Thaw Thread"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp("Freeze Process"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp("Thaw Process"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp("Freeze Machine"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Machine}}, -{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp("Thaw Machine"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Machine}}, -{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp("Freeze Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp("Thaw Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp("Freeze Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp("Thaw Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp("Set Entity Color"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp("Set Entity Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp("Attach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp("Exit"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp("Run Command"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("commands"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("OS Event"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp("Select Thread"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp("Select Unwind"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp("Up One Frame"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp("Down One Frame"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp("Increase UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp("Decrease UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp("Increase Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp("Decrease Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp("Open New Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp("Close Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp("Toggle Fullscreen"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp("Bring To Front"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp("Popup Accept"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp("Popup Cancel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp("Reset To Default Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp("Reset To Compact Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp("Split Panel Left"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp("Split Panel Up"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp("Split Panel Right"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp("Split Panel Down"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp("Split Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp("Rotate Panel Columns"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp("Focus Next Panel"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp("Focus Previous Panel"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Up"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Down"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp("Undo"), RD_IconKind_Undo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp("Redo"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp("Go Back"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp("Go Forward"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp("Close Panel"), RD_IconKind_ClosePanel, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp("Focus Next Tab"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp("Focus Previous Tab"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("Move Tab Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("Move Tab Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp("Open Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("Close Tab"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp("Move Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Top"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Bottom"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp("Set Current Path"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp("Open"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp("Switch"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_RecentFile, CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp("Switch To Partner File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp("Record File In Project"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("Go To Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("Go To Source"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp("Open User"), RD_IconKind_Person, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp("Open Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp("Open Recent Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_RecentProject, CTRL_EntityKind_Null}}, -{ str8_lit_comp("apply_user_data"), str8_lit_comp("Applies user data from the active user file."), str8_lit_comp(""), str8_lit_comp("Apply User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("apply_project_data"), str8_lit_comp("Applies project data from the active project file."), str8_lit_comp(""), str8_lit_comp("Apply Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp("Write User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp("Write Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp("Edit"), RD_IconKind_Pencil, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp("Accept"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp("Cancel"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp("Move Left"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp("Move Right"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp("Move Up"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp("Move Down"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Left Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Right Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Up Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Down Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp("Move Left Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp("Move Right Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp("Move Up Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp("Move Down Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp("Move Up Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp("Move Down Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp("Move Up Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp("Move Down Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp("Move Left Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp("Move Right Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp("Move Up Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp("Move Down Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Up Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Down Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Up Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Down Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp("Move Up Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp("Move Down Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp("Move Home"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp("Move End"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Home Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp("Move End Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp("Select All"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Delete Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Delete Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Backspace Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Backspace Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("Copy"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp("Cut"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp("Paste"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp("Insert Text"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp("Go To Line"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp("Go To Address"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp("Center Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp("Contain Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp("Find Text (Forward)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp("Find Text (Backwards)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp("Find Next"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp("Find Previous"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp("Find Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp("Find Selected Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("Go To Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("Go To Name At Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Cursor"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Mouse"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp("Set Columns"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("Toggle Address Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("Toggle Code Bytes Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_entity"), str8_lit_comp("Enables an entity."), str8_lit_comp(""), str8_lit_comp("Enable Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_entity"), str8_lit_comp("Disables an entity."), str8_lit_comp(""), str8_lit_comp("Disable Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_entity"), str8_lit_comp("Selects an entity, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp("Select Entity"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("remove_entity"), str8_lit_comp("Removes an entity."), str8_lit_comp(""), str8_lit_comp("Remove Entity"), RD_IconKind_Trash, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("name_entity"), str8_lit_comp("Equips an entity with a name."), str8_lit_comp(""), str8_lit_comp("Name Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("condition_entity"), str8_lit_comp("Equips an entity with a condition string."), str8_lit_comp(""), str8_lit_comp("Condition Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("duplicate_entity"), str8_lit_comp("Duplicates an entity."), str8_lit_comp(""), str8_lit_comp("Duplicate Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("relocate_entity"), str8_lit_comp("Relocates an entity."), str8_lit_comp(""), str8_lit_comp("Relocate Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("Add Address Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("Add Function Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("Add Watch Pin"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_cursor"), str8_lit_comp("Runs the selected thread to the current cursor."), str8_lit_comp("line"), str8_lit_comp("Run To Cursor"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("Add Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp("Select Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp("Enable Target"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp("Disable Target"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp("Find Code Location"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("filter"), str8_lit_comp("Begins filtering the active view."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp("Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("apply_filter"), str8_lit_comp("Applies the typed filter to the active view."), str8_lit_comp("sort,search,filter,find,apply"), str8_lit_comp("Apply Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("clear_filter"), str8_lit_comp("Clears the filter applied to the active view."), str8_lit_comp("sort,search,filter,find,clear"), str8_lit_comp("Clear Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp("Getting Started"), RD_IconKind_QuestionMark, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp("Commands"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp("Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp("Targets"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp("File Path Map"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp("Breakpoints"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp("Watch Pins"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp("Scheduler"), RD_IconKind_Scheduler, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp("Call Stack"), RD_IconKind_Thread, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp("Modules"), RD_IconKind_Module, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp("Watch"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp("Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp("Registers"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp("Globals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp("Thread Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp("Types"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp("Procedures"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp("Pending File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp("Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp("Output"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp("Memory"), RD_IconKind_Grid, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("exception_filters"), str8_lit_comp("Opens the exception filters view."), str8_lit_comp("exceptions,filters"), str8_lit_comp("Exception Filters"), RD_IconKind_Gear, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp("Settings"), RD_IconKind_Gear, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp("Pick File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp("Pick Folder"), RD_IconKind_FolderOpenFilled, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("complete_query"), str8_lit_comp("Completes a query."), str8_lit_comp(""), str8_lit_comp("Complete Query"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel_query"), str8_lit_comp("Cancels a query."), str8_lit_comp(""), str8_lit_comp("Cancel Query"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp("Log Marker"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_step_into"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp("query:unattached_processes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:lister"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:call_stack"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_entity"), str8_lit_comp("Selects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("deselect_entity"), str8_lit_comp("Deselects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_simple_panels"), str8_lit_comp("Resets the window to the simple panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_projects"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("deselect_cfg"), str8_lit_comp("Deselects a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("search"), str8_lit_comp("Begins searching within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("search_backwards"), str8_lit_comp("Begins searching backwards within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("update_lister"), str8_lit_comp("Updates a query input."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, }; -RD_StringBindingPair rd_default_binding_table[110] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[109] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -454,12 +610,11 @@ RD_StringBindingPair rd_default_binding_table[110] = {str8_lit_comp("step_out"), {OS_Key_F11, 0 |OS_Modifier_Shift }}, {str8_lit_comp("halt"), {OS_Key_X, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("halt"), {OS_Key_Pause, 0 }}, -{str8_lit_comp("soft_halt_refresh"), {OS_Key_R, 0 |OS_Modifier_Alt}}, {str8_lit_comp("run"), {OS_Key_F5, 0 }}, {str8_lit_comp("restart"), {OS_Key_F5, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("step_into"), {OS_Key_F11, 0 }}, {str8_lit_comp("step_over"), {OS_Key_F10, 0 }}, -{str8_lit_comp("run_to_cursor"), {OS_Key_F10, 0 |OS_Modifier_Ctrl }}, +{str8_lit_comp("run_to_line"), {OS_Key_F10, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("set_next_statement"), {OS_Key_F10, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("inc_ui_font_scale"), {OS_Key_Equal, 0 |OS_Modifier_Alt}}, {str8_lit_comp("dec_ui_font_scale"), {OS_Key_Minus, 0 |OS_Modifier_Alt}}, @@ -542,8 +697,8 @@ RD_StringBindingPair rd_default_binding_table[110] = {str8_lit_comp("insert_text"), {OS_Key_Null, 0 }}, {str8_lit_comp("goto_line"), {OS_Key_G, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("goto_address"), {OS_Key_G, 0 |OS_Modifier_Alt}}, -{str8_lit_comp("find_text_forward"), {OS_Key_F, 0 |OS_Modifier_Ctrl }}, -{str8_lit_comp("find_text_backward"), {OS_Key_R, 0 |OS_Modifier_Ctrl }}, +{str8_lit_comp("search"), {OS_Key_F, 0 |OS_Modifier_Ctrl }}, +{str8_lit_comp("search_backwards"), {OS_Key_R, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("find_next"), {OS_Key_F3, 0 }}, {str8_lit_comp("find_prev"), {OS_Key_F3, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("find_selected_thread"), {OS_Key_F4, 0 }}, @@ -555,9 +710,9 @@ RD_StringBindingPair rd_default_binding_table[110] = {str8_lit_comp("toggle_breakpoint"), {OS_Key_F9, 0 }}, {str8_lit_comp("add_target"), {OS_Key_T, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_Modifier_Shift }}, -{str8_lit_comp("filter"), {OS_Key_Slash, 0 |OS_Modifier_Ctrl }}, -{str8_lit_comp("run_command"), {OS_Key_F1, 0 }}, +{str8_lit_comp("open_lister"), {OS_Key_F1, 0 }}, {str8_lit_comp("log_marker"), {OS_Key_M, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, +{str8_lit_comp("toggle_dev_menu"), {OS_Key_D, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, }; String8 rd_binding_version_remap_old_name_table[8] = @@ -584,7 +739,7 @@ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("toggle_breakpoint"), }; -String8 rd_icon_kind_text_table[69] = +String8 rd_icon_kind_text_table[74] = { str8_lit_comp(""), str8_lit_comp("b"), @@ -614,6 +769,7 @@ str8_lit_comp("O"), str8_lit_comp("o"), str8_lit_comp("!"), str8_lit_comp("1"), +str8_lit_comp("V"), str8_lit_comp("<"), str8_lit_comp(">"), str8_lit_comp("^"), @@ -654,231 +810,11 @@ str8_lit_comp("A"), str8_lit_comp("?"), str8_lit_comp("4"), str8_lit_comp("5"), -str8_lit_comp("c"), -}; - -String8 rd_collection_name_table[18] = -{ -str8_lit_comp("watches"), -str8_lit_comp("targets"), -str8_lit_comp("breakpoints"), -str8_lit_comp("watch_pins"), -str8_lit_comp("file_path_maps"), -str8_lit_comp("auto_view_rules"), -str8_lit_comp("machines"), -str8_lit_comp("processes"), -str8_lit_comp("threads"), -str8_lit_comp("modules"), -str8_lit_comp("scheduler_machine"), -str8_lit_comp("scheduler_process"), -str8_lit_comp("locals"), -str8_lit_comp("registers"), -str8_lit_comp("globals"), -str8_lit_comp("thread_locals"), -str8_lit_comp("types"), -str8_lit_comp("procedures"), -}; - -RD_EntityKind rd_collection_entity_kind_table[18] = -{ -RD_EntityKind_Watch, -RD_EntityKind_Target, -RD_EntityKind_Breakpoint, -RD_EntityKind_WatchPin, -RD_EntityKind_FilePathMap, -RD_EntityKind_AutoViewRule, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -}; - -CTRL_EntityKind rd_collection_ctrl_entity_kind_table[18] = -{ -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Machine, -CTRL_EntityKind_Process, -CTRL_EntityKind_Thread, -CTRL_EntityKind_Module, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -}; - -EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[18] = -{ -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(watches), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(targets), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(breakpoints), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(watch_pins), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(file_path_maps), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(auto_view_rules), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(machines), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(processes), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(threads), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(modules), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(scheduler_machine), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(scheduler_process), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(locals), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(registers), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(globals), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(thread_locals), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(types), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(procedures), -}; - -EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[18] = -{ -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(watches), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(targets), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(breakpoints), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(watch_pins), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(file_path_maps), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(auto_view_rules), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(machines), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(processes), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(threads), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(modules), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(scheduler_machine), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(scheduler_process), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(locals), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(registers), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(globals), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(thread_locals), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(types), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(procedures), -}; - -EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[18] = -{ -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(targets), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(breakpoints), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watch_pins), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(file_path_maps), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(auto_view_rules), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(machines), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(processes), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(threads), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(modules), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(scheduler_machine), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(scheduler_process), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(globals), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(thread_locals), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(types), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(procedures), -}; - -EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[18] = -{ -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(watches), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(targets), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(breakpoints), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(watch_pins), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(file_path_maps), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(auto_view_rules), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(machines), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(processes), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(threads), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(modules), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(scheduler_machine), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(scheduler_process), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(globals), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(thread_locals), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(types), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(procedures), -}; - -RD_ViewRuleInfo rd_view_rule_kind_info_table[35] = -{ -{{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}, -{str8_lit_comp("empty"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(empty)}, -{str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(getting_started)}, -{str8_lit_comp("exception_filters"), str8_lit_comp("An interface which controls whether or not the debugger will halt attached processes upon encountering specific exception codes for the first time."), str8_lit_comp("Exception Filters"), str8_lit_comp(""), RD_IconKind_Gear, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(exception_filters)}, -{str8_lit_comp("settings"), str8_lit_comp("An interface to modify general settings for the debugger's appearance and behavior."), str8_lit_comp("Settings"), str8_lit_comp(""), RD_IconKind_Gear, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(settings)}, -{str8_lit_comp("pending_file"), str8_lit_comp(""), str8_lit_comp("Pending File"), str8_lit_comp(""), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(pending_file)}, -{str8_lit_comp("commands"), str8_lit_comp(""), str8_lit_comp("Commands"), str8_lit_comp(""), RD_IconKind_List, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(commands)}, -{str8_lit_comp("file_system"), str8_lit_comp(""), str8_lit_comp("File System"), str8_lit_comp(""), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(file_system)}, -{str8_lit_comp("system_processes"), str8_lit_comp(""), str8_lit_comp("System Processes"), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(system_processes)}, -{str8_lit_comp("entity_lister"), str8_lit_comp(""), str8_lit_comp("Entities"), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(entity_lister)}, -{str8_lit_comp("ctrl_entity_lister"), str8_lit_comp(""), str8_lit_comp("Control Entities"), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(ctrl_entity_lister)}, -{str8_lit_comp("symbol_lister"), str8_lit_comp(""), str8_lit_comp("Symbols"), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(symbol_lister)}, -{str8_lit_comp("watch"), str8_lit_comp("The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section."), str8_lit_comp("Watch"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(watch)}, -{str8_lit_comp("locals"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with local variables found within the selected call stack frame of the selected thread, according to the associated debug info. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Locals"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(locals)}, -{str8_lit_comp("registers"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with all register names according to the selected thread's architecture. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Registers"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(registers)}, -{str8_lit_comp("globals"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with all global variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Globals"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(globals)}, -{str8_lit_comp("thread_locals"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with all thread local variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Thread Locals"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(thread_locals)}, -{str8_lit_comp("types"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with all types within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Types"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(types)}, -{str8_lit_comp("procedures"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with all procedures within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Procedures"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(procedures)}, -{str8_lit_comp("targets"), str8_lit_comp("Displays a list of all targets, as well as controls for enabling, disabling, launching, editing, or deleting each target. For more information on targets, read the `Targets` section."), str8_lit_comp("Targets"), str8_lit_comp(""), RD_IconKind_Target, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(targets)}, -{str8_lit_comp("file_path_map"), str8_lit_comp("Displays a table of *path maps*. Each path map is a pair of file or folder paths, one being a 'source' path, and one being a 'destination' path. These pairs are used by the debugger when automatically searching for specific files - for instance, when attempting to snap to a source code location specified by debug info. If debug info refers to a path on the machine on which a target executable was originally built, but that path is not valid on the debugger machine, but some alternative path exists, then path maps may be used to redirect the debugger from the debug info's specified paths to the associated appropriate debugger machine file paths."), str8_lit_comp("File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(file_path_map)}, -{str8_lit_comp("auto_view_rules"), str8_lit_comp("Displays a table of *auto view rules*. Each *auto view rule* is a pair, with one element being a type, and the other being a view rule, which should be automatically applied to expressions of that type, when possible."), str8_lit_comp("Auto View Rules"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(auto_view_rules)}, -{str8_lit_comp("breakpoints"), str8_lit_comp("Displays a table of all breakpoints, containing information about each breakpoint's name, location, and hit count. Also contains per-breakpoint controls for enabling, deleting, or editing each breakpoint. For more information on breakpoints and their features, read the 'Breakpoints' section."), str8_lit_comp("Breakpoints"), str8_lit_comp(""), RD_IconKind_CircleFilled, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(breakpoints)}, -{str8_lit_comp("watch_pins"), str8_lit_comp("Displays a table of all watch pins (watched expressions, like those found in `Watch`, but instead of being within a table, being pinned to some source code location, like breakpoints). This table contains each pin's name, location, and controls for editing or deleting each pin."), str8_lit_comp("Watch Pins"), str8_lit_comp(""), RD_IconKind_Pin, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(watch_pins)}, -{str8_lit_comp("scheduler"), str8_lit_comp("Displays all processes and threads to which the debugger is currently attached, and contains controls for selecting and freezing threads."), str8_lit_comp("Scheduler"), str8_lit_comp(""), RD_IconKind_Scheduler, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(scheduler)}, -{str8_lit_comp("call_stack"), str8_lit_comp("Displays the call stack of the currently selected thread. Each frame in the call stack contains the associated module, function name, and return address. Allows selection of a particular call stack frame other than the top."), str8_lit_comp("Call Stack"), str8_lit_comp(""), RD_IconKind_Thread, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(call_stack)}, -{str8_lit_comp("modules"), str8_lit_comp("Displays a table of all modules currently loaded by any process to which the debugger is attached. This table displays each module's name, virtual address range in the containing process' address space, and which debug info file is being used by the debugger for the associated module."), str8_lit_comp("Modules"), str8_lit_comp(""), RD_IconKind_Module, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(modules)}, -{str8_lit_comp("text"), str8_lit_comp(""), str8_lit_comp("Text"), str8_lit_comp("x:{'lang':lang, 'size':expr}"), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(text) , RD_VIEW_RULE_UI_FUNCTION_NAME(text)}, -{str8_lit_comp("disasm"), str8_lit_comp("Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space."), str8_lit_comp("Disassembly"), str8_lit_comp("x:{'arch':arch, 'size':expr}"), RD_IconKind_Glasses, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(disasm) , RD_VIEW_RULE_UI_FUNCTION_NAME(disasm)}, -{str8_lit_comp("output"), str8_lit_comp("Displays debug strings, output from attached processes."), str8_lit_comp("Output"), str8_lit_comp(""), RD_IconKind_List, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(output)}, -{str8_lit_comp("memory"), str8_lit_comp("A hex-editor-like grid interface for viewing memory."), str8_lit_comp("Memory"), str8_lit_comp("x:{'size':expr}"), RD_IconKind_Grid, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(memory) , RD_VIEW_RULE_UI_FUNCTION_NAME(memory)}, -{str8_lit_comp("bitmap"), str8_lit_comp("Visualizes memory as a bitmap."), str8_lit_comp("Bitmap"), str8_lit_comp("x:{'w':expr, 'h':expr, 'fmt':tex2dformat}"), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(bitmap) , RD_VIEW_RULE_UI_FUNCTION_NAME(bitmap)}, -{str8_lit_comp("checkbox"), str8_lit_comp("Visualizes memory as an RGBA color."), str8_lit_comp("Checkbox"), str8_lit_comp(""), RD_IconKind_CheckFilled, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*1|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(checkbox)}, -{str8_lit_comp("color_rgba"), str8_lit_comp("Visualizes memory as an RGBA color."), str8_lit_comp("Color (RGBA)"), str8_lit_comp(""), RD_IconKind_Palette, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*1|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(color_rgba) , RD_VIEW_RULE_UI_FUNCTION_NAME(color_rgba)}, -{str8_lit_comp("geo3d"), str8_lit_comp("Visualizes memory as 3D geometry."), str8_lit_comp("Geometry (3D)"), str8_lit_comp("x:{'count':expr, 'vtx':expr, 'vtx_size':expr}"), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(geo3d) , RD_VIEW_RULE_UI_FUNCTION_NAME(geo3d)}, -}; - -RD_IconKind rd_entity_kind_icon_kind_table[27] = -{ -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Binoculars, -RD_IconKind_FileOutline, -RD_IconKind_Pin, -RD_IconKind_Binoculars, -RD_IconKind_Binoculars, -RD_IconKind_CircleFilled, -RD_IconKind_CircleFilled, -RD_IconKind_Null, -RD_IconKind_Target, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Window, -RD_IconKind_XSplit, -RD_IconKind_Null, -RD_IconKind_Briefcase, -RD_IconKind_FileOutline, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, +str8_lit_comp("6"), +str8_lit_comp("&"), +str8_lit_comp("*"), +str8_lit_comp("("), +str8_lit_comp(")"), }; String8 rd_theme_preset_display_string_table[9] = @@ -907,6 +843,19 @@ str8_lit_comp("four_coder"), str8_lit_comp("far_manager"), }; +String8 rd_theme_preset_cfg_string_table[9] = +{ +str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x31393dff,\n match: background: 0x31393dff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x4f3022ff,\n line_info_1: 0x4f3e15ff,\n line_info_2: 0x434e2aff,\n line_info_3: 0x36241fff,\n line_info_4: 0x4f3022ff,\n line_info_5: 0x4f3e15ff,\n line_info_6: 0x434e2aff,\n line_info_7: 0x36241fff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x31393d5f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n auto:\n {\n background: 0x693847ff,\n border: 0x9e6274ff,\n inactive:\n {\n background: 0x2f2633ff,\n border: 0x685073ff,\n }\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +}; + String8 rd_theme_color_version_remap_old_name_table[22] = { str8_lit_comp("plain_text"), @@ -959,52 +908,121 @@ str8_lit_comp("negative_pop_button_background"), str8_lit_comp("neutral_pop_button_background"), }; -Vec4F32 rd_theme_preset_colors__default_dark[76] = +Vec4F32 rd_theme_preset_colors__default_dark[145] = { rgba_from_u32_lit_comp(0xff00ffff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x2b3740ff), +rgba_from_u32_lit_comp(0x2b3740ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0xfda200ff), -rgba_from_u32_lit_comp(0xffffffff), -rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x222222fe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x2c5b36ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x355b6eff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x6f5135fe), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), rgba_from_u32_lit_comp(0xcbcbcbff), -rgba_from_u32_lit_comp(0x42a2cffe), +rgba_from_u32_lit_comp(0x42a2cfff), rgba_from_u32_lit_comp(0xfec746ff), rgba_from_u32_lit_comp(0x98bc80ff), rgba_from_u32_lit_comp(0xb7afd5ff), @@ -1017,14 +1035,14 @@ rgba_from_u32_lit_comp(0xd96759ff), rgba_from_u32_lit_comp(0x717171ff), rgba_from_u32_lit_comp(0x7f7f7fff), rgba_from_u32_lit_comp(0xbebebeff), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), +rgba_from_u32_lit_comp(0x99503dff), +rgba_from_u32_lit_comp(0xfe8249ff), +rgba_from_u32_lit_comp(0xffba17ff), +rgba_from_u32_lit_comp(0xcefd69ff), +rgba_from_u32_lit_comp(0x99503dff), +rgba_from_u32_lit_comp(0xfe8249ff), +rgba_from_u32_lit_comp(0xffba17ff), +rgba_from_u32_lit_comp(0xcefd69ff), rgba_from_u32_lit_comp(0xffcb7fff), rgba_from_u32_lit_comp(0xb2ff65ff), rgba_from_u32_lit_comp(0xff99e5ff), @@ -1039,50 +1057,119 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x355b6eff), }; -Vec4F32 rd_theme_preset_colors__default_light[76] = +Vec4F32 rd_theme_preset_colors__default_light[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4d9e2eff), -rgba_from_u32_lit_comp(0xbd371eff), -rgba_from_u32_lit_comp(0x0064a7ff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x699830ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0x9c5900ff), -rgba_from_u32_lit_comp(0xffffffff), -rgba_from_u32_lit_comp(0x0000004c), -rgba_from_u32_lit_comp(0xa6a6a63f), -rgba_from_u32_lit_comp(0x4848480c), rgba_from_u32_lit_comp(0xa4a4a43f), -rgba_from_u32_lit_comp(0x003d7a48), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0xff30005f), +rgba_from_u32_lit_comp(0x0000004c), rgba_from_u32_lit_comp(0xccccccfe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0xeaeaea7f), -rgba_from_u32_lit_comp(0x3e4c577f), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0xccccccc0), -rgba_from_u32_lit_comp(0x33333333), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x65f534ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0xff694cff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0xa6becaff), -rgba_from_u32_lit_comp(0xa6a6a6fd), -rgba_from_u32_lit_comp(0xa9a9a9fe), -rgba_from_u32_lit_comp(0xc0c0c0fe), -rgba_from_u32_lit_comp(0xa98b6fff), -rgba_from_u32_lit_comp(0xffffff4d), -rgba_from_u32_lit_comp(0x8282827f), -rgba_from_u32_lit_comp(0xffffff19), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), rgba_from_u32_lit_comp(0x4d4d4dff), rgba_from_u32_lit_comp(0x205670fe), rgba_from_u32_lit_comp(0x996b00ff), @@ -1119,50 +1206,119 @@ rgba_from_u32_lit_comp(0xff2800ff), rgba_from_u32_lit_comp(0xa6becaff), }; -Vec4F32 rd_theme_preset_colors__vs_dark[76] = +Vec4F32 rd_theme_preset_colors__vs_dark[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0xfda200ff), -rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x0000003f), rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x1b1b1bfd), -rgba_from_u32_lit_comp(0x1b1b1bfd), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x2c5b36ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x355b6eff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x0079ccff), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0xfefefe14), -rgba_from_u32_lit_comp(0xffffff00), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), rgba_from_u32_lit_comp(0xcbcbcbff), rgba_from_u32_lit_comp(0xdcdcaaff), rgba_from_u32_lit_comp(0x4ec9afff), @@ -1199,52 +1355,121 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x355b6eff), }; -Vec4F32 rd_theme_preset_colors__vs_light[76] = +Vec4F32 rd_theme_preset_colors__vs_light[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc46451ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0x002affff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xa3a3a37e), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x0000000c), rgba_from_u32_lit_comp(0xfefefe53), -rgba_from_u32_lit_comp(0x3d74ab4b), -rgba_from_u32_lit_comp(0x0000001e), -rgba_from_u32_lit_comp(0x5f12005f), +rgba_from_u32_lit_comp(0xa3a3a37e), rgba_from_u32_lit_comp(0xfefefefe), rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xffffff7f), -rgba_from_u32_lit_comp(0xffffff7f), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xfefefec7), -rgba_from_u32_lit_comp(0x33333333), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x84ce93ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xbd3e24ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x6e9db5ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xe8e8e8fe), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xfffffffe), -rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xcdd4dc7f), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), rgba_from_u32_lit_comp(0x000000ff), rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), rgba_from_u32_lit_comp(0xa33700ff), rgba_from_u32_lit_comp(0x007666ff), rgba_from_u32_lit_comp(0xb7afd5ff), @@ -1279,50 +1504,119 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x6e9db5ff), }; -Vec4F32 rd_theme_preset_colors__solarized_dark[76] = +Vec4F32 rd_theme_preset_colors__solarized_dark[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x9999998a), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0xfda200ff), -rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x0000003f), rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), rgba_from_u32_lit_comp(0x002a35fe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x00202bff), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), -rgba_from_u32_lit_comp(0x007fa14e), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0xfdfdfd3a), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x2c5b36ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x803425ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x355b6eff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x005e77fe), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x005e77fe), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xfefefe3a), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xfefefe3a), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xfefefe3a), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), rgba_from_u32_lit_comp(0xcbcbcbff), rgba_from_u32_lit_comp(0xcb4a15ff), rgba_from_u32_lit_comp(0xcb4a15ff), @@ -1359,50 +1653,119 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x355b6eff), }; -Vec4F32 rd_theme_preset_colors__solarized_light[76] = +Vec4F32 rd_theme_preset_colors__solarized_light[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x818181ff), -rgba_from_u32_lit_comp(0x586e75ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0x92743dff), -rgba_from_u32_lit_comp(0x747474ff), -rgba_from_u32_lit_comp(0xc9bfa394), -rgba_from_u32_lit_comp(0xe4dac090), -rgba_from_u32_lit_comp(0xffffff0c), rgba_from_u32_lit_comp(0x0000001c), -rgba_from_u32_lit_comp(0x678cb24c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), +rgba_from_u32_lit_comp(0xc9bfa394), rgba_from_u32_lit_comp(0xfcf5e2fe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xeee8d5ff), -rgba_from_u32_lit_comp(0x3e4c577f), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xffffff7c), -rgba_from_u32_lit_comp(0x33333333), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0xbdb9aa00), -rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xb6ddbeff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xf8b0a1ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xb2d3e3ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xe3dbc7fe), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xfdf6e3ff), -rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xd4cfc0fe), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), rgba_from_u32_lit_comp(0x657b83ff), rgba_from_u32_lit_comp(0xcb4a15ff), rgba_from_u32_lit_comp(0xcb4a15ff), @@ -1439,50 +1802,119 @@ rgba_from_u32_lit_comp(0xff684bff), rgba_from_u32_lit_comp(0xb2d3e3ff), }; -Vec4F32 rd_theme_preset_colors__handmade_hero[76] = +Vec4F32 rd_theme_preset_colors__handmade_hero[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x6e512eff), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0xfda200ff), -rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x0000003f), rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), rgba_from_u32_lit_comp(0x0c0c0cfe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), -rgba_from_u32_lit_comp(0x0c0c0c32), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x423425fe), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x132e19ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x15445cff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x1f1f27fe), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x1f1f27fe), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x131315ee), -rgba_from_u32_lit_comp(0xffffff19), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), rgba_from_u32_lit_comp(0xa08462ff), rgba_from_u32_lit_comp(0xcc5634ff), rgba_from_u32_lit_comp(0xd8a51bff), @@ -1519,50 +1951,119 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x15445cff), }; -Vec4F32 rd_theme_preset_colors__four_coder[76] = +Vec4F32 rd_theme_preset_colors__four_coder[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x566e4bff), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0xfda200ff), -rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x0000003f), rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), rgba_from_u32_lit_comp(0x0c0c0cfe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), -rgba_from_u32_lit_comp(0x0c0c0c3e), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x152f1bff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x43150cff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x1b323eff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x212721fe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x212721fe), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x3a3a3a7f), -rgba_from_u32_lit_comp(0x00000019), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), rgba_from_u32_lit_comp(0x90b080ff), rgba_from_u32_lit_comp(0x42a2cffe), rgba_from_u32_lit_comp(0xfd7c52ff), @@ -1599,50 +2100,119 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x1b323eff), }; -Vec4F32 rd_theme_preset_colors__far_manager[76] = +Vec4F32 rd_theme_preset_colors__far_manager[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x00a9a9ff), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x0000003f), rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), rgba_from_u32_lit_comp(0x000081fe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0x0000fffe), -rgba_from_u32_lit_comp(0x007d7dff), -rgba_from_u32_lit_comp(0x007d7dff), -rgba_from_u32_lit_comp(0xfefefe00), -rgba_from_u32_lit_comp(0x007c7c55), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x00ffff55), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x2c5b36ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x933100ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x007d7dff), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x007d7dff), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xfefefe19), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), rgba_from_u32_lit_comp(0x00fefeff), rgba_from_u32_lit_comp(0x65b1ffff), rgba_from_u32_lit_comp(0xfec746ff), @@ -1692,50 +2262,119 @@ rd_theme_preset_colors__four_coder, rd_theme_preset_colors__far_manager, }; -String8 rd_theme_color_display_string_table[76] = +String8 rd_theme_color_display_string_table[145] = { str8_lit_comp("Null"), -str8_lit_comp("Text"), -str8_lit_comp("Text (Positive)"), -str8_lit_comp("Text (Negative)"), -str8_lit_comp("Text (Neutral)"), -str8_lit_comp("Text (Weak)"), -str8_lit_comp("Cursor"), -str8_lit_comp("Cursor (Inactive)"), -str8_lit_comp("Focus"), -str8_lit_comp("Hover"), -str8_lit_comp("Drop Shadow"), -str8_lit_comp("Disabled Overlay"), -str8_lit_comp("Drop Site Overlay"), str8_lit_comp("Inactive Panel Overlay"), -str8_lit_comp("Selection Overlay"), -str8_lit_comp("Highlight Overlay"), -str8_lit_comp("Error Highlight Overlay"), +str8_lit_comp("Drop Shadow"), str8_lit_comp("Base Background"), str8_lit_comp("Base Background (Alternate)"), +str8_lit_comp("Base Background (Good)"), +str8_lit_comp("Base Background (Bad)"), +str8_lit_comp("Base Background (Pop)"), str8_lit_comp("Base Border"), +str8_lit_comp("Base Text"), +str8_lit_comp("Base Text (Weak)"), +str8_lit_comp("Base Hover"), +str8_lit_comp("Base Focus"), +str8_lit_comp("Base Cursor"), +str8_lit_comp("Base Selection"), str8_lit_comp("Menu Bar Background"), str8_lit_comp("Menu Bar Background (Alternate)"), +str8_lit_comp("Menu Bar Background (Good)"), +str8_lit_comp("Menu Bar Background (Bad)"), +str8_lit_comp("Menu Bar Background (Pop)"), str8_lit_comp("Menu Bar Border"), -str8_lit_comp("Floating Background"), -str8_lit_comp("Floating Background (Alternate)"), -str8_lit_comp("Floating Border"), -str8_lit_comp("Implicit Button Background"), -str8_lit_comp("Implicit Button Border"), -str8_lit_comp("Plain Button Background"), -str8_lit_comp("Plain Button Border"), -str8_lit_comp("Positive Pop Button Background"), -str8_lit_comp("Positive Pop Button Border"), -str8_lit_comp("Negative Pop Button Background"), -str8_lit_comp("Negative Pop Button Border"), -str8_lit_comp("Neutral Pop Button Background"), -str8_lit_comp("Neutral Pop Button Border"), -str8_lit_comp("Scroll Bar Button Background"), -str8_lit_comp("Scroll Bar Button Border"), +str8_lit_comp("Menu Bar Text"), +str8_lit_comp("Menu Bar Text (Weak)"), +str8_lit_comp("Menu Bar Hover"), +str8_lit_comp("Menu Bar Focus"), +str8_lit_comp("Menu Bar Cursor"), +str8_lit_comp("Menu Bar Selection"), +str8_lit_comp("Good Background"), +str8_lit_comp("Good Background (Alternate)"), +str8_lit_comp("Good Background (Good)"), +str8_lit_comp("Good Background (Bad)"), +str8_lit_comp("Good Background (Pop)"), +str8_lit_comp("Good Border"), +str8_lit_comp("Good Text"), +str8_lit_comp("Good Text (Weak)"), +str8_lit_comp("Good Hover"), +str8_lit_comp("Good Focus"), +str8_lit_comp("Good Cursor"), +str8_lit_comp("Good Selection"), +str8_lit_comp("Bad Background"), +str8_lit_comp("Bad Background (Alternate)"), +str8_lit_comp("Bad Background (Good)"), +str8_lit_comp("Bad Background (Bad)"), +str8_lit_comp("Bad Background (Pop)"), +str8_lit_comp("Bad Border"), +str8_lit_comp("Bad Text"), +str8_lit_comp("Bad Text (Weak)"), +str8_lit_comp("Bad Hover"), +str8_lit_comp("Bad Focus"), +str8_lit_comp("Bad Cursor"), +str8_lit_comp("Bad Selection"), +str8_lit_comp("Pop Background"), +str8_lit_comp("Pop Background (Alternate)"), +str8_lit_comp("Pop Background (Good)"), +str8_lit_comp("Pop Background (Bad)"), +str8_lit_comp("Pop Background (Pop)"), +str8_lit_comp("Pop Border"), +str8_lit_comp("Pop Text"), +str8_lit_comp("Pop Text (Weak)"), +str8_lit_comp("Pop Hover"), +str8_lit_comp("Pop Focus"), +str8_lit_comp("Pop Cursor"), +str8_lit_comp("Pop Selection"), +str8_lit_comp("Scroll Bar Background"), +str8_lit_comp("Scroll Bar Background (Alternate)"), +str8_lit_comp("Scroll Bar Background (Good)"), +str8_lit_comp("Scroll Bar Background (Bad)"), +str8_lit_comp("Scroll Bar Background (Pop)"), +str8_lit_comp("Scroll Bar Border"), +str8_lit_comp("Scroll Bar Text"), +str8_lit_comp("Scroll Bar Text (Weak)"), +str8_lit_comp("Scroll Bar Hover"), +str8_lit_comp("Scroll Bar Focus"), +str8_lit_comp("Scroll Bar Cursor"), +str8_lit_comp("Scroll Bar Selection"), str8_lit_comp("Tab Background"), +str8_lit_comp("Tab Background (Alternate)"), +str8_lit_comp("Tab Background (Good)"), +str8_lit_comp("Tab Background (Bad)"), +str8_lit_comp("Tab Background (Pop)"), str8_lit_comp("Tab Border"), -str8_lit_comp("Tab Background (Inactive)"), -str8_lit_comp("Tab Border (Inactive)"), +str8_lit_comp("Tab Text"), +str8_lit_comp("Tab Text (Weak)"), +str8_lit_comp("Tab Hover"), +str8_lit_comp("Tab Focus"), +str8_lit_comp("Tab Cursor"), +str8_lit_comp("Tab Selection"), +str8_lit_comp("Tab (Inactive) Background"), +str8_lit_comp("Tab (Inactive) Background (Alternate)"), +str8_lit_comp("Tab (Inactive) Background (Good)"), +str8_lit_comp("Tab (Inactive) Background (Bad)"), +str8_lit_comp("Tab (Inactive) Background (Pop)"), +str8_lit_comp("Tab (Inactive) Border"), +str8_lit_comp("Tab (Inactive) Text"), +str8_lit_comp("Tab (Inactive) Text (Weak)"), +str8_lit_comp("Tab (Inactive) Hover"), +str8_lit_comp("Tab (Inactive) Focus"), +str8_lit_comp("Tab (Inactive) Cursor"), +str8_lit_comp("Tab (Inactive) Selection"), +str8_lit_comp("Drop Site Background"), +str8_lit_comp("Drop Site Background (Alternate)"), +str8_lit_comp("Drop Site Background (Good)"), +str8_lit_comp("Drop Site Background (Bad)"), +str8_lit_comp("Drop Site Background (Pop)"), +str8_lit_comp("Drop Site Border"), +str8_lit_comp("Drop Site Text"), +str8_lit_comp("Drop Site Text (Weak)"), +str8_lit_comp("Drop Site Hover"), +str8_lit_comp("Drop Site Focus"), +str8_lit_comp("Drop Site Cursor"), +str8_lit_comp("Drop Site Selection"), str8_lit_comp("Code (Default)"), str8_lit_comp("Code (Symbol)"), str8_lit_comp("Code (Type)"), @@ -1772,50 +2411,119 @@ str8_lit_comp("Breakpoint"), str8_lit_comp("Cache Line Boundary"), }; -String8 rd_theme_color_cfg_string_table[76] = +String8 rd_theme_color_cfg_string_table[145] = { str8_lit_comp("null"), -str8_lit_comp("text"), -str8_lit_comp("text_positive"), -str8_lit_comp("text_negative"), -str8_lit_comp("text_neutral"), -str8_lit_comp("text_weak"), -str8_lit_comp("cursor"), -str8_lit_comp("cursor_inactive"), -str8_lit_comp("focus"), -str8_lit_comp("hover"), -str8_lit_comp("drop_shadow"), -str8_lit_comp("disabled_overlay"), -str8_lit_comp("drop_site_overlay"), str8_lit_comp("inactive_panel_overlay"), -str8_lit_comp("selection_overlay"), -str8_lit_comp("highlight_overlay"), -str8_lit_comp("error_highlight_overlay"), +str8_lit_comp("drop_shadow"), str8_lit_comp("base_background"), str8_lit_comp("base_background_alt"), +str8_lit_comp("base_background_good"), +str8_lit_comp("base_background_bad"), +str8_lit_comp("base_background_pop"), str8_lit_comp("base_border"), +str8_lit_comp("base_text"), +str8_lit_comp("base_text_weak"), +str8_lit_comp("base_hover"), +str8_lit_comp("base_focus"), +str8_lit_comp("base_cursor"), +str8_lit_comp("base_cursor"), str8_lit_comp("menu_bar_background"), str8_lit_comp("menu_bar_background_alt"), +str8_lit_comp("menu_bar_background_good"), +str8_lit_comp("menu_bar_background_bad"), +str8_lit_comp("menu_bar_background_pop"), str8_lit_comp("menu_bar_border"), -str8_lit_comp("floating_background"), -str8_lit_comp("floating_background_alt"), -str8_lit_comp("floating_border"), -str8_lit_comp("implicit_button_background"), -str8_lit_comp("implicit_button_border"), -str8_lit_comp("plain_button_background"), -str8_lit_comp("plain_button_border"), -str8_lit_comp("positive_pop_button_background"), -str8_lit_comp("positive_pop_button_border"), -str8_lit_comp("negative_pop_button_background"), -str8_lit_comp("negative_pop_button_border"), -str8_lit_comp("neutral_pop_button_background"), -str8_lit_comp("neutral_pop_button_border"), -str8_lit_comp("scroll_bar_button_background"), -str8_lit_comp("scroll_bar_button_border"), +str8_lit_comp("menu_bar_text"), +str8_lit_comp("menu_bar_text_weak"), +str8_lit_comp("menu_bar_hover"), +str8_lit_comp("menu_bar_focus"), +str8_lit_comp("menu_bar_cursor"), +str8_lit_comp("menu_bar_cursor"), +str8_lit_comp("good_background"), +str8_lit_comp("good_background_alt"), +str8_lit_comp("good_background_good"), +str8_lit_comp("good_background_bad"), +str8_lit_comp("good_background_pop"), +str8_lit_comp("good_border"), +str8_lit_comp("good_text"), +str8_lit_comp("good_text_weak"), +str8_lit_comp("good_hover"), +str8_lit_comp("good_focus"), +str8_lit_comp("good_cursor"), +str8_lit_comp("good_cursor"), +str8_lit_comp("bad_background"), +str8_lit_comp("bad_background_alt"), +str8_lit_comp("bad_background_good"), +str8_lit_comp("bad_background_bad"), +str8_lit_comp("bad_background_pop"), +str8_lit_comp("bad_border"), +str8_lit_comp("bad_text"), +str8_lit_comp("bad_text_weak"), +str8_lit_comp("bad_hover"), +str8_lit_comp("bad_focus"), +str8_lit_comp("bad_cursor"), +str8_lit_comp("bad_cursor"), +str8_lit_comp("pop_background"), +str8_lit_comp("pop_background_alt"), +str8_lit_comp("pop_background_good"), +str8_lit_comp("pop_background_bad"), +str8_lit_comp("pop_background_pop"), +str8_lit_comp("pop_border"), +str8_lit_comp("pop_text"), +str8_lit_comp("pop_text_weak"), +str8_lit_comp("pop_hover"), +str8_lit_comp("pop_focus"), +str8_lit_comp("pop_cursor"), +str8_lit_comp("pop_cursor"), +str8_lit_comp("scroll_bar_background"), +str8_lit_comp("scroll_bar_background_alt"), +str8_lit_comp("scroll_bar_background_good"), +str8_lit_comp("scroll_bar_background_bad"), +str8_lit_comp("scroll_bar_background_pop"), +str8_lit_comp("scroll_bar_border"), +str8_lit_comp("scroll_bar_text"), +str8_lit_comp("scroll_bar_text_weak"), +str8_lit_comp("scroll_bar_hover"), +str8_lit_comp("scroll_bar_focus"), +str8_lit_comp("scroll_bar_cursor"), +str8_lit_comp("scroll_bar_cursor"), str8_lit_comp("tab_background"), +str8_lit_comp("tab_background_alt"), +str8_lit_comp("tab_background_good"), +str8_lit_comp("tab_background_bad"), +str8_lit_comp("tab_background_pop"), str8_lit_comp("tab_border"), -str8_lit_comp("tab_background_inactive"), -str8_lit_comp("tab_border_inactive"), +str8_lit_comp("tab_text"), +str8_lit_comp("tab_text_weak"), +str8_lit_comp("tab_hover"), +str8_lit_comp("tab_focus"), +str8_lit_comp("tab_cursor"), +str8_lit_comp("tab_cursor"), +str8_lit_comp("tab_inactive_background"), +str8_lit_comp("tab_inactive_background_alt"), +str8_lit_comp("tab_inactive_background_good"), +str8_lit_comp("tab_inactive_background_bad"), +str8_lit_comp("tab_inactive_background_pop"), +str8_lit_comp("tab_inactive_border"), +str8_lit_comp("tab_inactive_text"), +str8_lit_comp("tab_inactive_text_weak"), +str8_lit_comp("tab_inactive_hover"), +str8_lit_comp("tab_inactive_focus"), +str8_lit_comp("tab_inactive_cursor"), +str8_lit_comp("tab_inactive_cursor"), +str8_lit_comp("drop_site_background"), +str8_lit_comp("drop_site_background_alt"), +str8_lit_comp("drop_site_background_good"), +str8_lit_comp("drop_site_background_bad"), +str8_lit_comp("drop_site_background_pop"), +str8_lit_comp("drop_site_border"), +str8_lit_comp("drop_site_text"), +str8_lit_comp("drop_site_text_weak"), +str8_lit_comp("drop_site_hover"), +str8_lit_comp("drop_site_focus"), +str8_lit_comp("drop_site_cursor"), +str8_lit_comp("drop_site_cursor"), str8_lit_comp("code_default"), str8_lit_comp("code_symbol"), str8_lit_comp("code_type"), @@ -1852,120 +2560,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 e466ec24..079f6938 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -6,47 +6,6 @@ #ifndef RADDBG_META_H #define RADDBG_META_H -typedef enum RD_CfgSrc -{ -RD_CfgSrc_User, -RD_CfgSrc_Project, -RD_CfgSrc_CommandLine, -RD_CfgSrc_Transient, -RD_CfgSrc_COUNT, -} RD_CfgSrc; - -typedef enum RD_EntityKind -{ -RD_EntityKind_Nil, -RD_EntityKind_Root, -RD_EntityKind_AutoViewRule, -RD_EntityKind_FilePathMap, -RD_EntityKind_WatchPin, -RD_EntityKind_Watch, -RD_EntityKind_ViewRule, -RD_EntityKind_Breakpoint, -RD_EntityKind_Condition, -RD_EntityKind_Location, -RD_EntityKind_Target, -RD_EntityKind_Executable, -RD_EntityKind_Arguments, -RD_EntityKind_WorkingDirectory, -RD_EntityKind_EntryPoint, -RD_EntityKind_StdoutPath, -RD_EntityKind_StderrPath, -RD_EntityKind_StdinPath, -RD_EntityKind_Window, -RD_EntityKind_Panel, -RD_EntityKind_View, -RD_EntityKind_RecentProject, -RD_EntityKind_RecentFile, -RD_EntityKind_Source, -RD_EntityKind_Dest, -RD_EntityKind_ConversionTask, -RD_EntityKind_ConversionFail, -RD_EntityKind_COUNT, -} RD_EntityKind; - typedef enum RD_RegSlot { RD_RegSlot_Null, @@ -60,8 +19,8 @@ RD_RegSlot_Panel, RD_RegSlot_View, RD_RegSlot_PrevView, RD_RegSlot_DstPanel, -RD_RegSlot_Entity, -RD_RegSlot_EntityList, +RD_RegSlot_Cfg, +RD_RegSlot_CfgList, RD_RegSlot_UnwindCount, RD_RegSlot_InlineDepth, RD_RegSlot_FilePath, @@ -75,9 +34,17 @@ RD_RegSlot_Vaddr, RD_RegSlot_Voff, RD_RegSlot_VaddrRange, RD_RegSlot_VoffRange, +RD_RegSlot_Expr, +RD_RegSlot_ViewRule, +RD_RegSlot_UIKey, +RD_RegSlot_OffPx, +RD_RegSlot_ListerFlags, +RD_RegSlot_RegSlot, RD_RegSlot_PID, RD_RegSlot_ForceConfirm, RD_RegSlot_PreferDisasm, +RD_RegSlot_NoRichTooltip, +RD_RegSlot_DoImplicitRoot, RD_RegSlot_Dir2, RD_RegSlot_String, RD_RegSlot_CmdName, @@ -90,7 +57,7 @@ typedef enum RD_CmdKind { RD_CmdKind_Null, RD_CmdKind_LaunchAndRun, -RD_CmdKind_LaunchAndInit, +RD_CmdKind_LaunchAndStepInto, RD_CmdKind_Kill, RD_CmdKind_KillAll, RD_CmdKind_Detach, @@ -104,7 +71,6 @@ RD_CmdKind_Halt, RD_CmdKind_SoftHaltRefresh, RD_CmdKind_SetThreadIP, RD_CmdKind_RunToLine, -RD_CmdKind_RunToAddress, RD_CmdKind_Run, RD_CmdKind_Restart, RD_CmdKind_StepInto, @@ -123,12 +89,15 @@ RD_CmdKind_SetEntityColor, RD_CmdKind_SetEntityName, RD_CmdKind_Attach, RD_CmdKind_Exit, +RD_CmdKind_OpenLister, RD_CmdKind_RunCommand, RD_CmdKind_OSEvent, RD_CmdKind_SelectThread, RD_CmdKind_SelectUnwind, RD_CmdKind_UpOneFrame, RD_CmdKind_DownOneFrame, +RD_CmdKind_SelectEntity, +RD_CmdKind_DeselectEntity, RD_CmdKind_IncUIFontScale, RD_CmdKind_DecUIFontScale, RD_CmdKind_IncCodeFontScale, @@ -141,6 +110,7 @@ RD_CmdKind_PopupAccept, RD_CmdKind_PopupCancel, RD_CmdKind_ResetToDefaultPanels, RD_CmdKind_ResetToCompactPanels, +RD_CmdKind_ResetToSimplePanels, RD_CmdKind_NewPanelLeft, RD_CmdKind_NewPanelUp, RD_CmdKind_NewPanelRight, @@ -159,6 +129,7 @@ RD_CmdKind_Redo, RD_CmdKind_GoBack, RD_CmdKind_GoForward, RD_CmdKind_ClosePanel, +RD_CmdKind_FocusTab, RD_CmdKind_NextTab, RD_CmdKind_PrevTab, RD_CmdKind_MoveTabRight, @@ -173,14 +144,13 @@ RD_CmdKind_Open, RD_CmdKind_Switch, RD_CmdKind_SwitchToPartnerFile, RD_CmdKind_RecordFileInProject, +RD_CmdKind_ShowFileInExplorer, RD_CmdKind_GoToDisassembly, RD_CmdKind_GoToSource, RD_CmdKind_SetFileReplacementPath, RD_CmdKind_OpenUser, RD_CmdKind_OpenProject, RD_CmdKind_OpenRecentProject, -RD_CmdKind_ApplyUserData, -RD_CmdKind_ApplyProjectData, RD_CmdKind_WriteUserData, RD_CmdKind_WriteProjectData, RD_CmdKind_Edit, @@ -243,14 +213,15 @@ RD_CmdKind_ToggleWatchExpressionAtMouse, RD_CmdKind_SetColumns, RD_CmdKind_ToggleAddressVisibility, RD_CmdKind_ToggleCodeBytesVisibility, -RD_CmdKind_EnableEntity, -RD_CmdKind_DisableEntity, -RD_CmdKind_SelectEntity, -RD_CmdKind_RemoveEntity, -RD_CmdKind_NameEntity, -RD_CmdKind_ConditionEntity, -RD_CmdKind_DuplicateEntity, -RD_CmdKind_RelocateEntity, +RD_CmdKind_EnableCfg, +RD_CmdKind_DisableCfg, +RD_CmdKind_SelectCfg, +RD_CmdKind_DeselectCfg, +RD_CmdKind_RemoveCfg, +RD_CmdKind_NameCfg, +RD_CmdKind_ConditionCfg, +RD_CmdKind_DuplicateCfg, +RD_CmdKind_RelocateCfg, RD_CmdKind_AddBreakpoint, RD_CmdKind_AddAddressBreakpoint, RD_CmdKind_AddFunctionBreakpoint, @@ -259,7 +230,7 @@ RD_CmdKind_EnableBreakpoint, RD_CmdKind_DisableBreakpoint, RD_CmdKind_AddWatchPin, RD_CmdKind_ToggleWatchPin, -RD_CmdKind_RunToCursor, +RD_CmdKind_AddAutoViewRule, RD_CmdKind_SetNextStatement, RD_CmdKind_AddTarget, RD_CmdKind_SelectTarget, @@ -267,12 +238,10 @@ RD_CmdKind_EnableTarget, RD_CmdKind_DisableTarget, RD_CmdKind_RegisterAsJITDebugger, RD_CmdKind_FindCodeLocation, -RD_CmdKind_Filter, -RD_CmdKind_ApplyFilter, -RD_CmdKind_ClearFilter, +RD_CmdKind_Search, +RD_CmdKind_SearchBackwards, RD_CmdKind_GettingStarted, RD_CmdKind_Commands, -RD_CmdKind_Target, RD_CmdKind_Targets, RD_CmdKind_FilePathMap, RD_CmdKind_AutoViewRules, @@ -292,13 +261,14 @@ RD_CmdKind_PendingFile, RD_CmdKind_Disassembly, RD_CmdKind_Output, RD_CmdKind_Memory, -RD_CmdKind_ExceptionFilters, RD_CmdKind_Settings, RD_CmdKind_PickFile, RD_CmdKind_PickFolder, RD_CmdKind_PickFileOrFolder, +RD_CmdKind_PushQuery, RD_CmdKind_CompleteQuery, RD_CmdKind_CancelQuery, +RD_CmdKind_UpdateQuery, RD_CmdKind_ToggleDevMenu, RD_CmdKind_LogMarker, RD_CmdKind_COUNT, @@ -334,6 +304,7 @@ RD_IconKind_RadioHollow, RD_IconKind_RadioFilled, RD_IconKind_CheckHollow, RD_IconKind_CheckFilled, +RD_IconKind_Check, RD_IconKind_LeftCaret, RD_IconKind_RightCaret, RD_IconKind_UpCaret, @@ -375,93 +346,126 @@ RD_IconKind_QuestionMark, RD_IconKind_Person, RD_IconKind_Briefcase, RD_IconKind_Dot, +RD_IconKind_Bitmap, +RD_IconKind_Cube, +RD_IconKind_WindowRestore, +RD_IconKind_WindowMinimize, RD_IconKind_COUNT, } RD_IconKind; -typedef enum RD_ViewRuleKind -{ -RD_ViewRuleKind_Null, -RD_ViewRuleKind_Empty, -RD_ViewRuleKind_GettingStarted, -RD_ViewRuleKind_ExceptionFilters, -RD_ViewRuleKind_Settings, -RD_ViewRuleKind_PendingFile, -RD_ViewRuleKind_Commands, -RD_ViewRuleKind_FileSystem, -RD_ViewRuleKind_SystemProcesses, -RD_ViewRuleKind_EntityLister, -RD_ViewRuleKind_CtrlEntityLister, -RD_ViewRuleKind_SymbolLister, -RD_ViewRuleKind_Watch, -RD_ViewRuleKind_Locals, -RD_ViewRuleKind_Registers, -RD_ViewRuleKind_Globals, -RD_ViewRuleKind_ThreadLocals, -RD_ViewRuleKind_Types, -RD_ViewRuleKind_Procedures, -RD_ViewRuleKind_Targets, -RD_ViewRuleKind_FilePathMap, -RD_ViewRuleKind_AutoViewRules, -RD_ViewRuleKind_Breakpoints, -RD_ViewRuleKind_WatchPins, -RD_ViewRuleKind_Scheduler, -RD_ViewRuleKind_CallStack, -RD_ViewRuleKind_Modules, -RD_ViewRuleKind_Text, -RD_ViewRuleKind_Disasm, -RD_ViewRuleKind_Output, -RD_ViewRuleKind_Memory, -RD_ViewRuleKind_Bitmap, -RD_ViewRuleKind_Checkbox, -RD_ViewRuleKind_ColorRGBA, -RD_ViewRuleKind_Geo3D, -RD_ViewRuleKind_COUNT, -} RD_ViewRuleKind; - typedef enum RD_ThemeColor { RD_ThemeColor_Null, -RD_ThemeColor_Text, -RD_ThemeColor_TextPositive, -RD_ThemeColor_TextNegative, -RD_ThemeColor_TextNeutral, -RD_ThemeColor_TextWeak, -RD_ThemeColor_Cursor, -RD_ThemeColor_CursorInactive, -RD_ThemeColor_Focus, -RD_ThemeColor_Hover, -RD_ThemeColor_DropShadow, -RD_ThemeColor_DisabledOverlay, -RD_ThemeColor_DropSiteOverlay, RD_ThemeColor_InactivePanelOverlay, -RD_ThemeColor_SelectionOverlay, -RD_ThemeColor_HighlightOverlay, -RD_ThemeColor_HighlightOverlayError, +RD_ThemeColor_DropShadow, RD_ThemeColor_BaseBackground, RD_ThemeColor_BaseBackgroundAlt, +RD_ThemeColor_BaseBackgroundGood, +RD_ThemeColor_BaseBackgroundBad, +RD_ThemeColor_BaseBackgroundPop, RD_ThemeColor_BaseBorder, +RD_ThemeColor_BaseText, +RD_ThemeColor_BaseTextWeak, +RD_ThemeColor_BaseHover, +RD_ThemeColor_BaseFocus, +RD_ThemeColor_BaseCursor, +RD_ThemeColor_BaseSelection, RD_ThemeColor_MenuBarBackground, RD_ThemeColor_MenuBarBackgroundAlt, +RD_ThemeColor_MenuBarBackgroundGood, +RD_ThemeColor_MenuBarBackgroundBad, +RD_ThemeColor_MenuBarBackgroundPop, RD_ThemeColor_MenuBarBorder, -RD_ThemeColor_FloatingBackground, -RD_ThemeColor_FloatingBackgroundAlt, -RD_ThemeColor_FloatingBorder, -RD_ThemeColor_ImplicitButtonBackground, -RD_ThemeColor_ImplicitButtonBorder, -RD_ThemeColor_PlainButtonBackground, -RD_ThemeColor_PlainButtonBorder, -RD_ThemeColor_PositivePopButtonBackground, -RD_ThemeColor_PositivePopButtonBorder, -RD_ThemeColor_NegativePopButtonBackground, -RD_ThemeColor_NegativePopButtonBorder, -RD_ThemeColor_NeutralPopButtonBackground, -RD_ThemeColor_NeutralPopButtonBorder, -RD_ThemeColor_ScrollBarButtonBackground, -RD_ThemeColor_ScrollBarButtonBorder, +RD_ThemeColor_MenuBarText, +RD_ThemeColor_MenuBarTextWeak, +RD_ThemeColor_MenuBarHover, +RD_ThemeColor_MenuBarFocus, +RD_ThemeColor_MenuBarCursor, +RD_ThemeColor_MenuBarSelection, +RD_ThemeColor_GoodBackground, +RD_ThemeColor_GoodBackgroundAlt, +RD_ThemeColor_GoodBackgroundGood, +RD_ThemeColor_GoodBackgroundBad, +RD_ThemeColor_GoodBackgroundPop, +RD_ThemeColor_GoodBorder, +RD_ThemeColor_GoodText, +RD_ThemeColor_GoodTextWeak, +RD_ThemeColor_GoodHover, +RD_ThemeColor_GoodFocus, +RD_ThemeColor_GoodCursor, +RD_ThemeColor_GoodSelection, +RD_ThemeColor_BadBackground, +RD_ThemeColor_BadBackgroundAlt, +RD_ThemeColor_BadBackgroundGood, +RD_ThemeColor_BadBackgroundBad, +RD_ThemeColor_BadBackgroundPop, +RD_ThemeColor_BadBorder, +RD_ThemeColor_BadText, +RD_ThemeColor_BadTextWeak, +RD_ThemeColor_BadHover, +RD_ThemeColor_BadFocus, +RD_ThemeColor_BadCursor, +RD_ThemeColor_BadSelection, +RD_ThemeColor_PopBackground, +RD_ThemeColor_PopBackgroundAlt, +RD_ThemeColor_PopBackgroundGood, +RD_ThemeColor_PopBackgroundBad, +RD_ThemeColor_PopBackgroundPop, +RD_ThemeColor_PopBorder, +RD_ThemeColor_PopText, +RD_ThemeColor_PopTextWeak, +RD_ThemeColor_PopHover, +RD_ThemeColor_PopFocus, +RD_ThemeColor_PopCursor, +RD_ThemeColor_PopSelection, +RD_ThemeColor_ScrollBarBackground, +RD_ThemeColor_ScrollBarBackgroundAlt, +RD_ThemeColor_ScrollBarBackgroundGood, +RD_ThemeColor_ScrollBarBackgroundBad, +RD_ThemeColor_ScrollBarBackgroundPop, +RD_ThemeColor_ScrollBarBorder, +RD_ThemeColor_ScrollBarText, +RD_ThemeColor_ScrollBarTextWeak, +RD_ThemeColor_ScrollBarHover, +RD_ThemeColor_ScrollBarFocus, +RD_ThemeColor_ScrollBarCursor, +RD_ThemeColor_ScrollBarSelection, RD_ThemeColor_TabBackground, +RD_ThemeColor_TabBackgroundAlt, +RD_ThemeColor_TabBackgroundGood, +RD_ThemeColor_TabBackgroundBad, +RD_ThemeColor_TabBackgroundPop, RD_ThemeColor_TabBorder, -RD_ThemeColor_TabBackgroundInactive, -RD_ThemeColor_TabBorderInactive, +RD_ThemeColor_TabText, +RD_ThemeColor_TabTextWeak, +RD_ThemeColor_TabHover, +RD_ThemeColor_TabFocus, +RD_ThemeColor_TabCursor, +RD_ThemeColor_TabSelection, +RD_ThemeColor_TabInactiveBackground, +RD_ThemeColor_TabInactiveBackgroundAlt, +RD_ThemeColor_TabInactiveBackgroundGood, +RD_ThemeColor_TabInactiveBackgroundBad, +RD_ThemeColor_TabInactiveBackgroundPop, +RD_ThemeColor_TabInactiveBorder, +RD_ThemeColor_TabInactiveText, +RD_ThemeColor_TabInactiveTextWeak, +RD_ThemeColor_TabInactiveHover, +RD_ThemeColor_TabInactiveFocus, +RD_ThemeColor_TabInactiveCursor, +RD_ThemeColor_TabInactiveSelection, +RD_ThemeColor_DropSiteBackground, +RD_ThemeColor_DropSiteBackgroundAlt, +RD_ThemeColor_DropSiteBackgroundGood, +RD_ThemeColor_DropSiteBackgroundBad, +RD_ThemeColor_DropSiteBackgroundPop, +RD_ThemeColor_DropSiteBorder, +RD_ThemeColor_DropSiteText, +RD_ThemeColor_DropSiteTextWeak, +RD_ThemeColor_DropSiteHover, +RD_ThemeColor_DropSiteFocus, +RD_ThemeColor_DropSiteCursor, +RD_ThemeColor_DropSiteSelection, RD_ThemeColor_CodeDefault, RD_ThemeColor_CodeSymbol, RD_ThemeColor_CodeType, @@ -513,29 +517,22 @@ RD_ThemePreset_FarManager, RD_ThemePreset_COUNT, } RD_ThemePreset; -typedef enum RD_SettingCode +typedef struct RD_VocabInfo RD_VocabInfo; +struct RD_VocabInfo { -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; +String8 code_name; +String8 code_name_plural; +String8 display_name; +String8 display_name_plural; +RD_IconKind icon_kind; +}; + +typedef struct RD_NameSchemaInfo RD_NameSchemaInfo; +struct RD_NameSchemaInfo +{ +String8 name; +String8 schema; +}; typedef struct RD_Regs RD_Regs; struct RD_Regs @@ -545,13 +542,13 @@ CTRL_Handle module; CTRL_Handle process; CTRL_Handle thread; CTRL_Handle ctrl_entity; -RD_Handle window; -RD_Handle panel; -RD_Handle view; -RD_Handle prev_view; -RD_Handle dst_panel; -RD_Handle entity; -RD_HandleList entity_list; +RD_CfgID window; +RD_CfgID panel; +RD_CfgID view; +RD_CfgID prev_view; +RD_CfgID dst_panel; +RD_CfgID cfg; +RD_CfgIDList cfg_list; U64 unwind_count; U64 inline_depth; String8 file_path; @@ -565,9 +562,17 @@ U64 vaddr; U64 voff; Rng1U64 vaddr_range; Rng1U64 voff_range; +String8 expr; +String8 view_rule; +UI_Key ui_key; +Vec2F32 off_px; +RD_ListerFlags lister_flags; +RD_RegSlot reg_slot; U32 pid; B32 force_confirm; B32 prefer_disasm; +B32 no_rich_tooltip; +B32 do_implicit_root; Dir2 dir2; String8 string; String8 cmd_name; @@ -580,8 +585,8 @@ struct RD_Query { RD_QueryFlags flags; RD_RegSlot slot; +String8 expr; String8 view_name; -RD_EntityKind entity_kind; CTRL_EntityKind ctrl_entity_kind; }; @@ -591,25 +596,11 @@ struct RD_CmdKindInfo String8 string; String8 description; String8 search_tags; -String8 display_name; -RD_IconKind icon_kind; +String8 ctx_filter; RD_CmdKindFlags flags; RD_Query query; }; -typedef struct RD_ViewRuleInfo RD_ViewRuleInfo; -struct RD_ViewRuleInfo -{ -String8 string; -String8 description; -String8 display_name; -String8 params_schema; -RD_IconKind icon_kind; -RD_ViewRuleInfoFlags flags; -EV_ViewRuleExprExpandInfoHookFunctionType *expr_expand_info; -RD_ViewRuleUIFunctionType *ui; -}; - #define rd_regs_lit_init_top \ .machine = rd_regs()->machine,\ .module = rd_regs()->module,\ @@ -621,8 +612,8 @@ RD_ViewRuleUIFunctionType *ui; .view = rd_regs()->view,\ .prev_view = rd_regs()->prev_view,\ .dst_panel = rd_regs()->dst_panel,\ -.entity = rd_regs()->entity,\ -.entity_list = rd_regs()->entity_list,\ +.cfg = rd_regs()->cfg,\ +.cfg_list = rd_regs()->cfg_list,\ .unwind_count = rd_regs()->unwind_count,\ .inline_depth = rd_regs()->inline_depth,\ .file_path = rd_regs()->file_path,\ @@ -636,566 +627,435 @@ RD_ViewRuleUIFunctionType *ui; .voff = rd_regs()->voff,\ .vaddr_range = rd_regs()->vaddr_range,\ .voff_range = rd_regs()->voff_range,\ +.expr = rd_regs()->expr,\ +.view_rule = rd_regs()->view_rule,\ +.ui_key = rd_regs()->ui_key,\ +.off_px = rd_regs()->off_px,\ +.lister_flags = rd_regs()->lister_flags,\ +.reg_slot = rd_regs()->reg_slot,\ .pid = rd_regs()->pid,\ .force_confirm = rd_regs()->force_confirm,\ .prefer_disasm = rd_regs()->prefer_disasm,\ +.no_rich_tooltip = rd_regs()->no_rich_tooltip,\ +.do_implicit_root = rd_regs()->do_implicit_root,\ .dir2 = rd_regs()->dir2,\ .string = rd_regs()->string,\ .cmd_name = rd_regs()->cmd_name,\ .params_tree = rd_regs()->params_tree,\ .os_event = rd_regs()->os_event,\ -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(watches); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(targets); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(breakpoints); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(watch_pins); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(file_path_maps); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(auto_view_rules); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(machines); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(processes); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(threads); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(modules); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_machine); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_process); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(locals); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(registers); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(globals); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(thread_locals); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(types); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(procedures); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(watches); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(targets); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(breakpoints); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(watch_pins); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(file_path_maps); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(auto_view_rules); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(machines); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(processes); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(threads); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(modules); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_machine); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_process); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(locals); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(registers); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(globals); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(thread_locals); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(types); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(procedures); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(targets); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(breakpoints); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watch_pins); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(file_path_maps); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(auto_view_rules); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(machines); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(processes); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(threads); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(modules); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_machine); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_process); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(globals); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(thread_locals); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(types); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(procedures); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(targets); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(breakpoints); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watch_pins); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(file_path_maps); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(auto_view_rules); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(machines); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(processes); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(threads); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(modules); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_machine); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(globals); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(thread_locals); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(types); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(procedures); -RD_VIEW_RULE_UI_FUNCTION_DEF(null); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(text); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(disasm); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(memory); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(bitmap); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(color_rgba); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(geo3d); -RD_VIEW_RULE_UI_FUNCTION_DEF(empty); -RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started); -RD_VIEW_RULE_UI_FUNCTION_DEF(exception_filters); -RD_VIEW_RULE_UI_FUNCTION_DEF(settings); -RD_VIEW_RULE_UI_FUNCTION_DEF(pending_file); -RD_VIEW_RULE_UI_FUNCTION_DEF(commands); -RD_VIEW_RULE_UI_FUNCTION_DEF(file_system); -RD_VIEW_RULE_UI_FUNCTION_DEF(system_processes); -RD_VIEW_RULE_UI_FUNCTION_DEF(entity_lister); -RD_VIEW_RULE_UI_FUNCTION_DEF(ctrl_entity_lister); -RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister); -RD_VIEW_RULE_UI_FUNCTION_DEF(watch); -RD_VIEW_RULE_UI_FUNCTION_DEF(locals); -RD_VIEW_RULE_UI_FUNCTION_DEF(registers); -RD_VIEW_RULE_UI_FUNCTION_DEF(globals); -RD_VIEW_RULE_UI_FUNCTION_DEF(thread_locals); -RD_VIEW_RULE_UI_FUNCTION_DEF(types); -RD_VIEW_RULE_UI_FUNCTION_DEF(procedures); -RD_VIEW_RULE_UI_FUNCTION_DEF(targets); -RD_VIEW_RULE_UI_FUNCTION_DEF(file_path_map); -RD_VIEW_RULE_UI_FUNCTION_DEF(auto_view_rules); -RD_VIEW_RULE_UI_FUNCTION_DEF(breakpoints); -RD_VIEW_RULE_UI_FUNCTION_DEF(watch_pins); -RD_VIEW_RULE_UI_FUNCTION_DEF(scheduler); -RD_VIEW_RULE_UI_FUNCTION_DEF(call_stack); -RD_VIEW_RULE_UI_FUNCTION_DEF(modules); -RD_VIEW_RULE_UI_FUNCTION_DEF(text); -RD_VIEW_RULE_UI_FUNCTION_DEF(disasm); -RD_VIEW_RULE_UI_FUNCTION_DEF(output); -RD_VIEW_RULE_UI_FUNCTION_DEF(memory); -RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap); -RD_VIEW_RULE_UI_FUNCTION_DEF(checkbox); -RD_VIEW_RULE_UI_FUNCTION_DEF(color_rgba); -RD_VIEW_RULE_UI_FUNCTION_DEF(geo3d); C_LINKAGE_BEGIN -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_CmdKind rd_cfg_src_apply_cmd_kind_table[4]; -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]; -extern String8 d_entity_kind_name_label_table[27]; -extern RD_EntityKindFlags rd_entity_kind_flags_table[27]; -extern Rng1U64 rd_reg_slot_range_table[34]; -extern RD_StringBindingPair rd_default_binding_table[110]; +extern RD_VocabInfo rd_vocab_info_table[308]; +extern RD_NameSchemaInfo rd_name_schema_info_table[16]; +extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; -extern String8 rd_icon_kind_text_table[69]; -extern String8 rd_collection_name_table[18]; -extern RD_EntityKind rd_collection_entity_kind_table[18]; -extern CTRL_EntityKind rd_collection_ctrl_entity_kind_table[18]; -extern EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[18]; -extern EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[18]; -extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[18]; -extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[18]; -extern RD_ViewRuleInfo rd_view_rule_kind_info_table[35]; -extern RD_IconKind rd_entity_kind_icon_kind_table[27]; +extern String8 rd_icon_kind_text_table[74]; extern String8 rd_theme_preset_display_string_table[9]; extern String8 rd_theme_preset_code_string_table[9]; +extern String8 rd_theme_preset_cfg_string_table[9]; extern String8 rd_theme_color_version_remap_old_name_table[22]; extern String8 rd_theme_color_version_remap_new_name_table[22]; -extern Vec4F32 rd_theme_preset_colors__default_dark[76]; -extern Vec4F32 rd_theme_preset_colors__default_light[76]; -extern Vec4F32 rd_theme_preset_colors__vs_dark[76]; -extern Vec4F32 rd_theme_preset_colors__vs_light[76]; -extern Vec4F32 rd_theme_preset_colors__solarized_dark[76]; -extern Vec4F32 rd_theme_preset_colors__solarized_light[76]; -extern Vec4F32 rd_theme_preset_colors__handmade_hero[76]; -extern Vec4F32 rd_theme_preset_colors__four_coder[76]; -extern Vec4F32 rd_theme_preset_colors__far_manager[76]; +extern Vec4F32 rd_theme_preset_colors__default_dark[145]; +extern Vec4F32 rd_theme_preset_colors__default_light[145]; +extern Vec4F32 rd_theme_preset_colors__vs_dark[145]; +extern Vec4F32 rd_theme_preset_colors__vs_light[145]; +extern Vec4F32 rd_theme_preset_colors__solarized_dark[145]; +extern Vec4F32 rd_theme_preset_colors__solarized_light[145]; +extern Vec4F32 rd_theme_preset_colors__handmade_hero[145]; +extern Vec4F32 rd_theme_preset_colors__four_coder[145]; +extern Vec4F32 rd_theme_preset_colors__far_manager[145]; 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]; +extern String8 rd_theme_color_display_string_table[145]; +extern String8 rd_theme_color_cfg_string_table[145]; 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, -0x0e,0x5d,0x06,0x6d,0x00,0x00,0x53,0xc0,0x00,0x00,0x00,0x38,0x66,0x70,0x67,0x6d,0x62,0x31,0xfb,0x7b,0x00,0x00,0x53,0xf8,0x00,0x00,0x0e,0x0c,0x67,0x61,0x73,0x70,0x00,0x00,0x00,0x10,0x00,0x00,0x53,0xb8,0x00,0x00,0x00,0x08,0x67,0x6c,0x79,0x66,0x3f,0x82,0x6a,0x1b,0x00,0x00,0x07,0x9c,0x00,0x00,0x43,0x86,0x68,0x65,0x61,0x64, -0x26,0x89,0x5f,0x83,0x00,0x00,0x4b,0x24,0x00,0x00,0x00,0x36,0x68,0x68,0x65,0x61,0x07,0x79,0x03,0xdb,0x00,0x00,0x4b,0x5c,0x00,0x00,0x00,0x24,0x68,0x6d,0x74,0x78,0xf3,0xce,0xff,0xc8,0x00,0x00,0x4b,0x80,0x00,0x00,0x01,0x30,0x6c,0x6f,0x63,0x61,0x8c,0xcb,0x7c,0x1e,0x00,0x00,0x4c,0xb0,0x00,0x00,0x00,0x9a,0x6d,0x61,0x78,0x70, -0x01,0xe3,0x0f,0x19,0x00,0x00,0x4d,0x4c,0x00,0x00,0x00,0x20,0x6e,0x61,0x6d,0x65,0xcd,0x9d,0x1a,0x1b,0x00,0x00,0x4d,0x6c,0x00,0x00,0x02,0xcd,0x70,0x6f,0x73,0x74,0x95,0xf6,0x72,0x8f,0x00,0x00,0x50,0x3c,0x00,0x00,0x03,0x79,0x70,0x72,0x65,0x70,0xeb,0x48,0xca,0x9d,0x00,0x00,0x62,0x04,0x00,0x00,0x00,0xa7,0x00,0x01,0x00,0x00, +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,0x43,0x62,0x22,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0xa3,0x60,0xa4,0x23,0x00,0x00,0x01,0xb0,0x00,0x00,0x06,0x12,0x63,0x76,0x74,0x20, +0x0e,0x1f,0x06,0xf3,0x00,0x00,0x51,0x5c,0x00,0x00,0x00,0x38,0x66,0x70,0x67,0x6d,0x62,0x31,0xfb,0x7b,0x00,0x00,0x51,0x94,0x00,0x00,0x0e,0x0c,0x67,0x61,0x73,0x70,0x00,0x00,0x00,0x10,0x00,0x00,0x51,0x54,0x00,0x00,0x00,0x08,0x67,0x6c,0x79,0x66,0x98,0xff,0x4e,0x69,0x00,0x00,0x07,0xc4,0x00,0x00,0x40,0xb8,0x68,0x65,0x61,0x64, +0x2b,0x9e,0xf7,0x7d,0x00,0x00,0x48,0x7c,0x00,0x00,0x00,0x36,0x68,0x68,0x65,0x61,0x07,0xc2,0x04,0x27,0x00,0x00,0x48,0xb4,0x00,0x00,0x00,0x24,0x68,0x6d,0x74,0x78,0x05,0x74,0xff,0xca,0x00,0x00,0x48,0xd8,0x00,0x00,0x01,0x44,0x6c,0x6f,0x63,0x61,0x74,0xb2,0x85,0xb8,0x00,0x00,0x4a,0x1c,0x00,0x00,0x00,0xa4,0x6d,0x61,0x78,0x70, +0x01,0xe8,0x0f,0x19,0x00,0x00,0x4a,0xc0,0x00,0x00,0x00,0x20,0x6e,0x61,0x6d,0x65,0xcd,0x9d,0x1c,0x1d,0x00,0x00,0x4a,0xe0,0x00,0x00,0x02,0xcd,0x70,0x6f,0x73,0x74,0x85,0xfb,0x3a,0x46,0x00,0x00,0x4d,0xb0,0x00,0x00,0x03,0xa3,0x70,0x72,0x65,0x70,0xeb,0x48,0xca,0x9d,0x00,0x00,0x5f,0xa0,0x00,0x00,0x00,0xa7,0x00,0x01,0x00,0x00, 0x00,0x0a,0x00,0x30,0x00,0x3e,0x00,0x02,0x44,0x46,0x4c,0x54,0x00,0x0e,0x6c,0x61,0x74,0x6e,0x00,0x1a,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x6c,0x69,0x67,0x61,0x00,0x08,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x04,0x00,0x04, -0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x01,0x00,0x06,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x03,0x35,0x01,0x90,0x00,0x05,0x00,0x00,0x02,0x7a,0x02,0xbc,0x00,0x00,0x00,0x8c,0x02,0x7a,0x02,0xbc,0x00,0x00,0x01,0xe0,0x00,0x31,0x01,0x02,0x00,0x00,0x02,0x00,0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x66,0x45,0x64,0x00,0xc0,0x00,0x21,0xe8,0x00,0x03,0x52,0xff,0x6a,0x00,0x5a,0x03,0xac,0x00,0x96,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x04, -0x00,0x00,0x02,0x58,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x52,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x2c,0x00,0x03,0x00,0x0a,0x00,0x00,0x02,0x58,0x00,0x04,0x01,0x26,0x00,0x00,0x00,0x20,0x00,0x20,0x00,0x04,0x00,0x00,0x00,0x23,0x00,0x27,0x00,0x2b,0x00,0x2e,0x00,0x31,0x00,0x35,0x00,0x39,0x00,0x3c,0x00,0x50,0x00,0x5b,0x00,0x5e, -0x00,0x73,0x00,0x7b,0x00,0x7d,0xe8,0x00,0xff,0xff,0x00,0x00,0x00,0x21,0x00,0x27,0x00,0x2b,0x00,0x2d,0x00,0x30,0x00,0x33,0x00,0x37,0x00,0x3c,0x00,0x3e,0x00,0x52,0x00,0x5d,0x00,0x61,0x00,0x75,0x00,0x7d,0xe8,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x20,0x00,0x24,0x00,0x24,0x00,0x24,0x00,0x26,0x00,0x28,0x00,0x2c,0x00,0x30,0x00,0x30,0x00,0x54,0x00,0x66,0x00,0x68,0x00,0x8c,0x00,0x98,0x00,0x98,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0a, -0x00,0x0b,0x00,0x0c,0x00,0x0d,0x00,0x0e,0x00,0x0f,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,0x14,0x00,0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x1a,0x00,0x1b,0x00,0x1c,0x00,0x1d,0x00,0x1e,0x00,0x1f,0x00,0x20,0x00,0x21,0x00,0x22,0x00,0x23,0x00,0x24,0x00,0x25,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x29,0x00,0x2a, -0x00,0x2b,0x00,0x2c,0x00,0x2d,0x00,0x2e,0x00,0x2f,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x3a,0x00,0x3b,0x00,0x3c,0x00,0x3d,0x00,0x3e,0x00,0x3f,0x00,0x40,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00,0x45,0x00,0x46,0x00,0x47,0x00,0x48,0x00,0x49,0x00,0x4a, -0x00,0x4b,0x00,0x00,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x06,0x07,0x00,0x08,0x09,0x00,0x0a,0x0b,0x0c,0x00,0x0d, -0x0e,0x0f,0x00,0x00,0x10,0x00,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x00,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x00,0x2e,0x2f,0x00,0x00,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x00,0x43,0x44,0x45, -0x46,0x47,0x48,0x49,0x00,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x01,0x00,0x06,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x03,0x3a,0x01,0x90,0x00,0x05,0x00,0x00,0x02,0x7a,0x02,0xbc,0x00,0x00,0x00,0x8c,0x02,0x7a,0x02,0xbc,0x00,0x00,0x01,0xe0,0x00,0x31,0x01,0x02,0x00,0x00,0x02,0x00,0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x66,0x45,0x64,0x00,0xc0,0x00,0x21,0x00,0x7d,0x03,0x52,0xff,0x6a,0x00,0x5a,0x03,0xac,0x00,0x96,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x04, +0x00,0x00,0x02,0x42,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x3c,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x2c,0x00,0x03,0x00,0x0a,0x00,0x00,0x02,0x42,0x00,0x04,0x01,0x10,0x00,0x00,0x00,0x18,0x00,0x10,0x00,0x03,0x00,0x08,0x00,0x23,0x00,0x2b,0x00,0x2e,0x00,0x31,0x00,0x39,0x00,0x3c,0x00,0x5b,0x00,0x5e,0x00,0x73,0x00,0x7b,0x00,0x7d, +0xff,0xff,0x00,0x00,0x00,0x21,0x00,0x26,0x00,0x2d,0x00,0x30,0x00,0x33,0x00,0x3c,0x00,0x3e,0x00,0x5d,0x00,0x61,0x00,0x75,0x00,0x7d,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x1c,0x00,0x26,0x00,0x28,0x00,0x2a,0x00,0x36, +0x00,0x36,0x00,0x70,0x00,0x72,0x00,0x96,0x00,0xa2,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0a,0x00,0x0b,0x00,0x0c,0x00,0x0d,0x00,0x0e,0x00,0x0f,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,0x14,0x00,0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x1a, +0x00,0x1b,0x00,0x1c,0x00,0x1d,0x00,0x1e,0x00,0x1f,0x00,0x20,0x00,0x21,0x00,0x22,0x00,0x23,0x00,0x24,0x00,0x25,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x29,0x00,0x2a,0x00,0x2b,0x00,0x2c,0x00,0x2d,0x00,0x2e,0x00,0x2f,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x3a, +0x00,0x3b,0x00,0x3c,0x00,0x3d,0x00,0x3e,0x00,0x3f,0x00,0x40,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00,0x45,0x00,0x46,0x00,0x47,0x00,0x48,0x00,0x49,0x00,0x4a,0x00,0x4b,0x00,0x4c,0x00,0x4d,0x00,0x4e,0x00,0x4f,0x00,0x50,0x00,0x00,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x00,0x00,0x04,0x05,0x06,0x07,0x08,0x09,0x00,0x0a,0x0b,0x00,0x0c,0x0d,0x00,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x00,0x00,0x15,0x00,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25, +0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x00,0x34,0x35,0x00,0x00,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x00,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x03,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x27, -0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x31, -0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x0e, -0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x41, -0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x46, -0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x1d,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x1e, -0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x4d,0x00,0x00,0x00,0x4d,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x4f,0x00,0x00,0x00,0x4f,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x52, -0x00,0x00,0x00,0x52,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x53,0x00,0x00,0x00,0x53,0x00,0x00,0x00,0x25,0x00,0x00,0x00,0x54,0x00,0x00,0x00,0x54,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x56,0x00,0x00,0x00,0x56,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x57, -0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x59,0x00,0x00,0x00,0x59,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x5a,0x00,0x00,0x00,0x5a,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x5b,0x00,0x00,0x00,0x5b,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x5d,0x00,0x00,0x00,0x5d,0x00,0x00,0x00,0x2e, -0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x2f,0x00,0x00,0x00,0x61,0x00,0x00,0x00,0x61,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x62,0x00,0x00,0x00,0x62,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x63,0x00,0x00,0x00,0x63,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x65, -0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x67,0x00,0x00,0x00,0x67,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x6a,0x00,0x00,0x00,0x6a, -0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x6b,0x00,0x00,0x00,0x6b,0x00,0x00,0x00,0x3a,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x3b,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x6e,0x00,0x00,0x00,0x6e,0x00,0x00,0x00,0x3d,0x00,0x00,0x00,0x6f,0x00,0x00,0x00,0x6f,0x00,0x00,0x00,0x3e, -0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x71,0x00,0x00,0x00,0x71,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x72,0x00,0x00,0x00,0x72,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x73,0x00,0x00,0x00,0x73,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x75,0x00,0x00,0x00,0x75,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x76, -0x00,0x00,0x00,0x76,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x79,0x00,0x00,0x00,0x79,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x7a,0x00,0x00,0x00,0x7a,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x7b,0x00,0x00,0x00,0x7b, -0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x7d,0x00,0x00,0x00,0x7d,0x00,0x00,0x00,0x4a,0x00,0x00,0xe8,0x00,0x00,0x00,0xe8,0x00,0x00,0x00,0x00,0x4b,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x49,0x4b,0xb0,0x24,0x50,0x58,0x40,0x13,0x00,0x01,0x00,0x02,0x01,0x02,0x63,0x04,0x01,0x00,0x00,0x03,0x5f, -0x00,0x03,0x03,0x10,0x00,0x4e,0x1b,0x40,0x19,0x00,0x03,0x04,0x01,0x00,0x01,0x03,0x00,0x67,0x00,0x01,0x02,0x02,0x01,0x57,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x01,0x02,0x4f,0x59,0x40,0x0f,0x02,0x00,0x1e,0x1b,0x16,0x13,0x0a,0x07,0x00,0x0f,0x02,0x0f,0x05,0x07,0x16,0x2b,0x01,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32, -0x36,0x35,0x11,0x34,0x26,0x17,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x71,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x34,0x7c,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x02,0xc3,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x59, -0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x06,0x00,0x00,0xff,0xba,0x02,0x80,0x03,0x02,0x00,0x13,0x00,0x1c,0x00,0x25,0x00,0x39,0x00,0x42,0x00,0x4b,0x00,0x84,0x40,0x0d,0x39,0x30,0x2f,0x26,0x0d,0x0c,0x03,0x02,0x08,0x02,0x04,0x01,0x4c,0x4b,0xb0,0x16,0x50,0x58,0x40,0x25,0x08,0x0c,0x02,0x04,0x0b,0x01, -0x02,0x03,0x04,0x02,0x69,0x09,0x01,0x05,0x05,0x01,0x61,0x07,0x01,0x01,0x01,0x10,0x4d,0x0d,0x0a,0x02,0x03,0x03,0x00,0x61,0x06,0x01,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x23,0x07,0x01,0x01,0x09,0x01,0x05,0x04,0x01,0x05,0x69,0x08,0x0c,0x02,0x04,0x0b,0x01,0x02,0x03,0x04,0x02,0x69,0x0d,0x0a,0x02,0x03,0x03,0x00,0x61,0x06,0x01, -0x00,0x00,0x11,0x00,0x4e,0x59,0x40,0x1f,0x44,0x43,0x1e,0x1d,0x48,0x47,0x43,0x4b,0x44,0x4b,0x41,0x40,0x3d,0x3c,0x35,0x34,0x2b,0x2a,0x22,0x21,0x1d,0x25,0x1e,0x25,0x13,0x14,0x19,0x17,0x0e,0x07,0x1a,0x2b,0x13,0x14,0x07,0x11,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x03,0x34,0x26,0x22, -0x06,0x14,0x16,0x32,0x36,0x03,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x01,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x27,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0xf0,0x48,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x32, -0x2a,0x38,0x28,0x28,0x38,0x2a,0x46,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x01,0xdc,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x48,0x74,0x28,0x38,0x2a,0x2a,0x38,0x28,0x44,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x02,0x8a,0x4c,0x22,0xfe,0x86,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0xfd,0x76,0x1e,0x28, -0x28,0x3a,0x28,0x28,0x02,0x30,0x28,0x3a,0x28,0x28,0x3a,0x28,0xfe,0x5c,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x6e,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x46,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x00,0x05,0x00,0x00,0xff,0xb1,0x03,0x12,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f, -0x00,0x37,0x00,0x5b,0x00,0x88,0x40,0x10,0x4b,0x39,0x02,0x08,0x06,0x29,0x21,0x19,0x11,0x09,0x01,0x06,0x01,0x00,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x2a,0x0a,0x01,0x08,0x00,0x06,0x08,0x59,0x0d,0x0b,0x02,0x06,0x04,0x02,0x02,0x00,0x01,0x06,0x00,0x69,0x00,0x07,0x07,0x0c,0x5f,0x00,0x0c,0x0c,0x10,0x4d,0x05,0x03,0x02,0x01, -0x01,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x40,0x28,0x00,0x0c,0x00,0x07,0x06,0x0c,0x07,0x67,0x0a,0x01,0x08,0x00,0x06,0x08,0x59,0x0d,0x0b,0x02,0x06,0x04,0x02,0x02,0x00,0x01,0x06,0x00,0x69,0x05,0x03,0x02,0x01,0x01,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x40,0x16,0x59,0x58,0x55,0x52,0x4f,0x4d,0x47,0x46,0x43, -0x40,0x26,0x22,0x13,0x26,0x26,0x26,0x26,0x26,0x23,0x0e,0x07,0x1f,0x2b,0x25,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x01,0x33, -0x27,0x26,0x27,0x23,0x06,0x07,0x05,0x15,0x14,0x06,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x37,0x3e,0x01,0x37,0x33,0x32,0x16,0x1f,0x01,0x33,0x32,0x16,0x01,0x1e,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8f,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08, -0x0a,0x8e,0x0a,0x07,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0xfe,0xd1,0xfa,0x1b,0x04,0x05,0xb1,0x06,0x04,0x01,0xeb,0x0a,0x08,0x36,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x35,0x08,0x0a,0x0a,0x08,0xac,0x27,0x09,0x2c,0x16,0xb2,0x17,0x2a,0x09,0x27,0xad,0x08,0x0a,0x52,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x08, -0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x08,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x02,0x32,0x41,0x05,0x01,0x01,0x05,0x53,0x24,0x08,0x0a,0xfd,0xef,0x2e,0x44,0x42,0x2e,0x02,0x13,0x0a,0x08,0x24,0x08,0x0a,0x5d,0x15,0x1c,0x01,0x1e,0x14,0x5d,0x0a,0x00,0x00,0x03,0x00,0x00,0xff,0xba,0x00,0xf0, -0x03,0x02,0x00,0x13,0x00,0x1c,0x00,0x25,0x00,0x62,0x40,0x09,0x13,0x0a,0x09,0x00,0x04,0x05,0x02,0x01,0x4c,0x4b,0xb0,0x16,0x50,0x58,0x40,0x1e,0x00,0x02,0x00,0x05,0x04,0x02,0x05,0x69,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x10,0x4d,0x06,0x01,0x04,0x04,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x1c,0x00,0x01,0x00, -0x03,0x02,0x01,0x03,0x69,0x00,0x02,0x00,0x05,0x04,0x02,0x05,0x69,0x06,0x01,0x04,0x04,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x59,0x40,0x0f,0x1e,0x1d,0x22,0x21,0x1d,0x25,0x1e,0x25,0x13,0x17,0x19,0x14,0x07,0x07,0x1a,0x2b,0x37,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07, -0x27,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0xa8,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x48,0x74,0x28,0x38,0x2a,0x2a,0x38,0x28,0x44,0x1c,0x2a,0x2a,0x38,0x28,0x28,0xa2,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x6e,0x1c, -0x28,0x28,0x3a,0x28,0x28,0xfd,0x46,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x00,0x00,0x00,0x02,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x23,0x00,0x30,0x00,0x6f,0x40,0x0a,0x0d,0x01,0x00,0x01,0x1f,0x01,0x04,0x03,0x02,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x26,0x02,0x01,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04, -0x01,0x03,0x04,0x7e,0x00,0x01,0x01,0x07,0x61,0x00,0x07,0x07,0x10,0x4d,0x00,0x04,0x04,0x06,0x62,0x00,0x06,0x06,0x11,0x06,0x4e,0x1b,0x40,0x24,0x02,0x01,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04,0x01,0x03,0x04,0x7e,0x00,0x07,0x00,0x01,0x00,0x07,0x01,0x67,0x00,0x04,0x04,0x06,0x62,0x00,0x06,0x06,0x11,0x06,0x4e, -0x59,0x40,0x0b,0x15,0x15,0x23,0x24,0x25,0x23,0x24,0x14,0x08,0x07,0x1e,0x2b,0x01,0x35,0x34,0x26,0x07,0x23,0x35,0x34,0x26,0x27,0x23,0x22,0x06,0x07,0x15,0x23,0x22,0x06,0x17,0x15,0x14,0x16,0x37,0x33,0x15,0x14,0x16,0x17,0x33,0x32,0x36,0x37,0x35,0x33,0x32,0x36,0x37,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x02, -0xa7,0x16,0x0e,0x8f,0x16,0x0e,0x47,0x0f,0x14,0x01,0x8f,0x0e,0x16,0x01,0x14,0x0f,0x8f,0x16,0x0e,0x47,0x0f,0x14,0x01,0x8f,0x0e,0x16,0xb2,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x3a,0x48,0x0e,0x16,0x01,0x8f,0x0f,0x14,0x01,0x16,0x0e,0x8f,0x14,0x0f,0x48,0x0e,0x16,0x01,0x8f,0x0f,0x14,0x01,0x16,0x0e,0x8f, -0x14,0x33,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x02,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0f,0x00,0x1c,0x00,0x3c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x15,0x00,0x00,0x00,0x03,0x61,0x00,0x03,0x03,0x10,0x4d,0x00,0x01,0x01,0x02,0x61,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x13,0x00,0x03,0x00,0x00,0x01, -0x03,0x00,0x67,0x00,0x01,0x01,0x02,0x61,0x00,0x02,0x02,0x11,0x02,0x4e,0x59,0xb6,0x15,0x15,0x35,0x24,0x04,0x07,0x1a,0x2b,0x01,0x35,0x34,0x26,0x07,0x21,0x22,0x06,0x17,0x15,0x14,0x16,0x37,0x21,0x32,0x36,0x37,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x02,0xa7,0x16,0x0e,0xfe,0x53,0x0e,0x16,0x01,0x14,0x0f,0x01, -0xad,0x0e,0x16,0xb2,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x3a,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x33,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x01,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x28,0x4b,0xb0,0x26,0x50,0x58,0x40,0x0b,0x00,0x01,0x01, -0x10,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0b,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x59,0xb4,0x15,0x13,0x02,0x07,0x18,0x2b,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x03,0x59,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x5e,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4, -0x74,0x74,0xc4,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x3c,0x01,0xed,0x00,0x0e,0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x35,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x36,0x33,0x21,0x32,0x16,0x02, -0x3b,0x0a,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x01,0xc9,0x0e,0x0b,0xfa,0x0b,0x0b,0xfa,0x0b,0x1c,0x16,0x16,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa0,0x03,0x0b,0x00,0x2d,0x00,0x42,0x00,0x8b,0x40,0x0a,0x3b,0x01,0x04,0x06,0x25,0x01,0x05,0x04,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x30,0x00, -0x07,0x01,0x02,0x01,0x07,0x02,0x80,0x00,0x06,0x02,0x04,0x02,0x06,0x04,0x80,0x00,0x04,0x05,0x02,0x04,0x05,0x7e,0x00,0x05,0x03,0x02,0x05,0x03,0x7e,0x00,0x03,0x00,0x00,0x03,0x00,0x64,0x00,0x02,0x02,0x01,0x5f,0x00,0x01,0x01,0x10,0x02,0x4e,0x1b,0x40,0x36,0x00,0x07,0x01,0x02,0x01,0x07,0x02,0x80,0x00,0x06,0x02,0x04,0x02,0x06, -0x04,0x80,0x00,0x04,0x05,0x02,0x04,0x05,0x7e,0x00,0x05,0x03,0x02,0x05,0x03,0x7e,0x00,0x01,0x00,0x02,0x06,0x01,0x02,0x67,0x00,0x03,0x00,0x00,0x03,0x57,0x00,0x03,0x03,0x00,0x60,0x00,0x00,0x03,0x00,0x50,0x59,0x40,0x0b,0x14,0x17,0x15,0x27,0x35,0x39,0x35,0x33,0x08,0x07,0x1e,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x35, -0x11,0x34,0x36,0x37,0x21,0x32,0x17,0x1e,0x01,0x0f,0x01,0x06,0x23,0x27,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x3d,0x01,0x34,0x3f,0x01,0x36,0x33,0x32,0x17,0x16,0x13,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x14,0x03,0x12,0x5e,0x43,0xfe,0x30, -0x43,0x5e,0x5e,0x43,0x01,0xd0,0x23,0x1e,0x09,0x03,0x07,0x1b,0x06,0x07,0x05,0x0d,0x0c,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x05,0x24,0x06,0x07,0x03,0x04,0x0b,0x81,0xfe,0x39,0x0d,0x24,0x0e,0xf0,0x0e,0x0e,0x3d,0x0e,0x24,0x0e,0x93,0x01,0x69,0x0d,0x24,0x0e,0x3e,0x0d,0x01,0x4b,0xb1,0x43,0x5e,0x5e,0x43,0x01, -0xd0,0x42,0x5e,0x01,0x0e,0x04,0x13,0x06,0x1c,0x05,0x01,0x03,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x8d,0x08,0x05,0x23,0x06,0x02,0x04,0x01,0x05,0xfe,0x3a,0x0e,0x0e,0xf0,0x0d,0x24,0x0e,0x3e,0x0d,0x0d,0x93,0x01,0x69,0x0d,0x0d,0x3d,0x0e,0x24,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0xb1,0x03,0x12,0x03,0x0b,0x00,0x0f, -0x00,0x1f,0x00,0x2f,0x00,0x3b,0x00,0x43,0x00,0x67,0x00,0xcf,0x40,0x10,0x57,0x45,0x02,0x06,0x08,0x29,0x21,0x19,0x11,0x09,0x01,0x06,0x00,0x01,0x02,0x4c,0x4b,0xb0,0x09,0x50,0x58,0x40,0x2f,0x00,0x09,0x0e,0x08,0x06,0x09,0x72,0x0f,0x0d,0x02,0x08,0x0c,0x0a,0x02,0x06,0x01,0x08,0x06,0x68,0x05,0x03,0x02,0x01,0x04,0x02,0x02,0x00, -0x07,0x01,0x00,0x69,0x00,0x0e,0x0e,0x10,0x4d,0x00,0x07,0x07,0x0b,0x5f,0x00,0x0b,0x0b,0x11,0x0b,0x4e,0x1b,0x4b,0xb0,0x24,0x50,0x58,0x40,0x30,0x00,0x09,0x0e,0x08,0x0e,0x09,0x08,0x80,0x0f,0x0d,0x02,0x08,0x0c,0x0a,0x02,0x06,0x01,0x08,0x06,0x68,0x05,0x03,0x02,0x01,0x04,0x02,0x02,0x00,0x07,0x01,0x00,0x69,0x00,0x0e,0x0e,0x10, -0x4d,0x00,0x07,0x07,0x0b,0x5f,0x00,0x0b,0x0b,0x11,0x0b,0x4e,0x1b,0x40,0x2d,0x00,0x0e,0x09,0x0e,0x85,0x00,0x09,0x08,0x09,0x85,0x0f,0x0d,0x02,0x08,0x0c,0x0a,0x02,0x06,0x01,0x08,0x06,0x68,0x05,0x03,0x02,0x01,0x04,0x02,0x02,0x00,0x07,0x01,0x00,0x69,0x00,0x07,0x07,0x0b,0x5f,0x00,0x0b,0x0b,0x11,0x0b,0x4e,0x59,0x59,0x40,0x1a, -0x65,0x64,0x61,0x5e,0x5b,0x59,0x53,0x52,0x4f,0x4c,0x49,0x47,0x41,0x3f,0x14,0x24,0x14,0x26,0x26,0x26,0x26,0x26,0x23,0x10,0x07,0x1f,0x2b,0x01,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b, -0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x13,0x11,0x21,0x11,0x14,0x1e,0x01,0x33,0x21,0x32,0x3e,0x01,0x01,0x33,0x27,0x26,0x27,0x23,0x06,0x07,0x05,0x15,0x14,0x06,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x37,0x3e,0x01,0x37,0x33,0x32,0x16,0x1f,0x01, -0x33,0x32,0x16,0x01,0x1e,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8f,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8e,0x0a,0x07,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x48,0xfe,0x0c,0x08,0x08,0x02,0x01,0xd0,0x02,0x08,0x08,0xfe,0x89,0xfa,0x1b,0x04,0x05,0xb1,0x06,0x04,0x01,0xeb,0x0a,0x08,0x36,0x34,0x25, -0xfe,0x30,0x25,0x34,0x01,0x35,0x08,0x0a,0x0a,0x08,0xac,0x27,0x09,0x2c,0x16,0xb2,0x17,0x2a,0x09,0x27,0xad,0x08,0x0a,0x01,0xb7,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0xfe,0x64,0x02,0x11, -0xfd,0xef,0x0c,0x14,0x0a,0x0a,0x14,0x02,0x65,0x41,0x05,0x01,0x01,0x05,0x53,0x24,0x08,0x0a,0xfd,0xef,0x2e,0x44,0x42,0x2e,0x02,0x13,0x0a,0x08,0x24,0x08,0x0a,0x5d,0x15,0x1c,0x01,0x1e,0x14,0x5d,0x0a,0x00,0x00,0x01,0x00,0x00,0xff,0x9c,0x03,0xac,0x03,0x20,0x00,0x2a,0x00,0x34,0x40,0x09,0x20,0x1e,0x16,0x12,0x04,0x00,0x01,0x01, -0x4c,0x4b,0xb0,0x17,0x50,0x58,0x40,0x0b,0x00,0x01,0x01,0x10,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0b,0x00,0x00,0x00,0x01,0x61,0x00,0x01,0x01,0x10,0x00,0x4e,0x59,0xb5,0x1b,0x1a,0x13,0x02,0x07,0x17,0x2b,0x25,0x16,0x1d,0x01,0x21,0x35,0x34,0x37,0x3e,0x01,0x35,0x34,0x26,0x27,0x2e,0x03,0x27,0x34,0x36,0x3f,0x01,0x26, -0x27,0x26,0x36,0x32,0x16,0x0f,0x01,0x16,0x15,0x0e,0x03,0x07,0x0e,0x01,0x15,0x14,0x16,0x02,0xe0,0xcc,0xfc,0x54,0xcc,0x5e,0x44,0x2c,0x0a,0x02,0x0e,0x0e,0x0e,0x02,0x0a,0x04,0x04,0x08,0x04,0x04,0x5a,0xe0,0x5c,0x06,0x0c,0x12,0x02,0x0e,0x0e,0x0e,0x02,0x08,0x2e,0x46,0x80,0x48,0x32,0x6a,0x6a,0x32,0x48,0x22,0x46,0x3c,0x16,0x36, -0x2e,0x0c,0x0c,0x04,0x1e,0x1c,0x10,0x14,0x02,0x04,0x32,0x26,0x36,0x74,0x74,0x36,0x58,0x08,0x22,0x1c,0x1e,0x04,0x0c,0x0c,0x30,0x34,0x16,0x3c,0x46,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xb6,0x03,0xe8,0x03,0x08,0x00,0x18,0x00,0x20,0x00,0x2d,0x00,0xcc,0xb5,0x25,0x01,0x09,0x0b,0x01,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x30, -0x0d,0x01,0x0b,0x08,0x09,0x08,0x0b,0x72,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07,0x07,0x02,0x5f,0x00,0x02,0x02,0x10,0x4d,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x4b,0xb0,0x1f,0x50,0x58,0x40,0x31,0x0d,0x01,0x0b,0x08,0x09,0x08,0x0b,0x09, -0x80,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07,0x07,0x02,0x5f,0x00,0x02,0x02,0x10,0x4d,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x40,0x2f,0x0d,0x01,0x0b,0x08,0x09,0x08,0x0b,0x09,0x80,0x00,0x02,0x00,0x07,0x01,0x02,0x07,0x67,0x0c,0x01,0x05, -0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x59,0x40,0x1e,0x21,0x21,0x00,0x00,0x21,0x2d,0x21,0x2d,0x2c,0x2b,0x29,0x26,0x23,0x22,0x20,0x1d,0x1b,0x1a,0x00,0x18,0x00,0x18,0x12,0x24,0x35,0x22,0x11,0x0e,0x07,0x1b,0x2b,0x01,0x15, -0x21,0x13,0x36,0x3b,0x01,0x36,0x3f,0x01,0x3e,0x01,0x3b,0x01,0x32,0x16,0x17,0x16,0x17,0x33,0x32,0x17,0x13,0x21,0x35,0x03,0x07,0x21,0x27,0x26,0x2b,0x01,0x22,0x13,0x35,0x21,0x06,0x07,0x06,0x23,0x21,0x22,0x35,0x27,0x21,0x15,0x01,0xc8,0xfe,0x38,0x0a,0x04,0x60,0xa0,0x10,0x15,0x17,0x0e,0x12,0x1c,0xde,0x1a,0x14,0x0c,0x12,0x2a, -0xa0,0x60,0x04,0x0a,0xfe,0x3a,0xa4,0x1c,0x01,0x24,0x1c,0x0e,0x1c,0x98,0x1c,0x96,0x01,0xae,0x06,0x04,0x06,0x54,0xfd,0x12,0x5a,0x0a,0x01,0xae,0x01,0x46,0x64,0x01,0x24,0x6c,0x1a,0x29,0x2d,0x1a,0x0c,0x0e,0x18,0x20,0x50,0x6c,0xfe,0xdc,0x64,0x01,0x62,0x36,0x36,0x1a,0xfd,0x8a,0x64,0x58,0x4e,0x54,0x54,0xa6,0x64,0x00,0x00,0x00, -0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x67,0x02,0x7c,0x00,0x0d,0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x17,0x13,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x16,0x01,0x65,0x14,0x20,0x09,0xfa, -0x0a,0x0a,0xfa,0x0b,0x1c,0x18,0x02,0x58,0xfe,0x0c,0x0e,0x16,0x0b,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x41,0x02,0x7d,0x00,0x0e,0x00,0x0a,0xb7,0x00,0x00,0x00,0x76,0x14,0x01,0x07,0x17,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x26,0x35,0x11,0x34,0x3e,0x01,0x1f,0x01,0x16,0x01,0x41,0x0a,0xfa,0x0b, -0x1c,0x16,0x16,0x1c,0x0b,0xfa,0x0a,0x01,0x5e,0x0e,0x0b,0xfa,0x0b,0x16,0x0e,0x01,0xf4,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x02,0x3b,0x01,0xc9,0x00,0x0e,0x00,0x18,0x40,0x15,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x15,0x32,0x02,0x07,0x18,0x2b,0x25,0x14, -0x06,0x27,0x21,0x22,0x2e,0x01,0x3f,0x01,0x36,0x32,0x1f,0x01,0x16,0x02,0x3b,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x1e,0x0a,0xfa,0x0a,0xab,0x0e,0x16,0x01,0x14,0x1e,0x0b,0xfa,0x0a,0x0a,0xfa,0x0b,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x5e,0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x03,0x01,0x00,0x01, -0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x17,0x19,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x17,0x16,0x14,0x0f,0x01,0x06,0x22,0x27,0x01,0x26,0x34,0x37,0x01,0x36,0x32,0x1f,0x01,0x16,0x01,0x5e,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0xfe,0xfc,0x06,0x06,0x01,0x04,0x05, -0x10,0x04,0x1c,0x06,0x02,0x22,0x07,0x05,0xdc,0xdb,0x06,0x0e,0x06,0x1c,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0x1c,0x05,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x4c,0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x0b,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01, -0x00,0x51,0x1c,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x17,0x01,0x16,0x01,0x4c,0x05,0xfe,0xfb,0x05,0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x10,0x04,0x01,0x05,0x05,0x01,0x3a,0x07,0x05,0xfe,0xfb,0x05,0x05,0x1c,0x06,0x0e,0x06, -0xdb,0xdc,0x05,0x0e,0x06,0x1c,0x06,0x06,0xfe,0xfc,0x05,0x00,0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08,0x00,0x16,0x00,0x3f,0x00,0x83,0x40,0x0b,0x38,0x36,0x02,0x03,0x05,0x13,0x01,0x02,0x03,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x24,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x00,0x06,0x00,0x03,0x02,0x06, -0x03,0x69,0x08,0x01,0x02,0x00,0x01,0x02,0x01,0x66,0x00,0x04,0x04,0x00,0x61,0x07,0x01,0x00,0x00,0x12,0x04,0x4e,0x1b,0x40,0x2b,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x07,0x01,0x00,0x00,0x04,0x06,0x00,0x04,0x69,0x00,0x06,0x00,0x03,0x02,0x06,0x03,0x69,0x08,0x01,0x02,0x01,0x01,0x02,0x59,0x08,0x01,0x02,0x02,0x01,0x62,0x00, -0x01,0x02,0x01,0x52,0x59,0x40,0x19,0x0a,0x09,0x01,0x00,0x27,0x26,0x22,0x20,0x1d,0x1b,0x11,0x0e,0x09,0x16,0x0a,0x16,0x05,0x04,0x00,0x08,0x01,0x08,0x09,0x07,0x16,0x2b,0x01,0x36,0x00,0x12,0x00,0x04,0x00,0x02,0x00,0x13,0x32,0x36,0x35,0x36,0x26,0x2b,0x01,0x22,0x06,0x07,0x14,0x16,0x17,0x13,0x36,0x35,0x34,0x26,0x23,0x22,0x07, -0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x32,0x17,0x16,0x15,0x14,0x07,0x06,0x0f,0x01,0x06,0x0f,0x01,0x06,0x07,0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x3f,0x01,0x36,0x01,0xc6,0xbe,0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xbc,0x1e,0x26,0x02,0x26,0x1e,0x02,0x1c,0x26,0x02,0x26,0x1c,0xa8,0x1a,0x6a,0x52, -0x40,0x28,0x44,0x04,0x6e,0x10,0x10,0x4e,0x0c,0x10,0x10,0x08,0x0c,0x16,0x0a,0x0a,0x15,0x0b,0x06,0x0e,0x04,0x6c,0x04,0x06,0x16,0x1c,0x2e,0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0xfd,0x1e,0x26,0x1c,0x1e,0x26,0x24,0x1c,0x1e,0x26,0x02,0x01,0x48,0x22,0x2c,0x4e,0x4c,0x1a,0x2a,0x68,0x04, -0x04,0x1a,0x1c,0x18,0x14,0x14,0x18,0x12,0x16,0x0c,0x08,0x0f,0x07,0x08,0x11,0x09,0x08,0x14,0x3a,0x08,0x04,0x0c,0x10,0x14,0x10,0x12,0x22,0x00,0x00,0x02,0x00,0x00,0xff,0xbd,0x03,0x4d,0x03,0x0b,0x00,0x08,0x00,0x1d,0x00,0x56,0xb5,0x00,0x01,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x10,0x00,0x00,0x00,0x02,0x5f,0x00, -0x02,0x02,0x10,0x4d,0x00,0x01,0x01,0x11,0x01,0x4e,0x1b,0x4b,0xb0,0x2a,0x50,0x58,0x40,0x0e,0x00,0x02,0x00,0x00,0x01,0x02,0x00,0x69,0x00,0x01,0x01,0x11,0x01,0x4e,0x1b,0x40,0x15,0x00,0x01,0x00,0x01,0x86,0x00,0x02,0x00,0x00,0x02,0x57,0x00,0x02,0x02,0x00,0x61,0x00,0x00,0x02,0x00,0x51,0x59,0x59,0xb5,0x38,0x1a,0x12,0x03,0x07, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x03,0xd0,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x50,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x05,0x00,0x00, +0x00,0x28,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x2e,0x00,0x00, +0x00,0x2e,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x35,0x00,0x00, +0x00,0x10,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x15,0x00,0x00, +0x00,0x3e,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x43,0x00,0x00, +0x00,0x43,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x1d,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x48,0x00,0x00, +0x00,0x20,0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x4d,0x00,0x00,0x00,0x4d,0x00,0x00,0x00,0x25,0x00,0x00, +0x00,0x4e,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x4f,0x00,0x00,0x00,0x4f,0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x51,0x00,0x00,0x00,0x51,0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x52,0x00,0x00,0x00,0x52,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x53,0x00,0x00, +0x00,0x53,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x54,0x00,0x00,0x00,0x54,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x56,0x00,0x00,0x00,0x56,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x2f,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x58,0x00,0x00, +0x00,0x30,0x00,0x00,0x00,0x59,0x00,0x00,0x00,0x59,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x5a,0x00,0x00,0x00,0x5a,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x5b,0x00,0x00,0x00,0x5b,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x5d,0x00,0x00,0x00,0x5d,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x35,0x00,0x00, +0x00,0x61,0x00,0x00,0x00,0x61,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x62,0x00,0x00,0x00,0x62,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x63,0x00,0x00,0x00,0x63,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x3a,0x00,0x00,0x00,0x66,0x00,0x00, +0x00,0x66,0x00,0x00,0x00,0x3b,0x00,0x00,0x00,0x67,0x00,0x00,0x00,0x67,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x3d,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x6a,0x00,0x00,0x00,0x6a,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x6b,0x00,0x00,0x00,0x6b,0x00,0x00, +0x00,0x40,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x6e,0x00,0x00,0x00,0x6e,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x6f,0x00,0x00,0x00,0x6f,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x45,0x00,0x00, +0x00,0x71,0x00,0x00,0x00,0x71,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x72,0x00,0x00,0x00,0x72,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x73,0x00,0x00,0x00,0x73,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x75,0x00,0x00,0x00,0x75,0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x76,0x00,0x00,0x00,0x76,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x77,0x00,0x00, +0x00,0x77,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x79,0x00,0x00,0x00,0x79,0x00,0x00,0x00,0x4d,0x00,0x00,0x00,0x7a,0x00,0x00,0x00,0x7a,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x7b,0x00,0x00,0x00,0x7b,0x00,0x00,0x00,0x4f,0x00,0x00,0x00,0x7d,0x00,0x00,0x00,0x7d,0x00,0x00, +0x00,0x50,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x25,0x40,0x22,0x00,0x01,0x00,0x02,0x01,0x02,0x63,0x04,0x01,0x00,0x00,0x03,0x5f,0x00,0x03,0x03,0x13,0x00,0x4e,0x02,0x00,0x1e,0x1b,0x16,0x13,0x0a,0x07,0x00,0x0f,0x02,0x0f,0x05,0x07,0x16,0x2b,0x01,0x21,0x22,0x06,0x07,0x11,0x14, +0x16,0x17,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x17,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x71,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x34,0x7c,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x02,0xc3,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01, +0xd0,0x25,0x34,0x59,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x06,0x00,0x00,0xff,0xba,0x02,0x80,0x03,0x02,0x00,0x13,0x00,0x1c,0x00,0x25,0x00,0x39,0x00,0x42,0x00,0x4b,0x00,0x54,0x40,0x51,0x39,0x30,0x2f,0x26,0x0d,0x0c,0x03,0x02,0x08,0x02,0x04,0x01,0x4c,0x08,0x0c,0x02,0x04,0x0b,0x01,0x02,0x03,0x04, +0x02,0x69,0x09,0x01,0x05,0x05,0x01,0x61,0x07,0x01,0x01,0x01,0x13,0x4d,0x0d,0x0a,0x02,0x03,0x03,0x00,0x61,0x06,0x01,0x00,0x00,0x11,0x00,0x4e,0x44,0x43,0x1e,0x1d,0x48,0x47,0x43,0x4b,0x44,0x4b,0x41,0x40,0x3d,0x3c,0x35,0x34,0x2b,0x2a,0x22,0x21,0x1d,0x25,0x1e,0x25,0x13,0x14,0x19,0x17,0x0e,0x07,0x1a,0x2b,0x13,0x14,0x07,0x11, +0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x03,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x03,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x01,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x27,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13, +0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0xf0,0x48,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x32,0x2a,0x38,0x28,0x28,0x38,0x2a,0x46,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x01,0xdc,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x48,0x74,0x28,0x38,0x2a,0x2a,0x38,0x28,0x44,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x02,0x8a,0x4c,0x22,0xfe, +0x86,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0xfd,0x76,0x1e,0x28,0x28,0x3a,0x28,0x28,0x02,0x30,0x28,0x3a,0x28,0x28,0x3a,0x28,0xfe,0x5c,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x6e,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x46,0x28,0x3a,0x28, +0x28,0x3a,0x28,0x00,0x00,0x05,0x00,0x00,0xff,0xb1,0x03,0x12,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x37,0x00,0x5b,0x00,0x53,0x40,0x50,0x4b,0x39,0x02,0x08,0x06,0x29,0x21,0x19,0x11,0x09,0x01,0x06,0x01,0x00,0x02,0x4c,0x0a,0x01,0x08,0x00,0x06,0x08,0x59,0x0d,0x0b,0x02,0x06,0x04,0x02,0x02,0x00,0x01,0x06,0x00,0x69,0x00, +0x07,0x07,0x0c,0x5f,0x00,0x0c,0x0c,0x13,0x4d,0x05,0x03,0x02,0x01,0x01,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x58,0x55,0x52,0x4f,0x4d,0x47,0x46,0x43,0x40,0x26,0x22,0x13,0x26,0x26,0x26,0x26,0x26,0x23,0x0e,0x07,0x1f,0x2b,0x25,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x11,0x34, +0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x01,0x33,0x27,0x26,0x27,0x23,0x06,0x07,0x05,0x15,0x14,0x06,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x37,0x3e,0x01, +0x37,0x33,0x32,0x16,0x1f,0x01,0x33,0x32,0x16,0x01,0x1e,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8f,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8e,0x0a,0x07,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0xfe,0xd1,0xfa,0x1b,0x04,0x05,0xb1,0x06,0x04,0x01,0xeb,0x0a,0x08,0x36,0x34,0x25,0xfe,0x30,0x25,0x34,0x01, +0x35,0x08,0x0a,0x0a,0x08,0xac,0x27,0x09,0x2c,0x16,0xb2,0x17,0x2a,0x09,0x27,0xad,0x08,0x0a,0x52,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x08,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x08,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x02,0x32,0x41,0x05,0x01,0x01,0x05,0x53,0x24,0x08, +0x0a,0xfd,0xef,0x2e,0x44,0x42,0x2e,0x02,0x13,0x0a,0x08,0x24,0x08,0x0a,0x5d,0x15,0x1c,0x01,0x1e,0x14,0x5d,0x0a,0x00,0x00,0x00,0x04,0xff,0xff,0xff,0xb1,0x04,0x2f,0x03,0x0b,0x00,0x08,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x52,0x40,0x4f,0x1d,0x14,0x02,0x01,0x03,0x0f,0x01,0x00,0x01,0x0e,0x0d,0x0c,0x09,0x04,0x02,0x00,0x1c,0x15, +0x02,0x04,0x02,0x04,0x4c,0x00,0x02,0x00,0x04,0x00,0x02,0x04,0x80,0x00,0x01,0x00,0x00,0x02,0x01,0x00,0x69,0x07,0x01,0x03,0x03,0x06,0x5f,0x00,0x06,0x06,0x13,0x4d,0x00,0x04,0x04,0x05,0x5f,0x00,0x05,0x05,0x11,0x05,0x4e,0x11,0x10,0x2e,0x2b,0x26,0x23,0x19,0x17,0x10,0x1f,0x11,0x1f,0x13,0x13,0x12,0x08,0x07,0x19,0x2b,0x01,0x14, +0x0e,0x01,0x26,0x34,0x36,0x1e,0x01,0x01,0x15,0x21,0x35,0x37,0x17,0x01,0x25,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x37,0x21,0x32,0x36,0x27,0x11,0x34,0x26,0x17,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x01,0x65,0x3e,0x5a,0x3e,0x3e,0x5a,0x3e,0x02,0x3c,0xfc,0xee,0xb2,0x5a,0x01,0x1d,0x01,0x1e, +0xfc,0x83,0x07,0x0a,0x01,0x0c,0x06,0x03,0x7d,0x07,0x0c,0x01,0x0a,0x51,0x34,0x25,0xfc,0x83,0x24,0x36,0x01,0x34,0x25,0x03,0x7d,0x25,0x34,0x02,0x11,0x2d,0x3e,0x02,0x42,0x56,0x42,0x04,0x3a,0xfe,0xfa,0xfa,0x6b,0xb3,0x59,0x01,0x1d,0xa1,0x0a,0x08,0xfd,0x5a,0x07,0x0c,0x01,0x0a,0x08,0x02,0xa6,0x08,0x0a,0x12,0xfd,0x5a,0x25,0x34, +0x01,0x36,0x24,0x02,0xa6,0x25,0x34,0x01,0x36,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xba,0x00,0xf0,0x03,0x02,0x00,0x13,0x00,0x1c,0x00,0x25,0x00,0x39,0x40,0x36,0x13,0x0a,0x09,0x00,0x04,0x05,0x02,0x01,0x4c,0x00,0x02,0x00,0x05,0x04,0x02,0x05,0x69,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x13,0x4d,0x06,0x01,0x04,0x04,0x00, +0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x1e,0x1d,0x22,0x21,0x1d,0x25,0x1e,0x25,0x13,0x17,0x19,0x14,0x07,0x07,0x1a,0x2b,0x37,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x27,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0xa8,0x48,0x46, +0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x48,0x74,0x28,0x38,0x2a,0x2a,0x38,0x28,0x44,0x1c,0x2a,0x2a,0x38,0x28,0x28,0xa2,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x6e,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x46,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x03,0xff,0xff,0xff,0x6a,0x04,0x78, +0x03,0x52,0x00,0x03,0x00,0x0c,0x00,0x26,0x00,0x38,0x40,0x35,0x00,0x08,0x00,0x03,0x04,0x08,0x03,0x67,0x07,0x01,0x04,0x00,0x01,0x02,0x04,0x01,0x67,0x00,0x02,0x00,0x05,0x00,0x02,0x05,0x67,0x00,0x00,0x06,0x06,0x00,0x57,0x00,0x00,0x00,0x06,0x60,0x00,0x06,0x00,0x06,0x50,0x33,0x25,0x33,0x26,0x21,0x11,0x11,0x11,0x10,0x09,0x07, +0x1f,0x2b,0x17,0x21,0x11,0x29,0x02,0x11,0x21,0x15,0x33,0x32,0x16,0x15,0x01,0x11,0x14,0x06,0x23,0x21,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x33,0x21,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x8f,0x01,0xac,0xfe,0x54,0x02,0x3b,0x01,0x1e,0xfe,0x53,0x36,0x25,0x34,0x01,0xad,0x34,0x25,0xfe,0xac,0x34,0x25,0xfd,0xe8, +0x24,0x36,0x01,0x34,0x25,0x01,0x54,0x34,0x25,0x02,0x18,0x24,0x36,0x07,0x01,0x1e,0x01,0xac,0x8f,0x34,0x25,0x01,0x1e,0xfd,0xe8,0x25,0x34,0xc5,0x25,0x34,0x34,0x25,0x02,0x18,0x25,0x34,0xc5,0x25,0x34,0x34,0x00,0x01,0xff,0xff,0xff,0xb1,0x03,0xe8,0x00,0xcf,0x00,0x0f,0x00,0x13,0x40,0x10,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x00, +0x11,0x00,0x4e,0x35,0x33,0x02,0x07,0x18,0x2b,0x25,0x15,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0xe8,0x34,0x25,0xfc,0xca,0x24,0x36,0x01,0x34,0x25,0x03,0x36,0x25,0x34,0x76,0x6b,0x25,0x34,0x01,0x36,0x24,0x6b,0x25,0x34,0x34,0x00,0x00,0x03,0x00,0x00,0xff,0x6a,0x03,0xa1,0x03,0x0b,0x00,0x03, +0x00,0x07,0x00,0x1f,0x00,0x1f,0x40,0x1c,0x07,0x06,0x05,0x03,0x02,0x01,0x00,0x07,0x00,0x01,0x01,0x4c,0x00,0x00,0x00,0x01,0x61,0x00,0x01,0x01,0x13,0x00,0x4e,0x1b,0x1e,0x02,0x07,0x18,0x2b,0x05,0x25,0x11,0x05,0x27,0x2d,0x01,0x0d,0x01,0x11,0x14,0x06,0x07,0x05,0x06,0x22,0x27,0x25,0x2e,0x01,0x35,0x11,0x34,0x36,0x37,0x25,0x36, +0x32,0x17,0x05,0x1e,0x01,0x01,0xf4,0x01,0x65,0xfe,0x9b,0x24,0x01,0x86,0xfe,0x7a,0xfe,0x7b,0x03,0x56,0x14,0x12,0xfe,0x77,0x0f,0x26,0x0f,0xfe,0x77,0x11,0x14,0x1a,0x15,0x01,0x89,0x0c,0x18,0x0d,0x01,0x89,0x15,0x1a,0x3b,0xc3,0x01,0x63,0x82,0x3f,0x8d,0x8e,0x8e,0x01,0xfe,0x54,0x14,0x22,0x09,0xd6,0x09,0x09,0xd6,0x0a,0x20,0x15, +0x01,0xac,0x17,0x24,0x08,0x8f,0x05,0x05,0x8f,0x08,0x24,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x44,0x02,0x80,0x00,0x13,0x00,0x31,0x40,0x2e,0x00,0x05,0x00,0x02,0x05,0x59,0x04,0x06,0x02,0x00,0x03,0x01,0x01,0x02,0x00,0x01,0x67,0x00,0x05,0x05,0x02,0x61,0x00,0x02,0x05,0x02,0x51,0x01,0x00,0x11,0x10,0x0e,0x0c,0x0b,0x09,0x07, +0x06,0x04,0x02,0x00,0x13,0x01,0x13,0x07,0x07,0x16,0x2b,0x01,0x32,0x14,0x2b,0x01,0x15,0x14,0x22,0x3d,0x01,0x23,0x22,0x34,0x3b,0x01,0x35,0x34,0x32,0x1d,0x01,0x02,0x26,0x1e,0x1e,0xd2,0x64,0xd2,0x1e,0x1e,0xd2,0x64,0x01,0x90,0x64,0xd2,0x1e,0x1e,0xd2,0x64,0xd2,0x1e,0x1e,0xd2,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x44, +0x01,0x90,0x00,0x07,0x00,0x20,0x40,0x1d,0x02,0x01,0x00,0x01,0x01,0x00,0x57,0x02,0x01,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x01,0x00,0x05,0x02,0x00,0x07,0x01,0x06,0x03,0x07,0x16,0x2b,0x01,0x32,0x14,0x23,0x21,0x22,0x34,0x33,0x02,0x26,0x1e,0x1e,0xfd,0xf8,0x1e,0x1e,0x01,0x90,0x64,0x64,0x00,0x00,0x00,0x01,0xff,0xfd, +0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x13,0x40,0x10,0x00,0x01,0x01,0x13,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x15,0x13,0x02,0x07,0x18,0x2b,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x03,0x59,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x5e,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74, +0x74,0xc4,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x3c,0x01,0xed,0x00,0x0e,0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x35,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x36,0x33,0x21,0x32,0x16,0x02, +0x3b,0x0a,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x01,0xc9,0x0e,0x0b,0xfa,0x0b,0x0b,0xfa,0x0b,0x1c,0x16,0x16,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa0,0x03,0x0b,0x00,0x2d,0x00,0x42,0x00,0x48,0x40,0x45,0x3b,0x01,0x04,0x06,0x25,0x01,0x05,0x04,0x02,0x4c,0x00,0x07,0x01,0x02,0x01,0x07,0x02,0x80, +0x00,0x06,0x02,0x04,0x02,0x06,0x04,0x80,0x00,0x04,0x05,0x02,0x04,0x05,0x7e,0x00,0x05,0x03,0x02,0x05,0x03,0x7e,0x00,0x03,0x00,0x00,0x03,0x00,0x64,0x00,0x02,0x02,0x01,0x5f,0x00,0x01,0x01,0x13,0x02,0x4e,0x14,0x17,0x15,0x27,0x35,0x39,0x35,0x33,0x08,0x07,0x1e,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36, +0x37,0x21,0x32,0x17,0x1e,0x01,0x0f,0x01,0x06,0x23,0x27,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x3d,0x01,0x34,0x3f,0x01,0x36,0x33,0x32,0x17,0x16,0x13,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x14,0x03,0x12,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e, +0x43,0x01,0xd0,0x23,0x1e,0x09,0x03,0x07,0x1b,0x06,0x07,0x05,0x0d,0x0c,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x05,0x24,0x06,0x07,0x03,0x04,0x0b,0x81,0xfe,0x39,0x0d,0x24,0x0e,0xf0,0x0e,0x0e,0x3d,0x0e,0x24,0x0e,0x93,0x01,0x69,0x0d,0x24,0x0e,0x3e,0x0d,0x01,0x4b,0xb1,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e, +0x01,0x0e,0x04,0x13,0x06,0x1c,0x05,0x01,0x03,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x8d,0x08,0x05,0x23,0x06,0x02,0x04,0x01,0x05,0xfe,0x3a,0x0e,0x0e,0xf0,0x0d,0x24,0x0e,0x3e,0x0d,0x0d,0x93,0x01,0x69,0x0d,0x0d,0x3d,0x0e,0x24,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0xb1,0x03,0x12,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f, +0x00,0x3b,0x00,0x43,0x00,0x67,0x00,0x5d,0x40,0x5a,0x57,0x45,0x02,0x06,0x08,0x29,0x21,0x19,0x11,0x09,0x01,0x06,0x00,0x01,0x02,0x4c,0x00,0x09,0x0e,0x08,0x0e,0x09,0x08,0x80,0x0f,0x0d,0x02,0x08,0x0c,0x0a,0x02,0x06,0x01,0x08,0x06,0x68,0x05,0x03,0x02,0x01,0x04,0x02,0x02,0x00,0x07,0x01,0x00,0x69,0x00,0x0e,0x0e,0x13,0x4d,0x00, +0x07,0x07,0x0b,0x5f,0x00,0x0b,0x0b,0x11,0x0b,0x4e,0x65,0x64,0x61,0x5e,0x5b,0x59,0x53,0x52,0x4f,0x4c,0x49,0x47,0x41,0x3f,0x14,0x24,0x14,0x26,0x26,0x26,0x26,0x26,0x23,0x10,0x07,0x1f,0x2b,0x01,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34, +0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x13,0x11,0x21,0x11,0x14,0x1e,0x01,0x33,0x21,0x32,0x3e,0x01,0x01,0x33,0x27,0x26,0x27,0x23,0x06,0x07,0x05,0x15,0x14,0x06,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b, +0x01,0x37,0x3e,0x01,0x37,0x33,0x32,0x16,0x1f,0x01,0x33,0x32,0x16,0x01,0x1e,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8f,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8e,0x0a,0x07,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x48,0xfe,0x0c,0x08,0x08,0x02,0x01,0xd0,0x02,0x08,0x08,0xfe,0x89,0xfa,0x1b,0x04,0x05, +0xb1,0x06,0x04,0x01,0xeb,0x0a,0x08,0x36,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x35,0x08,0x0a,0x0a,0x08,0xac,0x27,0x09,0x2c,0x16,0xb2,0x17,0x2a,0x09,0x27,0xad,0x08,0x0a,0x01,0xb7,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a, +0x08,0x01,0x41,0x08,0x0a,0x0a,0xfe,0x64,0x02,0x11,0xfd,0xef,0x0c,0x14,0x0a,0x0a,0x14,0x02,0x65,0x41,0x05,0x01,0x01,0x05,0x53,0x24,0x08,0x0a,0xfd,0xef,0x2e,0x44,0x42,0x2e,0x02,0x13,0x0a,0x08,0x24,0x08,0x0a,0x5d,0x15,0x1c,0x01,0x1e,0x14,0x5d,0x0a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0x9c,0x03,0xac,0x03,0x20,0x00,0x2a, +0x00,0x34,0x40,0x09,0x20,0x1e,0x16,0x12,0x04,0x00,0x01,0x01,0x4c,0x4b,0xb0,0x18,0x50,0x58,0x40,0x0b,0x00,0x01,0x01,0x10,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0b,0x00,0x00,0x00,0x01,0x61,0x00,0x01,0x01,0x10,0x00,0x4e,0x59,0xb5,0x1b,0x1a,0x13,0x02,0x07,0x17,0x2b,0x25,0x16,0x1d,0x01,0x21,0x35,0x34,0x37,0x3e,0x01, +0x35,0x34,0x26,0x27,0x2e,0x03,0x27,0x34,0x36,0x3f,0x01,0x26,0x27,0x26,0x36,0x32,0x16,0x0f,0x01,0x16,0x15,0x0e,0x03,0x07,0x0e,0x01,0x15,0x14,0x16,0x02,0xe0,0xcc,0xfc,0x54,0xcc,0x5e,0x44,0x2c,0x0a,0x02,0x0e,0x0e,0x0e,0x02,0x0a,0x04,0x04,0x08,0x04,0x04,0x5a,0xe0,0x5c,0x06,0x0c,0x12,0x02,0x0e,0x0e,0x0e,0x02,0x08,0x2e,0x46, +0x80,0x48,0x32,0x6a,0x6a,0x32,0x48,0x22,0x46,0x3c,0x16,0x36,0x2e,0x0c,0x0c,0x04,0x1e,0x1c,0x10,0x14,0x02,0x04,0x32,0x26,0x36,0x74,0x74,0x36,0x58,0x08,0x22,0x1c,0x1e,0x04,0x0c,0x0c,0x30,0x34,0x16,0x3c,0x46,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xb6,0x03,0xe8,0x03,0x08,0x00,0x18,0x00,0x20,0x00,0x2d,0x00,0x94,0xb5,0x25, +0x01,0x09,0x0b,0x01,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x30,0x0d,0x01,0x0b,0x08,0x09,0x08,0x0b,0x72,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07,0x07,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x40,0x31,0x0d, +0x01,0x0b,0x08,0x09,0x08,0x0b,0x09,0x80,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07,0x07,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x40,0x1e,0x21,0x21,0x00,0x00,0x21,0x2d,0x21,0x2d,0x2c,0x2b,0x29,0x26,0x23, +0x22,0x20,0x1d,0x1b,0x1a,0x00,0x18,0x00,0x18,0x12,0x24,0x35,0x22,0x11,0x0e,0x07,0x1b,0x2b,0x01,0x15,0x21,0x13,0x36,0x3b,0x01,0x36,0x3f,0x01,0x3e,0x01,0x3b,0x01,0x32,0x16,0x17,0x16,0x17,0x33,0x32,0x17,0x13,0x21,0x35,0x03,0x07,0x21,0x27,0x26,0x2b,0x01,0x22,0x13,0x35,0x21,0x06,0x07,0x06,0x23,0x21,0x22,0x35,0x27,0x21,0x15, +0x01,0xc8,0xfe,0x38,0x0a,0x04,0x60,0xa0,0x10,0x15,0x17,0x0e,0x12,0x1c,0xde,0x1a,0x14,0x0c,0x12,0x2a,0xa0,0x60,0x04,0x0a,0xfe,0x3a,0xa4,0x1c,0x01,0x24,0x1c,0x0e,0x1c,0x98,0x1c,0x96,0x01,0xae,0x06,0x04,0x06,0x54,0xfd,0x12,0x5a,0x0a,0x01,0xae,0x01,0x46,0x64,0x01,0x24,0x6c,0x1a,0x29,0x2d,0x1a,0x0c,0x0e,0x18,0x20,0x50,0x6c, +0xfe,0xdc,0x64,0x01,0x62,0x36,0x36,0x1a,0xfd,0x8a,0x64,0x58,0x4e,0x54,0x54,0xa6,0x64,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xdc,0x01,0xcc,0x00,0x08,0x00,0x20,0x40,0x1d,0x02,0x01,0x00,0x01,0x01,0x00,0x59,0x02,0x01,0x00,0x00,0x01,0x61,0x00,0x01,0x00,0x01,0x51,0x01,0x00,0x05,0x04,0x00,0x08,0x01,0x08,0x03,0x07, +0x16,0x2b,0x13,0x32,0x16,0x14,0x06,0x22,0x26,0x34,0x36,0x6e,0x2e,0x40,0x40,0x5c,0x40,0x40,0x01,0xcc,0x40,0x5a,0x42,0x42,0x5a,0x40,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x67,0x02,0x7c,0x00,0x0d,0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01, +0x00,0x51,0x17,0x13,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x16,0x01,0x65,0x14,0x20,0x09,0xfa,0x0a,0x0a,0xfa,0x0b,0x1c,0x18,0x02,0x58,0xfe,0x0c,0x0e,0x16,0x0b,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x41,0x02,0x7d,0x00,0x0e,0x00,0x0a,0xb7,0x00, +0x00,0x00,0x76,0x14,0x01,0x07,0x17,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x26,0x35,0x11,0x34,0x3e,0x01,0x1f,0x01,0x16,0x01,0x41,0x0a,0xfa,0x0b,0x1c,0x16,0x16,0x1c,0x0b,0xfa,0x0a,0x01,0x5e,0x0e,0x0b,0xfa,0x0b,0x16,0x0e,0x01,0xf4,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x02,0x3b,0x01,0xc9,0x00,0x0e, +0x00,0x18,0x40,0x15,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x15,0x32,0x02,0x07,0x18,0x2b,0x25,0x14,0x06,0x27,0x21,0x22,0x2e,0x01,0x3f,0x01,0x36,0x32,0x1f,0x01,0x16,0x02,0x3b,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x1e,0x0a,0xfa,0x0a,0xab,0x0e,0x16,0x01,0x14,0x1e,0x0b, +0xfa,0x0a,0x0a,0xfa,0x0b,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x5e,0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x03,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x17,0x19,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x17,0x16,0x14,0x0f,0x01,0x06,0x22,0x27, +0x01,0x26,0x34,0x37,0x01,0x36,0x32,0x1f,0x01,0x16,0x01,0x5e,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0xfe,0xfc,0x06,0x06,0x01,0x04,0x05,0x10,0x04,0x1c,0x06,0x02,0x22,0x07,0x05,0xdc,0xdb,0x06,0x0e,0x06,0x1c,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0x1c,0x05,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x4c, +0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x0b,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x1c,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x17,0x01,0x16,0x01,0x4c,0x05,0xfe,0xfb,0x05, +0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x10,0x04,0x01,0x05,0x05,0x01,0x3a,0x07,0x05,0xfe,0xfb,0x05,0x05,0x1c,0x06,0x0e,0x06,0xdb,0xdc,0x05,0x0e,0x06,0x1c,0x06,0x06,0xfe,0xfc,0x05,0x00,0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08,0x00,0x16,0x00,0x3f,0x00,0x83,0x40,0x0b,0x38,0x36,0x02,0x03, +0x05,0x13,0x01,0x02,0x03,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x24,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x00,0x06,0x00,0x03,0x02,0x06,0x03,0x69,0x08,0x01,0x02,0x00,0x01,0x02,0x01,0x66,0x00,0x04,0x04,0x00,0x61,0x07,0x01,0x00,0x00,0x12,0x04,0x4e,0x1b,0x40,0x2b,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x07,0x01,0x00, +0x00,0x04,0x06,0x00,0x04,0x69,0x00,0x06,0x00,0x03,0x02,0x06,0x03,0x69,0x08,0x01,0x02,0x01,0x01,0x02,0x59,0x08,0x01,0x02,0x02,0x01,0x62,0x00,0x01,0x02,0x01,0x52,0x59,0x40,0x19,0x0a,0x09,0x01,0x00,0x27,0x26,0x22,0x20,0x1d,0x1b,0x11,0x0e,0x09,0x16,0x0a,0x16,0x05,0x04,0x00,0x08,0x01,0x08,0x09,0x07,0x16,0x2b,0x01,0x36,0x00, +0x12,0x00,0x04,0x00,0x02,0x00,0x13,0x32,0x36,0x35,0x36,0x26,0x2b,0x01,0x22,0x06,0x07,0x14,0x16,0x17,0x13,0x36,0x35,0x34,0x26,0x23,0x22,0x07,0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x32,0x17,0x16,0x15,0x14,0x07,0x06,0x0f,0x01,0x06,0x0f,0x01,0x06,0x07,0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x3f,0x01,0x36,0x01,0xc6,0xbe, +0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xbc,0x1e,0x26,0x02,0x26,0x1e,0x02,0x1c,0x26,0x02,0x26,0x1c,0xa8,0x1a,0x6a,0x52,0x40,0x28,0x44,0x04,0x6e,0x10,0x10,0x4e,0x0c,0x10,0x10,0x08,0x0c,0x16,0x0a,0x0a,0x15,0x0b,0x06,0x0e,0x04,0x6c,0x04,0x06,0x16,0x1c,0x2e,0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee, +0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0xfd,0x1e,0x26,0x1c,0x1e,0x26,0x24,0x1c,0x1e,0x26,0x02,0x01,0x48,0x22,0x2c,0x4e,0x4c,0x1a,0x2a,0x68,0x04,0x04,0x1a,0x1c,0x18,0x14,0x14,0x18,0x12,0x16,0x0c,0x08,0x0f,0x07,0x08,0x11,0x09,0x08,0x14,0x3a,0x08,0x04,0x0c,0x10,0x14,0x10,0x12,0x22,0x00,0x00,0x02,0x00,0x00,0xff,0xbd,0x03,0x4d, +0x03,0x0b,0x00,0x08,0x00,0x1d,0x00,0x3a,0xb5,0x00,0x01,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x29,0x50,0x58,0x40,0x10,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x00,0x01,0x01,0x11,0x01,0x4e,0x1b,0x40,0x10,0x00,0x01,0x00,0x01,0x86,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x13,0x00,0x4e,0x59,0xb5,0x38,0x1a,0x12,0x03,0x07, 0x19,0x2b,0x13,0x34,0x26,0x0e,0x01,0x1e,0x02,0x36,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x2e,0x01,0x3d,0x01,0x34,0x36,0x37,0x33,0x32,0x16,0x17,0x01,0x16,0xfa,0x2a,0x3a,0x2c,0x02,0x28,0x3e,0x26,0x02,0x55,0x14,0xfe,0xee,0x16,0x3b,0x14,0xfe,0x71,0x15,0x1e,0x2a,0x1d,0xe9,0x1d,0x48,0x15,0x01,0x8f,0x14,0x02,0x58,0x1e,0x2a, 0x02,0x26,0x40,0x24,0x06,0x30,0xfe,0xd9,0x1e,0x15,0xfe,0xee,0x15,0x15,0x01,0x8f,0x15,0x48,0x1d,0xe8,0x1d,0x2a,0x01,0x1e,0x15,0xfe,0x71,0x15,0x00,0x0d,0x00,0x00,0xff,0xea,0x03,0xca,0x02,0xd2,0x00,0x03,0x00,0x07,0x00,0x0b,0x00,0x0f,0x00,0x13,0x00,0x17,0x00,0x1b,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x2b,0x00,0x2f,0x00,0x33, -0x00,0xfd,0x4b,0xb0,0x32,0x50,0x58,0x40,0x49,0x18,0x12,0x0c,0x03,0x06,0x00,0x07,0x00,0x06,0x07,0x80,0x20,0x19,0x13,0x1d,0x0d,0x05,0x07,0x03,0x00,0x07,0x03,0x7e,0x17,0x11,0x0b,0x03,0x05,0x02,0x04,0x02,0x05,0x04,0x80,0x16,0x10,0x0a,0x03,0x04,0x01,0x02,0x04,0x01,0x7e,0x1f,0x15,0x0e,0x1c,0x09,0x05,0x02,0x1a,0x01,0x01,0x02, -0x01,0x63,0x14,0x1e,0x0f,0x08,0x1b,0x05,0x03,0x03,0x00,0x60,0x00,0x00,0x00,0x13,0x03,0x4e,0x1b,0x40,0x54,0x18,0x12,0x0c,0x03,0x06,0x00,0x07,0x00,0x06,0x07,0x80,0x20,0x19,0x13,0x1d,0x0d,0x05,0x07,0x03,0x00,0x07,0x03,0x7e,0x17,0x11,0x0b,0x03,0x05,0x02,0x04,0x02,0x05,0x04,0x80,0x16,0x10,0x0a,0x03,0x04,0x01,0x02,0x04,0x01, -0x7e,0x00,0x00,0x14,0x1e,0x0f,0x08,0x1b,0x05,0x03,0x02,0x00,0x03,0x67,0x1f,0x15,0x0e,0x1c,0x09,0x05,0x02,0x05,0x01,0x02,0x58,0x1f,0x15,0x0e,0x1c,0x09,0x05,0x02,0x02,0x01,0x5f,0x1a,0x01,0x01,0x02,0x01,0x4f,0x59,0x40,0x52,0x30,0x30,0x28,0x28,0x1c,0x1c,0x18,0x18,0x10,0x10,0x04,0x04,0x00,0x00,0x30,0x33,0x30,0x33,0x32,0x31, -0x2f,0x2e,0x2d,0x2c,0x28,0x2b,0x28,0x2b,0x2a,0x29,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1c,0x1f,0x1c,0x1f,0x1e,0x1d,0x18,0x1b,0x18,0x1b,0x1a,0x19,0x17,0x16,0x15,0x14,0x10,0x13,0x10,0x13,0x12,0x11,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x04,0x07,0x04,0x07,0x06,0x05,0x00,0x03,0x00,0x03,0x11,0x21,0x07,0x17,0x2b,0x15, -0x11,0x21,0x11,0x01,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01,0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x05,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01,0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x03,0xca,0xfe,0x3d,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0xe1,0x9e, -0x9e,0x9e,0x9e,0x9e,0xfd,0x5b,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0xe1,0x9d,0x9d,0x9d,0x9d,0x9d,0x16,0x02,0xe8,0xfd,0x18,0x01,0xc4,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e,0x9e,0x43,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e,0x9e,0x00,0x00,0x00, -0x00,0x02,0xff,0xff,0xff,0xf9,0x04,0x19,0x03,0x0b,0x00,0x12,0x00,0x29,0x00,0x47,0x4b,0xb0,0x26,0x50,0x58,0x40,0x15,0x00,0x04,0x00,0x02,0x01,0x04,0x02,0x68,0x00,0x01,0x00,0x00,0x01,0x00,0x63,0x00,0x03,0x03,0x10,0x03,0x4e,0x1b,0x40,0x1d,0x00,0x03,0x04,0x03,0x85,0x00,0x04,0x00,0x02,0x01,0x04,0x02,0x68,0x00,0x01,0x00,0x00, -0x01,0x57,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x59,0xb7,0x23,0x3a,0x23,0x36,0x35,0x05,0x07,0x1b,0x2b,0x01,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x2e,0x01,0x3f,0x01,0x3e,0x01,0x33,0x21,0x32,0x16,0x27,0x15,0x21,0x22,0x06,0x0f,0x02,0x27,0x26,0x37,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16, -0x04,0x19,0x12,0xbb,0x18,0x56,0x26,0xfd,0xa1,0x13,0x1c,0x01,0x11,0xbc,0x18,0x56,0x25,0x02,0x5f,0x13,0x1e,0xc0,0xfe,0x30,0x35,0x72,0x23,0xbc,0x02,0x01,0x01,0x01,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x2f,0x34,0x48,0x01,0x3f,0x11,0x14,0xdd,0x1c,0x28,0x0e,0x22,0x14,0xdd,0x1c,0x28,0x0e,0xaf,0x5a,0x34,0x29,0xdd,0x03,0x07,0x05,0x02, -0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x01,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x14,0x00,0x35,0x4b,0xb0,0x26,0x50,0x58,0x40,0x0d,0x00,0x02,0x00,0x00,0x02,0x00,0x64,0x00,0x01,0x01,0x10,0x01,0x4e,0x1b,0x40,0x15,0x00,0x01,0x02,0x01,0x85,0x00,0x02,0x00,0x00,0x02,0x57,0x00,0x02,0x02,0x00,0x60,0x00,0x00,0x02, -0x00,0x50,0x59,0xb5,0x23,0x35,0x33,0x03,0x07,0x19,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0xa1,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x01,0xff,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12, -0x4a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x1f,0x40,0x1c,0x01,0x01,0x00,0x49,0x03,0x02,0x02,0x00,0x01,0x00,0x86,0x00,0x01,0x01,0x13,0x01,0x4e,0x00,0x00,0x00,0x06,0x00,0x06,0x11,0x12,0x04,0x07,0x18,0x2b,0x09,0x02,0x33,0x11,0x21,0x11,0x02,0xf8,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x78, -0x01,0x6e,0xfe,0x84,0x01,0x7c,0x01,0x5e,0xfe,0xa2,0x00,0x00,0x00,0x02,0xff,0xf7,0xff,0xe2,0x03,0xdb,0x03,0x12,0x00,0x17,0x00,0x20,0x00,0x42,0x4b,0xb0,0x1c,0x50,0x58,0x40,0x11,0x00,0x02,0x01,0x02,0x85,0x03,0x01,0x01,0x01,0x00,0x61,0x00,0x00,0x00,0x14,0x00,0x4e,0x1b,0x40,0x17,0x00,0x02,0x01,0x02,0x85,0x03,0x01,0x01,0x00, -0x00,0x01,0x59,0x03,0x01,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x59,0x40,0x0c,0x19,0x18,0x1d,0x1c,0x18,0x20,0x19,0x20,0x2f,0x04,0x07,0x17,0x2b,0x01,0x1e,0x01,0x06,0x07,0x06,0x26,0x06,0x07,0x06,0x1e,0x01,0x07,0x0e,0x02,0x23,0x22,0x26,0x37,0x3e,0x01,0x37,0x24,0x03,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x59, -0x48,0x3a,0x12,0x1a,0x10,0x4c,0x54,0x26,0x1e,0x12,0x32,0x02,0x02,0x44,0xb8,0x7c,0xba,0xd2,0x0a,0x08,0xc0,0x78,0x01,0x22,0x48,0x1e,0x2c,0x2c,0x3e,0x2c,0x2c,0x02,0x6e,0x30,0x7c,0x54,0x06,0x04,0x1c,0x08,0x2a,0x2e,0x3a,0x48,0x0e,0x1a,0x4a,0x4a,0xca,0x90,0x76,0xea,0x22,0x54,0xfd,0x8a,0x2c,0x40,0x2a,0x2a,0x40,0x2c,0x00,0x00, -0x00,0x02,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x06,0x00,0x18,0x00,0x33,0x40,0x30,0x01,0x01,0x00,0x03,0x01,0x4c,0x00,0x03,0x00,0x03,0x85,0x04,0x01,0x00,0x01,0x00,0x85,0x00,0x01,0x02,0x02,0x01,0x57,0x00,0x01,0x01,0x02,0x60,0x00,0x02,0x01,0x02,0x50,0x00,0x00,0x18,0x16,0x11,0x0e,0x0b,0x09,0x00,0x06,0x00,0x06,0x05, -0x07,0x16,0x2b,0x01,0x11,0x16,0x1f,0x01,0x16,0x17,0x05,0x14,0x16,0x17,0x21,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21,0x02,0x3b,0x0d,0x08,0xe3,0x08,0x08,0xfe,0xb1,0x20,0x16,0x01,0x2f,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xbe,0x02,0x34,0x01,0x08,0x08,0x08,0xe4,0x07,0x0d,0x12,0x16,0x1e, -0x01,0xfd,0xb3,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c,0x17,0x1e,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x08,0x00,0x6a,0x00,0x72,0x40,0x15,0x65,0x59,0x4c,0x41,0x04,0x00,0x04,0x3b,0x0a,0x02,0x01,0x00,0x34,0x28,0x1b,0x10,0x04,0x03,0x01,0x03,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x20,0x00,0x00, -0x00,0x05,0x5f,0x00,0x05,0x05,0x10,0x4d,0x00,0x03,0x03,0x04,0x61,0x06,0x01,0x04,0x04,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x1e,0x00,0x05,0x00,0x00,0x01,0x05,0x00,0x69,0x00,0x03,0x03,0x04,0x61,0x06,0x01,0x04,0x04,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x59, -0x40,0x0f,0x5c,0x5b,0x53,0x51,0x49,0x48,0x2b,0x2a,0x22,0x20,0x13,0x12,0x07,0x07,0x18,0x2b,0x01,0x34,0x26,0x22,0x0e,0x01,0x16,0x32,0x36,0x25,0x15,0x14,0x06,0x0f,0x01,0x06,0x07,0x16,0x17,0x16,0x14,0x07,0x0e,0x01,0x27,0x22,0x2f,0x01,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x35,0x27,0x26,0x27,0x07,0x06,0x22,0x27,0x26, -0x27,0x26,0x34,0x37,0x3e,0x01,0x37,0x26,0x2f,0x01,0x2e,0x01,0x27,0x35,0x34,0x36,0x3f,0x01,0x36,0x37,0x26,0x27,0x26,0x34,0x37,0x3e,0x01,0x33,0x32,0x1f,0x01,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x32,0x16,0x1f,0x01,0x16,0x17,0x37,0x36,0x32,0x17,0x16,0x17,0x16,0x14,0x07,0x0e,0x01,0x07,0x16,0x1f,0x01,0x1e,0x01,0x02,0x3b,0x52, -0x78,0x52,0x02,0x56,0x74,0x56,0x01,0x1c,0x08,0x07,0x68,0x0a,0x0b,0x13,0x28,0x06,0x05,0x0f,0x50,0x0d,0x07,0x07,0x4d,0x19,0x1a,0x09,0x07,0x04,0x10,0x7c,0x08,0x0c,0x10,0x1b,0x17,0x4f,0x06,0x10,0x06,0x46,0x16,0x04,0x05,0x08,0x28,0x0a,0x0f,0x08,0x66,0x07,0x08,0x01,0x0a,0x05,0x68,0x08,0x0e,0x17,0x25,0x06,0x05,0x0f,0x50,0x0d, -0x07,0x08,0x4d,0x18,0x1a,0x09,0x08,0x03,0x11,0x7c,0x07,0x0c,0x01,0x0f,0x1c,0x17,0x4f,0x05,0x0f,0x07,0x48,0x14,0x04,0x04,0x09,0x28,0x0a,0x0f,0x08,0x66,0x07,0x0a,0x01,0x5e,0x3b,0x54,0x54,0x76,0x54,0x54,0x78,0x7c,0x07,0x0c,0x01,0x10,0x1e,0x15,0x1b,0x32,0x06,0x0e,0x06,0x15,0x50,0x01,0x05,0x3c,0x0d,0x08,0x4c,0x1c,0x10,0x0a, -0x07,0x67,0x09,0x0c,0x3c,0x05,0x06,0x40,0x1e,0x05,0x0e,0x06,0x0c,0x32,0x0f,0x1c,0x1b,0x0f,0x01,0x0c,0x07,0x7c,0x07,0x0c,0x01,0x10,0x19,0x1a,0x20,0x2d,0x07,0x0c,0x07,0x14,0x50,0x05,0x3c,0x0d,0x08,0x4c,0x1c,0x10,0x0a,0x07,0x67,0x09,0x0b,0x3b,0x05,0x05,0x43,0x1c,0x05,0x0e,0x06,0x0c,0x32,0x0f,0x1c,0x1a,0x10,0x01,0x0c,0x00, -0x00,0x09,0x00,0x00,0xff,0xf9,0x03,0xe8,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0x8f,0x00,0x80,0x4b,0xb0,0x26,0x50,0x58,0x40,0x26,0x0f,0x09,0x02,0x03,0x0e,0x08,0x02,0x02,0x01,0x03,0x02,0x67,0x0b,0x05,0x02,0x01,0x0a,0x04,0x02,0x00,0x01,0x00,0x63,0x10,0x0c,0x02,0x06, -0x06,0x07,0x5f,0x11,0x0d,0x02,0x07,0x07,0x10,0x06,0x4e,0x1b,0x40,0x2e,0x11,0x0d,0x02,0x07,0x10,0x0c,0x02,0x06,0x03,0x07,0x06,0x67,0x0f,0x09,0x02,0x03,0x0e,0x08,0x02,0x02,0x01,0x03,0x02,0x67,0x0b,0x05,0x02,0x01,0x00,0x00,0x01,0x57,0x0b,0x05,0x02,0x01,0x01,0x00,0x5f,0x0a,0x04,0x02,0x00,0x01,0x00,0x4f,0x59,0x40,0x1e,0x8e, -0x8b,0x86,0x83,0x7e,0x7b,0x76,0x73,0x6e,0x6b,0x66,0x63,0x5e,0x5b,0x56,0x53,0x4e,0x4b,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x12,0x07,0x1f,0x2b,0x25,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x13,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15, -0x14,0x06,0x07,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15, -0x14,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x37,0x33,0x32,0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x1e,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17, -0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17, -0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0x9a,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x01,0x06,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe,0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c, -0x16,0x20,0x01,0x1e,0x02,0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe,0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x02,0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01, -0x20,0x01,0x08,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0x00,0x05,0x00,0x00,0xff,0x6a,0x03,0xe8,0x03,0x52,0x00,0x10,0x00,0x14,0x00,0x25,0x00,0x2f,0x00,0x39,0x00,0x65,0x40,0x62,0x33,0x29,0x02,0x07,0x08,0x21,0x01,0x05,0x02,0x1d,0x15,0x0d,0x0c,0x04,0x00,0x05,0x03,0x4c,0x04,0x01,0x05,0x01,0x4b,0x0a,0x01,0x08,0x09,0x01, -0x07,0x01,0x08,0x07,0x67,0x00,0x02,0x05,0x01,0x02,0x57,0x06,0x0c,0x03,0x0b,0x04,0x01,0x00,0x05,0x00,0x01,0x05,0x69,0x06,0x0c,0x03,0x0b,0x04,0x01,0x01,0x00,0x5f,0x04,0x01,0x00,0x01,0x00,0x4f,0x11,0x11,0x00,0x00,0x37,0x35,0x32,0x31,0x2d,0x2b,0x28,0x27,0x24,0x22,0x1f,0x1e,0x1b,0x19,0x11,0x14,0x11,0x14,0x13,0x12,0x00,0x10, -0x00,0x0f,0x37,0x0d,0x07,0x17,0x2b,0x01,0x11,0x14,0x06,0x07,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x13,0x36,0x33,0x21,0x11,0x23,0x11,0x01,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x22,0x26,0x27,0x11,0x33,0x32,0x17,0x25,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x05,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32, -0x16,0x01,0x89,0x16,0x0e,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x8b,0x04,0x0d,0x01,0x9f,0x8e,0x02,0x3b,0x16,0x0e,0xfe,0xe3,0x0f,0x14,0x01,0x0f,0x14,0x01,0xed,0x0d,0x04,0xfe,0x3e,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x01,0x77,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x02,0x9f,0xfe,0x54,0x0f,0x14,0x01,0xfe,0xbf,0x0f,0x14,0x01,0x16,0x0e,0x01, -0x1d,0x01,0xe8,0x0c,0xfe,0x78,0x01,0x88,0xfe,0x0c,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x41,0x16,0x0e,0x01,0xac,0x0c,0xad,0x7d,0x7d,0x08,0x0a,0x0a,0x08,0x7d,0x7d,0x08,0x0a,0x0a,0x00,0x08,0xff,0xff,0xff,0xf8,0x03,0xe9,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0xad, -0x40,0x28,0x79,0x78,0x71,0x49,0x48,0x41,0x06,0x08,0x09,0x69,0x61,0x60,0x29,0x21,0x20,0x06,0x04,0x05,0x59,0x58,0x51,0x50,0x19,0x18,0x11,0x10,0x08,0x02,0x03,0x39,0x38,0x31,0x09,0x08,0x01,0x06,0x00,0x01,0x04,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x2a,0x0d,0x01,0x05,0x0c,0x01,0x04,0x03,0x05,0x04,0x67,0x0b,0x01,0x03,0x0a,0x01, -0x02,0x01,0x03,0x02,0x67,0x07,0x01,0x01,0x06,0x01,0x00,0x01,0x00,0x63,0x0e,0x01,0x08,0x08,0x09,0x5f,0x0f,0x01,0x09,0x09,0x10,0x08,0x4e,0x1b,0x40,0x31,0x0f,0x01,0x09,0x0e,0x01,0x08,0x05,0x09,0x08,0x67,0x0d,0x01,0x05,0x0c,0x01,0x04,0x03,0x05,0x04,0x67,0x0b,0x01,0x03,0x0a,0x01,0x02,0x01,0x03,0x02,0x67,0x07,0x01,0x01,0x00, -0x00,0x01,0x57,0x07,0x01,0x01,0x01,0x00,0x5f,0x06,0x01,0x00,0x01,0x00,0x4f,0x59,0x40,0x1a,0x7d,0x7b,0x75,0x73,0x6d,0x6b,0x65,0x64,0x5d,0x5b,0x55,0x54,0x4d,0x4c,0x26,0x26,0x17,0x26,0x17,0x17,0x17,0x17,0x14,0x10,0x07,0x1f,0x2b,0x37,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x27,0x15,0x14, -0x06,0x27,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14, -0x06,0x27,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x8f,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01, -0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0xfc,0xa6,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd, -0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x76,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xd0,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xfe,0x4c,0x6b,0x07,0x0c, -0x01,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0x02,0x7d,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xfe,0x4d,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xcf,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x02,0x83, -0x03,0x0b,0x00,0x07,0x00,0x1f,0x00,0x47,0x4b,0xb0,0x26,0x50,0x58,0x40,0x14,0x05,0x03,0x02,0x00,0x00,0x02,0x00,0x02,0x63,0x00,0x01,0x01,0x04,0x61,0x00,0x04,0x04,0x10,0x01,0x4e,0x1b,0x40,0x1c,0x00,0x04,0x00,0x01,0x00,0x04,0x01,0x69,0x05,0x03,0x02,0x00,0x02,0x02,0x00,0x59,0x05,0x03,0x02,0x00,0x00,0x02,0x5f,0x00,0x02,0x00, -0x02,0x4f,0x59,0x40,0x09,0x23,0x13,0x25,0x36,0x13,0x10,0x06,0x07,0x1c,0x2b,0x13,0x21,0x35,0x34,0x26,0x0e,0x01,0x17,0x05,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17,0x33,0x35,0x34,0x36,0x32,0x16,0x07,0x15,0x33,0x32,0x16,0xb3,0x01,0x1d,0x54,0x76,0x54,0x01,0x01,0xd0,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01,0x20, -0x16,0x11,0x94,0xcc,0x96,0x02,0x12,0x17,0x1e,0x01,0xa5,0x6c,0x3b,0x54,0x02,0x50,0x3d,0xa1,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01,0x6c,0x66,0x94,0x94,0x66,0x6c,0x1e,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x06,0x01,0x01,0x00,0x01,0x4c,0x00,0x01, +0x00,0xa9,0x40,0xa6,0x18,0x12,0x0c,0x03,0x06,0x00,0x07,0x00,0x06,0x07,0x80,0x20,0x19,0x13,0x1d,0x0d,0x05,0x07,0x03,0x00,0x07,0x03,0x7e,0x17,0x11,0x0b,0x03,0x05,0x02,0x04,0x02,0x05,0x04,0x80,0x16,0x10,0x0a,0x03,0x04,0x01,0x02,0x04,0x01,0x7e,0x00,0x00,0x14,0x1e,0x0f,0x08,0x1b,0x05,0x03,0x02,0x00,0x03,0x67,0x1f,0x15,0x0e, +0x1c,0x09,0x05,0x02,0x05,0x01,0x02,0x58,0x1f,0x15,0x0e,0x1c,0x09,0x05,0x02,0x02,0x01,0x5f,0x1a,0x01,0x01,0x02,0x01,0x4f,0x30,0x30,0x28,0x28,0x1c,0x1c,0x18,0x18,0x10,0x10,0x04,0x04,0x00,0x00,0x30,0x33,0x30,0x33,0x32,0x31,0x2f,0x2e,0x2d,0x2c,0x28,0x2b,0x28,0x2b,0x2a,0x29,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1c,0x1f, +0x1c,0x1f,0x1e,0x1d,0x18,0x1b,0x18,0x1b,0x1a,0x19,0x17,0x16,0x15,0x14,0x10,0x13,0x10,0x13,0x12,0x11,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x04,0x07,0x04,0x07,0x06,0x05,0x00,0x03,0x00,0x03,0x11,0x21,0x07,0x17,0x2b,0x15,0x11,0x21,0x11,0x01,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01, +0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x05,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01,0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x03,0xca,0xfe,0x3d,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0xe1,0x9e,0x9e,0x9e,0x9e,0x9e,0xfd,0x5b,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0xe1,0x9d,0x9d,0x9d,0x9d,0x9d,0x16, +0x02,0xe8,0xfd,0x18,0x01,0xc4,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e,0x9e,0x43,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e,0x9e,0x00,0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xf9,0x04,0x19,0x03,0x0b,0x00,0x12,0x00,0x29,0x00,0x20,0x40,0x1d,0x00,0x04, +0x00,0x02,0x01,0x04,0x02,0x68,0x00,0x01,0x00,0x00,0x01,0x00,0x63,0x00,0x03,0x03,0x13,0x03,0x4e,0x23,0x3a,0x23,0x36,0x35,0x05,0x07,0x1b,0x2b,0x01,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x2e,0x01,0x3f,0x01,0x3e,0x01,0x33,0x21,0x32,0x16,0x27,0x15,0x21,0x22,0x06,0x0f,0x02,0x27,0x26,0x37,0x11,0x34,0x36,0x3b,0x01,0x32,0x16, +0x1d,0x01,0x21,0x32,0x16,0x04,0x19,0x12,0xbb,0x18,0x56,0x26,0xfd,0xa1,0x13,0x1c,0x01,0x11,0xbc,0x18,0x56,0x25,0x02,0x5f,0x13,0x1e,0xc0,0xfe,0x30,0x35,0x72,0x23,0xbc,0x02,0x01,0x01,0x01,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x2f,0x34,0x48,0x01,0x3f,0x11,0x14,0xdd,0x1c,0x28,0x0e,0x22,0x14,0xdd,0x1c,0x28,0x0e,0xaf,0x5a,0x34,0x29, +0xdd,0x03,0x07,0x05,0x02,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x14,0x00,0x16,0x40,0x13,0x00,0x02,0x00,0x00,0x02,0x00,0x64,0x00,0x01,0x01,0x13,0x01,0x4e,0x23,0x35,0x33,0x03,0x07,0x19,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36, +0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0xa1,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x01,0xff,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x1d,0x40,0x1a,0x01,0x01,0x00,0x49, +0x00,0x01,0x00,0x01,0x85,0x03,0x02,0x02,0x00,0x00,0x76,0x00,0x00,0x00,0x06,0x00,0x06,0x11,0x12,0x04,0x07,0x18,0x2b,0x09,0x02,0x33,0x11,0x21,0x11,0x02,0xf8,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x78,0x01,0x6e,0xfe,0x84,0x01,0x7c,0x01,0x5e,0xfe,0xa2,0x00,0x02,0xff,0xf7,0xff,0xe2,0x03,0xdb,0x03,0x12,0x00,0x17,0x00,0x20,0x00,0x26, +0x40,0x23,0x00,0x02,0x01,0x02,0x85,0x03,0x01,0x01,0x00,0x00,0x01,0x59,0x03,0x01,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x19,0x18,0x1d,0x1c,0x18,0x20,0x19,0x20,0x2f,0x04,0x07,0x17,0x2b,0x01,0x1e,0x01,0x06,0x07,0x06,0x26,0x06,0x07,0x06,0x1e,0x01,0x07,0x0e,0x02,0x23,0x22,0x26,0x37,0x3e,0x01,0x37,0x24,0x03,0x32,0x36, +0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x59,0x48,0x3a,0x12,0x1a,0x10,0x4c,0x54,0x26,0x1e,0x12,0x32,0x02,0x02,0x44,0xb8,0x7c,0xba,0xd2,0x0a,0x08,0xc0,0x78,0x01,0x22,0x48,0x1e,0x2c,0x2c,0x3e,0x2c,0x2c,0x02,0x6e,0x30,0x7c,0x54,0x06,0x04,0x1c,0x08,0x2a,0x2e,0x3a,0x48,0x0e,0x1a,0x4a,0x4a,0xca,0x90,0x76,0xea,0x22,0x54,0xfd,0x8a, +0x2c,0x40,0x2a,0x2a,0x40,0x2c,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x06,0x00,0x18,0x00,0x33,0x40,0x30,0x01,0x01,0x00,0x03,0x01,0x4c,0x00,0x03,0x00,0x03,0x85,0x04,0x01,0x00,0x01,0x00,0x85,0x00,0x01,0x02,0x02,0x01,0x57,0x00,0x01,0x01,0x02,0x60,0x00,0x02,0x01,0x02,0x50,0x00,0x00,0x18,0x16,0x11, +0x0e,0x0b,0x09,0x00,0x06,0x00,0x06,0x05,0x07,0x16,0x2b,0x01,0x11,0x16,0x1f,0x01,0x16,0x17,0x05,0x14,0x16,0x17,0x21,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21,0x02,0x3b,0x0d,0x08,0xe3,0x08,0x08,0xfe,0xb1,0x20,0x16,0x01,0x2f,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xbe,0x02,0x34,0x01,0x08, +0x08,0x08,0xe4,0x07,0x0d,0x12,0x16,0x1e,0x01,0xfd,0xb3,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c,0x17,0x1e,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x08,0x00,0x6a,0x00,0x45,0x40,0x42,0x65,0x59,0x4c,0x41,0x04,0x00,0x04,0x3b,0x0a,0x02,0x01,0x00,0x34,0x28,0x1b,0x10,0x04,0x03,0x01,0x03,0x4c,0x06, +0x01,0x04,0x00,0x03,0x02,0x04,0x03,0x69,0x00,0x00,0x00,0x05,0x5f,0x00,0x05,0x05,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x5c,0x5b,0x53,0x51,0x49,0x48,0x2b,0x2a,0x22,0x20,0x13,0x12,0x07,0x07,0x18,0x2b,0x01,0x34,0x26,0x22,0x0e,0x01,0x16,0x32,0x36,0x25,0x15,0x14,0x06,0x0f,0x01,0x06,0x07,0x16,0x17, +0x16,0x14,0x07,0x0e,0x01,0x27,0x22,0x2f,0x01,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x35,0x27,0x26,0x27,0x07,0x06,0x22,0x27,0x26,0x27,0x26,0x34,0x37,0x3e,0x01,0x37,0x26,0x2f,0x01,0x2e,0x01,0x27,0x35,0x34,0x36,0x3f,0x01,0x36,0x37,0x26,0x27,0x26,0x34,0x37,0x3e,0x01,0x33,0x32,0x1f,0x01,0x36,0x37,0x36,0x37,0x36,0x3b, +0x01,0x32,0x16,0x1f,0x01,0x16,0x17,0x37,0x36,0x32,0x17,0x16,0x17,0x16,0x14,0x07,0x0e,0x01,0x07,0x16,0x1f,0x01,0x1e,0x01,0x02,0x3b,0x52,0x78,0x52,0x02,0x56,0x74,0x56,0x01,0x1c,0x08,0x07,0x68,0x0a,0x0b,0x13,0x28,0x06,0x05,0x0f,0x50,0x0d,0x07,0x07,0x4d,0x19,0x1a,0x09,0x07,0x04,0x10,0x7c,0x08,0x0c,0x10,0x1b,0x17,0x4f,0x06, +0x10,0x06,0x46,0x16,0x04,0x05,0x08,0x28,0x0a,0x0f,0x08,0x66,0x07,0x08,0x01,0x0a,0x05,0x68,0x08,0x0e,0x17,0x25,0x06,0x05,0x0f,0x50,0x0d,0x07,0x08,0x4d,0x18,0x1a,0x09,0x08,0x03,0x11,0x7c,0x07,0x0c,0x01,0x0f,0x1c,0x17,0x4f,0x05,0x0f,0x07,0x48,0x14,0x04,0x04,0x09,0x28,0x0a,0x0f,0x08,0x66,0x07,0x0a,0x01,0x5e,0x3b,0x54,0x54, +0x76,0x54,0x54,0x78,0x7c,0x07,0x0c,0x01,0x10,0x1e,0x15,0x1b,0x32,0x06,0x0e,0x06,0x15,0x50,0x01,0x05,0x3c,0x0d,0x08,0x4c,0x1c,0x10,0x0a,0x07,0x67,0x09,0x0c,0x3c,0x05,0x06,0x40,0x1e,0x05,0x0e,0x06,0x0c,0x32,0x0f,0x1c,0x1b,0x0f,0x01,0x0c,0x07,0x7c,0x07,0x0c,0x01,0x10,0x19,0x1a,0x20,0x2d,0x07,0x0c,0x07,0x14,0x50,0x05,0x3c, +0x0d,0x08,0x4c,0x1c,0x10,0x0a,0x07,0x67,0x09,0x0b,0x3b,0x05,0x05,0x43,0x1c,0x05,0x0e,0x06,0x0c,0x32,0x0f,0x1c,0x1a,0x10,0x01,0x0c,0x00,0x00,0x00,0x09,0x00,0x00,0xff,0xf9,0x03,0xe8,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0x8f,0x00,0x47,0x40,0x44,0x0f,0x09,0x02,0x03, +0x0e,0x08,0x02,0x02,0x01,0x03,0x02,0x67,0x0b,0x05,0x02,0x01,0x0a,0x04,0x02,0x00,0x01,0x00,0x63,0x10,0x0c,0x02,0x06,0x06,0x07,0x5f,0x11,0x0d,0x02,0x07,0x07,0x13,0x06,0x4e,0x8e,0x8b,0x86,0x83,0x7e,0x7b,0x76,0x73,0x6e,0x6b,0x66,0x63,0x5e,0x5b,0x56,0x53,0x4e,0x4b,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x12,0x07,0x1f, +0x2b,0x25,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x13,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32, +0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x37,0x33,0x32, +0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x1e,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20, +0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17, +0x1e,0x9a,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x01,0x06,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe,0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x02,0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe, +0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x02,0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0x01,0x08,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0x00,0x00,0x05,0x00,0x00,0xff,0x6a,0x03,0xe8,0x03,0x52,0x00,0x10,0x00,0x14,0x00,0x25, +0x00,0x2f,0x00,0x39,0x00,0x65,0x40,0x62,0x33,0x29,0x02,0x07,0x08,0x21,0x01,0x05,0x02,0x1d,0x15,0x0d,0x0c,0x04,0x00,0x05,0x03,0x4c,0x04,0x01,0x05,0x01,0x4b,0x0a,0x01,0x08,0x09,0x01,0x07,0x01,0x08,0x07,0x67,0x00,0x02,0x05,0x01,0x02,0x57,0x06,0x0c,0x03,0x0b,0x04,0x01,0x00,0x05,0x00,0x01,0x05,0x69,0x06,0x0c,0x03,0x0b,0x04, +0x01,0x01,0x00,0x5f,0x04,0x01,0x00,0x01,0x00,0x4f,0x11,0x11,0x00,0x00,0x37,0x35,0x32,0x31,0x2d,0x2b,0x28,0x27,0x24,0x22,0x1f,0x1e,0x1b,0x19,0x11,0x14,0x11,0x14,0x13,0x12,0x00,0x10,0x00,0x0f,0x37,0x0d,0x07,0x17,0x2b,0x01,0x11,0x14,0x06,0x07,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x13,0x36,0x33,0x21,0x11,0x23,0x11, +0x01,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x22,0x26,0x27,0x11,0x33,0x32,0x17,0x25,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x05,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x89,0x16,0x0e,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x8b,0x04,0x0d,0x01,0x9f,0x8e,0x02,0x3b,0x16,0x0e,0xfe,0xe3,0x0f,0x14,0x01,0x0f, +0x14,0x01,0xed,0x0d,0x04,0xfe,0x3e,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x01,0x77,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x02,0x9f,0xfe,0x54,0x0f,0x14,0x01,0xfe,0xbf,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x01,0xe8,0x0c,0xfe,0x78,0x01,0x88,0xfe,0x0c,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x41,0x16,0x0e,0x01,0xac,0x0c,0xad,0x7d,0x7d,0x08, +0x0a,0x0a,0x08,0x7d,0x7d,0x08,0x0a,0x0a,0x00,0x08,0xff,0xff,0xff,0xf8,0x03,0xe9,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0x6f,0x40,0x6c,0x79,0x78,0x71,0x49,0x48,0x41,0x06,0x08,0x09,0x69,0x61,0x60,0x29,0x21,0x20,0x06,0x04,0x05,0x59,0x58,0x51,0x50,0x19,0x18,0x11,0x10, +0x08,0x02,0x03,0x39,0x38,0x31,0x09,0x08,0x01,0x06,0x00,0x01,0x04,0x4c,0x0d,0x01,0x05,0x0c,0x01,0x04,0x03,0x05,0x04,0x67,0x0b,0x01,0x03,0x0a,0x01,0x02,0x01,0x03,0x02,0x67,0x07,0x01,0x01,0x06,0x01,0x00,0x01,0x00,0x63,0x0e,0x01,0x08,0x08,0x09,0x5f,0x0f,0x01,0x09,0x09,0x13,0x08,0x4e,0x7d,0x7b,0x75,0x73,0x6d,0x6b,0x65,0x64, +0x5d,0x5b,0x55,0x54,0x4d,0x4c,0x26,0x26,0x17,0x26,0x17,0x17,0x17,0x17,0x14,0x10,0x07,0x1f,0x2b,0x37,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x27,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x3b, +0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x33, +0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x8f,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01, +0x0c,0x06,0x02,0xee,0x07,0x0c,0xfc,0xa6,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x76,0x6b, +0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xd0,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xfe,0x4c,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0x02,0x7d,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xfe,0x4d,0x6b,0x07,0x0c,0x01, +0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xcf,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x02,0x83,0x03,0x0b,0x00,0x07,0x00,0x1f,0x00,0x20,0x40,0x1d,0x05,0x03,0x02,0x00,0x00,0x02,0x00,0x02,0x63,0x00,0x01,0x01,0x04,0x61, +0x00,0x04,0x04,0x13,0x01,0x4e,0x23,0x13,0x25,0x36,0x13,0x10,0x06,0x07,0x1c,0x2b,0x13,0x21,0x35,0x34,0x26,0x0e,0x01,0x17,0x05,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17,0x33,0x35,0x34,0x36,0x32,0x16,0x07,0x15,0x33,0x32,0x16,0xb3,0x01,0x1d,0x54,0x76,0x54,0x01,0x01,0xd0,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01, +0x20,0x16,0x11,0x94,0xcc,0x96,0x02,0x12,0x17,0x1e,0x01,0xa5,0x6c,0x3b,0x54,0x02,0x50,0x3d,0xa1,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01,0x6c,0x66,0x94,0x94,0x66,0x6c,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x06,0x01,0x01,0x00,0x01,0x4c,0x00,0x01, 0x00,0x4a,0x05,0x01,0x01,0x49,0x00,0x00,0x01,0x01,0x00,0x57,0x00,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x11,0x11,0x02,0x07,0x18,0x2b,0x01,0x15,0x21,0x11,0x21,0x15,0x01,0x01,0x7a,0x01,0x60,0xfe,0xa0,0xfe,0x86,0x02,0xda,0xbe,0xfe,0x86,0xc0,0x01,0x7c,0x00,0x00,0x02,0xff,0xff,0xff,0xb1,0x04,0x2f,0x03,0x52,0x00,0x0f, 0x00,0x2f,0x00,0x2e,0x40,0x2b,0x09,0x01,0x02,0x01,0x00,0x20,0x01,0x03,0x02,0x02,0x4c,0x00,0x05,0x00,0x00,0x01,0x05,0x00,0x67,0x00,0x01,0x04,0x01,0x02,0x03,0x01,0x02,0x67,0x00,0x03,0x03,0x11,0x03,0x4e,0x35,0x26,0x36,0x26,0x26,0x14,0x06,0x07,0x1c,0x2b,0x01,0x11,0x34,0x26,0x27,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x33,0x21, 0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x14,0x1e,0x01,0x17,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x34,0x3e,0x01,0x35,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0xe8,0x0a,0x08,0xfc,0x83,0x07,0x0a,0x01,0x0c,0x06,0x03,0x7d,0x07,0x0c,0x46,0x34,0x25,0xfe,0xd1,0x12,0x10,0x01,0x14,0x0f,0xfe,0xe2,0x0f,0x14,0x01, 0x12,0x12,0xfe,0xd0,0x24,0x36,0x01,0x34,0x25,0x03,0x7d,0x25,0x34,0x01,0x28,0x01,0xd1,0x07,0x0a,0x01,0x0c,0x06,0xfe,0x2f,0x07,0x0a,0x0a,0x01,0xd8,0xfd,0xa1,0x25,0x34,0x01,0x14,0x2e,0x22,0x07,0x0e,0x16,0x16,0x0e,0x08,0x22,0x2c,0x15,0x36,0x24,0x02,0x5f,0x25,0x34,0x34,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xe1,0x02,0xf8, -0x02,0xdb,0x00,0x21,0x00,0x31,0x00,0x71,0xb6,0x11,0x06,0x02,0x00,0x03,0x01,0x4c,0x4b,0xb0,0x1a,0x50,0x58,0x40,0x18,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x69,0x00,0x04,0x04,0x02,0x61,0x00,0x02,0x02,0x13,0x4d,0x00,0x01,0x01,0x14,0x01,0x4e,0x1b,0x4b,0xb0,0x1d,0x50,0x58,0x40,0x16,0x00,0x02,0x00,0x04,0x03,0x02,0x04,0x69,0x00, -0x03,0x00,0x00,0x01,0x03,0x00,0x69,0x00,0x01,0x01,0x14,0x01,0x4e,0x1b,0x40,0x1d,0x00,0x01,0x00,0x01,0x86,0x00,0x02,0x00,0x04,0x03,0x02,0x04,0x69,0x00,0x03,0x00,0x00,0x03,0x59,0x00,0x03,0x03,0x00,0x61,0x00,0x00,0x03,0x00,0x51,0x59,0x59,0xb7,0x15,0x2b,0x1d,0x25,0x22,0x05,0x07,0x1b,0x2b,0x01,0x0e,0x01,0x23,0x22,0x26,0x27, -0x0f,0x01,0x06,0x23,0x22,0x26,0x35,0x34,0x3f,0x02,0x2e,0x01,0x35,0x34,0x37,0x3e,0x01,0x32,0x17,0x16,0x17,0x16,0x15,0x14,0x07,0x06,0x25,0x1e,0x01,0x33,0x32,0x3e,0x01,0x34,0x2e,0x01,0x22,0x0e,0x01,0x15,0x14,0x16,0x02,0xa8,0x29,0x66,0x36,0x31,0x5d,0x28,0x33,0x82,0x15,0x18,0x1e,0x2d,0x0f,0x81,0x7e,0x20,0x22,0x27,0x25,0x80, -0x95,0x40,0x3f,0x26,0x26,0x14,0x14,0xfe,0x99,0x19,0x40,0x21,0x2d,0x4f,0x2e,0x2f,0x4e,0x5b,0x4f,0x2f,0x1a,0x01,0x00,0x29,0x2a,0x22,0x20,0x7d,0x82,0x0f,0x2f,0x1e,0x1a,0x13,0x82,0x33,0x26,0x5e,0x32,0x4b,0x40,0x3f,0x4b,0x27,0x25,0x3f,0x41,0x4a,0x38,0x32,0x34,0x24,0x18,0x1a,0x2e,0x4f,0x5d,0x4e,0x2e,0x2f,0x4e,0x2d,0x22,0x40, -0x00,0x02,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x19,0x00,0x47,0x4b,0xb0,0x26,0x50,0x58,0x40,0x16,0x04,0x01,0x00,0x00,0x03,0x61,0x00,0x03,0x03,0x10,0x4d,0x00,0x01,0x01,0x02,0x61,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x14,0x00,0x03,0x04,0x01,0x00,0x01,0x03,0x00,0x69,0x00,0x01,0x01,0x02,0x61,0x00,0x02, -0x02,0x11,0x02,0x4e,0x59,0x40,0x0f,0x01,0x00,0x17,0x16,0x11,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x05,0x07,0x16,0x2b,0x01,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e,0x01,0x2e,0x02,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x01,0xad,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6, -0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x02,0x8e,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x4d,0x02,0xff,0x00,0x06,0x00,0x14,0x00,0x19,0x00,0x24,0x00,0xaa,0x40,0x17,0x1e,0x01,0x02,0x05,0x1d,0x16, -0x0e,0x07,0x04,0x03,0x02,0x19,0x03,0x02,0x03,0x00,0x03,0x01,0x01,0x01,0x00,0x04,0x4c,0x4b,0xb0,0x09,0x50,0x58,0x40,0x23,0x00,0x05,0x02,0x05,0x85,0x00,0x02,0x03,0x02,0x85,0x00,0x03,0x00,0x00,0x03,0x70,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x4b,0xb0,0x12,0x50, -0x58,0x40,0x22,0x00,0x05,0x02,0x05,0x85,0x00,0x02,0x03,0x02,0x85,0x00,0x03,0x00,0x03,0x85,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x40,0x23,0x00,0x05,0x02,0x05,0x85,0x00,0x02,0x03,0x02,0x85,0x00,0x03,0x00,0x03,0x85,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x04,0x80, -0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x59,0x59,0x40,0x12,0x00,0x00,0x21,0x20,0x18,0x17,0x10,0x0f,0x09,0x08,0x00,0x06,0x00,0x06,0x14,0x07,0x07,0x17,0x2b,0x17,0x37,0x27,0x07,0x15,0x33,0x15,0x01,0x34,0x23,0x22,0x07,0x01,0x06,0x15,0x14,0x33,0x32,0x37,0x01,0x36,0x27,0x17,0x01,0x23,0x35,0x01,0x14,0x0f,0x01, -0x27,0x37,0x36,0x32,0x1f,0x01,0x16,0xcb,0x32,0x83,0x33,0x48,0x01,0x5f,0x0c,0x05,0x04,0xfe,0xd1,0x04,0x0d,0x05,0x04,0x01,0x2f,0x03,0x1e,0xe8,0xfe,0x30,0xe8,0x03,0x4d,0x14,0x5d,0xe8,0x5d,0x14,0x3b,0x16,0x83,0x14,0x07,0x33,0x83,0x33,0x3c,0x47,0x02,0x06,0x0c,0x04,0xfe,0xd2,0x04,0x06,0x0c,0x04,0x01,0x2e,0x04,0x71,0xe8,0xfe, -0x2f,0xe9,0x01,0x9a,0x1d,0x15,0x5d,0xe9,0x5c,0x15,0x15,0x83,0x16,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x01,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x01,0x4a,0x02,0x01,0x00,0x49,0x00,0x01,0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x11,0x13, -0x02,0x07,0x18,0x2b,0x09,0x02,0x35,0x21,0x11,0x21,0x01,0x5e,0x01,0x7c,0xfe,0x84,0xfe,0xa2,0x01,0x5e,0x02,0xda,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x7a,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xab,0x03,0x6b,0x03,0x20,0x00,0x0f,0x00,0x13,0x00,0x1f,0x00,0x38,0x40,0x35,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x0b, -0x03,0x02,0x01,0x4c,0x00,0x02,0x02,0x00,0x5f,0x04,0x01,0x00,0x00,0x10,0x4d,0x00,0x03,0x03,0x01,0x5f,0x00,0x01,0x01,0x11,0x01,0x4e,0x01,0x00,0x13,0x12,0x11,0x10,0x09,0x06,0x00,0x0f,0x01,0x0e,0x05,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x07, -0x17,0x07,0x17,0x37,0x17,0x37,0x27,0x37,0x27,0x07,0x87,0x0c,0x11,0x11,0x0c,0x02,0xc6,0x0c,0x11,0x11,0x0c,0xfd,0x58,0x02,0x8b,0xfd,0x75,0x01,0x87,0x2d,0x52,0x52,0x2d,0x53,0x52,0x2e,0x53,0x53,0x2e,0x52,0x03,0x1f,0x12,0x0c,0xfc,0xc8,0x0c,0x11,0x11,0x0c,0x03,0x38,0x0c,0x12,0x3b,0xfd,0x02,0x02,0xcb,0x2e,0x52,0x53,0x2d,0x52, -0x52,0x2d,0x53,0x52,0x2e,0x52,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x84,0x03,0x8f,0x03,0x33,0x00,0x02,0x00,0x10,0x00,0x3c,0x00,0x68,0x00,0xf2,0x40,0x0b,0x01,0x01,0x0a,0x02,0x62,0x36,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x32,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x03,0x00,0x0a,0x03,0x57,0x0e,0x05,0x02,0x02, -0x0f,0x01,0x0a,0x06,0x02,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x04,0x11,0x02,0x00,0x00,0x13,0x00,0x4e,0x1b,0x4b,0xb0,0x16,0x50,0x58,0x40,0x36,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x03,0x04,0x0a,0x03,0x57,0x0e,0x05,0x02,0x02,0x0f,0x01,0x0a,0x06,0x02,0x0a, -0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x00,0x04,0x04,0x13,0x4d,0x11,0x01,0x00,0x00,0x13,0x00,0x4e,0x1b,0x40,0x39,0x12,0x01,0x01,0x03,0x01,0x85,0x11,0x01,0x00,0x04,0x02,0x04,0x00,0x02,0x80,0x00,0x03,0x04,0x0a,0x03,0x57,0x0e,0x05,0x02,0x02,0x0f,0x01,0x0a,0x06, -0x02,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x00,0x04,0x04,0x13,0x04,0x4e,0x59,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x68,0x66,0x5e,0x5c,0x5b,0x59,0x4d,0x4b,0x4a,0x48,0x3f,0x3d,0x3c,0x3a,0x32,0x30,0x2f,0x2d,0x21,0x1f,0x1e,0x1c,0x13,0x11,0x0c,0x0b,0x0a,0x09, -0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27,0x25,0x22,0x06,0x1d,0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x13,0x33,0x32,0x16,0x1d,0x01,0x14,0x16,0x17,0x16,0x17,0x16,0x3b,0x01,0x15,0x23,0x22,0x07,0x06,0x07,0x06,0x07,0x06,0x1d,0x01,0x14,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32, -0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x36,0x37,0x36,0x37,0x36,0x3d,0x01,0x34,0x37,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0x90,0x63,0x64,0xfe,0xcd,0x0d,0x13,0x3f,0x01,0x58, -0x3f,0x12,0x0d,0x55,0x1b,0x47,0x45,0x07,0x0b,0x09,0x12,0x0e,0x1c,0x0f,0x0f,0x1a,0x12,0x0f,0x0c,0x08,0x05,0x03,0x0f,0x22,0x34,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10,0x1c,0x20,0x0a,0x08,0x05,0x04,0x07,0x07,0x23,0x33,0x27,0x1b,0x15,0x55,0x4e,0x4e,0x55,0x15,0x02, -0xb1,0xac,0xac,0x82,0x12,0x0d,0xe7,0xc7,0x2e,0x4e,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x09,0x0a,0x05,0x05,0x33,0x05,0x03,0x0a,0x08,0x0f,0x0d,0x14,0x80,0x1d,0x33,0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54,0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09,0x0b,0x33,0x08,0x09,0x08,0x0f,0x14,0x0d,0x57, -0x21,0x16,0x19,0x24,0x12,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x17,0x40,0x14,0x06,0x01,0x00,0x4a,0x02,0x01,0x00,0x01,0x00,0x85,0x00,0x01,0x01,0x76,0x11,0x11,0x10,0x03,0x07,0x19,0x2b,0x01,0x23,0x11,0x21,0x11,0x23,0x01,0x02,0xf8,0xc0,0xfe, -0x88,0xc0,0x01,0x7c,0x01,0x50,0xfe,0xa2,0x01,0x5e,0x01,0x7c,0x00,0x01,0x00,0x00,0x00,0x00,0x03,0xa5,0x02,0x98,0x00,0x15,0x00,0x1d,0x40,0x1a,0x0f,0x01,0x00,0x01,0x01,0x4c,0x00,0x02,0x01,0x02,0x85,0x00,0x01,0x00,0x01,0x85,0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x26, -0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x03,0xa5,0x10,0xfe,0x20,0x10,0x2c,0x10,0xfe,0xea,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0x01,0x6e,0x10,0x2c,0x10,0x4c,0x10,0x02,0x16,0x16,0x10,0xfe,0x20,0x0f,0x0f,0x01,0x16,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa5,0x01,0x6f,0x10,0x10,0x4c,0x0f,0x00,0x03,0xff,0xf5, -0xff,0xb1,0x03,0xf3,0x03,0x52,0x00,0x0f,0x00,0x21,0x00,0x33,0x00,0x33,0x40,0x30,0x1b,0x11,0x02,0x03,0x02,0x09,0x01,0x02,0x01,0x00,0x02,0x4c,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x01,0x01,0x04,0x5f,0x00,0x04,0x04,0x11,0x04,0x4e,0x17,0x38,0x27,0x27,0x26,0x23,0x06,0x07,0x1c, -0x2b,0x25,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x1d,0x01,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34,0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x17,0x14,0x16,0x37,0x33,0x32,0x36,0x03,0x01,0x16,0x07,0x0e,0x01,0x07,0x21,0x22,0x26,0x27,0x26,0x37,0x01,0x3e,0x01,0x32,0x16,0x02,0x3b,0x0a,0x07,0x6c,0x07,0x0a,0x0a,0x07,0x6c,0x07, -0x0a,0x01,0x0a,0x05,0x07,0x07,0x7a,0x06,0x08,0x05,0x09,0x0c,0x07,0x67,0x08,0x0c,0x08,0x01,0xac,0x14,0x15,0x09,0x22,0x12,0xfc,0xa6,0x12,0x22,0x09,0x15,0x14,0x01,0xad,0x09,0x22,0x26,0x22,0x53,0x6a,0x08,0x0a,0x0a,0x08,0x6a,0x08,0x0a,0x01,0x0c,0xd7,0x01,0x01,0x06,0x04,0x06,0x06,0x04,0x08,0xff,0x05,0x08,0x01,0x06,0x02,0x10, -0xfc,0xee,0x23,0x23,0x11,0x12,0x01,0x14,0x10,0x23,0x23,0x03,0x12,0x11,0x14,0x14,0x00,0x04,0x00,0x00,0xff,0x79,0x03,0xd1,0x03,0x3c,0x00,0x0f,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x36,0x40,0x33,0x07,0x01,0x05,0x03,0x01,0x01,0x05,0x01,0x63,0x06,0x01,0x04,0x04,0x00,0x5f,0x09,0x02,0x08,0x03,0x00,0x00,0x12,0x04,0x4e,0x11,0x10, -0x01,0x00,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x19,0x16,0x10,0x1f,0x11,0x1e,0x09,0x06,0x00,0x0f,0x01,0x0e,0x0a,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x33,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x21, -0x11,0x21,0x38,0x0d,0x13,0x13,0x0d,0x01,0x7c,0x0d,0x12,0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0x01,0x7d,0x0d,0x12,0x12,0x0d,0xfc,0xa6,0x01,0x3e,0xfe,0xc2,0x01,0xfc,0x01,0x3e,0xfe,0xc2,0x03,0x3b,0x12,0x0d,0xfc,0x7d,0x0d,0x12,0x12,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d,0x12,0x12,0x0d,0x03,0x83,0x0d,0x12,0x3e,0xfc, -0xbb,0x03,0x45,0xfc,0xbb,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x7e,0x03,0xd6,0x03,0x37,0x00,0x0f,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x3d,0x40,0x3a,0x00,0x04,0x00,0x01,0x02,0x04,0x01,0x67,0x00,0x02,0x09,0x01,0x07,0x06,0x02,0x07,0x67,0x00,0x06,0x00,0x03,0x06,0x03,0x63,0x08,0x01,0x05,0x05,0x00,0x5f,0x00,0x00,0x00,0x12, -0x05,0x4e,0x24,0x24,0x20,0x20,0x24,0x27,0x24,0x27,0x26,0x25,0x20,0x23,0x20,0x23,0x14,0x35,0x35,0x35,0x32,0x0a,0x07,0x1b,0x2b,0x01,0x34,0x26,0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x15,0x34,0x26,0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x03,0x11,0x21,0x11,0x01,0x11,0x21, -0x11,0x03,0xd5,0x12,0x0d,0xfc,0x7d,0x0d,0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d,0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x3f,0xfc,0xbc,0x03,0x44,0xfc,0xbc,0x03,0x17,0x0d,0x12,0x12,0x0d,0xfe,0x84,0x0d,0x12,0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0xfe,0x83,0x0d,0x12,0x12,0x0d,0x03,0x5a,0xfe,0xc2,0x01,0x3e,0xfe, -0x04,0xfe,0xc1,0x01,0x3f,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x89,0x03,0xdc,0x03,0x38,0x00,0x02,0x00,0x10,0x00,0x39,0x00,0x62,0x00,0xcc,0x40,0x0b,0x01,0x01,0x06,0x0a,0x5c,0x33,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x21,0x50,0x58,0x40,0x3f,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x02,0x80, -0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f,0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x1b,0x40,0x45,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80, -0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f,0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x62,0x60, -0x58,0x56,0x55,0x53,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x1f,0x1d,0x1c,0x1a,0x13,0x11,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27,0x25,0x22,0x06,0x1d,0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x01,0x33,0x32,0x16,0x1d,0x01,0x14, -0x1e,0x02,0x3b,0x01,0x15,0x23,0x22,0x07,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x3e,0x02,0x3d,0x01,0x34,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07, -0x16,0x1d,0x01,0x14,0x3b,0x01,0x03,0xdc,0x63,0x64,0xfd,0x31,0x0d,0x13,0x3f,0x02,0xf4,0x3f,0x12,0x0d,0xfe,0xb9,0x1b,0x47,0x45,0x07,0x16,0x22,0x18,0x10,0x10,0x16,0x16,0x10,0x14,0x07,0x08,0x06,0x21,0x38,0x25,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10,0x1c,0x1f,0x15,0x07, -0x0f,0x21,0x34,0x27,0x1b,0x15,0x55,0x4d,0x4e,0x54,0x15,0x02,0x85,0xad,0xad,0xb3,0x12,0x0d,0xe7,0xc7,0x6d,0x8d,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x13,0x0a,0x33,0x04,0x04,0x12,0x1c,0x14,0x80,0x1d,0x1a,0x19,0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54,0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09, -0x0b,0x33,0x08,0x13,0x1a,0x14,0x57,0x20,0x30,0x23,0x13,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x43,0x00,0x7b,0x40,0x0f,0x18,0x01,0x03,0x04,0x13,0x01,0x02,0x00,0x03,0x06,0x01,0x01,0x00,0x03,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x24,0x05,0x01, -0x03,0x02,0x01,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x00,0x01,0x07,0x04,0x01,0x69,0x00,0x07,0x00,0x08,0x07,0x08,0x63,0x00,0x06,0x06,0x09,0x5f,0x00,0x09,0x09,0x10,0x06,0x4e,0x1b,0x40,0x2a,0x00,0x09,0x00,0x06,0x04,0x09,0x06,0x67,0x05,0x01,0x03,0x02,0x01,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x00,0x01,0x07,0x04,0x01,0x69,0x00, -0x07,0x08,0x08,0x07,0x57,0x00,0x07,0x07,0x08,0x5f,0x00,0x08,0x07,0x08,0x4f,0x59,0x40,0x0e,0x42,0x3f,0x35,0x35,0x36,0x14,0x23,0x26,0x14,0x23,0x23,0x0a,0x07,0x1f,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x35,0x34,0x36,0x3b,0x01,0x32,0x16, -0x1d,0x01,0x33,0x32,0x16,0x13,0x11,0x34,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x47,0x34,0x25, -0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x07,0x0a,0xc5,0x08,0x0a,0x0a,0x08,0xc5,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe, -0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x59,0xb6,0x09,0x01,0x02,0x00,0x01,0x01,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x1a,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x67,0x00,0x03,0x00,0x04,0x03,0x04,0x63,0x00,0x02,0x02,0x05, -0x5f,0x00,0x05,0x05,0x10,0x02,0x4e,0x1b,0x40,0x20,0x00,0x05,0x00,0x02,0x01,0x05,0x02,0x67,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x67,0x00,0x03,0x04,0x04,0x03,0x57,0x00,0x03,0x03,0x04,0x5f,0x00,0x04,0x03,0x04,0x4f,0x59,0x40,0x09,0x35,0x35,0x35,0x36,0x26,0x23,0x06,0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x3d, -0x01,0x34,0x36,0x33,0x21,0x32,0x16,0x13,0x11,0x34,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xfe,0x30,0x08,0x0a,0x0a,0x08,0x01,0xd0,0x08,0x0a,0x47,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01, -0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58, -0x01,0xd4,0x00,0x15,0x00,0x21,0xb1,0x06,0x64,0x44,0x40,0x16,0x07,0x01,0x00,0x02,0x01,0x4c,0x00,0x02,0x00,0x02,0x85,0x01,0x01,0x00,0x00,0x76,0x17,0x14,0x14,0x03,0x07,0x19,0x2b,0xb1,0x06,0x00,0x44,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01,0x26,0x34,0x37,0x01,0x36,0x32,0x17,0x01,0x16,0x02,0x58,0x06, -0x1c,0x05,0x0e,0x06,0xdc,0xdb,0x05,0x10,0x04,0x1c,0x06,0x06,0x01,0x04,0x05,0x0e,0x06,0x01,0x04,0x06,0xbd,0x07,0x05,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0xfe,0xfc,0x05,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0x89,0x03,0x42,0x03,0x33,0x00,0x0f,0x00,0x19,0x00,0x33,0x00,0x3f,0x00,0x4b, -0x00,0x57,0x00,0x8c,0x40,0x89,0x56,0x01,0x0c,0x0d,0x44,0x01,0x0a,0x0b,0x3e,0x01,0x08,0x09,0x03,0x4c,0x00,0x02,0x03,0x05,0x03,0x02,0x05,0x80,0x00,0x05,0x0d,0x03,0x05,0x0d,0x7e,0x00,0x0b,0x0c,0x0a,0x0c,0x0b,0x0a,0x80,0x00,0x0a,0x09,0x0c,0x0a,0x09,0x7e,0x00,0x09,0x08,0x0c,0x09,0x08,0x7e,0x10,0x01,0x08,0x07,0x0c,0x08,0x07, -0x7e,0x00,0x0d,0x11,0x01,0x0c,0x0b,0x0d,0x0c,0x67,0x00,0x07,0x00,0x01,0x07,0x01,0x64,0x06,0x04,0x0f,0x03,0x03,0x03,0x00,0x5f,0x0e,0x01,0x00,0x00,0x12,0x03,0x4e,0x4e,0x4c,0x36,0x34,0x10,0x10,0x01,0x00,0x54,0x52,0x4c,0x57,0x4e,0x57,0x48,0x45,0x42,0x40,0x3c,0x3a,0x34,0x3f,0x36,0x3f,0x32,0x2f,0x2a,0x28,0x25,0x22,0x1f,0x1d, -0x10,0x19,0x10,0x19,0x16,0x13,0x09,0x06,0x00,0x0f,0x01,0x0e,0x12,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x17,0x15,0x14,0x16,0x3b,0x01,0x32,0x36,0x3d,0x01,0x13,0x11,0x34,0x26,0x07,0x23,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x37,0x35,0x23,0x22,0x06,0x17,0x11,0x14,0x16, -0x33,0x21,0x32,0x36,0x27,0x21,0x22,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x07,0x14,0x27,0x21,0x22,0x26,0x37,0x34,0x33,0x21,0x32,0x15,0x14,0x06,0x27,0x21,0x22,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x07,0x14,0x02,0xa6,0x41,0x5a,0x01,0x5c,0x40,0xfd,0xf6,0x41,0x5a,0x01,0x5c,0x40,0x68,0x20,0x15,0xd0,0x16,0x1e,0x9c,0x1e,0x15,0x35, -0x3c,0x2c,0xd0,0x2b,0x3e,0x01,0x35,0x15,0x20,0x01,0x1e,0x16,0x02,0x0a,0x15,0x1e,0x68,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x1a,0xfe,0x60,0x0b,0x10,0x01,0x1a,0x01,0xa0,0x1a,0x0e,0x0c,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x03,0x33,0x5c,0x40,0xfd,0x8f,0x41,0x5c,0x5c,0x41,0x02,0x71,0x41,0x5a,0x01, -0x68,0x34,0x15,0x20,0x20,0x15,0x34,0xfd,0x5b,0x02,0x71,0x15,0x20,0x01,0x34,0x2b,0x3c,0x01,0x3e,0x2a,0x34,0x1e,0x16,0xfd,0x8f,0x15,0x20,0x20,0x49,0x19,0x0c,0x0e,0x01,0x10,0x0b,0x19,0x9d,0x0e,0x0c,0x19,0x19,0x0b,0x10,0x9d,0x19,0x0b,0x10,0x01,0x0e,0x0c,0x19,0x00,0x00,0x03,0x00,0x00,0xff,0xf9,0x04,0x29,0x03,0x0b,0x00,0x11, -0x00,0x27,0x00,0x45,0x00,0x88,0xb5,0x24,0x01,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x2b,0x00,0x07,0x04,0x03,0x04,0x07,0x03,0x80,0x00,0x03,0x02,0x04,0x03,0x02,0x7e,0x08,0x09,0x02,0x02,0x00,0x00,0x01,0x02,0x00,0x68,0x00,0x01,0x00,0x05,0x01,0x05,0x63,0x00,0x04,0x04,0x06,0x5f,0x00,0x06,0x06,0x10,0x04,0x4e,0x1b, -0x40,0x31,0x00,0x07,0x04,0x03,0x04,0x07,0x03,0x80,0x00,0x03,0x02,0x04,0x03,0x02,0x7e,0x00,0x06,0x00,0x04,0x07,0x06,0x04,0x67,0x08,0x09,0x02,0x02,0x00,0x00,0x01,0x02,0x00,0x68,0x00,0x01,0x05,0x05,0x01,0x57,0x00,0x01,0x01,0x05,0x5f,0x00,0x05,0x01,0x05,0x4f,0x59,0x40,0x17,0x13,0x12,0x42,0x40,0x3d,0x3b,0x38,0x35,0x30,0x2d, -0x21,0x1e,0x19,0x16,0x12,0x27,0x13,0x27,0x36,0x31,0x0a,0x07,0x18,0x2b,0x01,0x34,0x23,0x21,0x22,0x06,0x0f,0x01,0x06,0x15,0x14,0x33,0x21,0x32,0x36,0x3f,0x01,0x36,0x25,0x21,0x35,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x26,0x07,0x23,0x22,0x06,0x15,0x11,0x37,0x3e,0x01,0x05,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x26, -0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x17,0x15,0x33,0x32,0x16,0x17,0x16,0x03,0xe2,0x1e,0xfd,0xa1,0x16,0x34,0x0d,0xa4,0x0b,0x1e,0x02,0x5f,0x17,0x32,0x0f,0xa4,0x0a,0xfd,0x83,0x01,0xad,0x20,0x16,0xfe,0xbf,0x17,0x1e,0x01,0x1e,0x17,0xb3,0x16,0x20,0x8f,0x19,0x50,0x02,0xea,0x19,0xa5,0x18,0x52,0x25, -0xfd,0xa1,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x2f,0x34,0x48,0x01,0x6b,0x1e,0x34,0x0b,0x08,0x01,0x4b,0x13,0x18,0x11,0xcb,0x0d,0x09,0x14,0x1a,0x10,0xcb,0x0c,0x64,0x5a,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfe,0x24,0xaf,0x1e,0x26,0x5a,0x23,0x20,0xcb,0x1e,0x26,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33, -0x12,0x4a,0x33,0x5a,0x1a,0x1b,0x11,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xdc,0x01,0xcc,0x00,0x08,0x00,0x20,0x40,0x1d,0x02,0x01,0x00,0x01,0x01,0x00,0x59,0x02,0x01,0x00,0x00,0x01,0x61,0x00,0x01,0x00,0x01,0x51,0x01,0x00,0x05,0x04,0x00,0x08,0x01,0x08,0x03,0x07,0x16,0x2b,0x13,0x32,0x16,0x14,0x06,0x22,0x26,0x34,0x36,0x6e, -0x2e,0x40,0x40,0x5c,0x40,0x40,0x01,0xcc,0x40,0x5a,0x42,0x42,0x5a,0x40,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb8,0x03,0x94,0x03,0x1f,0x00,0x02,0x00,0x10,0x00,0x39,0x00,0x66,0x01,0x0d,0x40,0x0b,0x60,0x33,0x02,0x07,0x06,0x01,0x01,0x02,0x07,0x02,0x4c,0x4b,0xb0,0x13,0x50,0x58,0x40,0x38,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80, -0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x08,0x12,0x04,0x11,0x05,0x00,0x01,0x09,0x00,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x4b,0xb0,0x1a,0x50,0x58,0x40,0x3f,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80, -0x12,0x04,0x11,0x03,0x00,0x08,0x01,0x08,0x00,0x01,0x80,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01,0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x40,0x45,0x00,0x02,0x07,0x09,0x07,0x02, -0x09,0x80,0x11,0x01,0x00,0x08,0x04,0x08,0x00,0x04,0x80,0x12,0x01,0x04,0x01,0x08,0x04,0x01,0x7e,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01,0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x59, -0x59,0x40,0x2d,0x03,0x03,0x00,0x00,0x66,0x64,0x5c,0x5a,0x59,0x57,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x20,0x1e,0x1d,0x1b,0x13,0x11,0x03,0x10,0x03,0x10,0x0d,0x0a,0x07,0x06,0x05,0x04,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x25,0x37,0x17,0x07,0x15,0x21,0x35,0x23,0x15,0x14,0x16,0x33,0x21,0x32,0x36, -0x3d,0x01,0x01,0x33,0x32,0x16,0x1d,0x01,0x14,0x17,0x1e,0x02,0x3b,0x01,0x15,0x23,0x22,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x3e,0x01,0x37,0x36,0x3d,0x01,0x34, -0x37,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0xcd,0x64,0x63,0x82,0xfe,0xa7,0x3e,0x12,0x0d,0x01,0x97,0x0d,0x13,0xfe,0xa0,0x1c,0x47,0x44,0x04,0x05,0x11,0x25,0x18,0x10,0x10,0x1c,0x20,0x14,0x07,0x07,0x07,0x22,0x35,0x26,0x1c,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa7, -0x1b,0x48,0x44,0x04,0x05,0x09,0x0a,0x23,0x18,0x0f,0x0f,0x1d,0x20,0x13,0x03,0x04,0x07,0x08,0x10,0x10,0x1b,0x1b,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0x6a,0xac,0xac,0x09,0x6a,0xb3,0xd3,0x0d,0x12,0x12,0x0d,0x8a,0x02,0xbe,0x42,0x44,0x54,0x14,0x0c,0x10,0x10,0x0c,0x33,0x08,0x14,0x19,0x15,0x80,0x21,0x16,0x19,0x23,0x12,0x33, -0x52,0x7f,0x59,0x0b,0x09,0x5c,0x54,0x54,0xfd,0x8b,0x42,0x43,0x7e,0x14,0x0c,0x10,0x08,0x0b,0x09,0x33,0x09,0x12,0x0e,0x0c,0x15,0x56,0x1a,0x1e,0x18,0x12,0x10,0x0b,0x09,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x03,0xff,0xfe,0x00,0x00,0x03,0xe8,0x02,0x60,0x00,0x20,0x00,0x24,0x00,0x28,0x00,0x36,0x40,0x33, -0x00,0x00,0x08,0x06,0x07,0x03,0x04,0x03,0x00,0x04,0x67,0x05,0x01,0x03,0x01,0x01,0x03,0x57,0x05,0x01,0x03,0x03,0x01,0x5f,0x02,0x01,0x01,0x03,0x01,0x4f,0x25,0x25,0x21,0x21,0x25,0x28,0x25,0x28,0x27,0x26,0x21,0x24,0x21,0x24,0x14,0x27,0x2a,0x18,0x09,0x07,0x1a,0x2b,0x11,0x26,0x37,0x25,0x36,0x17,0x16,0x0f,0x01,0x21,0x27,0x26, -0x37,0x36,0x17,0x05,0x16,0x07,0x03,0x06,0x23,0x21,0x26,0x2f,0x01,0x26,0x0f,0x01,0x06,0x23,0x21,0x26,0x27,0x37,0x17,0x21,0x37,0x33,0x17,0x21,0x37,0x02,0x0a,0x01,0x68,0x1d,0x0c,0x0b,0x19,0xe3,0x02,0x92,0xe4,0x19,0x0b,0x0e,0x1d,0x01,0x6a,0x0b,0x02,0x1b,0x08,0x19,0xfe,0xc7,0x19,0x06,0x31,0x27,0x35,0x32,0x06,0x1a,0xfe,0xc8, -0x1b,0x04,0x27,0x13,0x01,0x04,0x2b,0xdd,0x29,0x01,0x03,0x14,0x01,0x82,0x0d,0x0c,0xba,0x0b,0x1b,0x21,0x0c,0x68,0x68,0x10,0x1d,0x1b,0x0b,0xba,0x0c,0x0d,0xff,0x00,0x1e,0x02,0x18,0xdf,0x19,0x18,0xe0,0x1a,0x02,0x1c,0xe2,0xbd,0xbd,0xbd,0xbd,0x00,0x00,0x03,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x13,0x00,0x1a,0x00,0x23, -0x00,0x39,0x40,0x36,0x14,0x01,0x02,0x04,0x01,0x4c,0x00,0x01,0x00,0x04,0x02,0x01,0x04,0x67,0x00,0x02,0x00,0x03,0x05,0x02,0x03,0x67,0x06,0x01,0x05,0x00,0x00,0x05,0x57,0x06,0x01,0x05,0x05,0x00,0x5f,0x00,0x00,0x05,0x00,0x4f,0x1b,0x1b,0x1b,0x23,0x1b,0x23,0x13,0x26,0x14,0x35,0x36,0x07,0x07,0x1b,0x2b,0x01,0x1e,0x01,0x15,0x11, -0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x17,0x07,0x15,0x33,0x26,0x2f,0x01,0x26,0x13,0x11,0x23,0x22,0x26,0x27,0x35,0x21,0x11,0x03,0x33,0x10,0x16,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xf4,0x16,0x36,0x0f,0x4a,0xd2,0x05,0x07,0xaf,0x06,0xc6,0xe8,0x17,0x1e,0x01,0xfe,0x53,0x02,0x7e, -0x10,0x34,0x18,0xfd,0x7e,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c,0x17,0x1e,0x01,0x16,0x10,0x26,0xd2,0x11,0x06,0xaf,0x07,0xfc,0xb0,0x02,0x3c,0x20,0x15,0xe9,0xfc,0xa6,0x00,0x01,0x00,0x00,0xff,0xaa,0x03,0x11,0x03,0x13,0x00,0x0b,0x00,0x06,0xb3,0x07,0x02,0x01,0x32,0x2b,0x09,0x01,0x06,0x26,0x35,0x11,0x34,0x36,0x17,0x01,0x16,0x14, -0x03,0x04,0xfd,0x1b,0x0d,0x12,0x12,0x0d,0x02,0xe5,0x0d,0x01,0x4d,0xfe,0x64,0x07,0x0a,0x0f,0x03,0x36,0x0e,0x0c,0x08,0xfe,0x64,0x07,0x14,0x00,0x00,0x01,0xff,0xff,0xff,0xae,0x02,0x3c,0x03,0x0f,0x00,0x1d,0x00,0x31,0xb7,0x1b,0x1a,0x12,0x03,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x0b,0x00,0x00,0x00,0x10,0x4d,0x00, -0x01,0x01,0x11,0x01,0x4e,0x1b,0x40,0x0b,0x00,0x00,0x00,0x01,0x5f,0x00,0x01,0x01,0x11,0x01,0x4e,0x59,0xb4,0x35,0x3d,0x02,0x07,0x18,0x2b,0x17,0x06,0x26,0x37,0x11,0x34,0x36,0x17,0x01,0x16,0x17,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x07,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x11,0x06,0x07,0x19,0x0a,0x10,0x01,0x0e,0x0b,0x01, -0x8c,0x05,0x03,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x03,0x05,0x47,0x0b,0x06,0x0f,0x03,0x36,0x0e,0x08,0x0c,0xfe,0x74,0x05,0x05,0x01,0x7a,0x0e,0x16,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x01,0x7b,0x06,0x05,0x00,0x00,0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08,0x00,0x13,0x00,0x29, -0x00,0xa7,0x40,0x0d,0x0c,0x01,0x03,0x02,0x23,0x22,0x18,0x17,0x04,0x05,0x07,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x32,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02,0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00,0x05,0x04,0x02,0x05,0x04,0x7e,0x0a,0x01,0x04,0x00,0x01,0x04,0x01,0x66,0x09,0x01,0x02, -0x02,0x00,0x61,0x08,0x01,0x00,0x00,0x12,0x02,0x4e,0x1b,0x40,0x39,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02,0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00,0x05,0x04,0x02,0x05,0x04,0x7e,0x08,0x01,0x00,0x09,0x01,0x02,0x03,0x00,0x02,0x69,0x0a,0x01,0x04,0x01,0x01,0x04,0x59,0x0a,0x01,0x04,0x04,0x01, -0x62,0x00,0x01,0x04,0x01,0x52,0x59,0x40,0x1f,0x15,0x14,0x0a,0x09,0x01,0x00,0x26,0x24,0x20,0x1e,0x1b,0x19,0x14,0x29,0x15,0x29,0x10,0x0e,0x09,0x13,0x0a,0x13,0x05,0x04,0x00,0x08,0x01,0x08,0x0b,0x07,0x16,0x2b,0x01,0x36,0x00,0x12,0x00,0x04,0x00,0x02,0x00,0x17,0x22,0x06,0x15,0x06,0x16,0x33,0x32,0x36,0x35,0x34,0x03,0x32,0x36, -0x37,0x27,0x06,0x23,0x22,0x3f,0x01,0x36,0x23,0x22,0x06,0x07,0x17,0x36,0x33,0x32,0x0f,0x01,0x06,0x01,0xc6,0xbe,0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xf2,0x2a,0x2e,0x02,0x22,0x20,0x26,0x2e,0xb4,0x1e,0x6c,0x34,0x12,0x30,0x18,0x0e,0x0a,0x2a,0x1a,0x30,0x1e,0x76,0x38,0x10,0x34,0x16,0x0c,0x0c,0x24,0x1a, -0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0x96,0x30,0x1a,0x1c,0x20,0x2c,0x20,0x3a,0xfd,0xae,0x34,0x34,0x18,0x24,0x26,0xa0,0x60,0x3a,0x2e,0x1a,0x22,0x22,0x98,0x68,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x31,0x00,0x6a,0x40,0x0b,0x2a,0x01,0x03,0x05,0x25,0x1d,0x02,0x04, -0x03,0x02,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x24,0x00,0x04,0x03,0x01,0x03,0x04,0x01,0x80,0x00,0x01,0x02,0x03,0x01,0x02,0x7e,0x00,0x03,0x03,0x05,0x61,0x00,0x05,0x05,0x10,0x4d,0x00,0x02,0x02,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x22,0x00,0x04,0x03,0x01,0x03,0x04,0x01,0x80,0x00,0x01,0x02,0x03,0x01,0x02,0x7e, -0x00,0x05,0x00,0x03,0x04,0x05,0x03,0x69,0x00,0x02,0x02,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x59,0x40,0x09,0x29,0x35,0x17,0x23,0x17,0x24,0x06,0x07,0x1c,0x2b,0x01,0x14,0x0e,0x02,0x23,0x22,0x26,0x27,0x26,0x34,0x3f,0x01,0x36,0x16,0x17,0x1e,0x01,0x33,0x32,0x3e,0x03,0x2e,0x02,0x22,0x06,0x07,0x17,0x16,0x06,0x2b,0x01,0x22, -0x26,0x27,0x35,0x34,0x36,0x1f,0x01,0x3e,0x01,0x33,0x32,0x1e,0x02,0x03,0x59,0x44,0x72,0xa0,0x56,0x60,0xae,0x3c,0x04,0x05,0x4c,0x06,0x11,0x04,0x29,0x76,0x43,0x3a,0x68,0x50,0x2a,0x02,0x2e,0x4c,0x6c,0x6f,0x64,0x28,0x4d,0x11,0x13,0x17,0xfa,0x0f,0x14,0x01,0x2c,0x11,0x48,0x3c,0x9a,0x52,0x57,0x9e,0x74,0x42,0x01,0x5e,0x57,0x9e, -0x74,0x44,0x52,0x49,0x06,0x0e,0x04,0x4d,0x05,0x01,0x06,0x35,0x3a,0x2e,0x4c,0x6a,0x74,0x6a,0x4c,0x2e,0x28,0x25,0x4d,0x10,0x2d,0x16,0x0e,0xfa,0x18,0x13,0x12,0x48,0x39,0x3e,0x44,0x74,0x9e,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf9,0x02,0x83,0x03,0x53,0x00,0x23,0x00,0x3a,0x40,0x37,0x00,0x04,0x05,0x00,0x05,0x04,0x00,0x80, -0x00,0x03,0x00,0x05,0x04,0x03,0x05,0x69,0x02,0x06,0x02,0x00,0x01,0x01,0x00,0x59,0x02,0x06,0x02,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x01,0x00,0x20,0x1f,0x1b,0x18,0x14,0x13,0x10,0x0e,0x09,0x06,0x00,0x23,0x01,0x23,0x07,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17, -0x33,0x35,0x34,0x36,0x1e,0x01,0x07,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x34,0x26,0x22,0x06,0x17,0x15,0x02,0x4d,0x17,0x1e,0x01,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01,0x20,0x16,0x11,0x94,0xcc,0x96,0x02,0x14,0x0f,0x24,0x0e,0x16,0x54,0x76,0x54,0x01,0x01,0xa5,0x1e,0x17,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01, -0xb3,0x67,0x94,0x02,0x90,0x69,0x0e,0x16,0x16,0x0e,0x3b,0x54,0x54,0x3b,0xb3,0x00,0x00,0x08,0x00,0x00,0xff,0x9f,0x03,0x8f,0x03,0x1d,0x00,0x04,0x00,0x09,0x00,0x0e,0x00,0x13,0x00,0x1b,0x00,0x23,0x00,0x2b,0x00,0x33,0x00,0x41,0x40,0x3e,0x21,0x20,0x15,0x14,0x0e,0x01,0x06,0x00,0x4a,0x31,0x30,0x25,0x24,0x10,0x09,0x06,0x01,0x49, -0x05,0x04,0x02,0x08,0x04,0x00,0x01,0x00,0x85,0x07,0x06,0x09,0x03,0x04,0x01,0x01,0x76,0x0f,0x0f,0x00,0x00,0x2d,0x2c,0x29,0x28,0x1d,0x1c,0x19,0x18,0x0f,0x13,0x0f,0x13,0x0b,0x0a,0x06,0x05,0x00,0x04,0x00,0x04,0x0a,0x07,0x16,0x2b,0x01,0x35,0x1e,0x01,0x17,0x07,0x33,0x0e,0x01,0x07,0x03,0x23,0x3e,0x01,0x37,0x11,0x15,0x2e,0x01, -0x27,0x01,0x35,0x1e,0x01,0x17,0x23,0x2e,0x01,0x01,0x23,0x3e,0x01,0x37,0x15,0x0e,0x01,0x01,0x15,0x2e,0x01,0x27,0x33,0x1e,0x01,0x01,0x33,0x0e,0x01,0x07,0x35,0x3e,0x01,0x02,0x09,0x3c,0x56,0x10,0xa2,0xa2,0x10,0x56,0x3c,0x71,0xa2,0x10,0x56,0x3c,0x3c,0x56,0x10,0x01,0x13,0x98,0xda,0x14,0x71,0x12,0x9a,0xfe,0x11,0x71,0x13,0xda, -0x99,0x6a,0x98,0x01,0x02,0x9a,0xd8,0x14,0x71,0x12,0x9a,0x01,0xef,0x71,0x15,0xd8,0x99,0x69,0x9a,0x01,0x97,0xa2,0x10,0x58,0x3a,0x71,0x3b,0x58,0x0f,0x01,0x13,0x3b,0x56,0x11,0xfe,0xed,0xa2,0x10,0x56,0x3c,0x01,0x86,0x71,0x13,0xda,0x99,0x6b,0x98,0xfe,0xfd,0x98,0xda,0x14,0x71,0x12,0x98,0xfe,0x0f,0x72,0x13,0xdc,0x98,0x6b,0x98, -0x01,0x03,0x99,0xda,0x14,0x72,0x12,0x98,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x03,0x00,0x21,0x00,0x31,0x00,0x45,0x00,0x8d,0x40,0x11,0x2b,0x2a,0x23,0x22,0x04,0x08,0x04,0x01,0x4c,0x0d,0x01,0x04,0x06,0x01,0x08,0x02,0x4b,0x4b,0xb0,0x26,0x50,0x58,0x40,0x2f,0x00,0x08,0x04,0x03,0x04,0x08,0x03,0x80,0x00,0x03, -0x06,0x04,0x03,0x06,0x7e,0x00,0x06,0x00,0x01,0x00,0x06,0x01,0x68,0x07,0x01,0x04,0x04,0x0a,0x5f,0x00,0x0a,0x0a,0x10,0x4d,0x05,0x02,0x02,0x00,0x00,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x40,0x2d,0x00,0x08,0x04,0x03,0x04,0x08,0x03,0x80,0x00,0x03,0x06,0x04,0x03,0x06,0x7e,0x00,0x0a,0x07,0x01,0x04,0x08,0x0a,0x04,0x67, -0x00,0x06,0x00,0x01,0x00,0x06,0x01,0x68,0x05,0x02,0x02,0x00,0x00,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x40,0x10,0x40,0x3d,0x38,0x35,0x17,0x26,0x33,0x11,0x13,0x3b,0x11,0x11,0x10,0x0b,0x07,0x1f,0x2b,0x17,0x21,0x35,0x21,0x05,0x33,0x11,0x34,0x26,0x2f,0x01,0x2e,0x01,0x07,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35, -0x23,0x11,0x33,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x07,0x03,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x17,0x15,0x14,0x16,0x37,0x33,0x32,0x36,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x1f,0x01,0x1e,0x01,0xd6,0x01,0xad,0xfe,0x53,0x01,0xf4,0x48,0x0c,0x05,0x9d,0x05,0x1c,0x08,0x1e,0x17,0xfe, -0xbe,0x16,0x1e,0x01,0x48,0x48,0x20,0x15,0x01,0xd1,0x16,0x20,0x01,0xd6,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x64,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x02,0x05,0x17,0x36,0x0f,0x9c,0x10,0x16,0x07,0xd6,0xd6,0x01,0xf4,0x08,0x1a,0x07,0x9c,0x06,0x0c,0x01,0xe8,0x16,0x20,0x20,0x16,0xe8,0xfd,0x36, -0xe8,0x16,0x20,0x20,0x16,0x01,0x1e,0xb2,0x08,0x0a,0x0a,0x08,0xb2,0x07,0x0c,0x01,0x0a,0x0a,0xfd,0xfa,0x16,0x20,0x20,0x16,0x02,0xee,0x16,0x20,0x18,0x0e,0x9d,0x0f,0x36,0x00,0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xb1,0x03,0xe8,0x03,0x0b,0x00,0x03,0x00,0x13,0x00,0x3c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x15,0x00,0x01,0x01,0x03,0x5f, -0x00,0x03,0x03,0x10,0x4d,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x13,0x00,0x03,0x00,0x01,0x00,0x03,0x01,0x67,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x59,0xb6,0x35,0x34,0x11,0x10,0x04,0x07,0x1a,0x2b,0x37,0x21,0x11,0x21,0x25,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x11,0x34,0x36, -0x37,0x21,0x32,0x16,0x8f,0x02,0xca,0xfd,0x36,0x03,0x59,0x34,0x25,0xfc,0xca,0x24,0x36,0x01,0x34,0x25,0x03,0x36,0x25,0x34,0x40,0x01,0xad,0xc4,0xfd,0x5a,0x25,0x34,0x01,0x36,0x24,0x02,0xa6,0x25,0x34,0x01,0x36,0x00,0x00,0x00,0x00,0x03,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x08,0x00,0x15,0x00,0x22,0x00,0x59,0x4b,0xb0, -0x26,0x50,0x58,0x40,0x1e,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x69,0x06,0x01,0x02,0x02,0x05,0x61,0x00,0x05,0x05,0x10,0x4d,0x00,0x03,0x03,0x04,0x61,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x40,0x1c,0x00,0x05,0x06,0x01,0x02,0x01,0x05,0x02,0x69,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x69,0x00,0x03,0x03,0x04,0x61,0x00,0x04,0x04,0x11, -0x04,0x4e,0x59,0x40,0x11,0x0a,0x09,0x20,0x1f,0x1a,0x19,0x10,0x0f,0x09,0x15,0x0a,0x15,0x13,0x12,0x07,0x07,0x18,0x2b,0x01,0x14,0x06,0x22,0x2e,0x01,0x36,0x32,0x16,0x27,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e,0x01,0x2e,0x02,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x02,0x3b,0x52,0x78,0x52,0x02,0x56,0x74,0x56, -0x90,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x5e,0x3b,0x54,0x54,0x76,0x54,0x54,0xf5,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x00,0x00,0x02,0x00,0x00, -0xff,0x6a,0x02,0x83,0x03,0x0b,0x00,0x0b,0x00,0x2e,0x00,0x65,0xb6,0x07,0x01,0x02,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x1d,0x00,0x03,0x02,0x03,0x86,0x09,0x05,0x02,0x01,0x04,0x01,0x02,0x03,0x01,0x02,0x67,0x08,0x06,0x02,0x00,0x00,0x07,0x5f,0x00,0x07,0x07,0x10,0x00,0x4e,0x1b,0x40,0x24,0x00,0x03,0x02,0x03,0x86, -0x00,0x07,0x08,0x06,0x02,0x00,0x01,0x07,0x00,0x69,0x09,0x05,0x02,0x01,0x02,0x02,0x01,0x59,0x09,0x05,0x02,0x01,0x01,0x02,0x5f,0x04,0x01,0x02,0x01,0x02,0x4f,0x59,0x40,0x0e,0x2d,0x2c,0x13,0x33,0x11,0x14,0x22,0x33,0x15,0x15,0x13,0x0a,0x07,0x1f,0x2b,0x01,0x35,0x34,0x26,0x22,0x06,0x1d,0x01,0x14,0x16,0x32,0x36,0x05,0x14,0x06, -0x27,0x23,0x03,0x0e,0x01,0x07,0x23,0x22,0x27,0x03,0x23,0x22,0x26,0x27,0x34,0x36,0x33,0x11,0x22,0x2e,0x01,0x36,0x37,0x21,0x32,0x16,0x14,0x06,0x27,0x11,0x32,0x16,0x01,0x0c,0x0a,0x10,0x0a,0x0a,0x10,0x0a,0x01,0x77,0x16,0x0e,0xef,0x1d,0x01,0x0a,0x06,0x01,0x0f,0x02,0x2b,0xe1,0x0f,0x14,0x01,0x58,0x37,0x1d,0x2a,0x02,0x2e,0x1b, -0x01,0x65,0x1d,0x2a,0x2a,0x1d,0x37,0x58,0x01,0x70,0xfa,0x08,0x0a,0x0a,0x08,0xfa,0x08,0x0a,0x0a,0xbd,0x0e,0x16,0x01,0xfe,0xf2,0x07,0x08,0x01,0x0f,0x01,0x0f,0x14,0x0f,0x45,0x6e,0x01,0x1e,0x2a,0x3a,0x2a,0x01,0x2c,0x38,0x2c,0x01,0xfe,0xe2,0x6e,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5b,0x03,0x0b,0x00,0x24,0x00,0x47,0x00,0x81, -0x40,0x13,0x43,0x25,0x02,0x06,0x09,0x2f,0x01,0x05,0x06,0x17,0x01,0x03,0x02,0x08,0x01,0x01,0x03,0x04,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x29,0x00,0x09,0x07,0x01,0x05,0x02,0x09,0x05,0x67,0x00,0x06,0x06,0x08,0x61,0x00,0x08,0x08,0x10,0x4d,0x04,0x01,0x02,0x02,0x01,0x61,0x00,0x01,0x01,0x14,0x4d,0x00,0x03,0x03,0x00,0x61,0x00, -0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x27,0x00,0x08,0x00,0x06,0x05,0x08,0x06,0x69,0x00,0x09,0x07,0x01,0x05,0x02,0x09,0x05,0x67,0x04,0x01,0x02,0x02,0x01,0x61,0x00,0x01,0x01,0x14,0x4d,0x00,0x03,0x03,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x59,0x40,0x0e,0x46,0x45,0x26,0x25,0x25,0x36,0x25,0x26,0x35,0x14,0x24,0x0a,0x07,0x1f, -0x2b,0x01,0x14,0x15,0x0e,0x01,0x23,0x22,0x26,0x27,0x07,0x06,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16,0x06,0x0f,0x01,0x1e,0x01,0x37,0x32,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x32,0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x36,0x3f,0x01,0x26,0x23,0x22,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x37,0x35,0x3e, -0x01,0x33,0x32,0x16,0x17,0x37,0x36,0x32,0x16,0x03,0x4b,0x24,0xe4,0x99,0x51,0x98,0x3c,0x48,0x0b,0x1c,0x16,0x16,0x0e,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x28,0x64,0x37,0x4a,0x82,0x27,0x06,0x18,0x04,0x0c,0x6b,0x08,0x0a,0x0e,0x14,0x10,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x52,0x70,0x4b,0x82,0x27,0x06,0x17,0x05,0x0c,0x6f,0x07,0x0c,0x01, -0x24,0xe6,0x99,0x51,0x9a,0x3c,0x48,0x0b,0x1c,0x18,0x01,0x05,0x03,0x01,0x96,0xba,0x3e,0x39,0x48,0x0b,0x16,0x0e,0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x24,0x2a,0x01,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x01,0xb8,0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x4d,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x06,0x04,0x96,0xba,0x3e,0x39,0x48,0x0b,0x16,0x00, -0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x39,0x40,0x09,0x18,0x10,0x08,0x00,0x04,0x00,0x01,0x01,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x0d,0x03,0x01,0x01,0x01,0x10,0x4d,0x02,0x01,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0d,0x03,0x01,0x01,0x01,0x00,0x5f,0x02,0x01,0x00,0x00,0x11,0x00,0x4e,0x59, -0xb6,0x35,0x35,0x35,0x33,0x04,0x07,0x1a,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0xfe,0x0b,0x14,0x10,0xfe,0xe3,0x0f,0x14, -0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0x02,0xe7,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f,0x00,0x30,0xb6,0x08,0x00,0x02,0x00,0x01,0x01,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x0b,0x00,0x01,0x01, -0x10,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0b,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x00,0x11,0x00,0x4e,0x59,0xb4,0x35,0x33,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10,0xfc,0xef,0x0f,0x14,0x01,0x16,0x0e,0x03,0x11,0x0f,0x16,0x02,0xe7,0xfc, -0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x00,0x00,0x01,0xff,0xfe,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x30,0x00,0x69,0x40,0x0a,0x2d,0x01,0x01,0x05,0x09,0x01,0x00,0x01,0x02,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x24,0x00,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x00,0x03,0x02,0x01,0x03,0x02,0x7e,0x00,0x01,0x01,0x05, -0x61,0x00,0x05,0x05,0x10,0x4d,0x00,0x02,0x02,0x04,0x61,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x40,0x22,0x00,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x00,0x03,0x02,0x01,0x03,0x02,0x7e,0x00,0x05,0x00,0x01,0x00,0x05,0x01,0x69,0x00,0x02,0x02,0x04,0x61,0x00,0x04,0x04,0x11,0x04,0x4e,0x59,0x40,0x09,0x27,0x27,0x13,0x27,0x24,0x33,0x06, -0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3f,0x01,0x26,0x23,0x22,0x0e,0x02,0x14,0x1e,0x02,0x33,0x32,0x36,0x37,0x3e,0x01,0x1f,0x01,0x1e,0x01,0x07,0x0e,0x01,0x07,0x22,0x2e,0x02,0x3e,0x03,0x33,0x32,0x16,0x17,0x37,0x36,0x16,0x03,0x59,0x14,0x10,0xfa,0x17,0x13,0x11,0x4d,0x52,0x70,0x3a,0x6a,0x4c,0x2e,0x2e,0x4c, -0x6a,0x3a,0x42,0x76,0x29,0x04,0x11,0x06,0x4c,0x05,0x02,0x06,0x3c,0xae,0x5f,0x57,0xa0,0x70,0x48,0x04,0x40,0x78,0x98,0x5b,0x52,0x98,0x3d,0x48,0x11,0x2c,0x02,0xc3,0xfa,0x0e,0x16,0x2d,0x10,0x4d,0x4d,0x2e,0x4c,0x6a,0x74,0x6a,0x4c,0x2e,0x3a,0x35,0x06,0x01,0x05,0x4d,0x04,0x0e,0x06,0x4a,0x50,0x01,0x44,0x74,0x9e,0xae,0x9e,0x74, -0x44,0x3e,0x39,0x48,0x12,0x13,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58,0x01,0xe6,0x00,0x15,0x00,0x19,0x40,0x16,0x0f,0x01,0x00,0x01,0x01,0x4c,0x02,0x01,0x01,0x00,0x01,0x85,0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37, -0x36,0x32,0x1f,0x01,0x16,0x02,0x58,0x06,0xfe,0xfc,0x05,0x10,0x04,0xfe,0xfc,0x06,0x06,0x1c,0x05,0x0e,0x06,0xdb,0xdc,0x05,0x10,0x04,0x1c,0x06,0x01,0xb7,0x07,0x05,0xfe,0xfb,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x00,0x00,0x00,0x03,0xff,0xfd,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0c, -0x00,0x1c,0x00,0x2e,0x00,0x6a,0x40,0x0d,0x28,0x1e,0x02,0x05,0x04,0x16,0x15,0x0e,0x03,0x03,0x02,0x02,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x1e,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x04,0x04,0x00,0x61,0x06,0x01,0x00,0x00,0x10,0x4d,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x11,0x01,0x4e,0x1b,0x40,0x1c,0x06,0x01,0x00, -0x00,0x04,0x05,0x00,0x04,0x67,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x11,0x01,0x4e,0x59,0x40,0x13,0x01,0x00,0x2c,0x2a,0x23,0x21,0x1a,0x18,0x12,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x07,0x07,0x16,0x2b,0x01,0x32,0x1e,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x13,0x35,0x34,0x26, -0x2b,0x01,0x22,0x06,0x07,0x15,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34,0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x13,0x14,0x16,0x3b,0x01,0x32,0x36,0x01,0xad,0x74,0xc6,0x72,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xc1,0x0a,0x07,0x6b,0x08,0x0a,0x01,0x0c,0x07,0x6b,0x07,0x0a,0x01,0x0a,0x06,0x05,0x08,0x7b,0x08,0x05,0x06, -0x0a,0x0a,0x09,0x67,0x08,0x0a,0x03,0x0b,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0xfd,0x48,0x6a,0x08,0x0a,0x0a,0x08,0x6a,0x08,0x0a,0x01,0x0c,0xc7,0x01,0x5a,0x07,0x03,0x05,0x05,0x03,0x07,0xfe,0xa6,0x06,0x08,0x08,0x00,0x01,0x00,0x00,0xff,0xef,0x02,0xd4,0x02,0x86,0x00,0x24,0x00,0x26,0x40,0x23,0x22,0x19,0x10,0x07, -0x04,0x00,0x02,0x01,0x4c,0x03,0x01,0x02,0x00,0x00,0x02,0x59,0x03,0x01,0x02,0x02,0x00,0x61,0x01,0x01,0x00,0x02,0x00,0x51,0x14,0x1c,0x14,0x14,0x04,0x07,0x1a,0x2b,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37,0x36,0x32,0x1f,0x01,0x16, -0x14,0x0f,0x01,0x17,0x16,0x02,0xd4,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10,0x10,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x0f,0x0f,0xa4,0xa4,0x0f,0x70,0x16,0x10,0x4c,0x0f,0x0f,0xa5,0xa5,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10, -0x10,0x4c,0x0f,0x2e,0x0f,0xa4,0xa4,0x0f,0x00,0x03,0x00,0x00,0xff,0xb1,0x03,0xc5,0x03,0x0b,0x00,0x0c,0x00,0x1c,0x00,0x2c,0x00,0x5c,0x40,0x0b,0x25,0x1d,0x02,0x04,0x05,0x00,0x01,0x01,0x00,0x02,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x1d,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x04,0x05,0x5f,0x00,0x05,0x05,0x10,0x4d, -0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x1b,0x00,0x05,0x00,0x04,0x03,0x05,0x04,0x67,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x59,0x40,0x09,0x35,0x35,0x35,0x35,0x24,0x32,0x06,0x07,0x1c,0x2b,0x01,0x34,0x26,0x07,0x23,0x22,0x0e,0x01,0x16,0x17, -0x33,0x32,0x36,0x25,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x37,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x37,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x02,0x5f,0x14,0x10,0x8e,0x0f,0x14,0x02,0x18,0x0d,0x8e,0x0f,0x16,0x01,0x41,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x23,0x14, -0x0f,0xfc,0xa6,0x0e,0x16,0x01,0x14,0x0f,0x03,0x5a,0x0e,0x16,0x01,0x82,0x0e,0x16,0x01,0x14,0x1e,0x14,0x01,0x16,0x79,0xfd,0xe8,0x0e,0x16,0x16,0x0e,0x02,0x18,0x0e,0x16,0x16,0xec,0x8f,0x0e,0x16,0x16,0x0e,0x8f,0x0e,0x16,0x16,0x00,0x05,0x00,0x00,0xff,0x88,0x03,0xac,0x03,0x34,0x00,0x43,0x00,0x4c,0x00,0x55,0x00,0x5e,0x00,0x67, -0x00,0x61,0x40,0x5e,0x3c,0x33,0x02,0x05,0x0a,0x1a,0x0f,0x02,0x01,0x05,0x2b,0x22,0x19,0x10,0x09,0x00,0x06,0x08,0x01,0x03,0x4c,0x07,0x01,0x05,0x03,0x01,0x01,0x08,0x05,0x01,0x67,0x00,0x0a,0x0f,0x0c,0x02,0x08,0x09,0x0a,0x08,0x69,0x10,0x0e,0x0d,0x03,0x09,0x04,0x02,0x02,0x00,0x09,0x00,0x65,0x00,0x0b,0x0b,0x06,0x61,0x00,0x06, -0x06,0x12,0x0b,0x4e,0x60,0x5f,0x64,0x63,0x5f,0x67,0x60,0x67,0x5d,0x5c,0x59,0x58,0x54,0x53,0x50,0x4f,0x4b,0x4a,0x15,0x36,0x16,0x37,0x18,0x36,0x16,0x36,0x14,0x11,0x07,0x1f,0x2b,0x25,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x34,0x2b,0x01,0x22,0x27,0x15,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x06,0x2b, -0x01,0x22,0x0e,0x01,0x1d,0x01,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x34,0x36,0x3b,0x01,0x32,0x3d,0x01,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x15,0x14,0x3b,0x01,0x32,0x16,0x15,0x05,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x13,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x34,0x26,0x22,0x06,0x14,0x16, -0x32,0x36,0x05,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x64,0x48,0x46,0x64,0x46,0x48,0x4c,0x64,0x2c,0x22,0x48,0x46,0x64,0x46,0x48,0x1e,0x2e,0x64,0x22,0x26,0x06,0x48,0x46,0x64,0x46,0x48,0x56,0x58,0x64,0x4c,0x48,0x46,0x64,0x46,0x48,0x4e,0x64,0x56,0x56,0xfd,0x5a,0x2a,0x38,0x28,0x28,0x38,0x2a,0xd4,0x28,0x38,0x2a,0x2a, -0x38,0x28,0x8a,0x2a,0x38,0x28,0x28,0x38,0x2a,0x01,0x18,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x70,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x4e,0x0c,0xcc,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0xcc,0x0c,0x26,0x1c,0x0c,0x72,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x40,0x6c,0x34,0x8c,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c, -0x22,0x8c,0x34,0x6c,0x40,0xe2,0x1e,0x28,0x28,0x3a,0x28,0x28,0x02,0xd8,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x26,0x1e,0x28,0x28,0x3a,0x28,0x28,0x28,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x6f,0x40,0x0a,0x0d,0x01,0x00,0x01,0x1f,0x01,0x04,0x03,0x02,0x4c, -0x4b,0xb0,0x24,0x50,0x58,0x40,0x26,0x02,0x01,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04,0x01,0x03,0x04,0x7e,0x00,0x01,0x01,0x07,0x5f,0x00,0x07,0x07,0x10,0x4d,0x00,0x04,0x04,0x06,0x60,0x00,0x06,0x06,0x11,0x06,0x4e,0x1b,0x40,0x24,0x02,0x01,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04,0x01,0x03,0x04, -0x7e,0x00,0x07,0x00,0x01,0x00,0x07,0x01,0x67,0x00,0x04,0x04,0x06,0x60,0x00,0x06,0x06,0x11,0x06,0x4e,0x59,0x40,0x0b,0x35,0x35,0x23,0x33,0x16,0x23,0x24,0x23,0x08,0x07,0x1e,0x2b,0x01,0x35,0x34,0x26,0x07,0x23,0x35,0x34,0x26,0x27,0x23,0x22,0x06,0x07,0x15,0x23,0x22,0x06,0x07,0x15,0x14,0x16,0x37,0x33,0x15,0x14,0x16,0x3b,0x01, -0x32,0x36,0x37,0x35,0x33,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xb3,0x16,0x0e,0x47,0x0f,0x14,0x01,0xb2,0x0f,0x14,0x01,0x16,0x0e,0xb2,0x16,0x0e,0x47,0x0f,0x14,0x01,0xb3,0x0e,0x16,0x8e,0x5e,0x43,0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01, -0x3a,0x48,0x0e,0x16,0x01,0xb3,0x0f,0x14,0x01,0x16,0x0e,0xb3,0x14,0x0f,0x48,0x0e,0x16,0x01,0xb3,0x0e,0x16,0x16,0x0e,0xb3,0x14,0x01,0x3f,0xfd,0xe8,0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x3c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x15,0x00, -0x00,0x00,0x03,0x5f,0x00,0x03,0x03,0x10,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x13,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x59,0xb6,0x35,0x35,0x26,0x33,0x04,0x07,0x1a,0x2b,0x01,0x35,0x34,0x26,0x07,0x21,0x22,0x06,0x07,0x15,0x14,0x16, -0x37,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x01,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x8e,0x5e,0x43,0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01,0x3a,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x01,0x3f,0xfd, -0xe8,0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x17,0x00,0x2c,0x00,0x51,0x4b,0xb0,0x26,0x50,0x58,0x40,0x1a,0x00,0x05,0x00,0x00,0x02,0x05,0x00,0x67,0x00,0x02,0x00,0x03,0x02,0x03,0x63,0x00,0x01,0x01,0x04,0x5f,0x00,0x04,0x04,0x10,0x01,0x4e,0x1b,0x40,0x20, -0x00,0x04,0x00,0x01,0x05,0x04,0x01,0x67,0x00,0x05,0x00,0x00,0x02,0x05,0x00,0x67,0x00,0x02,0x03,0x03,0x02,0x57,0x00,0x02,0x02,0x03,0x5f,0x00,0x03,0x02,0x03,0x4f,0x59,0x40,0x09,0x23,0x35,0x35,0x35,0x35,0x33,0x06,0x07,0x1c,0x2b,0x25,0x11,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x26,0x07,0x23,0x22,0x06,0x15,0x11,0x14, -0x16,0x33,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0x59,0x1e,0x17,0xfe,0x77,0x17,0x1e,0x01,0x1e,0x17,0xb3,0x16,0x20,0x20,0x16,0x02,0xa7,0x16,0x20,0x47,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x76,0x01, -0x89,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfd,0xe8,0x16,0x20,0x20,0x01,0x9f,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x1b,0xf3,0xb7,0xb3,0x5f,0x0f,0x3c,0xf5,0x00,0x0f,0x03,0xe8,0x00,0x00,0x00,0x00,0xe1,0xa1,0x0d,0xf0, -0x00,0x00,0x00,0x00,0xe1,0xa1,0x0d,0xf1,0xff,0xf5,0xff,0x6a,0x04,0x2f,0x03,0x53,0x00,0x00,0x00,0x08,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x03,0x52,0xff,0x6a,0x00,0x00,0x04,0x2f,0xff,0xf5,0xff,0xf5,0x04,0x2f,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4c, -0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x80,0x00,0x00,0x03,0x11,0x00,0x00,0x00,0xf0,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x59,0xff,0xfd,0x03,0x59,0xff,0xfd,0x02,0x3b,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x11,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0xe8,0x00,0x00,0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00,0x02,0x3b,0xff,0xff, -0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x03,0xca,0x00,0x00,0x04,0x2f,0xff,0xff,0x03,0xa0,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xd4,0xff,0xf7,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xff,0x02,0x82,0x00,0x00,0x02,0xda,0x00,0x00, -0x04,0x2f,0xff,0xff,0x02,0xf8,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x59,0x00,0x00,0x02,0xda,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xf5,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x82,0x00,0x00, -0x03,0x42,0x00,0x00,0x04,0x2f,0x00,0x00,0x00,0xdc,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe7,0xff,0xfe,0x03,0x59,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x3b,0xff,0xff,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x02,0x82,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0xff,0xff,0x03,0x59,0xff,0xfd,0x02,0x82,0x00,0x00, -0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0xff,0xfe,0x02,0x82,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x11,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x01,0x0a,0x01,0xce,0x02,0x3a,0x02,0xb8,0x03,0x06, -0x03,0x34,0x03,0x60,0x04,0x0c,0x05,0x06,0x05,0x62,0x06,0x12,0x06,0x3c,0x06,0x5e,0x06,0x88,0x06,0xc0,0x06,0xf8,0x07,0xa0,0x08,0x00,0x08,0xd2,0x09,0x36,0x09,0x74,0x09,0x98,0x09,0xf2,0x0a,0x3a,0x0b,0x12,0x0c,0x18,0x0c,0xa4,0x0d,0xae,0x0e,0x06,0x0e,0x2c,0x0e,0x8e,0x0f,0x12,0x0f,0x64,0x0f,0xfa,0x10,0x22,0x10,0x76,0x11,0x7a, -0x11,0x98,0x11,0xd0,0x12,0x3a,0x12,0x96,0x12,0xf6,0x13,0xdc,0x14,0x78,0x14,0xee,0x15,0x28,0x15,0xec,0x16,0x96,0x16,0xba,0x17,0xc8,0x18,0x2a,0x18,0x82,0x18,0xa0,0x18,0xea,0x19,0x86,0x1a,0x06,0x1a,0x5a,0x1a,0xd6,0x1b,0x84,0x1b,0xc8,0x1c,0x30,0x1c,0xaa,0x1d,0x52,0x1d,0xa2,0x1d,0xd8,0x1e,0x56,0x1e,0x8c,0x1f,0x08,0x1f,0x56, -0x1f,0xc8,0x20,0x84,0x21,0x06,0x21,0x58,0x21,0xc3,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x4c,0x00,0x90,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x42,0x00,0x7b,0x00,0x8d,0x00,0x00,0x00,0xba,0x0e,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0xde,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x35,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x07,0x00,0x3d,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x08,0x00,0x44,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x00,0x4c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x0b,0x00,0x54,0x00,0x01,0x00,0x00,0x00,0x00, -0x00,0x06,0x00,0x08,0x00,0x5f,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x2b,0x00,0x67,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x13,0x00,0x92,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x00,0x00,0x6a,0x00,0xa5,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x01,0x00,0x10,0x01,0x0f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x02,0x00,0x0e, -0x01,0x1f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x03,0x00,0x10,0x01,0x2d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x04,0x00,0x10,0x01,0x3d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x05,0x00,0x16,0x01,0x4d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x06,0x00,0x10,0x01,0x63,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x0a,0x00,0x56,0x01,0x73,0x00,0x03, -0x00,0x01,0x04,0x09,0x00,0x0b,0x00,0x26,0x01,0xc9,0x43,0x6f,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x43,0x29,0x20,0x32,0x30,0x32,0x33,0x20,0x62,0x79,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x73,0x20,0x40,0x20,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x66, -0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x52,0x65,0x67,0x75,0x6c,0x61,0x72,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x47,0x65,0x6e,0x65,0x72,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x73,0x76, -0x67,0x32,0x74,0x74,0x66,0x20,0x66,0x72,0x6f,0x6d,0x20,0x46,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x20,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x2e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x43,0x00,0x6f,0x00,0x70,0x00,0x79,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x68,0x00, -0x74,0x00,0x20,0x00,0x28,0x00,0x43,0x00,0x29,0x00,0x20,0x00,0x32,0x00,0x30,0x00,0x32,0x00,0x33,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x6f,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x69,0x00,0x6e,0x00,0x61,0x00,0x6c,0x00,0x20,0x00,0x61,0x00,0x75,0x00,0x74,0x00,0x68,0x00,0x6f,0x00,0x72,0x00,0x73,0x00,0x20,0x00,0x40,0x00, -0x20,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x52,0x00,0x65,0x00,0x67,0x00,0x75,0x00,0x6c,0x00,0x61,0x00,0x72,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00, -0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x31,0x00,0x2e,0x00,0x30,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x47,0x00, -0x65,0x00,0x6e,0x00,0x65,0x00,0x72,0x00,0x61,0x00,0x74,0x00,0x65,0x00,0x64,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x73,0x00,0x76,0x00,0x67,0x00,0x32,0x00,0x74,0x00,0x74,0x00,0x66,0x00,0x20,0x00,0x66,0x00,0x72,0x00,0x6f,0x00,0x6d,0x00,0x20,0x00,0x46,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00, -0x6f,0x00,0x20,0x00,0x70,0x00,0x72,0x00,0x6f,0x00,0x6a,0x00,0x65,0x00,0x63,0x00,0x74,0x00,0x2e,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,0x2f,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x00,0x00,0x00,0x02,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12, -0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,0x01,0x20,0x01,0x21,0x01,0x22,0x01,0x23,0x01,0x24,0x01,0x25,0x01,0x26,0x01,0x27,0x01,0x28,0x01,0x29,0x01,0x2a,0x01,0x2b,0x01,0x2c,0x01,0x2d,0x01,0x2e,0x01,0x2f,0x01,0x30,0x01,0x31,0x01,0x32, -0x01,0x33,0x01,0x34,0x01,0x35,0x01,0x36,0x01,0x37,0x01,0x38,0x01,0x39,0x01,0x3a,0x01,0x3b,0x01,0x3c,0x01,0x3d,0x01,0x3e,0x01,0x3f,0x01,0x40,0x01,0x41,0x01,0x42,0x01,0x43,0x01,0x44,0x01,0x45,0x01,0x46,0x01,0x47,0x01,0x48,0x01,0x49,0x01,0x4a,0x01,0x4b,0x01,0x4c,0x01,0x4d,0x00,0x0b,0x63,0x68,0x65,0x63,0x6b,0x2d,0x65,0x6d, -0x70,0x74,0x79,0x0d,0x66,0x6c,0x6f,0x77,0x2d,0x70,0x61,0x72,0x61,0x6c,0x6c,0x65,0x6c,0x05,0x74,0x72,0x61,0x73,0x68,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x6c,0x69,0x6e,0x65,0x0c,0x70,0x6c,0x75,0x73,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x0d,0x6d,0x69,0x6e,0x75,0x73,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x06,0x63,0x69,0x72, -0x63,0x6c,0x65,0x08,0x64,0x6f,0x77,0x6e,0x2d,0x64,0x69,0x72,0x05,0x63,0x68,0x65,0x63,0x6b,0x0b,0x74,0x72,0x61,0x73,0x68,0x2d,0x65,0x6d,0x70,0x74,0x79,0x04,0x75,0x73,0x65,0x72,0x09,0x62,0x72,0x69,0x65,0x66,0x63,0x61,0x73,0x65,0x08,0x6c,0x65,0x66,0x74,0x2d,0x64,0x69,0x72,0x09,0x72,0x69,0x67,0x68,0x74,0x2d,0x64,0x69,0x72, -0x06,0x75,0x70,0x2d,0x64,0x69,0x72,0x0a,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x6c,0x65,0x66,0x74,0x0b,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x72,0x69,0x67,0x68,0x74,0x0c,0x68,0x65,0x6c,0x70,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x74,0x61,0x67,0x04,0x67,0x72,0x69,0x64,0x0b,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f,0x70,0x65,0x6e, -0x06,0x66,0x6f,0x6c,0x64,0x65,0x72,0x09,0x64,0x6f,0x77,0x6e,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x70,0x61,0x6c,0x65,0x74,0x74,0x65,0x07,0x64,0x6f,0x63,0x2d,0x69,0x6e,0x76,0x03,0x63,0x6f,0x67,0x02,0x74,0x68,0x0a,0x62,0x69,0x6e,0x6f,0x63,0x75,0x6c,0x61,0x72,0x73,0x04,0x6c,0x69,0x73,0x74,0x04,0x6c,0x6f,0x63,0x6b,0x09,0x6c,0x65, -0x66,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x64,0x65,0x73,0x6b,0x74,0x6f,0x70,0x06,0x73,0x65,0x61,0x72,0x63,0x68,0x0c,0x63,0x69,0x72,0x63,0x6c,0x65,0x2d,0x65,0x6d,0x70,0x74,0x79,0x06,0x70,0x65,0x6e,0x63,0x69,0x6c,0x0a,0x72,0x69,0x67,0x68,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x0b,0x63,0x6c,0x6f,0x73,0x65,0x5f,0x70,0x61,0x6e,0x65, -0x6c,0x08,0x73,0x74,0x65,0x70,0x69,0x6e,0x74,0x6f,0x07,0x75,0x70,0x2d,0x62,0x6f,0x6c,0x64,0x02,0x6f,0x6b,0x09,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f,0x6e,0x10,0x68,0x6f,0x72,0x69,0x7a,0x6f,0x6e,0x74,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x0e,0x76,0x65,0x72,0x74,0x69,0x63,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x08, -0x73,0x74,0x65,0x70,0x6f,0x76,0x65,0x72,0x10,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x11,0x6d,0x69,0x6e,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x08,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x75,0x70,0x09,0x63,0x6c,0x69,0x70,0x62,0x6f,0x61,0x72,0x64,0x11,0x66, -0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f,0x70,0x65,0x6e,0x2d,0x65,0x6d,0x70,0x74,0x79,0x03,0x64,0x6f,0x74,0x07,0x73,0x74,0x65,0x70,0x6f,0x75,0x74,0x07,0x67,0x6c,0x61,0x73,0x73,0x65,0x73,0x03,0x64,0x6f,0x63,0x04,0x70,0x6c,0x61,0x79,0x06,0x74,0x6f,0x2d,0x65,0x6e,0x64,0x0c,0x69,0x6e,0x66,0x6f,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65, -0x64,0x03,0x63,0x63,0x77,0x0d,0x6c,0x6f,0x63,0x6b,0x2d,0x6f,0x70,0x65,0x6e,0x2d,0x61,0x6c,0x74,0x06,0x74,0x61,0x72,0x67,0x65,0x74,0x06,0x66,0x6c,0x6f,0x70,0x70,0x79,0x0f,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x6d,0x61,0x78,0x69,0x6d,0x69,0x7a,0x65,0x0b,0x64,0x6f,0x74,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x70,0x69, -0x6e,0x09,0x61,0x72,0x72,0x6f,0x77,0x73,0x2d,0x63,0x77,0x05,0x70,0x61,0x75,0x73,0x65,0x04,0x73,0x74,0x6f,0x70,0x02,0x63,0x77,0x0a,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x64,0x6f,0x77,0x6e,0x11,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f,0x6e,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x06,0x63,0x61,0x6e,0x63,0x65,0x6c,0x03,0x62,0x6f, -0x78,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x74,0x72,0x65,0x65,0x0c,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x0d,0x6d,0x69,0x6e,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x0c,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x65,0x6d,0x70,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0xff,0xff,0x00,0x0f, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x7e,0x01,0x1e,0x00,0x7d,0x00,0x7d,0x01,0x1e,0x03,0x18,0xff,0xb1,0x03,0x38,0x02,0xc8,0xff,0xd0,0xff,0xb1,0x03,0x18,0xff,0xb1,0x03,0x38,0x02,0xc8,0xff,0xd0,0xff,0xb1,0xb0,0x00,0x2c,0x20,0xb0,0x00,0x55,0x58, -0x45,0x59,0x20,0x20,0x4b,0xb8,0x00,0x0e,0x51,0x4b,0xb0,0x06,0x53,0x5a,0x58,0xb0,0x34,0x1b,0xb0,0x28,0x59,0x60,0x66,0x20,0x8a,0x55,0x58,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00,0x63,0x63,0x23,0x62,0x1b,0x21,0x21,0xb0,0x00,0x59,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x01,0x2c,0xb0,0x20, -0x60,0x66,0x2d,0xb0,0x02,0x2c,0x23,0x21,0x23,0x21,0x2d,0xb0,0x03,0x2c,0x20,0x64,0xb3,0x03,0x14,0x15,0x00,0x42,0x43,0xb0,0x13,0x43,0x20,0x60,0x60,0x42,0xb1,0x02,0x14,0x43,0x42,0xb1,0x25,0x03,0x43,0xb0,0x02,0x43,0x54,0x78,0x20,0xb0,0x0c,0x23,0xb0,0x02,0x43,0x43,0x61,0x64,0xb0,0x04,0x50,0x78,0xb2,0x02,0x02,0x02,0x43,0x60, -0x42,0xb0,0x21,0x65,0x1c,0x21,0xb0,0x02,0x43,0x43,0xb2,0x0e,0x15,0x01,0x42,0x1c,0x20,0xb0,0x02,0x43,0x23,0x42,0xb2,0x13,0x01,0x13,0x43,0x60,0x42,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb2,0x16,0x01,0x02,0x43,0x60,0x42,0x2d,0xb0,0x04,0x2c,0xb0,0x03,0x2b,0xb0,0x15,0x43,0x58,0x23,0x21,0x23,0x21,0xb0,0x16,0x43,0x43,0x23,0xb0, -0x00,0x50,0x58,0x65,0x59,0x1b,0x20,0x64,0x20,0xb0,0xc0,0x50,0xb0,0x04,0x26,0x5a,0xb2,0x28,0x01,0x0d,0x43,0x45,0x63,0x45,0xb0,0x06,0x45,0x58,0x21,0xb0,0x03,0x25,0x59,0x52,0x5b,0x58,0x21,0x23,0x21,0x1b,0x8a,0x58,0x20,0xb0,0x50,0x50,0x58,0x21,0xb0,0x40,0x59,0x1b,0x20,0xb0,0x38,0x50,0x58,0x21,0xb0,0x38,0x59,0x59,0x20,0xb1, -0x01,0x0d,0x43,0x45,0x63,0x45,0x61,0x64,0xb0,0x28,0x50,0x58,0x21,0xb1,0x01,0x0d,0x43,0x45,0x63,0x45,0x20,0xb0,0x30,0x50,0x58,0x21,0xb0,0x30,0x59,0x1b,0x20,0xb0,0xc0,0x50,0x58,0x20,0x66,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x0a,0x50,0x58,0x60,0x1b,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0,0x0a,0x60,0x1b,0x20,0xb0,0x36,0x50,0x58,0x21, -0xb0,0x36,0x60,0x1b,0x60,0x59,0x59,0x59,0x1b,0xb0,0x02,0x25,0xb0,0x0c,0x43,0x63,0xb0,0x00,0x52,0x58,0xb0,0x00,0x4b,0xb0,0x0a,0x50,0x58,0x21,0xb0,0x0c,0x43,0x1b,0x4b,0xb0,0x1e,0x50,0x58,0x21,0xb0,0x1e,0x4b,0x61,0xb8,0x10,0x00,0x63,0xb0,0x0c,0x43,0x63,0xb8,0x05,0x00,0x62,0x59,0x59,0x64,0x61,0x59,0xb0,0x01,0x2b,0x59,0x59, -0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x59,0x20,0x64,0xb0,0x16,0x43,0x23,0x42,0x59,0x2d,0xb0,0x05,0x2c,0x20,0x45,0x20,0xb0,0x04,0x25,0x61,0x64,0x20,0xb0,0x07,0x43,0x50,0x58,0xb0,0x07,0x23,0x42,0xb0,0x08,0x23,0x42,0x1b,0x21,0x21,0x59,0xb0,0x01,0x60,0x2d,0xb0,0x06,0x2c,0x23,0x21,0x23,0x21,0xb0,0x03,0x2b,0x20,0x64,0xb1,0x07, -0x62,0x42,0x20,0xb0,0x08,0x23,0x42,0xb0,0x06,0x45,0x58,0x1b,0xb1,0x01,0x0d,0x43,0x45,0x63,0xb1,0x01,0x0d,0x43,0xb0,0x01,0x60,0x45,0x63,0xb0,0x05,0x2a,0x21,0x20,0xb0,0x08,0x43,0x20,0x8a,0x20,0x8a,0xb0,0x01,0x2b,0xb1,0x30,0x05,0x25,0xb0,0x04,0x26,0x51,0x58,0x60,0x50,0x1b,0x61,0x52,0x59,0x58,0x23,0x59,0x21,0x59,0x20,0xb0, -0x40,0x53,0x58,0xb0,0x01,0x2b,0x1b,0x21,0xb0,0x40,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x2d,0xb0,0x07,0x2c,0xb0,0x09,0x43,0x2b,0xb2,0x00,0x02,0x00,0x43,0x60,0x42,0x2d,0xb0,0x08,0x2c,0xb0,0x09,0x23,0x42,0x23,0x20,0xb0,0x00,0x23,0x42,0x61,0xb0,0x02,0x62,0x66,0xb0,0x01,0x63,0xb0,0x01,0x60,0xb0,0x07,0x2a,0x2d,0xb0,0x09, -0x2c,0x20,0x20,0x45,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0a,0x2c,0xb2,0x09,0x0e,0x00,0x43,0x45,0x42,0x2a,0x21,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x0b,0x2c,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00, -0x43,0x60,0x42,0x2d,0xb0,0x0c,0x2c,0x20,0x20,0x45,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0,0x00,0x1b,0xb0,0x30,0x50,0x58,0xb0,0x20,0x1b,0xb0,0x40,0x59,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0, -0x01,0x60,0x2d,0xb0,0x0d,0x2c,0x20,0x20,0x45,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0xb0,0x24,0x50,0x58,0xb0,0x00,0x1b,0xb0,0x40,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0e,0x2c,0x20,0xb0,0x00,0x23,0x42, -0xb3,0x0d,0x0c,0x00,0x03,0x45,0x50,0x58,0x21,0x1b,0x23,0x21,0x59,0x2a,0x21,0x2d,0xb0,0x0f,0x2c,0xb1,0x02,0x02,0x45,0xb0,0x64,0x61,0x44,0x2d,0xb0,0x10,0x2c,0xb0,0x01,0x60,0x20,0x20,0xb0,0x0f,0x43,0x4a,0xb0,0x00,0x50,0x58,0x20,0xb0,0x0f,0x23,0x42,0x59,0xb0,0x10,0x43,0x4a,0xb0,0x00,0x52,0x58,0x20,0xb0,0x10,0x23,0x42,0x59, -0x2d,0xb0,0x11,0x2c,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0x20,0xb8,0x04,0x00,0x63,0x8a,0x23,0x61,0xb0,0x11,0x43,0x60,0x20,0x8a,0x60,0x20,0xb0,0x11,0x23,0x42,0x23,0x2d,0xb0,0x12,0x2c,0x4b,0x54,0x58,0xb1,0x04,0x64,0x44,0x59,0x24,0xb0,0x0d,0x65,0x23,0x78,0x2d,0xb0,0x13,0x2c,0x4b,0x51,0x58,0x4b,0x53,0x58,0xb1,0x04,0x64, -0x44,0x59,0x1b,0x21,0x59,0x24,0xb0,0x13,0x65,0x23,0x78,0x2d,0xb0,0x14,0x2c,0xb1,0x00,0x12,0x43,0x55,0x58,0xb1,0x12,0x12,0x43,0xb0,0x01,0x61,0x42,0xb0,0x11,0x2b,0x59,0xb0,0x00,0x43,0xb0,0x02,0x25,0x42,0xb1,0x0f,0x02,0x25,0x42,0xb1,0x10,0x02,0x25,0x42,0xb0,0x01,0x16,0x23,0x20,0xb0,0x03,0x25,0x50,0x58,0xb1,0x01,0x00,0x43, -0x60,0xb0,0x04,0x25,0x42,0x8a,0x8a,0x20,0x8a,0x23,0x61,0xb0,0x10,0x2a,0x21,0x23,0xb0,0x01,0x61,0x20,0x8a,0x23,0x61,0xb0,0x10,0x2a,0x21,0x1b,0xb1,0x01,0x00,0x43,0x60,0xb0,0x02,0x25,0x42,0xb0,0x02,0x25,0x61,0xb0,0x10,0x2a,0x21,0x59,0xb0,0x0f,0x43,0x47,0xb0,0x10,0x43,0x47,0x60,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0, -0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb1,0x00,0x00,0x13,0x23,0x44,0xb0,0x01,0x43,0xb0,0x00,0x3e,0xb2,0x01,0x01,0x01,0x43,0x60,0x42,0x2d,0xb0,0x15,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb0,0x12,0x23,0x42, -0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60,0x42,0x20,0x60,0xb7,0x18,0x18,0x01,0x00,0x11,0x00,0x13,0x00,0x42,0x42,0x42,0x8a,0x60,0x20,0xb0,0x14,0x23,0x42,0xb0,0x01,0x61,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b,0x1b,0x22,0x59,0x2d,0xb0,0x16,0x2c,0xb1,0x00,0x15,0x2b,0x2d,0xb0,0x17,0x2c,0xb1,0x01,0x15,0x2b,0x2d, -0xb0,0x18,0x2c,0xb1,0x02,0x15,0x2b,0x2d,0xb0,0x19,0x2c,0xb1,0x03,0x15,0x2b,0x2d,0xb0,0x1a,0x2c,0xb1,0x04,0x15,0x2b,0x2d,0xb0,0x1b,0x2c,0xb1,0x05,0x15,0x2b,0x2d,0xb0,0x1c,0x2c,0xb1,0x06,0x15,0x2b,0x2d,0xb0,0x1d,0x2c,0xb1,0x07,0x15,0x2b,0x2d,0xb0,0x1e,0x2c,0xb1,0x08,0x15,0x2b,0x2d,0xb0,0x1f,0x2c,0xb1,0x09,0x15,0x2b,0x2d, -0xb0,0x2b,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x06,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x5d,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2c,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x16,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x71,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2d,0x2c,0x23,0x20,0xb0, -0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x26,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x72,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x20,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02,0x45,0x54,0x58,0xb0,0x12,0x23,0x42,0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60,0x42,0x20,0x60,0xb0,0x01,0x61,0xb5,0x18,0x18,0x01,0x00,0x11, -0x00,0x42,0x42,0x8a,0x60,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b,0x1b,0x22,0x59,0x2d,0xb0,0x21,0x2c,0xb1,0x00,0x20,0x2b,0x2d,0xb0,0x22,0x2c,0xb1,0x01,0x20,0x2b,0x2d,0xb0,0x23,0x2c,0xb1,0x02,0x20,0x2b,0x2d,0xb0,0x24,0x2c,0xb1,0x03,0x20,0x2b,0x2d,0xb0,0x25,0x2c,0xb1,0x04,0x20,0x2b,0x2d,0xb0,0x26,0x2c,0xb1,0x05,0x20,0x2b,0x2d, -0xb0,0x27,0x2c,0xb1,0x06,0x20,0x2b,0x2d,0xb0,0x28,0x2c,0xb1,0x07,0x20,0x2b,0x2d,0xb0,0x29,0x2c,0xb1,0x08,0x20,0x2b,0x2d,0xb0,0x2a,0x2c,0xb1,0x09,0x20,0x2b,0x2d,0xb0,0x2e,0x2c,0x20,0x3c,0xb0,0x01,0x60,0x2d,0xb0,0x2f,0x2c,0x20,0x60,0xb0,0x18,0x60,0x20,0x43,0x23,0xb0,0x01,0x60,0x43,0xb0,0x02,0x25,0x61,0xb0,0x01,0x60,0xb0, -0x2e,0x2a,0x21,0x2d,0xb0,0x30,0x2c,0xb0,0x2f,0x2b,0xb0,0x2f,0x2a,0x2d,0xb0,0x31,0x2c,0x20,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x61,0x38,0x23,0x20,0x8a,0x55,0x58,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62, -0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x61,0x38,0x1b,0x21,0x59,0x2d,0xb0,0x32,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x16,0xb0,0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x33,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02, -0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x16,0xb0,0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x34,0x2c,0x20,0x35,0xb0,0x01,0x60,0x2d,0xb0,0x35,0x2c,0x00,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x45,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01, -0x63,0xb0,0x01,0x2b,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x01,0x2b,0xb0,0x00,0x16,0xb4,0x00,0x00,0x00,0x00,0x00,0x44,0x3e,0x23,0x38,0xb1,0x34,0x01,0x15,0x2a,0x21,0x2d,0xb0,0x36,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62, -0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb0,0x00,0x43,0x61,0x38,0x2d,0xb0,0x37,0x2c,0x2e,0x17,0x3c,0x2d,0xb0,0x38,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb0,0x00,0x43,0x61,0xb0,0x01,0x43, -0x63,0x38,0x2d,0xb0,0x39,0x2c,0xb1,0x02,0x00,0x16,0x25,0x20,0x2e,0x20,0x47,0xb0,0x00,0x23,0x42,0xb0,0x02,0x25,0x49,0x8a,0x8a,0x47,0x23,0x47,0x23,0x61,0x20,0x58,0x62,0x1b,0x21,0x59,0xb0,0x01,0x23,0x42,0xb2,0x38,0x01,0x01,0x15,0x14,0x2a,0x2d,0xb0,0x3a,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25,0xb0,0x04,0x25, -0x47,0x23,0x47,0x23,0x61,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x65,0x8a,0x2e,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x3b,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25,0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x20,0xb0,0x60,0x50,0x58, -0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3,0x04,0x26,0x05,0x1a,0x59,0x42,0x42,0x23,0x20,0xb0,0x0a,0x43,0x20,0x8a,0x23,0x47,0x23,0x47,0x23,0x61,0x23,0x46,0x60,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01,0x2b,0x20,0x8a,0x8a,0x61,0x20, -0xb0,0x04,0x43,0x60,0x64,0x23,0xb0,0x05,0x43,0x61,0x64,0x50,0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x1b,0x23,0xb0,0x0a,0x43,0x46,0xb0,0x02,0x25,0xb0,0x0a, -0x43,0x47,0x23,0x47,0x23,0x61,0x60,0x20,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x06,0x43,0x60,0xb0,0x01,0x2b,0xb0,0x05,0x25,0x61,0xb0,0x05,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63, -0xb0,0x04,0x26,0x61,0x20,0xb0,0x04,0x25,0x60,0x64,0x23,0xb0,0x03,0x25,0x60,0x64,0x50,0x58,0x21,0x1b,0x23,0x21,0x59,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x59,0x2d,0xb0,0x3c,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0x20,0x20,0xb0,0x05,0x26,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x23,0x3c,0x38,0x2d,0xb0,0x3d, -0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x23,0x42,0x20,0x20,0x20,0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x2d,0xb0,0x3e,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x03,0x25,0xb0,0x02,0x25,0x47,0x23,0x47,0x23,0x61,0xb0,0x00,0x54,0x58,0x2e,0x20,0x3c,0x23,0x21,0x1b,0xb0,0x02,0x25,0xb0,0x02,0x25,0x47, -0x23,0x47,0x23,0x61,0x20,0xb0,0x05,0x25,0xb0,0x04,0x25,0x47,0x23,0x47,0x23,0x61,0xb0,0x06,0x25,0xb0,0x05,0x25,0x49,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00,0x63,0x63,0x23,0x20,0x58,0x62,0x1b,0x21,0x59,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x2e,0x23,0x20, -0x20,0x3c,0x8a,0x38,0x23,0x21,0x59,0x2d,0xb0,0x3f,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x43,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0x60,0xb0,0x20,0x60,0x66,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x40,0x2c,0x23,0x20,0x2e, -0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x41,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x42,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25, -0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x43,0x2c,0xb0,0x3a,0x2b,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20, -0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x44,0x2c,0xb0,0x3b,0x2b,0x8a,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x8a,0x38,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x45,0x2c,0xb0,0x00, -0x16,0xb0,0x04,0x25,0xb0,0x04,0x26,0x20,0x20,0x20,0x46,0x23,0x47,0x61,0xb0,0x0c,0x23,0x42,0x2e,0x47,0x23,0x47,0x23,0x61,0xb0,0x0b,0x43,0x2b,0x23,0x20,0x3c,0x20,0x2e,0x23,0x38,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x46,0x2c,0xb1,0x0a,0x04,0x25,0x42,0xb0,0x00,0x16,0xb0,0x04,0x25,0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23, -0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x20,0xb0,0x60,0x50,0x58,0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3,0x04,0x26,0x05,0x1a,0x59,0x42,0x42,0x23,0x20,0x47,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01, -0x2b,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x04,0x43,0x60,0x64,0x23,0xb0,0x05,0x43,0x61,0x64,0x50,0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0xb0,0x02,0x25,0x46,0x61,0x38,0x23,0x20,0x3c,0x23,0x38,0x1b,0x21,0x20,0x20, -0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x21,0x59,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x47,0x2c,0xb1,0x00,0x3a,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x48,0x2c,0xb1,0x00,0x3b,0x2b,0x21,0x23,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x23,0x38,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x49, -0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00,0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4a,0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00,0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4b,0x2c,0xb1,0x00,0x01,0x14,0x13,0xb0,0x37,0x2a,0x2d,0xb0,0x4c,0x2c,0xb0,0x39,0x2a, -0x2d,0xb0,0x4d,0x2c,0xb0,0x00,0x16,0x45,0x23,0x20,0x2e,0x20,0x46,0x8a,0x23,0x61,0x38,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x4e,0x2c,0xb0,0x0a,0x23,0x42,0xb0,0x4d,0x2b,0x2d,0xb0,0x4f,0x2c,0xb2,0x00,0x00,0x46,0x2b,0x2d,0xb0,0x50,0x2c,0xb2,0x00,0x01,0x46,0x2b,0x2d,0xb0,0x51,0x2c,0xb2,0x01,0x00,0x46,0x2b,0x2d,0xb0,0x52,0x2c, -0xb2,0x01,0x01,0x46,0x2b,0x2d,0xb0,0x53,0x2c,0xb2,0x00,0x00,0x47,0x2b,0x2d,0xb0,0x54,0x2c,0xb2,0x00,0x01,0x47,0x2b,0x2d,0xb0,0x55,0x2c,0xb2,0x01,0x00,0x47,0x2b,0x2d,0xb0,0x56,0x2c,0xb2,0x01,0x01,0x47,0x2b,0x2d,0xb0,0x57,0x2c,0xb3,0x00,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x58,0x2c,0xb3,0x00,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x59, -0x2c,0xb3,0x01,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x5a,0x2c,0xb3,0x01,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x5b,0x2c,0xb3,0x00,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5c,0x2c,0xb3,0x00,0x01,0x01,0x43,0x2b,0x2d,0xb0,0x5d,0x2c,0xb3,0x01,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5e,0x2c,0xb3,0x01,0x01,0x01,0x43,0x2b,0x2d,0xb0,0x5f,0x2c,0xb2,0x00,0x00, -0x45,0x2b,0x2d,0xb0,0x60,0x2c,0xb2,0x00,0x01,0x45,0x2b,0x2d,0xb0,0x61,0x2c,0xb2,0x01,0x00,0x45,0x2b,0x2d,0xb0,0x62,0x2c,0xb2,0x01,0x01,0x45,0x2b,0x2d,0xb0,0x63,0x2c,0xb2,0x00,0x00,0x48,0x2b,0x2d,0xb0,0x64,0x2c,0xb2,0x00,0x01,0x48,0x2b,0x2d,0xb0,0x65,0x2c,0xb2,0x01,0x00,0x48,0x2b,0x2d,0xb0,0x66,0x2c,0xb2,0x01,0x01,0x48, -0x2b,0x2d,0xb0,0x67,0x2c,0xb3,0x00,0x00,0x00,0x44,0x2b,0x2d,0xb0,0x68,0x2c,0xb3,0x00,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x69,0x2c,0xb3,0x01,0x00,0x00,0x44,0x2b,0x2d,0xb0,0x6a,0x2c,0xb3,0x01,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x6b,0x2c,0xb3,0x00,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6c,0x2c,0xb3,0x00,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6d, -0x2c,0xb3,0x01,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6e,0x2c,0xb3,0x01,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6f,0x2c,0xb1,0x00,0x3c,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x70,0x2c,0xb1,0x00,0x3c,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x71,0x2c,0xb1,0x00,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x72,0x2c,0xb0,0x00,0x16,0xb1,0x00,0x3c,0x2b, -0xb0,0x42,0x2b,0x2d,0xb0,0x73,0x2c,0xb1,0x01,0x3c,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x74,0x2c,0xb1,0x01,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x75,0x2c,0xb0,0x00,0x16,0xb1,0x01,0x3c,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x76,0x2c,0xb1,0x00,0x3d,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x77,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x40,0x2b, -0x2d,0xb0,0x78,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x79,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7a,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7b,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x7c,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7d,0x2c,0xb1,0x00,0x3e,0x2b,0x2e, -0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x7e,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7f,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x80,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x81,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x82,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x83,0x2c, -0xb1,0x01,0x3e,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x84,0x2c,0xb1,0x00,0x3f,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x85,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x86,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x87,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x88,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x40, -0x2b,0x2d,0xb0,0x89,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x8a,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x8b,0x2c,0xb2,0x0b,0x00,0x03,0x45,0x50,0x58,0xb0,0x06,0x1b,0xb2,0x04,0x02,0x03,0x45,0x58,0x23,0x21,0x1b,0x21,0x59,0x59,0x42,0x2b,0xb0,0x08,0x65,0xb0,0x03,0x24,0x50,0x78,0xb1,0x05,0x01,0x15,0x45, -0x58,0x30,0x59,0x2d,0x00,0x4b,0xb8,0x00,0xc8,0x52,0x58,0xb1,0x01,0x01,0x8e,0x59,0xb0,0x01,0xb9,0x08,0x00,0x08,0x00,0x63,0x70,0xb1,0x00,0x07,0x42,0xb2,0x19,0x01,0x00,0x2a,0xb1,0x00,0x07,0x42,0xb3,0x0d,0x09,0x01,0x0a,0x2a,0xb1,0x00,0x07,0x42,0xb3,0x16,0x06,0x01,0x0a,0x2a,0xb1,0x00,0x08,0x42,0xba,0x03,0x80,0x00,0x01,0x00, -0x0b,0x2a,0xb1,0x00,0x09,0x42,0xba,0x00,0x80,0x00,0x01,0x00,0x0b,0x2a,0xb9,0x00,0x03,0x00,0x00,0x44,0xb1,0x24,0x01,0x88,0x51,0x58,0xb0,0x40,0x88,0x58,0xb9,0x00,0x03,0x00,0x64,0x44,0xb1,0x28,0x01,0x88,0x51,0x58,0xb8,0x08,0x00,0x88,0x58,0xb9,0x00,0x03,0x00,0x00,0x44,0x59,0x1b,0xb1,0x27,0x01,0x88,0x51,0x58,0xba,0x08,0x80, -0x00,0x01,0x04,0x40,0x88,0x63,0x54,0x58,0xb9,0x00,0x03,0x00,0x00,0x44,0x59,0x59,0x59,0x59,0x59,0xb3,0x10,0x06,0x01,0x0e,0x2a,0xb8,0x01,0xff,0x85,0xb0,0x04,0x8d,0xb1,0x02,0x00,0x44,0xb3,0x05,0x64,0x06,0x00,0x44,0x44,0x00, +0x02,0xdb,0x00,0x21,0x00,0x31,0x00,0x2f,0x40,0x2c,0x11,0x06,0x02,0x00,0x03,0x01,0x4c,0x00,0x01,0x00,0x01,0x86,0x00,0x02,0x00,0x04,0x03,0x02,0x04,0x69,0x00,0x03,0x00,0x00,0x03,0x59,0x00,0x03,0x03,0x00,0x61,0x00,0x00,0x03,0x00,0x51,0x15,0x2b,0x1d,0x25,0x22,0x05,0x07,0x1b,0x2b,0x01,0x0e,0x01,0x23,0x22,0x26,0x27,0x0f,0x01, +0x06,0x23,0x22,0x26,0x35,0x34,0x3f,0x02,0x2e,0x01,0x35,0x34,0x37,0x3e,0x01,0x32,0x17,0x16,0x17,0x16,0x15,0x14,0x07,0x06,0x25,0x1e,0x01,0x33,0x32,0x3e,0x01,0x34,0x2e,0x01,0x22,0x0e,0x01,0x15,0x14,0x16,0x02,0xa8,0x29,0x66,0x36,0x31,0x5d,0x28,0x33,0x82,0x15,0x18,0x1e,0x2d,0x0f,0x81,0x7e,0x20,0x22,0x27,0x25,0x80,0x95,0x40, +0x3f,0x26,0x26,0x14,0x14,0xfe,0x99,0x19,0x40,0x21,0x2d,0x4f,0x2e,0x2f,0x4e,0x5b,0x4f,0x2f,0x1a,0x01,0x00,0x29,0x2a,0x22,0x20,0x7d,0x82,0x0f,0x2f,0x1e,0x1a,0x13,0x82,0x33,0x26,0x5e,0x32,0x4b,0x40,0x3f,0x4b,0x27,0x25,0x3f,0x41,0x4a,0x38,0x32,0x34,0x24,0x18,0x1a,0x2e,0x4f,0x5d,0x4e,0x2e,0x2f,0x4e,0x2d,0x22,0x40,0x00,0x00, +0x00,0x02,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x19,0x00,0x28,0x40,0x25,0x04,0x01,0x00,0x00,0x03,0x61,0x00,0x03,0x03,0x13,0x4d,0x00,0x01,0x01,0x02,0x61,0x00,0x02,0x02,0x11,0x02,0x4e,0x01,0x00,0x17,0x16,0x11,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x05,0x07,0x16,0x2b,0x01,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e, +0x01,0x2e,0x02,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x01,0xad,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x02,0x8e,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74, +0x74,0xc4,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x4d,0x02,0xff,0x00,0x06,0x00,0x14,0x00,0x19,0x00,0x24,0x00,0xe3,0x40,0x17,0x1e,0x01,0x02,0x05,0x1d,0x16,0x0e,0x07,0x04,0x03,0x02,0x19,0x03,0x02,0x03,0x00,0x03,0x01,0x01,0x01,0x00,0x04,0x4c,0x4b,0xb0,0x0a,0x50,0x58,0x40,0x26,0x00,0x02,0x05,0x03,0x05,0x02,0x03,0x80, +0x00,0x03,0x00,0x00,0x03,0x70,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x05,0x05,0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x4b,0xb0,0x12,0x50,0x58,0x40,0x27,0x00,0x02,0x05,0x03,0x05,0x02,0x03,0x80,0x00,0x03,0x00,0x05,0x03,0x00,0x7e,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x05,0x05, +0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x4b,0xb0,0x29,0x50,0x58,0x40,0x28,0x00,0x02,0x05,0x03,0x05,0x02,0x03,0x80,0x00,0x03,0x00,0x05,0x03,0x00,0x7e,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x04,0x80,0x00,0x05,0x05,0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x40,0x23, +0x00,0x05,0x02,0x05,0x85,0x00,0x02,0x03,0x02,0x85,0x00,0x03,0x00,0x03,0x85,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x04,0x80,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x59,0x59,0x59,0x40,0x12,0x00,0x00,0x21,0x20,0x18,0x17,0x10,0x0f,0x09,0x08,0x00,0x06,0x00,0x06,0x14,0x07,0x07,0x17,0x2b,0x17,0x37,0x27,0x07,0x15, +0x33,0x15,0x01,0x34,0x23,0x22,0x07,0x01,0x06,0x15,0x14,0x33,0x32,0x37,0x01,0x36,0x27,0x17,0x01,0x23,0x35,0x01,0x14,0x0f,0x01,0x27,0x37,0x36,0x32,0x1f,0x01,0x16,0xcb,0x32,0x83,0x33,0x48,0x01,0x5f,0x0c,0x05,0x04,0xfe,0xd1,0x04,0x0d,0x05,0x04,0x01,0x2f,0x03,0x1e,0xe8,0xfe,0x30,0xe8,0x03,0x4d,0x14,0x5d,0xe8,0x5d,0x14,0x3b, +0x16,0x83,0x14,0x07,0x33,0x83,0x33,0x3c,0x47,0x02,0x06,0x0c,0x04,0xfe,0xd2,0x04,0x06,0x0c,0x04,0x01,0x2e,0x04,0x71,0xe8,0xfe,0x2f,0xe9,0x01,0x9a,0x1d,0x15,0x5d,0xe9,0x5c,0x15,0x15,0x83,0x16,0x00,0x00,0x00,0x05,0xff,0xff,0xff,0xf9,0x03,0x59,0x02,0xc4,0x00,0x08,0x00,0x11,0x00,0x21,0x00,0x2b,0x00,0x41,0x00,0x8e,0x40,0x0f, +0x13,0x01,0x01,0x04,0x09,0x00,0x02,0x00,0x01,0x1b,0x01,0x05,0x00,0x03,0x4c,0x4b,0xb0,0x0a,0x50,0x58,0x40,0x30,0x03,0x01,0x01,0x04,0x00,0x04,0x01,0x00,0x80,0x02,0x01,0x00,0x05,0x08,0x00,0x70,0x00,0x09,0x00,0x07,0x06,0x09,0x07,0x67,0x00,0x06,0x00,0x04,0x01,0x06,0x04,0x67,0x00,0x05,0x08,0x08,0x05,0x58,0x00,0x05,0x05,0x08, +0x60,0x00,0x08,0x05,0x08,0x50,0x1b,0x40,0x31,0x03,0x01,0x01,0x04,0x00,0x04,0x01,0x00,0x80,0x02,0x01,0x00,0x05,0x04,0x00,0x05,0x7e,0x00,0x09,0x00,0x07,0x06,0x09,0x07,0x67,0x00,0x06,0x00,0x04,0x01,0x06,0x04,0x67,0x00,0x05,0x08,0x08,0x05,0x58,0x00,0x05,0x05,0x08,0x60,0x00,0x08,0x05,0x08,0x50,0x59,0x40,0x0e,0x3d,0x3a,0x37, +0x23,0x13,0x26,0x25,0x13,0x14,0x13,0x12,0x0a,0x07,0x1f,0x2b,0x25,0x14,0x06,0x22,0x26,0x3e,0x01,0x1e,0x01,0x17,0x14,0x06,0x22,0x26,0x3e,0x01,0x1e,0x01,0x17,0x35,0x34,0x26,0x27,0x21,0x22,0x06,0x07,0x15,0x14,0x16,0x17,0x21,0x32,0x36,0x01,0x21,0x03,0x2e,0x01,0x23,0x21,0x22,0x06,0x07,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26, +0x37,0x35,0x34,0x37,0x13,0x3e,0x01,0x17,0x21,0x32,0x16,0x17,0x13,0x16,0x02,0x44,0x1a,0x24,0x1c,0x02,0x18,0x28,0x16,0x91,0x1a,0x24,0x1c,0x02,0x18,0x28,0x16,0x41,0x0c,0x06,0xfd,0x59,0x07,0x0a,0x01,0x0c,0x06,0x02,0xa7,0x07,0x0a,0xfd,0x52,0x02,0x93,0x58,0x02,0x0e,0x07,0xfe,0x4b,0x07,0x0e,0x02,0x02,0x9e,0x34,0x25,0xfd,0x59, +0x24,0x36,0x01,0x09,0x6e,0x09,0x34,0x1e,0x01,0xb5,0x1f,0x32,0x0a,0x6e,0x09,0xab,0x12,0x1a,0x1a,0x24,0x1c,0x02,0x18,0x14,0x12,0x1a,0x1a,0x24,0x1c,0x02,0x18,0x6d,0xb3,0x07,0x0a,0x01,0x0c,0x06,0xb3,0x07,0x0a,0x01,0x0c,0x01,0x12,0x01,0x0d,0x07,0x0a,0x0a,0x07,0xfe,0x9a,0xb3,0x25,0x34,0x34,0x25,0xb3,0x0e,0x1c,0x01,0x52,0x1d, +0x26,0x01,0x24,0x1e,0xfe,0xae,0x1c,0x00,0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x01,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x01,0x4a,0x02,0x01,0x00,0x49,0x00,0x01,0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x11,0x13,0x02,0x07,0x18,0x2b,0x09,0x02,0x35,0x21, +0x11,0x21,0x01,0x5e,0x01,0x7c,0xfe,0x84,0xfe,0xa2,0x01,0x5e,0x02,0xda,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x7a,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xab,0x03,0x6b,0x03,0x20,0x00,0x0f,0x00,0x13,0x00,0x1f,0x00,0x38,0x40,0x35,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x0b,0x03,0x02,0x01,0x4c,0x00,0x02,0x02,0x00, +0x5f,0x04,0x01,0x00,0x00,0x10,0x4d,0x00,0x03,0x03,0x01,0x5f,0x00,0x01,0x01,0x11,0x01,0x4e,0x01,0x00,0x13,0x12,0x11,0x10,0x09,0x06,0x00,0x0f,0x01,0x0e,0x05,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x07,0x17,0x07,0x17,0x37,0x17,0x37,0x27,0x37, +0x27,0x07,0x87,0x0c,0x11,0x11,0x0c,0x02,0xc6,0x0c,0x11,0x11,0x0c,0xfd,0x58,0x02,0x8b,0xfd,0x75,0x01,0x87,0x2d,0x52,0x52,0x2d,0x53,0x52,0x2e,0x53,0x53,0x2e,0x52,0x03,0x1f,0x12,0x0c,0xfc,0xc8,0x0c,0x11,0x11,0x0c,0x03,0x38,0x0c,0x12,0x3b,0xfd,0x02,0x02,0xcb,0x2e,0x52,0x53,0x2d,0x52,0x52,0x2d,0x53,0x52,0x2e,0x52,0x00,0x00, +0x00,0x04,0x00,0x00,0xff,0x84,0x03,0x8f,0x03,0x33,0x00,0x02,0x00,0x10,0x00,0x3c,0x00,0x68,0x01,0x4d,0x40,0x0b,0x01,0x01,0x0a,0x02,0x62,0x36,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x36,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x72,0x0e,0x05,0x02,0x02,0x0a,0x0a,0x02,0x59,0x0d, +0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b,0x4b,0xb0,0x13,0x50,0x58,0x40,0x3c,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x70,0x0e,0x05,0x02,0x02,0x0a, +0x0a,0x02,0x59,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b,0x4b,0xb0,0x16,0x50,0x58,0x40,0x3d,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e, +0x0e,0x05,0x02,0x02,0x0a,0x0a,0x02,0x59,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b,0x40,0x44,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e, +0x00,0x03,0x04,0x0a,0x03,0x57,0x0e,0x05,0x02,0x02,0x0f,0x01,0x0a,0x06,0x02,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x59,0x59,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x68,0x66,0x5e,0x5c,0x5b,0x59,0x4d,0x4b,0x4a, +0x48,0x3f,0x3d,0x3c,0x3a,0x32,0x30,0x2f,0x2d,0x21,0x1f,0x1e,0x1c,0x13,0x11,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27,0x25,0x22,0x06,0x1d,0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x13,0x33,0x32,0x16,0x1d,0x01,0x14,0x16,0x17,0x16,0x17,0x16,0x3b,0x01, +0x15,0x23,0x22,0x07,0x06,0x07,0x06,0x07,0x06,0x1d,0x01,0x14,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x36,0x37,0x36,0x37,0x36,0x3d,0x01,0x34,0x37,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01, +0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0x90,0x63,0x64,0xfe,0xcd,0x0d,0x13,0x3f,0x01,0x58,0x3f,0x12,0x0d,0x55,0x1b,0x47,0x45,0x07,0x0b,0x09,0x12,0x0e,0x1c,0x0f,0x0f,0x1a,0x12,0x0f,0x0c,0x08,0x05,0x03,0x0f,0x22,0x34,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10, +0x1c,0x20,0x0a,0x08,0x05,0x04,0x07,0x07,0x23,0x33,0x27,0x1b,0x15,0x55,0x4e,0x4e,0x55,0x15,0x02,0xb1,0xac,0xac,0x82,0x12,0x0d,0xe7,0xc7,0x2e,0x4e,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x09,0x0a,0x05,0x05,0x33,0x05,0x03,0x0a,0x08,0x0f,0x0d,0x14,0x80,0x1d,0x33,0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54, +0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09,0x0b,0x33,0x08,0x09,0x08,0x0f,0x14,0x0d,0x57,0x21,0x16,0x19,0x24,0x12,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x17,0x40,0x14,0x06,0x01,0x00,0x4a,0x02,0x01,0x00,0x01,0x00,0x85,0x00,0x01, +0x01,0x76,0x11,0x11,0x10,0x03,0x07,0x19,0x2b,0x01,0x23,0x11,0x21,0x11,0x23,0x01,0x02,0xf8,0xc0,0xfe,0x88,0xc0,0x01,0x7c,0x01,0x50,0xfe,0xa2,0x01,0x5e,0x01,0x7c,0x00,0x01,0x00,0x00,0x00,0x00,0x03,0xa5,0x02,0x98,0x00,0x15,0x00,0x1d,0x40,0x1a,0x0f,0x01,0x00,0x01,0x01,0x4c,0x00,0x02,0x01,0x02,0x85,0x00,0x01,0x00,0x01,0x85, +0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x03,0xa5,0x10,0xfe,0x20,0x10,0x2c,0x10,0xfe,0xea,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0x01,0x6e,0x10,0x2c,0x10,0x4c,0x10,0x02,0x16,0x16,0x10,0xfe,0x20,0x0f, +0x0f,0x01,0x16,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa5,0x01,0x6f,0x10,0x10,0x4c,0x0f,0x00,0x03,0xff,0xf5,0xff,0xb1,0x03,0xf3,0x03,0x52,0x00,0x0f,0x00,0x21,0x00,0x33,0x00,0x33,0x40,0x30,0x1b,0x11,0x02,0x03,0x02,0x09,0x01,0x02,0x01,0x00,0x02,0x4c,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67, +0x00,0x01,0x01,0x04,0x5f,0x00,0x04,0x04,0x11,0x04,0x4e,0x17,0x38,0x27,0x27,0x26,0x23,0x06,0x07,0x1c,0x2b,0x25,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x1d,0x01,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34,0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x17,0x14,0x16,0x37,0x33,0x32,0x36,0x03,0x01,0x16,0x07,0x0e,0x01,0x07,0x21,0x22, +0x26,0x27,0x26,0x37,0x01,0x3e,0x01,0x32,0x16,0x02,0x3b,0x0a,0x07,0x6c,0x07,0x0a,0x0a,0x07,0x6c,0x07,0x0a,0x01,0x0a,0x05,0x07,0x07,0x7a,0x06,0x08,0x05,0x09,0x0c,0x07,0x67,0x08,0x0c,0x08,0x01,0xac,0x14,0x15,0x09,0x22,0x12,0xfc,0xa6,0x12,0x22,0x09,0x15,0x14,0x01,0xad,0x09,0x22,0x26,0x22,0x53,0x6a,0x08,0x0a,0x0a,0x08,0x6a, +0x08,0x0a,0x01,0x0c,0xd7,0x01,0x01,0x06,0x04,0x06,0x06,0x04,0x08,0xff,0x05,0x08,0x01,0x06,0x02,0x10,0xfc,0xee,0x23,0x23,0x11,0x12,0x01,0x14,0x10,0x23,0x23,0x03,0x12,0x11,0x14,0x14,0x00,0x04,0x00,0x00,0xff,0x79,0x03,0xd1,0x03,0x3c,0x00,0x0f,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x36,0x40,0x33,0x07,0x01,0x05,0x03,0x01,0x01, +0x05,0x01,0x63,0x06,0x01,0x04,0x04,0x00,0x5f,0x09,0x02,0x08,0x03,0x00,0x00,0x12,0x04,0x4e,0x11,0x10,0x01,0x00,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x19,0x16,0x10,0x1f,0x11,0x1e,0x09,0x06,0x00,0x0f,0x01,0x0e,0x0a,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x33,0x22, +0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x21,0x11,0x21,0x38,0x0d,0x13,0x13,0x0d,0x01,0x7c,0x0d,0x12,0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0x01,0x7d,0x0d,0x12,0x12,0x0d,0xfc,0xa6,0x01,0x3e,0xfe,0xc2,0x01,0xfc,0x01,0x3e,0xfe,0xc2,0x03,0x3b,0x12,0x0d,0xfc,0x7d,0x0d,0x12, +0x12,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d,0x12,0x12,0x0d,0x03,0x83,0x0d,0x12,0x3e,0xfc,0xbb,0x03,0x45,0xfc,0xbb,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x7e,0x03,0xd6,0x03,0x37,0x00,0x0f,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x3d,0x40,0x3a,0x00,0x04,0x00,0x01,0x02,0x04,0x01,0x67,0x00,0x02,0x09,0x01,0x07,0x06, +0x02,0x07,0x67,0x00,0x06,0x00,0x03,0x06,0x03,0x63,0x08,0x01,0x05,0x05,0x00,0x5f,0x00,0x00,0x00,0x12,0x05,0x4e,0x24,0x24,0x20,0x20,0x24,0x27,0x24,0x27,0x26,0x25,0x20,0x23,0x20,0x23,0x14,0x35,0x35,0x35,0x32,0x0a,0x07,0x1b,0x2b,0x01,0x34,0x26,0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x15,0x34,0x26, +0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x03,0x11,0x21,0x11,0x01,0x11,0x21,0x11,0x03,0xd5,0x12,0x0d,0xfc,0x7d,0x0d,0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d,0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x3f,0xfc,0xbc,0x03,0x44,0xfc,0xbc,0x03,0x17,0x0d,0x12,0x12,0x0d,0xfe,0x84,0x0d,0x12, +0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0xfe,0x83,0x0d,0x12,0x12,0x0d,0x03,0x5a,0xfe,0xc2,0x01,0x3e,0xfe,0x04,0xfe,0xc1,0x01,0x3f,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x89,0x03,0xdc,0x03,0x38,0x00,0x02,0x00,0x10,0x00,0x39,0x00,0x62,0x01,0x0d,0x40,0x0b,0x01,0x01,0x06,0x0a,0x5c,0x33,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x1c, +0x50,0x58,0x40,0x38,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x02,0x80,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x0a,0x4e,0x1b,0x4b,0xb0,0x21, +0x50,0x58,0x40,0x3f,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x02,0x80,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f,0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08, +0x09,0x08,0x51,0x1b,0x40,0x45,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f,0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10, +0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x59,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x62,0x60,0x58,0x56,0x55,0x53,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x1f,0x1d,0x1c,0x1a,0x13,0x11,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27, +0x25,0x22,0x06,0x1d,0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x01,0x33,0x32,0x16,0x1d,0x01,0x14,0x1e,0x02,0x3b,0x01,0x15,0x23,0x22,0x07,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01, +0x2b,0x01,0x35,0x33,0x32,0x3e,0x02,0x3d,0x01,0x34,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x03,0xdc,0x63,0x64,0xfd,0x31,0x0d,0x13,0x3f,0x02,0xf4,0x3f,0x12,0x0d,0xfe,0xb9,0x1b,0x47,0x45,0x07,0x16,0x22,0x18,0x10,0x10,0x16,0x16,0x10,0x14,0x07,0x08,0x06,0x21,0x38,0x25,0x1b,0x16, +0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10,0x1c,0x1f,0x15,0x07,0x0f,0x21,0x34,0x27,0x1b,0x15,0x55,0x4d,0x4e,0x54,0x15,0x02,0x85,0xad,0xad,0xb3,0x12,0x0d,0xe7,0xc7,0x6d,0x8d,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x13,0x0a,0x33,0x04,0x04,0x12,0x1c,0x14,0x80,0x1d,0x1a,0x19, +0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54,0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09,0x0b,0x33,0x08,0x13,0x1a,0x14,0x57,0x20,0x30,0x23,0x13,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x43,0x00,0x44,0x40,0x41, +0x18,0x01,0x03,0x04,0x13,0x01,0x02,0x00,0x03,0x06,0x01,0x01,0x00,0x03,0x4c,0x05,0x01,0x03,0x02,0x01,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x00,0x01,0x07,0x04,0x01,0x69,0x00,0x07,0x00,0x08,0x07,0x08,0x63,0x00,0x06,0x06,0x09,0x5f,0x00,0x09,0x09,0x13,0x06,0x4e,0x42,0x3f,0x35,0x35,0x36,0x14,0x23,0x26,0x14,0x23,0x23,0x0a,0x07, +0x1f,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x33,0x32,0x16,0x13,0x11,0x34,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11, +0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x47,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0xc4,0x08, +0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x07,0x0a,0xc5,0x08,0x0a,0x0a,0x08,0xc5,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x2d,0x40,0x2a, +0x09,0x01,0x02,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x67,0x00,0x03,0x00,0x04,0x03,0x04,0x63,0x00,0x02,0x02,0x05,0x5f,0x00,0x05,0x05,0x13,0x02,0x4e,0x35,0x35,0x35,0x36,0x26,0x23,0x06,0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x3d,0x01,0x34,0x36,0x33,0x21,0x32,0x16,0x13,0x11,0x34,0x26,0x23, +0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xfe,0x30,0x08,0x0a,0x0a,0x08,0x01,0xd0,0x08,0x0a,0x47,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43, +0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58,0x01,0xd4,0x00,0x15,0x00,0x21,0xb1,0x06,0x64,0x44,0x40,0x16, +0x07,0x01,0x00,0x02,0x01,0x4c,0x00,0x02,0x00,0x02,0x85,0x01,0x01,0x00,0x00,0x76,0x17,0x14,0x14,0x03,0x07,0x19,0x2b,0xb1,0x06,0x00,0x44,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01,0x26,0x34,0x37,0x01,0x36,0x32,0x17,0x01,0x16,0x02,0x58,0x06,0x1c,0x05,0x0e,0x06,0xdc,0xdb,0x05,0x10,0x04,0x1c,0x06,0x06, +0x01,0x04,0x05,0x0e,0x06,0x01,0x04,0x06,0xbd,0x07,0x05,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0xfe,0xfc,0x05,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0x89,0x03,0x42,0x03,0x33,0x00,0x0f,0x00,0x19,0x00,0x33,0x00,0x3f,0x00,0x4b,0x00,0x57,0x00,0x8c,0x40,0x89,0x56,0x01,0x0c,0x0d,0x44,0x01, +0x0a,0x0b,0x3e,0x01,0x08,0x09,0x03,0x4c,0x00,0x02,0x03,0x05,0x03,0x02,0x05,0x80,0x00,0x05,0x0d,0x03,0x05,0x0d,0x7e,0x00,0x0b,0x0c,0x0a,0x0c,0x0b,0x0a,0x80,0x00,0x0a,0x09,0x0c,0x0a,0x09,0x7e,0x00,0x09,0x08,0x0c,0x09,0x08,0x7e,0x10,0x01,0x08,0x07,0x0c,0x08,0x07,0x7e,0x00,0x0d,0x11,0x01,0x0c,0x0b,0x0d,0x0c,0x67,0x00,0x07, +0x00,0x01,0x07,0x01,0x64,0x06,0x04,0x0f,0x03,0x03,0x03,0x00,0x5f,0x0e,0x01,0x00,0x00,0x12,0x03,0x4e,0x4e,0x4c,0x36,0x34,0x10,0x10,0x01,0x00,0x54,0x52,0x4c,0x57,0x4e,0x57,0x48,0x45,0x42,0x40,0x3c,0x3a,0x34,0x3f,0x36,0x3f,0x32,0x2f,0x2a,0x28,0x25,0x22,0x1f,0x1d,0x10,0x19,0x10,0x19,0x16,0x13,0x09,0x06,0x00,0x0f,0x01,0x0e, +0x12,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x17,0x15,0x14,0x16,0x3b,0x01,0x32,0x36,0x3d,0x01,0x13,0x11,0x34,0x26,0x07,0x23,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x37,0x35,0x23,0x22,0x06,0x17,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x27,0x21,0x22,0x35,0x34,0x36,0x37,0x21, +0x32,0x16,0x07,0x14,0x27,0x21,0x22,0x26,0x37,0x34,0x33,0x21,0x32,0x15,0x14,0x06,0x27,0x21,0x22,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x07,0x14,0x02,0xa6,0x41,0x5a,0x01,0x5c,0x40,0xfd,0xf6,0x41,0x5a,0x01,0x5c,0x40,0x68,0x20,0x15,0xd0,0x16,0x1e,0x9c,0x1e,0x15,0x35,0x3c,0x2c,0xd0,0x2b,0x3e,0x01,0x35,0x15,0x20,0x01,0x1e,0x16, +0x02,0x0a,0x15,0x1e,0x68,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x1a,0xfe,0x60,0x0b,0x10,0x01,0x1a,0x01,0xa0,0x1a,0x0e,0x0c,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x03,0x33,0x5c,0x40,0xfd,0x8f,0x41,0x5c,0x5c,0x41,0x02,0x71,0x41,0x5a,0x01,0x68,0x34,0x15,0x20,0x20,0x15,0x34,0xfd,0x5b,0x02,0x71,0x15, +0x20,0x01,0x34,0x2b,0x3c,0x01,0x3e,0x2a,0x34,0x1e,0x16,0xfd,0x8f,0x15,0x20,0x20,0x49,0x19,0x0c,0x0e,0x01,0x10,0x0b,0x19,0x9d,0x0e,0x0c,0x19,0x19,0x0b,0x10,0x9d,0x19,0x0b,0x10,0x01,0x0e,0x0c,0x19,0x00,0x00,0x03,0x00,0x00,0xff,0xf9,0x04,0x29,0x03,0x0b,0x00,0x11,0x00,0x27,0x00,0x45,0x00,0x4b,0x40,0x48,0x24,0x01,0x01,0x00, +0x01,0x4c,0x00,0x07,0x04,0x03,0x04,0x07,0x03,0x80,0x00,0x03,0x02,0x04,0x03,0x02,0x7e,0x08,0x09,0x02,0x02,0x00,0x00,0x01,0x02,0x00,0x68,0x00,0x01,0x00,0x05,0x01,0x05,0x63,0x00,0x04,0x04,0x06,0x5f,0x00,0x06,0x06,0x13,0x04,0x4e,0x13,0x12,0x42,0x40,0x3d,0x3b,0x38,0x35,0x30,0x2d,0x21,0x1e,0x19,0x16,0x12,0x27,0x13,0x27,0x36, +0x31,0x0a,0x07,0x18,0x2b,0x01,0x34,0x23,0x21,0x22,0x06,0x0f,0x01,0x06,0x15,0x14,0x33,0x21,0x32,0x36,0x3f,0x01,0x36,0x25,0x21,0x35,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x26,0x07,0x23,0x22,0x06,0x15,0x11,0x37,0x3e,0x01,0x05,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d, +0x01,0x21,0x32,0x16,0x17,0x15,0x33,0x32,0x16,0x17,0x16,0x03,0xe2,0x1e,0xfd,0xa1,0x16,0x34,0x0d,0xa4,0x0b,0x1e,0x02,0x5f,0x17,0x32,0x0f,0xa4,0x0a,0xfd,0x83,0x01,0xad,0x20,0x16,0xfe,0xbf,0x17,0x1e,0x01,0x1e,0x17,0xb3,0x16,0x20,0x8f,0x19,0x50,0x02,0xea,0x19,0xa5,0x18,0x52,0x25,0xfd,0xa1,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a, +0x01,0x2f,0x34,0x48,0x01,0x6b,0x1e,0x34,0x0b,0x08,0x01,0x4b,0x13,0x18,0x11,0xcb,0x0d,0x09,0x14,0x1a,0x10,0xcb,0x0c,0x64,0x5a,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfe,0x24,0xaf,0x1e,0x26,0x5a,0x23,0x20,0xcb,0x1e,0x26,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x33,0x5a,0x1a,0x1b,0x11,0x00,0x00, +0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x17,0x00,0x2c,0x00,0x26,0x40,0x23,0x00,0x05,0x00,0x00,0x02,0x05,0x00,0x67,0x00,0x02,0x00,0x03,0x02,0x03,0x63,0x00,0x01,0x01,0x04,0x5f,0x00,0x04,0x04,0x13,0x01,0x4e,0x23,0x35,0x35,0x35,0x35,0x33,0x06,0x07,0x1c,0x2b,0x25,0x11,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35, +0x34,0x26,0x07,0x23,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0x59,0x1e,0x17,0xfe,0x77,0x17,0x1e,0x01,0x1e,0x17,0xb3,0x16,0x20,0x20,0x16,0x02,0xa7,0x16,0x20,0x47,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33, +0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x76,0x01,0x89,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfd,0xe8,0x16,0x20,0x20,0x01,0x9f,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb8,0x03,0x94,0x03,0x1f,0x00,0x02,0x00,0x10,0x00,0x39,0x00,0x66,0x01,0x0d, +0x40,0x0b,0x60,0x33,0x02,0x07,0x06,0x01,0x01,0x02,0x07,0x02,0x4c,0x4b,0xb0,0x13,0x50,0x58,0x40,0x38,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x08,0x12,0x04,0x11,0x05,0x00,0x01,0x09,0x00,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f, +0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x4b,0xb0,0x1b,0x50,0x58,0x40,0x3f,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x12,0x04,0x11,0x03,0x00,0x08,0x01,0x08,0x00,0x01,0x80,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01,0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09, +0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x40,0x45,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x11,0x01,0x00,0x08,0x04,0x08,0x00,0x04,0x80,0x12,0x01,0x04,0x01,0x08,0x04,0x01,0x7e,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01, +0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x59,0x59,0x40,0x2d,0x03,0x03,0x00,0x00,0x66,0x64,0x5c,0x5a,0x59,0x57,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x20,0x1e,0x1d,0x1b,0x13,0x11,0x03,0x10,0x03,0x10,0x0d, +0x0a,0x07,0x06,0x05,0x04,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x25,0x37,0x17,0x07,0x15,0x21,0x35,0x23,0x15,0x14,0x16,0x33,0x21,0x32,0x36,0x3d,0x01,0x01,0x33,0x32,0x16,0x1d,0x01,0x14,0x17,0x1e,0x02,0x3b,0x01,0x15,0x23,0x22,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d, +0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x3e,0x01,0x37,0x36,0x3d,0x01,0x34,0x37,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0xcd,0x64,0x63,0x82,0xfe,0xa7,0x3e,0x12,0x0d,0x01,0x97,0x0d,0x13,0xfe, +0xa0,0x1c,0x47,0x44,0x04,0x05,0x11,0x25,0x18,0x10,0x10,0x1c,0x20,0x14,0x07,0x07,0x07,0x22,0x35,0x26,0x1c,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa7,0x1b,0x48,0x44,0x04,0x05,0x09,0x0a,0x23,0x18,0x0f,0x0f,0x1d,0x20,0x13,0x03,0x04,0x07,0x08,0x10,0x10,0x1b,0x1b,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0x6a,0xac,0xac,0x09,0x6a,0xb3, +0xd3,0x0d,0x12,0x12,0x0d,0x8a,0x02,0xbe,0x42,0x44,0x54,0x14,0x0c,0x10,0x10,0x0c,0x33,0x08,0x14,0x19,0x15,0x80,0x21,0x16,0x19,0x23,0x12,0x33,0x52,0x7f,0x59,0x0b,0x09,0x5c,0x54,0x54,0xfd,0x8b,0x42,0x43,0x7e,0x14,0x0c,0x10,0x08,0x0b,0x09,0x33,0x09,0x12,0x0e,0x0c,0x15,0x56,0x1a,0x1e,0x18,0x12,0x10,0x0b,0x09,0x33,0x53,0x55, +0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x03,0xff,0xfe,0x00,0x00,0x03,0xe8,0x02,0x60,0x00,0x20,0x00,0x24,0x00,0x28,0x00,0x36,0x40,0x33,0x00,0x00,0x08,0x06,0x07,0x03,0x04,0x03,0x00,0x04,0x67,0x05,0x01,0x03,0x01,0x01,0x03,0x57,0x05,0x01,0x03,0x03,0x01,0x5f,0x02,0x01,0x01,0x03,0x01,0x4f,0x25,0x25,0x21,0x21,0x25,0x28, +0x25,0x28,0x27,0x26,0x21,0x24,0x21,0x24,0x14,0x27,0x2a,0x18,0x09,0x07,0x1a,0x2b,0x11,0x26,0x37,0x25,0x36,0x17,0x16,0x0f,0x01,0x21,0x27,0x26,0x37,0x36,0x17,0x05,0x16,0x07,0x03,0x06,0x23,0x21,0x26,0x2f,0x01,0x26,0x0f,0x01,0x06,0x23,0x21,0x26,0x27,0x37,0x17,0x21,0x37,0x33,0x17,0x21,0x37,0x02,0x0a,0x01,0x68,0x1d,0x0c,0x0b, +0x19,0xe3,0x02,0x92,0xe4,0x19,0x0b,0x0e,0x1d,0x01,0x6a,0x0b,0x02,0x1b,0x08,0x19,0xfe,0xc7,0x19,0x06,0x31,0x27,0x35,0x32,0x06,0x1a,0xfe,0xc8,0x1b,0x04,0x27,0x13,0x01,0x04,0x2b,0xdd,0x29,0x01,0x03,0x14,0x01,0x82,0x0d,0x0c,0xba,0x0b,0x1b,0x21,0x0c,0x68,0x68,0x10,0x1d,0x1b,0x0b,0xba,0x0c,0x0d,0xff,0x00,0x1e,0x02,0x18,0xdf, +0x19,0x18,0xe0,0x1a,0x02,0x1c,0xe2,0xbd,0xbd,0xbd,0xbd,0x00,0x00,0x03,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x13,0x00,0x1a,0x00,0x23,0x00,0x39,0x40,0x36,0x14,0x01,0x02,0x04,0x01,0x4c,0x00,0x01,0x00,0x04,0x02,0x01,0x04,0x67,0x00,0x02,0x00,0x03,0x05,0x02,0x03,0x67,0x06,0x01,0x05,0x00,0x00,0x05,0x57,0x06,0x01,0x05, +0x05,0x00,0x5f,0x00,0x00,0x05,0x00,0x4f,0x1b,0x1b,0x1b,0x23,0x1b,0x23,0x13,0x26,0x14,0x35,0x36,0x07,0x07,0x1b,0x2b,0x01,0x1e,0x01,0x15,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x17,0x07,0x15,0x33,0x26,0x2f,0x01,0x26,0x13,0x11,0x23,0x22,0x26,0x27,0x35,0x21,0x11,0x03,0x33,0x10,0x16,0x1e, +0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xf4,0x16,0x36,0x0f,0x4a,0xd2,0x05,0x07,0xaf,0x06,0xc6,0xe8,0x17,0x1e,0x01,0xfe,0x53,0x02,0x7e,0x10,0x34,0x18,0xfd,0x7e,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c,0x17,0x1e,0x01,0x16,0x10,0x26,0xd2,0x11,0x06,0xaf,0x07,0xfc,0xb0,0x02,0x3c,0x20,0x15,0xe9,0xfc,0xa6,0x00,0x01,0x00,0x00, +0xff,0xaa,0x03,0x11,0x03,0x13,0x00,0x0b,0x00,0x06,0xb3,0x07,0x02,0x01,0x32,0x2b,0x09,0x01,0x06,0x26,0x35,0x11,0x34,0x36,0x17,0x01,0x16,0x14,0x03,0x04,0xfd,0x1b,0x0d,0x12,0x12,0x0d,0x02,0xe5,0x0d,0x01,0x4d,0xfe,0x64,0x07,0x0a,0x0f,0x03,0x36,0x0e,0x0c,0x08,0xfe,0x64,0x07,0x14,0x00,0x00,0x01,0xff,0xff,0xff,0xae,0x02,0x3c, +0x03,0x0f,0x00,0x1d,0x00,0x1b,0x40,0x18,0x1b,0x1a,0x12,0x03,0x01,0x00,0x01,0x4c,0x00,0x00,0x00,0x13,0x4d,0x00,0x01,0x01,0x11,0x01,0x4e,0x35,0x3d,0x02,0x07,0x18,0x2b,0x17,0x06,0x26,0x37,0x11,0x34,0x36,0x17,0x01,0x16,0x17,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x07,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x11,0x06,0x07,0x19, +0x0a,0x10,0x01,0x0e,0x0b,0x01,0x8c,0x05,0x03,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x03,0x05,0x47,0x0b,0x06,0x0f,0x03,0x36,0x0e,0x08,0x0c,0xfe,0x74,0x05,0x05,0x01,0x7a,0x0e,0x16,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x01,0x7b,0x06,0x05,0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08, +0x00,0x13,0x00,0x29,0x00,0xa7,0x40,0x0d,0x0c,0x01,0x03,0x02,0x23,0x22,0x18,0x17,0x04,0x05,0x07,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x32,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02,0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00,0x05,0x04,0x02,0x05,0x04,0x7e,0x0a,0x01,0x04,0x00,0x01,0x04,0x01, +0x66,0x09,0x01,0x02,0x02,0x00,0x61,0x08,0x01,0x00,0x00,0x12,0x02,0x4e,0x1b,0x40,0x39,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02,0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00,0x05,0x04,0x02,0x05,0x04,0x7e,0x08,0x01,0x00,0x09,0x01,0x02,0x03,0x00,0x02,0x69,0x0a,0x01,0x04,0x01,0x01,0x04,0x59,0x0a, +0x01,0x04,0x04,0x01,0x62,0x00,0x01,0x04,0x01,0x52,0x59,0x40,0x1f,0x15,0x14,0x0a,0x09,0x01,0x00,0x26,0x24,0x20,0x1e,0x1b,0x19,0x14,0x29,0x15,0x29,0x10,0x0e,0x09,0x13,0x0a,0x13,0x05,0x04,0x00,0x08,0x01,0x08,0x0b,0x07,0x16,0x2b,0x01,0x36,0x00,0x12,0x00,0x04,0x00,0x02,0x00,0x17,0x22,0x06,0x15,0x06,0x16,0x33,0x32,0x36,0x35, +0x34,0x03,0x32,0x36,0x37,0x27,0x06,0x23,0x22,0x3f,0x01,0x36,0x23,0x22,0x06,0x07,0x17,0x36,0x33,0x32,0x0f,0x01,0x06,0x01,0xc6,0xbe,0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xf2,0x2a,0x2e,0x02,0x22,0x20,0x26,0x2e,0xb4,0x1e,0x6c,0x34,0x12,0x30,0x18,0x0e,0x0a,0x2a,0x1a,0x30,0x1e,0x76,0x38,0x10,0x34,0x16, +0x0c,0x0c,0x24,0x1a,0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0x96,0x30,0x1a,0x1c,0x20,0x2c,0x20,0x3a,0xfd,0xae,0x34,0x34,0x18,0x24,0x26,0xa0,0x60,0x3a,0x2e,0x1a,0x22,0x22,0x98,0x68,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x31,0x00,0x3b,0x40,0x38,0x2a,0x01,0x03,0x05, +0x25,0x1d,0x02,0x04,0x03,0x02,0x4c,0x00,0x04,0x03,0x01,0x03,0x04,0x01,0x80,0x00,0x01,0x02,0x03,0x01,0x02,0x7e,0x00,0x03,0x03,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x02,0x02,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x29,0x35,0x17,0x23,0x17,0x24,0x06,0x07,0x1c,0x2b,0x01,0x14,0x0e,0x02,0x23,0x22,0x26,0x27,0x26,0x34,0x3f, +0x01,0x36,0x16,0x17,0x1e,0x01,0x33,0x32,0x3e,0x03,0x2e,0x02,0x22,0x06,0x07,0x17,0x16,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x1f,0x01,0x3e,0x01,0x33,0x32,0x1e,0x02,0x03,0x59,0x44,0x72,0xa0,0x56,0x60,0xae,0x3c,0x04,0x05,0x4c,0x06,0x11,0x04,0x29,0x76,0x43,0x3a,0x68,0x50,0x2a,0x02,0x2e,0x4c,0x6c,0x6f,0x64,0x28,0x4d, +0x11,0x13,0x17,0xfa,0x0f,0x14,0x01,0x2c,0x11,0x48,0x3c,0x9a,0x52,0x57,0x9e,0x74,0x42,0x01,0x5e,0x57,0x9e,0x74,0x44,0x52,0x49,0x06,0x0e,0x04,0x4d,0x05,0x01,0x06,0x35,0x3a,0x2e,0x4c,0x6a,0x74,0x6a,0x4c,0x2e,0x28,0x25,0x4d,0x10,0x2d,0x16,0x0e,0xfa,0x18,0x13,0x12,0x48,0x39,0x3e,0x44,0x74,0x9e,0x00,0x00,0x00,0x01,0x00,0x00, +0xff,0xf9,0x02,0x83,0x03,0x53,0x00,0x23,0x00,0x3a,0x40,0x37,0x00,0x04,0x05,0x00,0x05,0x04,0x00,0x80,0x00,0x03,0x00,0x05,0x04,0x03,0x05,0x69,0x02,0x06,0x02,0x00,0x01,0x01,0x00,0x59,0x02,0x06,0x02,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x01,0x00,0x20,0x1f,0x1b,0x18,0x14,0x13,0x10,0x0e,0x09,0x06,0x00,0x23,0x01,0x23, +0x07,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17,0x33,0x35,0x34,0x36,0x1e,0x01,0x07,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x34,0x26,0x22,0x06,0x17,0x15,0x02,0x4d,0x17,0x1e,0x01,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01,0x20,0x16,0x11,0x94,0xcc,0x96,0x02,0x14,0x0f,0x24,0x0e,0x16, +0x54,0x76,0x54,0x01,0x01,0xa5,0x1e,0x17,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01,0xb3,0x67,0x94,0x02,0x90,0x69,0x0e,0x16,0x16,0x0e,0x3b,0x54,0x54,0x3b,0xb3,0x00,0x00,0x08,0x00,0x00,0xff,0x9f,0x03,0x8f,0x03,0x1d,0x00,0x04,0x00,0x09,0x00,0x0e,0x00,0x13,0x00,0x1b,0x00,0x23,0x00,0x2b,0x00,0x33,0x00,0x41, +0x40,0x3e,0x21,0x20,0x15,0x14,0x0e,0x01,0x06,0x00,0x4a,0x31,0x30,0x25,0x24,0x10,0x09,0x06,0x01,0x49,0x05,0x04,0x02,0x08,0x04,0x00,0x01,0x00,0x85,0x07,0x06,0x09,0x03,0x04,0x01,0x01,0x76,0x0f,0x0f,0x00,0x00,0x2d,0x2c,0x29,0x28,0x1d,0x1c,0x19,0x18,0x0f,0x13,0x0f,0x13,0x0b,0x0a,0x06,0x05,0x00,0x04,0x00,0x04,0x0a,0x07,0x16, +0x2b,0x01,0x35,0x1e,0x01,0x17,0x07,0x33,0x0e,0x01,0x07,0x03,0x23,0x3e,0x01,0x37,0x11,0x15,0x2e,0x01,0x27,0x01,0x35,0x1e,0x01,0x17,0x23,0x2e,0x01,0x01,0x23,0x3e,0x01,0x37,0x15,0x0e,0x01,0x01,0x15,0x2e,0x01,0x27,0x33,0x1e,0x01,0x01,0x33,0x0e,0x01,0x07,0x35,0x3e,0x01,0x02,0x09,0x3c,0x56,0x10,0xa2,0xa2,0x10,0x56,0x3c,0x71, +0xa2,0x10,0x56,0x3c,0x3c,0x56,0x10,0x01,0x13,0x98,0xda,0x14,0x71,0x12,0x9a,0xfe,0x11,0x71,0x13,0xda,0x99,0x6a,0x98,0x01,0x02,0x9a,0xd8,0x14,0x71,0x12,0x9a,0x01,0xef,0x71,0x15,0xd8,0x99,0x69,0x9a,0x01,0x97,0xa2,0x10,0x58,0x3a,0x71,0x3b,0x58,0x0f,0x01,0x13,0x3b,0x56,0x11,0xfe,0xed,0xa2,0x10,0x56,0x3c,0x01,0x86,0x71,0x13, +0xda,0x99,0x6b,0x98,0xfe,0xfd,0x98,0xda,0x14,0x71,0x12,0x98,0xfe,0x0f,0x72,0x13,0xdc,0x98,0x6b,0x98,0x01,0x03,0x99,0xda,0x14,0x72,0x12,0x98,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x03,0x00,0x21,0x00,0x31,0x00,0x45,0x00,0x53,0x40,0x50,0x2b,0x2a,0x23,0x22,0x04,0x08,0x04,0x01,0x4c,0x0d,0x01,0x04,0x06,0x01, +0x08,0x02,0x4b,0x00,0x08,0x04,0x03,0x04,0x08,0x03,0x80,0x00,0x03,0x06,0x04,0x03,0x06,0x7e,0x00,0x06,0x00,0x01,0x00,0x06,0x01,0x68,0x07,0x01,0x04,0x04,0x0a,0x5f,0x00,0x0a,0x0a,0x13,0x4d,0x05,0x02,0x02,0x00,0x00,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x40,0x3d,0x38,0x35,0x17,0x26,0x33,0x11,0x13,0x3b,0x11,0x11,0x10,0x0b, +0x07,0x1f,0x2b,0x17,0x21,0x35,0x21,0x05,0x33,0x11,0x34,0x26,0x2f,0x01,0x2e,0x01,0x07,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35,0x23,0x11,0x33,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x07,0x03,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x17,0x15,0x14,0x16,0x37,0x33,0x32,0x36,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34, +0x36,0x33,0x21,0x32,0x16,0x1f,0x01,0x1e,0x01,0xd6,0x01,0xad,0xfe,0x53,0x01,0xf4,0x48,0x0c,0x05,0x9d,0x05,0x1c,0x08,0x1e,0x17,0xfe,0xbe,0x16,0x1e,0x01,0x48,0x48,0x20,0x15,0x01,0xd1,0x16,0x20,0x01,0xd6,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x64,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x02,0x05, +0x17,0x36,0x0f,0x9c,0x10,0x16,0x07,0xd6,0xd6,0x01,0xf4,0x08,0x1a,0x07,0x9c,0x06,0x0c,0x01,0xe8,0x16,0x20,0x20,0x16,0xe8,0xfd,0x36,0xe8,0x16,0x20,0x20,0x16,0x01,0x1e,0xb2,0x08,0x0a,0x0a,0x08,0xb2,0x07,0x0c,0x01,0x0a,0x0a,0xfd,0xfa,0x16,0x20,0x20,0x16,0x02,0xee,0x16,0x20,0x18,0x0e,0x9d,0x0f,0x36,0x00,0x00,0x02,0xff,0xff, +0xff,0xb1,0x03,0xe8,0x03,0x0b,0x00,0x03,0x00,0x13,0x00,0x1f,0x40,0x1c,0x00,0x01,0x01,0x03,0x5f,0x00,0x03,0x03,0x13,0x4d,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x35,0x34,0x11,0x10,0x04,0x07,0x1a,0x2b,0x37,0x21,0x11,0x21,0x25,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x8f, +0x02,0xca,0xfd,0x36,0x03,0x59,0x34,0x25,0xfc,0xca,0x24,0x36,0x01,0x34,0x25,0x03,0x36,0x25,0x34,0x40,0x01,0xad,0xc4,0xfd,0x5a,0x25,0x34,0x01,0x36,0x24,0x02,0xa6,0x25,0x34,0x01,0x36,0x00,0x03,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x08,0x00,0x15,0x00,0x22,0x00,0x32,0x40,0x2f,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x69, +0x06,0x01,0x02,0x02,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x03,0x03,0x04,0x61,0x00,0x04,0x04,0x11,0x04,0x4e,0x0a,0x09,0x20,0x1f,0x1a,0x19,0x10,0x0f,0x09,0x15,0x0a,0x15,0x13,0x12,0x07,0x07,0x18,0x2b,0x01,0x14,0x06,0x22,0x2e,0x01,0x36,0x32,0x16,0x27,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e,0x01,0x2e,0x02,0x01,0x14,0x0e,0x01, +0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x02,0x3b,0x52,0x78,0x52,0x02,0x56,0x74,0x56,0x90,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x5e,0x3b,0x54,0x54,0x76,0x54,0x54,0xf5,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0, +0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0x6a,0x02,0x83,0x03,0x0b,0x00,0x0b,0x00,0x2e,0x00,0x35,0x40,0x32,0x07,0x01,0x02,0x01,0x00,0x01,0x4c,0x00,0x03,0x02,0x03,0x86,0x09,0x05,0x02,0x01,0x04,0x01,0x02,0x03,0x01,0x02,0x67,0x08,0x06,0x02,0x00,0x00,0x07,0x5f,0x00,0x07,0x07,0x13, +0x00,0x4e,0x2d,0x2c,0x13,0x33,0x11,0x14,0x22,0x33,0x15,0x15,0x13,0x0a,0x07,0x1f,0x2b,0x01,0x35,0x34,0x26,0x22,0x06,0x1d,0x01,0x14,0x16,0x32,0x36,0x05,0x14,0x06,0x27,0x23,0x03,0x0e,0x01,0x07,0x23,0x22,0x27,0x03,0x23,0x22,0x26,0x27,0x34,0x36,0x33,0x11,0x22,0x2e,0x01,0x36,0x37,0x21,0x32,0x16,0x14,0x06,0x27,0x11,0x32,0x16, +0x01,0x0c,0x0a,0x10,0x0a,0x0a,0x10,0x0a,0x01,0x77,0x16,0x0e,0xef,0x1d,0x01,0x0a,0x06,0x01,0x0f,0x02,0x2b,0xe1,0x0f,0x14,0x01,0x58,0x37,0x1d,0x2a,0x02,0x2e,0x1b,0x01,0x65,0x1d,0x2a,0x2a,0x1d,0x37,0x58,0x01,0x70,0xfa,0x08,0x0a,0x0a,0x08,0xfa,0x08,0x0a,0x0a,0xbd,0x0e,0x16,0x01,0xfe,0xf2,0x07,0x08,0x01,0x0f,0x01,0x0f,0x14, +0x0f,0x45,0x6e,0x01,0x1e,0x2a,0x3a,0x2a,0x01,0x2c,0x38,0x2c,0x01,0xfe,0xe2,0x6e,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5b,0x03,0x0b,0x00,0x24,0x00,0x47,0x00,0x4b,0x40,0x48,0x43,0x25,0x02,0x06,0x09,0x2f,0x01,0x05,0x06,0x17,0x01,0x03,0x02,0x08,0x01,0x01,0x03,0x04,0x4c,0x00,0x09,0x07,0x01,0x05,0x02,0x09,0x05,0x67,0x04,0x01, +0x02,0x00,0x01,0x00,0x02,0x01,0x69,0x00,0x06,0x06,0x08,0x61,0x00,0x08,0x08,0x13,0x4d,0x00,0x03,0x03,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x46,0x45,0x26,0x25,0x25,0x36,0x25,0x26,0x35,0x14,0x24,0x0a,0x07,0x1f,0x2b,0x01,0x14,0x15,0x0e,0x01,0x23,0x22,0x26,0x27,0x07,0x06,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16, +0x06,0x0f,0x01,0x1e,0x01,0x37,0x32,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x32,0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x36,0x3f,0x01,0x26,0x23,0x22,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x37,0x35,0x3e,0x01,0x33,0x32,0x16,0x17,0x37,0x36,0x32,0x16,0x03,0x4b,0x24,0xe4,0x99,0x51,0x98,0x3c,0x48,0x0b,0x1c,0x16,0x16, +0x0e,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x28,0x64,0x37,0x4a,0x82,0x27,0x06,0x18,0x04,0x0c,0x6b,0x08,0x0a,0x0e,0x14,0x10,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x52,0x70,0x4b,0x82,0x27,0x06,0x17,0x05,0x0c,0x6f,0x07,0x0c,0x01,0x24,0xe6,0x99,0x51,0x9a,0x3c,0x48,0x0b,0x1c,0x18,0x01,0x05,0x03,0x01,0x96,0xba,0x3e,0x39,0x48,0x0b,0x16,0x0e, +0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x24,0x2a,0x01,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x01,0xb8,0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x4d,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x06,0x04,0x96,0xba,0x3e,0x39,0x48,0x0b,0x16,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x20,0x40,0x1d,0x18,0x10, +0x08,0x00,0x04,0x00,0x01,0x01,0x4c,0x03,0x01,0x01,0x01,0x13,0x4d,0x02,0x01,0x00,0x00,0x11,0x00,0x4e,0x35,0x35,0x35,0x33,0x04,0x07,0x1a,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10, +0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0xfe,0x0b,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0x02,0xe7,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f, +0x00,0x1a,0x40,0x17,0x08,0x00,0x02,0x00,0x01,0x01,0x4c,0x00,0x01,0x01,0x13,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x35,0x33,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10,0xfc,0xef,0x0f,0x14,0x01,0x16,0x0e,0x03,0x11,0x0f,0x16,0x02,0xe7,0xfc,0xee,0x0e, +0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x01,0xff,0xfe,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x30,0x00,0x3a,0x40,0x37,0x2d,0x01,0x01,0x05,0x09,0x01,0x00,0x01,0x02,0x4c,0x00,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x00,0x03,0x02,0x01,0x03,0x02,0x7e,0x00,0x01,0x01,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x02,0x02,0x04,0x61, +0x00,0x04,0x04,0x11,0x04,0x4e,0x27,0x27,0x13,0x27,0x24,0x33,0x06,0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3f,0x01,0x26,0x23,0x22,0x0e,0x02,0x14,0x1e,0x02,0x33,0x32,0x36,0x37,0x3e,0x01,0x1f,0x01,0x1e,0x01,0x07,0x0e,0x01,0x07,0x22,0x2e,0x02,0x3e,0x03,0x33,0x32,0x16,0x17,0x37,0x36,0x16,0x03,0x59,0x14,0x10, +0xfa,0x17,0x13,0x11,0x4d,0x52,0x70,0x3a,0x6a,0x4c,0x2e,0x2e,0x4c,0x6a,0x3a,0x42,0x76,0x29,0x04,0x11,0x06,0x4c,0x05,0x02,0x06,0x3c,0xae,0x5f,0x57,0xa0,0x70,0x48,0x04,0x40,0x78,0x98,0x5b,0x52,0x98,0x3d,0x48,0x11,0x2c,0x02,0xc3,0xfa,0x0e,0x16,0x2d,0x10,0x4d,0x4d,0x2e,0x4c,0x6a,0x74,0x6a,0x4c,0x2e,0x3a,0x35,0x06,0x01,0x05, +0x4d,0x04,0x0e,0x06,0x4a,0x50,0x01,0x44,0x74,0x9e,0xae,0x9e,0x74,0x44,0x3e,0x39,0x48,0x12,0x13,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58,0x01,0xe6,0x00,0x15,0x00,0x19,0x40,0x16,0x0f,0x01,0x00,0x01,0x01,0x4c,0x02,0x01,0x01,0x00,0x01,0x85,0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06, +0x22,0x27,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37,0x36,0x32,0x1f,0x01,0x16,0x02,0x58,0x06,0xfe,0xfc,0x05,0x10,0x04,0xfe,0xfc,0x06,0x06,0x1c,0x05,0x0e,0x06,0xdb,0xdc,0x05,0x10,0x04,0x1c,0x06,0x01,0xb7,0x07,0x05,0xfe,0xfb,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x00,0x00, +0x00,0x03,0xff,0xfd,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0c,0x00,0x1c,0x00,0x2e,0x00,0x41,0x40,0x3e,0x28,0x1e,0x02,0x05,0x04,0x16,0x15,0x0e,0x03,0x03,0x02,0x02,0x4c,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x04,0x04,0x00,0x61,0x06,0x01,0x00,0x00,0x13,0x4d,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x11,0x01,0x4e,0x01, +0x00,0x2c,0x2a,0x23,0x21,0x1a,0x18,0x12,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x07,0x07,0x16,0x2b,0x01,0x32,0x1e,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x13,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x07,0x15,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34,0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x13,0x14,0x16,0x3b,0x01,0x32, +0x36,0x01,0xad,0x74,0xc6,0x72,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xc1,0x0a,0x07,0x6b,0x08,0x0a,0x01,0x0c,0x07,0x6b,0x07,0x0a,0x01,0x0a,0x06,0x05,0x08,0x7b,0x08,0x05,0x06,0x0a,0x0a,0x09,0x67,0x08,0x0a,0x03,0x0b,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0xfd,0x48,0x6a,0x08,0x0a,0x0a,0x08,0x6a,0x08,0x0a,0x01, +0x0c,0xc7,0x01,0x5a,0x07,0x03,0x05,0x05,0x03,0x07,0xfe,0xa6,0x06,0x08,0x08,0x00,0x00,0x01,0x00,0x00,0xff,0xef,0x02,0xd4,0x02,0x86,0x00,0x24,0x00,0x26,0x40,0x23,0x22,0x19,0x10,0x07,0x04,0x00,0x02,0x01,0x4c,0x03,0x01,0x02,0x00,0x00,0x02,0x59,0x03,0x01,0x02,0x02,0x00,0x61,0x01,0x01,0x00,0x02,0x00,0x51,0x14,0x1c,0x14,0x14, +0x04,0x07,0x1a,0x2b,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37,0x36,0x32,0x1f,0x01,0x16,0x14,0x0f,0x01,0x17,0x16,0x02,0xd4,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10,0x10,0x4c,0x10,0x2c,0x10, +0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x0f,0x0f,0xa4,0xa4,0x0f,0x70,0x16,0x10,0x4c,0x0f,0x0f,0xa5,0xa5,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10,0x10,0x4c,0x0f,0x2e,0x0f,0xa4,0xa4,0x0f,0x00,0x03,0x00,0x00,0xff,0xb1,0x03,0xc5,0x03,0x0b,0x00,0x0c,0x00,0x1c,0x00,0x2c,0x00,0x34,0x40,0x31, +0x25,0x1d,0x02,0x04,0x05,0x00,0x01,0x01,0x00,0x02,0x4c,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x04,0x05,0x5f,0x00,0x05,0x05,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x35,0x35,0x35,0x35,0x24,0x32,0x06,0x07,0x1c,0x2b,0x01,0x34,0x26,0x07,0x23,0x22,0x0e,0x01,0x16,0x17,0x33,0x32,0x36,0x25, +0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x37,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x37,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x02,0x5f,0x14,0x10,0x8e,0x0f,0x14,0x02,0x18,0x0d,0x8e,0x0f,0x16,0x01,0x41,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x23,0x14,0x0f,0xfc,0xa6,0x0e, +0x16,0x01,0x14,0x0f,0x03,0x5a,0x0e,0x16,0x01,0x82,0x0e,0x16,0x01,0x14,0x1e,0x14,0x01,0x16,0x79,0xfd,0xe8,0x0e,0x16,0x16,0x0e,0x02,0x18,0x0e,0x16,0x16,0xec,0x8f,0x0e,0x16,0x16,0x0e,0x8f,0x0e,0x16,0x16,0x00,0x05,0x00,0x00,0xff,0x88,0x03,0xac,0x03,0x34,0x00,0x43,0x00,0x4c,0x00,0x55,0x00,0x5e,0x00,0x67,0x00,0x61,0x40,0x5e, +0x3c,0x33,0x02,0x05,0x0a,0x1a,0x0f,0x02,0x01,0x05,0x2b,0x22,0x19,0x10,0x09,0x00,0x06,0x08,0x01,0x03,0x4c,0x07,0x01,0x05,0x03,0x01,0x01,0x08,0x05,0x01,0x67,0x00,0x0a,0x0f,0x0c,0x02,0x08,0x09,0x0a,0x08,0x69,0x10,0x0e,0x0d,0x03,0x09,0x04,0x02,0x02,0x00,0x09,0x00,0x65,0x00,0x0b,0x0b,0x06,0x61,0x00,0x06,0x06,0x12,0x0b,0x4e, +0x60,0x5f,0x64,0x63,0x5f,0x67,0x60,0x67,0x5d,0x5c,0x59,0x58,0x54,0x53,0x50,0x4f,0x4b,0x4a,0x15,0x36,0x16,0x37,0x18,0x36,0x16,0x36,0x14,0x11,0x07,0x1f,0x2b,0x25,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x34,0x2b,0x01,0x22,0x27,0x15,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x06,0x2b,0x01,0x22,0x0e,0x01, +0x1d,0x01,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x34,0x36,0x3b,0x01,0x32,0x3d,0x01,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x15,0x14,0x3b,0x01,0x32,0x16,0x15,0x05,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x13,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x05,0x32, +0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x64,0x48,0x46,0x64,0x46,0x48,0x4c,0x64,0x2c,0x22,0x48,0x46,0x64,0x46,0x48,0x1e,0x2e,0x64,0x22,0x26,0x06,0x48,0x46,0x64,0x46,0x48,0x56,0x58,0x64,0x4c,0x48,0x46,0x64,0x46,0x48,0x4e,0x64,0x56,0x56,0xfd,0x5a,0x2a,0x38,0x28,0x28,0x38,0x2a,0xd4,0x28,0x38,0x2a,0x2a,0x38,0x28,0x8a,0x2a, +0x38,0x28,0x28,0x38,0x2a,0x01,0x18,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x70,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x4e,0x0c,0xcc,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0xcc,0x0c,0x26,0x1c,0x0c,0x72,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x40,0x6c,0x34,0x8c,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x8c,0x34,0x6c, +0x40,0xe2,0x1e,0x28,0x28,0x3a,0x28,0x28,0x02,0xd8,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x26,0x1e,0x28,0x28,0x3a,0x28,0x28,0x28,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x3e,0x40,0x3b,0x0d,0x01,0x00,0x01,0x1f,0x01,0x04,0x03,0x02,0x4c,0x02,0x01,0x00,0x01, +0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04,0x01,0x03,0x04,0x7e,0x00,0x01,0x01,0x07,0x5f,0x00,0x07,0x07,0x13,0x4d,0x00,0x04,0x04,0x06,0x60,0x00,0x06,0x06,0x11,0x06,0x4e,0x35,0x35,0x23,0x33,0x16,0x23,0x24,0x23,0x08,0x07,0x1e,0x2b,0x01,0x35,0x34,0x26,0x07,0x23,0x35,0x34,0x26,0x27,0x23,0x22,0x06,0x07,0x15,0x23,0x22,0x06, +0x07,0x15,0x14,0x16,0x37,0x33,0x15,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x35,0x33,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xb3,0x16,0x0e,0x47,0x0f,0x14,0x01,0xb2,0x0f,0x14,0x01,0x16,0x0e,0xb2,0x16,0x0e,0x47,0x0f,0x14,0x01,0xb3,0x0e,0x16,0x8e,0x5e,0x43, +0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01,0x3a,0x48,0x0e,0x16,0x01,0xb3,0x0f,0x14,0x01,0x16,0x0e,0xb3,0x14,0x0f,0x48,0x0e,0x16,0x01,0xb3,0x0e,0x16,0x16,0x0e,0xb3,0x14,0x01,0x3f,0xfd,0xe8,0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0f, +0x00,0x1f,0x00,0x1f,0x40,0x1c,0x00,0x00,0x00,0x03,0x5f,0x00,0x03,0x03,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x35,0x35,0x26,0x33,0x04,0x07,0x1a,0x2b,0x01,0x35,0x34,0x26,0x07,0x21,0x22,0x06,0x07,0x15,0x14,0x16,0x37,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37, +0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x01,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x8e,0x5e,0x43,0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01,0x3a,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x01,0x3f,0xfd,0xe8,0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x00,0x01,0x00,0x00, +0x00,0x01,0x00,0x00,0x98,0xdf,0x81,0x07,0x5f,0x0f,0x3c,0xf5,0x00,0x0f,0x03,0xe8,0x00,0x00,0x00,0x00,0xe4,0x07,0x59,0xed,0x00,0x00,0x00,0x00,0xe4,0x07,0x59,0xee,0xff,0xf5,0xff,0x6a,0x04,0x78,0x03,0x53,0x00,0x00,0x00,0x08,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x03,0x52,0xff,0x6a,0x00,0x00,0x04,0x76, +0xff,0xf5,0xff,0xf5,0x04,0x78,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x80,0x00,0x00,0x03,0x11,0x00,0x00,0x04,0x2f,0xff,0xff,0x00,0xf0,0x00,0x00,0x04,0x76,0xff,0xff,0x03,0xe8,0xff,0xff,0x03,0xe8,0x00,0x00,0x02,0x44,0x00,0x00, +0x02,0x44,0x00,0x00,0x03,0x59,0xff,0xfd,0x02,0x3b,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x11,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0xdc,0x00,0x00,0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00,0x02,0x3b,0xff,0xff,0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x03,0xca,0x00,0x00, +0x04,0x2f,0xff,0xff,0x03,0xa0,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xd4,0xff,0xf7,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xff,0x02,0x82,0x00,0x00,0x02,0xda,0x00,0x00,0x04,0x2f,0xff,0xff,0x02,0xf8,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x59,0x00,0x00,0x03,0x59,0xff,0xff, +0x02,0xda,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xf5,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x82,0x00,0x00,0x03,0x42,0x00,0x00,0x04,0x2f,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0xe8,0x00,0x00, +0x03,0xe7,0xff,0xfe,0x03,0x59,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x3b,0xff,0xff,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x02,0x82,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0xff,0xff,0x03,0x59,0xff,0xfd,0x02,0x82,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0xff,0xfe, +0x02,0x82,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x11,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,0xe0,0x01,0x8a,0x02,0x04,0x02,0x5a,0x02,0xb2,0x02,0xd8,0x03,0x24,0x03,0x5a,0x03,0x7c,0x03,0xa0,0x03,0xcc,0x04,0x56,0x05,0x18,0x05,0x74,0x06,0x08, +0x06,0x2c,0x06,0x56,0x06,0x78,0x06,0xa2,0x06,0xda,0x07,0x12,0x07,0xba,0x08,0x0c,0x08,0xb4,0x09,0x06,0x09,0x34,0x09,0x56,0x09,0xa2,0x09,0xea,0x0a,0xac,0x0b,0x96,0x0c,0x22,0x0d,0x0e,0x0d,0x52,0x0d,0x78,0x0d,0xda,0x0e,0x3e,0x0e,0x80,0x0f,0x32,0x0f,0xe2,0x10,0x0a,0x10,0x5e,0x11,0x90,0x11,0xae,0x11,0xe6,0x12,0x50,0x12,0xac, +0x13,0x0c,0x14,0x14,0x14,0x94,0x14,0xf4,0x15,0x2e,0x15,0xf2,0x16,0x7e,0x16,0xd4,0x17,0xe2,0x18,0x44,0x18,0x9c,0x18,0xba,0x18,0xf8,0x19,0x94,0x19,0xfc,0x1a,0x50,0x1a,0xcc,0x1b,0x5c,0x1b,0x90,0x1b,0xe4,0x1c,0x46,0x1c,0xd4,0x1d,0x18,0x1d,0x42,0x1d,0xa8,0x1d,0xde,0x1e,0x46,0x1e,0x94,0x1e,0xf2,0x1f,0xae,0x20,0x18,0x20,0x5c, +0x00,0x01,0x00,0x00,0x00,0x51,0x00,0x90,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x42,0x00,0x7b,0x00,0x8d,0x00,0x00,0x00,0xba,0x0e,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0xde,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x35,0x00,0x01, +0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x07,0x00,0x3d,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x08,0x00,0x44,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x00,0x4c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x0b,0x00,0x54,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x08,0x00,0x5f,0x00,0x01,0x00,0x00,0x00,0x00, +0x00,0x0a,0x00,0x2b,0x00,0x67,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x13,0x00,0x92,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x00,0x00,0x6a,0x00,0xa5,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x01,0x00,0x10,0x01,0x0f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x02,0x00,0x0e,0x01,0x1f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x03,0x00,0x10, +0x01,0x2d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x04,0x00,0x10,0x01,0x3d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x05,0x00,0x16,0x01,0x4d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x06,0x00,0x10,0x01,0x63,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x0a,0x00,0x56,0x01,0x73,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x0b,0x00,0x26,0x01,0xc9,0x43,0x6f, +0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x43,0x29,0x20,0x32,0x30,0x32,0x35,0x20,0x62,0x79,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x73,0x20,0x40,0x20,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x52,0x65,0x67,0x75,0x6c, +0x61,0x72,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x47,0x65,0x6e,0x65,0x72,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x73,0x76,0x67,0x32,0x74,0x74,0x66,0x20,0x66,0x72,0x6f,0x6d,0x20,0x46, +0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x20,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x2e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x43,0x00,0x6f,0x00,0x70,0x00,0x79,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x68,0x00,0x74,0x00,0x20,0x00,0x28,0x00,0x43,0x00,0x29,0x00,0x20,0x00, +0x32,0x00,0x30,0x00,0x32,0x00,0x35,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x6f,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x69,0x00,0x6e,0x00,0x61,0x00,0x6c,0x00,0x20,0x00,0x61,0x00,0x75,0x00,0x74,0x00,0x68,0x00,0x6f,0x00,0x72,0x00,0x73,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00, +0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x52,0x00,0x65,0x00,0x67,0x00,0x75,0x00,0x6c,0x00,0x61,0x00,0x72,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x66,0x00,0x6f,0x00, +0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x31,0x00,0x2e,0x00,0x30,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x47,0x00,0x65,0x00,0x6e,0x00,0x65,0x00,0x72,0x00,0x61,0x00,0x74,0x00, +0x65,0x00,0x64,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x73,0x00,0x76,0x00,0x67,0x00,0x32,0x00,0x74,0x00,0x74,0x00,0x66,0x00,0x20,0x00,0x66,0x00,0x72,0x00,0x6f,0x00,0x6d,0x00,0x20,0x00,0x46,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x20,0x00,0x70,0x00,0x72,0x00,0x6f,0x00,0x6a,0x00, +0x65,0x00,0x63,0x00,0x74,0x00,0x2e,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,0x2f,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18, +0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,0x01,0x20,0x01,0x21,0x01,0x22,0x01,0x23,0x01,0x24,0x01,0x25,0x01,0x26,0x01,0x27,0x01,0x28,0x01,0x29,0x01,0x2a,0x01,0x2b,0x01,0x2c,0x01,0x2d,0x01,0x2e,0x01,0x2f,0x01,0x30,0x01,0x31,0x01,0x32,0x01,0x33,0x01,0x34,0x01,0x35,0x01,0x36,0x01,0x37,0x01,0x38, +0x01,0x39,0x01,0x3a,0x01,0x3b,0x01,0x3c,0x01,0x3d,0x01,0x3e,0x01,0x3f,0x01,0x40,0x01,0x41,0x01,0x42,0x01,0x43,0x01,0x44,0x01,0x45,0x01,0x46,0x01,0x47,0x01,0x48,0x01,0x49,0x01,0x4a,0x01,0x4b,0x01,0x4c,0x01,0x4d,0x01,0x4e,0x01,0x4f,0x01,0x50,0x01,0x51,0x01,0x52,0x00,0x0b,0x63,0x68,0x65,0x63,0x6b,0x2d,0x65,0x6d,0x70,0x74, +0x79,0x0d,0x66,0x6c,0x6f,0x77,0x2d,0x70,0x61,0x72,0x61,0x6c,0x6c,0x65,0x6c,0x05,0x74,0x72,0x61,0x73,0x68,0x07,0x70,0x69,0x63,0x74,0x75,0x72,0x65,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x6c,0x69,0x6e,0x65,0x0e,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x72,0x65,0x73,0x74,0x6f,0x72,0x65,0x0f,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x6d,0x69, +0x6e,0x69,0x6d,0x69,0x7a,0x65,0x04,0x63,0x75,0x62,0x65,0x04,0x70,0x6c,0x75,0x73,0x05,0x6d,0x69,0x6e,0x75,0x73,0x06,0x63,0x69,0x72,0x63,0x6c,0x65,0x08,0x64,0x6f,0x77,0x6e,0x2d,0x64,0x69,0x72,0x05,0x63,0x68,0x65,0x63,0x6b,0x0b,0x74,0x72,0x61,0x73,0x68,0x2d,0x65,0x6d,0x70,0x74,0x79,0x04,0x75,0x73,0x65,0x72,0x09,0x62,0x72, +0x69,0x65,0x66,0x63,0x61,0x73,0x65,0x03,0x64,0x6f,0x74,0x08,0x6c,0x65,0x66,0x74,0x2d,0x64,0x69,0x72,0x09,0x72,0x69,0x67,0x68,0x74,0x2d,0x64,0x69,0x72,0x06,0x75,0x70,0x2d,0x64,0x69,0x72,0x0a,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x6c,0x65,0x66,0x74,0x0b,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x72,0x69,0x67,0x68,0x74,0x0c,0x68,0x65,0x6c, +0x70,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x74,0x61,0x67,0x04,0x67,0x72,0x69,0x64,0x0b,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f,0x70,0x65,0x6e,0x06,0x66,0x6f,0x6c,0x64,0x65,0x72,0x09,0x64,0x6f,0x77,0x6e,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x70,0x61,0x6c,0x65,0x74,0x74,0x65,0x07,0x64,0x6f,0x63,0x2d,0x69,0x6e,0x76,0x03, +0x63,0x6f,0x67,0x02,0x74,0x68,0x0a,0x62,0x69,0x6e,0x6f,0x63,0x75,0x6c,0x61,0x72,0x73,0x04,0x6c,0x69,0x73,0x74,0x04,0x6c,0x6f,0x63,0x6b,0x09,0x6c,0x65,0x66,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x64,0x65,0x73,0x6b,0x74,0x6f,0x70,0x06,0x73,0x65,0x61,0x72,0x63,0x68,0x0c,0x63,0x69,0x72,0x63,0x6c,0x65,0x2d,0x65,0x6d,0x70,0x74, +0x79,0x06,0x70,0x65,0x6e,0x63,0x69,0x6c,0x03,0x68,0x64,0x64,0x0a,0x72,0x69,0x67,0x68,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x0b,0x63,0x6c,0x6f,0x73,0x65,0x5f,0x70,0x61,0x6e,0x65,0x6c,0x08,0x73,0x74,0x65,0x70,0x69,0x6e,0x74,0x6f,0x07,0x75,0x70,0x2d,0x62,0x6f,0x6c,0x64,0x02,0x6f,0x6b,0x09,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f, +0x6e,0x10,0x68,0x6f,0x72,0x69,0x7a,0x6f,0x6e,0x74,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x0e,0x76,0x65,0x72,0x74,0x69,0x63,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x08,0x73,0x74,0x65,0x70,0x6f,0x76,0x65,0x72,0x10,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x11,0x6d,0x69,0x6e,0x75, +0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x08,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x75,0x70,0x09,0x63,0x6c,0x69,0x70,0x62,0x6f,0x61,0x72,0x64,0x11,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f,0x70,0x65,0x6e,0x2d,0x65,0x6d,0x70,0x74,0x79,0x0c,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x65,0x6d,0x70,0x74,0x79,0x07, +0x73,0x74,0x65,0x70,0x6f,0x75,0x74,0x07,0x67,0x6c,0x61,0x73,0x73,0x65,0x73,0x03,0x64,0x6f,0x63,0x04,0x70,0x6c,0x61,0x79,0x06,0x74,0x6f,0x2d,0x65,0x6e,0x64,0x0c,0x69,0x6e,0x66,0x6f,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x63,0x63,0x77,0x0d,0x6c,0x6f,0x63,0x6b,0x2d,0x6f,0x70,0x65,0x6e,0x2d,0x61,0x6c,0x74,0x06,0x74, +0x61,0x72,0x67,0x65,0x74,0x06,0x66,0x6c,0x6f,0x70,0x70,0x79,0x0f,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x6d,0x61,0x78,0x69,0x6d,0x69,0x7a,0x65,0x0b,0x64,0x6f,0x74,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x70,0x69,0x6e,0x09,0x61,0x72,0x72,0x6f,0x77,0x73,0x2d,0x63,0x77,0x05,0x70,0x61,0x75,0x73,0x65,0x04,0x73,0x74,0x6f, +0x70,0x02,0x63,0x77,0x0a,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x64,0x6f,0x77,0x6e,0x11,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f,0x6e,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x06,0x63,0x61,0x6e,0x63,0x65,0x6c,0x03,0x62,0x6f,0x78,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x74,0x72,0x65,0x65,0x0c,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61, +0x72,0x65,0x64,0x0d,0x6d,0x69,0x6e,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0xff,0xff,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x7e,0x01,0x1e,0x00,0x7d,0x00,0x7d,0x01,0x1e,0x03,0x18,0xff,0xb1, +0x03,0x38,0x03,0x0b,0xff,0xb1,0xff,0xb1,0x03,0x18,0xff,0xb1,0x03,0x38,0x03,0x0b,0xff,0xb1,0xff,0xb1,0xb0,0x00,0x2c,0x20,0xb0,0x00,0x55,0x58,0x45,0x59,0x20,0x20,0x4b,0xb8,0x00,0x0e,0x51,0x4b,0xb0,0x06,0x53,0x5a,0x58,0xb0,0x34,0x1b,0xb0,0x28,0x59,0x60,0x66,0x20,0x8a,0x55,0x58,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00, +0x63,0x63,0x23,0x62,0x1b,0x21,0x21,0xb0,0x00,0x59,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x01,0x2c,0xb0,0x20,0x60,0x66,0x2d,0xb0,0x02,0x2c,0x23,0x21,0x23,0x21,0x2d,0xb0,0x03,0x2c,0x20,0x64,0xb3,0x03,0x14,0x15,0x00,0x42,0x43,0xb0,0x13,0x43,0x20,0x60,0x60,0x42,0xb1,0x02,0x14,0x43,0x42,0xb1, +0x25,0x03,0x43,0xb0,0x02,0x43,0x54,0x78,0x20,0xb0,0x0c,0x23,0xb0,0x02,0x43,0x43,0x61,0x64,0xb0,0x04,0x50,0x78,0xb2,0x02,0x02,0x02,0x43,0x60,0x42,0xb0,0x21,0x65,0x1c,0x21,0xb0,0x02,0x43,0x43,0xb2,0x0e,0x15,0x01,0x42,0x1c,0x20,0xb0,0x02,0x43,0x23,0x42,0xb2,0x13,0x01,0x13,0x43,0x60,0x42,0x23,0xb0,0x00,0x50,0x58,0x65,0x59, +0xb2,0x16,0x01,0x02,0x43,0x60,0x42,0x2d,0xb0,0x04,0x2c,0xb0,0x03,0x2b,0xb0,0x15,0x43,0x58,0x23,0x21,0x23,0x21,0xb0,0x16,0x43,0x43,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x1b,0x20,0x64,0x20,0xb0,0xc0,0x50,0xb0,0x04,0x26,0x5a,0xb2,0x28,0x01,0x0d,0x43,0x45,0x63,0x45,0xb0,0x06,0x45,0x58,0x21,0xb0,0x03,0x25,0x59,0x52,0x5b,0x58, +0x21,0x23,0x21,0x1b,0x8a,0x58,0x20,0xb0,0x50,0x50,0x58,0x21,0xb0,0x40,0x59,0x1b,0x20,0xb0,0x38,0x50,0x58,0x21,0xb0,0x38,0x59,0x59,0x20,0xb1,0x01,0x0d,0x43,0x45,0x63,0x45,0x61,0x64,0xb0,0x28,0x50,0x58,0x21,0xb1,0x01,0x0d,0x43,0x45,0x63,0x45,0x20,0xb0,0x30,0x50,0x58,0x21,0xb0,0x30,0x59,0x1b,0x20,0xb0,0xc0,0x50,0x58,0x20, +0x66,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x0a,0x50,0x58,0x60,0x1b,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0,0x0a,0x60,0x1b,0x20,0xb0,0x36,0x50,0x58,0x21,0xb0,0x36,0x60,0x1b,0x60,0x59,0x59,0x59,0x1b,0xb0,0x02,0x25,0xb0,0x0c,0x43,0x63,0xb0,0x00,0x52,0x58,0xb0,0x00,0x4b,0xb0,0x0a,0x50,0x58,0x21,0xb0,0x0c,0x43,0x1b,0x4b,0xb0,0x1e,0x50, +0x58,0x21,0xb0,0x1e,0x4b,0x61,0xb8,0x10,0x00,0x63,0xb0,0x0c,0x43,0x63,0xb8,0x05,0x00,0x62,0x59,0x59,0x64,0x61,0x59,0xb0,0x01,0x2b,0x59,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x59,0x20,0x64,0xb0,0x16,0x43,0x23,0x42,0x59,0x2d,0xb0,0x05,0x2c,0x20,0x45,0x20,0xb0,0x04,0x25,0x61,0x64,0x20,0xb0,0x07,0x43,0x50,0x58,0xb0,0x07, +0x23,0x42,0xb0,0x08,0x23,0x42,0x1b,0x21,0x21,0x59,0xb0,0x01,0x60,0x2d,0xb0,0x06,0x2c,0x23,0x21,0x23,0x21,0xb0,0x03,0x2b,0x20,0x64,0xb1,0x07,0x62,0x42,0x20,0xb0,0x08,0x23,0x42,0xb0,0x06,0x45,0x58,0x1b,0xb1,0x01,0x0d,0x43,0x45,0x63,0xb1,0x01,0x0d,0x43,0xb0,0x01,0x60,0x45,0x63,0xb0,0x05,0x2a,0x21,0x20,0xb0,0x08,0x43,0x20, +0x8a,0x20,0x8a,0xb0,0x01,0x2b,0xb1,0x30,0x05,0x25,0xb0,0x04,0x26,0x51,0x58,0x60,0x50,0x1b,0x61,0x52,0x59,0x58,0x23,0x59,0x21,0x59,0x20,0xb0,0x40,0x53,0x58,0xb0,0x01,0x2b,0x1b,0x21,0xb0,0x40,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x2d,0xb0,0x07,0x2c,0xb0,0x09,0x43,0x2b,0xb2,0x00,0x02,0x00,0x43,0x60,0x42,0x2d,0xb0,0x08, +0x2c,0xb0,0x09,0x23,0x42,0x23,0x20,0xb0,0x00,0x23,0x42,0x61,0xb0,0x02,0x62,0x66,0xb0,0x01,0x63,0xb0,0x01,0x60,0xb0,0x07,0x2a,0x2d,0xb0,0x09,0x2c,0x20,0x20,0x45,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0a,0x2c,0xb2, +0x09,0x0e,0x00,0x43,0x45,0x42,0x2a,0x21,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x0b,0x2c,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x0c,0x2c,0x20,0x20,0x45,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0, +0x00,0x1b,0xb0,0x30,0x50,0x58,0xb0,0x20,0x1b,0xb0,0x40,0x59,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0d,0x2c,0x20,0x20,0x45,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0xb0,0x24,0x50,0x58,0xb0,0x00,0x1b,0xb0, +0x40,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0e,0x2c,0x20,0xb0,0x00,0x23,0x42,0xb3,0x0d,0x0c,0x00,0x03,0x45,0x50,0x58,0x21,0x1b,0x23,0x21,0x59,0x2a,0x21,0x2d,0xb0,0x0f,0x2c,0xb1,0x02,0x02,0x45,0xb0,0x64,0x61,0x44,0x2d,0xb0,0x10,0x2c,0xb0,0x01,0x60,0x20,0x20, +0xb0,0x0f,0x43,0x4a,0xb0,0x00,0x50,0x58,0x20,0xb0,0x0f,0x23,0x42,0x59,0xb0,0x10,0x43,0x4a,0xb0,0x00,0x52,0x58,0x20,0xb0,0x10,0x23,0x42,0x59,0x2d,0xb0,0x11,0x2c,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0x20,0xb8,0x04,0x00,0x63,0x8a,0x23,0x61,0xb0,0x11,0x43,0x60,0x20,0x8a,0x60,0x20,0xb0,0x11,0x23,0x42,0x23,0x2d,0xb0,0x12, +0x2c,0x4b,0x54,0x58,0xb1,0x04,0x64,0x44,0x59,0x24,0xb0,0x0d,0x65,0x23,0x78,0x2d,0xb0,0x13,0x2c,0x4b,0x51,0x58,0x4b,0x53,0x58,0xb1,0x04,0x64,0x44,0x59,0x1b,0x21,0x59,0x24,0xb0,0x13,0x65,0x23,0x78,0x2d,0xb0,0x14,0x2c,0xb1,0x00,0x12,0x43,0x55,0x58,0xb1,0x12,0x12,0x43,0xb0,0x01,0x61,0x42,0xb0,0x11,0x2b,0x59,0xb0,0x00,0x43, +0xb0,0x02,0x25,0x42,0xb1,0x0f,0x02,0x25,0x42,0xb1,0x10,0x02,0x25,0x42,0xb0,0x01,0x16,0x23,0x20,0xb0,0x03,0x25,0x50,0x58,0xb1,0x01,0x00,0x43,0x60,0xb0,0x04,0x25,0x42,0x8a,0x8a,0x20,0x8a,0x23,0x61,0xb0,0x10,0x2a,0x21,0x23,0xb0,0x01,0x61,0x20,0x8a,0x23,0x61,0xb0,0x10,0x2a,0x21,0x1b,0xb1,0x01,0x00,0x43,0x60,0xb0,0x02,0x25, +0x42,0xb0,0x02,0x25,0x61,0xb0,0x10,0x2a,0x21,0x59,0xb0,0x0f,0x43,0x47,0xb0,0x10,0x43,0x47,0x60,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb1,0x00,0x00,0x13,0x23,0x44, +0xb0,0x01,0x43,0xb0,0x00,0x3e,0xb2,0x01,0x01,0x01,0x43,0x60,0x42,0x2d,0xb0,0x15,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb0,0x12,0x23,0x42,0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60,0x42,0x20,0x60,0xb7,0x18,0x18,0x01,0x00,0x11,0x00,0x13,0x00,0x42,0x42,0x42,0x8a,0x60,0x20,0xb0,0x14,0x23,0x42,0xb0,0x01, +0x61,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b,0x1b,0x22,0x59,0x2d,0xb0,0x16,0x2c,0xb1,0x00,0x15,0x2b,0x2d,0xb0,0x17,0x2c,0xb1,0x01,0x15,0x2b,0x2d,0xb0,0x18,0x2c,0xb1,0x02,0x15,0x2b,0x2d,0xb0,0x19,0x2c,0xb1,0x03,0x15,0x2b,0x2d,0xb0,0x1a,0x2c,0xb1,0x04,0x15,0x2b,0x2d,0xb0,0x1b,0x2c,0xb1,0x05,0x15,0x2b,0x2d,0xb0,0x1c,0x2c,0xb1, +0x06,0x15,0x2b,0x2d,0xb0,0x1d,0x2c,0xb1,0x07,0x15,0x2b,0x2d,0xb0,0x1e,0x2c,0xb1,0x08,0x15,0x2b,0x2d,0xb0,0x1f,0x2c,0xb1,0x09,0x15,0x2b,0x2d,0xb0,0x2b,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x06,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x5d,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2c,0x2c,0x23,0x20,0xb0,0x10, +0x62,0x66,0xb0,0x01,0x63,0xb0,0x16,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x71,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2d,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x26,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x72,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x20,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02,0x45,0x54,0x58, +0xb0,0x12,0x23,0x42,0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60,0x42,0x20,0x60,0xb0,0x01,0x61,0xb5,0x18,0x18,0x01,0x00,0x11,0x00,0x42,0x42,0x8a,0x60,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b,0x1b,0x22,0x59,0x2d,0xb0,0x21,0x2c,0xb1,0x00,0x20,0x2b,0x2d,0xb0,0x22,0x2c,0xb1,0x01,0x20,0x2b,0x2d,0xb0,0x23,0x2c,0xb1, +0x02,0x20,0x2b,0x2d,0xb0,0x24,0x2c,0xb1,0x03,0x20,0x2b,0x2d,0xb0,0x25,0x2c,0xb1,0x04,0x20,0x2b,0x2d,0xb0,0x26,0x2c,0xb1,0x05,0x20,0x2b,0x2d,0xb0,0x27,0x2c,0xb1,0x06,0x20,0x2b,0x2d,0xb0,0x28,0x2c,0xb1,0x07,0x20,0x2b,0x2d,0xb0,0x29,0x2c,0xb1,0x08,0x20,0x2b,0x2d,0xb0,0x2a,0x2c,0xb1,0x09,0x20,0x2b,0x2d,0xb0,0x2e,0x2c,0x20, +0x3c,0xb0,0x01,0x60,0x2d,0xb0,0x2f,0x2c,0x20,0x60,0xb0,0x18,0x60,0x20,0x43,0x23,0xb0,0x01,0x60,0x43,0xb0,0x02,0x25,0x61,0xb0,0x01,0x60,0xb0,0x2e,0x2a,0x21,0x2d,0xb0,0x30,0x2c,0xb0,0x2f,0x2b,0xb0,0x2f,0x2a,0x2d,0xb0,0x31,0x2c,0x20,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0, +0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x61,0x38,0x23,0x20,0x8a,0x55,0x58,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x61,0x38,0x1b,0x21,0x59,0x2d,0xb0,0x32,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42, +0xb0,0x01,0x16,0xb0,0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x33,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02,0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x16,0xb0,0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x34,0x2c,0x20,0x35,0xb0,0x01,0x60,0x2d,0xb0, +0x35,0x2c,0x00,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x45,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x01,0x2b,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x01,0x2b,0xb0,0x00,0x16,0xb4,0x00,0x00,0x00,0x00, +0x00,0x44,0x3e,0x23,0x38,0xb1,0x34,0x01,0x15,0x2a,0x21,0x2d,0xb0,0x36,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb0,0x00,0x43,0x61,0x38,0x2d,0xb0,0x37,0x2c,0x2e,0x17,0x3c,0x2d,0xb0,0x38,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0, +0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb0,0x00,0x43,0x61,0xb0,0x01,0x43,0x63,0x38,0x2d,0xb0,0x39,0x2c,0xb1,0x02,0x00,0x16,0x25,0x20,0x2e,0x20,0x47,0xb0,0x00,0x23,0x42,0xb0,0x02,0x25,0x49,0x8a,0x8a,0x47,0x23,0x47,0x23,0x61,0x20,0x58,0x62,0x1b,0x21,0x59, +0xb0,0x01,0x23,0x42,0xb2,0x38,0x01,0x01,0x15,0x14,0x2a,0x2d,0xb0,0x3a,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25,0xb0,0x04,0x25,0x47,0x23,0x47,0x23,0x61,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x65,0x8a,0x2e,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x3b,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25, +0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x20,0xb0,0x60,0x50,0x58,0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3,0x04,0x26,0x05,0x1a,0x59,0x42,0x42,0x23,0x20,0xb0,0x0a,0x43,0x20,0x8a,0x23,0x47,0x23,0x47,0x23,0x61,0x23,0x46,0x60,0xb0, +0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01,0x2b,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x04,0x43,0x60,0x64,0x23,0xb0,0x05,0x43,0x61,0x64,0x50,0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40, +0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x1b,0x23,0xb0,0x0a,0x43,0x46,0xb0,0x02,0x25,0xb0,0x0a,0x43,0x47,0x23,0x47,0x23,0x61,0x60,0x20,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x06, +0x43,0x60,0xb0,0x01,0x2b,0xb0,0x05,0x25,0x61,0xb0,0x05,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x04,0x26,0x61,0x20,0xb0,0x04,0x25,0x60,0x64,0x23,0xb0,0x03,0x25,0x60,0x64,0x50,0x58,0x21,0x1b,0x23,0x21,0x59,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x59,0x2d,0xb0, +0x3c,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0x20,0x20,0xb0,0x05,0x26,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x23,0x3c,0x38,0x2d,0xb0,0x3d,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x23,0x42,0x20,0x20,0x20,0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x2d,0xb0,0x3e,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42, +0xb0,0x03,0x25,0xb0,0x02,0x25,0x47,0x23,0x47,0x23,0x61,0xb0,0x00,0x54,0x58,0x2e,0x20,0x3c,0x23,0x21,0x1b,0xb0,0x02,0x25,0xb0,0x02,0x25,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x05,0x25,0xb0,0x04,0x25,0x47,0x23,0x47,0x23,0x61,0xb0,0x06,0x25,0xb0,0x05,0x25,0x49,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00,0x63,0x63,0x23,0x20, +0x58,0x62,0x1b,0x21,0x59,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x2e,0x23,0x20,0x20,0x3c,0x8a,0x38,0x23,0x21,0x59,0x2d,0xb0,0x3f,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x43,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0x60,0xb0,0x20,0x60,0x66,0xb0, +0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x40,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x41,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0, +0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x42,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30, +0x01,0x14,0x2b,0x2d,0xb0,0x43,0x2c,0xb0,0x3a,0x2b,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x44,0x2c,0xb0,0x3b,0x2b,0x8a,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x8a,0x38,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43, +0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x45,0x2c,0xb0,0x00,0x16,0xb0,0x04,0x25,0xb0,0x04,0x26,0x20,0x20,0x20,0x46,0x23,0x47,0x61,0xb0,0x0c,0x23,0x42,0x2e,0x47,0x23,0x47,0x23,0x61,0xb0,0x0b,0x43,0x2b,0x23,0x20,0x3c,0x20,0x2e,0x23,0x38,0xb1, +0x30,0x01,0x14,0x2b,0x2d,0xb0,0x46,0x2c,0xb1,0x0a,0x04,0x25,0x42,0xb0,0x00,0x16,0xb0,0x04,0x25,0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x20,0xb0,0x60,0x50,0x58,0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3,0x04,0x26,0x05,0x1a,0x59, +0x42,0x42,0x23,0x20,0x47,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01,0x2b,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x04,0x43,0x60,0x64,0x23,0xb0,0x05,0x43,0x61,0x64,0x50,0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20, +0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0xb0,0x02,0x25,0x46,0x61,0x38,0x23,0x20,0x3c,0x23,0x38,0x1b,0x21,0x20,0x20,0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x21,0x59,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x47,0x2c,0xb1,0x00,0x3a,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x48,0x2c,0xb1,0x00, +0x3b,0x2b,0x21,0x23,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x23,0x38,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x49,0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00,0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4a,0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00, +0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4b,0x2c,0xb1,0x00,0x01,0x14,0x13,0xb0,0x37,0x2a,0x2d,0xb0,0x4c,0x2c,0xb0,0x39,0x2a,0x2d,0xb0,0x4d,0x2c,0xb0,0x00,0x16,0x45,0x23,0x20,0x2e,0x20,0x46,0x8a,0x23,0x61,0x38,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x4e,0x2c,0xb0,0x0a,0x23,0x42,0xb0,0x4d,0x2b,0x2d,0xb0,0x4f, +0x2c,0xb2,0x00,0x00,0x46,0x2b,0x2d,0xb0,0x50,0x2c,0xb2,0x00,0x01,0x46,0x2b,0x2d,0xb0,0x51,0x2c,0xb2,0x01,0x00,0x46,0x2b,0x2d,0xb0,0x52,0x2c,0xb2,0x01,0x01,0x46,0x2b,0x2d,0xb0,0x53,0x2c,0xb2,0x00,0x00,0x47,0x2b,0x2d,0xb0,0x54,0x2c,0xb2,0x00,0x01,0x47,0x2b,0x2d,0xb0,0x55,0x2c,0xb2,0x01,0x00,0x47,0x2b,0x2d,0xb0,0x56,0x2c, +0xb2,0x01,0x01,0x47,0x2b,0x2d,0xb0,0x57,0x2c,0xb3,0x00,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x58,0x2c,0xb3,0x00,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x59,0x2c,0xb3,0x01,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x5a,0x2c,0xb3,0x01,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x5b,0x2c,0xb3,0x00,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5c,0x2c,0xb3,0x00,0x01,0x01,0x43, +0x2b,0x2d,0xb0,0x5d,0x2c,0xb3,0x01,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5e,0x2c,0xb3,0x01,0x01,0x01,0x43,0x2b,0x2d,0xb0,0x5f,0x2c,0xb2,0x00,0x00,0x45,0x2b,0x2d,0xb0,0x60,0x2c,0xb2,0x00,0x01,0x45,0x2b,0x2d,0xb0,0x61,0x2c,0xb2,0x01,0x00,0x45,0x2b,0x2d,0xb0,0x62,0x2c,0xb2,0x01,0x01,0x45,0x2b,0x2d,0xb0,0x63,0x2c,0xb2,0x00,0x00, +0x48,0x2b,0x2d,0xb0,0x64,0x2c,0xb2,0x00,0x01,0x48,0x2b,0x2d,0xb0,0x65,0x2c,0xb2,0x01,0x00,0x48,0x2b,0x2d,0xb0,0x66,0x2c,0xb2,0x01,0x01,0x48,0x2b,0x2d,0xb0,0x67,0x2c,0xb3,0x00,0x00,0x00,0x44,0x2b,0x2d,0xb0,0x68,0x2c,0xb3,0x00,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x69,0x2c,0xb3,0x01,0x00,0x00,0x44,0x2b,0x2d,0xb0,0x6a,0x2c,0xb3, +0x01,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x6b,0x2c,0xb3,0x00,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6c,0x2c,0xb3,0x00,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6d,0x2c,0xb3,0x01,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6e,0x2c,0xb3,0x01,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6f,0x2c,0xb1,0x00,0x3c,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x70,0x2c,0xb1, +0x00,0x3c,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x71,0x2c,0xb1,0x00,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x72,0x2c,0xb0,0x00,0x16,0xb1,0x00,0x3c,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x73,0x2c,0xb1,0x01,0x3c,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x74,0x2c,0xb1,0x01,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x75,0x2c,0xb0,0x00,0x16,0xb1,0x01,0x3c,0x2b, +0xb0,0x42,0x2b,0x2d,0xb0,0x76,0x2c,0xb1,0x00,0x3d,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x77,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x78,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x79,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7a,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7b, +0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x7c,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7d,0x2c,0xb1,0x00,0x3e,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x7e,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7f,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x80,0x2c,0xb1,0x00,0x3e,0x2b,0xb0, +0x42,0x2b,0x2d,0xb0,0x81,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x82,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x83,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x84,0x2c,0xb1,0x00,0x3f,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x85,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x86,0x2c, +0xb1,0x00,0x3f,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x87,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x88,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x89,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x8a,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x8b,0x2c,0xb2,0x0b,0x00,0x03,0x45,0x50,0x58,0xb0,0x06, +0x1b,0xb2,0x04,0x02,0x03,0x45,0x58,0x23,0x21,0x1b,0x21,0x59,0x59,0x42,0x2b,0xb0,0x08,0x65,0xb0,0x03,0x24,0x50,0x78,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x2d,0x00,0x4b,0xb8,0x00,0xc8,0x52,0x58,0xb1,0x01,0x01,0x8e,0x59,0xb0,0x01,0xb9,0x08,0x00,0x08,0x00,0x63,0x70,0xb1,0x00,0x07,0x42,0xb2,0x19,0x01,0x00,0x2a,0xb1,0x00, +0x07,0x42,0xb3,0x0d,0x09,0x01,0x0a,0x2a,0xb1,0x00,0x07,0x42,0xb3,0x16,0x06,0x01,0x0a,0x2a,0xb1,0x00,0x08,0x42,0xba,0x03,0x80,0x00,0x01,0x00,0x0b,0x2a,0xb1,0x00,0x09,0x42,0xba,0x00,0x80,0x00,0x01,0x00,0x0b,0x2a,0xb9,0x00,0x03,0x00,0x00,0x44,0xb1,0x24,0x01,0x88,0x51,0x58,0xb0,0x40,0x88,0x58,0xb9,0x00,0x03,0x00,0x64,0x44, +0xb1,0x28,0x01,0x88,0x51,0x58,0xb8,0x08,0x00,0x88,0x58,0xb9,0x00,0x03,0x00,0x00,0x44,0x59,0x1b,0xb1,0x27,0x01,0x88,0x51,0x58,0xba,0x08,0x80,0x00,0x01,0x04,0x40,0x88,0x63,0x54,0x58,0xb9,0x00,0x03,0x00,0x00,0x44,0x59,0x59,0x59,0x59,0x59,0xb3,0x10,0x06,0x01,0x0e,0x2a,0xb8,0x01,0xff,0x85,0xb0,0x04,0x8d,0xb1,0x02,0x00,0x44, +0xb3,0x05,0x64,0x06,0x00,0x44,0x44,0x00, }; read_only global String8 rd_icon_font_bytes = {rd_icon_font_bytes__data, sizeof(rd_icon_font_bytes__data)}; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index de4675fc..4a74ce1a 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -6,142 +6,322 @@ @embed_file rd_icon_font_bytes: "../data/icons.ttf" @embed_file rd_default_main_font_bytes: "../data/Roboto-Regular.ttf" +//@embed_file rd_default_main_font_bytes: "../data/seguisb.ttf" @embed_file rd_default_code_font_bytes: "../data/liberation-mono.ttf" //@embed_file rd_default_code_font_bytes: "../data/Inconsolata-Regular.ttf" @embed_file rd_icon_file_bytes: "../data/logo.ico" //////////////////////////////// -//~ rjf: Config Sources +//~ rjf: Vocabulary Map -@table(string, name, load_cmd, write_cmd, apply_cmd) -RD_CfgSrcTable: +@table(code_name code_name_plural display_name display_name_plural icon_kind) +RD_VocabTable: +// NOTE(rjf): the _ character is used as a fastpath for default rules. when +// pluralizing, you just append an `s`, and so on. { - {"user" User OpenUser WriteUserData ApplyUserData } - {"project" Project OpenProject WriteProjectData ApplyProjectData } - {"command_line" CommandLine Null Null Null } - {"transient" Transient Null Null Null } + {auto_view_rule _ "Auto View Rule" _ Binoculars } + {file_path_map _ "File Path Map" _ FileOutline } + {watch_pin _ "Watch Pin" _ Pin } + {watch watches "Watch" "Watches" Binoculars } + {view_rule _ "View Rule" _ Binoculars } + {breakpoint _ "Breakpoint" _ CircleFilled } + {condition _ "Condition" _ Null } + {location _ "Location" _ Null } + {source_location _ "Source Location" _ Null } + {address_location _ "Address Location" _ Null } + {target _ "Target" _ Target } + {executable _ "Executable" _ Module } + {arguments arguments "Arguments" "Arguments" Null } + {exe exes "Executable" _ Module } + {dbg dbgs "Debug Info Path" _ Module } + {vaddr_range _ "Virtual Address Range" _ Null } + {min _ "Minimum" _ Null } + {max _ "Maximum" _ Null } + {working_directory working_directories "Working Directory" "Working Directories" FolderClosedFilled } + {entry_point _ "Entry Point" _ Null } + {stdout_path _ "Standard Output Path" _ Null } + {stderr_path _ "Standard Error Path" _ Null } + {stdin_path _ "Standard Input Path" _ Null } + {window _ "Window" _ Window } + {panel _ "Panel" _ Null } + {view _ "View" _ Null } + {tab _ "Tab" _ Null } + {recent_project _ "Recent Project" _ Briefcase } + {recent_file _ "Recent File" _ FileOutline } + {src _ "Source" _ Null } + {dst _ "Destination" _ Null } + {conversion_task _ "Conversion Task" _ Null } + {conversion_fail _ "Conversion Fail" _ Null } + {lang _ "Language" _ Null } + {arch _ "Architecture" _ Null } + {expr _ "Expression" _ Null } + {expression _ "Expression" _ Null } + {size _ "Size" _ Null } + {count _ "Count" _ Null } + {bool _ "Boolean" _ Null } + {w _ "Width" _ Null } + {h _ "Height" _ Null } + {fmt _ "Format" _ Null } + {addresses addresses "Addresses" "Addresses" Null } + {code_bytes code_bytes "Code Bytes" "Code Bytes" Null } + {vtx _ "Vertex Buffer" _ Null } + {vtx_size _ "Vertex Buffer Size" _ Null } + {label _ "Label" _ Null } + {thread _ "Thread" _ Thread } + {threads "" "Threads" "" Threads } + {process processes "Process" "Processes" Scheduler } + {processes "" "Processes" "" Scheduler } + {machine _ "Machine" _ Machine } + {module _ "Module" _ Module } + {getting_started "" "Getting Started" "" QuestionMark } + {disasm "" "Disassembly" "" Glasses } + {text "" "Text" "" FileOutline } + {type _ "Type" _ Null } + {procedure _ "Procedure" _ Null } + {global_variable _ "Global Variable" _ Null } + {global _ "Global" _ Null } + {thread_variable _ "Thread Variable" _ Null } + {thread_local _ "Thread Local" _ Null } + {call_stack _ "Call Stack" _ Thread } + {output _ "Output" _ List } + {scheduler _ "Scheduler" _ Scheduler } + {register _ "Register" _ Null } + {local _ "Local" _ Null } + {memory memories "Memory" "Memories" Grid } + {hit_count hit_counts "Hit Count" "Hit Counts" Null } + {enabled "" "Enabled" "Enabled" Null } + {disabled "" "Disabled" "Disabled" Null } + {debug_subprocesses "" "Debug Subprocesses" "" Null } + {environment _ "Environment" _ Null } + {frozen "" "Frozen" "" Null } + {id _ "ID" _ Null } + {last_modified_time _ "Last Modified Time" _ Null } + {creation_time _ "Creation Time" _ Null } + {data _ "Data" _ Null } + {unattached_processes "" "Unattached Processes" "" Scheduler } + {user _ "User" _ Person } + {project _ "Project" _ Briefcase } + {recent_project _ "Recent Project" _ Briefcase } + {recent_file _ "Recent File" _ FileOutline } + {show_addresses "" "Show Addresses" "" Null } + {show_code_bytes "" "Show Code Bytes" "" Null } + {show_source_lines "" "Show Source Lines" "" Null } + {show_symbol_names "" "Show Symbol Names" "" Null } + {show_line_numbers "" "Show Line Numbers" "" Null } + {syntax syntaxes "Syntax" "Syntaxes" Null } + {num_columns "" "Number of Columns" "" Null } + {bitmap _ "Bitmap" _ Bitmap } + {geo3d "" "Geometry (3D)" "" Cube } } -@enum RD_CfgSrc: +@struct RD_VocabInfo: { - @expand(RD_CfgSrcTable a) `$(a.name)`, - COUNT, + `String8 code_name`; + `String8 code_name_plural`; + `String8 display_name`; + `String8 display_name_plural`; + `RD_IconKind icon_kind`; } -@data(String8) rd_cfg_src_string_table: +@data(RD_VocabInfo) rd_vocab_info_table: { - @expand(RD_CfgSrcTable a) `str8_lit_comp("$(a.string)")`, -} - -@data(RD_CmdKind) rd_cfg_src_load_cmd_kind_table: -{ - @expand(RD_CfgSrcTable a) `RD_CmdKind_$(a.load_cmd)`, -} - -@data(RD_CmdKind) rd_cfg_src_write_cmd_kind_table: -{ - @expand(RD_CfgSrcTable a) `RD_CmdKind_$(a.write_cmd)`, -} - -@data(RD_CmdKind) rd_cfg_src_apply_cmd_kind_table: -{ - @expand(RD_CfgSrcTable a) `RD_CmdKind_$(a.apply_cmd)`; + @expand(RD_VocabTable a) `{str8_lit_comp("$(a.code_name)"), str8_lit_comp("$(a.code_name_plural == _ -> a.code_name .. 's')$(a.code_name_plural != _ -> a.code_name_plural)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.display_name_plural == _ -> a.display_name .. 's')$(a.display_name_plural != _ -> a.display_name_plural)"), RD_IconKind_$(a.icon_kind)}`; + @expand(D_CmdTable a) `{str8_lit_comp("$(a.string)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.canonical_icon)}`; + @expand(RD_CmdTable a) `{str8_lit_comp("$(a.string)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.canonical_icon)}`; } //////////////////////////////// -//~ rjf: Entity Kind Tables +//~ rjf: Schemas -@table(name name_lower name_lower_plural op_delete op_freeze op_edit op_rename op_enable op_cond op_dup name_is_code name_is_path user_lifetime is_serialized name_label icon_kind display_string) -// | | -// | _____________________________________________________________________________________________________________________________________/ -// | / -// operations________ names lt sz -// /..................\ /...\ | | -// dl fz ed rn en cn dp nc np ul iz -RD_EntityKindTable: +@table(name schema) RD_SchemaTable: { - {Nil nil nils 0 0 0 0 0 0 0 0 0 0 0 "Label" Null "Nil" } - {Root root roots 0 0 0 0 0 0 0 0 0 0 0 "Label" Null "Root" } + //- rjf: settings + { + settings, + ```x: + { + @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, + } + ``` + } - //- rjf: auto view rules - {AutoViewRule auto_view_rule auto_view_rules 1 0 0 0 0 0 0 0 0 1 1 "Label" Binoculars "Auto View Rule" } - - //- rjf: file path maps - {FilePathMap file_path_map file_path_maps 1 0 0 0 0 0 0 0 0 0 1 "Label" FileOutline "File Path Map" } - - //- rjf: watch pins - {WatchPin watch_pin watch_pins 1 0 0 1 0 0 1 1 0 1 1 "Expression" Pin "Watch Pin" } - - //- rjf: watches - {Watch watch watches 1 0 0 1 1 0 1 1 0 1 1 "Expression" Binoculars "Watch" } - {ViewRule view_rule view_rules 1 0 0 1 1 0 1 1 0 1 0 "Expression" Binoculars "View Rule" } - - //- rjf: breakpoints - {Breakpoint breakpoint breakpoints 1 0 0 1 1 1 1 1 0 1 1 "Label" CircleFilled "Breakpoint" } - {Condition condition conditions 0 0 0 0 0 0 0 1 0 1 0 "Expression" CircleFilled "Condition" } - - //- rjf: user-controlled locations (source, addresses, symbol names) - {Location location locations 0 0 0 0 0 0 0 1 1 1 0 "Location" Null "Location" } + //- rjf: views + { + text, + ``` + x: + { + 'lang':lang, + 'size':code_string, + @default(1) 'show_line_numbers':bool, + } + ``` + } + { + disasm, + ``` + x: + { + 'arch': arch, + 'syntax': dasm_syntax, + 'size': code_string, + @default(1) 'show_addresses': bool, + @default(0) 'show_code_bytes': bool, + @default(1) 'show_source_lines': bool, + @default(1) 'show_symbol_names': bool, + @default(1) 'show_line_numbers': bool, + } + ``` + } + { + memory, + ``` + x: + { + 'size': code_string, + @default(16) 'num_columns': @range[1, 64] u64, + } + ``` + } + { + bitmap, + ``` + x: + { + 'w': code_string, + 'h': code_string, + 'fmt': tex2dformat, + } + ``` + } //- rjf: targets - {Target target targets 1 0 1 1 1 0 1 0 0 1 1 "Label" Target "Target" } - {Executable executable executables 0 0 0 0 0 0 0 0 1 1 0 "Executable" Null "Executable" } - {Arguments arguments argumentses 0 0 0 0 0 0 0 0 0 1 0 "Arguments" Null "Arguments" } - {WorkingDirectory working_directory working_directories 0 0 0 0 0 0 0 0 1 1 0 "Path" Null "Working Directory" } - {EntryPoint entry_point entry_points 0 0 0 0 0 0 0 0 0 1 0 "Symbol Name" Null "Entry Point" } - {StdoutPath stdout_path stdout_paths 0 0 0 0 0 0 0 0 1 1 0 "Path" Null "Standard Output Path" } - {StderrPath stderr_path stderr_paths 0 0 0 0 0 0 0 0 1 1 0 "Path" Null "Standard Error Path" } - {StdinPath stdin_path stdin_paths 0 0 0 0 0 0 0 0 1 1 0 "Path" Null "Standard Input Path" } + { + target, + ``` + @commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg) + @collection_commands(add_target) + x: + { + 'label': code_string, + 'executable': path, + 'arguments': string, + 'working_directory': path, + 'entry_point': code_string, + 'stdout_path': path, + 'stderr_path': path, + 'stdin_path': path, + 'environment': query, + 'debug_subprocesses': bool, + @no_expand @default(0) 'enabled': bool, + } + ```, + } - //- rjf: frontend containers (windows, panels, views) - {Window window windows 1 0 0 0 0 0 1 0 0 1 1 "Label" Window "Window" } - {Panel panel panels 1 0 0 0 0 0 1 0 0 1 1 "Label" XSplit "Panel" } - {View view views 1 0 0 0 0 0 1 0 0 1 1 "Label" Null "View" } + //- rjf: breakpoints + { + breakpoint, + ``` + @commands(enable_cfg, remove_cfg) + @collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint) + x: + { + 'label': code_string, + 'condition': code_string, + 'source_location': path_pt, + 'address_location': code_string, + 'hit_count': u64, + @no_expand @default(1) 'enabled': bool, + } + ```, + } + + //- rjf: watch pins + { + watch_pin, + ``` + @commands(remove_cfg) + @collection_commands(add_watch_pin) + x: + { + 'expression': code_string, + 'view_rule': code_string, + 'source_location': path_pt, + 'address_location': code_string, + } + ```, + } + + //- rjf: file path maps + { + file_path_map, + ```@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}```, + } + + //- rjf: auto view rules + { + auto_view_rule, + ```@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}```, + } //- rjf: recent projects - {RecentProject recent_project recent_projects 0 0 0 0 0 0 0 0 1 0 1 "Path" Briefcase "Recent Project" } + { + recent_project, + ```x:{'path':path}```, + } //- rjf: recent files - {RecentFile recent_file recent_files 0 0 0 0 0 0 0 0 1 0 1 "Path" FileOutline "Recent File" } + { + recent_file, + ```x:{'path':path}```, + } - //- rjf: src -> dst mapping - {Source source sources 0 0 0 0 0 0 0 0 0 0 0 "Path" Null "Source" } - {Dest dest dests 0 0 0 0 0 0 0 0 0 0 0 "Path" Null "Destination" } - - //- rjf: parser task entities - {ConversionTask conversion_task conversion_tasks 0 0 0 1 0 0 0 0 0 0 0 "Label" Null "Conversion Task" } - {ConversionFail conversion_fail conversion_fails 0 0 0 1 0 0 0 0 0 0 0 "Label" Null "Conversion Failure" } + //- rjf: control entities + { + machine, + ```x:{'label':code_string, @no_expand 'active':bool, 'unattached_processes':query, 'processes':query}```, + } + { + process, + ```x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'modules':query, 'threads':query}```, + } + { + module, + ```x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}```, + } + { + thread, + ```x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':query}```, + } } -@enum RD_EntityKind: +@struct RD_NameSchemaInfo: { - @expand(RD_EntityKindTable a) `$(a.name)`, - COUNT, + `String8 name`; + `String8 schema`; } -@data(String8) d_entity_kind_display_string_table: +@data(RD_NameSchemaInfo) rd_name_schema_info_table: { - @expand(RD_EntityKindTable a) `str8_lit_comp("$(a.display_string)")`, -} - -@data(String8) d_entity_kind_name_lower_table: -{ - @expand(RD_EntityKindTable a) `str8_lit_comp("$(a.name_lower)")`, -} - -@data(String8) d_entity_kind_name_lower_plural_table: -{ - @expand(RD_EntityKindTable a) `str8_lit_comp("$(a.name_lower_plural)")`, -} - -@data(String8) d_entity_kind_name_label_table: -{ - @expand(RD_EntityKindTable a) `str8_lit_comp("$(a.name_label)")`, -} - -@data(RD_EntityKindFlags) rd_entity_kind_flags_table: -{ - @expand(RD_EntityKindTable a) `($(a.op_delete)*RD_EntityKindFlag_CanDelete) | ($(a.op_freeze)*RD_EntityKindFlag_CanFreeze) | ($(a.op_edit)*RD_EntityKindFlag_CanEdit) | ($(a.op_rename)*RD_EntityKindFlag_CanRename) | ($(a.op_enable)*RD_EntityKindFlag_CanEnable) | ($(a.op_cond)*RD_EntityKindFlag_CanCondition) | ($(a.op_dup)*RD_EntityKindFlag_CanDuplicate) | ($(a.name_is_code)*RD_EntityKindFlag_NameIsCode) | ($(a.name_is_path)*RD_EntityKindFlag_NameIsPath) | ($(a.user_lifetime)*RD_EntityKindFlag_UserDefinedLifetime) | ($(a.is_serialized)*RD_EntityKindFlag_IsSerializedToConfig)`, + @expand(RD_SchemaTable a) `{str8_lit_comp("$(a.name)"), str8_lit_comp("$(a.schema)")}` } //////////////////////////////// @@ -150,19 +330,21 @@ RD_EntityKindTable: @table(c_type name_lower name) RD_RegTable: { - // rjf: entity slots + // rjf: ctrl entities {CTRL_Handle machine Machine } {CTRL_Handle module Module } {CTRL_Handle process Process } {CTRL_Handle thread Thread } {CTRL_Handle ctrl_entity CtrlEntity } - {RD_Handle window Window } - {RD_Handle panel Panel } - {RD_Handle view View } - {RD_Handle prev_view PrevView } - {RD_Handle dst_panel DstPanel } - {RD_Handle entity Entity } - {RD_HandleList entity_list EntityList } + + // rjf: cfgs + {RD_CfgID window Window } + {RD_CfgID panel Panel } + {RD_CfgID view View } + {RD_CfgID prev_view PrevView } + {RD_CfgID dst_panel DstPanel } + {RD_CfgID cfg Cfg } + {RD_CfgIDList cfg_list CfgList } // rjf: frame selection {U64 unwind_count UnwindCount } @@ -181,10 +363,22 @@ RD_RegTable: {Rng1U64 vaddr_range VaddrRange } {Rng1U64 voff_range VoffRange } + // rjf: evaluation + {String8 expr Expr } + {String8 view_rule ViewRule } + + // rjf: ui context + {UI_Key ui_key UIKey } + {Vec2F32 off_px OffPx } + {RD_ListerFlags lister_flags ListerFlags } + {RD_RegSlot reg_slot RegSlot } + // rjf: general parameters {U32 pid PID } {B32 force_confirm ForceConfirm } {B32 prefer_disasm PreferDisasm } + {B32 no_rich_tooltip NoRichTooltip } + {B32 do_implicit_root DoImplicitRoot} {Dir2 dir2 Dir2 } {String8 string String } {String8 cmd_name CmdName } @@ -220,269 +414,275 @@ RD_RegTable: //////////////////////////////// //~ rjf: Command Table -@table(name ui_vis ipc_docs_vis q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ) -// / | | | \___ _____________________________________________________/ | | | | | -// / | | | \ / | | | | | -RD_CmdTable: // | | | | | | | | | | +@table(name ui_vis ipc_docs_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_floating q_required canonical_icon string display_name desc search_tags ctx_filter) +// / | | | | \___ __________________________/ | | | | | | +// / | | | | \ / | | | | | | +RD_CmdTable: // | | | | | | | | | | | | { //- rjf: exiting - {Exit 1 1 Null null Nil Null 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" } + {Exit 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" "" } + + //- rjf: top-level lister + {OpenLister 1 1 "query:lister" Null null Nil Null 0 0 0 0 0 0 0 Null "open_lister" "Open Lister" "Opens the lister." "help,cmd" "" } //- rjf: command runner - {RunCommand 1 1 CmdName commands Nil Null 0 0 0 0 0 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" } + {RunCommand 1 1 "query:commands" CmdName commands Nil Null 0 0 0 0 0 1 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" } //- rjf: os event passthrough - {OSEvent 0 0 Null null Nil Null 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" } + {OSEvent 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" "" } //- rjf: thread/frame selection - {SelectThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Null "select_thread" "Select Thread" "Selects a thread." "" } - {SelectUnwind 0 1 Null null Nil Null 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" } - {UpOneFrame 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" } - {DownOneFrame 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" } + {SelectThread 0 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Thread "select_thread" "Select Thread" "Selects a thread." "" "" } + {SelectUnwind 0 1 "query:call_stack" Null null Nil Null 0 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } + {UpOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" "" } + {DownOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" "" } + {SelectEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_entity" "Select Entity" "Selects a control entity." "" "" } + {DeselectEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_entity" "Deselect Entity" "Deselects a control entity." "" "" } //- rjf: font sizes - {IncUIFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "inc_ui_font_scale" "Increase UI Font Scale" "Increases the font size used for UI." "" } - {DecUIFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "dec_ui_font_scale" "Decrease UI Font Scale" "Decreases the font size used for UI." "" } - {IncCodeFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "inc_code_font_scale" "Increase Code Font Scale" "Increases the font size used for code." "" } - {DecCodeFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "dec_code_font_scale" "Decrease Code Font Scale" "Decreases the font size used for code." "" } + {IncUIFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_ui_font_scale" "Increase UI Font Scale" "Increases the font size used for UI." "" "" } + {DecUIFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_ui_font_scale" "Decrease UI Font Scale" "Decreases the font size used for UI." "" "" } + {IncCodeFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_code_font_scale" "Increase Code Font Scale" "Increases the font size used for code." "" "" } + {DecCodeFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_code_font_scale" "Decrease Code Font Scale" "Decreases the font size used for code." "" "" } //- rjf: windows - {OpenWindow 1 1 Null null Nil Null 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" } - {CloseWindow 1 1 Null null Nil Null 0 0 0 0 0 0 Window "close_window" "Close Window" "Closes an opened window." "" } - {ToggleFullscreen 1 1 Null null Nil Null 0 0 0 0 0 0 Window "toggle_fullscreen" "Toggle Fullscreen" "Toggles fullscreen view on the active window." "" } - {BringToFront 0 1 Null null Nil Null 0 0 0 0 0 0 Window "bring_to_front" "Bring To Front" "Brings all windows to the front, and focuses the most recently focused window." "top" } + {OpenWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" "" } + {CloseWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "close_window" "Close Window" "Closes an opened window." "" "" } + {ToggleFullscreen 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "toggle_fullscreen" "Toggle Fullscreen" "Toggles fullscreen view on the active window." "" "" } + {BringToFront 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "bring_to_front" "Bring To Front" "Brings all windows to the front, and focuses the most recently focused window." "top" "" } //- rjf: popups - {PopupAccept 0 1 Null null Nil Null 0 0 0 0 0 0 Null "popup_accept" "Popup Accept" "Accepts the active popup prompt." "" } - {PopupCancel 0 1 Null null Nil Null 0 0 0 0 0 0 Null "popup_cancel" "Popup Cancel" "Cancels the active popup prompt." "" } + {PopupAccept 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "popup_accept" "Popup Accept" "Accepts the active popup prompt." "" "" } + {PopupCancel 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "popup_cancel" "Popup Cancel" "Cancels the active popup prompt." "" "" } //- rjf: panel splitting - {ResetToDefaultPanels 1 1 Null null Nil Null 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" } - {ResetToCompactPanels 1 1 Null null Nil Null 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" } - {NewPanelLeft 1 1 Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_left" "Split Panel Left" "Creates a new panel to the left of the active panel." "panel" } - {NewPanelUp 1 1 Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_up" "Split Panel Up" "Creates a new panel at the top of the active panel." "panel" } - {NewPanelRight 1 1 Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_right" "Split Panel Right" "Creates a new panel to the right of the active panel." "panel" } - {NewPanelDown 1 1 Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_down" "Split Panel Down" "Creates a new panel at the bottom of the active panel." "panel" } - {SplitPanel 0 0 Null null Nil Null 0 0 0 0 0 0 Null "split_panel" "Split Panel" "Creates a new panel in a given direction, and moves a tab to it, if specified." "" } + {ResetToDefaultPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" "" } + {ResetToCompactPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" "" } + {ResetToSimplePanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_simple_panels" "Reset To Simple Panel Layout" "Resets the window to the simple panel layout." "panel" "" } + {NewPanelLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 XSplit "new_panel_left" "Split Panel Left" "Creates a new panel to the left of the active panel." "panel" "" } + {NewPanelUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 YSplit "new_panel_up" "Split Panel Up" "Creates a new panel at the top of the active panel." "panel" "" } + {NewPanelRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 XSplit "new_panel_right" "Split Panel Right" "Creates a new panel to the right of the active panel." "panel" "" } + {NewPanelDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 YSplit "new_panel_down" "Split Panel Down" "Creates a new panel at the bottom of the active panel." "panel" "" } + {SplitPanel 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "split_panel" "Split Panel" "Creates a new panel in a given direction, and moves a tab to it, if specified." "" "" } //- rjf: panel rotation - {RotatePanelColumns 1 1 Null null Nil Null 0 0 0 0 0 0 Null "rotate_panel_columns" "Rotate Panel Columns" "Rotates all panels at the closest column level of the panel hierarchy." "" } + {RotatePanelColumns 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "rotate_panel_columns" "Rotate Panel Columns" "Rotates all panels at the closest column level of the panel hierarchy." "" "" } //- rjf: focused panel changing - {NextPanel 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "next_panel" "Focus Next Panel" "Cycles the active panel forward." "" } - {PrevPanel 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_panel" "Focus Previous Panel" "Cycles the active panel backwards." "" } - {FocusPanel 0 0 Null null Nil Null 0 0 0 0 0 0 Null "focus_panel" "Focus Panel" "Focuses a new panel." "" } - {FocusPanelRight 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "focus_panel_right" "Focus Panel Right" "Focuses a panel rightward of the currently focused panel." "" } - {FocusPanelLeft 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "focus_panel_left" "Focus Panel Left" "Focuses a panel leftward of the currently focused panel." "" } - {FocusPanelUp 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "focus_panel_up" "Focus Panel Up" "Focuses a panel upward of the currently focused panel." "" } - {FocusPanelDown 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "focus_panel_down" "Focus Panel Down" "Focuses a panel downward of the currently focused panel." "" } + {NextPanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "next_panel" "Focus Next Panel" "Cycles the active panel forward." "" "" } + {PrevPanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "prev_panel" "Focus Previous Panel" "Cycles the active panel backwards." "" "" } + {FocusPanel 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "focus_panel" "Focus Panel" "Focuses a new panel." "" "" } + {FocusPanelRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "focus_panel_right" "Focus Panel Right" "Focuses a panel rightward of the currently focused panel." "" "" } + {FocusPanelLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "focus_panel_left" "Focus Panel Left" "Focuses a panel leftward of the currently focused panel." "" "" } + {FocusPanelUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "focus_panel_up" "Focus Panel Up" "Focuses a panel upward of the currently focused panel." "" "" } + {FocusPanelDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "focus_panel_down" "Focus Panel Down" "Focuses a panel downward of the currently focused panel." "" "" } //- rjf: undo/redo - {Undo 0 0 Null null Nil Null 0 0 0 0 0 0 Undo "undo" "Undo" "Undoes the previous action." "" } - {Redo 0 0 Null null Nil Null 0 0 0 0 0 0 Redo "redo" "Redo" "Redoes the first previously undone action." "" } + {Undo 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Undo "undo" "Undo" "Undoes the previous action." "" "" } + {Redo 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Redo "redo" "Redo" "Redoes the first previously undone action." "" "" } //- rjf: focus history - {GoBack 0 0 Null null Nil Null 0 0 0 0 0 0 LeftArrow "go_back" "Go Back" "Returns to the previously selected panel and tab in recorded history." "" } - {GoForward 0 0 Null null Nil Null 0 0 0 0 0 0 RightArrow "go_forward" "Go Forward" "Returns to the next selected panel and tab in recorded history." "" } + {GoBack 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "go_back" "Go Back" "Returns to the previously selected panel and tab in recorded history." "" "" } + {GoForward 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "go_forward" "Go Forward" "Returns to the next selected panel and tab in recorded history." "" "" } //- rjf: panel removal - {ClosePanel 1 1 Null null Nil Null 0 0 0 0 0 0 ClosePanel "close_panel" "Close Panel" "Closes the currently active panel." "" } + {ClosePanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 ClosePanel "close_panel" "Close Panel" "Closes the currently active panel." "" "" } //- rjf: panel tab - {NextTab 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "next_tab" "Focus Next Tab" "Focuses the next tab on the active panel." "" } - {PrevTab 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" } - {MoveTabRight 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" } - {MoveTabLeft 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" } - {OpenTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" } - {CloseTab 1 1 Null null Nil Null 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" } - {MoveTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" } - {TabBarTop 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" } - {TabBarBottom 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" } + {FocusTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "focus_tab" "Focus Tab" "Focuses the passed tab within its containing panel." "" "" } + {NextTab 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "next_tab" "Focus Next Tab" "Focuses the next tab on the active panel." "" "" } + {PrevTab 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" "" } + {MoveTabRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" "$tab," } + {MoveTabLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" "$tab," } + {OpenTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" "" } + {CloseTab 1 1 "" View null Nil Null 0 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } + {MoveTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } + {TabBarTop 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } + {TabBarBottom 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" "$tab," } //- rjf: files - {SetCurrentPath 0 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" } - {Open 1 1 FilePath null Nil Null 1 0 0 0 0 1 FileOutline "open" "Open" "Opens a file." "code,source,file" } - {Switch 1 1 Entity null RecentFile Null 0 0 0 0 0 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" } - {SwitchToPartnerFile 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" } - {RecordFileInProject 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" } + {SetCurrentPath 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } + {Open 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } + {Switch 1 1 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } + {SwitchToPartnerFile 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } + {RecordFileInProject 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } + {ShowFileInExplorer 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } //- rjf: source <-> disasm - {GoToDisassembly 1 1 Null null Nil Null 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" } - {GoToSource 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "go_to_source" "Go To Source" "Goes to the source code, if any, for a given disassembly line." "code,source,disassembly,disasm" } + {GoToDisassembly 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" "$text_pt," } + {GoToSource 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "go_to_source" "Go To Source" "Goes to the source code, if any, for a given disassembly line." "code,source,disassembly,disasm" "" } //- rjf: override file links - {SetFileReplacementPath 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" } + {SetFileReplacementPath 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" "" } //- rjf: setting config paths - {OpenUser 1 1 FilePath null Nil Null 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" } - {OpenProject 1 1 FilePath null Nil Null 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" } - {OpenRecentProject 1 1 Entity null RecentProject Null 0 0 0 0 0 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" } - - //- rjf: loading/applying stateful config changes - {ApplyUserData 0 0 Null null Nil Null 0 0 0 0 0 0 Null "apply_user_data" "Apply User Data" "Applies user data from the active user file." "" } - {ApplyProjectData 0 0 Null null Nil Null 0 0 0 0 0 0 Null "apply_project_data" "Apply Project Data" "Applies project data from the active project file." "" } + {OpenUser 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } + {OpenProject 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } + {OpenRecentProject 1 1 "query:recent_projects" Cfg null RecentProject Null 0 0 0 0 0 1 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } //- rjf: writing config changes - {WriteUserData 0 1 Null null Nil Null 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" } - {WriteProjectData 0 1 Null null Nil Null 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" } + {WriteUserData 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } + {WriteProjectData 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" "" } //- rjf: meta controls - {Edit 1 1 Null null Nil Null 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" } - {Accept 1 1 Null null Nil Null 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" } - {Cancel 1 1 Null null Nil Null 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" } + {Edit 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" "" } + {Accept 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" "" } + {Cancel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" "" } //- rjf: directional movement & text controls - {MoveLeft 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" } - {MoveRight 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" } - {MoveUp 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up" "Move Up" "Moves the cursor or selection up." "" } - {MoveDown 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down" "Move Down" "Moves the cursor or selection down." "" } - {MoveLeftSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_select" "Move Left Select" "Moves the cursor or selection left, while selecting." "" } - {MoveRightSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_select" "Move Right Select" "Moves the cursor or selection right, while selecting." "" } - {MoveUpSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_select" "Move Up Select" "Moves the cursor or selection up, while selecting." "" } - {MoveDownSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_select" "Move Down Select" "Moves the cursor or selection down, while selecting." "" } - {MoveLeftChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Select" "Moves the cursor or selection left one chunk." "" } - {MoveRightChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Select" "Moves the cursor or selection right one chunk." "" } - {MoveUpChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk" "Move Up Chunk" "Moves the cursor or selection up one chunk." "" } - {MoveDownChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk" "Move Down Chunk" "Moves the cursor or selection down one chunk." "" } - {MoveUpPage 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_page" "Move Up Page" "Moves the cursor or selection up one page." "" } - {MoveDownPage 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_page" "Move Down Page" "Moves the cursor or selection down one page." "" } - {MoveUpWhole 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole" "Move Up Whole" "Moves the cursor or selection to the beginning of the relevant content." "" } - {MoveDownWhole 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole" "Move Down Whole" "Moves the cursor or selection to the end of the relevant content." "" } - {MoveLeftChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk_select" "Move Left Chunk Select" "Moves the cursor or selection left one chunk." "" } - {MoveRightChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk_select" "Move Right Chunk Select" "Moves the cursor or selection right one chunk." "" } - {MoveUpChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk_select" "Move Up Chunk Select" "Moves the cursor or selection up one chunk." "" } - {MoveDownChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk_select" "Move Down Chunk Select" "Moves the cursor or selection down one chunk." "" } - {MoveUpPageSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_page_select" "Move Up Page Select" "Moves the cursor or selection up one page, while selecting." "" } - {MoveDownPageSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" } - {MoveUpWholeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" } - {MoveDownWholeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" } - {MoveUpReorder 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" } - {MoveDownReorder 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" } - {MoveHome 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" } - {MoveEnd 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" } - {MoveHomeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" } - {MoveEndSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_end_select" "Move End Select" "Moves the cursor to the end of the line, while selecting." "" } - {SelectAll 1 1 Null null Nil Null 0 0 0 0 0 0 Null "select_all" "Select All" "Selects everything possible." "" } - {DeleteSingle 1 1 Null null Nil Null 0 0 0 0 0 0 Null "delete_single" "Delete Single" "Deletes a single element to the right of the cursor, or the active selection." "" } - {DeleteChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "delete_chunk" "Delete Chunk" "Deletes a chunk to the right of the cursor, or the active selection." "" } - {BackspaceSingle 1 1 Null null Nil Null 0 0 0 0 0 0 Null "backspace_single" "Backspace Single" "Deletes a single element to the left of the cursor, or the active selection." "" } - {BackspaceChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "backspace_chunk" "Backspace Chunk" "Deletes a chunk to the left of the cursor, or the active selection." "" } - {Copy 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "copy" "Copy" "Copies the active selection to the clipboard." "" } - {Cut 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "cut" "Cut" "Copies the active selection to the clipboard, then deletes it." "" } - {Paste 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" } - {InsertText 0 1 Null null Nil Null 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" } + {MoveLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" "" } + {MoveRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" "" } + {MoveUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up" "Move Up" "Moves the cursor or selection up." "" "" } + {MoveDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down" "Move Down" "Moves the cursor or selection down." "" "" } + {MoveLeftSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_select" "Move Left Select" "Moves the cursor or selection left, while selecting." "" "" } + {MoveRightSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_select" "Move Right Select" "Moves the cursor or selection right, while selecting." "" "" } + {MoveUpSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_select" "Move Up Select" "Moves the cursor or selection up, while selecting." "" "" } + {MoveDownSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_select" "Move Down Select" "Moves the cursor or selection down, while selecting." "" "" } + {MoveLeftChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Chunk" "Moves the cursor or selection left one chunk." "" "" } + {MoveRightChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Chunk" "Moves the cursor or selection right one chunk." "" "" } + {MoveUpChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_chunk" "Move Up Chunk" "Moves the cursor or selection up one chunk." "" "" } + {MoveDownChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_chunk" "Move Down Chunk" "Moves the cursor or selection down one chunk." "" "" } + {MoveUpPage 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_page" "Move Up Page" "Moves the cursor or selection up one page." "" "" } + {MoveDownPage 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_page" "Move Down Page" "Moves the cursor or selection down one page." "" "" } + {MoveUpWhole 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_whole" "Move Up Whole" "Moves the cursor or selection to the beginning of the relevant content." "" "" } + {MoveDownWhole 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_whole" "Move Down Whole" "Moves the cursor or selection to the end of the relevant content." "" "" } + {MoveLeftChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_chunk_select" "Move Left Chunk Select" "Moves the cursor or selection left one chunk." "" "" } + {MoveRightChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_chunk_select" "Move Right Chunk Select" "Moves the cursor or selection right one chunk." "" "" } + {MoveUpChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_chunk_select" "Move Up Chunk Select" "Moves the cursor or selection up one chunk." "" "" } + {MoveDownChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_chunk_select" "Move Down Chunk Select" "Moves the cursor or selection down one chunk." "" "" } + {MoveUpPageSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_page_select" "Move Up Page Select" "Moves the cursor or selection up one page, while selecting." "" "" } + {MoveDownPageSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" "" } + {MoveUpWholeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" "" } + {MoveDownWholeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" "" } + {MoveUpReorder 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" "" } + {MoveDownReorder 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" "" } + {MoveHome 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" "" } + {MoveEnd 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" "" } + {MoveHomeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" "" } + {MoveEndSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_end_select" "Move End Select" "Moves the cursor to the end of the line, while selecting." "" "" } + {SelectAll 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "select_all" "Select All" "Selects everything possible." "" "" } + {DeleteSingle 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "delete_single" "Delete Single" "Deletes a single element to the right of the cursor, or the active selection." "" "" } + {DeleteChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "delete_chunk" "Delete Chunk" "Deletes a chunk to the right of the cursor, or the active selection." "" "" } + {BackspaceSingle 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "backspace_single" "Backspace Single" "Deletes a single element to the left of the cursor, or the active selection." "" "" } + {BackspaceChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "backspace_chunk" "Backspace Chunk" "Deletes a chunk to the left of the cursor, or the active selection." "" "" } + {Copy 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "copy" "Copy" "Copies the active selection to the clipboard." "" "$text_rng," } + {Cut 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "cut" "Cut" "Copies the active selection to the clipboard, then deletes it." "" "" } + {Paste 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" "" } + {InsertText 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" "" } //- rjf: code navigation - {GoToLine 1 1 Cursor null Nil Null 0 0 0 0 1 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" } - {GoToAddress 1 1 Vaddr null Nil Null 0 0 0 0 1 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" } - {CenterCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" } - {ContainCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" } - {FindTextForward 1 1 String null Nil Null 0 0 1 1 1 1 Find "find_text_forward" "Find Text (Forward)" "Searches the current code file forward (from the cursor) for a string." "" } - {FindTextBackward 1 1 String null Nil Null 0 0 1 1 1 1 Find "find_text_backward" "Find Text (Backwards)" "Searches the current code file backwards (from the cursor) for a string." "" } - {FindNext 1 1 Null null Nil Null 0 0 1 0 0 0 Find "find_next" "Find Next" "Searches the current code file forward (from the cursor) for the last searched string." "" } - {FindPrev 1 1 Null null Nil Null 0 0 1 0 0 0 Find "find_prev" "Find Previous" "Searches the current code file backwards (from the cursor) for the last searched string." "" } + {GoToLine 1 1 "" Cursor null Nil Null 0 0 0 0 1 0 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" "" } + {GoToAddress 1 1 "" Vaddr null Nil Null 0 0 0 0 1 0 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" "" } + {CenterCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" "" } + {ContainCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" "" } + {FindTextForward 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "find_text_forward" "Find Text (Forward)" "Searches the current code file forward (from the cursor) for a string." "" "" } + {FindTextBackward 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "find_text_backward" "Find Text (Backwards)" "Searches the current code file backwards (from the cursor) for a string." "" "" } + {FindNext 1 1 "" Null null Nil Null 0 0 1 0 0 0 0 Find "find_next" "Find Next" "Searches the current code file forward (from the cursor) for the last searched string." "" "" } + {FindPrev 1 1 "" Null null Nil Null 0 0 1 0 0 0 0 Find "find_prev" "Find Previous" "Searches the current code file backwards (from the cursor) for the last searched string." "" "" } //- rjf: thread finding - {FindThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Find "find_thread" "Find Thread" "Jumps to the passed thread in either source code, disassembly, or both if they're already open." "" } - {FindSelectedThread 1 1 Null null Nil Null 0 0 0 0 0 0 Find "find_selected_thread" "Find Selected Thread" "Jumps to the selected thread in either source code, disassembly, or both if they're already open." "" } + {FindThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Find "find_thread" "Find Thread" "Jumps to the passed thread in either source code, disassembly, or both if they're already open." "" "" } + {FindSelectedThread 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Find "find_selected_thread" "Find Selected Thread" "Jumps to the selected thread in either source code, disassembly, or both if they're already open." "" "" } //- rjf: name finding - {GoToName 1 1 String symbol_lister Nil Null 0 0 0 0 1 1 Null "goto_name" "Go To Name" "Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible." "" } - {GoToNameAtCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "goto_name_at_cursor" "Go To Name At Cursor" "Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible." "" } + {GoToName 1 1 "query:procedures" String symbol_lister Nil Null 0 0 0 0 1 1 1 Null "goto_name" "Go To Name" "Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible." "" "$text_pt," } + {GoToNameAtCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "goto_name_at_cursor" "Go To Name At Cursor" "Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible." "" "" } //- rjf: watch expressions - {ToggleWatchExpression 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr" "Toggle Watch Expression" "Adds or removes an expression to an opened watch view." "" } - {ToggleWatchExpressionAtCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_cursor" "Toggle Watch Expression At Cursor" "Adds or removes the expression that the cursor or selection is currently over to an opened watch view." "" } - {ToggleWatchExpressionAtMouse 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" } + {ToggleWatchExpression 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr" "Toggle Watch Expression" "Adds or removes an expression to an opened watch view." "" "$text_pt," } + {ToggleWatchExpressionAtCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_cursor" "Toggle Watch Expression At Cursor" "Adds or removes the expression that the cursor or selection is currently over to an opened watch view." "" "" } + {ToggleWatchExpressionAtMouse 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" "" } //- rjf: memory view parameterization - {SetColumns 1 1 Null null Nil Null 0 0 0 0 1 1 Thumbnails "set_columns" "Set Columns" "Sets the number of columns for a memory view." "" } + {SetColumns 1 1 "" Null null Nil Null 0 0 0 0 1 1 1 Thumbnails "set_columns" "Set Columns" "Sets the number of columns for a memory view." "" "" } //- rjf: disassembly view parameterization - {ToggleAddressVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_address_visibility" "Toggle Address Visibility" "Toggles the visibility of addresses in a disassembly view." "" } - {ToggleCodeBytesVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" } + {ToggleAddressVisibility 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Thumbnails "toggle_address_visibility" "Toggle Address Visibility" "Toggles the visibility of addresses in a disassembly view." "" "$disasm," } + {ToggleCodeBytesVisibility 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" "$disasm," } - //- rjf: general entity operations - {EnableEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "enable_entity" "Enable Entity" "Enables an entity." "" } - {DisableEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "disable_entity" "Disable Entity" "Disables an entity." "" } - {SelectEntity 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "select_entity" "Select Entity" "Selects an entity, disabling all others of the same kind." "" } - {RemoveEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_entity" "Remove Entity" "Removes an entity." "" } - {NameEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_entity" "Name Entity" "Equips an entity with a name." "" } - {ConditionEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "condition_entity" "Condition Entity" "Equips an entity with a condition string." "" } - {DuplicateEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "duplicate_entity" "Duplicate Entity" "Duplicates an entity." "" } - {RelocateEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "relocate_entity" "Relocate Entity" "Relocates an entity." "" } + //- rjf: general config operations + {EnableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } + {DisableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } + {SelectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } + {DeselectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect Config Tree" "Deselects a config tree." "" "" } + {RemoveCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } + {NameCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } + {ConditionCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } + {DuplicateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "duplicate_cfg" "Duplicate Config Tree" "Duplicates a config tree." "" "" } + {RelocateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates a config tree." "" "" } //- rjf: breakpoints - {AddBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" } - {AddAddressBreakpoint 1 0 Vaddr null Nil Null 0 0 0 0 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" } - {AddFunctionBreakpoint 1 0 String symbol_lister Nil Null 0 0 0 0 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" } - {ToggleBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" } - {EnableBreakpoint 1 1 Entity null Breakpoint Null 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" } - {DisableBreakpoint 1 1 Entity null Breakpoint Null 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" } + {AddBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } + {AddAddressBreakpoint 1 0 "" Expr null Nil Null 0 0 0 0 1 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } + {AddFunctionBreakpoint 1 0 "query:procedures" Expr symbol_lister Nil Null 0 0 0 0 1 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" "$breakpoints," } + {ToggleBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } + {EnableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } + {DisableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } //- rjf: watch pins - {AddWatchPin 1 1 String null Nil Null 0 0 0 0 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" } - {ToggleWatchPin 1 0 String null Nil Null 0 0 0 0 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" } + {AddWatchPin 1 1 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } + {ToggleWatchPin 1 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } - //- rjf: cursor operations - {RunToCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Play "run_to_cursor" "Run To Cursor" "Runs the selected thread to the current cursor." "line" } - {SetNextStatement 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" } + //- rjf: auto view rule + {AddAutoViewRule 1 1 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } + + //- rjf: line operations + {SetNextStatement 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } //- rjf: targets - {AddTarget 1 1 FilePath null Nil Null 1 0 0 0 0 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" } - {SelectTarget 1 1 Entity null Target Null 0 0 0 0 0 1 Target "select_target" "Select Target" "Selects a target." "" } - {EnableTarget 1 1 Entity null Target Null 0 0 0 0 0 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" } - {DisableTarget 1 1 Entity null Target Null 0 0 0 0 0 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" } + {AddTarget 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } + {SelectTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 Target "select_target" "Select Target" "Selects a target." "" "" } + {EnableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } + {DisableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } //- rjf: attaching - {RegisterAsJITDebugger 1 1 Null null Nil Null 0 0 0 0 0 0 Null "register_as_jit_debugger" "Register As Just-In-Time (JIT) Debugger" "Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system." "" } + {RegisterAsJITDebugger 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "register_as_jit_debugger" "Register As Just-In-Time (JIT) Debugger" "Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system." "" "" } //- rjf: snap-to-code-location - {FindCodeLocation 0 1 FilePath null Nil Null 0 0 0 0 0 1 FileOutline "find_code_location" "Find Code Location" "Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary." "" } + {FindCodeLocation 0 1 "" FilePath null Nil Null 0 0 0 0 0 1 1 FileOutline "find_code_location" "Find Code Location" "Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary." "" "" } - //- rjf: general-purpose view filtering - {Filter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "filter" "Filter" "Begins filtering the active view." "sort,search,filter,find" } - {ApplyFilter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "apply_filter" "Apply Filter" "Applies the typed filter to the active view." "sort,search,filter,find,apply" } - {ClearFilter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "clear_filter" "Clear Filter" "Clears the filter applied to the active view." "sort,search,filter,find,clear" } + //- rjf: searching + {Search 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "search" "Search" "Begins searching within the active interface." "sort,search,filter,find" "" } + {SearchBackwards 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "search_backwards" "Search Backwards" "Begins searching backwards within the active interface." "sort,search,filter,find" "" } //- rjf: view drivers - {GettingStarted 1 1 Null null Nil Null 0 0 0 0 0 0 QuestionMark "getting_started" "Getting Started" "Opens the menu for information on getting started." "tutorial,help" } - {Commands 0 0 Null null Nil Null 0 0 0 0 0 0 List "commands" "Commands" "Opens the list of all commands." "" } - {Target 0 0 Null null Nil Null 0 0 0 0 0 0 Target "target" "Target" "Opens the editor for a target." "" } - {Targets 1 1 Null null Nil Null 0 0 0 0 0 0 Target "targets" "Targets" "Opens the list of all targets." "" } - {FilePathMap 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "file_path_map" "File Path Map" "Opens the file path mapping editor." "" } - {AutoViewRules 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "auto_view_rules" "Auto View Rules" "Opens the auto view rule editor." "" } - {Breakpoints 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "breakpoints" "Breakpoints" "Opens the breakpoints view." "" } - {WatchPins 1 1 Null null Nil Null 0 0 0 0 0 0 Pin "watch_pins" "Watch Pins" "Opens the watch pins view." "" } - {Scheduler 1 1 Null null Nil Null 0 0 0 0 0 0 Scheduler "scheduler" "Scheduler" "Opens the scheduler view, for process and thread controls." "threads,processes,targets" } - {CallStack 1 1 Null null Nil Null 0 0 0 0 0 0 Thread "call_stack" "Call Stack" "Opens the call stack view." "callstack,thread,unwind" } - {Modules 1 1 Null null Nil Null 0 0 0 0 0 0 Module "modules" "Modules" "Opens the modules view." "" } - {Watch 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "watch" "Watch" "Opens a watch view." "" } - {Locals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "locals" "Locals" "Opens a locals view." "" } - {Registers 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "registers" "Registers" "Opens a registers view." "" } - {Globals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "globals" "Globals" "Opens a globals view." "" } - {ThreadLocals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "thread_locals" "Thread Locals" "Opens a thread locals view." "" } - {Types 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "types" "Types" "Opens a types view." "" } - {Procedures 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "procedures" "Procedures" "Opens a procedures view." "" } - {PendingFile 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "pending_file" "Pending File" "Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it." "" } - {Disassembly 1 1 Null null Nil Null 0 0 0 0 0 0 Glasses "disasm" "Disassembly" "Opens the disassembly view." "disasm" } - {Output 1 1 Null null Nil Null 0 0 0 0 0 0 List "output" "Output" "Opens an output view." "" } - {Memory 1 1 Null null Nil Null 0 0 0 0 0 0 Grid "memory" "Memory" "Opens a memory view." "" } - {ExceptionFilters 1 1 Null null Nil Null 0 0 0 0 0 0 Gear "exception_filters" "Exception Filters" "Opens the exception filters view." "exceptions,filters" } - {Settings 1 1 Null null Nil Null 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" } + {GettingStarted 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 QuestionMark "getting_started" "Getting Started" "Opens the menu for information on getting started." "tutorial,help" "" } + {Commands 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 List "commands" "Commands" "Opens the list of all commands." "" "" } + {Targets 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Target "targets" "Targets" "Opens the list of all targets." "" "" } + {FilePathMap 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "file_path_map" "File Path Map" "Opens the file path mapping editor." "" "" } + {AutoViewRules 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "auto_view_rules" "Auto View Rules" "Opens the auto view rule editor." "" "" } + {Breakpoints 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "breakpoints" "Breakpoints" "Opens the breakpoints view." "" "" } + {WatchPins 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Pin "watch_pins" "Watch Pins" "Opens the watch pins view." "" "" } + {Scheduler 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Scheduler "scheduler" "Scheduler" "Opens the scheduler view, for process and thread controls." "threads,processes,targets" "" } + {CallStack 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Thread "call_stack" "Call Stack" "Opens the call stack view." "callstack,thread,unwind" "" } + {Modules 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Module "modules" "Modules" "Opens the modules view." "" "" } + {Watch 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "watch" "Watch" "Opens a watch view." "" "" } + {Locals 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "locals" "Locals" "Opens a locals view." "" "" } + {Registers 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "registers" "Registers" "Opens a registers view." "" "" } + {Globals 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "globals" "Globals" "Opens a globals view." "" "" } + {ThreadLocals 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "thread_locals" "Thread Locals" "Opens a thread locals view." "" "" } + {Types 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "types" "Types" "Opens a types view." "" "" } + {Procedures 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "procedures" "Procedures" "Opens a procedures view." "" "" } + {PendingFile 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "pending_file" "Pending File" "Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it." "" "" } + {Disassembly 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Glasses "disasm" "Disassembly" "Opens the disassembly view." "disasm" "" } + {Output 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 List "output" "Output" "Opens an output view." "" "" } + {Memory 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Grid "memory" "Memory" "Opens a memory view." "" "" } + {Settings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" "" } //- rjf: queries - {PickFile 0 0 FilePath null Nil Null 1 0 0 0 0 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" } - {PickFolder 0 0 FilePath null Nil Null 0 1 0 0 0 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" } - {PickFileOrFolder 0 0 FilePath null Nil Null 1 1 0 0 0 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" } + {PickFile 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } + {PickFolder 0 0 `folder:\\"$input\\"` FilePath null Nil Null 0 1 0 0 0 1 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } + {PickFileOrFolder 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 1 0 0 0 1 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } - //- rjf: query completion - {CompleteQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "complete_query" "Complete Query" "Completes a query." "" } - {CancelQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "cancel_query" "Cancel Query" "Cancels a query." "" } + //- rjf: query stack + {PushQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" "" } + {CompleteQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" "" } + {CancelQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" "" } + {UpdateQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "update_lister" "Update Lister" "Updates a query input." "" "" } //- rjf: developer commands - {ToggleDevMenu 1 1 Null null Nil Null 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" } - {LogMarker 1 1 Null null Nil Null 0 0 0 0 0 0 Null "log_marker" "Log Marker" "Logs a marker in the application log, to denote specific points in time within the log." "" } + {ToggleDevMenu 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" "" } + {LogMarker 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "log_marker" "Log Marker" "Logs a marker in the application log, to denote specific points in time within the log." "" "" } } @enum RD_CmdKind: @@ -497,8 +697,8 @@ RD_CmdTable: // | | | | { `RD_QueryFlags flags`; `RD_RegSlot slot`; + `String8 expr`; `String8 view_name`; - `RD_EntityKind entity_kind`; `CTRL_EntityKind ctrl_entity_kind`; } @@ -507,8 +707,7 @@ RD_CmdTable: // | | | | `String8 string`; `String8 description`; `String8 search_tags`; - `String8 display_name`; - `RD_IconKind icon_kind`; + `String8 ctx_filter`; `RD_CmdKindFlags flags`; `RD_Query query`; }; @@ -517,9 +716,9 @@ RD_CmdTable: // | | | | { `{0}`, @expand(D_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), RD_EntityKind_$(a.q_ent_kind), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Floating*$(a.q_floating))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; @expand(RD_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), RD_EntityKind_$(a.q_ent_kind), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Floating*$(a.q_floating))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; } //////////////////////////////// @@ -535,14 +734,13 @@ RD_DefaultBindingTable: { "step_out" F11 0 shift 0 } { "halt" X ctrl shift 0 } { "halt" Pause 0 0 0 } - { "soft_halt_refresh" R 0 0 alt } //- rjf: high-level composite target control operations { "run" F5 0 0 0 } { "restart" F5 ctrl shift 0 } { "step_into" F11 0 0 0 } { "step_over" F10 0 0 0 } - { "run_to_cursor" F10 ctrl 0 0 } + { "run_to_line" F10 ctrl 0 0 } { "set_next_statement" F10 ctrl shift 0 } //- rjf: font sizes @@ -653,8 +851,8 @@ RD_DefaultBindingTable: //- rjf: code navigation { "goto_line" G ctrl 0 0 } { "goto_address" G 0 0 alt } - { "find_text_forward" F ctrl 0 0 } - { "find_text_backward" R ctrl 0 0 } + { "search" F ctrl 0 0 } + { "search_backwards" R ctrl 0 0 } { "find_next" F3 0 0 0 } { "find_prev" F3 shift 0 0 } @@ -679,17 +877,16 @@ RD_DefaultBindingTable: //- rjf: attaching { "attach" F6 0 shift 0 } - //- rjf: filtering - { "filter" Slash ctrl 0 0 } - //- rjf: command lister - { "run_command" F1 0 0 0 } + // { "run_command" F1 0 0 0 } + { "open_lister" F1 0 0 0 } //- rjf: developer commands { "log_marker" M ctrl shift alt } + { "toggle_dev_menu" D ctrl shift alt } } -@data(RD_StringBindingPair) rd_default_binding_table: +@data(`struct {String8 string; RD_Binding binding;}`) @c_file rd_default_binding_table: { @expand(RD_DefaultBindingTable a) ```{str8_lit_comp("$(a.name)"), {OS_Key_$(a.key), 0 $(a.ctrl != 0 -> `|OS_Modifier_Ctrl`) $(a.shift != 0 -> `|OS_Modifier_Shift`) $(a.alt != 0 -> `|OS_Modifier_Alt`)}}```; } @@ -755,6 +952,7 @@ RD_IconTable: (RadioFilled "o") (CheckHollow "!") (CheckFilled "1") + (Check "V") (LeftCaret "<") (RightCaret ">") (UpCaret "^") @@ -795,7 +993,11 @@ RD_IconTable: (QuestionMark "?") (Person "4") (Briefcase "5") - (Dot "c") + (Dot "6") + (Bitmap "&") + (Cube "*") + (WindowRestore "(") + (WindowMinimize ")") } @enum RD_IconKind: @@ -809,139 +1011,34 @@ RD_IconTable: @expand(RD_IconTable a) `str8_lit_comp("$(a.text)")`; } -//////////////////////////////// -//~ rjf: Collections - -@table(name entity_kind ctrl_entity_kind id_space) -RD_CollectionTable: -{ - //- rjf: frontend entity groups - {watches Watch Null x} - {targets Target Null x} - {breakpoints Breakpoint Null x} - {watch_pins WatchPin Null x} - {file_path_maps FilePathMap Null x} - {auto_view_rules AutoViewRule Null x} - - //- rjf: control entity groups - {machines Nil Machine x} - {processes Nil Process x} - {threads Nil Thread x} - {modules Nil Module x} - - //- rjf: scheduling control entity hierarchies - {scheduler_machine Nil Null x} - {scheduler_process Nil Null x} - - //- rjf: debug info / architecture watch tables - {locals Nil Null -} - {registers Nil Null -} - {globals Nil Null x} - {thread_locals Nil Null x} - {types Nil Null x} - {procedures Nil Null x} -} - -@gen -{ - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF($(a.name));`; - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF($(a.name));`; - @expand(RD_CollectionTable a) `$(a.id_space == x -> "EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF("..a.name..");")`; - @expand(RD_CollectionTable a) `$(a.id_space == x -> "EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF("..a.name..");")`; -} - -@data(String8) rd_collection_name_table: -{ - @expand(RD_CollectionTable a) `str8_lit_comp("$(a.name)")` -} - -@data(RD_EntityKind) rd_collection_entity_kind_table: -{ - @expand(RD_CollectionTable a) `RD_EntityKind_$(a.entity_kind)`, -} - -@data(CTRL_EntityKind) rd_collection_ctrl_entity_kind_table: -{ - @expand(RD_CollectionTable a) `CTRL_EntityKind_$(a.ctrl_entity_kind)`, -} - -@data(`EV_ViewRuleExprExpandInfoHookFunctionType *`) rd_collection_expr_expand_info_hook_function_table: -{ - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME($(a.name))` -} - -@data(`EV_ViewRuleExprExpandRangeInfoHookFunctionType *`) rd_collection_expr_expand_range_info_hook_function_table: -{ - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME($(a.name))` -} - -@data(`EV_ViewRuleExprExpandIDFromNumHookFunctionType *`) rd_collection_expr_expand_id_from_num_hook_function_table: -{ - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME($(a.id_space == x -> a.name)$(a.id_space != x -> identity))` -} - -@data(`EV_ViewRuleExprExpandIDFromNumHookFunctionType *`) rd_collection_expr_expand_num_from_id_hook_function_table: -{ - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME($(a.id_space == x -> a.name)$(a.id_space != x -> identity))` -} - //////////////////////////////// //~ rjf: View Rules -@table(name name_lower display_name params_schema icon can_filter filter_is_code typing_automatically_filters can_use_in_watch_table can_fill_value_cell can_expand show_in_docs description) +@table(name name_lower display_name params_schema icon can_filter filter_is_code typing_automatically_filters can_use_in_watch_table can_fill_value_cell can_expand show_in_docs description) RD_ViewRuleTable: { //- rjf: basics - { Empty empty "" "" Null 0 0 0 0 0 0 0 "" } - { GettingStarted getting_started "Getting Started" "" QuestionMark 0 0 0 0 0 0 0 "" } + { Empty empty "" "" Null 0 0 0 0 0 0 0 "" } + { GettingStarted getting_started "Getting Started" "" QuestionMark 0 0 0 0 0 0 0 "" } //- rjf: meta (settings) - { ExceptionFilters exception_filters "Exception Filters" "" Gear 0 0 0 0 0 0 1 "An interface which controls whether or not the debugger will halt attached processes upon encountering specific exception codes for the first time." } - { Settings settings "Settings" "" Gear 0 0 0 0 0 0 1 "An interface to modify general settings for the debugger's appearance and behavior." } + { Settings settings "Settings" "" Gear 0 0 0 0 0 0 1 "An interface to modify general settings for the debugger's appearance and behavior." } //- rjf: temporary view for loading files - must analyze file before picking viewer - { PendingFile pending_file "Pending File" "" FileOutline 0 0 0 0 0 0 0 "" } + { PendingFile pending_file "Pending File" "" FileOutline 0 0 0 0 0 0 0 "" } - //- rjf: query listers - { Commands commands "Commands" "" List 0 0 0 0 0 0 0 "" } - { FileSystem file_system "File System" "" FileOutline 0 0 0 0 0 0 0 "" } - { SystemProcesses system_processes "System Processes" "" Null 0 0 0 0 0 0 0 "" } - { EntityLister entity_lister "Entities" "" Null 0 0 0 0 0 0 0 "" } - { CtrlEntityLister ctrl_entity_lister "Control Entities" "" Null 0 0 0 0 0 0 0 "" } - { SymbolLister symbol_lister "Symbols" "" Null 0 0 0 0 0 0 0 "" } - - //- rjf: watch or watch-style tables - { Watch watch "Watch" "" Binoculars 1 1 1 0 0 0 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." } - { Locals locals "Locals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with local variables found within the selected call stack frame of the selected thread, according to the associated debug info. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Registers registers "Registers" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all register names according to the selected thread's architecture. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Globals globals "Globals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all global variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { ThreadLocals thread_locals "Thread Locals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all thread local variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Types types "Types" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all types within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Procedures procedures "Procedures" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all procedures within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - - //- rjf: configuration watch tables - { Targets targets "Targets" "" Target 1 1 1 0 0 0 1 "Displays a list of all targets, as well as controls for enabling, disabling, launching, editing, or deleting each target. For more information on targets, read the `Targets` section." } - { FilePathMap file_path_map "File Path Map" "" FileOutline 1 1 1 0 0 0 1 "Displays a table of *path maps*. Each path map is a pair of file or folder paths, one being a 'source' path, and one being a 'destination' path. These pairs are used by the debugger when automatically searching for specific files - for instance, when attempting to snap to a source code location specified by debug info. If debug info refers to a path on the machine on which a target executable was originally built, but that path is not valid on the debugger machine, but some alternative path exists, then path maps may be used to redirect the debugger from the debug info's specified paths to the associated appropriate debugger machine file paths." } - { AutoViewRules auto_view_rules "Auto View Rules" "" Binoculars 1 1 1 0 0 0 1 "Displays a table of *auto view rules*. Each *auto view rule* is a pair, with one element being a type, and the other being a view rule, which should be automatically applied to expressions of that type, when possible." } - { Breakpoints breakpoints "Breakpoints" "" CircleFilled 1 1 1 0 0 0 1 "Displays a table of all breakpoints, containing information about each breakpoint's name, location, and hit count. Also contains per-breakpoint controls for enabling, deleting, or editing each breakpoint. For more information on breakpoints and their features, read the 'Breakpoints' section." } - { WatchPins watch_pins "Watch Pins" "" Pin 1 1 1 0 0 0 1 "Displays a table of all watch pins (watched expressions, like those found in `Watch`, but instead of being within a table, being pinned to some source code location, like breakpoints). This table contains each pin's name, location, and controls for editing or deleting each pin." } - - //- rjf: debug entity info watch tables - { Scheduler scheduler "Scheduler" "" Scheduler 1 1 1 0 0 0 1 "Displays all processes and threads to which the debugger is currently attached, and contains controls for selecting and freezing threads." } - { CallStack call_stack "Call Stack" "" Thread 1 1 1 0 0 0 1 "Displays the call stack of the currently selected thread. Each frame in the call stack contains the associated module, function name, and return address. Allows selection of a particular call stack frame other than the top." } - { Modules modules "Modules" "" Module 1 1 1 0 0 0 1 "Displays a table of all modules currently loaded by any process to which the debugger is attached. This table displays each module's name, virtual address range in the containing process' address space, and which debug info file is being used by the debugger for the associated module." } - - //- rjf: data visualizers - { Text text "Text" "x:{'lang':lang, 'size':expr}" FileOutline 0 0 0 1 0 1 0 "" } - { Disasm disasm "Disassembly" "x:{'arch':arch, 'size':expr}" Glasses 0 0 0 1 0 1 1 "Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space." } - { Output output "Output" "" List 0 0 0 0 0 0 1 "Displays debug strings, output from attached processes." } - { Memory memory "Memory" "x:{'size':expr}" Grid 0 0 0 1 0 1 1 "A hex-editor-like grid interface for viewing memory." } - { Bitmap bitmap "Bitmap" "x:{'w':expr, 'h':expr, 'fmt':tex2dformat}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as a bitmap." } - { Checkbox checkbox "Checkbox" "" CheckFilled 0 0 0 1 1 0 1 "Visualizes memory as an RGBA color." } - { ColorRGBA color_rgba "Color (RGBA)" "" Palette 0 0 0 1 1 1 1 "Visualizes memory as an RGBA color." } - { Geo3D geo3d "Geometry (3D)" "x:{'count':expr, 'vtx':expr, 'vtx_size':expr}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as 3D geometry." } + //- rjf: visualizers + { Watch watch "Watch" "" Binoculars 1 1 1 0 0 0 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." } + { Text text "Text" "x:{'lang':lang, 'size':expr}" FileOutline 0 0 0 1 0 1 0 "" } + { Disasm disasm "Disassembly" "x:{'arch':arch, 'size':expr, 'addresses':bool, 'code_bytes':bool}" Glasses 0 0 0 1 0 1 1 "Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space." } + { Memory memory "Memory" "x:{'size':expr}" Grid 0 0 0 1 0 1 1 "A hex-editor-like grid interface for viewing memory." } + { Bitmap bitmap "Bitmap" "x:{'w':expr, 'h':expr, 'fmt':tex2dformat}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as a bitmap." } + { Checkbox checkbox "Checkbox" "" CheckFilled 0 0 0 1 1 0 1 "Visualizes memory as an RGBA color." } + { ColorRGBA color_rgba "Color (RGBA)" "" Palette 0 0 0 1 1 1 1 "Visualizes memory as an RGBA color." } + { Geo3D geo3d "Geometry (3D)" "x:{'count':expr, 'vtx':expr, 'vtx_size':expr}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as 3D geometry." } } +/* @enum RD_ViewRuleKind: { Null, @@ -957,38 +1054,165 @@ RD_ViewRuleTable: `String8 params_schema`; `RD_IconKind icon_kind`; `RD_ViewRuleInfoFlags flags`; - `EV_ViewRuleExprExpandInfoHookFunctionType *expr_expand_info`; + `EV_ExpandRuleInfoHookFunctionType *expr_expand_info`; `RD_ViewRuleUIFunctionType *ui`; } @gen { `RD_VIEW_RULE_UI_FUNCTION_DEF(null);`, - @expand(RD_ViewRuleTable a) `$(a.can_use_in_watch_table != 0 && a.can_expand != 0 -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`, + @expand(RD_ViewRuleTable a) `$(a.can_use_in_watch_table != 0 && a.can_expand != 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`, @expand(RD_ViewRuleTable a) `RD_VIEW_RULE_UI_FUNCTION_DEF($(a.name_lower));`, } @data(RD_ViewRuleInfo) rd_view_rule_kind_info_table: { - `{{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}`, - @expand(RD_ViewRuleTable a) `{str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.description)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.params_schema)"), RD_IconKind_$(a.icon), (RD_ViewRuleInfoFlag_ShowInDocs*$(a.show_in_docs)|RD_ViewRuleInfoFlag_CanFilter*$(a.can_filter)|RD_ViewRuleInfoFlag_FilterIsCode*$(a.filter_is_code)|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*$(a.typing_automatically_filters)|RD_ViewRuleInfoFlag_CanUseInWatchTable*$(a.can_use_in_watch_table)|RD_ViewRuleInfoFlag_CanFillValueCell*$(a.can_fill_value_cell)|RD_ViewRuleInfoFlag_CanExpand*$(a.can_expand)), $(a.can_expand != 0 -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(" .. a.name_lower .. ")") $(a.can_expand == 0 -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil)"), RD_VIEW_RULE_UI_FUNCTION_NAME($(a.name_lower))}`, -} - -//////////////////////////////// -//~ rjf: Built-In Debug Engine Kind -> Icon Kind Table - -@data(RD_IconKind) rd_entity_kind_icon_kind_table: -{ - @expand(RD_EntityKindTable a) `RD_IconKind_$(a.icon_kind)`, + `{{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}`, + @expand(RD_ViewRuleTable a) `{str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.description)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.params_schema)"), RD_IconKind_$(a.icon), (RD_ViewRuleInfoFlag_ShowInDocs*$(a.show_in_docs)|RD_ViewRuleInfoFlag_CanFilter*$(a.can_filter)|RD_ViewRuleInfoFlag_FilterIsCode*$(a.filter_is_code)|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*$(a.typing_automatically_filters)|RD_ViewRuleInfoFlag_CanUseInWatchTable*$(a.can_use_in_watch_table)|RD_ViewRuleInfoFlag_CanFillValueCell*$(a.can_fill_value_cell)|RD_ViewRuleInfoFlag_CanExpand*$(a.can_expand)), $(a.can_expand != 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_NAME(" .. a.name_lower .. ")") $(a.can_expand == 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil)"), RD_VIEW_RULE_UI_FUNCTION_NAME($(a.name_lower))}`, } +*/ //////////////////////////////// //~ rjf: Theme Tables -@table(name_upper name_lower display_string) +@table(name_upper name_lower display_string cfg) RD_ThemePresetTable: { - { DefaultDark default_dark "Default (Dark)" } + //- rjf: default dark theme + { + DefaultDark default_dark "Default (Dark)", + ```theme: + { + background: 0x1b1b1bff, + alt: background: 0x222222ff, + pop: background: 0x355b6eff, + fresh: background: 0x31393dff, + match: background: 0x31393dff, + border: 0x404040ff, + text: 0xe5e5e5ff, + weak: text: 0xa4a4a4ff, + good: text: 0x32a852ff, + bad: text: 0xcf5242ff, + hover: 0xffffffff, + focus: 0xfda200ff, + cursor: 0x8aff00ff, + selection: 0x99ccffff, + inactive: background: 0x0000002f, + drop_shadow: 0x0000007f, + + good_pop: + { + background: 0x2c5b36ff, + border: 0x568761ff, + hover: 0xe3f5d3ff, + weak: text: 0xe3f5d3ff, + } + + bad_pop: + { + background: 0x803425ff, + hover: 0xff825cff, + } + + code_default: 0xcbcbcbff, + code_symbol: 0x42a2cfff, + code_type: 0xfec746ff, + code_local: 0x98bc80ff, + code_register: 0xb7afd5ff, + code_keyword: 0xb38d4cff, + code_delimiter_or_operator: 0x767676ff, + code_numeric: 0x98abb1ff, + code_numeric_alt_digit_group: 0x738287ff, + code_string: 0x98abb1ff, + code_meta: 0xd96759ff, + code_comment: 0x717171ff, + line_info_0: 0x4f3022ff, + line_info_1: 0x4f3e15ff, + line_info_2: 0x434e2aff, + line_info_3: 0x36241fff, + line_info_4: 0x4f3022ff, + line_info_5: 0x4f3e15ff, + line_info_6: 0x434e2aff, + line_info_7: 0x36241fff, + thread_0: 0xffcb7fff, + thread_1: 0xb2ff65ff, + thread_2: 0xff99e5ff, + thread_3: 0x6598ffff, + thread_4: 0x65ffcbff, + thread_5: 0xff9819ff, + thread_6: 0x9932ffff, + thread_7: 0x65ff4cff, + thread_unwound: 0xb2ccd8ff, + thread_error: 0xb23219ff, + breakpoint: 0xa72911ff, + + floating: + { + background: 0x1b1b1baf, + background: alt: 0x0000005f, + background: fresh: 0x31393d5f, + border: 0xbfbfbf1f, + scroll_bar: + { + background: 0x3b3b3b5f, + border: 0x5f5f5f5f, + } + } + + menu_bar: + { + background: 0x2b3740ff, + border: 0x3e4c57ff, + } + + scroll_bar: + { + background: 0x2b2b2bff, + border: 0x3f3f3fff, + } + + implicit: + { + background: 0x00000000, + border: 0x00000000, + } + + hollow: + { + background: 0x00000000, + border: 0xffffff1f, + } + + tab: + { + background: 0x6f5135ff, + border: 0x8a6e54ff, + inactive: + { + background: 0x2b3740ff, + border: 0x3e4c57ff, + } + auto: + { + background: 0x693847ff, + border: 0x9e6274ff, + inactive: + { + background: 0x2f2633ff, + border: 0x685073ff, + } + } + } + + drop_site: + { + background: 0xffffff05, + border: 0xffffff0f, + } + } + ``` + } + { DefaultLight default_light "Default (Light)" } { VSDark vs_dark "VS (Dark)" } { VSLight vs_light "VS (Light)" } @@ -999,99 +1223,178 @@ RD_ThemePresetTable: { FarManager far_manager "Far Manager" } } -@table(name display_name name_lower default_dark default_light vs_dark vs_light solarized_dark solarized_light handmade_hero four_coder far_manager desc) +@table(name display_name name_lower default_dark default_light vs_dark vs_light solarized_dark solarized_light handmade_hero four_coder far_manager desc) RD_ThemeColorTable: { - {Null "Null" null 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff ""} + {Null "Null" null 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff ""} - //- rjf: global ui colors - {Text "Text" text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TextPositive "Text (Positive)" text_positive 0x4dc221ff 0x4d9e2eff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff ""} - {TextNegative "Text (Negative)" text_negative 0xc56452ff 0xbd371eff 0xc56452ff 0xc46451ff 0xc56452ff 0xc56452ff 0xc56452ff 0xc56452ff 0xc56452ff ""} - {TextNeutral "Text (Neutral)" text_neutral 0x307eb2ff 0x0064a7ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff ""} - {TextWeak "Text (Weak)" text_weak 0xa4a4a4fe 0x4c4c4cff 0xa4a4a4fe 0x0000007f 0x9999998a 0x818181ff 0x6e512eff 0x566e4bff 0x00a9a9ff ""} - {Cursor "Cursor" cursor 0x8aff00ff 0x699830ff 0x8aff00ff 0x000000ff 0x8aff00ff 0x586e75ff 0x8aff00ff 0x8aff00ff 0x8aff00ff ""} - {CursorInactive "Cursor (Inactive)" cursor_inactive 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff ""} - {Focus "Focus" focus 0xfda200ff 0x9c5900ff 0xfda200ff 0x002affff 0xfda200ff 0x92743dff 0xfda200ff 0xfda200ff 0x00fefeff ""} - {Hover "Hover" hover 0xffffffff 0xffffffff 0xffffffff 0x000000ff 0xffffffff 0x747474ff 0xffffffff 0xffffffff 0xffffffff ""} - {DropShadow "Drop Shadow" drop_shadow 0x0000007f 0x0000004c 0x0000007f 0xa3a3a37e 0x0000007f 0xc9bfa394 0x0000007f 0x0000007f 0x0000007f ""} - {DisabledOverlay "Disabled Overlay" disabled_overlay 0x0000003f 0xa6a6a63f 0x0000003f 0x0000003f 0x0000003f 0xe4dac090 0x0000003f 0x0000003f 0x0000003f ""} - {DropSiteOverlay "Drop Site Overlay" drop_site_overlay 0xffffff0c 0x4848480c 0xffffff0c 0x0000000c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c ""} - {InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay 0x0000003f 0xa4a4a43f 0x0000003f 0xfefefe53 0x0000003f 0x0000001c 0x0000003f 0x0000003f 0x0000003f ""} - {SelectionOverlay "Selection Overlay" selection_overlay 0x99ccff4c 0x003d7a48 0x99ccff4c 0x3d74ab4b 0x99ccff4c 0x678cb24c 0x99ccff4c 0x99ccff4c 0x99ccff4c ""} - {HighlightOverlay "Highlight Overlay" highlight_overlay 0xffffff1e 0xffffff1e 0xffffff1e 0x0000001e 0xffffff1e 0xffffff1e 0xffffff1e 0xffffff1e 0xffffff1e ""} - {HighlightOverlayError "Error Highlight Overlay" error_highlight_overlay 0x5f12005f 0xff30005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f ""} + //- rjf: global colors + {InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay 0x000000ff 0xa4a4a43f 0x0000003f 0xfefefe53 0x0000003f 0x0000001c 0x0000003f 0x0000003f 0x0000003f ""} + {DropShadow "Drop Shadow" drop_shadow 0x000000ff 0x0000004c 0x0000007f 0xa3a3a37e 0x0000007f 0xc9bfa394 0x0000007f 0x0000007f 0x0000007f ""} - //- rjf: base ui container colors - {BaseBackground "Base Background" base_background 0x1b1b1bfe 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {BaseBackgroundAlt "Base Background (Alternate)" base_background_alt 0x222222fe 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {BaseBorder "Base Border" base_border 0x3f3f3ffe 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + //- rjf: base palette + {BaseBackground "Base Background" base_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {BaseBackgroundAlt "Base Background (Alternate)" base_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BaseBackgroundGood "Base Background (Good)" base_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BaseBackgroundBad "Base Background (Bad)" base_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BaseBackgroundPop "Base Background (Pop)" base_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BaseBorder "Base Border" base_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {BaseText "Base Text" base_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BaseTextWeak "Base Text (Weak)" base_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BaseHover "Base Hover" base_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BaseFocus "Base Focus" base_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BaseCursor "Base Cursor" base_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BaseSelection "Base Selection" base_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - //- rjf: menu bar ui container colors - {MenuBarBackground "Menu Bar Background" menu_bar_background 0x3e4c577f 0xeaeaea7f 0x1b1b1bfd 0xffffff7f 0x00202bff 0xeee8d5ff 0x0c0c0cfe 0x0c0c0cfe 0x007d7dff ""} - {MenuBarBackgroundAlt "Menu Bar Background (Alternate)" menu_bar_background_alt 0x3e4c577f 0x3e4c577f 0x1b1b1bfd 0xffffff7f 0x3e4c577f 0x3e4c577f 0x3e4c577f 0x3e4c577f 0x007d7dff ""} - {MenuBarBorder "Menu Bar Border" menu_bar_border 0xffffff19 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xffffff19 0xbebaabfe 0xffffff19 0xffffff19 0xfefefe00 ""} + //- rjf: menu bar palette + {MenuBarBackground "Menu Bar Background" menu_bar_background 0x2b3740ff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {MenuBarBackgroundAlt "Menu Bar Background (Alternate)" menu_bar_background_alt 0x2b3740ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {MenuBarBackgroundGood "Menu Bar Background (Good)" menu_bar_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {MenuBarBackgroundBad "Menu Bar Background (Bad)" menu_bar_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {MenuBarBackgroundPop "Menu Bar Background (Pop)" menu_bar_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {MenuBarBorder "Menu Bar Border" menu_bar_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {MenuBarText "Menu Bar Text" menu_bar_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {MenuBarTextWeak "Menu Bar Text (Weak)" menu_bar_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {MenuBarHover "Menu Bar Hover" menu_bar_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {MenuBarFocus "Menu Bar Focus" menu_bar_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {MenuBarCursor "Menu Bar Cursor" menu_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {MenuBarSelection "Menu Bar Selection" menu_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - //- rjf: floating ui container colors - {FloatingBackground "Floating Background" floating_background 0x33333333 0xccccccc0 0x33333333 0xfefefec7 0x007fa14e 0xffffff7c 0x0c0c0c32 0x0c0c0c3e 0x007c7c55 ""} - {FloatingBackgroundAlt "Floating Background (Alternate)" floating_background_alt 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 ""} - {FloatingBorder "Floating Border" floating_border 0x3f3f3ffd 0xa4a4a4fe 0x3f3f3ffd 0xb6b6b6ff 0xfdfdfd3a 0xbebaabfe 0x423425fe 0x3f3f3ffd 0x00ffff55 ""} + //- rjf: good palette + {GoodBackground "Good Background" good_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {GoodBackgroundAlt "Good Background (Alternate)" good_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {GoodBackgroundGood "Good Background (Good)" good_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {GoodBackgroundBad "Good Background (Bad)" good_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {GoodBackgroundPop "Good Background (Pop)" good_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {GoodBorder "Good Border" good_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {GoodText "Good Text" good_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {GoodTextWeak "Good Text (Weak)" good_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {GoodHover "Good Hover" good_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {GoodFocus "Good Focus" good_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {GoodCursor "Good Cursor" good_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {GoodSelection "Good Selection" good_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - //- rjf: ui element colors - {ImplicitButtonBackground "Implicit Button Background" implicit_button_background 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 ""} - {ImplicitButtonBorder "Implicit Button Border" implicit_button_border 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0xbdb9aa00 0x00000000 0x00000000 0x00000000 ""} - {PlainButtonBackground "Plain Button Background" plain_button_background 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe ""} - {PlainButtonBorder "Plain Button Border" plain_button_border 0x3f3f3ffe 0x3f3f3ffe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffe 0x3f3f3ffe 0x3f3f3ffe ""} - {PositivePopButtonBackground "Positive Pop Button Background" positive_pop_button_background 0x2c5b36ff 0x65f534ff 0x2c5b36ff 0x84ce93ff 0x2c5b36ff 0xb6ddbeff 0x132e19ff 0x152f1bff 0x2c5b36ff ""} - {PositivePopButtonBorder "Positive Pop Button Border" positive_pop_button_border 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} - {NegativePopButtonBackground "Negative Pop Button Background" negative_pop_button_background 0x803425ff 0xff694cff 0x803425ff 0xbd3e24ff 0x803425ff 0xf8b0a1ff 0x803425ff 0x43150cff 0x803425ff ""} - {NegativePopButtonBorder "Negative Pop Button Border" negative_pop_button_border 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} - {NeutralPopButtonBackground "Neutral Pop Button Background" neutral_pop_button_background 0x355b6eff 0xa6becaff 0x355b6eff 0x6e9db5ff 0x355b6eff 0xb2d3e3ff 0x15445cff 0x1b323eff 0x933100ff ""} - {NeutralPopButtonBorder "Neutral Pop Button Border" neutral_pop_button_border 0x3f3f3ffd 0xa6a6a6fd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} - {ScrollBarButtonBackground "Scroll Bar Button Background" scroll_bar_button_background 0x2b2b2bfe 0xa9a9a9fe 0x2b2b2bfe 0xe8e8e8fe 0x005e77fe 0xe3dbc7fe 0x1f1f27fe 0x212721fe 0x007d7dff ""} - {ScrollBarButtonBorder "Scroll Bar Button Border" scroll_bar_button_border 0x3f3f3ffe 0xc0c0c0fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0xfefefe4d 0x3f3f3ffe 0x3f3f3ffe ""} - {TabBackground "Tab Background" tab_background 0x6f5135fe 0xa98b6fff 0x0079ccff 0xfffffffe 0x005e77fe 0xfdf6e3ff 0x1f1f27fe 0x212721fe 0x007d7dff ""} - {TabBorder "Tab Border" tab_border 0xfefefe4d 0xffffff4d 0xfefefe4d 0xb6b6b6ff 0xfefefe4d 0xbebaabfe 0xfefefe4d 0xfefefe4d 0xfefefe4d ""} - {TabBackgroundInactive "Tab Background (Inactive)" tab_background_inactive 0x3e4c577f 0x8282827f 0xfefefe14 0xcdd4dc7f 0x3e4c577f 0xd4cfc0fe 0x131315ee 0x3a3a3a7f 0x3e4c577f ""} - {TabBorderInactive "Tab Border (Inactive)" tab_border_inactive 0xffffff19 0xffffff19 0xffffff00 0xb6b6b6ff 0xffffff19 0xbebaabfe 0xffffff19 0x00000019 0xfefefe19 ""} + //- rjf: bad palette + {BadBackground "Bad Background" bad_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {BadBackgroundAlt "Bad Background (Alternate)" bad_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BadBackgroundGood "Bad Background (Good)" bad_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BadBackgroundBad "Bad Background (Bad)" bad_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BadBackgroundPop "Bad Background (Pop)" bad_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BadBorder "Bad Border" bad_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {BadText "Bad Text" bad_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BadTextWeak "Bad Text (Weak)" bad_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BadHover "Bad Hover" bad_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BadFocus "Bad Focus" bad_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BadCursor "Bad Cursor" bad_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BadSelection "Bad Selection" bad_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - //- rjf: code colors - {CodeDefault "Code (Default)" code_default 0xcbcbcbff 0x4d4d4dff 0xcbcbcbff 0x000000ff 0xcbcbcbff 0x657b83ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {CodeSymbol "Code (Symbol)" code_symbol 0x42a2cffe 0x205670fe 0xdcdcaaff 0x000000ff 0xcb4a15ff 0xcb4a15ff 0xcc5634ff 0x42a2cffe 0x65b1ffff ""} - {CodeType "Code (Type)" code_type 0xfec746ff 0x996b00ff 0x4ec9afff 0xa33700ff 0xcb4a15ff 0xcb4a15ff 0xd8a51bff 0xfd7c52ff 0xfec746ff ""} - {CodeLocal "Code (Local)" code_local 0x98bc80ff 0x446a2bff 0x9cdbfeff 0x007666ff 0x98bc80ff 0x258ad2ff 0xc04047ff 0x98bc80ff 0x00ff00ff ""} - {CodeRegister "Code (Register)" code_register 0xb7afd5ff 0x4c35a1ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff 0x373345ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff ""} - {CodeKeyword "Code (Keyword)" code_keyword 0xb38d4cff 0x573700ff 0x569cd6ff 0x0000ffff 0x849803ff 0x586e75ff 0xac7a09ff 0xd08f1eff 0x00ffffff ""} - {CodeDelimiterOperator "Code (Delimiters/Operators)" code_delimiter_operator 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0xa08462ff 0x90b080ff 0xffffffff ""} - {CodeNumeric "Code (Numeric)" code_numeric 0x98abb1ff 0x3f6e7dff 0xb5cea8ff 0x088658ff 0xd33582ff 0xd33482ef 0x698e21ff 0x4fff2eff 0x00ff00ff ""} - {CodeNumericAltDigitGroup "Code (Numeric, Alt. Digit Group)" code_numeric_alt_digit_group 0x738287ff 0x1f4450ff 0x729360ff 0x0c3828ff 0x902559ff 0x8e2659ff 0x3a4e11ff 0x3ccd21ff 0x738287ff ""} - {CodeString "Code (String)" code_string 0x98abb1ff 0x3c606bff 0xd59b85ff 0xa31414ff 0x1f9d91ff 0x29a198ff 0x6a8e22ff 0x4fff2eff 0x98abb1ff ""} - {CodeMeta "Code (Meta)" code_meta 0xd96759ff 0xad3627ff 0xd59c85ff 0x0000ffff 0x839802ff 0xd96759ff 0xdab98fff 0xa0b8a0ff 0xff0000ff ""} - {CodeComment "Code (Comment)" code_comment 0x717171ff 0x4b4b4bff 0x57a54aff 0x008000ff 0x556a6fff 0x93a1a1ff 0x686868ff 0x1e8fefff 0xffffffff ""} - {CodeLineNumbers "Code Line Numbers" code_line_numbers 0x7f7f7fff 0x4b4b4bff 0x2a91afff 0x227893ff 0x566c73ff 0x227893ef 0xa08462ff 0x7e7e7ffe 0x007d7dff ""} - {CodeLineNumbersSelected "Code Line Numbers (Selected)" code_line_numbers_selected 0xbebebeff 0x000000ff 0x9ddaecff 0x123d4bfe 0xa2aaacff 0x111e22ef 0xc8b399ff 0xbebebeff 0x00fefeff ""} + //- rjf: pop palette + {PopBackground "Pop Background" pop_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {PopBackgroundAlt "Pop Background (Alternate)" pop_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {PopBackgroundGood "Pop Background (Good)" pop_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {PopBackgroundBad "Pop Background (Bad)" pop_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {PopBackgroundPop "Pop Background (Pop)" pop_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {PopBorder "Pop Border" pop_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {PopText "Pop Text" pop_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {PopTextWeak "Pop Text (Weak)" pop_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {PopHover "Pop Hover" pop_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {PopFocus "Pop Focus" pop_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {PopCursor "Pop Cursor" pop_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {PopSelection "Pop Selection" pop_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - //- rjf: debugging colors - {LineInfoBackground0 "Line Info Background 0" line_info_background_0 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} - {LineInfoBackground1 "Line Info Background 1" line_info_background_1 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} - {LineInfoBackground2 "Line Info Background 2" line_info_background_2 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} - {LineInfoBackground3 "Line Info Background 3" line_info_background_3 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} - {LineInfoBackground4 "Line Info Background 4" line_info_background_4 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} - {LineInfoBackground5 "Line Info Background 5" line_info_background_5 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} - {LineInfoBackground6 "Line Info Background 6" line_info_background_6 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} - {LineInfoBackground7 "Line Info Background 7" line_info_background_7 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} - {Thread0 "Thread 0" thread_0 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0xffcb7fff 0xffcb7fff ""} - {Thread1 "Thread 1" thread_1 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0xb2ff65ff 0xb2ff65ff ""} - {Thread2 "Thread 2" thread_2 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0xff99e5ff 0xff99e5ff ""} - {Thread3 "Thread 3" thread_3 0x6598ffff 0x30456fff 0x6598ffff 0x30456fff 0x6598ffff 0x30456fff 0x6598ffff 0x6598ffff 0x6598ffff ""} - {Thread4 "Thread 4" thread_4 0x65ffcbff 0x264f41ff 0x65ffcbff 0x264f41ff 0x65ffcbff 0x264f41ff 0x65ffcbff 0x65ffcbff 0x65ffcbff ""} - {Thread5 "Thread 5" thread_5 0xff9819ff 0x736a5fff 0xff9819ff 0x736a5fff 0xff9819ff 0x736a5fff 0xff9819ff 0xff9819ff 0xff9819ff ""} - {Thread6 "Thread 6" thread_6 0x9932ffff 0x472f5eff 0x9932ffff 0x472f5eff 0x9932ffff 0x472f5eff 0x9932ffff 0x9932ffff 0x9932ffff ""} - {Thread7 "Thread 7" thread_7 0x65ff4cff 0x405d3bff 0x65ff4cff 0x405d3bff 0x65ff4cff 0x405d3bff 0x65ff4cff 0x65ff4cff 0x65ff4cff ""} - {ThreadUnwound "Thread (Unwound)" thread_unwound 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0xb2ccd8ff 0xb2ccd8ff ""} - {ThreadError "Thread (Error)" thread_error 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23218ff 0xb23219ff 0xb23219ff 0xb23219ff ""} - {Breakpoint "Breakpoint" breakpoint 0xa72911ff 0xff2800ff 0xa72911ff 0xa72911ff 0xa72911ff 0xff684bff 0xa72911ff 0xa72911ff 0xff2800ff ""} - {CacheLineBoundary "Cache Line Boundary" cache_line_boundary 0x355b6eff 0xa6becaff 0x355b6eff 0x6e9db5ff 0x355b6eff 0xb2d3e3ff 0x15445cff 0x1b323eff 0x933100ff ""} + //- rjf: scroll bar palette + {ScrollBarBackground "Scroll Bar Background" scroll_bar_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {ScrollBarBackgroundAlt "Scroll Bar Background (Alternate)" scroll_bar_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {ScrollBarBackgroundGood "Scroll Bar Background (Good)" scroll_bar_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {ScrollBarBackgroundBad "Scroll Bar Background (Bad)" scroll_bar_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {ScrollBarBackgroundPop "Scroll Bar Background (Pop)" scroll_bar_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {ScrollBarBorder "Scroll Bar Border" scroll_bar_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {ScrollBarText "Scroll Bar Text" scroll_bar_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {ScrollBarTextWeak "Scroll Bar Text (Weak)" scroll_bar_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {ScrollBarHover "Scroll Bar Hover" scroll_bar_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {ScrollBarFocus "Scroll Bar Focus" scroll_bar_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {ScrollBarCursor "Scroll Bar Cursor" scroll_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {ScrollBarSelection "Scroll Bar Selection" scroll_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + + //- rjf: tab (active) palette + {TabBackground "Tab Background" tab_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {TabBackgroundAlt "Tab Background (Alternate)" tab_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabBackgroundGood "Tab Background (Good)" tab_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabBackgroundBad "Tab Background (Bad)" tab_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabBackgroundPop "Tab Background (Pop)" tab_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabBorder "Tab Border" tab_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {TabText "Tab Text" tab_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabTextWeak "Tab Text (Weak)" tab_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabHover "Tab Hover" tab_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabFocus "Tab Focus" tab_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabCursor "Tab Cursor" tab_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabSelection "Tab Selection" tab_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + + //- rjf: tab (inactive) palette + {TabInactiveBackground "Tab (Inactive) Background" tab_inactive_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {TabInactiveBackgroundAlt "Tab (Inactive) Background (Alternate)" tab_inactive_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabInactiveBackgroundGood "Tab (Inactive) Background (Good)" tab_inactive_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabInactiveBackgroundBad "Tab (Inactive) Background (Bad)" tab_inactive_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabInactiveBackgroundPop "Tab (Inactive) Background (Pop)" tab_inactive_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabInactiveBorder "Tab (Inactive) Border" tab_inactive_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {TabInactiveText "Tab (Inactive) Text" tab_inactive_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabInactiveTextWeak "Tab (Inactive) Text (Weak)" tab_inactive_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabInactiveHover "Tab (Inactive) Hover" tab_inactive_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabInactiveFocus "Tab (Inactive) Focus" tab_inactive_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabInactiveCursor "Tab (Inactive) Cursor" tab_inactive_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabInactiveSelection "Tab (Inactive) Selection" tab_inactive_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + + //- rjf: drop site palette + {DropSiteBackground "Drop Site Background" drop_site_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {DropSiteBackgroundAlt "Drop Site Background (Alternate)" drop_site_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {DropSiteBackgroundGood "Drop Site Background (Good)" drop_site_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {DropSiteBackgroundBad "Drop Site Background (Bad)" drop_site_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {DropSiteBackgroundPop "Drop Site Background (Pop)" drop_site_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {DropSiteBorder "Drop Site Border" drop_site_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {DropSiteText "Drop Site Text" drop_site_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {DropSiteTextWeak "Drop Site Text (Weak)" drop_site_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {DropSiteHover "Drop Site Hover" drop_site_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {DropSiteFocus "Drop Site Focus" drop_site_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {DropSiteCursor "Drop Site Cursor" drop_site_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {DropSiteSelection "Drop Site Selection" drop_site_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + + //- rjf: code colors (extra text colors which extend 'base') + {CodeDefault "Code (Default)" code_default 0xcbcbcbff 0x4d4d4dff 0xcbcbcbff 0x000000ff 0xcbcbcbff 0x657b83ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {CodeSymbol "Code (Symbol)" code_symbol 0x42a2cfff 0x205670fe 0xdcdcaaff 0x000000ff 0xcb4a15ff 0xcb4a15ff 0xcc5634ff 0x42a2cffe 0x65b1ffff ""} + {CodeType "Code (Type)" code_type 0xfec746ff 0x996b00ff 0x4ec9afff 0xa33700ff 0xcb4a15ff 0xcb4a15ff 0xd8a51bff 0xfd7c52ff 0xfec746ff ""} + {CodeLocal "Code (Local)" code_local 0x98bc80ff 0x446a2bff 0x9cdbfeff 0x007666ff 0x98bc80ff 0x258ad2ff 0xc04047ff 0x98bc80ff 0x00ff00ff ""} + {CodeRegister "Code (Register)" code_register 0xb7afd5ff 0x4c35a1ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff 0x373345ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff ""} + {CodeKeyword "Code (Keyword)" code_keyword 0xb38d4cff 0x573700ff 0x569cd6ff 0x0000ffff 0x849803ff 0x586e75ff 0xac7a09ff 0xd08f1eff 0x00ffffff ""} + {CodeDelimiterOperator "Code (Delimiters/Operators)" code_delimiter_operator 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0xa08462ff 0x90b080ff 0xffffffff ""} + {CodeNumeric "Code (Numeric)" code_numeric 0x98abb1ff 0x3f6e7dff 0xb5cea8ff 0x088658ff 0xd33582ff 0xd33482ef 0x698e21ff 0x4fff2eff 0x00ff00ff ""} + {CodeNumericAltDigitGroup "Code (Numeric, Alt. Digit Group)" code_numeric_alt_digit_group 0x738287ff 0x1f4450ff 0x729360ff 0x0c3828ff 0x902559ff 0x8e2659ff 0x3a4e11ff 0x3ccd21ff 0x738287ff ""} + {CodeString "Code (String)" code_string 0x98abb1ff 0x3c606bff 0xd59b85ff 0xa31414ff 0x1f9d91ff 0x29a198ff 0x6a8e22ff 0x4fff2eff 0x98abb1ff ""} + {CodeMeta "Code (Meta)" code_meta 0xd96759ff 0xad3627ff 0xd59c85ff 0x0000ffff 0x839802ff 0xd96759ff 0xdab98fff 0xa0b8a0ff 0xff0000ff ""} + {CodeComment "Code (Comment)" code_comment 0x717171ff 0x4b4b4bff 0x57a54aff 0x008000ff 0x556a6fff 0x93a1a1ff 0x686868ff 0x1e8fefff 0xffffffff ""} + {CodeLineNumbers "Code Line Numbers" code_line_numbers 0x7f7f7fff 0x4b4b4bff 0x2a91afff 0x227893ff 0x566c73ff 0x227893ef 0xa08462ff 0x7e7e7ffe 0x007d7dff ""} + {CodeLineNumbersSelected "Code Line Numbers (Selected)" code_line_numbers_selected 0xbebebeff 0x000000ff 0x9ddaecff 0x123d4bfe 0xa2aaacff 0x111e22ef 0xc8b399ff 0xbebebeff 0x00fefeff ""} + + //- rjf: debugging colors (extra text/element colors which extend 'base') + {LineInfoBackground0 "Line Info Background 0" line_info_background_0 0x99503dff 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} + {LineInfoBackground1 "Line Info Background 1" line_info_background_1 0xfe8249ff 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} + {LineInfoBackground2 "Line Info Background 2" line_info_background_2 0xffba17ff 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} + {LineInfoBackground3 "Line Info Background 3" line_info_background_3 0xcefd69ff 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} + {LineInfoBackground4 "Line Info Background 4" line_info_background_4 0x99503dff 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} + {LineInfoBackground5 "Line Info Background 5" line_info_background_5 0xfe8249ff 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} + {LineInfoBackground6 "Line Info Background 6" line_info_background_6 0xffba17ff 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} + {LineInfoBackground7 "Line Info Background 7" line_info_background_7 0xcefd69ff 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} + {Thread0 "Thread 0" thread_0 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0xffcb7fff 0xffcb7fff ""} + {Thread1 "Thread 1" thread_1 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0xb2ff65ff 0xb2ff65ff ""} + {Thread2 "Thread 2" thread_2 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0xff99e5ff 0xff99e5ff ""} + {Thread3 "Thread 3" thread_3 0x6598ffff 0x30456fff 0x6598ffff 0x30456fff 0x6598ffff 0x30456fff 0x6598ffff 0x6598ffff 0x6598ffff ""} + {Thread4 "Thread 4" thread_4 0x65ffcbff 0x264f41ff 0x65ffcbff 0x264f41ff 0x65ffcbff 0x264f41ff 0x65ffcbff 0x65ffcbff 0x65ffcbff ""} + {Thread5 "Thread 5" thread_5 0xff9819ff 0x736a5fff 0xff9819ff 0x736a5fff 0xff9819ff 0x736a5fff 0xff9819ff 0xff9819ff 0xff9819ff ""} + {Thread6 "Thread 6" thread_6 0x9932ffff 0x472f5eff 0x9932ffff 0x472f5eff 0x9932ffff 0x472f5eff 0x9932ffff 0x9932ffff 0x9932ffff ""} + {Thread7 "Thread 7" thread_7 0x65ff4cff 0x405d3bff 0x65ff4cff 0x405d3bff 0x65ff4cff 0x405d3bff 0x65ff4cff 0x65ff4cff 0x65ff4cff ""} + {ThreadUnwound "Thread (Unwound)" thread_unwound 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0xb2ccd8ff 0xb2ccd8ff ""} + {ThreadError "Thread (Error)" thread_error 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23218ff 0xb23219ff 0xb23219ff 0xb23219ff ""} + {Breakpoint "Breakpoint" breakpoint 0xa72911ff 0xff2800ff 0xa72911ff 0xa72911ff 0xa72911ff 0xff684bff 0xa72911ff 0xa72911ff 0xff2800ff ""} + {CacheLineBoundary "Cache Line Boundary" cache_line_boundary 0x355b6eff 0xa6becaff 0x355b6eff 0x6e9db5ff 0x355b6eff 0xb2d3e3ff 0x15445cff 0x1b323eff 0x933100ff ""} } @table(old_name new_name) @@ -1143,6 +1446,11 @@ RD_ThemeColorVersionRemapTable: @expand(RD_ThemePresetTable a) `str8_lit_comp("$(a.name_lower)")`, } +@data(String8) rd_theme_preset_cfg_string_table: +{ + @expand(RD_ThemePresetTable a) `str8_lit_comp("$(a.cfg)")`, +} + @data(String8) rd_theme_color_version_remap_old_name_table: { @expand(RD_ThemeColorVersionRemapTable a) `str8_lit_comp("$(a.old_name)")` @@ -1177,64 +1485,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 575fd4c1..670d1564 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10,116 +10,1294 @@ #include "generated/raddbg.meta.c" //////////////////////////////// -//~ rjf: Handles +//~ rjf: Commands Eval Hooks -internal RD_Handle -rd_handle_zero(void) +E_LOOKUP_INFO_FUNCTION_DEF(commands) { - RD_Handle result = {0}; + E_LookupInfo result = {0}; + if(filter.size != 0) + { + Temp scratch = scratch_begin(&arena, 1); + String8List cmd_names = {0}; + for EachNonZeroEnumVal(RD_CmdKind, k) + { + RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; + String8 name = info->string; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, name); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &cmd_names, name); + } + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &cmd_names); + result.user_data = accel; + result.idxed_expr_count = accel->count; + scratch_end(scratch); + } + else + { + result.idxed_expr_count = RD_CmdKind_COUNT; + } return result; } -internal B32 -rd_handle_match(RD_Handle a, RD_Handle b) +E_LOOKUP_ACCESS_FUNCTION_DEF(commands) { - return (a.u64[0] == b.u64[0] && a.u64[1] == b.u64[1]); -} - -internal void -rd_handle_list_push_node(RD_HandleList *list, RD_HandleNode *node) -{ - DLLPushBack(list->first, list->last, node); - list->count += 1; -} - -internal void -rd_handle_list_push(Arena *arena, RD_HandleList *list, RD_Handle handle) -{ - RD_HandleNode *n = push_array(arena, RD_HandleNode, 1); - n->handle = handle; - rd_handle_list_push_node(list, n); -} - -internal RD_HandleList -rd_handle_list_copy(Arena *arena, RD_HandleList list) -{ - RD_HandleList result = {0}; - for(RD_HandleNode *n = list.first; n != 0; n = n->next) + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_MemberAccess) { - rd_handle_list_push(arena, &result, n->handle); + String8 cmd_name = rhs->string; + result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + result.irtree_and_type.mode = E_Mode_Value; + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCmd), e_irtree_const_u(arena, e_id_from_string(cmd_name))); + } + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(commands) +{ + U64 out_idx = 0; + if(user_data != 0) + { + String8Array *accel = (String8Array *)user_data; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + String8 cmd_name = accel->v[idx]; + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); + expr->value.u64 = e_id_from_string(cmd_name); + exprs[out_idx] = expr; + } + } + else + { + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + RD_CmdKind cmd_kind = (RD_CmdKind)idx; + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); + expr->value.u64 = e_id_from_string(cmd_name); + exprs[out_idx] = expr; + } + } +} + +//////////////////////////////// +//~ rjf: Watches Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(watches) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); + RD_CfgList cfgs_list__filtered = cfgs_list; + if(filter.size != 0) + { + MemoryZeroStruct(&cfgs_list__filtered); + for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) + { + String8 expr = rd_expr_from_cfg(n->v); + B32 passes_filter = 1; + if(filter.size != 0) + { + E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind != E_TypeKind_Set) + { + passes_filter = 0; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr); + if(matches.count == matches.needle_part_count) + { + passes_filter = 1; + } + } + } + if(passes_filter) + { + rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); + } + } + } + RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); + cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list__filtered); + result.user_data = cfgs; + result.idxed_expr_count = cfgs->count + 1; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(watches) +{ + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + Rng1U64 legal_idx_range = r1u64(0, cfgs->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 cfg_idx = read_range.min + idx; + if(cfg_idx < cfgs->count) + { + String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; + exprs[idx] = e_parse_expr_from_text(arena, expr_string).exprs.first; + exprs_strings[idx] = push_str8_copy(arena, expr_string); + } + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(watches) +{ + U64 id = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(1 <= num && num <= cfgs->count) + { + U64 idx = (num-1); + id = cfgs->v[idx]->id; + } + else if(num == cfgs->count+1) + { + id = max_U64; + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(watches) +{ + U64 num = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(id != 0 && id != max_U64) + { + for EachIndex(idx, cfgs->count) + { + if(cfgs->v[idx]->id == id) + { + num = idx+1; + break; + } + } + } + else if(id == max_U64) + { + num = cfgs->count + 1; + } + return num; +} + +//////////////////////////////// +//~ rjf: Locals Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(locals) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_parse_state->ctx->locals_map); + e_string2num_map_node_array_sort__in_place(&nodes); + String8List exprs_filtered = {0}; + for EachIndex(idx, nodes.count) + { + String8 local_expr_string = nodes.v[idx]->string; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, local_expr_string); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &exprs_filtered, local_expr_string); + } + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &exprs_filtered); + result.user_data = accel; + result.idxed_expr_count = accel->count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(locals) +{ + String8Array *accel = (String8Array *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + String8 expr_string = accel->v[read_range.min + idx]; + exprs[idx] = e_parse_expr_from_text(arena, expr_string).exprs.last; + exprs_strings[idx] = push_str8_copy(arena, expr_string); + } +} + +//////////////////////////////// +//~ rjf: Registers Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(registers) +{ + Temp scratch = scratch_begin(&arena, 1); + CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + Arch arch = thread->arch; + U64 reg_count = regs_reg_code_count_from_arch(arch); + U64 alias_count = regs_alias_code_count_from_arch(arch); + String8 *reg_strings = regs_reg_code_string_table_from_arch(arch); + String8 *alias_strings = regs_alias_code_string_table_from_arch(arch); + String8List exprs_list = {0}; + for(U64 idx = 1; idx < reg_count; idx += 1) + { + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, reg_strings[idx]); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &exprs_list, reg_strings[idx]); + } + } + for(U64 idx = 1; idx < alias_count; idx += 1) + { + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, alias_strings[idx]); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &exprs_list, alias_strings[idx]); + } + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &exprs_list); + E_LookupInfo info = {accel, 0, accel->count}; + scratch_end(scratch); + return info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(registers) +{ + String8Array *accel = (String8Array *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + String8 register_name = accel->v[read_range.min + idx]; + String8 register_expr = push_str8f(arena, "reg:%S", register_name); + exprs_strings[idx] = register_name; + exprs[idx] = e_parse_expr_from_text(arena, register_expr).exprs.last; + } +} + +//////////////////////////////// +//~ rjf: Schema'd Set Eval Hooks + +typedef struct RD_SchemaLookupAccel RD_SchemaLookupAccel; +struct RD_SchemaLookupAccel +{ + RD_Cfg *cfg; + CTRL_Entity *entity; + MD_Node *schema; + MD_Node **children; + U64 children_count; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(schema) +{ + E_LookupInfo result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + // rjf: unpack + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + E_TypeKey type_key = lhs->type_key; + E_Type *type = e_type_from_key__cached(type_key); + MD_Node *schema = rd_schema_from_name(type->name); + + // rjf: gather expansion children + typedef struct ExpandChildNode ExpandChildNode; + struct ExpandChildNode + { + ExpandChildNode *next; + MD_Node *n; + }; + ExpandChildNode *first_child_node = 0; + ExpandChildNode *last_child_node = 0; + U64 child_count = 0; + for MD_EachNode(child, schema->first) + { + if(!md_node_has_tag(child, str8_lit("no_expand"), 0)) + { + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, child->string); + if(matches.count == matches.needle_part_count) + { + ExpandChildNode *n = push_array(scratch.arena, ExpandChildNode, 1); + n->n = child; + SLLQueuePush(first_child_node, last_child_node, n); + child_count += 1; + } + } + } + + // rjf: flatten expansion member list + MD_Node **children = push_array(arena, MD_Node *, child_count); + { + U64 idx = 0; + for(ExpandChildNode *n = first_child_node; n != 0; n = n->next, idx += 1) + { + children[idx] = n->n; + } + } + + // rjf: build accelerator for lookups + RD_SchemaLookupAccel *accel = push_array(arena, RD_SchemaLookupAccel, 1); + accel->cfg = rd_cfg_from_eval_space(interpret.space); + accel->entity = rd_ctrl_entity_from_eval_space(interpret.space); + accel->schema = schema; + accel->children = children; + accel->children_count = child_count; + + // rjf: fill result + result.user_data = accel; + result.named_expr_count = child_count; + + scratch_end(scratch); + } + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(schema) +{ + RD_SchemaLookupAccel *accel = (RD_SchemaLookupAccel *)user_data; + E_IRTreeAndType irtree = {&e_irnode_nil}; + if(kind == E_ExprKind_MemberAccess) + { + MD_Node *child_schema = &md_nil_node; + for MD_EachNode(child, accel->schema->first) + { + if(str8_match(child->string, rhs->string, 0)) + { + child_schema = child; + break; + } + } + if(child_schema != &md_nil_node) + { + RD_Cfg *cfg = accel->cfg; + CTRL_Entity *entity = accel->entity; + RD_Cfg *child = rd_cfg_child_from_string(cfg, child_schema->string); + E_TypeKey child_type_key = zero_struct; + if(0){} + + //- rjf: ctrl entity members + else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("label"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), entity->string.size, E_TypeFlag_IsCodeText); + } + else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("exe"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), entity->string.size, E_TypeFlag_IsPathText); + } + else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("dbg"), 0)) + { + CTRL_Entity *dbg = ctrl_entity_child_from_kind(entity, CTRL_EntityKind_DebugInfoPath); + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), dbg->string.size, E_TypeFlag_IsPathText); + } + + //- rjf: cfg members + else if(str8_match(child_schema->first->string, str8_lit("code_string"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsCodeText); + } + else if(str8_match(child_schema->first->string, str8_lit("path"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPathText); + } + else if(str8_match(child_schema->first->string, str8_lit("path_pt"), 0)) + { + Temp scratch = scratch_begin(&arena, 1); + String8 string = push_str8f(scratch.arena, "%S%s%S%s%S", child->first->string, child->first->string.size ? ":" : "", child->first->first->string, child->first->first->first->string.size ? ":" : "", child->first->first->first->string); + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), string.size, E_TypeFlag_IsPathText); + scratch_end(scratch); + } + else if(str8_match(child_schema->first->string, str8_lit("string"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPlainText); + } + + //- rjf: catchall cases + else if(str8_match(child_schema->first->string, str8_lit("u64"), 0)) + { + child_type_key = e_type_key_basic(E_TypeKind_U64); + } + else if(str8_match(child_schema->first->string, str8_lit("bool"), 0)) + { + child_type_key = e_type_key_basic(E_TypeKind_Bool); + } + else if(str8_match(child_schema->first->string, str8_lit("vaddr_range"), 0)) + { + Temp scratch = scratch_begin(&arena, 1); + E_MemberList vaddr_range_members_list = {0}; + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("min"), .off = 0); + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("max"), .off = 8); + E_MemberArray vaddr_range_members = e_member_array_from_list(scratch.arena, &vaddr_range_members_list); + child_type_key = e_type_key_cons(.kind = E_TypeKind_Struct, .name = str8_lit("vaddr_range"), .count = vaddr_range_members.count, .members = vaddr_range_members.v); + scratch_end(scratch); + } + else if(str8_match(child_schema->first->string, str8_lit("query"), 0)) + { + child_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = child_schema->string); + } + + //- rjf: evaluate + E_Space child_eval_space = zero_struct; + if(cfg != &rd_nil_cfg) + { + child_eval_space = e_space_make(RD_EvalSpaceKind_MetaCfg); + child_eval_space.u64s[0] = cfg->id; + child_eval_space.u64s[1] = e_id_from_string(child_schema->string); + } + else + { + child_eval_space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + child_eval_space.u64s[2] = e_id_from_string(child_schema->string); + } + irtree.root = e_irtree_set_space(arena, child_eval_space, e_push_irnode(arena, RDI_EvalOp_ConstU64)); + irtree.type_key = child_type_key; + irtree.mode = E_Mode_Offset; + } + } + E_LookupAccess access = {irtree}; + return access; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(schema) +{ + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + RD_SchemaLookupAccel *accel = (RD_SchemaLookupAccel *)user_data; + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + if(0 <= idx && idx < accel->children_count) + { + MD_Node *child_schema = accel->children[idx]; + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, child_schema->string); + } + } +} + +//////////////////////////////// +//~ rjf: Config Collection Eval Hooks + +typedef struct RD_CfgCollectionLookupAccel RD_CfgCollectionLookupAccel; +struct RD_CfgCollectionLookupAccel +{ + String8Array cmds; + RD_CfgArray cfgs; + Rng1U64 cmds_idx_range; + Rng1U64 cfgs_idx_range; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(cfgs) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + //- rjf: determine which cfg we'll use to scope the lookups + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + RD_Cfg *scoping_cfg = rd_cfg_from_eval_space(lhs_interp.space); + + //- rjf: determine which kind of child we'll be gathering + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + String8 cfg_name = rd_singular_from_code_name_plural(lhs_type->name); + + //- rjf: gather cfgs + RD_CfgList cfgs_list = {0}; + if(scoping_cfg == &rd_nil_cfg) + { + cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name); + } + else + { + cfgs_list = rd_cfg_child_list_from_string(scratch.arena, scoping_cfg, cfg_name); + } + + //- rjf: filter cfgs + RD_CfgList cfgs_list__filtered = cfgs_list; + if(filter.size != 0) + { + MemoryZeroStruct(&cfgs_list__filtered); + for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) + { + DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, n->v); + String8 string = dr_string_from_fstrs(scratch.arena, &fstrs); + FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, filter, string); + if(fuzzy_matches.count == fuzzy_matches.needle_part_count) + { + rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); + } + } + } + + //- rjf: gather commands + String8List cmds_list = {0}; + if(filter.size == 0) + { + MD_Node *schema = rd_schema_from_name(cfg_name); + MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); + for MD_EachNode(cmd, collection_cmds_root->first) + { + str8_list_push(arena, &cmds_list, cmd->string); + } + } + + //- rjf: package & fill + RD_CfgCollectionLookupAccel *accel = push_array(arena, RD_CfgCollectionLookupAccel, 1); + accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list__filtered); + accel->cmds = str8_array_from_list(arena, &cmds_list); + accel->cmds_idx_range = r1u64(0, accel->cmds.count); + accel->cfgs_idx_range = r1u64(accel->cmds_idx_range.max, accel->cmds_idx_range.max + accel->cfgs.count); + result.user_data = accel; + result.idxed_expr_count = accel->cfgs.count + accel->cmds.count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(cfgs) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupAccess result = {{&e_irnode_nil}}; + RD_Cfg *cfg = &rd_nil_cfg; + if(kind == E_ExprKind_MemberAccess) + { + String8 rhs_name = rhs->string; + RD_CfgID id = 0; + if(str8_match(str8_prefix(rhs_name, 1), str8_lit("$"), 0) && + try_u64_from_str8_c_rules(str8_skip(rhs_name, 1), &id)) + { + cfg = rd_cfg_from_id(id); + } + } + else if(kind == E_ExprKind_ArrayIndex) + { + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + U64 rhs_idx = rhs_value.u64; + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; + if(0 <= rhs_idx && rhs_idx < accel->cfgs.count) + { + cfg = accel->cfgs.v[rhs_idx]; + } + } + if(cfg != &rd_nil_cfg) + { + E_Space cfg_space = rd_eval_space_from_cfg(cfg); + String8 cfg_name = cfg->string; + E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); + result.irtree_and_type.root = e_irtree_set_space(arena, cfg_space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = cfg_type_key; + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(cfgs) +{ + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; + Rng1U64 cmds_idx_range = accel->cmds_idx_range; + Rng1U64 cfgs_idx_range = accel->cfgs_idx_range; + U64 dst_idx = 0; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + + // rjf: fill commands + { + Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); + U64 read_count = dim_1u64(read_range); + E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")).exprs.last; + E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(arena, commands); + for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) + { + String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; + exprs[dst_idx] = e_expr_irext_member_access(arena, commands, &commands_irtree, cmd_name); + } + } + + // rjf: fill cfgs + { + Rng1U64 read_range = intersect_1u64(cfgs_idx_range, idx_range); + U64 read_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) + { + RD_Cfg *cfg = accel->cfgs.v[idx + read_range.min - cfgs_idx_range.min]; + exprs[dst_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, push_str8f(arena, "$%I64d", cfg->id)); + } + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(cfgs) +{ + U64 id = 0; + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; + if(num != 0) + { + U64 idx = num-1; + if(contains_1u64(accel->cfgs_idx_range, idx)) + { + RD_Cfg *cfg = accel->cfgs.v[idx - accel->cfgs_idx_range.min]; + id = cfg->id; + } + else if(contains_1u64(accel->cmds_idx_range, idx)) + { + id = num; + id |= (1ull<<63); + } + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(cfgs) +{ + U64 num = 0; + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; + if(id != 0) + { + if(id & (1ull<<63)) + { + num = id; + num &= ~(1ull<<63); + } + else for EachIndex(idx, accel->cfgs.count) + { + if(accel->cfgs.v[idx]->id == id) + { + num = idx + accel->cfgs_idx_range.min + 1; + break; + } + } + } + return num; +} + +//////////////////////////////// +//~ rjf: Call Stack Eval Hooks + +typedef struct RD_CallStackLookupAccel RD_CallStackLookupAccel; +struct RD_CallStackLookupAccel +{ + Arch arch; + CTRL_Handle process; + CTRL_CallStack call_stack; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(call_stack) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + RD_CallStackLookupAccel *accel = push_array(arena, RD_CallStackLookupAccel, 1); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interp = e_interpret(bytecode); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(interp.space); + if(entity->kind == CTRL_EntityKind_Thread) + { + CTRL_Entity *process = ctrl_process_from_entity(entity); + CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); + accel->arch = entity->arch; + accel->process = process->handle; + accel->call_stack = ctrl_call_stack_from_unwind(arena, rd_state->frame_di_scope, process, &base_unwind); + result.idxed_expr_count = accel->call_stack.count; + } + result.user_data = accel; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(call_stack) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + RD_CallStackLookupAccel *accel = (RD_CallStackLookupAccel *)user_data; + CTRL_CallStack *call_stack = &accel->call_stack; + if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->count) + { + CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, accel->process); + CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; + result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), e_irtree_const_u(arena, regs_rip_from_arch_block(accel->arch, f->regs))); + result.irtree_and_type.type_key = e_type_key_cons(.arch = process->arch, .kind = E_TypeKind_Ptr, .direct_key = e_type_key_basic(E_TypeKind_Function), .count = 1, .depth = f->inline_depth); + result.irtree_and_type.mode = E_Mode_Value; + } + scratch_end(scratch); } return result; } //////////////////////////////// -//~ rjf: Config Type Functions +//~ rjf: Target / Environment Eval Hooks -internal void -rd_cfg_table_push_unparsed_string(Arena *arena, RD_CfgTable *table, String8 string, RD_CfgSrc source) +E_LOOKUP_INFO_FUNCTION_DEF(environment) { - if(table->slot_count == 0) + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); { - table->slot_count = 64; - table->slots = push_array(arena, RD_CfgSlot, table->slot_count); - } - MD_TokenizeResult tokenize = md_tokenize_from_text(arena, string); - MD_ParseResult parse = md_parse_from_text_tokens(arena, str8_lit(""), string, tokenize.tokens); - for MD_EachNode(tln, parse.root->first) if(tln->string.size != 0) - { - // rjf: map string -> hash*slot - String8 string = str8(tln->string.str, tln->string.size); - U64 hash = d_hash_from_string__case_insensitive(string); - U64 slot_idx = hash % table->slot_count; - RD_CfgSlot *slot = &table->slots[slot_idx]; - - // rjf: find existing value for this string - RD_CfgVal *val = 0; - for(RD_CfgVal *v = slot->first; v != 0; v = v->hash_next) + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + RD_Cfg *target = rd_cfg_from_eval_space(interpret.space); + RD_CfgList env_strings = {0}; + for(RD_Cfg *child = target->first; child != &rd_nil_cfg; child = child->next) { - if(str8_match(v->string, string, StringMatchFlag_CaseInsensitive)) + if(str8_match(child->string, str8_lit("environment"), 0)) { - val = v; - break; + rd_cfg_list_push(scratch.arena, &env_strings, child); } } - - // rjf: create new value if needed - if(val == 0) + RD_CfgArray *accel = push_array(arena, RD_CfgArray, 1); + *accel = rd_cfg_array_from_list(arena, &env_strings); + result.user_data = accel; + result.idxed_expr_count = accel->count + 1; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(environment) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) { - val = push_array(arena, RD_CfgVal, 1); - val->string = push_str8_copy(arena, string); - val->insertion_stamp = table->insertion_stamp_counter; - SLLStackPush_N(slot->first, val, hash_next); - SLLQueuePush_N(table->first_val, table->last_val, val, linear_next); - table->insertion_stamp_counter += 1; + RD_Cfg *cfg = cfgs->v[rhs_value.u64]; + result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + } + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(environment) +{ + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + Rng1U64 legal_idx_range = r1u64(0, cfgs->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 cfg_idx = read_range.min + idx; + if(cfg_idx < cfgs->count) + { + exprs[idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, cfg_idx); } - - // rjf: create new node within this value - RD_CfgTree *tree = push_array(arena, RD_CfgTree, 1); - SLLQueuePush_NZ(&d_nil_cfg_tree, val->first, val->last, tree, next); - tree->source = source; - tree->root = md_tree_copy(arena, tln); } } -internal RD_CfgVal * -rd_cfg_val_from_string(RD_CfgTable *table, String8 string) +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment) { - RD_CfgVal *result = &d_nil_cfg_val; - if(table->slot_count != 0) + U64 id = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(1 <= num && num <= cfgs->count) { - U64 hash = d_hash_from_string__case_insensitive(string); - U64 slot_idx = hash % table->slot_count; - RD_CfgSlot *slot = &table->slots[slot_idx]; - for(RD_CfgVal *val = slot->first; val != 0; val = val->hash_next) + U64 idx = (num-1); + id = cfgs->v[idx]->id; + } + else if(num == cfgs->count+1) + { + id = max_U64; + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment) +{ + U64 num = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(id != 0 && id != max_U64) + { + for EachIndex(idx, cfgs->count) { - if(str8_match(val->string, string, StringMatchFlag_CaseInsensitive)) + if(cfgs->v[idx]->id == id) { - result = val; + num = idx+1; break; } } } + else if(id == max_U64) + { + num = cfgs->count + 1; + } + return num; +} + +//////////////////////////////// +//~ rjf: Unattached System Process List Eval Hooks + +typedef struct RD_UnattachedProcessesAccel RD_UnattachedProcessesAccel; +struct RD_UnattachedProcessesAccel +{ + DMN_ProcessInfo *infos; + CTRL_Entity **machines; + U64 infos_count; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(unattached_processes) +{ + E_LookupInfo info = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: evaluate lhs machine, if we have one + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + CTRL_Entity *lhs_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); + + //- rjf: gather all machines we're searching through + CTRL_EntityList machines = {0}; + if(lhs_entity->kind == CTRL_EntityKind_Machine) + { + ctrl_entity_list_push(scratch.arena, &machines, lhs_entity); + } + else + { + machines = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Machine); + } + + //- rjf: gather system processes from this machine + typedef struct Node Node; + struct Node + { + Node *next; + CTRL_Entity *machine; + DMN_ProcessInfo info; + }; + Node *first = 0; + Node *last = 0; + U64 count = 0; + for(CTRL_EntityNode *n = machines.first; n != 0; n = n->next) + { + CTRL_Entity *machine = n->v; + DMN_ProcessIter iter = {0}; + dmn_process_iter_begin(&iter); + for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) + { + B32 passes_filter = 1; + if(filter.size != 0) + { + passes_filter = 0; + FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, info.name); + FuzzyMatchRangeList pid_matches = fuzzy_match_find(scratch.arena, filter, push_str8f(scratch.arena, "%I64u", info.pid)); + if(name_matches.count == name_matches.needle_part_count || pid_matches.count == pid_matches.needle_part_count) + { + passes_filter = 1; + } + } + if(passes_filter) + { + Node *node = push_array(scratch.arena, Node, 1); + SLLQueuePush(first, last, node); + node->machine = machine; + node->info = info; + count += 1; + } + } + dmn_process_iter_end(&iter); + } + + //- rjf: list -> array + U64 infos_count = count; + DMN_ProcessInfo *infos = push_array(arena, DMN_ProcessInfo, infos_count); + CTRL_Entity **infos_machines = push_array(arena, CTRL_Entity *, infos_count); + { + U64 idx = 0; + for(Node *n = first; n != 0; n = n->next, idx += 1) + { + infos[idx] = n->info; + infos[idx].name = push_str8_copy(arena, infos[idx].name); + infos_machines[idx] = n->machine; + } + } + + //- rjf: build accelerator + RD_UnattachedProcessesAccel *accel = push_array(arena, RD_UnattachedProcessesAccel, 1); + accel->infos = infos; + accel->infos_count = infos_count; + accel->machines = infos_machines; + info.user_data = accel; + info.idxed_expr_count = infos_count; + scratch_end(scratch); + } + return info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(unattached_processes) +{ + RD_UnattachedProcessesAccel *accel = (RD_UnattachedProcessesAccel *)user_data; + U64 out_idx = 0; + E_TypeKey unattached_process_type = e_type_key_cons(.kind = E_TypeKind_U128, .name = str8_lit("unattached_process")); + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = unattached_process_type; + expr->value.u128.u64[0] = accel->infos[idx].pid; + expr->value.u128.u64[1] = e_id_from_string(accel->infos[idx].name); + expr->space = rd_eval_space_from_ctrl_entity(accel->machines[idx], RD_EvalSpaceKind_MetaUnattachedProcess); + exprs[out_idx] = expr; + } +} + +//////////////////////////////// +//~ rjf: Control Entity Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + //- rjf: determine which entity we're looking under + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + CTRL_Entity *scoping_entity = &ctrl_entity_nil; + if(lhs_interp.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + { + scoping_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); + } + + //- rjf: determine which type of child we're gathering + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + String8 name = rd_singular_from_code_name_plural(lhs_type->name); + CTRL_EntityKind entity_kind = CTRL_EntityKind_Null; + for EachNonZeroEnumVal(CTRL_EntityKind, k) + { + if(str8_match(name, ctrl_entity_kind_code_name_table[k], 0)) + { + entity_kind = k; + break; + } + } + + //- rjf: gather list of all entities which fit the bill + CTRL_EntityList list = {0}; + if(scoping_entity == &ctrl_entity_nil) + { + list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, entity_kind); + } + else + { + for(CTRL_Entity *child = scoping_entity->first; child != &ctrl_entity_nil; child = child->next) + { + if(child->kind == entity_kind) + { + ctrl_entity_list_push(scratch.arena, &list, child); + } + } + } + + //- rjf: filter the list + CTRL_EntityList list__filtered = list; + if(filter.size != 0) + { + MemoryZeroStruct(&list__filtered); + for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) + { + CTRL_Entity *entity = n->v; + DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, entity, 1); + String8 title_string = dr_string_from_fstrs(scratch.arena, &fstrs); + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, title_string); + if(matches.count == matches.needle_part_count) + { + ctrl_entity_list_push(scratch.arena, &list__filtered, entity); + } + } + } + + //- rjf: list -> array & fill + CTRL_EntityArray *array = push_array(arena, CTRL_EntityArray, 1); + *array = ctrl_entity_array_from_list(arena, &list__filtered); + result.user_data = array; + result.idxed_expr_count = array->count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupAccess result = {{&e_irnode_nil}}; + CTRL_Entity *entity = &ctrl_entity_nil; + if(kind == E_ExprKind_MemberAccess) + { + String8 rhs_name = rhs->string; + CTRL_Handle handle = ctrl_handle_from_string(rhs_name); + entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + } + else if(kind == E_ExprKind_ArrayIndex) + { + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + U64 rhs_idx = rhs_value.u64; + CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; + if(0 <= rhs_idx && rhs_idx < entities->count) + { + entity = entities->v[rhs_idx]; + } + } + if(entity != &ctrl_entity_nil) + { + E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + String8 name = ctrl_entity_kind_code_name_table[entity->kind]; + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = type_key; + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(ctrl_entities) +{ + CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + Rng1U64 legal_range = r1u64(0, entities->count); + Rng1U64 read_range = intersect_1u64(legal_range, idx_range); + U64 read_count = dim_1u64(read_range); + for(U64 out_idx = 0; out_idx < read_count; out_idx += 1) + { + CTRL_Entity *entity = entities->v[out_idx + read_range.min]; + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, ctrl_string_from_handle(arena, entity->handle)); + } +} + +//////////////////////////////// +//~ rjf: Debug Info Tables Eval Hooks + +typedef struct RD_DebugInfoTableLookupAccel RD_DebugInfoTableLookupAccel; +struct RD_DebugInfoTableLookupAccel +{ + RDI_SectionKind section; + U64 rdis_count; + RDI_Parsed **rdis; + DI_SearchItemArray items; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table) +{ + Temp scratch = scratch_begin(&arena, 1); + + // rjf: determine which debug info section we're dealing with + RDI_SectionKind section = RDI_SectionKind_NULL; + { + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + if(0){} + else if(str8_match(lhs_type->name, str8_lit("procedures"), 0)) {section = RDI_SectionKind_Procedures;} + else if(str8_match(lhs_type->name, str8_lit("globals"), 0)) {section = RDI_SectionKind_GlobalVariables;} + else if(str8_match(lhs_type->name, str8_lit("thread_locals"), 0)) {section = RDI_SectionKind_ThreadVariables;} + else if(str8_match(lhs_type->name, str8_lit("types"), 0)) {section = RDI_SectionKind_UDTs;} + } + + // rjf: gather debug info table items + RD_DebugInfoTableLookupAccel *accel = push_array(arena, RD_DebugInfoTableLookupAccel, 1); + if(section != RDI_SectionKind_NULL) + { + U64 endt_us = rd_state->frame_eval_memread_endt_us; + + //- rjf: unpack context + DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena); + DI_KeyArray dbgi_keys = di_key_array_from_list(scratch.arena, &dbgi_keys_list); + U64 rdis_count = dbgi_keys.count; + RDI_Parsed **rdis = push_array(arena, RDI_Parsed *, rdis_count); + for(U64 idx = 0; idx < rdis_count; idx += 1) + { + rdis[idx] = di_rdi_from_key(rd_state->frame_di_scope, &dbgi_keys.v[idx], endt_us); + } + + //- rjf: query all filtered items from dbgi searching system + U128 fuzzy_search_key = {d_hash_from_string(str8_struct(&rd_regs()->view)), (U64)section}; + B32 items_stale = 0; + DI_SearchParams params = {section, dbgi_keys}; + accel->section = section; + accel->rdis_count = rdis_count; + accel->rdis = rdis; + accel->items = di_search_items_from_key_params_query(rd_state->frame_di_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); + if(items_stale) + { + rd_request_frame(); + } + } + E_LookupInfo info = {accel, 0, accel->items.count}; + scratch_end(scratch); + return info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + U64 needed_row_count = dim_1u64(idx_range); + for EachIndex(idx, needed_row_count) + { + // rjf: unpack row + DI_SearchItem *item = &accel->items.v[idx_range.min + idx]; + + // rjf: skip bad elements + if(item->dbgi_idx >= accel->rdis_count) + { + continue; + } + + // rjf: unpack row info + RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; + E_Module *module = &e_parse_state->ctx->modules[item->dbgi_idx]; + + // rjf: build expr + E_Expr *item_expr = &e_expr_nil; + { + U64 element_idx = item->idx; + switch(accel->section) + { + default:{}break; + case RDI_SectionKind_Procedures: + { + Temp scratch = scratch_begin(&arena, 1); + RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); + RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + String8 symbol_name = {0}; + symbol_name.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &symbol_name.size); + String8List strings = {0}; + e_type_lhs_string_from_key(scratch.arena, type_key, &strings, 0, 0); + str8_list_push(scratch.arena, &strings, symbol_name); + e_type_rhs_string_from_key(scratch.arena, type_key, &strings, 0); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Value; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string = str8_list_join(arena, &strings, 0); + scratch_end(scratch); + }break; + case RDI_SectionKind_GlobalVariables: + { + RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); + U64 voff = gvar->voff; + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = gvar->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Offset; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_ThreadVariables: + { + RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(tvar->tls_off)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = tvar->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Offset; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_UDTs: + { + RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_state->ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); + item_expr->type_key = type_key; + }break; + } + } + + // rjf: fill + exprs[idx] = item_expr; + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + U64 id = 0; + if(0 < num && num <= accel->items.count) + { + id = accel->items.v[num-1].idx+1; + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + U64 num = di_search_item_num_from_array_element_idx__linear_search(&accel->items, id-1); + return num; +} + +//////////////////////////////// +//~ rjf: Config ID Type Functions + +internal void +rd_cfg_id_list_push(Arena *arena, RD_CfgIDList *list, RD_CfgID id) +{ + RD_CfgIDNode *n = push_array(arena, RD_CfgIDNode, 1); + n->v = id; + SLLQueuePush(list->first, list->last, n); + list->count += 1; +} + +internal RD_CfgIDList +rd_cfg_id_list_copy(Arena *arena, RD_CfgIDList *src) +{ + RD_CfgIDList result = {0}; + for(RD_CfgIDNode *n = src->first; n != 0; n = n->next) + { + rd_cfg_id_list_push(arena, &result, n->v); + } return result; } @@ -130,16 +1308,18 @@ internal void rd_regs_copy_contents(Arena *arena, RD_Regs *dst, RD_Regs *src) { MemoryCopyStruct(dst, src); - dst->entity_list = rd_handle_list_copy(arena, src->entity_list); + dst->cfg_list = rd_cfg_id_list_copy(arena, &src->cfg_list); dst->file_path = push_str8_copy(arena, src->file_path); dst->lines = d_line_list_copy(arena, &src->lines); dst->dbgi_key = di_key_copy(arena, &src->dbgi_key); + dst->expr = push_str8_copy(arena, src->expr); + dst->view_rule = push_str8_copy(arena, src->view_rule); dst->string = push_str8_copy(arena, src->string); dst->cmd_name = push_str8_copy(arena, src->cmd_name); dst->params_tree = md_tree_copy(arena, src->params_tree); - if(dst->entity_list.count == 0 && !rd_handle_match(rd_handle_zero(), dst->entity)) + if(dst->cfg_list.count == 0 && dst->cfg != 0) { - rd_handle_list_push(arena, &dst->entity_list, dst->entity); + rd_cfg_id_list_push(arena, &dst->cfg_list, dst->cfg); } } @@ -165,695 +1345,46 @@ rd_cmd_list_push_new(Arena *arena, RD_CmdList *cmds, String8 name, RD_Regs *regs } //////////////////////////////// -//~ rjf: Entity Functions +//~ rjf: View UI Rule Functions -//- rjf: nil - -internal B32 -rd_entity_is_nil(RD_Entity *entity) +internal RD_ViewUIRuleMap * +rd_view_ui_rule_map_make(Arena *arena, U64 slots_count) { - return (entity == 0 || entity == &rd_nil_entity); -} - -//- rjf: handle <-> entity conversions - -internal U64 -rd_index_from_entity(RD_Entity *entity) -{ - return (U64)(entity - rd_state->entities_base); -} - -internal RD_Handle -rd_handle_from_entity(RD_Entity *entity) -{ - RD_Handle handle = rd_handle_zero(); - if(!rd_entity_is_nil(entity)) - { - handle.u64[0] = rd_index_from_entity(entity); - handle.u64[1] = entity->gen; - } - return handle; -} - -internal RD_Entity * -rd_entity_from_handle(RD_Handle handle) -{ - RD_Entity *result = rd_state->entities_base + handle.u64[0]; - if(handle.u64[0] >= rd_state->entities_count || result->gen != handle.u64[1]) - { - result = &rd_nil_entity; - } - return result; -} - -//- rjf: entity recursion iterators - -internal RD_EntityRec -rd_entity_rec_depth_first(RD_Entity *entity, RD_Entity *subtree_root, U64 sib_off, U64 child_off) -{ - RD_EntityRec result = {0}; - if(!rd_entity_is_nil(*MemberFromOffset(RD_Entity **, entity, child_off))) - { - result.next = *MemberFromOffset(RD_Entity **, entity, child_off); - result.push_count = 1; - } - else for(RD_Entity *parent = entity; parent != subtree_root && !rd_entity_is_nil(parent); parent = parent->parent) - { - if(parent != subtree_root && !rd_entity_is_nil(*MemberFromOffset(RD_Entity **, parent, sib_off))) - { - result.next = *MemberFromOffset(RD_Entity **, parent, sib_off); - break; - } - result.pop_count += 1; - } - return result; -} - -//- rjf: ancestor/child introspection - -internal RD_Entity * -rd_entity_child_from_kind(RD_Entity *entity, RD_EntityKind kind) -{ - RD_Entity *result = &rd_nil_entity; - for(RD_Entity *child = entity->first; !rd_entity_is_nil(child); child = child->next) - { - if(!(child->flags & RD_EntityFlag_MarkedForDeletion) && child->kind == kind) - { - result = child; - break; - } - } - return result; -} - -//- rjf: entity list building - -internal void -rd_entity_list_push(Arena *arena, RD_EntityList *list, RD_Entity *entity) -{ - RD_EntityNode *n = push_array(arena, RD_EntityNode, 1); - n->entity = entity; - SLLQueuePush(list->first, list->last, n); - list->count += 1; -} - -internal RD_EntityArray -rd_entity_array_from_list(Arena *arena, RD_EntityList *list) -{ - RD_EntityArray result = {0}; - result.count = list->count; - result.v = push_array(arena, RD_Entity *, result.count); - U64 idx = 0; - for(RD_EntityNode *n = list->first; n != 0; n = n->next, idx += 1) - { - result.v[idx] = n->entity; - } - return result; -} - -//- rjf: entity -> color operations - -internal Vec4F32 -rd_hsva_from_entity(RD_Entity *entity) -{ - Vec4F32 result = {0}; - if(entity->flags & RD_EntityFlag_HasColor) - { - result = entity->color_hsva; - } - return result; -} - -internal Vec4F32 -rd_rgba_from_entity(RD_Entity *entity) -{ - Vec4F32 result = {0}; - if(entity->flags & RD_EntityFlag_HasColor) - { - Vec3F32 hsv = v3f32(entity->color_hsva.x, entity->color_hsva.y, entity->color_hsva.z); - Vec3F32 rgb = rgb_from_hsv(hsv); - result = v4f32(rgb.x, rgb.y, rgb.z, entity->color_hsva.w); - } - else switch(entity->kind) - { - default:{}break; - case RD_EntityKind_Breakpoint: - { - result = rd_rgba_from_theme_color(RD_ThemeColor_Breakpoint); - }break; - } - return result; -} - -//- rjf: entity -> expansion tree keys - -internal EV_Key -rd_ev_key_from_entity(RD_Entity *entity) -{ - EV_Key parent_key = rd_parent_ev_key_from_entity(entity); - EV_Key key = ev_key_make(ev_hash_from_key(parent_key), (U64)entity); - return key; -} - -internal EV_Key -rd_parent_ev_key_from_entity(RD_Entity *entity) -{ - EV_Key parent_key = ev_key_make(5381, (U64)entity); - return parent_key; -} - -//////////////////////////////// -//~ rjf: View Type Functions - -internal B32 -rd_view_is_nil(RD_View *view) -{ - return (view == 0 || view == &rd_nil_view); -} - -internal B32 -rd_view_is_project_filtered(RD_View *view) -{ - B32 result = 0; - String8 view_project = view->project_path; - if(view_project.size != 0) - { - RD_ViewRuleKind kind = rd_view_rule_kind_from_string(view->spec->string); - // TODO(rjf): @hack hack hack - this should be completely determined if the view - // is parameterized by an expression, but that is currently the same string as the - // query, and so we can't rely on that. when query expressions are separated from - // filter strings, we can rely on that here. - if((kind == RD_ViewRuleKind_Text || - kind == RD_ViewRuleKind_Disasm || - kind == RD_ViewRuleKind_Memory || - kind == RD_ViewRuleKind_Bitmap || - kind == RD_ViewRuleKind_Geo3D) && - view->query_string_size != 0) - { - String8 current_project = rd_cfg_path_from_src(RD_CfgSrc_Project); - result = !path_match_normalized(view_project, current_project); - } - } - return result; -} - -internal RD_Handle -rd_handle_from_view(RD_View *view) -{ - RD_Handle handle = rd_handle_zero(); - if(!rd_view_is_nil(view)) - { - handle.u64[0] = (U64)view; - handle.u64[1] = view->generation; - } - return handle; -} - -internal RD_View * -rd_view_from_handle(RD_Handle handle) -{ - RD_View *result = (RD_View *)handle.u64[0]; - if(rd_view_is_nil(result) || result->generation != handle.u64[1]) - { - result = &rd_nil_view; - } - return result; -} - -//////////////////////////////// -//~ rjf: View Spec Type Functions - -internal RD_ViewRuleKind -rd_view_rule_kind_from_string(String8 string) -{ - RD_ViewRuleKind kind = RD_ViewRuleKind_Null; - for EachEnumVal(RD_ViewRuleKind, k) - { - if(str8_match(string, rd_view_rule_kind_info_table[k].string, 0)) - { - kind = k; - break; - } - } - return kind; -} - -internal RD_ViewRuleInfo * -rd_view_rule_info_from_kind(RD_ViewRuleKind kind) -{ - return &rd_view_rule_kind_info_table[kind]; -} - -internal RD_ViewRuleInfo * -rd_view_rule_info_from_string(String8 string) -{ - RD_ViewRuleInfo *result = &rd_nil_view_rule_info; - { - RD_ViewRuleKind kind = rd_view_rule_kind_from_string(string); - if(kind != RD_ViewRuleKind_Null) - { - result = &rd_view_rule_kind_info_table[kind]; - } - } - return result; -} - -//////////////////////////////// -//~ rjf: Panel Type Functions - -//- rjf: basic type functions - -internal B32 -rd_panel_is_nil(RD_Panel *panel) -{ - return panel == 0 || panel == &rd_nil_panel; -} - -internal RD_Handle -rd_handle_from_panel(RD_Panel *panel) -{ - RD_Handle h = {0}; - h.u64[0] = (U64)panel; - h.u64[1] = panel->generation; - return h; -} - -internal RD_Panel * -rd_panel_from_handle(RD_Handle handle) -{ - RD_Panel *panel = (RD_Panel *)handle.u64[0]; - if(panel == 0 || panel->generation != handle.u64[1]) - { - panel = &rd_nil_panel; - } - return panel; -} - -internal UI_Key -rd_ui_key_from_panel(RD_Panel *panel) -{ - UI_Key panel_key = ui_key_from_stringf(ui_key_zero(), "panel_window_%p", panel); - return panel_key; -} - -//- rjf: tree construction - -internal void -rd_panel_insert(RD_Panel *parent, RD_Panel *prev_child, RD_Panel *new_child) -{ - DLLInsert_NPZ(&rd_nil_panel, parent->first, parent->last, prev_child, new_child, next, prev); - parent->child_count += 1; - new_child->parent = parent; + RD_ViewUIRuleMap *map = push_array(arena, RD_ViewUIRuleMap, 1); + map->slots_count = slots_count; + map->slots = push_array(arena, RD_ViewUIRuleSlot, map->slots_count); + return map; } internal void -rd_panel_remove(RD_Panel *parent, RD_Panel *child) +rd_view_ui_rule_map_insert(Arena *arena, RD_ViewUIRuleMap *map, String8 string, RD_ViewUIFunctionType *ui) { - DLLRemove_NPZ(&rd_nil_panel, parent->first, parent->last, child, next, prev); - child->next = child->prev = child->parent = &rd_nil_panel; - parent->child_count -= 1; + U64 hash = d_hash_from_string(string); + U64 slot_idx = hash%map->slots_count; + RD_ViewUIRuleNode *n = push_array(arena, RD_ViewUIRuleNode, 1); + n->v.name = push_str8_copy(arena, string); + n->v.ui = ui; + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); } -//- rjf: tree walk - -internal RD_PanelRec -rd_panel_rec_depth_first(RD_Panel *panel, U64 sib_off, U64 child_off) +internal RD_ViewUIRule * +rd_view_ui_rule_from_string(String8 string) { - RD_PanelRec rec = {0}; - if(!rd_panel_is_nil(*MemberFromOffset(RD_Panel **, panel, child_off))) + RD_ViewUIRule *rule = &rd_nil_view_ui_rule; { - rec.next = *MemberFromOffset(RD_Panel **, panel, child_off); - rec.push_count = 1; - } - else if(!rd_panel_is_nil(*MemberFromOffset(RD_Panel **, panel, sib_off))) - { - rec.next = *MemberFromOffset(RD_Panel **, panel, sib_off); - } - else - { - RD_Panel *uncle = &rd_nil_panel; - for(RD_Panel *p = panel->parent; !rd_panel_is_nil(p); p = p->parent) + RD_ViewUIRuleMap *map = rd_state->view_ui_rule_map; + U64 hash = d_hash_from_string(string); + U64 slot_idx = hash%map->slots_count; + for(RD_ViewUIRuleNode *n = map->slots[slot_idx].first; n != 0; n = n->next) { - rec.pop_count += 1; - if(!rd_panel_is_nil(*MemberFromOffset(RD_Panel **, p, sib_off))) + if(str8_match(n->v.name, string, 0)) { - uncle = *MemberFromOffset(RD_Panel **, p, sib_off); + rule = &n->v; break; } } - rec.next = uncle; } - return rec; -} - -//- rjf: panel -> rect calculations - -internal Rng2F32 -rd_target_rect_from_panel_child(Rng2F32 parent_rect, RD_Panel *parent, RD_Panel *panel) -{ - Rng2F32 rect = parent_rect; - if(!rd_panel_is_nil(parent)) - { - Vec2F32 parent_rect_size = dim_2f32(parent_rect); - Axis2 axis = parent->split_axis; - rect.p1.v[axis] = rect.p0.v[axis]; - for(RD_Panel *child = parent->first; !rd_panel_is_nil(child); child = child->next) - { - rect.p1.v[axis] += parent_rect_size.v[axis] * child->pct_of_parent; - if(child == panel) - { - break; - } - rect.p0.v[axis] = rect.p1.v[axis]; - } - //rect.p0.v[axis] += parent_rect_size.v[axis] * panel->off_pct_of_parent.v[axis]; - //rect.p0.v[axis2_flip(axis)] += parent_rect_size.v[axis2_flip(axis)] * panel->off_pct_of_parent.v[axis2_flip(axis)]; - } - rect.x0 = round_f32(rect.x0); - rect.x1 = round_f32(rect.x1); - rect.y0 = round_f32(rect.y0); - rect.y1 = round_f32(rect.y1); - return rect; -} - -internal Rng2F32 -rd_target_rect_from_panel(Rng2F32 root_rect, RD_Panel *root, RD_Panel *panel) -{ - Temp scratch = scratch_begin(0, 0); - - // rjf: count ancestors - U64 ancestor_count = 0; - for(RD_Panel *p = panel->parent; !rd_panel_is_nil(p); p = p->parent) - { - ancestor_count += 1; - } - - // rjf: gather ancestors - RD_Panel **ancestors = push_array(scratch.arena, RD_Panel *, ancestor_count); - { - U64 ancestor_idx = 0; - for(RD_Panel *p = panel->parent; !rd_panel_is_nil(p); p = p->parent) - { - ancestors[ancestor_idx] = p; - ancestor_idx += 1; - } - } - - // rjf: go from highest ancestor => panel and calculate rect - Rng2F32 parent_rect = root_rect; - for(S64 ancestor_idx = (S64)ancestor_count-1; - 0 <= ancestor_idx && ancestor_idx < ancestor_count; - ancestor_idx -= 1) - { - RD_Panel *ancestor = ancestors[ancestor_idx]; - RD_Panel *parent = ancestor->parent; - if(!rd_panel_is_nil(parent)) - { - parent_rect = rd_target_rect_from_panel_child(parent_rect, parent, ancestor); - } - } - - // rjf: calculate final rect - Rng2F32 rect = rd_target_rect_from_panel_child(parent_rect, panel->parent, panel); - - scratch_end(scratch); - return rect; -} - -//- rjf: view ownership insertion/removal - -internal void -rd_panel_insert_tab_view(RD_Panel *panel, RD_View *prev_view, RD_View *view) -{ - DLLInsert_NPZ(&rd_nil_view, panel->first_tab_view, panel->last_tab_view, prev_view, view, order_next, order_prev); - panel->tab_view_count += 1; - if(!rd_view_is_project_filtered(view)) - { - panel->selected_tab_view = rd_handle_from_view(view); - } -} - -internal void -rd_panel_remove_tab_view(RD_Panel *panel, RD_View *view) -{ - if(rd_view_from_handle(panel->selected_tab_view) == view) - { - panel->selected_tab_view = rd_handle_zero(); - if(rd_handle_match(rd_handle_zero(), panel->selected_tab_view)) - { - for(RD_View *v = view->order_next; !rd_view_is_nil(v); v = v->order_next) - { - if(!rd_view_is_project_filtered(v)) - { - panel->selected_tab_view = rd_handle_from_view(v); - break; - } - } - } - if(rd_handle_match(rd_handle_zero(), panel->selected_tab_view)) - { - for(RD_View *v = view->order_prev; !rd_view_is_nil(v); v = v->order_prev) - { - if(!rd_view_is_project_filtered(v)) - { - panel->selected_tab_view = rd_handle_from_view(v); - break; - } - } - } - } - DLLRemove_NPZ(&rd_nil_view, panel->first_tab_view, panel->last_tab_view, view, order_next, order_prev); - panel->tab_view_count -= 1; -} - -internal RD_View * -rd_selected_tab_from_panel(RD_Panel *panel) -{ - RD_View *view = rd_view_from_handle(panel->selected_tab_view); - if(rd_view_is_project_filtered(view)) - { - view = &rd_nil_view; - } - return view; -} - -//- rjf: icons & display strings - -internal RD_IconKind -rd_icon_kind_from_view(RD_View *view) -{ - RD_IconKind result = view->spec->icon_kind; - return result; -} - -internal DR_FancyStringList -rd_title_fstrs_from_view(Arena *arena, RD_View *view, Vec4F32 primary_color, Vec4F32 secondary_color, F32 size) -{ - DR_FancyStringList result = {0}; - Temp scratch = scratch_begin(&arena, 1); - String8 query = str8(view->query_buffer, view->query_string_size); - String8 file_path = rd_file_path_from_eval_string(scratch.arena, query); - - //- rjf: query is file path - do specific file name strings - if(file_path.size != 0) - { - // rjf: compute disambiguated file name - String8List qualifiers = {0}; - String8 file_name = str8_skip_last_slash(file_path); - if(rd_state->ambiguous_path_slots_count != 0) - { - U64 hash = d_hash_from_string__case_insensitive(file_name); - U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; - RD_AmbiguousPathNode *node = 0; - { - for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; - n != 0; - n = n->next) - { - if(str8_match(n->name, file_name, StringMatchFlag_CaseInsensitive)) - { - node = n; - break; - } - } - } - if(node != 0 && node->paths.node_count > 1) - { - // rjf: get all colliding paths - String8Array collisions = str8_array_from_list(scratch.arena, &node->paths); - - // rjf: get all reversed path parts for each collision - String8List *collision_parts_reversed = push_array(scratch.arena, String8List, collisions.count); - for EachIndex(idx, collisions.count) - { - String8List parts = str8_split_path(scratch.arena, collisions.v[idx]); - for(String8Node *n = parts.first; n != 0; n = n->next) - { - str8_list_push_front(scratch.arena, &collision_parts_reversed[idx], n->string); - } - } - - // rjf: get the search path & its reversed parts - String8List parts = str8_split_path(scratch.arena, file_path); - String8List parts_reversed = {0}; - for(String8Node *n = parts.first; n != 0; n = n->next) - { - str8_list_push_front(scratch.arena, &parts_reversed, n->string); - } - - // rjf: iterate all collision part reversed lists, in lock-step with - // search path; disqualify until we only have one path remaining; gather - // qualifiers - { - U64 num_collisions_left = collisions.count; - String8Node **collision_nodes = push_array(scratch.arena, String8Node *, collisions.count); - for EachIndex(idx, collisions.count) - { - collision_nodes[idx] = collision_parts_reversed[idx].first; - } - for(String8Node *n = parts_reversed.first; num_collisions_left > 1 && n != 0; n = n->next) - { - B32 part_is_qualifier = 0; - for EachIndex(idx, collisions.count) - { - if(collision_nodes[idx] != 0 && !str8_match(collision_nodes[idx]->string, n->string, StringMatchFlag_CaseInsensitive)) - { - collision_nodes[idx] = 0; - num_collisions_left -= 1; - part_is_qualifier = 1; - } - else if(collision_nodes[idx] != 0) - { - collision_nodes[idx] = collision_nodes[idx]->next; - } - } - if(part_is_qualifier) - { - str8_list_push_front(scratch.arena, &qualifiers, n->string); - } - } - } - } - } - - // rjf: push qualifiers - for(String8Node *n = qualifiers.first; n != 0; n = n->next) - { - String8 string = push_str8f(arena, "<%S> ", n->string); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size*0.95f, secondary_color, string); - } - - // rjf: push file name - DR_FancyString fstr = - { - rd_font_from_slot(RD_FontSlot_Main), - push_str8_copy(arena, file_name), - primary_color, - size, - }; - dr_fancy_string_list_push(arena, &result, &fstr); - } - - //- rjf: query is not file path - do general case, for view rule & expression - else - { - DR_FancyString fstr1 = - { - rd_font_from_slot(RD_FontSlot_Main), - view->spec->display_name, - primary_color, - size, - }; - dr_fancy_string_list_push(arena, &result, &fstr1); - if(query.size != 0) - { - DR_FancyString fstr2 = - { - rd_font_from_slot(RD_FontSlot_Code), - str8_lit(" "), - primary_color, - size, - }; - dr_fancy_string_list_push(arena, &result, &fstr2); - DR_FancyString fstr3 = - { - rd_font_from_slot(RD_FontSlot_Code), - push_str8_copy(arena, query), - secondary_color, - size*0.8f, - }; - dr_fancy_string_list_push(arena, &result, &fstr3); - } - } - scratch_end(scratch); - return result; -} - -//////////////////////////////// -//~ rjf: Window Type Functions - -internal RD_Handle -rd_handle_from_window(RD_Window *window) -{ - RD_Handle handle = {0}; - if(window != 0) - { - handle.u64[0] = (U64)window; - handle.u64[1] = window->gen; - } - return handle; -} - -internal RD_Window * -rd_window_from_handle(RD_Handle handle) -{ - RD_Window *window = (RD_Window *)handle.u64[0]; - if(window != 0 && window->gen != handle.u64[1]) - { - window = 0; - } - return window; -} - -//////////////////////////////// -//~ rjf: Command Parameters From Context - -internal B32 -rd_prefer_dasm_from_window(RD_Window *window) -{ - RD_Panel *panel = window->focused_panel; - RD_View *view = rd_selected_tab_from_panel(panel); - RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(view->spec->string); - B32 result = 0; - if(view_kind == RD_ViewRuleKind_Disasm) - { - result = 1; - } - else if(view_kind == RD_ViewRuleKind_Text) - { - result = 0; - } - else - { - B32 has_src = 0; - B32 has_dasm = 0; - for(RD_Panel *p = window->root_panel; !rd_panel_is_nil(p); p = rd_panel_rec_depth_first_pre(p).next) - { - RD_View *p_view = rd_selected_tab_from_panel(p); - RD_ViewRuleKind p_view_kind = rd_view_rule_kind_from_string(p_view->spec->string); - if(p_view_kind == RD_ViewRuleKind_Text) - { - has_src = 1; - } - if(p_view_kind == RD_ViewRuleKind_Disasm) - { - has_dasm = 1; - } - } - if(has_src && !has_dasm) {result = 0;} - if(has_dasm && !has_src) {result = 1;} - } - return result; + return rule; } //////////////////////////////// @@ -909,147 +1440,148 @@ rd_get_hover_regs(void) return rd_state->hover_regs; } -internal void -rd_open_ctx_menu(UI_Key anchor_box_key, Vec2F32 anchor_box_off, RD_RegSlot slot) -{ - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) - { - ui_ctx_menu_open(rd_state->ctx_menu_key, anchor_box_key, anchor_box_off); - arena_clear(window->ctx_menu_arena); - window->ctx_menu_regs = rd_regs_copy(window->ctx_menu_arena, rd_regs()); - window->ctx_menu_regs_slot = slot; - } -} - //////////////////////////////// //~ rjf: Name Allocation internal U64 -rd_name_bucket_idx_from_string_size(U64 size) +rd_name_bucket_num_from_string_size(U64 size) { - U64 size_rounded = u64_up_to_pow2(size+1); - size_rounded = ClampBot((1<<4), size_rounded); - U64 bucket_idx = 0; - switch(size_rounded) + U64 bucket_num = 0; + if(size > 0) { - case 1<<4: {bucket_idx = 0;}break; - case 1<<5: {bucket_idx = 1;}break; - case 1<<6: {bucket_idx = 2;}break; - case 1<<7: {bucket_idx = 3;}break; - case 1<<8: {bucket_idx = 4;}break; - case 1<<9: {bucket_idx = 5;}break; - case 1<<10:{bucket_idx = 6;}break; - default:{bucket_idx = ArrayCount(rd_state->free_name_chunks)-1;}break; + for EachElement(idx, rd_name_bucket_chunk_sizes) + { + if(size <= rd_name_bucket_chunk_sizes[idx]) + { + bucket_num = idx+1; + break; + } + } } - return bucket_idx; + return bucket_num; } internal String8 rd_name_alloc(String8 string) { - if(string.size == 0) {return str8_zero();} - U64 bucket_idx = rd_name_bucket_idx_from_string_size(string.size); - - // rjf: loop -> find node, allocate if not there - // - // (we do a loop here so that all allocation logic goes through - // the same path, such that we *always* pull off a free list, - // rather than just using what was pushed onto an arena directly, - // which is not undoable; the free lists we control, and are thus - // trivially undoable) - // + //- rjf: allocate node RD_NameChunkNode *node = 0; - for(;node == 0;) { - node = rd_state->free_name_chunks[bucket_idx]; - - // rjf: pull from bucket free list - if(node != 0) + U64 bucket_num = rd_name_bucket_num_from_string_size(string.size); + if(bucket_num == ArrayCount(rd_name_bucket_chunk_sizes)) { - if(bucket_idx == ArrayCount(rd_state->free_name_chunks)-1) + RD_NameChunkNode *best_node = 0; + RD_NameChunkNode *best_node_prev = 0; + U64 best_node_size = max_U64; { - node = 0; - RD_NameChunkNode *prev = 0; - for(RD_NameChunkNode *n = rd_state->free_name_chunks[bucket_idx]; - n != 0; - prev = n, n = n->next) + for(RD_NameChunkNode *n = rd_state->free_name_chunks[bucket_num-1], *prev = 0; n != 0; (prev = n, n = n->next)) { - if(n->size >= string.size) + if(n->size >= string.size && n->size < best_node_size) { - if(prev == 0) - { - rd_state->free_name_chunks[bucket_idx] = n->next; - } - else - { - prev->next = n->next; - } - node = n; - break; + best_node = n; + best_node_prev = prev; + best_node_size = n->size; } } } + if(best_node != 0) + { + node = best_node; + if(best_node_prev) + { + best_node_prev->next = best_node->next; + } + else + { + rd_state->free_name_chunks[bucket_num-1] = best_node->next; + } + } else { - SLLStackPop(rd_state->free_name_chunks[bucket_idx]); + U64 chunk_size = u64_up_to_pow2(string.size); + node = (RD_NameChunkNode *)push_array(rd_state->arena, U8, chunk_size); } } - - // rjf: no found node -> allocate new, push onto associated free list - if(node == 0) + else if(bucket_num != 0) { - U64 chunk_size = 0; - if(bucket_idx < ArrayCount(rd_state->free_name_chunks)-1) + node = rd_state->free_name_chunks[bucket_num-1]; + if(node != 0) { - chunk_size = 1<<(bucket_idx+4); + SLLStackPop(rd_state->free_name_chunks[bucket_num-1]); } else { - chunk_size = u64_up_to_pow2(string.size); + node = (RD_NameChunkNode *)push_array(rd_state->arena, U8, rd_name_bucket_chunk_sizes[bucket_num-1]); } - U8 *chunk_memory = push_array(rd_state->arena, U8, chunk_size); - RD_NameChunkNode *chunk = (RD_NameChunkNode *)chunk_memory; - chunk->size = chunk_size; - SLLStackPush(rd_state->free_name_chunks[bucket_idx], chunk); } } - // rjf: fill string & return - String8 allocated_string = str8((U8 *)node, string.size); - MemoryCopy((U8 *)node, string.str, string.size); - return allocated_string; + //- rjf: fill node + String8 result = {0}; + if(node != 0) + { + result.str = (U8 *)node; + result.size = string.size; + MemoryCopy(result.str, string.str, result.size); + } + return result; } internal void rd_name_release(String8 string) { - if(string.size == 0) {return;} - U64 bucket_idx = rd_name_bucket_idx_from_string_size(string.size); - RD_NameChunkNode *node = (RD_NameChunkNode *)string.str; - node->size = u64_up_to_pow2(string.size); - SLLStackPush(rd_state->free_name_chunks[bucket_idx], node); + U64 bucket_num = rd_name_bucket_num_from_string_size(string.size); + if(1 <= bucket_num && bucket_num <= ArrayCount(rd_name_bucket_chunk_sizes)) + { + U64 bucket_idx = bucket_num-1; + RD_NameChunkNode *node = (RD_NameChunkNode *)string.str; + SLLStackPush(rd_state->free_name_chunks[bucket_idx], node); + node->size = u64_up_to_pow2(string.size); + } } //////////////////////////////// -//~ rjf: New Config/Entity Data Structure Functions +//~ rjf: Config Tree Functions internal RD_Cfg * rd_cfg_alloc(void) { + // rjf: allocate RD_Cfg *result = rd_state->free_cfg; - if(result) { - SLLStackPop(rd_state->free_cfg); + if(result) + { + SLLStackPop(rd_state->free_cfg); + } + else + { + result = push_array_no_zero(rd_state->arena, RD_Cfg, 1); + } } - else - { - result = push_array_no_zero(rd_state->arena, RD_Cfg, 1); - } - U64 old_gen = result->gen; + + // rjf: generate ID & fill + rd_state->cfg_id_gen += 1; MemoryZeroStruct(result); result->first = result->last = result->next = result->prev = result->parent = &rd_nil_cfg; - result->gen = old_gen + 1; + result->id = rd_state->cfg_id_gen; + + // rjf: store to ID -> cfg map + { + RD_CfgNode *cfg_id_node = rd_state->free_cfg_id_node; + if(cfg_id_node != 0) + { + SLLStackPop(rd_state->free_cfg_id_node); + } + else + { + cfg_id_node = push_array(rd_state->arena, RD_CfgNode, 1); + } + U64 hash = d_hash_from_string(str8_struct(&result->id)); + U64 slot_idx = hash%rd_state->cfg_id_slots_count; + DLLPushBack(rd_state->cfg_id_slots[slot_idx].first, rd_state->cfg_id_slots[slot_idx].last, cfg_id_node); + cfg_id_node->v = result; + } + return result; } @@ -1057,22 +1589,66 @@ internal void rd_cfg_release(RD_Cfg *cfg) { Temp scratch = scratch_begin(0, 0); + + // rjf: unhook from context rd_cfg_unhook(cfg->parent, cfg); + + // rjf: gather root & all descendants RD_CfgList nodes = {0}; for(RD_Cfg *c = cfg; c != &rd_nil_cfg; c = rd_cfg_rec__depth_first(cfg, c).next) { rd_cfg_list_push(scratch.arena, &nodes, c); } + + // rjf: release all nodes for(RD_CfgNode *n = nodes.first; n != 0; n = n->next) { RD_Cfg *c = n->v; - c->gen += 1; rd_name_release(c->string); SLLStackPush(rd_state->free_cfg, c); + U64 hash = d_hash_from_string(str8_struct(&c->id)); + U64 slot_idx = hash%rd_state->cfg_id_slots_count; + for(RD_CfgNode *n = rd_state->cfg_id_slots[slot_idx].first; n != 0; n = n->next) + { + if(n->v == c) + { + DLLRemove(rd_state->cfg_id_slots[slot_idx].first, rd_state->cfg_id_slots[slot_idx].last, n); + SLLStackPush(rd_state->free_cfg_id_node, n); + break; + } + } } + scratch_end(scratch); } +internal void +rd_cfg_release_all_children(RD_Cfg *cfg) +{ + for(RD_Cfg *child = cfg->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) + { + next = child->next; + rd_cfg_release(child); + } +} + +internal RD_Cfg * +rd_cfg_from_id(RD_CfgID id) +{ + RD_Cfg *result = &rd_nil_cfg; + U64 hash = d_hash_from_string(str8_struct(&id)); + U64 slot_idx = hash%rd_state->cfg_id_slots_count; + for(RD_CfgNode *n = rd_state->cfg_id_slots[slot_idx].first; n != 0; n = n->next) + { + if(n->v->id == id) + { + result = n->v; + break; + } + } + return result; +} + internal RD_Cfg * rd_cfg_new(RD_Cfg *parent, String8 string) { @@ -1095,27 +1671,102 @@ rd_cfg_newf(RD_Cfg *parent, char *fmt, ...) return result; } +internal RD_Cfg * +rd_cfg_new_replace(RD_Cfg *parent, String8 string) +{ + Temp scratch = scratch_begin(0, 0); + string = push_str8_copy(scratch.arena, string); + for(RD_Cfg *child = parent->first->next, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) + { + next = child->next; + rd_cfg_release(child); + } + if(parent->first == &rd_nil_cfg) + { + rd_cfg_new(parent, str8_zero()); + } + RD_Cfg *child = parent->first; + rd_cfg_equip_string(child, string); + scratch_end(scratch); + return child; +} + +internal RD_Cfg * +rd_cfg_new_replacef(RD_Cfg *parent, char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + RD_Cfg *result = rd_cfg_new_replace(parent, string); + va_end(args); + scratch_end(scratch); + return result; +} + +internal RD_Cfg * +rd_cfg_deep_copy(RD_Cfg *src_root) +{ + RD_CfgRec rec = {0}; + RD_Cfg *dst_root = &rd_nil_cfg; + RD_Cfg *dst_parent = &rd_nil_cfg; + for(RD_Cfg *src = src_root; src != &rd_nil_cfg; src = rec.next) + { + RD_Cfg *dst = rd_cfg_new(dst_parent, src->string); + if(dst_root == &rd_nil_cfg) + { + dst_root = dst; + } + rec = rd_cfg_rec__depth_first(src_root, src); + if(rec.push_count > 0) + { + dst_parent = dst; + } + else for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) + { + dst_parent = dst_parent->parent; + } + } + return dst_root; +} + internal void rd_cfg_equip_string(RD_Cfg *cfg, String8 string) { - if(cfg->string.size != 0) - { - rd_name_release(cfg->string); - } + rd_name_release(cfg->string); cfg->string = rd_name_alloc(string); } +internal void +rd_cfg_equip_stringf(RD_Cfg *cfg, char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + rd_cfg_equip_string(cfg, string); + va_end(args); + scratch_end(scratch); +} + internal void rd_cfg_insert_child(RD_Cfg *parent, RD_Cfg *prev_child, RD_Cfg *new_child) { - DLLInsert_NPZ(&rd_nil_cfg, parent->first, parent->last, prev_child, new_child, next, prev); - new_child->parent = parent; + if(parent != &rd_nil_cfg) + { + if(new_child->parent != &rd_nil_cfg) + { + rd_cfg_unhook(new_child->parent, new_child); + } + DLLInsert_NPZ(&rd_nil_cfg, parent->first, parent->last, prev_child, new_child, next, prev); + new_child->parent = parent; + } } internal void rd_cfg_unhook(RD_Cfg *parent, RD_Cfg *child) { - if(parent == child->parent && parent != &rd_nil_cfg) + if(child != &rd_nil_cfg && parent == child->parent && parent != &rd_nil_cfg) { DLLRemove_NPZ(&rd_nil_cfg, parent->first, parent->last, child, next, prev); child->parent = &rd_nil_cfg; @@ -1137,6 +1788,28 @@ rd_cfg_child_from_string(RD_Cfg *parent, String8 string) return child; } +internal RD_Cfg * +rd_cfg_child_from_string_or_alloc(RD_Cfg *parent, String8 string) +{ + RD_Cfg *child = rd_cfg_child_from_string(parent, string); + if(child == &rd_nil_cfg) + { + child = rd_cfg_new(parent, string); + } + return child; +} + +internal RD_Cfg * +rd_cfg_child_from_string_or_parent(RD_Cfg *parent, String8 string) +{ + RD_Cfg *result = rd_cfg_child_from_string(parent, string); + if(result == &rd_nil_cfg) + { + result = parent; + } + return result; +} + internal RD_CfgList rd_cfg_child_list_from_string(Arena *arena, RD_Cfg *parent, String8 string) { @@ -1168,6 +1841,20 @@ rd_cfg_top_level_list_from_string(Arena *arena, String8 string) return result; } +internal RD_CfgArray +rd_cfg_array_from_list(Arena *arena, RD_CfgList *list) +{ + RD_CfgArray array = {0}; + array.count = list->count; + array.v = push_array_no_zero(arena, RD_Cfg *, array.count); + U64 idx = 0; + for(RD_CfgNode *n = list->first; n != 0; n = n->next, idx += 1) + { + array.v[idx] = n->v; + } + return array; +} + internal RD_CfgList rd_cfg_tree_list_from_string(Arena *arena, String8 string) { @@ -1182,18 +1869,20 @@ rd_cfg_tree_list_from_string(Arena *arena, String8 string) for(MD_Node *src_n = tln; !md_node_is_nil(src_n); src_n = rec.next) { RD_Cfg *dst_n = rd_cfg_alloc(); - rd_cfg_equip_string(dst_n, src_n->string); + String8 src_n_string = src_n->string; + String8 src_n_string__raw = raw_from_escaped_str8(scratch.arena, src_n_string); + rd_cfg_equip_string(dst_n, src_n_string__raw); if(dst_active_parent_n != &rd_nil_cfg) { rd_cfg_insert_child(dst_active_parent_n, dst_active_parent_n->last, dst_n); } rec = md_node_rec_depth_first_pre(src_n, tln); + if(dst_active_parent_n == &rd_nil_cfg) + { + dst_root_n = dst_n; + } if(rec.push_count > 0) { - if(dst_active_parent_n == &rd_nil_cfg) - { - dst_root_n = dst_n; - } dst_active_parent_n = dst_n; } else for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) @@ -1348,261 +2037,508 @@ rd_cfg_list_push(Arena *arena, RD_CfgList *list, RD_Cfg *cfg) { RD_CfgNode *n = push_array(arena, RD_CfgNode, 1); n->v = cfg; - SLLQueuePush(list->first, list->last, n); + DLLPushBack(list->first, list->last, n); list->count += 1; } -//////////////////////////////// -//~ rjf: Entity State Functions - -//- rjf: entity allocation + tree forming - -internal RD_Entity * -rd_entity_alloc(RD_Entity *parent, RD_EntityKind kind) +internal void +rd_cfg_list_push_front(Arena *arena, RD_CfgList *list, RD_Cfg *cfg) { - B32 user_defined_lifetime = !!(rd_entity_kind_flags_table[kind] & RD_EntityKindFlag_UserDefinedLifetime); - U64 free_list_idx = !!user_defined_lifetime; - if(rd_entity_is_nil(parent)) { parent = rd_state->entities_root; } - - // rjf: empty free list -> push new - if(!rd_state->entities_free[free_list_idx]) + RD_CfgNode *n = push_array(arena, RD_CfgNode, 1); + n->v = cfg; + if(list->first != 0) { - RD_Entity *entity = push_array(rd_state->entities_arena, RD_Entity, 1); - rd_state->entities_count += 1; - rd_state->entities_free_count += 1; - SLLStackPush(rd_state->entities_free[free_list_idx], entity); - } - - // rjf: pop new entity off free-list - RD_Entity *entity = rd_state->entities_free[free_list_idx]; - SLLStackPop(rd_state->entities_free[free_list_idx]); - rd_state->entities_free_count -= 1; - rd_state->entities_active_count += 1; - - // rjf: zero entity - { - U64 gen = entity->gen; - MemoryZeroStruct(entity); - entity->gen = gen; - } - - // rjf: set up alloc'd entity links - entity->first = entity->last = entity->next = entity->prev = entity->parent = &rd_nil_entity; - entity->parent = parent; - - // rjf: stitch up parent links - if(rd_entity_is_nil(parent)) - { - rd_state->entities_root = entity; + n->next = list->first; } else { - DLLPushBack_NPZ(&rd_nil_entity, parent->first, parent->last, entity, next, prev); + list->last = n; } - - // rjf: fill out metadata - entity->kind = kind; - rd_state->entities_id_gen += 1; - entity->id = rd_state->entities_id_gen; - entity->gen += 1; - entity->alloc_time_us = os_now_microseconds(); - - // rjf: initialize to deleted, record history, then "undelete" if this allocation can be undone - if(user_defined_lifetime) - { - // TODO(rjf) - } - - // rjf: dirtify caches - rd_state->kind_alloc_gens[kind] += 1; - - // rjf: log - LogInfoNamedBlockF("new_entity") - { - log_infof("kind: \"%S\"\n", d_entity_kind_display_string_table[kind]); - log_infof("id: $0x%I64x\n", entity->id); - } - - return entity; + list->first = n; + list->count += 1; } -internal void -rd_entity_mark_for_deletion(RD_Entity *entity) +internal RD_PanelTree +rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) { - if(!rd_entity_is_nil(entity)) + Temp scratch = scratch_begin(&arena, 1); + RD_Cfg *wcfg = rd_window_from_cfg(cfg); + RD_Cfg *src_root = rd_cfg_child_from_string(wcfg, str8_lit("panels")); + RD_PanelNode *dst_root = &rd_nil_panel_node; + RD_PanelNode *dst_focused = &rd_nil_panel_node; { - entity->flags |= RD_EntityFlag_MarkedForDeletion; - rd_state->kind_alloc_gens[entity->kind] += 1; + Axis2 active_split_axis = rd_cfg_child_from_string(wcfg, str8_lit("split_x")) != &rd_nil_cfg ? Axis2_X : Axis2_Y; + RD_CfgRec rec = {0}; + RD_PanelNode *dst_active_parent = &rd_nil_panel_node; + for(RD_Cfg *src = src_root; src != &rd_nil_cfg; src = rec.next) + { + // rjf: build a panel node + RD_PanelNode *dst = push_array(arena, RD_PanelNode, 1); + MemoryCopyStruct(dst, &rd_nil_panel_node); + dst->parent = dst_active_parent; + if(dst_active_parent != &rd_nil_panel_node) + { + DLLPushBack_NPZ(&rd_nil_panel_node, dst_active_parent->first, dst_active_parent->last, dst, next, prev); + dst_active_parent->child_count += 1; + } + if(dst_root == &rd_nil_panel_node) + { + dst_root = dst; + } + + // rjf: extract cfg info + B32 panel_has_children = 0; + dst->cfg = src; + dst->pct_of_parent = (src == src_root ? 1.f : (F32)f64_from_str8(src->string)); + dst->tab_side = (rd_cfg_child_from_string(src, str8_lit("tabs_on_bottom")) != &rd_nil_cfg ? Side_Max : Side_Min); + dst->split_axis = active_split_axis; + for(RD_Cfg *src_child = src->first; src_child != &rd_nil_cfg; src_child = src_child->next) + { + MD_TokenizeResult tokenize = md_tokenize_from_text(scratch.arena, src_child->string); + if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Numeric) + { + panel_has_children = 1; + } + else if(str8_match(src_child->string, str8_lit("tabs_on_bottom"), 0)) + { + // NOTE(rjf): skip - this is a panel option. + } + else if(str8_match(src_child->string, str8_lit("selected"), 0)) + { + dst_focused = dst; + } + else if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Identifier) + { + rd_cfg_list_push(arena, &dst->tabs, src_child); + if(rd_cfg_child_from_string(src_child, str8_lit("selected")) != &rd_nil_cfg) + { + dst->selected_tab = src_child; + } + } + } + + // rjf: recurse + rec = rd_cfg_rec__depth_first(src_root, src); + if(!panel_has_children) + { + MemoryZeroStruct(&rec); + rec.next = &rd_nil_cfg; + for(RD_Cfg *p = src; p != src_root && p != &rd_nil_cfg; p = p->parent, rec.pop_count += 1) + { + if(p->next != &rd_nil_cfg) + { + rec.next = p->next; + break; + } + } + } + if(rec.push_count > 0) + { + dst_active_parent = dst; + active_split_axis = axis2_flip(active_split_axis); + } + else for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) + { + dst_active_parent = dst_active_parent->parent; + active_split_axis = axis2_flip(active_split_axis); + } + } } + scratch_end(scratch); + RD_PanelTree tree = {dst_root, dst_focused}; + return tree; } -internal void -rd_entity_release(RD_Entity *entity) +internal RD_PanelNodeRec +rd_panel_node_rec__depth_first(RD_PanelNode *root, RD_PanelNode *panel, U64 sib_off, U64 child_off) +{ + RD_PanelNodeRec rec = {&rd_nil_panel_node}; + if(*MemberFromOffset(RD_PanelNode **, panel, child_off) != &rd_nil_panel_node) + { + rec.next = *MemberFromOffset(RD_PanelNode **, panel, child_off); + rec.push_count += 1; + } + else for(RD_PanelNode *p = panel; p != &rd_nil_panel_node && p != root; p = p->parent, rec.pop_count += 1) + { + if(*MemberFromOffset(RD_PanelNode **, p, sib_off) != &rd_nil_panel_node) + { + rec.next = *MemberFromOffset(RD_PanelNode **, p, sib_off); + break; + } + } + return rec; +} + +internal RD_PanelNode * +rd_panel_node_from_tree_cfg(RD_PanelNode *root, RD_Cfg *cfg) +{ + RD_PanelNode *result = &rd_nil_panel_node; + for(RD_PanelNode *p = root; + p != &rd_nil_panel_node; + p = rd_panel_node_rec__depth_first_pre(root, p).next) + { + if(p->cfg == cfg) + { + result = p; + break; + } + } + return result; +} + +internal Rng2F32 +rd_target_rect_from_panel_node_child(Rng2F32 parent_rect, RD_PanelNode *parent, RD_PanelNode *panel) +{ + Rng2F32 rect = parent_rect; + if(parent != &rd_nil_panel_node) + { + Vec2F32 parent_rect_size = dim_2f32(parent_rect); + Axis2 axis = parent->split_axis; + rect.p1.v[axis] = rect.p0.v[axis]; + for(RD_PanelNode *child = parent->first; child != &rd_nil_panel_node; child = child->next) + { + rect.p1.v[axis] += parent_rect_size.v[axis] * child->pct_of_parent; + if(child == panel) + { + break; + } + rect.p0.v[axis] = rect.p1.v[axis]; + } + //rect.p0.v[axis] += parent_rect_size.v[axis] * panel->off_pct_of_parent.v[axis]; + //rect.p0.v[axis2_flip(axis)] += parent_rect_size.v[axis2_flip(axis)] * panel->off_pct_of_parent.v[axis2_flip(axis)]; + } + rect.x0 = round_f32(rect.x0); + rect.x1 = round_f32(rect.x1); + rect.y0 = round_f32(rect.y0); + rect.y1 = round_f32(rect.y1); + return rect; +} + +internal Rng2F32 +rd_target_rect_from_panel_node(Rng2F32 root_rect, RD_PanelNode *root, RD_PanelNode *panel) { Temp scratch = scratch_begin(0, 0); - // rjf: unpack - U64 free_list_idx = !!(rd_entity_kind_flags_table[entity->kind] & RD_EntityKindFlag_UserDefinedLifetime); - - // rjf: release whole tree - typedef struct Task Task; - struct Task + // rjf: count ancestors + U64 ancestor_count = 0; + for(RD_PanelNode *p = panel->parent; p != &rd_nil_panel_node; p = p->parent) { - Task *next; - RD_Entity *e; - }; - Task start_task = {0, entity}; - Task *first_task = &start_task; - Task *last_task = &start_task; - for(Task *task = first_task; task != 0; task = task->next) - { - for(RD_Entity *child = task->e->first; !rd_entity_is_nil(child); child = child->next) - { - Task *t = push_array(scratch.arena, Task, 1); - t->e = child; - SLLQueuePush(first_task, last_task, t); - } - LogInfoNamedBlockF("end_entity") - { - log_infof("kind: \"%S\"\n", d_entity_kind_display_string_table[task->e->kind]); - log_infof("id: $0x%I64x\n", task->e->id); - } - SLLStackPush(rd_state->entities_free[free_list_idx], task->e); - rd_state->entities_free_count += 1; - rd_state->entities_active_count -= 1; - task->e->gen += 1; - if(task->e->string.size != 0) - { - rd_name_release(task->e->string); - } - rd_state->kind_alloc_gens[task->e->kind] += 1; + ancestor_count += 1; } + // rjf: gather ancestors + RD_PanelNode **ancestors = push_array(scratch.arena, RD_PanelNode *, ancestor_count); + { + U64 ancestor_idx = 0; + for(RD_PanelNode *p = panel->parent; p != &rd_nil_panel_node; p = p->parent) + { + ancestors[ancestor_idx] = p; + ancestor_idx += 1; + } + } + + // rjf: go from highest ancestor => panel and calculate rect + Rng2F32 parent_rect = root_rect; + for(S64 ancestor_idx = (S64)ancestor_count-1; + 0 <= ancestor_idx && ancestor_idx < ancestor_count; + ancestor_idx -= 1) + { + RD_PanelNode *ancestor = ancestors[ancestor_idx]; + RD_PanelNode *parent = ancestor->parent; + if(parent != &rd_nil_panel_node) + { + parent_rect = rd_target_rect_from_panel_node_child(parent_rect, parent, ancestor); + } + } + + // rjf: calculate final rect + Rng2F32 rect = rd_target_rect_from_panel_node_child(parent_rect, panel->parent, panel); + scratch_end(scratch); + return rect; } -internal void -rd_entity_change_parent(RD_Entity *entity, RD_Entity *old_parent, RD_Entity *new_parent, RD_Entity *prev_child) +internal B32 +rd_cfg_is_project_filtered(RD_Cfg *cfg) { - Assert(entity->parent == old_parent); - Assert(prev_child->parent == old_parent || rd_entity_is_nil(prev_child)); - if(prev_child != entity) + RD_Cfg *project = rd_cfg_child_from_string(cfg, str8_lit("project")); + B32 result = (project != &rd_nil_cfg && !path_match_normalized(rd_state->project_path, project->first->string)); + return result; +} + +internal RD_KeyMapNodePtrList +rd_key_map_node_ptr_list_from_name(Arena *arena, String8 string) +{ + RD_KeyMapNodePtrList list = {0}; { - // rjf: fix up links - if(!rd_entity_is_nil(old_parent)) + U64 hash = d_hash_from_string(string); + U64 slot_idx = hash%rd_state->key_map->name_slots_count; + for(RD_KeyMapNode *n = rd_state->key_map->name_slots[slot_idx].first; n != 0; n = n->name_hash_next) { - DLLRemove_NPZ(&rd_nil_entity, old_parent->first, old_parent->last, entity, next, prev); + if(str8_match(n->name, string, 0)) + { + RD_KeyMapNodePtr *ptr = push_array(arena, RD_KeyMapNodePtr, 1); + ptr->v = n; + SLLQueuePush(list.first, list.last, ptr); + list.count += 1; + } } - if(!rd_entity_is_nil(new_parent)) + } + return list; +} + +internal RD_KeyMapNodePtrList +rd_key_map_node_ptr_list_from_binding(Arena *arena, RD_Binding binding) +{ + RD_KeyMapNodePtrList list = {0}; + { + U64 hash = d_hash_from_string(str8_struct(&binding)); + U64 slot_idx = hash%rd_state->key_map->binding_slots_count; + for(RD_KeyMapNode *n = rd_state->key_map->binding_slots[slot_idx].first; n != 0; n = n->binding_hash_next) { - DLLInsert_NPZ(&rd_nil_entity, new_parent->first, new_parent->last, prev_child, entity, next, prev); + if(MemoryMatchStruct(&binding, &n->binding)) + { + RD_KeyMapNodePtr *ptr = push_array(arena, RD_KeyMapNodePtr, 1); + ptr->v = n; + SLLQueuePush(list.first, list.last, ptr); + list.count += 1; + } } - entity->parent = new_parent; + } + return list; +} + +internal Vec4F32 +rd_hsva_from_cfg(RD_Cfg *cfg) +{ + Vec4F32 hsva = {0}; + RD_Cfg *hsva_root = rd_cfg_child_from_string(cfg, str8_lit("hsva")); + RD_Cfg *h = hsva_root->first; + RD_Cfg *s = h->next; + RD_Cfg *v = s->next; + RD_Cfg *a = v->next; + hsva.x = (F32)f64_from_str8(h->string); + hsva.y = (F32)f64_from_str8(s->string); + hsva.z = (F32)f64_from_str8(v->string); + hsva.w = (F32)f64_from_str8(a->string); + return hsva; +} + +internal Vec4F32 +rd_color_from_cfg(RD_Cfg *cfg) +{ + Vec4F32 hsva = rd_hsva_from_cfg(cfg); + Vec4F32 rgba = linear_from_srgba(rgba_from_hsva(hsva)); + return rgba; +} + +internal B32 +rd_disabled_from_cfg(RD_Cfg *cfg) +{ + MD_Node *schema = rd_schema_from_name(cfg->string); + MD_Node *enabled_schema = md_child_from_string(schema, str8_lit("enabled"), 0); + MD_Node *default_tag = md_tag_from_string(enabled_schema, str8_lit("default"), 0); + String8 value_string = rd_cfg_child_from_string(cfg, str8_lit("enabled"))->first->string; + if(value_string.size == 0) + { + value_string = default_tag->first->string; + } + B32 is_enabled = (str8_match(value_string, str8_lit("1"), 0)); + B32 is_disabled = !is_enabled; + if(value_string.size == 0) + { + is_disabled = 0; + } + return is_disabled; +} + +internal RD_Location +rd_location_from_cfg(RD_Cfg *cfg) +{ + RD_Location dst_loc = {0}; + { + RD_Cfg *src_loc = rd_cfg_child_from_string(cfg, str8_lit("source_location")); + RD_Cfg *addr_loc = rd_cfg_child_from_string(cfg, str8_lit("address_location")); + if(src_loc != &rd_nil_cfg) + { + dst_loc.file_path = src_loc->first->string; + try_s64_from_str8_c_rules(src_loc->first->first->string, &dst_loc.pt.line); + if(!try_s64_from_str8_c_rules(src_loc->first->first->first->string, &dst_loc.pt.column)) + { + dst_loc.pt.column = 1; + } + } + else if(addr_loc != &rd_nil_cfg) + { + dst_loc.expr = addr_loc->first->string; + } + } + return dst_loc; +} + +internal String8 +rd_label_from_cfg(RD_Cfg *cfg) +{ + RD_Cfg *label_root = rd_cfg_child_from_string(cfg, str8_lit("label")); + String8 result = label_root->first->string; + return result; +} + +internal String8 +rd_expr_from_cfg(RD_Cfg *cfg) +{ + RD_Cfg *expr_root = rd_cfg_child_from_string(cfg, str8_lit("expression")); + String8 result = expr_root->first->string; + return result; +} + +internal String8 +rd_view_rule_from_cfg(RD_Cfg *cfg) +{ + RD_Cfg *view_rule = rd_cfg_child_from_string(cfg, str8_lit("view_rule")); + String8 result = view_rule->first->string; + return result; +} + +internal String8 +rd_path_from_cfg(RD_Cfg *cfg) +{ + RD_Cfg *root = rd_cfg_child_from_string(cfg, str8_lit("path")); + String8 result = root->first->string; + return result; +} + +internal D_Target +rd_target_from_cfg(Arena *arena, RD_Cfg *cfg) +{ + D_Target target = {0}; + target.exe = rd_cfg_child_from_string(cfg, str8_lit("executable"))->first->string; + target.args = rd_cfg_child_from_string(cfg, str8_lit("arguments"))->first->string; + target.working_directory = rd_cfg_child_from_string(cfg, str8_lit("working_directory"))->first->string; + target.custom_entry_point_name = rd_cfg_child_from_string(cfg, str8_lit("entry_point"))->first->string; + target.stdout_path = rd_cfg_child_from_string(cfg, str8_lit("stdout_path"))->first->string; + target.stderr_path = rd_cfg_child_from_string(cfg, str8_lit("stderr_path"))->first->string; + target.stdin_path = rd_cfg_child_from_string(cfg, str8_lit("stdin_path"))->first->string; + target.debug_subprocesses = (rd_cfg_child_from_string(cfg, str8_lit("debug_subprocesses")) != &rd_nil_cfg); + for(RD_Cfg *child = cfg->first; child != &rd_nil_cfg; child = child->next) + { + if(str8_match(child->string, str8_lit("environment"), 0)) + { + str8_list_push(arena, &target.env, child->first->string); + } + } + return target; +} + +internal MD_Node * +rd_schema_from_name(String8 name) +{ + MD_Node *schema = &md_nil_node; + for EachElement(idx, rd_name_schema_info_table) + { + if(str8_match(name, rd_name_schema_info_table[idx].name, 0)) + { + schema = rd_state->schemas[idx]; + break; + } + } + return schema; +} + +internal String8 +rd_setting_from_name(String8 name) +{ + String8 result = {0}; + { + // rjf: find most-granular config scope to begin looking for the setting + RD_Cfg *view_cfg = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *start_cfg = view_cfg; + for(RD_Cfg *p = start_cfg->parent; p != &rd_nil_cfg; p = p->parent) + { + if(str8_match(p->string, str8_lit("transient"), 0)) + { + start_cfg = &rd_nil_cfg; + break; + } + } + if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_id(rd_regs()->panel); } + if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_id(rd_regs()->window); } - // rjf: notify - rd_state->kind_alloc_gens[entity->kind] += 1; + // rjf: scan upwards the config tree until we find the setting + RD_Cfg *setting = rd_cfg_child_from_string(view_cfg, name); + for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && setting == &rd_nil_cfg; cfg = cfg->parent) + { + setting = rd_cfg_child_from_string(cfg, name); + } + + // rjf: return resultant child string stored under this key + result = setting->first->string; + + // rjf: no result -> look for default in settings + if(result.size == 0) ProfScope("default setting schema lookup") + { + Temp scratch = scratch_begin(0, 0); + String8 schema_names[] = + { + view_cfg->string, + str8_lit("settings"), + }; + for EachElement(idx, schema_names) + { + MD_Node *schema = rd_schema_from_name(schema_names[idx]); + MD_Node *setting = md_child_from_string(schema, name, 0); + MD_Node *default_tag = md_tag_from_string(setting, str8_lit("default"), 0); + if(default_tag != &md_nil_node) + { + result = default_tag->first->string; + break; + } + } + scratch_end(scratch); + } } + return result; } -internal RD_Entity * -rd_entity_child_from_kind_or_alloc(RD_Entity *entity, RD_EntityKind kind) +internal RD_Cfg * +rd_immediate_cfg_from_key(String8 string) { - RD_Entity *child = rd_entity_child_from_kind(entity, kind); - if(rd_entity_is_nil(child)) + RD_Cfg *transient = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); + RD_Cfg *immediate = &rd_nil_cfg; + RD_Cfg *cfg = &rd_nil_cfg; + for(RD_Cfg *child = transient->first; child != &rd_nil_cfg; child = child->next) { - child = rd_entity_alloc(entity, kind); + if(str8_match(child->string, str8_lit("immediate"), 0)) + { + cfg = rd_cfg_child_from_string(child, string); + if(cfg != &rd_nil_cfg) + { + immediate = child; + break; + } + } } - return child; -} - -//- rjf: entity simple equipment - -internal void -rd_entity_equip_txt_pt(RD_Entity *entity, TxtPt point) -{ - rd_require_entity_nonnil(entity, return); - entity->text_point = point; - entity->flags |= RD_EntityFlag_HasTextPoint; -} - -internal void -rd_entity_equip_disabled(RD_Entity *entity, B32 value) -{ - rd_require_entity_nonnil(entity, return); - entity->disabled = value; -} - -internal void -rd_entity_equip_u64(RD_Entity *entity, U64 u64) -{ - rd_require_entity_nonnil(entity, return); - entity->u64 = u64; - entity->flags |= RD_EntityFlag_HasU64; -} - -internal void -rd_entity_equip_color_rgba(RD_Entity *entity, Vec4F32 rgba) -{ - rd_require_entity_nonnil(entity, return); - Vec3F32 rgb = v3f32(rgba.x, rgba.y, rgba.z); - Vec3F32 hsv = hsv_from_rgb(rgb); - Vec4F32 hsva = v4f32(hsv.x, hsv.y, hsv.z, rgba.w); - rd_entity_equip_color_hsva(entity, hsva); -} - -internal void -rd_entity_equip_color_hsva(RD_Entity *entity, Vec4F32 hsva) -{ - rd_require_entity_nonnil(entity, return); - entity->color_hsva = hsva; - entity->flags |= RD_EntityFlag_HasColor; -} - -internal void -rd_entity_equip_cfg_src(RD_Entity *entity, RD_CfgSrc cfg_src) -{ - rd_require_entity_nonnil(entity, return); - entity->cfg_src = cfg_src; -} - -internal void -rd_entity_equip_timestamp(RD_Entity *entity, U64 timestamp) -{ - rd_require_entity_nonnil(entity, return); - entity->timestamp = timestamp; -} - -//- rjf: control layer correllation equipment - -internal void -rd_entity_equip_vaddr(RD_Entity *entity, U64 vaddr) -{ - rd_require_entity_nonnil(entity, return); - entity->vaddr = vaddr; - entity->flags |= RD_EntityFlag_HasVAddr; -} - -//- rjf: name equipment - -internal void -rd_entity_equip_name(RD_Entity *entity, String8 name) -{ - rd_require_entity_nonnil(entity, return); - if(entity->string.size != 0) + if(cfg == &rd_nil_cfg) { - rd_name_release(entity->string); - } - if(name.size != 0) - { - entity->string = rd_name_alloc(name); - } - else - { - entity->string = str8_zero(); + immediate = rd_cfg_new(transient, str8_lit("immediate")); + cfg = rd_cfg_new(immediate, string); } + rd_cfg_new(immediate, str8_lit("hot")); + return cfg; } -//- rjf: file path map override lookups +internal RD_Cfg * +rd_immediate_cfg_from_keyf(char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 key = push_str8fv(scratch.arena, fmt, args); + RD_Cfg *result = rd_immediate_cfg_from_key(key); + va_end(args); + scratch_end(scratch); + return result; +} internal String8 rd_mapped_from_file_path(Arena *arena, String8 file_path) @@ -1613,13 +2549,13 @@ rd_mapped_from_file_path(Arena *arena, String8 file_path) { String8 file_path__normalized = path_normalized_from_string(scratch.arena, file_path); String8List file_path_parts = str8_split_path(scratch.arena, file_path__normalized); - RD_EntityList maps = rd_query_cached_entity_list_with_kind(RD_EntityKind_FilePathMap); + RD_CfgList maps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("file_path_map")); String8 best_map_dst = {0}; U64 best_map_match_length = max_U64; String8Node *best_map_remaining_suffix_first = 0; - for(RD_EntityNode *n = maps.first; n != 0; n = n->next) + for(RD_CfgNode *n = maps.first; n != 0; n = n->next) { - String8 map_src = rd_entity_child_from_kind(n->entity, RD_EntityKind_Source)->string; + String8 map_src = rd_cfg_child_from_string(n->v, str8_lit("source"))->first->string; String8 map_src__normalized = path_normalized_from_string(scratch.arena, map_src); String8List map_src_parts = str8_split_path(scratch.arena, map_src__normalized); B32 matches = 1; @@ -1639,7 +2575,7 @@ rd_mapped_from_file_path(Arena *arena, String8 file_path) if(matches && match_length < best_map_match_length) { best_map_match_length = match_length; - best_map_dst = rd_entity_child_from_kind(n->entity, RD_EntityKind_Dest)->string; + best_map_dst = rd_cfg_child_from_string(n->v, str8_lit("dest"))->first->string; best_map_remaining_suffix_first = file_path_part_n; } } @@ -1684,17 +2620,17 @@ rd_possible_overrides_from_file_path(Arena *arena, String8 file_path) PathStyle pth_style = PathStyle_Relative; String8List pth_parts = path_normalized_list_from_string(scratch.arena, file_path, &pth_style); { - RD_EntityList links = rd_query_cached_entity_list_with_kind(RD_EntityKind_FilePathMap); - for(RD_EntityNode *n = links.first; n != 0; n = n->next) + RD_CfgList links = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("file_path_map")); + for(RD_CfgNode *n = links.first; n != 0; n = n->next) { //- rjf: unpack link - RD_Entity *link = n->entity; - RD_Entity *src = rd_entity_child_from_kind(link, RD_EntityKind_Source); - RD_Entity *dst = rd_entity_child_from_kind(link, RD_EntityKind_Dest); + RD_Cfg *link = n->v; + RD_Cfg *src = rd_cfg_child_from_string(link, str8_lit("source")); + RD_Cfg *dst = rd_cfg_child_from_string(link, str8_lit("dest")); PathStyle src_style = PathStyle_Relative; PathStyle dst_style = PathStyle_Relative; - String8List src_parts = path_normalized_list_from_string(scratch.arena, src->string, &src_style); - String8List dst_parts = path_normalized_list_from_string(scratch.arena, dst->string, &dst_style); + String8List src_parts = path_normalized_list_from_string(scratch.arena, src->first->string, &src_style); + String8List dst_parts = path_normalized_list_from_string(scratch.arena, dst->first->string, &dst_style); //- rjf: determine if this link can possibly redirect to the target file path B32 dst_redirects_to_pth = 0; @@ -1732,287 +2668,31 @@ rd_possible_overrides_from_file_path(Arena *arena, String8 file_path) } } } + scratch_end(scratch); return result; } -//- rjf: top-level state queries - -internal RD_Entity * -rd_entity_root(void) +internal E_Expr * +rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg) { - return rd_state->entities_root; -} - -internal RD_EntityList -rd_push_entity_list_with_kind(Arena *arena, RD_EntityKind kind) -{ - ProfBeginFunction(); - RD_EntityList result = {0}; - for(RD_Entity *entity = rd_state->entities_root; - !rd_entity_is_nil(entity); - entity = rd_entity_rec_depth_first_pre(entity, &rd_nil_entity).next) + E_Expr *expr = &e_expr_nil; { - if(entity->kind == kind && !(entity->flags & RD_EntityFlag_MarkedForDeletion)) - { - rd_entity_list_push(arena, &result, entity); - } + // TODO(rjf): @cfg } - ProfEnd(); - return result; -} - -internal RD_Entity * -rd_entity_from_id(RD_EntityID id) -{ - RD_Entity *result = &rd_nil_entity; - for(RD_Entity *e = rd_entity_root(); - !rd_entity_is_nil(e); - e = rd_entity_rec_depth_first_pre(e, &rd_nil_entity).next) - { - if(e->id == id) - { - result = e; - break; - } - } - return result; -} - -internal RD_Entity * -rd_entity_from_name_and_kind(String8 string, RD_EntityKind kind) -{ - RD_Entity *result = &rd_nil_entity; - RD_EntityList all_of_this_kind = rd_query_cached_entity_list_with_kind(kind); - for(RD_EntityNode *n = all_of_this_kind.first; n != 0; n = n->next) - { - if(str8_match(n->entity->string, string, 0)) - { - result = n->entity; - break; - } - } - return result; -} - -//////////////////////////////// -//~ rjf: Frontend Entity Info Extraction - -internal D_Target -rd_d_target_from_entity(RD_Entity *entity) -{ - RD_Entity *src_target_exe = rd_entity_child_from_kind(entity, RD_EntityKind_Executable); - RD_Entity *src_target_args = rd_entity_child_from_kind(entity, RD_EntityKind_Arguments); - RD_Entity *src_target_wdir = rd_entity_child_from_kind(entity, RD_EntityKind_WorkingDirectory); - RD_Entity *src_target_stdo = rd_entity_child_from_kind(entity, RD_EntityKind_StdoutPath); - RD_Entity *src_target_stde = rd_entity_child_from_kind(entity, RD_EntityKind_StderrPath); - RD_Entity *src_target_stdi = rd_entity_child_from_kind(entity, RD_EntityKind_StdinPath); - RD_Entity *src_target_entry = rd_entity_child_from_kind(entity, RD_EntityKind_EntryPoint); - D_Target target = {0}; - target.exe = src_target_exe->string; - target.args = src_target_args->string; - target.working_directory = src_target_wdir->string; - target.custom_entry_point_name = src_target_entry->string; - target.stdout_path = src_target_stdo->string; - target.stderr_path = src_target_stde->string; - target.stdin_path = src_target_stdi->string; - target.debug_subprocesses = entity->debug_subprocesses; - return target; -} - -internal DR_FancyStringList -rd_title_fstrs_from_entity(Arena *arena, RD_Entity *entity, Vec4F32 secondary_color, F32 size) -{ - DR_FancyStringList result = {0}; - RD_Entity *exe = rd_entity_child_from_kind(entity, RD_EntityKind_Executable); - RD_Entity *args = rd_entity_child_from_kind(entity, RD_EntityKind_Arguments); - RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location); - RD_Entity *cnd = rd_entity_child_from_kind(entity, RD_EntityKind_Condition); - RD_Entity *src = rd_entity_child_from_kind(entity, RD_EntityKind_Source); - RD_Entity *dst = rd_entity_child_from_kind(entity, RD_EntityKind_Dest); - RD_IconKind icon_kind = rd_entity_kind_icon_kind_table[entity->kind]; - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Text); - if(icon_kind != RD_IconKind_Null) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[icon_kind]); - } - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); - if(entity->kind == RD_EntityKind_Target && entity->cfg_src == RD_CfgSrc_CommandLine) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), rd_icon_kind_text_table[RD_IconKind_Info]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); - } - String8 name = entity->string; - B32 name_is_code = 1; - if(rd_entity_kind_flags_table[entity->kind] & RD_EntityKindFlag_NameIsPath) - { - name_is_code = 0; - } - String8 location = {0}; - B32 location_is_code = 0; - String8 exe_name = str8_skip_last_slash(exe->string); - String8 args_string = args->string; - String8 cnd_string = cnd->string; - if(!rd_entity_is_nil(loc)) - { - if(loc->string.size != 0 && loc->flags & RD_EntityFlag_HasTextPoint) - { - location = push_str8f(arena, "%S:%I64d:%I64d", loc->string, loc->text_point.line, loc->text_point.column); - location_is_code = 0; - } - else if(loc->string.size != 0) - { - location = loc->string; - location_is_code = 1; - } - else if(loc->flags & RD_EntityFlag_HasVAddr) - { - location = push_str8f(arena, "0x%I64x", loc->vaddr); - location_is_code = 1; - } - } - B32 extra = 0; - F32 size_extrafied = size; - Vec4F32 color_extrafied = color; - if(name.size != 0) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), size, color, name); - extra = 1; - size_extrafied = size*0.95f; - color_extrafied = secondary_color; - } - if(location.size != 0) - { - if(extra) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - } - if(location_is_code) - { - DR_FancyStringList loc_fstrs = {0}; - RD_Font(RD_FontSlot_Code) - loc_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0, color_extrafied, location); - dr_fancy_string_list_concat_in_place(&result, &loc_fstrs); - } - else - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size_extrafied, color_extrafied, location); - } - extra = 1; - size_extrafied = size*0.95f; - color_extrafied = secondary_color; - } - if(exe_name.size != 0) - { - if(extra) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - } - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size_extrafied, color_extrafied, exe_name); - extra = 1; - size_extrafied = size*0.95f; - color_extrafied = secondary_color; - } - if(args_string.size != 0) - { - if(extra) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - } - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size_extrafied, color_extrafied, args_string); - extra = 1; - size_extrafied = size*0.95f; - color_extrafied = secondary_color; - } - if(cnd_string.size != 0) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, color_extrafied, str8_lit(" if ")); - RD_Font(RD_FontSlot_Code) UI_FontSize(size_extrafied) - { - DR_FancyStringList cnd_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0.f, color_extrafied, cnd_string); - dr_fancy_string_list_concat_in_place(&result, &cnd_fstrs); - } - } - if(entity->kind == RD_EntityKind_FilePathMap) - { - String8 src_string = src->string; - Vec4F32 src_color = color; - String8 dst_string = dst->string; - Vec4F32 dst_color = color; - if(src_string.size == 0) - { - src_string = str8_lit("(source path)"); - src_color = secondary_color; - } - if(dst_string.size == 0) - { - dst_string = str8_lit("(destination path)"); - dst_color = secondary_color; - } - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size, src_color, src_string); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[RD_IconKind_RightArrow]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size, dst_color, dst_string); - } - if(entity->kind == RD_EntityKind_AutoViewRule) - { - String8 src_string = src->string; - Vec4F32 src_color = color; - String8 dst_string = dst->string; - Vec4F32 dst_color = color; - DR_FancyStringList src_fstrs = {0}; - DR_FancyStringList dst_fstrs = {0}; - if(src_string.size == 0) - { - src_string = str8_lit("(type)"); - src_color = secondary_color; - dr_fancy_string_list_push_new(arena, &src_fstrs, rd_font_from_slot(RD_FontSlot_Main), size, src_color, src_string); - } - else RD_Font(RD_FontSlot_Code) - { - src_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0, src_color, src_string); - } - if(dst_string.size == 0) - { - dst_string = str8_lit("(view rule)"); - dst_color = secondary_color; - dr_fancy_string_list_push_new(arena, &dst_fstrs, rd_font_from_slot(RD_FontSlot_Main), size, dst_color, dst_string); - } - else RD_Font(RD_FontSlot_Code) - { - dst_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0, dst_color, dst_string); - } - dr_fancy_string_list_concat_in_place(&result, &src_fstrs); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[RD_IconKind_RightArrow]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&result, &dst_fstrs); - } - if((entity->kind == RD_EntityKind_Target || entity->kind == RD_EntityKind_Breakpoint) && entity->disabled) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size*0.95f, secondary_color, str8_lit("(Disabled)")); - } - if(entity->kind == RD_EntityKind_Breakpoint) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - String8 string = push_str8f(arena, "(%I64u hit%s)", entity->u64, entity->u64 == 1 ? "" : "s"); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size_extrafied, secondary_color, string); - } - return result; + return expr; } //////////////////////////////// //~ rjf: Control Entity Info Extraction internal Vec4F32 -rd_rgba_from_ctrl_entity(CTRL_Entity *entity) +rd_color_from_ctrl_entity(CTRL_Entity *entity) { - Vec4F32 result = rd_rgba_from_theme_color(RD_ThemeColor_Text); + Vec4F32 result = {0}; if(entity->rgba != 0) { - result = rgba_from_u32(entity->rgba); + result = linear_from_srgba(rgba_from_u32(entity->rgba)); } if(entity->rgba == 0) switch(entity->kind) { @@ -2023,11 +2703,11 @@ rd_rgba_from_ctrl_entity(CTRL_Entity *entity) CTRL_Entity *main_thread = ctrl_entity_child_from_kind(process, CTRL_EntityKind_Thread); if(main_thread != entity) { - result = rd_rgba_from_theme_color(RD_ThemeColor_Thread1); + result = ui_color_from_name(str8_lit("thread_1")); } else { - result = rd_rgba_from_theme_color(RD_ThemeColor_Thread0); + result = ui_color_from_name(str8_lit("thread_0")); } }break; } @@ -2049,134 +2729,28 @@ rd_name_from_ctrl_entity(Arena *arena, CTRL_Entity *entity) return string; } -internal DR_FancyStringList -rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secondary_color, F32 size, B32 include_extras) -{ - DR_FancyStringList result = {0}; - - //- rjf: unpack entity info - F32 extras_size = size*0.95f; - Vec4F32 color = rd_rgba_from_ctrl_entity(entity); - String8 name = rd_name_from_ctrl_entity(arena, entity); - RD_IconKind icon_kind = RD_IconKind_Null; - B32 name_is_code = 0; - switch(entity->kind) - { - default:{}break; - case CTRL_EntityKind_Machine: {icon_kind = RD_IconKind_Machine;}break; - case CTRL_EntityKind_Process: {icon_kind = RD_IconKind_Threads;}break; - case CTRL_EntityKind_Thread: {icon_kind = RD_IconKind_Thread; name_is_code = 1;}break; - case CTRL_EntityKind_Module: {icon_kind = RD_IconKind_Module;}break; - } - - //- rjf: push icon - if(icon_kind != RD_IconKind_Null) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[icon_kind]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); - } - - //- rjf: push containing process prefix - if(entity->kind == CTRL_EntityKind_Thread || - entity->kind == CTRL_EntityKind_Module) - { - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); - if(processes.count > 1) - { - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); - String8 process_name = rd_name_from_ctrl_entity(arena, process); - Vec4F32 process_color = rd_rgba_from_ctrl_entity(process); - if(process_name.size != 0) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size, process_color, process_name); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" / ")); - } - } - } - - //- rjf: push name - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), size, color, name); - - //- rjf: threads get callstack extras - if(entity->kind == CTRL_EntityKind_Thread && include_extras) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); - DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); - Arch arch = entity->arch; - CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); - for(U64 idx = 0, limit = 6; idx < unwind.frames.count && idx < limit; idx += 1) - { - CTRL_UnwindFrame *f = &unwind.frames.v[unwind.frames.count - 1 - idx]; - U64 rip_vaddr = regs_rip_from_arch_block(arch, f->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); - U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); - if(rdi != &di_rdi_parsed_nil) - { - RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, rip_voff); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); - name = push_str8_copy(arena, name); - if(name.size != 0) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), extras_size, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); - if(idx+1 < unwind.frames.count) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), extras_size, secondary_color, str8_lit(" > ")); - if(idx+1 == limit) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), extras_size, secondary_color, str8_lit("...")); - } - } - } - } - } - di_scope_close(di_scope); - } - - //- rjf: modules get debug info status extras - if(entity->kind == CTRL_EntityKind_Module && include_extras) - { - DI_Scope *di_scope = di_scope_open(); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(entity); - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); - if(rdi->raw_data_size == 0) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), extras_size, secondary_color, str8_lit("(Symbols not found)")); - } - di_scope_close(di_scope); - } - - return result; -} - //////////////////////////////// //~ rjf: Evaluation Spaces -//- rjf: entity <-> eval space +//- rjf: cfg <-> eval space -internal RD_Entity * -rd_entity_from_eval_space(E_Space space) +internal RD_Cfg * +rd_cfg_from_eval_space(E_Space space) { - RD_Entity *entity = &rd_nil_entity; - if(space.kind == RD_EvalSpaceKind_MetaEntity) + RD_Cfg *cfg = &rd_nil_cfg; + if(space.kind == RD_EvalSpaceKind_MetaCfg) { - RD_Handle handle = {space.u64s[0], space.u64s[1]}; - entity = rd_entity_from_handle(handle); + RD_CfgID id = space.u64s[0]; + cfg = rd_cfg_from_id(id); } - return entity; + return cfg; } internal E_Space -rd_eval_space_from_entity(RD_Entity *entity) +rd_eval_space_from_cfg(RD_Cfg *cfg) { - E_Space space = e_space_make(RD_EvalSpaceKind_MetaEntity); - RD_Handle handle = rd_handle_from_entity(entity); - space.u64s[0] = handle.u64[0]; - space.u64s[1] = handle.u64[1]; + E_Space space = e_space_make(RD_EvalSpaceKind_MetaCfg); + space.u64s[0] = cfg->id; return space; } @@ -2187,7 +2761,8 @@ rd_ctrl_entity_from_eval_space(E_Space space) { CTRL_Entity *entity = &ctrl_entity_nil; if(space.kind == RD_EvalSpaceKind_CtrlEntity || - space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) { CTRL_Handle handle; handle.machine_id = space.u64s[0]; @@ -2206,119 +2781,6 @@ rd_eval_space_from_ctrl_entity(CTRL_Entity *entity, E_SpaceKind kind) return space; } -//- rjf: entity -> meta eval - -internal CTRL_MetaEval * -rd_ctrl_meta_eval_from_entity(Arena *arena, RD_Entity *entity) -{ - ProfBeginFunction(); - CTRL_MetaEval *meval = push_array(arena, CTRL_MetaEval, 1); - RD_Entity *exe = rd_entity_child_from_kind(entity, RD_EntityKind_Executable); - RD_Entity *args= rd_entity_child_from_kind(entity, RD_EntityKind_Arguments); - RD_Entity *wdir= rd_entity_child_from_kind(entity, RD_EntityKind_WorkingDirectory); - RD_Entity *entr= rd_entity_child_from_kind(entity, RD_EntityKind_EntryPoint); - RD_Entity *stdo= rd_entity_child_from_kind(entity, RD_EntityKind_StdoutPath); - RD_Entity *stde= rd_entity_child_from_kind(entity, RD_EntityKind_StderrPath); - RD_Entity *stdi= rd_entity_child_from_kind(entity, RD_EntityKind_StdinPath); - RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location); - RD_Entity *cnd = rd_entity_child_from_kind(entity, RD_EntityKind_Condition); - RD_Entity *src = rd_entity_child_from_kind(entity, RD_EntityKind_Source); - RD_Entity *dst = rd_entity_child_from_kind(entity, RD_EntityKind_Dest); - String8 label_string = push_str8_copy(arena, entity->string); - String8 src_loc_string = {0}; - String8 vaddr_loc_string = {0}; - String8 function_loc_string = {0}; - if(loc->flags & RD_EntityFlag_HasTextPoint) - { - src_loc_string = push_str8f(arena, "%S:%I64u:%I64u", loc->string, loc->text_point.line, loc->text_point.column); - } - else if(loc->flags & RD_EntityFlag_HasVAddr) - { - vaddr_loc_string = push_str8f(arena, "0x%I64x", loc->vaddr); - } - else if(loc->string.size != 0) - { - function_loc_string = push_str8_copy(arena, loc->string); - } - String8 cnd_string = push_str8_copy(arena, cnd->string); - meval->enabled = !entity->disabled; - meval->hit_count = entity->u64; - meval->color = u32_from_rgba(rd_rgba_from_entity(entity)); - meval->label = label_string; - meval->exe = exe->string; - meval->args = args->string; - meval->working_directory = wdir->string; - meval->entry_point = entr->string; - meval->stdout_path = stdo->string; - meval->stderr_path = stde->string; - meval->stdin_path = stdi->string; - meval->source_location = src_loc_string; - meval->address_location = vaddr_loc_string; - meval->function_location = function_loc_string; - meval->condition = cnd_string; - meval->debug_subprocesses.b32 = entity->debug_subprocesses; - switch(entity->kind) - { - default:{}break; - case RD_EntityKind_FilePathMap: - { - meval->source_path = src->string; - meval->destination_path = dst->string; - }break; - case RD_EntityKind_AutoViewRule: - { - meval->type = src->string; - meval->view_rule = dst->string; - }break; - } - ProfEnd(); - return meval; -} - -internal CTRL_MetaEval * -rd_ctrl_meta_eval_from_ctrl_entity(Arena *arena, CTRL_Entity *entity) -{ - ProfBeginFunction(); - CTRL_MetaEval *meval = push_array(arena, CTRL_MetaEval, 1); - meval->frozen = entity->is_frozen; - meval->vaddr_range = entity->vaddr_range; - meval->color = entity->rgba; - meval->label = entity->string; - meval->id = entity->id; - if(entity->kind == CTRL_EntityKind_Thread) - { - DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(arena, di_scope, process, &base_unwind); - meval->callstack.count = rich_unwind.total_frame_count; - meval->callstack.v = push_array(arena, CTRL_MetaEvalFrame, meval->callstack.count); - U64 idx = 0; - for(U64 base_idx = 0; base_idx < rich_unwind.concrete_frame_count; base_idx += 1) - { - U64 inline_idx = 0; - for(CTRL_CallStackInlineFrame *f = rich_unwind.frames[base_idx].first_inline_frame; f != 0; f = f->next, inline_idx += 1) - { - meval->callstack.v[idx].vaddr = regs_rip_from_arch_block(entity->arch, rich_unwind.frames[base_idx].regs); - meval->callstack.v[idx].inline_depth = inline_idx + 1; - idx += 1; - } - meval->callstack.v[idx].vaddr = regs_rip_from_arch_block(entity->arch, rich_unwind.frames[base_idx].regs); - idx += 1; - } - di_scope_close(di_scope); - } - if(entity->kind == CTRL_EntityKind_Module) - { - DI_Key dbgi_key = ctrl_dbgi_key_from_module(entity); - meval->label = str8_skip_last_slash(entity->string); - meval->exe = path_normalized_from_string(arena, entity->string); - meval->dbg = path_normalized_from_string(arena, dbgi_key.path); - } - ProfEnd(); - return meval; -} - //- rjf: eval space reads/writes internal B32 @@ -2326,12 +2788,10 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) { Temp scratch = scratch_begin(0, 0); B32 result = 0; - CTRL_MetaEval *meval_read = 0; - Rng1U64 meval_legal_range = {0}; switch(space.kind) { - //- rjf: filesystem reads - case E_SpaceKind_FileSystem: + //- rjf: reads from hash store key + case E_SpaceKind_HashStoreKey: { U128 key = space.u128; U128 hash = hs_hash_from_key(key, 0); @@ -2349,6 +2809,39 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) hs_scope_close(scope); }break; + //- rjf: file reads + case E_SpaceKind_File: + { + // rjf: unpack space/path + U64 file_path_string_id = space.u64_0; + String8 file_path = e_string_from_id(file_path_string_id); + + // rjf: find containing chunk range + U64 chunk_size = KB(4); + Rng1U64 containing_range = range; + containing_range.min -= containing_range.min%chunk_size; + containing_range.max += chunk_size-1; + containing_range.max -= containing_range.max%chunk_size; + + // rjf: map to hash + U128 key = fs_key_from_path_range(file_path, containing_range); + U128 hash = hs_hash_from_key(key, 0); + + // rjf: look up from hash store + HS_Scope *scope = hs_scope_open(); + { + String8 data = hs_data_from_hash(scope, hash); + Rng1U64 legal_range = r1u64(containing_range.min, containing_range.min + data.size); + Rng1U64 read_range = intersect_1u64(range, legal_range); + if(read_range.min < read_range.max) + { + result = 1; + MemoryCopy(out, data.str + read_range.min - containing_range.min, dim_1u64(read_range)); + } + } + hs_scope_close(scope); + }break; + //- rjf: interior control entity reads (inside process address space or thread register block) case RD_EvalSpaceKind_CtrlEntity: { @@ -2358,19 +2851,16 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) default:{}break; case CTRL_EntityKind_Process: { - Temp scratch = scratch_begin(0, 0); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, entity->handle, range, d_state->frame_eval_memread_endt_us); + CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, entity->handle, range, rd_state->frame_eval_memread_endt_us); String8 data = slice.data; if(data.size == dim_1u64(range)) { result = 1; MemoryCopy(out, data.str, data.size); } - scratch_end(scratch); }break; case CTRL_EntityKind_Thread: { - Temp scratch = scratch_begin(0, 0); CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); U64 frame_idx = e_interpret_ctx->reg_unwind_count; if(frame_idx < unwind.frames.count) @@ -2383,75 +2873,117 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) MemoryCopy(out, (U8 *)f->regs + read_range.min, read_size); result = (read_size == dim_1u64(range)); } - scratch_end(scratch); }break; } }break; - //- rjf: meta reads (metadata about either control entities or debugger state) - case RD_EvalSpaceKind_MetaCtrlEntity: + //- rjf: meta-config reads + case RD_EvalSpaceKind_MetaCfg: { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); - U64 hash = ctrl_hash_from_handle(entity->handle); - U64 slot_idx = hash%rd_state->ctrl_entity_meval_cache_slots_count; - RD_CtrlEntityMetaEvalCacheSlot *slot = &rd_state->ctrl_entity_meval_cache_slots[slot_idx]; - RD_CtrlEntityMetaEvalCacheNode *node = 0; - for(RD_CtrlEntityMetaEvalCacheNode *n = slot->first; n != 0; n = n->next) + // rjf: unpack cfg + RD_Cfg *root_cfg = rd_cfg_from_eval_space(space); + String8 child_key = e_string_from_id(space.u64s[1]); + RD_Cfg *cfg = root_cfg; + if(child_key.size != 0) { - if(ctrl_handle_match(n->handle, entity->handle)) + cfg = rd_cfg_child_from_string(root_cfg, child_key); + } + + // rjf: determine data to read from, depending on child type in schema + String8 read_data = {0}; + if(child_key.size != 0) + { + MD_Node *root_schema = rd_schema_from_name(root_cfg->string); + MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); + String8 child_type_name = child_schema->first->string; + if(str8_match(child_type_name, str8_lit("path_pt"), 0)) { - node = n; - break; + read_data = push_str8f(scratch.arena, "%S%s%S%s%S", cfg->first->string, cfg->first->string.size ? ":" : "", cfg->first->first->string, cfg->first->first->first->string.size ? ":" : "", cfg->first->first->first->string); + } + else if(str8_match(child_type_name, str8_lit("path"), 0) || + str8_match(child_type_name, str8_lit("code_string"), 0) || + str8_match(child_type_name, str8_lit("string"), 0)) + { + read_data = cfg->first->string; + } + else if(str8_match(child_type_name, str8_lit("bool"), 0)) + { + String8 value_string = cfg->first->string; + if(value_string.size == 0) + { + value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; + } + B32 value = str8_match(value_string, str8_lit("1"), 0); + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + } + else if(str8_match(child_type_name, str8_lit("u64"), 0)) + { + String8 value_string = cfg->first->string; + if(value_string.size == 0) + { + value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; + } + U64 value = 0; + try_u64_from_str8_c_rules(value_string, &value); + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); } } - if(!node) - { - CTRL_MetaEval *meval = rd_ctrl_meta_eval_from_ctrl_entity(scratch.arena, entity); - String8 meval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, meval); - U64 pos_min = arena_pos(rd_frame_arena()); - arena_push(rd_frame_arena(), 0, 64); - CTRL_MetaEval *meval_read = struct_from_serialized(rd_frame_arena(), CTRL_MetaEval, meval_srlzed); - struct_rebase_ptrs(CTRL_MetaEval, meval_read, meval_read); - U64 pos_opl = arena_pos(scratch.arena); - node = push_array(rd_frame_arena(), RD_CtrlEntityMetaEvalCacheNode, 1); - SLLQueuePush(slot->first, slot->last, node); - node->handle = entity->handle; - node->meval = meval_read; - node->range = r1u64(0, pos_opl-pos_min); - } - meval_read = node->meval; - meval_legal_range = node->range; - }goto meta_eval; - case RD_EvalSpaceKind_MetaEntity: - { - // rjf: calculate meta evaluation - CTRL_MetaEval *meval = rd_ctrl_meta_eval_from_entity(scratch.arena, rd_entity_from_eval_space(space)); - // rjf: copy meta evaluation to scratch arena, to form range of legal reads - arena_push(scratch.arena, 0, 64); - String8 meval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, meval); - U64 pos_min = arena_pos(scratch.arena); - meval_read = struct_from_serialized(scratch.arena, CTRL_MetaEval, meval_srlzed); - U64 pos_opl = arena_pos(scratch.arena); - - // rjf: rebase all pointer values in meta evaluation to be relative to base pointer - struct_rebase_ptrs(CTRL_MetaEval, meval_read, meval_read); - - // rjf: form legal range - meval_legal_range = r1u64(0, pos_opl-pos_min); - }goto meta_eval; - meta_eval:; - { - if(contains_1u64(meval_legal_range, range.min)) + // rjf: perform read + Rng1U64 legal_range = r1u64(0, read_data.size); + Rng1U64 read_range = intersect_1u64(range, legal_range); + if(read_range.min < read_range.max) { result = 1; - U64 range_dim = dim_1u64(range); - U64 bytes_to_read = Min(range_dim, (meval_legal_range.max - range.min)); - MemoryCopy(out, ((U8 *)meval_read) + range.min, bytes_to_read); - if(bytes_to_read < range_dim) + MemoryCopy(out, read_data.str + read_range.min, dim_1u64(read_range)); + } + }break; + + //- rjf: meta-entity reads + case RD_EvalSpaceKind_MetaCtrlEntity: + { + // rjf: unpack cfg + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); + String8 child_key = e_string_from_id(space.u64s[2]); + + // rjf: determine data to read from, depending on child name in schema + String8 read_data = {0}; + if(child_key.size != 0) + { + MD_Node *root_schema = rd_schema_from_name(ctrl_entity_kind_code_name_table[entity->kind]); + MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); + if(str8_match(child_schema->string, str8_lit("exe"), 0) || + str8_match(child_schema->string, str8_lit("label"), 0)) { - MemoryZero((U8 *)out + bytes_to_read, range_dim - bytes_to_read); + read_data = entity->string; } + else if(str8_match(child_schema->string, str8_lit("dbg"), 0)) + { + read_data = ctrl_entity_child_from_kind(entity, CTRL_EntityKind_DebugInfoPath)->string; + } + else if(str8_match(child_schema->string, str8_lit("vaddr_range"), 0)) + { + read_data = str8_struct(&entity->vaddr_range); + } + else if(str8_match(child_schema->string, str8_lit("id"), 0)) + { + read_data = str8_struct(&entity->id); + } + else if(str8_match(child_schema->string, str8_lit("active"), 0)) + { + B32 is_frozen = ctrl_entity_tree_is_frozen(entity); + B32 is_active = !is_frozen; + read_data = push_str8_copy(scratch.arena, str8_struct(&is_active)); + } + } + + // rjf: perform read + Rng1U64 legal_range = r1u64(0, read_data.size); + Rng1U64 read_range = intersect_1u64(range, legal_range); + if(read_range.min < read_range.max) + { + result = 1; + MemoryCopy(out, read_data.str + read_range.min, dim_1u64(read_range)); } }break; } @@ -2494,100 +3026,115 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) } }break; - //- rjf: meta-entity writes - case RD_EvalSpaceKind_MetaEntity: + //- rjf: meta-config writes + case RD_EvalSpaceKind_MetaCfg: { Temp scratch = scratch_begin(0, 0); - // rjf: get entity, produce meta-eval - RD_Entity *entity = rd_entity_from_eval_space(space); - CTRL_MetaEval *meval = rd_ctrl_meta_eval_from_entity(scratch.arena, entity); + // rjf: unpack write info + String8 write_string = str8_cstring_capped(in, (U8 *)in + dim_1u64(range)); - // rjf: copy meta evaluation to scratch arena, to form range of legal reads - arena_push(scratch.arena, 0, 64); - String8 meval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, meval); - U64 pos_min = arena_pos(scratch.arena); - CTRL_MetaEval *meval_read = struct_from_serialized(scratch.arena, CTRL_MetaEval, meval_srlzed); - U64 pos_opl = arena_pos(scratch.arena); - - // rjf: rebase all pointer values in meta evaluation to be relative to base pointer - struct_rebase_ptrs(CTRL_MetaEval, meval_read, meval_read); - - // rjf: perform write to entity - if(0){} -#define FlatMemberCase(name) else if(range.min == OffsetOf(CTRL_MetaEval, name) && dim_1u64(range) <= sizeof(meval_read->name)) -#define StringMemberCase(name) else if(range.min == (U64)meval_read->name.str) - FlatMemberCase(enabled) {result = 1; rd_entity_equip_disabled(entity, !!((U8 *)in)[0]);} - FlatMemberCase(debug_subprocesses) {result = 1; entity->debug_subprocesses = !!((U8 *)in)[0]; } - StringMemberCase(label) {result = 1; rd_entity_equip_name(entity, str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(exe) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Executable), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(args) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Arguments), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(working_directory) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_WorkingDirectory), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(entry_point) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_EntryPoint), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(stdout_path) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_StdoutPath), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(stderr_path) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_StderrPath), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(stdin_path) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_StdinPath), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(source_path) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Source), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(destination_path) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Dest), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(type) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Source), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(view_rule) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Dest), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(condition) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Condition), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(source_location) + // rjf: unpack cfg + RD_Cfg *root_cfg = rd_cfg_from_eval_space(space); + String8 child_key = e_string_from_id(space.u64s[1]); + RD_Cfg *cfg = root_cfg; + if(child_key.size != 0) { - result = 1; - String8TxtPtPair src_loc = str8_txt_pt_pair_from_string(str8_cstring_capped(in, (U8 *)in + 4096)); - RD_Entity *loc = rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Location); - rd_entity_equip_name(loc, src_loc.string); - rd_entity_equip_txt_pt(loc, src_loc.pt); + cfg = rd_cfg_child_from_string(root_cfg, child_key); } - StringMemberCase(address_location) + + // rjf: perform write, based on child type in schema + if(child_key.size != 0) { - U64 vaddr = 0; - if(try_u64_from_str8_c_rules(str8_cstring_capped(in, (U8 *)in + 4096), &vaddr)) + MD_Node *root_schema = rd_schema_from_name(root_cfg->string); + MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); + String8 child_type_name = child_schema->first->string; + if(str8_match(child_type_name, str8_lit("path_pt"), 0)) { - RD_Entity *loc = rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Location); - rd_entity_equip_vaddr(loc, vaddr); - rd_entity_equip_name(loc, str8_zero()); - loc->flags &= ~RD_EntityFlag_HasTextPoint; + result = 0; + } + else if(str8_match(child_type_name, str8_lit("path"), 0) || + str8_match(child_type_name, str8_lit("code_string"), 0) || + str8_match(child_type_name, str8_lit("string"), 0)) + { + RD_Cfg *child = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); + rd_cfg_new_replace(child, write_string); + result = 1; + } + else if(str8_match(child_type_name, str8_lit("bool"), 0)) + { + if(range.max == range.min) + { + rd_cfg_release(rd_cfg_child_from_string(root_cfg, child_key)); + } + else + { + U64 value = 0; + MemoryCopy(&value, in, dim_1u64(range)); + RD_Cfg *child = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); + rd_cfg_new_replacef(child, "%I64u", !!value); + } + result = 1; + } + else if(str8_match(child_type_name, str8_lit("u64"), 0)) + { + if(range.max == range.min) + { + rd_cfg_release(rd_cfg_child_from_string(root_cfg, child_key)); + } + else + { + U64 value = 0; + MemoryCopy(&value, in, dim_1u64(range)); + RD_Cfg *child = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); + rd_cfg_new_replacef(child, "%I64u", value); + } result = 1; } } - StringMemberCase(function_location) - { - result = 1; - RD_Entity *loc = rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Location); - loc->flags &= ~RD_EntityFlag_HasTextPoint; - rd_entity_equip_name(loc, str8_cstring_capped(in, (U8 *)in + 4096)); - } -#undef FlatMemberCase -#undef StringMemberCase + scratch_end(scratch); }break; + case RD_EvalSpaceKind_MetaCtrlEntity: { Temp scratch = scratch_begin(0, 0); - // rjf: get entity, produce meta-eval + // rjf: unpack write info + String8 write_string = str8_cstring_capped(in, (U8 *)in + dim_1u64(range)); + + // rjf: unpack cfg CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); - CTRL_MetaEval *meval = rd_ctrl_meta_eval_from_ctrl_entity(scratch.arena, entity); + String8 child_key = e_string_from_id(space.u64s[2]); - // rjf: copy meta evaluation to scratch arena, to form range of legal reads - arena_push(scratch.arena, 0, 64); - String8 meval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, meval); - U64 pos_min = arena_pos(scratch.arena); - CTRL_MetaEval *meval_read = struct_from_serialized(scratch.arena, CTRL_MetaEval, meval_srlzed); - U64 pos_opl = arena_pos(scratch.arena); + // rjf: perform write, based on child name in schema + if(child_key.size != 0) + { + MD_Node *root_schema = rd_schema_from_name(ctrl_entity_kind_code_name_table[entity->kind]); + MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); + if(str8_match(child_schema->string, str8_lit("label"), 0)) + { + rd_cmd(D_CmdKind_SetEntityName, .ctrl_entity = entity->handle, .string = write_string); + } + else if(str8_match(child_schema->string, str8_lit("dbg"), 0)) + { + // TODO(rjf) + } + else if(str8_match(child_schema->string, str8_lit("active"), 0)) + { + B32 new_active = 0; + MemoryCopy(&new_active, in, dim_1u64(range)); + if(!new_active) + { + rd_cmd(D_CmdKind_FreezeEntity, .ctrl_entity = entity->handle); + } + else + { + rd_cmd(D_CmdKind_ThawEntity, .ctrl_entity = entity->handle); + } + } + } - // rjf: rebase all pointer values in meta evaluation to be relative to base pointer - struct_rebase_ptrs(CTRL_MetaEval, meval_read, meval_read); - - // rjf: perform write to entity - if(0){} -#define FlatMemberCase(name) else if(range.min == OffsetOf(CTRL_MetaEval, name) && dim_1u64(range) <= sizeof(meval_read->name)) -#define StringMemberCase(name) else if(range.min == (U64)meval_read->name.str) - StringMemberCase(label) {result = 1; ctrl_entity_equip_string(d_state->ctrl_entity_store, entity, str8_cstring_capped(in, (U8 *)in + 4096));} -#undef FlatMemberCase -#undef StringMemberCase scratch_end(scratch); }break; } @@ -2602,10 +3149,16 @@ rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated) U128 result = {0}; switch(space.kind) { - case E_SpaceKind_FileSystem: + case E_SpaceKind_HashStoreKey: { result = space.u128; }break; + case E_SpaceKind_File: + { + U64 file_path_string_id = space.u64_0; + String8 file_path = e_string_from_id(file_path_string_id); + result = fs_key_from_path_range(file_path, range); + }break; case RD_EvalSpaceKind_CtrlEntity: { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); @@ -2626,21 +3179,23 @@ rd_whole_range_from_eval_space(E_Space space) Rng1U64 result = {0}; switch(space.kind) { - case E_SpaceKind_FileSystem: + case E_SpaceKind_HashStoreKey: { - HS_Scope *scope = hs_scope_open(); - U128 hash = {0}; - for(U64 idx = 0; idx < 2; idx += 1) + U128 key = space.u128; + U128 hash = hs_hash_from_key(key, 0); + HS_Scope *hs_scope = hs_scope_open(); { - hash = hs_hash_from_key(space.u128, idx); - if(!u128_match(hash, u128_zero())) - { - break; - } + String8 data = hs_data_from_hash(hs_scope, hash); + result = r1u64(0, data.size); } - String8 data = hs_data_from_hash(scope, hash); - result = r1u64(0, data.size); - hs_scope_close(scope); + hs_scope_close(hs_scope); + }break; + case E_SpaceKind_File: + { + U64 file_path_string_id = space.u64_0; + String8 file_path = e_string_from_id(file_path_string_id); + FileProperties props = os_properties_from_file_path(file_path); + result = r1u64(0, props.size); }break; case RD_EvalSpaceKind_CtrlEntity: { @@ -2663,19 +3218,21 @@ internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping) { B32 result = 0; - if(dst_eval.mode == E_Mode_Offset) + if(dst_eval.irtree.mode == E_Mode_Offset) { Temp scratch = scratch_begin(0, 0); - E_TypeKey type_key = e_type_unwrap(dst_eval.type_key); + E_TypeKey type_key = e_type_unwrap(dst_eval.irtree.type_key); E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(dst_eval.type_key))); + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(dst_eval.irtree.type_key))); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); String8 commit_data = {0}; B32 commit_at_ptr_dest = 0; if((E_TypeKind_FirstBasic <= type_kind && type_kind <= E_TypeKind_LastBasic) || type_kind == E_TypeKind_Enum) { - E_Eval src_eval = e_eval_from_string(scratch.arena, string); + E_Expr *src_expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; + E_Expr *src_expr__casted = e_expr_ref_cast(scratch.arena, type_key, src_expr); + E_Eval src_eval = e_eval_from_expr(scratch.arena, src_expr__casted); commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); } @@ -2683,9 +3240,13 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un { E_Eval src_eval = e_eval_from_string(scratch.arena, string); E_Eval src_eval_value = e_value_eval_from_eval(src_eval); - E_TypeKind src_eval_value_type_kind = e_type_kind_from_key(src_eval_value.type_key); + E_TypeKind src_eval_value_type_kind = e_type_kind_from_key(src_eval_value.irtree.type_key); if(direct_type_kind == E_TypeKind_Char8 || + direct_type_kind == E_TypeKind_Char16 || + direct_type_kind == E_TypeKind_Char32 || direct_type_kind == E_TypeKind_UChar8 || + direct_type_kind == E_TypeKind_UChar16 || + direct_type_kind == E_TypeKind_UChar32 || e_type_kind_is_integer(direct_type_kind)) { B32 is_quoted = 0; @@ -2714,21 +3275,41 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un { commit_at_ptr_dest = 1; } + switch(direct_type_kind) + { + default:{}break; + case E_TypeKind_S16: + case E_TypeKind_U16: + case E_TypeKind_Char16: + case E_TypeKind_UChar16: + { + String16 data16 = str16_from_8(scratch.arena, commit_data); + commit_data = str8((U8 *)data16.str, data16.size*sizeof(U16)); + }break; + case E_TypeKind_Char32: + case E_TypeKind_UChar32: + case E_TypeKind_S32: + case E_TypeKind_U32: + { + String32 data32 = str32_from_8(scratch.arena, commit_data); + commit_data = str8((U8 *)data32.str, data32.size*sizeof(U32)); + }break; + } } else if(type_kind == E_TypeKind_Ptr && (e_type_kind_is_pointer_or_ref(src_eval_value_type_kind) || e_type_kind_is_integer(src_eval_value_type_kind)) && - src_eval_value.mode == E_Mode_Value) + src_eval_value.irtree.mode == E_Mode_Value) { commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); - commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(src_eval.type_key)); + commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(src_eval.irtree.type_key)); commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); } } - if(commit_data.size != 0 && e_type_byte_size_from_key(type_key) != 0) + if(commit_data.size != 0 && !e_type_key_match(e_type_key_zero(), type_key)) { U64 dst_offset = dst_eval.value.u64; - if(dst_eval.mode == E_Mode_Offset && commit_at_ptr_dest) + if(dst_eval.irtree.mode == E_Mode_Offset && commit_at_ptr_dest) { E_Eval dst_value_eval = e_value_eval_from_eval(dst_eval); dst_offset = dst_value_eval.value.u64; @@ -2740,125 +3321,27 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un return result; } -//- rjf: view rule config tree info extraction - -internal U64 -rd_base_offset_from_eval(E_Eval eval) -{ - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(eval.type_key))) - { - eval = e_value_eval_from_eval(eval); - } - return eval.value.u64; -} - -internal E_Value -rd_value_from_params_key(MD_Node *params, String8 key) -{ - Temp scratch = scratch_begin(0, 0); - MD_Node *key_node = md_child_from_string(params, key, 0); - String8 expr = md_string_from_children(scratch.arena, key_node); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - scratch_end(scratch); - return value_eval.value; -} - -internal Rng1U64 -rd_range_from_eval_params(E_Eval eval, MD_Node *params) -{ - Temp scratch = scratch_begin(0, 0); - U64 size = rd_value_from_params_key(params, str8_lit("size")).u64; - E_TypeKey type_key = e_type_unwrap(eval.type_key); - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.type_key))); - } - if(size == 0 && eval.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Union || - type_kind == E_TypeKind_Class || - type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(e_type_unwrap(eval.type_key)); - } - if(size == 0) - { - size = KB(16); - } - Rng1U64 result = {0}; - result.min = rd_base_offset_from_eval(eval); - result.max = result.min + size; - scratch_end(scratch); - return result; -} - -internal TXT_LangKind -rd_lang_kind_from_eval_params(E_Eval eval, MD_Node *params) -{ - TXT_LangKind lang_kind = TXT_LangKind_Null; - if(eval.expr->kind == E_ExprKind_LeafFilePath) - { - lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(eval.expr->string)); - } - else - { - MD_Node *lang_node = md_child_from_string(params, str8_lit("lang"), 0); - String8 lang_kind_string = lang_node->first->string; - lang_kind = txt_lang_kind_from_extension(lang_kind_string); - } - return lang_kind; -} - -internal Arch -rd_arch_from_eval_params(E_Eval eval, MD_Node *params) -{ - Arch arch = Arch_Null; - MD_Node *arch_node = md_child_from_string(params, str8_lit("arch"), 0); - String8 arch_kind_string = arch_node->first->string; - if(str8_match(arch_kind_string, str8_lit("x64"), StringMatchFlag_CaseInsensitive)) - { - arch = Arch_x64; - } - return arch; -} - -internal Vec2S32 -rd_dim2s32_from_eval_params(E_Eval eval, MD_Node *params) -{ - Vec2S32 dim = v2s32(1, 1); - { - dim.x = rd_value_from_params_key(params, str8_lit("w")).s32; - dim.y = rd_value_from_params_key(params, str8_lit("h")).s32; - } - return dim; -} - -internal R_Tex2DFormat -rd_tex2dformat_from_eval_params(E_Eval eval, MD_Node *params) -{ - R_Tex2DFormat result = R_Tex2DFormat_RGBA8; - { - MD_Node *fmt_node = md_child_from_string(params, str8_lit("fmt"), 0); - for EachNonZeroEnumVal(R_Tex2DFormat, fmt) - { - if(str8_match(r_tex2d_format_display_string_table[fmt], fmt_node->first->string, StringMatchFlag_CaseInsensitive)) - { - result = fmt; - break; - } - } - } - return result; -} - //- rjf: eval <-> file path +internal String8 +rd_file_path_from_eval(Arena *arena, E_Eval eval) +{ + String8 result = {0}; + switch(eval.space.kind) + { + default:{}break; + case E_SpaceKind_File: + { + result = push_str8_copy(arena, e_string_from_id(eval.space.u64_0)); + }break; + case E_SpaceKind_FileSystem: + { + result = push_str8_copy(arena, e_string_from_id(eval.value.u64)); + }break; + } + return result; +} + internal String8 rd_file_path_from_eval_string(Arena *arena, String8 string) { @@ -2866,10 +3349,7 @@ rd_file_path_from_eval_string(Arena *arena, String8 string) { Temp scratch = scratch_begin(&arena, 1); E_Eval eval = e_eval_from_string(scratch.arena, string); - if(eval.expr->kind == E_ExprKind_LeafFilePath) - { - result = raw_from_escaped_str8(arena, eval.expr->string); - } + result = rd_file_path_from_eval(arena, eval); scratch_end(scratch); } return result; @@ -2880,218 +3360,2423 @@ rd_eval_string_from_file_path(Arena *arena, String8 string) { Temp scratch = scratch_begin(&arena, 1); String8 string_escaped = escaped_from_raw_str8(scratch.arena, string); - String8 result = push_str8f(arena, "file:\"%S\"", string_escaped); + String8 result = push_str8f(arena, "file:\"%S\".data", string_escaped); scratch_end(scratch); return result; } +//- rjf: eval -> query + +internal String8 +rd_query_from_eval_string(Arena *arena, String8 string) +{ + String8 result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; + if(expr->kind == E_ExprKind_LeafIdent && + str8_match(expr->qualifier, str8_lit("query"), 0)) + { + result = expr->string; + } + scratch_end(scratch); + } + return result; +} + //////////////////////////////// -//~ rjf: View State Functions +//~ rjf: View Functions -//- rjf: allocation/releasing - -internal RD_View * -rd_view_alloc(void) +internal RD_ViewState * +rd_view_state_from_cfg(RD_Cfg *cfg) { - // rjf: allocate - RD_View *view = rd_state->free_view; + RD_CfgID id = cfg->id; + U64 hash = d_hash_from_string(str8_struct(&id)); + U64 slot_idx = hash%rd_state->view_state_slots_count; + RD_ViewStateSlot *slot = &rd_state->view_state_slots[slot_idx]; + RD_ViewState *view_state = &rd_nil_view_state; + for(RD_ViewState *v = slot->first; v != 0; v = v->hash_next) { - if(!rd_view_is_nil(view)) + if(v->cfg_id == id) { - rd_state->free_view_count -= 1; - SLLStackPop_N(rd_state->free_view, alloc_next); - U64 generation = view->generation; - MemoryZeroStruct(view); - view->generation = generation; + view_state = v; + break; + } + } + if(view_state == &rd_nil_view_state) + { + view_state = rd_state->free_view_state; + if(view_state) + { + SLLStackPop_N(rd_state->free_view_state, hash_next); } else { - view = push_array(rd_state->arena, RD_View, 1); + view_state = push_array(rd_state->arena, RD_ViewState, 1); } - view->generation += 1; + MemoryCopyStruct(view_state, &rd_nil_view_state); + DLLPushBack_NP(slot->first, slot->last, view_state, hash_next, hash_prev); + view_state->cfg_id = id; + view_state->arena = arena_alloc(); + view_state->arena_reset_pos = arena_pos(view_state->arena); + view_state->ev_view = ev_view_alloc(); } - - // rjf: initialize - view->arena = arena_alloc(); - view->spec = &rd_nil_view_rule_info; - view->project_path_arena = arena_alloc(); - view->project_path = str8_zero(); - for(U64 idx = 0; idx < ArrayCount(view->params_arenas); idx += 1) + if(view_state != &rd_nil_view_state) { - view->params_arenas[idx] = arena_alloc(); - view->params_roots[idx] = &md_nil_node; + view_state->last_frame_index_touched = rd_state->frame_index; } - view->query_cursor = view->query_mark = txt_pt(1, 1); - view->query_string_size = 0; - rd_state->allocated_view_count += 1; - DLLPushBack_NPZ(&rd_nil_view, rd_state->first_view, rd_state->last_view, view, alloc_next, alloc_prev); - return view; + return view_state; } internal void -rd_view_release(RD_View *view) +rd_view_ui(Rng2F32 rect) { - DLLRemove_NPZ(&rd_nil_view, rd_state->first_view, rd_state->last_view, view, alloc_next, alloc_prev); - SLLStackPush_N(rd_state->free_view, view, alloc_next); - for(RD_View *tchild = view->first_transient, *next = 0; !rd_view_is_nil(tchild); tchild = next) - { - next = tchild->order_next; - rd_view_release(tchild); - } - view->first_transient = view->last_transient = &rd_nil_view; - view->transient_view_slots_count = 0; - view->transient_view_slots = 0; - for(RD_ArenaExt *ext = view->first_arena_ext; ext != 0; ext = ext->next) - { - arena_release(ext->arena); - } - view->first_arena_ext = view->last_arena_ext = 0; - arena_release(view->project_path_arena); - for(U64 idx = 0; idx < ArrayCount(view->params_arenas); idx += 1) - { - arena_release(view->params_arenas[idx]); - } - arena_release(view->arena); - view->generation += 1; - rd_state->allocated_view_count -= 1; - rd_state->free_view_count += 1; -} - -//- rjf: equipment - -internal void -rd_view_equip_spec(RD_View *view, RD_ViewRuleInfo *spec, String8 query, MD_Node *params) -{ - // rjf: fill params tree - for(U64 idx = 0; idx < ArrayCount(view->params_arenas); idx += 1) - { - arena_clear(view->params_arenas[idx]); - } - view->params_roots[0] = md_tree_copy(view->params_arenas[0], params); - view->params_write_gen = view->params_read_gen = 0; + ProfBeginFunction(); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); + String8 view_name = view->string; + String8 expr_string = rd_expr_from_cfg(view); - // rjf: fill query buffer - rd_view_equip_query(view, query); - - // rjf: initialize state for new view spec + ////////////////////////////// + //- rjf: query extension + // + RD_Cfg *query_root = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *input_root = rd_cfg_child_from_string(query_root, str8_lit("input")); + RD_Cfg *cmd_root = rd_cfg_child_from_string(query_root, str8_lit("cmd")); + String8 current_input = input_root->first->string; + B32 search_row_is_open = (vs->query_is_selected); + F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!search_row_is_open, .initial = (F32)!!search_row_is_open); + if(search_row_open_t > 0.001f) { - for(RD_ArenaExt *ext = view->first_arena_ext; ext != 0; ext = ext->next) + String8 cmd_name = cmd_root->first->string; + RD_IconKind icon = rd_icon_kind_from_code_name(cmd_name); + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + + //- rjf: store cfg's string into view's + vs->query_string_size = Min(sizeof(vs->query_buffer), current_input.size); + MemoryCopy(vs->query_buffer, current_input.str, vs->query_string_size); + + //- rjf: clamp cursor + if(vs->query_cursor.column == 0) { - arena_release(ext->arena); + vs->query_mark = txt_pt(1, 1); + vs->query_cursor = txt_pt(1, vs->query_string_size+1); } - for(RD_View *tchild = view->first_transient, *next = 0; !rd_view_is_nil(tchild); tchild = next) + + //- rjf: determine dimensions + F32 search_row_height_target = ui_top_px_height(); + F32 search_row_height = search_row_open_t*search_row_height_target; + search_row_height = Min(search_row_height, dim_2f32(rect).y); + rect.y0 += search_row_height; + rect.y0 = floor_f32(rect.y0); + + //- rjf: build container + UI_Box *search_row = &ui_nil_box; + UI_PrefHeight(ui_px(search_row_height, 1.f)) { - next = tchild->order_next; - rd_view_release(tchild); + search_row = ui_build_box_from_stringf(UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DrawDropShadow, "###search"); } - view->first_transient = view->last_transient = &rd_nil_view; - view->first_arena_ext = view->last_arena_ext = 0; - view->transient_view_slots_count = 0; - view->transient_view_slots = 0; - arena_clear(view->arena); - view->user_data = 0; + + //- rjf: build contents + UI_Parent(search_row) UI_WidthFill UI_HeightFill UI_Focus(vs->query_is_selected ? UI_FocusKind_On : UI_FocusKind_Off) + RD_Font(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput ? RD_FontSlot_Code : RD_FontSlot_Main) + { + UI_TextAlignment(UI_TextAlign_Center) + UI_Transparency(1-search_row_open_t) + UI_PrefWidth(ui_em(2.5f, 1.f)) + UI_TagF("weak") + RD_Font(RD_FontSlot_Icons) + ui_label(rd_icon_kind_text_table[icon == RD_IconKind_Null ? RD_IconKind_Find : icon]); + UI_Transparency(1-search_row_open_t) + RD_Font(RD_FontSlot_Main) UI_PrefWidth(ui_text_dim(1, 1)) + ui_label(rd_display_from_code_name(cmd_name)); + ui_spacer(ui_em(0.5f, 1.f)); + RD_CellParams params = {0}; + { + params.flags |= !!(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput) * RD_CellFlag_CodeContents; + params.flags |= RD_CellFlag_Border; + params.cursor = &vs->query_cursor; + params.mark = &vs->query_mark; + params.edit_buffer = vs->query_buffer; + params.edit_string_size_out = &vs->query_string_size; + params.edit_buffer_size = sizeof(vs->query_buffer); + params.pre_edit_value = current_input; + } + UI_Transparency(1-search_row_open_t) + { + UI_Signal sig = rd_cellf(¶ms, "###search"); + if(ui_pressed(sig)) + { + vs->query_is_selected = 1; + rd_cmd(RD_CmdKind_FocusPanel); + } + } + } + + //- rjf: commit string to view + if(input_root == &rd_nil_cfg) + { + input_root = rd_cfg_child_from_string_or_alloc(query_root, str8_lit("input")); + } + rd_cfg_new_replace(input_root, str8(vs->query_buffer, vs->query_string_size)); } - MemoryZeroStruct(&view->scroll_pos); - view->spec = spec; - arena_clear(view->project_path_arena); - view->project_path = push_str8_copy(view->project_path_arena, rd_cfg_path_from_src(RD_CfgSrc_Project)); - view->is_filtering = 0; - view->is_filtering_t = 0; -} - -internal void -rd_view_equip_query(RD_View *view, String8 query) -{ - view->query_string_size = Min(sizeof(view->query_buffer), query.size); - MemoryCopy(view->query_buffer, query.str, view->query_string_size); - view->query_cursor = view->query_mark = txt_pt(1, query.size+1); -} - -internal void -rd_view_equip_loading_info(RD_View *view, B32 is_loading, U64 progress_v, U64 progress_target) -{ - view->loading_t_target = (F32)!!is_loading; - view->loading_progress_v = progress_v; - view->loading_progress_v_target = progress_target; - if(is_loading) + + ////////////////////////////// + //- rjf: build main view container + // + UI_Box *view_container = &ui_nil_box; + UI_WidthFill UI_HeightFill { - view->loading_t = view->loading_t_target; + view_container = ui_build_box_from_key(0, ui_key_zero()); } -} - -//- rjf: user state extensions - -internal void * -rd_view_get_or_push_user_state(RD_View *view, U64 size) -{ - void *result = view->user_data; - if(result == 0) + + ////////////////////////////// + //- rjf: fill view container + // + UI_Parent(view_container) { - view->user_data = result = push_array(view->arena, U8, size); + //////////////////////////// + //- rjf: special-case view: "getting started" + // + if(0){} + else if(str8_match(view_name, str8_lit("getting_started"), 0)) + { + Temp scratch = scratch_begin(0, 0); + ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); + UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) + UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) + { + RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); + CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + + //- rjf: icon & info + UI_Padding(ui_em(2.f, 1.f)) UI_TagF("weak") + { + //- rjf: icon + { + F32 icon_dim = ui_top_font_size()*10.f; + UI_PrefHeight(ui_px(icon_dim, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_PrefWidth(ui_px(icon_dim, 1.f)) + { + R_Handle texture = rd_state->icon_texture; + Vec2S32 texture_dim = r_size_from_tex2d(texture); + ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); + } + } + + //- rjf: info + UI_Padding(ui_em(2.f, 1.f)) + UI_WidthFill UI_PrefHeight(ui_em(2.f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_text_dim(10, 1)) + { + ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); + } + } + + //- rjf: targets state dependent helper + B32 helper_built = 0; + if(processes.count == 0) + { + helper_built = 1; + switch(targets.count) + { + //- rjf: user has no targets. build helper for adding them + case 0: + { + UI_PrefHeight(ui_em(3.75f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_em(22.f, 1.f)) + UI_CornerRadius(ui_top_font_size()/2.f) + UI_TagF("pop") + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Add, 0, "Add Target"))) + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); + } + }break; + + //- rjf: user has 1 target. build helper for launching it + case 1: + { + RD_Cfg *target_cfg = rd_cfg_list_first(&targets); + D_Target target = rd_target_from_cfg(scratch.arena, target_cfg); + String8 target_full_path = target.exe; + String8 target_name = str8_skip_last_slash(target_full_path); + UI_PrefHeight(ui_em(3.75f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_em(22.f, 1.f)) + UI_CornerRadius(ui_top_font_size()/2.f) + UI_TagF("good_pop") + { + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Launch %S", target_name))) + { + rd_cmd(RD_CmdKind_LaunchAndRun, .cfg = target_cfg->id); + } + ui_spacer(ui_em(1.5f, 1)); + if(ui_clicked(rd_icon_buttonf(RD_IconKind_StepInto, 0, "Step Into %S", target_name))) + { + rd_cmd(RD_CmdKind_LaunchAndStepInto, .cfg = target_cfg->id); + } + } + }break; + + //- rjf: user has N targets. + default: + { + helper_built = 0; + }break; + } + } + + //- rjf: or text + if(helper_built) + { + UI_TagF("weak") + UI_PrefHeight(ui_em(2.25f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_WidthFill + ui_labelf("- or -"); + } + + //- rjf: helper text for command lister activation + UI_TagF("weak") + UI_PrefHeight(ui_em(2.25f, 1.f)) UI_Row + UI_PrefWidth(ui_text_dim(10, 1)) + UI_TextAlignment(UI_TextAlign_Center) + UI_Padding(ui_pct(1, 0)) + { + ui_labelf("use"); + UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); + ui_labelf("to search for commands and options"); + } + } + scratch_end(scratch); + } + + //////////////////////////// + //- rjf: special-case view: pending + // + else if(str8_match(view_name, str8_lit("pending"), 0)) + { + Temp scratch = scratch_begin(0, 0); + typedef struct State State; + struct State + { + Arena *deferred_cmd_arena; + RD_CmdList deferred_cmds; + }; + State *state = rd_view_state(State); + if(state->deferred_cmd_arena == 0) + { + state->deferred_cmd_arena = rd_push_view_arena(); + } + rd_store_view_loading_info(1, 0, 0); + + // rjf: any commands sent to this view need to be deferred until loading is complete + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) + { + RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); + switch(kind) + { + default:{}break; + case RD_CmdKind_GoToLine: + case RD_CmdKind_GoToAddress: + case RD_CmdKind_CenterCursor: + case RD_CmdKind_ContainCursor: + { + rd_cmd_list_push_new(state->deferred_cmd_arena, &state->deferred_cmds, cmd->name, cmd->regs); + }break; + } + } + + // rjf: unpack view's target expression & hash + String8 expr_string = rd_expr_from_cfg(view); + E_Eval eval = e_eval_from_string(scratch.arena, expr_string); + Rng1U64 range = r1u64(0, 1024); + U128 key = rd_key_from_eval_space_range(eval.space, range, 0); + U128 hash = hs_hash_from_key(key, 0); + + // rjf: determine if hash's blob is ready, and which viewer to use + B32 data_is_ready = 0; + String8 new_view_name = {0}; + { + HS_Scope *hs_scope = hs_scope_open(); + if(!u128_match(hash, u128_zero())) + { + String8 data = hs_data_from_hash(hs_scope, hash); + U64 num_utf8_bytes = 0; + U64 num_unknown_bytes = 0; + for(U64 idx = 0; idx < data.size && idx < range.max;) + { + UnicodeDecode decode = utf8_decode(data.str+idx, data.size-idx); + if(decode.codepoint != max_U32 && (decode.inc > 1 || + (10 <= decode.codepoint && decode.codepoint <= 13) || + (32 <= decode.codepoint && decode.codepoint <= 126))) + { + num_utf8_bytes += decode.inc; + idx += decode.inc; + } + else + { + num_unknown_bytes += 1; + idx += 1; + } + } + data_is_ready = 1; + if(num_utf8_bytes > num_unknown_bytes*4 || num_unknown_bytes == 0) + { + new_view_name = str8_lit("text"); + } + else + { + new_view_name = str8_lit("memory"); + } + } + hs_scope_close(hs_scope); + } + + // rjf: if we don't have a viewer, just use the memory viewer. + if(new_view_name.size == 0) + { + new_view_name = str8_lit("memory"); + } + + // rjf: if data is ready and we have the name of a new visualizer, + // dispatch deferred commands & change this view's string to be + // that of the new visualizer. + if(data_is_ready && new_view_name.size != 0) + { + for(RD_CmdNode *cmd_node = state->deferred_cmds.first; + cmd_node != 0; + cmd_node = cmd_node->next) + { + RD_Cmd *cmd = &cmd_node->cmd; + rd_push_cmd(cmd->name, cmd->regs); + } + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + rd_cfg_equip_string(view, new_view_name); + RD_ViewState *vs = rd_view_state_from_cfg(view); + for(RD_ArenaExt *ext = vs->first_arena_ext; ext != 0; ext = ext->next) + { + arena_release(ext->arena); + } + arena_pop_to(vs->arena, vs->arena_reset_pos); + vs->user_data = 0; + vs->first_arena_ext = vs->last_arena_ext = 0; + } + + // rjf: if we don't have a viewer, for whatever reason, then just + // close the tab. + if(data_is_ready && new_view_name.size == 0) + { + rd_cmd(RD_CmdKind_CloseTab); + } + + scratch_end(scratch); + } + + //////////////////////////// + //- rjf: watch view + // + else if(str8_match(view_name, str8_lit("watch"), 0)) + { + Temp scratch = scratch_begin(0, 0); + E_Eval eval = e_eval_from_string(scratch.arena, expr_string); + RD_WatchViewState *ewv = rd_view_state(RD_WatchViewState); + UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); + F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; + B32 is_first_frame = 0; + if(ewv->initialized == 0) + { + is_first_frame = 1; + ewv->initialized = 1; + ewv->filter_arena = rd_push_view_arena(); + ewv->text_edit_arena = rd_push_view_arena(); + } + + ////////////////////////////// + //- rjf: unpack arguments + // + EV_View *eval_view = rd_view_eval_view(); + F32 row_height_px = ui_top_px_height(); + S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); + F32 row_string_max_size_px = dim_2f32(rect).x; + EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules; + String8 filter = rd_view_query_input(); + Vec4F32 pop_background_rgba = {0}; + UI_TagF("pop") pop_background_rgba = ui_color_from_name(str8_lit("background")); + + ////////////////////////////// + //- rjf: whenever the filter changes, we want to reset the cursor/mark state + // + if(!str8_match(filter, ewv->last_filter, 0)) + { + MemoryZeroStruct(&ewv->cursor); + MemoryZeroStruct(&ewv->mark); + MemoryZeroStruct(&ewv->next_cursor); + MemoryZeroStruct(&ewv->next_mark); + arena_clear(ewv->filter_arena); + ewv->last_filter = push_str8_copy(ewv->filter_arena, filter); + } + + ////////////////////////////// + //- rjf: decide if root should be implicit + // + // "implicit" means -> root is automatically expanded, row depth is 1 less than the + // block tree structure would suggest. this would be used if the root is, for instance, + // the "collection of all watches", to build a watch window. but this behavior is not + // as desirable if we are just using some other expression as the root. + // + B32 implicit_root = !rd_view_cfg_value_from_string(str8_lit("explicit_root")).u64; + + ////////////////////////////// + //- rjf: determine autocompletion string + // + String8 autocomplete_hint_string = {0}; + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_AutocompleteHint) + { + autocomplete_hint_string = evt->string; + break; + } + } + } + + ////////////////////////////// + //- rjf: process commands + // + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) + { + RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); + switch(kind) + { + default:{}break; + case RD_CmdKind_Search: + case RD_CmdKind_SearchBackwards: + { + vs->query_is_selected = 0; + }break; + } + } + + ////////////////////////////// + //- rjf: consume events & perform navigations/edits - calculate state + // + EV_BlockTree block_tree = {0}; + EV_BlockRangeList block_ranges = {0}; + UI_ScrollListRowBlockArray row_blocks = {0}; + Vec2S64 cursor_tbl = {0}; + Vec2S64 mark_tbl = {0}; + Rng2S64 selection_tbl = {0}; + ProfScope("consume events & perform navigations/edits - calculate state") UI_Focus(UI_FocusKind_On) + { + B32 state_dirty = 1; + B32 snap_to_cursor = 0; + B32 cursor_dirty__tbl = 0; + B32 take_autocomplete = 0; + for(UI_Event *event = 0;;) + { + ////////////////////////// + //- rjf: state -> viz blocks + // + if(state_dirty) ProfScope("state -> viz blocks") + { + MemoryZeroStruct(&block_tree); + MemoryZeroStruct(&block_ranges); + if(implicit_root || is_first_frame) + { + ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); + } + block_tree = ev_block_tree_from_exprs(scratch.arena, eval_view, filter, eval.exprs); + block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); + if(implicit_root && block_ranges.first != 0) + { + block_ranges.count -= 1; + block_ranges.first = block_ranges.first->next; + } + } + + ////////////////////////// + //- rjf: block ranges -> ui row blocks + // + ProfScope("block ranges -> ui row blocks") + { + UI_ScrollListRowBlockChunkList row_block_chunks = {0}; + for(EV_BlockRangeNode *n = block_ranges.first; n != 0; n = n->next) + { + UI_ScrollListRowBlock block = {0}; + block.row_count = dim_1u64(n->v.range); + block.item_count = n->v.block->single_item ? 1 : dim_1u64(n->v.range); + ui_scroll_list_row_block_chunk_list_push(scratch.arena, &row_block_chunks, 256, &block); + } + row_blocks = ui_scroll_list_row_block_array_from_chunk_list(scratch.arena, &row_block_chunks); + } + + ////////////////////////// + //- rjf: conclude state update + // + if(state_dirty) + { + state_dirty = 0; + } + + ////////////////////////////// + //- rjf: 2D table coordinates * blocks -> stable cursor state + // + if(cursor_dirty__tbl) + { + cursor_dirty__tbl = 0; + struct + { + RD_WatchPt *pt_state; + Vec2S64 pt_tbl; + } + points[] = + { + {&ewv->cursor, cursor_tbl}, + {&ewv->mark, mark_tbl}, + }; + for(U64 point_idx = 0; point_idx < ArrayCount(points); point_idx += 1) + { + EV_Key last_key = points[point_idx].pt_state->key; + EV_Key last_parent_key = points[point_idx].pt_state->parent_key; + points[point_idx].pt_state[0] = rd_watch_pt_from_tbl(&block_ranges, points[point_idx].pt_tbl); + if(ev_key_match(ev_key_zero(), points[point_idx].pt_state->key) && points[point_idx].pt_tbl.y != 0) + { + points[point_idx].pt_state->key = last_parent_key; + EV_ExpandNode *node = ev_expand_node_from_key(eval_view, last_parent_key); + for(EV_ExpandNode *n = node; n != 0; n = n->parent) + { + points[point_idx].pt_state->key = n->key; + if(n->expanded == 0) + { + break; + } + } + } + if(point_idx == 0 && + (!ev_key_match(ewv->cursor.key, last_key) || + !ev_key_match(ewv->cursor.parent_key, last_parent_key))) + { + ewv->text_editing = 0; + } + } + ewv->next_cursor = ewv->cursor; + ewv->next_mark = ewv->mark; + } + + ////////////////////////// + //- rjf: stable cursor state * blocks -> 2D table coordinates + // + EV_WindowedRowList mark_rows = {0}; + Rng2S64 cursor_tbl_range = {0}; + { + // rjf: compute 2d table coordinates + cursor_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->cursor); + mark_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->mark); + + // rjf: compute legal coordinate range, given selection-defining row + Rng1S64 cursor_x_range = {0}; + { + EV_Row *row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, mark_tbl.y); + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + cursor_x_range = r1s64(0, (S64)row_info.cells.count-1); + } + cursor_tbl_range = r2s64(v2s64(cursor_x_range.min, 0), v2s64(cursor_x_range.max, block_tree.total_item_count - implicit_root)); + + // rjf: clamp x positions of cursor/mark tbl + for EachEnumVal(Axis2, axis) + { + cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); + mark_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), mark_tbl.v[axis]); + } + + // rjf: form selection range table coordinates + selection_tbl = r2s64p(Min(cursor_tbl.x, mark_tbl.x), Min(cursor_tbl.y, mark_tbl.y), + Max(cursor_tbl.x, mark_tbl.x), Max(cursor_tbl.y, mark_tbl.y)); + } + + ////////////////////////// + //- rjf: [table] snap to cursor + // + if(snap_to_cursor) + { + Rng1S64 global_vnum_range = r1s64(1, block_tree.total_row_count+1); + if(contains_1s64(global_vnum_range, cursor_tbl.y)) + { + UI_ScrollPt *scroll_pt = &scroll_pos.y; + + //- rjf: compute visible row range + Rng1S64 visible_row_num_range = r1s64(scroll_pt->idx + 1 - !!(scroll_pt->off < 0), + scroll_pt->idx + 1 + num_possible_visible_rows); + + //- rjf: compute cursor row range from cursor item + Rng1S64 cursor_visibility_row_num_range = {0}; + cursor_visibility_row_num_range.min = ev_vnum_from_num(&block_ranges, cursor_tbl.y) - 1; + cursor_visibility_row_num_range.max = cursor_visibility_row_num_range.min + 3; + + //- rjf: compute deltas & apply + S64 min_delta = Min(0, cursor_visibility_row_num_range.min-visible_row_num_range.min); + S64 max_delta = Max(0, cursor_visibility_row_num_range.max-visible_row_num_range.max); + S64 new_num = (S64)scroll_pt->idx + 1 + min_delta + max_delta; + new_num = clamp_1s64(global_vnum_range, new_num); + if(new_num > 0) + { + U64 new_idx = (U64)(new_num - 1); + ui_scroll_pt_target_idx(scroll_pt, new_idx); + } + } + } + + ////////////////////////////// + //- rjf: apply cursor/mark rugpull change + // + B32 cursor_rugpull = 0; + if(!rd_watch_pt_match(ewv->cursor, ewv->next_cursor)) + { + cursor_rugpull = 1; + ewv->cursor = ewv->next_cursor; + ewv->mark = ewv->next_mark; + } + + ////////////////////////// + //- rjf: grab next event, if any - otherwise exit the loop, as we now have + // the most up-to-date state + // + B32 next_event_good = ui_next_event(&event); + if(!cursor_rugpull && (!next_event_good || !ui_is_focus_active())) + { + break; + } + UI_Event dummy_evt = zero_struct; + UI_Event *evt = &dummy_evt; + if(next_event_good) + { + evt = event; + } + B32 taken = 0; + + ////////////////////////////// + //- rjf: consume query-completion events, if this view is being used as a query + // + { + RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); + if(lister != &rd_nil_cfg && + evt->kind == UI_EventKind_Press && + evt->slot == UI_EventActionSlot_Accept && + selection_tbl.min.y == selection_tbl.max.y) + { + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd")); + String8 cmd_name = cmd->first->string; + + // rjf: if we have no selection, just pick the first row + EV_Row *row = 0; + if(selection_tbl.min.y == 0 && selection_tbl.max.y == 0) + { + row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, 1); + } + + // rjf: if we do have a selection, compute that row + else + { + row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, selection_tbl.min.y); + } + + // rjf: use row to complete query + if(row->expr != &e_expr_nil) + { + taken = 1; + E_Eval eval = e_eval_from_expr(scratch.arena, row->expr); + switch(eval.space.kind) + { + default: + { + String8 symbol_name = d_symbol_name_from_process_vaddr(scratch.arena, ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), eval.value.u64, 0, 0); + rd_cmd(RD_CmdKind_CompleteQuery, .string = symbol_name); + }break; + case E_SpaceKind_File: + case E_SpaceKind_FileSystem: + { + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + String8 file = rd_file_path_from_eval(scratch.arena, eval); + if(str8_match(type->name, str8_lit("folder"), 0)) + { + String8 new_input_string = push_str8f(scratch.arena, "%S/", file); + rd_cmd(RD_CmdKind_UpdateQuery, .string = new_input_string); + } + else + { + rd_cmd(RD_CmdKind_CompleteQuery, .file_path = file); + } + }break; + case RD_EvalSpaceKind_MetaCfg: + { + RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); + rd_cmd(RD_CmdKind_CompleteQuery, .cfg = cfg->id); + }break; + case RD_EvalSpaceKind_MetaUnattachedProcess: + { + U64 pid = eval.value.u128.u64[0]; + rd_cmd(RD_CmdKind_CompleteQuery, .pid = pid); + }break; + } + } + } + } + + ////////////////////////// + //- rjf: begin editing on some operations + // + if(!ewv->text_editing && + (evt->kind == UI_EventKind_Text || + evt->flags & UI_EventFlag_Paste || + (evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Edit)) && + selection_tbl.min.x == selection_tbl.max.x && + (selection_tbl.min.y != 0 || selection_tbl.max.y != 0)) + { + Vec2S64 selection_dim = dim_2s64(selection_tbl); + arena_clear(ewv->text_edit_arena); + ewv->text_edit_state_slots_count = u64_up_to_pow2(selection_dim.y+1); + ewv->text_edit_state_slots_count = Max(ewv->text_edit_state_slots_count, 64); + ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState*, ewv->text_edit_state_slots_count); + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + B32 any_edits_started = 0; + for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags & (~EV_StringFlag_ReadOnlyDisplayRules), &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + if(cell_info.flags & RD_WatchCellFlag_CanEdit) + { + any_edits_started = 1; + String8 string = cell_info.string; + string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); + RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; + U64 hash = ev_hash_from_key(pt.key); + U64 slot_idx = hash%ewv->text_edit_state_slots_count; + RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); + SLLStackPush_N(ewv->text_edit_state_slots[slot_idx], edit_state, pt_hash_next); + edit_state->pt = pt; + edit_state->cursor = txt_pt(1, string.size+1); + edit_state->mark = txt_pt(1, 1); + edit_state->input_size = string.size; + MemoryCopy(edit_state->input_buffer, string.str, string.size); + edit_state->initial_size = string.size; + MemoryCopy(edit_state->initial_buffer, string.str, string.size); + } + } + } + ewv->text_editing = any_edits_started; + } + + ////////////////////////// + //- rjf: [table] do cell-granularity multi-cursor 'accept' operations (expansions / etc.); if + // cannot apply to multi-cursor, then just don't take the event + // + if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept && + (selection_tbl.min.y != 0 || selection_tbl.max.y != 0) && + (selection_tbl.max.y - selection_tbl.min.y > 0)) + { + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + if(row_node != 0) + { + taken = 1; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) + { + // rjf: unpack row info + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + + // rjf: loop through X selections and perform operations for each + for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) + { +#if 0 // TODO(rjf): @cfg (multicursor watch window press operations) + //- rjf: determine operation for this cell + typedef enum OpKind + { + OpKind_Null, + OpKind_DoExpand, + } + OpKind; + OpKind kind = OpKind_Null; + switch(row_kind) + { + default:{}break; + case RD_WatchViewRowKind_Normal: + { + RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); + switch(col->kind) + { + default:{}break; + case RD_WatchViewColumnKind_Expr: {kind = OpKind_DoExpand;}break; + } + }break; + case RD_WatchViewRowKind_PrettyEntityControls: + if((!rd_entity_is_nil(row_info.collection_entity) || row_info.collection_ctrl_entity != &ctrl_entity_nil) && selection_tbl.min.x == 1 && selection_tbl.max.x == 1) + { + kind = OpKind_DoExpand; + }break; + } + + //- rjf: perform operation + switch(kind) + { + default:{taken = 0;}break; + case OpKind_DoExpand: + if(ev_row_is_expandable(row)) + { + B32 is_expanded = ev_expansion_from_key(eval_view, row->key); + ev_key_set_expansion(eval_view, row->block->key, row->key, !is_expanded); + }break; + } +#endif + } + } + } + } + + ////////////////////////// + //- rjf: [text] apply textual edits + // + if(ewv->text_editing) + { + B32 editing_complete = ((evt->kind == UI_EventKind_Press && (evt->slot == UI_EventActionSlot_Cancel || evt->slot == UI_EventActionSlot_Accept)) || + (evt->kind == UI_EventKind_Navigate && evt->delta_2s32.y != 0) || + cursor_rugpull); + rd_state->text_edit_mode = 1; + if(editing_complete || + ((evt->kind == UI_EventKind_Edit || + evt->kind == UI_EventKind_Navigate || + evt->kind == UI_EventKind_Text) && + evt->delta_2s32.y == 0)) + { + taken = 1; + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; + RD_WatchViewTextEditState *edit_state = rd_watch_view_text_edit_state_from_pt(ewv, pt); + String8 string = str8(edit_state->input_buffer, edit_state->input_size); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); + + // rjf: copy + if(op.flags & UI_TxtOpFlag_Copy && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y) + { + os_set_clipboard_text(op.copy); + } + + // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op + if(autocomplete_hint_string.size != 0) + { + take_autocomplete = 1; + String8 word_query = rd_lister_query_word_from_input_string_off(string, edit_state->cursor.column-1); + U64 word_off = (U64)(word_query.str - string.str); + String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); + new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); + MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); + edit_state->input_size = new_string.size; + edit_state->cursor = edit_state->mark = txt_pt(1, word_off+1+autocomplete_hint_string.size); + string = str8(edit_state->input_buffer, edit_state->input_size); + op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); + } + + // rjf: cancel? -> revert to initial string + if(editing_complete && evt->slot == UI_EventActionSlot_Cancel) + { + string = str8(edit_state->initial_buffer, edit_state->initial_size); + } + + // rjf: obtain edited string + String8 new_string = string; + if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) + { + new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(op.range.min.column, op.range.max.column), op.replace); + } + + // rjf: commit to edit state + new_string.size = Min(new_string.size, sizeof(edit_state->input_buffer)); + MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); + edit_state->input_size = new_string.size; + edit_state->cursor = op.cursor; + edit_state->mark = op.mark; + + // rjf: commit edited cell string + switch(cell->kind) + { + case RD_WatchCellKind_Expr: + { + RD_Cfg *cfg = row_info.group_cfg_child; + String8 child_key = str8_lit("expression"); + if(cfg == &rd_nil_cfg && editing_complete && new_string.size != 0) + { + RD_Cfg *new_cfg_parent = row_info.group_cfg_parent; + if(new_cfg_parent != &rd_nil_cfg) + { + child_key = str8_zero(); + } + if(new_cfg_parent == &rd_nil_cfg) + { + RD_CfgList all_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, row_info.group_cfg_name); + new_cfg_parent = rd_cfg_list_last(&all_cfgs)->parent; + } + if(new_cfg_parent == &rd_nil_cfg) + { + new_cfg_parent = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + } + cfg = rd_cfg_new(new_cfg_parent, row_info.group_cfg_name); + state_dirty = 1; + snap_to_cursor = 1; + } + if(cfg != &rd_nil_cfg) + { + RD_Cfg *expr = child_key.size != 0 ? rd_cfg_child_from_string_or_alloc(cfg, child_key) : cfg; + rd_cfg_new_replace(expr, new_string); + } + }break; + case RD_WatchCellKind_Tag: + if(editing_complete) + { + ev_key_set_view_rule(eval_view, pt.key, new_string); + RD_Cfg *cfg = row_info.group_cfg_child; + if(cfg != &rd_nil_cfg && new_string.size != 0) + { + RD_Cfg *view_rule = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("view_rule")); + rd_cfg_new(view_rule, new_string); + } + else if(cfg != &rd_nil_cfg && new_string.size == 0) + { + rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("view_rule"))); + } + }break; + case RD_WatchCellKind_Eval: + { + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + if(cell_info.eval.irtree.mode == E_Mode_Offset) + { + B32 should_commit_asap = editing_complete; + if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) + { + should_commit_asap = 1; + } + else if(evt->slot != UI_EventActionSlot_Cancel) + { + should_commit_asap = editing_complete; + } + if(should_commit_asap) + { + B32 success = 0; + success = rd_commit_eval_value_string(cell_info.eval, new_string, 0); + if(!success) + { + log_user_error(str8_lit("Could not commit value successfully.")); + } + } + } + }break; + } + } + } + } + if(editing_complete) + { + ewv->text_editing = 0; + } + } + + ////////////////////////// + //- rjf: [table] do cell-granularity copies + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Copy) + { + taken = 1; + String8List strs = {0}; + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + String8 cell_string = cell_info.string; + cell_string = str8_skip_chop_whitespace(cell_string); + U64 comma_pos = str8_find_needle(cell_string, 0, str8_lit(","), 0); + if(selection_tbl.min.x != selection_tbl.max.x || selection_tbl.min.y != selection_tbl.max.y) + { + str8_list_pushf(scratch.arena, &strs, "%s%S%s%s", + comma_pos < cell_string.size ? "\"" : "", + cell_string, + comma_pos < cell_string.size ? "\"" : "", + cell_x+1 <= selection_tbl.max.x ? "," : ""); + } + else + { + str8_list_push(scratch.arena, &strs, cell_string); + } + } + if(y+1 <= selection_tbl.max.y) + { + str8_list_push(scratch.arena, &strs, str8_lit("\n")); + } + } + String8 string = str8_list_join(scratch.arena, &strs, 0); + os_set_clipboard_text(string); + } + + ////////////////////////// + //- rjf: [table] do cell-granularity deletions + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Delete) + { + taken = 1; + state_dirty = 1; + snap_to_cursor = 1; + RD_CfgList cfgs_to_remove = {0}; + RD_WatchPt next_cursor_pt = {0}; + B32 next_cursor_set = 0; + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; + switch(cell->kind) + { + default:{}break; + case RD_WatchCellKind_Expr: + { + RD_Cfg *cfg = row_info.group_cfg_child; + if(cfg != &rd_nil_cfg) + { + rd_cfg_list_push(scratch.arena, &cfgs_to_remove, cfg); + U64 deleted_num = row->block->lookup_rule->num_from_id(row->key.child_id, row->block->lookup_rule_user_data); + if(deleted_num != 0) + { + EV_Key parent_key = row->block->parent->key; + EV_Key key = row->block->key; + U64 fallback_id_prev = row->block->lookup_rule->id_from_num(deleted_num-1, row->block->lookup_rule_user_data); + U64 fallback_id_next = row->block->lookup_rule->id_from_num(deleted_num+1, row->block->lookup_rule_user_data); + if(fallback_id_next != 0) + { + parent_key = row->block->key; + key = ev_key_make(row->key.parent_hash, fallback_id_next); + } + else if(fallback_id_prev != 0) + { + parent_key = row->block->key; + key = ev_key_make(row->key.parent_hash, fallback_id_prev); + } + RD_WatchPt new_pt = {parent_key, key, pt.cell_id}; + next_cursor_pt = new_pt; + next_cursor_set = 1; + state_dirty = 1; + } + } + }break; + case RD_WatchCellKind_Tag: + { + if(row_info.group_cfg_child != &rd_nil_cfg) + { + rd_cfg_release(rd_cfg_child_from_string(row_info.group_cfg_child, str8_lit("view_rule"))); + } + ev_key_set_view_rule(eval_view, row->key, str8_zero()); + state_dirty = 1; + }break; + case RD_WatchCellKind_Eval: + { + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + rd_commit_eval_value_string(cell_info.eval, str8_zero(), 0); + }break; + } + } + } + for(RD_CfgNode *n = cfgs_to_remove.first; n != 0; n = n->next) + { + rd_cfg_release(n->v); + } + if(next_cursor_set) + { + ewv->cursor = ewv->mark = ewv->next_cursor = ewv->next_mark = next_cursor_pt; + } + } + + ////////////////////////// + //- rjf: [table] apply deltas to cursor & mark + // + if(!ewv->text_editing && !(evt->flags & UI_EventFlag_Delete) && !(evt->flags & UI_EventFlag_Reorder)) + { + B32 cursor_tbl_min_is_empty_selection[Axis2_COUNT] = {0, 1}; + Vec2S32 delta = evt->delta_2s32; + if(evt->flags & UI_EventFlag_PickSelectSide && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) + { + if(delta.x > 0 || delta.y > 0) + { + cursor_tbl.x = selection_tbl.max.x; + cursor_tbl.y = selection_tbl.max.y; + } + else if(delta.x < 0 || delta.y < 0) + { + cursor_tbl.x = selection_tbl.min.x; + cursor_tbl.y = selection_tbl.min.y; + } + } + if(evt->flags & UI_EventFlag_ZeroDeltaOnSelect && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) + { + MemoryZeroStruct(&delta); + } + B32 moved = 1; + switch(evt->delta_unit) + { + default:{moved = 0;}break; + case UI_EventDeltaUnit_Char: + { + for EachEnumVal(Axis2, axis) + { + cursor_tbl.v[axis] += delta.v[axis]; + if(cursor_tbl.v[axis] < cursor_tbl_range.min.v[axis]) + { + cursor_tbl.v[axis] = cursor_tbl_range.max.v[axis]; + } + if(cursor_tbl.v[axis] > cursor_tbl_range.max.v[axis]) + { + cursor_tbl.v[axis] = cursor_tbl_range.min.v[axis]; + } + cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); + } + }break; + case UI_EventDeltaUnit_Word: + case UI_EventDeltaUnit_Line: + case UI_EventDeltaUnit_Page: + { + cursor_tbl.x = (delta.x>0 ? (cursor_tbl_range.max.x) : + delta.x<0 ? (cursor_tbl_range.min.x + !!cursor_tbl_min_is_empty_selection[Axis2_X]) : + cursor_tbl.x); + cursor_tbl.y += ((delta.y>0 ? +(num_possible_visible_rows-3) : + delta.y<0 ? -(num_possible_visible_rows-3) : + 0)); + cursor_tbl.y = clamp_1s64(r1s64(cursor_tbl_range.min.y + !!cursor_tbl_min_is_empty_selection[Axis2_Y], + cursor_tbl_range.max.y), + cursor_tbl.y); + }break; + case UI_EventDeltaUnit_Whole: + { + for EachEnumVal(Axis2, axis) + { + cursor_tbl.v[axis] = (delta.v[axis]>0 ? cursor_tbl_range.max.v[axis] : delta.v[axis]<0 ? cursor_tbl_range.min.v[axis] + !!cursor_tbl_min_is_empty_selection[axis] : cursor_tbl.v[axis]); + } + }break; + } + if(moved) + { + taken = 1; + cursor_dirty__tbl = 1; + snap_to_cursor = 1; + } + } + + ////////////////////////// + //- rjf: [table] stick table mark to cursor if needed + // + if(!ewv->text_editing) + { + if(taken && !(evt->flags & UI_EventFlag_KeepMark)) + { + mark_tbl = cursor_tbl; + } + } + + ////////////////////////// + //- rjf: [table] do cell-granularity reorders + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Reorder) + { + taken = 1; + if(filter.size == 0) + { + // rjf: determine blocks of each endpoint of the table selection + EV_Block *selection_endpoint_blocks[2] = + { + ev_block_range_from_num(&block_ranges, selection_tbl.min.y).block, + ev_block_range_from_num(&block_ranges, selection_tbl.max.y).block, + }; + + // rjf: pick shallowest block within which we can do reordering + U64 selection_depths[2] = + { + ev_depth_from_block(selection_endpoint_blocks[0]), + ev_depth_from_block(selection_endpoint_blocks[1]), + }; + EV_Block *selection_block = (selection_depths[1] < selection_depths[0] + ? selection_endpoint_blocks[1] + : selection_endpoint_blocks[0]); + + // rjf: find selection keys within the block in which we are doing reordering + EV_Key selection_keys_in_block[2] = {0}; + { + for EachElement(idx, selection_endpoint_blocks) + { + EV_Block *endpoint_block = selection_endpoint_blocks[idx]; + if(endpoint_block == selection_block) + { + selection_keys_in_block[idx] = ev_key_from_num(&block_ranges, selection_tbl.v[idx].y); + } + else + { + for(;endpoint_block->parent != selection_block && endpoint_block != &ev_nil_block;) + { + endpoint_block = endpoint_block->parent; + } + if(endpoint_block->parent == selection_block) + { + selection_keys_in_block[idx] = endpoint_block->key; + } + } + } + EV_Key fallback_key = {0}; + for EachElement(idx, selection_endpoint_blocks) + { + if(!ev_key_match(selection_keys_in_block[idx], ev_key_zero())) + { + fallback_key = selection_keys_in_block[idx]; + } + } + for EachElement(idx, selection_endpoint_blocks) + { + if(ev_key_match(selection_keys_in_block[idx], ev_key_zero())) + { + selection_keys_in_block[idx] = fallback_key; + } + } + } + + // rjf: determine collection info for the block + String8 group_cfg_name = {0}; + { + E_IRTreeAndType block_irtree = e_irtree_and_type_from_expr(scratch.arena, selection_block->expr); + E_TypeKey block_type_key = block_irtree.type_key; + E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); + if(block_type_kind == E_TypeKind_Set) + { + E_Type *block_type = e_type_from_key__cached(block_type_key); + group_cfg_name = rd_singular_from_code_name_plural(block_type->name); + if(group_cfg_name.size == 0) + { + group_cfg_name = block_type->name; + } + } + } + + // rjf: map selection endpoints to cfgs + RD_Cfg *first_cfg = &rd_nil_cfg; + RD_Cfg *last_cfg = &rd_nil_cfg; + if(group_cfg_name.size != 0) + { + first_cfg = rd_cfg_from_id(selection_keys_in_block[0].child_id); + last_cfg = rd_cfg_from_id(selection_keys_in_block[1].child_id); + } + + // rjf: reorder + if(first_cfg != &rd_nil_cfg && last_cfg != &rd_nil_cfg) + { + RD_Cfg *first_cfg_prev = &rd_nil_cfg; + RD_Cfg *last_cfg_next = &rd_nil_cfg; + for(RD_Cfg *prev = first_cfg->prev; prev != &rd_nil_cfg; prev = prev->prev) + { + if(str8_match(prev->string, first_cfg->string, 0)) + { + first_cfg_prev = prev; + break; + } + } + for(RD_Cfg *next = last_cfg->next; next != &rd_nil_cfg; next = next->next) + { + if(str8_match(next->string, last_cfg->string, 0)) + { + last_cfg_next = next; + break; + } + } + if(evt->delta_2s32.y < 0 && first_cfg != &rd_nil_cfg && first_cfg_prev != &rd_nil_cfg) + { + state_dirty = 1; + snap_to_cursor = 1; + RD_Cfg *parent = first_cfg_prev->parent; + rd_cfg_unhook(parent, first_cfg_prev); + rd_cfg_insert_child(parent, last_cfg, first_cfg_prev); + } + if(evt->delta_2s32.y > 0 && last_cfg != &rd_nil_cfg && last_cfg_next != &rd_nil_cfg) + { + state_dirty = 1; + snap_to_cursor = 1; + RD_Cfg *parent = last_cfg_next->parent; + rd_cfg_unhook(parent, last_cfg_next); + rd_cfg_insert_child(parent, first_cfg_prev, last_cfg_next); + } + } + } + } + + ////////////////////////// + //- rjf: consume event, if taken + // + if(taken && evt != &dummy_evt) + { + ui_eat_event(evt); + } + } + if(take_autocomplete) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_AutocompleteHint) + { + ui_eat_event(evt); + break; + } + } + } + } + + ////////////////////////////// + //- rjf: build ui + // + B32 pressed = 0; + ProfScope("build ui") + { + Vec2F32 rect_dim = dim_2f32(rect); + F32 contents_width_px = (rect_dim.x - floor_f32(ui_top_font_size()*1.5f)); + Rng1S64 visible_row_rng = {0}; + UI_ScrollListParams scroll_list_params = {0}; + { + scroll_list_params.flags = UI_ScrollListFlag_All; + scroll_list_params.row_height_px = row_height_px; + scroll_list_params.dim_px = rect_dim; + scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, 0)); + scroll_list_params.item_range = r1s64(0, block_tree.total_row_count - !!implicit_root); + scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; + scroll_list_params.row_blocks = row_blocks; + } + UI_BoxFlags disabled_flags = ui_top_flags(); + if(d_ctrl_targets_running()) + { + disabled_flags |= UI_BoxFlag_Disabled; + } + UI_ScrollListSignal scroll_list_sig = {0}; + UI_Focus(UI_FocusKind_On) + UI_ScrollList(&scroll_list_params, &scroll_pos.y, + 0, + 0, + &visible_row_rng, + &scroll_list_sig) + UI_Focus(UI_FocusKind_Null) + { + ui_set_next_pref_height(ui_children_sum(1)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *table = ui_build_box_from_string(0, str8_lit("table")); + UI_Parent(table) + { + Vec2F32 scroll_list_view_off_px = ui_top_parent()->parent->view_off; + + //////////////////////// + //- rjf: viz blocks -> rows + // + EV_WindowedRowList rows = {0}; + { + rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min+1, visible_row_rng.max+2)); + } + + //////////////////////// + //- rjf: rows -> row infos + // + RD_WatchRowInfo *row_infos = push_array(scratch.arena, RD_WatchRowInfo, rows.count); + { + U64 idx = 0; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) + { + EV_Row *row = &row_node->row; + row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); + } + } + + //////////////////////// + //- rjf: build boundaries + // + B32 cell_pcts_are_dirty = 0; + ProfScope("build boundaries") + { + U64 idx = 0; + U64 boundary_start_idx = 0; + EV_Row *last_row = 0; + RD_WatchRowInfo *last_row_info = 0; + for(EV_WindowedRowNode *row_node = rows.first;; row_node = row_node->next, idx += 1) + { + //- rjf: determine if this row breaks the topology + B32 is_new_topology = (row_node == 0); + if(row_node != 0 && last_row_info != 0) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo *row_info = &row_infos[idx]; + for(RD_WatchCell *last_cell = last_row_info->cells.first, *this_cell = row_info->cells.first;; + last_cell = last_cell->next, this_cell = this_cell->next) + { + if(last_cell == 0 && this_cell == 0) + { + break; + } + if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) + { + is_new_topology = 1; + break; + } + if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) + { + is_new_topology = 1; + break; + } + } + } + + //- rjf: if we reached a new topology, or the end -> build boundaries for all cell separations + if(is_new_topology) + { + EV_Row *row = last_row; + RD_WatchRowInfo *row_info = last_row_info; + F32 row_width_px = contents_width_px; + if(row_info != 0) + { + U64 row_hash = ev_hash_from_key(row->key); + F32 cell_x_px = 0; + U64 cell_idx = 0; + for(RD_WatchCell *cell = row_info->cells.first; cell != 0 && cell->next != 0; cell = cell->next, cell_idx += 1) + { + if(cell->pct == 0 || cell->next->pct == 0) + { + continue; + } + U64 cell_id = rd_id_from_watch_cell(cell); + F32 cell_width_px = cell->px + cell->pct * row_width_px; + F32 next_cell_x_px = cell_x_px + cell_width_px; + { + Rng2F32 rect = r2f32p(next_cell_x_px - ui_top_font_size()*0.4f, + boundary_start_idx*row_height_px, + next_cell_x_px + ui_top_font_size()*0.4f, + idx*row_height_px); + UI_Rect(rect) UI_HoverCursor(OS_Cursor_LeftRight) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_Floating, "boundary_%I64x_%I64x", row_hash, cell_id); + UI_Signal sig = ui_signal_from_box(box); + if(ui_dragging(sig)) + { + typedef struct DragData DragData; + struct DragData + { + F32 min_pct; + F32 max_pct; + }; + if(ui_pressed(sig)) + { + DragData drag_data = {cell->pct, cell->next->pct}; + ui_store_drag_struct(&drag_data); + } + DragData *drag_data = ui_get_drag_struct(DragData); + F32 min_pct__pre = drag_data->min_pct; + F32 max_pct__pre = drag_data->max_pct; + F32 min_px__pre = min_pct__pre*row_width_px; + F32 max_px__pre = max_pct__pre*row_width_px; + F32 min_px__post = min_px__pre + ui_drag_delta().x; + F32 max_px__post = max_px__pre - ui_drag_delta().x; + F32 min_pct__post = min_px__post/row_width_px; + F32 max_pct__post = max_px__post/row_width_px; + if(min_pct__post < 0.05f) + { + min_pct__post = 0.05f; + max_pct__post = (min_pct__pre + max_pct__pre) - min_pct__post; + } + if(max_pct__post < 0.05f) + { + max_pct__post = 0.05f; + min_pct__post = (min_pct__pre + max_pct__pre) - max_pct__post; + } + if(ui_double_clicked(sig)) + { + F32 default_sum = cell->default_pct + cell->next->default_pct; + F32 current_sum = min_pct__pre + max_pct__pre;; + min_pct__post = current_sum * (cell->default_pct / default_sum); + max_pct__post = current_sum * (cell->next->default_pct / default_sum); + ui_kill_action(); + } + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string_or_alloc(view, row_info->cell_style_key); + RD_Cfg *min_cfg = &rd_nil_cfg; + RD_Cfg *max_cfg = &rd_nil_cfg; + { + RD_Cfg *pct_child = style->first; + U64 c_idx = 0; + for(RD_WatchCell *c = row_info->cells.first; c != 0; c = c->next, c_idx += 1) + { + if(pct_child == &rd_nil_cfg) + { + pct_child = rd_cfg_newf(style, "%f", c->pct); + } + if(c_idx == cell_idx) + { + min_cfg = pct_child; + } + if(c_idx == cell_idx+1) + { + max_cfg = pct_child; + } + pct_child = pct_child->next; + } + rd_cfg_equip_stringf(min_cfg, "%f", min_pct__post); + rd_cfg_equip_stringf(max_cfg, "%f", max_pct__post); + cell_pcts_are_dirty = 1; + } + } + } + } + cell_x_px = next_cell_x_px; + } + } + boundary_start_idx = idx; + } + + //- rjf: advance + if(row_node == 0) + { + break; + } + else + { + last_row = &row_node->row; + last_row_info = &row_infos[idx]; + } + } + } + + //////////////////////// + //- rjf: if cell widths are dirty -> recompute row infos + // + if(cell_pcts_are_dirty) + { + U64 idx = 0; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) + { + EV_Row *row = &row_node->row; + row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); + } + } + + //////////////////////// + //- rjf: build table + // + ProfScope("build table") + { + U64 local_row_idx = 0; + U64 global_row_idx = rows.count_before_semantic; + RD_WatchRowInfo last_row_info = {0}; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1, local_row_idx += 1) + { + //////////////////////// + //- rjf: unpack row info + // + ProfBegin("unpack row info"); + EV_Row *row = &row_node->row; + RD_WatchRowInfo *row_info = &row_infos[local_row_idx]; + U64 row_hash = ev_hash_from_key(row->key); + U64 row_depth = ev_depth_from_block(row->block); + B32 row_selected = (selection_tbl.min.y <= global_row_idx+1 && global_row_idx+1 <= selection_tbl.max.y); + B32 row_expanded = ev_expansion_from_key(eval_view, row->key); + B32 next_row_expanded = row_expanded; + B32 row_is_expandable = row_info->can_expand; + if(implicit_root && row_depth > 0) + { + row_depth -= 1; + } + ProfEnd(); + + //////////////////////// + //- rjf: determine if this row fits the last row's topology + // + B32 row_matches_last_row_topology = 1; + if(row_node != rows.first) + { + for(RD_WatchCell *last_cell = last_row_info.cells.first, *this_cell = row_info->cells.first;; + last_cell = last_cell->next, this_cell = this_cell->next) + { + if(last_cell == 0 && this_cell == 0) + { + break; + } + if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) + { + row_matches_last_row_topology = 0; + break; + } + if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) + { + row_matches_last_row_topology = 0; + break; + } + } + } + + //////////////////////// + //- rjf: store last row's info, for next iteration + // + last_row_info = *row_info; + + //////////////////////// + //- rjf: determine if row's data is fresh and/or bad + // + ProfBegin("determine if row's data is fresh and/or bad"); + B32 row_is_fresh = 0; + B32 row_is_bad = 0; + switch(row_info->eval.irtree.mode) + { + default:{}break; + case E_Mode_Offset: + { + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); + if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) + { + U64 size = e_type_byte_size_from_key(row_info->eval.irtree.type_key); + size = Min(size, 64); + Rng1U64 vaddr_rng = r1u64(row_info->eval.value.u64, row_info->eval.value.u64+size); + CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, rd_state->frame_eval_memread_endt_us); + for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) + { + if(slice.byte_changed_flags[idx] != 0) + { + row_is_fresh = 1; + } + if(slice.byte_bad_flags[idx] != 0) + {row_is_bad = 1; + } + } + } + }break; + } + ProfEnd(); + + //////////////////////// + //- rjf: determine row's flags & color palette + // + ProfBegin("determine row's flags & color palette"); + UI_BoxFlags row_flags = UI_BoxFlag_DisableFocusOverlay; + { + if(row_is_fresh) + { + ui_set_next_tag(str8_lit("fresh")); + row_flags |= UI_BoxFlag_DrawBackground; + } + else if(global_row_idx & 1) + { + ui_set_next_tag(str8_lit("alt")); + row_flags |= UI_BoxFlag_DrawBackground; + } + if(!row_matches_last_row_topology) + { + row_flags |= UI_BoxFlag_DrawSideTop; + } + } + ProfEnd(); + + //////////////////////// + //- rjf: build row box + // + ui_set_next_flags(disabled_flags); + ui_set_next_pref_width(ui_px(contents_width_px, 1.f)); + ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); + ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); + UI_Box *row_box = ui_build_box_from_stringf(row_flags|((!row_node->next)*UI_BoxFlag_DrawSideBottom)|UI_BoxFlag_Clickable, "row_%I64x", row_hash); + + ////////////////////// + //- rjf: build row contents + // + RD_RegsScope(.module = row_info->module->handle) UI_Parent(row_box) + { + //////////////////// + //- rjf: draw start of cache lines in expansions + // + if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) + { + U64 row_offset = row_info->eval.value.u64; + if((row_info->eval.irtree.mode == E_Mode_Offset || row_info->eval.irtree.mode == E_Mode_Null) && + row_offset%64 == 0 && row_depth > 0) + { + ui_set_next_fixed_x(0); + ui_set_next_fixed_y(0); + ui_set_next_fixed_height(ui_top_font_size()*0.2f); + ui_set_next_tag(str8_lit("pop")); + ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } + + ////////////// + //- rjf: draw mid-row cache line boundaries in expansions + // + if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) + { + if((row_info->eval.irtree.mode == E_Mode_Offset || row_info->eval.irtree.mode == E_Mode_Null) && + row_info->eval.value.u64%64 != 0 && + row_depth > 0 && + !row_expanded) + { + U64 next_off = (row_info->eval.value.u64 + e_type_byte_size_from_key(row_info->eval.irtree.type_key)); + if(next_off%64 != 0 && row_info->eval.value.u64/64 < next_off/64) + { + ui_set_next_fixed_x(0); + ui_set_next_fixed_y(row_height_px - ui_top_font_size()*0.5f); + ui_set_next_fixed_height(ui_top_font_size()*1.f); + ui_set_next_tag(str8_lit("pop")); + ui_set_next_transparency(0.5f); + ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } + } + + ////////////// + //- rjf: build all cells + // + S64 cell_x = 0; + F32 cell_x_px = 0; + for(RD_WatchCell *cell = row_info->cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + //////////// + //- rjf: unpack cell info + // + U64 cell_id = rd_id_from_watch_cell(cell); + RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; + RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); + B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); + F32 next_cell_x_px = cell_x_px + cell_width_px; + B32 cell_toggled = (e_value_eval_from_eval(cell_info.eval).value.u64 != 0); + B32 next_cell_toggled = cell_toggled; + + //////////// + //- rjf: determine cell's palette + // + UI_BoxFlags cell_flags = 0; + Vec4F32 cell_background_color_override = {0}; + String8 cell_tag = {0}; + { + if(cell_info.cfg->id == rd_get_hover_regs()->cfg && + rd_state->hover_regs_slot == RD_RegSlot_Cfg) + { + RD_Cfg *cfg = cell_info.cfg; + Vec4F32 rgba = rd_color_from_cfg(cfg); + rgba.w *= 0.05f; + if(rgba.w == 0) + { + rgba = pop_background_rgba; + rgba.w *= 0.5f; + } + rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); + cell_background_color_override = rgba; + cell_flags |= UI_BoxFlag_DrawBackground; + } + else if(ctrl_handle_match(cell_info.entity->handle, rd_get_hover_regs()->ctrl_entity) && + rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity) + { + CTRL_Entity *entity = cell_info.entity; + Vec4F32 rgba = rd_color_from_ctrl_entity(entity); + rgba.w *= 0.05f; + if(rgba.w == 0) + { + rgba = pop_background_rgba; + rgba.w *= 0.5f; + } + rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); + cell_background_color_override = rgba; + cell_flags |= UI_BoxFlag_DrawBackground; + } + } + + //////////// + //- rjf: build cell container + // + UI_Box *cell_box = &ui_nil_box; + UI_PrefWidth(ui_px(cell_width_px, 0.f)) + { + ui_set_next_fixed_height(floor_f32(row->visual_size * row_height_px)); + cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft|cell_flags, "cell_%I64x_%I64x", row_hash, cell_id); + } + + //////////// + //- rjf: build cell contents + // + UI_Signal sig = {0}; + ProfScope("build cell contents") + UI_Parent(cell_box) + UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) + UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) + RD_Font(RD_FontSlot_Code) + UI_TagF("weak") + UI_Tag(cell_tag) + { + //- rjf: cell has errors? -> build error box + if(cell_info.flags & RD_WatchCellFlag_IsErrored) RD_Font(RD_FontSlot_Main) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); + sig = ui_signal_from_box(box); + UI_Parent(box) UI_Flags(0) + { + rd_error_label(cell_info.string); + } + } + + //- rjf: cell has hook? -> build ui by calling hook + else if(cell_info.view_ui_rule != &rd_nil_view_ui_rule) + { + Rng2F32 cell_rect = r2f32p(cell_x_px, 0, next_cell_x_px, row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); + ui_set_next_fixed_y(-1.f * (row_node->visual_size_skipped) * row_height_px); + ui_set_next_fixed_height((row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped) * row_height_px); + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable|UI_BoxFlag_FloatingY, "###val_%I64x", row_hash); + UI_Parent(box) + { + RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, cell_info.view_ui_rule->name); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.exprs.last)); + rd_cfg_new(view, str8_lit("selected")); + RD_RegsScope(.view = view->id, .file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval)) + UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) + UI_Flags(0) + { + // rjf: 'pull out' button + UI_TagF(".") UI_TagF("tab") UI_Rect(r2f32p(ui_top_font_size()*1.5f, + ui_top_font_size()*1.5f, + ui_top_font_size()*1.5f + ui_top_font_size()*3.f, + ui_top_font_size()*1.5f + ui_top_font_size()*3.f)) + UI_CornerRadius(ui_top_font_size()*1.5f) + UI_TextAlignment(UI_TextAlign_Center) + UI_HoverCursor(OS_Cursor_HandPoint) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(ui_top_font_size()*0.8f) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_Floating| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_DrawHotEffects, + "%S###pull_out", + rd_icon_kind_text_table[RD_IconKind_Window]); + UI_Signal sig = ui_signal_from_box(box); + if(ui_dragging(sig) && !contains_2f32(box->rect, ui_mouse())) + { + rd_drag_begin(RD_RegSlot_View); + } + } + + // rjf: loading animation container + UI_Box *loading_overlay_container = &ui_nil_box; + UI_Parent(box) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + } + + // rjf: view ui contents + cell_info.view_ui_rule->ui(cell_info.eval, cell_info.view_ui_tag, cell_rect); + + // rjf: loading fill + UI_Parent(loading_overlay_container) + { + RD_ViewState *vs = rd_view_state_from_cfg(view); + rd_loading_overlay(cell_rect, vs->loading_t, vs->loading_progress_v, vs->loading_progress_v_target); + } + } + + } + sig = ui_signal_from_box(box); + } + + //- rjf: cell is call stack frame? -> build arrow if this is the selected frame, otherwise leave empty + else if(cell->kind == RD_WatchCellKind_CallStackFrame) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); + sig = ui_signal_from_box(box); + if(ctrl_handle_match(row_info->callstack_thread->handle, rd_base_regs()->thread) && + row_info->callstack_unwind_index == rd_base_regs()->unwind_count && + row_info->callstack_inline_depth == rd_base_regs()->inline_depth) + { + UI_Parent(box) UI_Flags(0) UI_TextAlignment(UI_TextAlign_Center) + { + Vec4F32 color = rd_color_from_ctrl_entity(row_info->callstack_thread); + RD_Font(RD_FontSlot_Icons) + UI_Flags(UI_BoxFlag_DisableTextTrunc) + UI_TextColor(color) + ui_label(rd_icon_kind_text_table[RD_IconKind_RightArrow]); + } + } + } + + //- rjf: build general cell + else + { + // rjf: compute visual params + B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); + B32 has_background = !!(cell_info.flags & RD_WatchCellFlag_Background); + B32 is_toggle_switch = (cell_info.eval.irtree.mode != E_Mode_Null && e_type_kind_from_key(cell_info.eval.irtree.type_key) == E_TypeKind_Bool); + B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); + B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); + String8 ghost_text = {0}; + if(cell->kind == RD_WatchCellKind_Expr && cell_info.string.size == 0) + { + ghost_text = str8_lit("Expression"); + is_non_code = !cell_selected || !ewv->text_editing; + } + else if(cell->kind == RD_WatchCellKind_Tag && cell_info.string.size == 0 && global_row_idx == 0) + { + ghost_text = str8_lit("View Rules"); + is_non_code = !cell_selected || !ewv->text_editing; + } + if(cell_selected && ewv->text_editing && cell->kind == RD_WatchCellKind_Expr) + { + is_non_code = 0; + is_button = 0; + is_activated_on_single_click = 0; + } + String8 searched_string = cell_info.string; + if(cell_info.fstrs.node_count != 0) + { + searched_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); + } + String8 search_query = rd_view_query_input(); + FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, search_query, searched_string); + if(fuzzy_matches.count == 0) + { + String8 path_needle = str8_skip_last_slash(search_query); + if(0 < path_needle.size && path_needle.size < search_query.size) + { + fuzzy_matches = fuzzy_match_find(scratch.arena, path_needle, searched_string); + } + } + + // rjf: form cell build parameters + RD_CellParams cell_params = {0}; + { + // rjf: set up base parameters + cell_params.flags = (RD_CellFlag_KeyboardClickable|RD_CellFlag_NoBackground|RD_CellFlag_CodeContents); + cell_params.depth = (cell_x == 0 ? row_depth : 0); + cell_params.cursor = &cell_edit_state->cursor; + cell_params.mark = &cell_edit_state->mark; + cell_params.edit_buffer = cell_edit_state->input_buffer; + cell_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); + cell_params.edit_string_size_out = &cell_edit_state->input_size; + cell_params.expanded_out = &next_row_expanded; + cell_params.pre_edit_value = cell_info.string; + cell_params.fstrs = cell_info.fstrs; + cell_params.fuzzy_matches = &fuzzy_matches; + + // rjf: apply expander (or substitute space) + if(row_is_expandable && cell == row_info->cells.first) + { + cell_params.flags |= RD_CellFlag_Expander; + } + else if(row_depth == !implicit_root && cell == row_info->cells.first) + { + cell_params.flags |= RD_CellFlag_ExpanderSpace; + } + else if(row_depth != 0 && cell == row_info->cells.first) + { + cell_params.flags |= RD_CellFlag_ExpanderSpace; + } + + // rjf: apply single-click-activation + if(is_activated_on_single_click) + { + cell_params.flags |= RD_CellFlag_SingleClickActivate; + } + + // rjf: apply code styles + if(is_non_code) + { + cell_params.flags &= ~RD_CellFlag_CodeContents; + } + + // rjf: apply button styles + if(is_button) + { + cell_params.flags |= RD_CellFlag_Button; + cell_params.flags &= ~RD_CellFlag_NoBackground; + if(row_depth == 0) + { + cell_params.flags &= ~RD_CellFlag_ExpanderSpace; + } + } + + // rjf: apply background + if(has_background) + { + cell_params.flags &= ~RD_CellFlag_NoBackground; + } + + // rjf: apply toggle-switch + if(is_toggle_switch) + { + cell_params.flags |= RD_CellFlag_ToggleSwitch; + cell_params.toggled_out = &next_cell_toggled; + } + } + + // rjf: build + if(cell_background_color_override.w != 0) + { + ui_push_background_color(cell_background_color_override); + } + UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) + RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) + { + sig = rd_cellf(&cell_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); + } + if(cell_background_color_override.w != 0) + { + ui_pop_background_color(); + } +#if 0 // TODO(rjf): @cfg (autocompletion) + if(ui_is_focus_active() && + selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && + txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) + { + String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); + rd_set_autocomp_lister_query(.ui_key = sig.box->key, + .off_px = v2f32(0, dim_2f32(sig.box->rect).y), + .string = input, + .cursor = cell_edit_state->cursor, + .lister_flags = cell_autocomp_flags); + } +#endif + } + } + + //////////// + //- rjf: handle interactions + // + { + // rjf: hover -> rich hover cfgs + if(ui_hovering(sig) && cell_info.cfg != &rd_nil_cfg) + { + RD_RegsScope(.cfg = cell_info.cfg->id, .no_rich_tooltip = 1) rd_set_hover_regs(RD_RegSlot_Cfg); + } + + // rjf: hover -> rich hover entities + if(ui_hovering(sig) && cell_info.entity != &ctrl_entity_nil) + { + RD_RegsScope(.ctrl_entity = cell_info.entity->handle, .no_rich_tooltip = 1) rd_set_hover_regs(RD_RegSlot_CtrlEntity); + } + + // rjf: dragging -> drag/drop + if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) + { + if(cell_info.eval.space.kind == E_SpaceKind_FileSystem) + { + String8 file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval); + RD_RegsScope(.file_path = file_path) rd_drag_begin(RD_RegSlot_FilePath); + } + else if(cell_info.cfg != &rd_nil_cfg) + { + RD_RegsScope(.cfg = cell_info.cfg->id) rd_drag_begin(RD_RegSlot_Cfg); + } + else if(cell_info.entity != &ctrl_entity_nil) + { + RD_RegsScope(.ctrl_entity = cell_info.entity->handle) switch(cell_info.entity->kind) + { + default:{rd_drag_begin(RD_RegSlot_CtrlEntity);}break; + case CTRL_EntityKind_Machine:{RD_RegsScope(.machine = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Machine);}break; + case CTRL_EntityKind_Process:{RD_RegsScope(.process = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Process);}break; + case CTRL_EntityKind_Module:{RD_RegsScope(.module = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Module);}break; + case CTRL_EntityKind_Thread:{RD_RegsScope(.thread = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Thread);}break; + } + } + else if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity || + row_info->eval.space.kind == E_SpaceKind_FileSystem || + row_info->eval.space.kind == E_SpaceKind_File || + row_info->eval.space.kind == E_SpaceKind_Null) + { + RD_RegsScope(.expr = e_string_from_expr(scratch.arena, row_info->eval.exprs.last), + .view_rule = ev_view_rule_from_key(rd_view_eval_view(), row->key)) + rd_drag_begin(RD_RegSlot_Expr); + } + } + + // rjf: (normally) single-click -> move selection here + if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_pressed(sig)) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + pressed = 1; + } + + // rjf: activation (double-click normally, or single-clicks with special buttons) + if((!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_double_clicked(sig)) || + ((cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_clicked(sig)) || + sig.f & UI_SignalFlag_KeyboardPressed) + { + // rjf: kill if a double-clickable cell + if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)) + { + ui_kill_action(); + } + + // rjf: this watch window is being queried? -> move curosr & accept + RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); + if(lister != &rd_nil_cfg) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + rd_cmd(RD_CmdKind_Accept); + } + + // rjf: has a command name? -> push command + else if(cell_info.cmd_name.size != 0) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); + RD_Cfg *cfg = rd_cfg_from_eval_space(row_info->eval.space); + RD_RegsScope(.cfg = cfg->id, .ctrl_entity = entity->handle) + { + if(cfg != &rd_nil_cfg || entity != &ctrl_entity_nil) + { + rd_push_cmd(cell_info.cmd_name, rd_regs()); + } + else + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cell_info.cmd_name); + } + } + } + + // rjf: row has callstack info? -> select unwind + else if(row_info->callstack_thread != &ctrl_entity_nil) + { + rd_cmd(RD_CmdKind_SelectThread, .thread = row_info->callstack_thread->handle); + rd_cmd(RD_CmdKind_SelectUnwind, + .unwind_count = row_info->callstack_unwind_index, + .inline_depth = row_info->callstack_inline_depth); + } + + // rjf: can edit? -> begin editing + else if(!(sig.f & UI_SignalFlag_KeyboardPressed) && cell_info.flags & RD_WatchCellFlag_CanEdit) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + rd_cmd(RD_CmdKind_Edit); + } + + // rjf: can expand? -> expand + else if(sig.f & UI_SignalFlag_KeyboardPressed && row_is_expandable) + { + next_row_expanded = !row_expanded; + } + + // rjf: can't edit, but has address info? -> go to address + else if(cell_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_info.eval.space); + CTRL_Entity *process = ctrl_process_from_entity(entity); + if(process != &ctrl_entity_nil) + { + U64 vaddr = cell_info.eval.value.u64; + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + U64 voff = ctrl_voff_from_vaddr(module, vaddr); + D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); + String8 file_path = {0}; + TxtPt pt = {0}; + if(lines.first != 0) + { + file_path = lines.first->v.file_path; + pt = lines.first->v.pt; + rd_cmd(RD_CmdKind_FindCodeLocation, + .process = process->handle, + .vaddr = vaddr, + .file_path = file_path, + .cursor = pt); + } + } + } + + // rjf: can't edit, but has cfg? -> find or select + else if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) + { + RD_Cfg *cfg = rd_cfg_from_eval_space(cell_info.eval.space); + RD_Location loc = rd_location_from_cfg(cfg); + if(loc.file_path.size != 0) + { + rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = 0, .file_path = loc.file_path, .cursor = loc.pt); + } + else if(loc.expr.size != 0) + { + U64 value = e_value_from_string(loc.expr).u64; + rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = value); + } + else if(str8_match(cfg->string, str8_lit("target"), 0) && sig.event_flags & OS_Modifier_Ctrl) + { + rd_cmd(RD_CmdKind_EnableCfg, .cfg = cfg->id); + } + else if(str8_match(cfg->string, str8_lit("target"), 0)) + { + rd_cmd(RD_CmdKind_SelectCfg, .cfg = cfg->id); + } + } + + // rjf: can't edit, but has thread? -> select + else if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_info.eval.space); + if(entity->kind == CTRL_EntityKind_Thread) + { + rd_cmd(RD_CmdKind_SelectThread, .thread = entity->handle); + } + } + } + + // rjf: hovering with inheritance string -> show tooltip + if(ui_hovering(sig) && cell_info.inheritance_tooltip.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) + { + ui_labelf("Inherited from "); + RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, ui_color_from_name(str8_lit("code_default")), cell_info.inheritance_tooltip); + } + } + + // rjf: hovering with error tooltip -> show tooltip + if(ui_hovering(sig) && cell_info.error_tooltip.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_info.error_tooltip); + } + } + + //////////// + //- rjf: commit toggle changes + // + if(next_cell_toggled != cell_toggled) + { + rd_commit_eval_value_string(cell_info.eval, next_cell_toggled ? str8_lit("1") : str8_lit("0"), 0); + } + + //////////// + //- rjf: bump x pixel coordinate + // + cell_x_px = next_cell_x_px; + } + } + + ////////////////////// + //- rjf: commit expansion state changes + // + if(next_row_expanded != row_expanded) + { + if(!ev_key_match(ev_key_root(), row->key)) + { + ev_key_set_expansion(eval_view, row->block->key, row->key, next_row_expanded); + } + } + } + } + } + } + } + + ////////////////////////////// + //- rjf: general table-wide press logic + // + if(pressed) + { + rd_cmd(RD_CmdKind_FocusPanel); + } + + rd_store_view_scroll_pos(scroll_pos); + scratch_end(scratch); + } + + //////////////////////////// + //- rjf: visualizer hook + // + else + { + Temp scratch = scratch_begin(0, 0); + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); + E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); + E_Expr *tag = rd_tag_from_cfg(scratch.arena, view); + view_ui_rule->ui(expr_eval, tag, rect); + scratch_end(scratch); + } } - return result; -} - -internal Arena * -rd_view_push_arena_ext(RD_View *view) -{ - RD_ArenaExt *ext = push_array(view->arena, RD_ArenaExt, 1); - ext->arena = arena_alloc(); - SLLQueuePush(view->first_arena_ext, view->last_arena_ext, ext); - return ext->arena; -} - -//- rjf: param saving - -internal void -rd_view_store_param(RD_View *view, String8 key, String8 value) -{ - B32 new_copy = 0; - if(view->params_write_gen == view->params_read_gen) + + //////////////////////////// + //- rjf: catchall query completion controls + // + if(vs->query_is_selected) UI_Focus(UI_FocusKind_On) { - view->params_write_gen += 1; - new_copy = 1; + if(ui_is_focus_active() && rd_cfg_child_from_string(view, str8_lit("lister")) == &rd_nil_cfg && ui_slot_press(UI_EventActionSlot_Cancel)) + { + vs->query_is_selected = 0; + vs->query_string_size = 0; + } + if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) + { + String8 cmd_name = rd_view_query_cmd(); + String8 input = rd_view_query_input(); + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + RD_RegsScope() + { + rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, input); + rd_cmd(RD_CmdKind_CompleteQuery); + } + } } - Arena *new_params_arena = view->params_arenas[view->params_write_gen%ArrayCount(view->params_arenas)]; - if(new_copy) - { - arena_clear(new_params_arena); - view->params_roots[view->params_write_gen%ArrayCount(view->params_arenas)] = md_tree_copy(new_params_arena, view->params_roots[view->params_read_gen%ArrayCount(view->params_arenas)]); - } - MD_Node *new_params_root = view->params_roots[view->params_write_gen%ArrayCount(view->params_arenas)]; - if(md_node_is_nil(new_params_root)) - { - new_params_root = view->params_roots[view->params_write_gen%ArrayCount(view->params_arenas)] = md_push_node(new_params_arena, MD_NodeKind_Main, 0, str8_zero(), str8_zero(), 0); - } - MD_Node *key_node = md_child_from_string(new_params_root, key, 0); - if(md_node_is_nil(key_node)) - { - String8 key_copy = push_str8_copy(new_params_arena, key); - key_node = md_push_node(new_params_arena, MD_NodeKind_Main, MD_NodeFlag_Identifier, key_copy, key_copy, 0); - md_node_push_child(new_params_root, key_node); - } - key_node->first = key_node->last = &md_nil_node; - String8 value_copy = push_str8_copy(new_params_arena, value); - MD_TokenizeResult value_tokenize = md_tokenize_from_text(new_params_arena, value_copy); - MD_ParseResult value_parse = md_parse_from_text_tokens(new_params_arena, str8_zero(), value_copy, value_tokenize.tokens); - for MD_EachNode(child, value_parse.root->first) - { - child->parent = key_node; - } - key_node->first = value_parse.root->first; - key_node->last = value_parse.root->last; -} - -internal void -rd_view_store_paramf(RD_View *view, String8 key, char *fmt, ...) -{ - Temp scratch = scratch_begin(0, 0); - va_list args; - va_start(args, fmt); - String8 string = push_str8fv(scratch.arena, fmt, args); - rd_view_store_param(view, key, string); - va_end(args); - scratch_end(scratch); + + vs->last_frame_index_built = rd_state->frame_index; + ProfEnd(); } //////////////////////////////// @@ -3102,33 +5787,280 @@ rd_view_store_paramf(RD_View *view, String8 key, char *fmt, ...) internal Arena * rd_view_arena(void) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - return view->arena; + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + return view_state->arena; } internal UI_ScrollPt2 rd_view_scroll_pos(void) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - return view->scroll_pos; + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + return view_state->scroll_pos; +} + +internal EV_View * +rd_view_eval_view(void) +{ + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + return view_state->ev_view; } internal String8 -rd_view_expr_string(void) +rd_view_query_cmd(void) { - // TODO(rjf): @entity_simplification filter and expr string need to be different - RD_View *view = rd_view_from_handle(rd_regs()->view); - String8 expr_string = str8(view->query_buffer, view->query_string_size); - return expr_string; + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd")); + String8 string = cmd->first->string; + return string; } internal String8 -rd_view_filter(void) +rd_view_query_input(void) { - // TODO(rjf): @entity_simplification filter and expr string need to be different - RD_View *view = rd_view_from_handle(rd_regs()->view); - String8 filter = str8(view->query_buffer, view->query_string_size); - return filter; + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); + String8 string = input->first->string; + return string; +} + +internal RD_Cfg * +rd_view_cfg_from_string(String8 string) +{ + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *cfg = rd_cfg_child_from_string(view, string); + return cfg; +} + +internal E_Value +rd_view_cfg_value_from_string(String8 string) +{ + Temp scratch = scratch_begin(0, 0); + RD_Cfg *root = rd_view_cfg_from_string(string); + String8 expr = root->first->string; + E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Value result = e_value_eval_from_eval(eval).value; + scratch_end(scratch); + return result; +} + +//- rjf: evaluation & tag (a view's 'call') parameter extraction + +internal U64 +rd_base_offset_from_eval(E_Eval eval) +{ + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(eval.irtree.type_key))) + { + eval = e_value_eval_from_eval(eval); + } + return eval.value.u64; +} + +internal Rng1U64 +rd_range_from_eval_tag(E_Eval eval, E_Expr *tag) +{ + U64 size = 0; + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("size"), 0)) + { + size = e_value_from_expr(param->first->next).u64; + break; + } + } + E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); + E_TypeKind type_kind = e_type_kind_from_key(type_key); + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.irtree.type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Union || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Array)) + { + size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.irtree.type_key))); + } + if(size == 0 && eval.irtree.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || + type_kind == E_TypeKind_Union || + type_kind == E_TypeKind_Class || + type_kind == E_TypeKind_Array)) + { + size = e_type_byte_size_from_key(e_type_unwrap(eval.irtree.type_key)); + } + if(size == 0) + { + size = KB(16); + } + Rng1U64 result = {0}; + result.min = rd_base_offset_from_eval(eval); + result.max = result.min + size; + return result; +} + +internal TXT_LangKind +rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) +{ + TXT_LangKind lang_kind = TXT_LangKind_Null; + Temp scratch = scratch_begin(0, 0); + String8 file_path = rd_file_path_from_eval(scratch.arena, eval); + if(file_path.size != 0) + { + lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(file_path)); + } + if(lang_kind == TXT_LangKind_Null) + { + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("lang"), 0)) + { + lang_kind = txt_lang_kind_from_extension(param->first->next->string); + break; + } + } + } + scratch_end(scratch); + return lang_kind; +} + +internal Arch +rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag) +{ + // rjf: try implicitly from either `eval` itself, or from context + CTRL_Entity *ctrl_entity = rd_ctrl_entity_from_eval_space(eval.space); + CTRL_Entity *process = ctrl_process_from_entity(ctrl_entity); + if(process == &ctrl_entity_nil) + { + process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + } + Arch arch = process->arch; + if(arch == Arch_Null) + { + arch = arch_from_context(); + } + + // rjf: try arch parameters + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + String8 param_arch_string = param->string; + if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("arch"), 0)) + { + param_arch_string = param->first->next->string; + } + if(str8_match(param->first->next->string, str8_lit("x64"), 0)) + { + arch = Arch_x64; + break; + } + } + + return arch; +} + +internal Vec2S32 +rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag) +{ + Vec2S32 dim = v2s32(1, 1); + B32 got_x = 0; + B32 got_y = 0; + + // rjf: try explicitly passed dimensions + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + if(param->kind == E_ExprKind_Define) + { + if(str8_match(param->first->string, str8_lit("w"), 0)) + { + got_x = 1; + dim.x = e_value_from_expr(param->first->next).s64; + } + if(str8_match(param->first->string, str8_lit("h"), 0)) + { + got_y = 1; + dim.y = e_value_from_expr(param->first->next).s64; + } + } + } + + // rjf: try ordered non-define arguments + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + if(param->kind != E_ExprKind_Define) + { + if(!got_x) + { + got_x = 1; + dim.x = e_value_from_expr(param).s64; + } + else if(!got_y) + { + got_y = 1; + dim.y = e_value_from_expr(param).s64; + break; + } + } + } + + return dim; +} + +internal R_Tex2DFormat +rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag) +{ + R_Tex2DFormat fmt = R_Tex2DFormat_RGBA8; + B32 got_fmt = 0; + + // rjf: try explicitly passed formats + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("fmt"), 0)) + { + got_fmt = 1; + for EachEnumVal(R_Tex2DFormat, f) + { + if(str8_match(param->first->next->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + { + fmt = f; + break; + } + } + } + } + + // rjf: try implicit non-define arguments + for(E_Expr *param = tag->first->next; param != &e_expr_nil && !got_fmt; param = param->next) + { + if(param->kind == E_ExprKind_LeafIdent) + { + for EachEnumVal(R_Tex2DFormat, f) + { + if(str8_match(param->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + { + fmt = f; + break; + } + } + } + } + + return fmt; +} + +internal E_Value +rd_value_from_eval_tag_key(E_Eval eval, E_Expr *tag, String8 key) +{ + E_Value value = zero_struct; + for(E_Expr *arg = tag->first->next; arg != &e_expr_nil; arg = arg->next) + { + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, key, 0)) + { + value = e_value_from_expr(arg->first->next); + break; + } + } + return value; } //- rjf: pushing/attaching view resources @@ -3136,17 +6068,24 @@ rd_view_filter(void) internal void * rd_view_state_by_size(U64 size) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - void *result = rd_view_get_or_push_user_state(view, size); - return result; + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + if(view_state->user_data == 0) + { + view_state->user_data = push_array(view_state->arena, U8, size); + } + return view_state->user_data; } internal Arena * rd_push_view_arena(void) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - Arena *result = rd_view_push_arena_ext(view); - return result; + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + RD_ArenaExt *ext = push_array(view_state->arena, RD_ArenaExt, 1); + ext->arena = arena_alloc(); + SLLQueuePush(view_state->first_arena_ext, view_state->last_arena_ext, ext); + return ext->arena; } //- rjf: storing view-attached state @@ -3154,38 +6093,47 @@ rd_push_view_arena(void) internal void rd_store_view_expr_string(String8 string) { - // TODO(rjf): @entity_simplification filter and expr string need to be different - RD_View *view = rd_view_from_handle(rd_regs()->view); - rd_view_equip_query(view, string); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new_replace(expr, string); } internal void rd_store_view_filter(String8 string) { - // TODO(rjf): @entity_simplification filter and expr string need to be different - RD_View *view = rd_view_from_handle(rd_regs()->view); - rd_view_equip_query(view, string); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *filter = rd_cfg_child_from_string_or_alloc(view, str8_lit("filter")); + rd_cfg_new_replace(filter, string); } internal void rd_store_view_loading_info(B32 is_loading, U64 progress_u64, U64 progress_u64_target) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - rd_view_equip_loading_info(view, is_loading, progress_u64, progress_u64_target); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + view_state->loading_t_target = (F32)!!is_loading; + view_state->loading_progress_v = progress_u64; + view_state->loading_progress_v_target = progress_u64_target; + if(view_state->last_frame_index_built+1 < rd_state->frame_index) + { + view_state->loading_t = view_state->loading_t_target; + } } internal void rd_store_view_scroll_pos(UI_ScrollPt2 pos) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - view->scroll_pos = pos; + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + view_state->scroll_pos = pos; } internal void rd_store_view_param(String8 key, String8 value) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - rd_view_store_param(view, key, value); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *child = rd_cfg_child_from_string_or_alloc(view, key); + rd_cfg_new_replace(child, value); } internal void @@ -3201,151 +6149,305 @@ rd_store_view_paramf(String8 key, char *fmt, ...) } //////////////////////////////// -//~ rjf: Expand-Keyed Transient View Functions +//~ rjf: Window Functions -internal RD_TransientViewNode * -rd_transient_view_node_from_ev_key(RD_View *owner_view, EV_Key key) +internal RD_Cfg * +rd_window_from_cfg(RD_Cfg *cfg) { - if(owner_view->transient_view_slots_count == 0) + RD_Cfg *result = &rd_nil_cfg; + for(RD_Cfg *c = cfg; c != &rd_nil_cfg; c = c->parent) { - owner_view->transient_view_slots_count = 256; - owner_view->transient_view_slots = push_array(owner_view->arena, RD_TransientViewSlot, owner_view->transient_view_slots_count); - } - U64 hash = ev_hash_from_key(key); - U64 slot_idx = hash%owner_view->transient_view_slots_count; - RD_TransientViewSlot *slot = &owner_view->transient_view_slots[slot_idx]; - RD_TransientViewNode *node = 0; - for(RD_TransientViewNode *n = slot->first; n != 0; n = n->next) - { - if(ev_key_match(n->key, key)) + if(c->parent->parent == rd_state->root_cfg && str8_match(c->string, str8_lit("window"), 0)) { - node = n; - n->last_frame_index_touched = rd_state->frame_index; + result = c; break; } } - if(node == 0) + return result; +} + +internal RD_WindowState * +rd_window_state_from_cfg(RD_Cfg *cfg) +{ + //- rjf: unpack + RD_Cfg *window_cfg = rd_window_from_cfg(cfg); + RD_CfgID id = window_cfg->id; + U64 hash = d_hash_from_string(str8_struct(&id)); + U64 slot_idx = hash%rd_state->window_state_slots_count; + RD_WindowStateSlot *slot = &rd_state->window_state_slots[slot_idx]; + + //- rjf: scan for existing window + RD_WindowState *ws = &rd_nil_window_state; + for(RD_WindowState *w = slot->first; w != 0; w = w->hash_next) { - if(!owner_view->free_transient_view_node) + if(w->cfg_id == id) { - owner_view->free_transient_view_node = push_array(rd_state->arena, RD_TransientViewNode, 1); - } - node = owner_view->free_transient_view_node; - SLLStackPop(owner_view->free_transient_view_node); - DLLPushBack(slot->first, slot->last, node); - node->key = key; - node->view = rd_view_alloc(); - node->initial_params_arena = arena_alloc(); - node->first_frame_index_touched = node->last_frame_index_touched = rd_state->frame_index; - DLLPushBack_NPZ(&rd_nil_view, owner_view->first_transient, owner_view->last_transient, node->view, order_next, order_prev); - } - return node; -} - -//////////////////////////////// -//~ rjf: Panel State Functions - -internal RD_Panel * -rd_panel_alloc(RD_Window *ws) -{ - RD_Panel *panel = ws->free_panel; - if(!rd_panel_is_nil(panel)) - { - SLLStackPop(ws->free_panel); - U64 generation = panel->generation; - MemoryZeroStruct(panel); - panel->generation = generation; - } - else - { - panel = push_array(ws->arena, RD_Panel, 1); - } - panel->first = panel->last = panel->next = panel->prev = panel->parent = &rd_nil_panel; - panel->first_tab_view = panel->last_tab_view = &rd_nil_view; - panel->generation += 1; - MemoryZeroStruct(&panel->animated_rect_pct); - return panel; -} - -internal void -rd_panel_release(RD_Window *ws, RD_Panel *panel) -{ - rd_panel_release_all_views(panel); - SLLStackPush(ws->free_panel, panel); - panel->generation += 1; -} - -internal void -rd_panel_release_all_views(RD_Panel *panel) -{ - for(RD_View *view = panel->first_tab_view, *next = 0; !rd_view_is_nil(view); view = next) - { - next = view->order_next; - rd_view_release(view); - } - panel->first_tab_view = panel->last_tab_view = &rd_nil_view; - panel->selected_tab_view = rd_handle_zero(); - panel->tab_view_count = 0; -} - -//////////////////////////////// -//~ rjf: Window State Functions - -internal RD_Window * -rd_window_open(Vec2F32 size, OS_Handle preferred_monitor, RD_CfgSrc cfg_src) -{ - RD_Window *window = rd_state->free_window; - if(window != 0) - { - SLLStackPop(rd_state->free_window); - U64 gen = window->gen; - MemoryZeroStruct(window); - window->gen = gen; - } - else - { - window = push_array(rd_state->arena, RD_Window, 1); - } - window->gen += 1; - window->frames_alive = 0; - window->cfg_src = cfg_src; - window->arena = arena_alloc(); - { - String8 title = str8_lit_comp(BUILD_TITLE_STRING_LITERAL); - window->os = os_window_open(size, OS_WindowFlag_CustomBorder, title); - } - window->r = r_window_equip(window->os); - window->ui = ui_state_alloc(); - window->ctx_menu_arena = arena_alloc(); - window->ctx_menu_regs = push_array(window->ctx_menu_arena, RD_Regs, 1); - window->ctx_menu_input_buffer_size = KB(4); - window->ctx_menu_input_buffer = push_array(window->arena, U8, window->ctx_menu_input_buffer_size); - window->drop_completion_arena = arena_alloc(); - window->hover_eval_arena = arena_alloc(); - window->autocomp_lister_params_arena = arena_alloc(); - window->free_panel = &rd_nil_panel; - window->root_panel = rd_panel_alloc(window); - window->focused_panel = window->root_panel; - window->query_cmd_arena = arena_alloc(); - window->query_view_stack_top = &rd_nil_view; - window->last_dpi = os_dpi_from_window(window->os); - for EachEnumVal(RD_SettingCode, code) - { - if(rd_setting_code_default_is_per_window_table[code]) - { - window->setting_vals[code] = rd_setting_code_default_val_table[code]; + ws = w; + break; } } - window->setting_vals[RD_SettingCode_MainFontSize].s32 = window->setting_vals[RD_SettingCode_MainFontSize].s32 * (window->last_dpi / 96.f); - window->setting_vals[RD_SettingCode_CodeFontSize].s32 = window->setting_vals[RD_SettingCode_CodeFontSize].s32 * (window->last_dpi / 96.f); - window->setting_vals[RD_SettingCode_MainFontSize].s32 = ClampBot(window->setting_vals[RD_SettingCode_MainFontSize].s32, rd_setting_code_default_val_table[RD_SettingCode_MainFontSize].s32); - window->setting_vals[RD_SettingCode_CodeFontSize].s32 = ClampBot(window->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)) + + //- rjf: allocate/open new window if one was not found + if(window_cfg != &rd_nil_cfg && ws == &rd_nil_window_state) { - os_window_set_monitor(window->os, preferred_monitor); + Temp scratch = scratch_begin(0, 0); + rd_state->frame_depth += 1; + + // rjf: unpack configuration options + B32 has_pos = 0; + Vec2F32 pos = {0}; + Vec2F32 size = {0}; + OS_Handle preferred_monitor = {0}; + { + RD_Cfg *pos_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("pos")); + has_pos = (pos_cfg != &rd_nil_cfg); + RD_Cfg *size_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("size")); + RD_Cfg *monitor_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("monitor")); + pos.x = (F32)f64_from_str8(pos_cfg->first->string); + pos.y = (F32)f64_from_str8(pos_cfg->first->next->string); + size.x = (F32)f64_from_str8(size_cfg->first->string); + size.y = (F32)f64_from_str8(size_cfg->first->next->string); + OS_HandleArray monitors = os_push_monitors_array(scratch.arena); + for EachIndex(idx, monitors.count) + { + String8 monitor_name = os_name_from_monitor(scratch.arena, monitors.v[idx]); + if(str8_match(monitor_name, monitor_cfg->first->string, StringMatchFlag_CaseInsensitive)) + { + preferred_monitor = monitors.v[idx]; + break; + } + } + } + + // rjf: allocate window + ws = rd_state->free_window_state; + if(ws != 0) + { + SLLStackPop_N(rd_state->free_window_state, order_next); + } + else + { + ws = push_array_no_zero(rd_state->arena, RD_WindowState, 1); + } + MemoryZeroStruct(ws); + + // rjf: fill out window + ws->cfg_id = id; + ws->arena = arena_alloc(); + { + String8 title = str8_lit_comp(BUILD_TITLE_STRING_LITERAL); + ws->os = os_window_open(r2f32p(pos.x, pos.y, pos.x+size.x, pos.y+size.y), (!has_pos*OS_WindowFlag_UseDefaultPosition)|OS_WindowFlag_CustomBorder, title); + } + ws->r = r_window_equip(ws->os); + ws->ui = ui_state_alloc(); + ws->drop_completion_arena = arena_alloc(); + ws->hover_eval_arena = arena_alloc(); + ws->query_arena = arena_alloc(); + ws->last_dpi = os_dpi_from_window(ws->os); + OS_Handle zero_monitor = {0}; + if(!os_handle_match(zero_monitor, preferred_monitor)) + { + os_window_set_monitor(ws->os, preferred_monitor); + } + if(rd_cfg_child_from_string(window_cfg, str8_lit("fullscreen")) != &rd_nil_cfg) + { + os_window_set_fullscreen(ws->os, 1); + } + if(rd_cfg_child_from_string(window_cfg, str8_lit("maximized")) != &rd_nil_cfg) + { + os_window_set_maximized(ws->os, 1); + } + + // rjf: hook up window links + DLLPushBack_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); + DLLPushBack_NP(slot->first, slot->last, ws, hash_next, hash_prev); + + rd_state->frame_depth -= 1; + scratch_end(scratch); } - if(rd_state->first_window == 0) RD_RegsScope(.window = rd_handle_from_window(window)) + + //- rjf: touch window for this frame + if(ws != &rd_nil_window_state) + { + ws->last_frame_index_touched = rd_state->frame_index; + } + + return ws; +} + +internal RD_WindowState * +rd_window_state_from_os_handle(OS_Handle os) +{ + RD_WindowState *ws = &rd_nil_window_state; + { + for(RD_WindowState *w = rd_state->first_window_state; + w != &rd_nil_window_state; + w = w->order_next) + { + if(os_handle_match(w->os, os)) + { + ws = w; + break; + } + } + } + return ws; +} + +#if COMPILER_MSVC && !BUILD_DEBUG +#pragma optimize("", off) +#endif + +internal void +rd_window_frame(void) +{ + Temp scratch = scratch_begin(0, 0); + ProfBeginFunction(); + + ////////////////////////////// + //- rjf: @window_frame_part unpack context + // + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(rd_cfg_from_id(rd_regs()->window)); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + B32 window_is_focused = (os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc); + B32 popup_is_open = (rd_state->popup_active); + B32 query_is_open = (ws->query_is_active); + U64 hover_eval_open_delay_us = 400000; + B32 hover_eval_is_open = (!popup_is_open && + !query_is_open && + ws->hover_eval_string.size != 0 && + ws->hover_eval_firstt_us+hover_eval_open_delay_us < ws->hover_eval_lastt_us && + rd_state->time_in_us - ws->hover_eval_lastt_us < hover_eval_open_delay_us); + if(!window_is_focused || popup_is_open) + { + ws->menu_bar_key_held = 0; + } + ws->window_temporarily_focused_ipc = 0; + ui_select_state(ws->ui); + + ////////////////////////////// + //- rjf: @window_frame_part compute window's theme + // + { + //- rjf: for this window, scan upwards, and then try the project, then the user, until we + // find explicit preset / colors trees in the config. we will prefer the tightest ones, so + // that windows can have their own colors, and have those override higher-up settings. + RD_Cfg *preset_cfg = &rd_nil_cfg; + RD_CfgList colors_cfgs = {0}; + RD_Cfg *scan_parents[] = {window, rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user"))}; + for EachElement(idx, scan_parents) + { + for(RD_Cfg *parent_cfg = scan_parents[idx]; parent_cfg != &rd_nil_cfg; parent_cfg = parent_cfg->parent) + { + if(preset_cfg != &rd_nil_cfg) + { + RD_Cfg *possible_preset_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("color_preset")); + if(possible_preset_cfg != &rd_nil_cfg) + { + preset_cfg = possible_preset_cfg; + } + } + RD_Cfg *colors_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("colors")); + if(colors_cfg != &rd_nil_cfg) + { + rd_cfg_list_push_front(scratch.arena, &colors_cfgs, colors_cfg); + } + if(preset_cfg != &rd_nil_cfg && colors_cfg != &rd_nil_cfg) + { + break; + } + } + } + + //- rjf: map the preset config to the associated preset tree + MD_Node *preset_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark]; + if(preset_cfg != &rd_nil_cfg) + { + String8 preset_name = preset_cfg->first->string; + for EachEnumVal(RD_ThemePreset, p) + { + if(str8_match(preset_name, rd_theme_preset_code_string_table[p], 0)) + { + preset_tree = rd_state->theme_preset_trees[p]; + break; + } + } + } + + //- rjf: build tasks for color applications - each task comprises of a metadesk + // tree, describing the color patterns + typedef struct ThemeTask ThemeTask; + struct ThemeTask + { + ThemeTask *next; + MD_Node *tree; + }; + ThemeTask start_task = {0, preset_tree}; + ThemeTask *first_task = &start_task; + ThemeTask *last_task = first_task; + { + for(RD_CfgNode *n = colors_cfgs.first; n != 0; n = n->next) + { + ThemeTask *t = push_array(scratch.arena, ThemeTask, 1); + SLLQueuePush(first_task, last_task, t); + t->tree = md_tree_from_string(scratch.arena, rd_string_from_cfg_tree(scratch.arena, n->v)); + } + } + + //- rjf: apply theme tasks, build each color pattern for this window's + // structured theme + typedef struct ThemePatternNode ThemePatternNode; + struct ThemePatternNode + { + ThemePatternNode *next; + UI_ThemePattern pattern; + }; + ThemePatternNode *first_pattern = 0; + ThemePatternNode *last_pattern = 0; + U64 pattern_count = 0; + for(ThemeTask *t = first_task; t != 0; t = t->next) + { + MD_Node *tree_root = t->tree; + for(MD_Node *n = tree_root; !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, tree_root).next) + { + if(n->flags & MD_NodeFlag_Numeric && md_node_is_nil(n->first)) + { + U64 color_srgba_u64 = 0; + try_u64_from_str8_c_rules(n->string, &color_srgba_u64); + Vec4F32 color_srgba = rgba_from_u32((U32)color_srgba_u64); + Vec4F32 color_linear = linear_from_srgba(color_srgba); + String8List tags = {0}; + for(MD_Node *parent = n->parent; parent != tree_root && !md_node_is_nil(parent); parent = parent->parent) + { + str8_list_push(scratch.arena, &tags, push_str8_copy(rd_frame_arena(), parent->string)); + } + ThemePatternNode *node = push_array(scratch.arena, ThemePatternNode, 1); + node->pattern.tags = str8_array_from_list(rd_frame_arena(), &tags); + node->pattern.linear = color_linear; + SLLQueuePush(first_pattern, last_pattern, node); + pattern_count += 1; + } + } + } + + //- rjf: convert to final pattern array + ws->theme = push_array(rd_frame_arena(), UI_Theme, 1); + ws->theme->patterns_count = pattern_count; + ws->theme->patterns = push_array(rd_frame_arena(), UI_ThemePattern, ws->theme->patterns_count); + { + U64 idx = 0; + for(ThemePatternNode *n = first_pattern; n != 0; n = n->next, idx += 1) + { + ws->theme->patterns[idx] = n->pattern; + } + } + } + + ////////////////////////////// + //- rjf: @window_frame_part pre-emptively rasterize common glyphs on the first frame + // + if(rd_state->first_window_state == ws && rd_state->last_window_state == ws && ws->frames_alive == 0) { RD_FontSlot english_font_slots[] = {RD_FontSlot_Main, RD_FontSlot_Code}; RD_FontSlot icon_font_slot = RD_FontSlot_Icons; @@ -3387,181 +6489,109 @@ rd_window_open(Vec2F32 size, OS_Handle preferred_monitor, RD_CfgSrc cfg_src) scratch_end(scratch); } } - DLLPushBack(rd_state->first_window, rd_state->last_window, window); - return window; -} - -internal RD_Window * -rd_window_from_os_handle(OS_Handle os) -{ - RD_Window *result = 0; - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) - { - if(os_handle_match(w->os, os)) - { - result = w; - break; - } - } - return result; -} - -#if COMPILER_MSVC && !BUILD_DEBUG -#pragma optimize("", off) -#endif - -internal void -rd_window_frame(RD_Window *ws) -{ - ProfBeginFunction(); ////////////////////////////// - //- rjf: unpack context + //- rjf: @window_frame_part commit window's position/status to underlying cfg tree // - B32 window_is_focused = os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc; - B32 popup_open = rd_state->popup_active; - B32 query_is_open = !rd_view_is_nil(ws->query_view_stack_top); - B32 hover_eval_is_open = (!popup_open && - ws->hover_eval_string.size != 0 && - ws->hover_eval_first_frame_idx+20 < ws->hover_eval_last_frame_idx && - rd_state->frame_index-ws->hover_eval_last_frame_idx < 20); - if(!window_is_focused || popup_open) { - ws->menu_bar_key_held = 0; - } - ws->window_temporarily_focused_ipc = 0; - ui_select_state(ws->ui); - - ////////////////////////////// - //- rjf: panels with no selected tabs? -> select. - // panels with selected tabs? -> ensure they have active tabs. - // - for(RD_Panel *panel = ws->root_panel; - !rd_panel_is_nil(panel); - panel = rd_panel_rec_depth_first_pre(panel).next) - { - if(!rd_panel_is_nil(panel->first)) + Temp scratch = scratch_begin(0, 0); + B32 is_fullscreen = os_window_is_fullscreen(ws->os); + B32 is_maximized = os_window_is_maximized(ws->os); + if(is_fullscreen) { - continue; + rd_cfg_child_from_string_or_alloc(window, str8_lit("fullscreen")); } - RD_View *view = rd_selected_tab_from_panel(panel); - if(rd_view_is_nil(view)) + else { - for(RD_View *tab = panel->first_tab_view; !rd_view_is_nil(tab); tab = tab->order_next) + rd_cfg_release(rd_cfg_child_from_string(window, str8_lit("fullscreen"))); + } + if(is_maximized) + { + rd_cfg_child_from_string_or_alloc(window, str8_lit("maximized")); + } + else + { + rd_cfg_release(rd_cfg_child_from_string(window, str8_lit("maximized"))); + } + + //- rjf: commit position + Rng2F32 window_rect = os_rect_from_window(ws->os); + if(!is_fullscreen && !is_maximized) + { + Vec2F32 pos = window_rect.p0; + RD_Cfg *pos_root = rd_cfg_child_from_string_or_alloc(window, str8_lit("pos")); + if((S32)pos.x != (S32)f64_from_str8(pos_root->first->string) || + (S32)pos.y != (S32)f64_from_str8(pos_root->last->string)) { - if(!rd_view_is_project_filtered(tab)) + RD_Cfg *x = pos_root->first; + if(x == &rd_nil_cfg) { - panel->selected_tab_view = rd_handle_from_view(tab); - break; + x= rd_cfg_alloc(); + rd_cfg_insert_child(pos_root, &rd_nil_cfg, x); } - } - } - if(!rd_view_is_nil(view)) - { - B32 found = 0; - for(RD_View *tab = panel->first_tab_view; !rd_view_is_nil(tab); tab = tab->order_next) - { - if(rd_view_is_project_filtered(tab)) {continue;} - if(tab == view) + RD_Cfg *y = x->next; + if(y == &rd_nil_cfg) { - found = 1; + y = rd_cfg_alloc(); + rd_cfg_insert_child(pos_root, x, y); } - } - if(!found) - { - panel->selected_tab_view = rd_handle_zero(); + rd_cfg_equip_stringf(x, "%i", (S32)pos.x); + rd_cfg_equip_stringf(y, "%i", (S32)pos.y); } } + + //- rjf: commit size + if(!is_fullscreen && !is_maximized) + { + Vec2F32 size = dim_2f32(window_rect); + RD_Cfg *size_root = rd_cfg_child_from_string_or_alloc(window, str8_lit("size")); + if((S32)size.x != (S32)f64_from_str8(size_root->first->string) || + (S32)size.y != (S32)f64_from_str8(size_root->last->string)) + { + RD_Cfg *width = size_root->first; + if(width == &rd_nil_cfg) + { + width = rd_cfg_alloc(); + rd_cfg_insert_child(size_root, &rd_nil_cfg, width); + } + RD_Cfg *height = width->next; + if(height == &rd_nil_cfg) + { + height = rd_cfg_alloc(); + rd_cfg_insert_child(size_root, width, height); + } + rd_cfg_equip_stringf(width, "%i", (S32)size.x); + rd_cfg_equip_stringf(height, "%i", (S32)size.y); + } + } + + //- rjf: commit monitor + { + OS_Handle monitor = os_monitor_from_window(ws->os); + String8 monitor_name = os_name_from_monitor(scratch.arena, monitor); + RD_Cfg *monitor_root = rd_cfg_child_from_string_or_alloc(window, str8_lit("monitor")); + if(!str8_match(monitor_root->first->string, monitor_name, 0)) + { + rd_cfg_new_replace(monitor_root, monitor_name); + } + } + scratch_end(scratch); } ////////////////////////////// - //- rjf: fill panel/view interaction registers + //- rjf: @window_frame_part fill panel/view interaction registers // - rd_regs()->panel = rd_handle_from_panel(ws->focused_panel); - rd_regs()->view = ws->focused_panel->selected_tab_view; + rd_regs()->panel = panel_tree.focused->cfg->id; + rd_regs()->view = panel_tree.focused->selected_tab->id; ////////////////////////////// - //- rjf: compute ui palettes from theme + //- rjf: @window_frame_part build UI // - { - RD_Theme *current = &rd_state->cfg_theme; - for EachEnumVal(RD_PaletteCode, code) - { - ws->cfg_palettes[code].null = v4f32(1, 0, 1, 1); - ws->cfg_palettes[code].cursor = current->colors[RD_ThemeColor_Cursor]; - ws->cfg_palettes[code].selection = current->colors[RD_ThemeColor_SelectionOverlay]; - } - ws->cfg_palettes[RD_PaletteCode_Base].background = current->colors[RD_ThemeColor_BaseBackground]; - ws->cfg_palettes[RD_PaletteCode_Base].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_Base].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_Base].border = current->colors[RD_ThemeColor_BaseBorder]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].background = current->colors[RD_ThemeColor_MenuBarBackground]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].border = current->colors[RD_ThemeColor_MenuBarBorder]; - ws->cfg_palettes[RD_PaletteCode_Floating].background = current->colors[RD_ThemeColor_FloatingBackground]; - ws->cfg_palettes[RD_PaletteCode_Floating].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_Floating].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_Floating].border = current->colors[RD_ThemeColor_FloatingBorder]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].background = current->colors[RD_ThemeColor_ImplicitButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].border = current->colors[RD_ThemeColor_ImplicitButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].background = current->colors[RD_ThemeColor_PlainButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].border = current->colors[RD_ThemeColor_PlainButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].background = current->colors[RD_ThemeColor_PositivePopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].border = current->colors[RD_ThemeColor_PositivePopButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].background = current->colors[RD_ThemeColor_NegativePopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].border = current->colors[RD_ThemeColor_NegativePopButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].background = current->colors[RD_ThemeColor_NeutralPopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].border = current->colors[RD_ThemeColor_NeutralPopButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].background = current->colors[RD_ThemeColor_ScrollBarButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].border = current->colors[RD_ThemeColor_ScrollBarButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_Tab].background = current->colors[RD_ThemeColor_TabBackground]; - ws->cfg_palettes[RD_PaletteCode_Tab].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_Tab].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_Tab].border = current->colors[RD_ThemeColor_TabBorder]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].background = current->colors[RD_ThemeColor_TabBackgroundInactive]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].border = current->colors[RD_ThemeColor_TabBorderInactive]; - ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].background = current->colors[RD_ThemeColor_DropSiteOverlay]; - 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) - { - for EachEnumVal(RD_PaletteCode, code) - { - if(ws->cfg_palettes[code].background.x != 0 || - ws->cfg_palettes[code].background.y != 0 || - ws->cfg_palettes[code].background.z != 0) - { - ws->cfg_palettes[code].background.w = 1; - } - } - } - } - - ////////////////////////////// - //- rjf: build UI - // - UI_Box *autocomp_box = &ui_nil_box; - UI_Box *hover_eval_box = &ui_nil_box; + UI_Box *lister_box = &ui_nil_box; ProfScope("build UI") { //////////////////////////// - //- rjf: set up + //- rjf: @window_ui_part set up // { // rjf: gather font info @@ -3585,99 +6615,97 @@ rd_window_frame(RD_Window *ws) icon_info.icon_kind_text_map[UI_IconKind_CheckFilled] = rd_icon_kind_text_table[RD_IconKind_CheckFilled]; } - // rjf: build widget palette info - UI_WidgetPaletteInfo widget_palette_info = {0}; - { - widget_palette_info.tooltip_palette = rd_palette_from_code(RD_PaletteCode_Floating); - widget_palette_info.ctx_menu_palette = rd_palette_from_code(RD_PaletteCode_Floating); - widget_palette_info.scrollbar_palette = rd_palette_from_code(RD_PaletteCode_ScrollBarButton); - } - // 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_name(str8_lit("hover_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_HotAnimations;} + if(rd_setting_b32_from_name(str8_lit("press_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ActiveAnimations;} + if(rd_setting_b32_from_name(str8_lit("focus_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_FocusAnimations;} + if(rd_setting_b32_from_name(str8_lit("tooltip_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_TooltipAnimations;} + if(rd_setting_b32_from_name(str8_lit("menu_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ContextMenuAnimations;} + if(rd_setting_b32_from_name(str8_lit("scrolling_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ScrollingAnimations;} } // rjf: begin & push initial stack values - ui_begin_build(ws->os, &ws->ui_events, &icon_info, &widget_palette_info, &animation_info, rd_state->frame_dt, rd_state->frame_dt); + ui_begin_build(ws->os, &ws->ui_events, &icon_info, ws->theme, &animation_info, rd_state->frame_dt, rd_state->frame_dt); ui_push_font(main_font); ui_push_font_size(main_font_size); ui_push_text_padding(main_font_size*0.3f); - ui_push_pref_width(ui_em(20.f, 1)); - ui_push_pref_height(ui_em(2.75f, 1.f)); - ui_push_palette(rd_palette_from_code(RD_PaletteCode_Base)); + ui_push_pref_width(ui_px(floor_f32(ui_top_font_size()*20.f), 1.f)); + ui_push_pref_height(ui_px(floor_f32(ui_top_font_size()*3.f), 1.f)); 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_name(str8_lit("smooth_main_text"))) {text_raster_flags |= FNT_RasterFlag_Smooth;} + if(rd_setting_b32_from_name(str8_lit("hint_main_text"))) {text_raster_flags |= FNT_RasterFlag_Hinted;} ui_push_text_raster_flags(text_raster_flags); } //////////////////////////// - //- rjf: calculate top-level rectangles + //- rjf: @window_ui_part calculate top-level rectangles/sizes // Rng2F32 window_rect = os_client_rect_from_window(ws->os); Vec2F32 window_rect_dim = dim_2f32(window_rect); - Rng2F32 top_bar_rect = r2f32p(window_rect.x0, window_rect.y0, window_rect.x0+window_rect_dim.x+1, window_rect.y0+ui_top_pref_height().value); - Rng2F32 bottom_bar_rect = r2f32p(window_rect.x0, window_rect_dim.y - ui_top_pref_height().value, window_rect.x0+window_rect_dim.x, window_rect.y0+window_rect_dim.y); + Rng2F32 top_bar_rect = r2f32p(window_rect.x0, window_rect.y0, window_rect.x0+window_rect_dim.x+1, window_rect.y0+ui_top_px_height()); + Rng2F32 bottom_bar_rect = r2f32p(window_rect.x0, window_rect_dim.y - ui_top_px_height(), window_rect.x0+window_rect_dim.x, window_rect.y0+window_rect_dim.y); Rng2F32 content_rect = r2f32p(window_rect.x0, top_bar_rect.y1, window_rect.x0+window_rect_dim.x, bottom_bar_rect.y0); F32 window_edge_px = os_dpi_from_window(ws->os)*0.035f; content_rect = pad_2f32(content_rect, -window_edge_px); //////////////////////////// - //- rjf: truncated string hover + //- rjf: @window_ui_part truncated string hover // if(ui_string_hover_active()) UI_Tooltip { Temp scratch = scratch_begin(0, 0); - String8 string = ui_string_hover_string(scratch.arena); - DR_FancyRunList runs = ui_string_hover_runs(scratch.arena); + DR_FStrList fstrs = ui_string_hover_fstrs(scratch.arena); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_string_fancy_runs(box, string, &runs); + ui_box_equip_display_fstrs(box, &fstrs); scratch_end(scratch); } //////////////////////////// - //- rjf: rich hover, drag/drop tooltips + //- rjf: @window_ui_part rich hover / drag/drop tooltips // - if(rd_state->hover_regs_slot != RD_RegSlot_Null || - (rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active())) + if((rd_state->hover_regs_slot != RD_RegSlot_Null && !rd_state->hover_regs->no_rich_tooltip) || (rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active())) { Temp scratch = scratch_begin(0, 0); RD_RegSlot slot = ((rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active()) ? rd_state->drag_drop_regs_slot : rd_state->hover_regs_slot); RD_Regs *regs = (((rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active()) ? rd_state->drag_drop_regs : rd_state->hover_regs)); CTRL_Entity *ctrl_entity = &ctrl_entity_nil; - RD_Palette(RD_PaletteCode_Floating) switch(slot) + switch(slot) { default:{}break; //////////////////////// - //- rjf: frontend entity tooltips + //- rjf: file path tooltips // - case RD_RegSlot_Entity: + case RD_RegSlot_FilePath: + UI_Tooltip + { + FileProperties props = os_properties_from_file_path(regs->file_path); + ui_set_next_pref_width(ui_children_sum(1)); + UI_Row + { + RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[props.flags & FilePropertyFlag_IsFolder ? RD_IconKind_FolderClosedFilled : RD_IconKind_FileOutline]); + ui_label(regs->file_path); + } + }break; + + //////////////////////// + //- rjf: cfg tooltips + // + case RD_RegSlot_Cfg: UI_Tooltip { // rjf: unpack - RD_Entity *entity = rd_entity_from_handle(regs->entity); - DR_FancyStringList fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), ui_top_font_size()); + RD_Cfg *cfg = rd_cfg_from_id(regs->cfg); + DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, cfg); // rjf: title UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(5, 1)) { UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fstrs); - } - - // rjf: temporary target -> display - if(entity->kind == RD_EntityKind_Target && entity->cfg_src == RD_CfgSrc_CommandLine) - { - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_label(str8_lit("Specified on the command line; will not be saved.")); + ui_box_equip_display_fstrs(box, &fstrs); } }break; @@ -3696,32 +6724,29 @@ rd_window_frame(RD_Window *ws) DI_Scope *di_scope = di_scope_open(); Arch arch = ctrl_entity->arch; String8 arch_str = string_from_arch(arch); - DR_FancyStringList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, - rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), - ui_top_font_size(), 0); + DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, 0); // rjf: title UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(5, 1)) { UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fstrs); + ui_box_equip_display_fstrs(box, &fstrs); ui_spacer(ui_em(0.5f, 1.f)); UI_FontSize(ui_top_font_size() - 1.f) UI_CornerRadius(ui_top_font_size()*0.5f) - RD_Palette(RD_PaletteCode_NeutralPopButton) { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_label(arch_str); + UI_TagF("weak") UI_FlagsAdd(UI_BoxFlag_DrawBorder) ui_label(arch_str); ui_spacer(ui_em(0.5f, 1.f)); if(ctrl_entity->kind == CTRL_EntityKind_Thread || ctrl_entity->kind == CTRL_EntityKind_Process) { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_labelf("ID: %i", (U32)ctrl_entity->id); + UI_TagF("weak") UI_FlagsAdd(UI_BoxFlag_DrawBorder) ui_labelf("ID: %i", (U32)ctrl_entity->id); } } } // rjf: debug info status - if(ctrl_entity->kind == CTRL_EntityKind_Module) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + if(ctrl_entity->kind == CTRL_EntityKind_Module) UI_TagF("weak") { DI_Scope *di_scope = di_scope_open(); DI_Key dbgi_key = ctrl_dbgi_key_from_module(ctrl_entity); @@ -3744,61 +6769,50 @@ rd_window_frame(RD_Window *ws) // rjf: unwind if(ctrl_entity->kind == CTRL_EntityKind_Thread) { + Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(ctrl_entity); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); - if(rich_unwind.concrete_frame_count != 0) + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); + if(call_stack.count != 0) { ui_spacer(ui_em(1.5f, 1.f)); } - for(U64 idx = 0; idx < rich_unwind.concrete_frame_count; idx += 1) + for(U64 idx = 0; idx < call_stack.count; idx += 1) { - CTRL_CallStackFrame *f = &rich_unwind.frames[idx]; + CTRL_CallStackFrame *f = &call_stack.frames[idx]; RDI_Parsed *rdi = f->rdi; RDI_Procedure *procedure = f->procedure; U64 rip_vaddr = regs_rip_from_arch_block(arch, f->regs); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); String8 module_name = module == &ctrl_entity_nil ? str8_lit("???") : str8_skip_last_slash(module->string); - - // rjf: inline frames - for(CTRL_CallStackInlineFrame *fin = f->last_inline_frame; fin != 0; fin = fin->prev) - UI_PrefWidth(ui_children_sum(1)) UI_Row - { - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, fin->inline_site->name_string_idx, &name.size); - name.size = Min(512, name.size); - UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(12.f, 1)) ui_labelf("0x%I64x", rip_vaddr); - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_label(str8_lit("[inlined]")); - if(name.size != 0) - { - RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1)) - { - rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); - } - } - else - { - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name); - } - } - - // rjf: concrete frame UI_PrefWidth(ui_children_sum(1)) UI_Row { String8 name = {0}; - name.str = rdi_name_from_procedure(rdi, procedure, &name.size); - name.size = Min(512, name.size); - UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(12.f, 1)) ui_labelf("0x%I64x", rip_vaddr); + if(f->inline_site != 0) + { + name.str = rdi_string_from_idx(rdi, f->inline_site->name_string_idx, &name.size); + name.size = Min(512, name.size); + } + else if(f->procedure != 0) + { + name.str = rdi_name_from_procedure(rdi, procedure, &name.size); + name.size = Min(512, name.size); + } + UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_TagF("weak") UI_PrefWidth(ui_em(12.f, 1)) ui_labelf("0x%I64x", rip_vaddr); + if(f->parent_num != 0) + { + RD_Font(RD_FontSlot_Code) UI_TagF("weak") UI_PrefWidth(ui_text_dim(10, 1)) ui_label(str8_lit("[inlined]")); + } if(name.size != 0) { RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1)) { - rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); + rd_code_label(1.f, 0, symbol_color, name); } } else { - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name); + RD_Font(RD_FontSlot_Code) UI_TagF("weak") UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name); } } } @@ -3806,12 +6820,32 @@ rd_window_frame(RD_Window *ws) di_scope_close(di_scope); }break; + + //////////////////////// + //- rjf: expression tooltips + // + case RD_RegSlot_Expr: + UI_Tooltip RD_Font(RD_FontSlot_Code) + { + ui_set_next_pref_width(ui_children_sum(1)); + UI_Row + { + rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), rd_state->drag_drop_regs->expr); + ui_spacer(ui_em(2.f, 1.f)); + E_Eval eval = e_eval_from_string(scratch.arena, rd_state->drag_drop_regs->expr); + if(eval.irtree.mode != E_Mode_Null) + { + String8 value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), EV_StringFlag_ReadOnlyDisplayRules, 10, ui_top_font(), ui_top_font_size(), ui_top_font_size()*20.f, eval); + rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), value_string); + } + } + }break; } scratch_end(scratch); } //////////////////////////// - //- rjf: drag/drop visualization tooltips + //- rjf: @window_ui_part drag/drop visualization tooltips // if(rd_drag_is_active() && window_is_focused) RD_RegsScope(.window = rd_state->drag_drop_regs->window, @@ -3819,42 +6853,44 @@ rd_window_frame(RD_Window *ws) .view = rd_state->drag_drop_regs->view) { Temp scratch = scratch_begin(0, 0); - RD_Panel *panel = rd_panel_from_handle(rd_state->drag_drop_regs->panel); - RD_Entity *entity = rd_entity_from_handle(rd_state->drag_drop_regs->entity); - RD_View *view = rd_view_from_handle(rd_state->drag_drop_regs->view); + RD_Cfg *view = rd_cfg_from_id(rd_state->drag_drop_regs->view); { //- rjf: tab dragging - if(rd_state->drag_drop_regs_slot == RD_RegSlot_View && !rd_view_is_nil(view)) + if(rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg) { + RD_Cfg *immediate_parent = &rd_nil_cfg; + for(RD_Cfg *p = view->parent; p != &rd_nil_cfg; p = p->parent) + { + if(str8_match(p->parent->string, str8_lit("immediate"), 0)) + { + immediate_parent = p->parent; + break; + } + } + if(immediate_parent != &rd_nil_cfg) + { + rd_cfg_new(immediate_parent, str8_lit("hot")); + } UI_Size main_width = ui_top_pref_width(); UI_Size main_height = ui_top_pref_height(); UI_TextAlign main_text_align = ui_top_text_alignment(); - RD_Palette(RD_PaletteCode_Tab) - UI_Tooltip + UI_Tooltip UI_PrefWidth(main_width) UI_PrefHeight(main_height) UI_TextAlignment(main_text_align) { + ui_state->tooltip_can_overflow_window = 1; ui_set_next_pref_width(ui_em(60.f, 1.f)); ui_set_next_pref_height(ui_em(40.f, 1.f)); ui_set_next_child_layout_axis(Axis2_Y); UI_Box *container = ui_build_box_from_key(0, ui_key_zero()); UI_Parent(container) { - UI_Row + UI_Row UI_PrefWidth(ui_text_dim(10, 1)) { - RD_IconKind icon_kind = rd_icon_kind_from_view(view); - DR_FancyStringList fstrs = rd_title_fstrs_from_view(scratch.arena, view, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_PrefWidth(ui_em(2.5f, 1.f)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_label(rd_icon_kind_text_table[icon_kind]); - UI_PrefWidth(ui_text_dim(10, 1)) - { - UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(name_box, &fstrs); - } + DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, view); + UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(name_box, &fstrs); } ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_pct(1, 0)); @@ -3862,8 +6898,7 @@ rd_window_frame(RD_Window *ws) UI_Box *view_preview_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_preview_container"); UI_Parent(view_preview_container) UI_Focus(UI_FocusKind_Off) UI_WidthFill { - RD_ViewRuleUIFunctionType *view_ui = view->spec->ui; - view_ui(str8(view->query_buffer, view->query_string_size), view->params_roots[view->params_read_gen%ArrayCount(view->params_roots)], view_preview_container->rect); + rd_view_ui(view_preview_container->rect); } } } @@ -3873,7 +6908,7 @@ rd_window_frame(RD_Window *ws) } //////////////////////////// - //- rjf: developer menu + //- rjf: @window_ui_part developer menu // if(ws->dev_menu_is_open) RD_Font(RD_FontSlot_Code) { @@ -3923,11 +6958,11 @@ rd_window_frame(RD_Window *ws) ui_divider(ui_em(1.f, 1.f)); ui_label(regs_info[idx].name); RD_Regs *regs = regs_info[idx].regs; -#define Handle(name) ui_labelf("%s: [0x%I64x, 0x%I64x]", #name, (regs->name).u64[0], (regs->name).u64[1]) - Handle(window); - Handle(panel); - Handle(view); -#undef Handle +#define ID(name) ui_labelf("%s: $0x%I64x", #name, (regs->name)) + ID(window); + ID(panel); + ID(view); +#undef ID #define Handle(name) ui_labelf("%s: [0x%I64x, 0x%I64x]", #name, (regs->name).machine_id, (regs->name).dmn_handle.u64[0]) Handle(machine); Handle(process); @@ -3948,17 +6983,17 @@ rd_window_frame(RD_Window *ws) ui_divider(ui_em(1.f, 1.f)); //- rjf: draw per-window stats - for(RD_Window *window = rd_state->first_window; window != 0; window = window->next) + for(RD_WindowState *w = rd_state->first_window_state; w != &rd_nil_window_state; w = w->order_next) { // rjf: calc ui hash chain length F64 avg_ui_hash_chain_length = 0; { F64 chain_count = 0; F64 chain_length_sum = 0; - for(U64 idx = 0; idx < ws->ui->box_table_size; idx += 1) + for(U64 idx = 0; idx < w->ui->box_table_size; idx += 1) { F64 chain_length = 0; - for(UI_Box *b = ws->ui->box_table[idx].hash_first; !ui_box_is_nil(b); b = b->hash_next) + for(UI_Box *b = w->ui->box_table[idx].hash_first; !ui_box_is_nil(b); b = b->hash_next) { chain_length += 1; } @@ -3973,13 +7008,13 @@ rd_window_frame(RD_Window *ws) ui_labelf("Target Hz: %.2f", 1.f/rd_state->frame_dt); ui_labelf("Ctrl Run Index: %I64u", ctrl_run_gen()); ui_labelf("Ctrl Mem Gen Index: %I64u", ctrl_mem_gen()); - ui_labelf("Window %p", window); + ui_labelf("Window %p", w); ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_pref_height(ui_children_sum(1)); UI_Row { ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Box Count: %I64u", window->ui->last_build_box_count); + ui_labelf("Box Count: %I64u", w->ui->last_build_box_count); } ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_pref_height(ui_children_sum(1)); @@ -3991,43 +7026,14 @@ rd_window_frame(RD_Window *ws) } ui_divider(ui_em(1.f, 1.f)); - - //- rjf: draw entity tree -#if 0 - RD_EntityRec rec = {0}; - S32 indent = 0; - UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("Entity Tree:"); - for(RD_Entity *e = rd_entity_root(); !rd_entity_is_nil(e); e = rec.next) - { - ui_set_next_pref_width(ui_children_sum(1)); - ui_set_next_pref_height(ui_children_sum(1)); - UI_Row - { - ui_spacer(ui_em(2.f*indent, 1.f)); - RD_Entity *dst = rd_entity_from_handle(e->entity_handle); - if(!rd_entity_is_nil(dst)) - { - ui_labelf("[link] %S -> %S", e->string, dst->string); - } - else - { - ui_labelf("%S: %S", d_entity_kind_display_string_table[e->kind], e->string); - } - } - rec = rd_entity_rec_depth_first_pre(e, rd_entity_root()); - indent += rec.push_count; - indent -= rec.pop_count; - } -#endif } } //////////////////////////// - //- rjf: top-level registers context menu + //- rjf: @window_ui_part top-level registers context menu // - RD_Palette(RD_PaletteCode_Floating) UI_CtxMenu(rd_state->ctx_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) +#if 0 + UI_CtxMenu(rd_state->ctx_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) { Temp scratch = scratch_begin(0, 0); RD_Regs *regs = ws->ctx_menu_regs; @@ -4088,7 +7094,7 @@ rd_window_frame(RD_Window *ws) } else { - rd_cmd(RD_CmdKind_RunToAddress, .vaddr = regs->vaddr); + rd_cmd(RD_CmdKind_RunToLine, .vaddr = regs->vaddr); } ui_ctx_menu_close(); } @@ -4155,499 +7161,146 @@ rd_window_frame(RD_Window *ws) // case RD_RegSlot_View: { - RD_Panel *panel = rd_panel_from_handle(regs->panel); - RD_View *view = rd_view_from_handle(regs->view); - RD_IconKind view_icon = rd_icon_kind_from_view(view); - DR_FancyStringList fstrs = rd_title_fstrs_from_view(scratch.arena, view, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); - String8 file_path = rd_file_path_from_eval_string(scratch.arena, str8(view->query_buffer, view->query_string_size)); - - // rjf: title - UI_Row +#if 0 // TODO(rjf): @cfg (context menus) + RD_Cfg *tab = rd_cfg_from_id(regs->view); + RD_RegsScope(.view = regs->view) { - ui_spacer(ui_em(1.f, 1.f)); - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_PrefWidth(ui_em(2.f, 1.f)) - UI_PrefHeight(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_label(rd_icon_kind_text_table[view_icon]); - UI_PrefWidth(ui_text_dim(10, 1)) + String8 expr = rd_view_expr_string(); + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(tab->string); + RD_IconKind view_icon = view_rule_info->icon_kind; + DR_FStrList fstrs = rd_title_fstrs_from_view(scratch.arena, view_rule_info->display_name, expr, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); + String8 file_path = rd_file_path_from_eval_string(scratch.arena, expr); + + // rjf: title + UI_Row { - UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(name_box, &fstrs); + ui_spacer(ui_em(1.f, 1.f)); + RD_Font(RD_FontSlot_Icons) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) + UI_PrefWidth(ui_em(2.f, 1.f)) + UI_PrefHeight(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + ui_label(rd_icon_kind_text_table[view_icon]); + UI_PrefWidth(ui_text_dim(10, 1)) + { + UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(name_box, &fstrs); + } } - } - - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); - - // rjf: copy name - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Name"))) - { - os_set_clipboard_text(dr_string_from_fancy_string_list(scratch.arena, &fstrs)); - ui_ctx_menu_close(); - } - - // rjf: copy full path - if(file_path.size != 0) - { - UI_Signal copy_full_path_sig = rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Full Path"); - String8 full_path = path_normalized_from_string(scratch.arena, file_path); - if(ui_clicked(copy_full_path_sig)) + + RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); + + // rjf: copy name + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Name"))) { - os_set_clipboard_text(full_path); + os_set_clipboard_text(dr_string_from_fstrs(scratch.arena, &fstrs)); ui_ctx_menu_close(); } - if(ui_hovering(copy_full_path_sig)) UI_Tooltip - { - ui_label(full_path); - } - } - - // rjf: show in explorer - if(file_path.size != 0) - { - UI_Signal sig = rd_icon_buttonf(RD_IconKind_FolderClosedFilled, 0, "Show In Explorer"); - if(ui_clicked(sig)) + + // rjf: copy full path + if(file_path.size != 0) { + UI_Signal copy_full_path_sig = rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Full Path"); String8 full_path = path_normalized_from_string(scratch.arena, file_path); - os_show_in_filesystem_ui(full_path); - ui_ctx_menu_close(); - } - } - - // rjf: filter controls - if(view->spec->flags & RD_ViewRuleInfoFlag_CanFilter) - { - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_Filter].string))) - { - rd_cmd(RD_CmdKind_Filter, .panel = rd_handle_from_panel(panel), .view = rd_handle_from_view(view)); - ui_ctx_menu_close(); - } - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_ClearFilter].string))) - { - rd_cmd(RD_CmdKind_ClearFilter, .panel = rd_handle_from_panel(panel), .view = rd_handle_from_view(view)); - ui_ctx_menu_close(); - } - } - - // rjf: close tab - if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Tab"))) - { - rd_cmd(RD_CmdKind_CloseTab, .panel = rd_handle_from_panel(panel), .view = rd_handle_from_view(view)); - ui_ctx_menu_close(); - } - - // rjf: param tree editing - UI_TextPadding(ui_top_font_size()*1.5f) RD_Font(RD_FontSlot_Code) - { - Temp scratch = scratch_begin(0, 0); - String8 schema_string = view->spec->params_schema; - MD_TokenizeResult schema_tokenize = md_tokenize_from_text(scratch.arena, schema_string); - MD_ParseResult schema_parse = md_parse_from_text_tokens(scratch.arena, str8_zero(), schema_string, schema_tokenize.tokens); - MD_Node *schema_root = schema_parse.root->first; - if(!md_node_is_nil(schema_root)) - { - if(!md_node_is_nil(schema_root->first)) + if(ui_clicked(copy_full_path_sig)) { - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); + os_set_clipboard_text(full_path); + ui_ctx_menu_close(); } - for MD_EachNode(key, schema_root->first) + if(ui_hovering(copy_full_path_sig)) UI_Tooltip { - UI_Row - { - MD_Node *params = view->params_roots[view->params_write_gen%ArrayCount(view->params_roots)]; - MD_Node *param_tree = md_child_from_string(params, key->string, 0); - String8 pre_edit_value = md_string_from_children(scratch.arena, param_tree); - UI_PrefWidth(ui_em(10.f, 1.f)) ui_label(key->string); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, pre_edit_value, "%S##view_param", key->string); - if(ui_committed(sig)) - { - String8 new_string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size); - rd_view_store_param(view, key->string, new_string); - } - } + ui_label(full_path); } } - scratch_end(scratch); - } - }break; - - ////////////////////// - //- rjf: ctrl entities - // - case RD_RegSlot_Machine: ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->machine); goto ctrl_entity_title; - case RD_RegSlot_Process: ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->process); goto ctrl_entity_title; - case RD_RegSlot_Module: ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->module); goto ctrl_entity_title; - case RD_RegSlot_Thread: ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->thread); goto ctrl_entity_title; - case RD_RegSlot_CtrlEntity: ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->ctrl_entity); goto ctrl_entity_title; - ctrl_entity_title:; - { - //- rjf: title - UI_Row - UI_PrefWidth(ui_text_dim(5, 1)) - UI_TextAlignment(UI_TextAlign_Center) - UI_TextPadding(ui_top_font_size()*1.5f) - { - DR_FancyStringList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, ui_top_palette()->text_weak, ui_top_font_size(), 0); - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(title_box, &fstrs); - if(ctrl_entity->kind == CTRL_EntityKind_Thread) + + // rjf: show in explorer + if(file_path.size != 0) { - ui_spacer(ui_em(0.5f, 1.f)); - UI_FontSize(ui_top_font_size() - 1.f) - UI_CornerRadius(ui_top_font_size()*0.5f) - RD_Palette(RD_PaletteCode_NeutralPopButton) - UI_TextPadding(ui_top_font_size()*0.5f) + UI_Signal sig = rd_icon_buttonf(RD_IconKind_FolderClosedFilled, 0, "Show In Explorer"); + if(ui_clicked(sig)) { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_label(string_from_arch(ctrl_entity->arch)); - ui_spacer(ui_em(0.5f, 1.f)); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_labelf("TID: %i", (U32)ctrl_entity->id); + String8 full_path = path_normalized_from_string(scratch.arena, file_path); + os_show_in_filesystem_ui(full_path); + ui_ctx_menu_close(); } } - } - - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); - - //- rjf: name editor - if(ctrl_entity->kind == CTRL_EntityKind_Thread) RD_Font(RD_FontSlot_Code) UI_TextPadding(ui_top_font_size()*1.5f) - { - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, ctrl_entity->string, "Name###ctrl_entity_string_edit_%p", ctrl_entity); - if(ui_committed(sig)) + + // rjf: filter controls + if(view_rule_info->flags & RD_ViewRuleInfoFlag_CanFilter) { - rd_cmd(RD_CmdKind_SetEntityName, .ctrl_entity = ctrl_entity->handle, .string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size)); - } - } - - // rjf: copy full path - if(ctrl_entity->kind == CTRL_EntityKind_Module) if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Full Path"))) - { - os_set_clipboard_text(ctrl_entity->string); - ui_ctx_menu_close(); - } - - // rjf: copy ID - if((ctrl_entity->kind == CTRL_EntityKind_Thread || - ctrl_entity->kind == CTRL_EntityKind_Process) && - ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy ID"))) - { - String8 string = str8_from_u64(scratch.arena, ctrl_entity->id, 10, 0, 0); - os_set_clipboard_text(string); - ui_ctx_menu_close(); - } - - // rjf: copy call stack - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Call Stack"))) - { - DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(ctrl_entity); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); - String8List lines = {0}; - for(U64 frame_idx = 0; frame_idx < rich_unwind.concrete_frame_count; frame_idx += 1) + if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_Filter].string))) { - CTRL_CallStackFrame *concrete_frame = &rich_unwind.frames[frame_idx]; - U64 rip_vaddr = regs_rip_from_arch_block(ctrl_entity->arch, concrete_frame->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); - RDI_Parsed *rdi = concrete_frame->rdi; - RDI_Procedure *procedure = concrete_frame->procedure; - for(CTRL_CallStackInlineFrame *inline_frame = concrete_frame->last_inline_frame; - inline_frame != 0; - inline_frame = inline_frame->prev) - { - RDI_InlineSite *inline_site = inline_frame->inline_site; - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); - str8_list_pushf(scratch.arena, &lines, "0x%I64x: [inlined] \"%S\"%s%S", rip_vaddr, name, module == &ctrl_entity_nil ? "" : " in ", module->string); - } - if(procedure != 0) - { - String8 name = {0}; - name.str = rdi_name_from_procedure(rdi, procedure, &name.size); - str8_list_pushf(scratch.arena, &lines, "0x%I64x: \"%S\"%s%S", rip_vaddr, name, module == &ctrl_entity_nil ? "" : " in ", module->string); - } - else if(module != &ctrl_entity_nil) - { - str8_list_pushf(scratch.arena, &lines, "0x%I64x: [??? in %S]", rip_vaddr, module->string); - } - else - { - str8_list_pushf(scratch.arena, &lines, "0x%I64x: [??? in ???]", rip_vaddr); - } + rd_cmd(RD_CmdKind_Filter); + ui_ctx_menu_close(); + } + if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_ClearFilter].string))) + { + rd_cmd(RD_CmdKind_ClearFilter); + ui_ctx_menu_close(); } - StringJoin join = {0}; - join.sep = join.post = str8_lit("\n"); - String8 text = str8_list_join(scratch.arena, &lines, &join); - os_set_clipboard_text(text); - ui_ctx_menu_close(); - di_scope_close(di_scope); } - } - - // rjf: find - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_FileOutline, 0, "Find"))) + + // rjf: close tab + if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Tab"))) { - rd_cmd(RD_CmdKind_FindThread, .thread = ctrl_entity->handle); + rd_cmd(RD_CmdKind_CloseTab); ui_ctx_menu_close(); } - } - - // rjf: selection - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - B32 is_selected = ctrl_handle_match(rd_base_regs()->thread, ctrl_entity->handle); - if(is_selected) - { - rd_icon_buttonf(RD_IconKind_Thread, 0, "[Selected]###select_entity"); - } - else if(ui_clicked(rd_icon_buttonf(RD_IconKind_Thread, 0, "Select###select_entity"))) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = ctrl_entity->handle); - ui_ctx_menu_close(); - } - } - - // rjf: freezing - if(ctrl_entity->kind == CTRL_EntityKind_Thread || - ctrl_entity->kind == CTRL_EntityKind_Process || - ctrl_entity->kind == CTRL_EntityKind_Machine) - { - B32 is_frozen = ctrl_entity_tree_is_frozen(ctrl_entity); - ui_set_next_palette(rd_palette_from_code(is_frozen ? RD_PaletteCode_NegativePopButton : RD_PaletteCode_PositivePopButton)); - if(is_frozen && ui_clicked(rd_icon_buttonf(RD_IconKind_Locked, 0, "Thaw###freeze_thaw"))) - { - rd_cmd(RD_CmdKind_ThawThread, .ctrl_entity = ctrl_entity->handle); - } - if(!is_frozen && ui_clicked(rd_icon_buttonf(RD_IconKind_Unlocked, 0, "Freeze###freeze_thaw"))) - { - rd_cmd(RD_CmdKind_FreezeThread, .ctrl_entity = ctrl_entity->handle); - } - } - - // rjf: callstack + + // rjf: param tree editing #if 0 - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); - if(ctrl_entity->kind == CTRL_EntityKind_Thread) UI_TextPadding(ui_top_font_size()*1.5f) - { - DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *thread = ctrl_entity; - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); - for(U64 idx = 0; idx < rich_unwind.concrete_frame_count; idx += 1) + UI_TextPadding(ui_top_font_size()*1.5f) RD_Font(RD_FontSlot_Code) { - CTRL_CallStackFrame *f = &rich_unwind.frames[idx]; - RDI_Parsed *rdi = f->rdi; - RDI_Procedure *procedure = f->procedure; - U64 rip_vaddr = regs_rip_from_arch_block(thread->arch, f->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); - String8 module_name = module == &ctrl_entity_nil ? str8_lit("???") : str8_skip_last_slash(module->string); - - // rjf: inline frames - for(CTRL_CallStackInlineFrame *fin = f->last_inline_frame; fin != 0; fin = fin->prev) + Temp scratch = scratch_begin(0, 0); + String8 schema_string = view->spec->params_schema; + MD_TokenizeResult schema_tokenize = md_tokenize_from_text(scratch.arena, schema_string); + MD_ParseResult schema_parse = md_parse_from_text_tokens(scratch.arena, str8_zero(), schema_string, schema_tokenize.tokens); + MD_Node *schema_root = schema_parse.root->first; + if(!md_node_is_nil(schema_root)) { - UI_Box *row = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_ClickToFocus, "###callstack_row_%I64x", idx); - UI_Signal sig = ui_signal_from_box(row); - ui_push_parent(row); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, fin->inline_site->name_string_idx, &name.size); - UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(16.f, 1)) ui_labelf("0x%I64x", rip_vaddr); - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_label(str8_lit("[inlined]")); - if(name.size != 0) + if(!md_node_is_nil(schema_root->first)) { - RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1)) - { - rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); - } + RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); } - else + for MD_EachNode(key, schema_root->first) { - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name); - } - ui_pop_parent(); - } - - // rjf: concrete frame - { - UI_Box *row = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_ClickToFocus, "###callstack_row_%I64x", idx); - UI_Signal sig = ui_signal_from_box(row); - ui_push_parent(row); - String8 name = {0}; - name.str = rdi_name_from_procedure(rdi, procedure, &name.size); - UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(16.f, 1)) ui_labelf("0x%I64x", rip_vaddr); - if(name.size != 0) - { - RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1)) + UI_Row { - rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); - } - } - else - { - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name); - } - ui_pop_parent(); - } - } - di_scope_close(di_scope); - } -#endif - - // rjf: color editor -#if 0 - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); - { - UI_Padding(ui_em(1.5f, 1.f)) - { - ui_set_next_pref_height(ui_em(9.f, 1.f)); - UI_Row UI_Padding(ui_pct(1, 0)) - { - UI_PrefWidth(ui_em(1.5f, 1.f)) UI_PrefHeight(ui_em(9.f, 1.f)) UI_Column UI_PrefHeight(ui_em(1.5f, 0.f)) - { - Vec4F32 presets[] = - { - v4f32(1.0f, 0.2f, 0.1f, 1.0f), - v4f32(1.0f, 0.8f, 0.2f, 1.0f), - v4f32(0.3f, 0.8f, 0.2f, 1.0f), - v4f32(0.1f, 0.8f, 0.4f, 1.0f), - v4f32(0.1f, 0.6f, 0.8f, 1.0f), - v4f32(0.5f, 0.3f, 0.8f, 1.0f), - v4f32(0.8f, 0.3f, 0.5f, 1.0f), - }; - UI_CornerRadius(ui_em(0.3f, 1.f).value) - for(U64 preset_idx = 0; preset_idx < ArrayCount(presets); preset_idx += 1) - { - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = presets[preset_idx])); - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_Clickable| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects, - "###color_preset_%i", (int)preset_idx); - UI_Signal sig = ui_signal_from_box(box); - if(ui_clicked(sig)) + MD_Node *params = view->params_roots[view->params_write_gen%ArrayCount(view->params_roots)]; + MD_Node *param_tree = md_child_from_string(params, key->string, 0); + String8 pre_edit_value = md_string_from_children(scratch.arena, param_tree); + UI_PrefWidth(ui_em(10.f, 1.f)) ui_label(key->string); + UI_Signal sig = rd_cellf(RD_CellFlag_Border|RD_CellFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, pre_edit_value, "%S##view_param", key->string); + if(ui_committed(sig)) { - Vec3F32 hsv = hsv_from_rgb(v3f32(presets[preset_idx].x, presets[preset_idx].y, presets[preset_idx].z)); - Vec4F32 hsva = v4f32(hsv.x, hsv.y, hsv.z, 1); - entity->color_hsva = hsva; + String8 new_string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size); + rd_view_store_param(view, key->string, new_string); } - ui_spacer(ui_em(0.3f, 1.f)); } } - - ui_spacer(ui_em(0.75f, 1.f)); - - UI_PrefWidth(ui_em(9.f, 1.f)) UI_PrefHeight(ui_em(9.f, 1.f)) - { - ui_sat_val_pickerf(entity->color_hsva.x, &entity->color_hsva.y, &entity->color_hsva.z, "###ent_satval_picker"); - } - - ui_spacer(ui_em(0.75f, 1.f)); - - UI_PrefWidth(ui_em(1.5f, 1.f)) UI_PrefHeight(ui_em(9.f, 1.f)) - ui_hue_pickerf(&entity->color_hsva.x, entity->color_hsva.y, entity->color_hsva.z, "###ent_hue_picker"); } + scratch_end(scratch); } - - UI_Row UI_Padding(ui_pct(1, 0)) UI_PrefWidth(ui_em(16.f, 1.f)) UI_CornerRadius(8.f) UI_TextAlignment(UI_TextAlign_Center) - RD_Palette(RD_PaletteCode_Floating) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Trash, 0, "Remove Color###color_toggle"))) - { - entity->flags &= ~RD_EntityFlag_HasColor; - } - } - - ui_spacer(ui_em(1.5f, 1.f)); +#endif } #endif }break; - - ////////////////////// - //- rjf: frontend entities - // - case RD_RegSlot_Entity: - { - RD_Entity *entity = rd_entity_from_handle(regs->entity); - RD_EntityKindFlags kind_flags = rd_entity_kind_flags_table[entity->kind]; - - //- rjf: title - UI_Row - UI_PrefWidth(ui_text_dim(5, 1)) - UI_TextAlignment(UI_TextAlign_Center) - UI_TextPadding(ui_top_font_size()*1.5f) - { - DR_FancyStringList fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, ui_top_palette()->text_weak, ui_top_font_size()); - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(title_box, &fstrs); - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - ui_spacer(ui_em(0.5f, 1.f)); - UI_FontSize(ui_top_font_size() - 1.f) - UI_CornerRadius(ui_top_font_size()*0.5f) - RD_Palette(RD_PaletteCode_NeutralPopButton) - UI_TextPadding(ui_top_font_size()*0.5f) - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_label(string_from_arch(ctrl_entity->arch)); - ui_spacer(ui_em(0.5f, 1.f)); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_labelf("TID: %i", (U32)ctrl_entity->id); - } - } - } - - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); - - //- rjf: name editor - if(kind_flags & RD_EntityKindFlag_CanRename) RD_Font(RD_FontSlot_Code) UI_TextPadding(ui_top_font_size()*1.5f) - { - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, entity->string, "Name###entity_string_edit_%p", ctrl_entity); - if(ui_committed(sig)) - { - rd_cmd(RD_CmdKind_NameEntity, .entity = regs->entity, .string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size)); - } - } - - //- rjf: condition editor - if(kind_flags & RD_EntityKindFlag_CanCondition) RD_Font(RD_FontSlot_Code) UI_TextPadding(ui_top_font_size()*1.5f) - { - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, rd_entity_child_from_kind(entity, RD_EntityKind_Condition)->string, "Condition###entity_condition_edit_%p", entity); - if(ui_committed(sig)) - { - rd_cmd(RD_CmdKind_ConditionEntity, .entity = regs->entity, .string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size)); - } - } - - //- rjf: name editor - if(entity->cfg_src == RD_CfgSrc_CommandLine) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Save, 0, "Save To Project"))) - { - rd_entity_equip_cfg_src(entity, RD_CfgSrc_Project); - } - } - }break; - } } scratch_end(scratch); } +#endif //////////////////////////// - //- rjf: drop-completion context menu + //- rjf: @window_ui_part drop-completion context menu // if(ws->drop_completion_paths.node_count != 0) { - RD_Palette(RD_PaletteCode_Floating) UI_CtxMenu(rd_state->drop_completion_key) - RD_Palette(RD_PaletteCode_ImplicitButton) - UI_PrefWidth(ui_em(40.f, 1.f)) + UI_CtxMenu(rd_state->drop_completion_key) UI_PrefWidth(ui_em(40.f, 1.f)) UI_TagF("implicit") { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") for(String8Node *n = ws->drop_completion_paths.first; n != 0; n = n->next) { UI_Row UI_Padding(ui_em(1.f, 1.f)) @@ -4656,7 +7309,7 @@ rd_window_frame(RD_Window *ws) UI_PrefWidth(ui_text_dim(10, 1)) ui_label(n->string); } } - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); + ui_divider(ui_em(1.f, 1.f)); if(ui_clicked(rd_icon_buttonf(RD_IconKind_Target, 0, "Add File%s As Target%s", (ws->drop_completion_paths.node_count > 1) ? "s" : "", (ws->drop_completion_paths.node_count > 1) ? "s" : ""))) @@ -4718,20 +7371,18 @@ rd_window_frame(RD_Window *ws) } //////////////////////////// - //- rjf: popup + //- rjf: @window_ui_part popup // { if(rd_state->popup_t > 0.005f) UI_TextAlignment(UI_TextAlign_Center) UI_Focus(rd_state->popup_active ? UI_FocusKind_Root : UI_FocusKind_Off) { Vec2F32 window_dim = dim_2f32(window_rect); UI_Box *bg_box = &ui_nil_box; - UI_Palette *palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_Floating)); - palette->background.w *= rd_state->popup_t; UI_Rect(window_rect) UI_ChildLayoutAxis(Axis2_X) UI_Focus(UI_FocusKind_On) UI_BlurSize(10*rd_state->popup_t) - UI_Palette(palette) + UI_Transparency(1-rd_state->popup_t) { bg_box = ui_build_box_from_stringf(UI_BoxFlag_FixedSize| UI_BoxFlag_Floating| @@ -4739,8 +7390,7 @@ rd_window_frame(RD_Window *ws) UI_BoxFlag_Scroll| UI_BoxFlag_DefaultFocusNav| UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawBackground, "###popup_%p", ws); + UI_BoxFlag_DrawBackgroundBlur, "###popup_%p", ws); } if(rd_state->popup_active) UI_Parent(bg_box) UI_Transparency(1-rd_state->popup_t) { @@ -4748,11 +7398,11 @@ rd_window_frame(RD_Window *ws) UI_WidthFill UI_PrefHeight(ui_children_sum(1.f)) UI_Column UI_Padding(ui_pct(1, 0)) { UI_TextRasterFlags(rd_raster_flags_from_slot(RD_FontSlot_Main)) UI_FontSize(ui_top_font_size()*2.f) UI_PrefHeight(ui_em(3.f, 1.f)) ui_label(rd_state->popup_title); - UI_PrefHeight(ui_em(3.f, 1.f)) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label(rd_state->popup_desc); + UI_PrefHeight(ui_em(3.f, 1.f)) UI_TagF("weak") ui_label(rd_state->popup_desc); ui_spacer(ui_em(1.5f, 1.f)); UI_Row UI_Padding(ui_pct(1.f, 0.f)) UI_PrefWidth(ui_em(16.f, 1.f)) UI_PrefHeight(ui_em(3.5f, 1.f)) UI_CornerRadius(ui_top_font_size()*0.5f) { - RD_Palette(RD_PaletteCode_NeutralPopButton) + UI_TagF("pop") if(ui_clicked(ui_buttonf("OK")) || (ui_key_match(bg_box->default_nav_focus_hot_key, ui_key_zero()) && ui_slot_press(UI_EventActionSlot_Accept))) { rd_cmd(RD_CmdKind_PopupAccept); @@ -4771,564 +7421,499 @@ rd_window_frame(RD_Window *ws) } //////////////////////////// - //- rjf: build auto-complete lister + //- rjf: @window_ui_part gather all tasks to build floating views // - ProfScope("build autocomplete lister") - if(!ui_key_match(ws->autocomp_root_key, ui_key_zero()) && ws->autocomp_last_frame_idx+1 >= rd_state->frame_index) + typedef struct FloatingViewTask FloatingViewTask; + struct FloatingViewTask { - String8 input = str8(ws->autocomp_lister_input_buffer, ws->autocomp_lister_input_size); - String8 query_word = rd_autocomp_query_word_from_input_string_off(input, ws->autocomp_cursor_off); - String8 query_path = rd_autocomp_query_path_from_input_string_off(input, ws->autocomp_cursor_off); - UI_Box *autocomp_root_box = ui_box_from_key(ws->autocomp_root_key); - if(!ui_box_is_nil(autocomp_root_box)) + FloatingViewTask *next; + RD_Cfg *view; + F32 row_height_px; + Rng2F32 rect; + String8 view_name; + String8 expr; + B32 is_focused; + B32 is_anchored; + UI_Signal signal; // NOTE(rjf): output, from build + B32 pressed; + B32 pressed_outside; + }; + FloatingViewTask *hover_eval_floating_view_task = 0; + FloatingViewTask *query_floating_view_task = 0; + FloatingViewTask *first_floating_view_task = 0; + FloatingViewTask *last_floating_view_task = 0; + RD_Font(RD_FontSlot_Code) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + { + //- rjf: try to add hover eval first { - Temp scratch = scratch_begin(0, 0); - DI_Scope *di_scope = di_scope_open(); - DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena); - DI_KeyArray dbgi_keys = di_key_array_from_list(scratch.arena, &dbgi_keys_list); + B32 build_hover_eval = (hover_eval_is_open && !rd_drag_is_active()); - //- rjf: grab rdis - U64 rdis_count = dbgi_keys.count; - RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); + // rjf: disable hover eval if hovered view is actively scrolling + if(hover_eval_is_open) { - for(U64 idx = 0; idx < rdis_count; idx += 1) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], 0); - RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); - rdis[idx] = rdi; - } - } - - //- rjf: unpack lister params - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); - U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_base_regs()->unwind_count); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); - U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - - //- rjf: gather lister items - RD_AutoCompListerItemChunkList item_list = {0}; - { - //- rjf: gather locals - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Locals) - { - E_String2NumMap *locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - E_String2NumMap *member_map = d_query_cached_member_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) + if(panel->first != &rd_nil_panel_node) { continue; } + RD_Cfg *tab = panel->selected_tab; + if(tab != &rd_nil_cfg) { - RD_AutoCompListerItem item = {0}; + RD_ViewState *vs = rd_view_state_from_cfg(tab); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); + if(contains_2f32(panel_rect, ui_mouse()) && + (abs_f32(vs->scroll_pos.x.off) > 0.01f || + abs_f32(vs->scroll_pos.y.off) > 0.01f)) { - item.string = n->string; - item.kind_string = str8_lit("Local"); - item.matches = fuzzy_match_find(scratch.arena, query_word, n->string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - for(E_String2NumMapNode *n = member_map->first; n != 0; n = n->order_next) - { - RD_AutoCompListerItem item = {0}; - { - item.string = n->string; - item.kind_string = str8_lit("Local (Member)"); - item.matches = fuzzy_match_find(scratch.arena, query_word, n->string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather registers - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Registers) - { - Arch arch = thread->arch; - U64 reg_names_count = regs_reg_code_count_from_arch(arch); - U64 alias_names_count = regs_alias_code_count_from_arch(arch); - String8 *reg_names = regs_reg_code_string_table_from_arch(arch); - String8 *alias_names = regs_alias_code_string_table_from_arch(arch); - for(U64 idx = 0; idx < reg_names_count; idx += 1) - { - if(reg_names[idx].size != 0) - { - RD_AutoCompListerItem item = {0}; - { - item.string = reg_names[idx]; - item.kind_string = str8_lit("Register"); - item.matches = fuzzy_match_find(scratch.arena, query_word, reg_names[idx]); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - for(U64 idx = 0; idx < alias_names_count; idx += 1) - { - if(alias_names[idx].size != 0) - { - RD_AutoCompListerItem item = {0}; - { - item.string = alias_names[idx]; - item.kind_string = str8_lit("Reg. Alias"); - item.matches = fuzzy_match_find(scratch.arena, query_word, alias_names[idx]); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - } - - //- rjf: gather view rules - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_ViewRules) - { - for(U64 slot_idx = 0; slot_idx < d_state->view_rule_spec_table_size; slot_idx += 1) - { - for(D_ViewRuleSpec *spec = d_state->view_rule_spec_table[slot_idx]; spec != 0 && spec != &d_nil_core_view_rule_spec; spec = spec->hash_next) - { - RD_AutoCompListerItem item = {0}; - { - item.string = spec->info.string; - item.kind_string = str8_lit("View Rule"); - item.matches = fuzzy_match_find(scratch.arena, query_word, spec->info.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - } - - //- rjf: gather members - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Members) - { - // TODO(rjf) - } - - //- rjf: gather globals - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Globals && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_GlobalVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_AutoCompListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Global"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather thread locals - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_ThreadLocals && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_ThreadVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_AutoCompListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Thread Local"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather procedures - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Procedures && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_Procedures, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_AutoCompListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Procedure"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather types - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Types && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_UDTs, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_AutoCompListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Type"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather languages - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Languages) - { - for EachNonZeroEnumVal(TXT_LangKind, lang) - { - RD_AutoCompListerItem item = {0}; - { - item.string = txt_extension_from_lang_kind(lang); - item.kind_string = str8_lit("Language"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(item.string.size != 0 && (query_word.size == 0 || item.matches.count != 0)) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather architectures - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Architectures) - { - for EachNonZeroEnumVal(Arch, arch) - { - RD_AutoCompListerItem item = {0}; - { - item.string = string_from_arch(arch); - item.kind_string = str8_lit("Arch"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather tex2dformats - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Tex2DFormats) - { - for EachEnumVal(R_Tex2DFormat, fmt) - { - RD_AutoCompListerItem item = {0}; - { - item.string = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); - item.kind_string = str8_lit("Format"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather view rule params - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_ViewRuleParams) - { - for(String8Node *n = ws->autocomp_lister_params.strings.first; n != 0; n = n->next) - { - String8 string = n->string; - RD_AutoCompListerItem item = {0}; - { - item.string = string; - item.kind_string = str8_lit("Parameter"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather files - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Files) - { - // rjf: find containing directory in query_path - String8 dir_str_in_input = {0}; - for(U64 i = 0; i < query_path.size; i += 1) - { - String8 substr1 = str8_substr(query_path, r1u64(i, i+1)); - String8 substr2 = str8_substr(query_path, r1u64(i, i+2)); - String8 substr3 = str8_substr(query_path, r1u64(i, i+3)); - if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i-1, query_path.size)); - } - else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - if(dir_str_in_input.size != 0) - { - break; - } - } - - // rjf: use query_path string to form various parts of search space - String8 prefix = {0}; - String8 path = {0}; - String8 search = {0}; - if(dir_str_in_input.size != 0) - { - String8 dir = dir_str_in_input; - U64 one_past_last_slash = dir.size; - for(U64 i = 0; i < dir_str_in_input.size; i += 1) - { - if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') - { - one_past_last_slash = i+1; - } - } - dir.size = one_past_last_slash; - path = dir; - search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); - prefix = str8_substr(query_path, r1u64(0, path.str - query_path.str)); - } - - // rjf: get current files, filtered - B32 allow_dirs = 1; - OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); - for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) - { - FuzzyMatchRangeList match_ranges = fuzzy_match_find(scratch.arena, search, info.name); - B32 fits_search = (search.size == 0 || match_ranges.count == match_ranges.needle_part_count); - B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); - if(fits_search && fits_dir_only) - { - RD_AutoCompListerItem item = {0}; - { - item.string = info.props.flags & FilePropertyFlag_IsFolder ? push_str8f(scratch.arena, "%S/", info.name) : info.name; - item.kind_string = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"); - item.matches = match_ranges; - item.is_non_code = 1; - } - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - os_file_iter_end(it); - } - } - - //- rjf: lister item list -> sorted array - RD_AutoCompListerItemArray item_array = rd_autocomp_lister_item_array_from_chunk_list(scratch.arena, &item_list); - rd_autocomp_lister_item_array_sort__in_place(&item_array); - - //- rjf: animate - { - // rjf: animate target # of rows - { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; - F32 target = Min((F32)item_array.count, 16.f); - if(abs_f32(target - ws->autocomp_num_visible_rows_t) > 0.01f) - { - rd_request_frame(); - } - ws->autocomp_num_visible_rows_t += (target - ws->autocomp_num_visible_rows_t) * rate; - if(abs_f32(target - ws->autocomp_num_visible_rows_t) <= 0.02f) - { - ws->autocomp_num_visible_rows_t = target; - } - } - - // rjf: animate open - { - F32 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->autocomp_open_t; - ws->autocomp_open_t += diff*rate; - if(abs_f32(diff) < 0.05f) - { - ws->autocomp_open_t = 1.f; - } - else - { - rd_request_frame(); - } - } - } - - //- rjf: build - if(item_array.count != 0) - { - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - ui_set_next_fixed_x(autocomp_root_box->rect.x0); - ui_set_next_fixed_y(autocomp_root_box->rect.y1); - ui_set_next_pref_width(ui_em(30.f, 1.f)); - ui_set_next_pref_height(ui_px(row_height_px*ws->autocomp_num_visible_rows_t + ui_top_font_size()*2.f, 1.f)); - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_corner_radius_01(ui_top_font_size()*0.25f); - ui_set_next_corner_radius_11(ui_top_font_size()*0.25f); - ui_set_next_corner_radius_10(ui_top_font_size()*0.25f); - UI_Focus(UI_FocusKind_On) - UI_Squish(0.25f-0.25f*ws->autocomp_open_t) - UI_Transparency(1.f-ws->autocomp_open_t) - RD_Palette(RD_PaletteCode_Floating) - { - autocomp_box = ui_build_box_from_stringf(UI_BoxFlag_DefaultFocusNavY| - UI_BoxFlag_Clickable| - UI_BoxFlag_Clip| - UI_BoxFlag_RoundChildrenByParent| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackground, - "autocomp_box"); - if(ws->autocomp_input_dirty) - { - ws->autocomp_input_dirty = 0; - autocomp_box->default_nav_focus_hot_key = autocomp_box->default_nav_focus_active_key = autocomp_box->default_nav_focus_next_hot_key = autocomp_box->default_nav_focus_next_active_key = ui_key_zero(); - } - } - UI_Parent(autocomp_box) - UI_WidthFill - UI_PrefHeight(ui_px(row_height_px, 1.f)) - RD_Font(RD_FontSlot_Code) - UI_HoverCursor(OS_Cursor_HandPoint) - UI_Focus(UI_FocusKind_Null) - RD_Palette(RD_PaletteCode_ImplicitButton) - UI_Padding(ui_em(1.f, 1.f)) - { - for(U64 idx = 0; idx < item_array.count; idx += 1) - { - RD_AutoCompListerItem *item = &item_array.v[idx]; - UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_MouseClickable, "autocomp_%I64x", idx); - UI_Parent(item_box) UI_Padding(ui_em(1.f, 1.f)) - { - UI_WidthFill RD_Font(item->is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) - { - UI_Box *box = item->is_non_code ? ui_label(item->string).box : rd_code_label(1.f, 0, ui_top_palette()->text, item->string); - ui_box_equip_fuzzy_match_ranges(box, &item->matches); - } - RD_Font(RD_FontSlot_Main) - UI_PrefWidth(ui_text_dim(10, 1)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_label(item->kind_string); - } - UI_Signal item_sig = ui_signal_from_box(item_box); - if(ui_clicked(item_sig)) - { - UI_Event move_back_evt = zero_struct; - move_back_evt.kind = UI_EventKind_Navigate; - move_back_evt.flags = UI_EventFlag_KeepMark; - move_back_evt.delta_2s32.x = -(S32)query_word.size; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &move_back_evt); - UI_Event paste_evt = zero_struct; - paste_evt.kind = UI_EventKind_Text; - paste_evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &paste_evt); - autocomp_box->default_nav_focus_hot_key = autocomp_box->default_nav_focus_active_key = autocomp_box->default_nav_focus_next_hot_key = autocomp_box->default_nav_focus_next_active_key = ui_key_zero(); - } - else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) - { - UI_Event evt = zero_struct; - evt.kind = UI_EventKind_AutocompleteHint; - evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); + build_hover_eval = 0; + ws->hover_eval_firstt_us = rd_state->time_in_us; } } } } - di_scope_close(di_scope); - scratch_end(scratch); + // rjf: choose hover evaluation expression + String8 hover_eval_expr = push_str8f(scratch.arena, "%S%s%S", ws->hover_eval_string, ws->hover_eval_view_rules.size != 0 ? " => " : "", ws->hover_eval_view_rules); + + // rjf: evaluate hover evaluation expression, & determine if it evaluates + // such that we want to build a hover eval. + E_Eval hover_eval = e_eval_from_string(scratch.arena, hover_eval_expr); + { + if(hover_eval.msgs.max_kind > E_MsgKind_Null) + { + build_hover_eval = 0; + } + else if(hover_eval.space.kind == RD_EvalSpaceKind_MetaCfg && + rd_cfg_from_eval_space(hover_eval.space) == &rd_nil_cfg) + { + build_hover_eval = 0; + } + else if((hover_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + hover_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) && + rd_ctrl_entity_from_eval_space(hover_eval.space) == &ctrl_entity_nil) + { + build_hover_eval = 0; + } + } + + // rjf: request frames if we're waiting to open + if(ws->hover_eval_string.size != 0 && + !hover_eval_is_open && + ws->hover_eval_lastt_us < ws->hover_eval_firstt_us+hover_eval_open_delay_us && + rd_state->time_in_us - ws->hover_eval_lastt_us < hover_eval_open_delay_us*2) + { + rd_request_frame(); + } + + // rjf: build hover eval task + if(build_hover_eval) + { + // rjf: determine if we have a top-level visualizer + EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); + + // rjf: determine view name + String8 view_name = str8_lit("watch"); + if(view_ui_rule != &rd_nil_view_ui_rule) + { + view_name = view_ui_rule->name; + } + + // rjf: build view + RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, view_name); + RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_new_replace(explicit_root, str8_lit("1")); + + // rjf: determine size of hover evaluation container + EV_BlockTree predicted_block_tree = {0}; + RD_RegsScope(.view = view->id) + { + predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); + } + F32 row_height_px = ui_top_px_height(); + U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); + if(ws->hover_eval_focused) + { + max_row_count *= 3; + } + U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); + F32 width_px = floor_f32(70.f*ui_top_font_size()); + F32 height_px = needed_row_count*row_height_px; + + // rjf: if arbitrary visualizer, pick catchall size + if(view_ui_rule != &rd_nil_view_ui_rule) + { + height_px = floor_f32(40.f*ui_top_font_size()); + } + + // rjf: determine hover eval top-level rect + Rng2F32 rect = r2f32p(ws->hover_eval_spawn_pos.x, + ws->hover_eval_spawn_pos.y, + ws->hover_eval_spawn_pos.x + width_px, + ws->hover_eval_spawn_pos.y + height_px); + + // rjf: push hover eval task + { + FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); + SLLQueuePush(first_floating_view_task, last_floating_view_task, t); + hover_eval_floating_view_task = t; + t->view = view; + t->row_height_px = row_height_px; + t->rect = rect; + t->view_name = view_name; + t->expr = hover_eval_expr; + t->is_focused = ws->hover_eval_focused; + t->is_anchored = 1; + } + } + + // rjf: reset focus state if hover eval is not being built + if(!build_hover_eval || ws->hover_eval_string.size == 0 || !hover_eval_is_open) + { + ws->hover_eval_focused = 0; + } + } + + //- rjf: force-close query, if it's anchored, but box is gone + if(query_is_open) + { + UI_Box *box = ui_box_from_key(ws->query_regs->ui_key); + if(!ui_key_match(ui_key_zero(), ws->query_regs->ui_key) && ui_box_is_nil(box)) + { + query_is_open = 0; + rd_cmd(RD_CmdKind_CancelQuery); + } + } + + //- rjf: force-close query, if it has an expression, but that expression does not evaluate + if(query_is_open) + { + String8 expr = ws->query_regs->expr; + E_Eval eval = e_eval_from_string(scratch.arena, expr); + if(eval.msgs.max_kind > E_MsgKind_Null) + { + query_is_open = 0; + rd_cmd(RD_CmdKind_CancelQuery); + } + else if(eval.space.kind == RD_EvalSpaceKind_MetaCfg && + rd_cfg_from_eval_space(eval.space) == &rd_nil_cfg) + { + query_is_open = 0; + rd_cmd(RD_CmdKind_CancelQuery); + } + else if((eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + eval.space.kind == RD_EvalSpaceKind_CtrlEntity) && + rd_ctrl_entity_from_eval_space(eval.space) == &ctrl_entity_nil) + { + query_is_open = 0; + rd_cmd(RD_CmdKind_CancelQuery); + } + } + + //- rjf: try to add opened query + if(query_is_open) + { + // rjf: unpack query info + String8 cmd_name = ws->query_regs->cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + String8 query_expr = ws->query_regs->expr; + if(cmd_name.size != 0) + { + query_expr = cmd_kind_info->query.expr; + } + B32 query_is_anchored = (!ui_box_is_nil(ui_box_from_key(ws->query_regs->ui_key))); + B32 query_is_lister = (cmd_name.size != 0); + B32 size_query_by_expr_eval = (query_is_anchored || query_expr.size == 0); + + // rjf: build view for query + RD_Cfg *root = rd_immediate_cfg_from_keyf("window_query_%p", window); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); + rd_cfg_new_replace(cmd, cmd_name); + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(query_is_lister) + { + rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); + vs->query_is_selected = 1; + } + else + { + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("lister"))); + } + + // rjf: compute query expression + if(query_expr.size == 0) + { + query_expr = str8(vs->query_buffer, vs->query_string_size); + } + else + { + U64 input_insertion_pos = str8_find_needle(query_expr, 0, str8_lit("$input"), 0); + if(input_insertion_pos < query_expr.size) + { + String8 pre_insertion = str8_prefix(query_expr, input_insertion_pos); + String8 post_insertion = str8_skip(query_expr, input_insertion_pos + 6); + query_expr = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->query_buffer, vs->query_string_size), post_insertion); + } + } + + // rjf: determine if we want an explicit root + B32 do_explicit_root = (!ws->query_regs->do_implicit_root && (query_expr.size == 0 || !query_is_lister)); + if(do_explicit_root) + { + RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_new(explicit_root, str8_lit("1")); + } + else + { + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); + } + + // rjf: evaluate query expression + E_Eval query_eval = e_eval_from_string(scratch.arena, query_expr); + + // rjf: compute query view's top-level rectangle + F32 row_height_px = ui_top_px_height(); + Rng2F32 rect = {0}; + RD_RegsScope(.view = view->id) + { + Vec2F32 content_rect_center = center_2f32(content_rect); + Vec2F32 content_rect_dim = dim_2f32(content_rect); + EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.exprs); + F32 query_width_px = floor_f32(content_rect_dim.x * 0.35f); + F32 max_query_height_px = content_rect_dim.y*0.8f; + F32 query_height_px = max_query_height_px; + if(size_query_by_expr_eval) + { + query_height_px = row_height_px * (predicted_block_tree.total_row_count - !do_explicit_root); + query_height_px = Min(query_height_px, max_query_height_px); + } + rect = r2f32p(content_rect_center.x - query_width_px/2, + content_rect_center.y - max_query_height_px/2.f, + content_rect_center.x + query_width_px/2, + content_rect_center.y - max_query_height_px/2.f + query_height_px); + if(!ui_key_match(ui_key_zero(), ws->query_regs->ui_key)) + { + UI_Box *anchor_box = ui_box_from_key(ws->query_regs->ui_key); + if(anchor_box != &ui_nil_box) + { + rect.x0 = anchor_box->rect.x0; + rect.y0 = anchor_box->rect.y1; + rect.x1 = rect.x0 + ui_top_font_size()*60.f; + rect.y1 = rect.y0 + query_height_px; + } + } + } + + // rjf: push query task + { + FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); + SLLQueuePush(first_floating_view_task, last_floating_view_task, t); + query_floating_view_task = t; + t->view = view; + t->row_height_px = row_height_px; + t->rect = rect; + t->view_name = str8_lit("watch"); + t->expr = query_expr; + t->is_focused = 1; + t->is_anchored = query_is_anchored; + } } } //////////////////////////// - //- rjf: top bar + //- rjf: @window_ui_part build all floating views + // + ProfScope("build all floating views") + RD_Font(RD_FontSlot_Code) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_TagF("floating") + UI_Focus(ui_any_ctx_menu_is_open() || ws->menu_bar_focused ? UI_FocusKind_Off : UI_FocusKind_Null) + { + F32 fast_open_rate = 1 - pow_f32(2, (-70.f * ui_state->animation_dt)); + F32 slow_open_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); + for(FloatingViewTask *t = first_floating_view_task; t != 0; t = t->next) + { + // rjf: unpack + RD_Cfg *view = t->view; + F32 row_height_px = t->row_height_px; + Rng2F32 rect = t->rect; + String8 view_name = t->view_name; + String8 expr = t->expr; + B32 is_focused = t->is_focused; + B32 is_anchored = t->is_anchored; + F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate); + + // rjf: build cfg tree + RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new(view, str8_lit("selected")); + rd_cfg_new_replace(expr_root, expr); + + // rjf: push view regs + rd_push_regs(.view = view->id); + { + String8 view_expr = rd_expr_from_cfg(view); + String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); + // NOTE(rjf): we want to only fill out this view's file path slot if it + // evaluates one - this way, a view can use the slot to know the selected + // file path (if there is one). this is useful when pushing commandas which + // apply to a cursor, for example. + if(view_file_path.size != 0) + { + rd_regs()->file_path = view_file_path; + } + } + + // rjf: build + UI_Focus(is_focused ? UI_FocusKind_On : UI_FocusKind_Off) + UI_PrefHeight(ui_px(row_height_px, 1.f)) + { + // rjf: build top-level container box + UI_Box *container = &ui_nil_box; + UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y) UI_Squish(0.1f-0.1f*open_t) UI_Transparency(1.f-open_t) + UI_CornerRadius(ui_top_font_size()*0.25f) + { + container = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_RoundChildrenByParent| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawDropShadow| + (UI_BoxFlag_SquishAnchored*!!is_anchored), + "floating_view_container_%p", view); + } + + // rjf: peek press inside/outside events + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_Press && + evt->key == OS_Key_LeftMouseButton) + { + if(contains_2f32(container->rect, evt->pos)) + { + t->pressed = 1; + } + else + { + t->pressed_outside = 1; + } + } + } + } + + // rjf: build overlay container for loading animation + UI_Box *loading_overlay_container = &ui_nil_box; + UI_Parent(container) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); + } + + // rjf: build contents + UI_Parent(container) UI_Focus(is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) + { + ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_height(ui_pct(1, 0)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); + UI_Parent(view_contents_container) UI_WidthFill + { + rd_view_ui(rect); + } + } + + // rjf: build loading overlay + { + RD_ViewState *vs = rd_view_state_from_cfg(view); + F32 loading_t = vs->loading_t; + if(loading_t > 0.01f) UI_Parent(loading_overlay_container) + { + rd_loading_overlay(rect, loading_t, vs->loading_progress_v, vs->loading_progress_v_target); + } + } + + // rjf: interact with container + UI_Signal sig = ui_signal_from_box(container); + t->signal = sig; + } + + // rjf: pop interaction registers; commit if this is focused + RD_Regs *view_regs = rd_pop_regs(); + if(is_focused) + { + MemoryCopyStruct(rd_regs(), view_regs); + } + + // rjf: is not anchored? -> darken rest of screen + if(!is_anchored) + { + UI_TagF("inactive") UI_Transparency(1-open_t) UI_Rect(content_rect) ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_Floating, ui_key_zero()); + } + } + } + + //////////////////////////// + //- rjf: @window_ui_part do special handling of floating view interactions + // + { + //- rjf: hover eval focus rules + if(hover_eval_floating_view_task) + { + UI_Signal sig = hover_eval_floating_view_task->signal; + if(ui_pressed(sig) || hover_eval_floating_view_task->pressed) + { + ws->hover_eval_focused = 1; + } + if(ui_mouse_over(sig) || ws->hover_eval_focused) + { + ws->hover_eval_lastt_us = rd_state->time_in_us; + } + else if(ws->hover_eval_lastt_us+1000000 < rd_state->time_in_us) + { + rd_request_frame(); + } + if(hover_eval_floating_view_task->pressed_outside) + { + ws->hover_eval_focused = 0; + MemoryZeroStruct(&ws->hover_eval_string); + arena_clear(ws->hover_eval_arena); + rd_request_frame(); + } + } + + //- rjf: query interactions + if(query_floating_view_task) + { + String8 cmd_name = ws->query_regs->cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + + // rjf: close queries + if(ui_slot_press(UI_EventActionSlot_Cancel) || query_floating_view_task->pressed_outside) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + + // rjf: any queries which take a file path mutate the debugger's "current path" + if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + { + RD_Cfg *view = query_floating_view_task->view; + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); + if(input != &rd_nil_cfg) + { + String8 path_chopped = str8_chop_last_slash(input->first->string); + rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); + } + } + } + } + + //////////////////////////// + //- rjf: @window_ui_part top bar // ProfScope("build top bar") { @@ -5336,8 +7921,8 @@ rd_window_frame(RD_Window *ws) os_window_push_custom_edges(ws->os, window_edge_px); os_window_push_custom_title_bar(ws->os, dim_2f32(top_bar_rect).y); ui_set_next_flags(UI_BoxFlag_DefaultFocusNav|UI_BoxFlag_DisableFocusOverlay); - RD_Palette(RD_PaletteCode_MenuBar) - UI_Focus((ws->menu_bar_focused && window_is_focused && !ui_any_ctx_menu_is_open() && !ws->hover_eval_focused) ? UI_FocusKind_On : UI_FocusKind_Null) + UI_Focus((ws->menu_bar_focused && window_is_focused && !ui_any_ctx_menu_is_open()) ? UI_FocusKind_On : UI_FocusKind_Null) + UI_TagF("menu_bar") UI_Pane(top_bar_rect, str8_lit("###top_bar")) UI_WidthFill UI_Row UI_Focus(UI_FocusKind_Null) @@ -5346,421 +7931,408 @@ rd_window_frame(RD_Window *ws) MemoryZeroArray(ui_top_parent()->parent->corner_radii); //- rjf: left column - ui_set_next_flags(UI_BoxFlag_Clip|UI_BoxFlag_ViewScrollX|UI_BoxFlag_ViewClamp); - UI_WidthFill UI_NamedRow(str8_lit("###menu_bar")) { - //- rjf: icon - UI_Padding(ui_em(0.5f, 1.f)) + ui_set_next_flags(UI_BoxFlag_Clip|UI_BoxFlag_ViewScrollX|UI_BoxFlag_ViewClamp); + UI_WidthFill UI_NamedRow(str8_lit("###menu_bar")) { - UI_PrefWidth(ui_px(dim_2f32(top_bar_rect).y - ui_top_font_size()*0.8f, 1.f)) - UI_Column - UI_Padding(ui_em(0.4f, 1.f)) - UI_HeightFill + //- rjf: icon + UI_Padding(ui_em(0.5f, 1.f)) { - R_Handle texture = rd_state->icon_texture; - Vec2S32 texture_dim = r_size_from_tex2d(texture); - ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); - } - } - - //- rjf: menu items - ui_set_next_flags(UI_BoxFlag_DrawBackground); - UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(20, 1)) UI_GroupKey(menu_bar_group_key) - { - // rjf: file menu - UI_Key file_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_file_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(file_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) - { - String8 cmds[] = - { - rd_cmd_kind_info_table[RD_CmdKind_Open].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenUser].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenProject].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenRecentProject].string, - rd_cmd_kind_info_table[RD_CmdKind_Exit].string, - }; - U32 codepoints[] = - { - 'o', - 'u', - 'p', - 'r', - 'x', - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - } - - // rjf: window menu - UI_Key window_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_window_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(window_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) - { - String8 cmds[] = - { - rd_cmd_kind_info_table[RD_CmdKind_OpenWindow].string, - rd_cmd_kind_info_table[RD_CmdKind_CloseWindow].string, - rd_cmd_kind_info_table[RD_CmdKind_ToggleFullscreen].string, - }; - U32 codepoints[] = - { - 'w', - 'c', - 'f', - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - } - - // rjf: panel menu - UI_Key panel_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_panel_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(panel_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) - { - String8 cmds[] = - { - rd_cmd_kind_info_table[RD_CmdKind_NewPanelUp].string, - rd_cmd_kind_info_table[RD_CmdKind_NewPanelDown].string, - rd_cmd_kind_info_table[RD_CmdKind_NewPanelRight].string, - rd_cmd_kind_info_table[RD_CmdKind_NewPanelLeft].string, - rd_cmd_kind_info_table[RD_CmdKind_ClosePanel].string, - rd_cmd_kind_info_table[RD_CmdKind_RotatePanelColumns].string, - rd_cmd_kind_info_table[RD_CmdKind_NextPanel].string, - rd_cmd_kind_info_table[RD_CmdKind_PrevPanel].string, - rd_cmd_kind_info_table[RD_CmdKind_CloseTab].string, - rd_cmd_kind_info_table[RD_CmdKind_NextTab].string, - rd_cmd_kind_info_table[RD_CmdKind_PrevTab].string, - rd_cmd_kind_info_table[RD_CmdKind_TabBarTop].string, - rd_cmd_kind_info_table[RD_CmdKind_TabBarBottom].string, - rd_cmd_kind_info_table[RD_CmdKind_ResetToDefaultPanels].string, - rd_cmd_kind_info_table[RD_CmdKind_ResetToCompactPanels].string, - }; - U32 codepoints[] = - { - 'u', - 'd', - 'r', - 'l', - 'x', - 'c', - 'n', - 'p', - 't', - 'b', - 'v', - 0, - 0, - 0, - 0, - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - } - - // rjf: view menu - UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(view_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) - { - String8 cmds[] = - { - rd_cmd_kind_info_table[RD_CmdKind_Targets].string, - rd_cmd_kind_info_table[RD_CmdKind_Scheduler].string, - rd_cmd_kind_info_table[RD_CmdKind_CallStack].string, - rd_cmd_kind_info_table[RD_CmdKind_Modules].string, - rd_cmd_kind_info_table[RD_CmdKind_Output].string, - rd_cmd_kind_info_table[RD_CmdKind_Memory].string, - rd_cmd_kind_info_table[RD_CmdKind_Disassembly].string, - rd_cmd_kind_info_table[RD_CmdKind_Watch].string, - rd_cmd_kind_info_table[RD_CmdKind_Locals].string, - rd_cmd_kind_info_table[RD_CmdKind_Registers].string, - rd_cmd_kind_info_table[RD_CmdKind_Globals].string, - rd_cmd_kind_info_table[RD_CmdKind_ThreadLocals].string, - rd_cmd_kind_info_table[RD_CmdKind_Types].string, - rd_cmd_kind_info_table[RD_CmdKind_Procedures].string, - rd_cmd_kind_info_table[RD_CmdKind_Breakpoints].string, - rd_cmd_kind_info_table[RD_CmdKind_WatchPins].string, - rd_cmd_kind_info_table[RD_CmdKind_FilePathMap].string, - rd_cmd_kind_info_table[RD_CmdKind_AutoViewRules].string, - rd_cmd_kind_info_table[RD_CmdKind_Settings].string, - rd_cmd_kind_info_table[RD_CmdKind_ExceptionFilters].string, - rd_cmd_kind_info_table[RD_CmdKind_GettingStarted].string, - }; - U32 codepoints[] = - { - 't', - 's', - 'k', - 'd', - 'o', - 'm', - 'y', - 'w', - 'l', - 'r', - 0, - 0, - 0, - 0, - 'b', - 'h', - 'p', - 'v', - 'e', - 'g', - 0, - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - } - - // rjf: targets menu - UI_Key targets_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_targets_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(targets_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) - { - Temp scratch = scratch_begin(0, 0); - String8 cmds[] = - { - rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string, - }; - U32 codepoints[] = - { - 'a', - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - scratch_end(scratch); - } - - // rjf: ctrl menu - UI_Key ctrl_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_ctrl_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(ctrl_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) - { - String8 cmds[] = - { - rd_cmd_kind_info_table[D_CmdKind_Run].string, - rd_cmd_kind_info_table[D_CmdKind_KillAll].string, - rd_cmd_kind_info_table[D_CmdKind_Restart].string, - rd_cmd_kind_info_table[D_CmdKind_Halt].string, - rd_cmd_kind_info_table[D_CmdKind_SoftHaltRefresh].string, - rd_cmd_kind_info_table[D_CmdKind_StepInto].string, - rd_cmd_kind_info_table[D_CmdKind_StepOver].string, - rd_cmd_kind_info_table[D_CmdKind_StepOut].string, - rd_cmd_kind_info_table[D_CmdKind_Attach].string, - }; - U32 codepoints[] = - { - 'r', - 'k', - 's', - 'h', - 'f', - 'i', - 'o', - 't', - 'a', - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - } - - // rjf: help menu - UI_Key help_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_help_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(help_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) - { - UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); - ui_spacer(ui_em(1.f, 1.f)); - UI_PrefHeight(ui_children_sum(1)) UI_Row UI_Padding(ui_pct(1, 0)) + UI_PrefWidth(ui_px(dim_2f32(top_bar_rect).y - ui_top_font_size()*0.8f, 1.f)) + UI_Column + UI_Padding(ui_em(0.4f, 1.f)) + UI_HeightFill { R_Handle texture = rd_state->icon_texture; Vec2S32 texture_dim = r_size_from_tex2d(texture); - UI_PrefWidth(ui_px(ui_top_font_size()*10.f, 1.f)) - UI_PrefHeight(ui_px(ui_top_font_size()*10.f, 1.f)) - ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); + ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); } - ui_spacer(ui_em(1.f, 1.f)); - UI_Row - UI_PrefWidth(ui_text_dim(10, 1)) - UI_TextAlignment(UI_TextAlign_Center) - UI_Padding(ui_pct(1, 0)) - { - ui_labelf("Search for commands by pressing "); - UI_Flags(UI_BoxFlag_DrawBorder) - UI_TextAlignment(UI_TextAlign_Center) - rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_RunCommand].string); - } - ui_spacer(ui_em(1.f, 1.f)); - RD_Palette(RD_PaletteCode_NeutralPopButton) - UI_Row UI_Padding(ui_pct(1, 0)) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_text_dim(10, 1)) - UI_CornerRadius(ui_top_font_size()*0.5f) - { - String8 url = str8_lit("https://github.com/EpicGamesExt/raddebugger/issues"); - UI_Signal sig = ui_button(str8_lit("Submit Request, Issue, or Bug Report")); - if(ui_clicked(sig)) - { - os_open_in_browser(url); - } - } - ui_spacer(ui_em(0.5f, 1.f)); } - // rjf: buttons - UI_TextAlignment(UI_TextAlign_Center) UI_HeightFill + //- rjf: menu items + if(dim_2f32(top_bar_rect).x > ui_top_font_size()*60) { - // rjf: set up table - struct + ui_set_next_flags(UI_BoxFlag_DrawBackground); + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(20, 1)) UI_GroupKey(menu_bar_group_key) { - String8 name; - U32 codepoint; - OS_Key key; - UI_Key menu_key; - } - items[] = - { - {str8_lit("File"), 'f', OS_Key_F, file_menu_key}, - {str8_lit("Window"), 'w', OS_Key_W, window_menu_key}, - {str8_lit("Panel"), 'p', OS_Key_P, panel_menu_key}, - {str8_lit("View"), 'v', OS_Key_V, view_menu_key}, - {str8_lit("Targets"), 't', OS_Key_T, targets_menu_key}, - {str8_lit("Control"), 'c', OS_Key_C, ctrl_menu_key}, - {str8_lit("Help"), 'h', OS_Key_H, help_menu_key}, - }; - - // rjf: determine if one of the menus is already open - B32 menu_open = 0; - U64 open_menu_idx = 0; - for(U64 idx = 0; idx < ArrayCount(items); idx += 1) - { - if(ui_ctx_menu_is_open(items[idx].menu_key)) + // rjf: file menu + UI_Key file_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_file_menu_key_")); + UI_CtxMenu(file_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { - menu_open = 1; - open_menu_idx = idx; - break; + String8 cmds[] = + { + rd_cmd_kind_info_table[RD_CmdKind_Open].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenUser].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenProject].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenRecentProject].string, + rd_cmd_kind_info_table[RD_CmdKind_Exit].string, + }; + U32 codepoints[] = + { + 'o', + 'u', + 'p', + 'r', + 'x', + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); } - } - - // rjf: navigate between menus - U64 open_menu_idx_prime = open_menu_idx; - if(menu_open && ws->menu_bar_focused && window_is_focused) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) + + // rjf: window menu + UI_Key window_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_window_menu_key_")); + UI_CtxMenu(window_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { - B32 taken = 0; - if(evt->delta_2s32.x > 0) + String8 cmds[] = { - taken = 1; - open_menu_idx_prime += 1; - open_menu_idx_prime = open_menu_idx_prime%ArrayCount(items); + rd_cmd_kind_info_table[RD_CmdKind_OpenWindow].string, + rd_cmd_kind_info_table[RD_CmdKind_CloseWindow].string, + rd_cmd_kind_info_table[RD_CmdKind_ToggleFullscreen].string, + }; + U32 codepoints[] = + { + 'w', + 'c', + 'f', + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); + } + + // rjf: panel menu + UI_Key panel_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_panel_menu_key_")); + UI_CtxMenu(panel_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") + { + String8 cmds[] = + { + rd_cmd_kind_info_table[RD_CmdKind_NewPanelUp].string, + rd_cmd_kind_info_table[RD_CmdKind_NewPanelDown].string, + rd_cmd_kind_info_table[RD_CmdKind_NewPanelRight].string, + rd_cmd_kind_info_table[RD_CmdKind_NewPanelLeft].string, + rd_cmd_kind_info_table[RD_CmdKind_ClosePanel].string, + rd_cmd_kind_info_table[RD_CmdKind_RotatePanelColumns].string, + rd_cmd_kind_info_table[RD_CmdKind_NextPanel].string, + rd_cmd_kind_info_table[RD_CmdKind_PrevPanel].string, + rd_cmd_kind_info_table[RD_CmdKind_CloseTab].string, + rd_cmd_kind_info_table[RD_CmdKind_NextTab].string, + rd_cmd_kind_info_table[RD_CmdKind_PrevTab].string, + rd_cmd_kind_info_table[RD_CmdKind_TabBarTop].string, + rd_cmd_kind_info_table[RD_CmdKind_TabBarBottom].string, + rd_cmd_kind_info_table[RD_CmdKind_ResetToDefaultPanels].string, + rd_cmd_kind_info_table[RD_CmdKind_ResetToCompactPanels].string, + rd_cmd_kind_info_table[RD_CmdKind_ResetToSimplePanels].string, + }; + U32 codepoints[] = + { + 'u', + 'd', + 'r', + 'l', + 'x', + 'c', + 'n', + 'p', + 't', + 'b', + 'v', + 0, + 0, + 0, + 0, + 0, + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); + } + + // rjf: view menu + UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); + UI_CtxMenu(view_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") + { + String8 cmds[] = + { + rd_cmd_kind_info_table[RD_CmdKind_Targets].string, + rd_cmd_kind_info_table[RD_CmdKind_Scheduler].string, + rd_cmd_kind_info_table[RD_CmdKind_CallStack].string, + rd_cmd_kind_info_table[RD_CmdKind_Modules].string, + rd_cmd_kind_info_table[RD_CmdKind_Output].string, + rd_cmd_kind_info_table[RD_CmdKind_Memory].string, + rd_cmd_kind_info_table[RD_CmdKind_Disassembly].string, + rd_cmd_kind_info_table[RD_CmdKind_Watch].string, + rd_cmd_kind_info_table[RD_CmdKind_Locals].string, + rd_cmd_kind_info_table[RD_CmdKind_Registers].string, + rd_cmd_kind_info_table[RD_CmdKind_Globals].string, + rd_cmd_kind_info_table[RD_CmdKind_ThreadLocals].string, + rd_cmd_kind_info_table[RD_CmdKind_Types].string, + rd_cmd_kind_info_table[RD_CmdKind_Procedures].string, + rd_cmd_kind_info_table[RD_CmdKind_Breakpoints].string, + rd_cmd_kind_info_table[RD_CmdKind_WatchPins].string, + rd_cmd_kind_info_table[RD_CmdKind_FilePathMap].string, + rd_cmd_kind_info_table[RD_CmdKind_AutoViewRules].string, + rd_cmd_kind_info_table[RD_CmdKind_Settings].string, + rd_cmd_kind_info_table[RD_CmdKind_GettingStarted].string, + }; + U32 codepoints[] = + { + 't', + 's', + 'k', + 'd', + 'o', + 'm', + 'y', + 'w', + 'l', + 'r', + 0, + 0, + 0, + 0, + 'b', + 'h', + 'p', + 'v', + 'g', + 0, + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); + } + + // rjf: targets menu + UI_Key targets_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_targets_menu_key_")); + UI_CtxMenu(targets_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") + { + Temp scratch = scratch_begin(0, 0); + String8 cmds[] = + { + rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string, + rd_cmd_kind_info_table[RD_CmdKind_LaunchAndRun].string, + rd_cmd_kind_info_table[RD_CmdKind_LaunchAndStepInto].string, + }; + U32 codepoints[] = + { + 'a', + 'r', + 's', + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); + scratch_end(scratch); + } + + // rjf: ctrl menu + UI_Key ctrl_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_ctrl_menu_key_")); + UI_CtxMenu(ctrl_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") + { + String8 cmds[] = + { + rd_cmd_kind_info_table[D_CmdKind_Run].string, + rd_cmd_kind_info_table[D_CmdKind_KillAll].string, + rd_cmd_kind_info_table[D_CmdKind_Restart].string, + rd_cmd_kind_info_table[D_CmdKind_Halt].string, + rd_cmd_kind_info_table[D_CmdKind_StepInto].string, + rd_cmd_kind_info_table[D_CmdKind_StepOver].string, + rd_cmd_kind_info_table[D_CmdKind_StepOut].string, + rd_cmd_kind_info_table[D_CmdKind_Attach].string, + }; + U32 codepoints[] = + { + 'r', + 'k', + 's', + 'h', + 'i', + 'o', + 't', + 'a', + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); + } + + // rjf: help menu + UI_Key help_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_help_menu_key_")); + UI_CtxMenu(help_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") + { + UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_TagF("weak") + ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); + ui_spacer(ui_em(1.f, 1.f)); + UI_PrefHeight(ui_children_sum(1)) UI_Row UI_Padding(ui_pct(1, 0)) + { + R_Handle texture = rd_state->icon_texture; + Vec2S32 texture_dim = r_size_from_tex2d(texture); + UI_PrefWidth(ui_px(ui_top_font_size()*10.f, 1.f)) + UI_PrefHeight(ui_px(ui_top_font_size()*10.f, 1.f)) + ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); } - if(evt->delta_2s32.x < 0) + ui_spacer(ui_em(1.f, 1.f)); + UI_Row + UI_PrefWidth(ui_text_dim(10, 1)) + UI_TextAlignment(UI_TextAlign_Center) + UI_Padding(ui_pct(1, 0)) { - taken = 1; - open_menu_idx_prime = open_menu_idx_prime > 0 ? open_menu_idx_prime-1 : (ArrayCount(items)-1); + ui_labelf("Search for commands and options by pressing "); + UI_Flags(UI_BoxFlag_DrawBorder) + UI_TextAlignment(UI_TextAlign_Center) + rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); } - if(taken) + ui_spacer(ui_em(1.f, 1.f)); + UI_TagF("pop") + UI_Row UI_Padding(ui_pct(1, 0)) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_text_dim(10, 1)) + UI_CornerRadius(ui_top_font_size()*0.5f) { - ui_eat_event(evt); + String8 url = str8_lit("https://github.com/EpicGamesExt/raddebugger/issues"); + UI_Signal sig = ui_button(str8_lit("Submit Request, Issue, or Bug Report")); + if(ui_clicked(sig)) + { + os_open_in_browser(url); + } + } + ui_spacer(ui_em(0.5f, 1.f)); + } + + // rjf: buttons + UI_TextAlignment(UI_TextAlign_Center) UI_HeightFill + { + // rjf: set up table + struct + { + String8 name; + U32 codepoint; + OS_Key key; + UI_Key menu_key; + } + items[] = + { + {str8_lit("File"), 'f', OS_Key_F, file_menu_key}, + {str8_lit("Window"), 'w', OS_Key_W, window_menu_key}, + {str8_lit("Panel"), 'p', OS_Key_P, panel_menu_key}, + {str8_lit("View"), 'v', OS_Key_V, view_menu_key}, + {str8_lit("Targets"), 't', OS_Key_T, targets_menu_key}, + {str8_lit("Control"), 'c', OS_Key_C, ctrl_menu_key}, + {str8_lit("Help"), 'h', OS_Key_H, help_menu_key}, + }; + + // rjf: determine if one of the menus is already open + B32 menu_open = 0; + U64 open_menu_idx = 0; + for(U64 idx = 0; idx < ArrayCount(items); idx += 1) + { + if(ui_ctx_menu_is_open(items[idx].menu_key)) + { + menu_open = 1; + open_menu_idx = idx; + break; + } + } + + // rjf: navigate between menus + U64 open_menu_idx_prime = open_menu_idx; + if(menu_open && ws->menu_bar_focused && window_is_focused) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + B32 taken = 0; + if(evt->delta_2s32.x > 0) + { + taken = 1; + open_menu_idx_prime += 1; + open_menu_idx_prime = open_menu_idx_prime%ArrayCount(items); + } + if(evt->delta_2s32.x < 0) + { + taken = 1; + open_menu_idx_prime = open_menu_idx_prime > 0 ? open_menu_idx_prime-1 : (ArrayCount(items)-1); + } + if(taken) + { + ui_eat_event(evt); + } + } + } + + // rjf: make ui + for(U64 idx = 0; idx < ArrayCount(items); idx += 1) + { + ui_set_next_fastpath_codepoint(items[idx].codepoint); + B32 alt_fastpath_key = 0; + if(ui_key_press(OS_Modifier_Alt, items[idx].key)) + { + alt_fastpath_key = 1; + } + if((ws->menu_bar_key_held || ws->menu_bar_focused) && !ui_any_ctx_menu_is_open()) + { + ui_set_next_flags(UI_BoxFlag_DrawTextFastpathCodepoint); + } + UI_Signal sig = rd_menu_bar_button(items[idx].name); + os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); + if(menu_open) + { + if((ui_hovering(sig) && !ui_ctx_menu_is_open(items[idx].menu_key)) || (open_menu_idx_prime == idx && open_menu_idx_prime != open_menu_idx)) + { + ui_ctx_menu_open(items[idx].menu_key, sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0)); + } + } + else if(ui_pressed(sig) || alt_fastpath_key) + { + if(ui_ctx_menu_is_open(items[idx].menu_key)) + { + ui_ctx_menu_close(); + } + else + { + ui_ctx_menu_open(items[idx].menu_key, sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0)); + } + } } } } - // rjf: make ui - for(U64 idx = 0; idx < ArrayCount(items); idx += 1) + ui_spacer(ui_em(0.75f, 1)); + + // rjf: conversion task visualization + UI_PrefWidth(ui_text_dim(10, 1)) UI_HeightFill UI_TagF("pop") { - ui_set_next_fastpath_codepoint(items[idx].codepoint); - B32 alt_fastpath_key = 0; - if(ui_key_press(OS_Modifier_Alt, items[idx].key)) + Temp scratch = scratch_begin(0, 0); + RD_CfgList tasks = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("conversion_task")); + for(RD_CfgNode *n = tasks.first; n != 0; n = n->next) { - alt_fastpath_key = 1; - } - if((ws->menu_bar_key_held || ws->menu_bar_focused) && !ui_any_ctx_menu_is_open()) - { - ui_set_next_flags(UI_BoxFlag_DrawTextFastpathCodepoint); - } - UI_Signal sig = rd_menu_bar_button(items[idx].name); - os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); - if(menu_open) - { - if((ui_hovering(sig) && !ui_ctx_menu_is_open(items[idx].menu_key)) || (open_menu_idx_prime == idx && open_menu_idx_prime != open_menu_idx)) + RD_Cfg *task = n->v; + F32 task_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "task_anim_%I64u", task->id), 1.f); + if(task_t > 0.5f) { - ui_ctx_menu_open(items[idx].menu_key, sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0)); - } - } - else if(ui_pressed(sig) || alt_fastpath_key) - { - if(ui_ctx_menu_is_open(items[idx].menu_key)) - { - ui_ctx_menu_close(); - } - else - { - ui_ctx_menu_open(items[idx].menu_key, sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0)); + String8 rdi_path = task->first->string; + String8 rdi_name = str8_skip_last_slash(rdi_path); + String8 task_text = push_str8f(scratch.arena, "Creating %S...", rdi_name); + UI_Key key = ui_key_from_stringf(ui_key_zero(), "task_%p", task); + UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawText|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, key); + os_window_push_custom_title_bar_client_area(ws->os, box->rect); + UI_Signal sig = ui_signal_from_box(box); + if(ui_hovering(sig)) UI_Tooltip + { + ui_label(rdi_path); + } + ui_box_equip_display_string(box, task_text); } } + scratch_end(scratch); } } } - - ui_spacer(ui_em(0.75f, 1)); - - // rjf: conversion task visualization - UI_PrefWidth(ui_text_dim(10, 1)) UI_HeightFill - RD_Palette(RD_PaletteCode_NeutralPopButton) - { - Temp scratch = scratch_begin(0, 0); - RD_EntityList tasks = rd_query_cached_entity_list_with_kind(RD_EntityKind_ConversionTask); - for(RD_EntityNode *n = tasks.first; n != 0; n = n->next) - { - RD_Entity *task = n->entity; - if(task->alloc_time_us + 500000 < os_now_microseconds()) - { - String8 rdi_path = task->string; - String8 rdi_name = str8_skip_last_slash(rdi_path); - String8 task_text = push_str8f(scratch.arena, "Creating %S...", rdi_name); - UI_Key key = ui_key_from_stringf(ui_key_zero(), "task_%p", task); - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawText|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, key); - os_window_push_custom_title_bar_client_area(ws->os, box->rect); - UI_Signal sig = ui_signal_from_box(box); - if(ui_hovering(sig)) UI_Tooltip - { - ui_label(rdi_path); - } - ui_box_equip_display_string(box, task_text); - } - } - scratch_end(scratch); - } } //- rjf: center column - UI_PrefWidth(ui_children_sum(1.f)) UI_Row - UI_PrefWidth(ui_em(2.25f, 1)) + if(dim_2f32(top_bar_rect).x > ui_top_font_size()*60) + UI_PrefWidth(ui_children_sum(1.f)) UI_Row + UI_PrefWidth(ui_em(2.5f, 1)) RD_Font(RD_FontSlot_Icons) UI_FontSize(ui_top_font_size()*0.85f) { Temp scratch = scratch_begin(0, 0); - RD_EntityList targets = rd_push_active_target_list(scratch.arena); + RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); - B32 have_targets = targets.count != 0; + B32 have_targets = (targets.count != 0); B32 can_send_signal = !d_ctrl_targets_running(); B32 can_play = (have_targets && (can_send_signal || d_ctrl_last_run_frame_idx()+4 > d_frame_index())); B32 can_pause = (!can_send_signal); @@ -5771,7 +8343,7 @@ rd_window_frame(RD_Window *ws) if(can_play || !have_targets || processes.count == 0) UI_TextAlignment(UI_TextAlign_Center) UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextPositive))) + UI_TagF(can_play ? "good" : "weak") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Play]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -5795,11 +8367,16 @@ rd_window_frame(RD_Window *ws) else { ui_labelf("Launch all active targets:"); - for(RD_EntityNode *n = targets.first; n != 0; n = n->next) + for(RD_CfgNode *n = targets.first; n != 0; n = n->next) { - DR_FancyStringList title_fstrs = rd_title_fstrs_from_entity(ui_build_arena(), n->entity, ui_top_palette()->text_weak, ui_top_font_size()); - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &title_fstrs); + RD_Cfg *target = n->v; + B32 target_is_enabled = !rd_disabled_from_cfg(target); + if(target_is_enabled) + { + DR_FStrList title_fstrs = rd_title_fstrs_from_cfg(ui_build_arena(), target); + UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(box, &title_fstrs); + } } } } @@ -5812,7 +8389,7 @@ rd_window_frame(RD_Window *ws) //- rjf: restart button else UI_TextAlignment(UI_TextAlign_Center) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextPositive))) + UI_TagF("good") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Redo]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -5833,7 +8410,7 @@ rd_window_frame(RD_Window *ws) //- rjf: pause button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_pause ? 0 : UI_BoxFlag_Disabled) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNeutral))) + UI_TagF("weak") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Pause]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -5859,7 +8436,7 @@ rd_window_frame(RD_Window *ws) //- rjf: stop button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_stop ? 0 : UI_BoxFlag_Disabled) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) + UI_TagF(can_stop ? "bad" : "weak") { UI_Signal sig = {0}; { @@ -5888,6 +8465,7 @@ rd_window_frame(RD_Window *ws) //- rjf: step over button UI_TextAlignment(UI_TextAlign_Center) UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) + UI_TagF("weak") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_StepOver]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -5916,6 +8494,7 @@ rd_window_frame(RD_Window *ws) //- rjf: step into button UI_TextAlignment(UI_TextAlign_Center) UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) + UI_TagF("weak") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_StepInto]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -5944,6 +8523,7 @@ rd_window_frame(RD_Window *ws) //- rjf: step out button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_step ? 0 : UI_BoxFlag_Disabled) + UI_TagF("weak") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_StepOut]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -5985,7 +8565,7 @@ rd_window_frame(RD_Window *ws) ui_spacer(ui_pct(1, 0)); // rjf: loaded user viz - if(do_user_prof) RD_Palette(RD_PaletteCode_NeutralPopButton) + if(do_user_prof) UI_TagF("pop") { ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_child_layout_axis(Axis2_X); @@ -5999,7 +8579,7 @@ rd_window_frame(RD_Window *ws) os_window_push_custom_title_bar_client_area(ws->os, user_box->rect); UI_Parent(user_box) UI_PrefWidth(ui_text_dim(10, 0)) UI_TextAlignment(UI_TextAlign_Center) { - String8 user_path = rd_cfg_path_from_src(RD_CfgSrc_User); + String8 user_path = rd_state->user_path; user_path = str8_chop_last_dot(user_path); RD_Font(RD_FontSlot_Icons) UI_TextRasterFlags(rd_raster_flags_from_slot(RD_FontSlot_Icons)) @@ -6019,7 +8599,7 @@ rd_window_frame(RD_Window *ws) } // rjf: loaded project viz - if(do_user_prof) RD_Palette(RD_PaletteCode_NeutralPopButton) + if(do_user_prof) UI_TagF("pop") { ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_child_layout_axis(Axis2_X); @@ -6033,7 +8613,7 @@ rd_window_frame(RD_Window *ws) os_window_push_custom_title_bar_client_area(ws->os, prof_box->rect); UI_Parent(prof_box) UI_PrefWidth(ui_text_dim(10, 0)) UI_TextAlignment(UI_TextAlign_Center) { - String8 prof_path = rd_cfg_path_from_src(RD_CfgSrc_Project); + String8 prof_path = rd_state->project_path; prof_path = str8_chop_last_dot(prof_path); RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[RD_IconKind_Briefcase]); @@ -6051,6 +8631,20 @@ rd_window_frame(RD_Window *ws) ui_spacer(ui_em(0.75f, 0)); } + // rjf: close dropdown + UI_Key close_ctx_menu_key = ui_key_from_stringf(ui_key_zero(), "###close_ctx_menu"); + UI_CtxMenu(close_ctx_menu_key) UI_TagF("implicit") + { + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Window, 0, "Close Window"))) + { + rd_cmd(RD_CmdKind_CloseWindow); + } + if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Exit"))) + { + rd_cmd(RD_CmdKind_Exit); + } + } + // rjf: min/max/close buttons { UI_Signal min_sig = {0}; @@ -6059,12 +8653,13 @@ rd_window_frame(RD_Window *ws) Vec2F32 bar_dim = dim_2f32(top_bar_rect); F32 button_dim = floor_f32(bar_dim.y); UI_PrefWidth(ui_px(button_dim, 1.f)) + UI_FontSize(ui_top_font_size()*0.75f) { - min_sig = rd_icon_buttonf(RD_IconKind_Minus, 0, "##minimize"); - max_sig = rd_icon_buttonf(RD_IconKind_Window, 0, "##maximize"); + min_sig = rd_icon_buttonf(RD_IconKind_WindowMinimize, 0, "##minimize"); + max_sig = rd_icon_buttonf(os_window_is_maximized(ws->os) ? RD_IconKind_WindowRestore : RD_IconKind_Window, 0, "##maximize"); } UI_PrefWidth(ui_px(button_dim, 1.f)) - RD_Palette(RD_PaletteCode_NegativePopButton) + UI_TagF("bad_pop") { cls_sig = rd_icon_buttonf(RD_IconKind_X, 0, "##close"); } @@ -6078,7 +8673,15 @@ rd_window_frame(RD_Window *ws) } if(ui_clicked(cls_sig)) { - rd_cmd(RD_CmdKind_CloseWindow, .window = rd_handle_from_window(ws)); + if(ws->order_next != &rd_nil_window_state || + ws->order_prev != &rd_nil_window_state) + { + ui_ctx_menu_open(close_ctx_menu_key, cls_sig.box->key, v2f32(0, dim_2f32(cls_sig.box->rect).y)); + } + else + { + rd_cmd(RD_CmdKind_Exit); + } } os_window_push_custom_title_bar_client_area(ws->os, min_sig.box->rect); os_window_push_custom_title_bar_client_area(ws->os, max_sig.box->rect); @@ -6089,16 +8692,13 @@ rd_window_frame(RD_Window *ws) } //////////////////////////// - //- rjf: bottom bar + //- rjf: @window_ui_part bottom bar // ProfScope("build bottom bar") { B32 is_running = d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < d_frame_index(); CTRL_Event stop_event = d_ctrl_last_stop_event(); - UI_Palette *positive_scheme = rd_palette_from_code(RD_PaletteCode_PositivePopButton); - UI_Palette *running_scheme = rd_palette_from_code(RD_PaletteCode_NeutralPopButton); - UI_Palette *negative_scheme = rd_palette_from_code(RD_PaletteCode_NegativePopButton); - UI_Palette *palette = running_scheme; + String8 tag = str8_lit("pop"); if(!is_running) { switch(stop_event.cause) @@ -6106,32 +8706,19 @@ rd_window_frame(RD_Window *ws) default: case CTRL_EventCause_Finished: { - palette = positive_scheme; + tag = str8_lit("good_pop"); }break; case CTRL_EventCause_UserBreakpoint: case CTRL_EventCause_InterruptedByException: case CTRL_EventCause_InterruptedByTrap: case CTRL_EventCause_InterruptedByHalt: { - palette = negative_scheme; + tag = str8_lit("bad_pop"); }break; } } - if(ws->error_t > 0.01f) - { - UI_Palette *blended_scheme = push_array(ui_build_arena(), UI_Palette, 1); - MemoryCopyStruct(blended_scheme, palette); - for EachEnumVal(UI_ColorCode, code) - { - for(U64 idx = 0; idx < 4; idx += 1) - { - blended_scheme->colors[code].v[idx] += (negative_scheme->colors[code].v[idx] - blended_scheme->colors[code].v[idx]) * ws->error_t; - } - } - palette = blended_scheme; - } UI_Flags(UI_BoxFlag_DrawBackground) UI_CornerRadius(0) - UI_Palette(palette) + UI_Tag(tag) UI_Pane(bottom_bar_rect, str8_lit("###bottom_bar")) UI_WidthFill UI_Row UI_Flags(0) { @@ -6155,9 +8742,9 @@ rd_window_frame(RD_Window *ws) else { Temp scratch = scratch_begin(0, 0); - DR_FancyStringList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); + DR_FStrList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &explanation_fstrs); + ui_box_equip_display_fstrs(box, &explanation_fstrs); scratch_end(scratch); } } @@ -6168,12 +8755,13 @@ rd_window_frame(RD_Window *ws) if(rd_state->bind_change_active) { RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(rd_state->bind_change_cmd_name); + String8 display_name = rd_display_from_code_name(info->string); UI_PrefWidth(ui_text_dim(10, 1)) UI_Flags(UI_BoxFlag_DrawBackground) UI_TextAlignment(UI_TextAlign_Center) UI_CornerRadius(4) - RD_Palette(RD_PaletteCode_NeutralPopButton) - ui_labelf("Currently rebinding \"%S\" hotkey", info->display_name); + UI_TagF("pop") + ui_labelf("Currently rebinding \"%S\" hotkey", display_name); } // rjf: error visualization @@ -6201,624 +8789,18 @@ rd_window_frame(RD_Window *ws) } //////////////////////////// - //- rjf: prepare query view stack for the in-progress command - // - if(ws->query_cmd_name.size != 0) - { - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(ws->query_cmd_name); - RD_RegSlot missing_slot = cmd_kind_info->query.slot; - String8 query_view_name = cmd_kind_info->query.view_name; - if(query_view_name.size == 0) - { - switch(missing_slot) - { - default:{}break; - case RD_RegSlot_Thread: - case RD_RegSlot_Module: - case RD_RegSlot_Process: - case RD_RegSlot_Machine: - case RD_RegSlot_CtrlEntity:{query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_CtrlEntityLister].string;}break; - case RD_RegSlot_Entity: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_EntityLister].string;}break; - case RD_RegSlot_EntityList:{query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_EntityLister].string;}break; - case RD_RegSlot_FilePath: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_FileSystem].string;}break; - case RD_RegSlot_PID: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_SystemProcesses].string;}break; - } - } - RD_ViewRuleInfo *view_spec = rd_view_rule_info_from_string(query_view_name); - if(ws->query_view_stack_top->spec != view_spec || - rd_view_is_nil(ws->query_view_stack_top)) - { - Temp scratch = scratch_begin(0, 0); - - // rjf: clear existing query stack - for(RD_View *query_view = ws->query_view_stack_top, *next = 0; - !rd_view_is_nil(query_view); - query_view = next) - { - next = query_view->order_next; - rd_view_release(query_view); - } - - // rjf: determine default query - String8 default_query = {0}; - switch(missing_slot) - { - default: - if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) - { - default_query = rd_push_search_string(scratch.arena); - }break; - case RD_RegSlot_FilePath: - { - default_query = path_normalized_from_string(scratch.arena, rd_state->current_path); - default_query = push_str8f(scratch.arena, "%S/", default_query); - }break; - } - - // rjf: construct & push new view - RD_View *view = rd_view_alloc(); - rd_view_equip_spec(view, view_spec, default_query, &md_nil_node); - if(cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) - { - view->query_mark = txt_pt(1, 1); - } - ws->query_view_stack_top = view; - ws->query_view_selected = 1; - view->order_next = &rd_nil_view; - - scratch_end(scratch); - } - } - - //////////////////////////// - //- rjf: animate query info - // - { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; - - // rjf: animate query view selection transition - { - F32 target = (F32)!!ws->query_view_selected; - F32 diff = abs_f32(target - ws->query_view_selected_t); - if(diff > 0.005f) - { - rd_request_frame(); - if(diff < 0.005f) - { - ws->query_view_selected_t = target; - } - ws->query_view_selected_t += (target - ws->query_view_selected_t) * rate; - } - } - - // rjf: animate query view open/close transition - { - F32 query_view_t_target = !rd_view_is_nil(ws->query_view_stack_top); - F32 diff = abs_f32(query_view_t_target - ws->query_view_t); - if(diff > 0.005f) - { - rd_request_frame(); - } - if(diff < 0.005f) - { - ws->query_view_t = query_view_t_target; - } - ws->query_view_t += (query_view_t_target - ws->query_view_t) * rate; - } - } - - //////////////////////////// - //- rjf: build query - // - if(!rd_view_is_nil(ws->query_view_stack_top)) - UI_Focus((window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && ws->query_view_selected) ? UI_FocusKind_On : UI_FocusKind_Off) - RD_Palette(RD_PaletteCode_Floating) - { - RD_View *view = ws->query_view_stack_top; - String8 query_cmd_name = ws->query_cmd_name; - RD_CmdKindInfo *query_cmd_info = rd_cmd_kind_info_from_string(query_cmd_name); - RD_Query *query = &query_cmd_info->query; - - //- rjf: calculate rectangles - Vec2F32 window_center = center_2f32(window_rect); - F32 query_container_width = dim_2f32(window_rect).x*0.5f; - F32 query_container_margin = ui_top_font_size()*8.f; - F32 query_line_edit_height = ui_top_font_size()*3.f; - Rng2F32 query_container_rect = r2f32p(window_center.x - query_container_width/2 + (1-ws->query_view_t)*query_container_width/4, - window_rect.y0 + query_container_margin, - window_center.x + query_container_width/2 - (1-ws->query_view_t)*query_container_width/4, - window_rect.y1 - query_container_margin); - if(ws->query_view_stack_top->spec == &rd_nil_view_rule_info) - { - query_container_rect.y1 = query_container_rect.y0 + query_line_edit_height; - } - query_container_rect.y1 = mix_1f32(query_container_rect.y0, query_container_rect.y1, ws->query_view_t); - Rng2F32 query_container_content_rect = r2f32p(query_container_rect.x0, - query_container_rect.y0+query_line_edit_height, - query_container_rect.x1, - query_container_rect.y1); - - //- rjf: build floating query view container - UI_Box *query_container_box = &ui_nil_box; - UI_Rect(query_container_rect) - UI_CornerRadius(ui_top_font_size()*0.2f) - UI_ChildLayoutAxis(Axis2_Y) - UI_Squish(0.25f-ws->query_view_t*0.25f) - UI_Transparency(1-ws->query_view_t) - { - query_container_box = ui_build_box_from_stringf(UI_BoxFlag_Floating| - UI_BoxFlag_AllowOverflow| - UI_BoxFlag_Clickable| - UI_BoxFlag_Clip| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow, - "panel_query_container"); - } - - //- rjf: build query text input - B32 query_completed = 0; - B32 query_cancelled = 0; - UI_Parent(query_container_box) - UI_WidthFill UI_PrefHeight(ui_px(query_line_edit_height, 1.f)) - UI_Focus(UI_FocusKind_On) - { - ui_set_next_flags(UI_BoxFlag_DrawDropShadow|UI_BoxFlag_DrawBorder); - UI_Row - { - UI_PrefWidth(ui_text_dim(0.f, 1.f)) UI_Padding(ui_em(1.f, 1.f)) - { - RD_IconKind icon_kind = query_cmd_info->icon_kind; - if(icon_kind != RD_IconKind_Null) - { - RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[icon_kind]); - } - ui_labelf("%S", query_cmd_info->display_name); - } - RD_Font((query->flags & RD_QueryFlag_CodeInput) ? RD_FontSlot_Code : RD_FontSlot_Main) - UI_TextPadding(ui_top_font_size()*0.5f) - { - UI_Signal sig = rd_line_edit(RD_LineEditFlag_Border| - (RD_LineEditFlag_CodeContents * !!(query->flags & RD_QueryFlag_CodeInput)), - 0, - 0, - &view->query_cursor, - &view->query_mark, - view->query_buffer, - sizeof(view->query_buffer), - &view->query_string_size, - 0, - str8(view->query_buffer, view->query_string_size), - str8_lit("###query_text_input")); - if(ui_pressed(sig)) - { - ws->query_view_selected = 1; - } - } - UI_PrefWidth(ui_em(5.f, 1.f)) UI_Focus(UI_FocusKind_Off) RD_Palette(RD_PaletteCode_PositivePopButton) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_RightArrow, 0, "##complete_query"))) - { - query_completed = 1; - } - } - UI_PrefWidth(ui_em(3.f, 1.f)) UI_Focus(UI_FocusKind_Off) RD_Palette(RD_PaletteCode_PlainButton) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "##cancel_query"))) - { - query_cancelled = 1; - } - } - } - } - - //- rjf: build query view - UI_Parent(query_container_box) UI_WidthFill UI_Focus(UI_FocusKind_Null) - RD_RegsScope(.view = rd_handle_from_view(view)) - { - RD_ViewRuleUIFunctionType *view_ui = view->spec->ui; - view_ui(str8(view->query_buffer, view->query_string_size), view->params_roots[view->params_read_gen%ArrayCount(view->params_roots)], query_container_content_rect); - } - - //- rjf: query submission - if(((ui_is_focus_active() || (window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && !ws->query_view_selected)) && - ui_slot_press(UI_EventActionSlot_Cancel)) || query_cancelled) - { - rd_cmd(RD_CmdKind_CancelQuery); - } - if((ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) || query_completed) - { - Temp scratch = scratch_begin(0, 0); - RD_View *view = ws->query_view_stack_top; - RD_RegsScope() - { - rd_regs_fill_slot_from_string(query->slot, str8(view->query_buffer, view->query_string_size)); - rd_cmd(RD_CmdKind_CompleteQuery); - } - scratch_end(scratch); - } - - //- rjf: take fallthrough interaction in query view - { - UI_Signal sig = ui_signal_from_box(query_container_box); - if(ui_pressed(sig)) - { - ws->query_view_selected = 1; - } - } - - //- rjf: build darkening overlay for rest of screen - UI_Palette(ui_build_palette(0, .background = mix_4f32(rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay), v4f32(0, 0, 0, 0), 1-ws->query_view_selected_t))) - UI_Rect(window_rect) - { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - else - { - ws->query_view_selected = 0; - } - - //////////////////////////// - //- rjf: build hover eval - // - ProfScope("build hover eval") - { - B32 build_hover_eval = hover_eval_is_open; - - // rjf: disable hover eval if hovered view is actively scrolling - if(hover_eval_is_open) - { - for(RD_Panel *panel = ws->root_panel; - !rd_panel_is_nil(panel); - panel = rd_panel_rec_depth_first_pre(panel).next) - { - if(!rd_panel_is_nil(panel->first)) { continue; } - Rng2F32 panel_rect = rd_target_rect_from_panel(content_rect, ws->root_panel, panel); - RD_View *view = rd_selected_tab_from_panel(panel); - if(!rd_view_is_nil(view) && - contains_2f32(panel_rect, ui_mouse()) && - (abs_f32(view->scroll_pos.x.off) > 0.01f || - abs_f32(view->scroll_pos.y.off) > 0.01f)) - { - build_hover_eval = 0; - ws->hover_eval_first_frame_idx = rd_state->frame_index; - } - } - } - - // rjf: reset open animation - if(ws->hover_eval_string.size == 0) - { - ws->hover_eval_open_t = 0; - ws->hover_eval_num_visible_rows_t = 0; - } - - // rjf: reset animation, but request frames if we're waiting to open - if(ws->hover_eval_string.size != 0 && !hover_eval_is_open && ws->hover_eval_last_frame_idx < ws->hover_eval_first_frame_idx+20 && rd_state->frame_index-ws->hover_eval_last_frame_idx < 50) - { - rd_request_frame(); - ws->hover_eval_num_visible_rows_t = 0; - ws->hover_eval_open_t = 0; - } - - // rjf: reset focus state if hover eval is not being built - if(!build_hover_eval || ws->hover_eval_string.size == 0 || !hover_eval_is_open) - { - ws->hover_eval_focused = 0; - } - - // rjf: build hover eval - if(build_hover_eval && ws->hover_eval_string.size != 0 && hover_eval_is_open) - RD_Font(RD_FontSlot_Code) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - RD_Palette(RD_PaletteCode_Floating) - { - Temp scratch = scratch_begin(0, 0); - DI_Scope *scope = di_scope_open(); - String8 expr = ws->hover_eval_string; - E_Eval eval = e_eval_from_string(scratch.arena, expr); - EV_ViewRuleList top_level_view_rules = {0}; - - //- rjf: build if good - if(!e_type_key_match(eval.type_key, e_type_key_zero()) && !ui_any_ctx_menu_is_open()) - UI_Focus((hover_eval_is_open && !ui_any_ctx_menu_is_open() && ws->hover_eval_focused && (!query_is_open || !ws->query_view_selected)) ? UI_FocusKind_Null : UI_FocusKind_Off) - { - //- rjf: eval -> viz artifacts - F32 row_height = floor_f32(ui_top_font_size()*2.8f); - RD_CfgTable cfg_table = {0}; - U64 expr_hash = d_hash_from_string(expr); - String8 ev_view_key_string = push_str8f(scratch.arena, "eval_hover_%I64x", expr_hash); - EV_View *ev_view = rd_ev_view_from_key(d_hash_from_string(ev_view_key_string)); - EV_Key parent_key = ev_key_make(5381, 1); - EV_Key key = ev_key_make(ev_hash_from_key(parent_key), 1); - EV_BlockTree block_tree = ev_block_tree_from_string(scratch.arena, ev_view, str8_zero(), expr, &top_level_view_rules); - EV_BlockRangeList block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); - // EV_BlockList viz_blocks = ev_block_list_from_view_expr_keys(scratch.arena, ev_view, str8_zero(), &top_level_view_rules, expr, parent_key, key, 0); - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - U32 default_radix = (entity->kind == CTRL_EntityKind_Thread ? 16 : 10); - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, ev_view, str8_zero(), &block_ranges, r1u64(0, 50)); - // EV_WindowedRowList viz_rows = ev_windowed_row_list_from_block_list(scratch.arena, ev_view, r1s64(0, 50), &viz_blocks); - - //- rjf: animate - { - // 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; - if(abs_f32(hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) > 0.5f) - { - rd_request_frame(); - } - else - { - ws->hover_eval_num_visible_rows_t = hover_eval_container_height_target; - } - } - - // 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; - if(abs_f32(diff) < 0.01f) - { - ws->hover_eval_open_t = 1.f; - } - else - { - rd_request_frame(); - } - } - } - - //- rjf: calculate width - F32 width_px = 40.f*ui_top_font_size(); - F32 expr_column_width_px = 15.f*ui_top_font_size(); - F32 value_column_width_px = 25.f*ui_top_font_size(); - if(rows.first != 0) - { - EV_Row *row = rows.first; - E_Eval row_eval = e_eval_from_expr(scratch.arena, row->expr); - String8 row_expr_string = ev_expr_string_from_row(scratch.arena, row, 0); - String8 row_display_value = rd_value_string_from_eval(scratch.arena, EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), 500.f, row_eval, row->member, row->view_rules); - expr_column_width_px = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, 0, row_expr_string).x + ui_top_font_size()*10.f; - value_column_width_px = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, 0, row_display_value).x + ui_top_font_size()*5.f; - F32 total_dim_px = (expr_column_width_px + value_column_width_px); - width_px = Min(80.f*ui_top_font_size(), total_dim_px*1.5f); - } - - //- rjf: build hover eval box - F32 hover_eval_container_height = ws->hover_eval_num_visible_rows_t; - F32 corner_radius = ui_top_font_size()*0.25f; - ui_set_next_fixed_x(ws->hover_eval_spawn_pos.x); - ui_set_next_fixed_y(ws->hover_eval_spawn_pos.y); - ui_set_next_pref_width(ui_px(width_px, 1.f)); - ui_set_next_pref_height(ui_px(hover_eval_container_height, 1.f)); - ui_set_next_corner_radius_00(0); - ui_set_next_corner_radius_01(corner_radius); - ui_set_next_corner_radius_10(corner_radius); - ui_set_next_corner_radius_11(corner_radius); - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_squish(0.25f-0.25f*ws->hover_eval_open_t); - ui_set_next_transparency(1.f-ws->hover_eval_open_t); - UI_Focus(UI_FocusKind_On) - { - hover_eval_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_Clip| - UI_BoxFlag_AllowOverflowY| - UI_BoxFlag_ViewScroll| - UI_BoxFlag_ViewClamp| - UI_BoxFlag_Floating| - UI_BoxFlag_AnimatePos| - UI_BoxFlag_Clickable| - UI_BoxFlag_DefaultFocusNav, - "###hover_eval"); - } - - //- rjf: build contents - UI_Parent(hover_eval_box) UI_PrefHeight(ui_px(row_height, 1.f)) - { - //- rjf: build rows - for(EV_Row *row = rows.first; row != 0; row = row->next) - { - //- rjf: unpack row - U64 row_depth = ev_depth_from_block(row->block); - E_Eval row_eval = e_eval_from_expr(scratch.arena, row->expr); - String8 row_expr_string = ev_expr_string_from_row(scratch.arena, row, 0); - String8 row_edit_value = rd_value_string_from_eval(scratch.arena, 0, default_radix, ui_top_font(), ui_top_font_size(), 500.f, row_eval, row->member, row->view_rules); - String8 row_display_value = rd_value_string_from_eval(scratch.arena, EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), 500.f, row_eval, row->member, row->view_rules); - B32 row_is_editable = ev_row_is_editable(row); - B32 row_is_expandable = ev_row_is_expandable(row); - - //- rjf: determine if row's data is fresh and/or bad - B32 row_is_fresh = 0; - B32 row_is_bad = 0; - switch(row_eval.mode) - { - default:{}break; - case E_Mode_Offset: - { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_eval.space); - if(space_entity->kind == CTRL_EntityKind_Process) - { - U64 size = e_type_byte_size_from_key(row_eval.type_key); - size = Min(size, 64); - Rng1U64 vaddr_rng = r1u64(row_eval.value.u64, row_eval.value.u64+size); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, 0); - for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) - { - if(slice.byte_changed_flags[idx] != 0) - { - row_is_fresh = 1; - } - if(slice.byte_bad_flags[idx] != 0) - { - row_is_bad = 1; - } - } - } - }break; - } - - //- rjf: build row - UI_WidthFill UI_Row - { - ui_spacer(ui_em(0.5f, 1.f)); - if(row_depth > 0) - { - for(U64 indent = 0; indent < row_depth; indent += 1) - { - ui_spacer(ui_em(0.5f, 1.f)); - UI_Flags(UI_BoxFlag_DrawSideLeft) ui_spacer(ui_em(1.f, 1.f)); - } - } - U64 row_hash = ev_hash_from_key(row->key); - B32 row_is_expanded = ev_expansion_from_key(ev_view, row->key); - if(row_is_expandable) - UI_PrefWidth(ui_em(1.f, 1)) - if(ui_pressed(ui_expanderf(row->block->rows_default_expanded ? !row_is_expanded : row_is_expanded, "###%I64x_%I64x_is_expanded", row->key.parent_hash, row->key.child_id))) - { - ev_key_set_expansion(ev_view, row->block->key, row->key, !row_is_expanded); - } - if(!row_is_expandable) - { - UI_PrefWidth(ui_em(1.f, 1)) - UI_Flags(UI_BoxFlag_DrawTextWeak) - RD_Font(RD_FontSlot_Icons) - ui_label(rd_icon_kind_text_table[RD_IconKind_Dot]); - } - UI_WidthFill UI_TextRasterFlags(rd_raster_flags_from_slot(RD_FontSlot_Code)) - { - UI_PrefWidth(ui_px(expr_column_width_px, 1.f)) rd_code_label(1.f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), row_expr_string); - ui_spacer(ui_em(1.5f, 1.f)); - if(row_is_editable) - { - if(row_is_fresh) - { - Vec4F32 rgba = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = rgba)); - } - UI_Signal sig = rd_line_editf(RD_LineEditFlag_CodeContents| - RD_LineEditFlag_DisplayStringIsCode| - RD_LineEditFlag_PreferDisplayString| - RD_LineEditFlag_Border, - 0, 0, &ws->hover_eval_txt_cursor, &ws->hover_eval_txt_mark, ws->hover_eval_txt_buffer, sizeof(ws->hover_eval_txt_buffer), &ws->hover_eval_txt_size, 0, row_edit_value, "%S###val_%I64x", row_display_value, row_hash); - if(ui_pressed(sig)) - { - ws->hover_eval_focused = 1; - } - if(ui_committed(sig)) - { - String8 commit_string = str8(ws->hover_eval_txt_buffer, ws->hover_eval_txt_size); - B32 success = rd_commit_eval_value_string(row_eval, commit_string, 1); - if(success == 0) - { - log_user_error(str8_lit("Could not commit value successfully.")); - } - } - } - else - { - if(row_is_fresh) - { - Vec4F32 rgba = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = rgba)); - ui_set_next_flags(UI_BoxFlag_DrawBackground); - } - rd_code_label(1.f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), row_display_value); - } - } - if(row == rows.first) - { - UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(3.f, 1.f)) - UI_CornerRadius00(0) - UI_CornerRadius01(0) - UI_CornerRadius10(0) - UI_CornerRadius11(0) - { - UI_Signal watch_sig = rd_icon_buttonf(RD_IconKind_List, 0, "###watch_hover_eval"); - if(ui_hovering(watch_sig)) UI_Tooltip RD_Font(RD_FontSlot_Main) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - { - ui_labelf("Add the hovered expression to an opened watch view."); - } - if(ui_clicked(watch_sig)) - { - rd_cmd(RD_CmdKind_ToggleWatchExpression, .string = expr); - } - } - if(ws->hover_eval_file_path.size != 0 || ws->hover_eval_vaddr != 0) - UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(3.f, 1.f)) - UI_CornerRadius10(corner_radius) - UI_CornerRadius11(corner_radius) - { - UI_Signal pin_sig = rd_icon_buttonf(RD_IconKind_Pin, 0, "###pin_hover_eval"); - if(ui_hovering(pin_sig)) UI_Tooltip RD_Font(RD_FontSlot_Main) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - UI_CornerRadius00(0) - UI_CornerRadius01(0) - UI_CornerRadius10(0) - UI_CornerRadius11(0) - { - ui_labelf("Pin the hovered expression to this code location."); - } - if(ui_clicked(pin_sig)) - { - rd_cmd(RD_CmdKind_ToggleWatchPin, - .file_path = ws->hover_eval_file_path, - .cursor = ws->hover_eval_file_pt, - .vaddr = ws->hover_eval_vaddr, - .string = expr); - } - } - } - } - } - UI_PrefWidth(ui_px(0, 0)) ui_spacer(ui_px(hover_eval_container_height-row_height, 1.f)); - } - - //- rjf: interact - { - UI_Signal hover_eval_sig = ui_signal_from_box(hover_eval_box); - if(ui_mouse_over(hover_eval_sig)) - { - ws->hover_eval_last_frame_idx = rd_state->frame_index; - } - else if(ws->hover_eval_last_frame_idx+2 < rd_state->frame_index) - { - rd_request_frame(); - } - if(ui_pressed(hover_eval_sig)) - { - ws->hover_eval_focused = 1; - } - } - } - - di_scope_close(scope); - scratch_end(scratch); - } - } - - //////////////////////////// - //- rjf: panel non-leaf UI (drag boundaries, drag/drop sites) + //- rjf: @window_ui_part panel non-leaf UI (drag boundaries, drag/drop sites) // B32 is_changing_panel_boundaries = 0; ProfScope("non-leaf panel UI") - for(RD_Panel *panel = ws->root_panel; - !rd_panel_is_nil(panel); - panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { ////////////////////////// //- rjf: continue on leaf panels // - if(rd_panel_is_nil(panel->first)) + if(panel->first == &rd_nil_panel_node) { continue; } @@ -6827,14 +8809,14 @@ rd_window_frame(RD_Window *ws) //- rjf: grab info // Axis2 split_axis = panel->split_axis; - Rng2F32 panel_rect = rd_target_rect_from_panel(content_rect, ws->root_panel, panel); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); ////////////////////////// //- rjf: boundary tab-drag/drop sites // { - RD_View *drag_view = rd_view_from_handle(rd_state->drag_drop_regs->view); - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && !rd_view_is_nil(drag_view)) + RD_Cfg *drag_view = rd_cfg_from_id(rd_state->drag_drop_regs->view); + if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && drag_view != &rd_nil_cfg) { //- rjf: params F32 drop_site_major_dim_px = ceil_f32(ui_top_font_size()*7.f); @@ -6846,10 +8828,10 @@ rd_window_frame(RD_Window *ws) // // (this does not naturally follow from the below algorithm, since the // root level panel only splits on X) - if(panel == ws->root_panel) UI_CornerRadius(corner_radius) + if(panel == panel_tree.root) UI_CornerRadius(corner_radius) { Vec2F32 panel_rect_center = center_2f32(panel_rect); - Axis2 axis = axis2_flip(ws->root_panel->split_axis); + Axis2 axis = axis2_flip(panel_tree.root->split_axis); for EachEnumVal(Side, side) { UI_Key key = ui_key_from_stringf(ui_key_zero(), "root_extra_split_%i", side); @@ -6862,9 +8844,10 @@ rd_window_frame(RD_Window *ws) // rjf: build UI_Box *site_box = &ui_nil_box; { - UI_Rect(site_rect) + F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); + UI_Rect(site_rect) UI_Squish(0.1f-0.1f*site_open_t) UI_Transparency(1-site_open_t) { - site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key); + site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); ui_signal_from_box(site_box); } UI_Box *site_box_viz = &ui_nil_box; @@ -6872,16 +8855,14 @@ rd_window_frame(RD_Window *ws) UI_Padding(ui_px(padding, 1.f)) UI_Column UI_Padding(ui_px(padding, 1.f)) + UI_GroupKey(key) { ui_set_next_child_layout_axis(axis2_flip(axis)); - if(ui_key_match(key, ui_drop_hot_key())) - { - ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = rd_rgba_from_theme_color(RD_ThemeColor_Hover))); - } site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackgroundBlur, ui_key_zero()); + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawHotEffects, ui_key_zero()); } UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) { @@ -6898,14 +8879,23 @@ rd_window_frame(RD_Window *ws) // rjf: viz if(ui_key_match(site_box->key, ui_drop_hot_key())) { - Rng2F32 future_split_rect = site_rect; - future_split_rect.p0.v[axis] -= drop_site_major_dim_px; - future_split_rect.p1.v[axis] += drop_site_major_dim_px; - future_split_rect.p0.v[axis2_flip(axis)] = panel_rect.p0.v[axis2_flip(axis)]; - future_split_rect.p1.v[axis2_flip(axis)] = panel_rect.p1.v[axis2_flip(axis)]; - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) + Rng2F32 future_split_rect_target = site_rect; + future_split_rect_target.p0.v[axis] -= drop_site_major_dim_px; + future_split_rect_target.p1.v[axis] += drop_site_major_dim_px; + future_split_rect_target.p0.v[axis2_flip(axis)] = panel_rect.p0.v[axis2_flip(axis)]; + future_split_rect_target.p1.v[axis2_flip(axis)] = panel_rect.p1.v[axis2_flip(axis)]; + future_split_rect_target = pad_2f32(future_split_rect_target, -ui_top_font_size()*2.f); + Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target); + Rng2F32 future_split_rect = { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), + }; + UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f) + { + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } } @@ -6917,9 +8907,9 @@ rd_window_frame(RD_Window *ws) Dir2_Invalid); if(dir != Dir2_Invalid) { - RD_Panel *split_panel = panel; + RD_PanelNode *split_panel = panel; rd_cmd(RD_CmdKind_SplitPanel, - .dst_panel = rd_handle_from_panel(split_panel), + .dst_panel = split_panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, .dir2 = dir); @@ -6930,12 +8920,12 @@ rd_window_frame(RD_Window *ws) //- rjf: iterate all children, build boundary drop sites Axis2 split_axis = panel->split_axis; - UI_CornerRadius(corner_radius) for(RD_Panel *child = panel->first;; child = child->next) + UI_CornerRadius(corner_radius) for(RD_PanelNode *child = panel->first;; child = child->next) { // rjf: form rect - Rng2F32 child_rect = rd_target_rect_from_panel_child(panel_rect, panel, child); + Rng2F32 child_rect = rd_target_rect_from_panel_node_child(panel_rect, panel, child); Vec2F32 child_rect_center = center_2f32(child_rect); - UI_Key key = ui_key_from_stringf(ui_key_zero(), "drop_boundary_%p_%p", panel, child); + UI_Key key = ui_key_from_stringf(ui_key_zero(), "drop_boundary_%p_%p", panel->cfg, child->cfg); Rng2F32 site_rect = r2f32(child_rect_center, child_rect_center); site_rect.p0.v[split_axis] = child_rect.p0.v[split_axis] - drop_site_minor_dim_px/2; site_rect.p1.v[split_axis] = child_rect.p0.v[split_axis] + drop_site_minor_dim_px/2; @@ -6945,9 +8935,10 @@ rd_window_frame(RD_Window *ws) // rjf: build UI_Box *site_box = &ui_nil_box; { - UI_Rect(site_rect) + F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); + UI_Rect(site_rect) UI_Squish(0.1f-0.1f*site_open_t) UI_Transparency(1-site_open_t) { - site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key); + site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); ui_signal_from_box(site_box); } UI_Box *site_box_viz = &ui_nil_box; @@ -6955,16 +8946,14 @@ rd_window_frame(RD_Window *ws) UI_Padding(ui_px(padding, 1.f)) UI_Column UI_Padding(ui_px(padding, 1.f)) + UI_GroupKey(key) { ui_set_next_child_layout_axis(axis2_flip(split_axis)); - if(ui_key_match(key, ui_drop_hot_key())) - { - ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = rd_rgba_from_theme_color(RD_ThemeColor_Hover))); - } site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackgroundBlur, ui_key_zero()); + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawHotEffects, ui_key_zero()); } UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) { @@ -6981,14 +8970,23 @@ rd_window_frame(RD_Window *ws) // rjf: viz if(ui_key_match(site_box->key, ui_drop_hot_key())) { - Rng2F32 future_split_rect = site_rect; - future_split_rect.p0.v[split_axis] -= drop_site_major_dim_px; - future_split_rect.p1.v[split_axis] += drop_site_major_dim_px; - future_split_rect.p0.v[axis2_flip(split_axis)] = child_rect.p0.v[axis2_flip(split_axis)]; - future_split_rect.p1.v[axis2_flip(split_axis)] = child_rect.p1.v[axis2_flip(split_axis)]; - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) + Rng2F32 future_split_rect_target = site_rect; + future_split_rect_target.p0.v[split_axis] -= drop_site_major_dim_px; + future_split_rect_target.p1.v[split_axis] += drop_site_major_dim_px; + future_split_rect_target.p0.v[axis2_flip(split_axis)] = child_rect.p0.v[axis2_flip(split_axis)]; + future_split_rect_target.p1.v[axis2_flip(split_axis)] = child_rect.p1.v[axis2_flip(split_axis)]; + future_split_rect_target = pad_2f32(future_split_rect_target, -ui_top_font_size()*2.f); + Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target); + Rng2F32 future_split_rect = { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), + }; + UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f) + { + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } } @@ -6996,21 +8994,21 @@ rd_window_frame(RD_Window *ws) if(ui_key_match(site_box->key, ui_drop_hot_key()) && rd_drag_drop()) { Dir2 dir = (panel->split_axis == Axis2_X ? Dir2_Left : Dir2_Up); - RD_Panel *split_panel = child; - if(rd_panel_is_nil(split_panel)) + RD_PanelNode *split_panel = child; + if(split_panel == &rd_nil_panel_node) { split_panel = panel->last; dir = (panel->split_axis == Axis2_X ? Dir2_Right : Dir2_Down); } rd_cmd(RD_CmdKind_SplitPanel, - .dst_panel = rd_handle_from_panel(split_panel), + .dst_panel = split_panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, .dir2 = dir); } // rjf: exit on opl child - if(rd_panel_is_nil(child)) + if(child == &rd_nil_panel_node) { break; } @@ -7021,12 +9019,14 @@ rd_window_frame(RD_Window *ws) ////////////////////////// //- rjf: do UI for drag boundaries between all children // - for(RD_Panel *child = panel->first; !rd_panel_is_nil(child) && !rd_panel_is_nil(child->next); child = child->next) + for(RD_PanelNode *child = panel->first; + child != &rd_nil_panel_node && child->next != &rd_nil_panel_node; + child = child->next) { - RD_Panel *min_child = child; - RD_Panel *max_child = min_child->next; - Rng2F32 min_child_rect = rd_target_rect_from_panel_child(panel_rect, panel, min_child); - Rng2F32 max_child_rect = rd_target_rect_from_panel_child(panel_rect, panel, max_child); + RD_PanelNode *min_child = child; + RD_PanelNode *max_child = min_child->next; + Rng2F32 min_child_rect = rd_target_rect_from_panel_node_child(panel_rect, panel, min_child); + Rng2F32 max_child_rect = rd_target_rect_from_panel_node_child(panel_rect, panel, max_child); Rng2F32 boundary_rect = {0}; { boundary_rect.p0.v[split_axis] = min_child_rect.p1.v[split_axis] - ui_top_font_size()/3; @@ -7038,7 +9038,7 @@ rd_window_frame(RD_Window *ws) UI_Rect(boundary_rect) { ui_set_next_hover_cursor(split_axis == Axis2_X ? OS_Cursor_LeftRight : OS_Cursor_UpDown); - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%p_%p", min_child, max_child); + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%p_%p", min_child->cfg, max_child->cfg); UI_Signal sig = ui_signal_from_box(box); if(ui_double_clicked(sig)) { @@ -7046,6 +9046,8 @@ rd_window_frame(RD_Window *ws) F32 sum_pct = min_child->pct_of_parent + max_child->pct_of_parent; min_child->pct_of_parent = 0.5f * sum_pct; max_child->pct_of_parent = 0.5f * sum_pct; + rd_cfg_equip_stringf(min_child->cfg, "%f", min_child->pct_of_parent); + rd_cfg_equip_stringf(max_child->cfg, "%f", max_child->pct_of_parent); } else if(ui_pressed(sig)) { @@ -7078,6 +9080,8 @@ rd_window_frame(RD_Window *ws) } min_child->pct_of_parent = min_pct__after; max_child->pct_of_parent = max_pct__after; + rd_cfg_equip_stringf(min_child->cfg, "%f", min_pct__after); + rd_cfg_equip_stringf(max_child->cfg, "%f", max_pct__after); is_changing_panel_boundaries = 1; } } @@ -7085,492 +9089,454 @@ rd_window_frame(RD_Window *ws) } //////////////////////////// - //- rjf: animate panels + //- rjf: @window_ui_part animate panels // { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-50.f * rd_state->frame_dt)) : 1.f; Vec2F32 content_rect_dim = dim_2f32(content_rect); if(content_rect_dim.x > 0 && content_rect_dim.y > 0) { - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - Rng2F32 target_rect_px = rd_target_rect_from_panel(content_rect, ws->root_panel, panel); + Rng2F32 target_rect_px = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); Rng2F32 target_rect_pct = r2f32p(target_rect_px.x0/content_rect_dim.x, target_rect_px.y0/content_rect_dim.y, target_rect_px.x1/content_rect_dim.x, target_rect_px.y1/content_rect_dim.y); - if(abs_f32(target_rect_pct.x0 - panel->animated_rect_pct.x0) > 0.005f || - abs_f32(target_rect_pct.y0 - panel->animated_rect_pct.y0) > 0.005f || - abs_f32(target_rect_pct.x1 - panel->animated_rect_pct.x1) > 0.005f || - abs_f32(target_rect_pct.y1 - panel->animated_rect_pct.y1) > 0.005f) - { - rd_request_frame(); - } - panel->animated_rect_pct.x0 += rate * (target_rect_pct.x0 - panel->animated_rect_pct.x0); - panel->animated_rect_pct.y0 += rate * (target_rect_pct.y0 - panel->animated_rect_pct.y0); - panel->animated_rect_pct.x1 += rate * (target_rect_pct.x1 - panel->animated_rect_pct.x1); - panel->animated_rect_pct.y1 += rate * (target_rect_pct.y1 - panel->animated_rect_pct.y1); - if(ws->frames_alive < 5 || is_changing_panel_boundaries) - { - panel->animated_rect_pct = target_rect_pct; - } + B32 reset = (ws->window_layout_reset || ws->frames_alive < 5 || is_changing_panel_boundaries); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0, .reset = reset); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0, .reset = reset); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1, .reset = reset); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1, .reset = reset); } } + ws->window_layout_reset = 0; } //////////////////////////// - //- rjf: panel leaf UI + //- rjf: @window_ui_part panel leaf UI // - ProfScope("leaf panel UI") - for(RD_Panel *panel = ws->root_panel; - !rd_panel_is_nil(panel); - panel = rd_panel_rec_depth_first_pre(panel).next) + if(content_rect.x1 > content_rect.x0 && content_rect.y1 > content_rect.y0) { - if(!rd_panel_is_nil(panel->first)) {continue;} - B32 panel_is_focused = (window_is_focused && - !ws->menu_bar_focused && - (!query_is_open || !ws->query_view_selected) && - !ui_any_ctx_menu_is_open() && - !ws->hover_eval_focused && - ws->focused_panel == panel); - UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) + ProfScope("leaf panel UI") + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - ////////////////////////// - //- rjf: calculate UI rectangles - // - Vec2F32 content_rect_dim = dim_2f32(content_rect); - Rng2F32 panel_rect_pct = panel->animated_rect_pct; - Rng2F32 panel_rect = r2f32p(panel_rect_pct.x0*content_rect_dim.x, - panel_rect_pct.y0*content_rect_dim.y, - panel_rect_pct.x1*content_rect_dim.x, - panel_rect_pct.y1*content_rect_dim.y); - panel_rect = pad_2f32(panel_rect, -1.f); - F32 tab_bar_rheight = ui_top_font_size()*3.f; - F32 tab_bar_vheight = ui_top_font_size()*2.6f; - F32 tab_bar_rv_diff = tab_bar_rheight - tab_bar_vheight; - F32 tab_spacing = ui_top_font_size()*0.4f; - F32 filter_bar_height = ui_top_font_size()*3.f; - Rng2F32 tab_bar_rect = r2f32p(panel_rect.x0, panel_rect.y0, panel_rect.x1, panel_rect.y0 + tab_bar_vheight); - Rng2F32 content_rect = r2f32p(panel_rect.x0, panel_rect.y0+tab_bar_vheight, panel_rect.x1, panel_rect.y1); - Rng2F32 filter_rect = {0}; - if(panel->tab_side == Side_Max) + if(panel->first != &rd_nil_panel_node) {continue;} + B32 panel_is_focused = (window_is_focused && + !ws->menu_bar_focused && + !query_is_open && + !ui_any_ctx_menu_is_open() && + !ws->hover_eval_focused && + panel_tree.focused == panel); + RD_Cfg *selected_tab = panel->selected_tab; + RD_ViewState *selected_tab_view_state = rd_view_state_from_cfg(selected_tab); + ProfScope("leaf panel UI work - %.*s: %.*s", str8_varg(selected_tab->string), str8_varg(rd_expr_from_cfg(selected_tab))) + UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) { - tab_bar_rect.y0 = panel_rect.y1 - tab_bar_vheight; - tab_bar_rect.y1 = panel_rect.y1; - content_rect.y0 = panel_rect.y0; - content_rect.y1 = panel_rect.y1 - tab_bar_vheight; - } - { - RD_View *tab = rd_selected_tab_from_panel(panel); - if(tab->is_filtering_t > 0.01f) + ////////////////////////// + //- rjf: calculate UI rectangles + // + Vec2F32 content_rect_dim = dim_2f32(content_rect); + Rng2F32 target_rect_px = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); + Rng2F32 target_rect_pct = r2f32p(target_rect_px.x0 / content_rect_dim.x, + target_rect_px.y0 / content_rect_dim.y, + target_rect_px.x1 / content_rect_dim.x, + target_rect_px.y1 / content_rect_dim.y); + Rng2F32 panel_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1)); + Rng2F32 panel_rect = r2f32p(panel_rect_pct.x0*content_rect_dim.x, + panel_rect_pct.y0*content_rect_dim.y, + panel_rect_pct.x1*content_rect_dim.x, + panel_rect_pct.y1*content_rect_dim.y); + panel_rect = pad_2f32(panel_rect, floor_f32(-ui_top_font_size()*0.15f)); + F32 tab_bar_rheight = floor_f32(ui_top_font_size()*3.5f); + F32 tab_bar_vheight = floor_f32(ui_top_font_size()*3.f); + F32 tab_bar_rv_diff = tab_bar_rheight - tab_bar_vheight; + F32 tab_spacing = floor_f32(ui_top_font_size()*0.4f); + Rng2F32 tab_bar_rect = r2f32p(panel_rect.x0, panel_rect.y0, panel_rect.x1, panel_rect.y0 + tab_bar_vheight); + Rng2F32 content_rect = r2f32p(panel_rect.x0, panel_rect.y0+tab_bar_vheight, panel_rect.x1, panel_rect.y1); + if(panel->tab_side == Side_Max) { - filter_rect.x0 = content_rect.x0; - filter_rect.y0 = content_rect.y0; - filter_rect.x1 = content_rect.x1; - content_rect.y0 += filter_bar_height*tab->is_filtering_t; - filter_rect.y1 = content_rect.y0; + tab_bar_rect.y0 = panel_rect.y1 - tab_bar_vheight; + tab_bar_rect.y1 = panel_rect.y1; + content_rect.y0 = panel_rect.y0; + content_rect.y1 = panel_rect.y1 - tab_bar_vheight; } - } - - ////////////////////////// - //- rjf: build combined split+movetab drag/drop sites - // - { - RD_View *view = rd_view_from_handle(rd_state->drag_drop_regs->view); - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && !rd_view_is_nil(view) && contains_2f32(panel_rect, ui_mouse())) + tab_bar_rect = intersect_2f32(tab_bar_rect, panel_rect); + content_rect = intersect_2f32(content_rect, panel_rect); + + ////////////////////////// + //- rjf: decide to skip this panel (e.g. if it is too small + // + B32 build_panel = (content_rect.x1 > content_rect.x0 && content_rect.y1 > content_rect.y0); + + ////////////////////////// + //- rjf: build combined split+movetab drag/drop sites + // + if(build_panel) { - F32 drop_site_dim_px = ceil_f32(ui_top_font_size()*7.f); - Vec2F32 drop_site_half_dim = v2f32(drop_site_dim_px/2, drop_site_dim_px/2); - Vec2F32 panel_center = center_2f32(panel_rect); - F32 corner_radius = ui_top_font_size()*0.5f; - F32 padding = ceil_f32(ui_top_font_size()*0.5f); - struct - { - UI_Key key; - Dir2 split_dir; - Rng2F32 rect; - } - sites[] = + RD_Cfg *view = rd_cfg_from_id(rd_state->drag_drop_regs->view); + if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg && contains_2f32(panel_rect, ui_mouse()) && ui_key_match(ui_drop_hot_key(), ui_key_zero())) { + F32 drop_site_dim_px = ceil_f32(ui_top_font_size()*7.f); + drop_site_dim_px = Min(drop_site_dim_px, dim_2f32(panel_rect).v[panel->split_axis]/4.f); + drop_site_dim_px = Max(drop_site_dim_px, ceil_f32(ui_top_font_size()*3.f)); + Vec2F32 drop_site_half_dim = v2f32(drop_site_dim_px/2, drop_site_dim_px/2); + Vec2F32 panel_center = center_2f32(panel_rect); + F32 corner_radius = ui_top_font_size()*0.5f; + F32 padding = ceil_f32(ui_top_font_size()*0.5f); + struct { - ui_key_from_stringf(ui_key_zero(), "drop_split_center_%p", panel), - Dir2_Invalid, - r2f32(sub_2f32(panel_center, drop_site_half_dim), - add_2f32(panel_center, drop_site_half_dim)) - }, + UI_Key key; + Dir2 split_dir; + Rng2F32 rect; + } + sites[] = { - ui_key_from_stringf(ui_key_zero(), "drop_split_up_%p", panel), - Dir2_Up, - r2f32p(panel_center.x-drop_site_half_dim.x, - panel_center.y-drop_site_half_dim.y - drop_site_half_dim.y*2, - panel_center.x+drop_site_half_dim.x, - panel_center.y+drop_site_half_dim.y - drop_site_half_dim.y*2), - }, + { + ui_key_from_stringf(ui_key_zero(), "drop_split_center_%p", panel->cfg), + Dir2_Invalid, + r2f32(sub_2f32(panel_center, drop_site_half_dim), + add_2f32(panel_center, drop_site_half_dim)) + }, + { + ui_key_from_stringf(ui_key_zero(), "drop_split_up_%p", panel->cfg), + Dir2_Up, + r2f32p(panel_center.x-drop_site_half_dim.x, + panel_center.y-drop_site_half_dim.y - drop_site_half_dim.y*2, + panel_center.x+drop_site_half_dim.x, + panel_center.y+drop_site_half_dim.y - drop_site_half_dim.y*2), + }, + { + ui_key_from_stringf(ui_key_zero(), "drop_split_down_%p", panel->cfg), + Dir2_Down, + r2f32p(panel_center.x-drop_site_half_dim.x, + panel_center.y-drop_site_half_dim.y + drop_site_half_dim.y*2, + panel_center.x+drop_site_half_dim.x, + panel_center.y+drop_site_half_dim.y + drop_site_half_dim.y*2), + }, + { + ui_key_from_stringf(ui_key_zero(), "drop_split_left_%p", panel->cfg), + Dir2_Left, + r2f32p(panel_center.x-drop_site_half_dim.x - drop_site_half_dim.x*2, + panel_center.y-drop_site_half_dim.y, + panel_center.x+drop_site_half_dim.x - drop_site_half_dim.x*2, + panel_center.y+drop_site_half_dim.y), + }, + { + ui_key_from_stringf(ui_key_zero(), "drop_split_right_%p", panel->cfg), + Dir2_Right, + r2f32p(panel_center.x-drop_site_half_dim.x + drop_site_half_dim.x*2, + panel_center.y-drop_site_half_dim.y, + panel_center.x+drop_site_half_dim.x + drop_site_half_dim.x*2, + panel_center.y+drop_site_half_dim.y), + }, + }; + UI_CornerRadius(corner_radius) + for(U64 idx = 0; idx < ArrayCount(sites); idx += 1) { - ui_key_from_stringf(ui_key_zero(), "drop_split_down_%p", panel), - Dir2_Down, - r2f32p(panel_center.x-drop_site_half_dim.x, - panel_center.y-drop_site_half_dim.y + drop_site_half_dim.y*2, - panel_center.x+drop_site_half_dim.x, - panel_center.y+drop_site_half_dim.y + drop_site_half_dim.y*2), - }, - { - ui_key_from_stringf(ui_key_zero(), "drop_split_left_%p", panel), - Dir2_Left, - r2f32p(panel_center.x-drop_site_half_dim.x - drop_site_half_dim.x*2, - panel_center.y-drop_site_half_dim.y, - panel_center.x+drop_site_half_dim.x - drop_site_half_dim.x*2, - panel_center.y+drop_site_half_dim.y), - }, - { - ui_key_from_stringf(ui_key_zero(), "drop_split_right_%p", panel), - Dir2_Right, - r2f32p(panel_center.x-drop_site_half_dim.x + drop_site_half_dim.x*2, - panel_center.y-drop_site_half_dim.y, - panel_center.x+drop_site_half_dim.x + drop_site_half_dim.x*2, - panel_center.y+drop_site_half_dim.y), - }, - }; - UI_CornerRadius(corner_radius) + UI_Key key = sites[idx].key; + Dir2 dir = sites[idx].split_dir; + Rng2F32 rect = sites[idx].rect; + Axis2 split_axis = axis2_from_dir2(dir); + Side split_side = side_from_dir2(dir); + if(dir != Dir2_Invalid && split_axis == panel->parent->split_axis) + { + continue; + } + UI_Box *site_box = &ui_nil_box; + { + F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); + UI_Rect(rect) UI_Squish(0.1f-0.1f*site_open_t) UI_Transparency(1-site_open_t) + { + site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); + ui_signal_from_box(site_box); + } + UI_Box *site_box_viz = &ui_nil_box; + UI_GroupKey(key) + UI_Parent(site_box) UI_WidthFill UI_HeightFill + UI_Padding(ui_px(padding, 1.f)) + UI_Column + UI_Padding(ui_px(padding, 1.f)) + { + ui_set_next_child_layout_axis(axis2_flip(split_axis)); + site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawDropShadow| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawHotEffects, ui_key_zero()); + } + if(dir != Dir2_Invalid) + { + UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) + { + ui_set_next_child_layout_axis(split_axis); + UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); + UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) UI_TagF("drop_site") + { + if(split_side == Side_Min) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } + ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); + ui_spacer(ui_px(padding, 1.f)); + if(split_side == Side_Max) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } + ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); + } + } + } + else + { + UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) + { + ui_set_next_child_layout_axis(split_axis); + UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); + UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) UI_TagF("drop_site") + { + ui_build_box_from_key(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } + } + } + if(ui_key_match(site_box->key, ui_drop_hot_key()) && rd_drag_drop()) + { + if(dir != Dir2_Invalid) + { + rd_cmd(RD_CmdKind_SplitPanel, + .dst_panel = panel->cfg->id, + .panel = rd_state->drag_drop_regs->panel, + .view = rd_state->drag_drop_regs->view, + .dir2 = dir); + } + else + { + rd_cmd(RD_CmdKind_MoveTab, + .dst_panel = panel->cfg->id, + .panel = rd_state->drag_drop_regs->panel, + .view = rd_state->drag_drop_regs->view, + .prev_view = rd_cfg_list_last(&panel->tabs)->id); + } + } + } for(U64 idx = 0; idx < ArrayCount(sites); idx += 1) + { + B32 is_drop_hot = ui_key_match(ui_drop_hot_key(), sites[idx].key); + if(is_drop_hot) + { + Axis2 split_axis = axis2_from_dir2(sites[idx].split_dir); + Side split_side = side_from_dir2(sites[idx].split_dir); + Rng2F32 future_split_rect_target = panel_rect; + if(sites[idx].split_dir != Dir2_Invalid) + { + Vec2F32 panel_center = center_2f32(panel_rect); + future_split_rect_target.v[side_flip(split_side)].v[split_axis] = panel_center.v[split_axis]; + } + future_split_rect_target = pad_2f32(future_split_rect_target, -ui_top_font_size()*2.f); + Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target); + Rng2F32 future_split_rect = + { + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), + }; + UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f) + { + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); + } + } + } + } + } + + ////////////////////////// + //- rjf: build catch-all panel drop-site + // + UI_Key catchall_drop_site_key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel->cfg); + if(build_panel) UI_Rect(panel_rect) + { + UI_Box *catchall_drop_site = ui_build_box_from_key(UI_BoxFlag_DropSite, catchall_drop_site_key); + ui_signal_from_box(catchall_drop_site); + } + + ////////////////////////// + //- rjf: panel not selected? -> darken + // + if(build_panel) if(panel != panel_tree.focused) + { + UI_Rect(content_rect) UI_TagF("inactive") + ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); + } + + ////////////////////////// + //- rjf: build panel container box + // + UI_Box *panel_box = &ui_nil_box; + if(build_panel) UI_Rect(content_rect) UI_ChildLayoutAxis(Axis2_Y) UI_CornerRadius(0) UI_Focus(UI_FocusKind_On) + { + UI_Key panel_key = ui_key_from_stringf(ui_key_zero(), "panel_box_%p", panel->cfg); + panel_box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| + UI_BoxFlag_Clip| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DisableFocusOverlay| + ((panel_tree.focused != panel)*UI_BoxFlag_DisableFocusBorder), + panel_key); + } + + ////////////////////////// + //- rjf: loading animation for stable view + // + UI_Box *loading_overlay_container = &ui_nil_box; + if(build_panel) UI_Parent(panel_box) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); + } + + ////////////////////////// + //- rjf: build selected tab view + // + if(build_panel) + UI_Parent(panel_box) + UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) + UI_WidthFill + { + //- rjf: push interaction registers, fill with per-view states + rd_push_regs(.panel = panel->cfg->id, + .view = selected_tab->id); { - UI_Key key = sites[idx].key; - Dir2 dir = sites[idx].split_dir; - Rng2F32 rect = sites[idx].rect; - Axis2 split_axis = axis2_from_dir2(dir); - Side split_side = side_from_dir2(dir); - if(dir != Dir2_Invalid && split_axis == panel->parent->split_axis) + String8 view_expr = rd_expr_from_cfg(selected_tab); + String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); + // NOTE(rjf): we want to only fill out this view's file path slot if it + // evaluates one - this way, a view can use the slot to know the selected + // file path (if there is one). this is useful when pushing commandas which + // apply to a cursor, for example. + if(view_file_path.size != 0) + { + rd_regs()->file_path = view_file_path; + } + } + + //- rjf: build view container + UI_Box *view_container_box = &ui_nil_box; + UI_FixedWidth(dim_2f32(content_rect).x) + UI_FixedHeight(dim_2f32(content_rect).y) + UI_ChildLayoutAxis(Axis2_Y) + { + view_container_box = ui_build_box_from_key(0, ui_key_zero()); + } + + //- rjf: build empty view + UI_Parent(view_container_box) if(selected_tab == &rd_nil_cfg && panel->parent != &rd_nil_panel_node) + { + ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); + UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) UI_TagF("weak") + UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) + { + UI_PrefHeight(ui_em(3.f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_em(15.f, 1.f)) + UI_CornerRadius(ui_top_font_size()/2.f) + UI_TagF("bad_pop") + { + if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Panel"))) + { + rd_cmd(RD_CmdKind_ClosePanel); + } + } + } + } + + //- rjf: build tab view + UI_Parent(view_container_box) if(selected_tab != &rd_nil_cfg) ProfScope("build tab view") + { + rd_view_ui(content_rect); + } + + //- rjf: pop interaction registers; commit if this is the selected view + RD_Regs *view_regs = rd_pop_regs(); + if(panel_is_focused) + { + MemoryCopyStruct(rd_regs(), view_regs); + } + } + + //////////////////////// + //- rjf: loading? -> fill loading overlay container + // + if(build_panel) + { + F32 selected_tab_loading_t = selected_tab_view_state->loading_t; + if(selected_tab_loading_t > 0.01f) UI_Parent(loading_overlay_container) + { + rd_loading_overlay(panel_rect, selected_tab_loading_t, selected_tab_view_state->loading_progress_v, selected_tab_view_state->loading_progress_v_target); + } + } + + ////////////////////////// + //- rjf: consume panel fallthrough interaction events + // + if(build_panel) + { + UI_Signal panel_sig = ui_signal_from_box(panel_box); + if(ui_pressed(panel_sig)) + { + rd_cmd(RD_CmdKind_FocusPanel, .panel = panel->cfg->id); + } + } + + ////////////////////////// + //- rjf: compute tab build tasks + // + typedef struct TabTask TabTask; + struct TabTask + { + TabTask *next; + RD_Cfg *tab; + DR_FStrList fstrs; + F32 tab_width; + }; + TabTask *first_tab_task = 0; + TabTask *last_tab_task = 0; + U64 tab_task_count = 0; + F32 tab_close_width_px = ui_top_font_size()*2.5f; + F32 max_tab_width_px = ui_top_font_size()*20.f; + if(build_panel) + { + B32 reset = (ws->window_layout_reset || ws->frames_alive < 5 || is_changing_panel_boundaries); + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) + { + RD_Cfg *tab = n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } - UI_Box *site_box = &ui_nil_box; - { - UI_Rect(rect) - { - site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key); - ui_signal_from_box(site_box); - } - UI_Box *site_box_viz = &ui_nil_box; - UI_Parent(site_box) UI_WidthFill UI_HeightFill - UI_Padding(ui_px(padding, 1.f)) - UI_Column - UI_Padding(ui_px(padding, 1.f)) - { - ui_set_next_child_layout_axis(axis2_flip(split_axis)); - if(ui_key_match(key, ui_drop_hot_key())) - { - ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = rd_rgba_from_theme_color(RD_ThemeColor_Hover))); - } - site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackgroundBlur, ui_key_zero()); - } - if(dir != Dir2_Invalid) - { - UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) - { - ui_set_next_child_layout_axis(split_axis); - UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) - { - if(split_side == Side_Min) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } - RD_Palette(RD_PaletteCode_DropSiteOverlay) ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); - ui_spacer(ui_px(padding, 1.f)); - if(split_side == Side_Max) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } - RD_Palette(RD_PaletteCode_DropSiteOverlay) ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); - } - } - } - else - { - UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) - { - ui_set_next_child_layout_axis(split_axis); - UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); - UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) RD_Palette(RD_PaletteCode_DropSiteOverlay) - { - ui_build_box_from_key(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - } - } - if(ui_key_match(site_box->key, ui_drop_hot_key()) && rd_drag_drop()) - { - if(dir != Dir2_Invalid) - { - rd_cmd(RD_CmdKind_SplitPanel, - .dst_panel = rd_handle_from_panel(panel), - .panel = rd_state->drag_drop_regs->panel, - .view = rd_state->drag_drop_regs->view, - .dir2 = dir); - } - else - { - rd_cmd(RD_CmdKind_MoveTab, - .dst_panel = rd_handle_from_panel(panel), - .panel = rd_state->drag_drop_regs->panel, - .view = rd_state->drag_drop_regs->view, - .prev_view = rd_handle_from_view(panel->last_tab_view)); - } - } - } - for(U64 idx = 0; idx < ArrayCount(sites); idx += 1) - { - B32 is_drop_hot = ui_key_match(ui_drop_hot_key(), sites[idx].key); - if(is_drop_hot) - { - Axis2 split_axis = axis2_from_dir2(sites[idx].split_dir); - Side split_side = side_from_dir2(sites[idx].split_dir); - Rng2F32 future_split_rect = panel_rect; - if(sites[idx].split_dir != Dir2_Invalid) - { - Vec2F32 panel_center = center_2f32(panel_rect); - future_split_rect.v[side_flip(split_side)].v[split_axis] = panel_center.v[split_axis]; - } - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) - { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - } - } - } - - ////////////////////////// - //- rjf: build catch-all panel drop-site - // - B32 catchall_drop_site_hovered = 0; - if(rd_drag_is_active() && ui_key_match(ui_key_zero(), ui_drop_hot_key())) - { - UI_Rect(panel_rect) - { - UI_Key key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel); - UI_Box *catchall_drop_site = ui_build_box_from_key(UI_BoxFlag_DropSite, key); - ui_signal_from_box(catchall_drop_site); - catchall_drop_site_hovered = ui_key_match(key, ui_drop_hot_key()); - } - } - - ////////////////////////// - //- rjf: build filtering box - // - { - RD_View *view = rd_selected_tab_from_panel(panel); - UI_Focus(UI_FocusKind_On) - { - if(view->is_filtering && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) - { - rd_cmd(RD_CmdKind_ApplyFilter, .view = rd_handle_from_view(view)); - } - if(view->is_filtering || view->is_filtering_t > 0.01f) - { - UI_Box *filter_box = &ui_nil_box; - UI_Rect(filter_rect) - { - ui_set_next_child_layout_axis(Axis2_X); - filter_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip|UI_BoxFlag_DrawBorder, "filter_box_%p", view); - } - UI_Parent(filter_box) UI_WidthFill UI_HeightFill - { - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - RD_Font(RD_FontSlot_Icons) - UI_TextAlignment(UI_TextAlign_Center) - ui_label(rd_icon_kind_text_table[RD_IconKind_Find]); - UI_PrefWidth(ui_text_dim(10, 1)) - { - ui_label(str8_lit("Filter")); - } - ui_spacer(ui_em(0.5f, 1.f)); - RD_Font(view->spec->flags & RD_ViewRuleInfoFlag_FilterIsCode ? RD_FontSlot_Code : RD_FontSlot_Main) - UI_Focus(view->is_filtering ? UI_FocusKind_On : UI_FocusKind_Off) - UI_TextPadding(ui_top_font_size()*0.5f) - { - UI_Signal sig = rd_line_edit(RD_LineEditFlag_CodeContents*!!(view->spec->flags & RD_ViewRuleInfoFlag_FilterIsCode), - 0, - 0, - &view->query_cursor, - &view->query_mark, - view->query_buffer, - sizeof(view->query_buffer), - &view->query_string_size, - 0, - str8(view->query_buffer, view->query_string_size), - str8_lit("###filter_text_input")); - if(ui_pressed(sig)) - { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(panel)); - } - } - } - } - } - } - - ////////////////////////// - //- rjf: panel not selected? -> darken - // - if(panel != ws->focused_panel) - { - UI_Palette(ui_build_palette(0, .background = rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay))) - UI_Rect(content_rect) - { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - - ////////////////////////// - //- rjf: build panel container box - // - UI_Box *panel_box = &ui_nil_box; - UI_Rect(content_rect) UI_ChildLayoutAxis(Axis2_Y) UI_CornerRadius(0) UI_Focus(UI_FocusKind_On) - { - UI_Key panel_key = rd_ui_key_from_panel(panel); - panel_box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| - UI_BoxFlag_Clip| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DisableFocusOverlay| - ((ws->focused_panel != panel)*UI_BoxFlag_DisableFocusBorder), - panel_key); - } - - ////////////////////////// - //- rjf: loading animation for stable view - // - UI_Box *loading_overlay_container = &ui_nil_box; - UI_Parent(panel_box) UI_WidthFill UI_HeightFill - { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); - } - - ////////////////////////// - //- rjf: build selected tab view - // - UI_Parent(panel_box) - UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) - UI_WidthFill - { - //- rjf: push interaction registers, fill with per-view states - rd_push_regs(); - { - RD_View *view = rd_selected_tab_from_panel(panel); - String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), str8(view->query_buffer, view->query_string_size)); - rd_regs()->panel = rd_handle_from_panel(panel); - rd_regs()->view = rd_handle_from_view(view); - if(view_file_path.size != 0) - { - rd_regs()->file_path = view_file_path; + TabTask *t = push_array(scratch.arena, TabTask, 1); + t->tab = tab; + t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab); + F32 tab_width_target = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; + tab_width_target = Min(max_tab_width_px, tab_width_target); + t->tab_width = floor_f32(ui_anim(ui_key_from_stringf(ui_key_zero(), "tab_width_%p", tab), tab_width_target, .initial = reset ? tab_width_target : 0)); + SLLQueuePush(first_tab_task, last_tab_task, t); + tab_task_count += 1; } } - //- rjf: build view container - UI_Box *view_container_box = &ui_nil_box; - UI_FixedWidth(dim_2f32(content_rect).x) - UI_FixedHeight(dim_2f32(content_rect).y) - UI_ChildLayoutAxis(Axis2_Y) - { - view_container_box = ui_build_box_from_key(0, ui_key_zero()); - } - - //- rjf: build empty view - UI_Parent(view_container_box) if(rd_view_is_nil(rd_selected_tab_from_panel(panel))) - { - RD_VIEW_RULE_UI_FUNCTION_NAME(empty)(str8_zero(), &md_nil_node, content_rect); - } - - //- rjf: build tab view - UI_Parent(view_container_box) if(!rd_view_is_nil(rd_selected_tab_from_panel(panel))) - { - RD_View *view = rd_selected_tab_from_panel(panel); - RD_ViewRuleUIFunctionType *view_ui = view->spec->ui; - view_ui(str8(view->query_buffer, view->query_string_size), view->params_roots[view->params_read_gen%ArrayCount(view->params_roots)], content_rect); - } - - //- rjf: pop interaction registers; commit if this is the selected view - RD_Regs *view_regs = rd_pop_regs(); - if(ws->focused_panel == panel) - { - MemoryCopyStruct(rd_regs(), view_regs); - } - } - - //////////////////////// - //- rjf: loading? -> fill loading overlay container - // - { - RD_View *view = rd_selected_tab_from_panel(panel); - if(view->loading_t > 0.01f) UI_Parent(loading_overlay_container) - { - rd_loading_overlay(panel_rect, view->loading_t, view->loading_progress_v, view->loading_progress_v_target); - } - } - - ////////////////////////// - //- rjf: take events to automatically start/end filtering, if applicable - // - UI_Focus(UI_FocusKind_On) - { - RD_View *view = rd_selected_tab_from_panel(panel); - if(ui_is_focus_active() && view->spec->flags & RD_ViewRuleInfoFlag_TypingAutomaticallyFilters && !view->is_filtering) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->flags & UI_EventFlag_Paste) - { - ui_eat_event(evt); - rd_cmd(RD_CmdKind_Filter); - rd_cmd(RD_CmdKind_Paste); - } - else if(evt->string.size != 0 && evt->kind == UI_EventKind_Text) - { - ui_eat_event(evt); - rd_cmd(RD_CmdKind_Filter); - rd_cmd(RD_CmdKind_InsertText, .string = evt->string); - } - } - } - if(view->spec->flags & RD_ViewRuleInfoFlag_CanFilter && (view->query_string_size != 0 || view->is_filtering) && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) - { - rd_cmd(RD_CmdKind_ClearFilter, .view = rd_handle_from_view(view)); - } - } - - ////////////////////////// - //- rjf: consume panel fallthrough interaction events - // - UI_Signal panel_sig = ui_signal_from_box(panel_box); - if(ui_pressed(panel_sig)) - { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(panel)); - } - - ////////////////////////// - //- rjf: build tab bar - // - UI_Focus(UI_FocusKind_Off) - { - Temp scratch = scratch_begin(0, 0); - - // rjf: types - typedef struct DropSite DropSite; - struct DropSite - { - F32 p; - RD_View *prev_view; - }; - - // rjf: prep output data - RD_View *next_selected_tab_view = rd_selected_tab_from_panel(panel); + ////////////////////////// + //- rjf: build tab bar container + // UI_Box *tab_bar_box = &ui_nil_box; - U64 drop_site_count = panel->tab_view_count+1; - DropSite *drop_sites = push_array(scratch.arena, DropSite, drop_site_count); - F32 drop_site_max_p = 0; - U64 view_idx = 0; - - // rjf: build - UI_CornerRadius(0) + if(build_panel) UI_CornerRadius(0) UI_Rect(tab_bar_rect) { - UI_Rect(tab_bar_rect) tab_bar_box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_AllowOverflowY|UI_BoxFlag_ViewClampX|UI_BoxFlag_ViewScrollX|UI_BoxFlag_Clickable, "tab_bar_%p", panel); + tab_bar_box = ui_build_box_from_stringf(UI_BoxFlag_Clip| + UI_BoxFlag_AllowOverflowY| + UI_BoxFlag_ViewClampX| + UI_BoxFlag_ViewScrollX| + UI_BoxFlag_Clickable, + "tab_bar_%p", panel->cfg); if(panel->tab_side == Side_Max) { tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = (tab_bar_rheight - tab_bar_vheight); @@ -7580,64 +9546,226 @@ rd_window_frame(RD_Window *ws) tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = 0; } } - UI_Parent(tab_bar_box) UI_PrefHeight(ui_pct(1, 0)) + + ////////////////////////// + //- rjf: determine tab drop site + // + B32 tab_drop_is_active = rd_drag_is_active() && ui_key_match(ui_drop_hot_key(), catchall_drop_site_key); + RD_Cfg *tab_drop_prev = &rd_nil_cfg; + if(build_panel) { - Temp scratch = scratch_begin(0, 0); - F32 corner_radius = ui_em(0.6f, 1.f).value; - ui_spacer(ui_px(1.f, 1.f)); - - // rjf: build tabs - UI_PrefWidth(ui_em(18.f, 0.5f)) - UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) + F32 best_prev_distance_px = 1000000.f; + TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; + F32 off = 0; + for(TabTask *task = &start_boundary_tab_task; task != 0; task = task->next) + { + off += task->tab_width; + Vec2F32 anchor_pt = v2f32(tab_bar_box->rect.x0 + off, tab_bar_box->rect.y1); + F32 distance = length_2f32(sub_2f32(ui_mouse(), anchor_pt)); + if(distance < best_prev_distance_px) + { + best_prev_distance_px = distance; + tab_drop_prev = task->tab; + } + } + } + + ////////////////////////// + //- rjf: turn off drop visualization if this drag would be a no-op + // + if(tab_drop_is_active && rd_state->drag_drop_regs->panel == panel->cfg->id) + { + TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; + if(tab_drop_prev->id == rd_state->drag_drop_regs->view) + { + tab_drop_is_active = 0; + } + if(tab_drop_is_active) for(TabTask *t = &start_boundary_tab_task; t != 0; t = t->next) + { + if(t->tab == tab_drop_prev && t->next != 0 && t->next->tab->id == rd_state->drag_drop_regs->view) + { + tab_drop_is_active = 0; + break; + } + } + } + + ////////////////////////// + //- rjf: build tab bar contents + // + if(build_panel) UI_Focus(UI_FocusKind_Off) UI_Parent(tab_bar_box) UI_Padding(ui_em(0.5f, 1.f)) UI_PrefHeight(ui_pct(1, 0)) UI_TagF("tab") + { + F32 corner_radius = ui_top_font_size()*0.6f; + TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; + UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) UI_CornerRadius01(panel->tab_side == Side_Min ? 0 : corner_radius) UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) UI_CornerRadius11(panel->tab_side == Side_Min ? 0 : corner_radius) - for(RD_View *view = panel->first_tab_view;; view = view->order_next, view_idx += 1) + for(TabTask *tab_task = &start_boundary_tab_task; tab_task != 0; tab_task = tab_task->next) { - temp_end(scratch); - if(rd_view_is_project_filtered(view)) { continue; } + RD_Cfg *tab = tab_task->tab; - // rjf: if before this tab is the prev-view of the current tab drag, - // draw empty space - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && catchall_drop_site_hovered) + //- rjf: build tab + DR_FStrList tab_fstrs = tab_task->fstrs; + F32 tab_width_px = tab_task->tab_width; + if(tab != &rd_nil_cfg) RD_RegsScope(.panel = panel->cfg->id, .view = tab->id) { - RD_Panel *dst_panel = rd_panel_from_handle(rd_last_drag_drop_panel); - RD_View *drag_view = rd_view_from_handle(rd_state->drag_drop_regs->view); - RD_View *dst_prev_view = rd_view_from_handle(rd_last_drag_drop_prev_tab); - if(dst_panel == panel && - ((!rd_view_is_nil(view) && dst_prev_view == view->order_prev && drag_view != view && drag_view != view->order_prev) || - (rd_view_is_nil(view) && dst_prev_view == panel->last_tab_view && drag_view != panel->last_tab_view))) + // rjf: gather info for this tab + B32 tab_is_selected = (tab == panel->selected_tab); + B32 tab_is_auto = (rd_cfg_child_from_string(tab, str8_lit("auto")) != &rd_nil_cfg); + + // rjf: begin vertical region for this tab + ui_set_next_child_layout_axis(Axis2_Y); + ui_set_next_pref_width(ui_px(tab_width_px, 1)); + UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab); + + // rjf: choose palette + B32 omit_name = 0; + if(rd_drag_is_active() && rd_state->drag_drop_regs->view == tab->id && rd_state->drag_drop_regs_slot == RD_RegSlot_View) { - UI_PrefWidth(ui_em(9.f, 0.2f)) UI_Column + omit_name = 1; + } + + // rjf: build tab container box + UI_Parent(tab_column_box) + UI_PrefHeight(ui_px(tab_bar_vheight, 1)) + UI_TagF(omit_name ? "hollow" : "") + UI_TagF(!omit_name && !tab_is_selected ? "inactive" : "") + UI_TagF(!omit_name && tab_is_auto ? "auto" : "") + { + if(panel->tab_side == Side_Max) { - ui_spacer(ui_em(0.2f, 1.f)); - UI_CornerRadius00(corner_radius) - UI_CornerRadius10(corner_radius) - RD_Palette(RD_PaletteCode_DropSiteOverlay) + ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); + } + else + { + ui_spacer(ui_px(1.f, 1.f)); + } + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + UI_Box *tab_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBorder| + (UI_BoxFlag_DrawDropShadow*tab_is_selected)| + UI_BoxFlag_Clickable, + "tab_%p", tab); + + // rjf: build tab contents + if(!omit_name) UI_Parent(tab_box) + { + UI_WidthFill UI_Row { - ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); + ui_spacer(ui_em(0.5f, 1.f)); + UI_PrefWidth(ui_text_dim(10, 0)) + { + UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(name_box, &tab_fstrs); + } + } + UI_PrefWidth(ui_px(tab_close_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f) + UI_TagF(".") UI_TagF("weak") UI_TagF("implicit") + UI_CornerRadius00(0) + UI_CornerRadius01(0) + { + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + UI_Box *close_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawActiveEffects, + "%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], tab); + UI_Signal sig = ui_signal_from_box(close_box); + if(ui_clicked(sig) || ui_middle_clicked(sig)) + { + rd_cmd(RD_CmdKind_CloseTab); + } + } + } + + // rjf: consume events for tab clicking + { + UI_Signal sig = ui_signal_from_box(tab_box); + if(ui_pressed(sig)) + { + rd_cmd(RD_CmdKind_FocusTab); + rd_cmd(RD_CmdKind_FocusPanel); + } + else if(ui_dragging(sig) && !rd_drag_is_active() && length_2f32(ui_drag_delta()) > 10.f) + { + rd_drag_begin(RD_RegSlot_View); + } + else if(ui_right_clicked(sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .do_implicit_root = 1, + .ui_key = sig.box->key, + .off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), + .expr = push_str8f(scratch.arena, "$%I64x", tab->id)); + } + else if(ui_middle_clicked(sig)) + { + rd_cmd(RD_CmdKind_CloseTab); } } } + + // rjf: space for next tab + { + ui_spacer(ui_px(floor_f32(ui_top_font_size()*0.4f), 1.f)); + } } - // rjf: end on nil view - if(rd_view_is_nil(view)) + //- rjf: if this is the currently active drop site's previous tab, then build empty space + // to visualize where tab will be moved once dropped + if(tab_drop_is_active && + rd_drag_is_active() && + rd_state->drag_drop_regs_slot == RD_RegSlot_View && + tab == tab_drop_prev) { - break; + // rjf: begin vertical region for this spot + ui_set_next_child_layout_axis(Axis2_Y); + ui_set_next_pref_width(ui_px(ui_top_font_size()*4.f, 1)); + UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab); + + // rjf: build spot container box + UI_Parent(tab_column_box) + UI_PrefHeight(ui_px(tab_bar_vheight, 1)) + UI_TagF("hollow") + { + if(panel->tab_side == Side_Max) + { + ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); + } + else + { + ui_spacer(ui_px(1.f, 1.f)); + } + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + ui_set_next_group_key(catchall_drop_site_key); + UI_Box *tab_box = ui_build_box_from_key(UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_Clickable, + ui_key_zero()); + } + + // rjf: space for next tab + { + ui_spacer(ui_px(floor_f32(ui_top_font_size()*0.4f), 1.f)); + } } - - // rjf: gather info for this tab - B32 view_is_selected = (view == rd_selected_tab_from_panel(panel)); - RD_IconKind icon_kind = rd_icon_kind_from_view(view); - DR_FancyStringList title_fstrs = rd_title_fstrs_from_view(scratch.arena, view, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); - - // rjf: begin vertical region for this tab + } + + // rjf: build add-new-tab button + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) + UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) + { ui_set_next_child_layout_axis(Axis2_Y); - UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", view); - - // rjf: build tab container box - UI_Parent(tab_column_box) UI_PrefHeight(ui_px(tab_bar_vheight, 1)) RD_Palette(view_is_selected ? RD_PaletteCode_Tab : RD_PaletteCode_TabInactive) + UI_Box *container = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "###add_new_tab"); + UI_Parent(container) { if(panel->tab_side == Side_Max) { @@ -7647,381 +9775,100 @@ rd_window_frame(RD_Window *ws) { ui_spacer(ui_px(1.f, 1.f)); } - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *tab_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBorder| - (UI_BoxFlag_DrawDropShadow*view_is_selected)| - UI_BoxFlag_Clickable, - "tab_%p", view); - - // rjf: build tab contents - UI_Parent(tab_box) + UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) + UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(ui_top_font_size()) + UI_TagF("implicit") + UI_TagF("weak") + UI_HoverCursor(OS_Cursor_HandPoint) { - UI_WidthFill UI_Row - { - ui_spacer(ui_em(0.5f, 1.f)); - if(icon_kind != RD_IconKind_Null) - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - RD_Font(RD_FontSlot_Icons) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(1.75f, 1.f)) - ui_label(rd_icon_kind_text_table[icon_kind]); - } - UI_PrefWidth(ui_text_dim(10, 0)) - { - UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(name_box, &title_fstrs); - } - } - UI_PrefWidth(ui_em(2.35f, 1.f)) UI_TextAlignment(UI_TextAlign_Center) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f) - UI_Flags(UI_BoxFlag_DrawTextWeak) - UI_CornerRadius00(0) - UI_CornerRadius01(0) - { - UI_Palette *palette = ui_build_palette(ui_top_palette()); - palette->background = v4f32(0, 0, 0, 0); - ui_set_next_palette(palette); - UI_Signal sig = ui_buttonf("%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], view); - if(ui_clicked(sig) || ui_middle_clicked(sig)) - { - rd_cmd(RD_CmdKind_CloseTab, .panel = rd_handle_from_panel(panel), .view = rd_handle_from_view(view)); - } - } - } - - // rjf: consume events for tab clicking - { - UI_Signal sig = ui_signal_from_box(tab_box); + UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_Clickable| + UI_BoxFlag_DisableTextTrunc, + "%S##add_new_tab_button_%p", + rd_icon_kind_text_table[RD_IconKind_Add], + panel->cfg); + UI_Signal sig = ui_signal_from_box(add_new_box); if(ui_pressed(sig)) { - next_selected_tab_view = view; - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(panel)); - } - else if(ui_dragging(sig) && !rd_drag_is_active() && length_2f32(ui_drag_delta()) > 10.f) - { - RD_RegsScope(.panel = rd_handle_from_panel(panel), - .view = rd_handle_from_view(view)) + rd_cmd(RD_CmdKind_FocusPanel); + UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); + if(ui_ctx_menu_is_open(view_menu_key)) { - rd_drag_begin(RD_RegSlot_View); + ui_ctx_menu_close(); + } + else + { + ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); } } - else if(ui_right_clicked(sig)) - { - RD_RegsScope(.panel = rd_handle_from_panel(panel), - .view = rd_handle_from_view(view)) - { - rd_open_ctx_menu(sig.box->key, v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), RD_RegSlot_View); - } - } - else if(ui_middle_clicked(sig)) - { - rd_cmd(RD_CmdKind_CloseTab, .panel = rd_handle_from_panel(panel), .view = rd_handle_from_view(view)); - } - } - } - - // rjf: space for next tab - { - ui_spacer(ui_em(0.3f, 1.f)); - } - - // rjf: store off drop-site - drop_sites[view_idx].p = tab_column_box->rect.x0 - tab_spacing/2; - drop_sites[view_idx].prev_view = view->order_prev; - drop_site_max_p = Max(tab_column_box->rect.x1, drop_site_max_p); - } - - // rjf: build add-new-tab button - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) - UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) - UI_Column - { - if(panel->tab_side == Side_Max) - { - ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); - } - else - { - ui_spacer(ui_px(1.f, 1.f)); - } - UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) - UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(ui_top_font_size()) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - UI_HoverCursor(OS_Cursor_HandPoint) - RD_Palette(RD_PaletteCode_ImplicitButton) - { - UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawText| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects| - UI_BoxFlag_Clickable| - UI_BoxFlag_DisableTextTrunc, - "%S##add_new_tab_button_%p", - rd_icon_kind_text_table[RD_IconKind_Add], - panel); - UI_Signal sig = ui_signal_from_box(add_new_box); - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(panel)); - UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); } } } - scratch_end(scratch); + // rjf: interact with tab bar + ui_signal_from_box(tab_bar_box); } - // rjf: interact with tab bar - ui_signal_from_box(tab_bar_box); - - // rjf: fill out last drop site + ////////////////////////// + //- rjf: accept tab drops + // + if(tab_drop_is_active && rd_drag_drop() && rd_state->drag_drop_regs_slot == RD_RegSlot_View) { - drop_sites[drop_site_count-1].p = drop_site_max_p; - drop_sites[drop_site_count-1].prev_view = panel->last_tab_view; + rd_cmd(RD_CmdKind_MoveTab, + .dst_panel = panel->cfg->id, + .panel = rd_state->drag_drop_regs->panel, + .view = rd_state->drag_drop_regs->view, + .prev_view = tab_drop_prev->id); } - // rjf: more precise drop-sites on tab bar + ////////////////////////// + //- rjf: accept file drops + // { - Vec2F32 mouse = ui_mouse(); - RD_View *view = rd_view_from_handle(rd_state->drag_drop_regs->view); - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && window_is_focused && contains_2f32(panel_rect, mouse) && !rd_view_is_nil(view)) + for(UI_Event *evt = 0; ui_next_event(&evt);) { - // rjf: mouse => hovered drop site - F32 min_distance = 0; - DropSite *active_drop_site = 0; - if(catchall_drop_site_hovered) + if(evt->kind == UI_EventKind_FileDrop && contains_2f32(content_rect, evt->pos)) { - for(U64 drop_site_idx = 0; drop_site_idx < drop_site_count; drop_site_idx += 1) + B32 need_drop_completion = 0; + arena_clear(ws->drop_completion_arena); + MemoryZeroStruct(&ws->drop_completion_paths); + for(String8Node *n = evt->paths.first; n != 0; n = n->next) { - F32 distance = abs_f32(drop_sites[drop_site_idx].p - mouse.x); - if(drop_site_idx == 0 || distance < min_distance) + Temp scratch = scratch_begin(0, 0); + String8 path = path_normalized_from_string(scratch.arena, n->string); + if(str8_match(str8_skip_last_dot(path), str8_lit("exe"), StringMatchFlag_CaseInsensitive)) { - active_drop_site = &drop_sites[drop_site_idx]; - min_distance = distance; + str8_list_push(ws->drop_completion_arena, &ws->drop_completion_paths, push_str8_copy(ws->drop_completion_arena, path)); + need_drop_completion = 1; } + else + { + rd_cmd(RD_CmdKind_Open, .file_path = path); + } + scratch_end(scratch); } - } - - // rjf: store closest prev-view - if(active_drop_site != 0) - { - rd_last_drag_drop_prev_tab = rd_handle_from_view(active_drop_site->prev_view); - } - else - { - rd_last_drag_drop_prev_tab = rd_handle_zero(); - } - - // rjf: vis - RD_Panel *drag_panel = rd_panel_from_handle(rd_state->drag_drop_regs->panel); - if(!rd_view_is_nil(view) && active_drop_site != 0) - { - RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_Rect(tab_bar_rect) - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - - // rjf: drop - if(catchall_drop_site_hovered && (active_drop_site != 0 && rd_drag_drop())) - { - RD_View *view = rd_view_from_handle(rd_state->drag_drop_regs->view); - RD_Panel *src_panel = rd_panel_from_handle(rd_state->drag_drop_regs->panel); - if(!rd_panel_is_nil(panel) && !rd_view_is_nil(view)) + if(need_drop_completion) { - rd_cmd(RD_CmdKind_MoveTab, - .panel = rd_handle_from_panel(src_panel), - .dst_panel = rd_handle_from_panel(panel), - .view = rd_handle_from_view(view), - .prev_view = rd_handle_from_view(active_drop_site->prev_view)); + ui_ctx_menu_open(rd_state->drop_completion_key, ui_key_zero(), evt->pos); } + ui_eat_event(evt); } } } - - // rjf: apply tab change - { - panel->selected_tab_view = rd_handle_from_view(next_selected_tab_view); - } - - scratch_end(scratch); - } - - ////////////////////////// - //- rjf: less granular panel-wide drop-site - // - if(catchall_drop_site_hovered) - { - rd_last_drag_drop_panel = rd_handle_from_panel(panel); - - RD_View *dragged_view = rd_view_from_handle(rd_state->drag_drop_regs->view); - B32 view_is_in_panel = 0; - for(RD_View *view = panel->first_tab_view; !rd_view_is_nil(view); view = view->order_next) - { - if(rd_view_is_project_filtered(view)) { continue; } - if(view == dragged_view) - { - view_is_in_panel = 1; - break; - } - } - - if(view_is_in_panel == 0) - { - // rjf: vis - { - RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_Rect(content_rect) - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - - // rjf: drop - { - if(rd_drag_drop()) - { - RD_Panel *src_panel = rd_panel_from_handle(rd_state->drag_drop_regs->panel); - RD_View *view = rd_view_from_handle(rd_state->drag_drop_regs->view); - if(rd_state->drag_drop_regs_slot == RD_RegSlot_View && !rd_view_is_nil(view)) - { - rd_cmd(RD_CmdKind_MoveTab, - .prev_view = rd_handle_from_view(panel->last_tab_view), - .panel = rd_handle_from_panel(src_panel), - .dst_panel = rd_handle_from_panel(panel), - .view = rd_handle_from_view(view)); - } - } - } - } - } - - ////////////////////////// - //- rjf: accept file drops - // - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_FileDrop && contains_2f32(content_rect, evt->pos)) - { - B32 need_drop_completion = 0; - arena_clear(ws->drop_completion_arena); - MemoryZeroStruct(&ws->drop_completion_paths); - for(String8Node *n = evt->paths.first; n != 0; n = n->next) - { - Temp scratch = scratch_begin(0, 0); - String8 path = path_normalized_from_string(scratch.arena, n->string); - if(str8_match(str8_skip_last_dot(path), str8_lit("exe"), StringMatchFlag_CaseInsensitive)) - { - str8_list_push(ws->drop_completion_arena, &ws->drop_completion_paths, push_str8_copy(ws->drop_completion_arena, path)); - need_drop_completion = 1; - } - else - { - rd_cmd(RD_CmdKind_Open, .file_path = path); - } - scratch_end(scratch); - } - if(need_drop_completion) - { - ui_ctx_menu_open(rd_state->drop_completion_key, ui_key_zero(), evt->pos); - } - ui_eat_event(evt); - } - } } } } //////////////////////////// - //- rjf: animate views - // - { - Temp scratch = scratch_begin(0, 0); - typedef struct Task Task; - struct Task - { - Task *next; - RD_Panel *panel; - RD_View *list_first; - RD_View *transient_owner; - }; - Task start_task = {0, &rd_nil_panel, ws->query_view_stack_top}; - Task *first_task = &start_task; - Task *last_task = first_task; - F32 rate = 1 - pow_f32(2, (-10.f * rd_state->frame_dt)); - F32 fast_rate = 1 - pow_f32(2, (-40.f * rd_state->frame_dt)); - for(RD_Panel *panel = ws->root_panel; - !rd_panel_is_nil(panel); - panel = rd_panel_rec_depth_first_pre(panel).next) - { - Task *t = push_array(scratch.arena, Task, 1); - SLLQueuePush(first_task, last_task, t); - t->panel = panel; - t->list_first = panel->first_tab_view; - } - for(Task *t = first_task; t != 0; t = t->next) - { - RD_View *list_first = t->list_first; - for(RD_View *view = list_first; !rd_view_is_nil(view); view = view->order_next) - { - if(!rd_view_is_nil(view->first_transient)) - { - Task *task = push_array(scratch.arena, Task, 1); - SLLQueuePush(first_task, last_task, task); - task->panel = t->panel; - task->list_first = view->first_transient; - task->transient_owner = view; - } - if(window_is_focused) - { - if(abs_f32(view->loading_t_target - view->loading_t) > 0.01f || - abs_f32(view->scroll_pos.x.off) > 0.01f || - abs_f32(view->scroll_pos.y.off) > 0.01f || - abs_f32(view->is_filtering_t - (F32)!!view->is_filtering)) - { - rd_request_frame(); - } - if(view->loading_t_target != 0 && (view == rd_selected_tab_from_panel(t->panel) || - t->transient_owner == rd_selected_tab_from_panel(t->panel))) - { - rd_request_frame(); - } - } - view->loading_t += (view->loading_t_target - view->loading_t) * rate; - view->is_filtering_t += ((F32)!!view->is_filtering - view->is_filtering_t) * fast_rate; - view->scroll_pos.x.off -= view->scroll_pos.x.off * (rd_setting_val_from_code(RD_SettingCode_ScrollingAnimations).s32 ? fast_rate : 1.f); - view->scroll_pos.y.off -= view->scroll_pos.y.off * (rd_setting_val_from_code(RD_SettingCode_ScrollingAnimations).s32 ? fast_rate : 1.f); - if(abs_f32(view->scroll_pos.x.off) < 0.01f) - { - view->scroll_pos.x.off = 0; - } - if(abs_f32(view->scroll_pos.y.off) < 0.01f) - { - view->scroll_pos.y.off = 0; - } - if(abs_f32(view->is_filtering_t - (F32)!!view->is_filtering) < 0.01f) - { - view->is_filtering_t = (F32)!!view->is_filtering; - } - if(view == rd_selected_tab_from_panel(t->panel) || - t->transient_owner == rd_selected_tab_from_panel(t->panel)) - { - view->loading_t_target = 0; - } - } - } - scratch_end(scratch); - } - - //////////////////////////// - //- rjf: drag/drop cancelling + //- rjf: @window_ui_part drag/drop cancelling // if(rd_drag_is_active() && ui_slot_press(UI_EventActionSlot_Cancel)) { @@ -8030,7 +9877,7 @@ rd_window_frame(RD_Window *ws) } //////////////////////////// - //- rjf: font size changing + //- rjf: @window_ui_part top-level font size changing // for(UI_Event *evt = 0; ui_next_event(&evt);) { @@ -8039,11 +9886,11 @@ rd_window_frame(RD_Window *ws) ui_eat_event(evt); if(evt->delta_2f32.y < 0) { - rd_cmd(RD_CmdKind_IncUIFontScale, .window = rd_handle_from_window(ws)); + rd_cmd(RD_CmdKind_IncUIFontScale); } else if(evt->delta_2f32.y > 0) { - rd_cmd(RD_CmdKind_DecUIFontScale, .window = rd_handle_from_window(ws)); + rd_cmd(RD_CmdKind_DecUIFontScale); } } } @@ -8052,77 +9899,18 @@ rd_window_frame(RD_Window *ws) } ////////////////////////////// - //- rjf: ensure hover eval is in-bounds - // - if(!ui_box_is_nil(hover_eval_box)) - { - UI_Box *root = hover_eval_box; - Rng2F32 window_rect = os_client_rect_from_window(ui_window()); - Rng2F32 root_rect = root->rect; - Vec2F32 shift = - { - -ClampBot(0, root_rect.x1 - window_rect.x1), - -ClampBot(0, root_rect.y1 - window_rect.y1), - }; - Rng2F32 new_root_rect = shift_2f32(root_rect, shift); - root->fixed_position = new_root_rect.p0; - root->fixed_size = dim_2f32(new_root_rect); - root->rect = new_root_rect; - for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis + 1)) - { - ui_calc_sizes_standalone__in_place_rec(root, axis); - ui_calc_sizes_upwards_dependent__in_place_rec(root, axis); - ui_calc_sizes_downwards_dependent__in_place_rec(root, axis); - ui_layout_enforce_constraints__in_place_rec(root, axis); - ui_layout_position__in_place_rec(root, axis); - } - } - - ////////////////////////////// - //- rjf: attach autocomp box to root, or hide if it has not been renewed - // - if(!ui_box_is_nil(autocomp_box) && ws->autocomp_last_frame_idx+1 >= rd_state->frame_index+1) - { - UI_Box *autocomp_root_box = ui_box_from_key(ws->autocomp_root_key); - if(!ui_box_is_nil(autocomp_root_box)) - { - Vec2F32 size = autocomp_box->fixed_size; - autocomp_box->fixed_position = v2f32(autocomp_root_box->rect.x0, autocomp_root_box->rect.y1); - autocomp_box->rect = r2f32(autocomp_box->fixed_position, add_2f32(autocomp_box->fixed_position, size)); - for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis + 1)) - { - ui_calc_sizes_standalone__in_place_rec(autocomp_box, axis); - ui_calc_sizes_upwards_dependent__in_place_rec(autocomp_box, axis); - ui_calc_sizes_downwards_dependent__in_place_rec(autocomp_box, axis); - ui_layout_enforce_constraints__in_place_rec(autocomp_box, axis); - ui_layout_position__in_place_rec(autocomp_box, axis); - } - } - } - else if(!ui_box_is_nil(autocomp_box) && ws->autocomp_last_frame_idx+1 < rd_state->frame_index+1) - { - UI_Box *autocomp_root_box = ui_box_from_key(ws->autocomp_root_key); - if(!ui_box_is_nil(autocomp_root_box)) - { - Vec2F32 size = autocomp_box->fixed_size; - Rng2F32 window_rect = os_client_rect_from_window(ws->os); - autocomp_box->fixed_position = v2f32(window_rect.x1, window_rect.y1); - autocomp_box->rect = r2f32(autocomp_box->fixed_position, add_2f32(autocomp_box->fixed_position, size)); - } - } - - ////////////////////////////// - //- rjf: hover eval cancelling + //- rjf: @window_frame_part hover eval cancelling // if(ws->hover_eval_string.size != 0 && ui_slot_press(UI_EventActionSlot_Cancel)) { MemoryZeroStruct(&ws->hover_eval_string); arena_clear(ws->hover_eval_arena); + ws->hover_eval_focused = 0; rd_request_frame(); } ////////////////////////////// - //- rjf: animate + //- rjf: @window_frame_part animate // if(ui_animating_from_state(ws->ui)) { @@ -8130,13 +9918,21 @@ rd_window_frame(RD_Window *ws) } ////////////////////////////// - //- rjf: draw UI + //- rjf: @window_frame_part draw UI // ws->draw_bucket = dr_bucket_make(); DR_BucketScope(ws->draw_bucket) ProfScope("draw UI") { Temp scratch = scratch_begin(0, 0); + F32 box_squish_epsilon = 0.001f; + Rng2F32 window_rect = os_client_rect_from_window(ws->os); + + //- rjf: unpack settings + B32 do_background_blur = rd_setting_b32_from_name(str8_lit("background_blur")); + Vec4F32 base_background_color = ui_color_from_name(str8_lit("background")); + Vec4F32 base_border_color = ui_color_from_name(str8_lit("border")); + Vec4F32 drop_shadow_color = ui_color_from_name(str8_lit("drop_shadow")); //- rjf: set up heatmap buckets F32 heatmap_bucket_size = 32.f; @@ -8155,14 +9951,12 @@ rd_window_frame(RD_Window *ws) //- rjf: draw background color { - Vec4F32 bg_color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackground); - dr_rect(os_client_rect_from_window(ws->os), bg_color, 0, 0, 0); + dr_rect(os_client_rect_from_window(ws->os), base_background_color, 0, 0, 0); } //- rjf: draw window border { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBorder); - dr_rect(os_client_rect_from_window(ws->os), color, 0, 1.f, 0.5f); + dr_rect(os_client_rect_from_window(ws->os), base_border_color, 0, 1.f, 0.5f); } //- rjf: recurse & draw @@ -8192,12 +9986,21 @@ rd_window_frame(RD_Window *ws) } // rjf: push squish - if(box->squish != 0) + if(box->squish > box_squish_epsilon) { Vec2F32 box_dim = dim_2f32(box->rect); - Mat3x3F32 box2origin_xform = make_translate_3x3f32(v2f32(-box->rect.x0 - box_dim.x/8, -box->rect.y0)); + Vec2F32 anchor_off = {0}; + if(box->flags & UI_BoxFlag_SquishAnchored) + { + anchor_off.x = box_dim.x/2.f; + } + else + { + anchor_off.y = -box_dim.y/8.f; + } + Mat3x3F32 box2origin_xform = make_translate_3x3f32(v2f32(-box->rect.x0 - box_dim.x/2 + anchor_off.x, -box->rect.y0 + anchor_off.y)); Mat3x3F32 scale_xform = make_scale_3x3f32(v2f32(1-box->squish, 1-box->squish)); - Mat3x3F32 origin2box_xform = make_translate_3x3f32(v2f32(box->rect.x0 + box_dim.x/8, box->rect.y0)); + Mat3x3F32 origin2box_xform = make_translate_3x3f32(v2f32(box->rect.x0 + box_dim.x/2 - anchor_off.x, box->rect.y0 - anchor_off.y)); Mat3x3F32 xform = mul_3x3f32(origin2box_xform, mul_3x3f32(scale_xform, box2origin_xform)); dr_push_xform2d(xform); dr_push_tex2d_sample_kind(R_Tex2DSampleKind_Linear); @@ -8207,73 +10010,77 @@ rd_window_frame(RD_Window *ws) if(box->flags & UI_BoxFlag_DrawDropShadow) { Rng2F32 drop_shadow_rect = shift_2f32(pad_2f32(box->rect, 8), v2f32(4, 4)); - Vec4F32 drop_shadow_color = rd_rgba_from_theme_color(RD_ThemeColor_DropShadow); - dr_rect(drop_shadow_rect, drop_shadow_color, 0.8f, 0, 8.f); + R_Rect2DInst *inst = dr_rect(drop_shadow_rect, drop_shadow_color, 0.8f, 0, 8.f); + MemoryCopyArray(inst->corner_radii, box->corner_radii); } // 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); } + // rjf: compute effective active t + F32 effective_active_t = box->active_t; + if(!(box->flags & UI_BoxFlag_DrawActiveEffects)) + { + effective_active_t = 0; + } + F32 t = box->hot_t*(1-effective_active_t); + + // rjf: compute background color + Vec4F32 box_background_color = box->background_color; + // rjf: draw background if(box->flags & UI_BoxFlag_DrawBackground) { - // rjf: main rectangle + // rjf: hot effect extension (drop shadow) + if(box->flags & UI_BoxFlag_DrawHotEffects) { - R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1), box->palette->colors[UI_ColorCode_Background], 0, 0, 1.f); - MemoryCopyArray(inst->corner_radii, box->corner_radii); + Rng2F32 drop_shadow_rect = shift_2f32(pad_2f32(box->rect, 8), v2f32(4, 4)); + Vec4F32 color = drop_shadow_color; + color.w *= t*box_background_color.w; + dr_rect(drop_shadow_rect, color, 0.8f, 0, 8.f); } + // rjf: draw background + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), box_background_color, 0, 0, 1.f); + MemoryCopyArray(inst->corner_radii, box->corner_radii); + // rjf: hot effect extension if(box->flags & UI_BoxFlag_DrawHotEffects) { - F32 effective_active_t = box->active_t; - if(!(box->flags & UI_BoxFlag_DrawActiveEffects)) - { - effective_active_t = 0; - } - F32 t = box->hot_t*(1-effective_active_t); + Vec4F32 hover_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("hover")); // rjf: brighten { - R_Rect2DInst *inst = dr_rect(box->rect, v4f32(0, 0, 0, 0), 0, 0, 1.f); - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); - color.w *= t*0.2f; + Vec4F32 color = hover_color; + color.w *= t*0.05f; + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), v4f32(0, 0, 0, 0), 0, 0, 1.f); inst->colors[Corner_00] = color; - inst->colors[Corner_01] = color; inst->colors[Corner_10] = color; - inst->colors[Corner_11] = color; - inst->colors[Corner_10].w *= t; - inst->colors[Corner_11].w *= t; MemoryCopyArray(inst->corner_radii, box->corner_radii); } - // rjf: slight emboss fadeoff - if(0) + // rjf: soft circle around mouse + if(box->hot_t > 0.01f) DR_ClipScope(box->rect) { - Rng2F32 rect = r2f32p(box->rect.x0, - box->rect.y0, - box->rect.x1, - box->rect.y1); - R_Rect2DInst *inst = dr_rect(rect, v4f32(0, 0, 0, 0), 0, 0, 1.f); - inst->colors[Corner_00] = v4f32(0.f, 0.f, 0.f, 0.0f*t); - inst->colors[Corner_01] = v4f32(0.f, 0.f, 0.f, 0.3f*t); - inst->colors[Corner_10] = v4f32(0.f, 0.f, 0.f, 0.0f*t); - inst->colors[Corner_11] = v4f32(0.f, 0.f, 0.f, 0.3f*t); - MemoryCopyArray(inst->corner_radii, box->corner_radii); + Vec4F32 color = hover_color; + color.w *= 0.02f*t; + Vec2F32 center = ui_mouse(); + Vec2F32 box_dim = dim_2f32(box->rect); + F32 max_dim = Max(box_dim.x, box_dim.y); + F32 radius = box->font_size*12.f; + radius = Min(max_dim, radius); + dr_rect(pad_2f32(r2f32(center, center), radius), color, radius, 0, radius/3.f); } } // rjf: active effect extension if(box->flags & UI_BoxFlag_DrawActiveEffects) { - Vec4F32 shadow_color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); - shadow_color.x *= 0.3f; - shadow_color.y *= 0.3f; - shadow_color.z *= 0.3f; + Vec4F32 shadow_color = drop_shadow_color; shadow_color.w *= 0.5f*box->active_t; Vec2F32 shadow_size = { @@ -8295,7 +10102,7 @@ rd_window_frame(RD_Window *ws) { R_Rect2DInst *inst = dr_rect(r2f32p(box->rect.x0, box->rect.y1 - shadow_size.y, box->rect.x1, box->rect.y1), v4f32(0, 0, 0, 0), 0, 0, 1.f); inst->colors[Corner_00] = inst->colors[Corner_10] = v4f32(0, 0, 0, 0); - inst->colors[Corner_01] = inst->colors[Corner_11] = v4f32(0.4f, 0.4f, 0.4f, 0.4f*box->active_t); + inst->colors[Corner_01] = inst->colors[Corner_11] = v4f32(1.0f, 1.0f, 1.0f, 0.08f*box->active_t); MemoryCopyArray(inst->corner_radii, box->corner_radii); } @@ -8332,15 +10139,24 @@ rd_window_frame(RD_Window *ws) FNT_Run ellipses_run = {0}; if(!(box->flags & UI_BoxFlag_DisableTextTrunc)) { + FNT_Tag ellipses_font = box->font; + F32 ellipses_size = box->font_size; + FNT_RasterFlags ellipses_raster_flags = box->text_raster_flags; + if(box->display_fstrs.last) + { + ellipses_font = box->display_fstrs.last->v.params.font; + ellipses_size = box->display_fstrs.last->v.params.size; + ellipses_raster_flags = box->display_fstrs.last->v.params.raster_flags; + } max_x = (box->rect.x1-text_position.x); - ellipses_run = fnt_push_run_from_string(scratch.arena, box->font, box->font_size, 0, box->tab_size, 0, str8_lit("...")); + ellipses_run = fnt_push_run_from_string(scratch.arena, ellipses_font, ellipses_size, 0, box->tab_size, ellipses_raster_flags, str8_lit("...")); } - dr_truncated_fancy_run_list(text_position, &box->display_string_runs, max_x, ellipses_run); - if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) + if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) UI_TagF("match") { - Vec4F32 match_color = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - dr_truncated_fancy_run_fuzzy_matches(text_position, &box->display_string_runs, max_x, &box->fuzzy_match_ranges, match_color); + Vec4F32 match_color = ui_color_from_tags_key_name(ui_top_tags_key(), str8_lit("background")); + dr_truncated_fancy_run_fuzzy_matches(text_position, &box->display_fruns, max_x, &box->fuzzy_match_ranges, match_color); } + dr_truncated_fancy_run_list(text_position, &box->display_fruns, max_x, ellipses_run); } // rjf: draw focus viz @@ -8425,64 +10241,63 @@ rd_window_frame(RD_Window *ws) dr_pop_clip(); } - // rjf: draw overlay - if(b->flags & UI_BoxFlag_DrawOverlay) - { - R_Rect2DInst *inst = dr_rect(b->rect, b->palette->colors[UI_ColorCode_Overlay], 0, 0, 1.f); - MemoryCopyArray(inst->corner_radii, b->corner_radii); - } - // rjf: draw border if(b->flags & UI_BoxFlag_DrawBorder) { - R_Rect2DInst *inst = dr_rect(pad_2f32(b->rect, 1.f), b->palette->colors[UI_ColorCode_Border], 0, 1.f, 1.f); + Vec4F32 border_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("border")); + Rng2F32 b_border_rect = pad_2f32(b->rect, 1.f); + R_Rect2DInst *inst = dr_rect(b_border_rect, border_color, 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); // rjf: hover effect if(b->flags & UI_BoxFlag_DrawHotEffects) { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); + Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("hover")); color.w *= b->hot_t; - R_Rect2DInst *inst = dr_rect(pad_2f32(b->rect, 1), color, 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(b_border_rect, color, 0, 1.f, 1.f); + inst->colors[Corner_01].w *= 0.2f; + inst->colors[Corner_11].w *= 0.2f; MemoryCopyArray(inst->corner_radii, b->corner_radii); } } // rjf: debug border rendering - if(0) + if(b->flags & UI_BoxFlag_Debug) { - R_Rect2DInst *inst = dr_rect(pad_2f32(b->rect, 1), v4f32(1, 0, 1, 0.25f), 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(b->rect, v4f32(1*box->pref_size[Axis2_X].strictness, 0, 1, 0.25f), 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); } // rjf: draw sides + if(b->flags & UI_BoxFlag_DrawSideTop|UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DrawSideLeft|UI_BoxFlag_DrawSideRight) { + Vec4F32 border_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("border")); Rng2F32 r = b->rect; F32 half_thickness = 1.f; - F32 softness = 0.5f; + F32 softness = 0.f; if(b->flags & UI_BoxFlag_DrawSideTop) { - dr_rect(r2f32p(r.x0, r.y0-half_thickness, r.x1, r.y0+half_thickness), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x0, r.y0, r.x1, r.y0+2*half_thickness), border_color, 0, 0, softness); } if(b->flags & UI_BoxFlag_DrawSideBottom) { - dr_rect(r2f32p(r.x0, r.y1-half_thickness, r.x1, r.y1+half_thickness), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x0, r.y1-2*half_thickness, r.x1, r.y1), border_color, 0, 0, softness); } if(b->flags & UI_BoxFlag_DrawSideLeft) { - dr_rect(r2f32p(r.x0-half_thickness, r.y0, r.x0+half_thickness, r.y1), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x0, r.y0, r.x0+2*half_thickness, r.y1), border_color, 0, 0, softness); } if(b->flags & UI_BoxFlag_DrawSideRight) { - dr_rect(r2f32p(r.x1-half_thickness, r.y0, r.x1+half_thickness, r.y1), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x1-2*half_thickness, r.y0, r.x1, r.y1), border_color, 0, 0, softness); } } // rjf: draw focus overlay if(b->flags & UI_BoxFlag_Clickable && !(b->flags & UI_BoxFlag_DisableFocusOverlay) && b->focus_hot_t > 0.01f) { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Focus); - color.w *= 0.2f*b->focus_hot_t; + Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("focus")); + color.w *= 0.09f*b->focus_hot_t; R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 0, 0.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); } @@ -8490,23 +10305,28 @@ rd_window_frame(RD_Window *ws) // rjf: draw focus border if(b->flags & UI_BoxFlag_Clickable && !(b->flags & UI_BoxFlag_DisableFocusBorder) && b->focus_active_t > 0.01f) { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Focus); + Rng2F32 rect = b->rect; + if(b->flags & UI_BoxFlag_Floating) + { + rect = pad_2f32(rect, 1.f); + rect = intersect_2f32(window_rect, rect); + } + Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("focus")); color.w *= b->focus_active_t; - R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(rect, color, 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); } // rjf: disabled overlay if(b->disabled_t >= 0.005f) { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_DisabledOverlay); - color.w *= b->disabled_t; - R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 0, 1); + Vec4F32 disabled_overlay_color = v4f32(base_background_color.x, base_background_color.y, base_background_color.z, b->disabled_t*0.3f); + R_Rect2DInst *inst = dr_rect(b->rect, disabled_overlay_color, 0, 0, 1); MemoryCopyArray(inst->corner_radii, b->corner_radii); } // rjf: pop squish - if(b->squish != 0) + if(b->squish > box_squish_epsilon) { dr_pop_xform2d(); dr_pop_tex2d_sample_kind(); @@ -8544,57 +10364,25 @@ rd_window_frame(RD_Window *ws) } //- rjf: draw border/overlay color to signify error - if(ws->error_t > 0.01f) + if(ws->error_t > 0.01f) UI_TagF("bad") { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_NegativePopButtonBackground); + Vec4F32 color = ui_color_from_name(str8_lit("text")); color.w *= ws->error_t; Rng2F32 rect = os_client_rect_from_window(ws->os); dr_rect(pad_2f32(rect, 24.f), color, 0, 16.f, 12.f); - dr_rect(rect, v4f32(color.x, color.y, color.z, color.w*0.05f), 0, 0, 0); - } - - //- rjf: scratch debug mouse drawing - if(DEV_scratch_mouse_draw) - { -#if 1 - Vec2F32 p = add_2f32(os_mouse_from_window(ws->os), v2f32(30, 0)); - dr_rect(os_client_rect_from_window(ws->os), v4f32(0, 0, 0, 0.9f), 0, 0, 0); - FNT_Run trailer_run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Main), 16.f, 0, 0, 0, str8_lit("...")); - DR_FancyStringList strs = {0}; - DR_FancyString str = {rd_font_from_slot(RD_FontSlot_Main), str8_lit("Shift + F5"), v4f32(1, 1, 1, 1), 72.f, 0.f}; - dr_fancy_string_list_push(scratch.arena, &strs, &str); - DR_FancyRunList runs = dr_fancy_run_list_from_fancy_string_list(scratch.arena, 0, FNT_RasterFlag_Smooth, &strs); - dr_truncated_fancy_run_list(p, &runs, 1000000.f, trailer_run); - dr_rect(r2f32(p, add_2f32(p, runs.dim)), v4f32(1, 0, 0, 0.5f), 0, 1, 0); - dr_rect(r2f32(sub_2f32(p, v2f32(4, 4)), add_2f32(p, v2f32(4, 4))), v4f32(1, 0, 1, 1), 0, 0, 0); -#else - Vec2F32 p = add_2f32(os_mouse_from_window(ws->os), v2f32(30, 0)); - dr_rect(os_client_rect_from_window(ws->os), v4f32(0, 0, 0, 0.4f), 0, 0, 0); - DR_FancyStringList strs = {0}; - DR_FancyString str1 = {rd_font_from_slot(RD_FontSlot_Main), str8_lit("T"), v4f32(1, 1, 1, 1), 16.f, 4.f}; - dr_fancy_string_list_push(scratch.arena, &strs, &str1); - DR_FancyString str2 = {rd_font_from_slot(RD_FontSlot_Main), str8_lit("his is a test of some "), v4f32(1, 0.5f, 0.5f, 1), 14.f, 0.f}; - dr_fancy_string_list_push(scratch.arena, &strs, &str2); - DR_FancyString str3 = {rd_font_from_slot(RD_FontSlot_Code), str8_lit("very fancy text!"), v4f32(1, 0.8f, 0.4f, 1), 18.f, 4.f, 4.f}; - dr_fancy_string_list_push(scratch.arena, &strs, &str3); - DR_FancyRunList runs = dr_fancy_run_list_from_fancy_string_list(scratch.arena, 0, 0, &strs); - FNT_Run trailer_run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Main), 16.f, 0, 0, 0, str8_lit("...")); - F32 limit = 500.f + sin_f32(rd_state->time_in_seconds/10.f)*200.f; - dr_truncated_fancy_run_list(p, &runs, limit, trailer_run); - dr_rect(r2f32p(p.x+limit, 0, p.x+limit+2.f, 1000), v4f32(1, 0, 0, 1), 0, 0, 0); - rd_request_frame(); -#endif + dr_rect(rect, v4f32(color.x, color.y, color.z, color.w*0.025f), 0, 0, 0); } scratch_end(scratch); } ////////////////////////////// - //- rjf: increment per-window frame counter + //- rjf: @window_frame_part increment per-window frame counter // ws->frames_alive += 1; ProfEnd(); + scratch_end(scratch); } #if COMPILER_MSVC && !BUILD_DEBUG @@ -8604,768 +10392,8 @@ rd_window_frame(RD_Window *ws) //////////////////////////////// //~ rjf: Eval Visualization -typedef struct RD_EntityExpandAccel RD_EntityExpandAccel; -struct RD_EntityExpandAccel -{ - RD_EntityArray entities; -}; - -typedef struct RD_CtrlEntityExpandAccel RD_CtrlEntityExpandAccel; -struct RD_CtrlEntityExpandAccel -{ - CTRL_EntityArray entities; -}; - -//- rjf: meta entities - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(watches) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_Watch); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(watches) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_Watch, 0); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_Watch, 0); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches) { return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_Watch, 0); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(targets) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_Target); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(targets) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_Target, 1); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(targets) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_Target, 1); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(targets) { return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_Target, 1); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(breakpoints) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_Breakpoint); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(breakpoints) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_Breakpoint, 1); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(breakpoints) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_Breakpoint, 1); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(breakpoints) { return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_Breakpoint, 1); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(watch_pins) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_WatchPin); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(watch_pins) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_WatchPin, 1); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watch_pins) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_WatchPin, 1); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watch_pins) { return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_WatchPin, 1); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(file_path_maps) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_FilePathMap); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(file_path_maps) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_FilePathMap, 1); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(file_path_maps) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_FilePathMap, 1); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(file_path_maps) { return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_FilePathMap, 1); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(auto_view_rules) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_AutoViewRule); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(auto_view_rules) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_AutoViewRule, 1); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(auto_view_rules){ return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_AutoViewRule, 1); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(auto_view_rules){ return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_AutoViewRule, 1); } - -//- rjf: control entity groups - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(machines) { return rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(arena, view, str8_zero(), expr, params, CTRL_EntityKind_Machine); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(machines) { return rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(arena, view, str8_zero(), expr, params, idx_range, user_data, CTRL_EntityKind_Machine); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(machines) { return rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(num, user_data, CTRL_EntityKind_Machine); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(machines) { return rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(id, user_data, CTRL_EntityKind_Machine); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(processes) { return rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(arena, view, filter, expr, params, CTRL_EntityKind_Process); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(processes) { return rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(arena, view, filter, expr, params, idx_range, user_data, CTRL_EntityKind_Process); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(processes) { return rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(num, user_data, CTRL_EntityKind_Process); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(processes) { return rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(id, user_data, CTRL_EntityKind_Process); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(threads) { return rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(arena, view, filter, expr, params, CTRL_EntityKind_Thread); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(threads) { return rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(arena, view, filter, expr, params, idx_range, user_data, CTRL_EntityKind_Thread); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(threads) { return rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(num, user_data, CTRL_EntityKind_Thread); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(threads) { return rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(id, user_data, CTRL_EntityKind_Thread); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(modules) { return rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(arena, view, filter, expr, params, CTRL_EntityKind_Module); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(modules) { return rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(arena, view, filter, expr, params, idx_range, user_data, CTRL_EntityKind_Module); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(modules) { return rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(num, user_data, CTRL_EntityKind_Module); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(modules) { return rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(id, user_data, CTRL_EntityKind_Module); } - -//- rjf: control entity hierarchies - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_machine) -{ - EV_ExpandInfo info = {0}; - Temp scratch = scratch_begin(&arena, 1); - E_Eval eval = e_eval_from_expr(scratch.arena, expr); - CTRL_Entity *machine = rd_ctrl_entity_from_eval_space(eval.space); - if(machine->kind == CTRL_EntityKind_Machine) - { - CTRL_EntityList processes = {0}; - for(CTRL_Entity *child = machine->first; child != &ctrl_entity_nil; child = child->next) - { - if(child->kind == CTRL_EntityKind_Process) - { - ctrl_entity_list_push(scratch.arena, &processes, child); - } - } - CTRL_EntityArray *processes_array = push_array(arena, CTRL_EntityArray, 1); - *processes_array = ctrl_entity_array_from_list(arena, &processes); - info.user_data = processes_array; - info.row_count = processes.count; - info.rows_default_expanded = 1; - } - scratch_end(scratch); - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_machine) -{ - EV_ExpandRangeInfo info = {0}; - { - CTRL_EntityArray *processes = (CTRL_EntityArray *)user_data; - if(processes != 0) - { - info.row_exprs_count = dim_1u64(idx_range); - info.row_strings = push_array(arena, String8, info.row_exprs_count); - info.row_view_rules = push_array(arena, String8, info.row_exprs_count); - info.row_exprs = push_array(arena, E_Expr *, info.row_exprs_count); - info.row_members = push_array(arena, E_Member *, info.row_exprs_count); - U64 row_expr_idx = 0; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, row_expr_idx += 1) - { - CTRL_Entity *process = processes->v[idx]; - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); - expr->space = rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_MetaCtrlEntity); - expr->mode = E_Mode_Offset; - expr->type_key = e_type_key_cons_base(type(CTRL_ProcessMetaEval));; - info.row_exprs[row_expr_idx] = expr; - info.row_members[row_expr_idx] = &e_member_nil; - } - } - } - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_machine) -{ - return num; -} - -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_machine) -{ - return id; -} - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_process) -{ - EV_ExpandInfo info = {0}; - Temp scratch = scratch_begin(&arena, 1); - E_Eval eval = e_eval_from_expr(scratch.arena, expr); - CTRL_Entity *process = rd_ctrl_entity_from_eval_space(eval.space); - if(process->kind == CTRL_EntityKind_Process) - { - CTRL_EntityList threads = {0}; - for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) - { - if(child->kind == CTRL_EntityKind_Thread) - { - B32 is_in_filter = 1; - if(filter.size != 0) - { - is_in_filter = 0; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, child->string); - if(matches.count == matches.needle_part_count) - { - is_in_filter = 1; - } - else - { - DI_Scope *di_scope = di_scope_open(); - CTRL_Unwind unwind = d_query_cached_unwind_from_thread(child); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &unwind); - for(U64 idx = 0; idx < call_stack.concrete_frame_count && idx < 5; idx += 1) - { - CTRL_CallStackFrame *f = &call_stack.frames[idx]; - String8 name = {0}; - name.str = rdi_string_from_idx(f->rdi, f->procedure->name_string_idx, &name.size); - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, name); - if(matches.count == matches.needle_part_count) - { - is_in_filter = 1; - break; - } - } - di_scope_close(di_scope); - } - } - if(is_in_filter) - { - ctrl_entity_list_push(scratch.arena, &threads, child); - } - } - } - CTRL_EntityArray *threads_array = push_array(arena, CTRL_EntityArray, 1); - *threads_array = ctrl_entity_array_from_list(arena, &threads); - info.user_data = threads_array; - info.row_count = threads.count; - } - scratch_end(scratch); - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_process) -{ - EV_ExpandRangeInfo info = {0}; - { - CTRL_EntityArray *threads = (CTRL_EntityArray *)user_data; - if(threads != 0) - { - info.row_exprs_count = dim_1u64(idx_range); - info.row_strings = push_array(arena, String8, info.row_exprs_count); - info.row_view_rules = push_array(arena, String8, info.row_exprs_count); - info.row_exprs = push_array(arena, E_Expr *, info.row_exprs_count); - info.row_members = push_array(arena, E_Member *, info.row_exprs_count); - U64 row_expr_idx = 0; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, row_expr_idx += 1) - { - CTRL_Entity *thread = threads->v[idx]; - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); - expr->space = rd_eval_space_from_ctrl_entity(thread, RD_EvalSpaceKind_MetaCtrlEntity); - expr->mode = E_Mode_Offset; - expr->type_key = e_type_key_cons_base(type(CTRL_ThreadMetaEval)); - info.row_exprs[row_expr_idx] = expr; - info.row_members[row_expr_idx] = &e_member_nil; - } - } - } - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_process) -{ - return num; -} - -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process) -{ - return id; -} - -//- rjf: locals - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(locals) -{ - Temp scratch = scratch_begin(&arena, 1); - E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_parse_ctx->locals_map); - e_string2num_map_node_array_sort__in_place(&nodes); - String8List exprs_filtered = {0}; - for EachIndex(idx, nodes.count) - { - String8 local_expr_string = nodes.v[idx]->string; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, local_expr_string); - if(matches.count == matches.needle_part_count) - { - str8_list_push(scratch.arena, &exprs_filtered, local_expr_string); - } - } - String8Array *accel = push_array(arena, String8Array, 1); - *accel = str8_array_from_list(arena, &exprs_filtered); - EV_ExpandInfo info = {accel, accel->count}; - scratch_end(scratch); - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(locals) -{ - String8Array *accel = (String8Array *)user_data; - EV_ExpandRangeInfo result = {0}; - { - U64 needed_row_count = dim_1u64(idx_range); - result.row_exprs_count = Min(needed_row_count, accel->count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - result.row_exprs[row_expr_idx] = e_parse_expr_from_text(arena, accel->v[idx_range.min + row_expr_idx]); - result.row_members[row_expr_idx] = &e_member_nil; - } - } - return result; -} - -//- rjf: registers - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(registers) -{ - Temp scratch = scratch_begin(&arena, 1); - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); - Arch arch = thread->arch; - U64 reg_count = regs_reg_code_count_from_arch(arch); - U64 alias_count = regs_alias_code_count_from_arch(arch); - String8 *reg_strings = regs_reg_code_string_table_from_arch(arch); - String8 *alias_strings = regs_alias_code_string_table_from_arch(arch); - String8List exprs_list = {0}; - for(U64 idx = 1; idx < reg_count; idx += 1) - { - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, reg_strings[idx]); - if(matches.count == matches.needle_part_count) - { - str8_list_push(scratch.arena, &exprs_list, reg_strings[idx]); - } - } - for(U64 idx = 1; idx < alias_count; idx += 1) - { - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, alias_strings[idx]); - if(matches.count == matches.needle_part_count) - { - str8_list_push(scratch.arena, &exprs_list, alias_strings[idx]); - } - } - String8Array *accel = push_array(arena, String8Array, 1); - *accel = str8_array_from_list(arena, &exprs_list); - EV_ExpandInfo info = {accel, accel->count}; - scratch_end(scratch); - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(registers) -{ - String8Array *accel = (String8Array *)user_data; - EV_ExpandRangeInfo result = {0}; - { - U64 needed_row_count = dim_1u64(idx_range); - result.row_exprs_count = Min(needed_row_count, accel->count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - String8 string = push_str8f(arena, "reg:%S", accel->v[idx_range.min + row_expr_idx]); - result.row_exprs[row_expr_idx] = e_parse_expr_from_text(arena, string); - result.row_members[row_expr_idx] = &e_member_nil; - } - } - return result; -} - -//- rjf: debug info tables - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(globals) {return rd_ev_view_rule_expr_expand_info__debug_info_tables(arena, view, filter, expr, params, RDI_SectionKind_GlobalVariables);} -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(globals) {return rd_ev_view_rule_expr_expand_range_info__debug_info_tables(arena, view, filter, expr, params, idx_range, user_data, RDI_SectionKind_GlobalVariables);} -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(globals) {return rd_ev_view_rule_expr_id_from_num__debug_info_tables(num, user_data, RDI_SectionKind_GlobalVariables); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(globals) {return rd_ev_view_rule_expr_num_from_id__debug_info_tables(id, user_data, RDI_SectionKind_GlobalVariables); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(thread_locals) {return rd_ev_view_rule_expr_expand_info__debug_info_tables(arena, view, filter, expr, params, RDI_SectionKind_ThreadVariables);} -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(thread_locals) {return rd_ev_view_rule_expr_expand_range_info__debug_info_tables(arena, view, filter, expr, params, idx_range, user_data, RDI_SectionKind_ThreadVariables);} -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(thread_locals) {return rd_ev_view_rule_expr_id_from_num__debug_info_tables(num, user_data, RDI_SectionKind_ThreadVariables); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(thread_locals) {return rd_ev_view_rule_expr_num_from_id__debug_info_tables(id, user_data, RDI_SectionKind_ThreadVariables); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(types) {return rd_ev_view_rule_expr_expand_info__debug_info_tables(arena, view, filter, expr, params, RDI_SectionKind_UDTs);} -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(types) {return rd_ev_view_rule_expr_expand_range_info__debug_info_tables(arena, view, filter, expr, params, idx_range, user_data, RDI_SectionKind_UDTs);} -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(types) {return rd_ev_view_rule_expr_id_from_num__debug_info_tables(num, user_data, RDI_SectionKind_UDTs); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(types) {return rd_ev_view_rule_expr_num_from_id__debug_info_tables(id, user_data, RDI_SectionKind_UDTs); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_expand_info__debug_info_tables(arena, view, filter, expr, params, RDI_SectionKind_Procedures);} -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_expand_range_info__debug_info_tables(arena, view, filter, expr, params, idx_range, user_data, RDI_SectionKind_Procedures);} -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_id_from_num__debug_info_tables(num, user_data, RDI_SectionKind_Procedures); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_num_from_id__debug_info_tables(id, user_data, RDI_SectionKind_Procedures); } - -internal EV_ExpandInfo -rd_ev_view_rule_expr_expand_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RD_EntityKind kind) -{ - RD_EntityExpandAccel *accel = push_array(arena, RD_EntityExpandAccel, 1); - Temp scratch = scratch_begin(&arena, 1); - { - RD_EntityList entities = rd_query_cached_entity_list_with_kind(kind); - RD_EntityList entities_filtered = {0}; - for(RD_EntityNode *n = entities.first; n != 0; n = n->next) - { - RD_Entity *entity = n->entity; - String8 entity_expr_string = entity->string; - B32 is_collection = 0; - for EachElement(idx, rd_collection_name_table) - { - if(str8_match(entity_expr_string, rd_collection_name_table[idx], 0)) - { - is_collection = 1; - break; - } - } - B32 is_in_filter = 1; - if(!is_collection && filter.size != 0) - { - RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location); - RD_Entity *exe = rd_entity_child_from_kind(entity, RD_EntityKind_Executable); - RD_Entity *args = rd_entity_child_from_kind(entity, RD_EntityKind_Arguments); - FuzzyMatchRangeList expr_matches = fuzzy_match_find(scratch.arena, filter, entity_expr_string); - FuzzyMatchRangeList loc_matches = fuzzy_match_find(scratch.arena, filter, loc->string); - FuzzyMatchRangeList exe_matches = fuzzy_match_find(scratch.arena, filter, exe->string); - FuzzyMatchRangeList args_matches = fuzzy_match_find(scratch.arena, filter, args->string); - is_in_filter = (expr_matches.count == expr_matches.needle_part_count || - loc_matches.count == loc_matches.needle_part_count || - exe_matches.count == exe_matches.needle_part_count || - args_matches.count == args_matches.needle_part_count); - } - if(is_collection || is_in_filter) - { - rd_entity_list_push(scratch.arena, &entities_filtered, entity); - } - } - accel->entities = rd_entity_array_from_list(arena, &entities_filtered); - } - scratch_end(scratch); - EV_ExpandInfo info = {accel, accel->entities.count + 1}; - info.add_new_row = 1; - return info; -} - -internal EV_ExpandRangeInfo -rd_ev_view_rule_expr_expand_range_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, RD_EntityKind kind, B32 add_new_at_top) -{ - RD_EntityExpandAccel *accel = (RD_EntityExpandAccel *)user_data; - EV_ExpandRangeInfo result = {0}; - { - U64 entities_base_idx = (U64)!!add_new_at_top; - U64 needed_row_count = dim_1u64(idx_range); - result.row_exprs_count = Min(needed_row_count, accel->entities.count+1); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - U64 child_idx = idx_range.min + row_expr_idx; - RD_Entity *entity = &rd_nil_entity; - if(entities_base_idx <= child_idx && child_idx < entities_base_idx+accel->entities.count) - { - entity = accel->entities.v[child_idx-entities_base_idx]; - } - if(!rd_entity_is_nil(entity)) - { - String8 entity_expr_string = (kind == RD_EntityKind_Watch ? entity->string : push_str8f(arena, "entity:$%I64u", entity->id)); - if(kind == RD_EntityKind_Watch) - { - result.row_strings[row_expr_idx] = entity_expr_string; - } - result.row_exprs[row_expr_idx] = e_parse_expr_from_text(arena, entity_expr_string); - result.row_view_rules[row_expr_idx] = rd_entity_child_from_kind(entity, RD_EntityKind_ViewRule)->string; - } - else - { - result.row_exprs[row_expr_idx] = &e_expr_nil; - } - result.row_members[row_expr_idx] = &e_member_nil; - } - } - return result; -} - -internal U64 -rd_ev_view_rule_expr_id_from_num__meta_entities(U64 num, void *user_data, RD_EntityKind kind, B32 add_new_at_top) -{ - U64 id = 0; - RD_EntityExpandAccel *accel = (RD_EntityExpandAccel *)user_data; - U64 entities_base_idx = (U64)!!add_new_at_top; - if(entities_base_idx+1 <= num && num < entities_base_idx+accel->entities.count+1) - { - id = accel->entities.v[num-(entities_base_idx+1)]->id; - } - else - { - id = max_U64; - } - return id; -} - -internal U64 -rd_ev_view_rule_expr_num_from_id__meta_entities(U64 id, void *user_data, RD_EntityKind kind, B32 add_new_at_top) -{ - RD_EntityExpandAccel *accel = (RD_EntityExpandAccel *)user_data; - U64 num = 0; - U64 entities_base_idx = (U64)!!add_new_at_top; - if(id == max_U64) - { - num = add_new_at_top ? 1 : (entities_base_idx + accel->entities.count + 1); - } - else for(U64 idx = 0; idx < accel->entities.count; idx += 1) - { - if(accel->entities.v[idx]->id == id) - { - num = entities_base_idx+idx+1; - break; - } - } - return num; -} - -internal EV_ExpandInfo -rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, CTRL_EntityKind kind) -{ - RD_CtrlEntityExpandAccel *accel = push_array(arena, RD_CtrlEntityExpandAccel, 1); - Temp scratch = scratch_begin(&arena, 1); - { - CTRL_EntityList entities = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, kind); - CTRL_EntityList entities_filtered = {0}; - for(CTRL_EntityNode *n = entities.first; n != 0; n = n->next) - { - CTRL_Entity *entity = n->v; - B32 is_in_filter = 1; - if(filter.size != 0) - { - is_in_filter = 0; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, entity->string); - if(matches.count == matches.needle_part_count) - { - is_in_filter = 1; - } - } - if(is_in_filter) - { - ctrl_entity_list_push(scratch.arena, &entities_filtered, entity); - } - } - accel->entities = ctrl_entity_array_from_list(arena, &entities_filtered); - } - scratch_end(scratch); - EV_ExpandInfo info = {accel, accel->entities.count}; - // TODO(rjf): hack - if(kind == CTRL_EntityKind_Machine) - { - info.rows_default_expanded = 1; - } - return info; -} - -internal EV_ExpandRangeInfo -rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, CTRL_EntityKind kind) -{ - RD_CtrlEntityExpandAccel *accel = (RD_CtrlEntityExpandAccel *)user_data; - EV_ExpandRangeInfo result = {0}; - { - U64 needed_row_count = dim_1u64(idx_range); - result.row_exprs_count = Min(needed_row_count, accel->entities.count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - CTRL_Entity *entity = accel->entities.v[idx_range.min + row_expr_idx]; - String8 entity_expr_string = push_str8f(arena, "ctrl_entity:$_%I64x_%I64x", entity->handle.machine_id, entity->handle.dmn_handle.u64[0]); - result.row_exprs[row_expr_idx] = e_parse_expr_from_text(arena, entity_expr_string); - result.row_members[row_expr_idx] = &e_member_nil; - } - } - return result; -} - -internal U64 -rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(U64 num, void *user_data, CTRL_EntityKind kind) -{ - RD_CtrlEntityExpandAccel *accel = (RD_CtrlEntityExpandAccel *)user_data; - U64 id = 0; - if(1 <= num && num <= accel->entities.count) - { - id = d_hash_from_string(str8_struct(&accel->entities.v[num-1]->handle)); - } - return id; -} - -internal U64 -rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(U64 id, void *user_data, CTRL_EntityKind kind) -{ - RD_CtrlEntityExpandAccel *accel = (RD_CtrlEntityExpandAccel *)user_data; - U64 num = 0; - if(id != 0) - { - for EachIndex(idx, accel->entities.count) - { - U64 idx_id = d_hash_from_string(str8_struct(&accel->entities.v[idx]->handle)); - if(idx_id == id) - { - num = idx+1; - break; - } - } - } - return num; -} - -typedef struct RD_DebugInfoTableExpandAccel RD_DebugInfoTableExpandAccel; -struct RD_DebugInfoTableExpandAccel -{ - U64 rdis_count; - RDI_Parsed **rdis; - DI_SearchItemArray items; -}; - -internal EV_ExpandInfo -rd_ev_view_rule_expr_expand_info__debug_info_tables(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RDI_SectionKind section) -{ - RD_DebugInfoTableExpandAccel *accel = push_array(arena, RD_DebugInfoTableExpandAccel, 1); - if(section != RDI_SectionKind_NULL) - { - Temp scratch = scratch_begin(&arena, 1); - U64 endt_us = os_now_microseconds()+200; - - //- rjf: unpack context - DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena); - DI_KeyArray dbgi_keys = di_key_array_from_list(scratch.arena, &dbgi_keys_list); - U64 rdis_count = dbgi_keys.count; - RDI_Parsed **rdis = push_array(arena, RDI_Parsed *, rdis_count); - for(U64 idx = 0; idx < rdis_count; idx += 1) - { - rdis[idx] = di_rdi_from_key(rd_state->frame_di_scope, &dbgi_keys.v[idx], endt_us); - } - - //- rjf: query all filtered items from dbgi searching system - U128 fuzzy_search_key = {(U64)view, (U64)section}; - B32 items_stale = 0; - DI_SearchParams params = {section, dbgi_keys}; - accel->rdis_count = rdis_count; - accel->rdis = rdis; - accel->items = di_search_items_from_key_params_query(rd_state->frame_di_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); - if(items_stale) - { - rd_request_frame(); - } - - scratch_end(scratch); - } - EV_ExpandInfo info = {accel, accel->items.count}; - return info; -} - -internal EV_ExpandRangeInfo -rd_ev_view_rule_expr_expand_range_info__debug_info_tables(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, RDI_SectionKind section) -{ - RD_DebugInfoTableExpandAccel *accel = (RD_DebugInfoTableExpandAccel *)user_data; - EV_ExpandRangeInfo result = {0}; - { - U64 needed_row_count = dim_1u64(idx_range); - result.row_exprs_count = Min(needed_row_count, accel->items.count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - // rjf: unpack row - DI_SearchItem *item = &accel->items.v[idx_range.min + row_expr_idx]; - - // rjf: skip bad elements - if(item->dbgi_idx >= accel->rdis_count) - { - continue; - } - - // rjf: unpack row info - RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; - E_Module *module = &e_parse_ctx->modules[item->dbgi_idx]; - - // rjf: build expr - E_Expr *item_expr = &e_expr_nil; - { - U64 element_idx = item->idx; - switch(section) - { - default:{}break; - case RDI_SectionKind_Procedures: - { - RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); - RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Value; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_GlobalVariables: - { - RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); - U64 voff = gvar->voff; - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = gvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_ThreadVariables: - { - RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(tvar->tls_off)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = tvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_UDTs: - { - RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); - item_expr->type_key = type_key; - }break; - } - } - - // rjf: fill - result.row_exprs[row_expr_idx] = item_expr; - result.row_members[row_expr_idx] = &e_member_nil; - } - } - return result; -} - -internal U64 -rd_ev_view_rule_expr_id_from_num__debug_info_tables(U64 num, void *user_data, RDI_SectionKind section) -{ - RD_DebugInfoTableExpandAccel *accel = (RD_DebugInfoTableExpandAccel *)user_data; - U64 id = 0; - if(0 < num && num <= accel->items.count) - { - id = accel->items.v[num-1].idx+1; - } - return id; -} - -internal U64 -rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 id, void *user_data, RDI_SectionKind section) -{ - RD_DebugInfoTableExpandAccel *accel = (RD_DebugInfoTableExpandAccel *)user_data; - U64 num = di_search_item_num_from_array_element_idx__linear_search(&accel->items, id-1); - return num; -} - -internal EV_View * -rd_ev_view_from_key(U64 key) -{ - U64 slot_idx = key % rd_state->eval_viz_view_cache_slots_count; - RD_EvalVizViewCacheNode *node = 0; - RD_EvalVizViewCacheSlot *slot = &rd_state->eval_viz_view_cache_slots[slot_idx]; - for(RD_EvalVizViewCacheNode *n = slot->first; n != 0; n = n->next) - { - if(n->key == key) - { - node = n; - break; - } - } - if(node == 0) - { - node = rd_state->eval_viz_view_cache_node_free; - if(node) - { - SLLStackPop(rd_state->eval_viz_view_cache_node_free); - } - else - { - node = push_array(rd_state->arena, RD_EvalVizViewCacheNode, 1); - } - DLLPushBack(slot->first, slot->last, node); - node->key = key; - node->v = ev_view_alloc(); - } - return node->v; -} - internal F32 -rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval eval, E_Member *member, EV_ViewRuleList *view_rules, String8List *out) +rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval root_eval, E_Eval eval, String8List *out) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -9377,35 +10405,35 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul B32 no_addr = 0; B32 no_string = 0; B32 has_array = 0; - for(EV_ViewRuleNode *n = view_rules->first; n != 0; n = n->next) + for(E_Expr *tag = root_eval.exprs.last->first_tag; tag != &e_expr_nil; tag = tag->next) { if(0){} - else if(str8_match(n->v.root->string, str8_lit("dec"), 0)) {radix = 10;} - else if(str8_match(n->v.root->string, str8_lit("hex"), 0)) {radix = 16;} - else if(str8_match(n->v.root->string, str8_lit("bin"), 0)) {radix = 2; } - else if(str8_match(n->v.root->string, str8_lit("oct"), 0)) {radix = 8; } - else if(str8_match(n->v.root->string, str8_lit("no_addr"), 0)) {no_addr = 1;} - else if(str8_match(n->v.root->string, str8_lit("no_string"), 0)) {no_string = 1;} - else if(str8_match(n->v.root->string, str8_lit("array"), 0)) {has_array = 1;} - else if(str8_match(n->v.root->string, str8_lit("digits"), 0)) + else if(str8_match(tag->string, str8_lit("dec"), 0)) {radix = 10;} + else if(str8_match(tag->string, str8_lit("hex"), 0)) {radix = 16;} + else if(str8_match(tag->string, str8_lit("bin"), 0)) {radix = 2; } + else if(str8_match(tag->string, str8_lit("oct"), 0)) {radix = 8; } + else if(str8_match(tag->string, str8_lit("no_addr"), 0)) {no_addr = 1;} + else if(str8_match(tag->string, str8_lit("no_string"), 0)) {no_string = 1;} + else if(str8_match(tag->string, str8_lit("array"), 0)) {has_array = 1;} + else if(str8_match(tag->string, str8_lit("digits"), 0)) { - String8 expr = md_string_from_children(scratch.arena, n->v.root); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - min_digits = (U32)value_eval.value.u64; + E_Expr *num_expr = tag->first->next; + E_Eval num_eval = e_eval_from_expr(scratch.arena, num_expr); + E_Eval num_value_eval = e_value_eval_from_eval(num_eval); + min_digits = (U32)num_value_eval.value.u64; } } - if(eval.space.kind == RD_EvalSpaceKind_MetaEntity || - eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + if(eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + eval.space.kind == RD_EvalSpaceKind_MetaCfg) { - E_TypeKind kind = e_type_kind_from_key(eval.type_key); + E_TypeKind kind = e_type_kind_from_key(eval.irtree.type_key); if(kind != E_TypeKind_Ptr) { no_addr = 1; } else { - E_Type *type = e_type_from_key(scratch.arena, eval.type_key); + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); if(!(type->flags & E_TypeFlag_External)) { no_addr = 1; @@ -9413,249 +10441,394 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } } - //- rjf: member evaluations -> display member info - if(eval.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.type_key) && member != &e_member_nil) + //- rjf: force no_string, if we are looking at padding members + if(eval.exprs.last->kind == E_ExprKind_MemberAccess) { - U64 member_byte_size = e_type_byte_size_from_key(eval.type_key); - String8 offset_string = str8_from_u64(arena, member->off, radix, 0, 0); - String8 size_string = str8_from_u64(arena, member_byte_size, radix, 0, 0); - str8_list_pushf(arena, out, "member (%S offset, %S byte%s)", offset_string, size_string, member_byte_size == 1 ? "" : "s"); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.exprs.last->first); + E_TypeKey struct_type = irtree.type_key; + for(B32 done = 0; !done;) + { + E_TypeKind kind = e_type_kind_from_key(struct_type); + if(kind == E_TypeKind_Null || + kind == E_TypeKind_Struct || + kind == E_TypeKind_Union || + kind == E_TypeKind_Class) + { + done = 1; + } + else if(e_type_kind_is_pointer_or_ref(kind)) + { + struct_type = e_type_direct_from_key(struct_type); + } + else + { + break; + } + } + E_Member member = e_type_member_from_key_name__cached(struct_type, eval.exprs.last->last->string); + if(member.kind == E_MemberKind_Padding) + { + no_string = 1; + } } - //- rjf: type evaluations -> display type basic information - else if(eval.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.type_key) && eval.expr->kind != E_ExprKind_MemberAccess) + //- rjf: type evaluations -> display type string + if(eval.irtree.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) { - String8 basic_type_kind_string = e_kind_basic_string_table[e_type_kind_from_key(eval.type_key)]; - U64 byte_size = e_type_byte_size_from_key(eval.type_key); - String8 size_string = str8_from_u64(arena, byte_size, radix, 0, 0); - str8_list_pushf(arena, out, "%S (%S byte%s)", basic_type_kind_string, size_string, byte_size == 1 ? "" : "s"); + String8 string = e_type_string_from_key(arena, eval.irtree.type_key); + str8_list_push(arena, out, string); } //- rjf: value/offset evaluations - else if(max_size > 0) switch(e_type_kind_from_key(e_type_unwrap(eval.type_key))) + else if(max_size > 0) { - //- rjf: default - leaf cases - default: + E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); + E_TypeKind kind = e_type_kind_from_key(type_key); + switch(kind) { - E_Eval value_eval = e_value_eval_from_eval(eval); - String8 string = ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; - str8_list_push(arena, out, string); - }break; - - //- rjf: pointers - case E_TypeKind_Function: - case E_TypeKind_Ptr: - case E_TypeKind_LRef: - case E_TypeKind_RRef: - { - // rjf: unpack type info - E_TypeKind type_kind = e_type_kind_from_key(e_type_unwrap(eval.type_key)); - E_TypeKey direct_type_key = e_type_unwrap(e_type_ptee_from_key(e_type_unwrap(eval.type_key))); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - - // rjf: unpack info about pointer destination - E_Eval value_eval = e_value_eval_from_eval(eval); - B32 ptee_has_content = (direct_type_kind != E_TypeKind_Null && direct_type_kind != E_TypeKind_Void); - B32 ptee_has_string = ((E_TypeKind_Char8 <= direct_type_kind && direct_type_kind <= E_TypeKind_UChar32) || - direct_type_kind == E_TypeKind_S8 || - direct_type_kind == E_TypeKind_U8); - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - String8 symbol_name = d_symbol_name_from_process_vaddr(arena, process, value_eval.value.u64, 1); - - // rjf: special case: push strings for textual string content - B32 did_content = 0; - B32 did_string = 0; - if(!did_content && ptee_has_string && !no_string) + //- rjf: default - leaf cases + default: { - did_content = 1; - did_string = 1; - U64 string_memory_addr = value_eval.value.u64; - U64 element_size = e_type_byte_size_from_key(direct_type_key); - U64 string_buffer_size = 256; - U8 *string_buffer = push_array(arena, U8, string_buffer_size); - for(U64 try_size = string_buffer_size; try_size >= 16; try_size /= 2) - { - B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+try_size)); - if(read_good) - { - break; - } - } - string_buffer[string_buffer_size-1] = 0; - String8 string = {0}; - switch(element_size) - { - default:{string = str8_cstring((char *)string_buffer);}break; - case 2: {string = str8_from_16(arena, str16_cstring((U16 *)string_buffer));}break; - case 4: {string = str8_from_32(arena, str32_cstring((U32 *)string_buffer));}break; - } - String8 string_escaped = ev_escaped_from_raw_string(arena, string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; - space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; - str8_list_push(arena, out, str8_lit("\"")); - str8_list_push(arena, out, string_escaped); - str8_list_push(arena, out, str8_lit("\"")); - } - - // rjf: special case: push strings for symbols - if(value_eval.value.u64 != 0 && - !did_content && symbol_name.size != 0 && - flags & EV_StringFlag_ReadOnlyDisplayRules && - ((type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Void) || - (type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Function) || - (type_kind == E_TypeKind_Function))) - { - did_content = 1; - str8_list_push(arena, out, symbol_name); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, symbol_name).x; - } - - // rjf: special case: need symbol name, don't have one - if(value_eval.value.u64 != 0 && - !did_content && symbol_name.size == 0 && - flags & EV_StringFlag_ReadOnlyDisplayRules && - ((type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Function) || - (type_kind == E_TypeKind_Function)) && - (flags & EV_StringFlag_ReadOnlyDisplayRules)) - { - did_content = 1; - String8 string = str8_lit("???"); - str8_list_push(arena, out, string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; - } - - // rjf: push pointer value - B32 did_ptr_value = 0; - if(!no_addr || value_eval.value.u64 == 0) - { - did_ptr_value = 1; - if(did_content) - { - String8 left_paren = str8_lit(" ("); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, left_paren).x; - str8_list_push(arena, out, left_paren); - } + E_Eval value_eval = e_value_eval_from_eval(eval); String8 string = ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; str8_list_push(arena, out, string); - if(did_content) - { - String8 right_paren = str8_lit(")"); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, right_paren).x; - str8_list_push(arena, out, right_paren); - } - } + }break; - // rjf: descend for all other cases - B32 did_arrow = 0; - if(value_eval.value.u64 != 0 && !did_content && ptee_has_content && (flags & EV_StringFlag_ReadOnlyDisplayRules)) + //- rjf: pointers + case E_TypeKind_Function: + case E_TypeKind_Ptr: + case E_TypeKind_LRef: + case E_TypeKind_RRef: { - if(did_ptr_value && !did_arrow) - { - did_arrow = 1; - String8 arrow = str8_lit(" -> "); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, arrow).x; - str8_list_push(arena, out, arrow); - } - did_content = 1; - if(depth < 4) - { - E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.expr); - E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, deref_eval, 0, view_rules, out); - } - else - { - String8 ellipses = str8_lit("..."); - str8_list_push(arena, out, ellipses); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - } - } - }break; - - //- rjf: arrays - case E_TypeKind_Array: - { - // rjf: unpack type info - E_Type *eval_type = e_type_from_key(scratch.arena, e_type_unwrap(eval.type_key)); - E_TypeKey direct_type_key = e_type_unwrap(eval_type->direct_type_key); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - U64 array_count = eval_type->count; - - // rjf: get pointed-at type - B32 array_is_string = ((E_TypeKind_Char8 <= direct_type_kind && direct_type_kind <= E_TypeKind_UChar32) || - direct_type_kind == E_TypeKind_S8 || - direct_type_kind == E_TypeKind_U8); - - // rjf: special case: push strings for textual string content - B32 did_content = 0; - if(!did_content && array_is_string && !no_string && (member == 0 || member->kind != E_MemberKind_Padding)) - { - U64 element_size = e_type_byte_size_from_key(direct_type_key); - did_content = 1; - U64 string_buffer_size = Clamp(1, array_count, 1024); - U8 *string_buffer = push_array(arena, U8, string_buffer_size); - switch(eval.mode) - { - default:{}break; - case E_Mode_Offset: - { - U64 string_memory_addr = eval.value.u64; - B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+string_buffer_size)); - }break; - case E_Mode_Value: - { - MemoryCopy(string_buffer, &eval.value.u512[0], Min(string_buffer_size, sizeof(eval.value))); - }break; - } - String8 string = {0}; - switch(element_size) - { - default:{string = str8_cstring_capped(string_buffer, string_buffer + string_buffer_size);}break; - case 2: {string = str8_from_16(arena, str16_cstring_capped(string_buffer, string_buffer + string_buffer_size));}break; - case 4: {string = str8_from_32(arena, str32_cstring((U32 *)string_buffer));}break; - } - String8 string_escaped = ev_escaped_from_raw_string(arena, string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; - space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; - str8_list_push(arena, out, str8_lit("\"")); - str8_list_push(arena, out, string_escaped); - str8_list_push(arena, out, str8_lit("\"")); - } - - // rjf: descend in all other cases - if(!did_content && (flags & EV_StringFlag_ReadOnlyDisplayRules)) - { - did_content = 1; + // rjf: unpack type info + E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); + E_Type *type = e_type_from_key__cached(type_key); + E_TypeKind type_kind = type->kind; + E_TypeKey direct_type_key = e_type_unwrap(e_type_ptee_from_key(type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - // rjf: [ + // rjf: unpack info about pointer destination + E_Eval value_eval = e_value_eval_from_eval(eval); + B32 ptee_has_content = (direct_type_kind != E_TypeKind_Null && direct_type_kind != E_TypeKind_Void); + B32 ptee_has_string = ((E_TypeKind_Char8 <= direct_type_kind && direct_type_kind <= E_TypeKind_UChar32) || + direct_type_kind == E_TypeKind_S8 || + direct_type_kind == E_TypeKind_U8); + E_Space space = value_eval.space; + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); + CTRL_Entity *process = ctrl_process_from_entity(entity); + if(process == &ctrl_entity_nil) { - String8 bracket = str8_lit("["); - str8_list_push(arena, out, bracket); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, bracket).x; + CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + process = ctrl_process_from_entity(thread); + } + String8 symbol_name = d_symbol_name_from_process_vaddr(arena, process, value_eval.value.u64, type->depth, 1); + + // rjf: special case: push strings for textual string content + B32 did_content = 0; + B32 did_string = 0; + if(!did_content && ptee_has_string && !no_string) + { + did_content = 1; + did_string = 1; + U64 string_memory_addr = value_eval.value.u64; + U64 element_size = e_type_byte_size_from_key(direct_type_key); + U64 string_buffer_size = 1024; + U8 *string_buffer = push_array(arena, U8, string_buffer_size); + for(U64 try_size = string_buffer_size; try_size >= 16; try_size /= 2) + { + B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+try_size)); + if(read_good) + { + break; + } + } + string_buffer[string_buffer_size-1] = 0; + String8 string = {0}; + switch(element_size) + { + default:{string = str8_cstring((char *)string_buffer);}break; + case 2: {string = str8_from_16(arena, str16_cstring((U16 *)string_buffer));}break; + case 4: {string = str8_from_32(arena, str32_cstring((U32 *)string_buffer));}break; + } + String8 string_escaped = string; + if(!no_addr || depth > 0) + { + string_escaped = ev_escaped_from_raw_string(arena, string); + } + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; + space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } + str8_list_push(arena, out, string_escaped); + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } + } + + // rjf: special case: push strings for symbols + if(value_eval.value.u64 != 0 && + !did_content && symbol_name.size != 0 && + flags & EV_StringFlag_ReadOnlyDisplayRules && + ((type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Void) || + (type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Function) || + (type_kind == E_TypeKind_Function))) + { + did_content = 1; + str8_list_push(arena, out, symbol_name); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, symbol_name).x; + } + + // rjf: special case: need symbol name, don't have one + if(value_eval.value.u64 != 0 && + !did_content && symbol_name.size == 0 && + flags & EV_StringFlag_ReadOnlyDisplayRules && + ((type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Function) || + (type_kind == E_TypeKind_Function)) && + (flags & EV_StringFlag_ReadOnlyDisplayRules)) + { + did_content = 1; + String8 string = str8_lit("???"); + str8_list_push(arena, out, string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; + } + + // rjf: push pointer value + B32 did_ptr_value = 0; + if(!no_addr || value_eval.value.u64 == 0) + { + did_ptr_value = 1; + if(did_content) + { + String8 left_paren = str8_lit(" ("); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, left_paren).x; + str8_list_push(arena, out, left_paren); + } + String8 string = ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; + str8_list_push(arena, out, string); + if(did_content) + { + String8 right_paren = str8_lit(")"); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, right_paren).x; + str8_list_push(arena, out, right_paren); + } + } + + // rjf: descend for all other cases + B32 did_arrow = 0; + if(value_eval.value.u64 != 0 && !did_content && ptee_has_content && (flags & EV_StringFlag_ReadOnlyDisplayRules)) + { + if(did_ptr_value && !did_arrow) + { + did_arrow = 1; + String8 arrow = str8_lit(" -> "); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, arrow).x; + str8_list_push(arena, out, arrow); + } + did_content = 1; + if(depth < 4) + { + if(type->count == 1) + { + E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.exprs.last); + E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); + space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_eval, deref_eval, out); + } + else + { + // rjf: unpack + E_IRTreeAndType irtree = eval.irtree; + E_LookupRule *lookup_rule = eval.lookup_rule_tag.rule; + E_Expr *lookup_rule_tag = eval.lookup_rule_tag.tag; + if(lookup_rule == &e_lookup_rule__default) + { + lookup_rule = root_eval.lookup_rule_tag.rule; + lookup_rule_tag = root_eval.lookup_rule_tag.tag; + } + E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); + U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); + String8 opener_string = str8_lit("["); + String8 closer_string = str8_lit("]"); + + // rjf: opener ({, [) + { + str8_list_push(arena, out, opener_string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, opener_string).x; + } + + // rjf: contents + { + B32 is_first = 1; + for(U64 idx = 0; idx < total_possible_child_count && max_size > space_taken; idx += 1) + { + E_Expr *expr = &e_expr_nil; + String8 expr_string = {0}; + lookup_rule->range(scratch.arena, eval.exprs.last, lookup_rule_tag, filter, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); + if(expr != &e_expr_nil) + { + if(!is_first) + { + String8 comma = str8_lit(", "); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; + str8_list_push(arena, out, comma); + } + is_first = 0; + E_Eval child_eval = e_eval_from_expr(scratch.arena, expr); + space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_eval, child_eval, out); + if(space_taken > max_size && idx+1 < total_possible_child_count) + { + String8 ellipses = str8_lit(", ..."); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; + str8_list_push(arena, out, ellipses); + } + } + } + } + + // rjf: closer (}, ]) + { + str8_list_push(arena, out, closer_string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, closer_string).x; + } + } + } + else + { + String8 ellipses = str8_lit("..."); + str8_list_push(arena, out, ellipses); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; + } + } + }break; + + //- rjf: arrays + case E_TypeKind_Array: + { + // rjf: unpack type info + E_Type *eval_type = e_type_from_key__cached(e_type_unwrap(eval.irtree.type_key)); + E_TypeKey direct_type_key = e_type_unwrap(eval_type->direct_type_key); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + U64 array_count = eval_type->count; + + // rjf: get pointed-at type + B32 array_is_string = ((E_TypeKind_Char8 <= direct_type_kind && direct_type_kind <= E_TypeKind_UChar32) || + direct_type_kind == E_TypeKind_S8 || + direct_type_kind == E_TypeKind_U8); + + // rjf: special case: push strings for textual string content + B32 did_content = 0; + if(!did_content && array_is_string && !no_string) + { + U64 element_size = e_type_byte_size_from_key(direct_type_key); + did_content = 1; + U64 string_buffer_size = Clamp(1, array_count, 1024); + U8 *string_buffer = push_array(arena, U8, string_buffer_size); + switch(eval.irtree.mode) + { + default:{}break; + case E_Mode_Offset: + { + U64 string_memory_addr = eval.value.u64; + B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+string_buffer_size)); + }break; + case E_Mode_Value: + { + MemoryCopy(string_buffer, &eval.value.u512[0], Min(string_buffer_size, sizeof(eval.value))); + }break; + } + String8 string = {0}; + switch(element_size) + { + default:{string = str8_cstring_capped(string_buffer, string_buffer + string_buffer_size);}break; + case 2: {string = str8_from_16(arena, str16_cstring_capped(string_buffer, string_buffer + string_buffer_size));}break; + case 4: {string = str8_from_32(arena, str32_cstring((U32 *)string_buffer));}break; + } + String8 string_escaped = ev_escaped_from_raw_string(arena, string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; + space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } + str8_list_push(arena, out, string_escaped); + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } + } + + // rjf: if we did not do any special content, then go to the regular arrays/structs/sets case + if(!did_content) + { + goto arrays_and_sets_and_structs; + } + }break; + + //- rjf: non-string-arrays/structs/sets + case E_TypeKind_Struct: + case E_TypeKind_Union: + case E_TypeKind_Class: + case E_TypeKind_IncompleteStruct: + case E_TypeKind_IncompleteUnion: + case E_TypeKind_IncompleteClass: + case E_TypeKind_Set: + arrays_and_sets_and_structs: + { + // rjf: unpack + E_IRTreeAndType irtree = eval.irtree; + E_LookupRule *lookup_rule = eval.lookup_rule_tag.rule; + E_Expr *lookup_rule_tag = eval.lookup_rule_tag.tag; + if(lookup_rule == &e_lookup_rule__default) + { + lookup_rule = root_eval.lookup_rule_tag.rule; + lookup_rule_tag = root_eval.lookup_rule_tag.tag; + } + E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); + U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); + String8 opener_string = str8_lit("{"); + String8 closer_string = str8_lit("}"); + if(lookup_info.idxed_expr_count > lookup_info.named_expr_count) + { + opener_string = str8_lit("["); + closer_string = str8_lit("]"); + } + + // rjf: opener ({, [) + { + str8_list_push(arena, out, opener_string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, opener_string).x; } // rjf: build contents if(depth < 4) { - for(U64 idx = 0; idx < array_count && max_size > space_taken; idx += 1) + B32 is_first = 1; + for(U64 idx = 0; idx < total_possible_child_count && max_size > space_taken; idx += 1) { - E_Expr *element_expr = e_expr_ref_array_index(scratch.arena, eval.expr, idx); - E_Eval element_eval = e_eval_from_expr(scratch.arena, element_expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, element_eval, 0, view_rules, out); - if(idx+1 < array_count) + E_Expr *expr = &e_expr_nil; + String8 expr_string = {0}; + lookup_rule->range(scratch.arena, eval.exprs.last, lookup_rule_tag, filter, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); + if(expr != &e_expr_nil) { - String8 comma = str8_lit(", "); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; - str8_list_push(arena, out, comma); - } - if(space_taken > max_size && idx+1 < array_count) - { - String8 ellipses = str8_lit("..."); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - str8_list_push(arena, out, ellipses); + if(!is_first) + { + String8 comma = str8_lit(", "); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; + str8_list_push(arena, out, comma); + } + is_first = 0; + E_Eval child_eval = e_eval_from_expr(scratch.arena, expr); + space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_eval, child_eval, out); + if(space_taken > max_size && idx+1 < total_possible_child_count) + { + String8 ellipses = str8_lit(", ..."); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; + str8_list_push(arena, out, ellipses); + } } } } @@ -9666,77 +10839,13 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; } - // rjf: ] + // rjf: closer (}, ]) { - String8 bracket = str8_lit("]"); - str8_list_push(arena, out, bracket); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, bracket).x; + str8_list_push(arena, out, closer_string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, closer_string).x; } - } - }break; - - //- rjf: structs - case E_TypeKind_Struct: - case E_TypeKind_Union: - case E_TypeKind_Class: - case E_TypeKind_IncompleteStruct: - case E_TypeKind_IncompleteUnion: - case E_TypeKind_IncompleteClass: - { - // rjf: open brace - { - String8 brace = str8_lit("{"); - str8_list_push(arena, out, brace); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, brace).x; - } - - // rjf: content - if(depth < 4) - { - E_MemberArray data_members = e_type_data_members_from_key__cached(e_type_unwrap(eval.type_key)); - for(U64 member_idx = 0; member_idx < data_members.count && max_size > space_taken; member_idx += 1) - { - E_Member *mem = &data_members.v[member_idx]; - E_Expr *dot_expr = e_expr_ref_member_access(scratch.arena, eval.expr, mem->name); - E_Expr *dot_expr_resolved = ev_resolved_from_expr(scratch.arena, dot_expr, view_rules); - E_Eval dot_eval = e_eval_from_expr(scratch.arena, dot_expr_resolved); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, dot_eval, 0, view_rules, out); - if(member_idx+1 < data_members.count) - { - String8 comma = str8_lit(", "); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; - str8_list_push(arena, out, comma); - } - if(space_taken > max_size && member_idx+1 < data_members.count) - { - String8 ellipses = str8_lit("..."); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - str8_list_push(arena, out, ellipses); - } - } - } - else - { - String8 ellipses = str8_lit("..."); - str8_list_push(arena, out, ellipses); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - } - - // rjf: close brace - { - String8 brace = str8_lit("}"); - str8_list_push(arena, out, brace); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, brace).x; - } - }break; - - //- rjf: collections - case E_TypeKind_Collection: - { - String8 placeholder = str8_lit("{...}"); - str8_list_push(arena, out, placeholder); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, placeholder).x; - }break; + }break; + } } scratch_end(scratch); @@ -9745,11 +10854,11 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } internal String8 -rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval, E_Member *member, EV_ViewRuleList *view_rules) +rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval) { Temp scratch = scratch_begin(&arena, 1); String8List strs = {0}; - rd_append_value_strings_from_eval(scratch.arena, flags, default_radix, font, font_size, max_size, 0, eval, member, view_rules, &strs); + rd_append_value_strings_from_eval(scratch.arena, filter, flags, default_radix, font, font_size, max_size, 0, eval, eval, &strs); String8 result = str8_list_join(arena, &strs, 0); scratch_end(scratch); return result; @@ -9759,43 +10868,43 @@ rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, //~ rjf: Hover Eval internal void -rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string) +rd_set_hover_eval(Vec2F32 pos, String8 string, String8 view_rules) { - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window->hover_eval_last_frame_idx+1 < rd_state->frame_index && + RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + if(ws->hover_eval_lastt_us < rd_state->time_in_us && ui_key_match(ui_active_key(UI_MouseButtonKind_Left), ui_key_zero()) && ui_key_match(ui_active_key(UI_MouseButtonKind_Middle), ui_key_zero()) && ui_key_match(ui_active_key(UI_MouseButtonKind_Right), ui_key_zero())) { - B32 is_new_string = !str8_match(window->hover_eval_string, string, 0); + B32 is_new_string = (!str8_match(ws->hover_eval_string, string, 0) || + !str8_match(ws->hover_eval_view_rules, view_rules, 0)); if(is_new_string) { - window->hover_eval_first_frame_idx = window->hover_eval_last_frame_idx = rd_state->frame_index; - arena_clear(window->hover_eval_arena); - window->hover_eval_string = push_str8_copy(window->hover_eval_arena, string); - window->hover_eval_file_path = push_str8_copy(window->hover_eval_arena, file_path); - window->hover_eval_file_pt = pt; - window->hover_eval_vaddr = vaddr; - window->hover_eval_focused = 0; + ws->hover_eval_firstt_us = ws->hover_eval_lastt_us = rd_state->time_in_us; + arena_clear(ws->hover_eval_arena); + ws->hover_eval_string = push_str8_copy(ws->hover_eval_arena, string); + ws->hover_eval_view_rules = push_str8_copy(ws->hover_eval_arena, view_rules); + ws->hover_eval_focused = 0; } - window->hover_eval_spawn_pos = pos; - window->hover_eval_last_frame_idx = rd_state->frame_index; + ws->hover_eval_spawn_pos = pos; + ws->hover_eval_lastt_us = rd_state->time_in_us; } } //////////////////////////////// -//~ rjf: Auto-Complete Lister +//~ rjf: Lister Functions internal void -rd_autocomp_lister_item_chunk_list_push(Arena *arena, RD_AutoCompListerItemChunkList *list, U64 cap, RD_AutoCompListerItem *item) +rd_lister_item_chunk_list_push(Arena *arena, RD_ListerItemChunkList *list, U64 cap, RD_ListerItem *item) { - RD_AutoCompListerItemChunkNode *n = list->last; + RD_ListerItemChunkNode *n = list->last; if(n == 0 || n->count >= n->cap) { - n = push_array(arena, RD_AutoCompListerItemChunkNode, 1); + n = push_array(arena, RD_ListerItemChunkNode, 1); SLLQueuePush(list->first, list->last, n); n->cap = cap; - n->v = push_array_no_zero(arena, RD_AutoCompListerItem, n->cap); + n->v = push_array_no_zero(arena, RD_ListerItem, n->cap); list->chunk_count += 1; } MemoryCopyStruct(&n->v[n->count], item); @@ -9803,23 +10912,23 @@ rd_autocomp_lister_item_chunk_list_push(Arena *arena, RD_AutoCompListerItemChunk list->total_count += 1; } -internal RD_AutoCompListerItemArray -rd_autocomp_lister_item_array_from_chunk_list(Arena *arena, RD_AutoCompListerItemChunkList *list) +internal RD_ListerItemArray +rd_lister_item_array_from_chunk_list(Arena *arena, RD_ListerItemChunkList *list) { - RD_AutoCompListerItemArray array = {0}; + RD_ListerItemArray array = {0}; array.count = list->total_count; - array.v = push_array_no_zero(arena, RD_AutoCompListerItem, array.count); + array.v = push_array_no_zero(arena, RD_ListerItem, array.count); U64 idx = 0; - for(RD_AutoCompListerItemChunkNode *n = list->first; n != 0; n = n->next) + for(RD_ListerItemChunkNode *n = list->first; n != 0; n = n->next) { - MemoryCopy(array.v+idx, n->v, sizeof(RD_AutoCompListerItem)*n->count); + MemoryCopy(array.v+idx, n->v, sizeof(RD_ListerItem)*n->count); idx += n->count; } return array; } internal int -rd_autocomp_lister_item_qsort_compare(RD_AutoCompListerItem *a, RD_AutoCompListerItem *b) +rd_lister_item_qsort_compare(RD_ListerItem *a, RD_ListerItem *b) { int result = 0; if(a->group < b->group) @@ -9830,11 +10939,27 @@ rd_autocomp_lister_item_qsort_compare(RD_AutoCompListerItem *a, RD_AutoCompListe { result = +1; } - else if(a->matches.count > b->matches.count) + else if(a->display_name__matches.count > b->display_name__matches.count) { result = -1; } - else if(a->matches.count < b->matches.count) + else if(a->display_name__matches.count < b->display_name__matches.count) + { + result = +1; + } + else if(a->description__matches.count > b->description__matches.count) + { + result = -1; + } + else if(a->description__matches.count < b->description__matches.count) + { + result = +1; + } + else if(a->kind_name__matches.count > b->kind_name__matches.count) + { + result = -1; + } + else if(a->kind_name__matches.count < b->kind_name__matches.count) { result = +1; } @@ -9854,13 +10979,616 @@ rd_autocomp_lister_item_qsort_compare(RD_AutoCompListerItem *a, RD_AutoCompListe } internal void -rd_autocomp_lister_item_array_sort__in_place(RD_AutoCompListerItemArray *array) +rd_lister_item_array_sort__in_place(RD_ListerItemArray *array) { - quick_sort(array->v, array->count, sizeof(array->v[0]), rd_autocomp_lister_item_qsort_compare); + quick_sort(array->v, array->count, sizeof(array->v[0]), rd_lister_item_qsort_compare); +} + +internal RD_ListerItemArray +rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, String8 needle, U64 cursor_off) +{ + Temp scratch = scratch_begin(&arena, 1); + DI_Scope *di_scope = di_scope_open(); + RD_ListerFlags flags = regs->lister_flags; + String8 needle_path = rd_lister_query_path_from_input_string_off(needle, cursor_off); + RD_ListerItemChunkList item_list = {0}; + DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena); + DI_KeyArray dbgi_keys = di_key_array_from_list(scratch.arena, &dbgi_keys_list); + +#if 0 // TODO(rjf): @cfg (lister) + + ////////////////////////// + //- rjf: determine all ctx filters + // + String8List ctx_filter_strings = {0}; + { + switch(regs->reg_slot) + { + default:{}break; + case RD_RegSlot_Cursor: + { + if(!txt_pt_match(regs->cursor, regs->mark)) + { + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$text_rng,"); + } + else + { + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$text_pt,"); + } + }break; + case RD_RegSlot_Cfg: + { + RD_Cfg *cfg = rd_cfg_from_id(regs->cfg); + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$%S,", cfg->string); + }break; + case RD_RegSlot_View: + { + RD_Cfg *view = rd_cfg_from_id(regs->view); + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$tab,"); + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$%S,", view->string); + String8 view_expr = rd_expr_from_cfg(view); + String8 view_file_path = rd_file_path_from_eval_string(scratch.arena, view_expr); + if(view_file_path.size != 0) + { + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$file,"); + } + } // fallthrough; + case RD_RegSlot_Panel: + { + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$panel,"); + }break; + } + } + + ////////////////////////// + //- rjf: grab rdis + // + U64 rdis_count = dbgi_keys.count; + RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); + { + for(U64 idx = 0; idx < rdis_count; idx += 1) + { + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], 0); + RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); + rdis[idx] = rdi; + } + } + + //- rjf: gather locals + if(flags & RD_ListerFlag_Locals) + { + CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_regs()->unwind_count); + CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); + U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + E_String2NumMap *locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); + E_String2NumMap *member_map = d_query_cached_member_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); + for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) + { + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, n->string); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = n->string, + .kind_name = str8_lit("Local"), + .display_name = n->string, + .display_name__matches = display_name__matches); + } + } + for(E_String2NumMapNode *n = member_map->first; n != 0; n = n->order_next) + { + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, n->string); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = n->string, + .kind_name = str8_lit("Local (Member)"), + .display_name = n->string, + .display_name__matches = display_name__matches); + } + } + } + + //- rjf: gather registers + if(flags & RD_ListerFlag_Registers) + { + CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + Arch arch = thread->arch; + U64 reg_names_count = regs_reg_code_count_from_arch(arch); + U64 alias_names_count = regs_alias_code_count_from_arch(arch); + String8 *reg_names = regs_reg_code_string_table_from_arch(arch); + String8 *alias_names = regs_alias_code_string_table_from_arch(arch); + for(U64 idx = 0; idx < reg_names_count; idx += 1) + { + if(reg_names[idx].size != 0) + { + String8 display_name = reg_names[idx]; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Register"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + for(U64 idx = 0; idx < alias_names_count; idx += 1) + { + if(alias_names[idx].size != 0) + { + String8 display_name = alias_names[idx]; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Reg. Alias"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + } + + //- rjf: gather view rules + if(flags & RD_ListerFlag_ViewRules) + { + for(U64 slot_idx = 0; slot_idx < d_state->view_rule_spec_table_size; slot_idx += 1) + { + for(D_ViewRuleSpec *spec = d_state->view_rule_spec_table[slot_idx]; spec != 0 && spec != &d_nil_core_view_rule_spec; spec = spec->hash_next) + { + String8 display_name = spec->info.string; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + String8 description = spec->info.description; + FuzzyMatchRangeList description__matches = fuzzy_match_find(arena, needle, description); + if(display_name__matches.count == display_name__matches.needle_part_count || + description__matches.count == description__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("View Rule"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .description = description, + .description__matches = description__matches); + } + } + } + } + + //- rjf: gather members + if(flags & RD_ListerFlag_Members) + { + // TODO(rjf) + } + + //- rjf: gather globals + if(flags & RD_ListerFlag_Globals && needle.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_GlobalVariables, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Global"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather thread locals + if(flags & RD_ListerFlag_ThreadLocals && needle.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_ThreadVariables, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Thread Local"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather procedures + if(flags & RD_ListerFlag_Procedures && needle.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_Procedures, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Procedure"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather types + if(flags & RD_ListerFlag_Types && needle.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_UDTs, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Type"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather languages + if(flags & RD_ListerFlag_Languages) + { + for EachNonZeroEnumVal(TXT_LangKind, lang) + { + String8 display_name = txt_extension_from_lang_kind(lang); + if(display_name.size != 0) + { + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Language"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + } + + //- rjf: gather architectures + if(flags & RD_ListerFlag_Architectures) + { + for EachNonZeroEnumVal(Arch, arch) + { + String8 display_name = string_from_arch(arch); + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Architecture"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + + //- rjf: gather tex2dformats + if(flags & RD_ListerFlag_Tex2DFormats) + { + for EachEnumVal(R_Tex2DFormat, fmt) + { + String8 display_name = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("2D Texture Format"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + + //- rjf: gather view rule params +#if 0 // TODO(rjf): @cfg (lister) + if(flags & RD_ListerFlag_ViewRuleParams) + { + for(String8Node *n = strings.first; n != 0; n = n->next) + { + String8 display_name = n->string; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("View Rule Parameter"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } +#endif + + //- rjf: gather files + if(flags & RD_ListerFlag_Files) + { + // rjf: find containing directory in needle_path + String8 dir_str_in_input = {0}; + for(U64 i = 0; i < needle_path.size; i += 1) + { + String8 substr1 = str8_substr(needle_path, r1u64(i, i+1)); + String8 substr2 = str8_substr(needle_path, r1u64(i, i+2)); + String8 substr3 = str8_substr(needle_path, r1u64(i, i+3)); + if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(needle_path, r1u64(i, needle_path.size)); + } + else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(needle_path, r1u64(i-1, needle_path.size)); + } + else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(needle_path, r1u64(i, needle_path.size)); + } + else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(needle_path, r1u64(i, needle_path.size)); + } + if(dir_str_in_input.size != 0) + { + break; + } + } + + // rjf: use needle_path string to form various parts of search space + String8 prefix = {0}; + String8 path = {0}; + String8 search = {0}; + if(dir_str_in_input.size != 0) + { + String8 dir = dir_str_in_input; + U64 one_past_last_slash = dir.size; + for(U64 i = 0; i < dir_str_in_input.size; i += 1) + { + if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') + { + one_past_last_slash = i+1; + } + } + dir.size = one_past_last_slash; + path = dir; + search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); + prefix = str8_substr(needle_path, r1u64(0, path.str - needle_path.str)); + } + + // rjf: get current files, filtered + if(dir_str_in_input.size != 0) + { + B32 allow_dirs = 1; + OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); + for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) + { + FuzzyMatchRangeList match_ranges = fuzzy_match_find(arena, search, info.name); + B32 fits_search = (match_ranges.count == match_ranges.needle_part_count); + B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); + if(fits_search && fits_dir_only) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = info.name, + .kind_name = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"), + .display_name = info.name, + .icon_kind = info.props.flags & FilePropertyFlag_IsFolder ? RD_IconKind_FolderClosedFilled : RD_IconKind_FileOutline, + .display_name__matches = match_ranges, + .flags = RD_ListerItemFlag_IsNonCode); + } + } + os_file_iter_end(it); + } + } + + //- rjf: gather commands + if(flags & RD_ListerFlag_Commands) + { + for EachNonZeroEnumVal(RD_CmdKind, k) + { + RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; + B32 included_by_filter_string = 0; + for(String8Node *n = ctx_filter_strings.first; n != 0; n = n->next) + { + B32 n_match = (str8_find_needle(info->ctx_filter, 0, n->string, 0) < info->ctx_filter.size); + if(n_match) + { + included_by_filter_string = 1; + break; + } + } + if(ctx_filter_strings.node_count == 0 || included_by_filter_string) + { + String8 cmd_display_name = info->display_name; + String8 cmd_desc = info->description; + String8 cmd_tags = info->search_tags; + FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, cmd_display_name); + FuzzyMatchRangeList desc_matches = fuzzy_match_find(arena, needle, cmd_desc); + FuzzyMatchRangeList tags_matches = fuzzy_match_find(arena, needle, cmd_tags); + if(name_matches.count == name_matches.needle_part_count || + desc_matches.count == name_matches.needle_part_count || + tags_matches.count > 0 || + name_matches.needle_part_count == 0) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .icon_kind = info->icon_kind, + .string = info->string, + .kind_name = str8_lit("Command"), + .display_name = cmd_display_name, + .display_name__matches = name_matches, + .description = cmd_desc, + .description__matches = desc_matches, + .flags = RD_ListerItemFlag_IsNonCode|RD_ListerItemFlag_Bindings); + } + } + } + } + + //- rjf: gather settings + if(flags & RD_ListerFlag_Settings) + { +#if 0 // TODO(rjf): @cfg (lister) + String8List schema_strings = {0}; + + // rjf: push schema for view + { + RD_Cfg *view = rd_cfg_from_id(regs->view); + String8 view_name = view->string; + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view_name); + str8_list_push(scratch.arena, &schema_strings, view_rule_info->params_schema); + } + + // rjf: for each schema, gather parameters + for(String8Node *n = schema_strings.first; n != 0; n = n->next) + { + MD_Node *schema = md_tree_from_string(scratch.arena, n->string)->first; + for MD_EachNode(param, schema->first) + { + RD_VocabInfo *param_vocab_info = rd_vocab_info_from_code_name(param->string); + String8 name = param_vocab_info->display_name; + RD_IconKind icon_kind = param_vocab_info->icon_kind; + FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, name); + if(name_matches.count == name_matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .icon_kind = icon_kind, + .string = param->string, + .kind_name = str8_lit("Setting"), + .display_name = name, + .display_name__matches = name_matches, + .flags = RD_ListerItemFlag_IsNonCode); + } + } + } +#endif + } + + //- rjf: gather system processes + if(flags & RD_ListerFlag_SystemProcesses) + { + U32 this_process_pid = os_get_process_info()->pid; + DMN_ProcessIter iter = {0}; + dmn_process_iter_begin(&iter); + for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) + { + if(info.pid == this_process_pid) + { + continue; + } + String8 name = push_str8f(scratch.arena, "%S (PID: %i)", info.name, info.pid); + FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, name); + if(name_matches.count == name_matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .icon_kind = RD_IconKind_Threads, + .string = name, + .kind_name = str8_lit("System Process"), + .display_name = name, + .display_name__matches = name_matches, + .flags = RD_ListerItemFlag_IsNonCode); + } + } + dmn_process_iter_end(&iter); + } + + //- rjf: lister item list -> sorted array + RD_ListerItemArray item_array = rd_lister_item_array_from_chunk_list(arena, &item_list); + rd_lister_item_array_sort__in_place(&item_array); +#endif + RD_ListerItemArray item_array = {0}; + di_scope_close(di_scope); + scratch_end(scratch); + return item_array; +} + +internal U64 +rd_hash_from_lister_item(RD_ListerItem *item) +{ + U64 item_hash = 5381; + item_hash = d_hash_from_seed_string(item_hash, item->string); + item_hash = d_hash_from_seed_string(item_hash, item->kind_name); + item_hash = d_hash_from_seed_string(item_hash, str8_struct(&item->group)); + return item_hash; } internal String8 -rd_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off) +rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off) { U64 word_start_off = 0; for(U64 off = 0; off < input.size && off < cursor_off; off += 1) @@ -9875,7 +11603,7 @@ rd_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off) } internal String8 -rd_autocomp_query_path_from_input_string_off(String8 input, U64 cursor_off) +rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off) { // rjf: find start of path U64 path_start_off = 0; @@ -9908,10 +11636,12 @@ rd_autocomp_query_path_from_input_string_off(String8 input, U64 cursor_off) return path; } -internal RD_AutoCompListerParams -rd_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off) +#if 0 // TODO(rjf): @cfg (lister) + +internal RD_ListerParams +rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off) { - RD_AutoCompListerParams params = {0}; + RD_ListerParams params = {0}; { Temp scratch = scratch_begin(&arena, 1); @@ -10019,15 +11749,15 @@ rd_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 stri for MD_EachNode(child, schema_node->first) { if(0){} - else if(str8_match(child->string, str8_lit("expr"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_AutoCompListerFlag_Locals;} - else if(str8_match(child->string, str8_lit("member"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_AutoCompListerFlag_Members;} - else if(str8_match(child->string, str8_lit("lang"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_AutoCompListerFlag_Languages;} - else if(str8_match(child->string, str8_lit("arch"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_AutoCompListerFlag_Architectures;} - else if(str8_match(child->string, str8_lit("tex2dformat"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_AutoCompListerFlag_Tex2DFormats;} + else if(str8_match(child->string, str8_lit("expr"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Locals;} + else if(str8_match(child->string, str8_lit("member"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Members;} + else if(str8_match(child->string, str8_lit("lang"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Languages;} + else if(str8_match(child->string, str8_lit("arch"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Architectures;} + else if(str8_match(child->string, str8_lit("tex2dformat"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Tex2DFormats;} else if(child->flags & (MD_NodeFlag_StringSingleQuote|MD_NodeFlag_StringDoubleQuote|MD_NodeFlag_StringTick)) { str8_list_push(arena, ¶ms.strings, child->string); - params.flags |= RD_AutoCompListerFlag_ViewRuleParams; + params.flags |= RD_ListerFlag_ViewRuleParams; } } break; @@ -10051,176 +11781,56 @@ rd_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 stri } internal void -rd_set_autocomp_lister_query(UI_Key root_key, RD_AutoCompListerParams *params, String8 input, U64 cursor_off) +rd_set_autocomp_lister_query_(RD_ListerParams *params) { - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(cursor_off != window->autocomp_cursor_off) + RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + arena_clear(ws->lister_arena); + ws->lister_regs = rd_regs_copy(ws->lister_arena, rd_regs()); + MemoryCopyStruct(&ws->lister_params, params); + ws->lister_params.strings = str8_list_copy(ws->lister_arena, &ws->lister_params.strings); + if(!(params->flags & RD_ListerFlag_LineEdit)) { - window->autocomp_input_dirty = 1; - window->autocomp_cursor_off = cursor_off; + ws->lister_input_size = Min(params->input.size, sizeof(ws->lister_input_buffer)); + MemoryCopy(ws->lister_input_buffer, params->input.str, ws->lister_input_size); } - if(!ui_key_match(window->autocomp_root_key, root_key)) - { - window->autocomp_num_visible_rows_t = 0; - window->autocomp_open_t = 0; - } - if(window->autocomp_last_frame_idx+1 < rd_state->frame_index) - { - window->autocomp_num_visible_rows_t = 0; - window->autocomp_open_t = 0; - } - window->autocomp_root_key = root_key; - arena_clear(window->autocomp_lister_params_arena); - MemoryCopyStruct(&window->autocomp_lister_params, params); - window->autocomp_lister_params.strings = str8_list_copy(window->autocomp_lister_params_arena, &window->autocomp_lister_params.strings); - window->autocomp_lister_input_size = Min(input.size, sizeof(window->autocomp_lister_input_buffer)); - MemoryCopy(window->autocomp_lister_input_buffer, input.str, window->autocomp_lister_input_size); - window->autocomp_last_frame_idx = rd_state->frame_index; + ws->lister_last_frame_idx = rd_state->frame_index; } -//////////////////////////////// -//~ rjf: Search Strings +#endif internal void -rd_set_search_string(String8 string) +rd_set_autocomp_lister_query_(RD_Regs *regs) { - arena_clear(rd_state->string_search_arena); - rd_state->string_search_string = push_str8_copy(rd_state->string_search_arena, string); -} - -internal String8 -rd_push_search_string(Arena *arena) -{ - String8 result = push_str8_copy(arena, rd_state->string_search_string); - return result; + RD_Cfg *window_cfg = rd_cfg_from_id(regs->window); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + if(ws->autocomp_lister == 0) + { + Arena *arena = arena_alloc(); + ws->autocomp_lister = push_array(arena, RD_Lister, 1); + ws->autocomp_lister->arena = arena; + } + Arena *arena = ws->autocomp_lister->arena; + arena_clear(arena); + ws->autocomp_lister = push_array(arena, RD_Lister, 1); + ws->autocomp_lister->arena = arena; + ws->autocomp_lister->regs = rd_regs_copy(arena, regs); + ws->autocomp_lister->input_string_size = Min(regs->string.size, sizeof(ws->autocomp_lister->input_buffer)); + MemoryCopy(ws->autocomp_lister->input_buffer, regs->string.str, ws->autocomp_lister->input_string_size); + ws->autocomp_lister->input_cursor = regs->cursor; + ws->autocomp_lister->input_mark = regs->mark; + ws->autocomp_lister_last_frame_idx = rd_state->frame_index; } //////////////////////////////// //~ rjf: Colors, Fonts, Config -//- rjf: keybindings - -internal OS_Key -rd_os_key_from_cfg_string(String8 string) -{ - OS_Key result = OS_Key_Null; - { - for(OS_Key key = OS_Key_Null; key < OS_Key_COUNT; key = (OS_Key)(key+1)) - { - if(str8_match(string, os_g_key_cfg_string_table[key], StringMatchFlag_CaseInsensitive)) - { - result = key; - break; - } - } - } - return result; -} - -internal void -rd_clear_bindings(void) -{ - arena_clear(rd_state->key_map_arena); - rd_state->key_map_table_size = 1024; - rd_state->key_map_table = push_array(rd_state->key_map_arena, RD_KeyMapSlot, rd_state->key_map_table_size); - rd_state->key_map_total_count = 0; -} - -internal RD_BindingList -rd_bindings_from_name(Arena *arena, String8 name) -{ - RD_BindingList result = {0}; - U64 hash = d_hash_from_string(name); - U64 slot = hash%rd_state->key_map_table_size; - for(RD_KeyMapNode *n = rd_state->key_map_table[slot].first; n != 0; n = n->hash_next) - { - if(str8_match(n->name, name, 0)) - { - RD_BindingNode *node = push_array(arena, RD_BindingNode, 1); - node->binding = n->binding; - SLLQueuePush(result.first, result.last, node); - result.count += 1; - } - } - return result; -} - -internal void -rd_bind_name(String8 name, RD_Binding binding) -{ - if(binding.key != OS_Key_Null) - { - U64 hash = d_hash_from_string(name); - U64 slot = hash%rd_state->key_map_table_size; - RD_KeyMapNode *existing_node = 0; - for(RD_KeyMapNode *n = rd_state->key_map_table[slot].first; n != 0; n = n->hash_next) - { - if(str8_match(n->name, name, 0) && n->binding.key == binding.key && n->binding.modifiers == binding.modifiers) - { - existing_node = n; - break; - } - } - if(existing_node == 0) - { - RD_KeyMapNode *n = rd_state->free_key_map_node; - if(n == 0) - { - n = push_array(rd_state->arena, RD_KeyMapNode, 1); - } - else - { - rd_state->free_key_map_node = rd_state->free_key_map_node->hash_next; - } - n->name = push_str8_copy(rd_state->arena, name); - n->binding = binding; - DLLPushBack_NP(rd_state->key_map_table[slot].first, rd_state->key_map_table[slot].last, n, hash_next, hash_prev); - rd_state->key_map_total_count += 1; - } - } -} - -internal void -rd_unbind_name(String8 name, RD_Binding binding) -{ - U64 hash = d_hash_from_string(name); - U64 slot = hash%rd_state->key_map_table_size; - for(RD_KeyMapNode *n = rd_state->key_map_table[slot].first, *next = 0; n != 0; n = next) - { - next = n->hash_next; - if(str8_match(n->name, name, 0) && n->binding.key == binding.key && n->binding.modifiers == binding.modifiers) - { - DLLRemove_NP(rd_state->key_map_table[slot].first, rd_state->key_map_table[slot].last, n, hash_next, hash_prev); - n->hash_next = rd_state->free_key_map_node; - rd_state->free_key_map_node = n; - rd_state->key_map_total_count -= 1; - } - } -} - -internal String8List -rd_cmd_name_list_from_binding(Arena *arena, RD_Binding binding) -{ - String8List result = {0}; - for(U64 idx = 0; idx < rd_state->key_map_table_size; idx += 1) - { - for(RD_KeyMapNode *n = rd_state->key_map_table[idx].first; n != 0; n = n->hash_next) - { - if(n->binding.key == binding.key && n->binding.modifiers == binding.modifiers) - { - str8_list_push(arena, &result, n->name); - } - } - } - return result; -} - //- rjf: colors internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color) { - return rd_state->cfg_theme.colors[color]; + return rd_state->theme->colors[color]; } internal RD_ThemeColor @@ -10253,7 +11863,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as local if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 local_num = e_num_from_string(e_parse_ctx->locals_map, string); + U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, string); if(local_num != 0) { mapped = 1; @@ -10264,7 +11874,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as member if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 member_num = e_num_from_string(e_parse_ctx->member_map, string); + U64 member_num = e_num_from_string(e_parse_state->ctx->member_map, string); if(member_num != 0) { mapped = 1; @@ -10275,7 +11885,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register if(!mapped) { - U64 reg_num = e_num_from_string(e_parse_ctx->regs_map, string); + U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, string); if(reg_num != 0) { mapped = 1; @@ -10286,7 +11896,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register alias if(!mapped) { - U64 alias_num = e_num_from_string(e_parse_ctx->reg_alias_map, string); + U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, string); if(alias_num != 0) { mapped = 1; @@ -10342,61 +11952,91 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str return color; } -//- rjf: code -> palette - -internal UI_Palette * -rd_palette_from_code(RD_PaletteCode code) -{ - RD_Window *window = rd_window_from_handle(rd_regs()->window); - UI_Palette *result = &window->cfg_palettes[code]; - return result; -} - //- rjf: fonts/sizes internal FNT_Tag rd_font_from_slot(RD_FontSlot slot) { - FNT_Tag result = rd_state->cfg_font_tags[slot]; + // rjf: determine key name for this font slot + String8 key = {0}; + switch(slot) + { + default:{}break; + case RD_FontSlot_Main:{key = str8_lit("main_font");}break; + case RD_FontSlot_Code:{key = str8_lit("code_font");}break; + } + + // rjf: determine font name + String8 font_name = {0}; + if(key.size != 0) + { + RD_Cfg *seed_cfg = &rd_nil_cfg; + if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_id(rd_regs()->view); } + if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_id(rd_regs()->panel); } + if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_id(rd_regs()->window); } + for(RD_Cfg *cfg = seed_cfg; cfg != &rd_nil_cfg; cfg = cfg->parent) + { + RD_Cfg *font_root = rd_cfg_child_from_string(cfg, key); + if(font_root != &rd_nil_cfg) + { + font_name = font_root->first->string; + break; + } + } + } + + // rjf: map name -> tag + FNT_Tag result = {0}; + if(font_name.size == 0) + { + switch(slot) + { + default: + case RD_FontSlot_Main: {result = fnt_tag_from_static_data_string(&rd_default_main_font_bytes);}break; + case RD_FontSlot_Code: {result = fnt_tag_from_static_data_string(&rd_default_code_font_bytes);}break; + case RD_FontSlot_Icons:{result = fnt_tag_from_static_data_string(&rd_icon_font_bytes);}break; + } + } + else + { + // TODO(rjf): need to handle "system font names" here. + result = fnt_tag_from_path(font_name); + } return result; } internal F32 rd_font_size_from_slot(RD_FontSlot slot) { - F32 result = 0; - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - F32 dpi = os_dpi_from_window(ws->os); - if(dpi != ws->last_dpi) - { - F32 old_dpi = ws->last_dpi; - F32 new_dpi = dpi; - ws->last_dpi = dpi; - S32 *pt_sizes[] = - { - &ws->setting_vals[RD_SettingCode_MainFontSize].s32, - &ws->setting_vals[RD_SettingCode_CodeFontSize].s32, - }; - for(U64 idx = 0; idx < ArrayCount(pt_sizes); idx += 1) - { - F32 ratio = pt_sizes[idx][0] / old_dpi; - F32 new_pt_size = ratio*new_dpi; - pt_sizes[idx][0] = (S32)new_pt_size; - } - } + F32 result = 11.f; + + // rjf: determine config key based on slot + String8 key = {0}; switch(slot) { - case RD_FontSlot_Code: - { - result = (F32)ws->setting_vals[RD_SettingCode_CodeFontSize].s32; - }break; - default: - case RD_FontSlot_Main: + default:{}break; case RD_FontSlot_Icons: - { - result = (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32; - }break; + case RD_FontSlot_Main:{key = str8_lit("main_font_size");}break; + case RD_FontSlot_Code:{key = str8_lit("code_font_size");}break; } + + // rjf: given key, find setting string + String8 setting_string = rd_setting_from_name(key); + + // rjf: if found, map setting string -> f64; otherwise use the window's monitor's DPI + // based on some default size. + if(setting_string.size) + { + result = (F32)f64_from_str8(setting_string); + } + else + { + RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + F32 dpi = os_dpi_from_window(ws->os); + result = 11.f * (dpi / 96.f); + } + return result; } @@ -10408,584 +12048,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_name(str8_lit("smooth_main_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_main_text"))*FNT_RasterFlag_Hinted);}break; + case RD_FontSlot_Code: {flags = (rd_setting_b32_from_name(str8_lit("smooth_code_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(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_Window *window = rd_window_from_handle(rd_regs()->window); - RD_SettingVal result = {0}; - if(window != 0) - { - result = window->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 -rd_qsort_compare__cfg_string_bindings(RD_StringBindingPair *a, RD_StringBindingPair *b) -{ - return strncmp((char *)a->string.str, (char *)b->string.str, Min(a->string.size, b->string.size)); -} - -internal String8List -rd_cfg_strings_from_gfx(Arena *arena, String8 root_path, RD_CfgSrc source) -{ - ProfBeginFunction(); - local_persist char *spaces = " "; - local_persist char *slashes= "////////////////////////////////////////////////////////////////////////////////"; - String8List strs = {0}; - - //- rjf: write all entities - { - for EachEnumVal(RD_EntityKind, k) - { - RD_EntityKindFlags k_flags = rd_entity_kind_flags_table[k]; - if(!(k_flags & RD_EntityKindFlag_IsSerializedToConfig)) - { - continue; - } - B32 first = 1; - RD_EntityList entities = rd_query_cached_entity_list_with_kind(k); - for(RD_EntityNode *n = entities.first; n != 0; n = n->next) - { - RD_Entity *entity = n->entity; - if(entity->cfg_src != source) - { - continue; - } - if(first) - { - first = 0; - String8 title_name = d_entity_kind_name_lower_plural_table[k]; - str8_list_pushf(arena, &strs, "/// %S %.*s\n\n", - title_name, - (int)Max(0, 79 - (title_name.size + 5)), - slashes); - } - RD_EntityRec rec = {0}; - S64 depth = 0; - for(RD_Entity *e = entity; !rd_entity_is_nil(e); e = rec.next) - { - //- rjf: get next iteration - rec = rd_entity_rec_depth_first_pre(e, entity); - - //- rjf: unpack entity info - typedef U32 EntityInfoFlags; - enum - { - EntityInfoFlag_HasName = (1<<0), - EntityInfoFlag_HasDisabled = (1<<1), - EntityInfoFlag_HasTxtPt = (1<<2), - EntityInfoFlag_HasVAddr = (1<<3), - EntityInfoFlag_HasColor = (1<<4), - EntityInfoFlag_HasChildren = (1<<5), - EntityInfoFlag_HasDebugSubprocesses = (1<<6), - }; - String8 entity_name_escaped = e->string; - // TODO(rjf): @hack - hardcoding in the "EntityKind_Location" here - this is because - // i am assuming an entity *kind* can 'know' about the 'pathness' of a string. this is - // not the case. post-0.9.12 i need to fix this. - if(rd_entity_kind_flags_table[e->kind] & RD_EntityKindFlag_NameIsPath && - (e->kind != RD_EntityKind_Location || e->flags & RD_EntityFlag_HasTextPoint)) - { - Temp scratch = scratch_begin(&arena, 1); - String8 path_normalized = path_normalized_from_string(scratch.arena, e->string); - entity_name_escaped = path_relative_dst_from_absolute_dst_src(arena, path_normalized, root_path); - scratch_end(scratch); - } - else - { - entity_name_escaped = escaped_from_raw_str8(arena, e->string); - } - EntityInfoFlags info_flags = 0; - if(entity_name_escaped.size != 0) { info_flags |= EntityInfoFlag_HasName; } - if(!!e->disabled) { info_flags |= EntityInfoFlag_HasDisabled; } - if(e->flags & RD_EntityFlag_HasTextPoint) { info_flags |= EntityInfoFlag_HasTxtPt; } - if(e->flags & RD_EntityFlag_HasVAddr) { info_flags |= EntityInfoFlag_HasVAddr; } - if(e->flags & RD_EntityFlag_HasColor) { info_flags |= EntityInfoFlag_HasColor; } - if(!rd_entity_is_nil(e->first)) { info_flags |= EntityInfoFlag_HasChildren; } - if(e->debug_subprocesses) { info_flags |= EntityInfoFlag_HasDebugSubprocesses; } - - //- rjf: write entity info - B32 opened_brace = 0; - switch(info_flags) - { - //- rjf: default path -> entity has lots of stuff, so write all info generically - default: - { - opened_brace = 1; - - // rjf: write entity title - str8_list_pushf(arena, &strs, "%S:\n{\n", d_entity_kind_name_lower_table[e->kind]); - - // rjf: write this entity's info - if(entity_name_escaped.size != 0) - { - str8_list_pushf(arena, &strs, "name: \"%S\"\n", entity_name_escaped); - } - if(e->disabled) - { - str8_list_pushf(arena, &strs, "disabled: 1\n"); - } - if(e->debug_subprocesses) - { - str8_list_pushf(arena, &strs, "debug_subprocesses: 1\n"); - } - if(e->flags & RD_EntityFlag_HasColor) - { - Vec4F32 hsva = rd_hsva_from_entity(e); - Vec4F32 rgba = rgba_from_hsva(hsva); - U32 rgba_hex = u32_from_rgba(rgba); - str8_list_pushf(arena, &strs, "color: 0x%x\n", rgba_hex); - } - if(e->flags & RD_EntityFlag_HasTextPoint) - { - str8_list_pushf(arena, &strs, "line: %I64d\n", e->text_point.line); - } - if(e->flags & RD_EntityFlag_HasVAddr) - { - str8_list_pushf(arena, &strs, "vaddr: (0x%I64x)\n", e->vaddr); - } - }break; - - //- rjf: single-line fast-paths - case EntityInfoFlag_HasName: - {str8_list_pushf(arena, &strs, "%S: \"%S\"\n", d_entity_kind_name_lower_table[e->kind], entity_name_escaped);}break; - case EntityInfoFlag_HasName|EntityInfoFlag_HasTxtPt: - {str8_list_pushf(arena, &strs, "%S: (\"%S\":%I64d)\n", d_entity_kind_name_lower_table[e->kind], entity_name_escaped, e->text_point.line);}break; - case EntityInfoFlag_HasVAddr: - {str8_list_pushf(arena, &strs, "%S: (0x%I64x)\n", d_entity_kind_name_lower_table[e->kind], e->vaddr);}break; - - //- rjf: empty - case 0: - {}break; - } - - // rjf: push - depth += rec.push_count; - - // rjf: pop - if(rec.push_count == 0) - { - for(S64 pop_idx = 0; pop_idx < rec.pop_count + opened_brace; pop_idx += 1) - { - if(depth > 0) - { - depth -= 1; - } - str8_list_pushf(arena, &strs, "}\n"); - } - } - - // rjf: separate top-level entities with extra newline - if(rd_entity_is_nil(rec.next) && (rec.pop_count != 0 || n->next == 0)) - { - str8_list_pushf(arena, &strs, "\n"); - } - } - } - } - } - - //- rjf: write exception code filters - if(source == RD_CfgSrc_Project) - { - str8_list_push(arena, &strs, str8_lit("/// exception code filters ////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - str8_list_push(arena, &strs, str8_lit("exception_code_filters:\n")); - str8_list_push(arena, &strs, str8_lit("{\n")); - for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)(CTRL_ExceptionCodeKind_Null+1); - k < CTRL_ExceptionCodeKind_COUNT; - k = (CTRL_ExceptionCodeKind)(k+1)) - { - String8 name = ctrl_exception_code_kind_lowercase_code_string_table[k]; - B32 value = !!(rd_state->ctrl_exception_code_filters[k/64] & (1ull<<(k%64))); - str8_list_pushf(arena, &strs, " %S: %i\n", name, value); - } - str8_list_push(arena, &strs, str8_lit("}\n\n")); - } - - //- rjf: serialize windows - { - B32 first = 1; - for(RD_Window *window = rd_state->first_window; window != 0; window = window->next) - { - if(window->cfg_src != source) - { - continue; - } - if(first) - { - first = 0; - str8_list_push(arena, &strs, str8_lit("/// windows ///////////////////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - } - OS_Handle monitor = os_monitor_from_window(window->os); - String8 monitor_name = os_name_from_monitor(arena, monitor); - RD_Panel *root_panel = window->root_panel; - Rng2F32 rect = os_rect_from_window(window->os); - Vec2F32 size = dim_2f32(rect); - str8_list_push (arena, &strs, str8_lit("window:\n")); - str8_list_push (arena, &strs, str8_lit("{\n")); - str8_list_pushf(arena, &strs, " %s%s%s\n", - root_panel->split_axis == Axis2_X ? "split_x" : "split_y", - os_window_is_fullscreen(window->os) ? " fullscreen" : "", - os_window_is_maximized(window->os) ? " maximized" : ""); - str8_list_pushf(arena, &strs, " monitor: \"%S\"\n", monitor_name); - str8_list_pushf(arena, &strs, " size: (%i %i)\n", (int)size.x, (int)size.y); - str8_list_pushf(arena, &strs, " dpi: %f\n", os_dpi_from_window(window->os)); - for EachEnumVal(RD_SettingCode, code) - { - RD_SettingVal current = window->setting_vals[code]; - if(current.set) - { - str8_list_pushf(arena, &strs, " %S: %i\n", rd_setting_code_lower_string_table[code], current.s32); - } - } - { - RD_PanelRec rec = {0}; - S32 indentation = 2; - String8 indent_str = str8_lit(" "); - str8_list_pushf(arena, &strs, " panels:\n"); - str8_list_pushf(arena, &strs, " {\n"); - for(RD_Panel *p = root_panel; !rd_panel_is_nil(p); p = rec.next) - { - // rjf: get recursion - rec = rd_panel_rec_depth_first_pre(p); - - // rjf: non-root needs pct node - if(p != root_panel) - { - str8_list_pushf(arena, &strs, "%.*s%g:\n", indentation*2, indent_str.str, p->pct_of_parent); - str8_list_pushf(arena, &strs, "%.*s{\n", indentation*2, indent_str.str); - indentation += 1; - } - - // rjf: per-panel options - struct { String8 key; B32 value; } options[] = - { - {str8_lit_comp("tabs_on_bottom"), p->tab_side == Side_Max}, - }; - B32 has_options = 0; - for(U64 op_idx = 0; op_idx < ArrayCount(options); op_idx += 1) - { - if(options[op_idx].value) - { - if(has_options == 0) - { - str8_list_pushf(arena, &strs, "%.*s", indentation*2, indent_str.str); - } - else - { - str8_list_pushf(arena, &strs, " "); - } - has_options = 1; - str8_list_push(arena, &strs, options[op_idx].key); - } - } - if(has_options) - { - str8_list_pushf(arena, &strs, "\n"); - } - - // rjf: views - for(RD_View *view = p->first_tab_view; !rd_view_is_nil(view); view = view->order_next) - { - String8 view_string = view->spec->string; - - // rjf: serialize views - { - str8_list_pushf(arena, &strs, "%.*s", indentation*2, indent_str.str); - - // rjf: serialize view string - str8_list_push(arena, &strs, view_string); - - // rjf: serialize view parameterizations - str8_list_push(arena, &strs, str8_lit(": {")); - if(view == rd_selected_tab_from_panel(p)) - { - str8_list_push(arena, &strs, str8_lit("selected ")); - } - { - if(view->project_path.size != 0) - { - Temp scratch = scratch_begin(&arena, 1); - String8 project_path_absolute = path_normalized_from_string(scratch.arena, view->project_path); - String8 project_path_relative = path_relative_dst_from_absolute_dst_src(scratch.arena, project_path_absolute, root_path); - str8_list_pushf(arena, &strs, "project:{\"%S\"} ", project_path_relative); - scratch_end(scratch); - } - } - if(view->query_string_size != 0) - { - Temp scratch = scratch_begin(&arena, 1); - String8 query_raw = str8(view->query_buffer, view->query_string_size); - { - String8 query_file_path = rd_file_path_from_eval_string(scratch.arena, query_raw); - if(query_file_path.size != 0) - { - query_file_path = path_relative_dst_from_absolute_dst_src(scratch.arena, query_file_path, root_path); - query_raw = push_str8f(scratch.arena, "file:\"%S\"", query_file_path); - } - } - String8 query_sanitized = escaped_from_raw_str8(scratch.arena, query_raw); - str8_list_pushf(arena, &strs, "query:{\"%S\"} ", query_sanitized); - scratch_end(scratch); - } - { - String8 reserved_keys[] = - { - str8_lit("project"), - str8_lit("query"), - str8_lit("selected"), - }; - MD_NodeRec rec = {0}; - MD_Node *params_root = view->params_roots[view->params_read_gen%ArrayCount(view->params_roots)]; - for(MD_Node *n = params_root; - !md_node_is_nil(n); - n = rec.next) - { - rec = md_node_rec_depth_first_pre(n, params_root); - B32 is_reserved_key = 0; - for(U64 idx = 0; idx < ArrayCount(reserved_keys); idx += 1) - { - if(str8_match(n->string, reserved_keys[idx], 0)) - { - is_reserved_key = 1; - break; - } - } - if(is_reserved_key) - { - rec = md_node_rec_depth_first(n, params_root, OffsetOf(MD_Node, next), OffsetOf(MD_Node, next)); - } - if(!is_reserved_key && n != params_root) - { - str8_list_pushf(arena, &strs, "%S", n->string); - if(n->first != &md_nil_node) - { - str8_list_pushf(arena, &strs, ":{"); - } - for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) - { - if(pop_idx == rec.pop_count-1 && rec.next == &md_nil_node) - { - break; - } - str8_list_pushf(arena, &strs, "}"); - } - if(rec.pop_count != 0 || n->next != &md_nil_node) - { - str8_list_pushf(arena, &strs, " "); - } - } - } - } - str8_list_push(arena, &strs, str8_lit("}\n")); - } - } - - // rjf: non-roots need closer - if(p != root_panel && rec.push_count == 0) - { - indentation -= 1; - str8_list_pushf(arena, &strs, "%.*s}\n", indentation*2, indent_str.str); - } - - // rjf: pop - for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) - { - indentation -= 1; - if(pop_idx == rec.pop_count-1 && rec.next == &rd_nil_panel) - { - break; - } - str8_list_pushf(arena, &strs, "%.*s}\n", indentation*2, indent_str.str); - } - } - str8_list_pushf(arena, &strs, " }\n"); - } - str8_list_push (arena, &strs, str8_lit("}\n")); - str8_list_push (arena, &strs, str8_lit("\n")); - } - } - - //- rjf: serialize keybindings - if(source == RD_CfgSrc_User) - { - Temp scratch = scratch_begin(&arena, 1); - String8 indent_str = str8_lit(" "); - U64 string_binding_pair_count = 0; - RD_StringBindingPair *string_binding_pairs = push_array(scratch.arena, RD_StringBindingPair, rd_state->key_map_total_count); - for(U64 idx = 0; - idx < rd_state->key_map_table_size && string_binding_pair_count < rd_state->key_map_total_count; - idx += 1) - { - for(RD_KeyMapNode *n = rd_state->key_map_table[idx].first; - n != 0 && string_binding_pair_count < rd_state->key_map_total_count; - n = n->hash_next) - { - RD_StringBindingPair *pair = string_binding_pairs + string_binding_pair_count; - pair->string = n->name; - pair->binding = n->binding; - string_binding_pair_count += 1; - } - } - quick_sort(string_binding_pairs, string_binding_pair_count, sizeof(RD_StringBindingPair), rd_qsort_compare__cfg_string_bindings); - if(string_binding_pair_count != 0) - { - str8_list_push(arena, &strs, str8_lit("/// keybindings ///////////////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - str8_list_push(arena, &strs, str8_lit("keybindings:\n")); - str8_list_push(arena, &strs, str8_lit("{\n")); - for(U64 idx = 0; idx < string_binding_pair_count; idx += 1) - { - RD_StringBindingPair *pair = string_binding_pairs + idx; - String8List modifiers_strings = os_string_list_from_modifiers(scratch.arena, pair->binding.modifiers); - StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; - String8 event_flags_string = str8_list_join(scratch.arena, &modifiers_strings, &join); - String8 key_string = push_str8_copy(scratch.arena, os_g_key_cfg_string_table[pair->binding.key]); - for(U64 i = 0; i < event_flags_string.size; i += 1) - { - event_flags_string.str[i] = char_to_lower(event_flags_string.str[i]); - } - String8 binding_string = push_str8f(scratch.arena, "%S%s%S", - event_flags_string, - event_flags_string.size > 0 ? " " : "", - key_string); - str8_list_pushf(arena, &strs, " {\"%S\"%.*s%S%.*s}\n", - pair->string, - 40 > pair->string.size ? ((int)(40 - pair->string.size)) : 0, indent_str.str, - binding_string, - 20 > binding_string.size ? ((int)(20 - binding_string.size)) : 0, indent_str.str); - } - str8_list_push(arena, &strs, str8_lit("}\n\n")); - } - scratch_end(scratch); - } - - //- rjf: serialize theme colors - if(source == RD_CfgSrc_User) - { - // rjf: determine if this theme matches an existing preset - B32 is_preset = 0; - RD_ThemePreset matching_preset = RD_ThemePreset_DefaultDark; - { - for(RD_ThemePreset p = (RD_ThemePreset)0; p < RD_ThemePreset_COUNT; p = (RD_ThemePreset)(p+1)) - { - B32 matches_this_preset = 1; - for(RD_ThemeColor c = (RD_ThemeColor)(RD_ThemeColor_Null+1); c < RD_ThemeColor_COUNT; c = (RD_ThemeColor)(c+1)) - { - if(!MemoryMatchStruct(&rd_state->cfg_theme_target.colors[c], &rd_theme_preset_colors_table[p][c])) - { - matches_this_preset = 0; - break; - } - } - if(matches_this_preset) - { - is_preset = 1; - matching_preset = p; - break; - } - } - } - - // rjf: serialize header - String8 indent_str = str8_lit(" "); - str8_list_push(arena, &strs, str8_lit("/// colors ////////////////////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - - // rjf: serialize preset theme - if(is_preset) - { - str8_list_pushf(arena, &strs, "color_preset: \"%S\"\n\n", rd_theme_preset_code_string_table[matching_preset]); - } - - // rjf: serialize non-preset theme - if(!is_preset) - { - str8_list_push(arena, &strs, str8_lit("colors:\n")); - str8_list_push(arena, &strs, str8_lit("{\n")); - for(RD_ThemeColor color = (RD_ThemeColor)(RD_ThemeColor_Null+1); - color < RD_ThemeColor_COUNT; - color = (RD_ThemeColor)(color+1)) - { - String8 color_name = rd_theme_color_cfg_string_table[color]; - Vec4F32 color_rgba = rd_state->cfg_theme_target.colors[color]; - String8 color_hex = hex_string_from_rgba_4f32(arena, color_rgba); - str8_list_pushf(arena, &strs, " %S:%.*s0x%S\n", - color_name, - 30 > color_name.size ? ((int)(30 - color_name.size)) : 0, indent_str.str, - color_hex); - } - str8_list_push(arena, &strs, str8_lit("}\n\n")); - } - } - - //- rjf: serialize fonts - if(source == RD_CfgSrc_User) - { - String8 code_font_path_escaped = escaped_from_raw_str8(arena, rd_state->cfg_code_font_path); - String8 main_font_path_escaped = escaped_from_raw_str8(arena, rd_state->cfg_main_font_path); - str8_list_push(arena, &strs, str8_lit("/// fonts /////////////////////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - str8_list_pushf(arena, &strs, "code_font: \"%S\"\n", code_font_path_escaped); - str8_list_pushf(arena, &strs, "main_font: \"%S\"\n", main_font_path_escaped); - str8_list_push(arena, &strs, str8_lit("\n")); - } - - //- rjf: serialize global settings - { - B32 first = 1; - for EachEnumVal(RD_SettingCode, code) - { - if(rd_setting_code_default_is_per_window_table[code]) - { - continue; - } - RD_SettingVal current = rd_state->cfg_setting_vals[source][code]; - if(current.set) - { - if(first) - { - first = 0; - str8_list_push(arena, &strs, str8_lit("/// global settings ///////////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - } - str8_list_pushf(arena, &strs, "%S: %i\n", rd_setting_code_lower_string_table[code], current.s32); - } - } - if(!first) - { - str8_list_push(arena, &strs, str8_lit("\n")); - } - } - - ProfEnd(); - return strs; -} - //////////////////////////////// //~ rjf: Process Control Info Stringification @@ -11004,12 +12072,13 @@ rd_string_from_exception_code(U32 code) return string; } -internal DR_FancyStringList +internal DR_FStrList rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, event->entity); - DR_FancyStringList thread_fstrs = rd_title_fstrs_from_ctrl_entity(arena, thread, ui_top_palette()->text, ui_top_font_size(), 0); - DR_FancyStringList fstrs = {0}; + DR_FStrList thread_fstrs = rd_title_fstrs_from_ctrl_entity(arena, thread, 0); + DR_FStrList fstrs = {0}; + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; switch(event->cause) { default:{}break; @@ -11019,12 +12088,12 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { if(thread != &ctrl_entity_nil) { - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" completed step")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" completed step")); } else { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit("Stopped")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Stopped")); } }break; @@ -11033,12 +12102,12 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { if(thread != &ctrl_entity_nil) { - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" stopped at entry point")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" stopped at entry point")); } else { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit("Stopped at entry point")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Stopped at entry point")); } }break; @@ -11047,10 +12116,10 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { if(thread != &ctrl_entity_nil) { - dr_fancy_string_list_push_new(arena, &fstrs, rd_font_from_slot(RD_FontSlot_Icons), ui_top_font_size(), ui_top_palette()->text, rd_icon_kind_text_table[RD_IconKind_CircleFilled]); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit a breakpoint")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_CircleFilled], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit a breakpoint")); } }break; @@ -11059,14 +12128,15 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { if(thread != &ctrl_entity_nil) { - dr_fancy_string_list_push_new(arena, &fstrs, rd_font_from_slot(RD_FontSlot_Icons), ui_top_font_size(), ui_top_palette()->text, rd_icon_kind_text_table[RD_IconKind_WarningBig]); + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_WarningBig], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); switch(event->exception_kind) { default: { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit an exception - ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception: ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); String8 exception_explanation_string = rd_string_from_exception_code(event->exception_code); String8 exception_info_string = push_str8f(arena, "%S%s%S%s", @@ -11074,49 +12144,47 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) exception_explanation_string.size != 0 ? " (" : "", exception_explanation_string, exception_explanation_string.size != 0 ? ")" : ""); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_info_string); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); }break; case CTRL_ExceptionKind_CppThrow: { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit a C++ exception - ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit a C++ exception: ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_code_string); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_code_string); }break; case CTRL_ExceptionKind_MemoryRead: { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit an exception - ")); - String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); - String8 exception_info_string = push_str8f(arena, "%S (Access violation reading 0x%I64x)", exception_code_string, event->vaddr_rng.min); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_info_string); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception: ")); + String8 exception_info_string = push_str8f(arena, "Access violation reading from address 0x%I64x", event->vaddr_rng.min); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); }break; case CTRL_ExceptionKind_MemoryWrite: { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit an exception - ")); - String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); - String8 exception_info_string = push_str8f(arena, "%S (Access violation writing 0x%I64x)", exception_code_string, event->vaddr_rng.min); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_info_string); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception: ")); + String8 exception_info_string = push_str8f(arena, "Access violation writing to address 0x%I64x", event->vaddr_rng.min); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); }break; case CTRL_ExceptionKind_MemoryExecute: { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit an exception - ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception: ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); - String8 exception_info_string = push_str8f(arena, "%S (Access violation executing 0x%I64x)", exception_code_string, event->vaddr_rng.min); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_info_string); + String8 exception_info_string = push_str8f(arena, "Access violation executing at address 0x%I64x", event->vaddr_rng.min); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); }break; } } else { - dr_fancy_string_list_push_new(arena, &fstrs, rd_font_from_slot(RD_FontSlot_Icons), ui_top_font_size(), ui_top_palette()->text, rd_icon_kind_text_table[RD_IconKind_WarningBig]); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit("Hit an exception - ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_WarningBig], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Hit an exception: ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); String8 exception_explanation_string = rd_string_from_exception_code(event->exception_code); String8 exception_info_string = push_str8f(arena, "%S%s%S%s", @@ -11124,29 +12192,76 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) exception_explanation_string.size != 0 ? " (" : "", exception_explanation_string, exception_explanation_string.size != 0 ? ")" : ""); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_info_string); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); } }break; //- rjf: trap case CTRL_EventCause_InterruptedByTrap: { - dr_fancy_string_list_push_new(arena, &fstrs, rd_font_from_slot(RD_FontSlot_Icons), ui_top_font_size(), ui_top_palette()->text, rd_icon_kind_text_table[RD_IconKind_WarningBig]); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit a trap")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_WarningBig], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit a trap")); }break; //- rjf: halt case CTRL_EventCause_InterruptedByHalt: { - dr_fancy_string_list_push_new(arena, &fstrs, rd_font_from_slot(RD_FontSlot_Icons), ui_top_font_size(), ui_top_palette()->text, rd_icon_kind_text_table[RD_IconKind_Pause]); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit("Halted")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_Pause], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Halted")); }break; } return fstrs; } +//////////////////////////////// +//~ rjf: Vocab Info Lookups + +internal RD_VocabInfo * +rd_vocab_info_from_code_name(String8 code_name) +{ + RD_VocabInfo *result = &rd_nil_vocab_info; + if(code_name.size != 0) + { + U64 hash = d_hash_from_string(code_name); + U64 slot_idx = hash%rd_state->vocab_info_map.single_slots_count; + for(RD_VocabInfoMapNode *n = rd_state->vocab_info_map.single_slots[slot_idx].first; + n != 0; + n = n->single_next) + { + if(str8_match(n->v.code_name, code_name, 0)) + { + result = &n->v; + break; + } + } + } + return result; +} + +internal RD_VocabInfo * +rd_vocab_info_from_code_name_plural(String8 code_name_plural) +{ + RD_VocabInfo *result = &rd_nil_vocab_info; + if(code_name_plural.size != 0) + { + U64 hash = d_hash_from_string(code_name_plural); + U64 slot_idx = hash%rd_state->vocab_info_map.plural_slots_count; + for(RD_VocabInfoMapNode *n = rd_state->vocab_info_map.plural_slots[slot_idx].first; + n != 0; + n = n->plural_next) + { + if(str8_match(n->v.code_name_plural, code_name_plural, 0)) + { + result = &n->v; + break; + } + } + } + return result; +} + //////////////////////////////// //~ rjf: Continuous Frame Requests @@ -11167,80 +12282,6 @@ rd_frame_arena(void) return rd_state->frame_arenas[rd_state->frame_index%ArrayCount(rd_state->frame_arenas)]; } -//- rjf: config paths - -internal String8 -rd_cfg_path_from_src(RD_CfgSrc src) -{ - return rd_state->cfg_paths[src]; -} - -//- rjf: entity cache queries - -internal RD_EntityList -rd_query_cached_entity_list_with_kind(RD_EntityKind kind) -{ - ProfBeginFunction(); - RD_EntityListCache *cache = &rd_state->kind_caches[kind]; - - // rjf: build cached list if we're out-of-date - if(cache->alloc_gen != rd_state->kind_alloc_gens[kind]) - { - cache->alloc_gen = rd_state->kind_alloc_gens[kind]; - if(cache->arena == 0) - { - cache->arena = arena_alloc(); - } - arena_clear(cache->arena); - cache->list = rd_push_entity_list_with_kind(cache->arena, kind); - } - - // rjf: grab & return cached list - RD_EntityList result = cache->list; - ProfEnd(); - return result; -} - -internal RD_EntityList -rd_push_active_target_list(Arena *arena) -{ - RD_EntityList active_targets = {0}; - RD_EntityList all_targets = rd_query_cached_entity_list_with_kind(RD_EntityKind_Target); - for(RD_EntityNode *n = all_targets.first; n != 0; n = n->next) - { - if(!n->entity->disabled) - { - rd_entity_list_push(arena, &active_targets, n->entity); - } - } - return active_targets; -} - -internal RD_Entity * -rd_entity_from_ev_key_and_kind(EV_Key key, RD_EntityKind kind) -{ - RD_Entity *result = &rd_nil_entity; - RD_EntityList list = rd_query_cached_entity_list_with_kind(kind); - for(RD_EntityNode *n = list.first; n != 0; n = n->next) - { - RD_Entity *entity = n->entity; - if(ev_key_match(rd_ev_key_from_entity(entity), key)) - { - result = entity; - break; - } - } - return result; -} - -//- rjf: config state - -internal RD_CfgTable * -rd_cfg_table(void) -{ - return &rd_state->cfg_table; -} - //////////////////////////////// //~ rjf: Registers @@ -11300,6 +12341,10 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 string) rd_regs()->cursor = pair.pt; } }break; + case RD_RegSlot_Expr: + { + rd_regs()->expr = push_str8_copy(rd_frame_arena(), string); + }break; case RD_RegSlot_Cursor: { U64 v = 0; @@ -11324,7 +12369,7 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 string) E_Eval eval = e_eval_from_string(scratch.arena, string); if(eval.msgs.max_kind == E_MsgKind_Null) { - E_TypeKind eval_type_kind = e_type_kind_from_key(e_type_unwrap(eval.type_key)); + E_TypeKind eval_type_kind = e_type_kind_from_key(e_type_unwrap(eval.irtree.type_key)); if(eval_type_kind == E_TypeKind_Ptr || eval_type_kind == E_TypeKind_LRef || eval_type_kind == E_TypeKind_RRef) @@ -11391,7 +12436,7 @@ rd_cmd_kind_info_from_string(String8 string) { RD_CmdKindInfo *info = &rd_nil_cmd_kind_info; { - // TODO(rjf): extend this by looking up into dynamically-registered commands by views + // TODO(rjf): @dynamic_cmds extend this by looking up into dynamically-registered commands by views RD_CmdKind kind = rd_cmd_kind_from_string(string); if(kind != RD_CmdKind_Null) { @@ -11429,6 +12474,20 @@ rd_next_cmd(RD_Cmd **cmd) return !!cmd[0]; } +internal B32 +rd_next_view_cmd(RD_Cmd **cmd) +{ + for(;rd_next_cmd(cmd);) + { + if(rd_regs()->view == cmd[0]->regs->view) + { + break; + } + } + B32 result = !!cmd[0]; + return result; +} + //////////////////////////////// //~ rjf: Main Layer Top-Level Calls @@ -11448,6 +12507,8 @@ rd_init(CmdLine *cmdln) rd_state->arena = arena; rd_state->quit_after_success = (cmd_line_has_flag(cmdln, str8_lit("quit_after_success")) || cmd_line_has_flag(cmdln, str8_lit("q"))); + rd_state->user_path_arena = arena_alloc(); + rd_state->project_path_arena = arena_alloc(); for(U64 idx = 0; idx < ArrayCount(rd_state->frame_arenas); idx += 1) { rd_state->frame_arenas[idx] = arena_alloc(); @@ -11470,28 +12531,61 @@ rd_init(CmdLine *cmdln) { rd_state->cmds_arenas[idx] = arena_alloc(); } - rd_state->entities_arena = arena_alloc(.reserve_size = GB(64), .commit_size = KB(64)); - rd_state->entities_root = &rd_nil_entity; - rd_state->entities_base = push_array(rd_state->entities_arena, RD_Entity, 0); - rd_state->entities_count = 0; - rd_state->entities_root = rd_entity_alloc(&rd_nil_entity, RD_EntityKind_Root); - rd_state->key_map_arena = arena_alloc(); rd_state->popup_arena = arena_alloc(); rd_state->ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("top_level_ctx_menu")); rd_state->drop_completion_key = ui_key_from_string(ui_key_zero(), str8_lit("drop_completion_ctx_menu")); - rd_state->string_search_arena = arena_alloc(); - rd_state->eval_viz_view_cache_slots_count = 1024; - rd_state->eval_viz_view_cache_slots = push_array(arena, RD_EvalVizViewCacheSlot, rd_state->eval_viz_view_cache_slots_count); - rd_state->cfg_main_font_path_arena = arena_alloc(); - rd_state->cfg_code_font_path_arena = arena_alloc(); rd_state->bind_change_arena = arena_alloc(); rd_state->drag_drop_arena = arena_alloc(); rd_state->drag_drop_regs = push_array(rd_state->drag_drop_arena, RD_Regs, 1); rd_state->top_regs = &rd_state->base_regs; - rd_clear_bindings(); - // rjf: set up top-level config entity trees + // rjf: set up schemas { + U64 schemas_count = ArrayCount(rd_name_schema_info_table); + rd_state->schemas = push_array(rd_state->arena, MD_Node *, schemas_count); + for EachIndex(idx, schemas_count) + { + rd_state->schemas[idx] = md_tree_from_string(rd_state->arena, rd_name_schema_info_table[idx].schema)->first; + } + } + + // rjf: set up theme presets + { + for EachEnumVal(RD_ThemePreset, p) + { + rd_state->theme_preset_trees[p] = md_tree_from_string(rd_state->arena, rd_theme_preset_cfg_string_table[p])->first; + } + } + + // rjf: set up vocab info map + { + rd_state->vocab_info_map.single_slots_count = 1024; + rd_state->vocab_info_map.single_slots = push_array(rd_state->arena, RD_VocabInfoMapSlot, rd_state->vocab_info_map.single_slots_count); + rd_state->vocab_info_map.plural_slots_count = 1024; + rd_state->vocab_info_map.plural_slots = push_array(rd_state->arena, RD_VocabInfoMapSlot, rd_state->vocab_info_map.plural_slots_count); + for EachElement(idx, rd_vocab_info_table) + { + RD_VocabInfoMapNode *n = push_array(rd_state->arena, RD_VocabInfoMapNode, 1); + MemoryCopyStruct(&n->v, &rd_vocab_info_table[idx]); + U64 single_hash = d_hash_from_string(n->v.code_name); + U64 plural_hash = d_hash_from_string(n->v.code_name_plural); + U64 single_slot_idx = single_hash%rd_state->vocab_info_map.single_slots_count; + U64 plural_slot_idx = plural_hash%rd_state->vocab_info_map.plural_slots_count; + if(n->v.code_name.size != 0) + { + SLLQueuePush_N(rd_state->vocab_info_map.single_slots[single_slot_idx].first, rd_state->vocab_info_map.single_slots[single_slot_idx].last, n, single_next); + } + if(n->v.code_name_plural.size != 0) + { + SLLQueuePush_N(rd_state->vocab_info_map.plural_slots[plural_slot_idx].first, rd_state->vocab_info_map.plural_slots[plural_slot_idx].last, n, plural_next); + } + } + } + + // rjf: set up top-level config entity trees & tables + { + rd_state->cfg_id_slots_count = 1024; + rd_state->cfg_id_slots = push_array(arena, RD_CfgSlot, rd_state->cfg_id_slots_count); rd_state->root_cfg = rd_cfg_alloc(); RD_Cfg *user_tree = rd_cfg_new(rd_state->root_cfg, str8_lit("user")); RD_Cfg *project_tree = rd_cfg_new(rd_state->root_cfg, str8_lit("project")); @@ -11499,53 +12593,47 @@ rd_init(CmdLine *cmdln) RD_Cfg *transient = rd_cfg_new(rd_state->root_cfg, str8_lit("transient")); } + // rjf: set up window cache + { + rd_state->window_state_slots_count = 64; + rd_state->window_state_slots = push_array(arena, RD_WindowStateSlot, rd_state->window_state_slots_count); + rd_state->first_window_state = rd_state->last_window_state = &rd_nil_window_state; + } + + // rjf: set up view cache + { + rd_state->view_state_slots_count = 4096; + rd_state->view_state_slots = push_array(arena, RD_ViewStateSlot, rd_state->view_state_slots_count); + } + // rjf: set up user / project paths { Temp scratch = scratch_begin(0, 0); // rjf: unpack command line arguments - String8 user_cfg_path = cmd_line_string(cmdln, str8_lit("user")); - String8 project_cfg_path = cmd_line_string(cmdln, str8_lit("project")); - if(project_cfg_path.size == 0) - { - project_cfg_path = cmd_line_string(cmdln, str8_lit("profile")); - } + String8 user_path = cmd_line_string(cmdln, str8_lit("user")); + String8 project_path = cmd_line_string(cmdln, str8_lit("project")); { String8 user_program_data_path = os_get_process_info()->user_program_data_path; String8 user_data_folder = push_str8f(scratch.arena, "%S/%S", user_program_data_path, str8_lit("raddbg")); os_make_directory(user_data_folder); - if(user_cfg_path.size == 0) + if(user_path.size == 0) { - user_cfg_path = push_str8f(scratch.arena, "%S/default.raddbg_user", user_data_folder); + user_path = push_str8f(scratch.arena, "%S/default.raddbg_user", user_data_folder); } - if(project_cfg_path.size == 0) + if(project_path.size == 0) { - project_cfg_path = push_str8f(scratch.arena, "%S/default.raddbg_project", user_data_folder); + project_path = push_str8f(scratch.arena, "%S/default.raddbg_project", user_data_folder); } } - // rjf: set up config path state - String8 cfg_src_paths[RD_CfgSrc_COUNT] = {user_cfg_path, project_cfg_path}; - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - rd_state->cfg_path_arenas[src] = arena_alloc(); - rd_cmd(rd_cfg_src_load_cmd_kind_table[src], .file_path = path_normalized_from_string(scratch.arena, cfg_src_paths[src])); - } + // rjf: do initial load + rd_cmd(RD_CmdKind_OpenUser, .file_path = user_path); + rd_cmd(RD_CmdKind_OpenProject, .file_path = project_path); - // rjf: set up config table arena - rd_state->cfg_arena = arena_alloc(); scratch_end(scratch); } - // rjf: set up initial exception filtering rules - for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)0; k < CTRL_ExceptionCodeKind_COUNT; k = (CTRL_ExceptionCodeKind)(k+1)) - { - if(ctrl_exception_code_kind_default_enable_table[k]) - { - rd_state->ctrl_exception_code_filters[k/64] |= 1ull<<(k%64); - } - } - // rjf: unpack icon image data { Temp scratch = scratch_begin(0, 0); @@ -11641,16 +12729,6 @@ rd_init(CmdLine *cmdln) scratch_end(scratch); } - // rjf: set up initial browse path - { - Temp scratch = scratch_begin(0, 0); - String8 current_path = os_get_current_path(scratch.arena); - String8 current_path_with_slash = push_str8f(scratch.arena, "%S/", current_path); - rd_state->current_path_arena = arena_alloc(); - rd_state->current_path = push_str8_copy(rd_state->current_path_arena, current_path_with_slash); - scratch_end(scratch); - } - ProfEnd(); } @@ -11659,15 +12737,8 @@ rd_frame(void) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - local_persist S32 depth = 0; log_scope_begin(); - //- TODO(rjf): @cfg debugging: stringify the current cfg tree - { - // String8 string = rd_string_from_cfg_tree(scratch.arena, rd_state->root_cfg); - // int x = 0; - } - ////////////////////////////// //- rjf: do per-frame resets // @@ -11685,42 +12756,246 @@ rd_frame(void) rd_state->hover_regs = push_array(rd_frame_arena(), RD_Regs, 1); rd_state->hover_regs_slot = RD_RegSlot_Null; } - if(depth == 0) - { - rd_state->frame_di_scope = di_scope_open(); - } B32 allow_text_hotkeys = !rd_state->text_edit_mode; rd_state->text_edit_mode = 0; - rd_state->ctrl_entity_meval_cache_slots_count = 1024; - rd_state->ctrl_entity_meval_cache_slots = push_array(rd_frame_arena(), RD_CtrlEntityMetaEvalCacheSlot, rd_state->ctrl_entity_meval_cache_slots_count); + + ////////////////////////////// + //- rjf: iterate all tabs, touch their view-states + // + if(rd_state->frame_depth == 0) + { + Temp scratch = scratch_begin(0, 0); + RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); + for(RD_CfgNode *n = windows.first; n != 0; n = n->next) + { + RD_Cfg *window = n->v; + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + for(RD_PanelNode *p = panel_tree.root; p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) + { + for(RD_CfgNode *n = p->tabs.first; n != 0; n = n->next) + { + RD_Cfg *tab = n->v; + if(rd_cfg_is_project_filtered(tab)) + { + continue; + } + rd_view_state_from_cfg(tab); + } + } + } + scratch_end(scratch); + } + + ////////////////////////////// + //- rjf: garbage collect untouched immediate cfg trees + // + if(rd_state->frame_depth == 0) + { + RD_Cfg *transient = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); + for(RD_Cfg *tln = transient->first, *next = &rd_nil_cfg; tln != &rd_nil_cfg; tln = next) + { + next = tln->next; + if(str8_match(tln->string, str8_lit("immediate"), 0)) + { + if(rd_cfg_child_from_string(tln, str8_lit("hot")) == &rd_nil_cfg) + { + rd_cfg_release(tln); + } + } + } + for(RD_Cfg *tln = transient->first; tln != &rd_nil_cfg; tln = tln->next) + { + if(str8_match(tln->string, str8_lit("immediate"), 0)) + { + rd_cfg_release(rd_cfg_child_from_string(tln, str8_lit("hot"))); + } + } + } + + ////////////////////////////// + //- rjf: garbage collect untouched window states + // + if(rd_state->frame_depth == 0) DeferLoop(rd_state->frame_depth += 1, rd_state->frame_depth -= 1) + { + for EachIndex(slot_idx, rd_state->window_state_slots_count) + { + for(RD_WindowState *ws = rd_state->window_state_slots[slot_idx].first, *next; ws != 0; ws = next) + { + next = ws->hash_next; + if(ws->last_frame_index_touched+2 < rd_state->frame_index) + { + ui_state_release(ws->ui); + r_window_unequip(ws->os, ws->r); + os_window_close(ws->os); + if(ws->autocomp_lister != 0) + { + arena_release(ws->autocomp_lister->arena); + } + for(RD_Lister *lister = ws->top_query_lister; lister != 0; lister = lister->next) + { + arena_release(lister->arena); + } + arena_release(ws->drop_completion_arena); + arena_release(ws->hover_eval_arena); + arena_release(ws->query_arena); + arena_release(ws->arena); + DLLRemove_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); + DLLRemove_NP(rd_state->window_state_slots[slot_idx].first, rd_state->window_state_slots[slot_idx].last, ws, hash_next, hash_prev); + SLLStackPush_N(rd_state->free_window_state, ws, order_next); + } + } + } + } + + ////////////////////////////// + //- rjf: garbage collect untouched view states + // + if(rd_state->frame_depth == 0) + { + for EachIndex(slot_idx, rd_state->view_state_slots_count) + { + for(RD_ViewState *vs = rd_state->view_state_slots[slot_idx].first, *next; vs != 0; vs = next) + { + next = vs->hash_next; + if(vs->last_frame_index_touched+2 < rd_state->frame_index) + { + ev_view_release(vs->ev_view); + for(RD_ArenaExt *ext = vs->first_arena_ext; ext != 0; ext = ext->next) + { + arena_release(ext->arena); + } + arena_release(vs->arena); + DLLRemove_NP(rd_state->view_state_slots[slot_idx].first, rd_state->view_state_slots[slot_idx].last, vs, hash_next, hash_prev); + SLLStackPush_N(rd_state->free_view_state, vs, hash_next); + } + } + } + } + + ////////////////////////////// + //- rjf: sync with di parsers + // + ProfScope("sync with di parsers") + { + DI_EventList events = di_p2u_pop_events(scratch.arena, 0); + for(DI_EventNode *n = events.first; n != 0; n = n->next) + { + DI_Event *event = &n->v; + switch(event->kind) + { + default:{}break; + case DI_EventKind_ConversionStarted: + { + RD_Cfg *root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); + RD_Cfg *task = rd_cfg_new(root, str8_lit("conversion_task")); + rd_cfg_new(task, event->string); + }break; + case DI_EventKind_ConversionEnded: + { + RD_Cfg *root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); + for(RD_Cfg *tln = root->first; tln != &rd_nil_cfg; tln = tln->next) + { + if(str8_match(tln->string, str8_lit("conversion_task"), 0) && str8_match(tln->first->string, event->string, 0)) + { + rd_cfg_release(tln); + break; + } + } + }break; + } + } + } + + ////////////////////////////// + //- rjf: animate all views + // + if(rd_state->frame_depth == 0) + { + F32 slow_rate = 1 - pow_f32(2, (-10.f * rd_state->frame_dt)); + F32 fast_rate = 1 - pow_f32(2, (-40.f * rd_state->frame_dt)); + for EachIndex(slot_idx, rd_state->view_state_slots_count) + { + for(RD_ViewState *vs = rd_state->view_state_slots[slot_idx].first; + vs != 0; + vs = vs->hash_next) + { + F32 scroll_x_diff = (-vs->scroll_pos.x.off); + F32 scroll_y_diff = (-vs->scroll_pos.y.off); + F32 loading_t_diff = (vs->loading_t_target - vs->loading_t); + vs->scroll_pos.x.off += scroll_x_diff*fast_rate; + vs->scroll_pos.y.off += scroll_y_diff*fast_rate; + vs->loading_t += loading_t_diff * slow_rate; + if(abs_f32(loading_t_diff) > 0.01f || + abs_f32(scroll_x_diff) > 0.01f || + abs_f32(scroll_y_diff) > 0.01f) + { + rd_request_frame(); + } + if(abs_f32(scroll_x_diff) <= 0.01f) + { + vs->scroll_pos.x.off = 0; + } + if(abs_f32(scroll_y_diff) <= 0.01f) + { + vs->scroll_pos.y.off = 0; + } + RD_Cfg *vcfg = rd_cfg_from_id(vs->cfg_id); + if(rd_cfg_child_from_string(vcfg, str8_lit("selected")) != &rd_nil_cfg) + { + if(vs->loading_t_target > 0.5f) + { + rd_request_frame(); + } + vs->loading_t_target = 0; + } + } + } + } ////////////////////////////// //- rjf: get events from the OS // OS_EventList events = {0}; - if(depth == 0) DeferLoop(depth += 1, depth -= 1) + if(rd_state->frame_depth == 0) DeferLoop(rd_state->frame_depth += 1, rd_state->frame_depth -= 1) { events = os_get_events(scratch.arena, rd_state->num_frames_requested == 0); } + ////////////////////////////// + //- rjf: open frame debug info scope + // + { + rd_state->frame_di_scope = di_scope_open(); + } + + ////////////////////////////// + //- rjf: calculate avg length in us of last many frames + // + U64 frame_time_history_avg_us = 0; + { + U64 num_frames_in_history = Min(ArrayCount(rd_state->frame_time_us_history), rd_state->frame_index); + U64 frame_time_history_sum_us = 0; + if(num_frames_in_history > 0) + { + for(U64 idx = 0; idx < num_frames_in_history; idx += 1) + { + frame_time_history_sum_us += rd_state->frame_time_us_history[idx]; + } + frame_time_history_avg_us = frame_time_history_sum_us/num_frames_in_history; + } + } + ////////////////////////////// //- rjf: pick target hz // + // pick among a number of sensible targets to snap to, given how well + // we've been performing + // // TODO(rjf): maximize target, given all windows and their monitors + // F32 target_hz = os_get_gfx_info()->default_refresh_rate; if(rd_state->frame_index > 32) { - // rjf: calculate average frame time out of the last N - U64 num_frames_in_history = Min(ArrayCount(rd_state->frame_time_us_history), rd_state->frame_index); - U64 frame_time_history_sum_us = 0; - for(U64 idx = 0; idx < num_frames_in_history; idx += 1) - { - frame_time_history_sum_us += rd_state->frame_time_us_history[idx]; - } - U64 frame_time_history_avg_us = frame_time_history_sum_us/num_frames_in_history; - - // rjf: pick among a number of sensible targets to snap to, given how well - // we've been performing F32 possible_alternate_hz_targets[] = {target_hz, 60.f, 120.f, 144.f, 240.f}; F32 best_target_hz = target_hz; S64 best_target_hz_frame_time_us_diff = max_S64; @@ -11741,6 +13016,20 @@ rd_frame(void) target_hz = best_target_hz; } + ////////////////////////////// + //- rjf: given frame time history, decide on amount of time we're willing to wait for memory read results + // for evaluations + // + { + rd_state->frame_eval_memread_endt_us = 0; + U64 frame_time_target_cap_us = (U64)(1000000/target_hz); + if(frame_time_history_avg_us < frame_time_target_cap_us) + { + U64 spare_time = (frame_time_target_cap_us - frame_time_history_avg_us) + 4000; + rd_state->frame_eval_memread_endt_us = os_now_microseconds() + spare_time; + } + } + ////////////////////////////// //- rjf: target Hz -> delta time // @@ -11764,9 +13053,8 @@ rd_frame(void) if(os_key_press(&events, os_handle_zero(), 0, OS_Key_Delete)) { rd_request_frame(); - rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); + rd_cfg_release(rd_cfg_from_id(rd_state->bind_change_binding_id)); rd_state->bind_change_active = 0; - rd_cmd(rd_cfg_src_write_cmd_kind_table[RD_CfgSrc_User]); } for(OS_Event *event = events.first, *next = 0; event != 0; event = next) { @@ -11783,23 +13071,218 @@ rd_frame(void) event->key != OS_Key_Shift) { rd_state->bind_change_active = 0; - RD_Binding binding = zero_struct; + RD_Cfg *binding = rd_cfg_from_id(rd_state->bind_change_binding_id); + if(binding == &rd_nil_cfg) { - binding.key = event->key; - binding.modifiers = event->modifiers; + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *keybindings = rd_cfg_child_from_string_or_alloc(user, str8_lit("keybindings")); + binding = rd_cfg_new(keybindings, str8_lit("")); } - rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); - rd_bind_name(rd_state->bind_change_cmd_name, binding); + rd_cfg_release_all_children(binding); + rd_cfg_new(binding, rd_state->bind_change_cmd_name); + rd_cfg_new(binding, os_g_key_cfg_string_table[event->key]); + if(event->modifiers & OS_Modifier_Ctrl) { rd_cfg_new(binding, str8_lit("ctrl")); } + if(event->modifiers & OS_Modifier_Shift) { rd_cfg_new(binding, str8_lit("shift")); } + if(event->modifiers & OS_Modifier_Alt) { rd_cfg_new(binding, str8_lit("alt")); } U32 codepoint = os_codepoint_from_modifiers_and_key(event->modifiers, event->key); os_text(&events, event->window, codepoint); os_eat_event(&events, event); - rd_cmd(rd_cfg_src_write_cmd_kind_table[RD_CfgSrc_User]); rd_request_frame(); break; } } } + ////////////////////////////// + //- rjf: build key map from config + // + ProfScope("build key map from config") + { + //- rjf: set up table + rd_state->key_map = push_array(rd_frame_arena(), RD_KeyMap, 1); + RD_KeyMap *key_map = rd_state->key_map; + key_map->name_slots_count = 4096; + key_map->name_slots = push_array(rd_frame_arena(), RD_KeyMapSlot, key_map->name_slots_count); + key_map->binding_slots_count = 4096; + key_map->binding_slots = push_array(rd_frame_arena(), RD_KeyMapSlot, key_map->binding_slots_count); + + //- rjf: gather & parse all explicitly stored keybinding sets + RD_CfgList keybindings_cfg_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("keybindings")); + for(RD_CfgNode *n = keybindings_cfg_list.first; n != 0; n = n->next) + { + RD_Cfg *keybindings_root = n->v; + for(RD_Cfg *keybinding = keybindings_root->first; keybinding != &rd_nil_cfg; keybinding = keybinding->next) + { + String8 name = {0}; + RD_Binding binding = {0}; + for(RD_Cfg *child = keybinding->first; child != &rd_nil_cfg; child = child->next) + { + if(0){} + else if(str8_match(child->string, str8_lit("ctrl"), 0)) { binding.modifiers |= OS_Modifier_Ctrl; } + else if(str8_match(child->string, str8_lit("alt"), 0)) { binding.modifiers |= OS_Modifier_Alt; } + else if(str8_match(child->string, str8_lit("shift"), 0)) { binding.modifiers |= OS_Modifier_Shift; } + else + { + OS_Key key = OS_Key_Null; + for EachEnumVal(OS_Key, k) + { + if(str8_match(child->string, os_g_key_cfg_string_table[k], StringMatchFlag_CaseInsensitive)) + { + key = k; + break; + } + } + if(key != OS_Key_Null) + { + binding.key = key; + } + else + { + name = child->string; + for(U64 idx = 0; idx < ArrayCount(rd_binding_version_remap_old_name_table); idx += 1) + { + if(str8_match(rd_binding_version_remap_old_name_table[idx], name, StringMatchFlag_CaseInsensitive)) + { + name = rd_binding_version_remap_new_name_table[idx]; + } + } + } + } + } + if(name.size != 0) + { + U64 name_hash = d_hash_from_string(name); + U64 binding_hash = d_hash_from_string(str8_struct(&binding)); + U64 name_slot_idx = name_hash%key_map->name_slots_count; + U64 binding_slot_idx = binding_hash%key_map->binding_slots_count; + RD_KeyMapNode *n = push_array(rd_frame_arena(), RD_KeyMapNode, 1); + n->cfg_id = keybinding->id; + n->name = push_str8_copy(rd_frame_arena(), name); + n->binding = binding; + SLLQueuePush_N(key_map->name_slots[name_slot_idx].first, key_map->name_slots[name_slot_idx].last, n, name_hash_next); + SLLQueuePush_N(key_map->binding_slots[binding_slot_idx].first, key_map->binding_slots[binding_slot_idx].last, n, binding_hash_next); + } + } + } + } + + ////////////////////////////// + //- rjf: build theme from config + // + ProfScope("build theme from config") + { + RD_Theme *theme_srgba = push_array(scratch.arena, RD_Theme, 1); + + //- rjf: gather globally-applying config options + RD_CfgList preset_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("color_preset")); + RD_CfgList colors_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("colors")); + + //- rjf: assume default-dark + MemoryCopy(theme_srgba->colors, rd_theme_preset_colors_table[RD_ThemePreset_DefaultDark], sizeof(rd_theme_preset_colors__default_dark)); + + //- rjf: apply explicitly-specified presets + for(RD_CfgNode *n = preset_roots.first; n != 0; n = n->next) + { + RD_Cfg *preset = n->v; + String8 preset_name = preset->first->string; + RD_ThemePreset preset_kind = (RD_ThemePreset)0; + B32 found_preset_kind = 0; + for(RD_ThemePreset p = (RD_ThemePreset)0; p < RD_ThemePreset_COUNT; p = (RD_ThemePreset)(p+1)) + { + if(str8_match(preset_name, rd_theme_preset_code_string_table[p], StringMatchFlag_CaseInsensitive)) + { + found_preset_kind = 1; + preset_kind = p; + break; + } + } + if(found_preset_kind) + { + MemoryCopy(theme_srgba->colors, rd_theme_preset_colors_table[preset_kind], sizeof(rd_theme_preset_colors__default_dark)); + } + } + + //- rjf: apply explicitly-specified color codes + for(RD_CfgNode *n = colors_roots.first; n != 0; n = n->next) + { + RD_Cfg *colors = n->v; + for(RD_Cfg *color = colors->first; color != &rd_nil_cfg; color = color->next) + { + String8 name = color->string; + RD_ThemeColor color_code = RD_ThemeColor_Null; + for(RD_ThemeColor c = RD_ThemeColor_Null; c < RD_ThemeColor_COUNT; c = (RD_ThemeColor)(c+1)) + { + if(str8_match(rd_theme_color_cfg_string_table[c], name, StringMatchFlag_CaseInsensitive)) + { + color_code = c; + break; + } + } + if(color_code != RD_ThemeColor_Null) + { + U64 color_val = 0; + if(try_u64_from_str8_c_rules(color->first->string, &color_val)) + { + Vec4F32 color_rgba = rgba_from_u32((U32)color_val); + theme_srgba->colors[color_code] = color_rgba; + } + } + } + } + + //- rjf: srgba -> linear, compute final theme + rd_state->theme_target = push_array(rd_frame_arena(), RD_Theme, 1); + RD_Theme *theme = rd_state->theme_target; + for EachEnumVal(RD_ThemeColor, c) + { + theme->colors[c] = linear_from_srgba(theme_srgba->colors[c]); + } + } + + ////////////////////////////// + //- rjf: animate theme + // + { + Temp scratch = scratch_begin(0, 0); + RD_Theme *last = push_array(scratch.arena, RD_Theme, 1); + if(rd_state->theme != 0) + { + MemoryCopyStruct(last, rd_state->theme); + } + rd_state->theme = push_array(rd_frame_arena(), RD_Theme, 1); + RD_Theme *current = rd_state->theme; + RD_Theme *target = rd_state->theme_target; + if(last) + { + MemoryCopyStruct(current, last); + } + if(rd_state->frame_index <= 2) + { + MemoryCopyStruct(current, target); + } + else + { + F32 rate = 1 - pow_f32(2, (-50.f * rd_state->frame_dt)); + for(RD_ThemeColor color = RD_ThemeColor_Null; + color < RD_ThemeColor_COUNT; + color = (RD_ThemeColor)(color+1)) + { + if(abs_f32(target->colors[color].x - current->colors[color].x) > 0.01f || + abs_f32(target->colors[color].y - current->colors[color].y) > 0.01f || + abs_f32(target->colors[color].z - current->colors[color].z) > 0.01f || + abs_f32(target->colors[color].w - current->colors[color].w) > 0.01f) + { + rd_request_frame(); + } + current->colors[color].x += (target->colors[color].x - current->colors[color].x) * rate; + current->colors[color].y += (target->colors[color].y - current->colors[color].y) * rate; + current->colors[color].z += (target->colors[color].z - current->colors[color].z) * rate; + current->colors[color].w += (target->colors[color].w - current->colors[color].w) * rate; + } + } + scratch_end(scratch); + } + ////////////////////////////// //- rjf: consume events // @@ -11811,12 +13294,15 @@ rd_frame(void) RD_RegsScope() { next = event->next; - RD_Window *window = rd_window_from_os_handle(event->window); - if(window != 0 && window != rd_window_from_handle(rd_regs()->window)) + RD_WindowState *ws = rd_window_state_from_os_handle(event->window); + if(ws != 0 && ws != rd_window_state_from_cfg(rd_cfg_from_id(rd_regs()->window))) { - rd_regs()->window = rd_handle_from_window(window); - rd_regs()->panel = rd_handle_from_panel(window->focused_panel); - rd_regs()->view = window->focused_panel->selected_tab_view; + Temp scratch = scratch_begin(0, 0); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_id(ws->cfg_id)); + rd_regs()->window = ws->cfg_id; + rd_regs()->panel = panel_tree.focused->cfg->id; + rd_regs()->view = panel_tree.focused->selected_tab->id; + scratch_end(scratch); } B32 take = 0; @@ -11827,10 +13313,10 @@ rd_frame(void) } //- rjf: try window close - if(!take && event->kind == OS_EventKind_WindowClose && window != 0) + if(!take && event->kind == OS_EventKind_WindowClose && ws != 0) { take = 1; - rd_cmd(RD_CmdKind_CloseWindow, .window = rd_handle_from_window(window)); + rd_cmd(RD_CmdKind_Exit); } //- rjf: try menu bar operations @@ -11839,34 +13325,34 @@ rd_frame(void) { take = 1; rd_request_frame(); - window->menu_bar_focused_on_press = window->menu_bar_focused; - window->menu_bar_key_held = 1; - window->menu_bar_focus_press_started = 1; + ws->menu_bar_focused_on_press = ws->menu_bar_focused; + ws->menu_bar_key_held = 1; + ws->menu_bar_focus_press_started = 1; } if(!take && event->kind == OS_EventKind_Release && event->key == OS_Key_Alt && event->modifiers == 0 && event->is_repeat == 0) { take = 1; rd_request_frame(); - window->menu_bar_key_held = 0; + ws->menu_bar_key_held = 0; } - if(window->menu_bar_focused && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->modifiers == 0 && event->is_repeat == 0) + if(ws->menu_bar_focused && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->modifiers == 0 && event->is_repeat == 0) { take = 1; rd_request_frame(); - window->menu_bar_focused = 0; + ws->menu_bar_focused = 0; } - else if(window->menu_bar_focus_press_started && !window->menu_bar_focused && event->kind == OS_EventKind_Release && event->modifiers == 0 && event->key == OS_Key_Alt && event->is_repeat == 0) + else if(ws->menu_bar_focus_press_started && !ws->menu_bar_focused && event->kind == OS_EventKind_Release && event->modifiers == 0 && event->key == OS_Key_Alt && event->is_repeat == 0) { take = 1; rd_request_frame(); - window->menu_bar_focused = !window->menu_bar_focused_on_press; - window->menu_bar_focus_press_started = 0; + ws->menu_bar_focused = !ws->menu_bar_focused_on_press; + ws->menu_bar_focus_press_started = 0; } - else if(event->kind == OS_EventKind_Press && event->key == OS_Key_Esc && window->menu_bar_focused && !ui_any_ctx_menu_is_open()) + else if(event->kind == OS_EventKind_Press && event->key == OS_Key_Esc && ws->menu_bar_focused && !ui_any_ctx_menu_is_open()) { take = 1; rd_request_frame(); - window->menu_bar_focused = 0; + ws->menu_bar_focused = 0; } } @@ -11874,13 +13360,13 @@ rd_frame(void) if(!take && event->kind == OS_EventKind_Press) { RD_Binding binding = {event->key, event->modifiers}; - String8List spec_candidates = rd_cmd_name_list_from_binding(scratch.arena, binding); - if(spec_candidates.first != 0) + RD_KeyMapNodePtrList key_map_nodes = rd_key_map_node_ptr_list_from_binding(scratch.arena, binding); + if(key_map_nodes.first != 0) { U32 hit_char = os_codepoint_from_modifiers_and_key(event->modifiers, event->key); if(hit_char == 0 || allow_text_hotkeys) { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = spec_candidates.first->string); + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = key_map_nodes.first->v->name); if(allow_text_hotkeys) { os_text(&events, event->window, hit_char); @@ -11889,13 +13375,13 @@ rd_frame(void) take = 1; if(event->modifiers & OS_Modifier_Alt) { - window->menu_bar_focus_press_started = 0; + ws->menu_bar_focus_press_started = 0; } } } else if(OS_Key_F1 <= event->key && event->key <= OS_Key_F19) { - window->menu_bar_focus_press_started = 0; + ws->menu_bar_focus_press_started = 0; } rd_request_frame(); } @@ -11910,7 +13396,7 @@ rd_frame(void) take = 1; if(event->modifiers & OS_Modifier_Alt) { - window->menu_bar_focus_press_started = 0; + ws->menu_bar_focus_press_started = 0; } } @@ -12011,135 +13497,410 @@ rd_frame(void) } e_select_parse_ctx(parse_ctx); - //////////////////////////// - //- rjf: create names/type-info for debugger collections - // - E_TypeKey collection_type_keys[ArrayCount(rd_collection_name_table)] = {0}; - for EachElement(idx, rd_collection_name_table) - { - collection_type_keys[idx] = e_type_key_cons(.kind = E_TypeKind_Collection, .name = rd_collection_name_table[idx]); - } - //////////////////////////// //- rjf: build eval IR context // - E_TypeKey meta_eval_type_key = e_type_key_cons_base(type(CTRL_MetaEval)); E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1); + if(e_ir_state != 0) { e_ir_state->ctx = 0; } { E_IRCtx *ctx = ir_ctx; - ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); - ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512); + ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); + ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512); + ctx->lookup_rule_map = push_array(scratch.arena, E_LookupRuleMap, 1); + ctx->lookup_rule_map[0] = e_lookup_rule_map_make(scratch.arena, 512); + ctx->irgen_rule_map = push_array(scratch.arena, E_IRGenRuleMap, 1); + ctx->irgen_rule_map[0] = e_irgen_rule_map_make(scratch.arena, 512); + ctx->auto_hook_map = push_array(scratch.arena, E_AutoHookMap, 1); + ctx->auto_hook_map[0] = e_auto_hook_map_make(scratch.arena, 512); - //- rjf: add macros for collections + //- rjf: build special member types for evallable meta types + E_TypeKey bool_type_key = {0}; + E_TypeKey u64_type_key = {0}; + E_TypeKey vaddr_range_type_key = {0}; + E_TypeKey code_string_type_key = {0}; + E_TypeKey path_type_key = {0}; + E_TypeKey string_type_key = {0}; + E_TypeKey path_pt_type_key = {0}; { - for EachElement(idx, rd_collection_name_table) + E_MemberList vaddr_range_members_list = {0}; + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("min"), .off = 0); + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("max"), .off = 8); + E_MemberArray vaddr_range_members = e_member_array_from_list(scratch.arena, &vaddr_range_members_list); + bool_type_key = e_type_key_basic(E_TypeKind_Bool); + u64_type_key = e_type_key_basic(E_TypeKind_U64); + vaddr_range_type_key = e_type_key_cons(.kind = E_TypeKind_Struct, .name = str8_lit("vaddr_range"), .count = vaddr_range_members.count, .members = vaddr_range_members.v); + code_string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); + path_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPathText); + string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPlainText); + path_pt_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPathText); + } + + //- rjf: build types for each evallable meta name + struct + { + String8 schema_type_name; + E_TypeKey type_key; + } + schema_type_name_key_map[] = + { + { str8_lit("bool"), bool_type_key }, + { str8_lit("u64"), u64_type_key }, + { str8_lit("vaddr_range"), vaddr_range_type_key }, + { str8_lit("code_string"), code_string_type_key }, + { str8_lit("path"), path_type_key }, + { str8_lit("string"), string_type_key }, + { str8_lit("path_pt"), path_pt_type_key }, + }; + E_TypeKey evallable_meta_types[ArrayCount(rd_name_schema_info_table)] = {0}; + for EachElement(idx, rd_name_schema_info_table) + { + String8 name = rd_name_schema_info_table[idx].name; + MD_Node *schema = rd_schema_from_name(name); + E_MemberList members_list = {0}; + U64 off = 0; + for MD_EachNode(child, schema->first) { + if(str8_match(child->first->string, str8_lit("query"), 0)) + { + e_member_list_push_new(scratch.arena, &members_list, + .type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = child->string), + .name = child->string); + } + else + { + String8 member_name = child->string; + E_TypeKey member_type_key = zero_struct; + for EachElement(schema_type_name_idx, schema_type_name_key_map) + { + if(str8_match(child->first->string, schema_type_name_key_map[schema_type_name_idx].schema_type_name, 0)) + { + member_type_key = schema_type_name_key_map[schema_type_name_idx].type_key; + break; + } + } + e_member_list_push_new(scratch.arena, &members_list, + .type_key = member_type_key, + .name = member_name, + .off = off); + off += e_type_byte_size_from_key(member_type_key); + } + } + E_MemberArray members = e_member_array_from_list(scratch.arena, &members_list); + evallable_meta_types[idx] = e_type_key_cons(.name = name, + .kind = E_TypeKind_Set, + .members = members.v, + .count = members.count); + } + + //- rjf: cache meta name -> type key correllation + rd_state->meta_name2type_map = push_array(rd_frame_arena(), E_String2TypeKeyMap, 1); + rd_state->meta_name2type_map[0] = e_string2typekey_map_make(rd_frame_arena(), 256); + for EachElement(idx, rd_name_schema_info_table) + { + String8 name = rd_name_schema_info_table[idx].name; + E_TypeKey type_key = evallable_meta_types[idx]; + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, + .info = E_LOOKUP_INFO_FUNCTION_NAME(schema), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(schema), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(schema)); + } + + //- rjf: add macros for evallable top-level config trees + String8 evallable_cfg_names[] = + { + str8_lit("breakpoint"), + str8_lit("watch_pin"), + str8_lit("target"), + str8_lit("file_path_map"), + str8_lit("auto_view_rule"), + str8_lit("recent_project"), + str8_lit("recent_file"), + }; + for EachElement(idx, evallable_cfg_names) + { + String8 name = evallable_cfg_names[idx]; + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, name); + for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) + { + RD_Cfg *cfg = n->v; + String8 label = rd_cfg_child_from_string(cfg, str8_lit("label"))->first->string; + String8 exe = rd_cfg_child_from_string(cfg, str8_lit("executable"))->first->string; + E_Space space = rd_eval_space_from_cfg(cfg); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->space = e_space_make(RD_EvalSpaceKind_MetaCollection); - expr->mode = E_Mode_Null; - expr->type_key = collection_type_keys[idx]; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, rd_collection_name_table[idx], expr); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x", cfg->id), expr); + if(exe.size != 0) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_skip_last_slash(exe), expr); + } + if(label.size != 0) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, label, expr); + } } } - //- rjf: add macros for all evallable debugger frontend entities + //- rjf: add macros for windows/tabs { - RD_EntityKind evallable_kinds[] = + RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); + for(RD_CfgNode *n = windows.first; n != 0; n = n->next) { - RD_EntityKind_Breakpoint, - RD_EntityKind_WatchPin, - RD_EntityKind_Target, - RD_EntityKind_FilePathMap, - RD_EntityKind_AutoViewRule, - }; - E_TypeKey evallable_kind_types[] = - { - e_type_key_cons_base(type(CTRL_BreakpointMetaEval)), - e_type_key_cons_base(type(CTRL_PinMetaEval)), - e_type_key_cons_base(type(CTRL_TargetMetaEval)), - e_type_key_cons_base(type(CTRL_FilePathMapMetaEval)), - e_type_key_cons_base(type(CTRL_AutoViewRuleMetaEval)), - }; - for EachElement(idx, evallable_kinds) - { - RD_EntityList list = rd_query_cached_entity_list_with_kind(evallable_kinds[idx]); - for(RD_EntityNode *n = list.first; n != 0; n = n->next) + RD_Cfg *window = n->v; + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + for(RD_PanelNode *p = panel_tree.root; + p != &rd_nil_panel_node; + p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) { - RD_Entity *entity = n->entity; - E_Space space = rd_eval_space_from_entity(entity); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->space = space; - expr->mode = E_Mode_Offset; - expr->type_key = evallable_kind_types[idx]; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64u", entity->id), expr); - if(entity->string.size != 0 && entity->kind != RD_EntityKind_WatchPin) + for(RD_CfgNode *tab_n = p->tabs.first; tab_n != 0; tab_n = tab_n->next) { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, entity->string, expr); + RD_Cfg *tab = tab_n->v; + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, tab->string); + E_Space space = rd_eval_space_from_cfg(tab); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x", tab->id), expr); } } } } - //- rjf: add macros for all evallable control entities + //- rjf: add macros for evallable control entities + String8 evallable_ctrl_names[] = { - CTRL_EntityKind evallable_kinds[] = + str8_lit("machine"), + str8_lit("process"), + str8_lit("thread"), + str8_lit("module"), + }; + for EachElement(idx, evallable_ctrl_names) + { + String8 name = evallable_ctrl_names[idx]; + CTRL_EntityKind kind = ctrl_entity_kind_from_string(name); + CTRL_EntityList list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, kind); + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) { - CTRL_EntityKind_Machine, - CTRL_EntityKind_Process, - CTRL_EntityKind_Thread, - CTRL_EntityKind_Module, - }; - E_TypeKey evallable_kind_types[] = - { - e_type_key_cons_base(type(CTRL_MachineMetaEval)), - e_type_key_cons_base(type(CTRL_ProcessMetaEval)), - e_type_key_cons_base(type(CTRL_ThreadMetaEval)), - e_type_key_cons_base(type(CTRL_ModuleMetaEval)), - }; - for EachElement(idx, evallable_kinds) - { - CTRL_EntityKind kind = evallable_kinds[idx]; - CTRL_EntityList list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, kind); - for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) + CTRL_Entity *entity = n->v; + E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, ctrl_string_from_handle(scratch.arena, entity->handle), expr); + if(entity->string.size != 0) { - CTRL_Entity *entity = n->v; - E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->space = space; - expr->mode = E_Mode_Offset; - expr->type_key = evallable_kind_types[idx]; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$_%I64x_%I64x", entity->handle.machine_id, entity->handle.dmn_handle.u64[0]), expr); - if(entity->string.size != 0) - { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, entity->string, expr); - } - if(kind == CTRL_EntityKind_Thread && ctrl_handle_match(rd_base_regs()->thread, entity->handle)) - { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_thread"), expr); - } - if(kind == CTRL_EntityKind_Process && ctrl_handle_match(rd_base_regs()->process, entity->handle)) - { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_process"), expr); - } - if(kind == CTRL_EntityKind_Module && ctrl_handle_match(rd_base_regs()->module, entity->handle)) - { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_module"), expr); - } + e_string2expr_map_insert(scratch.arena, ctx->macro_map, entity->string, expr); + } + if(kind == CTRL_EntityKind_Machine && entity->handle.machine_id == CTRL_MachineID_Local) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("local_machine"), expr); + } + if(kind == CTRL_EntityKind_Thread && ctrl_handle_match(rd_base_regs()->thread, entity->handle)) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_thread"), expr); + } + if(kind == CTRL_EntityKind_Process && ctrl_handle_match(rd_base_regs()->process, entity->handle)) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_process"), expr); + } + if(kind == CTRL_EntityKind_Module && ctrl_handle_match(rd_base_regs()->module, entity->handle)) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_module"), expr); } } + e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_key = type_key, .tag_expr_string = name); + } + + //- rjf: add macro for 'call_stack' -> 'query:current_thread.callstack' + { + E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("query:current_thread.call_stack")).exprs.first; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("call_stack"), expr); + } + + //- rjf: add macro for watches group + { + String8 collection_name = str8_lit("watches"); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_EditableChildren); + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, + .info = E_LOOKUP_INFO_FUNCTION_NAME(watches), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(watches), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(watches), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(watches)); + } + + //- rjf: add lookup rules for queries + { + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("environment"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(environment), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(environment), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(environment), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(environment), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(environment)); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("call_stack"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(call_stack), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(call_stack)); + } + + //- rjf: add macro for collections with specific lookup rules (but no unique id rules) + { + struct + { + String8 name; + E_LookupInfoFunctionType *lookup_info; + E_LookupRangeFunctionType *lookup_range; + } + collection_infos[] = + { +#define Collection(name) {str8_lit_comp(#name), E_LOOKUP_INFO_FUNCTION_NAME(name), E_LOOKUP_RANGE_FUNCTION_NAME(name)} + Collection(locals), + Collection(registers), +#undef Collection + }; + for EachElement(idx, collection_infos) + { + String8 collection_name = collection_infos[idx].name; + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, + .info = collection_infos[idx].lookup_info, + .range = collection_infos[idx].lookup_range); + } + } + + //- rjf: add macros for debug info table collections + String8 debug_info_table_collection_names[] = + { + str8_lit_comp("procedures"), + str8_lit_comp("thread_locals"), + str8_lit_comp("globals"), + str8_lit_comp("types"), + }; + for EachElement(idx, debug_info_table_collection_names) + { + String8 name = debug_info_table_collection_names[idx]; + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, + .info = E_LOOKUP_INFO_FUNCTION_NAME(debug_info_table), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(debug_info_table), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(debug_info_table), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(debug_info_table)); + } + + //- rjf: add macros for all config collections + for EachElement(cfg_name_idx, evallable_cfg_names) + { + String8 cfg_name = evallable_cfg_names[cfg_name_idx]; + String8 collection_name = rd_plural_from_code_name(cfg_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = collection_type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, + .info = E_LOOKUP_INFO_FUNCTION_NAME(cfgs), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(cfgs), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(cfgs), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(cfgs), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(cfgs)); + } + + //- rjf: add macros for all ctrl entity collections + for EachElement(ctrl_name_idx, evallable_ctrl_names) + { + String8 kind_name = evallable_ctrl_names[ctrl_name_idx]; + String8 collection_name = rd_plural_from_code_name(kind_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = collection_type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, + .info = E_LOOKUP_INFO_FUNCTION_NAME(ctrl_entities), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(ctrl_entities), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(ctrl_entities)); + } + + //- rjf: add macro / lookup rules for unattached processes + { + String8 collection_name = str8_lit("unattached_processes"); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = collection_type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("unattached_processes"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(unattached_processes), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(unattached_processes)); + } + + //- rjf: add macro for commands + { + String8 name = str8_lit("commands"); + E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, + .info = E_LOOKUP_INFO_FUNCTION_NAME(commands), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(commands), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(commands)); + } + + //- rjf: add macro for output log + { + HS_Scope *hs_scope = hs_scope_open(); + U128 key = d_state->output_log_key; + U128 hash = hs_hash_from_key(key, 0); + String8 data = hs_data_from_hash(hs_scope, hash); + E_Space space = e_space_make(E_SpaceKind_HashStoreKey); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + space.u128 = key; + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size, 0); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("output"), expr); + hs_scope_close(hs_scope); } //- rjf: add macros for all watches which define identifiers - RD_EntityList watches = rd_query_cached_entity_list_with_kind(RD_EntityKind_Watch); - for(RD_EntityNode *n = watches.first; n != 0; n = n->next) + RD_CfgList watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); + for(RD_CfgNode *n = watches.first; n != 0; n = n->next) { - RD_Entity *watch = n->entity; - String8 expr = watch->string; - E_TokenArray tokens = e_token_array_from_text(scratch.arena, expr); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, expr, &tokens); + RD_Cfg *watch = n->v; + String8 expr = rd_expr_from_cfg(watch); + E_Parse parse = e_parse_expr_from_text__cached(expr); if(parse.msgs.max_kind == E_MsgKind_Null) { - e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ctx->macro_map, parse.expr); + for(E_Expr *expr = parse.exprs.first; expr != &e_expr_nil; expr = expr->next) + { + e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ctx->macro_map, expr); + } + } + } + + //- rjf: add auto-hook rules for auto-view-rules + { + RD_CfgList auto_view_rules = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("auto_view_rule")); + for(RD_CfgNode *n = auto_view_rules.first; n != 0; n = n->next) + { + RD_Cfg *rule = n->v; + String8 type_string = rd_cfg_child_from_string(rule, str8_lit("type"))->first->string; + String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("view_rule"))->first->string; + e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string); } } } @@ -12159,84 +13920,48 @@ rd_frame(void) ctx->reg_unwind_count = unwind_count; ctx->module_base = push_array(scratch.arena, U64, 1); ctx->module_base[0] = module->vaddr_range.min; - ctx->frame_base = push_array(scratch.arena, U64, 1); ctx->tls_base = push_array(scratch.arena, U64, 1); ctx->tls_base[0] = d_query_cached_tls_base_vaddr_from_process_root_rip(process, tls_root_vaddr, rip_vaddr); } - e_select_interpret_ctx(interpret_ctx, eval_modules_primary->rdi, rip_voff); - - //////////////////////////// - //- rjf: build eval visualization view rule table - // - EV_ViewRuleInfoTable *view_rule_info_table = push_array(scratch.arena, EV_ViewRuleInfoTable, 1); - { - ev_view_rule_info_table_push_builtins(scratch.arena, view_rule_info_table); - - // rjf: collection view rules - for EachElement(idx, rd_collection_name_table) - { - EV_ViewRuleInfo info = {0}; - info.string = rd_collection_name_table[idx]; - info.flags = EV_ViewRuleInfoFlag_Expandable; - info.expr_resolution = EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity); - info.expr_expand_info = rd_collection_expr_expand_info_hook_function_table[idx]; - info.expr_expand_range_info = rd_collection_expr_expand_range_info_hook_function_table[idx]; - info.expr_expand_id_from_num = rd_collection_expr_expand_id_from_num_hook_function_table[idx]; - info.expr_expand_num_from_id = rd_collection_expr_expand_num_from_id_hook_function_table[idx]; - ev_view_rule_info_table_push(scratch.arena, view_rule_info_table, &info); - } - - // rjf: visualizer view rules - for EachEnumVal(RD_ViewRuleKind, k) - { - RD_ViewRuleInfo *src_info = &rd_view_rule_kind_info_table[k]; - if(src_info->flags & RD_ViewRuleInfoFlag_CanUseInWatchTable) - { - EV_ViewRuleInfo dst_info = {0}; - dst_info.string = src_info->string; - dst_info.flags = src_info->flags & RD_ViewRuleInfoFlag_CanExpand ? EV_ViewRuleInfoFlag_Expandable : 0; - dst_info.expr_resolution = EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity); - dst_info.expr_expand_info = src_info->expr_expand_info; - dst_info.expr_expand_range_info = EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil); - dst_info.expr_expand_id_from_num = EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity); - dst_info.expr_expand_num_from_id = EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity); - ev_view_rule_info_table_push(scratch.arena, view_rule_info_table, &dst_info); - } - } - } - ev_select_view_rule_info_table(view_rule_info_table); + e_select_interpret_ctx(interpret_ctx); //////////////////////////// - //- rjf: build eval visualization auto-view-rule table + //- rjf: build eval expand rule table // - EV_AutoViewRuleTable *auto_view_rule_table = push_array(scratch.arena, EV_AutoViewRuleTable, 1); + EV_ExpandRuleTable *expand_rule_table = push_array(scratch.arena, EV_ExpandRuleTable, 1); + ev_select_expand_rule_table(expand_rule_table); + + //////////////////////////// + //- rjf: build view ui rule map + // + rd_state->view_ui_rule_map = rd_view_ui_rule_map_make(scratch.arena, 512); { - // ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, e_type_key_cons_base(type(CTRL_CheckB32)), str8_lit("checkbox"), 1); - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, e_type_key_cons_base(type(CTRL_MetaEvalFrameArray)), str8_lit("slice"), 1); - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, e_type_key_cons_base(type(CTRL_MachineMetaEval)), str8_lit("scheduler_machine"), 1); - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, e_type_key_cons_base(type(CTRL_ProcessMetaEval)), str8_lit("scheduler_process"), 1); - for EachElement(idx, rd_collection_name_table) + // TODO(rjf): generate via metaprogram + struct { - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, collection_type_keys[idx], rd_collection_name_table[idx], 1); + String8 name; + RD_ViewUIFunctionType *ui; + EV_ExpandRuleInfoHookFunctionType *expand; } - RD_EntityList auto_view_rules = rd_query_cached_entity_list_with_kind(RD_EntityKind_AutoViewRule); - for(RD_EntityNode *n = auto_view_rules.first; n != 0; n = n->next) + table[] = { - RD_Entity *rule = n->entity; - RD_Entity *src = rd_entity_child_from_kind(rule, RD_EntityKind_Source); - RD_Entity *dst = rd_entity_child_from_kind(rule, RD_EntityKind_Dest); - String8 type_string = src->string; - String8 view_rule_string = dst->string; - E_TokenArray tokens = e_token_array_from_text(scratch.arena, type_string); - E_Parse type_parse = e_parse_type_from_text_tokens(scratch.arena, type_string, &tokens); - E_TypeKey type_key = e_type_from_expr(type_parse.expr); - if(!e_type_key_match(e_type_key_zero(), type_key)) + {str8_lit("text"), RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, + {str8_lit("disasm"), RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, + {str8_lit("memory"), RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, + {str8_lit("bitmap"), RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, + {str8_lit("checkbox"), RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, + {str8_lit("color_rgba"), RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, + {str8_lit("geo3d"), RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, + }; + for EachElement(idx, table) + { + rd_view_ui_rule_map_insert(scratch.arena, rd_state->view_ui_rule_map, table[idx].name, table[idx].ui); + if(table[idx].expand != 0) { - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, type_key, view_rule_string, 0); + ev_expand_rule_table_push_new(scratch.arena, expand_rule_table, table[idx].name, table[idx].expand); } } } - ev_select_auto_view_rule_table(auto_view_rule_table); //////////////////////////// //- rjf: autosave if needed @@ -12254,8 +13979,7 @@ rd_frame(void) //////////////////////////// //- rjf: process top-level graphical commands // - B32 panel_reset_done = 0; - if(depth == 0) + if(rd_state->frame_depth == 0) { for(;rd_next_cmd(&cmd);) RD_RegsScope() { @@ -12267,8 +13991,10 @@ rd_frame(void) rd_request_frame(); // rjf: process command + String8 dst_path = {0}; + String8 bucket_name = {0}; Dir2 split_dir = Dir2_Invalid; - RD_Panel *split_panel = &rd_nil_panel; + RD_Cfg *split_panel = &rd_nil_cfg; U64 panel_sib_off = 0; U64 panel_child_off = 0; Vec2S32 panel_change_dir = {0}; @@ -12277,7 +14003,7 @@ rd_frame(void) //- rjf: default cases case RD_CmdKind_Run: case RD_CmdKind_LaunchAndRun: - case RD_CmdKind_LaunchAndInit: + case RD_CmdKind_LaunchAndStepInto: case RD_CmdKind_StepInto: case RD_CmdKind_StepOver: case RD_CmdKind_Restart: @@ -12285,10 +14011,11 @@ rd_frame(void) CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(processes.count == 0 || kind == RD_CmdKind_Restart) { - RD_EntityList bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - for(RD_EntityNode *n = bps.first; n != 0; n = n->next) + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { - n->entity->u64 = 0; + RD_Cfg *hit_count = rd_cfg_child_from_string_or_alloc(n->v, str8_lit("hit_count")); + rd_cfg_new_replace(hit_count, str8_lit("0")); } } } // fallthrough @@ -12297,7 +14024,6 @@ rd_frame(void) // rjf: try to run engine command if(D_CmdKind_Null < (D_CmdKind)kind && (D_CmdKind)kind < D_CmdKind_COUNT) { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); D_CmdParams params = {0}; params.machine = rd_regs()->machine; params.process = rd_regs()->process; @@ -12309,21 +14035,34 @@ rd_frame(void) params.vaddr = rd_regs()->vaddr; params.prefer_disasm = rd_regs()->prefer_disasm; params.pid = rd_regs()->pid; - if(entity->kind == RD_EntityKind_Target) - { - params.targets.count = 1; - params.targets.v = push_array(scratch.arena, D_Target, params.targets.count); - params.targets.v[0] = rd_d_target_from_entity(entity); - } + params.targets.count = 1; + params.targets.v = push_array(scratch.arena, D_Target, params.targets.count); + params.targets.v[0] = rd_target_from_cfg(scratch.arena, rd_cfg_from_id(rd_regs()->cfg)); d_push_cmd((D_CmdKind)kind, ¶ms); } // rjf: try to open tabs for "view driver" commands +#if 0 // TODO(rjf): @cfg (tab opening) RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(cmd->name); if(view_rule_info != &rd_nil_view_rule_info) { rd_cmd(RD_CmdKind_OpenTab, .string = str8_zero(), .params_tree = md_tree_from_string(scratch.arena, cmd->name)->first); } +#endif + }break; + + //- rjf: top-level lister + case RD_CmdKind_OpenLister: + { + RD_ListerFlags lister_flags = (RD_ListerFlag_LineEdit| + RD_ListerFlag_Descriptions| + RD_ListerFlag_KindLabel| + RD_ListerFlag_Procedures| + RD_ListerFlag_Files| + RD_ListerFlag_Commands| + RD_ListerFlag_Settings| + RD_ListerFlag_SystemProcesses); + rd_cmd(RD_CmdKind_PushQuery, .lister_flags = lister_flags); }break; //- rjf: command fast path @@ -12340,15 +14079,7 @@ rd_frame(void) // rjf: command has required query -> prep query else { - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) - { - arena_clear(window->query_cmd_arena); - window->query_cmd_name = push_str8_copy(window->query_cmd_arena, cmd->regs->cmd_name); - window->query_cmd_regs = rd_regs_copy(window->query_cmd_arena, rd_regs()); - MemoryZeroArray(window->query_cmd_regs_mask); - window->query_view_selected = 1; - } + rd_cmd(RD_CmdKind_PushQuery, .lister_flags = rd_regs()->lister_flags|RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Descriptions); } }break; @@ -12386,76 +14117,66 @@ rd_frame(void) //- rjf: windows case RD_CmdKind_OpenWindow: { - RD_Window *originating_window = rd_window_from_handle(rd_regs()->window); - if(originating_window == 0) + RD_Cfg *old_window = rd_cfg_from_id(rd_regs()->window); + RD_Cfg *bucket = old_window->parent; + if(bucket == &rd_nil_cfg) { - originating_window = rd_state->first_window; + bucket = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); } - OS_Handle preferred_monitor = {0}; - DeferLoop(depth += 1, depth -= 1) + RD_Cfg *new_window = rd_cfg_new(bucket, str8_lit("window")); + RD_Cfg *size = rd_cfg_new(new_window, str8_lit("size")); + rd_cfg_newf(size, "1280"); + rd_cfg_newf(size, "720"); + for(RD_Cfg *old_child = old_window->first; old_child != &rd_nil_cfg; old_child = old_child->next) { - RD_Window *new_ws = rd_window_open(v2f32(1280, 720), preferred_monitor, RD_CfgSrc_User); - if(originating_window) + if(!str8_match(old_child->string, str8_lit("panels"), 0) && + !str8_match(old_child->string, str8_lit("size"), 0) && + !str8_match(old_child->string, str8_lit("pos"), 0) && + !str8_match(old_child->string, str8_lit("monitor"), 0) && + !str8_match(old_child->string, str8_lit("fullscreen"), 0) && + !str8_match(old_child->string, str8_lit("maximized"), 0)) { - MemoryCopy(new_ws->setting_vals, originating_window->setting_vals, sizeof(RD_SettingVal)*RD_SettingCode_COUNT); + RD_Cfg *new_child = rd_cfg_deep_copy(old_child); + rd_cfg_insert_child(new_window, new_window->last, new_child); } } + RD_Cfg *panels = rd_cfg_new(new_window, str8_lit("panels")); + rd_cfg_new(panels, str8_lit("selected")); }break; case RD_CmdKind_CloseWindow: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - if(ws != 0) + RD_CfgList all_windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); + RD_Cfg *wcfg = rd_cfg_from_id(rd_regs()->window); + if(all_windows.count == 1 && all_windows.first->v == wcfg) { - // rjf: is this the last window? -> exit - if(rd_state->first_window == rd_state->last_window && rd_state->first_window == ws) - { - rd_cmd(RD_CmdKind_Exit); - } - - // rjf: not the last window? -> just release this window - else - { - // NOTE(rjf): we need to explicitly release all panel views, because views - // are a global concept and otherwise would leak. - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) - { - rd_panel_release_all_views(panel); - } - - ui_state_release(ws->ui); - DLLRemove(rd_state->first_window, rd_state->last_window, ws); - r_window_unequip(ws->os, ws->r); - os_window_close(ws->os); - arena_release(ws->query_cmd_arena); - arena_release(ws->ctx_menu_arena); - arena_release(ws->drop_completion_arena); - arena_release(ws->hover_eval_arena); - arena_release(ws->autocomp_lister_params_arena); - arena_release(ws->arena); - SLLStackPush(rd_state->free_window, ws); - ws->gen += 1; - } + rd_cmd(RD_CmdKind_Exit); + } + else + { + rd_cfg_release(wcfg); } }break; case RD_CmdKind_ToggleFullscreen: { - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) + RD_Cfg *wcfg = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(wcfg); + if(ws != &rd_nil_window_state) { - os_window_set_fullscreen(window->os, !os_window_is_fullscreen(window->os)); + os_window_set_fullscreen(ws->os, !os_window_is_fullscreen(ws->os)); } }break; case RD_CmdKind_BringToFront: { - RD_Window *last_focused_window = rd_window_from_handle(rd_state->last_focused_window); - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + RD_Cfg *last_focused_wcfg = rd_cfg_from_id(rd_state->last_focused_window); + RD_WindowState *last_focused_ws = rd_window_state_from_cfg(last_focused_wcfg); + if(last_focused_ws == &rd_nil_window_state) { - os_window_set_minimized(w->os, 0); - os_window_focus(last_focused_window->os); + last_focused_ws = rd_state->first_window_state; } - if(last_focused_window != 0) + if(last_focused_ws != &rd_nil_window_state) { - os_window_focus(last_focused_window->os); + os_window_set_minimized(last_focused_ws->os, 0); + os_window_focus(last_focused_ws->os); } }break; @@ -12478,1181 +14199,223 @@ rd_frame(void) //- rjf: config path saving/loading/applying case RD_CmdKind_OpenRecentProject: { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - if(entity->kind == RD_EntityKind_RecentProject) + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); + RD_Cfg *path = rd_cfg_child_from_string(cfg, str8_lit("path")); + if(str8_match(cfg->string, str8_lit("recent_project"), 0) && + path->first->string.size != 0) { - rd_cmd(RD_CmdKind_OpenProject, .file_path = entity->string); + rd_cmd(RD_CmdKind_OpenProject, .file_path = path->first->string); } }break; case RD_CmdKind_OpenUser: case RD_CmdKind_OpenProject: { - //- TODO(rjf): @cfg load & apply user/project data to the cfg data structure -#if 0 + String8 file_root_key = (kind == RD_CmdKind_OpenUser ? str8_lit("user") : str8_lit("project")); + RD_Cfg *file_root = rd_cfg_child_from_string(rd_state->root_cfg, file_root_key); + + //- rjf: load the new file's data + String8 file_path = rd_regs()->file_path; + String8 file_data = os_data_from_file_path(scratch.arena, file_path); + + //- rjf: determine if the file is good + B32 file_is_okay = 0; { - String8 file_root_key = (kind == RD_CmdKind_OpenUser ? str8_lit("user") : str8_lit("project")); - RD_Cfg *file_root = rd_cfg_child_from_string(rd_state->root_cfg, file_root_key); - - //- rjf: eliminate all old state under this file tree - for(RD_Cfg *tln = file_root->first, *next = &rd_nil_cfg; - tln != &rd_nil_cfg; - tln = next) - { - next = tln->next; - rd_cfg_release(tln); - } - - //- rjf: load & parse the new file, generate cfg entities for it - String8 file_path = rd_regs()->file_path; - String8 file_data = os_data_from_file_path(scratch.arena, file_path); - RD_CfgList file_cfg_list = rd_cfg_tree_list_from_string(scratch.arena, file_data); - - //- rjf: insert the new cfg entities into this file tree - for(RD_CfgNode *n = file_cfg_list.first; n != 0; n = n->next) - { - rd_cfg_insert_child(file_root, file_root->last, n->v); - } - } -#endif - - // TODO(rjf): dear lord this is so overcomplicated, this needs to be collapsed down & simplified ASAP - - B32 load_cfg[RD_CfgSrc_COUNT] = {0}; - RD_CfgSrc cfg_src = (RD_CfgSrc)0; - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - load_cfg[src] = (kind == rd_cfg_src_load_cmd_kind_table[src]); - if(load_cfg[src]) - { - cfg_src = src; - } - } - - //- rjf: normalize path - String8 new_path = path_normalized_from_string(scratch.arena, rd_regs()->file_path); - - //- rjf: path -> data - FileProperties props = {0}; - String8 data = {0}; - { - OS_Handle file = os_file_open(OS_AccessFlag_ShareRead|OS_AccessFlag_Read, new_path); - props = os_properties_from_file(file); - data = os_string_from_file_range(scratch.arena, file, r1u64(0, props.size)); - os_file_close(file); - } - - //- rjf: investigate file path/data - B32 file_is_okay = 1; - if(props.modified != 0 && data.size != 0 && !str8_match(str8_prefix(data, 9), str8_lit("// raddbg"), 0) && rd_state->cfg_cached_timestamp[cfg_src] != 0) - { - file_is_okay = 0; - } - - //- rjf: set new config paths - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - if(load_cfg[src]) - { - arena_clear(rd_state->cfg_path_arenas[src]); - rd_state->cfg_paths[src] = push_str8_copy(rd_state->cfg_path_arenas[src], new_path); - } - } - } - - //- rjf: get config file properties - FileProperties cfg_props[RD_CfgSrc_COUNT] = {0}; - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - String8 path = rd_cfg_path_from_src(src); - cfg_props[src] = os_properties_from_file_path(path); - } - } - - //- rjf: load files - String8 cfg_data[RD_CfgSrc_COUNT] = {0}; - U64 cfg_timestamps[RD_CfgSrc_COUNT] = {0}; - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - String8 path = rd_cfg_path_from_src(src); - OS_Handle file = os_file_open(OS_AccessFlag_ShareRead|OS_AccessFlag_Read, path); - FileProperties props = os_properties_from_file(file); - String8 data = os_string_from_file_range(scratch.arena, file, r1u64(0, props.size)); - if(props.modified != 0) - { - cfg_data[src] = data; - cfg_timestamps[src] = props.modified; - } - os_file_close(file); - } - } - - //- rjf: determine if we need to save config - B32 cfg_save[RD_CfgSrc_COUNT] = {0}; - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - cfg_save[src] = (load_cfg[src] && cfg_props[src].created == 0); - } - } - - //- rjf: determine if we need to reload config - B32 cfg_load[RD_CfgSrc_COUNT] = {0}; - B32 cfg_load_any = 0; - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - cfg_load[src] = (load_cfg[src] && ((cfg_save[src] == 0 && rd_state->cfg_cached_timestamp[src] != cfg_timestamps[src]) || cfg_props[src].created == 0)); - cfg_load_any = cfg_load_any || cfg_load[src]; - } - } - - //- rjf: load => build new config table - if(cfg_load_any) - { - arena_clear(rd_state->cfg_arena); - MemoryZeroStruct(&rd_state->cfg_table); - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - rd_cfg_table_push_unparsed_string(rd_state->cfg_arena, &rd_state->cfg_table, cfg_data[src], src); - } - } - - //- rjf: load => dispatch apply - // - // NOTE(rjf): must happen before `save`. we need to create a default before saving, which - // occurs in the 'apply' path. - // - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - if(cfg_load[src]) - { - RD_CmdKind cmd_kind = rd_cfg_src_apply_cmd_kind_table[src]; - rd_cmd(cmd_kind); - rd_state->cfg_cached_timestamp[src] = cfg_timestamps[src]; - } - } - } - - //- rjf: save => dispatch write - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - if(cfg_save[src]) - { - RD_CmdKind cmd_kind = rd_cfg_src_write_cmd_kind_table[src]; - rd_cmd(cmd_kind); - } - } + FileProperties file_props = os_properties_from_file_path(file_path); + file_is_okay = ((file_props.size == 0 && file_props.created == 0) || + str8_match(str8_prefix(file_data, 9), str8_lit("// raddbg"), 0)); } //- rjf: bad file -> alert user if(!file_is_okay) { - log_user_errorf("\"%S\" appears to refer to an existing file which is not a RADDBG config file. This would overwrite the file.", new_path); + log_user_errorf("\"%S\" appears to refer to an existing file which is not a RADDBG config file. This would overwrite the file.", file_path); } - }break; - - //- rjf: loading/applying stateful config changes - case RD_CmdKind_ApplyUserData: - case RD_CmdKind_ApplyProjectData: - { - RD_CfgTable *table = rd_cfg_table(); - OS_HandleArray monitors = os_push_monitors_array(scratch.arena); - //- rjf: get config source - RD_CfgSrc src = RD_CfgSrc_User; - for(RD_CfgSrc s = (RD_CfgSrc)0; s < RD_CfgSrc_COUNT; s = (RD_CfgSrc)(s+1)) + //- rjf: eliminate all old state under this file tree + if(file_is_okay) { - if(kind == rd_cfg_src_apply_cmd_kind_table[s]) + rd_cfg_release_all_children(file_root); + } + + //- rjf: parse the new file, generate cfg entities for it + RD_CfgList file_cfg_list = {0}; + if(file_is_okay) + { + file_cfg_list = rd_cfg_tree_list_from_string(scratch.arena, file_data); + } + + //- rjf: store path + if(file_is_okay) + { + switch(kind) { - src = s; - break; + default:{}break; + case RD_CmdKind_OpenUser: + { + arena_clear(rd_state->user_path_arena); + rd_state->user_path = push_str8_copy(rd_state->user_path_arena, file_path); + }break; + case RD_CmdKind_OpenProject: + { + arena_clear(rd_state->project_path_arena); + rd_state->project_path = push_str8_copy(rd_state->project_path_arena, file_path); + }break; } } - //- rjf: get paths - String8 cfg_path = rd_cfg_path_from_src(src); - String8 cfg_folder = str8_chop_last_slash(cfg_path); - - //- rjf: keep track of recent projects - if(src == RD_CfgSrc_Project) + //- rjf: insert the new cfg entities into this file tree + if(file_is_okay) { - //- TODO(rjf): @cfg keep track of recent projects + for(RD_CfgNode *n = file_cfg_list.first; n != 0; n = n->next) { - RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_CfgList recent_projects = rd_cfg_child_list_from_string(scratch.arena, user, str8_lit("recent_project")); - RD_Cfg *recent_project = &rd_nil_cfg; - for(RD_CfgNode *n = recent_projects.first; n != 0; n = n->next) + rd_cfg_insert_child(file_root, file_root->last, n->v); + } + } + + //- rjf: if config did not open any windows for the user, then we need to open a sensible default + if(file_is_okay && kind == RD_CmdKind_OpenUser) + { + RD_CfgList all_user_windows = rd_cfg_child_list_from_string(scratch.arena, file_root, str8_lit("window")); + if(all_user_windows.count == 0) + { + OS_Handle monitor = os_primary_monitor(); + String8 monitor_name = os_name_from_monitor(scratch.arena, monitor); + Vec2F32 monitor_dim = os_dim_from_monitor(monitor); + F32 monitor_dpi = os_dpi_from_monitor(monitor); + Vec2F32 window_dim = v2f32(monitor_dim.x*4/5, monitor_dim.y*4/5); + RD_Cfg *new_window = rd_cfg_new(file_root, str8_lit("window")); + RD_Cfg *size = rd_cfg_new(new_window, str8_lit("size")); + rd_cfg_newf(size, "%f", window_dim.x); + rd_cfg_newf(size, "%f", window_dim.y); + F32 line_height_guess = 11.f * (monitor_dpi / 96.f); + F32 num_lines_in_monitor_height = monitor_dim.y / line_height_guess; + if(num_lines_in_monitor_height < 100) { - if(path_match_normalized(n->v->string, cfg_path)) - { - recent_project = n->v; - break; - } + rd_cmd(RD_CmdKind_ResetToCompactPanels, .window = new_window->id); } - if(recent_project == &rd_nil_cfg) + else { - recent_project = rd_cfg_new(user, str8_lit("recent_project")); - rd_cfg_new(recent_project, path_normalized_from_string(scratch.arena, cfg_path)); - } - rd_cfg_unhook(user, recent_project); - rd_cfg_insert_child(user, &rd_nil_cfg, recent_project); - recent_projects = rd_cfg_child_list_from_string(scratch.arena, user, str8_lit("recent_project")); - if(recent_projects.count > 32) - { - rd_cfg_release(recent_projects.last->v); + rd_cmd(RD_CmdKind_ResetToDefaultPanels, .window = new_window->id); } } - RD_EntityList recent_projects = rd_query_cached_entity_list_with_kind(RD_EntityKind_RecentProject); - RD_Entity *recent_project = &rd_nil_entity; - for(RD_EntityNode *n = recent_projects.first; n != 0; n = n->next) + } + + //- rjf: if config did not define any keybindings for the user, then we need to build a sensible default + if(file_is_okay && kind == RD_CmdKind_OpenUser) + { + RD_CfgList all_keybindings = rd_cfg_child_list_from_string(scratch.arena, file_root, str8_lit("keybindings")); + if(all_keybindings.count == 0) { - if(path_match_normalized(cfg_path, n->entity->string)) + RD_Cfg *keybindings = rd_cfg_new(file_root, str8_lit("keybindings")); + for EachElement(idx, rd_default_binding_table) { - recent_project = n->entity; + String8 name = rd_default_binding_table[idx].string; + RD_Binding binding = rd_default_binding_table[idx].binding; + RD_Cfg *binding_root = rd_cfg_new(keybindings, str8_zero()); + rd_cfg_new(binding_root, name); + rd_cfg_new(binding_root, os_g_key_cfg_string_table[binding.key]); + if(binding.modifiers & OS_Modifier_Ctrl) {rd_cfg_newf(binding_root, "ctrl");} + if(binding.modifiers & OS_Modifier_Shift) {rd_cfg_newf(binding_root, "shift");} + if(binding.modifiers & OS_Modifier_Alt) {rd_cfg_newf(binding_root, "alt");} + } + } + } + + //- rjf: record recently-opened projects in the user + if(file_is_okay && kind == RD_CmdKind_OpenProject) + { + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_CfgList recent_projects = rd_cfg_child_list_from_string(scratch.arena, user, str8_lit("recent_project")); + RD_Cfg *recent_project = &rd_nil_cfg; + for(RD_CfgNode *n = recent_projects.first; n != 0; n = n->next) + { + if(path_match_normalized(rd_path_from_cfg(n->v), file_path)) + { + recent_project = n->v; break; } } - if(rd_entity_is_nil(recent_project)) + if(recent_project == &rd_nil_cfg) { - recent_project = rd_entity_alloc(rd_entity_root(), RD_EntityKind_RecentProject); - rd_entity_equip_name(recent_project, path_normalized_from_string(scratch.arena, cfg_path)); - rd_entity_equip_cfg_src(recent_project, RD_CfgSrc_User); + recent_project = rd_cfg_new(user, str8_lit("recent_project")); + RD_Cfg *path_root = rd_cfg_new(recent_project, str8_lit("path")); + rd_cfg_new(path_root, path_normalized_from_string(scratch.arena, file_path)); } - } - - //- rjf: eliminate all existing entities which are derived from config - { - for EachEnumVal(RD_EntityKind, k) + rd_cfg_unhook(user, recent_project); + rd_cfg_insert_child(user, &rd_nil_cfg, recent_project); + recent_projects = rd_cfg_child_list_from_string(scratch.arena, user, str8_lit("recent_project")); + if(recent_projects.count > 32) { - RD_EntityKindFlags k_flags = rd_entity_kind_flags_table[k]; - if(k_flags & RD_EntityKindFlag_IsSerializedToConfig) - { - RD_EntityList entities = rd_query_cached_entity_list_with_kind(k); - for(RD_EntityNode *n = entities.first; n != 0; n = n->next) - { - if(n->entity->cfg_src == src) - { - rd_entity_mark_for_deletion(n->entity); - } - } - } - } - } - - //- rjf: apply all entities - { - for EachEnumVal(RD_EntityKind, k) - { - RD_EntityKindFlags k_flags = rd_entity_kind_flags_table[k]; - if(k_flags & RD_EntityKindFlag_IsSerializedToConfig) - { - RD_CfgVal *k_val = rd_cfg_val_from_string(table, d_entity_kind_name_lower_table[k]); - for(RD_CfgTree *k_tree = k_val->first; - k_tree != &d_nil_cfg_tree; - k_tree = k_tree->next) - { - if(k_tree->source != src) - { - continue; - } - RD_Entity *entity = rd_entity_alloc(rd_entity_root(), k); - rd_entity_equip_cfg_src(entity, k_tree->source); - - // rjf: iterate config tree - typedef struct Task Task; - struct Task - { - Task *next; - RD_Entity *entity; - MD_Node *n; - }; - Task start_task = {0, entity, k_tree->root}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - MD_Node *node = t->n; - for MD_EachNode(child, node->first) - { - // rjf: standalone string literals under an entity -> name - if(child->flags & MD_NodeFlag_StringLiteral && child->first == &md_nil_node) - { - String8 string = raw_from_escaped_str8(scratch.arena, child->string); - // TODO(rjf): @hack - hardcoding in the "EntityKind_Location" here - this is because - // i am assuming an entity *kind* can 'know' about the 'pathness' of a string. this is - // not the case. post-0.9.12 i need to fix this. - if(rd_entity_kind_flags_table[t->entity->kind] & RD_EntityKindFlag_NameIsPath && - t->entity->kind != RD_EntityKind_Location) - { - string = path_absolute_dst_from_relative_dst_src(scratch.arena, string, cfg_folder); - } - rd_entity_equip_name(t->entity, string); - } - - // rjf: standalone string literals under an entity, with a numeric child -> name & text location - if(child->flags & MD_NodeFlag_StringLiteral && child->first->flags & MD_NodeFlag_Numeric && child->first->first == &md_nil_node) - { - String8 string = raw_from_escaped_str8(scratch.arena, child->string); - if(rd_entity_kind_flags_table[t->entity->kind] & RD_EntityKindFlag_NameIsPath) - { - string = path_absolute_dst_from_relative_dst_src(scratch.arena, string, cfg_folder); - } - rd_entity_equip_name(t->entity, string); - S64 line = 0; - try_s64_from_str8_c_rules(child->first->string, &line); - TxtPt pt = txt_pt(line, 1); - rd_entity_equip_txt_pt(t->entity, pt); - } - - // rjf: standalone hex literals under an entity -> vaddr - if(child->flags & MD_NodeFlag_Numeric && child->first == &md_nil_node && str8_match(str8_substr(child->string, r1u64(0, 2)), str8_lit("0x"), 0)) - { - U64 vaddr = 0; - try_u64_from_str8_c_rules(child->string, &vaddr); - rd_entity_equip_vaddr(t->entity, vaddr); - } - - // rjf: specifically named entity equipment - if((str8_match(child->string, str8_lit("name"), StringMatchFlag_CaseInsensitive) || - str8_match(child->string, str8_lit("label"), StringMatchFlag_CaseInsensitive)) && - child->first != &md_nil_node) - { - String8 string = raw_from_escaped_str8(scratch.arena, child->first->string); - // TODO(rjf): @hack - hardcoding in the "EntityKind_Location" here - this is because - // i am assuming an entity *kind* can 'know' about the 'pathness' of a string. this is - // not the case. post-0.9.12 i need to fix this. - if(rd_entity_kind_flags_table[t->entity->kind] & RD_EntityKindFlag_NameIsPath && - (t->entity->kind != RD_EntityKind_Location || !md_node_is_nil(md_child_from_string(node, str8_lit("line"), 0)))) - { - string = path_absolute_dst_from_relative_dst_src(scratch.arena, string, cfg_folder); - } - rd_entity_equip_name(t->entity, string); - } - if((str8_match(child->string, str8_lit("active"), StringMatchFlag_CaseInsensitive) || - str8_match(child->string, str8_lit("enabled"), StringMatchFlag_CaseInsensitive)) && - child->first != &md_nil_node) - { - rd_entity_equip_disabled(t->entity, !str8_match(child->first->string, str8_lit("1"), 0)); - } - if(str8_match(child->string, str8_lit("disabled"), StringMatchFlag_CaseInsensitive) && child->first != &md_nil_node) - { - rd_entity_equip_disabled(t->entity, str8_match(child->first->string, str8_lit("1"), 0)); - } - if(str8_match(child->string, str8_lit("debug_subprocesses"), StringMatchFlag_CaseInsensitive) && child->first != &md_nil_node) - { - t->entity->debug_subprocesses = str8_match(child->first->string, str8_lit("1"), 0); - } - if(str8_match(child->string, str8_lit("hsva"), StringMatchFlag_CaseInsensitive) && child->first != &md_nil_node) - { - Vec4F32 hsva = {0}; - hsva.x = (F32)f64_from_str8(child->first->string); - hsva.y = (F32)f64_from_str8(child->first->next->string); - hsva.z = (F32)f64_from_str8(child->first->next->next->string); - hsva.w = (F32)f64_from_str8(child->first->next->next->next->string); - rd_entity_equip_color_hsva(t->entity, hsva); - } - if(str8_match(child->string, str8_lit("color"), StringMatchFlag_CaseInsensitive) && child->first != &md_nil_node) - { - Vec4F32 rgba = rgba_from_hex_string_4f32(child->first->string); - Vec4F32 hsva = hsva_from_rgba(rgba); - rd_entity_equip_color_hsva(t->entity, hsva); - } - if(str8_match(child->string, str8_lit("line"), StringMatchFlag_CaseInsensitive) && child->first != &md_nil_node) - { - S64 line = 0; - try_s64_from_str8_c_rules(child->first->string, &line); - TxtPt pt = txt_pt(line, 1); - rd_entity_equip_txt_pt(t->entity, pt); - } - if((str8_match(child->string, str8_lit("vaddr"), StringMatchFlag_CaseInsensitive) || - str8_match(child->string, str8_lit("addr"), StringMatchFlag_CaseInsensitive)) && - child->first != &md_nil_node) - { - U64 vaddr = 0; - try_u64_from_str8_c_rules(child->first->string, &vaddr); - rd_entity_equip_vaddr(t->entity, vaddr); - } - - // rjf: sub-entity -> create new task - RD_EntityKind sub_entity_kind = RD_EntityKind_Nil; - for EachEnumVal(RD_EntityKind, k2) - { - if(child->flags & MD_NodeFlag_Identifier && child->first != &md_nil_node && - (str8_match(child->string, d_entity_kind_name_lower_table[k2], StringMatchFlag_CaseInsensitive) || - (k2 == RD_EntityKind_Executable && str8_match(child->string, str8_lit("exe"), StringMatchFlag_CaseInsensitive)))) - { - Task *task = push_array(scratch.arena, Task, 1); - task->next = t->next; - task->entity = rd_entity_alloc(t->entity, k2); - task->n = child; - t->next = task; - break; - } - } - } - } - } - } - } - } - - //- rjf: apply exception code filters - RD_CfgVal *filter_tables = rd_cfg_val_from_string(table, str8_lit("exception_code_filters")); - for(RD_CfgTree *table = filter_tables->first; - table != &d_nil_cfg_tree; - table = table->next) - { - for MD_EachNode(rule, table->root->first) - { - String8 name = rule->string; - String8 val_string = rule->first->string; - U64 val = 0; - if(try_u64_from_str8_c_rules(val_string, &val)) - { - CTRL_ExceptionCodeKind kind = CTRL_ExceptionCodeKind_Null; - for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)(CTRL_ExceptionCodeKind_Null+1); - k < CTRL_ExceptionCodeKind_COUNT; - k = (CTRL_ExceptionCodeKind)(k+1)) - { - if(str8_match(name, ctrl_exception_code_kind_lowercase_code_string_table[k], 0)) - { - kind = k; - break; - } - } - if(kind != CTRL_ExceptionCodeKind_Null) - { - if(val) - { - rd_state->ctrl_exception_code_filters[kind/64] |= (1ull<<(kind%64)); - } - else - { - rd_state->ctrl_exception_code_filters[kind/64] &= ~(1ull<<(kind%64)); - } - } - } - } - } - - //- rjf: eliminate all windows - for(RD_Window *window = rd_state->first_window; window != 0; window = window->next) - { - if(window->cfg_src != src) - { - continue; - } - rd_cmd(RD_CmdKind_CloseWindow, .window = rd_handle_from_window(window)); - } - - //- rjf: apply fonts - { - FNT_Tag defaults[RD_FontSlot_COUNT] = - { - fnt_tag_from_static_data_string(&rd_default_main_font_bytes), - fnt_tag_from_static_data_string(&rd_default_code_font_bytes), - fnt_tag_from_static_data_string(&rd_icon_font_bytes), - }; - MemoryZeroArray(rd_state->cfg_font_tags); - { - RD_CfgVal *code_font_val = rd_cfg_val_from_string(table, str8_lit("code_font")); - RD_CfgVal *main_font_val = rd_cfg_val_from_string(table, str8_lit("main_font")); - MD_Node *code_font_node = code_font_val->last->root; - MD_Node *main_font_node = main_font_val->last->root; - String8 code_font_relative_path = code_font_node->first->string; - String8 main_font_relative_path = main_font_node->first->string; - if(!md_node_is_nil(code_font_node)) - { - arena_clear(rd_state->cfg_code_font_path_arena); - rd_state->cfg_code_font_path = raw_from_escaped_str8(rd_state->cfg_code_font_path_arena, code_font_relative_path); - } - if(!md_node_is_nil(main_font_node)) - { - arena_clear(rd_state->cfg_main_font_path_arena); - rd_state->cfg_main_font_path = raw_from_escaped_str8(rd_state->cfg_main_font_path_arena, main_font_relative_path); - } - String8 code_font_path = path_absolute_dst_from_relative_dst_src(scratch.arena, code_font_relative_path, cfg_folder); - String8 main_font_path = path_absolute_dst_from_relative_dst_src(scratch.arena, main_font_relative_path, cfg_folder); - if(os_file_path_exists(code_font_path) && !md_node_is_nil(code_font_node) && code_font_relative_path.size != 0) - { - rd_state->cfg_font_tags[RD_FontSlot_Code] = fnt_tag_from_path(code_font_path); - } - if(os_file_path_exists(main_font_path) && !md_node_is_nil(main_font_node) && main_font_relative_path.size != 0) - { - rd_state->cfg_font_tags[RD_FontSlot_Main] = fnt_tag_from_path(main_font_path); - } - } - for(RD_FontSlot slot = (RD_FontSlot)0; slot < RD_FontSlot_COUNT; slot = (RD_FontSlot)(slot+1)) - { - if(fnt_tag_match(fnt_tag_zero(), rd_state->cfg_font_tags[slot])) - { - rd_state->cfg_font_tags[slot] = defaults[slot]; - } - } - } - - //- rjf: build windows & panel layouts - RD_CfgVal *windows = rd_cfg_val_from_string(table, str8_lit("window")); - for(RD_CfgTree *window_tree = windows->first; - window_tree != &d_nil_cfg_tree; - window_tree = window_tree->next) - { - // rjf: skip wrong source - if(window_tree->source != src) - { - continue; - } - - // rjf: grab metadata - B32 is_fullscreen = 0; - B32 is_maximized = 0; - Axis2 top_level_split_axis = Axis2_X; - OS_Handle preferred_monitor = os_primary_monitor(); - Vec2F32 size = {0}; - F32 dpi = 0.f; - RD_SettingVal setting_vals[RD_SettingCode_COUNT] = {0}; - { - for MD_EachNode(n, window_tree->root->first) - { - if(n->flags & MD_NodeFlag_Identifier && - md_node_is_nil(n->first) && - str8_match(n->string, str8_lit("split_x"), StringMatchFlag_CaseInsensitive)) - { - top_level_split_axis = Axis2_X; - } - if(n->flags & MD_NodeFlag_Identifier && - md_node_is_nil(n->first) && - str8_match(n->string, str8_lit("split_y"), StringMatchFlag_CaseInsensitive)) - { - top_level_split_axis = Axis2_Y; - } - if(n->flags & MD_NodeFlag_Identifier && - md_node_is_nil(n->first) && - str8_match(n->string, str8_lit("fullscreen"), StringMatchFlag_CaseInsensitive)) - { - is_fullscreen = 1; - } - if(n->flags & MD_NodeFlag_Identifier && - md_node_is_nil(n->first) && - str8_match(n->string, str8_lit("maximized"), StringMatchFlag_CaseInsensitive)) - { - is_maximized = 1; - } - } - MD_Node *monitor_node = md_child_from_string(window_tree->root, str8_lit("monitor"), 0); - String8 preferred_monitor_name = monitor_node->first->string; - for(U64 idx = 0; idx < monitors.count; idx += 1) - { - String8 monitor_name = os_name_from_monitor(scratch.arena, monitors.v[idx]); - if(str8_match(monitor_name, preferred_monitor_name, StringMatchFlag_CaseInsensitive)) - { - preferred_monitor = monitors.v[idx]; - break; - } - } - Vec2F32 preferred_monitor_size = os_dim_from_monitor(preferred_monitor); - MD_Node *size_node = md_child_from_string(window_tree->root, str8_lit("size"), 0); - { - String8 x_string = size_node->first->string; - String8 y_string = size_node->first->next->string; - U64 x_u64 = 0; - U64 y_u64 = 0; - if(!try_u64_from_str8_c_rules(x_string, &x_u64)) - { - x_u64 = (U64)(preferred_monitor_size.x*2/3); - } - if(!try_u64_from_str8_c_rules(y_string, &y_u64)) - { - y_u64 = (U64)(preferred_monitor_size.y*2/3); - } - size.x = (F32)x_u64; - size.y = (F32)y_u64; - } - MD_Node *dpi_node = md_child_from_string(window_tree->root, str8_lit("dpi"), 0); - String8 dpi_string = md_string_from_children(scratch.arena, dpi_node); - dpi = f64_from_str8(dpi_string); - for EachEnumVal(RD_SettingCode, code) - { - MD_Node *code_node = md_child_from_string(window_tree->root, rd_setting_code_lower_string_table[code], 0); - if(!md_node_is_nil(code_node)) - { - S64 val_s64 = 0; - try_s64_from_str8_c_rules(code_node->first->string, &val_s64); - setting_vals[code].set = 1; - setting_vals[code].s32 = (S32)val_s64; - setting_vals[code].s32 = clamp_1s32(rd_setting_code_s32_range_table[code], setting_vals[code].s32); - } - } - } - - // rjf: open window - RD_Window *ws = rd_window_open(size, preferred_monitor, window_tree->source); - if(dpi != 0.f) { ws->last_dpi = dpi; } - for EachEnumVal(RD_SettingCode, code) - { - if(setting_vals[code].set == 0 && rd_setting_code_default_is_per_window_table[code]) - { - setting_vals[code] = rd_setting_code_default_val_table[code]; - } - } - MemoryCopy(ws->setting_vals, setting_vals, sizeof(setting_vals[0])*ArrayCount(setting_vals)); - - // rjf: build panel tree - MD_Node *panel_tree = md_child_from_string(window_tree->root, str8_lit("panels"), 0); - RD_Panel *panel_parent = ws->root_panel; - panel_parent->split_axis = top_level_split_axis; - MD_NodeRec rec = {0}; - for(MD_Node *n = panel_tree, *next = &md_nil_node; - !md_node_is_nil(n); - n = next) - { - // rjf: assume we're just moving to the next one initially... - next = n->next; - - // rjf: grab root panel - RD_Panel *panel = &rd_nil_panel; - if(n == panel_tree) - { - panel = ws->root_panel; - panel->pct_of_parent = 1.f; - } - - // rjf: allocate & insert non-root panels - these will have a numeric string, determining - // pct of parent - if(n->flags & MD_NodeFlag_Numeric) - { - panel = rd_panel_alloc(ws); - rd_panel_insert(panel_parent, panel_parent->last, panel); - panel->split_axis = axis2_flip(panel_parent->split_axis); - panel->pct_of_parent = (F32)f64_from_str8(n->string); - } - - // rjf: do general per-panel work - if(!rd_panel_is_nil(panel)) - { - // rjf: determine if this panel has panel children - B32 has_panel_children = 0; - for MD_EachNode(child, n->first) - { - if(child->flags & MD_NodeFlag_Numeric) - { - has_panel_children = 1; - break; - } - } - - // rjf: apply panel options - for MD_EachNode(op, n->first) - { - if(md_node_is_nil(op->first) && str8_match(op->string, str8_lit("tabs_on_bottom"), 0)) - { - panel->tab_side = Side_Max; - } - } - - // rjf: apply panel views/tabs/commands - RD_View *selected_view = &rd_nil_view; - for MD_EachNode(op, n->first) - { - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(op->string); - if(view_rule_info == &rd_nil_view_rule_info || has_panel_children != 0) - { - continue; - } - - // rjf: allocate view & apply view-specific parameterizations - RD_View *view = &rd_nil_view; - B32 view_is_selected = 0; - RD_ViewRuleInfoFlags view_rule_info_flags = view_rule_info->flags; - { - // rjf: allocate view - view = rd_view_alloc(); - - // rjf: check if this view is selected - view_is_selected = !md_node_is_nil(md_child_from_string(op, str8_lit("selected"), 0)); - - // rjf: read project path - String8 project_path = str8_lit(""); - { - MD_Node *project_node = md_child_from_string(op, str8_lit("project"), 0); - if(!md_node_is_nil(project_node)) - { - project_path = path_absolute_dst_from_relative_dst_src(scratch.arena, project_node->first->string, cfg_folder); - } - } - - // rjf: read view query string - String8 view_query = str8_lit(""); - { - String8 escaped_query = md_child_from_string(op, str8_lit("query"), 0)->first->string; - view_query = raw_from_escaped_str8(scratch.arena, escaped_query); - } - - // rjf: convert file queries from relative to absolute - { - String8 query_file_path = rd_file_path_from_eval_string(scratch.arena, view_query); - if(query_file_path.size != 0) - { - query_file_path = path_absolute_dst_from_relative_dst_src(scratch.arena, query_file_path, cfg_folder); - view_query = push_str8f(scratch.arena, "file:\"%S\"", query_file_path); - } - } - - // rjf: set up view - rd_view_equip_spec(view, view_rule_info, view_query, op); - if(project_path.size != 0) - { - arena_clear(view->project_path_arena); - view->project_path = push_str8_copy(view->project_path_arena, project_path); - } - } - - // rjf: insert - if(!rd_view_is_nil(view)) - { - rd_panel_insert_tab_view(panel, panel->last_tab_view, view); - if(view_is_selected) - { - selected_view = view; - } - } - } - - // rjf: select selected view - if(!rd_view_is_nil(selected_view)) - { - panel->selected_tab_view = rd_handle_from_view(selected_view); - } - - // rjf: recurse from this panel - if(has_panel_children) - { - next = n->first; - panel_parent = panel; - } - else for(MD_Node *p = n; - p != &md_nil_node && p != panel_tree; - p = p->parent, panel_parent = panel_parent->parent) - { - if(p->next != &md_nil_node) - { - next = p->next; - break; - } - } - } - } - - // rjf: initiate fullscreen - if(is_fullscreen) - { - os_window_set_fullscreen(ws->os, 1); - } - - // rjf: initiate maximize - if(is_maximized) - { - os_window_set_maximized(ws->os, 1); - } - - // rjf: focus the biggest panel - { - RD_Panel *best_leaf_panel = &rd_nil_panel; - F32 best_leaf_panel_area = 0; - Rng2F32 root_rect = r2f32p(0, 0, 1000, 1000); // NOTE(rjf): we can assume any size - just need proportions. - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) - { - if(rd_panel_is_nil(panel->first)) - { - Rng2F32 rect = rd_target_rect_from_panel(root_rect, ws->root_panel, panel); - Vec2F32 dim = dim_2f32(rect); - F32 area = dim.x*dim.y; - if(best_leaf_panel_area == 0 || area > best_leaf_panel_area) - { - best_leaf_panel_area = area; - best_leaf_panel = panel; - } - } - } - ws->focused_panel = best_leaf_panel; - } - } - - //- rjf: apply keybindings - if(src == RD_CfgSrc_User) - { - rd_clear_bindings(); - } - RD_CfgVal *keybindings = rd_cfg_val_from_string(table, str8_lit("keybindings")); - for(RD_CfgTree *keybinding_set = keybindings->first; - keybinding_set != &d_nil_cfg_tree; - keybinding_set = keybinding_set->next) - { - for MD_EachNode(keybind, keybinding_set->root->first) - { - String8 cmd_name = {0}; - OS_Key key = OS_Key_Null; - MD_Node *ctrl_node = &md_nil_node; - MD_Node *shift_node = &md_nil_node; - MD_Node *alt_node = &md_nil_node; - for MD_EachNode(child, keybind->first) - { - if(str8_match(child->string, str8_lit("ctrl"), 0)) - { - ctrl_node = child; - } - else if(str8_match(child->string, str8_lit("shift"), 0)) - { - shift_node = child; - } - else if(str8_match(child->string, str8_lit("alt"), 0)) - { - alt_node = child; - } - else - { - OS_Key k = rd_os_key_from_cfg_string(child->string); - if(k != OS_Key_Null) - { - key = k; - } - else - { - cmd_name = child->string; - for(U64 idx = 0; idx < ArrayCount(rd_binding_version_remap_old_name_table); idx += 1) - { - if(str8_match(rd_binding_version_remap_old_name_table[idx], child->string, StringMatchFlag_CaseInsensitive)) - { - String8 new_name = rd_binding_version_remap_new_name_table[idx]; - cmd_name = new_name; - } - } - } - } - } - if(cmd_name.size != 0 && key != OS_Key_Null) - { - OS_Modifiers flags = 0; - if(!md_node_is_nil(ctrl_node)) { flags |= OS_Modifier_Ctrl; } - if(!md_node_is_nil(shift_node)) { flags |= OS_Modifier_Shift; } - if(!md_node_is_nil(alt_node)) { flags |= OS_Modifier_Alt; } - RD_Binding binding = {key, flags}; - rd_bind_name(cmd_name, binding); - } - } - } - - //- rjf: reset theme to default - MemoryCopy(rd_state->cfg_theme_target.colors, rd_theme_preset_colors__default_dark, sizeof(rd_theme_preset_colors__default_dark)); - MemoryCopy(rd_state->cfg_theme.colors, rd_theme_preset_colors__default_dark, sizeof(rd_theme_preset_colors__default_dark)); - - //- rjf: apply theme presets - RD_CfgVal *color_preset = rd_cfg_val_from_string(table, str8_lit("color_preset")); - B32 preset_applied = 0; - if(color_preset != &d_nil_cfg_val) - { - String8 color_preset_name = color_preset->last->root->first->string; - RD_ThemePreset preset = (RD_ThemePreset)0; - B32 found_preset = 0; - for(RD_ThemePreset p = (RD_ThemePreset)0; p < RD_ThemePreset_COUNT; p = (RD_ThemePreset)(p+1)) - { - if(str8_match(color_preset_name, rd_theme_preset_code_string_table[p], StringMatchFlag_CaseInsensitive)) - { - found_preset = 1; - preset = p; - break; - } - } - if(found_preset) - { - preset_applied = 1; - MemoryCopy(rd_state->cfg_theme_target.colors, rd_theme_preset_colors_table[preset], sizeof(rd_theme_preset_colors__default_dark)); - MemoryCopy(rd_state->cfg_theme.colors, rd_theme_preset_colors_table[preset], sizeof(rd_theme_preset_colors__default_dark)); - } - } - - //- rjf: apply individual theme colors - B8 theme_color_hit[RD_ThemeColor_COUNT] = {0}; - RD_CfgVal *colors = rd_cfg_val_from_string(table, str8_lit("colors")); - for(RD_CfgTree *colors_set = colors->first; - colors_set != &d_nil_cfg_tree; - colors_set = colors_set->next) - { - for MD_EachNode(color, colors_set->root->first) - { - String8 saved_color_name = color->string; - String8List candidate_color_names = {0}; - str8_list_push(scratch.arena, &candidate_color_names, saved_color_name); - for(U64 idx = 0; idx < ArrayCount(rd_theme_color_version_remap_old_name_table); idx += 1) - { - if(str8_match(rd_theme_color_version_remap_old_name_table[idx], saved_color_name, StringMatchFlag_CaseInsensitive)) - { - str8_list_push(scratch.arena, &candidate_color_names, rd_theme_color_version_remap_new_name_table[idx]); - } - } - for(String8Node *name_n = candidate_color_names.first; name_n != 0; name_n = name_n->next) - { - String8 name = name_n->string; - RD_ThemeColor color_code = RD_ThemeColor_Null; - for(RD_ThemeColor c = RD_ThemeColor_Null; c < RD_ThemeColor_COUNT; c = (RD_ThemeColor)(c+1)) - { - if(str8_match(rd_theme_color_cfg_string_table[c], name, StringMatchFlag_CaseInsensitive)) - { - color_code = c; - break; - } - } - if(color_code != RD_ThemeColor_Null) - { - theme_color_hit[color_code] = 1; - MD_Node *hex_cfg = color->first; - String8 hex_string = hex_cfg->string; - U64 hex_val = 0; - try_u64_from_str8_c_rules(hex_string, &hex_val); - Vec4F32 color_rgba = rgba_from_u32((U32)hex_val); - rd_state->cfg_theme_target.colors[color_code] = color_rgba; - if(rd_state->frame_index <= 2) - { - rd_state->cfg_theme.colors[color_code] = color_rgba; - } - } - } - } - } - - //- rjf: no preset -> autofill all missing colors from the preset with the most similar background - if(!preset_applied) - { - RD_ThemePreset closest_preset = RD_ThemePreset_DefaultDark; - F32 closest_preset_bg_distance = 100000000; - for(RD_ThemePreset p = (RD_ThemePreset)0; p < RD_ThemePreset_COUNT; p = (RD_ThemePreset)(p+1)) - { - Vec4F32 cfg_bg = rd_state->cfg_theme_target.colors[RD_ThemeColor_BaseBackground]; - Vec4F32 pre_bg = rd_theme_preset_colors_table[p][RD_ThemeColor_BaseBackground]; - Vec4F32 diff = sub_4f32(cfg_bg, pre_bg); - Vec3F32 diff3 = diff.xyz; - F32 distance = length_3f32(diff3); - if(distance < closest_preset_bg_distance) - { - closest_preset = p; - closest_preset_bg_distance = distance; - } - } - for(RD_ThemeColor c = (RD_ThemeColor)(RD_ThemeColor_Null+1); - c < RD_ThemeColor_COUNT; - c = (RD_ThemeColor)(c+1)) - { - if(!theme_color_hit[c]) - { - rd_state->cfg_theme_target.colors[c] = rd_state->cfg_theme.colors[c] = rd_theme_preset_colors_table[closest_preset][c]; - } - } - } - - //- rjf: if theme colors are all zeroes, then set to default - config appears busted - { - B32 all_colors_are_zero = 1; - Vec4F32 zero_color = {0}; - for(RD_ThemeColor c = (RD_ThemeColor)(RD_ThemeColor_Null+1); c < RD_ThemeColor_COUNT; c = (RD_ThemeColor)(c+1)) - { - if(!MemoryMatchStruct(&rd_state->cfg_theme_target.colors[c], &zero_color)) - { - all_colors_are_zero = 0; - break; - } - } - if(all_colors_are_zero) - { - MemoryCopy(rd_state->cfg_theme_target.colors, rd_theme_preset_colors__default_dark, sizeof(rd_theme_preset_colors__default_dark)); - MemoryCopy(rd_state->cfg_theme.colors, rd_theme_preset_colors__default_dark, sizeof(rd_theme_preset_colors__default_dark)); - } - } - - //- rjf: apply settings - B8 setting_codes_hit[RD_SettingCode_COUNT] = {0}; - MemoryZero(&rd_state->cfg_setting_vals[src][0], sizeof(RD_SettingVal)*RD_SettingCode_COUNT); - for EachEnumVal(RD_SettingCode, code) - { - String8 name = rd_setting_code_lower_string_table[code]; - RD_CfgVal *code_cfg_val = rd_cfg_val_from_string(table, name); - RD_CfgTree *code_tree = code_cfg_val->last; - if(code_tree->source == src) - { - MD_Node *val_node = code_tree->root->first; - S64 val = 0; - if(try_s64_from_str8_c_rules(val_node->string, &val)) - { - rd_state->cfg_setting_vals[src][code].set = 1; - rd_state->cfg_setting_vals[src][code].s32 = (S32)val; - } - setting_codes_hit[code] = !md_node_is_nil(val_node); - } - } - - //- rjf: if config applied 0 settings, we need to do some sensible default - if(src == RD_CfgSrc_User) - { - for EachEnumVal(RD_SettingCode, code) - { - if(!setting_codes_hit[code]) - { - rd_state->cfg_setting_vals[src][code] = rd_setting_code_default_val_table[code]; - } - } - } - - //- rjf: if config opened 0 windows, we need to do some sensible default - if(src == RD_CfgSrc_User && windows->first == &d_nil_cfg_tree) - { - OS_Handle preferred_monitor = os_primary_monitor(); - Vec2F32 monitor_dim = os_dim_from_monitor(preferred_monitor); - Vec2F32 window_dim = v2f32(monitor_dim.x*4/5, monitor_dim.y*4/5); - RD_Window *ws = rd_window_open(window_dim, preferred_monitor, RD_CfgSrc_User); - F32 font_size = (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32; - F32 num_lines_in_monitor_height = monitor_dim.y / font_size; - if(num_lines_in_monitor_height < 100) - { - rd_cmd(RD_CmdKind_ResetToCompactPanels, .window = rd_handle_from_window(ws)); - } - else - { - rd_cmd(RD_CmdKind_ResetToDefaultPanels, .window = rd_handle_from_window(ws)); - } - } - - //- rjf: if config bound 0 keys, we need to do some sensible default - if(src == RD_CfgSrc_User && rd_state->key_map_total_count == 0) - { - for(U64 idx = 0; idx < ArrayCount(rd_default_binding_table); idx += 1) - { - RD_StringBindingPair *pair = &rd_default_binding_table[idx]; - rd_bind_name(pair->string, pair->binding); - } - } - - //- rjf: always ensure that the meta controls have bindings - if(src == RD_CfgSrc_User) - { - struct - { - String8 name; - OS_Key fallback_key; - } - meta_ctrls[] = - { - { rd_cmd_kind_info_table[RD_CmdKind_Edit].string, OS_Key_F2 }, - { rd_cmd_kind_info_table[RD_CmdKind_Accept].string, OS_Key_Return }, - { rd_cmd_kind_info_table[RD_CmdKind_Cancel].string, OS_Key_Esc }, - }; - for(U64 idx = 0; idx < ArrayCount(meta_ctrls); idx += 1) - { - RD_BindingList bindings = rd_bindings_from_name(scratch.arena, meta_ctrls[idx].name); - if(bindings.count == 0) - { - RD_Binding binding = {meta_ctrls[idx].fallback_key, 0}; - rd_bind_name(meta_ctrls[idx].name, binding); - } + rd_cfg_release(recent_projects.last->v); } } }break; //- rjf: writing config changes - case RD_CmdKind_WriteUserData: - case RD_CmdKind_WriteProjectData: + case RD_CmdKind_WriteUserData: dst_path = rd_state->user_path; bucket_name = str8_lit("user"); goto write; + case RD_CmdKind_WriteProjectData: dst_path = rd_state->project_path; bucket_name = str8_lit("project"); goto write; + write:; { - RD_CfgSrc src = RD_CfgSrc_User; - for(RD_CfgSrc s = (RD_CfgSrc)0; s < RD_CfgSrc_COUNT; s = (RD_CfgSrc)(s+1)) + B32 dst_exists = (os_properties_from_file_path(dst_path).created != 0); + String8 temp_path = push_str8f(scratch.arena, "%S.temp", dst_path); + String8 overwritten_path = push_str8f(scratch.arena, "%S.old", dst_path); + RD_Cfg *tree_root = rd_cfg_child_from_string(rd_state->root_cfg, bucket_name); + String8List strings = {0}; + str8_list_pushf(scratch.arena, &strings, "// raddbg %s %S file\n\n", BUILD_VERSION_STRING_LITERAL, bucket_name); + for(RD_Cfg *child = tree_root->first; child != &rd_nil_cfg; child = child->next) { - if(kind == rd_cfg_src_write_cmd_kind_table[s]) - { - src = s; - break; - } + str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, child)); + } + String8 data = str8_list_join(scratch.arena, &strings, 0); + B32 temp_write_good = os_write_data_to_file_path(temp_path, data); + B32 old_move_good = (temp_write_good && (!dst_exists || os_move_file_path(overwritten_path, dst_path))); + B32 new_move_good = (old_move_good && os_move_file_path(dst_path, temp_path)); + if(new_move_good && dst_exists) + { + os_delete_file_at_path(overwritten_path); + } + else if(!new_move_good && old_move_good && dst_exists) + { + os_move_file_path(dst_path, overwritten_path); } - String8 path = rd_cfg_path_from_src(src); - String8List rd_strs = rd_cfg_strings_from_gfx(scratch.arena, path, src); - String8 header = push_str8f(scratch.arena, "// raddbg %s file\n\n", rd_cfg_src_string_table[src].str); - String8List strs = {0}; - str8_list_push(scratch.arena, &strs, header); - str8_list_concat_in_place(&strs, &rd_strs); - String8 data = str8_list_join(scratch.arena, &strs, 0); - String8 data_indented = indented_from_string(scratch.arena, data); - os_write_data_to_file_path(path, data_indented); - }break; - - //- rjf: code navigation - case RD_CmdKind_FindTextForward: - case RD_CmdKind_FindTextBackward: - { - rd_set_search_string(rd_regs()->string); - }break; - - //- rjf: find next and find prev - case RD_CmdKind_FindNext: - { - rd_cmd(RD_CmdKind_FindTextForward, .string = rd_push_search_string(scratch.arena)); - }break; - case RD_CmdKind_FindPrev: - { - rd_cmd(RD_CmdKind_FindTextBackward, .string = rd_push_search_string(scratch.arena)); }break; //- rjf: font sizes case RD_CmdKind_IncUIFontScale: { fnt_reset(); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) - { - window->setting_vals[RD_SettingCode_MainFontSize].set = 1; - window->setting_vals[RD_SettingCode_MainFontSize].s32 += 1; - window->setting_vals[RD_SettingCode_MainFontSize].s32 = clamp_1s32(rd_setting_code_s32_range_table[RD_SettingCode_MainFontSize], window->setting_vals[RD_SettingCode_MainFontSize].s32); - } + F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); + F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); + rd_cfg_new_replacef(main_font_size, "%f", new_font_size); }break; case RD_CmdKind_DecUIFontScale: { fnt_reset(); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) - { - window->setting_vals[RD_SettingCode_MainFontSize].set = 1; - window->setting_vals[RD_SettingCode_MainFontSize].s32 -= 1; - window->setting_vals[RD_SettingCode_MainFontSize].s32 = clamp_1s32(rd_setting_code_s32_range_table[RD_SettingCode_MainFontSize], window->setting_vals[RD_SettingCode_MainFontSize].s32); - } + F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); + F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); + rd_cfg_new_replacef(main_font_size, "%f", new_font_size); }break; case RD_CmdKind_IncCodeFontScale: { fnt_reset(); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) - { - window->setting_vals[RD_SettingCode_CodeFontSize].set = 1; - window->setting_vals[RD_SettingCode_CodeFontSize].s32 += 1; - window->setting_vals[RD_SettingCode_CodeFontSize].s32 = clamp_1s32(rd_setting_code_s32_range_table[RD_SettingCode_CodeFontSize], window->setting_vals[RD_SettingCode_CodeFontSize].s32); - } + 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_id(rd_regs()->window); + RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); + rd_cfg_new_replacef(code_font_size, "%f", new_font_size); }break; case RD_CmdKind_DecCodeFontScale: { fnt_reset(); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) - { - window->setting_vals[RD_SettingCode_CodeFontSize].set = 1; - window->setting_vals[RD_SettingCode_CodeFontSize].s32 -= 1; - window->setting_vals[RD_SettingCode_CodeFontSize].s32 = clamp_1s32(rd_setting_code_s32_range_table[RD_SettingCode_CodeFontSize], window->setting_vals[RD_SettingCode_CodeFontSize].s32); - } + 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_id(rd_regs()->window); + RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); + rd_cfg_new_replacef(code_font_size, "%f", new_font_size); }break; //- rjf: panel creation @@ -13663,109 +14426,173 @@ rd_frame(void) case RD_CmdKind_SplitPanel: { split_dir = rd_regs()->dir2; - split_panel = rd_panel_from_handle(rd_regs()->dst_panel); + split_panel = rd_cfg_from_id(rd_regs()->dst_panel); }goto split; split:; if(split_dir != Dir2_Invalid) { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - if(rd_panel_is_nil(split_panel)) - { - split_panel = ws->focused_panel; - } - RD_Panel *new_panel = &rd_nil_panel; + // rjf: unpack Axis2 split_axis = axis2_from_dir2(split_dir); Side split_side = side_from_dir2(split_dir); - RD_Panel *panel = split_panel; - RD_Panel *parent = panel->parent; - if(!rd_panel_is_nil(parent) && parent->split_axis == split_axis) + if(split_panel == &rd_nil_cfg) { - RD_Panel *next = rd_panel_alloc(ws); - rd_panel_insert(parent, split_side == Side_Max ? panel : panel->prev, next); - next->pct_of_parent = 1.f/parent->child_count; - for(RD_Panel *child = parent->first; !rd_panel_is_nil(child); child = child->next) - { - if(child != next) - { - child->pct_of_parent *= (F32)(parent->child_count-1) / (parent->child_count); - } - } - ws->focused_panel = next; - new_panel = next; + split_panel = rd_cfg_from_id(rd_regs()->panel); } + RD_Cfg *new_panel_cfg = &rd_nil_cfg; + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, split_panel); + RD_PanelNode *panel_root = panel_tree.root; + RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_root, split_panel); + RD_PanelNode *parent = panel->parent; + + // rjf: splitting on same axis as parent -> insert new sibling on same axis, adjust sizes + if(parent != &rd_nil_panel_node && parent->split_axis == split_axis) + { + RD_Cfg *parent_cfg = parent->cfg; + RD_Cfg *panel_cfg = panel->cfg; + RD_Cfg *new_cfg = rd_cfg_alloc(); + rd_cfg_insert_child(parent_cfg, split_side == Side_Max ? panel_cfg : panel_cfg->prev, new_cfg); + rd_cfg_equip_stringf(new_cfg, "%f", 1.f/(parent->child_count+1)); + for(RD_PanelNode *child = parent->first; child != &rd_nil_panel_node; child = child->next) + { + F32 old_pct = child->pct_of_parent; + F32 new_pct = old_pct * ((F32)(parent->child_count) / (parent->child_count+1)); + rd_cfg_equip_stringf(child->cfg, "%f", new_pct); + } + new_panel_cfg = new_cfg; + } + + // rjf: splitting on opposite axis as parent - need to create new replacement node, + new sibling else { - RD_Panel *pre_prev = panel->prev; - RD_Panel *pre_parent = parent; - RD_Panel *new_parent = rd_panel_alloc(ws); - new_parent->pct_of_parent = panel->pct_of_parent; - if(!rd_panel_is_nil(pre_parent)) + RD_Cfg *split_panel_prev = panel->prev->cfg; + RD_Cfg *new_parent = rd_cfg_alloc(); + RD_Cfg *new_sibling = rd_cfg_alloc(); + rd_cfg_equip_string(new_parent, split_panel->string); + rd_cfg_equip_string(split_panel, str8_lit("0.5")); + rd_cfg_equip_string(new_sibling, str8_lit("0.5")); + if(parent->cfg != &rd_nil_cfg) { - rd_panel_remove(pre_parent, panel); - rd_panel_insert(pre_parent, pre_prev, new_parent); + rd_cfg_unhook(parent->cfg, split_panel); + rd_cfg_insert_child(parent->cfg, split_panel_prev, new_parent); } else { - ws->root_panel = new_parent; + rd_cfg_equip_string(new_parent, str8_lit("panels")); + RD_Cfg *window_cfg = rd_window_from_cfg(split_panel); + rd_cfg_insert_child(window_cfg, window_cfg->last, new_parent); } - RD_Panel *left = panel; - RD_Panel *right = rd_panel_alloc(ws); - new_panel = right; + RD_Cfg *min = split_panel; + RD_Cfg *max = new_sibling; if(split_side == Side_Min) { - Swap(RD_Panel *, left, right); + Swap(RD_Cfg *, min, max); } - rd_panel_insert(new_parent, &rd_nil_panel, left); - rd_panel_insert(new_parent, left, right); - new_parent->split_axis = split_axis; - left->pct_of_parent = 0.5f; - right->pct_of_parent = 0.5f; - ws->focused_panel = new_panel; + rd_cfg_insert_child(new_parent, new_parent->last, min); + rd_cfg_insert_child(new_parent, new_parent->last, max); + new_panel_cfg = new_sibling; } - if(!rd_panel_is_nil(new_panel->prev)) + + // rjf: pre-emptively set up the animation rectangle, depending on where + // the new panel was inserted { - Rng2F32 prev_rect_pct = new_panel->prev->animated_rect_pct; - new_panel->animated_rect_pct = prev_rect_pct; - new_panel->animated_rect_pct.p0.v[split_axis] = new_panel->animated_rect_pct.p1.v[split_axis]; - } - if(!rd_panel_is_nil(new_panel->next)) - { - Rng2F32 next_rect_pct = new_panel->next->animated_rect_pct; - new_panel->animated_rect_pct = next_rect_pct; - new_panel->animated_rect_pct.p1.v[split_axis] = new_panel->animated_rect_pct.p0.v[split_axis]; - } - RD_Panel *move_tab_panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *move_tab = rd_view_from_handle(rd_regs()->view); - if(!rd_panel_is_nil(new_panel) && !rd_view_is_nil(move_tab) && !rd_panel_is_nil(move_tab_panel) && - kind == RD_CmdKind_SplitPanel) - { - rd_panel_remove_tab_view(move_tab_panel, move_tab); - rd_panel_insert_tab_view(new_panel, new_panel->last_tab_view, move_tab); - new_panel->selected_tab_view = rd_handle_from_view(move_tab); - B32 move_tab_panel_is_empty = 1; - for(RD_View *v = move_tab_panel->first_tab_view; !rd_view_is_nil(v); v = v->order_next) + RD_WindowState *ws = rd_window_state_from_cfg(new_panel_cfg); + if(ws != &rd_nil_window_state) { - if(!rd_view_is_project_filtered(v)) + ui_select_state(ws->ui); + RD_PanelTree new_panel_tree = rd_panel_tree_from_cfg(scratch.arena, new_panel_cfg); + RD_PanelNode *new_panel = rd_panel_node_from_tree_cfg(new_panel_tree.root, new_panel_cfg); + Rng2F32 stub_content_rect = r2f32p(0, 0, 1000, 1000); + Vec2F32 stub_content_rect_dim = dim_2f32(stub_content_rect); + Rng2F32 new_rect_px = rd_target_rect_from_panel_node(stub_content_rect, new_panel_tree.root, new_panel); + Rng2F32 new_rect_pct = r2f32p(new_rect_px.x0/stub_content_rect_dim.x, + new_rect_px.y0/stub_content_rect_dim.y, + new_rect_px.x1/stub_content_rect_dim.x, + new_rect_px.y1/stub_content_rect_dim.y); + if(new_panel->prev != &rd_nil_panel_node) { - move_tab_panel_is_empty = 0; - break; + Rng2F32 target_prev_rect_px = rd_target_rect_from_panel_node(stub_content_rect, panel_tree.root, rd_panel_node_from_tree_cfg(panel_tree.root, new_panel->prev->cfg)); + Rng2F32 target_prev_rect_pct = r2f32p(target_prev_rect_px.x0/stub_content_rect_dim.x, + target_prev_rect_px.y0/stub_content_rect_dim.y, + target_prev_rect_px.x1/stub_content_rect_dim.x, + target_prev_rect_px.y1/stub_content_rect_dim.y); + Rng2F32 prev_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->prev->cfg), target_prev_rect_pct.x0, .initial = target_prev_rect_pct.x0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->prev->cfg), target_prev_rect_pct.y0, .initial = target_prev_rect_pct.y0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->prev->cfg), target_prev_rect_pct.x1, .initial = target_prev_rect_pct.x1), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->prev->cfg), target_prev_rect_pct.y1, .initial = target_prev_rect_pct.y1)); + new_rect_pct = prev_rect_pct; + new_rect_pct.p0.v[split_axis] = new_rect_pct.p1.v[split_axis]; + } + if(new_panel->next != &rd_nil_panel_node) + { + Rng2F32 target_next_rect_px = rd_target_rect_from_panel_node(stub_content_rect, panel_tree.root, rd_panel_node_from_tree_cfg(panel_tree.root, new_panel->next->cfg)); + Rng2F32 target_next_rect_pct = r2f32p(target_next_rect_px.x0/stub_content_rect_dim.x, + target_next_rect_px.y0/stub_content_rect_dim.y, + target_next_rect_px.x1/stub_content_rect_dim.x, + target_next_rect_px.y1/stub_content_rect_dim.y); + Rng2F32 next_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->next->cfg), target_next_rect_pct.x0, .initial = target_next_rect_pct.x0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->next->cfg), target_next_rect_pct.y0, .initial = target_next_rect_pct.y0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->next->cfg), target_next_rect_pct.x1, .initial = target_next_rect_pct.x1), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->next->cfg), target_next_rect_pct.y1, .initial = target_next_rect_pct.y1)); + new_rect_pct = next_rect_pct; + new_rect_pct.p1.v[split_axis] = new_rect_pct.p0.v[split_axis]; + } + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->cfg), new_rect_pct.x0, .initial = new_rect_pct.x0, .reset = 1); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->cfg), new_rect_pct.x1, .initial = new_rect_pct.x1, .reset = 1); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->cfg), new_rect_pct.y0, .initial = new_rect_pct.y0, .reset = 1); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->cfg), new_rect_pct.y1, .initial = new_rect_pct.y1, .reset = 1); + } + } + + // rjf: if this split was caused by drag/dropping a tab, and the originating panel + // has no further tabs, then close the originating panel + RD_Cfg *dragdrop_origin_panel_cfg = rd_cfg_from_id(rd_regs()->panel); + RD_Cfg *dragdrop_tab = rd_cfg_from_id(rd_regs()->view); + if(kind == RD_CmdKind_SplitPanel && + new_panel_cfg != &rd_nil_cfg && dragdrop_tab != &rd_nil_cfg && dragdrop_origin_panel_cfg != &rd_nil_cfg) + { + rd_cfg_unhook(dragdrop_origin_panel_cfg, dragdrop_tab); + rd_cfg_insert_child(new_panel_cfg, new_panel_cfg->last, dragdrop_tab); + RD_PanelTree origin_panel_tree = rd_panel_tree_from_cfg(scratch.arena, dragdrop_origin_panel_cfg); + RD_PanelNode *origin_panel = rd_panel_node_from_tree_cfg(origin_panel_tree.root, dragdrop_origin_panel_cfg); + if(origin_panel->selected_tab == &rd_nil_cfg) + { + for(RD_CfgNode *n = origin_panel->tabs.first; n != 0; n = n->next) + { + if(!rd_cfg_is_project_filtered(n->v)) + { + rd_cmd(RD_CmdKind_FocusTab, .panel = origin_panel->cfg->id, .view = n->v->id); + break; + } } } - if(move_tab_panel_is_empty && move_tab_panel != ws->root_panel && - move_tab_panel != new_panel->prev && move_tab_panel != new_panel->next) + if(origin_panel->cfg != split_panel && origin_panel->tabs.count == 0) { - rd_cmd(RD_CmdKind_ClosePanel, .panel = rd_handle_from_panel(move_tab_panel)); + rd_cmd(RD_CmdKind_ClosePanel); } + rd_cmd(RD_CmdKind_FocusTab, .panel = new_panel_cfg->id, .view = dragdrop_tab->id); + } + + // rjf: focus new panel + if(new_panel_cfg != &rd_nil_cfg) + { + rd_cmd(RD_CmdKind_FocusPanel, .panel = new_panel_cfg->id); + } + + // rjf: tabs on bottom on split panel? -> tabs on bottom on new panel + if(panel->tab_side == Side_Max && split_axis == Axis2_X) + { + rd_cmd(RD_CmdKind_TabBarBottom, .panel = new_panel_cfg->id); } }break; //- rjf: panel rotation case RD_CmdKind_RotatePanelColumns: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *panel = ws->focused_panel; - RD_Panel *parent = &rd_nil_panel; - for(RD_Panel *p = panel->parent; !rd_panel_is_nil(p); p = p->parent) + RD_Cfg *panel_cfg = rd_cfg_from_id(rd_regs()->panel); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel_cfg); + RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, panel_cfg); + RD_PanelNode *parent = &rd_nil_panel_node; + for(RD_PanelNode *p = panel->parent; p != &rd_nil_panel_node; p = p->parent) { if(p->split_axis == Axis2_X) { @@ -13773,49 +14600,77 @@ rd_frame(void) break; } } - if(!rd_panel_is_nil(parent) && parent->child_count > 1) + if(parent != &rd_nil_panel_node && parent->child_count > 1) { - RD_Panel *old_first = parent->first; - RD_Panel *new_first = parent->first->next; - old_first->next = &rd_nil_panel; - old_first->prev = parent->last; - parent->last->next = old_first; - new_first->prev = &rd_nil_panel; - parent->first = new_first; - parent->last = old_first; + RD_Cfg *rotated = parent->first->cfg; + rd_cfg_unhook(parent->cfg, parent->first->cfg); + rd_cfg_insert_child(parent->cfg, parent->last->cfg, rotated); } }break; //- rjf: panel focusing - case RD_CmdKind_NextPanel: panel_sib_off = OffsetOf(RD_Panel, next); panel_child_off = OffsetOf(RD_Panel, first); goto cycle; - case RD_CmdKind_PrevPanel: panel_sib_off = OffsetOf(RD_Panel, prev); panel_child_off = OffsetOf(RD_Panel, last); goto cycle; + case RD_CmdKind_NextPanel: panel_sib_off = OffsetOf(RD_PanelNode, next); panel_child_off = OffsetOf(RD_PanelNode, first); goto cycle; + case RD_CmdKind_PrevPanel: panel_sib_off = OffsetOf(RD_PanelNode, prev); panel_child_off = OffsetOf(RD_PanelNode, last); goto cycle; cycle:; { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - for(RD_Panel *panel = ws->focused_panel; !rd_panel_is_nil(panel);) + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_id(rd_regs()->window)); + RD_PanelNode *next_focused = &rd_nil_panel_node; + for(RD_PanelNode *p = panel_tree.focused; + p != &rd_nil_panel_node; + p = rd_panel_node_rec__depth_first(panel_tree.root, p, panel_sib_off, panel_child_off).next) { - RD_PanelRec rec = rd_panel_rec_depth_first(panel, panel_sib_off, panel_child_off); - panel = rec.next; - if(rd_panel_is_nil(panel)) + if(p != panel_tree.focused && p->first == &rd_nil_panel_node) { - panel = ws->root_panel; - } - if(rd_panel_is_nil(panel->first)) - { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(panel)); + next_focused = p; break; } } + if(next_focused == &rd_nil_panel_node) + { + for(RD_PanelNode *p = panel_tree.root; + p != &rd_nil_panel_node; + p = rd_panel_node_rec__depth_first(panel_tree.root, p, panel_sib_off, panel_child_off).next) + { + if(p != panel_tree.focused && p->first == &rd_nil_panel_node) + { + next_focused = p; + break; + } + } + } + rd_cmd(RD_CmdKind_FocusPanel, .panel = next_focused->cfg->id); }break; case RD_CmdKind_FocusPanel: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - if(!rd_panel_is_nil(panel)) + RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel); + RD_Cfg *selection_cfg = &rd_nil_cfg; + for(RD_PanelNode *p = panel_tree.root; + p != &rd_nil_panel_node; + p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) { - ws->focused_panel = panel; + RD_Cfg *p_cfg = p->cfg; + RD_Cfg *p_selection = rd_cfg_child_from_string(p_cfg, str8_lit("selected")); + if(selection_cfg == &rd_nil_cfg) + { + selection_cfg = p_selection; + } + else for(RD_Cfg *s = p_selection; s != &rd_nil_cfg; s = rd_cfg_child_from_string(p_cfg, str8_lit("selected"))) + { + rd_cfg_release(s); + } + } + if(selection_cfg == &rd_nil_cfg) + { + selection_cfg = rd_cfg_alloc(); + rd_cfg_equip_string(selection_cfg, str8_lit("selected")); + } + if(panel != &rd_nil_cfg) + { + rd_cfg_insert_child(panel, &rd_nil_cfg, selection_cfg); + RD_Cfg *window = rd_window_from_cfg(panel); + RD_WindowState *ws = rd_window_state_from_cfg(window); ws->menu_bar_focused = 0; - ws->query_view_selected = 0; } }break; @@ -13826,39 +14681,40 @@ rd_frame(void) case RD_CmdKind_FocusPanelDown: panel_change_dir = v2s32(+0, +1); goto focus_panel_dir; focus_panel_dir:; { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *src_panel = ws->focused_panel; - Rng2F32 src_panel_rect = rd_target_rect_from_panel(r2f32(v2f32(0, 0), v2f32(1000, 1000)), ws->root_panel, src_panel); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *src_panel = panel_tree.focused; + Rng2F32 src_panel_rect = rd_target_rect_from_panel_node(r2f32(v2f32(0, 0), v2f32(1000, 1000)), panel_tree.root, src_panel); Vec2F32 src_panel_center = center_2f32(src_panel_rect); Vec2F32 src_panel_half_dim = scale_2f32(dim_2f32(src_panel_rect), 0.5f); Vec2F32 travel_dim = add_2f32(src_panel_half_dim, v2f32(10.f, 10.f)); Vec2F32 travel_dst = add_2f32(src_panel_center, mul_2f32(travel_dim, v2f32((F32)panel_change_dir.x, (F32)panel_change_dir.y))); - RD_Panel *dst_root = &rd_nil_panel; - for(RD_Panel *p = ws->root_panel; !rd_panel_is_nil(p); p = rd_panel_rec_depth_first_pre(p).next) + RD_PanelNode *dst_root = &rd_nil_panel_node; + for(RD_PanelNode *p = panel_tree.root; p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) { - if(p == src_panel || !rd_panel_is_nil(p->first)) + if(p == src_panel || p->first != &rd_nil_panel_node) { continue; } - Rng2F32 p_rect = rd_target_rect_from_panel(r2f32(v2f32(0, 0), v2f32(1000, 1000)), ws->root_panel, p); + Rng2F32 p_rect = rd_target_rect_from_panel_node(r2f32(v2f32(0, 0), v2f32(1000, 1000)), panel_tree.root, p); if(contains_2f32(p_rect, travel_dst)) { dst_root = p; break; } } - if(!rd_panel_is_nil(dst_root)) + if(dst_root != &rd_nil_panel_node) { - RD_Panel *dst_panel = &rd_nil_panel; - for(RD_Panel *p = dst_root; !rd_panel_is_nil(p); p = rd_panel_rec_depth_first_pre(p).next) + RD_PanelNode *dst_panel = &rd_nil_panel_node; + for(RD_PanelNode *p = dst_root; p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first_pre(dst_root, p).next) { - if(rd_panel_is_nil(p->first) && p != src_panel) + if(p->first == &rd_nil_panel_node && p != src_panel) { dst_panel = p; break; } } - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(dst_panel)); + rd_cmd(RD_CmdKind_FocusPanel, .panel = dst_panel->cfg->id); } }break; @@ -13873,8 +14729,9 @@ rd_frame(void) //- rjf: files case RD_CmdKind_SetCurrentPath: { - arena_clear(rd_state->current_path_arena); - rd_state->current_path = push_str8_copy(rd_state->current_path_arena, rd_regs()->file_path); + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *current_path = rd_cfg_child_from_string_or_alloc(user, str8_lit("current_path")); + rd_cfg_new_replace(current_path, rd_regs()->file_path); }break; case RD_CmdKind_SetFileReplacementPath: { @@ -13941,30 +14798,23 @@ rd_frame(void) String8 map_src = str8_list_join(scratch.arena, &map_src_parts, &map_join); String8 map_dst = str8_list_join(scratch.arena, &map_dst_parts, &map_join); - //- rjf: store as file path map entity - //- TODO(rjf): @cfg store as file path map entity - { - RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_Cfg *map = rd_cfg_new(user, str8_lit("file_path_map")); - RD_Cfg *src = rd_cfg_new(map, str8_lit("source")); - RD_Cfg *dst = rd_cfg_new(map, str8_lit("dest")); - rd_cfg_new(src, map_src); - rd_cfg_new(dst, map_dst); - } - RD_Entity *map = rd_entity_alloc(rd_entity_root(), RD_EntityKind_FilePathMap); - RD_Entity *src = rd_entity_alloc(map, RD_EntityKind_Source); - RD_Entity *dst = rd_entity_alloc(map, RD_EntityKind_Dest); - rd_entity_equip_name(src, map_src); - rd_entity_equip_name(dst, map_dst); + //- rjf: store as file path map cfg + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *map = rd_cfg_new(user, str8_lit("file_path_map")); + RD_Cfg *src = rd_cfg_new(map, str8_lit("source")); + RD_Cfg *dst = rd_cfg_new(map, str8_lit("dest")); + rd_cfg_new(src, map_src); + rd_cfg_new(dst, map_dst); }break; //- rjf: panel removal case RD_CmdKind_ClosePanel: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - RD_Panel *parent = panel->parent; - if(!rd_panel_is_nil(parent)) + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, rd_cfg_from_id(rd_regs()->panel)); + RD_PanelNode *parent = panel->parent; + if(parent != &rd_nil_panel_node) { Axis2 split_axis = parent->split_axis; @@ -13972,217 +14822,342 @@ rd_frame(void) // we should just remove both children. if(parent->child_count == 2) { - RD_Panel *discard_child = panel; - RD_Panel *keep_child = panel == parent->first ? parent->last : parent->first; - RD_Panel *grandparent = parent->parent; - RD_Panel *parent_prev = parent->prev; + RD_PanelNode *discard_child = panel; + RD_PanelNode *keep_child = (panel == parent->first ? parent->last : parent->first); + RD_PanelNode *grandparent = parent->parent; + RD_PanelNode *parent_prev = parent->prev; F32 pct_of_parent = parent->pct_of_parent; // rjf: unhook kept child - rd_panel_remove(parent, keep_child); + rd_cfg_unhook(parent->cfg, keep_child->cfg); // rjf: unhook this subtree - if(!rd_panel_is_nil(grandparent)) + if(grandparent != &rd_nil_panel_node) { - rd_panel_remove(grandparent, parent); + rd_cfg_unhook(grandparent->cfg, parent->cfg); } - // rjf: release the things we should discard + // rjf: release the containing tree { - rd_panel_release(ws, parent); - rd_panel_release(ws, discard_child); + rd_cfg_release(parent->cfg); } // rjf: re-hook our kept child into the overall tree - if(rd_panel_is_nil(grandparent)) + if(grandparent == &rd_nil_panel_node) { - ws->root_panel = keep_child; + rd_cfg_equip_string(keep_child->cfg, str8_lit("panels")); + rd_cfg_insert_child(window, window->last, keep_child->cfg); } else { - rd_panel_insert(grandparent, parent_prev, keep_child); - } - keep_child->pct_of_parent = pct_of_parent; - - // rjf: reset focus, if needed - if(ws->focused_panel == discard_child) - { - ws->focused_panel = keep_child; - for(RD_Panel *grandchild = ws->focused_panel; !rd_panel_is_nil(grandchild); grandchild = grandchild->first) - { - ws->focused_panel = grandchild; - } + rd_cfg_insert_child(grandparent->cfg, parent_prev->cfg, keep_child->cfg); + rd_cfg_equip_stringf(keep_child->cfg, "%f", pct_of_parent); } // rjf: keep-child split-axis == grandparent split-axis? bubble keep-child up into grandparent's children - if(!rd_panel_is_nil(grandparent) && grandparent->split_axis == keep_child->split_axis && !rd_panel_is_nil(keep_child->first)) + if(grandparent != &rd_nil_panel_node && grandparent->split_axis == keep_child->split_axis && keep_child->first != &rd_nil_panel_node) { - rd_panel_remove(grandparent, keep_child); - RD_Panel *prev = parent_prev; - for(RD_Panel *child = keep_child->first, *next = 0; !rd_panel_is_nil(child); child = next) + rd_cfg_unhook(grandparent->cfg, keep_child->cfg); + RD_Cfg *prev = parent_prev->cfg; + for(RD_PanelNode *child = keep_child->first, *next = &rd_nil_panel_node; child != &rd_nil_panel_node; child = next) { next = child->next; - rd_panel_remove(keep_child, child); - rd_panel_insert(grandparent, prev, child); - prev = child; - child->pct_of_parent *= keep_child->pct_of_parent; + rd_cfg_unhook(keep_child->cfg, child->cfg); + rd_cfg_insert_child(grandparent->cfg, prev, child->cfg); + prev = child->cfg; + F32 old_pct = child->pct_of_parent; + F32 new_pct = old_pct * pct_of_parent; + rd_cfg_equip_stringf(child->cfg, "%f", new_pct); } - rd_panel_release(ws, keep_child); + rd_cfg_release(keep_child->cfg); + } + + // rjf: reset focus, if needed + if(panel_tree.focused == discard_child) + { + RD_PanelTree new_panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *new_focused = rd_panel_node_from_tree_cfg(panel_tree.root, keep_child->cfg); + for(RD_PanelNode *grandchild = new_focused; grandchild != &rd_nil_panel_node; grandchild = grandchild->first) + { + new_focused = grandchild; + } + rd_cmd(RD_CmdKind_FocusPanel, .panel = new_focused->cfg->id); } } // NOTE(rjf): Otherwise we can just remove this child. else { - RD_Panel *next = &rd_nil_panel; + // rjf: remove + RD_PanelNode *next = &rd_nil_panel_node; F32 removed_size_pct = panel->pct_of_parent; - if(rd_panel_is_nil(next)) { next = panel->prev; } - if(rd_panel_is_nil(next)) { next = panel->next; } - rd_panel_remove(parent, panel); - rd_panel_release(ws, panel); - if(ws->focused_panel == panel) + if(next == &rd_nil_panel_node) { next = panel->prev; } + if(next == &rd_nil_panel_node) { next = panel->next; } + rd_cfg_unhook(parent->cfg, panel->cfg); + rd_cfg_release(panel->cfg); + + // rjf: resize siblings to this node { - ws->focused_panel = next; - for(RD_Panel *grandchild = ws->focused_panel; !rd_panel_is_nil(grandchild); grandchild = grandchild->first) + RD_PanelTree new_panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *new_parent = rd_panel_node_from_tree_cfg(new_panel_tree.root, parent->cfg); + for(RD_PanelNode *child = new_parent->first; child != &rd_nil_panel_node; child = child->next) { - ws->focused_panel = grandchild; + RD_Cfg *cfg = child->cfg; + F32 old_pct = child->pct_of_parent; + F32 new_pct = old_pct / (1.f-removed_size_pct); + rd_cfg_equip_stringf(cfg, "%f", new_pct); } } - for(RD_Panel *child = parent->first; !rd_panel_is_nil(child); child = child->next) + + // rjf: reset focus, if needed + if(panel_tree.focused == panel) { - child->pct_of_parent /= 1.f-removed_size_pct; + RD_PanelTree new_panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *new_focused = rd_panel_node_from_tree_cfg(panel_tree.root, next->cfg); + for(RD_PanelNode *grandchild = new_focused; grandchild != &rd_nil_panel_node; grandchild = grandchild->first) + { + new_focused = grandchild; + } + rd_cmd(RD_CmdKind_FocusPanel, .panel = new_focused->cfg->id); } } } }break; //- rjf: panel tab controls + case RD_CmdKind_FocusTab: + { + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *panel = tab->parent; + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel); + RD_PanelNode *panel_node = rd_panel_node_from_tree_cfg(panel_tree.root, panel); + RD_Cfg *selection_cfg = &rd_nil_cfg; + for(RD_CfgNode *n = panel_node->tabs.first; n != 0; n = n->next) + { + RD_Cfg *tab_selection_cfg = rd_cfg_child_from_string(n->v, str8_lit("selected")); + if(selection_cfg == &rd_nil_cfg) + { + selection_cfg = tab_selection_cfg; + } + else for(RD_Cfg *s = tab_selection_cfg; s != &rd_nil_cfg; s = rd_cfg_child_from_string(n->v, str8_lit("selected"))) + { + rd_cfg_release(s); + } + } + if(selection_cfg == &rd_nil_cfg) + { + selection_cfg = rd_cfg_alloc(); + rd_cfg_equip_string(selection_cfg, str8_lit("selected")); + } + rd_cfg_insert_child(tab, &rd_nil_cfg, selection_cfg); + }break; case RD_CmdKind_NextTab: { - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *start_view = rd_selected_tab_from_panel(panel); - RD_View *next_view = start_view; - U64 idx = 0; - for(RD_View *v = start_view; !rd_view_is_nil(v); v = (rd_view_is_nil(v->order_next) ? panel->first_tab_view : v->order_next), idx += 1) + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *focused = panel_tree.focused; + RD_CfgNode *selected_tab_n = 0; + for(RD_CfgNode *n = focused->tabs.first; n != 0; n = n->next) { - if(v == start_view && idx != 0) + if(n->v == focused->selected_tab) { - break; - } - if(!rd_view_is_project_filtered(v) && v != start_view) - { - next_view = v; + selected_tab_n = n; break; } } - panel->selected_tab_view = rd_handle_from_view(next_view); + RD_Cfg *next_selected_tab = &rd_nil_cfg; + U64 idx = 0; + for(RD_CfgNode *tab_n = selected_tab_n; + tab_n != 0 && (tab_n != selected_tab_n || idx == 0); + ((tab_n->next == 0) ? (tab_n = focused->tabs.first) : (tab_n = tab_n->next)), idx += 1) + { + if(!rd_cfg_is_project_filtered(tab_n->v) && tab_n != selected_tab_n) + { + next_selected_tab = tab_n->v; + break; + } + } + if(next_selected_tab != &rd_nil_cfg) + { + rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); + } }break; case RD_CmdKind_PrevTab: { - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *start_view = rd_selected_tab_from_panel(panel); - RD_View *next_view = start_view; - U64 idx = 0; - for(RD_View *v = start_view; !rd_view_is_nil(v); v = (rd_view_is_nil(v->order_prev) ? panel->last_tab_view : v->order_prev), idx += 1) + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *focused = panel_tree.focused; + RD_CfgNode *selected_tab_n = 0; + for(RD_CfgNode *n = focused->tabs.last; n != 0; n = n->prev) { - if(v == start_view && idx != 0) + if(n->v == focused->selected_tab) { - break; - } - if(!rd_view_is_project_filtered(v) && v != start_view) - { - next_view = v; + selected_tab_n = n; break; } } - panel->selected_tab_view = rd_handle_from_view(next_view); + RD_Cfg *next_selected_tab = &rd_nil_cfg; + U64 idx = 0; + for(RD_CfgNode *tab_n = selected_tab_n; + tab_n != 0 && (tab_n != selected_tab_n || idx == 0); + ((tab_n->prev == 0) ? (tab_n = focused->tabs.last) : (tab_n = tab_n->prev)), idx += 1) + { + if(!rd_cfg_is_project_filtered(tab_n->v) && tab_n != selected_tab_n) + { + next_selected_tab = tab_n->v; + break; + } + } + if(next_selected_tab != &rd_nil_cfg) + { + rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); + } }break; case RD_CmdKind_MoveTabRight: case RD_CmdKind_MoveTabLeft: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *panel = ws->focused_panel; - RD_View *view = rd_selected_tab_from_panel(panel); - RD_View *prev_view = (kind == RD_CmdKind_MoveTabRight ? view->order_next : view->order_prev->order_prev); - if(!rd_view_is_nil(prev_view) || kind == RD_CmdKind_MoveTabLeft) + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *window = rd_window_from_cfg(tab); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, tab->parent); + RD_CfgList filtered_tabs = {0}; + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) { - rd_cmd(RD_CmdKind_MoveTab, - .panel = rd_handle_from_panel(panel), - .dst_panel = rd_handle_from_panel(panel), - .view = rd_handle_from_view(view), - .prev_view = rd_handle_from_view(prev_view)); + if(rd_cfg_is_project_filtered(n->v)) + { + continue; + } + rd_cfg_list_push(scratch.arena, &filtered_tabs, n->v); } + RD_Cfg *tab_prev2 = &rd_nil_cfg; + RD_Cfg *tab_prev = &rd_nil_cfg; + RD_Cfg *tab_next = &rd_nil_cfg; + { + RD_Cfg *prev2 = &rd_nil_cfg; + RD_Cfg *prev = &rd_nil_cfg; + RD_Cfg *next = &rd_nil_cfg; + for(RD_CfgNode *n = filtered_tabs.first; n != 0; (prev2 = prev, prev = n->v, n = n->next)) + { + next = n->next ? n->next->v : &rd_nil_cfg; + if(n->v == tab) + { + tab_prev2 = prev2; + tab_prev = prev; + tab_next = next; + break; + } + } + } + RD_Cfg *new_prev = (kind == RD_CmdKind_MoveTabRight ? tab_next : tab_prev2); + if(new_prev == tab_prev && filtered_tabs.last) + { + new_prev = filtered_tabs.last->v; + } + rd_cmd(RD_CmdKind_MoveTab, + .dst_panel = panel->cfg->id, + .view = tab->id, + .prev_view = new_prev->id); }break; case RD_CmdKind_OpenTab: { + String8 expr_file_path = rd_file_path_from_eval_string(scratch.arena, rd_regs()->expr); + RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); + RD_Cfg *tab = rd_cfg_new(panel, rd_regs()->string); + RD_Cfg *expr = rd_cfg_new(tab, str8_lit("expression")); + rd_cfg_new(expr, rd_regs()->expr); + if(expr_file_path.size != 0) + { + RD_Cfg *project = rd_cfg_new(tab, str8_lit("project")); + rd_cfg_new(project, rd_state->project_path); + } + rd_cmd(RD_CmdKind_FocusTab, .view = tab->id); +#if 0 // TODO(rjf): @cfg (tab opening) RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); RD_View *view = rd_view_alloc(); String8 query = rd_regs()->string; RD_ViewRuleInfo *spec = rd_view_rule_info_from_string(rd_regs()->params_tree->string); rd_view_equip_spec(view, spec, query, rd_regs()->params_tree); rd_panel_insert_tab_view(panel, panel->last_tab_view, view); +#endif }break; case RD_CmdKind_CloseTab: { - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *view = rd_view_from_handle(rd_regs()->view); - if(!rd_view_is_nil(view)) + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, tab); + RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, tab->parent); + B32 found_selected = 0; + RD_Cfg *next_selected_tab = &rd_nil_cfg; + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) { - rd_panel_remove_tab_view(panel, view); - rd_view_release(view); - } - }break; - case RD_CmdKind_MoveTab: - { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *src_panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *view = rd_view_from_handle(rd_regs()->view); - RD_Panel *dst_panel = rd_panel_from_handle(rd_regs()->dst_panel); - RD_View *prev_view = rd_view_from_handle(rd_regs()->prev_view); - if(!rd_panel_is_nil(src_panel) && - !rd_panel_is_nil(dst_panel) && - prev_view != view) - { - rd_panel_remove_tab_view(src_panel, view); - rd_panel_insert_tab_view(dst_panel, prev_view, view); - ws->focused_panel = dst_panel; - B32 src_panel_is_empty = 1; - for(RD_View *v = src_panel->first_tab_view; !rd_view_is_nil(v); v = v->order_next) + if(n->v == panel->selected_tab) { - if(!rd_view_is_project_filtered(v)) + found_selected = 1; + } + else if(!rd_cfg_is_project_filtered(n->v)) + { + next_selected_tab = n->v; + if(found_selected) { - src_panel_is_empty = 0; break; } } - if(src_panel_is_empty && src_panel != ws->root_panel) + } + rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); + rd_cfg_release(tab); + }break; + case RD_CmdKind_MoveTab: + { + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *prev_tab = rd_cfg_from_id(rd_regs()->prev_view); + RD_Cfg *src_panel = tab->parent; + RD_Cfg *dst_panel = rd_cfg_from_id(rd_regs()->dst_panel); + if(dst_panel != &rd_nil_cfg && prev_tab != tab) + { + rd_cfg_unhook(src_panel, tab); + rd_cfg_insert_child(dst_panel, prev_tab, tab); + rd_cmd(RD_CmdKind_FocusTab, .panel = dst_panel->id, .view = tab->id); + rd_cmd(RD_CmdKind_FocusPanel, .panel = dst_panel->id); + RD_PanelTree src_panel_tree = rd_panel_tree_from_cfg(scratch.arena, src_panel); + RD_PanelNode *src_panel_node = rd_panel_node_from_tree_cfg(src_panel_tree.root, src_panel); + B32 src_panel_is_empty = 0; + if(src_panel != dst_panel) { - rd_cmd(RD_CmdKind_ClosePanel, .panel = rd_handle_from_panel(src_panel)); + src_panel_is_empty = 1; + for(RD_CfgNode *n = src_panel_node->tabs.first; n != 0; n = n->next) + { + if(!rd_cfg_is_project_filtered(n->v)) + { + rd_cmd(RD_CmdKind_FocusTab, .panel = src_panel->id, .view = n->v->id); + src_panel_is_empty = 0; + break; + } + } + } + if(src_panel_is_empty) + { + rd_cmd(RD_CmdKind_ClosePanel, .panel = src_panel->id); } } }break; case RD_CmdKind_TabBarTop: { - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - panel->tab_side = Side_Min; + RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); + rd_cfg_release(rd_cfg_child_from_string(panel, str8_lit("tabs_on_bottom"))); }break; case RD_CmdKind_TabBarBottom: { - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - panel->tab_side = Side_Max; + RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); + rd_cfg_child_from_string_or_alloc(panel, str8_lit("tabs_on_bottom")); }break; //- rjf: files case RD_CmdKind_Open: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); String8 path = rd_regs()->file_path; FileProperties props = os_properties_from_file_path(path); if(props.created != 0) { rd_cmd(RD_CmdKind_RecordFileInProject); - rd_cmd(RD_CmdKind_OpenTab, - .string = rd_eval_string_from_file_path(scratch.arena, path), - .params_tree = md_tree_from_string(scratch.arena, rd_view_rule_kind_info_table[RD_ViewRuleKind_PendingFile].string)->first); + rd_cmd(RD_CmdKind_OpenTab, .string = str8_lit("pending"), .expr = rd_eval_string_from_file_path(scratch.arena, path)); } else { @@ -14191,90 +15166,39 @@ rd_frame(void) }break; case RD_CmdKind_Switch: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *src_panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *src_view = rd_view_from_handle(rd_regs()->view); - RD_ViewRuleKind src_view_kind = rd_view_rule_kind_from_string(src_view->spec->string); - RD_Entity *recent_file = rd_entity_from_handle(rd_regs()->entity); - if(!rd_entity_is_nil(recent_file)) - { - String8 recent_file_path = recent_file->string; - RD_Panel *existing_panel = &rd_nil_panel; - RD_View *existing_view = &rd_nil_view; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) - { - if(!rd_panel_is_nil(panel->first)) - { - continue; - } - for(RD_View *v = panel->first_tab_view; !rd_view_is_nil(v); v = v->order_next) - { - if(rd_view_is_project_filtered(v)) { continue; } - String8 v_path = rd_file_path_from_eval_string(scratch.arena, str8(v->query_buffer, v->query_string_size)); - RD_ViewRuleKind v_kind = rd_view_rule_kind_from_string(v->spec->string); - if(str8_match(v_path, recent_file_path, StringMatchFlag_CaseInsensitive) && v_kind == src_view_kind) - { - existing_panel = panel; - existing_view = v; - goto done_existing_view_search__switch; - } - } - } - done_existing_view_search__switch:; - if(rd_view_is_nil(existing_view)) - { - rd_cmd(RD_CmdKind_OpenTab, - .string = rd_eval_string_from_file_path(scratch.arena, recent_file_path), - .params_tree = md_tree_from_string(scratch.arena, rd_view_rule_kind_info_table[RD_ViewRuleKind_PendingFile].string)->first); - } - else - { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(existing_panel)); - existing_panel->selected_tab_view = rd_handle_from_view(existing_view); - } - } + RD_Cfg *recent_file = rd_cfg_from_id(rd_regs()->cfg); + RD_Cfg *path_root = rd_cfg_child_from_string(recent_file, str8_lit("path")); + String8 path = path_root->first->string; + rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = path, .cursor = txt_pt(0, 0), .vaddr = 0); }break; case RD_CmdKind_SwitchToPartnerFile: { - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *view = rd_selected_tab_from_panel(panel); + String8 file_path = rd_regs()->file_path; + String8 file_full_path = path_normalized_from_string(scratch.arena, file_path); + String8 file_folder = str8_chop_last_slash(file_full_path); + String8 file_name = str8_skip_last_slash(str8_chop_last_dot(file_full_path)); + String8 file_ext = str8_skip_last_dot(file_full_path); + String8 partner_ext_candidates[] = { - String8 file_path = rd_file_path_from_eval_string(scratch.arena, str8(view->query_buffer, view->query_string_size)); - String8 file_full_path = path_normalized_from_string(scratch.arena, file_path); - String8 file_folder = str8_chop_last_slash(file_full_path); - String8 file_name = str8_skip_last_slash(str8_chop_last_dot(file_full_path)); - String8 file_ext = str8_skip_last_dot(file_full_path); - String8 partner_ext_candidates[] = + str8_lit_comp("h"), + str8_lit_comp("hpp"), + str8_lit_comp("hxx"), + str8_lit_comp("c"), + str8_lit_comp("cc"), + str8_lit_comp("cxx"), + str8_lit_comp("cpp"), + }; + for(U64 idx = 0; idx < ArrayCount(partner_ext_candidates); idx += 1) + { + if(!str8_match(partner_ext_candidates[idx], file_ext, StringMatchFlag_CaseInsensitive)) { - str8_lit_comp("h"), - str8_lit_comp("hpp"), - str8_lit_comp("hxx"), - str8_lit_comp("c"), - str8_lit_comp("cc"), - str8_lit_comp("cxx"), - str8_lit_comp("cpp"), - }; - for(U64 idx = 0; idx < ArrayCount(partner_ext_candidates); idx += 1) - { - if(!str8_match(partner_ext_candidates[idx], file_ext, StringMatchFlag_CaseInsensitive)) + String8 candidate = push_str8f(scratch.arena, "%S.%S", file_name, partner_ext_candidates[idx]); + String8 candidate_path = push_str8f(scratch.arena, "%S/%S", file_folder, candidate); + FileProperties candidate_props = os_properties_from_file_path(candidate_path); + if(candidate_props.modified != 0) { - String8 candidate = push_str8f(scratch.arena, "%S.%S", file_name, partner_ext_candidates[idx]); - String8 candidate_path = push_str8f(scratch.arena, "%S/%S", file_folder, candidate); - FileProperties candidate_props = os_properties_from_file_path(candidate_path); - if(candidate_props.modified != 0) - { - RD_Entity *recent_file = rd_entity_from_name_and_kind(candidate_path, RD_EntityKind_RecentFile); - if(!rd_entity_is_nil(recent_file)) - { - rd_cmd(RD_CmdKind_Switch, .entity = rd_handle_from_entity(recent_file)); - } - else - { - rd_cmd(RD_CmdKind_RecordFileInProject, .file_path = candidate_path); - rd_cmd(RD_CmdKind_OpenTab, .string = rd_eval_string_from_file_path(scratch.arena, candidate_path), .params_tree = md_tree_from_string(scratch.arena, view->spec->string)->first); - } - break; - } + rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = candidate_path, .cursor = txt_pt(0, 0), .vaddr = 0); + break; } } } @@ -14283,59 +15207,37 @@ rd_frame(void) if(rd_regs()->file_path.size != 0) { String8 path = path_normalized_from_string(scratch.arena, rd_regs()->file_path); - - //- TODO(rjf): @cfg record file in project + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + RD_CfgList recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_file")); + RD_Cfg *recent_file = &rd_nil_cfg; + for(RD_CfgNode *n = recent_files.first; n != 0; n = n->next) { - RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - RD_CfgList recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_files")); - RD_Cfg *recent_file = &rd_nil_cfg; - for(RD_CfgNode *n = recent_files.first; n != 0; n = n->next) + if(path_match_normalized(rd_path_from_cfg(n->v), path)) { - if(path_match_normalized(n->v->string, path)) - { - recent_file = n->v; - break; - } - } - if(recent_file == &rd_nil_cfg) - { - recent_file = rd_cfg_new(project, str8_lit("recent_file")); - rd_cfg_new(recent_file, path); - } - rd_cfg_unhook(project, recent_file); - rd_cfg_insert_child(project, &rd_nil_cfg, recent_file); - recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_files")); - if(recent_files.count > 256) - { - rd_cfg_release(recent_files.last->v); - } - } - - RD_EntityList recent_files = rd_query_cached_entity_list_with_kind(RD_EntityKind_RecentFile); - if(recent_files.count >= 256) - { - rd_entity_mark_for_deletion(recent_files.first->entity); - } - RD_Entity *existing_recent_file = &rd_nil_entity; - for(RD_EntityNode *n = recent_files.first; n != 0; n = n->next) - { - if(str8_match(n->entity->string, path, StringMatchFlag_CaseInsensitive)) - { - existing_recent_file = n->entity; + recent_file = n->v; break; } } - if(rd_entity_is_nil(existing_recent_file)) + if(recent_file == &rd_nil_cfg) { - RD_Entity *recent_file = rd_entity_alloc(rd_entity_root(), RD_EntityKind_RecentFile); - rd_entity_equip_name(recent_file, path); - rd_entity_equip_cfg_src(recent_file, RD_CfgSrc_Project); + recent_file = rd_cfg_new(project, str8_lit("recent_file")); + RD_Cfg *path_root = rd_cfg_new(recent_file, str8_lit("path")); + rd_cfg_new(path_root, path); } - else + rd_cfg_unhook(project, recent_file); + rd_cfg_insert_child(project, &rd_nil_cfg, recent_file); + recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_file")); + if(recent_files.count > 256) { - rd_entity_change_parent(existing_recent_file, rd_entity_root(), rd_entity_root(), rd_entity_root()->last); + rd_cfg_release(recent_files.last->v); } }break; + case RD_CmdKind_ShowFileInExplorer: + if(rd_regs()->file_path.size != 0) + { + String8 full_path = path_normalized_from_string(scratch.arena, rd_regs()->file_path); + os_show_in_filesystem_ui(full_path); + }break; //- rjf: source <-> disasm case RD_CmdKind_GoToDisassembly: @@ -14370,372 +15272,282 @@ rd_frame(void) //- rjf: panel built-in layout builds case RD_CmdKind_ResetToDefaultPanels: case RD_CmdKind_ResetToCompactPanels: + case RD_CmdKind_ResetToSimplePanels: { - panel_reset_done = 1; - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_Cfg *panels = rd_cfg_child_from_string(window, str8_lit("panels")); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); - typedef enum Layout + //- rjf: define all of the "fixed" tabs we care about +#define FixedTab_XList \ +X(watches)\ +X(locals)\ +X(registers)\ +X(globals)\ +X(thread_locals)\ +X(types)\ +X(procedures)\ +X(call_stack)\ +X(breakpoints)\ +X(watch_pins)\ +X(targets)\ +X(threads)\ +X(processes)\ +X(machines)\ +X(modules)\ +Y(output, text, "query:output")\ +Y(disasm, disasm, "")\ +Y(memory, memory, "")\ +Z(getting_started) +#define X(name) RD_Cfg *name = &rd_nil_cfg; +#define Y(name, rule, expr) RD_Cfg *name = &rd_nil_cfg; +#define Z(name) RD_Cfg *name = &rd_nil_cfg; + FixedTab_XList +#undef X +#undef Y +#undef Z + + //- rjf: find all the fixed tabs, and all text viewers + B32 any_fixed_tabs_found = 0; + RD_CfgList texts = {0}; + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - Layout_Default, - Layout_Compact, + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) + { + RD_Cfg *tab = n->v; + B32 need_unhook = 1; + if(0){} +#define X(name) else if(str8_match(tab->string, str8_lit("watch"), 0) && str8_match(rd_expr_from_cfg(tab), str8_lit("query:" #name), 0)) {name = tab;} +#define Y(name, rule, expr) else if(str8_match(tab->string, str8_lit(#rule), 0) && str8_match(rd_expr_from_cfg(tab), str8_lit(expr), 0)) {name = tab;} +#define Z(name) else if(str8_match(tab->string, str8_lit(#name), 0)) {name = tab;} + FixedTab_XList +#undef X +#undef Y +#undef Z + else if(str8_match(tab->string, str8_lit("text"), 0)) {rd_cfg_list_push(scratch.arena, &texts, tab);} + else + { + need_unhook = 0; + } + if(need_unhook) + { + rd_cfg_unhook(panel->cfg, tab); + any_fixed_tabs_found = 1; + } + } } - Layout; - Layout layout = Layout_Default; + + //- rjf: release the old panel tree + rd_cfg_release(panels); + + //- rjf: allocate any missing tabs +#define X(name) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit("watch")); RD_Cfg *expr_cfg = rd_cfg_new(name, str8_lit("expression")); rd_cfg_new(expr_cfg, str8_lit("query:" #name));} +#define Y(name, rule, expr) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit(#rule)); RD_Cfg *expr_cfg = rd_cfg_new(name, str8_lit("expression")); rd_cfg_new(expr_cfg, str8_lit(expr));} +#define Z(name) if(name == &rd_nil_cfg && !any_fixed_tabs_found) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit(#name));} + FixedTab_XList +#undef X +#undef Y +#undef Z + + //- rjf: eliminate all tab selections +#define X(name) if(name != &rd_nil_cfg) {rd_cfg_release(rd_cfg_child_from_string(name, str8_lit("selected")));} +#define Y(name, rule, expr) if(name != &rd_nil_cfg) {rd_cfg_release(rd_cfg_child_from_string(name, str8_lit("selected")));} +#define Z(name) if(name != &rd_nil_cfg) {rd_cfg_release(rd_cfg_child_from_string(name, str8_lit("selected")));} + FixedTab_XList +#undef X +#undef Y +#undef Z + for(RD_CfgNode *n = texts.first; n != 0; n = n->next) + { + rd_cfg_release(rd_cfg_child_from_string(n->v, str8_lit("selected"))); + } + + //- rjf: create the panel root + panels = rd_cfg_new(window, str8_lit("panels")); + + //- rjf: rebuild the new panel tree switch(kind) { default:{}break; - case RD_CmdKind_ResetToDefaultPanels:{layout = Layout_Default;}break; - case RD_CmdKind_ResetToCompactPanels:{layout = Layout_Compact;}break; - } - - //- rjf: gather all panels in the panel tree - remove & gather views - // we'd like to keep in the next layout - RD_HandleList panels_to_close = {0}; - RD_HandleList views_to_close = {0}; - RD_View *watch = &rd_nil_view; - RD_View *locals = &rd_nil_view; - RD_View *regs = &rd_nil_view; - RD_View *globals = &rd_nil_view; - RD_View *tlocals = &rd_nil_view; - RD_View *types = &rd_nil_view; - RD_View *procs = &rd_nil_view; - RD_View *callstack = &rd_nil_view; - RD_View *breakpoints = &rd_nil_view; - RD_View *watch_pins = &rd_nil_view; - RD_View *output = &rd_nil_view; - RD_View *targets = &rd_nil_view; - RD_View *scheduler = &rd_nil_view; - RD_View *modules = &rd_nil_view; - RD_View *disasm = &rd_nil_view; - RD_View *memory = &rd_nil_view; - RD_View *getting_started = &rd_nil_view; - RD_HandleList code_views = {0}; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) - { - RD_Handle handle = rd_handle_from_panel(panel); - rd_handle_list_push(scratch.arena, &panels_to_close, handle); - for(RD_View *view = panel->first_tab_view, *next = 0; !rd_view_is_nil(view); view = next) - { - next = view->order_next; - RD_ViewRuleKind view_rule_kind = rd_view_rule_kind_from_string(view->spec->string); - B32 needs_delete = 1; - switch(view_rule_kind) - { - default:{}break; - case RD_ViewRuleKind_Watch: {if(rd_view_is_nil(watch)) { needs_delete = 0; watch = view;} }break; - case RD_ViewRuleKind_Locals: {if(rd_view_is_nil(locals)) { needs_delete = 0; locals = view;} }break; - case RD_ViewRuleKind_Registers: {if(rd_view_is_nil(regs)) { needs_delete = 0; regs = view;} }break; - case RD_ViewRuleKind_Globals: {if(rd_view_is_nil(globals)) { needs_delete = 0; globals = view;} }break; - case RD_ViewRuleKind_ThreadLocals: {if(rd_view_is_nil(tlocals)) { needs_delete = 0; tlocals = view;} }break; - case RD_ViewRuleKind_Types: {if(rd_view_is_nil(types)) { needs_delete = 0; types = view;} }break; - case RD_ViewRuleKind_Procedures: {if(rd_view_is_nil(procs)) { needs_delete = 0; procs = view;} }break; - case RD_ViewRuleKind_CallStack: {if(rd_view_is_nil(callstack)) { needs_delete = 0; callstack = view;} }break; - case RD_ViewRuleKind_Breakpoints: {if(rd_view_is_nil(breakpoints)) { needs_delete = 0; breakpoints = view;} }break; - case RD_ViewRuleKind_WatchPins: {if(rd_view_is_nil(watch_pins)) { needs_delete = 0; watch_pins = view;} }break; - case RD_ViewRuleKind_Output: {if(rd_view_is_nil(output)) { needs_delete = 0; output = view;} }break; - case RD_ViewRuleKind_Targets: {if(rd_view_is_nil(targets)) { needs_delete = 0; targets = view;} }break; - case RD_ViewRuleKind_Scheduler: {if(rd_view_is_nil(scheduler)) { needs_delete = 0; scheduler = view;} }break; - case RD_ViewRuleKind_Modules: {if(rd_view_is_nil(modules)) { needs_delete = 0; modules = view;} }break; - case RD_ViewRuleKind_Disasm: {if(rd_view_is_nil(disasm)) { needs_delete = 0; disasm = view;} }break; - case RD_ViewRuleKind_Memory: {if(rd_view_is_nil(memory)) { needs_delete = 0; memory = view;} }break; - case RD_ViewRuleKind_GettingStarted:{if(rd_view_is_nil(getting_started)) { needs_delete = 0; getting_started = view;} }break; - case RD_ViewRuleKind_Text: - { - needs_delete = 0; - rd_handle_list_push(scratch.arena, &code_views, rd_handle_from_view(view)); - }break; - } - if(!needs_delete) - { - rd_panel_remove_tab_view(panel, view); - } - } - } - - //- rjf: close all panels/views - for(RD_HandleNode *n = panels_to_close.first; n != 0; n = n->next) - { - RD_Panel *panel = rd_panel_from_handle(n->handle); - if(panel != ws->root_panel) - { - rd_panel_release(ws, panel); - } - else - { - rd_panel_release_all_views(panel); - panel->first = panel->last = &rd_nil_panel; - } - } - - //- rjf: allocate any missing views - if(rd_view_is_nil(watch)) - { - watch = rd_view_alloc(); - rd_view_equip_spec(watch, rd_view_rule_info_from_kind(RD_ViewRuleKind_Watch), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(locals)) - { - locals = rd_view_alloc(); - rd_view_equip_spec(locals, rd_view_rule_info_from_kind(RD_ViewRuleKind_Locals), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(regs)) - { - regs = rd_view_alloc(); - rd_view_equip_spec(regs, rd_view_rule_info_from_kind(RD_ViewRuleKind_Registers), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(globals)) - { - globals = rd_view_alloc(); - rd_view_equip_spec(globals, rd_view_rule_info_from_kind(RD_ViewRuleKind_Globals), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(tlocals)) - { - tlocals = rd_view_alloc(); - rd_view_equip_spec(tlocals, rd_view_rule_info_from_kind(RD_ViewRuleKind_ThreadLocals), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(types)) - { - types = rd_view_alloc(); - rd_view_equip_spec(types, rd_view_rule_info_from_kind(RD_ViewRuleKind_Types), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(procs)) - { - procs = rd_view_alloc(); - rd_view_equip_spec(procs, rd_view_rule_info_from_kind(RD_ViewRuleKind_Procedures), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(callstack)) - { - callstack = rd_view_alloc(); - rd_view_equip_spec(callstack, rd_view_rule_info_from_kind(RD_ViewRuleKind_CallStack), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(breakpoints)) - { - breakpoints = rd_view_alloc(); - rd_view_equip_spec(breakpoints, rd_view_rule_info_from_kind(RD_ViewRuleKind_Breakpoints), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(watch_pins)) - { - watch_pins = rd_view_alloc(); - rd_view_equip_spec(watch_pins, rd_view_rule_info_from_kind(RD_ViewRuleKind_WatchPins), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(output)) - { - output = rd_view_alloc(); - rd_view_equip_spec(output, rd_view_rule_info_from_kind(RD_ViewRuleKind_Output), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(targets)) - { - targets = rd_view_alloc(); - rd_view_equip_spec(targets, rd_view_rule_info_from_kind(RD_ViewRuleKind_Targets), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(scheduler)) - { - scheduler = rd_view_alloc(); - rd_view_equip_spec(scheduler, rd_view_rule_info_from_kind(RD_ViewRuleKind_Scheduler), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(modules)) - { - modules = rd_view_alloc(); - rd_view_equip_spec(modules, rd_view_rule_info_from_kind(RD_ViewRuleKind_Modules), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(disasm)) - { - disasm = rd_view_alloc(); - rd_view_equip_spec(disasm, rd_view_rule_info_from_kind(RD_ViewRuleKind_Disasm), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(memory)) - { - memory = rd_view_alloc(); - rd_view_equip_spec(memory, rd_view_rule_info_from_kind(RD_ViewRuleKind_Memory), str8_zero(), &md_nil_node); - } - if(code_views.count == 0 && rd_view_is_nil(getting_started)) - { - getting_started = rd_view_alloc(); - rd_view_equip_spec(getting_started, rd_view_rule_info_from_kind(RD_ViewRuleKind_GettingStarted), str8_zero(), &md_nil_node); - } - - //- rjf: apply layout - switch(layout) - { - //- rjf: default layout - case Layout_Default: + + //- rjf: (default layout) + case RD_CmdKind_ResetToDefaultPanels: { // rjf: root split - ws->root_panel->split_axis = Axis2_X; - RD_Panel *root_0 = rd_panel_alloc(ws); - RD_Panel *root_1 = rd_panel_alloc(ws); - rd_panel_insert(ws->root_panel, ws->root_panel->last, root_0); - rd_panel_insert(ws->root_panel, ws->root_panel->last, root_1); - root_0->pct_of_parent = 0.85f; - root_1->pct_of_parent = 0.15f; + rd_cfg_child_from_string_or_alloc(window, str8_lit("split_x")); + RD_Cfg *root_0 = rd_cfg_new(panels, str8_lit("0.85")); + RD_Cfg *root_1 = rd_cfg_new(panels, str8_lit("0.15")); // rjf: root_0 split - root_0->split_axis = Axis2_Y; - RD_Panel *root_0_0 = rd_panel_alloc(ws); - RD_Panel *root_0_1 = rd_panel_alloc(ws); - rd_panel_insert(root_0, root_0->last, root_0_0); - rd_panel_insert(root_0, root_0->last, root_0_1); - root_0_0->pct_of_parent = 0.80f; - root_0_1->pct_of_parent = 0.20f; + RD_Cfg *root_0_0 = rd_cfg_new(root_0, str8_lit("0.80")); + RD_Cfg *root_0_1 = rd_cfg_new(root_0, str8_lit("0.20")); // rjf: root_1 split - root_1->split_axis = Axis2_Y; - RD_Panel *root_1_0 = rd_panel_alloc(ws); - RD_Panel *root_1_1 = rd_panel_alloc(ws); - rd_panel_insert(root_1, root_1->last, root_1_0); - rd_panel_insert(root_1, root_1->last, root_1_1); - root_1_0->pct_of_parent = 0.50f; - root_1_1->pct_of_parent = 0.50f; - rd_panel_insert_tab_view(root_1_0, root_1_0->last_tab_view, targets); - rd_panel_insert_tab_view(root_1_1, root_1_1->last_tab_view, scheduler); - root_1_0->selected_tab_view = rd_handle_from_view(targets); - root_1_1->selected_tab_view = rd_handle_from_view(scheduler); - root_1_1->tab_side = Side_Max; + RD_Cfg *root_1_0 = rd_cfg_new(root_1, str8_lit("0.50")); + RD_Cfg *root_1_1 = rd_cfg_new(root_1, str8_lit("0.50")); + rd_cfg_insert_child(root_1_0, root_1_0->last, targets); + rd_cfg_insert_child(root_1_1, root_1_1->last, threads); + rd_cfg_insert_child(root_1_1, root_1_1->last, processes); + rd_cfg_insert_child(root_1_1, root_1_1->last, machines); + rd_cfg_new(targets, str8_lit("selected")); + rd_cfg_new(threads, str8_lit("selected")); - // rjf: root_0_0 split - root_0_0->split_axis = Axis2_X; - RD_Panel *root_0_0_0 = rd_panel_alloc(ws); - RD_Panel *root_0_0_1 = rd_panel_alloc(ws); - rd_panel_insert(root_0_0, root_0_0->last, root_0_0_0); - rd_panel_insert(root_0_0, root_0_0->last, root_0_0_1); - root_0_0_0->pct_of_parent = 0.25f; - root_0_0_1->pct_of_parent = 0.75f; + // rjf: root 0_0 split + RD_Cfg *root_0_0_0 = rd_cfg_new(root_0_0, str8_lit("0.25")); + RD_Cfg *root_0_0_1 = rd_cfg_new(root_0_0, str8_lit("0.75")); // rjf: root_0_0_0 split - root_0_0_0->split_axis = Axis2_Y; - RD_Panel *root_0_0_0_0 = rd_panel_alloc(ws); - RD_Panel *root_0_0_0_1 = rd_panel_alloc(ws); - rd_panel_insert(root_0_0_0, root_0_0_0->last, root_0_0_0_0); - rd_panel_insert(root_0_0_0, root_0_0_0->last, root_0_0_0_1); - root_0_0_0_0->pct_of_parent = 0.5f; - root_0_0_0_1->pct_of_parent = 0.5f; - rd_panel_insert_tab_view(root_0_0_0_0, root_0_0_0_0->last_tab_view, disasm); - root_0_0_0_0->selected_tab_view = rd_handle_from_view(disasm); - rd_panel_insert_tab_view(root_0_0_0_1, root_0_0_0_1->last_tab_view, breakpoints); - rd_panel_insert_tab_view(root_0_0_0_1, root_0_0_0_1->last_tab_view, watch_pins); - rd_panel_insert_tab_view(root_0_0_0_1, root_0_0_0_1->last_tab_view, output); - rd_panel_insert_tab_view(root_0_0_0_1, root_0_0_0_1->last_tab_view, memory); - root_0_0_0_1->selected_tab_view = rd_handle_from_view(output); + RD_Cfg *root_0_0_0_0 = rd_cfg_new(root_0_0_0, str8_lit("0.50")); + RD_Cfg *root_0_0_0_1 = rd_cfg_new(root_0_0_0, str8_lit("0.50")); + rd_cfg_insert_child(root_0_0_0_0, root_0_0_0_0->last, disasm); + rd_cfg_new(disasm, str8_lit("selected")); + rd_cfg_insert_child(root_0_0_0_1, root_0_0_0_1->last, breakpoints); + rd_cfg_insert_child(root_0_0_0_1, root_0_0_0_1->last, watch_pins); + rd_cfg_insert_child(root_0_0_0_1, root_0_0_0_1->last, output); + rd_cfg_insert_child(root_0_0_0_1, root_0_0_0_1->last, memory); + rd_cfg_new(output, str8_lit("selected")); // rjf: root_0_1 split - root_0_1->split_axis = Axis2_X; - RD_Panel *root_0_1_0 = rd_panel_alloc(ws); - RD_Panel *root_0_1_1 = rd_panel_alloc(ws); - rd_panel_insert(root_0_1, root_0_1->last, root_0_1_0); - rd_panel_insert(root_0_1, root_0_1->last, root_0_1_1); - root_0_1_0->pct_of_parent = 0.60f; - root_0_1_1->pct_of_parent = 0.40f; - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, watch); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, locals); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, regs); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, globals); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, tlocals); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, types); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, procs); - root_0_1_0->selected_tab_view = rd_handle_from_view(watch); - root_0_1_0->tab_side = Side_Max; - rd_panel_insert_tab_view(root_0_1_1, root_0_1_1->last_tab_view, callstack); - rd_panel_insert_tab_view(root_0_1_1, root_0_1_1->last_tab_view, modules); - root_0_1_1->selected_tab_view = rd_handle_from_view(callstack); - root_0_1_1->tab_side = Side_Max; + RD_Cfg *root_0_1_0 = rd_cfg_new(root_0_1, str8_lit("0.60")); + RD_Cfg *root_0_1_1 = rd_cfg_new(root_0_1, str8_lit("0.40")); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, watches); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, locals); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, registers); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, globals); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, thread_locals); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, types); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, procedures); + rd_cfg_new(watches, str8_lit("selected")); + rd_cfg_new(root_0_1_0, str8_lit("tabs_on_bottom")); + rd_cfg_insert_child(root_0_1_1, root_0_1_1->last, call_stack); + rd_cfg_insert_child(root_0_1_1, root_0_1_1->last, modules); + rd_cfg_new(call_stack, str8_lit("selected")); + rd_cfg_new(root_0_1_1, str8_lit("tabs_on_bottom")); // rjf: fill main panel with getting started, OR all collected code views - if(!rd_view_is_nil(getting_started)) + RD_Cfg *main_panel = root_0_0_1; + if(getting_started != &rd_nil_cfg) { - rd_panel_insert_tab_view(root_0_0_1, root_0_0_1->last_tab_view, getting_started); + rd_cfg_insert_child(main_panel, main_panel->last, getting_started); + rd_cfg_new(getting_started, str8_lit("selected")); } - for(RD_HandleNode *n = code_views.first; n != 0; n = n->next) + else if(texts.first) { - RD_View *view = rd_view_from_handle(n->handle); - if(!rd_view_is_nil(view)) - { - rd_panel_insert_tab_view(root_0_0_1, root_0_0_1->last_tab_view, view); - } + rd_cfg_new(texts.first->v, str8_lit("selected")); + } + for(RD_CfgNode *n = texts.first; n != 0; n = n->next) + { + rd_cfg_insert_child(main_panel, main_panel->last, n->v); } - // rjf: choose initial focused panel - ws->focused_panel = root_0_0_1; + // rjf: set main panel as selected + rd_cfg_new(main_panel, str8_lit("selected")); }break; - //- rjf: compact layout: - case Layout_Compact: + //- rjf: (compact layout) + case RD_CmdKind_ResetToCompactPanels: { // rjf: root split - ws->root_panel->split_axis = Axis2_X; - RD_Panel *root_0 = rd_panel_alloc(ws); - RD_Panel *root_1 = rd_panel_alloc(ws); - rd_panel_insert(ws->root_panel, ws->root_panel->last, root_0); - rd_panel_insert(ws->root_panel, ws->root_panel->last, root_1); - root_0->pct_of_parent = 0.25f; - root_1->pct_of_parent = 0.75f; + rd_cfg_child_from_string_or_alloc(window, str8_lit("split_x")); + RD_Cfg *root_0 = rd_cfg_new(panels, str8_lit("0.25")); + RD_Cfg *root_1 = rd_cfg_new(panels, str8_lit("0.75")); // rjf: root_0 split - root_0->split_axis = Axis2_Y; - RD_Panel *root_0_0 = rd_panel_alloc(ws); - { - if(!rd_view_is_nil(watch)) { rd_panel_insert_tab_view(root_0_0, root_0_0->last_tab_view, watch); } - if(!rd_view_is_nil(types)) { rd_panel_insert_tab_view(root_0_0, root_0_0->last_tab_view, types); } - root_0_0->selected_tab_view = rd_handle_from_view(watch); - } - RD_Panel *root_0_1 = rd_panel_alloc(ws); - { - if(!rd_view_is_nil(scheduler)) { rd_panel_insert_tab_view(root_0_1, root_0_1->last_tab_view, scheduler); } - if(!rd_view_is_nil(targets)) { rd_panel_insert_tab_view(root_0_1, root_0_1->last_tab_view, targets); } - if(!rd_view_is_nil(breakpoints)) { rd_panel_insert_tab_view(root_0_1, root_0_1->last_tab_view, breakpoints); } - if(!rd_view_is_nil(watch_pins)) { rd_panel_insert_tab_view(root_0_1, root_0_1->last_tab_view, watch_pins); } - root_0_1->selected_tab_view = rd_handle_from_view(scheduler); - } - RD_Panel *root_0_2 = rd_panel_alloc(ws); - { - if(!rd_view_is_nil(disasm)) { rd_panel_insert_tab_view(root_0_2, root_0_2->last_tab_view, disasm); } - if(!rd_view_is_nil(output)) { rd_panel_insert_tab_view(root_0_2, root_0_2->last_tab_view, output); } - root_0_2->selected_tab_view = rd_handle_from_view(disasm); - } - RD_Panel *root_0_3 = rd_panel_alloc(ws); - { - if(!rd_view_is_nil(callstack)) { rd_panel_insert_tab_view(root_0_3, root_0_3->last_tab_view, callstack); } - if(!rd_view_is_nil(modules)) { rd_panel_insert_tab_view(root_0_3, root_0_3->last_tab_view, modules); } - root_0_3->selected_tab_view = rd_handle_from_view(callstack); - } - rd_panel_insert(root_0, root_0->last, root_0_0); - rd_panel_insert(root_0, root_0->last, root_0_1); - rd_panel_insert(root_0, root_0->last, root_0_2); - rd_panel_insert(root_0, root_0->last, root_0_3); - root_0_0->pct_of_parent = 0.25f; - root_0_1->pct_of_parent = 0.25f; - root_0_2->pct_of_parent = 0.25f; - root_0_3->pct_of_parent = 0.25f; + RD_Cfg *root_0_0 = rd_cfg_new(root_0, str8_lit("0.25")); + RD_Cfg *root_0_1 = rd_cfg_new(root_0, str8_lit("0.25")); + RD_Cfg *root_0_2 = rd_cfg_new(root_0, str8_lit("0.25")); + RD_Cfg *root_0_3 = rd_cfg_new(root_0, str8_lit("0.25")); + rd_cfg_insert_child(root_0_0, root_0_0->last, watches); + rd_cfg_insert_child(root_0_0, root_0_0->last, types); + rd_cfg_new(watches, str8_lit("selected")); + rd_cfg_insert_child(root_0_1, root_0_1->last, threads); + rd_cfg_insert_child(root_0_1, root_0_1->last, targets); + rd_cfg_insert_child(root_0_1, root_0_1->last, breakpoints); + rd_cfg_insert_child(root_0_1, root_0_1->last, watch_pins); + rd_cfg_new(threads, str8_lit("selected")); + rd_cfg_insert_child(root_0_2, root_0_2->last, disasm); + rd_cfg_insert_child(root_0_2, root_0_2->last, output); + rd_cfg_new(disasm, str8_lit("selected")); + rd_cfg_insert_child(root_0_3, root_0_3->last, call_stack); + rd_cfg_insert_child(root_0_3, root_0_3->last, modules); + rd_cfg_new(call_stack, str8_lit("selected")); // rjf: fill main panel with getting started, OR all collected code views - if(!rd_view_is_nil(getting_started)) + RD_Cfg *main_panel = root_1; + if(getting_started != &rd_nil_cfg) { - rd_panel_insert_tab_view(root_1, root_1->last_tab_view, getting_started); + rd_cfg_insert_child(main_panel, main_panel->last, getting_started); + rd_cfg_new(getting_started, str8_lit("selected")); } - for(RD_HandleNode *n = code_views.first; n != 0; n = n->next) + else if(texts.first) { - RD_View *view = rd_view_from_handle(n->handle); - if(!rd_view_is_nil(view)) - { - rd_panel_insert_tab_view(root_1, root_1->last_tab_view, view); - } + rd_cfg_new(texts.first->v, str8_lit("selected")); + } + for(RD_CfgNode *n = texts.first; n != 0; n = n->next) + { + rd_cfg_insert_child(main_panel, main_panel->last, n->v); } - // rjf: choose initial focused panel - ws->focused_panel = root_1; + // rjf: set main panel as selected + rd_cfg_new(main_panel, str8_lit("selected")); + }break; + + //- rjf: simple layout + case RD_CmdKind_ResetToSimplePanels: + { + // rjf: root split + rd_cfg_child_from_string_or_alloc(window, str8_lit("split_x")); + RD_Cfg *root_0 = rd_cfg_new(panels, str8_lit("0.25")); + RD_Cfg *root_1 = rd_cfg_new(panels, str8_lit("0.75")); + + // rjf: fill smaller panel with watch + rd_cfg_insert_child(root_0, root_0->last, watches); + rd_cfg_new(watches, str8_lit("selected")); + + // rjf: fill main panel with getting started, OR all collected code views + RD_Cfg *main_panel = root_1; + if(getting_started != &rd_nil_cfg) + { + rd_cfg_insert_child(main_panel, main_panel->last, getting_started); + rd_cfg_new(getting_started, str8_lit("selected")); + } + else if(texts.first) + { + rd_cfg_new(texts.first->v, str8_lit("selected")); + } + for(RD_CfgNode *n = texts.first; n != 0; n = n->next) + { + rd_cfg_insert_child(main_panel, main_panel->last, n->v); + } + + // rjf: set main panel as selected + rd_cfg_new(main_panel, str8_lit("selected")); }break; } - // rjf: dispatch cfg saves - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) + //- rjf: release any unused views from the previous layout +#define X(name) if(name->parent == &rd_nil_cfg) {rd_cfg_release(name);} +#define Y(name, rule, expr) if(name->parent == &rd_nil_cfg) {rd_cfg_release(name);} +#define Z(name) if(name->parent == &rd_nil_cfg) {rd_cfg_release(name);} + FixedTab_XList +#undef X +#undef Y +#undef Z + + //- rjf: remember that we reset the panel layouts + RD_WindowState *ws = rd_window_state_from_cfg(window); + if(ws != &rd_nil_window_state) { - RD_CmdKind write_cmd = rd_cfg_src_write_cmd_kind_table[src]; - rd_cmd(write_cmd, .file_path = rd_cfg_path_from_src(src)); + ws->window_layout_reset = 1; } }break; //- rjf: thread finding case RD_CmdKind_FindThread: - for(RD_Window *ws = rd_state->first_window; ws != 0; ws = ws->next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) + RD_RegsScope(.window = ws->cfg_id) { DI_Scope *scope = di_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); @@ -14807,7 +15619,8 @@ rd_frame(void) di_scope_close(scope); }break; case RD_CmdKind_FindSelectedThread: - for(RD_Window *ws = rd_state->first_window; ws != 0; ws = ws->next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) + RD_RegsScope(.window = ws->cfg_id) { CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); rd_cmd(RD_CmdKind_FindThread, @@ -14859,8 +15672,9 @@ rd_frame(void) String8List search_parts = str8_split_path(scratch.arena, file_part_of_name); // rjf: get source path - RD_View *src_view = rd_view_from_handle(rd_regs()->view); - String8 src_file_path = rd_file_path_from_eval_string(scratch.arena, str8(src_view->query_buffer, src_view->query_string_size)); + RD_Cfg *src_view = rd_cfg_from_id(rd_regs()->view); + String8 src_view_expr = rd_expr_from_cfg(src_view); + String8 src_file_path = rd_file_path_from_eval_string(scratch.arena, src_view_expr); String8List src_file_parts = str8_split_path(scratch.arena, src_file_path); // rjf: search for actual file @@ -14973,7 +15787,8 @@ rd_frame(void) // the biggest empty panel. // 4. If there is no empty panel, then we will pick the biggest // panel. - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); // rjf: grab things to find. path * point, process * address, etc. String8 file_path = {0}; @@ -15009,25 +15824,28 @@ rd_frame(void) } // rjf: first, try to find panel/view pair that already has the src file open - RD_Panel *panel_w_this_src_code = &rd_nil_panel; - RD_View *view_w_this_src_code = &rd_nil_view; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + RD_PanelNode *panel_w_this_src_code = &rd_nil_panel_node; + RD_Cfg *view_w_this_src_code = &rd_nil_cfg; + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - if(!rd_panel_is_nil(panel->first)) + if(panel->first != &rd_nil_panel_node) { continue; } - for(RD_View *view = panel->first_tab_view; !rd_view_is_nil(view); view = view->order_next) + for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next) { - if(rd_view_is_project_filtered(view)) { continue; } - String8 view_file_path = rd_file_path_from_eval_string(scratch.arena, str8(view->query_buffer, view->query_string_size)); - RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(view->spec->string); - if((view_kind == RD_ViewRuleKind_Text || view_kind == RD_ViewRuleKind_PendingFile) && - path_match_normalized(view_file_path, file_path)) + RD_Cfg *tab = tab_n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } + String8 tab_expr = rd_expr_from_cfg(tab); + String8 tab_file_path = rd_file_path_from_eval_string(scratch.arena, tab_expr); + if((str8_match(tab->string, str8_lit("text"), 0) || str8_match(tab->string, str8_lit("pending"), 0)) && + path_match_normalized(tab_file_path, file_path)) { panel_w_this_src_code = panel; - view_w_this_src_code = view; - if(view == rd_selected_tab_from_panel(panel)) + view_w_this_src_code = tab; + if(tab == panel->selected_tab) { break; } @@ -15035,25 +15853,53 @@ rd_frame(void) } } - // rjf: find a panel that already has *any* code open (prioritize largest) - RD_Panel *panel_w_any_src_code = &rd_nil_panel; + // rjf: try to find panel/view pair that has any *auto* source code tab open + RD_PanelNode *panel_w_auto = &rd_nil_panel_node; + RD_Cfg *view_w_auto = &rd_nil_cfg; + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - Rng2F32 root_rect = os_client_rect_from_window(ws->os); - F32 best_panel_area = 0; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + if(panel->first != &rd_nil_panel_node) { - if(!rd_panel_is_nil(panel->first)) + continue; + } + for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next) + { + RD_Cfg *tab = tab_n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } + if(str8_match(tab->string, str8_lit("text"), 0) && + rd_cfg_child_from_string(tab, str8_lit("auto")) != &rd_nil_cfg) + { + panel_w_auto = panel; + view_w_auto = tab; + } + } + } + + // rjf: find a panel that already has *any* code open (prioritize largest) + RD_PanelNode *panel_w_any_src_code = &rd_nil_panel_node; + { + Rng2F32 root_rect = r2f32(v2f32(0, 0), v2f32(1000, 1000)); + F32 best_panel_area = 0; + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) + { + if(panel->first != &rd_nil_panel_node) { continue; } - Rng2F32 panel_rect = rd_target_rect_from_panel(root_rect, ws->root_panel, panel); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(root_rect, panel_tree.root, panel); Vec2F32 panel_rect_dim = dim_2f32(panel_rect); F32 panel_area = panel_rect_dim.x*panel_rect_dim.y; - for(RD_View *view = panel->first_tab_view; !rd_view_is_nil(view); view = view->order_next) + for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next) { - if(rd_view_is_project_filtered(view)) { continue; } - RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(view->spec->string); - if(view_kind == RD_ViewRuleKind_Text && panel_area > best_panel_area) + RD_Cfg *tab = tab_n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } + String8 view_expr = rd_expr_from_cfg(tab); + String8 file_path = rd_file_path_from_eval_string(scratch.arena, view_expr); + if(str8_match(tab->string, str8_lit("text"), 0) && file_path.size != 0 && panel_area > best_panel_area) { panel_w_any_src_code = panel; best_panel_area = panel_area; @@ -15064,34 +15910,39 @@ rd_frame(void) } // rjf: try to find panel/view pair that has disassembly open (prioritize largest) - RD_Panel *panel_w_disasm = &rd_nil_panel; - RD_View *view_w_disasm = &rd_nil_view; + RD_PanelNode *panel_w_disasm = &rd_nil_panel_node; + RD_Cfg *view_w_disasm = &rd_nil_cfg; { - Rng2F32 root_rect = os_client_rect_from_window(ws->os); + Rng2F32 root_rect = r2f32(v2f32(0, 0), v2f32(1000, 1000)); F32 best_panel_area = 0; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - if(!rd_panel_is_nil(panel->first)) + if(panel->first != &rd_nil_panel_node) { continue; } - Rng2F32 panel_rect = rd_target_rect_from_panel(root_rect, ws->root_panel, panel); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(root_rect, panel_tree.root, panel); Vec2F32 panel_rect_dim = dim_2f32(panel_rect); F32 panel_area = panel_rect_dim.x*panel_rect_dim.y; - RD_View *panel_selected_tab = rd_selected_tab_from_panel(panel); - for(RD_View *view = panel->first_tab_view; !rd_view_is_nil(view); view = view->order_next) + for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next) { - if(rd_view_is_project_filtered(view)) { continue; } - RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(view->spec->string); - B32 view_is_selected = (view == panel_selected_tab); - if(view_kind == RD_ViewRuleKind_Disasm && view->query_string_size == 0 && panel_area > best_panel_area) + RD_Cfg *tab = tab_n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } + RD_RegsScope(.view = tab->id) { - panel_w_disasm = panel; - view_w_disasm = view; - best_panel_area = panel_area; - if(view_is_selected) + B32 tab_is_selected = (tab == panel->selected_tab); + String8 expr_string = rd_expr_from_cfg(tab); + if(str8_match(tab->string, str8_lit("disasm"), 0) && expr_string.size == 0 && panel_area > best_panel_area) { - break; + panel_w_disasm = panel; + view_w_disasm = tab; + best_panel_area = panel_area; + if(tab_is_selected) + { + break; + } } } } @@ -15099,73 +15950,81 @@ rd_frame(void) } // rjf: find the biggest panel - RD_Panel *biggest_panel = &rd_nil_panel; + RD_PanelNode *biggest_panel = &rd_nil_panel_node; { - Rng2F32 root_rect = os_client_rect_from_window(ws->os); + Rng2F32 root_rect = r2f32(v2f32(0, 0), v2f32(1000, 1000)); F32 best_panel_area = 0; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - if(!rd_panel_is_nil(panel->first)) + if(panel->first != &rd_nil_panel_node) { continue; } - Rng2F32 panel_rect = rd_target_rect_from_panel(root_rect, ws->root_panel, panel); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(root_rect, panel_tree.root, panel); Vec2F32 panel_rect_dim = dim_2f32(panel_rect); - F32 area = panel_rect_dim.x * panel_rect_dim.y; - if((best_panel_area == 0 || area > best_panel_area)) + F32 panel_area = panel_rect_dim.x*panel_rect_dim.y; + if((best_panel_area == 0 || panel_area > best_panel_area)) { - best_panel_area = area; + best_panel_area = panel_area; biggest_panel = panel; } } } // rjf: find the biggest empty panel - RD_Panel *biggest_empty_panel = &rd_nil_panel; + RD_PanelNode *biggest_empty_panel = &rd_nil_panel_node; { - Rng2F32 root_rect = os_client_rect_from_window(ws->os); + Rng2F32 root_rect = r2f32(v2f32(0, 0), v2f32(1000, 1000)); F32 best_panel_area = 0; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - if(!rd_panel_is_nil(panel->first)) + if(panel->first != &rd_nil_panel_node) { continue; } - Rng2F32 panel_rect = rd_target_rect_from_panel(root_rect, ws->root_panel, panel); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(root_rect, panel_tree.root, panel); Vec2F32 panel_rect_dim = dim_2f32(panel_rect); - F32 area = panel_rect_dim.x * panel_rect_dim.y; + F32 panel_area = panel_rect_dim.x*panel_rect_dim.y; B32 panel_is_empty = 1; - for(RD_View *v = panel->first_tab_view; !rd_view_is_nil(v); v = v->order_next) + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) { - if(!rd_view_is_project_filtered(v)) + RD_Cfg *tab = n->v; + if(!rd_cfg_is_project_filtered(tab)) { panel_is_empty = 0; break; } } - if(panel_is_empty && (best_panel_area == 0 || area > best_panel_area)) + if(panel_is_empty && (best_panel_area == 0 || panel_area > best_panel_area)) { - best_panel_area = area; + best_panel_area = panel_area; biggest_empty_panel = panel; } } } // rjf: choose panel for source code - RD_Panel *src_code_dst_panel = &rd_nil_panel; + RD_PanelNode *src_code_dst_panel = &rd_nil_panel_node; + if(file_path.size != 0) { - if(rd_panel_is_nil(src_code_dst_panel)) { src_code_dst_panel = panel_w_this_src_code; } - if(rd_panel_is_nil(src_code_dst_panel)) { src_code_dst_panel = panel_w_any_src_code; } - if(rd_panel_is_nil(src_code_dst_panel)) { src_code_dst_panel = biggest_empty_panel; } - if(rd_panel_is_nil(src_code_dst_panel)) { src_code_dst_panel = biggest_panel; } + if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = panel_w_this_src_code; } + if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = panel_w_auto; } + if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = panel_w_any_src_code; } + if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = biggest_empty_panel; } + if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = biggest_panel; } } // rjf: choose panel for disassembly - RD_Panel *disasm_dst_panel = &rd_nil_panel; + RD_PanelNode *disasm_dst_panel = &rd_nil_panel_node; + if(vaddr != 0) { - if(rd_panel_is_nil(disasm_dst_panel)) { disasm_dst_panel = panel_w_disasm; } - if(rd_panel_is_nil(disasm_dst_panel)) { disasm_dst_panel = biggest_empty_panel; } - if(rd_panel_is_nil(disasm_dst_panel)) { disasm_dst_panel = biggest_panel; } + if(disasm_dst_panel == &rd_nil_panel_node) { disasm_dst_panel = panel_w_disasm; } + if(disasm_dst_panel == &rd_nil_panel_node) { disasm_dst_panel = biggest_empty_panel; } + if(disasm_dst_panel == &rd_nil_panel_node) { disasm_dst_panel = biggest_panel; } } // rjf: if disasm and source code match: @@ -15175,56 +16034,75 @@ rd_frame(void) { if(rd_regs()->prefer_disasm) { - src_code_dst_panel = &rd_nil_panel; + src_code_dst_panel = &rd_nil_panel_node; } else { - disasm_dst_panel = &rd_nil_panel; + disasm_dst_panel = &rd_nil_panel_node; } } // rjf: if disasm is not preferred, and we have no disassembly view // open at all, cancel disasm, so that it doesn't open if the user // doesn't want it. - if(!rd_regs()->prefer_disasm && panel_w_disasm == &rd_nil_panel) + if(!rd_regs()->prefer_disasm && panel_w_disasm == &rd_nil_panel_node && file_path.size != 0) { - disasm_dst_panel = &rd_nil_panel; + disasm_dst_panel = &rd_nil_panel_node; + } + + // rjf: if disasm is not preferred, and we have no disassembly view + // *selected* at all, cancel disasm, so that it doesn't open if the user + // doesn't want it. + if(!rd_regs()->prefer_disasm && view_w_disasm != &rd_nil_cfg && rd_cfg_child_from_string(view_w_disasm, str8_lit("selected")) == &rd_nil_cfg && + file_path.size != 0) + { + disasm_dst_panel = &rd_nil_panel_node; } // rjf: given the above, find source code location. - if(file_path.size != 0 && src_code_dst_panel != &rd_nil_panel) + if(file_path.size != 0 && src_code_dst_panel != &rd_nil_panel_node) { - RD_Panel *dst_panel = src_code_dst_panel; + RD_PanelNode *dst_panel = src_code_dst_panel; // rjf: construct new view if needed - RD_View *dst_view = view_w_this_src_code; - if(!rd_panel_is_nil(dst_panel) && rd_view_is_nil(view_w_this_src_code)) + RD_Cfg *dst_tab = view_w_this_src_code; + if(dst_tab == &rd_nil_cfg && dst_panel == panel_w_auto && view_w_auto != &rd_nil_cfg) { - RD_View *view = rd_view_alloc(); - String8 file_path_query = rd_eval_string_from_file_path(scratch.arena, file_path); - rd_view_equip_spec(view, rd_view_rule_info_from_kind(RD_ViewRuleKind_Text), file_path_query, &md_nil_node); - rd_panel_insert_tab_view(dst_panel, dst_panel->last_tab_view, view); - dst_view = view; + dst_tab = view_w_auto; + RD_ViewState *vs = rd_view_state_from_cfg(dst_tab); + vs->last_frame_index_built = 0; + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(dst_tab, str8_lit("expression")); + rd_cfg_new_replace(expr, rd_eval_string_from_file_path(scratch.arena, file_path)); + rd_cfg_new_replace(rd_cfg_child_from_string(dst_tab, str8_lit("cursor_line")), str8_lit("1")); + rd_cfg_new_replace(rd_cfg_child_from_string(dst_tab, str8_lit("cursor_column")), str8_lit("1")); + rd_cfg_new_replace(rd_cfg_child_from_string(dst_tab, str8_lit("mark_line")), str8_lit("1")); + rd_cfg_new_replace(rd_cfg_child_from_string(dst_tab, str8_lit("mark_column")), str8_lit("1")); + } + else if(dst_panel != &rd_nil_panel_node && dst_tab == &rd_nil_cfg) + { + dst_tab = rd_cfg_new(dst_panel->cfg, str8_lit("text")); + RD_Cfg *expr = rd_cfg_new(dst_tab, str8_lit("expression")); + rd_cfg_new(expr, rd_eval_string_from_file_path(scratch.arena, file_path)); + rd_cfg_new(dst_tab, str8_lit("auto")); } // rjf: determine if we need a contain or center RD_CmdKind cursor_snap_kind = RD_CmdKind_CenterCursor; - if(!rd_panel_is_nil(dst_panel) && dst_view == view_w_this_src_code && rd_selected_tab_from_panel(dst_panel) == dst_view) + if(dst_panel != &rd_nil_panel_node && dst_tab == view_w_this_src_code && dst_panel->selected_tab == dst_tab) { cursor_snap_kind = RD_CmdKind_ContainCursor; } // rjf: move cursor & snap-to-cursor - if(!rd_panel_is_nil(dst_panel)) + if(dst_panel != &rd_nil_panel_node) RD_RegsScope(.panel = dst_panel->cfg->id, + .view = dst_tab->id) { - dst_panel->selected_tab_view = rd_handle_from_view(dst_view); - rd_cmd(RD_CmdKind_GoToLine, - .panel = rd_handle_from_panel(dst_panel), - .view = rd_handle_from_view(dst_view), - .cursor = point); - rd_cmd(cursor_snap_kind, - .panel = rd_handle_from_panel(dst_panel), - .view = rd_handle_from_view(dst_view)); + rd_cmd(RD_CmdKind_FocusTab); + if(point.line != 0) + { + rd_cmd(RD_CmdKind_GoToLine, .cursor = point); + } + rd_cmd(cursor_snap_kind); } // rjf: record @@ -15232,267 +16110,277 @@ rd_frame(void) } // rjf: given the above, find disassembly location. - if(process != &ctrl_entity_nil && vaddr != 0 && disasm_dst_panel != &rd_nil_panel) + if(process != &ctrl_entity_nil && vaddr != 0 && disasm_dst_panel != &rd_nil_panel_node) { - RD_Panel *dst_panel = disasm_dst_panel; + RD_PanelNode *dst_panel = disasm_dst_panel; - // rjf: construct new view if needed - RD_View *dst_view = view_w_disasm; - if(!rd_panel_is_nil(dst_panel) && rd_view_is_nil(view_w_disasm)) + // rjf: construct new tab if needed + RD_Cfg *dst_tab = view_w_disasm; + if(dst_panel != &rd_nil_panel_node && view_w_disasm == &rd_nil_cfg) { - RD_View *view = rd_view_alloc(); - rd_view_equip_spec(view, rd_view_rule_info_from_kind(RD_ViewRuleKind_Disasm), str8_zero(), &md_nil_node); - rd_panel_insert_tab_view(dst_panel, dst_panel->last_tab_view, view); - dst_view = view; + dst_tab = rd_cfg_new(dst_panel->cfg, str8_lit("disasm")); } // rjf: determine if we need a contain or center RD_CmdKind cursor_snap_kind = RD_CmdKind_CenterCursor; - if(dst_view == view_w_disasm && rd_selected_tab_from_panel(dst_panel) == dst_view) + if(dst_tab == view_w_disasm && dst_panel->selected_tab == dst_tab) { cursor_snap_kind = RD_CmdKind_ContainCursor; } // rjf: move cursor & snap-to-cursor - if(!rd_panel_is_nil(dst_panel)) + if(dst_panel != &rd_nil_panel_node) RD_RegsScope(.panel = dst_panel->cfg->id, + .view = dst_tab->id) { - dst_panel->selected_tab_view = rd_handle_from_view(dst_view); - rd_cmd(RD_CmdKind_GoToAddress, - .process = process->handle, .vaddr = vaddr, - .panel = rd_handle_from_panel(dst_panel), - .view = rd_handle_from_view(dst_view)); + rd_cmd(RD_CmdKind_FocusTab); + rd_cmd(RD_CmdKind_GoToAddress, .process = process->handle, .vaddr = vaddr); rd_cmd(cursor_snap_kind); } } }break; - //- rjf: filtering - case RD_CmdKind_Filter: + //- rjf: queries + case RD_CmdKind_PushQuery: { - RD_View *view = rd_view_from_handle(rd_regs()->view); - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - B32 view_is_tab = 0; - for(RD_View *tab = panel->first_tab_view; !rd_view_is_nil(tab); tab = tab->order_next) + String8 cmd_name = rd_regs()->cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + + // rjf: floating queries -> set up window to build immediate-mode top-level query + RD_Cfg *view = &rd_nil_cfg; + if(cmd_name.size == 0 || cmd_kind_info->query.flags & RD_QueryFlag_Floating) { - if(rd_view_is_project_filtered(tab)) { continue; } - if(tab == view) + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + if(ws != &rd_nil_window_state) { - view_is_tab = 1; - break; + ws->query_is_active = 1; + arena_clear(ws->query_arena); + ws->query_regs = rd_regs_copy(ws->query_arena, rd_regs()); + } + RD_Cfg *window_query = rd_immediate_cfg_from_keyf("window_query_%p", window); + view = rd_cfg_child_from_string_or_alloc(window_query, str8_lit("watch")); + } + + // rjf: non-floating -> embed in tab parameter + else + { + view = rd_cfg_from_id(rd_regs()->view); + } + + // rjf: unpack view's query info + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); + RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + + // rjf: choose initial input string + String8 initial_input = {0}; + if(cmd_name.size != 0) + { + if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + { + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *current_path = rd_cfg_child_from_string(user, str8_lit("current_path")); + String8 current_path_string = current_path->first->string; + if(current_path_string.size == 0) + { + current_path_string = path_normalized_from_string(scratch.arena, os_get_current_path(scratch.arena)); + } + else + { + current_path_string = path_normalized_from_string(scratch.arena, current_path_string); + } + initial_input = path_normalized_from_string(scratch.arena, current_path_string); + initial_input = push_str8f(scratch.arena, "%S/", initial_input); + } + else if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) + { + initial_input = input->first->string; } } - if(view_is_tab && view->spec->flags & RD_ViewRuleInfoFlag_CanFilter) + + // rjf: build query state + String8 current_query_cmd_name = cmd->first->string; + rd_cfg_new_replace(input, initial_input); + rd_cfg_new_replace(cmd, cmd_name); + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(cmd_name.size != 0) { - view->is_filtering ^= 1; - view->query_cursor = txt_pt(1, 1+(S64)view->query_string_size); - view->query_mark = txt_pt(1, 1); + if(!vs->query_is_selected && cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) + { + vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_mark = txt_pt(1, 1); + } + else + { + vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_mark = vs->query_cursor; + } + if(!str8_match(current_query_cmd_name, cmd_name, 0)) + { + vs->query_is_selected = 1; + } + else + { + vs->query_is_selected ^= 1; + } } }break; - case RD_CmdKind_ClearFilter: - { - RD_View *view = rd_view_from_handle(rd_regs()->view); - if(!rd_view_is_nil(view)) - { - view->query_string_size = 0; - view->is_filtering = 0; - view->query_cursor = view->query_mark = txt_pt(1, 1); - } - }break; - case RD_CmdKind_ApplyFilter: - { - RD_View *view = rd_view_from_handle(rd_regs()->view); - if(!rd_view_is_nil(view)) - { - view->is_filtering = 0; - } - }break; - - //- rjf: query completion case RD_CmdKind_CompleteQuery: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - String8 query_cmd_name = ws->query_cmd_name; - RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(query_cmd_name); - RD_RegSlot slot = info->query.slot; - - // rjf: compound command parameters - if(slot != RD_RegSlot_Null && !(ws->query_cmd_regs_mask[slot/64] & (1ull<<(slot%64)))) + String8 cmd_name = rd_view_query_cmd(); + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + RD_RegsScope() { - RD_Regs *regs_copy = rd_regs_copy(ws->query_cmd_arena, rd_regs()); - Rng1U64 offset_range_in_regs = rd_reg_slot_range_table[slot]; - MemoryCopy((U8 *)(ws->query_cmd_regs) + offset_range_in_regs.min, - (U8 *)(regs_copy) + offset_range_in_regs.min, - dim_1u64(offset_range_in_regs)); - ws->query_cmd_regs_mask[slot/64] |= (1ull<<(slot%64)); + rd_push_cmd(cmd_name, rd_regs()); } - - // rjf: determine if command is ready to run - B32 command_ready = 1; - if(slot != RD_RegSlot_Null && !(ws->query_cmd_regs_mask[slot/64] & (1ull<<(slot%64)))) + if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) { - command_ready = 0; + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + ws->query_is_active = 0; } - - // rjf: end this query - if(!(info->query.flags & RD_QueryFlag_KeepOldInput)) + else if(!(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput)) { - rd_cmd(RD_CmdKind_CancelQuery); - } - - // rjf: unset command register slot, if we keep old input (and thus need - // to re-query user) - if(info->query.flags & RD_QueryFlag_KeepOldInput) - { - ws->query_cmd_regs_mask[slot/64] &= ~(1ull<<(slot%64)); - } - - // rjf: push command if possible - if(command_ready) - { - rd_push_cmd(ws->query_cmd_name, ws->query_cmd_regs); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); + vs->query_is_selected = 0; + vs->query_string_size = 0; } }break; case RD_CmdKind_CancelQuery: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - arena_clear(ws->query_cmd_arena); - MemoryZeroStruct(&ws->query_cmd_name); - ws->query_cmd_regs = 0; - MemoryZeroArray(ws->query_cmd_regs_mask); - for(RD_View *v = ws->query_view_stack_top, *next = 0; !rd_view_is_nil(v); v = next) + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + if(ws != &rd_nil_window_state) { - next = v->order_next; - rd_view_release(v); + ws->query_is_active = 0; + arena_clear(ws->query_arena); + ws->query_regs = 0; } - ws->query_view_stack_top = &rd_nil_view; + }break; + case RD_CmdKind_UpdateQuery: + { + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + rd_cfg_new_replace(input, rd_regs()->string); + RD_ViewState *vs = rd_view_state_from_cfg(view); + vs->query_cursor = vs->query_mark = txt_pt(1, rd_regs()->string.size+1); + vs->query_string_size = Min(sizeof(vs->query_buffer), rd_regs()->string.size); + MemoryCopy(vs->query_buffer, rd_regs()->string.str, vs->query_string_size); }break; //- rjf: developer commands case RD_CmdKind_ToggleDevMenu: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); ws->dev_menu_is_open ^= 1; }break; //- rjf: general entity operations - case RD_CmdKind_SelectEntity: + case RD_CmdKind_SelectCfg: case RD_CmdKind_SelectTarget: { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - RD_EntityList all_of_the_same_kind = rd_query_cached_entity_list_with_kind(entity->kind); - B32 is_selected = !entity->disabled; - for(RD_EntityNode *n = all_of_the_same_kind.first; n != 0; n = n->next) + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); + RD_CfgList all_of_the_same_kind = rd_cfg_top_level_list_from_string(scratch.arena, cfg->string); + B32 is_selected = !rd_disabled_from_cfg(cfg); + for(RD_CfgNode *n = all_of_the_same_kind.first; n != 0; n = n->next) { - RD_Entity *e = n->entity; - rd_entity_equip_disabled(e, 1); - } - if(!is_selected) - { - rd_entity_equip_disabled(entity, 0); + RD_Cfg *c = n->v; + rd_cfg_release(rd_cfg_child_from_string(c, str8_lit("enabled"))); } + RD_Cfg *enabled_root = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("enabled")); + rd_cfg_new_replace(enabled_root, str8_lit("1")); }break; - case RD_CmdKind_EnableEntity: + case RD_CmdKind_EnableCfg: case RD_CmdKind_EnableBreakpoint: case RD_CmdKind_EnableTarget: { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - rd_entity_equip_disabled(entity, 0); + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); + RD_Cfg *enabled_root = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("enabled")); + rd_cfg_new_replacef(enabled_root, "1"); }break; - case RD_CmdKind_DisableEntity: + case RD_CmdKind_DisableCfg: case RD_CmdKind_DisableBreakpoint: case RD_CmdKind_DisableTarget: + case RD_CmdKind_DeselectCfg: { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - rd_entity_equip_disabled(entity, 1); + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); + rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("enabled"))); }break; - case RD_CmdKind_RemoveEntity: + case RD_CmdKind_RemoveCfg: { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - RD_EntityKindFlags kind_flags = rd_entity_kind_flags_table[entity->kind]; - if(kind_flags & RD_EntityKindFlag_CanDelete) + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); + rd_cfg_release(cfg); + }break; + case RD_CmdKind_NameCfg: + { + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); + if(rd_regs()->string.size != 0) { - rd_entity_mark_for_deletion(entity); - } - }break; - case RD_CmdKind_NameEntity: - { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - String8 string = rd_regs()->string; - rd_entity_equip_name(entity, string); - }break; - case RD_CmdKind_ConditionEntity: - { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - String8 string = rd_regs()->string; - if(string.size != 0) - { - RD_Entity *child = rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Condition); - rd_entity_equip_name(child, string); + RD_Cfg *label = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("label")); + rd_cfg_new(label, rd_regs()->string); } else { - RD_Entity *child = rd_entity_child_from_kind(entity, RD_EntityKind_Condition); - rd_entity_mark_for_deletion(child); + rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("label"))); } }break; - case RD_CmdKind_DuplicateEntity: + case RD_CmdKind_ConditionCfg: { - RD_Entity *src = rd_entity_from_handle(rd_regs()->entity); - if(!rd_entity_is_nil(src)) + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); + if(rd_regs()->string.size != 0) { - typedef struct Task Task; - struct Task + RD_Cfg *cnd = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("condition")); + rd_cfg_new(cnd, rd_regs()->string); + } + else + { + rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("condition"))); + } + }break; + case RD_CmdKind_DuplicateCfg: + { + RD_Cfg *src = rd_cfg_from_id(rd_regs()->cfg); + RD_Cfg *dst = rd_cfg_deep_copy(src); + rd_cfg_insert_child(src->parent, src, dst); + }break; + case RD_CmdKind_RelocateCfg: + { + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); + + // rjf: release old location info + { + RD_Cfg *src_loc = rd_cfg_child_from_string(cfg, str8_lit("source_location")); + RD_Cfg *addr_loc = rd_cfg_child_from_string(cfg, str8_lit("address_location")); + rd_cfg_release(src_loc); + rd_cfg_release(addr_loc); + } + + // rjf: attach new location info + { + String8 file_path = rd_regs()->file_path; + TxtPt pt = rd_regs()->cursor; + String8 expr_string = rd_regs()->expr; + U64 vaddr = rd_regs()->vaddr; + if(expr_string.size == 0 && vaddr != 0) { - Task *next; - RD_Entity *src_n; - RD_Entity *dst_parent; - }; - Task starter_task = {0, src, src->parent}; - Task *first_task = &starter_task; - Task *last_task = &starter_task; - for(Task *task = first_task; task != 0; task = task->next) - { - RD_Entity *src_n = task->src_n; - RD_Entity *dst_n = rd_entity_alloc(task->dst_parent, task->src_n->kind); - if(src_n->flags & RD_EntityFlag_HasTextPoint) {rd_entity_equip_txt_pt(dst_n, src_n->text_point);} - if(src_n->flags & RD_EntityFlag_HasU64) {rd_entity_equip_u64(dst_n, src_n->u64);} - if(src_n->flags & RD_EntityFlag_HasColor) {rd_entity_equip_color_hsva(dst_n, rd_hsva_from_entity(src_n));} - if(src_n->flags & RD_EntityFlag_HasVAddr) {rd_entity_equip_vaddr(dst_n, src_n->vaddr);} - if(src_n->disabled) {rd_entity_equip_disabled(dst_n, 1);} - if(src_n->string.size != 0) {rd_entity_equip_name(dst_n, src_n->string);} - dst_n->cfg_src = src_n->cfg_src; - for(RD_Entity *src_child = task->src_n->first; !rd_entity_is_nil(src_child); src_child = src_child->next) - { - Task *child_task = push_array(scratch.arena, Task, 1); - child_task->src_n = src_child; - child_task->dst_parent = dst_n; - SLLQueuePush(first_task, last_task, child_task); - } + expr_string = push_str8f(scratch.arena, "0x%I64x", vaddr); + } + if(file_path.size != 0 && pt.line != 0) + { + RD_Cfg *src_loc = rd_cfg_new(cfg, str8_lit("source_location")); + RD_Cfg *file = rd_cfg_new(src_loc, file_path); + RD_Cfg *line = rd_cfg_newf(file, "%I64d", pt.line); + RD_Cfg *col = rd_cfg_newf(line, "%I64d", pt.column); + (void)col; + } + else if(expr_string.size != 0) + { + RD_Cfg *vaddr_loc = rd_cfg_new(cfg, str8_lit("address_location")); + rd_cfg_new(vaddr_loc, expr_string); } - } - }break; - case RD_CmdKind_RelocateEntity: - { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - RD_Entity *location = rd_entity_child_from_kind(entity, RD_EntityKind_Location); - if(rd_entity_is_nil(location)) - { - location = rd_entity_alloc(entity, RD_EntityKind_Location); - } - location->flags &= ~RD_EntityFlag_HasTextPoint; - location->flags &= ~RD_EntityFlag_HasVAddr; - if(rd_regs()->cursor.line != 0) - { - rd_entity_equip_txt_pt(location, rd_regs()->cursor); - } - if(rd_regs()->vaddr != 0) - { - rd_entity_equip_vaddr(location, rd_regs()->vaddr); - rd_entity_equip_name(location, str8_zero()); - } - if(rd_regs()->file_path.size != 0) - { - rd_entity_equip_name(location, rd_regs()->file_path); } }break; @@ -15502,99 +16390,45 @@ rd_frame(void) { String8 file_path = rd_regs()->file_path; TxtPt pt = rd_regs()->cursor; - String8 string = rd_regs()->string; U64 vaddr = rd_regs()->vaddr; - if(file_path.size != 0 || string.size != 0 || vaddr != 0) + String8 expr = rd_regs()->expr; + if(expr.size == 0 && vaddr != 0) { - //- TODO(rjf): @cfg add/toggle breakpoint + expr = push_str8f(scratch.arena, "0x%I64x", vaddr); + } + if(file_path.size != 0 || expr.size != 0) + { + B32 already_exists = 0; + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { - B32 removed_already_existing = 0; - if(kind == RD_CmdKind_ToggleBreakpoint) + RD_Cfg *bp = n->v; + RD_Cfg *cnd = rd_cfg_child_from_string(bp, str8_lit("condition")); + RD_Location loc = rd_location_from_cfg(bp); + B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc.file_path, file_path) && loc.pt.line == pt.line); + B32 loc_matches_expr = (expr.size != 0 && str8_match(expr, loc.expr, 0)); + if((loc_matches_file_pt || loc_matches_expr) && cnd->first->string.size == 0) { - RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); - for(RD_CfgNode *n = bps.first; n != 0; n = n->next) + if(kind == RD_CmdKind_ToggleBreakpoint) { - RD_Cfg *bp = n->v; - RD_Cfg *loc = rd_cfg_child_from_string(bp, str8_lit("location")); - S64 loc_line = 0; - U64 loc_vaddr = 0; - B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc->first->string, file_path) && try_s64_from_str8_c_rules(loc->first->first->string, &loc_line) && loc_line == pt.line); - B32 loc_matches_string = (string.size != 0 && str8_match(loc->first->string, string, 0)); - B32 loc_matches_vaddr = (vaddr != 0 && try_u64_from_str8_c_rules(loc->first->string, &loc_vaddr) && loc_vaddr == vaddr); - if(loc_matches_file_pt || loc_matches_string || loc_matches_vaddr) - { - rd_cfg_release(bp); - removed_already_existing = 1; - break; - } - } - } - if(!removed_already_existing) - { - RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - RD_Cfg *bp = rd_cfg_new(project, str8_lit("breakpoint")); - RD_Cfg *loc = rd_cfg_new(bp, str8_lit("location")); - if(vaddr != 0) - { - rd_cfg_newf(loc, "0x%I64x", vaddr); - } - else if(string.size != 0) - { - rd_cfg_new(loc, string); - } - else if(file_path.size != 0) - { - RD_Cfg *file_path_cfg = rd_cfg_new(loc, file_path); - rd_cfg_newf(file_path_cfg, "%I64d", pt.line); + rd_cfg_release(bp); } + already_exists = 1; + break; } } - B32 removed_already_existing = 0; - if(kind == RD_CmdKind_ToggleBreakpoint) + if(!already_exists) { - RD_EntityList bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - for(RD_EntityNode *n = bps.first; n != 0; n = n->next) - { - RD_Entity *bp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(bp, RD_EntityKind_Location); - if((loc->flags & RD_EntityFlag_HasTextPoint && path_match_normalized(loc->string, file_path) && loc->text_point.line == pt.line) || - (loc->flags & RD_EntityFlag_HasVAddr && loc->vaddr == vaddr) || - (!(loc->flags & RD_EntityFlag_HasTextPoint) && str8_match(loc->string, string, 0))) - { - rd_entity_mark_for_deletion(bp); - removed_already_existing = 1; - break; - } - } - } - if(!removed_already_existing) - { - RD_Entity *bp = rd_entity_alloc(rd_entity_root(), RD_EntityKind_Breakpoint); - rd_entity_equip_cfg_src(bp, RD_CfgSrc_Project); - RD_Entity *loc = rd_entity_alloc(bp, RD_EntityKind_Location); - if(vaddr != 0) - { - rd_entity_equip_vaddr(loc, vaddr); - } - else if(string.size != 0) - { - rd_entity_equip_name(loc, string); - } - else if(file_path.size != 0 && pt.line != 0) - { - rd_entity_equip_name(loc, file_path); - rd_entity_equip_txt_pt(loc, pt); - } + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + RD_Cfg *bp = rd_cfg_new(project, str8_lit("breakpoint")); + rd_cmd(RD_CmdKind_RelocateCfg, .cfg = bp->id); } } }break; case RD_CmdKind_AddAddressBreakpoint: - { - rd_cmd(RD_CmdKind_AddBreakpoint, .string = str8_zero()); - }break; case RD_CmdKind_AddFunctionBreakpoint: { - rd_cmd(RD_CmdKind_AddBreakpoint, .vaddr = 0); + rd_cmd(RD_CmdKind_AddBreakpoint, .file_path = str8_zero()); }break; //- rjf: watch pins @@ -15603,101 +16437,72 @@ rd_frame(void) { String8 file_path = rd_regs()->file_path; TxtPt pt = rd_regs()->cursor; - String8 string = rd_regs()->string; + String8 expr_string = rd_regs()->expr; + String8 view_rule_string = rd_regs()->view_rule; U64 vaddr = rd_regs()->vaddr; - //- TODO(rjf): @cfg add/toggle watch pin - { - B32 removed_already_existing = 0; - if(kind == RD_CmdKind_ToggleWatchPin) - { - RD_CfgList wps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch_pin")); - for(RD_CfgNode *n = wps.first; n != 0; n = n->next) - { - RD_Cfg *wp = n->v; - RD_Cfg *name = rd_cfg_child_from_string(wp, str8_lit("name")); - RD_Cfg *loc = rd_cfg_child_from_string(wp, str8_lit("location")); - S64 loc_line = 0; - U64 loc_vaddr = 0; - B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc->first->string, file_path) && try_s64_from_str8_c_rules(loc->first->first->string, &loc_line) && loc_line == pt.line); - B32 loc_matches_vaddr = (vaddr != 0 && try_u64_from_str8_c_rules(loc->first->string, &loc_vaddr) && loc_vaddr == vaddr); - B32 loc_matches_expr = (string.size != 0 && str8_match(name->first->string, string, 0)); - if(loc_matches_expr && (loc_matches_file_pt || loc_matches_vaddr)) - { - rd_cfg_release(wp); - removed_already_existing = 1; - break; - } - } - } - if(!removed_already_existing) - { - RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - RD_Cfg *wp = rd_cfg_new(project, str8_lit("watch_pin")); - RD_Cfg *name = rd_cfg_new(wp, str8_lit("name")); - RD_Cfg *loc = rd_cfg_new(wp, str8_lit("location")); - rd_cfg_new(name, string); - if(vaddr != 0) - { - rd_cfg_newf(loc, "0x%I64x", vaddr); - } - else if(file_path.size != 0) - { - RD_Cfg *file_path_cfg = rd_cfg_new(loc, file_path); - rd_cfg_newf(file_path_cfg, "%I64d", pt.line); - } - } - } B32 removed_already_existing = 0; if(kind == RD_CmdKind_ToggleWatchPin) { - RD_EntityList wps = rd_query_cached_entity_list_with_kind(RD_EntityKind_WatchPin); - for(RD_EntityNode *n = wps.first; n != 0; n = n->next) + RD_CfgList wps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch_pin")); + for(RD_CfgNode *n = wps.first; n != 0; n = n->next) { - RD_Entity *wp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(wp, RD_EntityKind_Location); - if(str8_match(wp->string, string, 0) && - ((loc->flags & RD_EntityFlag_HasTextPoint && path_match_normalized(loc->string, file_path) && loc->text_point.line == pt.line) || - (loc->flags & RD_EntityFlag_HasVAddr && loc->vaddr == vaddr))) + RD_Cfg *wp = n->v; + RD_Cfg *expr = rd_cfg_child_from_string(wp, str8_lit("expression")); + RD_Location loc = rd_location_from_cfg(wp); + B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc.file_path, file_path) && loc.pt.line == pt.line); + B32 loc_matches_expr = (expr_string.size != 0 && str8_match(expr_string, loc.expr, 0)); + if((loc_matches_file_pt || loc_matches_expr) && str8_match(expr->first->string, expr_string, 0)) { - rd_entity_mark_for_deletion(wp); + rd_cfg_release(wp); removed_already_existing = 1; - break; } } } if(!removed_already_existing) { - RD_Entity *wp = rd_entity_alloc(rd_entity_root(), RD_EntityKind_WatchPin); - rd_entity_equip_name(wp, string); - rd_entity_equip_cfg_src(wp, RD_CfgSrc_Project); - RD_Entity *loc = rd_entity_alloc(wp, RD_EntityKind_Location); - if(file_path.size != 0 && pt.line != 0) - { - rd_entity_equip_name(loc, file_path); - rd_entity_equip_txt_pt(loc, pt); - } - else if(vaddr != 0) - { - rd_entity_equip_vaddr(loc, vaddr); - } + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + RD_Cfg *wp = rd_cfg_new(project, str8_lit("watch_pin")); + RD_Cfg *expr = rd_cfg_new(wp, str8_lit("expression")); + RD_Cfg *view_rule = rd_cfg_new(wp, str8_lit("view_rule")); + rd_cfg_new(expr, expr_string); + rd_cfg_new(view_rule, view_rule_string); + rd_cmd(RD_CmdKind_RelocateCfg, .cfg = wp->id, .expr = str8_zero()); } }break; + //- rjf: auto view rules + case RD_CmdKind_AddAutoViewRule: + { + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + rd_cfg_new(project, str8_lit("auto_view_rule")); + }break; + //- rjf: watches case RD_CmdKind_ToggleWatchExpression: if(rd_regs()->string.size != 0) { - RD_Entity *existing_watch = rd_entity_from_name_and_kind(rd_regs()->string, RD_EntityKind_Watch); - if(rd_entity_is_nil(existing_watch)) + RD_CfgList all_existing_watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); + RD_Cfg *existing_watch = &rd_nil_cfg; + for(RD_CfgNode *n = all_existing_watches.first; n != 0; n = n->next) { - RD_Entity *watch = &rd_nil_entity; - watch = rd_entity_alloc(rd_entity_root(), RD_EntityKind_Watch); - rd_entity_equip_cfg_src(watch, RD_CfgSrc_Project); - rd_entity_equip_name(watch, rd_regs()->string); + RD_Cfg *watch = n->v; + String8 expr = rd_expr_from_cfg(watch); + if(str8_match(expr, rd_regs()->string, 0)) + { + existing_watch = watch; + break; + } + } + if(existing_watch == &rd_nil_cfg) + { + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + RD_Cfg *watch = rd_cfg_new(project, str8_lit("watch")); + RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); + rd_cfg_new(expr, rd_regs()->string); } else { - rd_entity_mark_for_deletion(existing_watch); + rd_cfg_release(existing_watch); } }break; @@ -15731,17 +16536,6 @@ rd_frame(void) txt_scope_close(txt_scope); hs_scope_close(hs_scope); }break; - case RD_CmdKind_RunToCursor: - { - if(rd_regs()->file_path.size != 0) - { - rd_cmd(RD_CmdKind_RunToLine); - } - else - { - rd_cmd(RD_CmdKind_RunToAddress); - } - }break; case RD_CmdKind_SetNextStatement: { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); @@ -15767,37 +16561,18 @@ rd_frame(void) //- rjf: targets case RD_CmdKind_AddTarget: { - //- TODO(rjf): @cfg add new target + String8 file_path = rd_regs()->file_path; + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + RD_Cfg *target = rd_cfg_new(project, str8_lit("target")); + RD_Cfg *exe = rd_cfg_new(target, str8_lit("executable")); + rd_cfg_new(exe, file_path); + String8 working_directory = str8_chop_last_slash(file_path); + if(working_directory.size != 0) { - String8 file_path = rd_regs()->file_path; - RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - RD_Cfg *target = rd_cfg_new(project, str8_lit("target")); - RD_Cfg *exe = rd_cfg_new(target, str8_lit("executable")); - rd_cfg_new(exe, file_path); - String8 working_directory = str8_chop_last_slash(file_path); - if(working_directory.size != 0) - { - RD_Cfg *wdir = rd_cfg_new(target, str8_lit("working_directory")); - rd_cfg_newf(wdir, "%S/", working_directory); - } - // TODO(rjf): (select target here) + RD_Cfg *wdir = rd_cfg_new(target, str8_lit("working_directory")); + rd_cfg_newf(wdir, "%S/", working_directory); } - - // rjf: build target - RD_Entity *entity = &rd_nil_entity; - entity = rd_entity_alloc(rd_entity_root(), RD_EntityKind_Target); - rd_entity_equip_disabled(entity, 1); - rd_entity_equip_cfg_src(entity, RD_CfgSrc_Project); - RD_Entity *exe = rd_entity_alloc(entity, RD_EntityKind_Executable); - rd_entity_equip_name(exe, rd_regs()->file_path); - String8 working_dir = str8_chop_last_slash(rd_regs()->file_path); - if(working_dir.size != 0) - { - String8 working_dir_path = push_str8f(scratch.arena, "%S/", working_dir); - RD_Entity *execution_path = rd_entity_alloc(entity, RD_EntityKind_WorkingDirectory); - rd_entity_equip_name(execution_path, working_dir_path); - } - rd_cmd(RD_CmdKind_SelectTarget, .entity = rd_handle_from_entity(entity)); + rd_cmd(RD_CmdKind_SelectTarget, .cfg = target->id); }break; //- rjf: jit-debugger registration @@ -15847,8 +16622,8 @@ rd_frame(void) case RD_CmdKind_OSEvent: { OS_Event *os_event = rd_regs()->os_event; - RD_Window *ws = rd_window_from_os_handle(os_event->window); - if(os_event != 0 && ws != 0) + RD_WindowState *ws = rd_window_state_from_os_handle(os_event->window); + if(os_event != 0 && ws != &rd_nil_window_state) { UI_Event ui_event = zero_struct; UI_EventKind kind = UI_EventKind_Null; @@ -15877,6 +16652,10 @@ rd_frame(void) }break; //- rjf: debug control context management operations + case RD_CmdKind_SelectEntity: + { + rd_cmd(RD_CmdKind_SelectThread, .thread = rd_regs()->ctrl_entity); + }break; case RD_CmdKind_SelectThread: { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); @@ -15897,19 +16676,16 @@ rd_frame(void) CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); - if(rd_regs()->unwind_count < rich_unwind.concrete_frame_count) + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); + CTRL_CallStackFrame *frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); + if(frame == 0) + { + frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, 0); + } + if(frame) { - CTRL_CallStackFrame *frame = &rich_unwind.frames[rd_regs()->unwind_count]; - U64 rip_vaddr = regs_rip_from_arch_block(thread->arch, frame->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); - rd_state->base_regs.v.module = module->handle; rd_state->base_regs.v.unwind_count = rd_regs()->unwind_count; - rd_state->base_regs.v.inline_depth = 0; - if(rd_regs()->inline_depth <= frame->inline_frame_count) - { - rd_state->base_regs.v.inline_depth = rd_regs()->inline_depth; - } + rd_state->base_regs.v.inline_depth = rd_regs()->inline_depth; } rd_cmd(RD_CmdKind_FindThread, .thread = thread->handle, .unwind_count = rd_state->base_regs.v.unwind_count, .inline_depth = rd_state->base_regs.v.inline_depth); di_scope_close(di_scope); @@ -15921,53 +16697,38 @@ rd_frame(void) CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); - U64 crnt_unwind_idx = rd_state->base_regs.v.unwind_count; - U64 crnt_inline_dpt = rd_state->base_regs.v.inline_depth; - U64 next_unwind_idx = crnt_unwind_idx; - U64 next_inline_dpt = crnt_inline_dpt; - if(crnt_unwind_idx < rich_unwind.concrete_frame_count) + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); + CTRL_CallStackFrame *current_frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); + CTRL_CallStackFrame *next_frame = current_frame; + if(current_frame != 0) switch(kind) { - CTRL_CallStackFrame *f = &rich_unwind.frames[crnt_unwind_idx]; - switch(kind) + default:{}break; + case RD_CmdKind_UpOneFrame: + if(current_frame > call_stack.frames) { - default:{}break; - case RD_CmdKind_UpOneFrame: - { - if(crnt_inline_dpt < f->inline_frame_count) - { - next_inline_dpt += 1; - } - else if(crnt_unwind_idx > 0) - { - next_unwind_idx -= 1; - next_inline_dpt = 0; - } - }break; - case RD_CmdKind_DownOneFrame: - { - if(crnt_inline_dpt > 0) - { - next_inline_dpt -= 1; - } - else if(crnt_unwind_idx < rich_unwind.concrete_frame_count) - { - next_unwind_idx += 1; - next_inline_dpt = (f+1)->inline_frame_count; - } - }break; - } + next_frame = current_frame-1; + }break; + case RD_CmdKind_DownOneFrame: + if(current_frame+1 < call_stack.frames + call_stack.count) + { + next_frame = current_frame+1; + }break; + } + if(next_frame != 0) + { + CTRL_CallStackFrame *next_base_frame = next_frame + next_frame->inline_depth; + rd_cmd(RD_CmdKind_SelectUnwind, + .unwind_count = next_frame->unwind_count, + .inline_depth = next_frame->inline_depth); } - rd_cmd(RD_CmdKind_SelectUnwind, - .unwind_count = next_unwind_idx, - .inline_depth = next_inline_dpt); di_scope_close(di_scope); }break; //- rjf: meta controls case RD_CmdKind_Edit: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Press; evt.slot = UI_EventActionSlot_Edit; @@ -15975,7 +16736,8 @@ rd_frame(void) }break; case RD_CmdKind_Accept: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Press; evt.slot = UI_EventActionSlot_Accept; @@ -15983,7 +16745,8 @@ rd_frame(void) }break; case RD_CmdKind_Cancel: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Press; evt.slot = UI_EventActionSlot_Cancel; @@ -15998,7 +16761,8 @@ rd_frame(void) // case RD_CmdKind_MoveLeft: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_PickSelectSide|UI_EventFlag_ZeroDeltaOnSelect|UI_EventFlag_ExplicitDirectional; @@ -16008,7 +16772,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveRight: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_PickSelectSide|UI_EventFlag_ZeroDeltaOnSelect|UI_EventFlag_ExplicitDirectional; @@ -16018,7 +16783,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUp: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -16028,7 +16794,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDown: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -16038,7 +16805,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveLeftSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -16048,7 +16816,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveRightSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -16058,7 +16827,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -16068,7 +16838,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -16078,7 +16849,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveLeftChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -16088,7 +16860,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveRightChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -16098,7 +16871,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -16108,7 +16882,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -16118,7 +16893,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpPage: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Page; @@ -16127,7 +16903,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownPage: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Page; @@ -16136,7 +16913,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpWhole: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Whole; @@ -16145,7 +16923,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownWhole: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Whole; @@ -16154,7 +16933,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveLeftChunkSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -16164,7 +16944,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveRightChunkSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -16174,7 +16955,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpChunkSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -16184,7 +16966,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownChunkSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -16194,7 +16977,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpPageSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -16204,7 +16988,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownPageSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -16214,7 +16999,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpWholeSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -16224,7 +17010,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownWholeSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -16234,7 +17021,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpReorder: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_Reorder; @@ -16244,7 +17032,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownReorder: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_Reorder; @@ -16254,7 +17043,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveHome: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Line; @@ -16263,7 +17053,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveEnd: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Line; @@ -16272,7 +17063,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveHomeSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -16282,7 +17074,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveEndSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -16292,7 +17085,8 @@ rd_frame(void) }break; case RD_CmdKind_SelectAll: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt1 = zero_struct; evt1.kind = UI_EventKind_Navigate; evt1.delta_unit = UI_EventDeltaUnit_Whole; @@ -16307,7 +17101,8 @@ rd_frame(void) }break; case RD_CmdKind_DeleteSingle: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; @@ -16317,7 +17112,8 @@ rd_frame(void) }break; case RD_CmdKind_DeleteChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; @@ -16327,7 +17123,8 @@ rd_frame(void) }break; case RD_CmdKind_BackspaceSingle: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete|UI_EventFlag_ZeroDeltaOnSelect; @@ -16337,7 +17134,8 @@ rd_frame(void) }break; case RD_CmdKind_BackspaceChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; @@ -16347,7 +17145,8 @@ rd_frame(void) }break; case RD_CmdKind_Copy: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Copy|UI_EventFlag_KeepMark; @@ -16355,7 +17154,8 @@ rd_frame(void) }break; case RD_CmdKind_Cut: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Copy|UI_EventFlag_Delete; @@ -16363,7 +17163,8 @@ rd_frame(void) }break; case RD_CmdKind_Paste: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Text; evt.string = os_get_clipboard_text(scratch.arena); @@ -16371,7 +17172,8 @@ rd_frame(void) }break; case RD_CmdKind_InsertText: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Text; evt.string = rd_regs()->string; @@ -16387,19 +17189,20 @@ rd_frame(void) D_TargetArray targets = {0}; ProfScope("gather targets") { - RD_EntityList target_entities = rd_query_cached_entity_list_with_kind(RD_EntityKind_Target); - targets.count = target_entities.count; + RD_CfgList target_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); + targets.count = target_cfgs.count; targets.v = push_array(scratch.arena, D_Target, targets.count); U64 idx = 0; - for(RD_EntityNode *n = target_entities.first; n != 0; n = n->next) + for(RD_CfgNode *n = target_cfgs.first; n != 0; n = n->next) { - RD_Entity *src_target = n->entity; - if(src_target->disabled) + RD_Cfg *src = n->v; + B32 src_is_disabled = rd_disabled_from_cfg(src); + if(src_is_disabled) { targets.count -= 1; continue; } - targets.v[idx] = rd_d_target_from_entity(src_target); + targets.v[idx] = rd_target_from_cfg(scratch.arena, src); idx += 1; } } @@ -16408,32 +17211,23 @@ rd_frame(void) //- rjf: gather breakpoints & meta-evals (for the engine, meta-evals can only be referenced by breakpoints) // D_BreakpointArray breakpoints = {0}; - CTRL_MetaEvalArray meta_evals = {0}; ProfScope("gather breakpoints & meta-evals") { - typedef struct MetaEvalNode MetaEvalNode; - struct MetaEvalNode - { - MetaEvalNode *next; - CTRL_MetaEval *meval; - }; - U64 meval_count = 0; - MetaEvalNode *first_meval = 0; - MetaEvalNode *last_meval = 0; - RD_EntityList bp_entities = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - breakpoints.count = bp_entities.count; + RD_CfgList bp_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + breakpoints.count = bp_cfgs.count; breakpoints.v = push_array(scratch.arena, D_Breakpoint, breakpoints.count); U64 idx = 0; - for(RD_EntityNode *n = bp_entities.first; n != 0; n = n->next) + for(RD_CfgNode *n = bp_cfgs.first; n != 0; n = n->next) { - RD_Entity *src_bp = n->entity; - if(src_bp->disabled) + RD_Cfg *src_bp = n->v; + B32 src_bp_is_disabled = rd_disabled_from_cfg(src_bp); + if(src_bp_is_disabled) { breakpoints.count -= 1; continue; } - RD_Entity *src_bp_loc = rd_entity_child_from_kind(src_bp, RD_EntityKind_Location); - RD_Entity *src_bp_cnd = rd_entity_child_from_kind(src_bp, RD_EntityKind_Condition); + RD_Location src_bp_loc = rd_location_from_cfg(src_bp); + String8 src_bp_cnd = rd_cfg_child_from_string(src_bp, str8_lit("condition"))->first->string; //- rjf: walk conditional breakpoint expression tree - for each leaf identifier, // determine if it resolves to a meta-evaluation. if it does, compute the meta @@ -16446,7 +17240,7 @@ rd_frame(void) // or not it is 'static', w.r.t. the control thread. // B32 is_static_for_ctrl_thread = 0; - if(src_bp_cnd->string.size != 0) + if(src_bp_cnd.size != 0) { typedef struct ExprWalkTask ExprWalkTask; struct ExprWalkTask @@ -16454,14 +17248,14 @@ rd_frame(void) ExprWalkTask *next; E_Expr *expr; }; - E_Expr *expr = e_parse_expr_from_text(scratch.arena, src_bp_cnd->string); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, src_bp_cnd).exprs.last; ExprWalkTask start_task = {0, expr}; ExprWalkTask *first_task = &start_task; for(ExprWalkTask *t = first_task; t != 0; t = t->next) { if(t->expr->kind == E_ExprKind_LeafIdent) { - E_Expr *macro_expr = e_string2expr_lookup(e_ir_ctx->macro_map, t->expr->string); + E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, t->expr->string); if(macro_expr != &e_expr_nil) { E_Eval eval = e_eval_from_expr(scratch.arena, macro_expr); @@ -16469,17 +17263,9 @@ rd_frame(void) { default:{is_static_for_ctrl_thread = 0;}break; case E_SpaceKind_Null: - case RD_EvalSpaceKind_MetaEntity: + case RD_EvalSpaceKind_MetaCfg: { is_static_for_ctrl_thread = 1; - RD_Entity *entity = rd_entity_from_eval_space(eval.space); - if(!rd_entity_is_nil(entity)) - { - MetaEvalNode *meval_node = push_array(scratch.arena, MetaEvalNode, 1); - meval_node->meval = rd_ctrl_meta_eval_from_entity(scratch.arena, entity); - SLLQueuePush(first_meval, last_meval, meval_node); - meval_count += 1; - } }break; } } @@ -16498,14 +17284,16 @@ rd_frame(void) // we can evaluate this condition early, and decide whether or not to send this // breakpoint. B32 is_statically_disqualified = 0; + String8 non_ctrl_thread_static_condition = src_bp_cnd; if(is_static_for_ctrl_thread) { - E_Eval eval = e_eval_from_string(scratch.arena, src_bp_cnd->string); + E_Eval eval = e_eval_from_string(scratch.arena, src_bp_cnd); E_Eval value_eval = e_value_eval_from_eval(eval); if(value_eval.value.u64 == 0) { is_statically_disqualified = 1; } + MemoryZeroStruct(&non_ctrl_thread_static_condition); } //- rjf: statically disqualified? -> skip @@ -16517,25 +17305,12 @@ rd_frame(void) //- rjf: fill breakpoint D_Breakpoint *dst_bp = &breakpoints.v[idx]; - dst_bp->file_path = src_bp_loc->string; - dst_bp->pt = src_bp_loc->text_point; - dst_bp->symbol_name = src_bp_loc->string; - dst_bp->vaddr = src_bp_loc->vaddr; - dst_bp->condition = src_bp_cnd->string; + dst_bp->file_path = src_bp_loc.file_path; + dst_bp->pt = src_bp_loc.pt; + dst_bp->vaddr_expr = src_bp_loc.expr; + dst_bp->condition = non_ctrl_thread_static_condition; idx += 1; } - - //- rjf: meta-eval list -> array - meta_evals.count = meval_count; - meta_evals.v = push_array(scratch.arena, CTRL_MetaEval, meta_evals.count); - { - U64 idx = 0; - for(MetaEvalNode *n = first_meval; n != 0; n = n->next) - { - MemoryCopyStruct(&meta_evals.v[idx], n->meval); - idx += 1; - } - } } //////////////////////////// @@ -16543,15 +17318,15 @@ rd_frame(void) // D_PathMapArray path_maps = {0}; { - RD_EntityList maps = rd_query_cached_entity_list_with_kind(RD_EntityKind_FilePathMap); + RD_CfgList maps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("file_path_map")); path_maps.count = maps.count; path_maps.v = push_array(scratch.arena, D_PathMap, path_maps.count); U64 idx = 0; - for(RD_EntityNode *n = maps.first; n != 0; n = n->next, idx += 1) + for(RD_CfgNode *n = maps.first; n != 0; n = n->next, idx += 1) { - RD_Entity *map = n->entity; - path_maps.v[idx].src = rd_entity_child_from_kind(map, RD_EntityKind_Source)->string; - path_maps.v[idx].dst = rd_entity_child_from_kind(map, RD_EntityKind_Dest)->string; + RD_Cfg *map = n->v; + path_maps.v[idx].src = rd_cfg_child_from_string(map, str8_lit("source"))->first->string; + path_maps.v[idx].dst = rd_cfg_child_from_string(map, str8_lit("dest"))->first->string; } } @@ -16560,14 +17335,57 @@ rd_frame(void) // U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64] = {0}; { - MemoryCopyArray(exception_code_filters, rd_state->ctrl_exception_code_filters); + Temp scratch = scratch_begin(0, 0); + for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)0; k < CTRL_ExceptionCodeKind_COUNT; k = (CTRL_ExceptionCodeKind)(k+1)) + { + if(ctrl_exception_code_kind_default_enable_table[k]) + { + exception_code_filters[k/64] |= 1ull<<(k%64); + } + } + RD_CfgList exception_code_filters_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("exception_code_filters")); + for(RD_CfgNode *n = exception_code_filters_roots.first; n != 0; n = n->next) + { + for(RD_Cfg *rule = n->v->first; rule != &rd_nil_cfg; rule = rule->next) + { + String8 name = rule->string; + String8 val_string = rule->first->string; + U64 val = 0; + if(try_u64_from_str8_c_rules(val_string, &val)) + { + CTRL_ExceptionCodeKind kind = CTRL_ExceptionCodeKind_Null; + for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)(CTRL_ExceptionCodeKind_Null+1); + k < CTRL_ExceptionCodeKind_COUNT; + k = (CTRL_ExceptionCodeKind)(k+1)) + { + if(str8_match(name, ctrl_exception_code_kind_lowercase_code_string_table[k], 0)) + { + kind = k; + break; + } + } + if(kind != CTRL_ExceptionCodeKind_Null) + { + if(val) + { + exception_code_filters[kind/64] |= (1ull<<(kind%64)); + } + else + { + exception_code_filters[kind/64] &= ~(1ull<<(kind%64)); + } + } + } + } + } + scratch_end(scratch); } //////////////////////////// //- rjf: tick debug engine // U64 cmd_count_pre_tick = rd_state->cmds[0].count; - D_EventList engine_events = d_tick(scratch.arena, &targets, &breakpoints, &path_maps, exception_code_filters, &meta_evals); + D_EventList engine_events = d_tick(scratch.arena, &targets, &breakpoints, &path_maps, exception_code_filters); //////////////////////////// //- rjf: process debug engine events @@ -16626,35 +17444,32 @@ rd_frame(void) // rjf: increment breakpoint hit counts if(evt->cause == D_EventCause_UserBreakpoint) { - RD_EntityList user_bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - for(RD_EntityNode *n = user_bps.first; n != 0; n = n->next) + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { - RD_Entity *bp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(bp, RD_EntityKind_Location); - D_LineList loc_lines = d_lines_from_file_path_line_num(scratch.arena, loc->string, loc->text_point.line); + RD_Cfg *bp = n->v; + RD_Cfg *hit_count_root = rd_cfg_child_from_string_or_alloc(bp, str8_lit("hit_count")); + U64 hit_count = 0; + try_u64_from_str8_c_rules(hit_count_root->first->string, &hit_count); + RD_Location loc = rd_location_from_cfg(bp); + D_LineList loc_lines = d_lines_from_file_path_line_num(scratch.arena, loc.file_path, loc.pt.line); + E_Value loc_value = e_value_from_string(loc.expr); if(loc_lines.first != 0) { for(D_LineNode *n = loc_lines.first; n != 0; n = n->next) { if(contains_1u64(n->v.voff_range, voff)) { - bp->u64 += 1; + hit_count += 1; break; } } } - else if(loc->flags & RD_EntityFlag_HasVAddr && vaddr == loc->vaddr) + else if(loc_value.u64 != 0 && vaddr == loc_value.u64) { - bp->u64 += 1; - } - else if(loc->string.size != 0) - { - U64 symb_voff = d_voff_from_dbgi_key_symbol_name(&dbgi_key, loc->string); - if(symb_voff == voff) - { - bp->u64 += 1; - } + hit_count += 1; } + rd_cfg_new_replacef(hit_count_root, "%I64u", hit_count); } } @@ -16662,9 +17477,9 @@ rd_frame(void) if(need_refocus && (selected_thread != &ctrl_entity_nil || thread != &ctrl_entity_nil)) { B32 any_window_is_focused = 0; - for(RD_Window *window = rd_state->first_window; window != 0; window = window->next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) { - if(os_window_is_focused(window->os)) + if(os_window_is_focused(ws->os)) { any_window_is_focused = 1; break; @@ -16672,16 +17487,17 @@ rd_frame(void) } if(!any_window_is_focused) { - RD_Window *window = rd_window_from_handle(rd_state->last_focused_window); - if(window == 0) + RD_Cfg *last_focused_window = rd_cfg_from_id(rd_state->last_focused_window); + RD_WindowState *ws = rd_window_state_from_cfg(last_focused_window); + if(ws == &rd_nil_window_state) { - window = rd_state->first_window; + ws = rd_state->first_window_state; } - if(window != 0) + if(ws != &rd_nil_window_state) { - os_window_set_minimized(window->os, 0); - os_window_bring_to_front(window->os); - os_window_focus(window->os); + os_window_set_minimized(ws->os, 0); + os_window_bring_to_front(ws->os); + os_window_focus(ws->os); } } } @@ -16710,7 +17526,7 @@ rd_frame(void) //- 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_name(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) @@ -16719,52 +17535,6 @@ rd_frame(void) } } - ////////////////////////////// - //- rjf: animate theme - // - { - RD_Theme *current = &rd_state->cfg_theme; - RD_Theme *target = &rd_state->cfg_theme_target; - F32 rate = 1 - pow_f32(2, (-50.f * rd_state->frame_dt)); - for(RD_ThemeColor color = RD_ThemeColor_Null; - color < RD_ThemeColor_COUNT; - color = (RD_ThemeColor)(color+1)) - { - if(abs_f32(target->colors[color].x - current->colors[color].x) > 0.01f || - abs_f32(target->colors[color].y - current->colors[color].y) > 0.01f || - abs_f32(target->colors[color].z - current->colors[color].z) > 0.01f || - abs_f32(target->colors[color].w - current->colors[color].w) > 0.01f) - { - rd_request_frame(); - } - current->colors[color].x += (target->colors[color].x - current->colors[color].x) * rate; - current->colors[color].y += (target->colors[color].y - current->colors[color].y) * rate; - current->colors[color].z += (target->colors[color].z - current->colors[color].z) * rate; - current->colors[color].w += (target->colors[color].w - current->colors[color].w) * rate; - } - } - - ////////////////////////////// - //- rjf: capture is active? -> keep rendering - // - if(ProfIsCapturing()) - { - // rd_request_frame(); - } - - ////////////////////////////// - //- rjf: commit params changes for all views - // - { - for(RD_View *v = rd_state->first_view; !rd_view_is_nil(v); v = v->alloc_next) - { - if(v->params_write_gen == v->params_read_gen+1) - { - v->params_read_gen += 1; - } - } - } - //////////////////////////// //- rjf: rotate command slots, bump command gen counter // @@ -16785,7 +17555,7 @@ rd_frame(void) // the commands pushed by the view will be in the queue, and the core can // treat that queue as r/w again. // - if(depth == 0) + if(rd_state->frame_depth == 0) { // rjf: rotate { @@ -16821,41 +17591,47 @@ rd_frame(void) Temp scratch = scratch_begin(0, 0); rd_state->ambiguous_path_slots_count = 512; rd_state->ambiguous_path_slots = push_array(rd_frame_arena(), RD_AmbiguousPathNode *, rd_state->ambiguous_path_slots_count); - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) { - for(RD_Panel *p = w->root_panel; !rd_panel_is_nil(p); p = rd_panel_rec_depth_first_pre(p).next) + RD_Cfg *window = rd_cfg_from_id(ws->cfg_id); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + for(RD_PanelNode *p = panel_tree.root; p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) { - for(RD_View *v = p->first_tab_view; !rd_view_is_nil(v); v = v->order_next) + for(RD_CfgNode *tab_n = p->tabs.first; tab_n != 0; tab_n = tab_n->next) { - if(rd_view_is_project_filtered(v)) + RD_Cfg *tab = tab_n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } - String8 eval_string = str8(v->query_buffer, v->query_string_size); - String8 file_path = rd_file_path_from_eval_string(scratch.arena, eval_string); - if(file_path.size != 0) + RD_RegsScope(.view = tab->id) { - String8 name = str8_skip_last_slash(file_path); - U64 hash = d_hash_from_string__case_insensitive(name); - U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; - RD_AmbiguousPathNode *node = 0; - for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; - n != 0; - n = n->next) + String8 eval_string = rd_expr_from_cfg(tab); + String8 file_path = rd_file_path_from_eval_string(scratch.arena, eval_string); + if(file_path.size != 0) { - if(str8_match(n->name, name, StringMatchFlag_CaseInsensitive)) + String8 name = str8_skip_last_slash(file_path); + U64 hash = d_hash_from_string__case_insensitive(name); + U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; + RD_AmbiguousPathNode *node = 0; + for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; + n != 0; + n = n->next) { - node = n; - break; + if(str8_match(n->name, name, StringMatchFlag_CaseInsensitive)) + { + node = n; + break; + } } + if(node == 0) + { + node = push_array(rd_frame_arena(), RD_AmbiguousPathNode, 1); + SLLStackPush(rd_state->ambiguous_path_slots[slot_idx], node); + node->name = push_str8_copy(rd_frame_arena(), name); + } + str8_list_push(rd_frame_arena(), &node->paths, push_str8_copy(rd_frame_arena(), file_path)); } - if(node == 0) - { - node = push_array(rd_frame_arena(), RD_AmbiguousPathNode, 1); - SLLStackPush(rd_state->ambiguous_path_slots[slot_idx], node); - node->name = push_str8_copy(rd_frame_arena(), name); - } - str8_list_push(rd_frame_arena(), &node->paths, push_str8_copy(rd_frame_arena(), file_path)); } } } @@ -16876,20 +17652,23 @@ rd_frame(void) //- rjf: update/render all windows // { - dr_begin_frame(); - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + dr_begin_frame(rd_font_from_slot(RD_FontSlot_Icons)); + RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); + for(RD_CfgNode *n = windows.first; n != 0; n = n->next) { + RD_Cfg *window = n->v; + RD_WindowState *w = rd_window_state_from_cfg(window); B32 window_is_focused = os_window_is_focused(w->os); if(window_is_focused) { - rd_state->last_focused_window = rd_handle_from_window(w); + rd_state->last_focused_window = w->cfg_id; } rd_push_regs(); - rd_regs()->window = rd_handle_from_window(w); - rd_window_frame(w); + rd_regs()->window = w->cfg_id; + rd_window_frame(); MemoryZeroStruct(&w->ui_events); RD_Regs *window_regs = rd_pop_regs(); - if(rd_window_from_handle(rd_state->last_focused_window) == w) + if(rd_state->last_focused_window == w->cfg_id) { MemoryCopyStruct(rd_regs(), window_regs); } @@ -16921,9 +17700,8 @@ rd_frame(void) } ////////////////////////////// - //- rjf: close scopes + //- rjf: close frame debug info scope // - if(depth == 0) { di_scope_close(rd_state->frame_di_scope); } @@ -16934,7 +17712,7 @@ rd_frame(void) ProfScope("submit rendering to all windows") { r_begin_frame(); - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + for(RD_WindowState *w = rd_state->first_window_state; w != &rd_nil_window_state; w = w->order_next) { r_window_begin_frame(w->os, w->r); dr_submit_bucket(w->os, w->r, w->draw_bucket); @@ -16946,48 +17724,21 @@ rd_frame(void) ////////////////////////////// //- rjf: show windows after first frame // - if(depth == 0) + if(rd_state->frame_depth == 0) { - RD_HandleList windows_to_show = {0}; - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + RD_CfgIDList windows_to_show = {0}; + for(RD_WindowState *w = rd_state->first_window_state; w != &rd_nil_window_state; w = w->order_next) { if(w->frames_alive == 1) { - rd_handle_list_push(scratch.arena, &windows_to_show, rd_handle_from_window(w)); + rd_cfg_id_list_push(scratch.arena, &windows_to_show, w->cfg_id); } } - for(RD_HandleNode *n = windows_to_show.first; n != 0; n = n->next) + for(RD_CfgIDNode *n = windows_to_show.first; n != 0; n = n->next) { - RD_Window *window = rd_window_from_handle(n->handle); - DeferLoop(depth += 1, depth -= 1) os_window_first_paint(window->os); - } - } - - ////////////////////////////// - //- rjf: eliminate entities that are marked for deletion - // - ProfScope("eliminate deleted entities") - { - for(RD_Entity *entity = rd_entity_root(), *next = 0; !rd_entity_is_nil(entity); entity = next) - { - next = rd_entity_rec_depth_first_pre(entity, &rd_nil_entity).next; - if(entity->flags & RD_EntityFlag_MarkedForDeletion) - { - B32 undoable = (rd_entity_kind_flags_table[entity->kind] & RD_EntityKindFlag_UserDefinedLifetime); - - // rjf: fixup next entity to iterate to - next = rd_entity_rec_depth_first(entity, &rd_nil_entity, OffsetOf(RD_Entity, next), OffsetOf(RD_Entity, next)).next; - - // rjf: eliminate root entity if we're freeing it - if(entity == rd_state->entities_root) - { - rd_state->entities_root = &rd_nil_entity; - } - - // rjf: unhook & release this entity tree - rd_entity_change_parent(entity, entity->parent, &rd_nil_entity, &rd_nil_entity); - rd_entity_release(entity); - } + RD_Cfg *window = rd_cfg_from_id(n->v); + RD_WindowState *ws = rd_window_state_from_cfg(window); + DeferLoop(rd_state->frame_depth += 1, rd_state->frame_depth -= 1) os_window_first_paint(ws->os); } } @@ -17003,11 +17754,12 @@ rd_frame(void) // rd_state->frame_index += 1; rd_state->time_in_seconds += rd_state->frame_dt; + rd_state->time_in_us += frame_time_us; ////////////////////////////// //- rjf: bump command batch ring buffer generation // - if(depth == 0) + if(rd_state->frame_depth == 0) { rd_state->cmds_gen += 1; } @@ -17021,11 +17773,11 @@ rd_frame(void) os_append_data_to_file_path(rd_state->log_path, log.strings[LogMsgKind_Info]); if(log.strings[LogMsgKind_UserError].size != 0) { - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) { - w->error_string_size = Min(sizeof(w->error_buffer), log.strings[LogMsgKind_UserError].size); - MemoryCopy(w->error_buffer, log.strings[LogMsgKind_UserError].str, w->error_string_size); - w->error_t = 1.f; + ws->error_string_size = Min(sizeof(ws->error_buffer), log.strings[LogMsgKind_UserError].size); + MemoryCopy(ws->error_buffer, log.strings[LogMsgKind_UserError].str, ws->error_string_size); + ws->error_t = 1.f; } } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 196a6328..568cdcb8 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -5,87 +5,27 @@ #define RADDBG_CORE_H //////////////////////////////// -//~ rjf: Handles +//~ rjf: Config IDs -typedef struct RD_Handle RD_Handle; -struct RD_Handle +typedef U64 RD_CfgID; + +typedef struct RD_CfgIDNode RD_CfgIDNode; +struct RD_CfgIDNode { - U64 u64[2]; + RD_CfgIDNode *next; + RD_CfgID v; }; -typedef struct RD_HandleNode RD_HandleNode; -struct RD_HandleNode +typedef struct RD_CfgIDList RD_CfgIDList; +struct RD_CfgIDList { - RD_HandleNode *next; - RD_HandleNode *prev; - RD_Handle handle; -}; - -typedef struct RD_HandleList RD_HandleList; -struct RD_HandleList -{ - RD_HandleNode *first; - RD_HandleNode *last; + RD_CfgIDNode *first; + RD_CfgIDNode *last; U64 count; }; //////////////////////////////// -//~ rjf: Evaluation Spaces - -typedef U64 RD_EvalSpaceKind; -enum -{ - RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, - RD_EvalSpaceKind_MetaEntity, - RD_EvalSpaceKind_MetaCtrlEntity, - RD_EvalSpaceKind_MetaCollection, -}; - -//////////////////////////////// -//~ rjf: Entity Kind Flags - -typedef U32 RD_EntityKindFlags; -enum -{ - //- rjf: allowed operations - RD_EntityKindFlag_CanDelete = (1<<0), - RD_EntityKindFlag_CanFreeze = (1<<1), - RD_EntityKindFlag_CanEdit = (1<<2), - RD_EntityKindFlag_CanRename = (1<<3), - RD_EntityKindFlag_CanEnable = (1<<4), - RD_EntityKindFlag_CanCondition = (1<<5), - RD_EntityKindFlag_CanDuplicate = (1<<6), - - //- rjf: name categorization - RD_EntityKindFlag_NameIsCode = (1<<7), - RD_EntityKindFlag_NameIsPath = (1<<8), - - //- rjf: lifetime categorization - RD_EntityKindFlag_UserDefinedLifetime = (1<<9), - - //- rjf: serialization - RD_EntityKindFlag_IsSerializedToConfig = (1<<10), -}; - -//////////////////////////////// -//~ rjf: Entity Flags - -typedef U32 RD_EntityFlags; -enum -{ - //- rjf: allocationless, simple equipment - RD_EntityFlag_HasTextPoint = (1<<0), - RD_EntityFlag_HasEntityHandle = (1<<2), - RD_EntityFlag_HasU64 = (1<<4), - RD_EntityFlag_HasColor = (1<<6), - RD_EntityFlag_HasVAddr = (1<<15), - - //- rjf: deletion - RD_EntityFlag_MarkedForDeletion = (1<<31), -}; - -//////////////////////////////// -//~ rjf: Binding Types +//~ rjf: Key Bindings typedef struct RD_Binding RD_Binding; struct RD_Binding @@ -94,40 +34,31 @@ struct RD_Binding OS_Modifiers modifiers; }; -typedef struct RD_BindingNode RD_BindingNode; -struct RD_BindingNode -{ - RD_BindingNode *next; - RD_Binding binding; -}; - -typedef struct RD_BindingList RD_BindingList; -struct RD_BindingList -{ - RD_BindingNode *first; - RD_BindingNode *last; - U64 count; -}; - -typedef struct RD_StringBindingPair RD_StringBindingPair; -struct RD_StringBindingPair -{ - String8 string; - RD_Binding binding; -}; - -//////////////////////////////// -//~ rjf: Key Map Types - typedef struct RD_KeyMapNode RD_KeyMapNode; struct RD_KeyMapNode { - RD_KeyMapNode *hash_next; - RD_KeyMapNode *hash_prev; + RD_KeyMapNode *name_hash_next; + RD_KeyMapNode *binding_hash_next; + RD_CfgID cfg_id; String8 name; RD_Binding binding; }; +typedef struct RD_KeyMapNodePtr RD_KeyMapNodePtr; +struct RD_KeyMapNodePtr +{ + RD_KeyMapNodePtr *next; + RD_KeyMapNode *v; +}; + +typedef struct RD_KeyMapNodePtrList RD_KeyMapNodePtrList; +struct RD_KeyMapNodePtrList +{ + RD_KeyMapNodePtr *first; + RD_KeyMapNodePtr *last; + U64 count; +}; + typedef struct RD_KeyMapSlot RD_KeyMapSlot; struct RD_KeyMapSlot { @@ -135,169 +66,63 @@ struct RD_KeyMapSlot RD_KeyMapNode *last; }; -//////////////////////////////// -//~ rjf: Setting Types - -typedef struct RD_SettingVal RD_SettingVal; -struct RD_SettingVal +typedef struct RD_KeyMap RD_KeyMap; +struct RD_KeyMap { - B32 set; - S32 s32; + U64 name_slots_count; + RD_KeyMapSlot *name_slots; + U64 binding_slots_count; + RD_KeyMapSlot *binding_slots; }; //////////////////////////////// -//~ rjf: View Rule Info Types +//~ rjf: Evaluation Spaces -typedef U32 RD_ViewRuleInfoFlags; +typedef U64 RD_EvalSpaceKind; enum { - RD_ViewRuleInfoFlag_ShowInDocs = (1<<0), - RD_ViewRuleInfoFlag_CanFilter = (1<<1), - RD_ViewRuleInfoFlag_FilterIsCode = (1<<2), - RD_ViewRuleInfoFlag_TypingAutomaticallyFilters = (1<<3), - RD_ViewRuleInfoFlag_CanUseInWatchTable = (1<<4), - RD_ViewRuleInfoFlag_CanFillValueCell = (1<<5), - RD_ViewRuleInfoFlag_CanExpand = (1<<6), - RD_ViewRuleInfoFlag_ProjectFiltered = (1<<7), -}; - -#define RD_VIEW_RULE_UI_FUNCTION_SIG(name) void name(String8 string, MD_Node *params, Rng2F32 rect) -#define RD_VIEW_RULE_UI_FUNCTION_NAME(name) rd_view_rule_ui_##name -#define RD_VIEW_RULE_UI_FUNCTION_DEF(name) internal RD_VIEW_RULE_UI_FUNCTION_SIG(RD_VIEW_RULE_UI_FUNCTION_NAME(name)) -typedef RD_VIEW_RULE_UI_FUNCTION_SIG(RD_ViewRuleUIFunctionType); - -//////////////////////////////// -//~ rjf: View Types - -typedef struct RD_View RD_View; - -typedef struct RD_ArenaExt RD_ArenaExt; -struct RD_ArenaExt -{ - RD_ArenaExt *next; - Arena *arena; -}; - -typedef struct RD_TransientViewNode RD_TransientViewNode; -struct RD_TransientViewNode -{ - RD_TransientViewNode *next; - RD_TransientViewNode *prev; - EV_Key key; - RD_View *view; - Arena *initial_params_arena; - MD_Node *initial_params; - U64 first_frame_index_touched; - U64 last_frame_index_touched; -}; - -typedef struct RD_TransientViewSlot RD_TransientViewSlot; -struct RD_TransientViewSlot -{ - RD_TransientViewNode *first; - RD_TransientViewNode *last; -}; - -typedef struct RD_View RD_View; -struct RD_View -{ - // rjf: allocation links (for iterating all views) - RD_View *alloc_next; - RD_View *alloc_prev; - - // rjf: ownership links ('owners' can have lists of views) - RD_View *order_next; - RD_View *order_prev; - - // rjf: transient view children - RD_View *first_transient; - RD_View *last_transient; - - // rjf: view specification info - struct RD_ViewRuleInfo *spec; - - // rjf: allocation info - U64 generation; - - // rjf: loading animation state - F32 loading_t; - F32 loading_t_target; - U64 loading_progress_v; - U64 loading_progress_v_target; - - // rjf: view project (for project-specific/filtered views) - Arena *project_path_arena; - String8 project_path; - - // rjf: view state - UI_ScrollPt2 scroll_pos; - - // rjf: view-lifetime allocation & user data extensions - Arena *arena; - RD_ArenaExt *first_arena_ext; - RD_ArenaExt *last_arena_ext; - U64 transient_view_slots_count; - RD_TransientViewSlot *transient_view_slots; - RD_TransientViewNode *free_transient_view_node; - void *user_data; - - // rjf: filter mode - B32 is_filtering; - F32 is_filtering_t; - - // rjf: params tree state - Arena *params_arenas[2]; - MD_Node *params_roots[2]; - U64 params_write_gen; - U64 params_read_gen; - - // rjf: text query state - TxtPt query_cursor; - TxtPt query_mark; - U64 query_string_size; - U8 query_buffer[KB(4)]; + RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, + RD_EvalSpaceKind_MetaQuery, + RD_EvalSpaceKind_MetaCfg, + RD_EvalSpaceKind_MetaCmd, + RD_EvalSpaceKind_MetaCtrlEntity, + RD_EvalSpaceKind_MetaUnattachedProcess, }; //////////////////////////////// -//~ rjf: Panel Types +//~ rjf: View UI Hook Types -typedef struct RD_Panel RD_Panel; -struct RD_Panel +#define RD_VIEW_UI_FUNCTION_SIG(name) void name(E_Eval eval, E_Expr *tag, Rng2F32 rect) +#define RD_VIEW_UI_FUNCTION_NAME(name) rd_view_ui__##name +#define RD_VIEW_UI_FUNCTION_DEF(name) internal RD_VIEW_UI_FUNCTION_SIG(RD_VIEW_UI_FUNCTION_NAME(name)) +typedef RD_VIEW_UI_FUNCTION_SIG(RD_ViewUIFunctionType); + +typedef struct RD_ViewUIRule RD_ViewUIRule; +struct RD_ViewUIRule { - // rjf: tree links/data - RD_Panel *first; - RD_Panel *last; - RD_Panel *next; - RD_Panel *prev; - RD_Panel *parent; - U64 child_count; - - // rjf: allocation data - U64 generation; - - // rjf: split data - Axis2 split_axis; - F32 pct_of_parent; - - // rjf: animated rectangle data - Rng2F32 animated_rect_pct; - - // rjf: tab params - Side tab_side; - - // rjf: stable views (tabs) - RD_View *first_tab_view; - RD_View *last_tab_view; - U64 tab_view_count; - RD_Handle selected_tab_view; + String8 name; + RD_ViewUIFunctionType *ui; }; -typedef struct RD_PanelRec RD_PanelRec; -struct RD_PanelRec +typedef struct RD_ViewUIRuleNode RD_ViewUIRuleNode; +struct RD_ViewUIRuleNode { - RD_Panel *next; - int push_count; - int pop_count; + RD_ViewUIRuleNode *next; + RD_ViewUIRule v; +}; + +typedef struct RD_ViewUIRuleSlot RD_ViewUIRuleSlot; +struct RD_ViewUIRuleSlot +{ + RD_ViewUIRuleNode *first; + RD_ViewUIRuleNode *last; +}; + +typedef struct RD_ViewUIRuleMap RD_ViewUIRuleMap; +struct RD_ViewUIRuleMap +{ + RD_ViewUIRuleSlot *slots; + U64 slots_count; }; //////////////////////////////// @@ -323,7 +148,8 @@ enum RD_QueryFlag_CodeInput = (1<<2), RD_QueryFlag_KeepOldInput = (1<<3), RD_QueryFlag_SelectOldInput = (1<<4), - RD_QueryFlag_Required = (1<<5), + RD_QueryFlag_Floating = (1<<5), + RD_QueryFlag_Required = (1<<6), }; typedef U32 RD_CmdKindFlags; @@ -333,51 +159,127 @@ enum RD_CmdKindFlag_ListInIPCDocs = (1<<1), }; +//////////////////////////////// +//~ rjf: Lister Flags + +typedef U32 RD_ListerFlags; +enum +{ + //- rjf: lister visual settings + RD_ListerFlag_LineEdit = (1<<0), // determines whether or not the lister has its own line edit, or if the filtering string is sourced by a user + RD_ListerFlag_Descriptions = (1<<1), // determines whether or not the lister items have descriptions (taller & bigger buttons) + RD_ListerFlag_KindLabel = (1<<2), // determines whether or not the lister items have labels for each item's kind + RD_ListerFlag_SizeByAnchor = (1<<3), // determines whether or not the lister is sized by the anchor box + + //- rjf: lister item sources + RD_ListerFlag_Locals = (1<<4), + RD_ListerFlag_Registers = (1<<5), + RD_ListerFlag_ViewRules = (1<<6), + RD_ListerFlag_ViewRuleParams = (1<<7), + RD_ListerFlag_Members = (1<<8), + RD_ListerFlag_Globals = (1<<9), + RD_ListerFlag_ThreadLocals = (1<<10), + RD_ListerFlag_Procedures = (1<<11), + RD_ListerFlag_Types = (1<<12), + RD_ListerFlag_Languages = (1<<13), + RD_ListerFlag_Architectures = (1<<14), + RD_ListerFlag_Tex2DFormats = (1<<15), + RD_ListerFlag_Files = (1<<16), + RD_ListerFlag_Commands = (1<<17), + RD_ListerFlag_Settings = (1<<18), + RD_ListerFlag_SystemProcesses= (1<<19), +}; + //////////////////////////////// //~ rjf: Generated Code #include "generated/raddbg.meta.h" //////////////////////////////// -//~ rjf: Config Types +//~ rjf: View State Types -typedef struct RD_CfgTree RD_CfgTree; -struct RD_CfgTree +typedef struct RD_ArenaExt RD_ArenaExt; +struct RD_ArenaExt { - RD_CfgTree *next; - RD_CfgSrc source; - MD_Node *root; + RD_ArenaExt *next; + Arena *arena; }; -typedef struct RD_CfgVal RD_CfgVal; -struct RD_CfgVal +typedef struct RD_ViewState RD_ViewState; +struct RD_ViewState { - RD_CfgVal *hash_next; - RD_CfgVal *linear_next; - RD_CfgTree *first; - RD_CfgTree *last; - U64 insertion_stamp; - String8 string; + // rjf: hash links & key + RD_ViewState *hash_next; + RD_ViewState *hash_prev; + RD_CfgID cfg_id; + + // rjf: touch info + U64 last_frame_index_touched; + U64 last_frame_index_built; + + // rjf: loading indicator info + F32 loading_t; + F32 loading_t_target; + U64 loading_progress_v; + U64 loading_progress_v_target; + + // rjf: scroll position + UI_ScrollPt2 scroll_pos; + + // rjf: eval visualization view state + EV_View *ev_view; + + // rjf: view-lifetime allocation & user data extensions + Arena *arena; + U64 arena_reset_pos; + RD_ArenaExt *first_arena_ext; + RD_ArenaExt *last_arena_ext; + void *user_data; + + // rjf: query state + B32 query_is_selected; + TxtPt query_cursor; + TxtPt query_mark; + U8 query_buffer[KB(1)]; + U64 query_string_size; }; -typedef struct RD_CfgSlot RD_CfgSlot; -struct RD_CfgSlot +typedef struct RD_ViewStateSlot RD_ViewStateSlot; +struct RD_ViewStateSlot { - RD_CfgVal *first; -}; - -typedef struct RD_CfgTable RD_CfgTable; -struct RD_CfgTable -{ - U64 slot_count; - RD_CfgSlot *slots; - U64 insertion_stamp_counter; - RD_CfgVal *first_val; - RD_CfgVal *last_val; + RD_ViewState *first; + RD_ViewState *last; }; //////////////////////////////// -//~ rjf: New Config/Entity Data Structure +//~ rjf: Vocabulary Map + +typedef struct RD_VocabInfoMapNode RD_VocabInfoMapNode; +struct RD_VocabInfoMapNode +{ + RD_VocabInfoMapNode *single_next; + RD_VocabInfoMapNode *plural_next; + RD_VocabInfo v; +}; + +typedef struct RD_VocabInfoMapSlot RD_VocabInfoMapSlot; +struct RD_VocabInfoMapSlot +{ + RD_VocabInfoMapNode *first; + RD_VocabInfoMapNode *last; +}; + +typedef struct RD_VocabInfoMap RD_VocabInfoMap; +struct RD_VocabInfoMap +{ + U64 single_slots_count; + RD_VocabInfoMapSlot *single_slots; + U64 plural_slots_count; + RD_VocabInfoMapSlot *plural_slots; +}; + +//////////////////////////////// +//~ rjf: Config Tree typedef struct RD_Cfg RD_Cfg; struct RD_Cfg @@ -387,7 +289,7 @@ struct RD_Cfg RD_Cfg *next; RD_Cfg *prev; RD_Cfg *parent; - U64 gen; + RD_CfgID id; String8 string; }; @@ -395,9 +297,17 @@ typedef struct RD_CfgNode RD_CfgNode; struct RD_CfgNode { RD_CfgNode *next; + RD_CfgNode *prev; RD_Cfg *v; }; +typedef struct RD_CfgSlot RD_CfgSlot; +struct RD_CfgSlot +{ + RD_CfgNode *first; + RD_CfgNode *last; +}; + typedef struct RD_CfgList RD_CfgList; struct RD_CfgList { @@ -406,6 +316,13 @@ struct RD_CfgList U64 count; }; +typedef struct RD_CfgArray RD_CfgArray; +struct RD_CfgArray +{ + RD_Cfg **v; + U64 count; +}; + typedef struct RD_CfgRec RD_CfgRec; struct RD_CfgRec { @@ -415,67 +332,54 @@ struct RD_CfgRec }; //////////////////////////////// -//~ rjf: Entity Types +//~ rjf: Structured Locations, Parsed From Config Trees -typedef U64 RD_EntityID; - -typedef struct RD_Entity RD_Entity; -struct RD_Entity +typedef struct RD_Location RD_Location; +struct RD_Location { - // rjf: tree links - RD_Entity *first; - RD_Entity *last; - RD_Entity *next; - RD_Entity *prev; - RD_Entity *parent; + String8 file_path; + TxtPt pt; + String8 expr; +}; + +//////////////////////////////// +//~ rjf: Structured Panel Trees, Parsed From Config Trees + +typedef struct RD_PanelNode RD_PanelNode; +struct RD_PanelNode +{ + // rjf: links data + RD_PanelNode *first; + RD_PanelNode *last; + RD_PanelNode *next; + RD_PanelNode *prev; + RD_PanelNode *parent; + U64 child_count; + RD_Cfg *cfg; - // rjf: metadata - RD_EntityKind kind; - RD_EntityFlags flags; - RD_EntityID id; - U64 gen; - U64 alloc_time_us; + // rjf: split data + Axis2 split_axis; + F32 pct_of_parent; - // rjf: basic equipment - TxtPt text_point; - B32 disabled; - B32 debug_subprocesses; - U64 u64; - U64 vaddr; - Vec4F32 color_hsva; - RD_CfgSrc cfg_src; - U64 timestamp; + // rjf: tab params + Side tab_side; - // rjf: string equipment - String8 string; + // rjf: which tabs are attached + RD_CfgList tabs; + RD_Cfg *selected_tab; }; -typedef struct RD_EntityNode RD_EntityNode; -struct RD_EntityNode +typedef struct RD_PanelTree RD_PanelTree; +struct RD_PanelTree { - RD_EntityNode *next; - RD_Entity *entity; + RD_PanelNode *root; + RD_PanelNode *focused; }; -typedef struct RD_EntityList RD_EntityList; -struct RD_EntityList +typedef struct RD_PanelNodeRec RD_PanelNodeRec; +struct RD_PanelNodeRec { - RD_EntityNode *first; - RD_EntityNode *last; - U64 count; -}; - -typedef struct RD_EntityArray RD_EntityArray; -struct RD_EntityArray -{ - RD_Entity **v; - U64 count; -}; - -typedef struct RD_EntityRec RD_EntityRec; -struct RD_EntityRec -{ - RD_Entity *next; + RD_PanelNode *next; S32 push_count; S32 pop_count; }; @@ -517,7 +421,7 @@ struct RD_RegsNode }; //////////////////////////////// -//~ rjf: Theme Types +//~ rjf: Structured Theme Types, Parsed From Config typedef struct RD_Theme RD_Theme; struct RD_Theme @@ -534,99 +438,86 @@ typedef enum RD_FontSlot } RD_FontSlot; -typedef enum RD_PaletteCode -{ - RD_PaletteCode_Base, - RD_PaletteCode_MenuBar, - RD_PaletteCode_Floating, - RD_PaletteCode_ImplicitButton, - RD_PaletteCode_PlainButton, - RD_PaletteCode_PositivePopButton, - RD_PaletteCode_NegativePopButton, - RD_PaletteCode_NeutralPopButton, - RD_PaletteCode_ScrollBarButton, - RD_PaletteCode_Tab, - RD_PaletteCode_TabInactive, - RD_PaletteCode_DropSiteOverlay, - RD_PaletteCode_COUNT -} -RD_PaletteCode; - //////////////////////////////// -//~ rjf: Auto-Complete Lister Types +//~ rjf: Lister Types -typedef U32 RD_AutoCompListerFlags; +typedef U32 RD_ListerItemFlags; enum { - RD_AutoCompListerFlag_Locals = (1<<0), - RD_AutoCompListerFlag_Registers = (1<<1), - RD_AutoCompListerFlag_ViewRules = (1<<2), - RD_AutoCompListerFlag_ViewRuleParams= (1<<3), - RD_AutoCompListerFlag_Members = (1<<4), - RD_AutoCompListerFlag_Globals = (1<<5), - RD_AutoCompListerFlag_ThreadLocals = (1<<6), - RD_AutoCompListerFlag_Procedures = (1<<7), - RD_AutoCompListerFlag_Types = (1<<8), - RD_AutoCompListerFlag_Languages = (1<<9), - RD_AutoCompListerFlag_Architectures = (1<<10), - RD_AutoCompListerFlag_Tex2DFormats = (1<<11), - RD_AutoCompListerFlag_Files = (1<<12), + RD_ListerItemFlag_IsNonCode = (1<<0), + RD_ListerItemFlag_Bindings = (1<<1), + RD_ListerItemFlag_Autocompletion = (1<<2), }; -typedef struct RD_AutoCompListerItem RD_AutoCompListerItem; -struct RD_AutoCompListerItem +typedef struct RD_ListerItem RD_ListerItem; +struct RD_ListerItem { + RD_ListerItemFlags flags; + RD_IconKind icon_kind; String8 string; - String8 kind_string; - FuzzyMatchRangeList matches; + String8 kind_name; + String8 display_name; + String8 description; + String8 search_tags; + FuzzyMatchRangeList kind_name__matches; + FuzzyMatchRangeList display_name__matches; + FuzzyMatchRangeList description__matches; U64 group; - B32 is_non_code; }; -typedef struct RD_AutoCompListerItemChunkNode RD_AutoCompListerItemChunkNode; -struct RD_AutoCompListerItemChunkNode +typedef struct RD_ListerItemChunkNode RD_ListerItemChunkNode; +struct RD_ListerItemChunkNode { - RD_AutoCompListerItemChunkNode *next; - RD_AutoCompListerItem *v; + RD_ListerItemChunkNode *next; + RD_ListerItem *v; U64 count; U64 cap; }; -typedef struct RD_AutoCompListerItemChunkList RD_AutoCompListerItemChunkList; -struct RD_AutoCompListerItemChunkList +typedef struct RD_ListerItemChunkList RD_ListerItemChunkList; +struct RD_ListerItemChunkList { - RD_AutoCompListerItemChunkNode *first; - RD_AutoCompListerItemChunkNode *last; + RD_ListerItemChunkNode *first; + RD_ListerItemChunkNode *last; U64 chunk_count; U64 total_count; }; -typedef struct RD_AutoCompListerItemArray RD_AutoCompListerItemArray; -struct RD_AutoCompListerItemArray +typedef struct RD_ListerItemArray RD_ListerItemArray; +struct RD_ListerItemArray { - RD_AutoCompListerItem *v; + RD_ListerItem *v; U64 count; }; -typedef struct RD_AutoCompListerParams RD_AutoCompListerParams; -struct RD_AutoCompListerParams +typedef struct RD_Lister RD_Lister; +struct RD_Lister { - RD_AutoCompListerFlags flags; - String8List strings; + RD_Lister *next; + Arena *arena; + RD_Regs *regs; + UI_ScrollPt scroll_pt; + U64 selected_item_hash; + U8 input_buffer[1024]; + U64 input_string_size; + TxtPt input_cursor; + TxtPt input_mark; }; //////////////////////////////// //~ rjf: Per-Window State -typedef struct RD_Window RD_Window; -struct RD_Window +typedef struct RD_WindowState RD_WindowState; +struct RD_WindowState { // rjf: links & metadata - RD_Window *next; - RD_Window *prev; - U64 gen; + RD_WindowState *order_next; + RD_WindowState *order_prev; + RD_WindowState *hash_next; + RD_WindowState *hash_prev; + RD_CfgID cfg_id; U64 frames_alive; - RD_CfgSrc cfg_src; + U64 last_frame_index_touched; // rjf: top-level info & handles Arena *arena; @@ -635,10 +526,10 @@ struct RD_Window UI_State *ui; F32 last_dpi; B32 window_temporarily_focused_ipc; + B32 window_layout_reset; - // rjf: config/settings - RD_SettingVal setting_vals[RD_SettingCode_COUNT]; - UI_Palette cfg_palettes[RD_PaletteCode_COUNT]; // derivative from theme + // rjf: theme (recomputed each frame) + UI_Theme *theme; // rjf: dev interface state B32 dev_menu_is_open; @@ -649,70 +540,34 @@ struct RD_Window B32 menu_bar_key_held; B32 menu_bar_focus_press_started; - // rjf: context menu state - Arena *ctx_menu_arena; - RD_Regs *ctx_menu_regs; - RD_RegSlot ctx_menu_regs_slot; - U8 *ctx_menu_input_buffer; - U64 ctx_menu_input_buffer_size; - U64 ctx_menu_input_string_size; - TxtPt ctx_menu_input_cursor; - TxtPt ctx_menu_input_mark; + // rjf: lister state + RD_Lister *top_query_lister; + RD_Lister *autocomp_lister; + U64 autocomp_lister_last_frame_idx; // rjf: drop-completion state Arena *drop_completion_arena; String8List drop_completion_paths; - // rjf: autocomplete lister state - U64 autocomp_last_frame_idx; - B32 autocomp_input_dirty; - UI_Key autocomp_root_key; - Arena *autocomp_lister_params_arena; - RD_AutoCompListerParams autocomp_lister_params; - U64 autocomp_cursor_off; - U8 autocomp_lister_input_buffer[1024]; - U64 autocomp_lister_input_size; - F32 autocomp_open_t; - F32 autocomp_num_visible_rows_t; - S64 autocomp_cursor_num; - - // rjf: query view stack - Arena *query_cmd_arena; - String8 query_cmd_name; - RD_Regs *query_cmd_regs; - U64 query_cmd_regs_mask[(RD_RegSlot_COUNT + 63) / 64]; - RD_View *query_view_stack_top; - B32 query_view_selected; - F32 query_view_selected_t; - F32 query_view_t; + // rjf: query state + B32 query_is_active; + Arena *query_arena; + RD_Regs *query_regs; // rjf: hover eval state B32 hover_eval_focused; - TxtPt hover_eval_txt_cursor; - TxtPt hover_eval_txt_mark; - U8 hover_eval_txt_buffer[1024]; - U64 hover_eval_txt_size; Arena *hover_eval_arena; Vec2F32 hover_eval_spawn_pos; String8 hover_eval_string; - U64 hover_eval_first_frame_idx; - U64 hover_eval_last_frame_idx; - String8 hover_eval_file_path; - TxtPt hover_eval_file_pt; - U64 hover_eval_vaddr; - F32 hover_eval_open_t; - F32 hover_eval_num_visible_rows_t; + String8 hover_eval_view_rules; + U64 hover_eval_firstt_us; + U64 hover_eval_lastt_us; // rjf: error state U8 error_buffer[512]; U64 error_string_size; F32 error_t; - // rjf: panel state - RD_Panel *root_panel; - RD_Panel *free_panel; - RD_Panel *focused_panel; - // rjf: per-frame ui events state UI_EventList ui_events; @@ -720,47 +575,28 @@ struct RD_Window DR_Bucket *draw_bucket; }; -//////////////////////////////// -//~ rjf: Eval Visualization View Cache Types - -typedef struct RD_EvalVizViewCacheNode RD_EvalVizViewCacheNode; -struct RD_EvalVizViewCacheNode +typedef struct RD_WindowStateSlot RD_WindowStateSlot; +struct RD_WindowStateSlot { - RD_EvalVizViewCacheNode *next; - RD_EvalVizViewCacheNode *prev; - U64 key; - EV_View *v; -}; - -typedef struct RD_EvalVizViewCacheSlot RD_EvalVizViewCacheSlot; -struct RD_EvalVizViewCacheSlot -{ - RD_EvalVizViewCacheNode *first; - RD_EvalVizViewCacheNode *last; -}; - -//////////////////////////////// -//~ rjf: Meta Evaluation Cache Types - -typedef struct RD_CtrlEntityMetaEvalCacheNode RD_CtrlEntityMetaEvalCacheNode; -struct RD_CtrlEntityMetaEvalCacheNode -{ - RD_CtrlEntityMetaEvalCacheNode *next; - CTRL_Handle handle; - CTRL_MetaEval *meval; - Rng1U64 range; -}; - -typedef struct RD_CtrlEntityMetaEvalCacheSlot RD_CtrlEntityMetaEvalCacheSlot; -struct RD_CtrlEntityMetaEvalCacheSlot -{ - RD_CtrlEntityMetaEvalCacheNode *first; - RD_CtrlEntityMetaEvalCacheNode *last; + RD_WindowState *first; + RD_WindowState *last; }; //////////////////////////////// //~ rjf: Main Per-Process Graphical State +read_only global U64 rd_name_bucket_chunk_sizes[] = +{ + 16, + 64, + 256, + 1024, + 4096, + 16384, + 65536, + 0xffffffffffffffffull, +}; + typedef struct RD_NameChunkNode RD_NameChunkNode; struct RD_NameChunkNode { @@ -768,14 +604,6 @@ struct RD_NameChunkNode U64 size; }; -typedef struct RD_EntityListCache RD_EntityListCache; -struct RD_EntityListCache -{ - Arena *arena; - U64 alloc_gen; - RD_EntityList list; -}; - typedef struct RD_AmbiguousPathNode RD_AmbiguousPathNode; struct RD_AmbiguousPathNode { @@ -791,6 +619,23 @@ struct RD_State Arena *arena; B32 quit; B32 quit_after_success; + S32 frame_depth; + U64 frame_eval_memread_endt_us; + + // rjf: config bucket paths + Arena *user_path_arena; + String8 user_path; + Arena *project_path_arena; + String8 project_path; + + // rjf: schema table + MD_Node **schemas; + + // rjf: default theme table + MD_Node *theme_preset_trees[RD_ThemePreset_COUNT]; + + // rjf: vocab table + RD_VocabInfoMap vocab_info_map; // rjf: log Log *log; @@ -802,6 +647,7 @@ struct RD_State U64 frame_time_us_history[64]; U64 num_frames_requested; F64 time_in_seconds; + U64 time_in_us; // rjf: frame parameters F32 frame_dt; @@ -810,10 +656,23 @@ struct RD_State // rjf: dbgi match store DI_MatchStore *match_store; - // rjf: ambiguous path table + // rjf: ambiguous path table (constructed from-scratch each frame) U64 ambiguous_path_slots_count; RD_AmbiguousPathNode **ambiguous_path_slots; + // rjf: key map (constructed from-scratch each frame) + RD_KeyMap *key_map; + + // rjf: theme target (constructed from-scratch each frame) + RD_Theme *theme; + RD_Theme *theme_target; + + // rjf: meta name -> eval type key map (constructed from-scratch each frame) + E_String2TypeKeyMap *meta_name2type_map; + + // rjf: name -> view ui map (constructed from-scratch each frame) + RD_ViewUIRuleMap *view_ui_rule_map; + // rjf: registers stack RD_RegsNode base_regs; RD_RegsNode *top_regs; @@ -838,19 +697,6 @@ struct RD_State // rjf: text editing mode state B32 text_edit_mode; - // rjf: string search state - Arena *string_search_arena; - String8 string_search_string; - - // rjf: eval visualization view cache - U64 eval_viz_view_cache_slots_count; - RD_EvalVizViewCacheSlot *eval_viz_view_cache_slots; - RD_EvalVizViewCacheNode *eval_viz_view_cache_node_free; - - // rjf: ctrl entity meta eval cache - U64 ctrl_entity_meval_cache_slots_count; - RD_CtrlEntityMetaEvalCacheSlot *ctrl_entity_meval_cache_slots; - // rjf: contextual hover info RD_Regs *hover_regs; RD_RegSlot hover_regs_slot; @@ -860,10 +706,6 @@ struct RD_State // rjf: icon texture R_Handle icon_texture; - // rjf: current path - Arena *current_path_arena; - String8 current_path; - // rjf: fixed ui keys UI_Key drop_completion_key; UI_Key ctx_menu_key; @@ -875,86 +717,38 @@ struct RD_State RD_DragDropState drag_drop_state; // rjf: cfg state - RD_NameChunkNode *free_name_chunks[8]; + RD_NameChunkNode *free_name_chunks[ArrayCount(rd_name_bucket_chunk_sizes)]; RD_Cfg *free_cfg; RD_Cfg *root_cfg; + U64 cfg_id_slots_count; + RD_CfgSlot *cfg_id_slots; + RD_CfgNode *free_cfg_id_node; + U64 cfg_id_gen; - //- - // TODO(rjf): TO BE ELIMINATED OR REPLACED VVVVVVVVVVVVVVVV - //- + // rjf: window state cache + U64 window_state_slots_count; + RD_WindowStateSlot *window_state_slots; + RD_WindowState *free_window_state; + RD_CfgID last_focused_window; + RD_WindowState *first_window_state; + RD_WindowState *last_window_state; - // rjf: entity state - Arena *entities_arena; - RD_Entity *entities_base; - U64 entities_count; - U64 entities_id_gen; - RD_Entity *entities_root; - RD_Entity *entities_free[2]; // [0] -> normal lifetime, not user defined; [1] -> user defined lifetime (& thus undoable) - U64 entities_free_count; - U64 entities_active_count; - - // rjf: entity query caches - U64 kind_alloc_gens[RD_EntityKind_COUNT]; - RD_EntityListCache kind_caches[RD_EntityKind_COUNT]; - - // rjf: key map table - Arena *key_map_arena; - U64 key_map_table_size; - RD_KeyMapSlot *key_map_table; - RD_KeyMapNode *free_key_map_node; - U64 key_map_total_count; + // rjf: view state cache + U64 view_state_slots_count; + RD_ViewStateSlot *view_state_slots; + RD_ViewState *free_view_state; // rjf: bind change Arena *bind_change_arena; B32 bind_change_active; + RD_CfgID bind_change_binding_id; String8 bind_change_cmd_name; - RD_Binding bind_change_binding; - - // rjf: windows - RD_Window *first_window; - RD_Window *last_window; - RD_Window *free_window; - U64 window_count; - B32 last_window_queued_save; - RD_Handle last_focused_window; - - // rjf: view state - RD_View *first_view; - RD_View *last_view; - RD_View *free_view; - U64 free_view_count; - U64 allocated_view_count; - - // rjf: config reading state - Arena *cfg_path_arenas[RD_CfgSrc_COUNT]; - String8 cfg_paths[RD_CfgSrc_COUNT]; - U64 cfg_cached_timestamp[RD_CfgSrc_COUNT]; - Arena *cfg_arena; - RD_CfgTable cfg_table; - U64 ctrl_exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]; - - // rjf: running theme state - RD_Theme cfg_theme_target; - RD_Theme cfg_theme; - Arena *cfg_main_font_path_arena; - Arena *cfg_code_font_path_arena; - String8 cfg_main_font_path; - String8 cfg_code_font_path; - FNT_Tag cfg_font_tags[RD_FontSlot_COUNT]; // derivative from font paths - - // rjf: global settings - RD_SettingVal cfg_setting_vals[RD_CfgSrc_COUNT][RD_SettingCode_COUNT]; - - //- - // TODO(rjf): TO BE ELIMINATED OR REPLACED ^^^^^^^^^^^^^^^^^^ - //- }; //////////////////////////////// //~ rjf: Globals -read_only global RD_CfgTree d_nil_cfg_tree = {&d_nil_cfg_tree, RD_CfgSrc_User, &md_nil_node}; -read_only global RD_CfgVal d_nil_cfg_val = {&d_nil_cfg_val, &d_nil_cfg_val, &d_nil_cfg_tree, &d_nil_cfg_tree}; +read_only global RD_VocabInfo rd_nil_vocab_info = {0}; read_only global RD_Cfg rd_nil_cfg = { @@ -965,67 +759,50 @@ read_only global RD_Cfg rd_nil_cfg = &rd_nil_cfg, }; -read_only global RD_Entity rd_nil_entity = +read_only global RD_PanelNode rd_nil_panel_node = { - &rd_nil_entity, - &rd_nil_entity, - &rd_nil_entity, - &rd_nil_entity, - &rd_nil_entity, + &rd_nil_panel_node, + &rd_nil_panel_node, + &rd_nil_panel_node, + &rd_nil_panel_node, + &rd_nil_panel_node, + 0, + &rd_nil_cfg, + .selected_tab = &rd_nil_cfg, }; read_only global RD_CmdKindInfo rd_nil_cmd_kind_info = {0}; -read_only global RD_ViewRuleInfo rd_nil_view_rule_info = +RD_VIEW_UI_FUNCTION_DEF(null); +read_only global RD_ViewUIRule rd_nil_view_ui_rule = { {0}, - {0}, - {0}, - {0}, - RD_IconKind_Null, - 0, - EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), - RD_VIEW_RULE_UI_FUNCTION_NAME(null) + RD_VIEW_UI_FUNCTION_NAME(null), }; -read_only global RD_View rd_nil_view = +read_only global RD_ViewState rd_nil_view_state = { - &rd_nil_view, - &rd_nil_view, - &rd_nil_view, - &rd_nil_view, - &rd_nil_view, - &rd_nil_view, - &rd_nil_view_rule_info, + &rd_nil_view_state, + &rd_nil_view_state, }; -read_only global RD_Panel rd_nil_panel = +read_only global RD_WindowState rd_nil_window_state = { - &rd_nil_panel, - &rd_nil_panel, - &rd_nil_panel, - &rd_nil_panel, - &rd_nil_panel, + &rd_nil_window_state, + &rd_nil_window_state, + &rd_nil_window_state, + &rd_nil_window_state, }; global RD_State *rd_state = 0; -global RD_Handle rd_last_drag_drop_panel = {0}; -global RD_Handle rd_last_drag_drop_prev_tab = {0}; +global RD_CfgID rd_last_drag_drop_panel = 0; +global RD_CfgID rd_last_drag_drop_prev_tab = 0; //////////////////////////////// -//~ rjf: Handle Type Pure Functions +//~ rjf: Config ID Type Functions -internal RD_Handle rd_handle_zero(void); -internal B32 rd_handle_match(RD_Handle a, RD_Handle b); -internal void rd_handle_list_push_node(RD_HandleList *list, RD_HandleNode *node); -internal void rd_handle_list_push(Arena *arena, RD_HandleList *list, RD_Handle handle); -internal RD_HandleList rd_handle_list_copy(Arena *arena, RD_HandleList list); - -//////////////////////////////// -//~ rjf: Config Type Pure Functions - -internal void rd_cfg_table_push_unparsed_string(Arena *arena, RD_CfgTable *table, String8 string, RD_CfgSrc source); -internal RD_CfgVal *rd_cfg_val_from_string(RD_CfgTable *table, String8 string); +internal void rd_cfg_id_list_push(Arena *arena, RD_CfgIDList *list, RD_CfgID id); +internal RD_CfgIDList rd_cfg_id_list_copy(Arena *arena, RD_CfgIDList *src); //////////////////////////////// //~ rjf: Registers Type Functions @@ -1039,94 +816,12 @@ internal RD_Regs *rd_regs_copy(Arena *arena, RD_Regs *src); internal void rd_cmd_list_push_new(Arena *arena, RD_CmdList *cmds, String8 name, RD_Regs *regs); //////////////////////////////// -//~ rjf: Entity Type Pure Functions +//~ rjf: View UI Rule Functions -//- rjf: nil -internal B32 rd_entity_is_nil(RD_Entity *entity); -#define rd_require_entity_nonnil(entity, if_nil_stmts) do{if(rd_entity_is_nil(entity)){if_nil_stmts;}}while(0) +internal RD_ViewUIRuleMap *rd_view_ui_rule_map_make(Arena *arena, U64 slots_count); +internal void rd_view_ui_rule_map_insert(Arena *arena, RD_ViewUIRuleMap *map, String8 string, RD_ViewUIFunctionType *ui); -//- rjf: handle <-> entity conversions -internal U64 rd_index_from_entity(RD_Entity *entity); -internal RD_Handle rd_handle_from_entity(RD_Entity *entity); -internal RD_Entity *rd_entity_from_handle(RD_Handle handle); - -//- rjf: entity recursion iterators -internal RD_EntityRec rd_entity_rec_depth_first(RD_Entity *entity, RD_Entity *subtree_root, U64 sib_off, U64 child_off); -#define rd_entity_rec_depth_first_pre(entity, subtree_root) rd_entity_rec_depth_first((entity), (subtree_root), OffsetOf(RD_Entity, next), OffsetOf(RD_Entity, first)) -#define rd_entity_rec_depth_first_post(entity, subtree_root) rd_entity_rec_depth_first((entity), (subtree_root), OffsetOf(RD_Entity, prev), OffsetOf(RD_Entity, last)) - -//- rjf: ancestor/child introspection -internal RD_Entity *rd_entity_child_from_kind(RD_Entity *entity, RD_EntityKind kind); - -//- rjf: entity list building -internal void rd_entity_list_push(Arena *arena, RD_EntityList *list, RD_Entity *entity); -internal RD_EntityArray rd_entity_array_from_list(Arena *arena, RD_EntityList *list); -#define rd_first_entity_from_list(list) ((list)->first != 0 ? (list)->first->entity : &rd_nil_entity) - -//- rjf: entity -> color operations -internal Vec4F32 rd_hsva_from_entity(RD_Entity *entity); -internal Vec4F32 rd_rgba_from_entity(RD_Entity *entity); - -//- rjf: entity -> expansion tree keys -internal EV_Key rd_ev_key_from_entity(RD_Entity *entity); -internal EV_Key rd_parent_ev_key_from_entity(RD_Entity *entity); - -//////////////////////////////// -//~ rjf: View Type Functions - -internal B32 rd_view_is_nil(RD_View *view); -internal B32 rd_view_is_project_filtered(RD_View *view); -internal RD_Handle rd_handle_from_view(RD_View *view); -internal RD_View *rd_view_from_handle(RD_Handle handle); - -//////////////////////////////// -//~ rjf: View Spec Type Functions - -internal RD_ViewRuleKind rd_view_rule_kind_from_string(String8 string); -internal RD_ViewRuleInfo *rd_view_rule_info_from_kind(RD_ViewRuleKind kind); -internal RD_ViewRuleInfo *rd_view_rule_info_from_string(String8 string); - -//////////////////////////////// -//~ rjf: Panel Type Functions - -//- rjf: basic type functions -internal B32 rd_panel_is_nil(RD_Panel *panel); -internal RD_Handle rd_handle_from_panel(RD_Panel *panel); -internal RD_Panel *rd_panel_from_handle(RD_Handle handle); -internal UI_Key rd_ui_key_from_panel(RD_Panel *panel); - -//- rjf: tree construction -internal void rd_panel_insert(RD_Panel *parent, RD_Panel *prev_child, RD_Panel *new_child); -internal void rd_panel_remove(RD_Panel *parent, RD_Panel *child); - -//- rjf: tree walk -internal RD_PanelRec rd_panel_rec_depth_first(RD_Panel *panel, U64 sib_off, U64 child_off); -#define rd_panel_rec_depth_first_pre(panel) rd_panel_rec_depth_first(panel, OffsetOf(RD_Panel, next), OffsetOf(RD_Panel, first)) -#define rd_panel_rec_depth_first_pre_rev(panel) rd_panel_rec_depth_first(panel, OffsetOf(RD_Panel, prev), OffsetOf(RD_Panel, last)) - -//- rjf: panel -> rect calculations -internal Rng2F32 rd_target_rect_from_panel_child(Rng2F32 parent_rect, RD_Panel *parent, RD_Panel *panel); -internal Rng2F32 rd_target_rect_from_panel(Rng2F32 root_rect, RD_Panel *root, RD_Panel *panel); - -//- rjf: view ownership insertion/removal -internal void rd_panel_insert_tab_view(RD_Panel *panel, RD_View *prev_view, RD_View *view); -internal void rd_panel_remove_tab_view(RD_Panel *panel, RD_View *view); -internal RD_View *rd_selected_tab_from_panel(RD_Panel *panel); - -//- rjf: icons & display strings -internal RD_IconKind rd_icon_kind_from_view(RD_View *view); -internal DR_FancyStringList rd_title_fstrs_from_view(Arena *arena, RD_View *view, Vec4F32 primary_color, Vec4F32 secondary_color, F32 size); - -//////////////////////////////// -//~ rjf: Window Type Functions - -internal RD_Handle rd_handle_from_window(RD_Window *window); -internal RD_Window *rd_window_from_handle(RD_Handle handle); - -//////////////////////////////// -//~ rjf: Command Parameters From Context - -internal B32 rd_prefer_dasm_from_window(RD_Window *window); +internal RD_ViewUIRule *rd_view_ui_rule_from_string(String8 string); //////////////////////////////// //~ rjf: Global Cross-Window UI Interaction State Functions @@ -1139,96 +834,98 @@ internal void rd_drag_kill(void); internal void rd_set_hover_regs(RD_RegSlot slot); internal RD_Regs *rd_get_hover_regs(void); -internal void rd_open_ctx_menu(UI_Key anchor_box_key, Vec2F32 anchor_box_off, RD_RegSlot slot); - //////////////////////////////// //~ rjf: Name Allocation -internal U64 rd_name_bucket_idx_from_string_size(U64 size); +internal U64 rd_name_bucket_num_from_string_size(U64 size); internal String8 rd_name_alloc(String8 string); internal void rd_name_release(String8 string); //////////////////////////////// -//~ rjf: New Config/Entity Data Structure Functions +//~ rjf: Config Tree Functions internal RD_Cfg *rd_cfg_alloc(void); internal void rd_cfg_release(RD_Cfg *cfg); +internal void rd_cfg_release_all_children(RD_Cfg *cfg); +internal RD_Cfg *rd_cfg_from_id(RD_CfgID id); internal RD_Cfg *rd_cfg_new(RD_Cfg *parent, String8 string); internal RD_Cfg *rd_cfg_newf(RD_Cfg *parent, char *fmt, ...); +internal RD_Cfg *rd_cfg_new_replace(RD_Cfg *parent, String8 string); +internal RD_Cfg *rd_cfg_new_replacef(RD_Cfg *parent, char *fmt, ...); +internal RD_Cfg *rd_cfg_deep_copy(RD_Cfg *src_root); internal void rd_cfg_equip_string(RD_Cfg *cfg, String8 string); +internal void rd_cfg_equip_stringf(RD_Cfg *cfg, char *fmt, ...); internal void rd_cfg_insert_child(RD_Cfg *parent, RD_Cfg *prev_child, RD_Cfg *new_child); internal void rd_cfg_unhook(RD_Cfg *parent, RD_Cfg *child); internal RD_Cfg *rd_cfg_child_from_string(RD_Cfg *parent, String8 string); +internal RD_Cfg *rd_cfg_child_from_string_or_alloc(RD_Cfg *parent, String8 string); +internal RD_Cfg *rd_cfg_child_from_string_or_parent(RD_Cfg *parent, String8 string); internal RD_CfgList rd_cfg_child_list_from_string(Arena *arena, RD_Cfg *parent, String8 string); internal RD_CfgList rd_cfg_top_level_list_from_string(Arena *arena, String8 string); +internal RD_CfgArray rd_cfg_array_from_list(Arena *arena, RD_CfgList *list); internal RD_CfgList rd_cfg_tree_list_from_string(Arena *arena, String8 string); internal String8 rd_string_from_cfg_tree(Arena *arena, RD_Cfg *cfg); internal RD_CfgRec rd_cfg_rec__depth_first(RD_Cfg *root, RD_Cfg *cfg); internal void rd_cfg_list_push(Arena *arena, RD_CfgList *list, RD_Cfg *cfg); +internal void rd_cfg_list_push_front(Arena *arena, RD_CfgList *list, RD_Cfg *cfg); +#define rd_cfg_list_first(list) ((list)->count ? (list)->first->v : &rd_nil_cfg) +#define rd_cfg_list_last(list) ((list)->count ? (list)->last->v : &rd_nil_cfg) -//////////////////////////////// -//~ rjf: Entity Stateful Functions +internal RD_PanelTree rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg); +internal RD_PanelNodeRec rd_panel_node_rec__depth_first(RD_PanelNode *root, RD_PanelNode *panel, U64 sib_off, U64 child_off); +#define rd_panel_node_rec__depth_first_pre(root, p) rd_panel_node_rec__depth_first((root), (p), OffsetOf(RD_PanelNode, next), OffsetOf(RD_PanelNode, first)) +#define rd_panel_node_rec__depth_first_pre_rev(root, p) rd_panel_node_rec__depth_first((root), (p), OffsetOf(RD_PanelNode, prev), OffsetOf(RD_PanelNode, last)) +internal RD_PanelNode *rd_panel_node_from_tree_cfg(RD_PanelNode *root, RD_Cfg *cfg); +internal Rng2F32 rd_target_rect_from_panel_node_child(Rng2F32 parent_rect, RD_PanelNode *parent, RD_PanelNode *panel); +internal Rng2F32 rd_target_rect_from_panel_node(Rng2F32 root_rect, RD_PanelNode *root, RD_PanelNode *panel); -//- rjf: entity allocation + tree forming -internal RD_Entity *rd_entity_alloc(RD_Entity *parent, RD_EntityKind kind); -internal void rd_entity_mark_for_deletion(RD_Entity *entity); -internal void rd_entity_release(RD_Entity *entity); -internal void rd_entity_change_parent(RD_Entity *entity, RD_Entity *old_parent, RD_Entity *new_parent, RD_Entity *prev_child); -internal RD_Entity *rd_entity_child_from_kind_or_alloc(RD_Entity *entity, RD_EntityKind kind); +internal B32 rd_cfg_is_project_filtered(RD_Cfg *cfg); -//- rjf: entity simple equipment -internal void rd_entity_equip_txt_pt(RD_Entity *entity, TxtPt point); -internal void rd_entity_equip_disabled(RD_Entity *entity, B32 b32); -internal void rd_entity_equip_u64(RD_Entity *entity, U64 u64); -internal void rd_entity_equip_color_rgba(RD_Entity *entity, Vec4F32 rgba); -internal void rd_entity_equip_color_hsva(RD_Entity *entity, Vec4F32 hsva); -internal void rd_entity_equip_cfg_src(RD_Entity *entity, RD_CfgSrc cfg_src); -internal void rd_entity_equip_timestamp(RD_Entity *entity, U64 timestamp); +internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_name(Arena *arena, String8 string); +internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_binding(Arena *arena, RD_Binding binding); -//- rjf: control layer correllation equipment -internal void rd_entity_equip_vaddr(RD_Entity *entity, U64 vaddr); +internal Vec4F32 rd_hsva_from_cfg(RD_Cfg *cfg); +internal Vec4F32 rd_color_from_cfg(RD_Cfg *cfg); -//- rjf: name equipment -internal void rd_entity_equip_name(RD_Entity *entity, String8 name); +internal B32 rd_disabled_from_cfg(RD_Cfg *cfg); +internal RD_Location rd_location_from_cfg(RD_Cfg *cfg); +internal String8 rd_label_from_cfg(RD_Cfg *cfg); +internal String8 rd_expr_from_cfg(RD_Cfg *cfg); +internal String8 rd_view_rule_from_cfg(RD_Cfg *cfg); +internal String8 rd_path_from_cfg(RD_Cfg *cfg); +internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); + +internal MD_Node *rd_schema_from_name(String8 name); + +internal String8 rd_setting_from_name(String8 name); +#define rd_setting_b32_from_name(name) (str8_match(rd_setting_from_name(name), str8_lit("1"), 0)) +#define rd_setting_u64_from_name(name) (u64_from_str8(rd_setting_from_name(name), 10)) + +internal RD_Cfg *rd_immediate_cfg_from_key(String8 string); +internal RD_Cfg *rd_immediate_cfg_from_keyf(char *fmt, ...); -//- rjf: file path map override lookups internal String8 rd_mapped_from_file_path(Arena *arena, String8 file_path); internal String8List rd_possible_overrides_from_file_path(Arena *arena, String8 file_path); -//- rjf: top-level state queries -internal RD_Entity *rd_entity_root(void); -internal RD_EntityList rd_push_entity_list_with_kind(Arena *arena, RD_EntityKind kind); -internal RD_Entity *rd_entity_from_id(RD_EntityID id); -internal RD_Entity *rd_entity_from_name_and_kind(String8 string, RD_EntityKind kind); - -//////////////////////////////// -//~ rjf: Frontend Entity Info Extraction - -internal D_Target rd_d_target_from_entity(RD_Entity *entity); -internal DR_FancyStringList rd_title_fstrs_from_entity(Arena *arena, RD_Entity *entity, Vec4F32 secondary_color, F32 size); +internal E_Expr *rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg); //////////////////////////////// //~ rjf: Control Entity Info Extraction -internal Vec4F32 rd_rgba_from_ctrl_entity(CTRL_Entity *entity); +internal Vec4F32 rd_color_from_ctrl_entity(CTRL_Entity *entity); internal String8 rd_name_from_ctrl_entity(Arena *arena, CTRL_Entity *entity); -internal DR_FancyStringList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secondary_color, F32 size, B32 include_extras); //////////////////////////////// //~ rjf: Evaluation Spaces -//- rjf: entity <-> eval space -internal RD_Entity *rd_entity_from_eval_space(E_Space space); -internal E_Space rd_eval_space_from_entity(RD_Entity *entity); +//- rjf: cfg <-> eval space +internal RD_Cfg *rd_cfg_from_eval_space(E_Space space); +internal E_Space rd_eval_space_from_cfg(RD_Cfg *cfg); //- rjf: ctrl entity <-> eval space internal CTRL_Entity *rd_ctrl_entity_from_eval_space(E_Space space); internal E_Space rd_eval_space_from_ctrl_entity(CTRL_Entity *entity, E_SpaceKind kind); -//- rjf: entity -> meta eval -internal CTRL_MetaEval *rd_ctrl_meta_eval_from_entity(Arena *arena, RD_Entity *entity); -internal CTRL_MetaEval *rd_ctrl_meta_eval_from_ctrl_entity(Arena *arena, CTRL_Entity *entity); - //- rjf: eval space reads/writes internal B32 rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range); internal B32 rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range); @@ -1245,42 +942,19 @@ internal Rng1U64 rd_whole_range_from_eval_space(E_Space space); //- rjf: writing values back to child processes internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping); -//- rjf: eval / view rule params tree info extraction -internal U64 rd_base_offset_from_eval(E_Eval eval); -internal E_Value rd_value_from_params_key(MD_Node *params, String8 key); -internal Rng1U64 rd_range_from_eval_params(E_Eval eval, MD_Node *params); -internal TXT_LangKind rd_lang_kind_from_eval_params(E_Eval eval, MD_Node *params); -internal Arch rd_arch_from_eval_params(E_Eval eval, MD_Node *params); -internal Vec2S32 rd_dim2s32_from_eval_params(E_Eval eval, MD_Node *params); -internal R_Tex2DFormat rd_tex2dformat_from_eval_params(E_Eval eval, MD_Node *params); - //- rjf: eval <-> file path +internal String8 rd_file_path_from_eval(Arena *arena, E_Eval eval); internal String8 rd_file_path_from_eval_string(Arena *arena, String8 string); internal String8 rd_eval_string_from_file_path(Arena *arena, String8 string); +//- rjf: eval -> query +internal String8 rd_query_from_eval_string(Arena *arena, String8 string); + //////////////////////////////// -//~ rjf: View State Functions +//~ rjf: View Functions -//- rjf: allocation/releasing -internal RD_View *rd_view_alloc(void); -internal void rd_view_release(RD_View *view); - -//- rjf: equipment -internal void rd_view_equip_spec(RD_View *view, RD_ViewRuleInfo *spec, String8 query, MD_Node *params); -internal void rd_view_equip_query(RD_View *view, String8 query); -internal void rd_view_equip_loading_info(RD_View *view, B32 is_loading, U64 progress_v, U64 progress_target); - -//- rjf: user state extensions -internal void *rd_view_get_or_push_user_state(RD_View *view, U64 size); -internal Arena *rd_view_push_arena_ext(RD_View *view); -#define rd_view_user_state(view, type) (type *)rd_view_get_or_push_user_state((view), sizeof(type)) - -//- rjf: param saving -internal void rd_view_store_param(RD_View *view, String8 key, String8 value); -internal void rd_view_store_paramf(RD_View *view, String8 key, char *fmt, ...); -#define rd_view_store_param_f32(view, key, f32) rd_view_store_paramf((view), (key), "%ff", (f32)) -#define rd_view_store_param_s64(view, key, s64) rd_view_store_paramf((view), (key), "%I64d", (s64)) -#define rd_view_store_param_u64(view, key, u64) rd_view_store_paramf((view), (key), "0x%I64x", (u64)) +internal RD_ViewState *rd_view_state_from_cfg(RD_Cfg *cfg); +internal void rd_view_ui(Rng2F32 rect); //////////////////////////////// //~ rjf: View Building API @@ -1288,8 +962,20 @@ internal void rd_view_store_paramf(RD_View *view, String8 key, char *fmt, ...); //- rjf: view info extraction internal Arena *rd_view_arena(void); internal UI_ScrollPt2 rd_view_scroll_pos(void); -internal String8 rd_view_expr_string(void); -internal String8 rd_view_filter(void); +internal EV_View *rd_view_eval_view(void); +internal String8 rd_view_query_cmd(void); +internal String8 rd_view_query_input(void); +internal RD_Cfg *rd_view_cfg_from_string(String8 string); +internal E_Value rd_view_cfg_value_from_string(String8 string); + +//- rjf: evaluation & tag (a view's 'call') parameter extraction +internal U64 rd_base_offset_from_eval(E_Eval eval); +internal Rng1U64 rd_range_from_eval_tag(E_Eval eval, E_Expr *tag); +internal TXT_LangKind rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag); +internal Arch rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag); +internal Vec2S32 rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag); +internal R_Tex2DFormat rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag); +internal E_Value rd_value_from_eval_tag_key(E_Eval eval, E_Expr *tag, String8 key); //- rjf: pushing/attaching view resources internal void *rd_view_state_by_size(U64 size); @@ -1308,108 +994,74 @@ internal void rd_store_view_paramf(String8 key, char *fmt, ...); #define rd_store_view_param_u64(key, u64) rd_store_view_paramf((key), "0x%I64x", (u64)) //////////////////////////////// -//~ rjf: Expand-Keyed Transient View Functions +//~ rjf: Window Functions -internal RD_TransientViewNode *rd_transient_view_node_from_ev_key(RD_View *owner_view, EV_Key key); - -//////////////////////////////// -//~ rjf: Panel State Functions - -internal RD_Panel *rd_panel_alloc(RD_Window *ws); -internal void rd_panel_release(RD_Window *ws, RD_Panel *panel); -internal void rd_panel_release_all_views(RD_Panel *panel); - -//////////////////////////////// -//~ rjf: Window State Functions - -internal RD_Window *rd_window_open(Vec2F32 size, OS_Handle preferred_monitor, RD_CfgSrc cfg_src); - -internal RD_Window *rd_window_from_os_handle(OS_Handle os); - -internal void rd_window_frame(RD_Window *ws); +internal RD_Cfg *rd_window_from_cfg(RD_Cfg *cfg); +internal RD_WindowState *rd_window_state_from_cfg(RD_Cfg *cfg); +internal RD_WindowState *rd_window_state_from_os_handle(OS_Handle os); +internal void rd_window_frame(void); //////////////////////////////// //~ rjf: Eval Visualization -internal EV_ExpandInfo rd_ev_view_rule_expr_expand_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RD_EntityKind kind); -internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, RD_EntityKind kind, B32 add_new_at_top); -internal U64 rd_ev_view_rule_expr_id_from_num__meta_entities(U64 num, void *user_data, RD_EntityKind kind, B32 add_new_at_top); -internal U64 rd_ev_view_rule_expr_num_from_id__meta_entities(U64 id, void *user_data, RD_EntityKind kind, B32 add_new_at_top); - -internal EV_ExpandInfo rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, CTRL_EntityKind kind); -internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, CTRL_EntityKind kind); -internal U64 rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(U64 num, void *user_data, CTRL_EntityKind kind); -internal U64 rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(U64 id, void *user_data, CTRL_EntityKind kind); - -internal EV_ExpandInfo rd_ev_view_rule_expr_expand_info__debug_info_tables(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RDI_SectionKind section); -internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__debug_info_tables(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, RDI_SectionKind section); -internal U64 rd_ev_view_rule_expr_id_from_num__debug_info_tables(U64 num, void *user_data, RDI_SectionKind section); -internal U64 rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 id, void *user_data, RDI_SectionKind section); - -internal EV_View *rd_ev_view_from_key(U64 key); -internal F32 rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval eval, E_Member *member, EV_ViewRuleList *view_rules, String8List *out); -internal String8 rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval, E_Member *member, EV_ViewRuleList *view_rules); +internal F32 rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval root_eval, E_Eval eval, String8List *out); +internal String8 rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval); //////////////////////////////// //~ rjf: Hover Eval -internal void rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string); +internal void rd_set_hover_eval(Vec2F32 pos, String8 string, String8 view_rules); //////////////////////////////// -//~ rjf: Auto-Complete Lister +//~ rjf: Lister Functions -internal void rd_autocomp_lister_item_chunk_list_push(Arena *arena, RD_AutoCompListerItemChunkList *list, U64 cap, RD_AutoCompListerItem *item); -internal RD_AutoCompListerItemArray rd_autocomp_lister_item_array_from_chunk_list(Arena *arena, RD_AutoCompListerItemChunkList *list); -internal int rd_autocomp_lister_item_qsort_compare(RD_AutoCompListerItem *a, RD_AutoCompListerItem *b); -internal void rd_autocomp_lister_item_array_sort__in_place(RD_AutoCompListerItemArray *array); +internal void rd_lister_item_chunk_list_push(Arena *arena, RD_ListerItemChunkList *list, U64 cap, RD_ListerItem *item); +#define rd_lister_item_chunk_list_push_new(arena, list, cap, ...) rd_lister_item_chunk_list_push((arena), (list), (cap), &(RD_ListerItem){.string = {0}, __VA_ARGS__}) +internal RD_ListerItemArray rd_lister_item_array_from_chunk_list(Arena *arena, RD_ListerItemChunkList *list); +internal int rd_lister_item_qsort_compare(RD_ListerItem *a, RD_ListerItem *b); +internal void rd_lister_item_array_sort__in_place(RD_ListerItemArray *array); +internal RD_ListerItemArray rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, String8 needle, U64 cursor_off); +internal U64 rd_hash_from_lister_item(RD_ListerItem *item); -internal String8 rd_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off); -internal String8 rd_autocomp_query_path_from_input_string_off(String8 input, U64 cursor_off); -internal RD_AutoCompListerParams rd_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off); -internal void rd_set_autocomp_lister_query(UI_Key root_key, RD_AutoCompListerParams *params, String8 input, U64 cursor_off); - -//////////////////////////////// -//~ rjf: Search Strings - -internal void rd_set_search_string(String8 string); -internal String8 rd_push_search_string(Arena *arena); +internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off); +internal String8 rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off); +#if 0 // TODO(rjf): @cfg (lister) +internal RD_ListerParams rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off); +internal void rd_set_autocomp_lister_query_(RD_ListerParams *params); +#define rd_set_autocomp_lister_query(...) rd_set_autocomp_lister_query_(&(RD_ListerParams){.flags = 0, __VA_ARGS__}) +#endif +internal void rd_set_autocomp_lister_query_(RD_Regs *regs); +#define rd_set_autocomp_lister_query(...) rd_set_autocomp_lister_query_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) //////////////////////////////// //~ rjf: Colors, Fonts, Config -//- rjf: keybindings -internal OS_Key rd_os_key_from_cfg_string(String8 string); -internal void rd_clear_bindings(void); -internal RD_BindingList rd_bindings_from_name(Arena *arena, String8 name); -internal void rd_bind_name(String8 name, RD_Binding binding); -internal void rd_unbind_name(String8 name, RD_Binding binding); -internal String8List rd_cmd_name_list_from_binding(Arena *arena, RD_Binding binding); - //- rjf: colors internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color); internal RD_ThemeColor rd_theme_color_from_txt_token_kind(TXT_TokenKind kind); internal RD_ThemeColor rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); -//- rjf: code -> palette -internal UI_Palette *rd_palette_from_code(RD_PaletteCode code); - //- rjf: fonts/sizes 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); - //////////////////////////////// //~ rjf: Process Control Info Stringification internal String8 rd_string_from_exception_code(U32 code); -internal DR_FancyStringList rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event); +internal DR_FStrList rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event); + +//////////////////////////////// +//~ rjf: Vocab Info Lookups + +internal RD_VocabInfo *rd_vocab_info_from_code_name(String8 code_name); +internal RD_VocabInfo *rd_vocab_info_from_code_name_plural(String8 code_name_plural); +#define rd_plural_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->code_name_plural) +#define rd_display_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->display_name) +#define rd_display_plural_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->display_name_plural) +#define rd_icon_kind_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->icon_kind) +#define rd_singular_from_code_name_plural(code_name_plural) (rd_vocab_info_from_code_name_plural(code_name_plural)->code_name) //////////////////////////////// //~ rjf: Continuous Frame Requests @@ -1422,17 +1074,6 @@ internal void rd_request_frame(void); //- rjf: per-frame arena internal Arena *rd_frame_arena(void); -//- rjf: config paths -internal String8 rd_cfg_path_from_src(RD_CfgSrc src); - -//- rjf: entity cache queries -internal RD_EntityList rd_query_cached_entity_list_with_kind(RD_EntityKind kind); -internal RD_EntityList rd_push_active_target_list(Arena *arena); -internal RD_Entity *rd_entity_from_ev_key_and_kind(EV_Key key, RD_EntityKind kind); - -//- rjf: config state -internal RD_CfgTable *rd_cfg_table(void); - //////////////////////////////// //~ rjf: Registers @@ -1457,6 +1098,7 @@ internal void rd_push_cmd(String8 name, RD_Regs *regs); //- rjf: iterating internal B32 rd_next_cmd(RD_Cmd **cmd); +internal B32 rd_next_view_cmd(RD_Cmd **cmd); //////////////////////////////// //~ rjf: Main Layer Top-Level Calls diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 54ca6ba9..28bc4b75 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -1,6 +1,48 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// +//~ rjf: 0.9.16 changes +// +// - Auto view rules have been upgraded to support type pattern-matching. This +// makes them usable for generic types in various languages. +// - The `slice` view rule has been streamlined and simplified. When an +// expression with a `slice` view rule is expanded, it will simply expand to +// the slice's contents, which matches the behavior with static arrays. +// - The `slice` view rule now supports `first, one-past-last` pointer pairs, +// as well as `base_pointer, length` pairs. +// - The syntax for view rules has changed to improve its familiarity, +// usability, and to improve its consistency with the rest of the evaluation +// language. It now appears like function calls, and many arguments no longer +// need to be explicitly named. For example, instead of +// `bitmap:{w:1024, h:1024}`, the new view rule syntax would be +// `bitmap(1024, 1024)`. Commas can still be omitted. Named arguments are +// still possible (and required in some cases): `disasm(size=1024, arch=x64)` +// - The hover evaluation feature has been majorly upgraded to support all +// features normally available in the `Watch` view. Hover evaluations now +// explicitly show type information, and contain a view rule column, which +// can be edited in an identical way as the `Watch` view. +// - Added "auto tabs", which are colored differently than normal tabs. These +// tabs are automatically opened by the debugger when snapping to source code +// which is not already opened. They are automatically replaced and recycled +// when the debugger needs to snap to new locations. This will greatly reduce +// the number of unused source code tabs accumulated throughout a debugging +// session. These tabs can still be promoted to permanent tabs, in which case +// they'll stay around until manually closed. +// - The `Scheduler` view has been removed, in favor of three separate views, +// which present various versions of the same information: `Threads`, +// `Processes`, and `Machines`. The justification for this is that the +// common case is debugging a small number of programs, usually 1, and for +// those purposes, the `Threads` view is sufficient if not desirable, and +// the extra information provided by `Processes` and `Machines`, while useful +// in other contexts, is not useful in that common case. +// - The two separate interfaces for editing threads, breakpoints, and watch +// pins (the right-click context menu and the dedicated tabs) have been +// merged. +// - Added the ability to add per-target environment strings. +// - Fixed an annoyance where the debugger would open a console window, even +// for graphical programs, causing a flicker. + //////////////////////////////// //~ rjf: feature cleanup, code dedup, code elimination pass: // @@ -25,6 +67,17 @@ // etc., all need to be merged, and optionally contextualized/filtered. // right-clicking a tab should be equivalent to spawning a command lister, // but only with commands that are directly +// +// [ ] r8 bitmap view rule seems incorrect? +// [ ] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) +// +// [ ] stepping-onto a line with a conditional breakpoint, which fails, causes a +// single step over the first instruction of that line, even if the thread +// would've stopped at the first instruction due to the step, were that bp not +// there. +// +// [ ] if a breakpoint matches the entry point's starting address, its hit count +// is not correctly incremented. //////////////////////////////// //~ rjf: post-0.9.12 TODO notes @@ -603,106 +656,58 @@ entry_point(CmdLine *cmd_line) String8List args = cmd_line->inputs; if(args.node_count > 0 && args.first->string.size != 0) { - //- TODO(rjf): @cfg setup initial target from command line arguments - { - Temp scratch = scratch_begin(0, 0); - - //- rjf: unpack command line inputs - String8 executable_name_string = {0}; - String8 arguments_string = {0}; - String8 working_directory_string = {0}; - { - // rjf: unpack full executable path - if(args.first->string.size != 0) - { - String8 current_path = os_get_current_path(scratch.arena); - String8 exe_name = args.first->string; - PathStyle style = path_style_from_str8(exe_name); - if(style == PathStyle_Relative) - { - exe_name = push_str8f(scratch.arena, "%S/%S", current_path, exe_name); - exe_name = path_normalized_from_string(scratch.arena, exe_name); - } - executable_name_string = exe_name; - } - - // rjf: unpack working directory - if(args.first->string.size != 0) - { - String8 path_part_of_arg = str8_chop_last_slash(args.first->string); - if(path_part_of_arg.size != 0) - { - String8 path = push_str8f(scratch.arena, "%S/", path_part_of_arg); - working_directory_string = path; - } - } - - // rjf: unpack arguments - String8List passthrough_args_list = {0}; - for(String8Node *n = args.first->next; n != 0; n = n->next) - { - str8_list_push(scratch.arena, &passthrough_args_list, n->string); - } - StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; - arguments_string = str8_list_join(scratch.arena, &passthrough_args_list, &join); - } - - //- rjf: build config tree - RD_Cfg *command_line_root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("command_line")); - RD_Cfg *target = rd_cfg_new(command_line_root, str8_lit("target")); - RD_Cfg *exe = rd_cfg_new(target, str8_lit("executable")); - RD_Cfg *args = rd_cfg_new(target, str8_lit("arguments")); - RD_Cfg *wdir = rd_cfg_new(target, str8_lit("working_directory")); - rd_cfg_new(exe, executable_name_string); - rd_cfg_new(args, arguments_string); - rd_cfg_new(wdir, working_directory_string); - - scratch_end(scratch); - } - Temp scratch = scratch_begin(0, 0); - RD_Entity *target = rd_entity_alloc(rd_entity_root(), RD_EntityKind_Target); - rd_entity_equip_cfg_src(target, RD_CfgSrc_CommandLine); - String8List passthrough_args_list = {0}; - for(String8Node *n = args.first->next; n != 0; n = n->next) - { - str8_list_push(scratch.arena, &passthrough_args_list, n->string); - } - // rjf: get current path - String8 current_path = os_get_current_path(scratch.arena); - - // rjf: equip exe - if(args.first->string.size != 0) + //- rjf: unpack command line inputs + String8 executable_name_string = {0}; + String8 arguments_string = {0}; + String8 working_directory_string = {0}; { - String8 exe_name = args.first->string; - RD_Entity *exe = rd_entity_alloc(target, RD_EntityKind_Executable); - PathStyle style = path_style_from_str8(exe_name); - if(style == PathStyle_Relative) + // rjf: unpack full executable path + if(args.first->string.size != 0) { - exe_name = push_str8f(scratch.arena, "%S/%S", current_path, exe_name); - exe_name = path_normalized_from_string(scratch.arena, exe_name); + String8 current_path = os_get_current_path(scratch.arena); + String8 exe_name = args.first->string; + PathStyle style = path_style_from_str8(exe_name); + if(style == PathStyle_Relative) + { + exe_name = push_str8f(scratch.arena, "%S/%S", current_path, exe_name); + exe_name = path_normalized_from_string(scratch.arena, exe_name); + } + executable_name_string = exe_name; } - rd_entity_equip_name(exe, exe_name); + + // rjf: unpack working directory + if(args.first->string.size != 0) + { + String8 path_part_of_arg = str8_chop_last_slash(args.first->string); + if(path_part_of_arg.size != 0) + { + String8 path = push_str8f(scratch.arena, "%S/", path_part_of_arg); + working_directory_string = path; + } + } + + // rjf: unpack arguments + String8List passthrough_args_list = {0}; + for(String8Node *n = args.first->next; n != 0; n = n->next) + { + str8_list_push(scratch.arena, &passthrough_args_list, n->string); + } + StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; + arguments_string = str8_list_join(scratch.arena, &passthrough_args_list, &join); } - // rjf: equip working directory - String8 path_part_of_arg = str8_chop_last_slash(args.first->string); - if(path_part_of_arg.size != 0) - { - String8 path = push_str8f(scratch.arena, "%S/", path_part_of_arg); - RD_Entity *wdir = rd_entity_alloc(target, RD_EntityKind_WorkingDirectory); - rd_entity_equip_name(wdir, path); - } + //- rjf: build config tree + RD_Cfg *command_line_root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("command_line")); + RD_Cfg *target = rd_cfg_new(command_line_root, str8_lit("target")); + RD_Cfg *exe = rd_cfg_new(target, str8_lit("executable")); + RD_Cfg *args = rd_cfg_new(target, str8_lit("arguments")); + RD_Cfg *wdir = rd_cfg_new(target, str8_lit("working_directory")); + rd_cfg_new(exe, executable_name_string); + rd_cfg_new(args, arguments_string); + rd_cfg_new(wdir, working_directory_string); - // rjf: equip args - StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; - String8 args_str = str8_list_join(scratch.arena, &passthrough_args_list, &join); - if(args_str.size != 0) - { - RD_Entity *args_entity = rd_entity_alloc(target, RD_EntityKind_Arguments); - rd_entity_equip_name(args_entity, args_str); - } scratch_end(scratch); } } @@ -754,29 +759,32 @@ entry_point(CmdLine *cmd_line) if(msg.size != 0) { log_infof("ipc_msg: \"%S\"", msg); - RD_Window *dst_window = rd_state->first_window; - for(RD_Window *window = dst_window; window != 0; window = window->next) + RD_WindowState *dst_ws = rd_state->first_window_state; + for(RD_WindowState *ws = dst_ws; ws != &rd_nil_window_state; ws = ws->order_next) { - if(os_window_is_focused(window->os)) + if(os_window_is_focused(ws->os)) { - dst_window = window; + dst_ws = ws; break; } } - if(dst_window != 0) + if(dst_ws != &rd_nil_window_state) { - dst_window->window_temporarily_focused_ipc = 1; + dst_ws->window_temporarily_focused_ipc = 1; U64 first_space_pos = str8_find_needle(msg, 0, str8_lit(" "), 0); String8 cmd_kind_name_string = str8_prefix(msg, first_space_pos); String8 cmd_args_string = str8_skip_chop_whitespace(str8_skip(msg, first_space_pos)); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_kind_name_string); if(cmd_kind_info != &rd_nil_cmd_kind_info) RD_RegsScope() { - if(dst_window != rd_window_from_handle(rd_regs()->window)) + if(dst_ws->cfg_id != rd_regs()->window) { - rd_regs()->window = rd_handle_from_window(dst_window); - rd_regs()->panel = rd_handle_from_panel(dst_window->focused_panel); - rd_regs()->view = dst_window->focused_panel->selected_tab_view; + Temp scratch = scratch_begin(0, 0); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_id(dst_ws->cfg_id)); + rd_regs()->window = dst_ws->cfg_id; + rd_regs()->panel = panel_tree.focused->cfg->id; + rd_regs()->view = panel_tree.focused->selected_tab->id; + scratch_end(scratch); } rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, cmd_args_string); rd_push_cmd(cmd_kind_name_string, rd_regs()); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 550e1fd1..31b07abb 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -7,6 +7,7 @@ internal void rd_code_view_init(RD_CodeViewState *cv) { + ProfBeginFunction(); if(cv->initialized == 0) { cv->initialized = 1; @@ -15,6 +16,7 @@ rd_code_view_init(RD_CodeViewState *cv) cv->center_cursor = 1; rd_store_view_loading_info(1, 0, 0); } + ProfEnd(); } internal RD_CodeViewBuildResult @@ -33,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_name(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; @@ -43,6 +45,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla S64 num_possible_visible_lines = (S64)(code_area_dim.y/code_line_height)+1; CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); + B32 do_line_numbers = rd_setting_b32_from_name(str8_lit("show_line_numbers")); ////////////////////////////// //- rjf: unpack information about the viewed source file, if any @@ -53,15 +56,8 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ////////////////////////////// //- rjf: process commands // - for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) { - // rjf: mismatched window/panel => skip - if(!rd_handle_match(rd_regs()->view, cmd->regs->view)) - { - continue; - } - - // rjf: process RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); switch(kind) { @@ -78,16 +74,28 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla { cv->contain_cursor = 1; }break; - case RD_CmdKind_FindTextForward: + case RD_CmdKind_Search: { arena_clear(cv->find_text_arena); cv->find_text_fwd = push_str8_copy(cv->find_text_arena, cmd->regs->string); }break; - case RD_CmdKind_FindTextBackward: + case RD_CmdKind_SearchBackwards: { arena_clear(cv->find_text_arena); cv->find_text_bwd = push_str8_copy(cv->find_text_arena, cmd->regs->string); }break; + case RD_CmdKind_FindNext: + { + String8 string = rd_view_query_input(); + arena_clear(cv->find_text_arena); + cv->find_text_fwd = push_str8_copy(cv->find_text_arena, string); + }break; + case RD_CmdKind_FindPrev: + { + String8 string = rd_view_query_input(); + arena_clear(cv->find_text_arena); + cv->find_text_bwd = push_str8_copy(cv->find_text_arena, string); + }break; case RD_CmdKind_ToggleWatchExpressionAtMouse: { cv->watch_expr_at_mouse = 1; @@ -131,41 +139,60 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ////////////////////////////// //- rjf: calculate line-range-dependent info // - F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3); + F32 line_num_width_px = 0; + if(do_line_numbers) + { + line_num_width_px = floor_f32(big_glyph_advance * (log10(visible_line_num_range.max) + 3)); + } F32 priority_margin_width_px = 0; F32 catchall_margin_width_px = 0; if(flags & RD_CodeViewBuildFlag_Margins) { - priority_margin_width_px = big_glyph_advance*3.5f; - catchall_margin_width_px = big_glyph_advance*3.5f; + priority_margin_width_px = floor_f32(big_glyph_advance*3.5f); + catchall_margin_width_px = floor_f32(big_glyph_advance*3.5f); } TXT_LineTokensSlice slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, text_info, text_data, visible_line_num_range); ////////////////////////////// - //- rjf: get active search query + //- rjf: selection on single line, no query? -> set search text // - String8 search_query = {0}; - Side search_query_side = Side_Invalid; - B32 search_query_is_active = 0; + if(rd_regs()->cursor.line == rd_regs()->mark.line) { - RD_Window *window = rd_window_from_handle(rd_regs()->window); - RD_CmdKind query_cmd_kind = rd_cmd_kind_from_string(window->query_cmd_name); - if(query_cmd_kind == RD_CmdKind_FindTextForward || - query_cmd_kind == RD_CmdKind_FindTextBackward) + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(!vs->query_is_selected) { - search_query = str8(window->query_view_stack_top->query_buffer, window->query_view_stack_top->query_string_size); - search_query_is_active = 1; - search_query_side = (query_cmd_kind == RD_CmdKind_FindTextForward) ? Side_Max : Side_Min; + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + String8 text = txt_string_from_info_data_txt_rng(text_info, text_data, txt_rng(rd_regs()->cursor, rd_regs()->mark)); + if(text.size < 256) + { + rd_cfg_new_replace(input, text); + } + else + { + rd_cfg_new_replace(input, str8_zero()); + } } } + ////////////////////////////// + //- rjf: get active search query + // + String8 search_query = rd_view_query_input(); + B32 search_query_is_active = 0; + ////////////////////////////// //- rjf: prepare code slice info bundle, for the viewable region of text // RD_CodeSliceParams code_slice_params = {0}; { // rjf: fill basics - code_slice_params.flags = RD_CodeSliceFlag_LineNums|RD_CodeSliceFlag_Clickable; + code_slice_params.flags = RD_CodeSliceFlag_Clickable; + if(do_line_numbers) + { + code_slice_params.flags |= RD_CodeSliceFlag_LineNums; + } if(flags & RD_CodeViewBuildFlag_Margins) { code_slice_params.flags |= RD_CodeSliceFlag_PriorityMargin|RD_CodeSliceFlag_CatchallMargin; @@ -174,9 +201,9 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla code_slice_params.line_text = push_array(scratch.arena, String8, visible_line_count); code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, visible_line_count); code_slice_params.line_tokens = push_array(scratch.arena, TXT_TokenArray, visible_line_count); - code_slice_params.line_bps = push_array(scratch.arena, RD_EntityList, visible_line_count); + code_slice_params.line_bps = push_array(scratch.arena, RD_CfgList, visible_line_count); code_slice_params.line_ips = push_array(scratch.arena, CTRL_EntityList, visible_line_count); - code_slice_params.line_pins = push_array(scratch.arena, RD_EntityList, visible_line_count); + code_slice_params.line_pins = push_array(scratch.arena, RD_CfgList, visible_line_count); code_slice_params.line_vaddrs = push_array(scratch.arena, U64, visible_line_count); code_slice_params.line_infos = push_array(scratch.arena, D_LineList, visible_line_count); code_slice_params.font = code_font; @@ -188,7 +215,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla code_slice_params.catchall_margin_width_px = catchall_margin_width_px; code_slice_params.line_num_width_px = line_num_width_px; code_slice_params.line_text_max_width_px = (F32)line_size_x; - code_slice_params.margin_float_off_px = scroll_pos.x.idx + scroll_pos.x.off; + code_slice_params.margin_float_off_px = scroll_pos.x.idx + floor_f32(scroll_pos.x.off); // rjf: fill text info { @@ -207,21 +234,21 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: find visible breakpoints for source code if(!dasm_lines) ProfScope("find visible breakpoints for source code") { - RD_EntityList bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - for(RD_EntityNode *n = bps.first; n != 0; n = n->next) + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { - RD_Entity *bp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(bp, RD_EntityKind_Location); - if(visible_line_num_range.min <= loc->text_point.line && loc->text_point.line <= visible_line_num_range.max) + RD_Cfg *bp = n->v; + RD_Location loc = rd_location_from_cfg(bp); + if(visible_line_num_range.min <= loc.pt.line && loc.pt.line <= visible_line_num_range.max) { for(String8Node *override_n = file_path_possible_overrides.first; override_n != 0; override_n = override_n->next) { - if(path_match_normalized(loc->string, override_n->string)) + if(path_match_normalized(loc.file_path, override_n->string)) { - U64 slice_line_idx = (loc->text_point.line-visible_line_num_range.min); - rd_entity_list_push(scratch.arena, &code_slice_params.line_bps[slice_line_idx], bp); + U64 slice_line_idx = (U64)(loc.pt.line-visible_line_num_range.min); + rd_cfg_list_push(scratch.arena, &code_slice_params.line_bps[slice_line_idx], bp); break; } } @@ -269,21 +296,21 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: find visible watch pins for source code if(!dasm_lines) ProfScope("find visible watch pins for source code") { - RD_EntityList wps = rd_query_cached_entity_list_with_kind(RD_EntityKind_WatchPin); - for(RD_EntityNode *n = wps.first; n != 0; n = n->next) + RD_CfgList wps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch_pin")); + for(RD_CfgNode *n = wps.first; n != 0; n = n->next) { - RD_Entity *wp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(wp, RD_EntityKind_Location); - if(visible_line_num_range.min <= loc->text_point.line && loc->text_point.line <= visible_line_num_range.max) + RD_Cfg *wp = n->v; + RD_Location loc = rd_location_from_cfg(wp); + if(visible_line_num_range.min <= loc.pt.line && loc.pt.line <= visible_line_num_range.max) { for(String8Node *override_n = file_path_possible_overrides.first; override_n != 0; override_n = override_n->next) { - if(path_match_normalized(loc->string, override_n->string)) + if(path_match_normalized(loc.file_path, override_n->string)) { - U64 slice_line_idx = (loc->text_point.line-visible_line_num_range.min); - rd_entity_list_push(scratch.arena, &code_slice_params.line_pins[slice_line_idx], wp); + U64 slice_line_idx = (loc.pt.line-visible_line_num_range.min); + rd_cfg_list_push(scratch.arena, &code_slice_params.line_pins[slice_line_idx], wp); break; } } @@ -331,20 +358,21 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: find breakpoints mapping to this disasm if(dasm_lines) ProfScope("find breakpoints mapping to this disassembly") { - RD_EntityList bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - for(RD_EntityNode *n = bps.first; n != 0; n = n->next) + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { - RD_Entity *bp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(bp, RD_EntityKind_Location); - if(loc->flags & RD_EntityFlag_HasVAddr && contains_1u64(dasm_vaddr_range, loc->vaddr)) + RD_Cfg *bp = n->v; + RD_Location loc = rd_location_from_cfg(bp); + E_Value loc_value = e_value_from_string(loc.expr); + if(contains_1u64(dasm_vaddr_range, loc_value.u64)) { - U64 off = loc->vaddr-dasm_vaddr_range.min; + U64 off = loc_value.u64 - dasm_vaddr_range.min; U64 idx = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, off); - S64 line_num = (S64)(idx+1); + S64 line_num = (S64)idx+1; if(contains_1s64(visible_line_num_range, line_num)) { U64 slice_line_idx = (line_num-visible_line_num_range.min); - rd_entity_list_push(scratch.arena, &code_slice_params.line_bps[slice_line_idx], bp); + rd_cfg_list_push(scratch.arena, &code_slice_params.line_bps[slice_line_idx], bp); } } } @@ -353,20 +381,21 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: find watch pins mapping to this disasm if(dasm_lines) ProfScope("find watch pins mapping to this disassembly") { - RD_EntityList pins = rd_query_cached_entity_list_with_kind(RD_EntityKind_WatchPin); - for(RD_EntityNode *n = pins.first; n != 0; n = n->next) + RD_CfgList wps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch_pin")); + for(RD_CfgNode *n = wps.first; n != 0; n = n->next) { - RD_Entity *pin = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(pin, RD_EntityKind_Location); - if(loc->flags & RD_EntityFlag_HasVAddr && contains_1u64(dasm_vaddr_range, loc->vaddr)) + RD_Cfg *wp = n->v; + RD_Location loc = rd_location_from_cfg(wp); + E_Value loc_value = e_value_from_string(loc.expr); + if(contains_1u64(dasm_vaddr_range, loc_value.u64)) { - U64 off = loc->vaddr-dasm_vaddr_range.min; + U64 off = loc_value.u64 - dasm_vaddr_range.min; U64 idx = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, off); - S64 line_num = (S64)(idx+1); + S64 line_num = (S64)idx+1; if(contains_1s64(visible_line_num_range, line_num)) { U64 slice_line_idx = (line_num-visible_line_num_range.min); - rd_entity_list_push(scratch.arena, &code_slice_params.line_pins[slice_line_idx], pin); + rd_cfg_list_push(scratch.arena, &code_slice_params.line_pins[slice_line_idx], wp); } } } @@ -443,9 +472,10 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla U64 needle_pos = str8_find_needle(line_string, search_start, cv->find_text_fwd, StringMatchFlag_CaseInsensitive); if(needle_pos < line_string.size) { - rd_regs()->cursor.line = line_num; - rd_regs()->cursor.column = needle_pos+1; - rd_regs()->mark = rd_regs()->cursor; + rd_regs()->mark.line = line_num; + rd_regs()->mark.column = needle_pos+1; + rd_regs()->cursor = rd_regs()->mark; + rd_regs()->cursor.column += cv->find_text_fwd.size; found = 1; break; } @@ -466,7 +496,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla cv->center_cursor = found; if(found == 0) { - log_user_errorf("Could not find \"%S\"", cv->find_text_fwd); + log_user_errorf("Could not find `%S`", cv->find_text_fwd); } } @@ -475,15 +505,16 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla { B32 found = 0; B32 first = 1; - S64 line_num_start = rd_regs()->cursor.line; + TxtRng rng = txt_rng(rd_regs()->cursor, rd_regs()->mark); + S64 line_num_start = rng.min.line; S64 line_num_last = (S64)text_info->lines_count; for(S64 line_num = line_num_start; 1 <= line_num && line_num <= line_num_last; first = 0) { // rjf: gather line info String8 line_string = str8_substr(text_data, text_info->lines_ranges[line_num-1]); - if(rd_regs()->cursor.line == line_num && first) + if(rng.min.line == line_num && first) { - line_string = str8_prefix(line_string, rd_regs()->cursor.column-1); + line_string = str8_prefix(line_string, rng.min.column-1); } // rjf: search string @@ -499,9 +530,10 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla } if(next_needle_pos < line_string.size) { - rd_regs()->cursor.line = line_num; - rd_regs()->cursor.column = next_needle_pos+1; - rd_regs()->mark = rd_regs()->cursor; + rd_regs()->mark.line = line_num; + rd_regs()->mark.column = next_needle_pos+1; + rd_regs()->cursor = rd_regs()->mark; + rd_regs()->cursor.column += cv->find_text_bwd.size; found = 1; break; } @@ -522,7 +554,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla cv->center_cursor = found; if(found == 0) { - log_user_errorf("Could not find \"%S\"", cv->find_text_bwd); + log_user_errorf("Could not find `%S`", cv->find_text_bwd); } } @@ -603,13 +635,6 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla cv->watch_expr_at_mouse = 0; rd_cmd(RD_CmdKind_ToggleWatchExpression, .string = txt_string_from_info_data_txt_rng(text_info, text_data, sig.mouse_expr_rng)); } - - //- rjf: selected text on single line, no query? -> set search text - if(!txt_pt_match(rd_regs()->cursor, rd_regs()->mark) && rd_regs()->cursor.line == rd_regs()->mark.line && search_query.size == 0) - { - String8 text = txt_string_from_info_data_txt_rng(text_info, text_data, txt_rng(rd_regs()->cursor, rd_regs()->mark)); - rd_set_search_string(text); - } } ////////////////////////////// @@ -790,165 +815,527 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //////////////////////////////// //~ rjf: Watch Views -//- rjf: index -> column +//- rjf: cell list building -internal RD_WatchViewColumn * -rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index) +internal U64 +rd_id_from_watch_cell(RD_WatchCell *cell) { - RD_WatchViewColumn *result = wv->first_column; - S64 idx = 0; - for(RD_WatchViewColumn *c = wv->first_column; c != 0; c = c->next, idx += 1) + U64 result = 5381; + result = e_hash_from_string(result, str8_struct(&cell->kind)); + if(cell->kind != RD_WatchCellKind_Expr) { - result = c; - if(idx == index) - { - break; - } + result = e_hash_from_string(result, str8_struct(&cell->eval.irtree.mode)); + result = e_hash_from_string(result, str8_struct(&cell->index)); + result = e_hash_from_string(result, str8_struct(&cell->default_pct)); } return result; } +internal RD_WatchCell * +rd_watch_cell_list_push(Arena *arena, RD_WatchCellList *list) +{ + RD_WatchCell *cell = push_array(arena, RD_WatchCell, 1); + cell->index = list->count; + SLLQueuePush(list->first, list->last, cell); + list->count += 1; + return cell; +} + +internal RD_WatchCell * +rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellList *list, RD_WatchCell *params) +{ + RD_WatchCell *cell = rd_watch_cell_list_push(arena, list); + U64 index = cell->index; + MemoryCopyStruct(cell, params); + cell->index = index; + if(cell->pct == 0) + { + cell->pct = cell->default_pct; + } + cell->next = 0; + return cell; +} + //- rjf: watch view points <-> table coordinates internal B32 -rd_watch_view_point_match(RD_WatchViewPoint a, RD_WatchViewPoint b) +rd_watch_pt_match(RD_WatchPt a, RD_WatchPt b) { - return (a.x == b.x && - ev_key_match(a.parent_key, b.parent_key) && - ev_key_match(a.key, b.key)); + return (ev_key_match(a.parent_key, b.parent_key) && + ev_key_match(a.key, b.key) && + a.cell_id == b.cell_id); } -internal RD_WatchViewPoint -rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) +internal RD_WatchPt +rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) { - RD_WatchViewPoint pt = zero_struct; - pt.x = tbl.x; - pt.key = ev_key_from_num(block_ranges, (U64)tbl.y); - pt.parent_key = ev_block_range_from_num(block_ranges, (U64)tbl.y).block->key; + RD_WatchPt pt = zero_struct; + { + Temp scratch = scratch_begin(0, 0); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_query_input(), block_ranges, (U64)tbl.y); + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + { + S64 x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, x += 1) + { + if(x == tbl.x) + { + pt.cell_id = rd_id_from_watch_cell(cell); + break; + } + } + } + pt.key = row->key; + pt.parent_key = row->block->key; + scratch_end(scratch); + } return pt; } internal Vec2S64 -rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint pt) +rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt) { Vec2S64 tbl = {0}; - tbl.x = pt.x; - tbl.y = (S64)ev_num_from_key(block_ranges, pt.key); + { + Temp scratch = scratch_begin(0, 0); + U64 num = ev_num_from_key(block_ranges, pt.key); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_query_input(), block_ranges, num); + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + tbl.x = 0; + { + S64 x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, x += 1) + { + U64 cell_id = rd_id_from_watch_cell(cell); + if(cell_id == pt.cell_id) + { + tbl.x = x; + break; + } + } + } + tbl.y = (S64)num; + scratch_end(scratch); + } return tbl; } -//- rjf: row -> context info +//- rjf: row -> info -internal RD_WatchViewRowInfo -rd_watch_view_row_info_from_row(EV_Row *row) +internal RD_WatchRowInfo +rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { - RD_WatchViewRowInfo info = {0}; + RD_WatchRowInfo info = { - Temp scratch = scratch_begin(0, 0); + .module = &ctrl_entity_nil, + .can_expand = ev_row_is_expandable(row), + .group_cfg_parent = &rd_nil_cfg, + .group_cfg_child = &rd_nil_cfg, + .group_entity = &ctrl_entity_nil, + .callstack_thread = &ctrl_entity_nil, + .view_ui_rule = &rd_nil_view_ui_rule, + .view_ui_tag = &e_expr_nil, + }; + { + Temp scratch = scratch_begin(&arena, 1); DI_Scope *di_scope = di_scope_open(); - // rjf: unpack block/key coordinates + // rjf: unpack key & block EV_Block *block = row->block; EV_Key key = row->key; + E_IRTreeAndType parent_irtree = e_irtree_and_type_from_expr(scratch.arena, block->expr); + E_Type *parent_type = e_type_from_key__cached(parent_irtree.type_key); + E_Eval block_eval = e_eval_from_expr(scratch.arena, row->block->expr); + E_TypeKey block_type_key = block_eval.irtree.type_key; + E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); + E_Type *block_type = e_type_from_key__cached(block_type_key); - // rjf: unpack parent block's expression - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, block->expr); - E_Type *type = e_type_from_key(scratch.arena, irtree.type_key); + // rjf: fill row's eval + info.eval = e_eval_from_expr(arena, row->expr); - // rjf: evaluate row - E_Eval row_eval = e_eval_from_expr(scratch.arena, row->expr); - - // rjf: determine collection entity kind, if any - RD_EntityKind collection_entity_kind = RD_EntityKind_Nil; - CTRL_EntityKind collection_ctrl_entity_kind = CTRL_EntityKind_Null; - for EachElement(idx, rd_collection_name_table) + // rjf: determine if row's expression is editable + if(block_type->flags & E_TypeFlag_EditableChildren || row->expr == &e_expr_nil) { - if(str8_match(type->name, rd_collection_name_table[idx], 0)) + info.expr_is_editable = 1; + } + + // rjf: determine row's module + CTRL_Entity *row_ctrl_entity = rd_ctrl_entity_from_eval_space(info.eval.space); + CTRL_Entity *row_module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); + if(info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + { + switch(row_ctrl_entity->kind) { - collection_entity_kind = rd_collection_entity_kind_table[idx]; - collection_ctrl_entity_kind = rd_collection_ctrl_entity_kind_table[idx]; - break; - } - } - - // rjf: extract frontend entity, if any - RD_Entity *entity = &rd_nil_entity; - if(collection_entity_kind != RD_EntityKind_Nil) - { - entity = rd_entity_from_id(key.child_id); - } - - // rjf: extract control entity, if any - CTRL_Entity *ctrl_entity = &ctrl_entity_nil; - if(collection_ctrl_entity_kind != CTRL_EntityKind_Null && block->expand_view_rule_info_user_data != 0) - { - U64 block_relative_num = block->expand_view_rule_info->expr_expand_num_from_id(key.child_id, block->expand_view_rule_info_user_data); - RD_CtrlEntityExpandAccel *accel = block->expand_view_rule_info_user_data; - if(1 <= block_relative_num && block_relative_num <= accel->entities.count) - { - ctrl_entity = accel->entities.v[block_relative_num-1]; - } - } - else if(row_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) - { - ctrl_entity = rd_ctrl_entity_from_eval_space(row_eval.space); - } - - // rjf: extract callstack thread, if any - CTRL_Entity *thread = &ctrl_entity_nil; - for(E_Expr *expr = block->expr, *next = &e_expr_nil; expr != &e_expr_nil; expr = next) - { - next = &e_expr_nil; - switch(expr->kind) - { - default:{}break; - case E_ExprKind_Ref:{next = expr->ref;}break; - case E_ExprKind_Cast:{next = expr->last;}break; - case E_ExprKind_MemberAccess:{next = expr->first;}break; - case E_ExprKind_ArrayIndex:{next = expr->first;}break; - case E_ExprKind_LeafIdent: + default: + case CTRL_EntityKind_Process: + if(info.eval.irtree.mode == E_Mode_Offset) { - E_Eval eval = e_eval_from_expr(scratch.arena, expr); - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - if(entity->kind == CTRL_EntityKind_Thread) - { - thread = entity; - goto done; - } + info.module = ctrl_module_from_process_vaddr(row_ctrl_entity, info.eval.value.u64); + }break; + case CTRL_EntityKind_Thread: + if(info.eval.irtree.mode == E_Mode_Value) + { + CTRL_Entity *process = ctrl_process_from_entity(row_ctrl_entity); + info.module = ctrl_module_from_process_vaddr(process, d_query_cached_rip_from_thread(row_ctrl_entity)); }break; } } - done:; - // rjf: extract callstack row information, if any - U64 unwind_count = 0; - U64 inline_depth = 0; - if(thread != &ctrl_entity_nil) + // rjf: determine call stack info + if(block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && str8_match(str8_lit("call_stack"), block_type->name, 0)) { - U64 block_relative_num = block->expand_view_rule_info->expr_expand_num_from_id(key.child_id, block->expand_view_rule_info_user_data); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process), &base_unwind); - U64 frame_num = 1; - for(U64 base_frame_idx = 0; base_frame_idx < rich_unwind.concrete_frame_count; base_frame_idx += 1, frame_num += 1) + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(block_eval.space); + if(entity->kind == CTRL_EntityKind_Thread) { - if(frame_num <= block_relative_num && block_relative_num < frame_num+1+rich_unwind.frames[base_frame_idx].inline_frame_count) + info.callstack_thread = entity; + U64 frame_num = block->lookup_rule->num_from_id(key.child_id, block->lookup_rule_user_data); + CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, ctrl_process_from_entity(entity), &unwind); + if(1 <= frame_num && frame_num <= call_stack.count) { - unwind_count = base_frame_idx; - inline_depth = block_relative_num - frame_num; - break; + CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1]; + info.callstack_unwind_index = f->unwind_count; + info.callstack_inline_depth = f->inline_depth; + info.callstack_vaddr = regs_rip_from_arch_block(entity->arch, f->regs); } - frame_num += rich_unwind.frames[base_frame_idx].inline_frame_count; } } - // rjf: fill - info.collection_entity_kind = collection_entity_kind; - info.collection_entity = entity; - info.collection_ctrl_entity_kind = collection_ctrl_entity_kind; - info.collection_ctrl_entity = ctrl_entity; - info.callstack_thread = thread; - info.callstack_unwind_index = unwind_count; - info.callstack_inline_depth = inline_depth; + // rjf: determine ctrl entity + if(block_type_kind == E_TypeKind_Set && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || + block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) + { + info.group_entity = rd_ctrl_entity_from_eval_space(info.eval.space); + } + + // rjf: determine cfg group name / parent + if(block_type_kind == E_TypeKind_Set && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || + block_eval.space.kind == RD_EvalSpaceKind_MetaCfg)) + { + info.group_cfg_parent = rd_cfg_from_eval_space(block_eval.space); + } + + // rjf: determine group cfg name + if(block_type_kind == E_TypeKind_Set) + { + String8 singular_name = rd_singular_from_code_name_plural(block_type->name); + if(singular_name.size != 0) + { + info.group_cfg_name = singular_name; + } + else + { + info.group_cfg_name = block_type->name; + } + } + + // rjf: determine row's group cfg + if(info.group_cfg_name.size != 0) + { + RD_CfgID id = row->key.child_id; + info.group_cfg_child = rd_cfg_from_id(id); + } + + // rjf: determine cfgs/entities that this row is evaluating + RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(info.eval.space); + CTRL_Entity *evalled_entity = (info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity ? rd_ctrl_entity_from_eval_space(info.eval.space) : &ctrl_entity_nil); + + // rjf: determine if this cfg/entity evaluation is top-level - e.g. if we + // are evaluating a cfg tree, or some descendant of it + B32 is_top_level = 0; + if(evalled_cfg != &rd_nil_cfg) + { + E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, evalled_cfg->string); + is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.irtree.type_key)); + } + if(evalled_entity != &ctrl_entity_nil) + { + String8 top_level_name = ctrl_entity_kind_code_name_table[evalled_entity->kind]; + E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, top_level_name); + is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.irtree.type_key)); + } + + // rjf: determine view ui rule + info.view_ui_rule = rd_view_ui_rule_from_string(row->block->expand_rule->string); + if(info.view_ui_rule != &rd_nil_view_ui_rule) + { + info.view_ui_tag = row->block->expand_tag; + } + + // rjf: fill row's cells + { + if(0){} + + // rjf: folder / file rows + else if(info.eval.space.kind == E_SpaceKind_FileSystem) + { + E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); + if(type->kind == E_TypeKind_Set) + { + String8 file_path = e_string_from_id(info.eval.value.u64); + DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, + .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, + .pct = 1.f, + .fstrs = fstrs); + if(str8_match(type->name, str8_lit("file"), 0)) + { + info.can_expand = 0; + } + } + else + { + info.cell_style_key = str8_lit("expr_and_eval"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); +#undef take_pct + } + } + + // rjf: singular button for unattached processes + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) + { + E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); + if(str8_match(type->name, str8_lit("unattached_process"), 0)) + { + U64 pid = info.eval.value.u128.u64[0]; + String8 name = e_string_from_id(info.eval.value.u128.u64[1]); + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + DR_FStrList fstrs = {0}; + UI_TagF("weak") + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, + rd_icon_kind_text_table[RD_IconKind_Scheduler], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), + .color = ui_color_from_name(str8_lit("text"))); + } + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, push_str8f(arena, "(PID: %I64u)", pid)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, name); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = fstrs); + } + } + + // rjf: lister rows + else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) + { + info.can_expand = 0; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f); + } + + // rjf: top-level cfg rows + else if(is_top_level && evalled_cfg != &rd_nil_cfg) + { + RD_Cfg *cfg = evalled_cfg; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg)); + MD_Node *schema = rd_schema_from_name(cfg->string); + MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("commands"), 0); + for MD_EachNode(cmd, cmds_root->first) + { + String8 cmd_name = cmd->string; + RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); + switch(cmd_kind) + { + default:{}break; + case RD_CmdKind_EnableCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(!is_disabled) + { + cmd_kind = RD_CmdKind_DisableCfg; + } + }break; + case RD_CmdKind_DisableCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(is_disabled) + { + cmd_kind = RD_CmdKind_EnableCfg; + } + }break; + case RD_CmdKind_SelectCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(!is_disabled) + { + cmd_kind = RD_CmdKind_DeselectCfg; + } + }break; + case RD_CmdKind_DeselectCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(is_disabled) + { + cmd_kind = RD_CmdKind_SelectCfg; + } + }break; + } + if(cmd_kind == RD_CmdKind_EnableCfg || cmd_kind == RD_CmdKind_DisableCfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_Background, + .px = floor_f32(ui_top_font_size()*6.f), + .string = str8_lit("($expr).enabled")); + } + else if(cmd_kind != RD_CmdKind_Null) + { + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); + } + } + } + + // rjf: top-level entity rows + else if(is_top_level && evalled_entity != &ctrl_entity_nil) + { + CTRL_Entity *entity = evalled_entity; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, 1)); + if(entity->kind == CTRL_EntityKind_Machine || + entity->kind == CTRL_EntityKind_Process || + entity->kind == CTRL_EntityKind_Thread) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, + .px = floor_f32(ui_top_font_size()*6.f), + .string = str8_lit("($expr).active")); + } + if(entity->kind == CTRL_EntityKind_Thread) + { + RD_CmdKind cmd_kind = RD_CmdKind_SelectEntity; + if(ctrl_handle_match(entity->handle, rd_base_regs()->thread)) + { + cmd_kind = RD_CmdKind_DeselectEntity; + } + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); + } + } + + // rjf: singular row for queries + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaQuery) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); + } + + // rjf: singular button for commands + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) + { + E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); + if(type->kind == E_TypeKind_Set) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = 0, .pct = 1.f); + } + else + { + String8 cmd_name = e_string_from_id(e_value_eval_from_eval(info.eval).value.u64); + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string)); + } + } + + // rjf: singular cell for view ui + else if(info.view_ui_rule != &rd_nil_view_ui_rule) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewUI, .pct = 1.f); + } + + // rjf: for 'add-new' rows in meta-cfg evaluation spaces, only do expr + else if(info.eval.exprs.last == &e_expr_nil && info.group_cfg_name.size != 0 && info.group_cfg_child == &rd_nil_cfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); + } + + // rjf: for meta-evaluation space booleans, only do expr + else if(e_type_kind_from_key(info.eval.irtree.type_key) == E_TypeKind_Bool && + (info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || + info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || + info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); + } + + // rjf: for meta-cfg evaluation spaces, only do expr/value + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || + info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || + info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + info.eval.space.kind == E_SpaceKind_File) + { + if(e_type_kind_from_key(info.eval.irtree.type_key) == E_TypeKind_Array && + e_type_kind_from_key(e_type_direct_from_key(info.eval.irtree.type_key)) == E_TypeKind_U8) + { + info.can_expand = 0; + } + info.cell_style_key = str8_lit("expr_and_eval"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); +#undef take_pct + } + + // rjf: procedures collections get only expr/value/view-rule + else if(block_type->kind == E_TypeKind_Set && str8_match(block_type->name, str8_lit("procedures"), 0)) + { + info.cell_style_key = str8_lit("expr_value_viewrule"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.65f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.15f, .pct = take_pct()); +#undef take_pct + } + + // rjf: callstack frames + else if(info.callstack_thread != &ctrl_entity_nil) + { + info.cell_style_key = str8_lit("call_stack_frame"); + CTRL_Entity *process = ctrl_process_from_entity(info.callstack_thread); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, info.callstack_vaddr); + E_Space space = rd_eval_space_from_ctrl_entity(module, RD_EvalSpaceKind_MetaCtrlEntity); + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("module")); + E_Eval module_eval = e_eval_from_expr(arena, expr); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, .default_pct = 0.05f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.55f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .eval = module_eval, .default_pct = 0.20f, .pct = take_pct()); +#undef take_pct + } + + // rjf: default cells + else + { + info.cell_style_key = str8_lit("normal"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .default_pct = 0.15f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.25f, .pct = take_pct()); +#undef take_pct + } + } di_scope_close(di_scope); scratch_end(scratch); @@ -956,240 +1343,313 @@ rd_watch_view_row_info_from_row(EV_Row *row) return info; } -//- rjf: watch view flags & row info -> row kind +//- rjf: row * cell -> string -internal RD_WatchViewRowKind -rd_watch_view_row_kind_from_flags_row_info(RD_WatchViewFlags flags, EV_Row *row, RD_WatchViewRowInfo *info) +internal RD_WatchRowCellInfo +rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_flags, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px) { - Temp scratch = scratch_begin(0, 0); - RD_ViewRuleInfo *ui_view_rule_info = rd_view_rule_info_from_string(row->block->expand_view_rule_info->string); - MD_Node *ui_view_rule_params_root = row->block->expand_view_rule_params; - if(ui_view_rule_info->ui == 0 || !(ui_view_rule_info->flags & RD_ViewRuleInfoFlag_CanUseInWatchTable)) - { - ui_view_rule_info = &rd_nil_view_rule_info; - ui_view_rule_params_root = &md_nil_node; - } - RD_WatchViewRowKind row_kind = RD_WatchViewRowKind_Normal; - E_Eval row_eval = e_eval_from_expr(scratch.arena, row->expr); - E_TypeKey row_type_key = row_eval.type_key; - E_TypeKind row_type_kind = e_type_kind_from_key(row_type_key); - if(ev_key_match(row->block->key, ev_key_root())) - { - row_kind = RD_WatchViewRowKind_Header; - } - else if(ui_view_rule_info != &rd_nil_view_rule_info && ui_view_rule_info->ui != 0) - { - row_kind = RD_WatchViewRowKind_Canvas; - } - else if(flags & RD_WatchViewFlag_PrettyEntityRows && - ((row_eval.value.u64 == 0 && row_type_kind == E_TypeKind_Struct) || - info->collection_entity_kind != RD_EntityKind_Nil || - info->collection_ctrl_entity_kind != CTRL_EntityKind_Null)) - { - row_kind = RD_WatchViewRowKind_PrettyEntityControls; - } - scratch_end(scratch); - return row_kind; -} - -//- rjf: row/column -> strings - -internal E_Expr * -rd_expr_from_watch_view_row_column(Arena *arena, EV_View *ev_view, EV_Row *row, RD_WatchViewColumn *col) -{ - E_Expr *expr = row->expr; - switch(col->kind) + RD_WatchRowCellInfo result = {0}; + + //- rjf: fill basics/defaults + result.view_ui_rule = &rd_nil_view_ui_rule; + result.view_ui_tag = &e_expr_nil; + result.fstrs = cell->fstrs; + result.flags = cell->flags; + result.cfg = &rd_nil_cfg; + result.entity = &ctrl_entity_nil; + + //- rjf: do per-kind fills + switch(cell->kind) { default:{}break; - case RD_WatchViewColumnKind_Member: + + //- rjf: expression cells -> if no string attached to row itself, form one from the + // expression tree. + case RD_WatchCellKind_Expr: { - Temp scratch = scratch_begin(&arena, 1); - String8 access_string = str8(col->string_buffer, col->string_size); - String8List accesses = str8_split(scratch.arena, access_string, (U8 *)".", 1, 0); - for(String8Node *n = accesses.first; n != 0; n = n->next) + if(row_info->expr_is_editable) { - expr = e_expr_ref_member_access(arena, expr, n->string); + result.flags |= RD_WatchCellFlag_CanEdit; } - scratch_end(scratch); - }break; - } - if(col->view_rule_size != 0) - { - EV_ViewRuleList *view_rules = ev_view_rule_list_from_string(arena, str8(col->view_rule_buffer, col->view_rule_size)); - expr = ev_resolved_from_expr(arena, expr, view_rules); - } - return expr; -} - -internal String8 -rd_string_from_eval_viz_row_column(Arena *arena, EV_View *ev, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px) -{ - ProfBeginFunction(); - String8 result = {0}; - E_Expr *row_col_expr = rd_expr_from_watch_view_row_column(arena, ev, row, col); - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: - ProfScope("expr cell string") - { - result = ev_expr_string_from_row(arena, row, string_flags); - }break; - case RD_WatchViewColumnKind_Value: - case RD_WatchViewColumnKind_Member: - ProfScope("value/member cell string") - { - EV_ViewRuleList *view_rules = row->view_rules; - if(col->view_rule_size != 0) + result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, row->expr)); + result.string = row->string; + if(result.string.size == 0) { - view_rules = ev_view_rule_list_copy(arena, row->view_rules); - ev_view_rule_list_push_string(arena, view_rules, str8(col->view_rule_buffer, col->view_rule_size)); - } - E_Eval eval = e_eval_from_expr(arena, row_col_expr); - result = rd_value_string_from_eval(arena, string_flags, default_radix, font, font_size, max_size_px, eval, row->member, view_rules); - }break; - case RD_WatchViewColumnKind_Type: - ProfScope("type cell string") - { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, row_col_expr); - E_TypeKey type_key = irtree.type_key; - result = !e_type_key_match(type_key, e_type_key_zero()) ? e_type_string_from_key(arena, type_key) : str8_zero(); - result = str8_skip_chop_whitespace(result); - }break; - case RD_WatchViewColumnKind_ViewRule: - ProfScope("view rule cell string") - { - result = ev_view_rule_from_key(ev, row->key); - }break; - case RD_WatchViewColumnKind_Module: - ProfScope("module cell string") - { - E_Eval eval = e_eval_from_expr(arena, row_col_expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - CTRL_Entity *process = ctrl_process_from_entity(entity); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, value_eval.value.u64); - result = push_str8_copy(arena, str8_skip_last_slash(module->string)); - }break; - case RD_WatchViewColumnKind_CallStackFrame: - ProfScope("call stack frame cell string") - { - Temp scratch = scratch_begin(&arena, 1); - DI_Scope *di_scope = di_scope_open(); - E_Eval eval = e_eval_from_expr(arena, row_col_expr); - E_Expr *vaddr_expr = e_expr_ref_member_access(scratch.arena, row_col_expr, str8_lit("vaddr")); - E_Expr *depth_expr = e_expr_ref_member_access(scratch.arena, row_col_expr, str8_lit("inline_depth")); - E_Eval vaddr_eval = e_eval_from_expr(scratch.arena, vaddr_expr); - E_Eval depth_eval = e_eval_from_expr(scratch.arena, depth_expr); - E_Eval vaddr_value_eval = e_value_eval_from_eval(vaddr_eval); - E_Eval depth_value_eval = e_value_eval_from_eval(depth_eval); - U64 vaddr = vaddr_value_eval.value.u64; - U64 depth = depth_value_eval.value.u64; - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - CTRL_Entity *process = ctrl_process_from_entity(entity); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); - DI_Key dbgi = ctrl_dbgi_key_from_module(module); - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi, 0); - if(rdi != &di_rdi_parsed_nil) - { - typedef struct ScopeTask ScopeTask; - struct ScopeTask + E_Expr *notable_expr = row->expr; + for(B32 good = 0; !good;) { - ScopeTask *next; - RDI_Scope *scope; - }; - U64 voff = ctrl_voff_from_vaddr(module, vaddr); - RDI_Scope *root_scope = rdi_scope_from_voff(rdi, voff); - ScopeTask start_task = {0, root_scope}; - ScopeTask *first_task = &start_task; - ScopeTask *last_task = &start_task; - for(;root_scope->parent_scope_idx != 0;) - { - root_scope = rdi_parent_from_scope(rdi, root_scope); - ScopeTask *t = push_array(scratch.arena, ScopeTask, 1); - SLLQueuePushFront(first_task, last_task, t); - t->scope = root_scope; - } - RDI_Scope *scope = root_scope; - U64 idx = 0; - for(ScopeTask *t = first_task; t != 0; t = t->next, idx += 1) - { - if(idx == depth) + switch(notable_expr->kind) { - scope = t->scope; - break; + default:{good = 1;}break; + case E_ExprKind_Address: + case E_ExprKind_Deref: + case E_ExprKind_Cast: + { + notable_expr = notable_expr->last; + }break; + case E_ExprKind_Ref: + { + notable_expr = notable_expr->ref; + }break; } } - RDI_Procedure *procedure = rdi_procedure_from_scope(rdi, scope); - RDI_InlineSite *inline_site = rdi_inline_site_from_scope(rdi, scope); - if(inline_site->name_string_idx != 0 || inline_site->type_idx != 0) + switch(notable_expr->kind) { - String8List parts = {0}; - E_TypeKey type = e_type_key_ext(E_TypeKind_Function, inline_site->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); - String8List type_lhs_parts = {0}; - e_type_lhs_string_from_key(scratch.arena, type, &type_lhs_parts, 0, 0); - String8List type_rhs_parts = {0}; - e_type_rhs_string_from_key(scratch.arena, type, &type_rhs_parts, 0); - str8_list_pushf(scratch.arena, &parts, "[inlined] "); - str8_list_concat_in_place(&parts, &type_lhs_parts); - str8_list_push(scratch.arena, &parts, name); - str8_list_concat_in_place(&parts, &type_rhs_parts); - result = str8_list_join(arena, &parts, 0); + default: + { + result.string = e_string_from_expr(arena, notable_expr); + }break; + case E_ExprKind_ArrayIndex: + { + result.string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last)); + }break; + case E_ExprKind_MemberAccess: + { + Temp scratch = scratch_begin(&arena, 1); + E_Member member = result.eval.irtree.member; + String8 member_name = member.name; + if(member_name.size == 0) + { + member_name = notable_expr->last->string; + } + if(member.inheritance_key_chain.count != 0) + { + String8List strings = {0}; + for(E_TypeKeyNode *n = member.inheritance_key_chain.first; n != 0; n = n->next) + { + String8 base_class_name = e_type_string_from_key(scratch.arena, n->v); + str8_list_push(scratch.arena, &strings, base_class_name); + } + result.inheritance_tooltip = str8_list_join(arena, &strings, &(StringJoin){.sep = str8_lit_comp("::")}); + } + B32 is_non_code = 0; + String8 string = push_str8f(arena, ".%S", member_name); + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg || + result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + result.eval.space.kind == E_SpaceKind_File || + result.eval.space.kind == E_SpaceKind_FileSystem) + { + String8 fancy_name = rd_display_from_code_name(member_name); + if(fancy_name.size != 0) + { + string = fancy_name; + is_non_code = 1; + } + } + result.flags |= (!!is_non_code * RD_WatchCellFlag_IsNonCode); + result.string = string; + scratch_end(scratch); + }break; } - else if(procedure->name_string_idx != 0 || procedure->type_idx != 0) + } + }break; + + //- rjf: evaluation cells -> wrap expression if needed, evaluate, & stringize + case RD_WatchCellKind_Eval: + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: use cell's wrap string to wrap row's expression + String8 wrap_string = cell->string; + E_Expr *root_expr = row->expr; + if(wrap_string.size != 0) + { + E_Expr *wrap_expr = e_parse_expr_from_text(scratch.arena, wrap_string).exprs.last; + root_expr = wrap_expr; + typedef struct Task Task; + struct Task { - String8List parts = {0}; - E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); - String8List type_lhs_parts = {0}; - e_type_lhs_string_from_key(scratch.arena, type, &type_lhs_parts, 0, 0); - String8List type_rhs_parts = {0}; - e_type_rhs_string_from_key(scratch.arena, type, &type_rhs_parts, 0); - str8_list_concat_in_place(&parts, &type_lhs_parts); - str8_list_push(scratch.arena, &parts, name); - str8_list_concat_in_place(&parts, &type_rhs_parts); - result = str8_list_join(arena, &parts, 0); + Task *next; + E_Expr *parent; + E_Expr *expr; + }; + Task start_task = {0, &e_expr_nil, wrap_expr}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + if(t->expr->kind == E_ExprKind_LeafIdent && str8_match(t->expr->string, str8_lit("$expr"), 0)) + { + E_Expr *original_expr_ref = e_expr_ref(scratch.arena, row->expr); + if(t->parent != &e_expr_nil) + { + e_expr_insert_child(t->parent, t->expr, original_expr_ref); + e_expr_remove_child(t->parent, t->expr); + } + else + { + root_expr = original_expr_ref; + } + } + else for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + SLLQueuePush(first_task, last_task, task); + task->parent = t->expr; + task->expr = child; + } + } + } + + //- rjf: evaluate wrapped expression + result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, root_expr)); + + //- rjf: determine default radix + U32 default_radix = 10; + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && + rd_ctrl_entity_from_eval_space(result.eval.space)->kind == CTRL_EntityKind_Module) + { + default_radix = 16; + } + + //- rjf: generate strings/flags based on that expression & fill + result.string = rd_value_string_from_eval(arena, rd_view_query_input(), string_flags, default_radix, font, font_size, max_size_px, result.eval); + result.flags |= !!(ev_type_key_is_editable(result.eval.irtree.type_key) && result.eval.irtree.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; + E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); + if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) + { + result.flags |= RD_WatchCellFlag_IsNonCode; + } + + scratch_end(scratch); + }break; + + //- rjf: tag cells -> look up attached tag + case RD_WatchCellKind_Tag: + { + EV_View *ev_view = rd_view_eval_view(); + result.string = ev_view_rule_from_key(ev_view, row->key); + result.flags |= RD_WatchCellFlag_CanEdit; + }break; + + //- rjf: view ui cells + case RD_WatchCellKind_ViewUI: + { + result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, row->expr)); + result.view_ui_rule = row_info->view_ui_rule; + result.view_ui_tag = row_info->view_ui_tag; + }break; + } + + //- rjf: adjust style based on evaluation + switch(cell->kind) + { + default:{}break; + case RD_WatchCellKind_Expr: + { + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && + result.eval.value.u64 == 0) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(result.eval.space); + E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); + if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) + { + result.entity = entity; + } + } + else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg && + result.eval.value.u64 == 0) + { + RD_Cfg *cfg = rd_cfg_from_eval_space(result.eval.space); + E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); + if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) + { + result.cfg = cfg; + result.fstrs = rd_title_fstrs_from_cfg(arena, cfg); + } + } + else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCmd) + { + result.cmd_name = e_string_from_id(result.eval.value.u64); + } + else if(result.eval.space.kind == E_SpaceKind_FileSystem) + { + E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); + if(type->kind == E_TypeKind_Set) + { + String8 file_path = e_string_from_id(result.eval.value.u64); + result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); + result.flags |= RD_WatchCellFlag_Button; + } + } + }break; + case RD_WatchCellKind_Eval: + { + if(result.eval.msgs.max_kind != E_MsgKind_Null) + { + Temp scratch = scratch_begin(&arena, 1); + result.flags |= RD_WatchCellFlag_IsErrored|RD_WatchCellFlag_IsNonCode; + String8List error_strings = {0}; + for(E_Msg *msg = result.eval.msgs.first; msg != 0; msg = msg->next) + { + str8_list_push(scratch.arena, &error_strings, msg->text); + if(msg->next) + { + str8_list_pushf(scratch.arena, &error_strings, " "); + } + } + result.string = str8_list_join(arena, &error_strings, 0); + scratch_end(scratch); + } + else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && + result.eval.value.u64 == 0) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(result.eval.space); + E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); + if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) + { + result.fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, 1); + result.flags |= RD_WatchCellFlag_Button; + result.entity = entity; + } + } + else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg && + result.eval.value.u64 == 0) + { + RD_Cfg *cfg = rd_cfg_from_eval_space(result.eval.space); + E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); + if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) + { + result.fstrs = rd_title_fstrs_from_cfg(arena, cfg); + result.flags |= RD_WatchCellFlag_Button; + result.cfg = cfg; + } + } + else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCmd) + { + String8 cmd_name = e_string_from_id(result.eval.value.u64); + if(cell->px != 0) UI_TagF("weak") + { + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Icons), rd_raster_flags_from_slot(RD_FontSlot_Icons), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(arena, &result.fstrs, ¶ms, rd_icon_kind_text_table[rd_icon_kind_from_code_name(cmd_name)]); } else { - result = str8_lit("???"); + result.fstrs = rd_title_fstrs_from_code_name(arena, cmd_name); + } + result.flags |= RD_WatchCellFlag_Button; + result.cmd_name = cmd_name; + } + else if(result.eval.space.kind == E_SpaceKind_FileSystem) + { + E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); + if(type->kind == E_TypeKind_Set) + { + String8 file_path = e_string_from_id(result.eval.value.u64); + result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); + result.flags |= RD_WatchCellFlag_Button; } } - else - { - result = str8_lit("???"); - } - di_scope_close(di_scope); - scratch_end(scratch); }break; } - if(col->dequote_string && - result.size >= 2 && - result.str[0] == '"' && - result.str[result.size-1] == '"') - { - result = str8_skip(str8_chop(result, 1), 1); - result = raw_from_escaped_str8(arena, result); - } - if(col->rangify_braces && result.size >= 2 && - result.str[0] == '{' && - result.str[result.size-1] == '}') - { - result = push_str8_copy(arena, result); - result.str[0] = '['; - result.str[result.size-1] = ')'; - } - ProfEnd(); + return result; } //- rjf: table coordinates -> text edit state internal RD_WatchViewTextEditState * -rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint pt) +rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt) { RD_WatchViewTextEditState *result = &wv->dummy_text_edit_state; if(wv->text_edit_state_slots_count != 0 && wv->text_editing != 0) @@ -1198,7 +1658,7 @@ rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint p U64 slot_idx = hash%wv->text_edit_state_slots_count; for(RD_WatchViewTextEditState *s = wv->text_edit_state_slots[slot_idx]; s != 0; s = s->pt_hash_next) { - if(rd_watch_view_point_match(pt, s->pt)) + if(rd_watch_pt_match(pt, s->pt)) { result = s; break; @@ -1208,4595 +1668,15 @@ rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint p return result; } -//- rjf: watch view column state mutation - -internal RD_WatchViewColumn * -rd_watch_view_column_alloc_(RD_WatchViewState *wv, RD_WatchViewColumnKind kind, F32 pct, RD_WatchViewColumnParams *params) -{ - if(!wv->free_column) - { - RD_WatchViewColumn *col = push_array(wv->column_arena, RD_WatchViewColumn, 1); - SLLStackPush(wv->free_column, col); - } - RD_WatchViewColumn *col = wv->free_column; - SLLStackPop(wv->free_column); - DLLPushBack(wv->first_column, wv->last_column, col); - wv->column_count += 1; - col->kind = kind; - col->pct = pct; - col->string_size = Min(sizeof(col->string_buffer), params->string.size); - MemoryCopy(col->string_buffer, params->string.str, col->string_size); - col->display_string_size = Min(sizeof(col->display_string_buffer), params->display_string.size); - MemoryCopy(col->display_string_buffer, params->display_string.str, col->display_string_size); - col->view_rule_size = Min(sizeof(col->view_rule_buffer), params->view_rule.size); - MemoryCopy(col->view_rule_buffer, params->view_rule.str, col->view_rule_size); - col->is_non_code = params->is_non_code; - col->dequote_string = params->dequote_string; - col->rangify_braces = params->rangify_braces; - return col; -} - -internal void -rd_watch_view_column_release(RD_WatchViewState *wv, RD_WatchViewColumn *col) -{ - DLLRemove(wv->first_column, wv->last_column, col); - SLLStackPush(wv->free_column, col); - wv->column_count -= 1; -} - -//- rjf: watch view main hooks - -internal void -rd_watch_view_init(RD_WatchViewState *ewv) -{ - if(ewv->initialized == 0) - { - ewv->initialized = 1; - ewv->column_arena = rd_push_view_arena(); - ewv->text_edit_arena = rd_push_view_arena(); - } -} - -internal void -rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 root_expr, String8 root_view_rule, B32 modifiable, U32 default_radix, Rng2F32 rect) -{ - ProfBeginFunction(); - 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; - - ////////////////////////////// - //- rjf: unpack arguments - // - EV_ViewRuleList *top_level_view_rules = ev_view_rule_list_from_string(scratch.arena, root_view_rule); - String8 eval_view_key_string = push_str8f(scratch.arena, "eval_view_watch_%p", ewv); - EV_View *eval_view = rd_ev_view_from_key(d_hash_from_string(eval_view_key_string)); - String8 filter = rd_view_filter(); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); - F32 row_string_max_size_px = dim_2f32(rect).x; - EV_StringFlags string_flags = 0; - if(flags & RD_WatchViewFlag_PrettyNameMembers) - { - string_flags |= EV_StringFlag_PrettyNames; - } - RD_WatchViewRowCtrl row_ctrls_[] = - { - {RD_EntityKind_Target, CTRL_EntityKind_Null, RD_CmdKind_LaunchAndRun }, - {RD_EntityKind_Target, CTRL_EntityKind_Null, RD_CmdKind_LaunchAndInit }, - {RD_EntityKind_Target, CTRL_EntityKind_Null, RD_CmdKind_SelectEntity }, - {RD_EntityKind_Target, CTRL_EntityKind_Null, RD_CmdKind_RemoveEntity }, - {RD_EntityKind_Breakpoint, CTRL_EntityKind_Null, RD_CmdKind_EnableEntity }, - {RD_EntityKind_Breakpoint, CTRL_EntityKind_Null, RD_CmdKind_RemoveEntity }, - {RD_EntityKind_FilePathMap, CTRL_EntityKind_Null, RD_CmdKind_RemoveEntity }, - {RD_EntityKind_AutoViewRule,CTRL_EntityKind_Null, RD_CmdKind_RemoveEntity }, - {RD_EntityKind_Nil, CTRL_EntityKind_Machine, RD_CmdKind_FreezeEntity }, - {RD_EntityKind_Nil, CTRL_EntityKind_Process, RD_CmdKind_Kill }, - {RD_EntityKind_Nil, CTRL_EntityKind_Process, RD_CmdKind_FreezeEntity }, - {RD_EntityKind_Nil, CTRL_EntityKind_Thread, RD_CmdKind_SelectThread }, - {RD_EntityKind_Nil, CTRL_EntityKind_Thread, RD_CmdKind_FreezeEntity }, - }; - RD_WatchViewRowCtrl *row_ctrls = row_ctrls_; - U64 row_ctrls_count = ArrayCount(row_ctrls_); - - ////////////////////////////// - //- rjf: root-level view rule which has a ui hook? call into that to build the UI - // - B32 is_top_level_hook = 0; - { - RD_ViewRuleInfo *hook_rule_info = 0; - MD_Node *hook_rule_root = &md_nil_node; - for(EV_ViewRuleNode *n = top_level_view_rules->first; n != 0; n = n->next) - { - RD_ViewRuleInfo *rule_info = rd_view_rule_info_from_string(n->v.root->string); - if(rule_info != &rd_nil_view_rule_info && rule_info->ui != 0) - { - hook_rule_info = rule_info; - hook_rule_root = n->v.root; - break; - } - } - if(hook_rule_info) - { - hook_rule_info->ui(root_expr, hook_rule_root, rect); - is_top_level_hook = 1; - } - } - - ////////////////////////////// - //- rjf: determine autocompletion string - // - String8 autocomplete_hint_string = {0}; - if(!is_top_level_hook) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_AutocompleteHint) - { - autocomplete_hint_string = evt->string; - break; - } - } - } - - ////////////////////////////// - //- rjf: consume events & perform navigations/edits - calculate state - // - EV_BlockTree block_tree = {0}; - EV_BlockRangeList block_ranges = {0}; - UI_ScrollListRowBlockArray row_blocks = {0}; - Vec2S64 cursor_tbl = {0}; - Vec2S64 mark_tbl = {0}; - Rng2S64 selection_tbl = {0}; - if(!is_top_level_hook) ProfScope("consume events & perform navigations/edits - calculate state") UI_Focus(UI_FocusKind_On) - { - B32 state_dirty = 1; - B32 snap_to_cursor = 0; - B32 cursor_dirty__tbl = 0; - B32 take_autocomplete = 0; - for(UI_Event *event = 0;;) - { - ////////////////////////// - //- rjf: state -> viz blocks - // - if(state_dirty) ProfScope("state -> viz blocks") - { - MemoryZeroStruct(&block_tree); - MemoryZeroStruct(&block_ranges); - ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); - block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, root_expr, top_level_view_rules); - block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); - } - - ////////////////////////// - //- rjf: block ranges -> ui row blocks - // - ProfScope("block ranges -> ui row blocks") - { - UI_ScrollListRowBlockChunkList row_block_chunks = {0}; - for(EV_BlockRangeNode *n = block_ranges.first; n != 0; n = n->next) - { - UI_ScrollListRowBlock block = {0}; - block.row_count = dim_1u64(n->v.range); - block.item_count = n->v.block->single_item ? 1 : dim_1u64(n->v.range); - ui_scroll_list_row_block_chunk_list_push(scratch.arena, &row_block_chunks, 256, &block); - } - row_blocks = ui_scroll_list_row_block_array_from_chunk_list(scratch.arena, &row_block_chunks); - } - - ////////////////////////// - //- rjf: conclude state update - // - if(state_dirty) - { - state_dirty = 0; - } - - ////////////////////////////// - //- rjf: 2D table coordinates * blocks -> stable cursor state - // - if(cursor_dirty__tbl) - { - cursor_dirty__tbl = 0; - struct - { - RD_WatchViewPoint *pt_state; - Vec2S64 pt_tbl; - } - points[] = - { - {&ewv->cursor, cursor_tbl}, - {&ewv->mark, mark_tbl}, - }; - for(U64 point_idx = 0; point_idx < ArrayCount(points); point_idx += 1) - { - EV_Key last_key = points[point_idx].pt_state->key; - EV_Key last_parent_key = points[point_idx].pt_state->parent_key; - points[point_idx].pt_state[0] = rd_watch_view_point_from_tbl(&block_ranges, points[point_idx].pt_tbl); - if(ev_key_match(ev_key_zero(), points[point_idx].pt_state->key)) - { - points[point_idx].pt_state->key = last_parent_key; - EV_ExpandNode *node = ev_expand_node_from_key(eval_view, last_parent_key); - for(EV_ExpandNode *n = node; n != 0; n = n->parent) - { - points[point_idx].pt_state->key = n->key; - if(n->expanded == 0) - { - break; - } - } - } - if(point_idx == 0 && - (!ev_key_match(ewv->cursor.key, last_key) || - !ev_key_match(ewv->cursor.parent_key, last_parent_key))) - { - ewv->text_editing = 0; - } - } - ewv->next_cursor = ewv->cursor; - ewv->next_mark = ewv->mark; - } - - ////////////////////////// - //- rjf: stable cursor state * blocks -> 2D table coordinates - // - EV_WindowedRowList mark_rows = {0}; - Rng2S64 cursor_tbl_range = {0}; - { - // rjf: compute 2d table coordinates - cursor_tbl = rd_tbl_from_watch_view_point(&block_ranges, ewv->cursor); - mark_tbl = rd_tbl_from_watch_view_point(&block_ranges, ewv->mark); - - // rjf: compute row at initial selection point (or just cursor point) - mark_rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, mark_tbl.y), - ui_scroll_list_row_from_item(&row_blocks, mark_tbl.y)+1)); - - // rjf: compute legal coordinate range, given selection-defining row - Rng1S64 cursor_x_range = r1s64(0, ewv->column_count-1); - if(mark_rows.first != 0) - { - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(mark_rows.first); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, mark_rows.first, &row_info); - if(row_kind == RD_WatchViewRowKind_PrettyEntityControls) - { - U64 row_ctrl_count = 0; - for EachIndex(idx, row_ctrls_count) - { - if(row_ctrls[idx].entity_kind == row_info.collection_entity->kind && - row_ctrls[idx].ctrl_entity_kind == row_info.collection_ctrl_entity->kind) - { - row_ctrl_count += 1; - } - } - cursor_x_range = r1s64(1, 1+row_ctrl_count); - } - } - cursor_tbl_range = r2s64(v2s64(cursor_x_range.min, 0), v2s64(cursor_x_range.max, block_tree.total_item_count-1)); - - // rjf: clamp x positions of cursor/mark tbl - for EachEnumVal(Axis2, axis) - { - cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); - mark_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), mark_tbl.v[axis]); - } - - // rjf: form selection range table coordinates - selection_tbl = r2s64p(Min(cursor_tbl.x, mark_tbl.x), Min(cursor_tbl.y, mark_tbl.y), - Max(cursor_tbl.x, mark_tbl.x), Max(cursor_tbl.y, mark_tbl.y)); - } - - ////////////////////////// - //- rjf: [table] snap to cursor - // - if(snap_to_cursor) - { - Rng1S64 item_range = r1s64(0, block_tree.total_item_count); - Rng1S64 row_range = r1s64(0, block_tree.total_row_count); - Rng1S64 scroll_row_idx_range = r1s64(row_range.min, ClampBot(row_range.min, row_range.max-1)); - S64 cursor_item_idx = cursor_tbl.y; - if(item_range.min <= cursor_item_idx && cursor_item_idx <= item_range.max) - { - UI_ScrollPt *scroll_pt = &scroll_pos.y; - - //- rjf: compute visible row range - Rng1S64 visible_row_range = r1s64(scroll_pt->idx + 0 - !!(scroll_pt->off < 0), - scroll_pt->idx + 0 + num_possible_visible_rows); - - //- rjf: compute cursor row range from cursor item - Rng1S64 cursor_visibility_row_range = {0}; - if(row_blocks.count == 0) - { - cursor_visibility_row_range = r1s64(cursor_item_idx-2, cursor_item_idx+3); - } - else - { - cursor_visibility_row_range.min = (S64)ui_scroll_list_row_from_item(&row_blocks, (U64)cursor_item_idx) - 1; - cursor_visibility_row_range.max = cursor_visibility_row_range.min + 3; - } - - //- rjf: compute deltas & apply - S64 min_delta = Min(0, cursor_visibility_row_range.min-visible_row_range.min); - S64 max_delta = Max(0, cursor_visibility_row_range.max-visible_row_range.max); - S64 new_idx = scroll_pt->idx+min_delta+max_delta; - new_idx = clamp_1s64(scroll_row_idx_range, new_idx); - ui_scroll_pt_target_idx(scroll_pt, new_idx); - } - } - - ////////////////////////////// - //- rjf: apply cursor/mark rugpull change - // - B32 cursor_rugpull = 0; - if(!rd_watch_view_point_match(ewv->cursor, ewv->next_cursor)) - { - cursor_rugpull = 1; - ewv->cursor = ewv->next_cursor; - ewv->mark = ewv->next_mark; - } - - ////////////////////////// - //- rjf: grab next event, if any - otherwise exit the loop, as we now have - // the most up-to-date state - // - B32 next_event_good = ui_next_event(&event); - if(!cursor_rugpull && (!next_event_good || !ui_is_focus_active())) - { - break; - } - UI_Event dummy_evt = zero_struct; - UI_Event *evt = &dummy_evt; - if(next_event_good) - { - evt = event; - } - B32 taken = 0; - - ////////////////////////// - //- rjf: begin editing on some operations - // - if(!ewv->text_editing && - (evt->kind == UI_EventKind_Text || - evt->flags & UI_EventFlag_Paste || - (evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Edit)) && - selection_tbl.min.x == selection_tbl.max.x && - (selection_tbl.min.y != 0 || selection_tbl.min.y != 0)) - { - Vec2S64 selection_dim = dim_2s64(selection_tbl); - arena_clear(ewv->text_edit_arena); - ewv->text_edit_state_slots_count = u64_up_to_pow2(selection_dim.y+1); - ewv->text_edit_state_slots_count = Max(ewv->text_edit_state_slots_count, 64); - ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState*, ewv->text_edit_state_slots_count); - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y), - ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y)+1)); - EV_Row *row = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row = row->next) - { - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); - if(row_kind == RD_WatchViewRowKind_Normal) - { - ewv->text_editing = 1; - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) - { - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - String8 string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); - RD_WatchViewPoint pt = {x, row->block->key, row->key}; - U64 hash = ev_hash_from_key(pt.key); - U64 slot_idx = hash%ewv->text_edit_state_slots_count; - RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); - SLLStackPush_N(ewv->text_edit_state_slots[slot_idx], edit_state, pt_hash_next); - edit_state->pt = pt; - edit_state->cursor = txt_pt(1, string.size+1); - edit_state->mark = txt_pt(1, 1); - edit_state->input_size = string.size; - MemoryCopy(edit_state->input_buffer, string.str, string.size); - edit_state->initial_size = string.size; - MemoryCopy(edit_state->initial_buffer, string.str, string.size); - } - } - } - } - - ////////////////////////// - //- rjf: [table] do cell-granularity multi-cursor 'accept' operations (expansions / etc.); if - // cannot apply to multi-cursor, then just don't take the event - // - if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept) - { - taken = 1; - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y), - ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y)+1)); - EV_Row *row = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row != 0; y += 1, row = row->next) - { - // rjf: unpack row info - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); - - // rjf: loop through X selections and perform operations for each - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) - { - //- rjf: determine operation for this cell - typedef enum OpKind - { - OpKind_Null, - OpKind_DoExpand, - } - OpKind; - OpKind kind = OpKind_Null; - switch(row_kind) - { - default:{}break; - case RD_WatchViewRowKind_Normal: - { - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: {kind = OpKind_DoExpand;}break; - } - }break; - case RD_WatchViewRowKind_PrettyEntityControls: - if((!rd_entity_is_nil(row_info.collection_entity) || row_info.collection_ctrl_entity != &ctrl_entity_nil) && selection_tbl.min.x == 1 && selection_tbl.max.x == 1) - { - kind = OpKind_DoExpand; - }break; - } - - //- rjf: perform operation - switch(kind) - { - default:{taken = 0;}break; - case OpKind_DoExpand: - if(ev_row_is_expandable(row)) - { - B32 is_expanded = ev_expansion_from_key(eval_view, row->key); - ev_key_set_expansion(eval_view, row->block->key, row->key, !is_expanded); - }break; - } - } - } - } - - ////////////////////////// - //- rjf: [text] apply textual edits - // - if(ewv->text_editing) - { - B32 editing_complete = ((evt->kind == UI_EventKind_Press && (evt->slot == UI_EventActionSlot_Cancel || evt->slot == UI_EventActionSlot_Accept)) || - (evt->kind == UI_EventKind_Navigate && evt->delta_2s32.y != 0) || - cursor_rugpull); - rd_state->text_edit_mode = 1; - if(editing_complete || - ((evt->kind == UI_EventKind_Edit || - evt->kind == UI_EventKind_Navigate || - evt->kind == UI_EventKind_Text) && - evt->delta_2s32.y == 0)) - { - taken = 1; - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y), - ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y)+1)); - EV_Row *row = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row = row->next) - { - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) - { - RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, v2s64(x, y)); - RD_WatchViewTextEditState *edit_state = rd_watch_view_text_edit_state_from_pt(ewv, pt); - String8 string = str8(edit_state->input_buffer, edit_state->input_size); - UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); - - // rjf: copy - if(op.flags & UI_TxtOpFlag_Copy && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y) - { - os_set_clipboard_text(op.copy); - } - - // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op - if(autocomplete_hint_string.size != 0) - { - take_autocomplete = 1; - String8 word_query = rd_autocomp_query_word_from_input_string_off(string, edit_state->cursor.column-1); - U64 word_off = (U64)(word_query.str - string.str); - String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); - new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); - MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); - edit_state->input_size = new_string.size; - edit_state->cursor = edit_state->mark = txt_pt(1, word_off+1+autocomplete_hint_string.size); - string = str8(edit_state->input_buffer, edit_state->input_size); - op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); - } - - // rjf: cancel? -> revert to initial string - if(editing_complete && evt->slot == UI_EventActionSlot_Cancel) - { - string = str8(edit_state->initial_buffer, edit_state->initial_size); - } - - // rjf: obtain edited string - String8 new_string = string; - if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) - { - new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(op.range.min.column, op.range.max.column), op.replace); - } - - // rjf: commit to edit state - new_string.size = Min(new_string.size, sizeof(edit_state->input_buffer)); - MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); - edit_state->input_size = new_string.size; - edit_state->cursor = op.cursor; - edit_state->mark = op.mark; - - // rjf: commit edited cell string - Vec2S64 tbl = v2s64(x, y); - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - { - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: - if(modifiable) - { - if(row_info.collection_entity_kind != RD_EntityKind_Nil) - { - RD_Entity *entity = row_info.collection_entity; - if(!rd_entity_is_nil(entity) || editing_complete) - { - if(rd_entity_is_nil(entity) && new_string.size != 0) - { - entity = rd_entity_alloc(rd_entity_root(), row_info.collection_entity_kind); - rd_entity_equip_cfg_src(entity, RD_CfgSrc_Project); - } - if(!rd_entity_is_nil(entity)) - { - rd_entity_equip_name(entity, new_string); - } - state_dirty = 1; - snap_to_cursor = 1; - } - } - }break; - case RD_WatchViewColumnKind_Member: - case RD_WatchViewColumnKind_Value: - { - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, y), - ui_scroll_list_row_from_item(&row_blocks, y)+1)); - if(rows.first != 0) - { - B32 should_commit_asap = editing_complete; - E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, eval_view, row, col); - E_Eval dst_eval = e_eval_from_expr(scratch.arena, expr); - if(dst_eval.space.kind == RD_EvalSpaceKind_MetaEntity) - { - should_commit_asap = 1; - } - else if(evt->slot != UI_EventActionSlot_Cancel) - { - should_commit_asap = editing_complete; - } - if(should_commit_asap) - { - B32 success = 0; - success = rd_commit_eval_value_string(dst_eval, new_string, !col->dequote_string); - if(!success) - { - log_user_error(str8_lit("Could not commit value successfully.")); - } - } - } - }break; - case RD_WatchViewColumnKind_Type:{}break; - case RD_WatchViewColumnKind_ViewRule: - if(editing_complete) - { - RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, tbl); - ev_key_set_view_rule(eval_view, pt.key, new_string); - if(row_info.collection_entity_kind != RD_EntityKind_Nil) - { - RD_Entity *entity = row_info.collection_entity; - RD_Entity *view_rule = rd_entity_child_from_kind(entity, RD_EntityKind_ViewRule); - if(rd_entity_is_nil(view_rule) && new_string.size != 0) - { - view_rule = rd_entity_alloc(entity, RD_EntityKind_ViewRule); - } - else if(!rd_entity_is_nil(view_rule) && new_string.size == 0) - { - rd_entity_mark_for_deletion(view_rule); - } - if(new_string.size != 0) - { - rd_entity_equip_name(view_rule, new_string); - } - state_dirty = 1; - snap_to_cursor = 1; - } - }break; - } - } - } - } - } - if(editing_complete) - { - ewv->text_editing = 0; - } - } - - ////////////////////////// - //- rjf: [table] do cell-granularity copies - // - if(!ewv->text_editing && evt->flags & UI_EventFlag_Copy) - { - taken = 1; - String8List strs = {0}; - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y), - ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y)+1)); - EV_Row *row = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row != 0; y += 1, row = row->next) - { - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) - { - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - String8 cell_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - cell_string = str8_skip_chop_whitespace(cell_string); - U64 comma_pos = str8_find_needle(cell_string, 0, str8_lit(","), 0); - if(selection_tbl.min.x != selection_tbl.max.x || selection_tbl.min.y != selection_tbl.max.y) - { - str8_list_pushf(scratch.arena, &strs, "%s%S%s%s", - comma_pos < cell_string.size ? "\"" : "", - cell_string, - comma_pos < cell_string.size ? "\"" : "", - x+1 <= selection_tbl.max.x ? "," : ""); - } - else - { - str8_list_push(scratch.arena, &strs, cell_string); - } - } - if(y+1 <= selection_tbl.max.y) - { - str8_list_push(scratch.arena, &strs, str8_lit("\n")); - } - } - String8 string = str8_list_join(scratch.arena, &strs, 0); - os_set_clipboard_text(string); - } - - ////////////////////////// - //- rjf: [table] do cell-granularity deletions - // - if(!ewv->text_editing && evt->flags & UI_EventFlag_Delete) - { - taken = 1; - state_dirty = 1; - snap_to_cursor = 1; - RD_EntityList entities_to_remove = {0}; - RD_WatchViewPoint next_cursor_pt = {0}; - B32 next_cursor_set = 0; - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y), - ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y)+1)); - EV_Row *row = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row = row->next) - { - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) - { - Vec2S64 tbl = v2s64(x, y); - RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, tbl); - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - if(tbl.y != 0 && (col->kind == RD_WatchViewColumnKind_Expr || row_kind == RD_WatchViewRowKind_PrettyEntityControls) && - row_info.collection_entity_kind != RD_EntityKind_Nil) - { - RD_Entity *entity = row_info.collection_entity; - if(!rd_entity_is_nil(entity)) - { - rd_entity_list_push(scratch.arena, &entities_to_remove, entity); - U64 deleted_id = row->key.child_id; - U64 deleted_num = row->block->expand_view_rule_info->expr_expand_num_from_id(deleted_id, row->block->expand_view_rule_info_user_data); - if(deleted_num != 0) - { - U64 fallback_id_next = row->block->expand_view_rule_info->expr_expand_id_from_num(deleted_num+1, row->block->expand_view_rule_info_user_data); - U64 fallback_id_prev = row->block->expand_view_rule_info->expr_expand_id_from_num(deleted_num-1, row->block->expand_view_rule_info_user_data); - EV_Key parent_key = row->block->key; - EV_Key key = ev_key_make(row->key.parent_hash, fallback_id_next ? fallback_id_next : fallback_id_prev); - if(key.child_id == 0) - { - key = row->block->key; - parent_key = row->block->parent->key; - } - RD_WatchViewPoint new_pt = {0, parent_key, key}; - next_cursor_pt = new_pt; - next_cursor_set = 1; - } - } - } - else if(tbl.y != 0 && col->kind == RD_WatchViewColumnKind_ViewRule && row_kind == RD_WatchViewRowKind_Normal) - { - if(row_info.collection_entity_kind != RD_EntityKind_Nil) - { - RD_Entity *entity = row_info.collection_entity; - RD_Entity *view_rule = rd_entity_child_from_kind(entity, RD_EntityKind_ViewRule); - rd_entity_mark_for_deletion(view_rule); - } - ev_key_set_view_rule(eval_view, row->key, str8_zero()); - } - else if(tbl.y != 0 && (col->kind == RD_WatchViewColumnKind_Value || col->kind == RD_WatchViewColumnKind_Member) && row_kind == RD_WatchViewRowKind_Normal) - { - E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, eval_view, row, col); - E_Eval dst_eval = e_eval_from_expr(scratch.arena, expr); - rd_commit_eval_value_string(dst_eval, str8_zero(), 0); - } - } - } - for(RD_EntityNode *n = entities_to_remove.first; n != 0; n = n->next) - { - rd_entity_mark_for_deletion(n->entity); - } - if(next_cursor_set) - { - ewv->cursor = ewv->mark = ewv->next_cursor = ewv->next_mark = next_cursor_pt; - } - } - - ////////////////////////// - //- rjf: [table] apply deltas to cursor & mark - // - if(!ewv->text_editing && !(evt->flags & UI_EventFlag_Delete) && !(evt->flags & UI_EventFlag_Reorder)) - { - B32 cursor_tbl_min_is_empty_selection[Axis2_COUNT] = {0, 1}; - Vec2S32 delta = evt->delta_2s32; - if(evt->flags & UI_EventFlag_PickSelectSide && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) - { - if(delta.x > 0 || delta.y > 0) - { - cursor_tbl.x = selection_tbl.max.x; - cursor_tbl.y = selection_tbl.max.y; - } - else if(delta.x < 0 || delta.y < 0) - { - cursor_tbl.x = selection_tbl.min.x; - cursor_tbl.y = selection_tbl.min.y; - } - } - if(evt->flags & UI_EventFlag_ZeroDeltaOnSelect && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) - { - MemoryZeroStruct(&delta); - } - B32 moved = 1; - switch(evt->delta_unit) - { - default:{moved = 0;}break; - case UI_EventDeltaUnit_Char: - { - for EachEnumVal(Axis2, axis) - { - cursor_tbl.v[axis] += delta.v[axis]; - if(cursor_tbl.v[axis] < cursor_tbl_range.min.v[axis]) - { - cursor_tbl.v[axis] = cursor_tbl_range.max.v[axis]; - } - if(cursor_tbl.v[axis] > cursor_tbl_range.max.v[axis]) - { - cursor_tbl.v[axis] = cursor_tbl_range.min.v[axis]; - } - cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); - } - }break; - case UI_EventDeltaUnit_Word: - case UI_EventDeltaUnit_Line: - case UI_EventDeltaUnit_Page: - { - cursor_tbl.x = (delta.x>0 ? (cursor_tbl_range.max.x) : - delta.x<0 ? (cursor_tbl_range.min.x + !!cursor_tbl_min_is_empty_selection[Axis2_X]) : - cursor_tbl.x); - cursor_tbl.y += ((delta.y>0 ? +(num_possible_visible_rows-3) : - delta.y<0 ? -(num_possible_visible_rows-3) : - 0)); - cursor_tbl.y = clamp_1s64(r1s64(cursor_tbl_range.min.y + !!cursor_tbl_min_is_empty_selection[Axis2_Y], - cursor_tbl_range.max.y), - cursor_tbl.y); - }break; - case UI_EventDeltaUnit_Whole: - { - for EachEnumVal(Axis2, axis) - { - cursor_tbl.v[axis] = (delta.v[axis]>0 ? cursor_tbl_range.max.v[axis] : delta.v[axis]<0 ? cursor_tbl_range.min.v[axis] + !!cursor_tbl_min_is_empty_selection[axis] : cursor_tbl.v[axis]); - } - }break; - } - if(moved) - { - taken = 1; - cursor_dirty__tbl = 1; - snap_to_cursor = 1; - } - } - - ////////////////////////// - //- rjf: [table] stick table mark to cursor if needed - // - if(!ewv->text_editing) - { - if(taken && !(evt->flags & UI_EventFlag_KeepMark)) - { - mark_tbl = cursor_tbl; - } - } - - ////////////////////////// - //- rjf: [table] do cell-granularity reorders - // - if(!ewv->text_editing && evt->flags & UI_EventFlag_Reorder) - { - taken = 1; - if(filter.size == 0) - { - // rjf: determine blocks of each endpoint of the table selection - EV_Block *selection_endpoint_blocks[2] = - { - ev_block_range_from_num(&block_ranges, selection_tbl.min.y).block, - ev_block_range_from_num(&block_ranges, selection_tbl.max.y).block, - }; - - // rjf: pick shallowest block within which we can do reordering - U64 selection_depths[2] = - { - ev_depth_from_block(selection_endpoint_blocks[0]), - ev_depth_from_block(selection_endpoint_blocks[1]), - }; - EV_Block *selection_block = (selection_depths[1] < selection_depths[0] - ? selection_endpoint_blocks[1] - : selection_endpoint_blocks[0]); - - // rjf: find selection keys within the block in which we are doing reordering - EV_Key selection_keys_in_block[2] = {0}; - { - for EachElement(idx, selection_endpoint_blocks) - { - EV_Block *endpoint_block = selection_endpoint_blocks[idx]; - if(endpoint_block == selection_block) - { - selection_keys_in_block[idx] = ev_key_from_num(&block_ranges, selection_tbl.v[idx].y); - } - else - { - for(;endpoint_block->parent != selection_block && endpoint_block != &ev_nil_block;) - { - endpoint_block = endpoint_block->parent; - } - if(endpoint_block->parent == selection_block) - { - selection_keys_in_block[idx] = endpoint_block->key; - } - } - } - EV_Key fallback_key = {0}; - for EachElement(idx, selection_endpoint_blocks) - { - if(!ev_key_match(selection_keys_in_block[idx], ev_key_zero())) - { - fallback_key = selection_keys_in_block[idx]; - } - } - for EachElement(idx, selection_endpoint_blocks) - { - if(ev_key_match(selection_keys_in_block[idx], ev_key_zero())) - { - selection_keys_in_block[idx] = fallback_key; - } - } - } - - // rjf: determine collection info for the block - RD_EntityKind collection_entity_kind = RD_EntityKind_Nil; - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, selection_block->expr); - E_Type *type = e_type_from_key(scratch.arena, irtree.type_key); - for EachElement(idx, rd_collection_name_table) - { - if(str8_match(type->name, rd_collection_name_table[idx], 0)) - { - collection_entity_kind = rd_collection_entity_kind_table[idx]; - break; - } - } - - // rjf: map selection endpoints to entities - RD_Entity *first_entity = &rd_nil_entity; - RD_Entity *last_entity = &rd_nil_entity; - if(collection_entity_kind != RD_EntityKind_Nil) - { - first_entity = rd_entity_from_id(selection_keys_in_block[0].child_id); - last_entity = rd_entity_from_id(selection_keys_in_block[1].child_id); - } - - // rjf: reorder - if(!rd_entity_is_nil(first_entity) && !rd_entity_is_nil(last_entity)) - { - RD_Entity *first_entity_prev = &rd_nil_entity; - RD_Entity *last_entity_next = &rd_nil_entity; - for(RD_Entity *prev = first_entity->prev; !rd_entity_is_nil(prev); prev = prev->prev) - { - if(prev->kind == collection_entity_kind) - { - first_entity_prev = prev; - break; - } - } - for(RD_Entity *next = last_entity->next; !rd_entity_is_nil(next); next = next->next) - { - if(next->kind == collection_entity_kind) - { - last_entity_next = next; - break; - } - } - if(evt->delta_2s32.y < 0 && !rd_entity_is_nil(first_entity) && !rd_entity_is_nil(first_entity_prev)) - { - state_dirty = 1; - snap_to_cursor = 1; - rd_entity_change_parent(first_entity_prev, first_entity_prev->parent, first_entity_prev->parent, last_entity); - } - if(evt->delta_2s32.y > 0 && !rd_entity_is_nil(last_entity) && !rd_entity_is_nil(last_entity_next)) - { - state_dirty = 1; - snap_to_cursor = 1; - rd_entity_change_parent(last_entity_next, last_entity_next->parent, last_entity_next->parent, first_entity_prev); - } - } - } - } - - ////////////////////////// - //- rjf: consume event, if taken - // - if(taken && evt != &dummy_evt) - { - ui_eat_event(evt); - } - } - if(take_autocomplete) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_AutocompleteHint) - { - ui_eat_event(evt); - break; - } - } - } - } - - ////////////////////////////// - //- rjf: build ui - // - B32 pressed = 0; - if(!is_top_level_hook) ProfScope("build ui") - { - F32 **col_pcts = push_array(scratch.arena, F32*, ewv->column_count); - { - S64 x = 0; - for(RD_WatchViewColumn *c = ewv->first_column; c != 0; c = c->next, x += 1) - { - col_pcts[x] = &c->pct; - } - } - Rng1S64 visible_row_rng = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = floor_f32(ui_top_font_size()*2.5f); - scroll_list_params.dim_px = dim_2f32(rect); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(ewv->column_count-1, block_tree.total_item_count)); - scroll_list_params.item_range = r1s64(0, block_tree.total_row_count - !!(flags & RD_WatchViewFlag_NoHeader)); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 0; - scroll_list_params.row_blocks = row_blocks; - } - UI_BoxFlags disabled_flags = ui_top_flags(); - if(d_ctrl_targets_running()) - { - disabled_flags |= UI_BoxFlag_Disabled; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &scroll_pos.y, - 0, - 0, - &visible_row_rng, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - UI_TableF(ewv->column_count, col_pcts, "table") - { - Vec2F32 scroll_list_view_off_px = ui_top_parent()->parent->view_off; - - //////////////////////////// - //- rjf: viz blocks -> rows - // - EV_WindowedRowList rows = {0}; - { - rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min + !!(flags & RD_WatchViewFlag_NoHeader), visible_row_rng.max + 1 + !!(flags & RD_WatchViewFlag_NoHeader))); - } - - //////////////////////////// - //- rjf: build table - // - ProfScope("build table") - { - U64 global_row_idx = rows.count_before_semantic; - for(EV_Row *row = rows.first; row != 0; row = row->next, global_row_idx += 1) - { - //////////////////////// - //- rjf: skip header - // - if(global_row_idx == 0 && flags & RD_WatchViewFlag_NoHeader) - { - continue; - } - - //////////////////////// - //- rjf: unpack row info - // - ProfBegin("unpack row info"); - U64 row_hash = ev_hash_from_key(row->key); - U64 row_depth = ev_depth_from_block(row->block); - if(row_depth > 0) - { - row_depth -= 1; - } - B32 row_selected = (selection_tbl.min.y <= global_row_idx && global_row_idx <= selection_tbl.max.y); - B32 row_expanded = ev_expansion_from_key(eval_view, row->key); - E_Eval row_eval = e_eval_from_expr(scratch.arena, row->expr); - CTRL_Entity *row_ctrl_entity = rd_ctrl_entity_from_eval_space(row_eval.space); - CTRL_Entity *row_module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); - if(row_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) - { - switch(row_ctrl_entity->kind) - { - default: - case CTRL_EntityKind_Process: - if(row_eval.mode == E_Mode_Offset) - { - row_module = ctrl_module_from_process_vaddr(row_ctrl_entity, row_eval.value.u64); - }break; - case CTRL_EntityKind_Thread: - if(row_eval.mode == E_Mode_Value) - { - CTRL_Entity *process = ctrl_process_from_entity(row_ctrl_entity); - row_module = ctrl_module_from_process_vaddr(process, d_query_cached_rip_from_thread(row_ctrl_entity)); - }break; - } - } - E_Type *row_type = e_type_from_key(scratch.arena, row_eval.type_key); - B32 row_is_expandable = ev_row_is_expandable(row); - B32 next_row_expanded = row_expanded; - RD_ViewRuleInfo *ui_view_rule_info = rd_view_rule_info_from_string(row->block->expand_view_rule_info->string); - MD_Node *ui_view_rule_params_root = row->block->expand_view_rule_params; - if(ui_view_rule_info->ui == 0 || !(ui_view_rule_info->flags & RD_ViewRuleInfoFlag_CanUseInWatchTable)) - { - ui_view_rule_info = &rd_nil_view_rule_info; - ui_view_rule_params_root = &md_nil_node; - } - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); - ProfEnd(); - - //////////////////////// - //- rjf: determine if row's data is fresh and/or bad - // - ProfBegin("determine if row's data is fresh and/or bad"); - B32 row_is_fresh = 0; - B32 row_is_bad = 0; - switch(row_eval.mode) - { - default:{}break; - case E_Mode_Offset: - { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_eval.space); - if(row_eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) - { - U64 size = e_type_byte_size_from_key(row_eval.type_key); - size = Min(size, 64); - Rng1U64 vaddr_rng = r1u64(row_eval.value.u64, row_eval.value.u64+size); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, 0); - for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) - { - if(slice.byte_changed_flags[idx] != 0) - { - row_is_fresh = 1; - } - if(slice.byte_bad_flags[idx] != 0) - {row_is_bad = 1; - } - } - } - }break; - } - ProfEnd(); - - //////////////////////// - //- rjf: determine row's flags & color palette - // - ProfBegin("determine row's flags & color palette"); - UI_BoxFlags row_flags = 0; - UI_Palette *palette = ui_top_palette(); - { - if(row_is_fresh) - { - palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); - row_flags |= UI_BoxFlag_DrawBackground; - } - else if(global_row_idx & 1) - { - palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackgroundAlt)); - row_flags |= UI_BoxFlag_DrawBackground; - } - switch(row_kind) - { - default:{}break; - case RD_WatchViewRowKind_Normal:{row_flags |= UI_BoxFlag_DisableFocusOverlay;}break; - case RD_WatchViewRowKind_Header:{row_flags |= UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DisableFocusOverlay;}break; - case RD_WatchViewRowKind_Canvas:{row_flags |= UI_BoxFlag_Clip|UI_BoxFlag_DrawBorder;}break; - case RD_WatchViewRowKind_PrettyEntityControls:{row_flags |= UI_BoxFlag_DisableFocusOverlay;}break; - } - } - ProfEnd(); - - //////////////////////// - //- rjf: build row box - // - ui_set_next_palette(palette); - ui_set_next_flags(disabled_flags); - ui_set_next_pref_width(ui_pct(1, 0)); - ui_set_next_pref_height(ui_px(scroll_list_params.row_height_px*row->visual_size, 1.f)); - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - UI_Box *row_box = ui_build_box_from_stringf(row_flags|(!row->next)*UI_BoxFlag_DrawSideBottom|UI_BoxFlag_Clickable, "row_%I64x", row_hash); - ui_ts_vector_idx += 1; - ui_ts_cell_idx = 0; - - ////////////////////// - //- rjf: build row contents - // - RD_RegsScope(.module = row_module->handle) UI_Parent(row_box) switch(row_kind) - { - //////////////////// - //- rjf: header row - // - case RD_WatchViewRowKind_Header: - ProfScope("header row") - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - { - for(RD_WatchViewColumn *col = ewv->first_column; col != 0; col = col->next) - UI_TableCell - { - String8 name = str8(col->display_string_buffer, col->display_string_size); - if(name.size == 0) - { - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: {name = str8_lit("Expression");}break; - case RD_WatchViewColumnKind_Value: {name = str8_lit("Value");}break; - case RD_WatchViewColumnKind_Type: {name = str8_lit("Type");}break; - case RD_WatchViewColumnKind_ViewRule:{name = str8_lit("View Rule");}break; - case RD_WatchViewColumnKind_Member: - { - name = str8(col->string_buffer, col->string_size); - }break; - } - } - switch(col->kind) - { - default: - { - ui_label(name); - }break; - case RD_WatchViewColumnKind_ViewRule: - { - if(rd_help_label(name)) UI_Tooltip - { - F32 max_width = ui_top_font_size()*35; - ui_label_multiline(max_width, str8_lit("View rules are used to tweak the way evaluated expressions are visualized. Multiple rules can be specified on each row. They are specified in a key:(value) form. Some examples follow:")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("array:(N)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that a pointer points to N elements, rather than only 1.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("omit:(member_1 ... member_n)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Omits a list of member names from appearing in struct, union, or class evaluations.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("only:(member_1 ... member_n)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that only the specified members should appear in struct, union, or class evaluations.")); - ui_spacer(ui_em(1.5f, 1)); -#if 0 // TODO(rjf): disabling until post-0.9.12 - RD_Font(RD_FontSlot_Code) ui_labelf("list:(next_link_member_name)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that some struct, union, or class forms the top of a linked list, with next_link_member_name being the member which points at the next element in the list.")); - ui_spacer(ui_em(1.5f, 1)); -#endif - RD_Font(RD_FontSlot_Code) ui_labelf("dec"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-10 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("hex"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-16 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("oct"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-8 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("bin"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-2 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("no_addr"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Displays only what pointers point to, if possible, without the pointer's address value.")); - ui_spacer(ui_em(1.5f, 1)); - } - }break; - } - } - } - }break; - - //////////////////// - //- rjf: canvas row - // - case RD_WatchViewRowKind_Canvas: - ProfScope("canvas row") UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off) - { - //- rjf: unpack - RD_WatchViewPoint pt = {0, row->block->key, row->key}; - RD_View *view = rd_view_from_handle(rd_regs()->view); - RD_TransientViewNode *canvas_view_node = rd_transient_view_node_from_ev_key(view, row->key); - RD_View *canvas_view = canvas_view_node->view; - String8 canvas_view_expr = e_string_from_expr(scratch.arena, row->expr); - B32 need_new_spec = (!str8_match(str8(canvas_view->query_buffer, canvas_view->query_string_size), canvas_view_expr, 0) || - !md_tree_match(canvas_view_node->initial_params, ui_view_rule_params_root, 0)); - if(need_new_spec) - { - arena_clear(canvas_view_node->initial_params_arena); - canvas_view_node->initial_params = md_tree_copy(canvas_view_node->initial_params_arena, ui_view_rule_params_root); - rd_view_equip_spec(canvas_view, ui_view_rule_info, canvas_view_expr, ui_view_rule_params_root); - } - Vec2F32 canvas_dim = v2f32(scroll_list_params.dim_px.x - ui_top_font_size()*1.5f, - (row->visual_size_skipped+row->visual_size+row->visual_size_chopped)*scroll_list_params.row_height_px); - Rng2F32 canvas_rect = r2f32p(rect.x0, - rect.y0 + ui_top_fixed_y(), - rect.x0 + canvas_dim.x, - rect.y0 + ui_top_fixed_y() + canvas_dim.y); - - //- rjf: peek clicks in canvas region, mark clicked - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_Press && evt->key == OS_Key_LeftMouseButton && contains_2f32(canvas_rect, evt->pos) && - contains_2f32(rect, evt->pos)) - { - pressed = 1; - break; - } - } - - //- rjf: build meta controls - ui_set_next_fixed_x(ui_top_font_size()*1.f); - ui_set_next_fixed_y(ui_top_font_size()*1.f + scroll_list_view_off_px.y*(row == rows.first)); - ui_set_next_pref_width(ui_em(3, 1)); - ui_set_next_pref_height(ui_em(3, 1)); - UI_Flags(UI_BoxFlag_DrawDropShadow) UI_CornerRadius(ui_top_font_size()*0.5f) - { - UI_Signal sig = rd_icon_buttonf(RD_IconKind_Window, 0, "###pop_out"); - if(ui_hovering(sig)) UI_Tooltip - { - ui_labelf("Pop out"); - } - if(ui_pressed(sig)) - { - pressed = 1; - } - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_OpenTab, - .string = e_string_from_expr(scratch.arena, row->expr), - .params_tree = ui_view_rule_params_root); - } - } - - //- rjf: build main column for canvas - ui_set_next_fixed_y(-1.f * (row->visual_size_skipped) * scroll_list_params.row_height_px); - ui_set_next_fixed_height((row->visual_size_skipped + row->visual_size + row->visual_size_chopped) * scroll_list_params.row_height_px); - ui_set_next_child_layout_axis(Axis2_X); - UI_Box *canvas_box = ui_build_box_from_stringf(UI_BoxFlag_FloatingY, "###canvas_%I64x", row_hash); - UI_Parent(canvas_box) UI_WidthFill UI_HeightFill - { - //- rjf: loading animation container - UI_Box *loading_overlay_container = &ui_nil_box; - UI_Parent(canvas_box) UI_WidthFill UI_HeightFill - { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); - } - - //- rjf: push interaction registers, fill with per-view states - rd_push_regs(); - { - rd_regs()->view = rd_handle_from_view(canvas_view); - rd_regs()->file_path = rd_file_path_from_eval_string(rd_frame_arena(), str8(canvas_view->query_buffer, canvas_view->query_string_size)); - } - - //- rjf: build - UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) - { - ui_view_rule_info->ui(str8(canvas_view->query_buffer, canvas_view->query_string_size), canvas_view->params_roots[canvas_view->params_read_gen%ArrayCount(canvas_view->params_roots)], canvas_rect); - } - - //- rjf: loading overlay fill - UI_Parent(loading_overlay_container) - { - rd_loading_overlay(canvas_rect, canvas_view->loading_t, canvas_view->loading_progress_v, canvas_view->loading_progress_v_target); - } - - //- rjf: pop interaction registers - rd_pop_regs(); - } - }break; - - //////////////////// - //- rjf: pretty entity controls row - // - case RD_WatchViewRowKind_PrettyEntityControls: - ProfScope("pretty entity controls row") - { - //- rjf: unpack - RD_EntityKind collection_entity_kind = row_info.collection_entity_kind; - CTRL_EntityKind collection_ctrl_entity_kind = row_info.collection_ctrl_entity_kind; - RD_Entity *entity = row_info.collection_entity; - CTRL_Entity *ctrl_entity = row_info.collection_ctrl_entity; - B32 entity_box_selected = (row_selected && selection_tbl.min.x <= 1 && 1 <= selection_tbl.max.x); - B32 is_hovering = ((rd_handle_match(rd_state->hover_regs->entity, rd_handle_from_entity(entity)) && - rd_state->hover_regs_slot == RD_RegSlot_Entity) || - (ctrl_handle_match(rd_state->hover_regs->thread, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Thread) || - (ctrl_handle_match(rd_state->hover_regs->module, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Module) || - (ctrl_handle_match(rd_state->hover_regs->process, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Process)); - - //- rjf: pick palette - UI_Palette *palette = ui_build_palette(ui_top_palette()); - if(entity->kind == RD_EntityKind_Target && !entity->disabled) - { - palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_NeutralPopButton)); - } - else if(ctrl_entity->kind == CTRL_EntityKind_Thread && ctrl_handle_match(ctrl_entity->handle, rd_regs()->thread)) - { - palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_NeutralPopButton)); - } - else - { - palette->background = v4f32(0, 0, 0, 0); - } - - //- rjf: build indentation - for(U64 idx = 0; idx < row_depth; idx += 1) - { - ui_set_next_flags(UI_BoxFlag_DrawSideLeft); - ui_spacer(ui_em(1.f, 1.f)); - } - - //- rjf: build add-new buttons - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_Target) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_Breakpoint) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 1 ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string); - } - ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 2 ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_WatchPin) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 1 ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddWatchPin].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddWatchPin].string); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_FilePathMap) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_icon_buttonf(RD_IconKind_FileOutline, 0, "Add File Path Map"))) - { - rd_entity_alloc(rd_entity_root(), RD_EntityKind_FilePathMap); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_AutoViewRule) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Binoculars, 0, "Add Auto View Rule"))) - { - rd_entity_alloc(rd_entity_root(), RD_EntityKind_AutoViewRule); - } - } - - //- rjf: build entity box - if(!rd_entity_is_nil(entity) || ctrl_entity != &ctrl_entity_nil) - { - //- rjf: unpack entity info - DR_FancyStringList fstrs = {0}; - if(!rd_entity_is_nil(entity)) - { - fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, ui_top_palette()->text_weak, ui_top_font_size()); - } - else if(ctrl_entity != &ctrl_entity_nil) - { - fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, ui_top_palette()->text_weak, ui_top_font_size(), 1); - } - String8 fstrs_string = dr_string_from_fancy_string_list(scratch.arena, &fstrs); - FuzzyMatchRangeList fstrs_matches = fuzzy_match_find(scratch.arena, filter, fstrs_string); - UI_Key hover_t_key = ui_key_from_stringf(ui_key_zero(), "entity_hover_t_%p_%p", entity, ctrl_entity); - F32 hover_t = ui_anim(hover_t_key, (F32)!!is_hovering, .rate = entity_hover_t_rate); - if(!rd_entity_is_nil(entity)) - { - palette->overlay = rd_rgba_from_entity(entity); - palette->overlay.w *= 0.3f; - } - else if(ctrl_entity != &ctrl_entity_nil) - { - palette->overlay = rd_rgba_from_ctrl_entity(ctrl_entity); - palette->overlay.w *= 0.3f; - } - if(palette->overlay.x == 0 && palette->overlay.y == 0 && palette->overlay.z == 0 && palette->overlay.w == 0) - { - palette->overlay = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - } - palette->overlay.w *= hover_t; - - //- rjf: build - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *entity_box = &ui_nil_box; - UI_FocusHot(entity_box_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_Palette(palette) - { - entity_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawOverlay| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawSideLeft| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawHotEffects, - "###entity_%p_%p", entity, ctrl_entity); - } - { - UI_Parent(entity_box) RD_RegsScope(.entity = rd_handle_from_entity(entity)) - { - RD_RegSlot slot = RD_RegSlot_Entity; - switch(ctrl_entity->kind) - { - default:{}break; - case CTRL_EntityKind_Machine:{slot = RD_RegSlot_Machine; rd_regs()->machine = ctrl_entity->handle;}break; - case CTRL_EntityKind_Thread: {slot = RD_RegSlot_Thread; rd_regs()->thread = ctrl_entity->handle;}break; - case CTRL_EntityKind_Process:{slot = RD_RegSlot_Process; rd_regs()->process = ctrl_entity->handle;}break; - case CTRL_EntityKind_Module: {slot = RD_RegSlot_Module; rd_regs()->module = ctrl_entity->handle;}break; - } - UI_PrefWidth(ui_em(2.f, 1.f)) if(ui_pressed(ui_expander(row->block->rows_default_expanded ? !row_expanded : row_expanded, str8_lit("###expanded")))) - { - next_row_expanded = !row_expanded; - } - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTruncatedHover, ui_key_zero()); - ui_box_equip_display_fancy_strings(title_box, &fstrs); - ui_box_equip_fuzzy_match_ranges(title_box, &fstrs_matches); - UI_Signal sig = ui_signal_from_box(entity_box); - if(ui_hovering(sig)) - { - rd_set_hover_regs(slot); - } - if(ui_right_clicked(sig)) - { - rd_open_ctx_menu(entity_box->key, v2f32(0, dim_2f32(entity_box->rect).y), slot); - } - if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) - { - rd_drag_begin(slot); - } - if(ui_pressed(sig)) - { - RD_WatchViewPoint cell_pt = {1, row->block->key, row->key}; - ewv->next_cursor = ewv->next_mark = cell_pt; - pressed = 1; - } - if(ui_double_clicked(sig)) - { - if(entity->kind == RD_EntityKind_Target) - { - rd_cmd(sig.event_flags & OS_Modifier_Ctrl && entity->disabled ? RD_CmdKind_EnableEntity : - sig.event_flags & OS_Modifier_Ctrl && !entity->disabled ? RD_CmdKind_DisableEntity : - RD_CmdKind_SelectEntity, .entity = rd_handle_from_entity(entity)); - } - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = ctrl_entity->handle); - } - if(entity->kind == RD_EntityKind_Breakpoint || - entity->kind == RD_EntityKind_WatchPin) - { - RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location); - rd_cmd(RD_CmdKind_FindCodeLocation, - .file_path = (loc->flags & RD_EntityFlag_HasTextPoint) ? loc->string : str8_zero(), - .cursor = loc->text_point, - .vaddr = loc->vaddr); - } - } - } - } - - //- rjf: build extra entity controls - UI_PrefWidth(ui_em(3.f, 1.f)) - { - U64 ctrl_idx = 1; - for EachIndex(idx, row_ctrls_count) - { - RD_WatchViewRowCtrl *ctrl = &row_ctrls[idx]; - if(ctrl->entity_kind == entity->kind && - ctrl->ctrl_entity_kind == ctrl_entity->kind) - { - UI_FocusHot(row_selected && selection_tbl.min.x <= ctrl_idx+1 && ctrl_idx+1 <= selection_tbl.max.x ? UI_FocusKind_On : UI_FocusKind_Off) - { - B32 is_frozen = ctrl_entity_tree_is_frozen(ctrl_entity); - RD_IconKind icon_kind = rd_cmd_kind_info_table[ctrl->kind].icon_kind; - UI_Palette *palette = ui_top_palette(); - if(ctrl->kind == RD_CmdKind_SelectEntity) - { - icon_kind = entity->disabled ? RD_IconKind_RadioHollow : RD_IconKind_RadioFilled; - } - if(ctrl->kind == RD_CmdKind_EnableEntity) - { - icon_kind = entity->disabled ? RD_IconKind_CheckHollow : RD_IconKind_CheckFilled; - } - if(ctrl->kind == RD_CmdKind_SelectThread) - { - icon_kind = (ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread) ? RD_IconKind_RadioFilled : RD_IconKind_RadioHollow); - } - if(ctrl->kind == RD_CmdKind_FreezeEntity) - { - icon_kind = is_frozen ? RD_IconKind_Locked : RD_IconKind_Unlocked; - palette = rd_palette_from_code(is_frozen ? RD_PaletteCode_NegativePopButton : RD_PaletteCode_PositivePopButton); - } - UI_Palette(palette) - { - UI_Signal sig = rd_icon_buttonf(icon_kind, 0, "###row_ctrl_%I64x", idx); - if(ui_clicked(sig)) - { - if(ctrl->kind == RD_CmdKind_SelectEntity) - { - rd_cmd(sig.event_flags & OS_Modifier_Ctrl && entity->disabled ? RD_CmdKind_EnableEntity : - sig.event_flags & OS_Modifier_Ctrl && !entity->disabled ? RD_CmdKind_DisableEntity : - RD_CmdKind_SelectEntity, .entity = rd_handle_from_entity(entity)); - } - else if(ctrl->kind == RD_CmdKind_EnableEntity) - { - rd_cmd(entity->disabled ? RD_CmdKind_EnableEntity : RD_CmdKind_DisableEntity, .entity = rd_handle_from_entity(entity)); - } - else if(ctrl->kind == RD_CmdKind_SelectThread) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = ctrl_entity->handle); - } - else if(ctrl->kind == RD_CmdKind_FreezeEntity) - { - rd_cmd(is_frozen ? RD_CmdKind_ThawEntity : RD_CmdKind_FreezeEntity, - .ctrl_entity = ctrl_entity->handle); - } - else if(ctrl->kind == RD_CmdKind_Kill) - { - rd_cmd(RD_CmdKind_Kill, .process = ctrl_entity->handle); - } - else - { - rd_cmd(ctrl->kind, .entity = rd_handle_from_entity(entity)); - } - } - } - } - ctrl_idx += 1; - } - } - } - } - }break; - - //////////////////// - //- rjf: normal row - // - default: - case RD_WatchViewRowKind_Normal: - ProfScope("normal row") UI_HeightFill - { - ////////////////////// - //- rjf: draw start of cache lines in expansions - // - if(!(flags & RD_WatchViewFlag_DisableCacheLines)) - { - U64 row_offset = row_eval.value.u64; - if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && - row_offset%64 == 0 && row_depth > 0) - { - ui_set_next_fixed_x(0); - ui_set_next_fixed_y(0); - ui_set_next_fixed_height(ui_top_font_size()*0.2f); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary))); - ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - - ////////////////////// - //- rjf: draw mid-row cache line boundaries in expansions - // - if(!(flags & RD_WatchViewFlag_DisableCacheLines)) - { - if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && - row_eval.value.u64%64 != 0 && - row_depth > 0 && - !row_expanded) - { - U64 next_off = (row_eval.value.u64 + e_type_byte_size_from_key(row_eval.type_key)); - if(next_off%64 != 0 && row_eval.value.u64/64 < next_off/64) - { - ui_set_next_fixed_x(0); - ui_set_next_fixed_y(scroll_list_params.row_height_px - ui_top_font_size()*0.5f); - ui_set_next_fixed_height(ui_top_font_size()*1.f); - Vec4F32 boundary_color = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary); - boundary_color.w *= 0.5f; - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = boundary_color)); - ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - } - - ////////////////////// - //- rjf: build all columns - // - ProfScope("build all columns") - { - S64 x = 0; - F32 x_px = 0; - for(RD_WatchViewColumn *col = ewv->first_column; col != 0; col = col->next, x += 1) - { - //- rjf: unpack cell info - RD_WatchViewPoint cell_pt = {x, row->block->key, row->key}; - RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); - B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x); - String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - - //- rjf: unpack column-kind-specific info - ProfBegin("unpack column-kind-specific info"); - E_Eval cell_eval = row_eval; - E_Type *cell_type = row_type; - B32 cell_can_edit = 0; - FuzzyMatchRangeList cell_matches = {0}; - String8 cell_inheritance_string = {0}; - String8 cell_error_string = {0}; - String8 cell_error_tooltip_string = {0}; - RD_AutoCompListerFlags cell_autocomp_flags = 0; - RD_ViewRuleUIFunctionType *cell_ui_hook = 0; - MD_Node *cell_ui_params = &md_nil_node; - Vec4F32 cell_base_color = ui_top_palette()->text; - RD_IconKind cell_icon = RD_IconKind_Null; - String8 cell_ghost_text = {0}; - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: - { - cell_can_edit = (row_depth == 0 && modifiable && filter.size == 0); - if(filter.size != 0) - { - cell_matches = fuzzy_match_find(scratch.arena, filter, ev_expr_string_from_row(scratch.arena, row, string_flags)); - } - cell_autocomp_flags = (RD_AutoCompListerFlag_Locals| - RD_AutoCompListerFlag_Procedures| - RD_AutoCompListerFlag_Globals| - RD_AutoCompListerFlag_ThreadLocals| - RD_AutoCompListerFlag_Types); - if(row->member != 0 && row->member->inheritance_key_chain.first != 0) - { - String8List inheritance_chain_type_names = {0}; - for(E_TypeKeyNode *n = row->member->inheritance_key_chain.first; n != 0; n = n->next) - { - String8 inherited_type_name = e_type_string_from_key(scratch.arena, n->v); - inherited_type_name = str8_skip_chop_whitespace(inherited_type_name); - str8_list_push(scratch.arena, &inheritance_chain_type_names, inherited_type_name); - } - if(inheritance_chain_type_names.node_count != 0) - { - StringJoin join = {0}; - join.sep = str8_lit("::"); - String8 inheritance_type = str8_list_join(scratch.arena, &inheritance_chain_type_names, &join); - cell_inheritance_string = inheritance_type; - } - } - }break; - case RD_WatchViewColumnKind_Value: - { - }goto value_cell; - case RD_WatchViewColumnKind_Member: - { - E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, eval_view, row, col); - cell_eval = e_eval_from_expr(scratch.arena, expr); - cell_type = e_type_from_key(scratch.arena, cell_eval.type_key); - }goto value_cell; - value_cell:; - { - E_MsgList msgs = cell_eval.msgs; - if(row_depth == 0 && row->string.size != 0) - { - E_TokenArray tokens = e_token_array_from_text(scratch.arena, row->string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, row->string, &tokens); - e_msg_list_concat_in_place(&parse.msgs, &msgs); - msgs = parse.msgs; - } - if(msgs.max_kind > E_MsgKind_Null) - { - String8List strings = {0}; - for(E_Msg *msg = msgs.first; msg != 0; msg = msg->next) - { - str8_list_push(scratch.arena, &strings, msg->text); - } - StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; - cell_error_string = str8_list_join(scratch.arena, &strings, &join); - } - if(row_is_bad) - { - cell_error_tooltip_string = str8_lit("Could not read memory successfully."); - } - cell_autocomp_flags = (RD_AutoCompListerFlag_Locals| - RD_AutoCompListerFlag_Procedures| - RD_AutoCompListerFlag_Globals| - RD_AutoCompListerFlag_ThreadLocals| - RD_AutoCompListerFlag_Types); - if(cell_type->flags & E_TypeFlag_IsPathText) - { - cell_autocomp_flags = RD_AutoCompListerFlag_Files; - } - if(ui_view_rule_info->flags & RD_ViewRuleInfoFlag_CanFillValueCell) - { - cell_ui_hook = ui_view_rule_info->ui; - cell_ui_params = ui_view_rule_params_root; - } - for(EV_ViewRuleNode *n = row->view_rules->first; n != 0; n = n->next) - { - EV_ViewRule *vr = &n->v; - RD_ViewRuleInfo *info = rd_view_rule_info_from_string(vr->root->string); - if(info->flags & RD_ViewRuleInfoFlag_CanFillValueCell && info->ui != 0) - { - cell_ui_hook = info->ui; - cell_ui_params = vr->root; - } - } - cell_can_edit = ev_type_key_is_editable(cell_eval.type_key); - }break; - case RD_WatchViewColumnKind_Type: - { - cell_can_edit = 0; - }break; - case RD_WatchViewColumnKind_ViewRule: - { - cell_can_edit = 1; - cell_autocomp_flags = RD_AutoCompListerFlag_ViewRules; - if(cell_pre_edit_string.size == 0) - { - EV_ViewRuleList *auto_view_rules = ev_auto_view_rules_from_type_key(scratch.arena, row_eval.type_key, 0, 1); - String8List strings = {0}; - for(EV_ViewRuleNode *n = auto_view_rules->first; n != 0; n = n->next) - { - str8_list_push(scratch.arena, &strings, n->v.root->string); - } - cell_ghost_text = str8_list_join(scratch.arena, &strings, &(StringJoin){.sep = str8_lit(", ")}); - } - }break; - case RD_WatchViewColumnKind_CallStackFrameSelection: - { - if(ctrl_handle_match(row_info.callstack_thread->handle, rd_regs()->thread) && - row_info.callstack_unwind_index == rd_regs()->unwind_count && - row_info.callstack_inline_depth == rd_regs()->inline_depth) - { - cell_icon = RD_IconKind_RightArrow; - cell_base_color = rd_rgba_from_ctrl_entity(row_info.callstack_thread); - } - }break; - } - ProfEnd(); - - //- rjf: apply column-specified view rules - ProfBegin("apply column-specified view rules"); - if(col->view_rule_size != 0) - { - String8 col_view_rule = str8(col->view_rule_buffer, col->view_rule_size); - EV_ViewRuleList *view_rules = ev_view_rule_list_from_string(scratch.arena, col_view_rule); - for(EV_ViewRuleNode *n = view_rules->first; n != 0; n = n->next) - { - EV_ViewRule *vr = &n->v; - RD_ViewRuleInfo *info = rd_view_rule_info_from_string(vr->root->string); - if(info->flags & RD_ViewRuleInfoFlag_CanFillValueCell && info->ui != 0) - { - cell_ui_hook = info->ui; - cell_ui_params = vr->root; - } - } - } - ProfEnd(); - - //- rjf: determine cell's palette - ProfBegin("determine cell's palette"); - UI_BoxFlags cell_flags = 0; - UI_Palette *palette = ui_top_palette(); - { - if(cell_error_tooltip_string.size != 0 || - cell_error_string.size != 0) - { - palette = ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError)); - cell_flags |= UI_BoxFlag_DrawBackground; - } - else if(cell_inheritance_string.size != 0) - { - palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); - cell_flags |= UI_BoxFlag_DrawBackground; - } - else - { - palette = ui_build_palette(ui_top_palette(), .text = cell_base_color); - } - } - ProfEnd(); - - //- rjf: determine if cell needs code styling - B32 cell_is_code = !col->is_non_code; - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: - { - cell_is_code = 1; - if(row->member != 0 && row->member->pretty_name.size != 0 && flags & RD_WatchViewFlag_PrettyNameMembers) - { - cell_is_code = 0; - } - }break; - case RD_WatchViewColumnKind_Value: - case RD_WatchViewColumnKind_Member: - { - if(cell_type->flags & E_TypeFlag_IsCodeText) - { - cell_is_code = 1; - } - else if(cell_type->flags & E_TypeFlag_IsPathText || - cell_type->flags & E_TypeFlag_IsPlainText) - { - cell_is_code = 0; - } - }break; - } - - //- rjf: build cell - UI_Signal sig = {0}; - ProfScope("build cell") - UI_Palette(palette) - UI_TableCell - UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) - UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) - RD_Font(cell_is_code ? RD_FontSlot_Code : RD_FontSlot_Main) - UI_FlagsAdd(row_depth > 0 ? UI_BoxFlag_DrawTextWeak : 0) - { - ui_set_next_flags(ui_top_flags() | cell_flags); - - // rjf: cell has errors? -> build error box - if(cell_error_string.size != 0) RD_Font(RD_FontSlot_Main) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_row_%I64x", x, row_hash); - sig = ui_signal_from_box(box); - UI_Parent(box) UI_Flags(0) - { - rd_error_label(cell_error_string); - } - } - - // rjf: cell has hook? -> build ui by calling hook - else if(cell_ui_hook != 0) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###val_%I64x", row_hash); - UI_Parent(box) - { - String8 row_expr = e_string_from_expr(scratch.arena, row->expr); - cell_ui_hook(row_expr, cell_ui_params, r2f32p(x_px, 0, x_px + col->pct*dim_2f32(rect).x, row_height_px)); - } - sig = ui_signal_from_box(box); - } - - // rjf: cell has icon? build icon - else if(cell_icon != RD_IconKind_Null) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###cell_%I64x", row_hash); - UI_Parent(box) RD_Font(RD_FontSlot_Icons) UI_WidthFill UI_TextAlignment(UI_TextAlign_Center) - { - ui_label(rd_icon_kind_text_table[cell_icon]); - } - sig = ui_signal_from_box(box); - } - - // rjf: build cell line edit - else - { - sig = rd_line_editf((RD_LineEditFlag_CodeContents*(!!cell_is_code)| - RD_LineEditFlag_NoBackground| - RD_LineEditFlag_KeyboardClickable| - RD_LineEditFlag_DisableEdit*(!cell_can_edit)| - RD_LineEditFlag_Expander*!!(x == 0 && row_is_expandable && col->kind == RD_WatchViewColumnKind_Expr)| - RD_LineEditFlag_ExpanderPlaceholder*(x == 0 && row_depth==0 && col->kind == RD_WatchViewColumnKind_Expr)| - RD_LineEditFlag_ExpanderSpace*(x == 0 && row_depth!=0 && col->kind == RD_WatchViewColumnKind_Expr)), - x == 0 ? row_depth : 0, - &cell_matches, - &cell_edit_state->cursor, &cell_edit_state->mark, cell_edit_state->input_buffer, sizeof(cell_edit_state->input_buffer), &cell_edit_state->input_size, &next_row_expanded, - cell_pre_edit_string, - "%S###%I64x_row_%I64x", cell_ghost_text, x, row_hash); - if(ui_is_focus_active() && - selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && - txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) - { - String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); - RD_AutoCompListerParams params = {cell_autocomp_flags}; - if(col->kind == RD_WatchViewColumnKind_ViewRule) - { - params = rd_view_rule_autocomp_lister_params_from_input_cursor(scratch.arena, input, cell_edit_state->cursor.column-1); - if(params.flags == 0) - { - params.flags = cell_autocomp_flags; - } - } - rd_set_autocomp_lister_query(sig.box->key, ¶ms, input, cell_edit_state->cursor.column-1); - } - } - } - - //- rjf: handle interactions - { - // rjf: single-click -> move selection here - if(ui_pressed(sig)) - { - ewv->next_cursor = ewv->next_mark = cell_pt; - pressed = 1; - } - - // rjf: double-click actions - if(ui_double_clicked(sig) || sig.f & UI_SignalFlag_KeyboardPressed) - { - ui_kill_action(); - - // rjf: has callstack info? -> select unwind - if(row_info.callstack_thread != &ctrl_entity_nil) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = row_info.callstack_thread->handle); - rd_cmd(RD_CmdKind_SelectUnwind, - .unwind_count = row_info.callstack_unwind_index, - .inline_depth = row_info.callstack_inline_depth); - } - - // rjf: can edit? -> begin editing - else if(cell_can_edit) - { - rd_cmd(RD_CmdKind_Edit); - } - - // rjf: cannot edit, has addr info? -> go to address - else if(row_kind == RD_WatchViewRowKind_Normal && - (col->kind == RD_WatchViewColumnKind_Value || - col->kind == RD_WatchViewColumnKind_Member) && - cell_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) - { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_eval.space); - CTRL_Entity *process = ctrl_process_from_entity(entity); - if(process != &ctrl_entity_nil) - { - U64 vaddr = cell_eval.value.u64; - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - U64 voff = ctrl_voff_from_vaddr(module, vaddr); - D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); - String8 file_path = {0}; - TxtPt pt = {0}; - if(lines.first != 0) - { - file_path = lines.first->v.file_path; - pt = lines.first->v.pt; - } - rd_cmd(RD_CmdKind_FindCodeLocation, - .process = process->handle, - .vaddr = vaddr, - .file_path = file_path, - .cursor = pt); - } - } - } - - // rjf: hovering with inheritance string -> show tooltip - if(ui_hovering(sig) && cell_inheritance_string.size != 0) UI_Tooltip - { - UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) - { - ui_labelf("Inherited from "); - RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), cell_inheritance_string); - } - } - - // rjf: hovering with error tooltip -> show tooltip - if(ui_hovering(sig) && cell_error_tooltip_string.size != 0) UI_Tooltip - { - UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_error_tooltip_string); - } - } - - //- rjf: bump x pixel coordinate - x_px += col->pct*dim_2f32(rect).x; - - //- rjf: [DEV] hovering -> watch key tooltips - if(DEV_eval_watch_key_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) - { - ui_labelf("Block Key: {0x%I64x, %I64u}", row->block->key.parent_hash, row->block->key.child_id); - ui_labelf("Row Key: {0x%I64x, %I64u}", row->key.parent_hash, row->key.child_id); - ui_labelf("Cursor Key: {0x%I64x, %I64u}", ewv->cursor.key.parent_hash, ewv->cursor.key.child_id); - ui_spacer(ui_em(1.f, 1.f)); - ui_labelf("Cursor Table Coordinates: {%I64u, %I64u}", selection_tbl.min.x, selection_tbl.min.y); - } - - //- rjf: [DEV] hovering -> eval system tooltips - if(DEV_eval_compiler_tooltips && x == 0 && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) - { - local_persist char *spaces = " "; - String8 string = ev_expr_string_from_row(scratch.arena, row, 0); - E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); - E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Text:"); - ui_label(string); - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Tokens:"); - for(U64 idx = 0; idx < tokens.count; idx += 1) - { - ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range)); - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Expression:"); - { - typedef struct Task Task; - struct Task - { - Task *next; - Task *prev; - E_Expr *expr; - S64 depth; - }; - Task start_task = {0, 0, parse.expr}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - String8 ext = {0}; - switch(t->expr->kind) - { - default: - { - if(t->expr->string.size != 0) - { - ext = push_str8f(scratch.arena, "'%S'", t->expr->string); - } - else if(t->expr->value.u32 != 0) - { - ext = push_str8f(scratch.arena, "0x%x", t->expr->value.u32); - } - else if(t->expr->value.f32 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f32); - } - else if(t->expr->value.f64 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f64); - } - else if(t->expr->value.u64 != 0) - { - ext = push_str8f(scratch.arena, "0x%I64x", t->expr->value.u64); - } - }break; - } - ui_labelf("%.*s%S%s%S", (int)t->depth*2, spaces, e_expr_kind_strings[t->expr->kind], ext.size ? " " : "", ext); - for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->expr = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("IR Tree:"); - { - typedef struct Task Task; - struct Task - { - Task *next; - Task *prev; - E_IRNode *node; - S64 depth; - }; - Task start_task = {0, 0, irtree.root}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - String8 op_string = {0}; - switch(t->node->op) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - ui_labelf("%.*s%S", (int)t->depth*2, spaces, op_string); - for(E_IRNode *child = t->node->first; child != &e_irnode_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->node = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Op List:"); - { - for(E_Op *op = oplist.first; op != 0; op = op->next) - { - String8 op_string = {0}; - switch(op->opcode) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - switch(op->opcode) - { - case E_IRExtKind_Bytecode:{ext = str8_lit("[bytecode]");}break; - default: - { - ext = str8_from_u64(scratch.arena, op->value.u64, 16, 0, 0); - }break; - } - ui_labelf(" %S%s%S", op_string, ext.size ? " " : "", ext); - } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Bytecode:"); - { - for(U64 idx = 0; idx < bytecode.size; idx += 1) - { - ui_labelf(" 0x%x ('%c')", (U32)bytecode.str[idx], (char)bytecode.str[idx]); - } - } - } - } - } - }break; - } - - ////////////////////// - //- rjf: commit expansion state changes - // - if(next_row_expanded != row_expanded) - { - ev_key_set_expansion(eval_view, row->block->key, row->key, next_row_expanded); - } - } - } - } - } - - ////////////////////////////// - //- rjf: general table-wide press logic - // - if(!is_top_level_hook) if(pressed) - { - rd_cmd(RD_CmdKind_FocusPanel); - } - - if(!is_top_level_hook) { rd_store_view_scroll_pos(scroll_pos); } - scratch_end(scratch); - di_scope_close(di_scope); - ProfEnd(); -} - //////////////////////////////// //~ rjf: null @view_hook_impl -RD_VIEW_RULE_UI_FUNCTION_DEF(null) {} - -//////////////////////////////// -//~ rjf: empty @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(empty) -{ - ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); - UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) - { - UI_PrefHeight(ui_em(3.f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(15.f, 1.f)) - UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_NegativePopButton) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Panel"))) - { - rd_cmd(RD_CmdKind_ClosePanel); - } - } - } -} - -//////////////////////////////// -//~ rjf: getting_started @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); - UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) - { - RD_EntityList targets = rd_push_active_target_list(scratch.arena); - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); - - //- rjf: icon & info - UI_Padding(ui_em(2.f, 1.f)) - { - //- rjf: icon - { - F32 icon_dim = ui_top_font_size()*10.f; - UI_PrefHeight(ui_px(icon_dim, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_PrefWidth(ui_px(icon_dim, 1.f)) - { - R_Handle texture = rd_state->icon_texture; - Vec2S32 texture_dim = r_size_from_tex2d(texture); - ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); - } - } - - //- rjf: info - UI_Padding(ui_em(2.f, 1.f)) - UI_WidthFill UI_PrefHeight(ui_em(2.f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_text_dim(10, 1)) - { - ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); - } - } - - //- rjf: targets state dependent helper - B32 helper_built = 0; - if(processes.count == 0) - { - helper_built = 1; - switch(targets.count) - { - //- rjf: user has no targets. build helper for adding them - case 0: - { - UI_PrefHeight(ui_em(3.75f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(22.f, 1.f)) - UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_NeutralPopButton) - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Add, 0, "Add Target"))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); - } - }break; - - //- rjf: user has 1 target. build helper for launching it - case 1: - { - RD_Entity *target = rd_first_entity_from_list(&targets); - String8 target_full_path = target->string; - String8 target_name = str8_skip_last_slash(target_full_path); - UI_PrefHeight(ui_em(3.75f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(22.f, 1.f)) - UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_PositivePopButton) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Launch %S", target_name))) - { - rd_cmd(RD_CmdKind_LaunchAndRun, .entity = rd_handle_from_entity(target)); - } - ui_spacer(ui_em(1.5f, 1)); - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Step Into %S", target_name))) - { - rd_cmd(RD_CmdKind_LaunchAndInit, .entity = rd_handle_from_entity(target)); - } - } - }break; - - //- rjf: user has N targets. - default: - { - helper_built = 0; - }break; - } - } - - //- rjf: or text - if(helper_built) - { - UI_PrefHeight(ui_em(2.25f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_WidthFill - ui_labelf("- or -"); - } - - //- rjf: helper text for command lister activation - UI_PrefHeight(ui_em(2.25f, 1.f)) UI_Row - UI_PrefWidth(ui_text_dim(10, 1)) - UI_TextAlignment(UI_TextAlign_Center) - UI_Padding(ui_pct(1, 0)) - RD_Palette(RD_PaletteCode_Floating) - { - ui_labelf("use"); - UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_RunCommand].string); - ui_labelf("to open command menu"); - } - } - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: commands @view_hook_impl - -typedef struct RD_CmdListerItem RD_CmdListerItem; -struct RD_CmdListerItem -{ - String8 cmd_name; - U64 registrar_idx; - U64 ordering_idx; - FuzzyMatchRangeList name_match_ranges; - FuzzyMatchRangeList desc_match_ranges; - FuzzyMatchRangeList tags_match_ranges; -}; - -typedef struct RD_CmdListerItemNode RD_CmdListerItemNode; -struct RD_CmdListerItemNode -{ - RD_CmdListerItemNode *next; - RD_CmdListerItem item; -}; - -typedef struct RD_CmdListerItemList RD_CmdListerItemList; -struct RD_CmdListerItemList -{ - RD_CmdListerItemNode *first; - RD_CmdListerItemNode *last; - U64 count; -}; - -typedef struct RD_CmdListerItemArray RD_CmdListerItemArray; -struct RD_CmdListerItemArray -{ - RD_CmdListerItem *v; - U64 count; -}; - -internal RD_CmdListerItemList -rd_cmd_lister_item_list_from_needle(Arena *arena, String8 needle) -{ - Temp scratch = scratch_begin(&arena, 1); - RD_CmdListerItemList result = {0}; - // TODO(rjf): extend this with dynamically-registered command info - for EachNonZeroEnumVal(RD_CmdKind, k) - { - RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; - if(info->flags & RD_CmdKindFlag_ListInUI) - { - String8 cmd_display_name = info->display_name; - String8 cmd_desc = info->description; - String8 cmd_tags = info->search_tags; - FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, cmd_display_name); - FuzzyMatchRangeList desc_matches = fuzzy_match_find(arena, needle, cmd_desc); - FuzzyMatchRangeList tags_matches = fuzzy_match_find(arena, needle, cmd_tags); - if(name_matches.count == name_matches.needle_part_count || - desc_matches.count == name_matches.needle_part_count || - tags_matches.count > 0 || - name_matches.needle_part_count == 0) - { - RD_CmdListerItemNode *node = push_array(arena, RD_CmdListerItemNode, 1); - node->item.cmd_name = info->string; - node->item.registrar_idx = (U64)k; - node->item.ordering_idx = (U64)k; - node->item.name_match_ranges = name_matches; - node->item.desc_match_ranges = desc_matches; - node->item.tags_match_ranges = tags_matches; - SLLQueuePush(result.first, result.last, node); - result.count += 1; - } - } - } - scratch_end(scratch); - return result; -} - -internal RD_CmdListerItemArray -rd_cmd_lister_item_array_from_list(Arena *arena, RD_CmdListerItemList list) -{ - RD_CmdListerItemArray result = {0}; - result.count = list.count; - result.v = push_array(arena, RD_CmdListerItem, result.count); - U64 idx = 0; - for(RD_CmdListerItemNode *n = list.first; n != 0; n = n->next, idx += 1) - { - result.v[idx] = n->item; - } - return result; -} - -internal int -rd_qsort_compare_cmd_lister__strength(RD_CmdListerItem *a, RD_CmdListerItem *b) -{ - int result = 0; - if(a->name_match_ranges.count > b->name_match_ranges.count) - { - result = -1; - } - else if(a->name_match_ranges.count < b->name_match_ranges.count) - { - result = +1; - } - else if(a->desc_match_ranges.count > b->desc_match_ranges.count) - { - result = -1; - } - else if(a->desc_match_ranges.count < b->desc_match_ranges.count) - { - result = +1; - } - else if(a->tags_match_ranges.count > b->tags_match_ranges.count) - { - result = -1; - } - else if(a->tags_match_ranges.count < b->tags_match_ranges.count) - { - result = +1; - } - else if(a->registrar_idx < b->registrar_idx) - { - result = -1; - } - else if(a->registrar_idx > b->registrar_idx) - { - result = +1; - } - else if(a->ordering_idx < b->ordering_idx) - { - result = -1; - } - else if(a->ordering_idx > b->ordering_idx) - { - result = +1; - } - return result; -} - -internal void -rd_cmd_lister_item_array_sort_by_strength__in_place(RD_CmdListerItemArray array) -{ - quick_sort(array.v, array.count, sizeof(RD_CmdListerItem), rd_qsort_compare_cmd_lister__strength); -} - -RD_VIEW_RULE_UI_FUNCTION_DEF(commands) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - - //- rjf: grab state - typedef struct RD_CmdsViewState RD_CmdsViewState; - struct RD_CmdsViewState - { - U64 selected_cmd_hash; - }; - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_CmdsViewState *cv = rd_view_state(RD_CmdsViewState); - - //- rjf: build filtered array of commands - RD_CmdListerItemList cmd_list = rd_cmd_lister_item_list_from_needle(scratch.arena, string); - RD_CmdListerItemArray cmd_array = rd_cmd_lister_item_array_from_list(scratch.arena, cmd_list); - rd_cmd_lister_item_array_sort_by_strength__in_place(cmd_array); - - //- rjf: submit best match when hitting enter w/ no selection - if(cv->selected_cmd_hash == 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - rd_cmd(RD_CmdKind_CompleteQuery, .cmd_name = (cmd_array.count > 0 ? cmd_array.v[0].cmd_name : str8_zero())); - } - - //- rjf: selected kind -> cursor - Vec2S64 cursor = {0}; - { - for(U64 idx = 0; idx < cmd_array.count; idx += 1) - { - if(d_hash_from_string(cmd_array.v[idx].cmd_name) == cv->selected_cmd_hash) - { - cursor.y = (S64)idx+1; - break; - } - } - } - - //- rjf: build contents - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = floor_f32(ui_top_font_size()*6.5f); - scroll_list_params.dim_px = dim_2f32(rect); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, cmd_array.count)); - scroll_list_params.item_range = r1s64(0, cmd_array.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - //- rjf: build buttons - for(S64 row_idx = visible_row_range.min; - row_idx <= visible_row_range.max && row_idx < cmd_array.count; - row_idx += 1) - { - RD_CmdListerItem *item = &cmd_array.v[row_idx]; - RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(item->cmd_name); - - //- rjf: build row contents - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_child_layout_axis(Axis2_X); - UI_Box *box = &ui_nil_box; - UI_Focus(cursor.y == row_idx+1 ? UI_FocusKind_On : UI_FocusKind_Off) - { - box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects, - "###cmd_button_%S", item->cmd_name); - } - UI_Parent(box) UI_PrefHeight(ui_em(1.65f, 1.f)) - { - //- rjf: icon - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_HeightFill - UI_Column - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - UI_HeightFill - UI_TextAlignment(UI_TextAlign_Center) - { - RD_IconKind icon = info->icon_kind; - if(icon != RD_IconKind_Null) - { - ui_label(rd_icon_kind_text_table[icon]); - } - } - - //- rjf: name + description - ui_set_next_pref_height(ui_pct(1, 0)); - UI_Column UI_Padding(ui_pct(1, 0)) - { - FNT_Tag font = ui_top_font(); - F32 font_size = ui_top_font_size(); - FNT_Metrics font_metrics = fnt_metrics_from_tag_size(font, font_size); - F32 font_line_height = fnt_line_height_from_metrics(&font_metrics); - String8 cmd_display_name = info->display_name; - String8 cmd_desc = info->description; - UI_Box *name_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "%S##name_%S", cmd_display_name, info->string); - UI_Box *desc_box = &ui_nil_box; - UI_PrefHeight(ui_em(1.8f, 1.f)) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - { - desc_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "%S##desc_%S", cmd_desc, info->string); - } - ui_box_equip_fuzzy_match_ranges(name_box, &item->name_match_ranges); - ui_box_equip_fuzzy_match_ranges(desc_box, &item->desc_match_ranges); - } - - //- rjf: bindings - ui_set_next_flags(UI_BoxFlag_Clickable); - UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_NamedColumn(str8_lit("binding_column")) UI_Padding(ui_em(1.5f, 1.f)) - { - ui_set_next_flags(UI_BoxFlag_Clickable); - UI_NamedRow(str8_lit("binding_row")) UI_Padding(ui_em(1.f, 1.f)) - { - rd_cmd_binding_buttons(item->cmd_name); - } - } - } - - //- rjf: interact - UI_Signal sig = ui_signal_from_box(box); - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_CompleteQuery, .cmd_name = item->cmd_name); - } - } - } - - //- rjf: map selected num -> selected kind - if(1 <= cursor.y && cursor.y <= cmd_array.count) - { - cv->selected_cmd_hash = d_hash_from_string(cmd_array.v[cursor.y-1].cmd_name); - } - else - { - cv->selected_cmd_hash = 0; - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: file_system @view_hook_impl - -typedef enum RD_FileSortKind -{ - RD_FileSortKind_Null, - RD_FileSortKind_Filename, - RD_FileSortKind_LastModified, - RD_FileSortKind_Size, - RD_FileSortKind_COUNT -} -RD_FileSortKind; - -typedef struct RD_FileInfo RD_FileInfo; -struct RD_FileInfo -{ - String8 filename; - FileProperties props; - FuzzyMatchRangeList match_ranges; -}; - -typedef struct RD_FileInfoNode RD_FileInfoNode; -struct RD_FileInfoNode -{ - RD_FileInfoNode *next; - RD_FileInfo file_info; -}; - -typedef struct RD_FileSystemViewPathState RD_FileSystemViewPathState; -struct RD_FileSystemViewPathState -{ - RD_FileSystemViewPathState *hash_next; - String8 normalized_path; - Vec2S64 cursor; -}; - -typedef struct RD_FileSystemViewState RD_FileSystemViewState; -struct RD_FileSystemViewState -{ - B32 initialized; - U64 path_state_table_size; - RD_FileSystemViewPathState **path_state_table; - RD_FileSortKind sort_kind; - Side sort_side; - Arena *cached_files_arena; - String8 cached_files_path; - RD_FileSortKind cached_files_sort_kind; - Side cached_files_sort_side; - U64 cached_file_count; - RD_FileInfo *cached_files; - F32 col_pcts[3]; -}; - -typedef struct RD_PathQuery RD_PathQuery; -struct RD_PathQuery -{ - String8 prefix; - String8 path; - String8 search; -}; - -internal RD_PathQuery -rd_path_query_from_string(String8 string) -{ - String8 dir_str_in_input = {0}; - for(U64 i = 0; i < string.size; i += 1) - { - String8 substr1 = str8_substr(string, r1u64(i, i+1)); - String8 substr2 = str8_substr(string, r1u64(i, i+2)); - String8 substr3 = str8_substr(string, r1u64(i, i+3)); - if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(string, r1u64(i, string.size)); - } - else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(string, r1u64(i-1, string.size)); - } - else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(string, r1u64(i, string.size)); - } - else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(string, r1u64(i, string.size)); - } - if(dir_str_in_input.size != 0) - { - break; - } - } - - RD_PathQuery path_query = {0}; - if(dir_str_in_input.size != 0) - { - String8 dir = dir_str_in_input; - String8 search = {0}; - U64 one_past_last_slash = dir.size; - for(U64 i = 0; i < dir_str_in_input.size; i += 1) - { - if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') - { - one_past_last_slash = i+1; - } - } - dir.size = one_past_last_slash; - search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); - path_query.path = dir; - path_query.search = search; - path_query.prefix = str8_substr(string, r1u64(0, path_query.path.str - string.str)); - } - return path_query; -} - -internal int -rd_qsort_compare_file_info__filename(RD_FileInfo *a, RD_FileInfo *b) -{ - return strncmp((char *)a->filename.str, (char *)b->filename.str, Min(a->filename.size, b->filename.size)); -} - -internal int -rd_qsort_compare_file_info__default(RD_FileInfo *a, RD_FileInfo *b) -{ - int result = 0; - if(a->props.flags & FilePropertyFlag_IsFolder && !(b->props.flags & FilePropertyFlag_IsFolder)) - { - result = -1; - } - else if(b->props.flags & FilePropertyFlag_IsFolder && !(a->props.flags & FilePropertyFlag_IsFolder)) - { - result = +1; - } - else - { - result = rd_qsort_compare_file_info__filename(a, b); - } - return result; -} - -internal int -rd_qsort_compare_file_info__default_filtered(RD_FileInfo *a, RD_FileInfo *b) -{ - int result = 0; - if(a->filename.size < b->filename.size) - { - result = -1; - } - else if(a->filename.size > b->filename.size) - { - result = +1; - } - return result; -} - -internal int -rd_qsort_compare_file_info__last_modified(RD_FileInfo *a, RD_FileInfo *b) -{ - return ((a->props.modified < b->props.modified) ? -1 : - (a->props.modified > b->props.modified) ? +1 : - 0); -} - -internal int -rd_qsort_compare_file_info__size(RD_FileInfo *a, RD_FileInfo *b) -{ - return ((a->props.size < b->props.size) ? -1 : - (a->props.size > b->props.size) ? +1 : - 0); -} - -RD_VIEW_RULE_UI_FUNCTION_DEF(file_system) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - String8 query = string; - String8 query_normalized = path_normalized_from_string(scratch.arena, query); - B32 query_has_slash = (query.size != 0 && char_to_correct_slash(query.str[query.size-1]) == '/'); - String8 query_normalized_with_opt_slash = push_str8f(scratch.arena, "%S%s", query_normalized, query_has_slash ? "/" : ""); - RD_PathQuery path_query = rd_path_query_from_string(query_normalized_with_opt_slash); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(window->query_cmd_name); - B32 file_selection = !!(cmd_kind_info->query.flags & RD_QueryFlag_AllowFiles); - B32 dir_selection = !!(cmd_kind_info->query.flags & RD_QueryFlag_AllowFolders); - - //- rjf: get extra state for this view - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_FileSystemViewState *fs = rd_view_state(RD_FileSystemViewState); - if(fs->initialized == 0) - { - fs->initialized = 1; - fs->path_state_table_size = 256; - fs->path_state_table = push_array(rd_view_arena(), RD_FileSystemViewPathState *, fs->path_state_table_size); - fs->cached_files_arena = rd_push_view_arena(); - fs->col_pcts[0] = 0.60f; - fs->col_pcts[1] = 0.20f; - fs->col_pcts[2] = 0.20f; - } - - //- rjf: grab state for the current path - RD_FileSystemViewPathState *ps = 0; - { - String8 key = query_normalized; - U64 hash = d_hash_from_string(key); - U64 slot = hash % fs->path_state_table_size; - for(RD_FileSystemViewPathState *p = fs->path_state_table[slot]; p != 0; p = p->hash_next) - { - if(str8_match(p->normalized_path, key, 0)) - { - ps = p; - break; - } - } - if(ps == 0) - { - ps = push_array(rd_view_arena(), RD_FileSystemViewPathState, 1); - ps->hash_next = fs->path_state_table[slot]; - fs->path_state_table[slot] = ps; - ps->normalized_path = push_str8_copy(rd_view_arena(), key); - } - } - - //- rjf: get file array from the current path - U64 file_count = fs->cached_file_count; - RD_FileInfo *files = fs->cached_files; - if(!str8_match(fs->cached_files_path, query_normalized_with_opt_slash, 0) || - fs->cached_files_sort_kind != fs->sort_kind || - fs->cached_files_sort_side != fs->sort_side) - { - arena_clear(fs->cached_files_arena); - - //- rjf: store off path that we're gathering from - fs->cached_files_path = push_str8_copy(fs->cached_files_arena, query_normalized_with_opt_slash); - fs->cached_files_sort_kind = fs->sort_kind; - fs->cached_files_sort_side = fs->sort_side; - - //- rjf: use stored path as the new browse path for the whole frontend - // (multiple file system views may conflict here. that's okay. we'll just always - // choose the most recent change to a file browser path, and live with the - // consequences). - { - rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_query.path); - } - - //- rjf: get files, filtered - U64 new_file_count = 0; - RD_FileInfoNode *first_file = 0; - RD_FileInfoNode *last_file = 0; - { - OS_FileIter *it = os_file_iter_begin(scratch.arena, path_query.path, 0); - for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) - { - FuzzyMatchRangeList match_ranges = fuzzy_match_find(fs->cached_files_arena, path_query.search, info.name); - B32 fits_search = (path_query.search.size == 0 || match_ranges.count == match_ranges.needle_part_count); - B32 fits_dir_only = !!(info.props.flags & FilePropertyFlag_IsFolder) || !dir_selection; - if(fits_search && fits_dir_only) - { - RD_FileInfoNode *node = push_array(scratch.arena, RD_FileInfoNode, 1); - node->file_info.filename = push_str8_copy(fs->cached_files_arena, info.name); - node->file_info.props = info.props; - node->file_info.match_ranges = match_ranges; - SLLQueuePush(first_file, last_file, node); - new_file_count += 1; - } - } - os_file_iter_end(it); - } - - //- rjf: convert list to array - RD_FileInfo *new_files = push_array(fs->cached_files_arena, RD_FileInfo, new_file_count); - { - U64 idx = 0; - for(RD_FileInfoNode *n = first_file; n != 0; n = n->next, idx += 1) - { - new_files[idx] = n->file_info; - } - } - - //- rjf: apply sort - switch(fs->sort_kind) - { - default: - { - if(path_query.search.size != 0) - { - quick_sort(new_files, new_file_count, sizeof(RD_FileInfo), rd_qsort_compare_file_info__default_filtered); - } - else - { - quick_sort(new_files, new_file_count, sizeof(RD_FileInfo), rd_qsort_compare_file_info__default); - } - }break; - case RD_FileSortKind_Filename: - { - quick_sort(new_files, new_file_count, sizeof(RD_FileInfo), rd_qsort_compare_file_info__filename); - }break; - case RD_FileSortKind_LastModified: - { - quick_sort(new_files, new_file_count, sizeof(RD_FileInfo), rd_qsort_compare_file_info__last_modified); - }break; - case RD_FileSortKind_Size: - { - quick_sort(new_files, new_file_count, sizeof(RD_FileInfo), rd_qsort_compare_file_info__size); - }break; - } - - //- rjf: apply reverse - if(fs->sort_kind != RD_FileSortKind_Null && fs->sort_side == Side_Max) - { - for(U64 idx = 0; idx < new_file_count/2; idx += 1) - { - U64 rev_idx = new_file_count - idx - 1; - Swap(RD_FileInfo, new_files[idx], new_files[rev_idx]); - } - } - - fs->cached_file_count = file_count = new_file_count; - fs->cached_files = files = new_files; - } - - //- rjf: submit best match when hitting enter w/ no selection - if(ps->cursor.y == 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - FileProperties query_normalized_with_opt_slash_props = os_properties_from_file_path(query_normalized_with_opt_slash); - FileProperties path_query_path_props = os_properties_from_file_path(path_query.path); - - // rjf: command search part is empty, but directory matches some file: - if(path_query_path_props.created != 0 && path_query.search.size == 0) - { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query_normalized_with_opt_slash); - } - - // rjf: command argument exactly matches some file: - else if(query_normalized_with_opt_slash_props.created != 0 && path_query.search.size != 0) - { - // rjf: is a folder -> autocomplete to slash - if(query_normalized_with_opt_slash_props.flags & FilePropertyFlag_IsFolder) - { - String8 new_path = push_str8f(scratch.arena, "%S%S/", path_query.path, path_query.search); - rd_store_view_filter(new_path); - } - - // rjf: is a file -> complete view - else - { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query_normalized_with_opt_slash); - } - } - - // rjf: command argument is empty, picking folders -> use current folder - else if(path_query.search.size == 0 && dir_selection) - { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = path_query.path); - } - - // rjf: command argument does not exactly match any file, but lister results are in: - else if(file_count != 0) - { - String8 filename = files[0].filename; - if(files[0].props.flags & FilePropertyFlag_IsFolder) - { - String8 existing_path = str8_chop_last_slash(path_query.path); - String8 new_path = push_str8f(scratch.arena, "%S/%S/", existing_path, files[0].filename); - rd_store_view_filter(new_path); - } - else - { - String8 file_path = push_str8f(scratch.arena, "%S%S", path_query.path, filename); - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = file_path); - } - } - - // rjf: command argument does not match any file, and lister is empty (new file) - else - { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query); - } - } - - //- rjf: build non-scrolled table header - U64 row_num = 1; - F32 **col_pcts = push_array(scratch.arena, F32 *, ArrayCount(fs->col_pcts)); - for(U64 idx = 0; idx < ArrayCount(fs->col_pcts); idx += 1) - { - col_pcts[idx] = &fs->col_pcts[idx]; - } - UI_PrefHeight(ui_px(row_height_px, 1)) UI_Focus(UI_FocusKind_Off) UI_TableF(ArrayCount(fs->col_pcts), col_pcts, "###fs_tbl") - { - UI_TableVector - { - struct - { - RD_FileSortKind kind; - String8 string; - } - kinds[] = - { - { RD_FileSortKind_Filename, str8_lit_comp("Filename") }, - { RD_FileSortKind_LastModified, str8_lit_comp("Last Modified") }, - { RD_FileSortKind_Size, str8_lit_comp("Size") }, - }; - for(U64 idx = 0; idx < ArrayCount(kinds); idx += 1) - { - B32 sorting = (fs->sort_kind == kinds[idx].kind); - UI_TableCell UI_FlagsAdd(sorting ? 0 : UI_BoxFlag_DrawTextWeak) - { - UI_Signal sig = ui_sort_header(sorting, - fs->cached_files_sort_side == Side_Min, - kinds[idx].string); - if(ui_clicked(sig)) - { - if(fs->sort_kind != kinds[idx].kind) - { - fs->sort_kind = kinds[idx].kind; - fs->sort_side = Side_Max; - } - else if(fs->sort_kind == kinds[idx].kind && fs->sort_side == Side_Max) - { - fs->sort_side = Side_Min; - } - else if(fs->sort_kind == kinds[idx].kind && fs->sort_side == Side_Min) - { - fs->sort_kind = RD_FileSortKind_Null; - } - } - } - } - } - } - - //- rjf: build file list - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 content_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(content_dim.x, content_dim.y-row_height_px); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, file_count+1)); - scroll_list_params.item_range = r1s64(0, file_count+1); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &ps->cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - // rjf: up-one-directory button (at idx 0) - if(visible_row_range.min == 0) - { - // rjf: build - UI_Signal sig = {0}; - UI_FocusHot(ps->cursor.y == row_num ? UI_FocusKind_On : UI_FocusKind_Off) - { - sig = ui_buttonf("###up_one"); - } - - // rjf: make content - UI_Parent(sig.box) - { - // rjf: icons - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_TextAlignment(UI_TextAlign_Center) - { - ui_label(rd_icon_kind_text_table[RD_IconKind_LeftArrow]); - } - - // rjf: text - { - ui_label(str8_lit("Up One Directory")); - } - - row_num += 1; - } - - // rjf: click => up one directory - if(ui_clicked(sig)) - { - String8 new_path = str8_chop_last_slash(str8_chop_last_slash(path_query.path)); - new_path = path_normalized_from_string(scratch.arena, new_path); - String8 new_cmd = push_str8f(scratch.arena, "%S%s", new_path, new_path.size != 0 ? "/" : ""); - rd_store_view_filter(new_cmd); - } - } - - // rjf: file buttons - for(U64 row_idx = Max(visible_row_range.min, 1); - row_idx <= visible_row_range.max && row_idx <= file_count; - row_idx += 1, row_num += 1) - { - U64 file_idx = row_idx-1; - RD_FileInfo *file = &files[file_idx]; - B32 file_kb_focus = (ps->cursor.y == (row_idx+1)); - - // rjf: make button - UI_Signal file_sig = {0}; - UI_FocusHot(file_kb_focus ? UI_FocusKind_On : UI_FocusKind_Off) - { - file_sig = ui_buttonf("##%S", file->filename); - } - - // rjf: make content - UI_Parent(file_sig.box) - { - UI_PrefWidth(ui_pct(fs->col_pcts[0], 1)) UI_Row - { - // rjf: icon to signify directory - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_TextAlignment(UI_TextAlign_Center) - { - if(file->props.flags & FilePropertyFlag_IsFolder) - { - ui_label((ui_key_match(ui_hot_key(), file_sig.box->key) || file_kb_focus) - ? rd_icon_kind_text_table[RD_IconKind_FolderOpenFilled] - : rd_icon_kind_text_table[RD_IconKind_FolderClosedFilled]); - } - else - { - ui_label(rd_icon_kind_text_table[RD_IconKind_FileOutline]); - } - } - - // rjf: filename - UI_PrefWidth(ui_pct(1, 0)) - { - UI_Box *box = ui_build_box_from_string(UI_BoxFlag_DrawText|UI_BoxFlag_DisableIDString, file->filename); - ui_box_equip_fuzzy_match_ranges(box, &file->match_ranges); - } - } - - // rjf: last-modified time - UI_PrefWidth(ui_pct(fs->col_pcts[1], 1)) UI_Row - UI_PrefWidth(ui_pct(1, 0)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - { - DateTime time = date_time_from_dense_time(file->props.modified); - DateTime time_local = os_local_time_from_universal(&time); - String8 string = push_date_time_string(scratch.arena, &time_local); - ui_label(string); - } - - // rjf: file size - UI_PrefWidth(ui_pct(fs->col_pcts[2], 1)) UI_Row - UI_PrefWidth(ui_pct(1, 0)) - { - if(file->props.size != 0) - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label(str8_from_memory_size(scratch.arena, file->props.size)); - } - } - } - - // rjf: click => activate this file - if(ui_clicked(file_sig)) - { - String8 existing_path = str8_chop_last_slash(path_query.path); - String8 new_path = push_str8f(scratch.arena, "%S%s%S/", existing_path, existing_path.size != 0 ? "/" : "", file->filename); - new_path = path_normalized_from_string(scratch.arena, new_path); - if(file->props.flags & FilePropertyFlag_IsFolder) - { - String8 new_cmd = push_str8f(scratch.arena, "%S%s", new_path, new_path.size != 0 ? "/" : ""); - rd_store_view_filter(new_cmd); - } - else - { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = new_path); - } - } - } - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: system_processes @view_hook_impl - -typedef struct RD_ProcessInfo RD_ProcessInfo; -struct RD_ProcessInfo -{ - DMN_ProcessInfo info; - B32 is_attached; - FuzzyMatchRangeList attached_match_ranges; - FuzzyMatchRangeList name_match_ranges; - FuzzyMatchRangeList pid_match_ranges; -}; - -typedef struct RD_ProcessInfoNode RD_ProcessInfoNode; -struct RD_ProcessInfoNode -{ - RD_ProcessInfoNode *next; - RD_ProcessInfo info; -}; - -typedef struct RD_ProcessInfoList RD_ProcessInfoList; -struct RD_ProcessInfoList -{ - RD_ProcessInfoNode *first; - RD_ProcessInfoNode *last; - U64 count; -}; - -typedef struct RD_ProcessInfoArray RD_ProcessInfoArray; -struct RD_ProcessInfoArray -{ - RD_ProcessInfo *v; - U64 count; -}; - -internal RD_ProcessInfoList -rd_process_info_list_from_query(Arena *arena, String8 query) -{ - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: gather PIDs that we're currently attached to - U64 attached_process_count = 0; - U32 *attached_process_pids = 0; - { - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); - attached_process_count = processes.count; - attached_process_pids = push_array(scratch.arena, U32, attached_process_count); - U64 idx = 0; - for(CTRL_EntityNode *n = processes.first; n != 0; n = n->next, idx += 1) - { - CTRL_Entity *process = n->v; - attached_process_pids[idx] = process->id; - } - } - - //- rjf: build list - RD_ProcessInfoList list = {0}; - { - DMN_ProcessIter iter = {0}; - dmn_process_iter_begin(&iter); - for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) - { - // rjf: skip root-level or otherwise 0-pid processes - if(info.pid == 0) - { - continue; - } - - // rjf: determine if this process is attached - B32 is_attached = 0; - for(U64 attached_idx = 0; attached_idx < attached_process_count; attached_idx += 1) - { - if(attached_process_pids[attached_idx] == info.pid) - { - is_attached = 1; - break; - } - } - - // rjf: gather fuzzy matches - FuzzyMatchRangeList attached_match_ranges = {0}; - FuzzyMatchRangeList name_match_ranges = fuzzy_match_find(arena, query, info.name); - FuzzyMatchRangeList pid_match_ranges = fuzzy_match_find(arena, query, push_str8f(scratch.arena, "%i", info.pid)); - if(is_attached) - { - attached_match_ranges = fuzzy_match_find(arena, query, str8_lit("[attached]")); - } - - // rjf: determine if this item is filtered out - B32 matches_query = (query.size == 0 || - (attached_match_ranges.needle_part_count != 0 && attached_match_ranges.count >= attached_match_ranges.needle_part_count) || - (name_match_ranges.count != 0 && name_match_ranges.count >= name_match_ranges.needle_part_count) || - (pid_match_ranges.count != 0 && pid_match_ranges.count >= pid_match_ranges.needle_part_count)); - - // rjf: push if unfiltered - if(matches_query) - { - RD_ProcessInfoNode *n = push_array(arena, RD_ProcessInfoNode, 1); - n->info.info = info; - n->info.info.name = push_str8_copy(arena, info.name); - n->info.is_attached = is_attached; - n->info.attached_match_ranges = attached_match_ranges; - n->info.name_match_ranges = name_match_ranges; - n->info.pid_match_ranges = pid_match_ranges; - SLLQueuePush(list.first, list.last, n); - list.count += 1; - } - } - dmn_process_iter_end(&iter); - } - - scratch_end(scratch); - return list; -} - -internal RD_ProcessInfoArray -rd_process_info_array_from_list(Arena *arena, RD_ProcessInfoList list) -{ - RD_ProcessInfoArray array = {0}; - array.count = list.count; - array.v = push_array(arena, RD_ProcessInfo, array.count); - U64 idx = 0; - for(RD_ProcessInfoNode *n = list.first; n != 0; n = n->next, idx += 1) - { - array.v[idx] = n->info; - } - return array; -} - -internal int -rd_qsort_compare_process_info(RD_ProcessInfo *a, RD_ProcessInfo *b) -{ - int result = 0; - if(a->pid_match_ranges.count > b->pid_match_ranges.count) - { - result = -1; - } - else if(a->pid_match_ranges.count < b->pid_match_ranges.count) - { - result = +1; - } - else if(a->name_match_ranges.count < b->name_match_ranges.count) - { - result = -1; - } - else if(a->name_match_ranges.count > b->name_match_ranges.count) - { - result = +1; - } - else if(a->attached_match_ranges.count < b->attached_match_ranges.count) - { - result = -1; - } - else if(a->attached_match_ranges.count > b->attached_match_ranges.count) - { - result = +1; - } - return result; -} - -internal void -rd_process_info_array_sort_by_strength__in_place(RD_ProcessInfoArray array) -{ - quick_sort(array.v, array.count, sizeof(RD_ProcessInfo), rd_qsort_compare_process_info); -} - -RD_VIEW_RULE_UI_FUNCTION_DEF(system_processes) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - - //- rjf: grab state - typedef struct RD_SystemProcessesViewState RD_SystemProcessesViewState; - struct RD_SystemProcessesViewState - { - B32 initialized; - B32 need_initial_gather; - U32 selected_pid; - Arena *cached_process_arena; - String8 cached_process_arg; - RD_ProcessInfoArray cached_process_array; - }; - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_SystemProcessesViewState *sp = rd_view_state(RD_SystemProcessesViewState); - if(sp->initialized == 0) - { - sp->initialized = 1; - sp->need_initial_gather = 1; - sp->cached_process_arena = rd_push_view_arena(); - } - - //- rjf: gather list of filtered process infos - String8 query = string; - RD_ProcessInfoArray process_info_array = sp->cached_process_array; - if(sp->need_initial_gather || !str8_match(sp->cached_process_arg, query, 0)) - { - arena_clear(sp->cached_process_arena); - sp->need_initial_gather = 0; - sp->cached_process_arg = push_str8_copy(sp->cached_process_arena, query); - RD_ProcessInfoList list = rd_process_info_list_from_query(sp->cached_process_arena, query); - sp->cached_process_array = rd_process_info_array_from_list(sp->cached_process_arena, list); - process_info_array = sp->cached_process_array; - rd_process_info_array_sort_by_strength__in_place(process_info_array); - } - - //- rjf: submit best match when hitting enter w/ no selection - if(sp->selected_pid == 0 && process_info_array.count > 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - RD_ProcessInfo *info = &process_info_array.v[0]; - rd_cmd(RD_CmdKind_CompleteQuery, .pid = info->info.pid); - } - - //- rjf: selected PID -> cursor - Vec2S64 cursor = {0}; - { - for(U64 idx = 0; idx < process_info_array.count; idx += 1) - { - if(process_info_array.v[idx].info.pid == sp->selected_pid) - { - cursor.y = idx+1; - break; - } - } - } - - //- rjf: build contents - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 content_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(content_dim.x, content_dim.y); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, process_info_array.count)); - scroll_list_params.item_range = r1s64(0, process_info_array.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - //- rjf: build rows - for(U64 idx = visible_row_range.min; - idx <= visible_row_range.max && idx < process_info_array.count; - idx += 1) - { - RD_ProcessInfo *info = &process_info_array.v[idx]; - B32 is_attached = info->is_attached; - UI_Signal sig = {0}; - UI_FocusHot(cursor.y == idx+1 ? UI_FocusKind_On : UI_FocusKind_Off) - { - sig = ui_buttonf("###proc_%i", info->info.pid); - } - UI_Parent(sig.box) - { - // rjf: icon - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_TextAlignment(UI_TextAlign_Center) - { - ui_label(rd_icon_kind_text_table[RD_IconKind_Threads]); - } - - // rjf: attached indicator - if(is_attached) UI_PrefWidth(ui_text_dim(10, 1)) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - { - UI_Box *attached_label = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "[attached]##attached_label_%i", (int)info->info.pid); - ui_box_equip_fuzzy_match_ranges(attached_label, &info->attached_match_ranges); - } - - // rjf: process name - UI_PrefWidth(ui_text_dim(10, 1)) - { - UI_Box *name_label = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "%S##name_label_%i", info->info.name, (int)info->info.pid); - ui_box_equip_fuzzy_match_ranges(name_label, &info->name_match_ranges); - } - - // rjf: process number - UI_PrefWidth(ui_text_dim(1, 1)) UI_TextAlignment(UI_TextAlign_Center) UI_TextPadding(0) - { - ui_labelf("[PID: "); - UI_Box *pid_label = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "%i##pid_label", info->info.pid); - ui_box_equip_fuzzy_match_ranges(pid_label, &info->pid_match_ranges); - ui_labelf("]"); - } - } - - // rjf: click => activate this specific process - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_CompleteQuery, .pid = info->info.pid); - } - } - } - - //- rjf: selected num -> selected PID - { - if(1 <= cursor.y && cursor.y <= process_info_array.count) - { - sp->selected_pid = process_info_array.v[cursor.y-1].info.pid; - } - else - { - sp->selected_pid = 0; - } - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: entity_lister @view_hook_impl - -typedef struct RD_EntityListerItem RD_EntityListerItem; -struct RD_EntityListerItem -{ - RD_Entity *entity; - FuzzyMatchRangeList name_match_ranges; -}; - -typedef struct RD_EntityListerItemNode RD_EntityListerItemNode; -struct RD_EntityListerItemNode -{ - RD_EntityListerItemNode *next; - RD_EntityListerItem item; -}; - -typedef struct RD_EntityListerItemList RD_EntityListerItemList; -struct RD_EntityListerItemList -{ - RD_EntityListerItemNode *first; - RD_EntityListerItemNode *last; - U64 count; -}; - -typedef struct RD_EntityListerItemArray RD_EntityListerItemArray; -struct RD_EntityListerItemArray -{ - RD_EntityListerItem *v; - U64 count; -}; - -internal RD_EntityListerItemList -rd_entity_lister_item_list_from_needle(Arena *arena, RD_EntityKind kind, RD_EntityFlags omit_flags, String8 needle) -{ - Temp scratch = scratch_begin(&arena, 1); - RD_EntityListerItemList result = {0}; - RD_EntityList ent_list = rd_query_cached_entity_list_with_kind(kind); - for(RD_EntityNode *n = ent_list.first; n != 0; n = n->next) - { - RD_Entity *entity = n->entity; - if(!(entity->flags & omit_flags)) - { - DR_FancyStringList title_fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, v4f32(0, 0, 0, 0), 0); - String8 title_string = dr_string_from_fancy_string_list(scratch.arena, &title_fstrs); - FuzzyMatchRangeList match_rngs = fuzzy_match_find(arena, needle, title_string); - if(match_rngs.count != 0 || needle.size == 0) - { - RD_EntityListerItemNode *item_n = push_array(arena, RD_EntityListerItemNode, 1); - item_n->item.entity = entity; - item_n->item.name_match_ranges = match_rngs; - SLLQueuePush(result.first, result.last, item_n); - result.count += 1; - } - } - } - scratch_end(scratch); - return result; -} - -internal RD_EntityListerItemArray -rd_entity_lister_item_array_from_list(Arena *arena, RD_EntityListerItemList list) -{ - RD_EntityListerItemArray result = {0}; - result.count = list.count; - result.v = push_array(arena, RD_EntityListerItem, result.count); - { - U64 idx = 0; - for(RD_EntityListerItemNode *n = list.first; n != 0; n = n->next, idx += 1) - { - result.v[idx] = n->item; - } - } - return result; -} - -internal int -rd_qsort_compare_entity_lister__strength(RD_EntityListerItem *a, RD_EntityListerItem *b) -{ - int result = 0; - if(a->name_match_ranges.count > b->name_match_ranges.count) - { - result = -1; - } - else if(a->name_match_ranges.count < b->name_match_ranges.count) - { - result = +1; - } - return result; -} - -internal void -rd_entity_lister_item_array_sort_by_strength__in_place(RD_EntityListerItemArray array) -{ - quick_sort(array.v, array.count, sizeof(RD_EntityListerItem), rd_qsort_compare_entity_lister__strength); -} - -RD_VIEW_RULE_UI_FUNCTION_DEF(entity_lister) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(window->query_cmd_name); - RD_EntityKind entity_kind = cmd_kind_info->query.entity_kind; - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); - - //- rjf: grab state - typedef struct RD_EntityListerViewState RD_EntityListerViewState; - struct RD_EntityListerViewState - { - RD_Handle selected_entity_handle; - }; - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_EntityListerViewState *fev = rd_view_state(RD_EntityListerViewState); - RD_Handle selected_entity_handle = fev->selected_entity_handle; - RD_Entity *selected_entity = rd_entity_from_handle(selected_entity_handle); - - //- rjf: build filtered array of entities - RD_EntityListerItemList ent_list = rd_entity_lister_item_list_from_needle(scratch.arena, entity_kind, 0, string); - RD_EntityListerItemArray ent_arr = rd_entity_lister_item_array_from_list(scratch.arena, ent_list); - rd_entity_lister_item_array_sort_by_strength__in_place(ent_arr); - - //- rjf: submit best match when hitting enter w/ no selection - if(rd_entity_is_nil(rd_entity_from_handle(fev->selected_entity_handle)) && ent_arr.count != 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - RD_Entity *ent = ent_arr.v[0].entity; - rd_cmd(RD_CmdKind_CompleteQuery, .entity = rd_handle_from_entity(ent)); - } - - //- rjf: selected entity -> cursor - Vec2S64 cursor = {0}; - { - for(U64 idx = 0; idx < ent_arr.count; idx += 1) - { - if(ent_arr.v[idx].entity == selected_entity) - { - cursor.y = (S64)(idx+1); - break; - } - } - } - - //- rjf: build list - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 content_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(content_dim.x, content_dim.y); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, ent_arr.count)); - scroll_list_params.item_range = r1s64(0, ent_arr.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - for(S64 idx = visible_row_range.min; - idx <= visible_row_range.max && idx < ent_arr.count; - idx += 1) - { - RD_EntityListerItem item = ent_arr.v[idx]; - RD_Entity *ent = item.entity; - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_child_layout_axis(Axis2_X); - UI_Box *box = &ui_nil_box; - UI_FocusHot(idx+1 == cursor.y ? UI_FocusKind_On : UI_FocusKind_Off) - { - box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects, - "###ent_btn_%p", ent); - } - UI_Parent(box) UI_WidthFill UI_Padding(ui_em(1.f, 1.f)) - { - DR_FancyStringList title_fstrs = rd_title_fstrs_from_entity(scratch.arena, ent, ui_top_palette()->text_weak, ui_top_font_size()); - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(title_box, &title_fstrs); - ui_box_equip_fuzzy_match_ranges(title_box, &item.name_match_ranges); - } - if(ui_clicked(ui_signal_from_box(box))) - { - rd_cmd(RD_CmdKind_CompleteQuery, .entity = rd_handle_from_entity(ent)); - } - } - } - - //- rjf: selected entity num -> handle - { - fev->selected_entity_handle = (1 <= cursor.y && cursor.y <= ent_arr.count) ? rd_handle_from_entity(ent_arr.v[cursor.y-1].entity) : rd_handle_zero(); - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: ctrl_entity_lister @view_hook_impl - -typedef struct RD_CtrlEntityListerItem RD_CtrlEntityListerItem; -struct RD_CtrlEntityListerItem -{ - CTRL_Entity *entity; - FuzzyMatchRangeList name_match_ranges; -}; - -typedef struct RD_CtrlEntityListerItemNode RD_CtrlEntityListerItemNode; -struct RD_CtrlEntityListerItemNode -{ - RD_CtrlEntityListerItemNode *next; - RD_CtrlEntityListerItem item; -}; - -typedef struct RD_CtrlEntityListerItemList RD_CtrlEntityListerItemList; -struct RD_CtrlEntityListerItemList -{ - RD_CtrlEntityListerItemNode *first; - RD_CtrlEntityListerItemNode *last; - U64 count; -}; - -typedef struct RD_CtrlEntityListerItemArray RD_CtrlEntityListerItemArray; -struct RD_CtrlEntityListerItemArray -{ - RD_CtrlEntityListerItem *v; - U64 count; -}; - -internal RD_CtrlEntityListerItemList -rd_ctrl_entity_lister_item_list_from_needle(Arena *arena, CTRL_EntityKind kind, String8 needle) -{ - Temp scratch = scratch_begin(&arena, 1); - RD_CtrlEntityListerItemList result = {0}; - CTRL_EntityList ent_list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, kind); - for(CTRL_EntityNode *n = ent_list.first; n != 0; n = n->next) - { - CTRL_Entity *entity = n->v; - DR_FancyStringList title_fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, entity, v4f32(0, 0, 0, 0), 0, 0); - String8 title_fstrs_text = dr_string_from_fancy_string_list(scratch.arena, &title_fstrs); - FuzzyMatchRangeList match_rngs = fuzzy_match_find(arena, needle, title_fstrs_text); - if(match_rngs.count == match_rngs.needle_part_count || needle.size == 0) - { - RD_CtrlEntityListerItemNode *item_n = push_array(arena, RD_CtrlEntityListerItemNode, 1); - item_n->item.entity = entity; - item_n->item.name_match_ranges = match_rngs; - SLLQueuePush(result.first, result.last, item_n); - result.count += 1; - } - } - scratch_end(scratch); - return result; -} - -internal RD_CtrlEntityListerItemArray -rd_ctrl_entity_lister_item_array_from_list(Arena *arena, RD_CtrlEntityListerItemList list) -{ - RD_CtrlEntityListerItemArray result = {0}; - result.count = list.count; - result.v = push_array(arena, RD_CtrlEntityListerItem, result.count); - { - U64 idx = 0; - for(RD_CtrlEntityListerItemNode *n = list.first; n != 0; n = n->next, idx += 1) - { - result.v[idx] = n->item; - } - } - return result; -} - -internal int -rd_qsort_compare_ctrl_entity_lister__strength(RD_CtrlEntityListerItem *a, RD_CtrlEntityListerItem *b) -{ - int result = 0; - if(a->name_match_ranges.count > b->name_match_ranges.count) - { - result = -1; - } - else if(a->name_match_ranges.count < b->name_match_ranges.count) - { - result = +1; - } - return result; -} - -internal void -rd_ctrl_entity_lister_item_array_sort_by_strength__in_place(RD_CtrlEntityListerItemArray array) -{ - quick_sort(array.v, array.count, sizeof(RD_CtrlEntityListerItem), rd_qsort_compare_ctrl_entity_lister__strength); -} - -RD_VIEW_RULE_UI_FUNCTION_DEF(ctrl_entity_lister) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(window->query_cmd_name); - CTRL_EntityKind entity_kind = cmd_kind_info->query.ctrl_entity_kind; - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); - - //- rjf: grab state - typedef struct RD_CtrlEntityListerViewState RD_CtrlEntityListerViewState; - struct RD_CtrlEntityListerViewState - { - CTRL_Handle selected_entity_handle; - }; - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_CtrlEntityListerViewState *fev = rd_view_state(RD_CtrlEntityListerViewState); - CTRL_Handle selected_entity_handle = fev->selected_entity_handle; - CTRL_Entity *selected_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, selected_entity_handle); - - //- rjf: build filtered array of entities - RD_CtrlEntityListerItemList ent_list = rd_ctrl_entity_lister_item_list_from_needle(scratch.arena, entity_kind, string); - RD_CtrlEntityListerItemArray ent_arr = rd_ctrl_entity_lister_item_array_from_list(scratch.arena, ent_list); - rd_ctrl_entity_lister_item_array_sort_by_strength__in_place(ent_arr); - - //- rjf: submit best match when hitting enter w/ no selection - if(ctrl_entity_from_handle(d_state->ctrl_entity_store, fev->selected_entity_handle) == &ctrl_entity_nil && ent_arr.count != 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - CTRL_Entity *ent = ent_arr.v[0].entity; - RD_RegsScope() - { - switch(ent->kind) - { - default:{}break; - case CTRL_EntityKind_Machine:{rd_regs()->machine = ent->handle;}break; - case CTRL_EntityKind_Process:{rd_regs()->process = ent->handle;}break; - case CTRL_EntityKind_Thread: {rd_regs()->thread = ent->handle;}break; - case CTRL_EntityKind_Module: {rd_regs()->module = ent->handle;}break; - } - rd_cmd(RD_CmdKind_CompleteQuery, .ctrl_entity = ent->handle); - } - } - - //- rjf: selected entity -> cursor - Vec2S64 cursor = {0}; - { - for(U64 idx = 0; idx < ent_arr.count; idx += 1) - { - if(ent_arr.v[idx].entity == selected_entity) - { - cursor.y = (S64)(idx+1); - break; - } - } - } - - //- rjf: build list - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 content_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(content_dim.x, content_dim.y); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, ent_arr.count)); - scroll_list_params.item_range = r1s64(0, ent_arr.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - for(S64 idx = visible_row_range.min; - idx <= visible_row_range.max && idx < ent_arr.count; - idx += 1) - { - RD_CtrlEntityListerItem item = ent_arr.v[idx]; - CTRL_Entity *ent = item.entity; - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_child_layout_axis(Axis2_X); - UI_Box *box = &ui_nil_box; - UI_FocusHot(idx+1 == cursor.y ? UI_FocusKind_On : UI_FocusKind_Off) - { - box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects, - "###ent_btn_%p", ent); - } - UI_Parent(box) UI_WidthFill UI_Padding(ui_em(1.f, 1.f)) - { - DR_FancyStringList title_fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ent, ui_top_palette()->text_weak, ui_top_font_size(), 1); - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(title_box, &title_fstrs); - ui_box_equip_fuzzy_match_ranges(title_box, &item.name_match_ranges); - } - if(ui_clicked(ui_signal_from_box(box))) - { - RD_RegsScope() - { - switch(ent->kind) - { - default:{}break; - case CTRL_EntityKind_Machine:{rd_regs()->machine = ent->handle;}break; - case CTRL_EntityKind_Process:{rd_regs()->process = ent->handle;}break; - case CTRL_EntityKind_Thread: {rd_regs()->thread = ent->handle;}break; - case CTRL_EntityKind_Module: {rd_regs()->module = ent->handle;}break; - } - rd_cmd(RD_CmdKind_CompleteQuery, .ctrl_entity = ent->handle); - } - } - } - } - - //- rjf: selected entity num -> handle - { - fev->selected_entity_handle = (1 <= cursor.y && cursor.y <= ent_arr.count) ? (ent_arr.v[cursor.y-1].entity->handle) : ctrl_handle_zero(); - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: symbol_lister @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - DI_Scope *di_scope = di_scope_open(); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena); - DI_KeyArray dbgi_keys = di_key_array_from_list(scratch.arena, &dbgi_keys_list); - DI_SearchParams search_params = {RDI_SectionKind_Procedures, dbgi_keys}; - U64 endt_us = os_now_microseconds()+200; - - //- rjf: grab rdis - U64 rdis_count = dbgi_keys.count; - RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); - { - for(U64 idx = 0; idx < rdis_count; idx += 1) - { - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], endt_us); - RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); - rdis[idx] = rdi; - } - } - - //- rjf: grab state - typedef struct RD_SymbolListerViewState RD_SymbolListerViewState; - struct RD_SymbolListerViewState - { - Vec2S64 cursor; - }; - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_SymbolListerViewState *slv = rd_view_state(RD_SymbolListerViewState); - - //- rjf: query -> raddbg, filtered items - U128 search_key = {rd_regs()->view.u64[0], rd_regs()->view.u64[1]}; - B32 items_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, string, endt_us, &items_stale); - if(items_stale) - { - rd_request_frame(); - } - - //- rjf: submit best match when hitting enter w/ no selection - if(slv->cursor.y == 0 && items.count != 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - DI_SearchItem *item = &items.v[0]; - if(item->dbgi_idx < rdis_count) - { - RDI_Parsed *rdi = rdis[item->dbgi_idx]; - U64 rdi_procedures_count = 0; - rdi_section_raw_table_from_kind(rdi, RDI_SectionKind_Procedures, &rdi_procedures_count); - if(item->idx < rdi_procedures_count) - { - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, item->idx); - U64 name_size = 0; - U8 *name_base = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 name = str8(name_base, name_size); - if(name.size != 0) - { - rd_cmd(RD_CmdKind_CompleteQuery, .string = name); - } - } - } - } - - //- rjf: build contents - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 content_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(content_dim.x, content_dim.y); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, items.count)); - scroll_list_params.item_range = r1s64(0, items.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &slv->cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - UI_TextRasterFlags(rd_raster_flags_from_slot(RD_FontSlot_Code)) - { - //- rjf: build rows - for(U64 idx = visible_row_range.min; - idx <= visible_row_range.max && idx < items.count; - idx += 1) - UI_Focus((slv->cursor.y == idx+1) ? UI_FocusKind_On : UI_FocusKind_Off) - { - DI_SearchItem *item = &items.v[idx]; - if(item->dbgi_idx >= rdis_count) {continue;} - DI_Key dbgi_key = dbgi_keys.v[item->dbgi_idx]; - RDI_Parsed *rdi = rdis[item->dbgi_idx]; - - //- rjf: unpack this item's info - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, item->idx); - U64 name_size = 0; - U8 *name_base = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 name = str8(name_base, name_size); - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, procedure->type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), procedure->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); - - //- rjf: build item button - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawText| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects, - "###procedure_%I64x", item->idx); - UI_Parent(box) UI_PrefWidth(ui_text_dim(10, 1)) RD_Font(RD_FontSlot_Code) - { - UI_Box *box = rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); - ui_box_equip_fuzzy_match_ranges(box, &item->match_ranges); - if(!e_type_key_match(e_type_key_zero(), type_key)) - { - String8 type_string = e_type_string_from_key(scratch.arena, type_key); - rd_code_label(0.5f, 0, rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), type_string); - } - } - - //- rjf: interact - UI_Signal sig = ui_signal_from_box(box); - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_CompleteQuery, .string = name); - } - if(ui_hovering(sig)) UI_Tooltip - { - RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); - RD_Font(RD_FontSlot_Main) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_labelf("Procedure #%I64u", idx); - U64 binary_voff = d_voff_from_dbgi_key_symbol_name(&dbgi_key, name); - D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, binary_voff); - if(lines.first != 0 && lines.first->v.file_path.size != 0 && lines.first->v.pt.line != 0) - { - String8 file_path = lines.first->v.file_path; - S64 line_num = lines.first->v.pt.line; - RD_Font(RD_FontSlot_Main) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_labelf("%S:%I64d", file_path, line_num); - } - else - { - RD_Font(RD_FontSlot_Main) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_label(str8_lit("(No source code location found)")); - } - } - } - } - - rd_store_view_scroll_pos(scroll_pos); - di_scope_close(di_scope); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: targets @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(targets) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); - } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:targets"), str8_lit("only: label exe args working_directory entry_point stdout_path stderr_path stdin_path debug_subprocesses b32 str"), 1, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: file_path_map @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(file_path_map) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); - } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:file_path_maps"), str8_lit("only: source_path destination_path str"), 1, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: auto_view_rules @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(auto_view_rules) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); - } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:auto_view_rules"), str8_lit("only: type view_rule str"), 1, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: breakpoints @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(breakpoints) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); - } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:breakpoints"), str8_lit("only: label condition str hit_count source_location address_location function_location"), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: watch_pins @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(watch_pins) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); - } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:watch_pins"), str8_lit("only: label source_location address_location str"), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: scheduler @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(scheduler) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); - } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:machines"), str8_lit("only: label str id callstack v count vaddr inline_depth"), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: call_stack @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(call_stack) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_CallStackFrameSelection, 0.05f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_CallStackFrame, 0.50f, .display_string = str8_lit("Symbol"), .dequote_string = 1); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Member, 0.20f, .string = str8_lit("vaddr"), .display_string = str8_lit("Address"), .view_rule = str8_lit("cast:U64")); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Module, 0.25f, .string = str8_lit("module.str"), .display_string = str8_lit("Module"), .dequote_string = 1, .is_non_code = 1); - } - rd_watch_view_build(wv, 0, str8_lit("thread:current_thread.callstack.v"), str8_lit("array:'thread:current_thread.callstack.count', hex"), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: modules @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(modules) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); - } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:modules"), str8_lit("only: exe dbg str vaddr_range min max"), 0, 16, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: watch @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(watch) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, 0, str8_lit("collection:watches"), str8_lit(""), 1, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: locals @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(locals) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, 0, str8_lit("collection:locals"), str8_lit(""), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: registers @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(registers) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, 0, str8_lit("collection:registers"), str8_lit("hex"), 0, 16, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: globals @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(globals) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, 0, str8_lit("collection:globals"), str8_lit(""), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: thread_locals @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(thread_locals) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, 0, str8_lit("collection:thread_locals"), str8_lit(""), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: types @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(types) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, 0, str8_lit("collection:types"), str8_lit(""), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: procedures @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(procedures) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.2f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.6f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.2f); - } - rd_watch_view_build(wv, 0, str8_lit("collection:procedures"), str8_lit(""), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: pending_file @view_hook_impl - -typedef struct RD_PendingFileViewState RD_PendingFileViewState; -struct RD_PendingFileViewState -{ - Arena *deferred_cmd_arena; - RD_CmdList deferred_cmds; -}; - -RD_VIEW_RULE_UI_FUNCTION_DEF(pending_file) -{ - Temp scratch = scratch_begin(0, 0); - RD_PendingFileViewState *pves = rd_view_state(RD_PendingFileViewState); - if(pves->deferred_cmd_arena == 0) - { - pves->deferred_cmd_arena = rd_push_view_arena(); - } - rd_store_view_loading_info(1, 0, 0); - - ////////////////////////////// - //- rjf: process commands - // - for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) - { - // rjf: mismatched window/panel => skip - if(!rd_handle_match(rd_regs()->view, cmd->regs->view)) - { - continue; - } - - // rjf: process - RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); - switch(kind) - { - default:break; - - // rjf: gather deferred commands to redispatch when entity is ready - case RD_CmdKind_GoToLine: - case RD_CmdKind_GoToAddress: - case RD_CmdKind_CenterCursor: - case RD_CmdKind_ContainCursor: - { - rd_cmd_list_push_new(pves->deferred_cmd_arena, &pves->deferred_cmds, cmd->name, cmd->regs); - }break; - } - } - - //- rjf: determine if file is ready, and which viewer to use - String8 expr_string = rd_view_expr_string(); - String8 file_path = rd_file_path_from_eval_string(scratch.arena, expr_string); - Rng1U64 file_range = r1u64(0, 1024); - U128 file_hash = fs_hash_from_path_range(file_path, file_range, 0); - B32 file_is_ready = 0; - RD_ViewRuleKind viewer_kind = RD_ViewRuleKind_Text; - { - HS_Scope *hs_scope = hs_scope_open(); - String8 data = hs_data_from_hash(hs_scope, file_hash); - if(!u128_match(file_hash, u128_zero())) - { - U64 num_utf8_bytes = 0; - U64 num_unknown_bytes = 0; - for(U64 idx = 0; idx < data.size && idx < file_range.max;) - { - UnicodeDecode decode = utf8_decode(data.str+idx, data.size-idx); - if(decode.codepoint != max_U32 && (decode.inc > 1 || - (10 <= decode.codepoint && decode.codepoint <= 13) || - (32 <= decode.codepoint && decode.codepoint <= 126))) - { - num_utf8_bytes += decode.inc; - idx += decode.inc; - } - else - { - num_unknown_bytes += 1; - idx += 1; - } - } - file_is_ready = 1; - if(num_utf8_bytes > num_unknown_bytes*4 || num_unknown_bytes == 0) - { - viewer_kind = RD_ViewRuleKind_Text; - } - else - { - viewer_kind = RD_ViewRuleKind_Memory; - } - } - hs_scope_close(hs_scope); - } - - //- rjf: if file is ready, dispatch all deferred commands - if(file_is_ready) - { - for(RD_CmdNode *cmd_node = pves->deferred_cmds.first; cmd_node != 0; cmd_node = cmd_node->next) - { - RD_Cmd *cmd = &cmd_node->cmd; - rd_push_cmd(cmd->name, cmd->regs); - } - arena_clear(pves->deferred_cmd_arena); - MemoryZeroStruct(&pves->deferred_cmds); - } - - //- rjf: if file is ready, move params tree to scratch for new command - MD_Node *params_copy = &md_nil_node; - if(file_is_ready) - { - params_copy = md_tree_copy(scratch.arena, params); - } - - //- rjf: if file is ready, replace this view with the correct one, if any viewer is specified - if(file_is_ready && viewer_kind != RD_ViewRuleKind_Null) - { - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_kind(viewer_kind); - String8 query = rd_eval_string_from_file_path(scratch.arena, file_path); - RD_View *view = rd_view_from_handle(rd_regs()->view); - rd_view_equip_spec(view, view_rule_info, query, params_copy); - } - - //- rjf: if entity is ready, but we have no viewer for it, then just close this tab - if(file_is_ready && viewer_kind == RD_ViewRuleKind_Null) - { - rd_cmd(RD_CmdKind_CloseTab); - } - - scratch_end(scratch); -} +RD_VIEW_UI_FUNCTION_DEF(null) {} //////////////////////////////// //~ rjf: text @view_hook_impl -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(text) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(text) { EV_ExpandInfo info = {0}; info.row_count = 8; @@ -5804,7 +1684,7 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(text) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(text) +RD_VIEW_UI_FUNCTION_DEF(text) { RD_CodeViewState *cv = rd_view_state(RD_CodeViewState); rd_code_view_init(cv); @@ -5822,15 +1702,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: process code-file commands // - for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) + ProfScope("process code-file commands") for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) { - // rjf: mismatched window/panel => skip - if(!rd_handle_match(rd_regs()->view, cmd->regs->view)) - { - continue; - } - - // rjf: process RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); switch(kind) { @@ -5839,7 +1712,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) // rjf: override file picking case RD_CmdKind_PickFile: { - String8 src = rd_file_path_from_eval_string(scratch.arena, rd_view_expr_string()); + String8 src = rd_regs()->file_path; String8 dst = cmd->regs->file_path; if(src.size != 0 && dst.size != 0) { @@ -5856,43 +1729,43 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: unpack parameterization info // - String8 path = rd_file_path_from_eval_string(rd_frame_arena(), string); - rd_regs()->file_path = path; + ProfBegin("unpack parameterization info"); + rd_regs()->file_path = rd_file_path_from_eval(rd_frame_arena(), eval); rd_regs()->vaddr = 0; rd_regs()->prefer_disasm = 0; - rd_regs()->cursor.line = rd_value_from_params_key(params, str8_lit("cursor_line")).s64; - rd_regs()->cursor.column = rd_value_from_params_key(params, str8_lit("cursor_column")).s64; - rd_regs()->mark.line = rd_value_from_params_key(params, str8_lit("mark_line")).s64; - rd_regs()->mark.column = rd_value_from_params_key(params, str8_lit("mark_column")).s64; + rd_regs()->cursor.line = rd_view_cfg_value_from_string(str8_lit("cursor_line")).s64; + rd_regs()->cursor.column = rd_view_cfg_value_from_string(str8_lit("cursor_column")).s64; + rd_regs()->mark.line = rd_view_cfg_value_from_string(str8_lit("mark_line")).s64; + rd_regs()->mark.column = rd_view_cfg_value_from_string(str8_lit("mark_column")).s64; if(rd_regs()->cursor.line == 0) { rd_regs()->cursor.line = 1; } if(rd_regs()->cursor.column == 0) { rd_regs()->cursor.column = 1; } - if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } - if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } - E_Eval eval = e_eval_from_string(scratch.arena, string); - Rng1U64 range = rd_range_from_eval_params(eval, params); + if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } + if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } + Rng1U64 range = rd_range_from_eval_tag(eval, tag); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); - rd_regs()->lang_kind = rd_lang_kind_from_eval_params(eval, params); + rd_regs()->lang_kind = rd_lang_kind_from_eval_tag(eval, tag); U128 hash = {0}; TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, rd_regs()->text_key, rd_regs()->lang_kind, &hash); String8 data = hs_data_from_hash(hs_scope, hash); - B32 file_is_missing = (path.size != 0 && os_properties_from_file_path(path).modified == 0); + B32 file_is_missing = (rd_regs()->file_path.size != 0 && os_properties_from_file_path(rd_regs()->file_path).modified == 0); B32 key_has_data = !u128_match(hash, u128_zero()) && info.lines_count; + ProfEnd(); ////////////////////////////// //- rjf: build missing file interface // - if(file_is_missing && !u128_match(hash, u128_zero())) + if(file_is_missing) { UI_WidthFill UI_HeightFill UI_Column UI_Padding(ui_pct(1, 0)) { Temp scratch = scratch_begin(0, 0); UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_em(3, 1)) UI_Row UI_Padding(ui_pct(1, 0)) - UI_PrefWidth(ui_text_dim(10, 1)) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) + UI_PrefWidth(ui_text_dim(1, 1)) + UI_TagF("weak") { RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); - ui_labelf("Could not find \"%S\".", path); + ui_labelf("Could not find \"%S\".", rd_regs()->file_path); } UI_PrefHeight(ui_em(3, 1)) UI_Row UI_Padding(ui_pct(1, 0)) @@ -5900,8 +1773,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) UI_CornerRadius(ui_top_font_size()/3) UI_PrefWidth(ui_text_dim(10, 1)) UI_Focus(UI_FocusKind_On) - RD_Palette(RD_PaletteCode_NeutralPopButton) UI_TextAlignment(UI_TextAlign_Center) + UI_TagF("pop") if(ui_clicked(ui_buttonf("Find alternative..."))) { rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_PickFile].string); @@ -5924,18 +1797,23 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) DI_KeyList dbgi_keys = {0}; if(!file_is_missing) { - RD_CodeViewBuildResult result = rd_code_view_build(scratch.arena, cv, RD_CodeViewBuildFlag_All, code_area_rect, data, &info, 0, r1u64(0, 0), di_key_zero()); + RD_CodeViewBuildFlags flags = RD_CodeViewBuildFlag_All; + if(rd_regs()->file_path.size == 0) + { + flags &= ~RD_CodeViewBuildFlag_Margins; + } + RD_CodeViewBuildResult result = rd_code_view_build(scratch.arena, cv, flags, code_area_rect, data, &info, 0, r1u64(0, 0), di_key_zero()); dbgi_keys = result.dbgi_keys; } ////////////////////////////// //- rjf: unpack cursor info // - if(path.size != 0) + if(rd_regs()->file_path.size != 0) { CTRL_Entity *module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - rd_regs()->lines = d_lines_from_dbgi_key_file_path_line_num(rd_frame_arena(), dbgi_key, path, rd_regs()->cursor.line); + rd_regs()->lines = d_lines_from_dbgi_key_file_path_line_num(rd_frame_arena(), dbgi_key, rd_regs()->file_path, rd_regs()->cursor.line); } ////////////////////////////// @@ -5944,7 +1822,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) B32 file_is_out_of_date = 0; String8 out_of_date_dbgi_name = {0}; { - U64 file_timestamp = fs_timestamp_from_path(path); + U64 file_timestamp = fs_properties_from_path(rd_regs()->file_path).modified; if(file_timestamp != 0) { for(DI_KeyNode *n = dbgi_keys.first; n != 0; n = n->next) @@ -5967,22 +1845,15 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) { ui_set_next_rect(shift_2f32(bottom_bar_rect, scale_2f32(rect.p0, -1.f))); ui_set_next_flags(UI_BoxFlag_DrawBackground); - UI_Palette *palette = ui_top_palette(); - if(file_is_out_of_date) - { - palette = rd_palette_from_code(RD_PaletteCode_NegativePopButton); - } - UI_Palette(palette) - UI_Row + UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_text_dim(10, 1)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") { - if(file_is_out_of_date) + if(file_is_out_of_date) UI_TagF("bad_pop") { UI_Box *box = &ui_nil_box; - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) - RD_Font(RD_FontSlot_Icons) + RD_Font(RD_FontSlot_Icons) { box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_Clickable, "%S###file_ood_warning", rd_icon_kind_text_table[RD_IconKind_WarningBig]); } @@ -5992,16 +1863,16 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) { ui_labelf("This file has changed since ", out_of_date_dbgi_name); - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNeutral))) ui_label(out_of_date_dbgi_name); + ui_label(out_of_date_dbgi_name); ui_labelf(" was produced."); } } } RD_Font(RD_FontSlot_Code) { - if(path.size != 0) + if(rd_regs()->file_path.size != 0) { - ui_label(path); + ui_label(rd_regs()->file_path); ui_spacer(ui_em(1.5f, 1)); } ui_labelf("Line: %I64d, Column: %I64d", rd_regs()->cursor.line, rd_regs()->cursor.column); @@ -6037,7 +1908,6 @@ struct RD_DisasmViewState B32 initialized; TxtPt cursor; TxtPt mark; - DASM_StyleFlags style_flags; CTRL_Handle temp_look_process; U64 temp_look_vaddr; U64 temp_look_run_gen; @@ -6045,7 +1915,7 @@ struct RD_DisasmViewState RD_CodeViewState cv; }; -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(disasm) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(disasm) { EV_ExpandInfo info = {0}; info.row_count = 8; @@ -6053,7 +1923,7 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(disasm) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) +RD_VIEW_UI_FUNCTION_DEF(disasm) { RD_DisasmViewState *dv = rd_view_state(RD_DisasmViewState); if(dv->initialized == 0) @@ -6061,7 +1931,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) dv->initialized = 1; dv->cursor = txt_pt(1, 1); dv->mark = txt_pt(1, 1); - dv->style_flags = DASM_StyleFlag_Addresses|DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines|DASM_StyleFlag_SymbolNames; rd_code_view_init(&dv->cv); } RD_CodeViewState *cv = &dv->cv; @@ -6078,19 +1947,19 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) // B32 auto_selected = 0; E_Space auto_space = {0}; - if(string.size == 0) + if(eval.exprs.last == &e_expr_nil) { if(dv->temp_look_vaddr != 0 && dv->temp_look_run_gen == ctrl_run_gen()) { auto_selected = 1; auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, dv->temp_look_process), RD_EvalSpaceKind_CtrlEntity); - string = push_str8f(scratch.arena, "(0x%I64x & (~(0x4000 - 1)))", dv->temp_look_vaddr); + eval = e_eval_from_stringf(scratch.arena, "(0x%I64x & (~(0x4000 - 1)))", dv->temp_look_vaddr); } else { auto_selected = 1; auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); - string = str8_lit("(rip.u64 & (~(0x4000 - 1)))"); + eval = e_eval_from_stringf(scratch.arena, "(rip.u64 & (~(0x4000 - 1)))"); } } @@ -6107,15 +1976,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) ////////////////////////////// //- rjf: process disassembly-specific commands // - for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) { - // rjf: mismatched window/panel => skip - if(!rd_handle_match(rd_regs()->view, cmd->regs->view)) - { - continue; - } - - // rjf: process RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); switch(kind) { @@ -6127,22 +1989,19 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) dv->temp_look_run_gen = ctrl_run_gen(); dv->goto_vaddr = cmd->regs->vaddr; }break; - case RD_CmdKind_ToggleCodeBytesVisibility: {dv->style_flags ^= DASM_StyleFlag_CodeBytes;}break; - case RD_CmdKind_ToggleAddressVisibility: {dv->style_flags ^= DASM_StyleFlag_Addresses;}break; } } ////////////////////////////// //- rjf: unpack parameterization info // - E_Eval eval = e_eval_from_string(scratch.arena, string); E_Space space = eval.space; if(auto_selected) { space = auto_space; } - Rng1U64 range = rd_range_from_eval_params(eval, params); - Arch arch = rd_arch_from_eval_params(eval, params); + Rng1U64 range = rd_range_from_eval_tag(eval, tag); + Arch arch = rd_arch_from_eval_tag(eval, tag); CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(space); CTRL_Entity *dasm_module = &ctrl_entity_nil; DI_Key dbgi_key = {0}; @@ -6158,14 +2017,35 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) base_vaddr = dasm_module->vaddr_range.min; }break; } + DASM_StyleFlags style_flags = 0; + DASM_Syntax syntax = DASM_Syntax_Intel; + { + if(rd_setting_b32_from_name(str8_lit("show_addresses"))) + { + style_flags |= DASM_StyleFlag_Addresses; + } + if(rd_setting_b32_from_name(str8_lit("show_code_bytes"))) + { + style_flags |= DASM_StyleFlag_CodeBytes; + } + if(rd_setting_b32_from_name(str8_lit("show_source_lines"))) + { + style_flags |= DASM_StyleFlag_SourceFilesNames; + style_flags |= DASM_StyleFlag_SourceLines; + } + if(rd_setting_b32_from_name(str8_lit("show_symbol_names"))) + { + style_flags |= DASM_StyleFlag_SymbolNames; + } + } U128 dasm_key = rd_key_from_eval_space_range(space, range, 0); U128 dasm_data_hash = {0}; DASM_Params dasm_params = {0}; { dasm_params.vaddr = range.min; dasm_params.arch = arch; - dasm_params.style_flags = dv->style_flags; - dasm_params.syntax = DASM_Syntax_Intel; + dasm_params.style_flags = style_flags; + dasm_params.syntax = syntax; dasm_params.base_vaddr = base_vaddr; dasm_params.dbgi_key = dbgi_key; } @@ -6232,7 +2112,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_text_dim(10, 1)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") RD_Font(RD_FontSlot_Code) { U64 cursor_vaddr = (1 <= rd_regs()->cursor.line && rd_regs()->cursor.line <= dasm_info.lines.count) ? (range.min+dasm_info.lines.v[rd_regs()->cursor.line-1].code_off) : 0; @@ -6260,107 +2140,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) scratch_end(scratch); } -//////////////////////////////// -//~ rjf: output @view_hook_impl - -typedef struct RD_OutputViewState RD_OutputViewState; -struct RD_OutputViewState -{ - U128 last_hash; - RD_CodeViewState cv; -}; - -RD_VIEW_RULE_UI_FUNCTION_DEF(output) -{ - RD_OutputViewState *ov = rd_view_state(RD_OutputViewState); - RD_CodeViewState *cv = &ov->cv; - rd_code_view_init(cv); - Temp scratch = scratch_begin(0, 0); - HS_Scope *hs_scope = hs_scope_open(); - TXT_Scope *txt_scope = txt_scope_open(); - - ////////////////////////////// - //- rjf: set up invariants - // - F32 bottom_bar_height = ui_top_font_size()*2.f; - Rng2F32 code_area_rect = r2f32p(rect.x0, rect.y0, rect.x1, rect.y1 - bottom_bar_height); - Rng2F32 bottom_bar_rect = r2f32p(rect.x0, rect.y1 - bottom_bar_height, rect.x1, rect.y1); - - ////////////////////////////// - //- rjf: unpack parameterization info - // - rd_regs()->file_path = str8_zero(); - rd_regs()->vaddr = 0; - rd_regs()->cursor.line = rd_value_from_params_key(params, str8_lit("cursor_line")).s64; - rd_regs()->cursor.column = rd_value_from_params_key(params, str8_lit("cursor_column")).s64; - rd_regs()->mark.line = rd_value_from_params_key(params, str8_lit("mark_line")).s64; - rd_regs()->mark.column = rd_value_from_params_key(params, str8_lit("mark_column")).s64; - - ////////////////////////////// - //- rjf: unpack text info - // - U128 key = d_state->output_log_key; - TXT_LangKind lang_kind = TXT_LangKind_Null; - U128 hash = {0}; - TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash); - String8 data = hs_data_from_hash(hs_scope, hash); - Rng1U64 empty_range = {0}; - if(info.lines_count == 0) - { - info.lines_count = 1; - info.lines_ranges = &empty_range; - } - - ////////////////////////////// - //- rjf: scroll-to-bottom - // - if(!u128_match(hash, ov->last_hash)) - { - ov->last_hash = hash; - cv->goto_line_num = info.lines_count; - cv->contain_cursor= 1; - } - - ////////////////////////////// - //- rjf: build code contents - // - { - rd_code_view_build(scratch.arena, cv, 0, code_area_rect, data, &info, 0, r1u64(0, 0), di_key_zero()); - } - - ////////////////////////////// - //- rjf: build bottom bar - // - { - ui_set_next_rect(shift_2f32(bottom_bar_rect, scale_2f32(rect.p0, -1.f))); - ui_set_next_flags(UI_BoxFlag_DrawBackground); - UI_Row - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_text_dim(10, 1)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - RD_Font(RD_FontSlot_Code) - { - ui_labelf("(Debug String Output)"); - ui_spacer(ui_em(1.5f, 1)); - ui_labelf("Line: %I64d, Column: %I64d", rd_regs()->cursor.line, rd_regs()->cursor.column); - ui_spacer(ui_pct(1, 0)); - ui_labelf("(read only)"); - } - } - - ////////////////////////////// - //- rjf: store params - // - rd_store_view_param_s64(str8_lit("cursor_line"), rd_regs()->cursor.line); - rd_store_view_param_s64(str8_lit("cursor_column"), rd_regs()->cursor.column); - rd_store_view_param_s64(str8_lit("mark_line"), rd_regs()->mark.line); - rd_store_view_param_s64(str8_lit("mark_column"), rd_regs()->mark.column); - - txt_scope_close(txt_scope); - hs_scope_close(hs_scope); - scratch_end(scratch); -} - //////////////////////////////// //~ rjf: memory @view_hook_impl @@ -6371,7 +2150,7 @@ struct RD_MemoryViewState B32 contain_cursor; }; -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(memory) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(memory) { EV_ExpandInfo info = {0}; info.row_count = 16; @@ -6379,7 +2158,7 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(memory) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(memory) +RD_VIEW_UI_FUNCTION_DEF(memory) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); @@ -6389,8 +2168,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) ////////////////////////////// //- rjf: unpack parameterization info // - E_Eval eval = e_eval_from_string(scratch.arena, string); - Rng1U64 space_range = rd_range_from_eval_params(eval, params); + Rng1U64 space_range = rd_range_from_eval_tag(eval, tag); if(eval.space.kind == 0) { eval.space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); @@ -6400,10 +2178,10 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) { space_range = r1u64(0, 0x7FFFFFFFFFFFull); } - U64 cursor = rd_value_from_params_key(params, str8_lit("cursor_vaddr")).u64; - U64 mark = rd_value_from_params_key(params, str8_lit("mark_vaddr")).u64; - U64 bytes_per_cell = rd_value_from_params_key(params, str8_lit("bytes_per_cell")).u64; - U64 num_columns = rd_value_from_params_key(params, str8_lit("num_columns")).u64; + U64 cursor = rd_view_cfg_value_from_string(str8_lit("cursor_vaddr")).u64; + U64 mark = rd_view_cfg_value_from_string(str8_lit("mark_vaddr")).u64; + U64 bytes_per_cell = rd_view_cfg_value_from_string(str8_lit("bytes_per_cell")).u64; + U64 num_columns = rd_view_cfg_value_from_string(str8_lit("num_columns")).u64; if(num_columns == 0) { num_columns = 16; @@ -6411,19 +2189,14 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) num_columns = ClampBot(1, num_columns); bytes_per_cell = ClampBot(1, bytes_per_cell); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); + Vec4F32 selection_color = ui_color_from_name(str8_lit("selection")); + Vec4F32 border_color = ui_color_from_name(str8_lit("border")); ////////////////////////////// //- rjf: process commands // - for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) { - // rjf: mismatched window/panel => skip - if(!rd_handle_match(rd_regs()->view, cmd->regs->view)) - { - continue; - } - - // rjf: process RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); switch(kind) { @@ -6452,6 +2225,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) //- rjf: unpack visual params // FNT_Tag font = rd_font_from_slot(RD_FontSlot_Code); + FNT_RasterFlags font_raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code); F32 font_size = rd_font_size_from_slot(RD_FontSlot_Code); F32 big_glyph_advance = fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("H")).x; F32 row_height_px = floor_f32(font_size*2.f); @@ -6612,11 +2386,12 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) ////////////////////////////// //- rjf: produce fancy string runs for all possible byte values in all cells // - DR_FancyStringList byte_fancy_strings[256] = {0}; + DR_FStrList byte_fstrs[256] = {0}; { - Vec4F32 full_color = rd_rgba_from_theme_color(RD_ThemeColor_TextPositive); - Vec4F32 zero_color = rd_rgba_from_theme_color(RD_ThemeColor_TextWeak); - for(U64 idx = 0; idx < ArrayCount(byte_fancy_strings); idx += 1) + Vec4F32 full_color = ui_color_from_name(str8_lit("text")); + Vec4F32 zero_color = full_color; + UI_TagF("weak") zero_color = ui_color_from_name(str8_lit("text")); + for(U64 idx = 0; idx < ArrayCount(byte_fstrs); idx += 1) { U8 byte = (U8)idx; F32 pct = (byte/255.f); @@ -6625,8 +2400,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) { text_color.w *= 0.5f; } - DR_FancyString fstr = {font, push_str8f(scratch.arena, "%02x", byte), text_color, font_size, 0, 0}; - dr_fancy_string_list_push(scratch.arena, &byte_fancy_strings[idx], &fstr); + DR_FStr fstr = {push_str8f(scratch.arena, "%02x", byte), {font, font_raster_flags, text_color, font_size, 0, 0}}; + dr_fstrs_push(scratch.arena, &byte_fstrs[idx], &fstr); } } @@ -6665,7 +2440,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread); //- rjf: fill unwind frame annotations - if(unwind.frames.count != 0) + if(unwind.frames.count != 0) UI_Tag(str8_lit("weak")) { U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, unwind.frames.v[0].regs); for(U64 idx = 1; idx < unwind.frames.count; idx += 1) @@ -6681,11 +2456,11 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) CTRL_Entity *module = ctrl_module_from_process_vaddr(process, f_rip); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); U64 rip_voff = ctrl_voff_from_vaddr(module, f_rip); - String8 symbol_name = d_symbol_name_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff, 1); + String8 symbol_name = d_symbol_name_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff, 0, 1); Annotation *annotation = push_array(scratch.arena, Annotation, 1); annotation->name_string = symbol_name.size != 0 ? symbol_name : str8_lit("[external code]"); annotation->kind_string = str8_lit("Call Stack Frame"); - annotation->color = symbol_name.size != 0 ? rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol) : rd_rgba_from_theme_color(RD_ThemeColor_TextWeak); + annotation->color = symbol_name.size != 0 ? ui_color_from_name(str8_lit("code_symbol")) : ui_color_from_name(str8_lit("text")); annotation->vaddr_range = frame_vaddr_range; for(U64 vaddr = frame_vaddr_range_in_viz.min; vaddr < frame_vaddr_range_in_viz.max; vaddr += 1) { @@ -6708,7 +2483,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) Annotation *annotation = push_array(scratch.arena, Annotation, 1); annotation->name_string = thread->string.size ? thread->string : push_str8f(scratch.arena, "TID: %I64u", thread->id); annotation->kind_string = str8_lit("Stack"); - annotation->color = rd_rgba_from_ctrl_entity(thread); + annotation->color = rd_color_from_ctrl_entity(thread); annotation->vaddr_range = stack_vaddr_range; for(U64 vaddr = stack_vaddr_range_in_viz.min; vaddr < stack_vaddr_range_in_viz.max; vaddr += 1) { @@ -6723,24 +2498,17 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) DI_Scope *scope = di_scope_open(); Vec4F32 color_gen_table[] = { - rd_rgba_from_theme_color(RD_ThemeColor_Thread0), - rd_rgba_from_theme_color(RD_ThemeColor_Thread1), - rd_rgba_from_theme_color(RD_ThemeColor_Thread2), - rd_rgba_from_theme_color(RD_ThemeColor_Thread3), - rd_rgba_from_theme_color(RD_ThemeColor_Thread4), - rd_rgba_from_theme_color(RD_ThemeColor_Thread5), - rd_rgba_from_theme_color(RD_ThemeColor_Thread6), - rd_rgba_from_theme_color(RD_ThemeColor_Thread7), + ui_color_from_name(str8_lit("code_local")), }; U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_regs()->unwind_count); - for(E_String2NumMapNode *n = e_parse_ctx->locals_map->first; n != 0; n = n->order_next) + for(E_String2NumMapNode *n = e_parse_state->ctx->locals_map->first; n != 0; n = n->order_next) { String8 local_name = n->string; E_Eval local_eval = e_eval_from_string(scratch.arena, local_name); - if(local_eval.mode == E_Mode_Offset) + if(local_eval.irtree.mode == E_Mode_Offset) { - E_TypeKind local_eval_type_kind = e_type_kind_from_key(local_eval.type_key); - U64 local_eval_type_size = e_type_byte_size_from_key(local_eval.type_key); + E_TypeKind local_eval_type_kind = e_type_kind_from_key(local_eval.irtree.type_key); + U64 local_eval_type_size = e_type_byte_size_from_key(local_eval.irtree.type_key); Rng1U64 vaddr_rng = r1u64(local_eval.value.u64, local_eval.value.u64+local_eval_type_size); Rng1U64 vaddr_rng_in_visible = intersect_1u64(viz_range_bytes, vaddr_rng); if(vaddr_rng_in_visible.max != vaddr_rng_in_visible.min) @@ -6749,7 +2517,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) { annotation->name_string = push_str8_copy(scratch.arena, local_name); annotation->kind_string = str8_lit("Local"); - annotation->type_string = e_type_string_from_key(scratch.arena, local_eval.type_key); + annotation->type_string = e_type_string_from_key(scratch.arena, local_eval.irtree.type_key); annotation->color = color_gen_table[(vaddr_rng.min/8)%ArrayCount(color_gen_table)]; annotation->vaddr_range = vaddr_rng; } @@ -6787,7 +2555,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) UI_Parent(header_box) RD_Font(RD_FontSlot_Code) UI_FontSize(font_size) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") { UI_PrefWidth(ui_px(big_glyph_advance*20.f, 1.f)) ui_labelf("Address"); UI_PrefWidth(ui_px(cell_width_px, 1.f)) @@ -6796,10 +2564,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) Rng1U64 col_selection_rng = r1u64(cursor%num_columns, mark%num_columns); for(U64 row_off = 0; row_off < num_columns*bytes_per_cell; row_off += bytes_per_cell) { - if(!(col_selection_rng.min <= row_off && row_off <= col_selection_rng.max)) - { - ui_set_next_flags(UI_BoxFlag_DrawTextWeak); - } ui_labelf("%I64X", row_off); } } @@ -6958,8 +2722,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) if(row_range_bytes.min%64 == 0) { row_is_boundary = 1; - Vec4F32 row_boundary_color = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = row_boundary_color)); + ui_set_next_tag(str8_lit("pop")); } UI_Box *row = ui_build_box_from_stringf(UI_BoxFlag_DrawSideTop*!!row_is_boundary, "row_%I64x", row_range_bytes.min); UI_Parent(row) @@ -6968,7 +2731,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) { if(!(selection.max >= row_range_bytes.min && selection.min < row_range_bytes.max)) { - ui_set_next_flags(UI_BoxFlag_DrawTextWeak); + ui_set_next_tag(str8_lit("weak")); } ui_labelf("0x%016I64X", row_range_bytes.min); } @@ -6998,12 +2761,10 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) // rjf: unpack visual cell info UI_BoxFlags cell_flags = 0; - Vec4F32 cell_border_rgba = {0}; Vec4F32 cell_bg_rgba = {0}; if(global_byte_num == mouse_hover_byte_num) { cell_flags |= UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawSideTop|UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DrawSideLeft|UI_BoxFlag_DrawSideRight; - cell_border_rgba = rd_rgba_from_theme_color(RD_ThemeColor_Hover); } if(annotation != 0) { @@ -7021,20 +2782,21 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) if(selection.min <= global_byte_idx && global_byte_idx <= selection.max) { cell_flags |= UI_BoxFlag_DrawBackground; - cell_bg_rgba = rd_rgba_from_theme_color(RD_ThemeColor_SelectionOverlay); + cell_bg_rgba = selection_color; + cell_bg_rgba.w *= 0.2f; } // rjf: build - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = cell_bg_rgba)); + ui_set_next_background_color(cell_bg_rgba); UI_Box *cell_box = ui_build_box_from_key(UI_BoxFlag_DrawText|cell_flags, ui_key_zero()); - ui_box_equip_display_fancy_strings(cell_box, &byte_fancy_strings[byte_value]); + ui_box_equip_display_fstrs(cell_box, &byte_fstrs[byte_value]); { F32 off = 0; for(Annotation *a = annotation; a != 0; a = a->next) { if(global_byte_idx == a->vaddr_range.min) UI_Parent(row_overlay_box) { - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = annotation->color)); + ui_set_next_background_color(annotation->color); ui_set_next_fixed_x(big_glyph_advance*20.f + col_idx*cell_width_px + -cell_width_px/8.f + off); ui_set_next_fixed_y((row_idx-viz_range_rows.min)*row_height_px + -cell_width_px/8.f); ui_set_next_fixed_width(cell_width_px/4.f); @@ -7059,7 +2821,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) } if(a->type_string.size != 0) { - rd_code_label(1.f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeType), a->type_string); + rd_code_label(1.f, 1, ui_color_from_name(str8_lit("code_type")), a->type_string); } UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label(str8_from_memory_size(scratch.arena, dim_1u64(a->vaddr_range))); if(a->next != 0) @@ -7099,11 +2861,13 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) DR_BucketScope(bucket) { Vec2F32 text_pos = ui_box_text_position(ascii_box); + Vec4F32 color = selection_color; + color.w *= 0.2f; dr_rect(r2f32p(text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, selection_in_row.min+0-row_range_bytes.min)).x - font_size/8.f, ascii_box->rect.y0, text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, selection_in_row.max+1-row_range_bytes.min)).x + font_size/4.f, ascii_box->rect.y1), - rd_rgba_from_theme_color(RD_ThemeColor_SelectionOverlay), + color, 0, 0, 1.f); } ui_box_equip_draw_bucket(ascii_box, bucket); @@ -7114,7 +2878,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) DR_BucketScope(bucket) { Vec2F32 text_pos = ui_box_text_position(ascii_box); - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); + Vec4F32 color = border_color; dr_rect(r2f32p(text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, mouse_hover_byte_num-1-row_range_bytes.min)).x - font_size/8.f, ascii_box->rect.y0, text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, mouse_hover_byte_num+0-row_range_bytes.min)).x + font_size/4.f, @@ -7142,7 +2906,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) footer_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, "footer"); UI_Parent(footer_box) RD_Font(RD_FontSlot_Code) UI_FontSize(font_size) { - UI_PrefWidth(ui_em(7.5f, 1.f)) UI_HeightFill UI_Column UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_PrefWidth(ui_em(7.5f, 1.f)) UI_HeightFill UI_Column UI_TagF("weak") UI_PrefHeight(ui_px(row_height_px, 0.f)) { ui_labelf("Address:"); @@ -7206,7 +2970,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) //////////////////////////////// //~ rjf: "graph" -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(graph) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(graph) { EV_ExpandInfo info = {0}; info.row_count = 8; @@ -7278,7 +3042,11 @@ internal UI_BOX_CUSTOM_DRAW(rd_bitmap_view_canvas_box_draw) Rng2F32 rect_cvs = rd_bitmap_canvas_from_screen_rect(draw_data->view_center_pos, draw_data->zoom, rect_scrn, rect_scrn); F32 grid_cell_size_cvs = box->font_size*10.f; F32 grid_line_thickness_px = Max(2.f, box->font_size*0.1f); - Vec4F32 grid_line_color = rd_rgba_from_theme_color(RD_ThemeColor_TextWeak); + Vec4F32 grid_line_color = {0}; + UI_TagF("weak") + { + grid_line_color = ui_color_from_name(str8_lit("text")); + } for EachEnumVal(Axis2, axis) { for(F32 v = rect_cvs.p0.v[axis] - mod_f32(rect_cvs.p0.v[axis], grid_cell_size_cvs); @@ -7298,7 +3066,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_bitmap_view_canvas_box_draw) } } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(bitmap) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(bitmap) { EV_ExpandInfo info = {0}; info.row_count = 8; @@ -7306,7 +3074,7 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(bitmap) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap) +RD_VIEW_UI_FUNCTION_DEF(bitmap) { Temp scratch = scratch_begin(0, 0); HS_Scope *hs_scope = hs_scope_open(); @@ -7315,9 +3083,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: evaluate expression // - E_Eval eval = e_eval_from_string(scratch.arena, string); - Vec2S32 dim = rd_dim2s32_from_eval_params(eval, params); - R_Tex2DFormat fmt = rd_tex2dformat_from_eval_params(eval, params); + Vec2S32 dim = rd_dim2s32_from_eval_tag(eval, tag); + R_Tex2DFormat fmt = rd_tex2dformat_from_eval_tag(eval, tag); U64 base_offset = rd_base_offset_from_eval(eval); U64 expected_size = dim.x*dim.y*r_tex2d_format_bytes_per_pixel_table[fmt]; Rng1U64 offset_range = r1u64(base_offset, base_offset + expected_size); @@ -7325,11 +3092,11 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: unpack params // - F32 zoom = rd_value_from_params_key(params, str8_lit("zoom")).f32; + F32 zoom = rd_view_cfg_value_from_string(str8_lit("zoom")).f32; Vec2F32 view_center_pos = { - rd_value_from_params_key(params, str8_lit("x")).f32, - rd_value_from_params_key(params, str8_lit("y")).f32, + rd_view_cfg_value_from_string(str8_lit("x")).f32, + rd_view_cfg_value_from_string(str8_lit("y")).f32, }; if(zoom == 0) { @@ -7509,16 +3276,13 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap) //////////////////////////////// //~ rjf: "checkbox" -RD_VIEW_RULE_UI_FUNCTION_DEF(checkbox) +RD_VIEW_UI_FUNCTION_DEF(checkbox) { - Temp scratch = scratch_begin(0, 0); - E_Eval eval = e_eval_from_string(scratch.arena, string); E_Eval value_eval = e_value_eval_from_eval(eval); if(ui_clicked(rd_icon_buttonf(value_eval.value.u64 == 0 ? RD_IconKind_CheckHollow : RD_IconKind_CheckFilled, 0, "###check"))) { rd_commit_eval_value_string(eval, value_eval.value.u64 == 0 ? str8_lit("1") : str8_lit("0"), 0); } - scratch_end(scratch); } //////////////////////////////// @@ -7530,7 +3294,7 @@ rd_rgba_from_eval_params(E_Eval eval, MD_Node *params) Vec4F32 rgba = {0}; { E_Eval value_eval = e_value_eval_from_eval(eval); - E_TypeKey type_key = eval.type_key; + E_TypeKey type_key = eval.irtree.type_key; E_TypeKind type_kind = e_type_kind_from_key(type_key); U64 type_size = e_type_byte_size_from_key(type_key); if(16 <= type_size) @@ -7546,7 +3310,7 @@ rd_rgba_from_eval_params(E_Eval eval, MD_Node *params) return rgba; } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(color_rgba) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(color_rgba) { EV_ExpandInfo info = {0}; info.row_count = 8; @@ -7554,13 +3318,12 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(color_rgba) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(color_rgba) +RD_VIEW_UI_FUNCTION_DEF(color_rgba) { Temp scratch = scratch_begin(0, 0); Vec2F32 dim = dim_2f32(rect); F32 padding = ui_top_font_size()*3.f; - E_Eval eval = e_eval_from_string(scratch.arena, string); - Vec4F32 rgba = rd_rgba_from_eval_params(eval, params); + Vec4F32 rgba = {0}; // TODO(rjf): @cfg rd_rgba_from_eval_params(eval, params); Vec4F32 hsva = hsva_from_rgba(rgba); //- rjf: too small -> just show components @@ -7571,26 +3334,20 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(color_rgba) UI_WidthFill RD_Font(RD_FontSlot_Code) { text_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - DR_FancyStringList fancy_strings = {0}; + DR_FStrList fstrs = {0}; { - DR_FancyString open_paren = {ui_top_font(), str8_lit("("), ui_top_palette()->text, ui_top_font_size(), 0, 0}; - DR_FancyString comma = {ui_top_font(), str8_lit(", "), ui_top_palette()->text, ui_top_font_size(), 0, 0}; - DR_FancyString r_fstr = {ui_top_font(), push_str8f(scratch.arena, "%.2f", rgba.x), v4f32(1.f, 0.25f, 0.25f, 1.f), ui_top_font_size(), 4.f, 0}; - DR_FancyString g_fstr = {ui_top_font(), push_str8f(scratch.arena, "%.2f", rgba.y), v4f32(0.25f, 1.f, 0.25f, 1.f), ui_top_font_size(), 4.f, 0}; - DR_FancyString b_fstr = {ui_top_font(), push_str8f(scratch.arena, "%.2f", rgba.z), v4f32(0.25f, 0.25f, 1.f, 1.f), ui_top_font_size(), 4.f, 0}; - DR_FancyString a_fstr = {ui_top_font(), push_str8f(scratch.arena, "%.2f", rgba.w), v4f32(1.f, 1.f, 1.f, 1.f), ui_top_font_size(), 4.f, 0}; - DR_FancyString clse_paren = {ui_top_font(), str8_lit(")"), ui_top_palette()->text, ui_top_font_size(), 0, 0}; - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &open_paren); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &r_fstr); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &comma); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &g_fstr); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &comma); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &b_fstr); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &comma); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &a_fstr); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &clse_paren); + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit("(")); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.x), .color = v4f32(1.f, 0.25f, 0.25f, 1.f), .underline_thickness = 4.f); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.y), .color = v4f32(0.25f, 1.f, 0.25f, 1.f), .underline_thickness = 4.f); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.z), .color = v4f32(0.25f, 0.25f, 1.f, 1.f), .underline_thickness = 4.f); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.w), .color = v4f32(1.f, 1.f, 1.f, 1.f), .underline_thickness = 4.f); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(")")); } - ui_box_equip_display_fancy_strings(text_box, &fancy_strings); + ui_box_equip_display_fstrs(text_box, &fstrs); } //- rjf: build color box @@ -7600,7 +3357,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(color_rgba) color_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "color_box"); UI_Parent(color_box) UI_PrefHeight(ui_em(1.875f, 1.f)) UI_Padding(ui_pct(1, 0)) { - UI_Palette(ui_build_palette(ui_top_palette(), .background = rgba)) UI_CornerRadius(ui_top_font_size()*0.5f) + UI_BackgroundColor(rgba) UI_CornerRadius(ui_top_font_size()*0.5f) ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } } @@ -7629,7 +3386,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(color_rgba) { UI_Signal h_sig = ui_hue_pickerf(&hsva.x, hsva.y, hsva.z, "hue_picker"); } - UI_PrefWidth(ui_children_sum(1)) UI_Column UI_PrefWidth(ui_text_dim(10, 1)) UI_PrefHeight(ui_em(2.f, 0.f)) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_PrefWidth(ui_children_sum(1)) UI_Column UI_PrefWidth(ui_text_dim(10, 1)) UI_PrefHeight(ui_em(2.f, 0.f)) RD_Font(RD_FontSlot_Code) + UI_TagF("weak") { ui_labelf("Hex"); ui_labelf("R"); @@ -7707,7 +3465,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_geo3d_box_draw) dr_mesh(draw_data->vertex_buffer, draw_data->index_buffer, R_GeoTopologyKind_Triangles, R_GeoVertexFlag_TexCoord|R_GeoVertexFlag_Normals|R_GeoVertexFlag_RGB, r_handle_zero(), mat_4x4f32(1.f)); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(geo3d) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(geo3d) { EV_ExpandInfo info = {0}; info.row_count = 16; @@ -7715,7 +3473,7 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(geo3d) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(geo3d) +RD_VIEW_UI_FUNCTION_DEF(geo3d) { Temp scratch = scratch_begin(0, 0); GEO_Scope *geo_scope = geo_scope_open(); @@ -7724,17 +3482,16 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(geo3d) ////////////////////////////// //- rjf: unpack parameters // - U64 count = rd_value_from_params_key(params, str8_lit("count")).u64; - U64 vtx_base_off = rd_value_from_params_key(params, str8_lit("vtx")).u64; - U64 vtx_size = rd_value_from_params_key(params, str8_lit("vtx_size")).u64; - F32 yaw_target = rd_value_from_params_key(params, str8_lit("yaw")).f32; - F32 pitch_target = rd_value_from_params_key(params, str8_lit("pitch")).f32; - F32 zoom_target = rd_value_from_params_key(params, str8_lit("zoom")).f32; + U64 count = rd_value_from_eval_tag_key(eval, tag, str8_lit("count")).u64; + U64 vtx_base_off = rd_value_from_eval_tag_key(eval, tag, str8_lit("vtx")).u64; + U64 vtx_size = rd_value_from_eval_tag_key(eval, tag, str8_lit("vtx_size")).u64; + F32 yaw_target = rd_view_cfg_value_from_string(str8_lit("yaw")).f32; + F32 pitch_target = rd_view_cfg_value_from_string(str8_lit("pitch")).f32; + F32 zoom_target = rd_view_cfg_value_from_string(str8_lit("zoom")).f32; ////////////////////////////// //- rjf: evaluate & unpack expression // - E_Eval eval = e_eval_from_string(scratch.arena, string); U64 base_offset = rd_base_offset_from_eval(eval); Rng1U64 idxs_range = r1u64(base_offset, base_offset+count*sizeof(U32)); Rng1U64 vtxs_range = r1u64(vtx_base_off, vtx_base_off+vtx_size); @@ -7827,840 +3584,3 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(geo3d) geo_scope_close(geo_scope); scratch_end(scratch); } - -//////////////////////////////// -//~ rjf: exception_filters @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(exception_filters) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - String8 query = string; - - //- rjf: get state - typedef struct RD_ExceptionFiltersViewState RD_ExceptionFiltersViewState; - struct RD_ExceptionFiltersViewState - { - Vec2S64 cursor; - }; - RD_ExceptionFiltersViewState *sv = rd_view_state(RD_ExceptionFiltersViewState); - - //- rjf: get list of options - typedef struct RD_ExceptionFiltersOption RD_ExceptionFiltersOption; - struct RD_ExceptionFiltersOption - { - String8 name; - FuzzyMatchRangeList matches; - B32 is_enabled; - CTRL_ExceptionCodeKind exception_code_kind; - }; - typedef struct RD_ExceptionFiltersOptionChunkNode RD_ExceptionFiltersOptionChunkNode; - struct RD_ExceptionFiltersOptionChunkNode - { - RD_ExceptionFiltersOptionChunkNode *next; - RD_ExceptionFiltersOption *v; - U64 cap; - U64 count; - }; - typedef struct RD_ExceptionFiltersOptionChunkList RD_ExceptionFiltersOptionChunkList; - struct RD_ExceptionFiltersOptionChunkList - { - RD_ExceptionFiltersOptionChunkNode *first; - RD_ExceptionFiltersOptionChunkNode *last; - U64 option_count; - U64 node_count; - }; - typedef struct RD_ExceptionFiltersOptionArray RD_ExceptionFiltersOptionArray; - struct RD_ExceptionFiltersOptionArray - { - RD_ExceptionFiltersOption *v; - U64 count; - }; - RD_ExceptionFiltersOptionChunkList opts_list = {0}; - for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)(CTRL_ExceptionCodeKind_Null+1); - k < CTRL_ExceptionCodeKind_COUNT; - k = (CTRL_ExceptionCodeKind)(k+1)) - { - RD_ExceptionFiltersOptionChunkNode *node = opts_list.last; - String8 name = push_str8f(scratch.arena, "0x%x %S", ctrl_exception_code_kind_code_table[k], ctrl_exception_code_kind_display_string_table[k]); - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, query, name); - if(matches.count >= matches.needle_part_count) - { - if(node == 0 || node->count >= node->cap) - { - node = push_array(scratch.arena, RD_ExceptionFiltersOptionChunkNode, 1); - node->cap = 256; - node->v = push_array_no_zero(scratch.arena, RD_ExceptionFiltersOption, node->cap); - SLLQueuePush(opts_list.first, opts_list.last, node); - opts_list.node_count += 1; - } - node->v[node->count].name = name; - node->v[node->count].matches = matches; - node->v[node->count].is_enabled = !!(rd_state->ctrl_exception_code_filters[k/64] & (1ull<<(k%64))); - node->v[node->count].exception_code_kind = k; - node->count += 1; - opts_list.option_count += 1; - } - } - RD_ExceptionFiltersOptionArray opts = {0}; - { - opts.count = opts_list.option_count; - opts.v = push_array_no_zero(scratch.arena, RD_ExceptionFiltersOption, opts.count); - U64 idx = 0; - for(RD_ExceptionFiltersOptionChunkNode *n = opts_list.first; n != 0; n = n->next) - { - MemoryCopy(opts.v+idx, n->v, n->count*sizeof(RD_ExceptionFiltersOption)); - idx += n->count; - } - } - - //- rjf: build option table - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 rect_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = rect_dim; - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, opts.count)); - scroll_list_params.item_range = r1s64(0, opts.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &sv->cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - for(S64 row = visible_row_range.min; row <= visible_row_range.max && row < opts.count; row += 1) - UI_FocusHot(sv->cursor.y == row+1 ? UI_FocusKind_On : UI_FocusKind_Off) - { - RD_ExceptionFiltersOption *opt = &opts.v[row]; - UI_Signal sig = rd_icon_buttonf(opt->is_enabled ? RD_IconKind_CheckFilled : RD_IconKind_CheckHollow, &opt->matches, "%S", opt->name); - if(ui_clicked(sig)) - { - if(opt->exception_code_kind != CTRL_ExceptionCodeKind_Null) - { - CTRL_ExceptionCodeKind k = opt->exception_code_kind; - if(opt->is_enabled) - { - rd_state->ctrl_exception_code_filters[k/64] &= ~(1ull<<(k%64)); - } - else - { - rd_state->ctrl_exception_code_filters[k/64] |= (1ull<<(k%64)); - } - } - } - } - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: settings @view_hook_impl - -typedef enum RD_SettingsItemKind -{ - RD_SettingsItemKind_CategoryHeader, - RD_SettingsItemKind_GlobalSetting, - RD_SettingsItemKind_WindowSetting, - RD_SettingsItemKind_ThemeColor, - RD_SettingsItemKind_ThemePreset, - RD_SettingsItemKind_COUNT -} -RD_SettingsItemKind; - -typedef struct RD_SettingsItem RD_SettingsItem; -struct RD_SettingsItem -{ - RD_SettingsItemKind kind; - String8 kind_string; - String8 string; - FuzzyMatchRangeList kind_string_matches; - FuzzyMatchRangeList string_matches; - RD_IconKind icon_kind; - RD_SettingCode code; - RD_ThemeColor color; - RD_ThemePreset preset; - RD_SettingsItemKind category; -}; - -typedef struct RD_SettingsItemNode RD_SettingsItemNode; -struct RD_SettingsItemNode -{ - RD_SettingsItemNode *next; - RD_SettingsItem v; -}; - -typedef struct RD_SettingsItemList RD_SettingsItemList; -struct RD_SettingsItemList -{ - RD_SettingsItemNode *first; - RD_SettingsItemNode *last; - U64 count; -}; - -typedef struct RD_SettingsItemArray RD_SettingsItemArray; -struct RD_SettingsItemArray -{ - RD_SettingsItem *v; - U64 count; -}; - -internal int -rd_qsort_compare_settings_item(RD_SettingsItem *a, RD_SettingsItem *b) -{ - int result = 0; - if(a->string_matches.count > b->string_matches.count) - { - result = -1; - } - else if(a->string_matches.count < b->string_matches.count) - { - result = +1; - } - else if(a->kind_string_matches.count > b->kind_string_matches.count) - { - result = -1; - } - else if(a->kind_string_matches.count < b->kind_string_matches.count) - { - result = +1; - } - return result; -} - -RD_VIEW_RULE_UI_FUNCTION_DEF(settings) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - String8 query = string; - RD_Window *window = rd_window_from_handle(rd_regs()->window); - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - - ////////////////////////////// - //- rjf: get state - // - typedef struct RD_SettingsViewState RD_SettingsViewState; - struct RD_SettingsViewState - { - B32 initialized; - Vec2S64 cursor; - TxtPt txt_cursor; - TxtPt txt_mark; - U8 txt_buffer[1024]; - U64 txt_size; - RD_ThemeColor color_ctx_menu_color; - Vec4F32 color_ctx_menu_color_hsva; - RD_ThemePreset preset_apply_confirm; - B32 category_opened[RD_SettingsItemKind_COUNT]; - }; - RD_SettingsViewState *sv = rd_view_state(RD_SettingsViewState); - if(!sv->initialized) - { - sv->initialized = 1; - sv->preset_apply_confirm = RD_ThemePreset_COUNT; - } - - ////////////////////////////// - //- rjf: gather all filtered settings items - // - RD_SettingsItemArray items = {0}; - { - RD_SettingsItemList items_list = {0}; - - //- rjf: global settings header - if(query.size == 0) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_CategoryHeader; - n->v.string = str8_lit("Global Interface Settings"); - n->v.icon_kind = sv->category_opened[RD_SettingsItemKind_GlobalSetting] ? RD_IconKind_DownCaret : RD_IconKind_RightCaret; - n->v.category = RD_SettingsItemKind_GlobalSetting; - } - - //- rjf: gather all global settings - if(sv->category_opened[RD_SettingsItemKind_GlobalSetting] || query.size != 0) - { - for EachEnumVal(RD_SettingCode, code) - { - if(rd_setting_code_default_is_per_window_table[code]) - { - continue; - } - String8 kind_string = str8_lit("Global Interface Setting"); - String8 string = rd_setting_code_display_string_table[code]; - FuzzyMatchRangeList kind_string_matches = fuzzy_match_find(scratch.arena, query, kind_string); - FuzzyMatchRangeList string_matches = fuzzy_match_find(scratch.arena, query, string); - if(string_matches.count == string_matches.needle_part_count || - kind_string_matches.count == kind_string_matches.needle_part_count) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_GlobalSetting; - n->v.kind_string = kind_string; - n->v.string = string; - n->v.kind_string_matches = kind_string_matches; - n->v.string_matches = string_matches; - n->v.icon_kind = RD_IconKind_Window; - n->v.code = code; - } - } - } - - //- rjf: window settings header - if(query.size == 0) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_CategoryHeader; - n->v.string = str8_lit("Window Interface Settings"); - n->v.icon_kind = sv->category_opened[RD_SettingsItemKind_WindowSetting] ? RD_IconKind_DownCaret : RD_IconKind_RightCaret; - n->v.category = RD_SettingsItemKind_WindowSetting; - } - - //- rjf: gather all window settings - if(sv->category_opened[RD_SettingsItemKind_WindowSetting] || query.size != 0) - { - for EachEnumVal(RD_SettingCode, code) - { - if(!rd_setting_code_default_is_per_window_table[code]) - { - continue; - } - String8 kind_string = str8_lit("Window Interface Setting"); - String8 string = rd_setting_code_display_string_table[code]; - FuzzyMatchRangeList kind_string_matches = fuzzy_match_find(scratch.arena, query, kind_string); - FuzzyMatchRangeList string_matches = fuzzy_match_find(scratch.arena, query, string); - if(string_matches.count == string_matches.needle_part_count || - kind_string_matches.count == kind_string_matches.needle_part_count) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_WindowSetting; - n->v.kind_string = kind_string; - n->v.string = string; - n->v.kind_string_matches = kind_string_matches; - n->v.string_matches = string_matches; - n->v.icon_kind = RD_IconKind_Window; - n->v.code = code; - } - } - } - - //- rjf: theme presets header - if(query.size == 0) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_CategoryHeader; - n->v.string = str8_lit("Theme Presets"); - n->v.icon_kind = sv->category_opened[RD_SettingsItemKind_ThemePreset] ? RD_IconKind_DownCaret : RD_IconKind_RightCaret; - n->v.category = RD_SettingsItemKind_ThemePreset; - } - - //- rjf: gather theme presets - if(sv->category_opened[RD_SettingsItemKind_ThemePreset] || query.size != 0) - { - for EachEnumVal(RD_ThemePreset, preset) - { - String8 kind_string = str8_lit("Theme Preset"); - String8 string = rd_theme_preset_display_string_table[preset]; - FuzzyMatchRangeList kind_string_matches = fuzzy_match_find(scratch.arena, query, kind_string); - FuzzyMatchRangeList string_matches = fuzzy_match_find(scratch.arena, query, string); - if(string_matches.count == string_matches.needle_part_count || - kind_string_matches.count == kind_string_matches.needle_part_count) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_ThemePreset; - n->v.kind_string = kind_string; - n->v.string = string; - n->v.kind_string_matches = kind_string_matches; - n->v.string_matches = string_matches; - n->v.icon_kind = RD_IconKind_Palette; - n->v.preset = preset; - } - } - } - - //- rjf: theme colors header - if(query.size == 0) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_CategoryHeader; - n->v.string = str8_lit("Theme Colors"); - n->v.icon_kind = sv->category_opened[RD_SettingsItemKind_ThemeColor] ? RD_IconKind_DownCaret : RD_IconKind_RightCaret; - n->v.category = RD_SettingsItemKind_ThemeColor; - } - - //- rjf: gather all theme colors - if(sv->category_opened[RD_SettingsItemKind_ThemeColor] || query.size != 0) - { - for EachNonZeroEnumVal(RD_ThemeColor, color) - { - String8 kind_string = str8_lit("Theme Color"); - String8 string = rd_theme_color_display_string_table[color]; - FuzzyMatchRangeList kind_string_matches = fuzzy_match_find(scratch.arena, query, kind_string); - FuzzyMatchRangeList string_matches = fuzzy_match_find(scratch.arena, query, string); - if(string_matches.count == string_matches.needle_part_count || - kind_string_matches.count == kind_string_matches.needle_part_count) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_ThemeColor; - n->v.kind_string = kind_string; - n->v.string = string; - n->v.kind_string_matches = kind_string_matches; - n->v.string_matches = string_matches; - n->v.icon_kind = RD_IconKind_Palette; - n->v.color = color; - } - } - } - - //- rjf: convert to array - items.count = items_list.count; - items.v = push_array(scratch.arena, RD_SettingsItem, items.count); - { - U64 idx = 0; - for(RD_SettingsItemNode *n = items_list.first; n != 0; n = n->next, idx += 1) - { - items.v[idx] = n->v; - } - } - } - - ////////////////////////////// - //- rjf: sort filtered settings item list - // - if(query.size != 0) - { - quick_sort(items.v, items.count, sizeof(items.v[0]), rd_qsort_compare_settings_item); - } - - ////////////////////////////// - //- rjf: produce per-color context menu keys - // - UI_Key *color_ctx_menu_keys = push_array(scratch.arena, UI_Key, RD_ThemeColor_COUNT); - { - for(RD_ThemeColor color = (RD_ThemeColor)(RD_ThemeColor_Null+1); - color < RD_ThemeColor_COUNT; - color = (RD_ThemeColor)(color+1)) - { - color_ctx_menu_keys[color] = ui_key_from_stringf(ui_key_zero(), "###settings_color_ctx_menu_%I64x", (U64)color); - } - } - - ////////////////////////////// - //- rjf: build color context menus - // - for(RD_ThemeColor color = (RD_ThemeColor)(RD_ThemeColor_Null+1); - color < RD_ThemeColor_COUNT; - color = (RD_ThemeColor)(color+1)) - { - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(color_ctx_menu_keys[color]) - UI_Padding(ui_em(1.5f, 1.f)) - UI_PrefWidth(ui_em(28.5f, 1)) UI_PrefHeight(ui_children_sum(1.f)) - { - // rjf: build title - UI_Row - { - ui_spacer(ui_em(1.5f, 1.f)); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label(rd_theme_color_display_string_table[color]); - } - - ui_spacer(ui_em(1.5f, 1.f)); - - // rjf: build picker - { - ui_set_next_pref_height(ui_em(22.f, 1.f)); - UI_Row UI_Padding(ui_pct(1, 0)) - { - UI_PrefWidth(ui_em(22.f, 1.f)) UI_PrefHeight(ui_em(22.f, 1.f)) UI_Flags(UI_BoxFlag_FocusNavSkip) - { - ui_sat_val_pickerf(sv->color_ctx_menu_color_hsva.x, &sv->color_ctx_menu_color_hsva.y, &sv->color_ctx_menu_color_hsva.z, "###settings_satval_picker"); - } - - ui_spacer(ui_em(0.75f, 1.f)); - - UI_PrefWidth(ui_em(1.5f, 1.f)) UI_PrefHeight(ui_em(22.f, 1.f)) UI_Flags(UI_BoxFlag_FocusNavSkip) - ui_hue_pickerf(&sv->color_ctx_menu_color_hsva.x, sv->color_ctx_menu_color_hsva.y, sv->color_ctx_menu_color_hsva.z, "###settings_hue_picker"); - - UI_PrefWidth(ui_em(1.5f, 1.f)) UI_PrefHeight(ui_em(22.f, 1.f)) UI_Flags(UI_BoxFlag_FocusNavSkip) - ui_alpha_pickerf(&sv->color_ctx_menu_color_hsva.w, "###settings_alpha_picker"); - } - } - - ui_spacer(ui_em(1.5f, 1.f)); - - // rjf: build line edits - UI_Row - UI_WidthFill - UI_Padding(ui_em(1.5f, 1.f)) - UI_PrefHeight(ui_children_sum(1.f)) - UI_Column - UI_PrefHeight(ui_em(2.25f, 1.f)) - { - Vec4F32 hsva = sv->color_ctx_menu_color_hsva; - Vec3F32 hsv = v3f32(hsva.x, hsva.y, hsva.z); - Vec3F32 rgb = rgb_from_hsv(hsv); - Vec4F32 rgba = v4f32(rgb.x, rgb.y, rgb.z, sv->color_ctx_menu_color_hsva.w); - String8 hex_string = hex_string_from_rgba_4f32(scratch.arena, rgba); - hex_string = push_str8f(scratch.arena, "#%S", hex_string); - String8 r_string = push_str8f(scratch.arena, "%.2f", rgba.x); - String8 g_string = push_str8f(scratch.arena, "%.2f", rgba.y); - String8 b_string = push_str8f(scratch.arena, "%.2f", rgba.z); - String8 h_string = push_str8f(scratch.arena, "%.2f", hsva.x); - String8 s_string = push_str8f(scratch.arena, "%.2f", hsva.y); - String8 v_string = push_str8f(scratch.arena, "%.2f", hsva.z); - String8 a_string = push_str8f(scratch.arena, "%.2f", rgba.w); - UI_Row RD_Font(RD_FontSlot_Code) - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("Hex"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, hex_string, "###hex_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_rgba = rgba_from_hex_string_4f32(string); - Vec4F32 new_hsva = hsva_from_rgba(new_rgba); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - ui_spacer(ui_em(0.75f, 1.f)); - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("R"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, r_string, "###r_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_rgba = v4f32((F32)f64_from_str8(string), rgba.y, rgba.z, rgba.w); - Vec4F32 new_hsva = hsva_from_rgba(new_rgba); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("G"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, g_string, "###g_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_rgba = v4f32(rgba.x, (F32)f64_from_str8(string), rgba.z, rgba.w); - Vec4F32 new_hsva = hsva_from_rgba(new_rgba); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("B"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, b_string, "###b_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_rgba = v4f32(rgba.x, rgba.y, (F32)f64_from_str8(string), rgba.w); - Vec4F32 new_hsva = hsva_from_rgba(new_rgba); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - ui_spacer(ui_em(0.75f, 1.f)); - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("H"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, h_string, "###h_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_hsva = v4f32((F32)f64_from_str8(string), hsva.y, hsva.z, hsva.w); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("S"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, s_string, "###s_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_hsva = v4f32(hsva.x, (F32)f64_from_str8(string), hsva.z, hsva.w); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("V"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, v_string, "###v_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_hsva = v4f32(hsva.x, hsva.y, (F32)f64_from_str8(string), hsva.w); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - ui_spacer(ui_em(0.75f, 1.f)); - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("A"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, a_string, "###a_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_hsva = v4f32(hsva.x, hsva.y, hsva.z, (F32)f64_from_str8(string)); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - } - - // rjf: commit state to theme - Vec4F32 hsva = sv->color_ctx_menu_color_hsva; - Vec3F32 hsv = v3f32(hsva.x, hsva.y, hsva.z); - Vec3F32 rgb = rgb_from_hsv(hsv); - Vec4F32 rgba = v4f32(rgb.x, rgb.y, rgb.z, sv->color_ctx_menu_color_hsva.w); - rd_state->cfg_theme_target.colors[sv->color_ctx_menu_color] = rgba; - } - } - - ////////////////////////////// - //- rjf: cancels - // - UI_Focus(UI_FocusKind_On) if(ui_is_focus_active() && sv->preset_apply_confirm < RD_ThemePreset_COUNT && ui_slot_press(UI_EventActionSlot_Cancel)) - { - sv->preset_apply_confirm = RD_ThemePreset_COUNT; - } - - ////////////////////////////// - //- rjf: build items list - // - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 rect_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(rect_dim.x, rect_dim.y); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, items.count)); - scroll_list_params.item_range = r1s64(0, items.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &scroll_pos.y, &sv->cursor, 0, &visible_row_range, &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - for(S64 row_num = visible_row_range.min; row_num <= visible_row_range.max && row_num < items.count; row_num += 1) - { - //- rjf: unpack item - RD_SettingsItem *item = &items.v[row_num]; - UI_Palette *palette = ui_top_palette(); - Vec4F32 rgba = ui_top_palette()->text_weak; - OS_Cursor cursor = OS_Cursor_HandPoint; - Rng1S32 s32_range = {0}; - B32 is_toggler = 0; - B32 is_toggled = 0; - B32 is_slider = 0; - S32 slider_s32_val = 0; - F32 slider_pct = 0.f; - UI_BoxFlags flags = UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects; - RD_SettingVal *val_table = &rd_state->cfg_setting_vals[RD_CfgSrc_User][0]; - switch(item->kind) - { - case RD_SettingsItemKind_COUNT:{}break; - case RD_SettingsItemKind_CategoryHeader: - { - cursor = OS_Cursor_HandPoint; - flags = UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawHotEffects; - }break; - case RD_SettingsItemKind_ThemePreset: - { - Vec4F32 *colors = rd_theme_preset_colors_table[item->preset]; - Vec4F32 bg_color = colors[RD_ThemeColor_BaseBackground]; - Vec4F32 tx_color = colors[RD_ThemeColor_Text]; - Vec4F32 tw_color = colors[RD_ThemeColor_TextWeak]; - Vec4F32 bd_color = colors[RD_ThemeColor_BaseBorder]; - palette = ui_build_palette(ui_top_palette(), - .text = tx_color, - .text_weak = tw_color, - .border = bd_color, - .background = bg_color); - }break; - case RD_SettingsItemKind_ThemeColor: - { - rgba = rd_rgba_from_theme_color(item->color); - }break; - case RD_SettingsItemKind_WindowSetting: {val_table = &window->setting_vals[0];}goto setting; - case RD_SettingsItemKind_GlobalSetting:{}goto setting; - setting:; - { - s32_range = rd_setting_code_s32_range_table[item->code]; - if(s32_range.min != 0 || s32_range.max != 1) - { - cursor = OS_Cursor_LeftRight; - is_slider = 1; - slider_s32_val = val_table[item->code].s32; - slider_pct = (F32)(slider_s32_val - s32_range.min) / dim_1s32(s32_range); - } - else - { - is_toggler = 1; - is_toggled = !!val_table[item->code].s32; - } - }break; - } - - //- rjf: build item widget - UI_Box *item_box = &ui_nil_box; - UI_Row - { - if(query.size == 0 && item->kind != RD_SettingsItemKind_CategoryHeader) - { - ui_set_next_flags(UI_BoxFlag_DrawSideLeft); - ui_spacer(ui_em(2.f, 1.f)); - } - UI_Focus(row_num+1 == sv->cursor.y ? UI_FocusKind_On : UI_FocusKind_Off) UI_Palette(palette) - { - ui_set_next_hover_cursor(cursor); - item_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|flags, "###option_%S_%S", item->kind_string, item->string); - UI_Parent(item_box) - { - if(item->icon_kind != RD_IconKind_Null) - { - UI_PrefWidth(ui_em(3.f, 1.f)) - RD_Font(RD_FontSlot_Icons) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rgba)) - UI_TextAlignment(UI_TextAlign_Center) - ui_label(rd_icon_kind_text_table[item->icon_kind]); - } - if(query.size != 0 && item->kind_string.size != 0) UI_PrefWidth(ui_text_dim(10, 1)) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DrawTextWeak, "%S", item->kind_string); - ui_box_equip_fuzzy_match_ranges(box, &item->kind_string_matches); - } - UI_PrefWidth(ui_text_dim(10, 1)) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "%S", item->string); - ui_box_equip_fuzzy_match_ranges(box, &item->string_matches); - } - if(is_slider) UI_PrefWidth(ui_text_dim(10, 1)) - { - UI_Flags(UI_BoxFlag_DrawTextWeak) - ui_labelf("(%i)", slider_s32_val); - UI_PrefWidth(ui_pct(slider_pct, 1.f)) UI_HeightFill UI_FixedX(0) UI_FixedY(0) - UI_Palette(ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay))) - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - if(is_toggler) - { - ui_spacer(ui_pct(1, 0)); - UI_PrefWidth(ui_em(2.5f, 1.f)) - RD_Font(RD_FontSlot_Icons) - UI_Flags(UI_BoxFlag_DrawTextWeak) - ui_label(rd_icon_kind_text_table[is_toggled ? RD_IconKind_CheckFilled : RD_IconKind_CheckHollow]); - } - if(item->kind == RD_SettingsItemKind_ThemePreset && sv->preset_apply_confirm == item->preset) - { - ui_spacer(ui_pct(1, 0)); - UI_PrefWidth(ui_text_dim(10, 1)) - RD_Palette(RD_PaletteCode_NegativePopButton) - UI_CornerRadius(ui_top_font_size()*0.5f) - UI_FontSize(ui_top_font_size()*0.9f) - UI_TextAlignment(UI_TextAlign_Center) - ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DrawBackground, "Click Again To Apply"); - } - } - } - } - - //- rjf: interact - UI_Signal sig = ui_signal_from_box(item_box); - if(item->kind == RD_SettingsItemKind_ThemeColor && ui_pressed(sig)) - { - Vec3F32 rgb = v3f32(rgba.x, rgba.y, rgba.z); - Vec3F32 hsv = hsv_from_rgb(rgb); - Vec4F32 hsva = v4f32(hsv.x, hsv.y, hsv.z, rgba.w); - if(ui_ctx_menu_is_open(color_ctx_menu_keys[item->color])) - { - ui_ctx_menu_close(); - } - else - { - ui_ctx_menu_open(color_ctx_menu_keys[item->color], item_box->key, v2f32(0, dim_2f32(item_box->rect).y)); - } - sv->color_ctx_menu_color = item->color; - sv->color_ctx_menu_color_hsva = v4f32(hsv.x, hsv.y, hsv.z, rgba.w); - rd_cmd(RD_CmdKind_FocusPanel); - } - if((item->kind == RD_SettingsItemKind_GlobalSetting || item->kind == RD_SettingsItemKind_WindowSetting) && - is_toggler && ui_clicked(sig)) - { - val_table[item->code].s32 ^= 1; - val_table[item->code].set = 1; - } - if((item->kind == RD_SettingsItemKind_GlobalSetting || item->kind == RD_SettingsItemKind_WindowSetting) && - is_slider && ui_dragging(sig)) - { - if(ui_pressed(sig)) - { - ui_store_drag_struct(&slider_s32_val); - } - S32 pre_drag_val = *ui_get_drag_struct(S32); - Vec2F32 delta = ui_drag_delta(); - S32 pst_drag_val = pre_drag_val + (S32)(delta.x/(ui_top_font_size()*2.f)); - pst_drag_val = clamp_1s32(s32_range, pst_drag_val); - val_table[item->code].s32 = pst_drag_val; - val_table[item->code].set = 1; - } - if(item->kind == RD_SettingsItemKind_ThemePreset && ui_clicked(sig)) - { - if(sv->preset_apply_confirm == item->preset) - { - Vec4F32 *colors = rd_theme_preset_colors_table[item->preset]; - MemoryCopy(rd_state->cfg_theme_target.colors, colors, sizeof(rd_state->cfg_theme_target.colors)); - sv->preset_apply_confirm = RD_ThemePreset_COUNT; - } - else - { - sv->preset_apply_confirm = item->preset; - } - } - if(item->kind != RD_SettingsItemKind_ThemePreset && ui_pressed(sig)) - { - sv->preset_apply_confirm = RD_ThemePreset_COUNT; - } - if(item->kind != RD_SettingsItemKind_ThemePreset && ui_pressed(sig)) - { - sv->preset_apply_confirm = RD_ThemePreset_COUNT; - } - if(item->kind == RD_SettingsItemKind_CategoryHeader && ui_pressed(sig)) - { - sv->category_opened[item->category] ^= 1; - } - } - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 0b3122fc..c67e9ba3 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -10,8 +10,8 @@ typedef U32 RD_CodeViewBuildFlags; enum { - RD_CodeViewBuildFlag_Margins = (1<<0), - RD_CodeViewBuildFlag_All = 0xffffffff, + RD_CodeViewBuildFlag_Margins = (1<<0), + RD_CodeViewBuildFlag_All = 0xffffffff, }; typedef struct RD_CodeViewState RD_CodeViewState; @@ -41,13 +41,85 @@ struct RD_CodeViewBuildResult //////////////////////////////// //~ rjf: Watch View Types -typedef U32 RD_WatchViewFlags; +typedef enum RD_WatchCellKind +{ + RD_WatchCellKind_Expr, // strings to represent expression itself + RD_WatchCellKind_Tag, // strings to represent attached tags at row-granularity + RD_WatchCellKind_Eval, // an evaluation of the expression, with some optional modification - e.g. `$expr.some_member`, or `typeof($expr)` + RD_WatchCellKind_ViewUI, // an arbitrary user interface, supplied by a hook + RD_WatchCellKind_CallStackFrame, // a slot for a yellow arrow, to show call stack frame selection +} +RD_WatchCellKind; + +typedef U32 RD_WatchCellFlags; enum { - RD_WatchViewFlag_NoHeader = (1<<0), - RD_WatchViewFlag_PrettyNameMembers = (1<<1), - RD_WatchViewFlag_PrettyEntityRows = (1<<2), - RD_WatchViewFlag_DisableCacheLines = (1<<3), + RD_WatchCellFlag_Button = (1<<0), + RD_WatchCellFlag_Background = (1<<1), + RD_WatchCellFlag_ActivateWithSingleClick = (1<<2), + RD_WatchCellFlag_IsNonCode = (1<<3), + RD_WatchCellFlag_CanEdit = (1<<4), + RD_WatchCellFlag_IsErrored = (1<<5), +}; + +typedef struct RD_WatchCell RD_WatchCell; +struct RD_WatchCell +{ + RD_WatchCell *next; + RD_WatchCellKind kind; + U64 index; + String8 string; + E_Eval eval; + DR_FStrList fstrs; + RD_WatchCellFlags flags; + F32 default_pct; + F32 pct; + F32 px; +}; + +typedef struct RD_WatchCellList RD_WatchCellList; +struct RD_WatchCellList +{ + RD_WatchCell *first; + RD_WatchCell *last; + U64 count; +}; + +typedef struct RD_WatchRowInfo RD_WatchRowInfo; +struct RD_WatchRowInfo +{ + E_Eval eval; + CTRL_Entity *module; + B32 can_expand; + B32 expr_is_editable; + String8 group_cfg_name; + RD_Cfg *group_cfg_parent; + RD_Cfg *group_cfg_child; + CTRL_Entity *group_entity; + CTRL_Entity *callstack_thread; + U64 callstack_unwind_index; + U64 callstack_inline_depth; + U64 callstack_vaddr; + String8 cell_style_key; + RD_WatchCellList cells; + RD_ViewUIRule *view_ui_rule; + E_Expr *view_ui_tag; +}; + +typedef struct RD_WatchRowCellInfo RD_WatchRowCellInfo; +struct RD_WatchRowCellInfo +{ + RD_WatchCellFlags flags; + E_Eval eval; + RD_Cfg *cfg; + CTRL_Entity *entity; + String8 cmd_name; + String8 string; + DR_FStrList fstrs; + String8 error_tooltip; + String8 inheritance_tooltip; + RD_ViewUIRule *view_ui_rule; + E_Expr *view_ui_tag; }; typedef enum RD_WatchViewColumnKind @@ -93,48 +165,19 @@ struct RD_WatchViewColumn B32 rangify_braces; }; -typedef struct RD_WatchViewRowCtrl RD_WatchViewRowCtrl; -struct RD_WatchViewRowCtrl +typedef struct RD_WatchPt RD_WatchPt; +struct RD_WatchPt { - RD_EntityKind entity_kind; - CTRL_EntityKind ctrl_entity_kind; - RD_CmdKind kind; -}; - -typedef enum RD_WatchViewRowKind -{ - RD_WatchViewRowKind_Normal, - RD_WatchViewRowKind_Header, - RD_WatchViewRowKind_Canvas, - RD_WatchViewRowKind_PrettyEntityControls, -} -RD_WatchViewRowKind; - -typedef struct RD_WatchViewPoint RD_WatchViewPoint; -struct RD_WatchViewPoint -{ - S64 x; EV_Key parent_key; EV_Key key; -}; - -typedef struct RD_WatchViewRowInfo RD_WatchViewRowInfo; -struct RD_WatchViewRowInfo -{ - RD_EntityKind collection_entity_kind; - RD_Entity *collection_entity; - CTRL_EntityKind collection_ctrl_entity_kind; - CTRL_Entity *collection_ctrl_entity; - CTRL_Entity *callstack_thread; - U64 callstack_unwind_index; - U64 callstack_inline_depth; + U64 cell_id; }; typedef struct RD_WatchViewTextEditState RD_WatchViewTextEditState; struct RD_WatchViewTextEditState { RD_WatchViewTextEditState *pt_hash_next; - RD_WatchViewPoint pt; + RD_WatchPt pt; TxtPt cursor; TxtPt mark; U8 input_buffer[1024]; @@ -148,18 +191,15 @@ struct RD_WatchViewState { B32 initialized; - // rjf: column state - Arena *column_arena; - RD_WatchViewColumn *first_column; - RD_WatchViewColumn *last_column; - RD_WatchViewColumn *free_column; - U64 column_count; + // rjf: filter history + Arena *filter_arena; + String8 last_filter; // rjf; table cursor state - RD_WatchViewPoint cursor; - RD_WatchViewPoint mark; - RD_WatchViewPoint next_cursor; - RD_WatchViewPoint next_mark; + RD_WatchPt cursor; + RD_WatchPt mark; + RD_WatchPt next_cursor; + RD_WatchPt next_mark; // rjf: text input state Arena *text_edit_arena; @@ -178,34 +218,46 @@ internal RD_CodeViewBuildResult rd_code_view_build(Arena *arena, RD_CodeViewStat //////////////////////////////// //~ rjf: Watch View Functions -//- rjf: index -> column -internal RD_WatchViewColumn *rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index); +//- rjf: cell list building +internal U64 rd_id_from_watch_cell(RD_WatchCell *cell); +internal RD_WatchCell *rd_watch_cell_list_push(Arena *arena, RD_WatchCellList *list); +internal RD_WatchCell *rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellList *list, RD_WatchCell *params); +#define rd_watch_cell_list_push_new(arena, list, kind_, ...) rd_watch_cell_list_push_new_((arena), (list), &(RD_WatchCell){.kind = (kind_), __VA_ARGS__}) //- rjf: watch view points <-> table coordinates -internal B32 rd_watch_view_point_match(RD_WatchViewPoint a, RD_WatchViewPoint b); -internal RD_WatchViewPoint rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl); -internal Vec2S64 rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint pt); +internal B32 rd_watch_pt_match(RD_WatchPt a, RD_WatchPt b); +internal RD_WatchPt rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl); +internal Vec2S64 rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt); -//- rjf: row -> context info -internal RD_WatchViewRowInfo rd_watch_view_row_info_from_row(EV_Row *row); +//- rjf: row -> info +internal RD_WatchRowInfo rd_watch_row_info_from_row(Arena *arena, EV_Row *row); -//- rjf: watch view flags & row & row info -> row kind -internal RD_WatchViewRowKind rd_watch_view_row_kind_from_flags_row_info(RD_WatchViewFlags flags, EV_Row *row, RD_WatchViewRowInfo *info); - -//- rjf: row/column -> exprs / strings -internal E_Expr *rd_expr_from_watch_view_row_column(Arena *arena, EV_View *ev_view, EV_Row *row, RD_WatchViewColumn *col); -internal String8 rd_string_from_eval_viz_row_column(Arena *arena, EV_View *ev, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px); +//- rjf: row * cell -> info +internal RD_WatchRowCellInfo rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_flags, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px); //- rjf: table coordinates -> text edit state -internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint pt); +internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt); -//- rjf: watch view column state mutation -internal RD_WatchViewColumn *rd_watch_view_column_alloc_(RD_WatchViewState *wv, RD_WatchViewColumnKind kind, F32 pct, RD_WatchViewColumnParams *params); -#define rd_watch_view_column_alloc(wv, kind, pct, ...) rd_watch_view_column_alloc_((wv), (kind), (pct), &(RD_WatchViewColumnParams){.string = str8_zero(), __VA_ARGS__}) -internal void rd_watch_view_column_release(RD_WatchViewState *wv, RD_WatchViewColumn *col); +//////////////////////////////// +//~ rjf: View Hooks -//- rjf: watch view main hooks -internal void rd_watch_view_init(RD_WatchViewState *ewv); -internal void rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 root_expr, String8 root_view_rule, B32 modifiable, U32 default_radix, Rng2F32 rect); +// TODO(rjf): eliminate once we are predeclaring these with metacode + +RD_VIEW_UI_FUNCTION_DEF(null); + +EV_EXPAND_RULE_INFO_FUNCTION_DEF(text); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(disasm); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(memory); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(bitmap); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(color_rgba); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(geo3d); + +RD_VIEW_UI_FUNCTION_DEF(text); +RD_VIEW_UI_FUNCTION_DEF(disasm); +RD_VIEW_UI_FUNCTION_DEF(memory); +RD_VIEW_UI_FUNCTION_DEF(bitmap); +RD_VIEW_UI_FUNCTION_DEF(checkbox); +RD_VIEW_UI_FUNCTION_DEF(color_rgba); +RD_VIEW_UI_FUNCTION_DEF(geo3d); #endif // RADDBG_VIEWS_H diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 0e2c3355..3537a855 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1,13 +1,621 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// +//~ rjf: UI Widgets: Fancy Title Strings + +internal DR_FStrList +rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) +{ + DR_FStrList result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: unpack config + B32 is_disabled = rd_disabled_from_cfg(cfg); + RD_Location loc = rd_location_from_cfg(cfg); + D_Target target = rd_target_from_cfg(scratch.arena, cfg); + String8 label_string = rd_label_from_cfg(cfg); + String8 expr_string = rd_expr_from_cfg(cfg); + String8 collection_name = {0}; + String8 file_path = rd_path_from_cfg(cfg); + Vec4F32 rgba = rd_color_from_cfg(cfg); + if(rgba.w == 0) + { + rgba = ui_color_from_name(str8_lit("text")); + } + Vec4F32 rgba_secondary = rgba; + UI_TagF("weak") + { + rgba_secondary = ui_color_from_name(str8_lit("text")); + } + RD_IconKind icon_kind = rd_icon_kind_from_code_name(cfg->string); + B32 is_from_command_line = 0; + { + RD_Cfg *cmd_line_root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("command_line")); + for(RD_Cfg *p = cfg->parent; p != &rd_nil_cfg; p = p->parent) + { + if(p == cmd_line_root) + { + is_from_command_line = 1; + break; + } + } + } + B32 is_within_window = 0; + { + for(RD_Cfg *p = cfg->parent; p != &rd_nil_cfg; p = p->parent) + { + if(str8_match(p->string, str8_lit("window"), 0)) + { + is_within_window = 1; + break; + } + } + } + if(expr_string.size != 0) + { + String8 query_name = rd_query_from_eval_string(arena, expr_string); + if(query_name.size != 0) + { + String8 query_code_name = query_name; + String8 query_display_name = rd_display_from_code_name(query_code_name); + collection_name = query_display_name; + if(query_display_name.size == 0) + { + query_code_name = rd_singular_from_code_name_plural(query_name); + collection_name = rd_display_plural_from_code_name(query_code_name); + if(str8_match(collection_name, str8_lit("Watches"), 0)) + { + collection_name = str8_lit("Watch"); + } + } + RD_IconKind query_icon_kind = rd_icon_kind_from_code_name(query_code_name); + if(query_icon_kind != RD_IconKind_Null) + { + icon_kind = query_icon_kind; + } + } + else + { + file_path = rd_file_path_from_eval_string(arena, expr_string); + if(file_path.size != 0) + { + icon_kind = RD_IconKind_FileOutline; + } + } + } + + //- rjf: set up color/size for all parts of the title + // + // the "running" part implies that it changes as things are added - + // so if a primary title is pushed, we can make the rest of the title + // more faded/smaller, but only after a primary title is pushed, + // which could be caused by many different potential parts of a cfg. + // + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), rgba, ui_top_font_size()}; + B32 running_is_secondary = 0; +#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = rgba_secondary; params.size = ui_top_font_size()*0.95f;} + + //- rjf: disabled? -> soften color + if(is_disabled) + { + params.color = rgba_secondary; + } + + //- rjf: push icon + if(icon_kind != RD_IconKind_Null) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push warning icon for command-line entities + if(is_from_command_line) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Info], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push view title, if from window, and no file path + if(is_within_window && file_path.size == 0 && collection_name.size == 0) + { + String8 view_display_name = rd_display_from_code_name(cfg->string); + if(view_display_name.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, view_display_name); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + } + + //- rjf: push label + if(label_string.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, label_string, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: push collection name + if(collection_name.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, collection_name); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: query is file path - do specific file name strings + else if(file_path.size != 0) + { + // rjf: compute disambiguated file name + String8List qualifiers = {0}; + String8 file_name = str8_skip_last_slash(file_path); + if(rd_state->ambiguous_path_slots_count != 0) + { + U64 hash = d_hash_from_string__case_insensitive(file_name); + U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; + RD_AmbiguousPathNode *node = 0; + { + for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; + n != 0; + n = n->next) + { + if(str8_match(n->name, file_name, StringMatchFlag_CaseInsensitive)) + { + node = n; + break; + } + } + } + if(node != 0 && node->paths.node_count > 1) + { + // rjf: get all colliding paths + String8Array collisions = str8_array_from_list(scratch.arena, &node->paths); + + // rjf: get all reversed path parts for each collision + String8List *collision_parts_reversed = push_array(scratch.arena, String8List, collisions.count); + for EachIndex(idx, collisions.count) + { + String8List parts = str8_split_path(scratch.arena, collisions.v[idx]); + for(String8Node *n = parts.first; n != 0; n = n->next) + { + str8_list_push_front(scratch.arena, &collision_parts_reversed[idx], n->string); + } + } + + // rjf: get the search path & its reversed parts + String8List parts = str8_split_path(scratch.arena, file_path); + String8List parts_reversed = {0}; + for(String8Node *n = parts.first; n != 0; n = n->next) + { + str8_list_push_front(scratch.arena, &parts_reversed, n->string); + } + + // rjf: iterate all collision part reversed lists, in lock-step with + // search path; disqualify until we only have one path remaining; gather + // qualifiers + { + U64 num_collisions_left = collisions.count; + String8Node **collision_nodes = push_array(scratch.arena, String8Node *, collisions.count); + for EachIndex(idx, collisions.count) + { + collision_nodes[idx] = collision_parts_reversed[idx].first; + } + for(String8Node *n = parts_reversed.first; num_collisions_left > 1 && n != 0; n = n->next) + { + B32 part_is_qualifier = 0; + for EachIndex(idx, collisions.count) + { + if(collision_nodes[idx] != 0 && !str8_match(collision_nodes[idx]->string, n->string, StringMatchFlag_CaseInsensitive)) + { + collision_nodes[idx] = 0; + num_collisions_left -= 1; + part_is_qualifier = 1; + } + else if(collision_nodes[idx] != 0) + { + collision_nodes[idx] = collision_nodes[idx]->next; + } + } + if(part_is_qualifier) + { + str8_list_push_front(scratch.arena, &qualifiers, n->string); + } + } + } + } + } + + // rjf: push qualifiers + if(qualifiers.node_count != 0) UI_TagF("weak") + { + for(String8Node *n = qualifiers.first; n != 0; n = n->next) + { + String8 string = push_str8f(arena, "<%S> ", n->string); + dr_fstrs_push_new(arena, &result, ¶ms, string, .color = ui_color_from_name(str8_lit("text"))); + } + } + + // rjf: push file name + dr_fstrs_push_new(arena, &result, ¶ms, push_str8_copy(arena, str8_skip_last_slash(file_path))); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: cfg has expression attached -> use that + else if(expr_string.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, expr_string, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: push text location + if(loc.file_path.size != 0) + { + String8 location_string = push_str8f(arena, "%S:%I64d:%I64d", str8_skip_last_slash(loc.file_path), loc.pt.line, loc.pt.column); + dr_fstrs_push_new(arena, &result, ¶ms, location_string); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: push address location + if(loc.expr.size != 0) + { + RD_Font(RD_FontSlot_Code) + { + DR_FStrList fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, params.color, loc.expr); + dr_fstrs_concat_in_place(&result, &fstrs); + } + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: push target executable name + if(target.exe.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_skip_last_slash(target.exe)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: push target arguments + if(target.args.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, target.args); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push conditions + { + String8 condition = rd_cfg_child_from_string(cfg, str8_lit("condition"))->first->string; + if(condition.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("if "), .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); + RD_Font(RD_FontSlot_Code) + { + DR_FStrList fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, params.color, condition); + dr_fstrs_concat_in_place(&result, &fstrs); + } + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + } + + //- rjf: push disabled marker + if(is_disabled) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("(Disabled)")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push hit count + { + String8 hit_count_value_string = rd_cfg_child_from_string(cfg, str8_lit("hit_count"))->first->string; + U64 hit_count = 0; + if(try_u64_from_str8_c_rules(hit_count_value_string, &hit_count) && hit_count != 0) + { + String8 hit_count_text = push_str8f(arena, "(%I64u hit%s)", hit_count, hit_count == 1 ? "" : "s"); + dr_fstrs_push_new(arena, &result, ¶ms, hit_count_text); + } + } + + //- rjf: special case: auto view rule + if(str8_match(cfg->string, str8_lit("auto_view_rule"), 0)) + { + String8 src_string = rd_cfg_child_from_string(cfg, str8_lit("type"))->first->string; + String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("view_rule"))->first->string; + Vec4F32 src_color = rgba; + Vec4F32 dst_color = rgba; + DR_FStrList src_fstrs = {0}; + DR_FStrList dst_fstrs = {0}; + if(src_string.size == 0) + { + src_string = str8_lit("(type)"); + src_color = rgba_secondary; + dr_fstrs_push_new(arena, &src_fstrs, ¶ms, src_string, .color = src_color); + } + else RD_Font(RD_FontSlot_Code) + { + src_fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, src_color, src_string); + } + if(dst_string.size == 0) + { + dst_string = str8_lit("(view rule)"); + dst_color = rgba_secondary; + dr_fstrs_push_new(arena, &dst_fstrs, ¶ms, dst_string, .color = dst_color); + } + else RD_Font(RD_FontSlot_Code) + { + dst_fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, dst_color, dst_string); + } + dr_fstrs_concat_in_place(&result, &src_fstrs); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&result, &dst_fstrs); + } + + //- rjf: special case: file path maps + if(str8_match(cfg->string, str8_lit("file_path_map"), 0)) + { + String8 src_string = rd_cfg_child_from_string(cfg, str8_lit("source"))->first->string; + String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("dest"))->first->string; + Vec4F32 src_color = rgba; + Vec4F32 dst_color = rgba; + if(src_string.size == 0) + { + src_string = str8_lit("(source path)"); + src_color = rgba_secondary; + } + if(dst_string.size == 0) + { + dst_string = str8_lit("(destination path)"); + dst_color = rgba_secondary; + } + dr_fstrs_push_new(arena, &result, ¶ms, src_string, .color = src_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, dst_string, .color = dst_color); + } + +#undef start_secondary + scratch_end(scratch); + } + return result; +} + +internal DR_FStrList +rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_extras) +{ + DR_FStrList result = {0}; + + //- rjf: unpack entity info + F32 extras_size = ui_top_font_size()*0.95f; + Vec4F32 color = rd_color_from_ctrl_entity(entity); + if(color.w == 0) + { + color = ui_color_from_name(str8_lit("text")); + } + Vec4F32 secondary_color = color; + UI_TagF("weak") + { + secondary_color = ui_color_from_name(str8_lit("text")); + } + String8 name = rd_name_from_ctrl_entity(arena, entity); + RD_IconKind icon_kind = RD_IconKind_Null; + B32 name_is_code = 0; + switch(entity->kind) + { + default:{}break; + case CTRL_EntityKind_Machine: {icon_kind = RD_IconKind_Machine;}break; + case CTRL_EntityKind_Process: {icon_kind = RD_IconKind_Threads;}break; + case CTRL_EntityKind_Thread: {icon_kind = RD_IconKind_Thread; name_is_code = 1;}break; + case CTRL_EntityKind_Module: {icon_kind = RD_IconKind_Module;}break; + } + + //- rjf: set up drawing params + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Code), rd_raster_flags_from_slot(RD_FontSlot_Code), color, ui_top_font_size()}; + + //- rjf: push icon + if(icon_kind != RD_IconKind_Null) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push frozen icon, if frozen + if((entity->kind == CTRL_EntityKind_Machine || + entity->kind == CTRL_EntityKind_Process || + entity->kind == CTRL_EntityKind_Thread) && + ctrl_entity_tree_is_frozen(entity)) + UI_TagF("bad") + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Locked], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_color_from_name(str8_lit("text"))); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push selected icon, if selected thread + if(entity->kind == CTRL_EntityKind_Thread) + { + B32 is_selected = ctrl_handle_match(entity->handle, rd_base_regs()->thread); + if(is_selected) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + } + + //- rjf: push containing process prefix + if(entity->kind == CTRL_EntityKind_Thread || + entity->kind == CTRL_EntityKind_Module) + { + CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + if(processes.count > 1) + { + CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); + String8 process_name = rd_name_from_ctrl_entity(arena, process); + Vec4F32 process_color = rd_color_from_ctrl_entity(process); + if(process_color.w == 0) + { + process_color = ui_color_from_name(str8_lit("text")); + } + if(process_name.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, process_name, .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = process_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, "(PID: %I64u)", process->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = ui_top_font_size()*0.9f); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" / "), .color = secondary_color); + } + } + } + + //- rjf: push name + dr_fstrs_push_new(arena, &result, ¶ms, name, + .font = rd_font_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), + .raster_flags = rd_raster_flags_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), + .color = color); + + //- rjf: push PID + if(entity->kind == CTRL_EntityKind_Process) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, " (PID: %I64u)", entity->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = ui_top_font_size()*0.85f); + } + + //- rjf: threads get callstack extras + if(entity->kind == CTRL_EntityKind_Thread && include_extras) + { + Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + DI_Scope *di_scope = di_scope_open(); + CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); + Arch arch = entity->arch; + CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); + for(U64 idx = 0, limit = 6; idx < unwind.frames.count && idx < limit; idx += 1) + { + CTRL_UnwindFrame *f = &unwind.frames.v[unwind.frames.count - 1 - idx]; + U64 rip_vaddr = regs_rip_from_arch_block(arch, f->regs); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); + U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); + if(rdi != &di_rdi_parsed_nil) + { + RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, rip_voff); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); + name = push_str8_copy(arena, name); + if(name.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, name, .size = extras_size, .color = symbol_color); + if(idx+1 < unwind.frames.count) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" > "), .color = secondary_color, .size = extras_size); + if(idx+1 == limit) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("..."), .color = secondary_color, .size = extras_size); + } + } + } + } + } + di_scope_close(di_scope); + } + + //- rjf: modules get debug info status extras + if(entity->kind == CTRL_EntityKind_Module && include_extras) + { + DI_Scope *di_scope = di_scope_open(); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(entity); + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); + if(rdi->raw_data_size == 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("(Symbols not found)"), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .size = extras_size, .color = secondary_color); + } + di_scope_close(di_scope); + } + + return result; +} + +internal DR_FStrList +rd_title_fstrs_from_code_name(Arena *arena, String8 code_name) +{ + DR_FStrList result = {0}; + { + RD_VocabInfo *info = rd_vocab_info_from_code_name(code_name); + + //- rjf: set up color/size for all parts of the title + // + // the "running" part implies that it changes as things are added - + // so if a primary title is pushed, we can make the rest of the title + // more faded/smaller, but only after a primary title is pushed, + // which could be caused by many different potential parts of a cfg. + // + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + + //- rjf: push icon + if(info->icon_kind != RD_IconKind_Null) UI_Tag(str8_lit("weak")) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[info->icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_color_from_name(str8_lit("text"))); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push display name + if(info->display_name.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, info->display_name); + } + + //- rjf: push code name as a fallback + else + { + dr_fstrs_push_new(arena, &result, ¶ms, code_name, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); + } + } + return result; +} + +internal DR_FStrList +rd_title_fstrs_from_file_path(Arena *arena, String8 file_path) +{ + DR_FStrList fstrs = {0}; + String8 file_name = str8_skip_last_slash(file_path); + FileProperties props = os_properties_from_file_path(file_path); + RD_IconKind icon_kind = RD_IconKind_FileOutline; + if(props.flags & FilePropertyFlag_IsFolder) + { + icon_kind = RD_IconKind_FolderClosedFilled; + } + if(file_path.size == 0 || str8_match(file_path, str8_lit("/"), StringMatchFlag_SlashInsensitive)) + { + icon_kind = RD_IconKind_Machine; + file_name = str8_lit("File System"); + } + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + UI_TagF("weak") + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, + rd_icon_kind_text_table[icon_kind], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), + .color = ui_color_from_name(str8_lit("text"))); + } + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + return fstrs; +} + //////////////////////////////// //~ rjf: UI Widgets: Loading Overlay internal void rd_loading_overlay(Rng2F32 rect, F32 loading_t, U64 progress_v, U64 progress_v_target) { - if(loading_t >= 0.001f) + if(loading_t >= 0.001f) UI_Focus(UI_FocusKind_Off) { // rjf: set up dimensions F32 edge_padding = 30.f; @@ -18,19 +626,8 @@ rd_loading_overlay(Rng2F32 rect, F32 loading_t, U64 progress_v, U64 progress_v_t F32 t = pow_f32(sin_f32((F32)rd_state->time_in_seconds / 1.8f), 2.f); F64 v = 1.f - abs_f32(0.5f - t); - // rjf: colors - Vec4F32 bg_color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackground); - Vec4F32 bd_color = rd_rgba_from_theme_color(RD_ThemeColor_FloatingBorder); - Vec4F32 hl_color = rd_rgba_from_theme_color(RD_ThemeColor_TextNeutral); - bg_color.w *= loading_t; - bd_color.w *= loading_t; - hl_color.w *= loading_t; - - // rjf: grab animation params - F32 bg_work_indicator_t = 1.f; - // rjf: build indicator - UI_CornerRadius(height/3.f) + UI_CornerRadius(height/3.f) UI_Transparency(1-loading_t) { // rjf: rects Rng2F32 indicator_region_rect = @@ -48,42 +645,35 @@ rd_loading_overlay(Rng2F32 rect, F32 loading_t, U64 progress_v, U64 progress_v_t indicator_rect = pad_2f32(indicator_rect, -1.f); // rjf: does the view have loading *progress* info? -> draw extra progress layer - if(progress_v != progress_v_target) + if(progress_v != progress_v_target) UI_TagF("drop_site") { F64 pct_done_f64 = ((F64)progress_v/(F64)progress_v_target); F32 pct_done = (F32)pct_done_f64; - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = v4f32(1, 1, 1, 0.2f*loading_t))); - ui_set_next_fixed_x(indicator_region_rect.x0); - ui_set_next_fixed_y(indicator_region_rect.y0); - ui_set_next_fixed_width(dim_2f32(indicator_region_rect).x*pct_done); - ui_set_next_fixed_height(dim_2f32(indicator_region_rect).y); - ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + Rng2F32 pct_rect = r2f32p(indicator_region_rect.x0, + indicator_region_rect.y0, + indicator_region_rect.x0 + (indicator_region_rect.x1 - indicator_region_rect.x0)*pct_done, + indicator_region_rect.y1); + UI_Rect(pct_rect) + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_Floating, ui_key_zero()); } // rjf: fill - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = hl_color)); - ui_set_next_fixed_x(indicator_rect.x0); - ui_set_next_fixed_y(indicator_rect.y0); - ui_set_next_fixed_width(dim_2f32(indicator_rect).x); - ui_set_next_fixed_height(dim_2f32(indicator_rect).y); - ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + UI_TagF("pop") UI_Rect(indicator_rect) + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_Floating, ui_key_zero()); // rjf: animated bar - ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = bd_color, .background = bg_color)); - ui_set_next_fixed_x(indicator_region_rect.x0); - ui_set_next_fixed_y(indicator_region_rect.y0); - ui_set_next_fixed_width(dim_2f32(indicator_region_rect).x); - ui_set_next_fixed_height(dim_2f32(indicator_region_rect).y); - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder|UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY|UI_BoxFlag_Clickable, "bg_system_status"); - UI_Signal sig = ui_signal_from_box(box); + UI_Rect(indicator_region_rect) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder|UI_BoxFlag_Floating|UI_BoxFlag_Clickable, "bg_system_status"); + UI_Signal sig = ui_signal_from_box(box); + } } // rjf: build background - UI_WidthFill UI_HeightFill + UI_WidthFill UI_HeightFill UI_Transparency(1-loading_t) UI_BlurSize(10.f*loading_t) { - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = bg_color)); ui_set_next_blur_size(10.f*loading_t); - ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_Floating, ui_key_zero()); } } } @@ -95,26 +685,27 @@ internal void rd_cmd_binding_buttons(String8 name) { Temp scratch = scratch_begin(0, 0); - RD_BindingList bindings = rd_bindings_from_name(scratch.arena, name); + RD_KeyMapNodePtrList key_map_nodes = rd_key_map_node_ptr_list_from_name(scratch.arena, name); //- rjf: build buttons for each binding - for(RD_BindingNode *n = bindings.first; n != 0; n = n->next) + for(RD_KeyMapNodePtr *n = key_map_nodes.first; n != 0; n = n->next) { - RD_Binding binding = n->binding; + RD_Binding binding = n->v->binding; B32 rebinding_active_for_this_binding = (rd_state->bind_change_active && str8_match(rd_state->bind_change_cmd_name, name, 0) && - rd_state->bind_change_binding.key == binding.key && - rd_state->bind_change_binding.modifiers == binding.modifiers); + n->v->cfg_id == rd_state->bind_change_binding_id); //- rjf: grab all conflicts - String8List specs_with_binding = rd_cmd_name_list_from_binding(scratch.arena, binding); B32 has_conflicts = 0; - for(String8Node *n = specs_with_binding.first; n != 0; n = n->next) + RD_KeyMapNodePtrList nodes_with_this_binding = rd_key_map_node_ptr_list_from_binding(scratch.arena, binding); { - if(!str8_match(n->string, name, 0)) + for(RD_KeyMapNodePtr *n2 = nodes_with_this_binding.first; n2 != 0; n2 = n2->next) { - has_conflicts = 1; - break; + if(!str8_match(n->v->name, n2->v->name, 0)) + { + has_conflicts = 1; + break; + } } } @@ -136,29 +727,10 @@ rd_cmd_binding_buttons(String8 name) } } - //- rjf: form color palette - UI_Palette *palette = ui_top_palette(); - if(has_conflicts || rebinding_active_for_this_binding) - { - palette = push_array(ui_build_arena(), UI_Palette, 1); - MemoryCopyStruct(palette, ui_top_palette()); - if(has_conflicts) - { - palette->colors[UI_ColorCode_Text] = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative); - palette->colors[UI_ColorCode_TextWeak] = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative); - } - if(rebinding_active_for_this_binding) - { - palette->colors[UI_ColorCode_Border] = rd_rgba_from_theme_color(RD_ThemeColor_Focus); - palette->colors[UI_ColorCode_Background] = rd_rgba_from_theme_color(RD_ThemeColor_Focus); - palette->colors[UI_ColorCode_Background].w *= 0.25f; - } - } - //- rjf: build box + ui_set_next_tag(has_conflicts ? str8_lit("bad_pop") : rebinding_active_for_this_binding ? str8_lit("pop") : str8_zero()); ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_text_alignment(UI_TextAlign_Center); - ui_set_next_palette(palette); ui_set_next_group_key(ui_key_zero()); ui_set_next_pref_width(ui_text_dim(ui_top_font_size()*1.f, 1)); UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| @@ -184,7 +756,7 @@ rd_cmd_binding_buttons(String8 name) arena_clear(rd_state->bind_change_arena); rd_state->bind_change_active = 1; rd_state->bind_change_cmd_name = push_str8_copy(rd_state->bind_change_arena, name); - rd_state->bind_change_binding = binding; + rd_state->bind_change_binding_id = n->v->cfg_id; } } else if(rd_state->bind_change_active && ui_clicked(sig)) @@ -196,12 +768,12 @@ rd_cmd_binding_buttons(String8 name) if(ui_hovering(sig) && has_conflicts) UI_Tooltip { UI_PrefWidth(ui_children_sum(1)) rd_error_label(str8_lit("This binding conflicts with those for:")); - for(String8Node *n = specs_with_binding.first; n != 0; n = n->next) + for(RD_KeyMapNodePtr *n2 = nodes_with_this_binding.first; n2 != 0; n2 = n2->next) { - if(!str8_match(n->string, name, 0)) + if(!str8_match(n2->v->name, n->v->name, 0)) { - RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(n->string); - ui_labelf("%S", info->display_name); + String8 display_name = rd_display_from_code_name(n2->v->name); + ui_labelf("%S", display_name); } } } @@ -210,16 +782,13 @@ rd_cmd_binding_buttons(String8 name) //- rjf: delete button if(rebinding_active_for_this_binding) UI_PrefWidth(ui_em(2.5f, 1.f)) - UI_Palette(ui_build_palette(ui_top_palette(), - .background = rd_rgba_from_theme_color(RD_ThemeColor_NegativePopButtonBackground), - .border = rd_rgba_from_theme_color(RD_ThemeColor_NegativePopButtonBorder), - .text = rd_rgba_from_theme_color(RD_ThemeColor_Text))) + UI_TagF("bad_pop") { ui_set_next_group_key(ui_key_zero()); UI_Signal sig = rd_icon_button(RD_IconKind_X, 0, str8_lit("###delete_binding")); if(ui_clicked(sig)) { - rd_unbind_name(name, binding); + rd_cfg_release(rd_cfg_from_id(rd_state->bind_change_binding_id)); rd_state->bind_change_active = 0; } } @@ -229,25 +798,15 @@ rd_cmd_binding_buttons(String8 name) } //- rjf: build "add new binding" button - RD_Font(RD_FontSlot_Icons) + B32 adding_new_binding = (rd_state->bind_change_active && + str8_match(rd_state->bind_change_cmd_name, name, 0) && + rd_state->bind_change_binding_id == 0); + RD_Font(RD_FontSlot_Icons) UI_TagF(adding_new_binding ? "pop" : "") { - UI_Palette *palette = ui_top_palette(); - B32 adding_new_binding = (rd_state->bind_change_active && - str8_match(rd_state->bind_change_cmd_name, name, 0) && - rd_state->bind_change_binding.key == OS_Key_Null && - rd_state->bind_change_binding.modifiers == 0); - if(adding_new_binding) - { - palette = ui_build_palette(ui_top_palette()); - palette->colors[UI_ColorCode_Border] = rd_rgba_from_theme_color(RD_ThemeColor_Focus); - palette->colors[UI_ColorCode_Background] = rd_rgba_from_theme_color(RD_ThemeColor_Focus); - palette->colors[UI_ColorCode_Background].w *= 0.25f; - } ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_text_alignment(UI_TextAlign_Center); ui_set_next_group_key(ui_key_zero()); ui_set_next_pref_width(ui_text_dim(ui_top_font_size()*1.f, 1)); - ui_set_next_palette(palette); UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| UI_BoxFlag_Clickable| UI_BoxFlag_DrawActiveEffects| @@ -263,7 +822,7 @@ rd_cmd_binding_buttons(String8 name) arena_clear(rd_state->bind_change_arena); rd_state->bind_change_active = 1; rd_state->bind_change_cmd_name = push_str8_copy(rd_state->bind_change_arena, name); - MemoryZeroStruct(&rd_state->bind_change_binding); + rd_state->bind_change_binding_id = 0; } else if(rd_state->bind_change_active && ui_clicked(sig)) { @@ -298,13 +857,13 @@ rd_cmd_spec_button(String8 name) "###cmd_%p", info); UI_Parent(box) UI_HeightFill UI_Padding(ui_em(1.f, 1.f)) { - RD_IconKind canonical_icon = info->icon_kind; + RD_IconKind canonical_icon = rd_icon_kind_from_code_name(name); if(canonical_icon != RD_IconKind_Null) { RD_Font(RD_FontSlot_Icons) UI_PrefWidth(ui_em(2.f, 1.f)) UI_TextAlignment(UI_TextAlign_Center) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") { ui_label(rd_icon_kind_text_table[canonical_icon]); } @@ -313,14 +872,14 @@ rd_cmd_spec_button(String8 name) { UI_Flags(UI_BoxFlag_DrawTextFastpathCodepoint) UI_FastpathCodepoint(box->fastpath_codepoint) - ui_label(info->display_name); + ui_label(rd_display_from_code_name(name)); ui_spacer(ui_pct(1, 0)); ui_set_next_flags(UI_BoxFlag_Clickable); ui_set_next_group_key(ui_key_zero()); UI_PrefWidth(ui_children_sum(1)) UI_FontSize(ui_top_font_size()*0.95f) UI_HeightFill UI_NamedRow(str8_lit("###bindings")) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") UI_FastpathCodepoint(0) { rd_cmd_binding_buttons(name); @@ -343,8 +902,9 @@ rd_cmd_list_menu_buttons(U64 count, String8 *cmd_names, U32 *fastpath_codepoints { rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cmd_names[idx]); ui_ctx_menu_close(); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - window->menu_bar_focused = 0; + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + ws->menu_bar_focused = 0; } } scratch_end(scratch); @@ -376,7 +936,8 @@ rd_icon_button(RD_IconKind kind, FuzzyMatchRangeList *matches, String8 string) RD_Font(RD_FontSlot_Icons) UI_PrefWidth(ui_em(2.f, 1.f)) UI_PrefHeight(ui_pct(1, 0)) - UI_FlagsAdd(UI_BoxFlag_DisableTextTrunc|UI_BoxFlag_DrawTextWeak) + UI_FlagsAdd(UI_BoxFlag_DisableTextTrunc) + UI_TagF("weak") ui_label(rd_icon_kind_text_table[kind]); if(display_string.size != 0) { @@ -464,7 +1025,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_thread_box_draw_extensions) if(u->hover_t > 0.001f) { Vec4F32 weak_thread_color = u->thread_color; - weak_thread_color.w *= 0.5f*u->hover_t; + weak_thread_color.w *= 0.15f*u->hover_t; R_Rect2DInst *inst = dr_rect(r2f32p(box->rect.x0, box->parent->rect.y0, box->rect.x0 + ui_top_font_size()*22.f*u->hover_t, @@ -478,7 +1039,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_thread_box_draw_extensions) if(u->is_selected && u->do_glow) { Vec4F32 weak_thread_color = u->thread_color; - weak_thread_color.w *= 0.3f; + weak_thread_color.w *= 0.1f; R_Rect2DInst *inst = dr_rect(r2f32p(box->rect.x0, box->parent->rect.y0, box->rect.x0 + ui_top_font_size()*22.f*u->alive_t, @@ -489,15 +1050,15 @@ internal UI_BOX_CUSTOM_DRAW(rd_thread_box_draw_extensions) } // rjf: locked icon on frozen threads - if(u->is_frozen) + if(u->is_frozen) UI_TagF("bad") { F32 lock_icon_off = ui_top_font_size()*0.2f; - Vec4F32 lock_icon_color = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative); + Vec4F32 color = ui_color_from_name(str8_lit("text")); dr_text(rd_font_from_slot(RD_FontSlot_Icons), box->font_size, 0, 0, FNT_RasterFlag_Smooth, v2f32((box->rect.x0 + box->rect.x1)/2 + lock_icon_off/2, box->rect.y0 + lock_icon_off/2), - lock_icon_color, + color, rd_icon_kind_text_table[RD_IconKind_Locked]); } } @@ -511,6 +1072,8 @@ struct RD_BreakpointBoxDrawExtData F32 remap_px_delta; B32 do_lines; B32 do_glow; + B32 is_disabled; + B32 is_conditioned; }; internal UI_BOX_CUSTOM_DRAW(rd_bp_box_draw_extensions) @@ -580,6 +1143,33 @@ internal UI_BOX_CUSTOM_DRAW(rd_bp_box_draw_extensions) remap_color, rd_icon_kind_text_table[RD_IconKind_CircleFilled]); } + + // rjf: draw conditioned marker + if(u->is_conditioned) UI_TagF(u->is_disabled ? "weak" : "") + { + Temp scratch = scratch_begin(0, 0); + Vec4F32 color = ui_color_from_name(str8_lit("text")); + FNT_Run run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Code), box->font_size*0.8f, 0, 0, FNT_RasterFlag_Smooth, str8_lit("if")); + Vec2F32 p = center_2f32(box->rect); + p.x -= run.dim.x*0.5f; + p.y += run.descent; + dr_text_run(p, color, run); + scratch_end(scratch); + } + + // rjf: draw disabled marker + if(u->is_disabled) + { + Temp scratch = scratch_begin(0, 0); + Vec4F32 color = ui_color_from_name(str8_lit("breakpoint")); + FNT_Run run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Icons), box->font_size*0.95f, 0, 0, FNT_RasterFlag_Smooth, str8_lit("x")); + Vec2F32 box_dim = dim_2f32(box->rect); + Vec2F32 p = center_2f32(box->rect); + p.x += box_dim.x*0.1f; + p.y -= box_dim.y*0.2f; + dr_text_run(p, color, run); + scratch_end(scratch); + } } internal RD_CodeSliceSignal @@ -601,17 +1191,23 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe B32 ctrlified = (os_get_modifiers() & OS_Modifier_Ctrl); Vec4F32 code_line_bgs[] = { - rd_rgba_from_theme_color(RD_ThemeColor_LineInfoBackground0), - rd_rgba_from_theme_color(RD_ThemeColor_LineInfoBackground1), - rd_rgba_from_theme_color(RD_ThemeColor_LineInfoBackground2), - rd_rgba_from_theme_color(RD_ThemeColor_LineInfoBackground3), + ui_color_from_name(str8_lit("line_info_0")), + ui_color_from_name(str8_lit("line_info_1")), + ui_color_from_name(str8_lit("line_info_2")), + ui_color_from_name(str8_lit("line_info_3")), }; - UI_Palette *margin_palette = rd_palette_from_code(RD_PaletteCode_Floating); - UI_Palette *margin_contents_palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_Floating)); - 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_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; + B32 do_thread_lines = rd_setting_b32_from_name(str8_lit("thread_lines")); + B32 do_thread_glow = rd_setting_b32_from_name(str8_lit("thread_glow")); + B32 do_bp_lines = rd_setting_b32_from_name(str8_lit("breakpoint_lines")); + B32 do_bp_glow = rd_setting_b32_from_name(str8_lit("breakpoint_glow")); + Vec4F32 pop_color = {0}; + UI_TagF("pop") + { + pop_color = ui_color_from_name(str8_lit("background")); + } ////////////////////////////// //- rjf: build top-level container @@ -639,17 +1235,20 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe Vec4F32 *line_bg_colors = push_array(scratch.arena, Vec4F32, dim_1s64(params->line_num_range)+1); { //- rjf: color line with stopper-thread red - U64 line_idx = 0; - for(S64 line_num = params->line_num_range.min; - line_num < params->line_num_range.max; - line_num += 1, line_idx += 1) + UI_TagF("bad_pop") { - CTRL_EntityList threads = params->line_ips[line_idx]; - for(CTRL_EntityNode *n = threads.first; n != 0; n = n->next) + U64 line_idx = 0; + for(S64 line_num = params->line_num_range.min; + line_num < params->line_num_range.max; + line_num += 1, line_idx += 1) { - if(n->v == stopper_thread && (stop_event.cause == CTRL_EventCause_InterruptedByTrap || stop_event.cause == CTRL_EventCause_InterruptedByException)) + CTRL_EntityList threads = params->line_ips[line_idx]; + for(CTRL_EntityNode *n = threads.first; n != 0; n = n->next) { - line_bg_colors[line_idx] = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError); + if(n->v == stopper_thread && (stop_event.cause == CTRL_EventCause_InterruptedByTrap || stop_event.cause == CTRL_EventCause_InterruptedByException)) + { + line_bg_colors[line_idx] = ui_color_from_name(str8_lit("background")); + } } } } @@ -659,7 +1258,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: build priority margin // UI_Box *priority_margin_container_box = &ui_nil_box; - if(params->flags & RD_CodeSliceFlag_PriorityMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) UI_Palette(margin_palette) ProfScope("build priority margins") + if(params->flags & RD_CodeSliceFlag_PriorityMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build priority margins") { if(params->margin_float_off_px != 0) { @@ -672,7 +1271,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); ui_set_next_child_layout_axis(Axis2_Y); priority_margin_container_box = ui_build_box_from_string(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable), str8_lit("priority_margin_container")); - UI_Parent(priority_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) UI_Palette(margin_contents_palette) + UI_Parent(priority_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) { U64 line_idx = 0; for(S64 line_num = params->line_num_range.min; @@ -681,7 +1280,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { CTRL_EntityList line_ips = params->line_ips[line_idx]; ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num); + UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num); UI_Parent(line_margin_box) { //- rjf: build margin thread ip ui @@ -701,18 +1300,22 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); // rjf: thread info => color - Vec4F32 color = rd_rgba_from_ctrl_entity(thread); + Vec4F32 color = rd_color_from_ctrl_entity(thread); { + if(color.w == 0) + { + color = ui_color_from_name(str8_lit("thread_1")); + } if(unwind_count != 0) { - color = rd_rgba_from_theme_color(RD_ThemeColor_ThreadUnwound); + color = ui_color_from_name(str8_lit("thread_unwound")); } else if(thread == stopper_thread && (stop_event.cause == CTRL_EventCause_InterruptedByHalt || stop_event.cause == CTRL_EventCause_InterruptedByTrap || stop_event.cause == CTRL_EventCause_InterruptedByException)) { - color = rd_rgba_from_theme_color(RD_ThemeColor_ThreadError); + color = ui_color_from_name(str8_lit("thread_error")); } if(d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < d_frame_index()) { @@ -720,7 +1323,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } if(thread != selected_thread) { - color.w *= 0.8f; + color.w *= 0.5f; } } @@ -731,8 +1334,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_pct(1, 0)); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = color)); ui_set_next_text_alignment(UI_TextAlign_Center); + ui_set_next_text_color(color); UI_Key thread_box_key = ui_key_from_stringf(top_container_box->key, "###ip_%I64x_%p", line_num, thread); UI_Box *thread_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc| UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| @@ -744,16 +1347,16 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: custom draw { RD_Regs *hover_regs = rd_get_hover_regs(); - B32 is_hovering = (ctrl_handle_match(hover_regs->thread, thread->handle) && - rd_state->hover_regs_slot == RD_RegSlot_Thread); + B32 is_hovering = (ctrl_handle_match(hover_regs->ctrl_entity, thread->handle) && + rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity); RD_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), RD_ThreadBoxDrawExtData, 1); u->thread_color = color; - u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); - 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->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###entity_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); + u->hover_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###entity_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 @@ -785,11 +1388,14 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: interactions if(ui_hovering(thread_sig) && !rd_drag_is_active()) { - RD_RegsScope(.thread = thread->handle) rd_set_hover_regs(RD_RegSlot_Thread); + RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } if(ui_right_clicked(thread_sig)) { - RD_RegsScope(.thread = thread->handle) rd_open_ctx_menu(thread_box->key, v2f32(0, thread_box->rect.y1-thread_box->rect.y0), RD_RegSlot_Thread); + rd_cmd(RD_CmdKind_PushQuery, + .ui_key = thread_box->key, + .off_px = v2f32(0, dim_2f32(thread_box->rect).y), + .expr = ctrl_string_from_handle(scratch.arena, thread->handle)); } if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse())) { @@ -805,7 +1411,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: build catchall margin // UI_Box *catchall_margin_container_box = &ui_nil_box; - if(params->flags & RD_CodeSliceFlag_CatchallMargin) UI_Focus(UI_FocusKind_Off) UI_Palette(margin_palette) UI_Parent(top_container_box) ProfScope("build catchall margins") + if(params->flags & RD_CodeSliceFlag_CatchallMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build catchall margins") + UI_TagF("floating") { if(params->margin_float_off_px != 0) { @@ -817,8 +1424,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_pref_width(ui_px(params->catchall_margin_width_px, 1)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); ui_set_next_child_layout_axis(Axis2_Y); - catchall_margin_container_box = ui_build_box_from_string(UI_BoxFlag_DrawSideLeft|UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable), str8_lit("catchall_margin_container")); - UI_Parent(catchall_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) UI_Palette(margin_contents_palette) + catchall_margin_container_box = ui_build_box_from_string(UI_BoxFlag_DrawSideRight|UI_BoxFlag_DrawSideLeft|UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable), str8_lit("catchall_margin_container")); + UI_Parent(catchall_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) { U64 line_idx = 0; for(S64 line_num = params->line_num_range.min; @@ -826,9 +1433,10 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num += 1, line_idx += 1) { CTRL_EntityList line_ips = params->line_ips[line_idx]; - RD_EntityList line_bps = params->line_bps[line_idx]; - RD_EntityList line_pins = params->line_pins[line_idx]; + RD_CfgList line_bps = params->line_bps[line_idx]; + RD_CfgList line_pins = params->line_pins[line_idx]; ui_set_next_hover_cursor(OS_Cursor_HandPoint); + ui_set_next_background_color(v4f32(0, 0, 0, 0)); UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num); UI_Parent(line_margin_box) { @@ -849,18 +1457,22 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); // rjf: thread info => color - Vec4F32 color = rd_rgba_from_ctrl_entity(thread); + Vec4F32 color = rd_color_from_ctrl_entity(thread); { + if(color.w == 0) + { + color = ui_color_from_name(str8_lit("thread_1")); + } if(unwind_count != 0) { - color = rd_rgba_from_theme_color(RD_ThemeColor_ThreadUnwound); + color = ui_color_from_name(str8_lit("thread_unwound")); } else if(thread == stopper_thread && (stop_event.cause == CTRL_EventCause_InterruptedByHalt || stop_event.cause == CTRL_EventCause_InterruptedByTrap || stop_event.cause == CTRL_EventCause_InterruptedByException)) { - color = rd_rgba_from_theme_color(RD_ThemeColor_ThreadError); + color = ui_color_from_name(str8_lit("thread_error")); } if(d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < d_frame_index()) { @@ -879,8 +1491,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_pct(1, 0)); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = color)); ui_set_next_text_alignment(UI_TextAlign_Center); + ui_set_next_text_color(color); UI_Key thread_box_key = ui_key_from_stringf(top_container_box->key, "###ip_%I64x_catchall_%p", line_num, thread); UI_Box *thread_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc| UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| @@ -892,12 +1504,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: custom draw { RD_Regs *hover_regs = rd_get_hover_regs(); - B32 is_hovering = (ctrl_handle_match(hover_regs->thread, thread->handle) && - rd_state->hover_regs_slot == RD_RegSlot_Thread); + B32 is_hovering = (ctrl_handle_match(hover_regs->ctrl_entity, thread->handle) && + rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity); RD_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), RD_ThreadBoxDrawExtData, 1); u->thread_color = color; - u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); - 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->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###entity_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); + u->hover_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###entity_hover_t_%p", thread), (F32)!!is_hovering, .rate = entity_hover_t_rate); u->is_selected = (thread == selected_thread); u->is_frozen = !!thread->is_frozen; ui_box_equip_custom_draw(thread_box, rd_thread_box_draw_extensions, u); @@ -931,11 +1543,14 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: interactions if(ui_hovering(thread_sig) && !rd_drag_is_active()) { - RD_RegsScope(.thread = thread->handle) rd_set_hover_regs(RD_RegSlot_Thread); + RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } if(ui_right_clicked(thread_sig)) { - RD_RegsScope(.thread = thread->handle) rd_open_ctx_menu(thread_box->key, v2f32(0, thread_box->rect.y1-thread_box->rect.y0), RD_RegSlot_Thread); + rd_cmd(RD_CmdKind_PushQuery, + .ui_key = thread_box->key, + .off_px = v2f32(0, dim_2f32(thread_box->rect).y), + .expr = ctrl_string_from_handle(scratch.arena, thread->handle)); } if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse())) { @@ -949,29 +1564,32 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } //- rjf: build margin breakpoint ui - for(RD_EntityNode *n = line_bps.first; n != 0; n = n->next) + for(RD_CfgNode *n = line_bps.first; n != 0; n = n->next) { - RD_Entity *bp = n->entity; - Vec4F32 bp_color = rd_rgba_from_theme_color(RD_ThemeColor_Breakpoint); - if(bp->flags & RD_EntityFlag_HasColor) + RD_Cfg *bp = n->v; + Vec4F32 bp_rgba = rd_color_from_cfg(bp); + if(bp_rgba.w == 0) { - bp_color = rd_rgba_from_entity(bp); + bp_rgba = ui_color_from_name(str8_lit("breakpoint")); } - if(bp->disabled) + B32 bp_is_disabled = rd_disabled_from_cfg(bp); + if(bp_is_disabled) { - bp_color = v4f32(bp_color.x * 0.6f, bp_color.y * 0.6f, bp_color.z * 0.6f, bp_color.w * 0.6f); + bp_rgba = v4f32(bp_rgba.x*0.45f, bp_rgba.y*0.45f, bp_rgba.z*0.45f, bp_rgba.w*0.45f); } // rjf: prep custom rendering data RD_BreakpointBoxDrawExtData *bp_draw = push_array(ui_build_arena(), RD_BreakpointBoxDrawExtData, 1); { RD_Regs *hover_regs = rd_get_hover_regs(); - B32 is_hovering = (rd_entity_from_handle(hover_regs->entity) == bp && rd_state->hover_regs_slot == RD_RegSlot_Entity); - bp_draw->color = bp_color; - 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; + B32 is_hovering = (rd_cfg_from_id(hover_regs->cfg) == bp && rd_state->hover_regs_slot == RD_RegSlot_Cfg); + bp_draw->color = bp_rgba; + bp_draw->alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "cfg_alive_t_%p", bp), 1.f, .rate = entity_alive_t_rate); + bp_draw->hover_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "cfg_hover_t_%p", bp), (F32)!!is_hovering, .rate = entity_hover_t_rate); + bp_draw->do_lines = do_bp_lines; + bp_draw->do_glow = do_bp_glow; + bp_draw->is_disabled = bp_is_disabled; + bp_draw->is_conditioned = (rd_cfg_child_from_string(bp, str8_lit("condition"))->first->string.size != 0); if(params->line_vaddrs[line_idx] == 0) { D_LineList *lines = ¶ms->line_infos[line_idx]; @@ -992,8 +1610,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_font_size(params->font_size * 1.f); ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = bp_color)); ui_set_next_text_alignment(UI_TextAlign_Center); + ui_set_next_text_color(bp_rgba); UI_Box *bp_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| UI_BoxFlag_DisableTextTrunc, @@ -1006,42 +1624,45 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: bp hovering if(ui_hovering(bp_sig) && !rd_drag_is_active()) { - RD_RegsScope(.entity = rd_handle_from_entity(bp)) rd_set_hover_regs(RD_RegSlot_Entity); + RD_RegsScope(.cfg = bp->id) rd_set_hover_regs(RD_RegSlot_Cfg); + } + + // rjf: bp right-click => open query + if(ui_right_clicked(bp_sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .ui_key = bp_box->key, + .off_px = v2f32(0, dim_2f32(bp_box->rect).y), + .expr = push_str8f(scratch.arena, "$%I64x", bp->id)); } // rjf: shift+click => enable breakpoint if(ui_clicked(bp_sig) && bp_sig.event_flags & OS_Modifier_Shift) { - rd_cmd(bp->disabled ? RD_CmdKind_EnableEntity : RD_CmdKind_DisableEntity, .entity = rd_handle_from_entity(bp)); + rd_cmd(bp_is_disabled ? RD_CmdKind_EnableCfg : RD_CmdKind_DisableCfg, .cfg = bp->id); } // rjf: click => remove breakpoint if(ui_clicked(bp_sig) && bp_sig.event_flags == 0) { - rd_cmd(RD_CmdKind_RemoveEntity, .entity = rd_handle_from_entity(bp)); + rd_cmd(RD_CmdKind_RemoveCfg, .cfg = bp->id); } // rjf: drag start if(ui_dragging(bp_sig) && !contains_2f32(bp_box->rect, ui_mouse())) { - RD_RegsScope(.entity = rd_handle_from_entity(bp)) rd_drag_begin(RD_RegSlot_Entity); - } - - // rjf: bp right-click menu - if(ui_right_clicked(bp_sig)) - { - RD_RegsScope(.entity = rd_handle_from_entity(bp)) rd_open_ctx_menu(bp_box->key, v2f32(0, bp_box->rect.y1-bp_box->rect.y0), RD_RegSlot_Entity); + RD_RegsScope(.cfg = bp->id) rd_drag_begin(RD_RegSlot_Cfg); } } //- rjf: build margin watch pin ui - for(RD_EntityNode *n = line_pins.first; n != 0; n = n->next) + for(RD_CfgNode *n = line_pins.first; n != 0; n = n->next) { - RD_Entity *pin = n->entity; - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Text); - if(pin->flags & RD_EntityFlag_HasColor) + RD_Cfg *pin = n->v; + Vec4F32 color = rd_color_from_cfg(pin); + if(color.w == 0) { - color = rd_rgba_from_entity(pin); + color = ui_color_from_name(str8_lit("code_default")); } // rjf: build box for watch @@ -1049,8 +1670,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_font_size(params->font_size * 1.f); ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = color)); ui_set_next_text_alignment(UI_TextAlign_Center); + ui_set_next_text_color(color); UI_Box *pin_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| UI_BoxFlag_DisableTextTrunc, @@ -1062,25 +1683,28 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: watch hovering if(ui_hovering(pin_sig) && !rd_drag_is_active()) { - RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_set_hover_regs(RD_RegSlot_Entity); + RD_RegsScope(.cfg = pin->id) rd_set_hover_regs(RD_RegSlot_Cfg); + } + + // rjf: pin right-click => open query + if(ui_right_clicked(pin_sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .ui_key = pin_box->key, + .off_px = v2f32(0, dim_2f32(pin_box->rect).y), + .expr = push_str8f(scratch.arena, "$%I64x", pin->id)); } // rjf: click => remove pin if(ui_clicked(pin_sig)) { - rd_cmd(RD_CmdKind_RemoveEntity, .entity = rd_handle_from_entity(pin)); + rd_cmd(RD_CmdKind_RemoveCfg, .cfg = pin->id); } // rjf: drag start if(ui_dragging(pin_sig) && !contains_2f32(pin_box->rect, ui_mouse())) { - RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_drag_begin(RD_RegSlot_Entity); - } - - // rjf: watch right-click menu - if(ui_right_clicked(pin_sig)) - { - RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_open_ctx_menu(pin_box->key, v2f32(0, pin_box->rect.y1-pin_box->rect.y0), RD_RegSlot_Entity); + RD_RegsScope(.cfg = pin->id) rd_drag_begin(RD_RegSlot_Cfg); } } } @@ -1102,6 +1726,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: build line numbers // if(params->flags & RD_CodeSliceFlag_LineNums) UI_Parent(top_container_box) ProfScope("build line numbers") UI_Focus(UI_FocusKind_Off) + UI_TagF("floating") { TxtRng select_rng = txt_rng(*cursor, *mark); Vec4F32 active_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeLineNumbersSelected); @@ -1109,7 +1734,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_fixed_x(floor_f32(params->margin_float_off_px + params->priority_margin_width_px + params->catchall_margin_width_px)); ui_set_next_pref_width(ui_px(params->line_num_width_px, 1.f)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); - ui_set_next_flags(UI_BoxFlag_DrawSideLeft|UI_BoxFlag_DrawSideRight); + ui_set_next_flags(UI_BoxFlag_DrawSideRight); UI_Column UI_PrefHeight(ui_px(params->line_height_px, 1.f)) RD_Font(RD_FontSlot_Code) @@ -1150,8 +1775,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } // rjf: build line num box - ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = text_color, .background = bg_color)); - ui_build_box_from_stringf(UI_BoxFlag_DrawText|(UI_BoxFlag_DrawBackground*!!has_line_info), "%I64u##line_num", line_num); + UI_TextColor(text_color) UI_BackgroundColor(bg_color) + ui_build_box_from_stringf(UI_BoxFlag_DrawText|(UI_BoxFlag_DrawBackground*!!has_line_info), "%I64u##line_num", line_num); } } } @@ -1160,7 +1785,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: build background for line numbers & margins // { - UI_Parent(top_container_box) RD_Palette(RD_PaletteCode_Floating) + UI_Parent(top_container_box) UI_TagF("floating") { ui_set_next_pref_width(ui_px(params->priority_margin_width_px + params->catchall_margin_width_px + params->line_num_width_px, 1)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); @@ -1191,8 +1816,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num += 1, line_idx += 1) { String8 line_text = params->line_text[line_idx]; - F32 line_text_dim = fnt_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, line_text).x + params->line_num_width_px; - line_extras_off[line_idx] = Max(line_text_dim, params->font_size*50); + F32 line_text_dim = fnt_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, line_text).x + params->line_num_width_px + params->catchall_margin_width_px + params->priority_margin_width_px; + line_extras_off[line_idx] = Max(line_text_dim, params->font_size*30); } } @@ -1231,12 +1856,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe (stop_event.cause == CTRL_EventCause_InterruptedByException || stop_event.cause == CTRL_EventCause_InterruptedByTrap)) { - DR_FancyStringList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); - UI_Parent(line_extras_boxes[line_idx]) UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) + DR_FStrList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); + UI_Parent(line_extras_boxes[line_idx]) UI_PrefWidth(ui_text_dim(10, 1)) UI_TextAlignment(UI_TextAlign_Center) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) + UI_TagF("bad_pop") { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "###exception_info"); - ui_box_equip_display_fancy_strings(box, &explanation_fstrs); + ui_box_equip_display_fstrs(box, &explanation_fstrs); } } } @@ -1254,22 +1879,23 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num < params->line_num_range.max; line_num += 1, line_idx += 1) { - RD_EntityList pins = params->line_pins[line_idx]; + RD_CfgList pins = params->line_pins[line_idx]; if(pins.count != 0) UI_Parent(line_extras_boxes[line_idx]) RD_Font(RD_FontSlot_Code) UI_FontSize(params->font_size) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) { - for(RD_EntityNode *n = pins.first; n != 0; n = n->next) + for(RD_CfgNode *n = pins.first; n != 0; n = n->next) { - RD_Entity *pin = n->entity; - String8 pin_expr = pin->string; - E_Eval eval = e_eval_from_string(scratch.arena, pin_expr); + RD_Cfg *pin = n->v; + String8 pin_expr = rd_expr_from_cfg(pin); + String8 pin_view_rule = rd_view_rule_from_cfg(pin); + String8 full_pin_expr = push_str8f(scratch.arena, "%S => %S", pin_expr, pin_view_rule); + E_Eval eval = e_eval_from_string(scratch.arena, full_pin_expr); String8 eval_string = {0}; - if(!e_type_key_match(e_type_key_zero(), eval.type_key)) + if(!e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) { - EV_ViewRuleList view_rules = {0}; - eval_string = rd_value_string_from_eval(scratch.arena, EV_StringFlag_ReadOnlyDisplayRules, 10, params->font, params->font_size, params->font_size*60.f, eval, &e_member_nil, &view_rules); + eval_string = rd_value_string_from_eval(scratch.arena, str8_zero(), EV_StringFlag_ReadOnlyDisplayRules, 10, params->font, params->font_size, params->font_size*60.f, eval); } ui_spacer(ui_em(1.5f, 1.f)); ui_set_next_pref_width(ui_children_sum(1)); @@ -1280,25 +1906,21 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_BoxFlag_DrawBorder, pin_box_key); UI_Parent(pin_box) UI_PrefWidth(ui_text_dim(10, 1)) { - Vec4F32 pin_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); - if(pin->flags & RD_EntityFlag_HasColor) + Vec4F32 pin_color = rd_color_from_cfg(pin); + if(pin_color.w == 0) { - pin_color = rd_rgba_from_entity(pin); + pin_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); } UI_PrefWidth(ui_em(1.5f, 1.f)) RD_Font(RD_FontSlot_Icons) - UI_Palette(ui_build_palette(ui_top_palette(), .text = pin_color)) UI_TextAlignment(UI_TextAlign_Center) UI_Flags(UI_BoxFlag_DisableTextTrunc) + UI_TextColor(pin_color) { UI_Signal sig = ui_buttonf("%S###pin_nub", rd_icon_kind_text_table[RD_IconKind_Pin]); if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) { - RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_drag_begin(RD_RegSlot_Entity); - } - if(ui_right_clicked(sig)) - { - RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_open_ctx_menu(sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0), RD_RegSlot_Entity); + RD_RegsScope(.cfg = pin->id) rd_drag_begin(RD_RegSlot_Cfg); } } rd_code_label(0.8f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), pin_expr); @@ -1307,7 +1929,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_Signal pin_sig = ui_signal_from_box(pin_box); if(ui_key_match(pin_box_key, ui_hot_key())) { - rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), str8_zero(), txt_pt(1, 1), 0, pin_expr); + rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), pin_expr, pin_view_rule); } } } @@ -1380,13 +2002,14 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ////////////////////////////// //- rjf: interact with margin box & text box // + B32 search_query_invalidated = 0; UI_Signal priority_margin_container_sig = ui_signal_from_box(priority_margin_container_box); UI_Signal catchall_margin_container_sig = ui_signal_from_box(catchall_margin_container_box); UI_Signal text_container_sig = ui_signal_from_box(text_container_box); B32 line_drag_drop = 0; - RD_Entity *line_drag_entity = &rd_nil_entity; + RD_Cfg *line_drag_cfg = &rd_nil_cfg; CTRL_Entity *line_drag_ctrl_entity = &ctrl_entity_nil; - Vec4F32 line_drag_drop_color = rd_rgba_from_theme_color(RD_ThemeColor_DropSiteOverlay); + Vec4F32 line_drag_drop_color = pop_color; { //- rjf: determine mouse drag range TxtRng mouse_drag_rng = txt_rng(mouse_pt, mouse_pt); @@ -1430,6 +2053,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe *preferred_column = cursor->column; } + //- rjf: dragging will invalidate the search string, so we don't want to draw it while dragging/releasing + if(ui_dragging(text_container_sig) || ui_released(text_container_sig)) + { + search_query_invalidated = 1; + } + //- rjf: right-click => code context menu if(ui_right_clicked(text_container_sig)) { @@ -1444,13 +2073,17 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe vaddr = params->line_vaddrs[cursor->line - params->line_num_range.min]; lines = params->line_infos[cursor->line - params->line_num_range.min]; } - RD_RegsScope(.cursor = *cursor, - .mark = *mark, - .vaddr = vaddr, - .lines = lines) - { - rd_open_ctx_menu(ui_key_zero(), sub_2f32(ui_mouse(), v2f32(2, 2)), RD_RegSlot_Cursor); - } +#if 0 // TODO(rjf): @cfg + rd_cmd(RD_CmdKind_PushQuery, + .reg_slot = RD_RegSlot_Cursor, + .ui_key = ui_get_selected_state()->root->key, + .off_px = sub_2f32(ui_mouse(), v2f32(2, 2)), + .cursor = *cursor, + .mark = *mark, + .vaddr = vaddr, + .lines = lines, + .lister_flags= RD_ListerFlag_LineEdit|RD_ListerFlag_Settings|RD_ListerFlag_Commands); +#endif } //- rjf: dragging threads, breakpoints, or watch pins over this slice -> @@ -1458,43 +2091,65 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(rd_drag_is_active() && contains_2f32(clipped_top_container_rect, ui_mouse())) { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_state->drag_drop_regs->thread); - RD_Entity *entity = rd_entity_from_handle(rd_state->drag_drop_regs->entity); - if(rd_state->drag_drop_regs_slot == RD_RegSlot_Entity && - (entity->kind == RD_EntityKind_WatchPin || - entity->kind == RD_EntityKind_Breakpoint)) + RD_Cfg *cfg = rd_cfg_from_id(rd_state->drag_drop_regs->cfg); + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Cfg && + (str8_match(cfg->string, str8_lit("breakpoint"), 0) || + str8_match(cfg->string, str8_lit("watch_pin"), 0))) { line_drag_drop = 1; - line_drag_entity = entity; - if(entity->flags & RD_EntityFlag_HasColor) + line_drag_cfg = cfg; + line_drag_drop_color = linear_from_srgba(rd_color_from_cfg(cfg)); + if(line_drag_drop_color.w == 0) { - line_drag_drop_color = rd_rgba_from_entity(entity); - line_drag_drop_color.w *= 0.5f; + line_drag_drop_color = pop_color; } } + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr) + { + line_drag_drop = 1; + line_drag_cfg = cfg; + line_drag_drop_color = pop_color; + } if(rd_state->drag_drop_regs_slot == RD_RegSlot_Thread) { line_drag_drop = 1; line_drag_ctrl_entity = thread; - line_drag_drop_color = rd_rgba_from_ctrl_entity(thread); - line_drag_drop_color.w *= 0.5f; + line_drag_drop_color = rd_color_from_ctrl_entity(thread); + if(line_drag_drop_color.w == 0) + { + line_drag_drop_color = pop_color; + } } } //- rjf: drop target is dropped -> process + if(contains_1s64(params->line_num_range, mouse_pt.line) && contains_2f32(clipped_top_container_rect, ui_mouse())) { - if(!rd_entity_is_nil(line_drag_entity) && rd_drag_drop() && contains_1s64(params->line_num_range, mouse_pt.line)) + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr && rd_drag_drop()) { - RD_Entity *dropped_entity = line_drag_entity; S64 line_num = mouse_pt.line; U64 line_idx = line_num - params->line_num_range.min; U64 line_vaddr = params->line_vaddrs[line_idx]; - rd_cmd(RD_CmdKind_RelocateEntity, - .entity = rd_handle_from_entity(dropped_entity), + rd_cmd(RD_CmdKind_AddWatchPin, + .expr = rd_state->drag_drop_regs->expr, + .view_rule = rd_state->drag_drop_regs->view_rule, .file_path = line_vaddr == 0 ? rd_regs()->file_path : str8_zero(), .cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0), .vaddr = line_vaddr); } - if(line_drag_ctrl_entity != &ctrl_entity_nil && rd_drag_drop() && contains_1s64(params->line_num_range, mouse_pt.line)) + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Cfg && line_drag_cfg != &rd_nil_cfg && rd_drag_drop()) + { + RD_Cfg *dropped_cfg = line_drag_cfg; + S64 line_num = mouse_pt.line; + U64 line_idx = line_num - params->line_num_range.min; + U64 line_vaddr = params->line_vaddrs[line_idx]; + rd_cmd(RD_CmdKind_RelocateCfg, + .cfg = dropped_cfg->id, + .file_path = line_vaddr == 0 ? rd_regs()->file_path : str8_zero(), + .cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0), + .vaddr = line_vaddr); + } + if(line_drag_ctrl_entity != &ctrl_entity_nil && rd_drag_drop()) { S64 line_num = mouse_pt.line; U64 line_idx = line_num - params->line_num_range.min; @@ -1591,7 +2246,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(!ui_dragging(text_container_sig) && text_container_sig.event_flags == 0 && mouse_expr.size != 0) { E_Eval eval = e_eval_from_string(scratch.arena, mouse_expr); - if(eval.msgs.max_kind == E_MsgKind_Null && (eval.mode != E_Mode_Null || mouse_expr_is_explicit)) + if(eval.msgs.max_kind == E_MsgKind_Null && (eval.irtree.mode != E_Mode_Null || mouse_expr_is_explicit)) { U64 line_vaddr = 0; if(contains_1s64(params->line_num_range, mouse_pt.line)) @@ -1599,7 +2254,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 line_idx = mouse_pt.line-params->line_num_range.min; line_vaddr = params->line_vaddrs[line_idx]; } - rd_set_hover_eval(mouse_expr_baseline_pos, rd_regs()->file_path, mouse_pt, line_vaddr, mouse_expr); + rd_set_hover_eval(mouse_expr_baseline_pos, mouse_expr, str8_zero()); } } @@ -1612,6 +2267,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe DR_BucketScope(bucket) { Vec4F32 color = line_drag_drop_color; + color.w *= 0.2f; Rng2F32 drop_line_rect = r2f32p(top_container_box->rect.x0, top_container_box->rect.y0 + (mouse_pt.line - params->line_num_range.min) * params->line_height_px, top_container_box->rect.x1, @@ -1639,16 +2295,16 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { TxtRngColorPairNode *n = push_array(scratch.arena, TxtRngColorPairNode, 1); n->rng = txt_rng(*cursor, *mark); - n->color = ui_top_palette()->colors[UI_ColorCode_Selection]; + n->color = ui_color_from_name(str8_lit("selection")); SLLQueuePush(first_txt_rng_color_pair, last_txt_rng_color_pair, n); } // rjf: push for ctrlified mouse expr - if(ctrlified && !txt_pt_match(result.mouse_expr_rng.max, result.mouse_expr_rng.min)) + if(ctrlified && !txt_pt_match(result.mouse_expr_rng.max, result.mouse_expr_rng.min)) UI_Tag(str8_lit("pop")) { TxtRngColorPairNode *n = push_array(scratch.arena, TxtRngColorPairNode, 1); n->rng = result.mouse_expr_rng; - n->color = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); + n->color = ui_color_from_name(str8_lit("background")); SLLQueuePush(first_txt_rng_color_pair, last_txt_rng_color_pair, n); } } @@ -1696,7 +2352,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(line_bg_color.w != 0) { ui_set_next_flags(UI_BoxFlag_DrawBackground); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = line_bg_color)); + ui_set_next_background_color(line_bg_color); } ui_set_next_tab_size(params->tab_size); UI_Box *line_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc|UI_BoxFlag_DrawText|UI_BoxFlag_DisableIDString, line_key); @@ -1704,20 +2360,18 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe dr_push_bucket(line_bucket); // rjf: string * tokens -> fancy string list - DR_FancyStringList line_fancy_strings = {0}; + DR_FStrList line_fstrs = {0}; { if(line_tokens->count == 0) { - DR_FancyString fstr = + DR_FStrParams fstr_params = { params->font, - line_string, + ui_top_text_raster_flags(), rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), params->font_size, - 0, - 0, }; - dr_fancy_string_list_push(scratch.arena, &line_fancy_strings, &fstr); + dr_fstrs_push_new(scratch.arena, &line_fstrs, &fstr_params, line_string); } else { @@ -1752,25 +2406,23 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } // rjf: push fancy string - DR_FancyString fstr = + DR_FStrParams fstr_params = { params->font, - token_string, + ui_top_text_raster_flags(), token_color, params->font_size, - 0, - 0, }; - dr_fancy_string_list_push(scratch.arena, &line_fancy_strings, &fstr); + dr_fstrs_push_new(scratch.arena, &line_fstrs, &fstr_params, token_string); } } } // rjf: equip fancy strings to line box - ui_box_equip_display_fancy_strings(line_box, &line_fancy_strings); + ui_box_equip_display_fstrs(line_box, &line_fstrs); // rjf: extra rendering for strings that are currently being searched for - if(params->search_query.size != 0) + if(!search_query_invalidated && params->search_query.size != 0) { for(U64 needle_pos = 0; needle_pos < line_string.size;) { @@ -1790,18 +2442,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_box->rect.x0+line_num_padding_px+match_column_pixel_off_range.max+2.f, line_box->rect.y1, }; - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - if(cursor->line == line_num && needle_pos+1 <= cursor->column && cursor->column < needle_pos+params->search_query.size+1) - { - color.x += (1.f - color.x) * 0.5f; - color.y += (1.f - color.y) * 0.5f; - color.z += (1.f - color.z) * 0.5f; - color.w += (1.f - color.w) * 0.5f; - } + Vec4F32 color = pop_color; if(!is_focused) { color.w *= 0.5f; } + color.w *= 0.2f; dr_rect(match_rect, color, 4.f, 0, 1.f); needle_pos += 1; } @@ -1846,6 +2492,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ceil_f32(line_box->rect.y1) + 1.f, }; Vec4F32 color = n->color; + color.w = ClampTop(color.w, 0.1f); if(!is_focused) { color.w *= 0.5f; @@ -1870,11 +2517,16 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe Rng2F32 cursor_rect = { ui_box_text_position(line_box).x+cursor_off_pixels-cursor_thickness/2.f, - line_box->rect.y0-params->font_size*0.25f, + line_box->rect.y0-params->font_size*0.125f, ui_box_text_position(line_box).x+cursor_off_pixels+cursor_thickness/2.f, - line_box->rect.y1+params->font_size*0.25f, + line_box->rect.y1+params->font_size*0.125f, }; - dr_rect(cursor_rect, rd_rgba_from_theme_color(is_focused ? RD_ThemeColor_Cursor : RD_ThemeColor_CursorInactive), 1.f, 0, 1.f); + Vec4F32 cursor_color = ui_color_from_name(str8_lit("cursor")); + if(!is_focused) + { + cursor_color.w *= 0.5f; + } + dr_rect(cursor_rect, cursor_color, 1.f, 0, 1.f); } // rjf: extra rendering for lines with line-info that match the hovered @@ -1899,7 +2551,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(matches) { Vec4F32 highlight_color = code_line_bgs[line_info_line_num % ArrayCount(code_line_bgs)]; - highlight_color.w *= 0.25f; + highlight_color.w *= 0.2f; dr_rect(line_box->rect, highlight_color, 0, 0, 0); } } @@ -2156,25 +2808,27 @@ rd_label(String8 string) active_part_flags ^= StringPartFlag_Code; } } - DR_FancyStringList fstrs = {0}; + DR_FStrList fstrs = {0}; for(StringPart *p = first_part; p != 0; p = p->next) { - DR_FancyString fstr = {0}; + DR_FStr fstr = {0}; { - fstr.font = ui_top_font(); fstr.string = p->string; - fstr.color = ui_top_palette()->colors[UI_ColorCode_Text]; - fstr.size = ui_top_font_size(); + fstr.params.font = ui_top_font(); + fstr.params.color = ui_color_from_name(str8_lit("text")); + fstr.params.size = ui_top_font_size(); + fstr.params.raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main); if(p->flags & StringPartFlag_Code) { - fstr.font = rd_font_from_slot(RD_FontSlot_Code); - fstr.color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); + fstr.params.font = rd_font_from_slot(RD_FontSlot_Code); + fstr.params.raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code); + fstr.params.color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); } } - dr_fancy_string_list_push(scratch.arena, &fstrs, &fstr); + dr_fstrs_push(scratch.arena, &fstrs, &fstr); } UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fstrs); + ui_box_equip_display_fstrs(box, &fstrs); UI_Signal sig = ui_signal_from_box(box); scratch_end(scratch); return sig; @@ -2185,13 +2839,12 @@ rd_error_label(String8 string) { UI_Box *box = ui_build_box_from_key(0, ui_key_zero()); UI_Signal sig = ui_signal_from_box(box); - UI_Parent(box) UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) + UI_Parent(box) { ui_set_next_font(rd_font_from_slot(RD_FontSlot_Icons)); ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); ui_set_next_text_alignment(UI_TextAlign_Center); - ui_set_next_flags(UI_BoxFlag_DrawTextWeak); - UI_PrefWidth(ui_em(2.25f, 1.f)) ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); + UI_TagF("weak") UI_PrefWidth(ui_em(2.25f, 1.f)) ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); UI_PrefWidth(ui_text_dim(10, 0)) rd_label(string); } return sig; @@ -2223,12 +2876,12 @@ rd_help_label(String8 string) return result; } -internal DR_FancyStringList -rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string) +internal DR_FStrList +rd_fstrs_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); - DR_FancyStringList fancy_strings = {0}; + DR_FStrList fstrs = {0}; TXT_TokenArray tokens = txt_token_array_from_string__c_cpp(scratch.arena, 0, string); TXT_Token *tokens_opl = tokens.v+tokens.count; S32 indirection_counter = 0; @@ -2246,14 +2899,17 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s { default: { - DR_FancyString fancy_string = + DR_FStr fstr = { - ui_top_font(), token_string, - token_color_rgba, - ui_top_font_size() * (1.f - !!indirection_size_change*(indirection_counter/10.f)), + { + ui_top_font(), + ui_top_text_raster_flags(), + token_color_rgba, + ui_top_font_size() * (1.f - !!indirection_size_change*(indirection_counter/10.f)), + } }; - dr_fancy_string_list_push(arena, &fancy_strings, &fancy_string); + dr_fstrs_push(arena, &fstrs, &fstr); }break; case TXT_TokenKind_Identifier: case TXT_TokenKind_Keyword: @@ -2265,14 +2921,17 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s F32 lookup_color_mix_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%S_lookup", token_string), 1.f); token_color_rgba = mix_4f32(token_color_rgba, lookup_color, lookup_color_mix_t); } - DR_FancyString fancy_string = + DR_FStr fstr = { - ui_top_font(), token_string, - token_color_rgba, - ui_top_font_size() * (1.f - !!indirection_size_change*(indirection_counter/10.f)), + { + ui_top_font(), + ui_top_text_raster_flags(), + token_color_rgba, + ui_top_font_size() * (1.f - !!indirection_size_change*(indirection_counter/10.f)), + }, }; - dr_fancy_string_list_push(arena, &fancy_strings, &fancy_string); + dr_fstrs_push(arena, &fstrs, &fstr); }break; case TXT_TokenKind_Numeric: { @@ -2318,14 +2977,17 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s // rjf: push prefix { - DR_FancyString fancy_string = + DR_FStr fstr = { - ui_top_font(), prefix, - token_color_rgba, - font_size, + { + ui_top_font(), + ui_top_text_raster_flags(), + token_color_rgba, + font_size, + }, }; - dr_fancy_string_list_push(arena, &fancy_strings, &fancy_string); + dr_fstrs_push(arena, &fstrs, &fstr); } // rjf: push digit groups @@ -2341,14 +3003,17 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s num_digits_passed = 0; if(start_idx < idx) { - DR_FancyString fancy_string = + DR_FStr fstr = { - ui_top_font(), str8_substr(whole, r1u64(start_idx, idx)), - odd ? token_color_rgba_alt : token_color_rgba, - font_size, + { + ui_top_font(), + ui_top_text_raster_flags(), + odd ? token_color_rgba_alt : token_color_rgba, + font_size, + }, }; - dr_fancy_string_list_push(arena, &fancy_strings, &fancy_string); + dr_fstrs_push(arena, &fstrs, &fstr); start_idx = idx; odd ^= 1; } @@ -2362,14 +3027,17 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s // rjf: push decimal { - DR_FancyString fancy_string = + DR_FStr fstr = { - ui_top_font(), decimal, - token_color_rgba, - font_size, + { + ui_top_font(), + ui_top_text_raster_flags(), + token_color_rgba, + font_size, + }, }; - dr_fancy_string_list_push(arena, &fancy_strings, &fancy_string); + dr_fstrs_push(arena, &fstrs, &fstr); } }break; @@ -2380,16 +3048,16 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s } scratch_end(scratch); ProfEnd(); - return fancy_strings; + return fstrs; } internal UI_Box * rd_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string) { Temp scratch = scratch_begin(0, 0); - DR_FancyStringList fancy_strings = rd_fancy_string_list_from_code_string(scratch.arena, alpha, indirection_size_change, base_color, string); + DR_FStrList fstrs = rd_fstrs_from_code_string(scratch.arena, alpha, indirection_size_change, base_color, string); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fancy_strings); + ui_box_equip_display_fstrs(box, &fstrs); scratch_end(scratch); return box; } @@ -2398,17 +3066,23 @@ rd_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String //~ rjf: UI Widgets: Line Edit internal UI_Signal -rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, B32 *expanded_out, String8 pre_edit_value, String8 string) +rd_cell(RD_CellParams *params, String8 string) { ProfBeginFunction(); + ////////////////////////////// //- rjf: unpack visual metrics + // F32 expander_size_px = ui_top_font_size()*2.f; + ////////////////////////////// //- rjf: make key + // UI_Key key = ui_key_from_string(ui_active_seed_key(), string); + ////////////////////////////// //- rjf: calculate & push focus + // B32 is_auto_focus_hot = ui_is_key_auto_focus_hot(key); B32 is_auto_focus_active = ui_is_key_auto_focus_active(key); if(is_auto_focus_hot) { ui_push_focus_hot(UI_FocusKind_On); } @@ -2418,64 +3092,134 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx B32 is_focus_hot_disabled = (!is_focus_hot && ui_top_focus_hot() == UI_FocusKind_On); B32 is_focus_active_disabled = (!is_focus_active && ui_top_focus_active() == UI_FocusKind_On); + ////////////////////////////// //- rjf: build top-level box + // if(is_focus_active || is_focus_active_disabled) { ui_set_next_hover_cursor(OS_Cursor_IBar); } + if(params->flags & RD_CellFlag_Button) + { + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + } UI_Box *box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| - (!!(flags & RD_LineEditFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| + (!!(params->flags & RD_CellFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| UI_BoxFlag_ClickToFocus| - UI_BoxFlag_DrawHotEffects| - (!(flags & RD_LineEditFlag_NoBackground)*UI_BoxFlag_DrawBackground)| - (!!(flags & RD_LineEditFlag_Border)*UI_BoxFlag_DrawBorder)| + (!!(params->flags & RD_CellFlag_Button)*UI_BoxFlag_DrawHotEffects)| + (!!(params->flags & RD_CellFlag_SingleClickActivate)*UI_BoxFlag_DrawActiveEffects)| + (!(params->flags & RD_CellFlag_NoBackground)*UI_BoxFlag_DrawBackground)| + (!!(params->flags & RD_CellFlag_Border)*UI_BoxFlag_DrawBorder)| ((is_auto_focus_hot || is_auto_focus_active)*UI_BoxFlag_KeyboardClickable)| (is_focus_active || is_focus_active_disabled)*(UI_BoxFlag_Clip), key); + ////////////////////////////// //- rjf: build indent - UI_Parent(box) for(S32 idx = 0; idx < depth; idx += 1) + // + UI_Parent(box) for(S32 idx = 0; idx < params->depth; idx += 1) { ui_set_next_flags(UI_BoxFlag_DrawSideLeft); ui_spacer(ui_em(1.f, 1.f)); } - //- rjf: build expander - if(flags & RD_LineEditFlag_Expander) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Parent(box) - UI_Flags(UI_BoxFlag_DrawSideLeft) - UI_Focus(UI_FocusKind_Off) + ////////////////////////////// + //- rjf: build expander (or placeholder, or space) + // { - UI_Signal expander_sig = ui_expanderf(*expanded_out, "expander"); - if(ui_pressed(expander_sig)) + //- rjf: build expander + if(params->flags & RD_CellFlag_Expander) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Parent(box) + UI_Flags(UI_BoxFlag_DrawSideLeft) + UI_Focus(UI_FocusKind_Off) { - *expanded_out ^= 1; + UI_Signal expander_sig = ui_expanderf(params->expanded_out[0], "expander"); + if(ui_pressed(expander_sig)) + { + params->expanded_out[0] ^= 1; + } + } + + //- rjf: build expander placeholder + else if(params->flags & RD_CellFlag_ExpanderPlaceholder) UI_Parent(box) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Focus(UI_FocusKind_Off) + { + UI_TagF("weak") + UI_Flags(UI_BoxFlag_DrawSideLeft) + RD_Font(RD_FontSlot_Icons) + UI_TextAlignment(UI_TextAlign_Center) + ui_label(rd_icon_kind_text_table[RD_IconKind_Dot]); + } + + //- rjf: build expander space + else if(params->flags & RD_CellFlag_ExpanderSpace) UI_Parent(box) UI_Focus(UI_FocusKind_Off) + { + UI_Flags(UI_BoxFlag_DrawSideLeft) ui_spacer(ui_px(expander_size_px, 1.f)); } } - //- rjf: build expander placeholder - else if(flags & RD_LineEditFlag_ExpanderPlaceholder) UI_Parent(box) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Focus(UI_FocusKind_Off) - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - UI_Flags(UI_BoxFlag_DrawSideLeft) - RD_Font(RD_FontSlot_Icons) - UI_TextAlignment(UI_TextAlign_Center) - ui_label(rd_icon_kind_text_table[RD_IconKind_Dot]); - } - - //- rjf: build expander space - else if(flags & RD_LineEditFlag_ExpanderSpace) UI_Parent(box) UI_Focus(UI_FocusKind_Off) - { - UI_Flags(UI_BoxFlag_DrawSideLeft) ui_spacer(ui_px(expander_size_px, 1.f)); - } - + ////////////////////////////// //- rjf: build scrollable container box + // UI_Box *scrollable_box = &ui_nil_box; - UI_Parent(box) UI_PrefWidth(ui_children_sum(0)) + UI_Parent(box) UI_WidthFill { - scrollable_box = ui_build_box_from_stringf(is_focus_active*(UI_BoxFlag_AllowOverflowX), "scroll_box_%p", edit_buffer); + scrollable_box = ui_build_box_from_stringf(is_focus_active*(UI_BoxFlag_AllowOverflowX), "scroll_box_%p", params->edit_buffer); } + ////////////////////////////// + //- rjf: build toggle-switch + // + if(params->flags & RD_CellFlag_ToggleSwitch && !is_focus_active) + UI_Parent(box) + { + B32 is_toggled = !!params->toggled_out[0]; + F32 toggle_t = ui_anim(ui_key_from_stringf(key, "toggled"), (F32)is_toggled, .initial = (F32)is_toggled); + F32 padding_px = floor_f32(ui_top_font_size()*0.65f); + F32 height_px = ui_top_px_height() - padding_px*2.f; + UI_PrefWidth(ui_children_sum(1.f)) + UI_HeightFill + UI_Column UI_Padding(ui_px(padding_px, 1.f)) + UI_Row UI_Padding(ui_px(padding_px, 1.f)) + UI_PrefWidth(ui_em(3.5f, 1.f)) + UI_PrefHeight(ui_px(height_px, 1.f)) + UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) + UI_TagF(is_toggled ? "good_pop" : "") + { + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + UI_Box *switch_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "toggle_switch"); + UI_Parent(switch_box) + { + RD_Font(RD_FontSlot_Icons) UI_PrefWidth(ui_pct(toggle_t, 0)) UI_Transparency(1.f - toggle_t) + { + ui_build_box_from_stringf(UI_BoxFlag_DisableTextTrunc | (toggle_t > 0.001f ? UI_BoxFlag_DrawText : 0), + "%S", rd_icon_kind_text_table[RD_IconKind_Check]); + } + UI_BackgroundColor(ui_color_from_name(str8_lit("text"))) + UI_PrefWidth(ui_px(height_px, 1.f)) + { + F32 extratoggler_padding_px = floor_f32(ui_top_font_size()*0.35f); + F32 toggler_size_px = height_px - extratoggler_padding_px*2.f; + UI_Column UI_Padding(ui_px(extratoggler_padding_px, 1.f)) + UI_Row UI_Padding(ui_px(extratoggler_padding_px, 1.f)) + UI_PrefWidth(ui_px(toggler_size_px, 1.f)) + UI_PrefHeight(ui_px(toggler_size_px, 1.f)) + UI_CornerRadius(floor_f32(toggler_size_px/2.f - 1.f)) + { + UI_Box *toggler = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, ui_key_zero()); + } + } + ui_spacer(ui_pct(1.f-toggle_t, 0)); + } + UI_Signal switch_sig = ui_signal_from_box(switch_box); + if(ui_pressed(switch_sig)) + { + params->toggled_out[0] ^= 1; + } + } + } + + ////////////////////////////// //- rjf: do non-textual edits (delete, copy, cut) + // B32 commit = 0; if(!is_focus_active && is_focus_hot) { @@ -2483,24 +3227,28 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx { if(evt->flags & UI_EventFlag_Copy) { - os_set_clipboard_text(pre_edit_value); + os_set_clipboard_text(params->pre_edit_value); } if(evt->flags & UI_EventFlag_Delete) { commit = 1; - edit_string_size_out[0] = 0; + params->edit_string_size_out[0] = 0; } } } + ////////////////////////////// //- rjf: get signal + // UI_Signal sig = ui_signal_from_box(box); if(commit) { sig.f |= UI_SignalFlag_Commit; } + ////////////////////////////// //- rjf: do start/end editing interaction + // B32 focus_started = 0; if(!is_focus_active) { @@ -2523,14 +3271,17 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } if(start_editing_via_sig || start_editing_via_typing) { - String8 edit_string = pre_edit_value; - edit_string.size = Min(edit_buffer_size, pre_edit_value.size); - MemoryCopy(edit_buffer, edit_string.str, edit_string.size); - edit_string_size_out[0] = edit_string.size; + String8 edit_string = params->pre_edit_value; + edit_string.size = Min(params->edit_buffer_size, params->pre_edit_value.size); + MemoryCopy(params->edit_buffer, edit_string.str, edit_string.size); + params->edit_string_size_out[0] = edit_string.size; ui_set_auto_focus_active_key(key); - ui_kill_action(); - *cursor = txt_pt(1, edit_string.size+1); - *mark = txt_pt(1, 1); + if(!(params->flags & RD_CellFlag_Button)) + { + ui_kill_action(); + } + params->cursor[0] = txt_pt(1, edit_string.size+1); + params->mark[0] = txt_pt(1, 1); focus_started = 1; } } @@ -2540,7 +3291,9 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx sig.f |= UI_SignalFlag_Commit; } + ////////////////////////////// //- rjf: determine autocompletion string + // String8 autocomplete_hint_string = {0}; { for(UI_Event *evt = 0; ui_next_event(&evt);) @@ -2552,15 +3305,17 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } } + ////////////////////////////// //- rjf: take navigation actions for editing + // B32 changes_made = 0; - if(!(flags & RD_LineEditFlag_DisableEdit) && (is_focus_active || focus_started)) + if(!(params->flags & RD_CellFlag_DisableEdit) && (is_focus_active || focus_started)) { Temp scratch = scratch_begin(0, 0); rd_state->text_edit_mode = 1; for(UI_Event *evt = 0; ui_next_event(&evt);) { - String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); // rjf: do not consume anything that doesn't fit a single-line's operations if((evt->kind != UI_EventKind_Edit && evt->kind != UI_EventKind_Navigate && evt->kind != UI_EventKind_Text) || evt->delta_2s32.y != 0) @@ -2569,20 +3324,20 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } // rjf: map this action to an op - UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, *cursor, *mark); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, params->cursor[0], params->mark[0]); // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op if(autocomplete_hint_string.size != 0) { - String8 word_query = rd_autocomp_query_word_from_input_string_off(edit_string, cursor->column-1); + String8 word_query = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); U64 word_off = (U64)(word_query.str - edit_string.str); String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); - new_string.size = Min(edit_buffer_size, new_string.size); - MemoryCopy(edit_buffer, new_string.str, new_string.size); - edit_string_size_out[0] = new_string.size; - *cursor = *mark = txt_pt(1, word_off+1+autocomplete_hint_string.size); - edit_string = str8(edit_buffer, edit_string_size_out[0]); - op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, *cursor, *mark); + new_string.size = Min(params->edit_buffer_size, new_string.size); + MemoryCopy(params->edit_buffer, new_string.str, new_string.size); + params->edit_string_size_out[0] = new_string.size; + params->cursor[0] = params->mark[0] = txt_pt(1, word_off+1+autocomplete_hint_string.size); + edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); + op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, params->cursor[0], params->mark[0]); MemoryZeroStruct(&autocomplete_hint_string); } @@ -2590,9 +3345,9 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) { String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(op.range.min.column, op.range.max.column), op.replace); - new_string.size = Min(edit_buffer_size, new_string.size); - MemoryCopy(edit_buffer, new_string.str, new_string.size); - edit_string_size_out[0] = new_string.size; + new_string.size = Min(params->edit_buffer_size, new_string.size); + MemoryCopy(params->edit_buffer, new_string.str, new_string.size); + params->edit_string_size_out[0] = new_string.size; } // rjf: perform copy @@ -2602,8 +3357,8 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } // rjf: commit op's changed cursor & mark to caller-provided state - *cursor = op.cursor; - *mark = op.mark; + params->cursor[0] = op.cursor; + params->mark[0] = op.mark; // rjf: consume event { @@ -2614,75 +3369,89 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx scratch_end(scratch); } + ////////////////////////////// //- rjf: build scrolled contents + // TxtPt mouse_pt = {0}; F32 cursor_off = 0; UI_Parent(scrollable_box) { - if(!is_focus_active && !is_focus_active_disabled && flags & RD_LineEditFlag_CodeContents) + if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) == 0) + { + ui_spacer(ui_em(0.5f, 1.f)); + } + if(!is_focus_active && !is_focus_active_disabled && params->fstrs.total_size != 0) + { + UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(label, ¶ms->fstrs); + if(params->fuzzy_matches != 0) + { + ui_box_equip_fuzzy_match_ranges(label, params->fuzzy_matches); + } + } + else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_CellFlag_CodeContents) { String8 display_string = ui_display_part_from_key_string(string); - if(!(flags & RD_LineEditFlag_PreferDisplayString) && pre_edit_value.size != 0) + if(!(params->flags & RD_CellFlag_PreferDisplayString) && params->pre_edit_value.size != 0) { - display_string = pre_edit_value; - UI_Box *box = rd_code_label(1.f, 1, ui_top_palette()->text, display_string); - if(matches != 0) + display_string = params->pre_edit_value; + UI_Box *box = rd_code_label(1.f, 1, ui_color_from_name(str8_lit("text")), display_string); + if(params->fuzzy_matches != 0) { - ui_box_equip_fuzzy_match_ranges(box, matches); + ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } - else if(flags & RD_LineEditFlag_DisplayStringIsCode) + else if(params->flags & RD_CellFlag_DisplayStringIsCode) { - UI_Box *box = rd_code_label(1.f, 1, ui_top_palette()->text, display_string); - if(matches != 0) + UI_Box *box = rd_code_label(1.f, 1, ui_color_from_name(str8_lit("text")), display_string); + if(params->fuzzy_matches != 0) { - ui_box_equip_fuzzy_match_ranges(box, matches); + ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } - else + else UI_TagF("weak") { - ui_set_next_flags(UI_BoxFlag_DrawTextWeak); UI_Box *box = ui_label(display_string).box; - if(matches != 0) + if(params->fuzzy_matches != 0) { - ui_box_equip_fuzzy_match_ranges(box, matches); + ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } } - else if(!is_focus_active && !is_focus_active_disabled && !(flags & RD_LineEditFlag_CodeContents)) + else if(!is_focus_active && !is_focus_active_disabled && !(params->flags & RD_CellFlag_CodeContents)) { String8 display_string = ui_display_part_from_key_string(string); - if(!(flags & RD_LineEditFlag_PreferDisplayString) && pre_edit_value.size != 0) + if(!(params->flags & RD_CellFlag_PreferDisplayString) && params->pre_edit_value.size != 0) { - display_string = pre_edit_value; + display_string = params->pre_edit_value; } else { - ui_set_next_flags(UI_BoxFlag_DrawTextWeak); + ui_set_next_tag(str8_lit("weak")); } UI_Box *box = ui_label(display_string).box; - if(matches != 0) + if(params->fuzzy_matches != 0) { - ui_box_equip_fuzzy_match_ranges(box, matches); + ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } - else if((is_focus_active || is_focus_active_disabled) && flags & RD_LineEditFlag_CodeContents) + else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_CellFlag_CodeContents) { - String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); Temp scratch = scratch_begin(0, 0); F32 total_text_width = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; - F32 total_editstr_width = total_text_width - !!(flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; + F32 total_editstr_width = total_text_width - !!(params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); - DR_FancyStringList code_fancy_strings = rd_fancy_string_list_from_code_string(scratch.arena, 1.f, 0, ui_top_palette()->text, edit_string); + DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); if(autocomplete_hint_string.size != 0) { - String8 query_word = rd_autocomp_query_word_from_input_string_off(edit_string, cursor->column-1); + String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); U64 off = 0; - U64 cursor_off = cursor->column-1; - DR_FancyStringNode *prev_n = 0; - for(DR_FancyStringNode *n = code_fancy_strings.first; n != 0; n = n->next) + U64 cursor_off = params->cursor->column-1; + DR_FStrNode *prev_n = 0; + for(DR_FStrNode *n = code_fstrs.first; n != 0; n = n->next) { if(off <= cursor_off && cursor_off <= off+n->v.string.size) { @@ -2692,13 +3461,13 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx off += n->v.string.size; } { - DR_FancyStringNode *autocomp_fstr_n = push_array(scratch.arena, DR_FancyStringNode, 1); - DR_FancyString *fstr = &autocomp_fstr_n->v; - fstr->font = ui_top_font(); + DR_FStrNode *autocomp_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); + DR_FStr *fstr = &autocomp_fstr_n->v; fstr->string = autocomplete_append_string; - fstr->color = ui_top_palette()->text; - fstr->color.w *= 0.5f; - fstr->size = ui_top_font_size(); + fstr->params.font = ui_top_font(); + fstr->params.color = ui_color_from_name(str8_lit("text")); + fstr->params.color.w *= 0.5f; + fstr->params.size = ui_top_font_size(); autocomp_fstr_n->next = prev_n ? prev_n->next : 0; if(prev_n != 0) { @@ -2706,84 +3475,88 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } if(prev_n == 0) { - code_fancy_strings.first = code_fancy_strings.last = autocomp_fstr_n; + code_fstrs.first = code_fstrs.last = autocomp_fstr_n; } if(prev_n != 0 && prev_n->next == 0) { - code_fancy_strings.last = autocomp_fstr_n; + code_fstrs.last = autocomp_fstr_n; } - code_fancy_strings.node_count += 1; - code_fancy_strings.total_size += autocomplete_hint_string.size; + code_fstrs.node_count += 1; + code_fstrs.total_size += autocomplete_hint_string.size; if(prev_n != 0 && cursor_off - off < prev_n->v.string.size) { String8 full_string = prev_n->v.string; U64 chop_amt = full_string.size - (cursor_off - off); prev_n->v.string = str8_chop(full_string, chop_amt); - code_fancy_strings.total_size -= chop_amt; + code_fstrs.total_size -= chop_amt; if(chop_amt != 0) { String8 post_cursor = str8_skip(full_string, cursor_off - off); - DR_FancyStringNode *post_fstr_n = push_array(scratch.arena, DR_FancyStringNode, 1); - DR_FancyString *post_fstr = &post_fstr_n->v; + DR_FStrNode *post_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); + DR_FStr *post_fstr = &post_fstr_n->v; MemoryCopyStruct(post_fstr, &prev_n->v); post_fstr->string = post_cursor; if(autocomp_fstr_n->next == 0) { - code_fancy_strings.last = post_fstr_n; + code_fstrs.last = post_fstr_n; } post_fstr_n->next = autocomp_fstr_n->next; autocomp_fstr_n->next = post_fstr_n; - code_fancy_strings.node_count += 1; - code_fancy_strings.total_size += post_cursor.size; + code_fstrs.node_count += 1; + code_fstrs.total_size += post_cursor.size; } } } } - ui_box_equip_display_fancy_strings(editstr_box, &code_fancy_strings); + ui_box_equip_display_fstrs(editstr_box, &code_fstrs); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); - draw_data->cursor = *cursor; - draw_data->mark = *mark; + draw_data->cursor = params->cursor[0]; + draw_data->mark = params->mark[0]; ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, params->cursor->column-1)).x; scratch_end(scratch); } - else if((is_focus_active || is_focus_active_disabled) && !(flags & RD_LineEditFlag_CodeContents)) + else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_CellFlag_CodeContents)) { - String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); F32 total_text_width = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; - F32 total_editstr_width = total_text_width - !!(flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; + F32 total_editstr_width = total_text_width - !!(params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); - draw_data->cursor = *cursor; - draw_data->mark = *mark; + draw_data->cursor = params->cursor[0]; + draw_data->mark = params->mark[0]; ui_box_equip_display_string(editstr_box, edit_string); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, params->cursor->column-1)).x; } } + ////////////////////////////// //- rjf: click+drag + // if(is_focus_active && ui_dragging(sig)) { if(ui_pressed(sig)) { - *mark = mouse_pt; + params->mark[0] = mouse_pt; } - *cursor = mouse_pt; + params->cursor[0] = mouse_pt; } if(!is_focus_active && is_focus_active_disabled && ui_pressed(sig)) { - *cursor = *mark = mouse_pt; + params->cursor[0] = params->mark[0] = mouse_pt; } + ////////////////////////////// //- rjf: focus cursor + // { - F32 visible_dim_px = dim_2f32(box->rect).x - expander_size_px - ui_top_font_size()*depth; + F32 visible_dim_px = dim_2f32(box->rect).x - expander_size_px - ui_top_font_size()*params->depth; if(visible_dim_px > 0) { Rng1F32 cursor_range_px = r1f32(cursor_off-ui_top_font_size()*2.f, cursor_off+ui_top_font_size()*2.f); @@ -2803,7 +3576,9 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } } + ////////////////////////////// //- rjf: pop focus + // if(is_auto_focus_hot) { ui_pop_focus_hot(); } if(is_auto_focus_active) { ui_pop_focus_active(); } @@ -2812,14 +3587,14 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } internal UI_Signal -rd_line_editf(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, B32 *expanded_out, String8 pre_edit_value, char *fmt, ...) +rd_cellf(RD_CellParams *params, char *fmt, ...) { Temp scratch = scratch_begin(0, 0); va_list args; va_start(args, fmt); String8 string = push_str8fv(scratch.arena, fmt, args); va_end(args); - UI_Signal sig = rd_line_edit(flags, depth, matches, cursor, mark, edit_buffer, edit_buffer_size, edit_string_size_out, expanded_out, pre_edit_value, string); + UI_Signal sig = rd_cell(params, string); scratch_end(scratch); return sig; } diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 9048161e..66d14bf3 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -5,21 +5,64 @@ #define RADDBG_WIDGETS_H //////////////////////////////// -//~ rjf: Line Edit Types +//~ rjf: Cell Types -typedef U32 RD_LineEditFlags; +typedef U32 RD_CellFlags; enum { - RD_LineEditFlag_Expander = (1<<0), - RD_LineEditFlag_ExpanderSpace = (1<<1), - RD_LineEditFlag_ExpanderPlaceholder = (1<<2), - RD_LineEditFlag_DisableEdit = (1<<3), - RD_LineEditFlag_CodeContents = (1<<4), - RD_LineEditFlag_KeyboardClickable = (1<<5), - RD_LineEditFlag_Border = (1<<6), - RD_LineEditFlag_NoBackground = (1<<7), - RD_LineEditFlag_PreferDisplayString = (1<<8), - RD_LineEditFlag_DisplayStringIsCode = (1<<9), + //- rjf: expander + RD_CellFlag_Expander = (1<<0), + RD_CellFlag_ExpanderSpace = (1<<1), + RD_CellFlag_ExpanderPlaceholder = (1<<2), + + //- rjf: toggle switch extension + RD_CellFlag_ToggleSwitch = (1<<3), + + //- rjf: slider extension + RD_CellFlag_Slider = (1<<4), + + //- rjf: behavior + RD_CellFlag_DisableEdit = (1<<5), + RD_CellFlag_KeyboardClickable = (1<<6), + RD_CellFlag_SingleClickActivate = (1<<7), + + //- rjf: contents description + RD_CellFlag_CodeContents = (1<<8), + + //- rjf: appearance + RD_CellFlag_Border = (1<<9), + RD_CellFlag_NoBackground = (1<<10), + RD_CellFlag_Button = (1<<11), + RD_CellFlag_PreferDisplayString = (1<<12), + RD_CellFlag_DisplayStringIsCode = (1<<13), +}; + +typedef struct RD_CellParams RD_CellParams; +struct RD_CellParams +{ + //- rjf: catachall parameters + RD_CellFlags flags; + S32 depth; + FuzzyMatchRangeList *fuzzy_matches; + String8 pre_edit_value; + DR_FStrList fstrs; + + //- rjf: expander r/w info + B32 *expanded_out; + + //- rjf: toggle-switch r/w info + B32 *toggled_out; + + //- rjf: slider info r/w info + Rng1U64 slider_value_range; + U64 *slider_value_out; + + //- rjf: text editing r/w info + TxtPt *cursor; + TxtPt *mark; + U8 *edit_buffer; + U64 edit_buffer_size; + U64 *edit_string_size_out; }; //////////////////////////////// @@ -43,9 +86,9 @@ struct RD_CodeSliceParams String8 *line_text; Rng1U64 *line_ranges; TXT_TokenArray *line_tokens; - RD_EntityList *line_bps; + RD_CfgList *line_bps; CTRL_EntityList *line_ips; - RD_EntityList *line_pins; + RD_CfgList *line_pins; U64 *line_vaddrs; D_LineList *line_infos; DI_KeyList relevant_dbgi_keys; @@ -77,6 +120,14 @@ struct RD_CodeSliceSignal #define RD_Palette(code) UI_Palette(rd_palette_from_code(code)) #define RD_Font(slot) UI_Font(rd_font_from_slot(slot)) UI_TextRasterFlags(rd_raster_flags_from_slot((slot))) +//////////////////////////////// +//~ rjf: UI Widgets: Fancy Title Strings + +internal DR_FStrList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg); +internal DR_FStrList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_extras); +internal DR_FStrList rd_title_fstrs_from_code_name(Arena *arena, String8 code_name); +internal DR_FStrList rd_title_fstrs_from_file_path(Arena *arena, String8 file_path); + //////////////////////////////// //~ rjf: UI Widgets: Loading Overlay @@ -108,13 +159,13 @@ internal B32 rd_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count internal UI_Signal rd_label(String8 string); internal UI_Signal rd_error_label(String8 string); internal B32 rd_help_label(String8 string); -internal DR_FancyStringList rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string); +internal DR_FStrList rd_fstrs_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string); internal UI_Box *rd_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string); //////////////////////////////// //~ rjf: UI Widgets: Line Edit -internal UI_Signal rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, B32 *expanded_out, String8 pre_edit_value, String8 string); -internal UI_Signal rd_line_editf(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, B32 *expanded_out, String8 pre_edit_value, char *fmt, ...); +internal UI_Signal rd_cell(RD_CellParams *params, String8 string); +internal UI_Signal rd_cellf(RD_CellParams *params, char *fmt, ...); #endif // RADDBG_WIDGETS_H diff --git a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c index 4d16f78b..f3c72e7e 100644 --- a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c +++ b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c @@ -27,6 +27,7 @@ #include "coff/coff_parse.h" #include "codeview/codeview.h" #include "codeview/codeview_parse.h" +#include "codeview/codeview_enum.h" #include "msf/msf.h" #include "msf/msf_parse.h" #include "pdb/pdb.h" @@ -43,6 +44,7 @@ #include "coff/coff_parse.c" #include "codeview/codeview.c" #include "codeview/codeview_parse.c" +#include "codeview/codeview_enum.c" #include "msf/msf.c" #include "msf/msf_parse.c" #include "pdb/pdb.c" @@ -223,7 +225,7 @@ entry_point(CmdLine *cmdline) { convert2bake = p2r_convert(arena, user2convert); } - + //- rjf: dump breakpad text String8List dump = {0}; ProfScope("dump breakpad text") diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 06d13313..51e48649 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 11"; ""; diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index bcec4915..0b8e911a 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -787,12 +787,11 @@ ASYNC_WORK_DEF(p2r_units_convert_work) } // rjf: build line table, fill with parsed binary annotations - if(inlinee_lines_parsed != 0) { // rjf: grab checksums sub-section CV_C13SubSectionNode *file_chksms = unit_c13->file_chksms_sub_section; - + // rjf: gathered lines typedef struct LineChunk LineChunk; struct LineChunk @@ -810,12 +809,12 @@ ASYNC_WORK_DEF(p2r_units_convert_work) U32 last_file_off = max_U32; U32 curr_file_off = max_U32; RDIM_LineTable* line_table = 0; - + CV_C13InlineSiteDecoder decoder = cv_c13_inline_site_decoder_init(inlinee_lines_parsed->file_off, inlinee_lines_parsed->first_source_ln, base_voff); for(;;) { CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitFile) { last_file_off = curr_file_off; @@ -829,7 +828,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) if((last_file_off != max_U32 && last_file_off != curr_file_off)) { String8 seq_file_name = {0}; - + if(last_file_off + sizeof(CV_C13Checksum) <= file_chksms->size) { CV_C13Checksum *checksum = (CV_C13Checksum*)(unit_c13->data.str + file_chksms->off + last_file_off); @@ -901,7 +900,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) first_line_chunk = last_line_chunk = 0; total_line_chunk_line_count = 0; } - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitLine) { LineChunk *chunk = last_line_chunk; @@ -919,7 +918,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) chunk->count += 1; total_line_chunk_line_count += 1; } - + if(step.flags == 0) { break; @@ -2436,14 +2435,14 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) for(;;) { CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitRange) { // rjf: build new range & add to scope RDIM_Rng1U64 voff_range = { step.range.min, step.range.max }; rdim_scope_push_voff_range(arena, &sym_scopes, scope, voff_range); } - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_ExtendLastRange) { if(scope->voff_ranges.last != 0) @@ -2451,7 +2450,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) scope->voff_ranges.last->v.max = step.range.max; } } - + if(step.flags == 0) { break; @@ -2524,7 +2523,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) named_streams = pdb_named_stream_table_from_info(arena, info); MemoryCopyStruct(&auth_guid, &info->auth_guid); scratch_end(scratch); - + if (info->features & PDB_FeatureFlag_MINIMAL_DBG_INFO) { fprintf(stderr, "ERROR: PDB was linked with /DEBUG:FASTLINK (partial debug info is not supported). Please relink using /DEBUG:FULL."); os_abort(1); @@ -2888,13 +2887,13 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) if(in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 1: construct all root/stub types from TPI") { itype_type_ptrs = push_array(arena, RDIM_Type *, tpi_leaf->itype_opl); - + ////////////////////////// //- build basic type // { RDIM_DataModel data_model = rdim_infer_data_model(OperatingSystem_Windows, top_level_info.arch); - + RDI_TypeKind short_type = rdim_short_type_from_data_model(data_model); RDI_TypeKind ushort_type = rdim_unsigned_short_type_from_data_model(data_model); RDI_TypeKind int_type = rdim_int_type_from_data_model(data_model); @@ -2904,7 +2903,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) RDI_TypeKind long_long_type = rdim_long_long_type_from_data_model(data_model); RDI_TypeKind ulong_long_type = rdim_unsigned_long_long_type_from_data_model(data_model); RDI_TypeKind ptr_type = rdim_pointer_size_t_type_from_data_model(data_model); - + struct { char * name; @@ -2959,7 +2958,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { "char32_t" , RDI_TypeKind_Char32 , CV_BasicType_CHAR32 , 1, 1, 1 }, // always UTF-32 { "__pointer" , ptr_type , CV_BasicType_PTR , 0, 0, 0 } }; - + for(U64 i = 0; i < ArrayCount(table); i += 1) { U64 builtin_size; @@ -2971,14 +2970,14 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { builtin_size = rdi_size_from_basic_type_kind(table[i].kind_rdi); } - + RDIM_Type *builtin = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); builtin->kind = table[i].kind_rdi; builtin->name = str8_cstring(table[i].name); builtin->byte_size = builtin_size; - + itype_type_ptrs[table[i].kind_cv] = builtin; - + if(table[i].make_pointer_near) { CV_TypeIndex near_ptr_itype = table[i].kind_cv | 0x100; @@ -2986,7 +2985,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) ptr_near->kind = RDI_TypeKind_Ptr; ptr_near->byte_size = 2; ptr_near->direct_type = builtin; - + itype_type_ptrs[near_ptr_itype] = ptr_near; } if(table[i].make_pointer_32) @@ -2996,7 +2995,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) ptr_32->kind = RDI_TypeKind_Ptr; ptr_32->byte_size = 4; ptr_32->direct_type = builtin; - + itype_type_ptrs[ptr_32_itype] = ptr_32; } if(table[i].make_pointer_64) @@ -3006,12 +3005,12 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) ptr_64->kind = RDI_TypeKind_Ptr; ptr_64->byte_size = 8; ptr_64->direct_type = builtin; - + itype_type_ptrs[ptr_64_itype] = ptr_64; } } } - + ////////////////////////// //- rjf: build non-basic type // @@ -3021,7 +3020,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) CV_RecRange *range = &tpi_leaf->leaf_ranges.ranges[itype-tpi_leaf->itype_first]; CV_LeafKind kind = range->hdr.kind; U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); - + if(range->off+range->hdr.size <= tpi_leaf->data.size && range->off+2+header_struct_size <= tpi_leaf->data.size && range->hdr.size >= 2) @@ -3278,7 +3277,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_Class : RDI_TypeKind_Struct); } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3286,7 +3285,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) U8 *unique_name_ptr = name_ptr + name.size + 1; dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); } - + dst_type->name = name; dst_type->byte_size = safe_cast_u32(size_u64); }break; @@ -3318,7 +3317,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) dst_type->byte_size = (U32)size_u64; dst_type->name = name; } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3354,7 +3353,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) dst_type->byte_size = (U32)size_u64; dst_type->name = name; } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3389,7 +3388,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) dst_type->byte_size = direct_type ? direct_type->byte_size : 0; dst_type->name = name; } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3576,7 +3575,7 @@ p2r_bake(Arena *arena, P2R_Convert2Bake *in) help_state.arena = p2r_state->arena; help_state.work_thread_arenas_count = p2r_state->work_thread_arenas_count; help_state.work_thread_arenas = p2r_state->work_thread_arenas; - + P2R_Bake2Serialize *result = push_array(arena, P2R_Bake2Serialize, 1); result->bake_results = rdim_bake(&help_state, &in->bake_params); return result; diff --git a/src/render/d3d11/generated/render_d3d11.meta.h b/src/render/d3d11/generated/render_d3d11.meta.h index 1031599d..5f5e1f12 100644 --- a/src/render/d3d11/generated/render_d3d11.meta.h +++ b/src/render/d3d11/generated/render_d3d11.meta.h @@ -83,6 +83,20 @@ str8_lit_comp( " return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r;\n" "}\n" "\n" +"float linear_from_srgb_f32(float x)\n" +"{\n" +" return x < 0.0404482362771082 ? x / 12.92 : pow((x + 0.055) / 1.055, 2.4);\n" +"}\n" +"\n" +"float4 linear_from_srgba(float4 v)\n" +"{\n" +" float4 result = float4(linear_from_srgb_f32(v.x),\n" +" linear_from_srgb_f32(v.y),\n" +" linear_from_srgb_f32(v.z),\n" +" v.w);\n" +" return result;\n" +"}\n" +"\n" "//- rjf: vertex shader\n" "\n" "Vertex2Pixel\n" @@ -122,7 +136,8 @@ str8_lit_comp( " cpu2vertex.corner_radii_px.w,\n" " cpu2vertex.corner_radii_px.z,\n" " };\n" -" float4 src_color[] = {\n" +" float4 src_color[] =\n" +" {\n" " cpu2vertex.color01,\n" " cpu2vertex.color00,\n" " cpu2vertex.color11,\n" @@ -164,6 +179,7 @@ str8_lit_comp( " if(vertex2pixel.omit_texture < 1)\n" " {\n" " albedo_sample = mul(main_t2d.Sample(main_sampler, vertex2pixel.texcoord_pct), texture_sample_channel_map);\n" +" albedo_sample = linear_from_srgba(albedo_sample);\n" " }\n" " \n" " // rjf: determine SDF sample position\n" diff --git a/src/render/d3d11/render_d3d11.c b/src/render/d3d11/render_d3d11.c index 84ac64a7..d4cdd22c 100644 --- a/src/render/d3d11/render_d3d11.c +++ b/src/render/d3d11/render_d3d11.c @@ -520,7 +520,7 @@ r_window_equip(OS_Handle handle) { swapchain_desc.Width = 0; // NOTE(rjf): use window width swapchain_desc.Height = 0; // NOTE(rjf): use window height - swapchain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + swapchain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; swapchain_desc.Stereo = FALSE; swapchain_desc.SampleDesc.Count = 1; swapchain_desc.SampleDesc.Quality = 0; @@ -672,8 +672,11 @@ r_tex2d_release(R_Handle handle) ProfBeginFunction(); OS_MutexScopeW(r_d3d11_state->device_rw_mutex) { - R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); - SLLStackPush(r_d3d11_state->first_to_free_tex2d, texture); + R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); + if(texture != &r_d3d11_tex2d_nil) + { + SLLStackPush(r_d3d11_state->first_to_free_tex2d, texture); + } } ProfEnd(); } @@ -705,16 +708,19 @@ r_fill_tex2d_region(R_Handle handle, Rng2S32 subrect, void *data) ProfBeginFunction(); OS_MutexScopeW(r_d3d11_state->device_rw_mutex) { - R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); - Assert(texture->kind == R_ResourceKind_Dynamic && "only dynamic texture can update region"); - U64 bytes_per_pixel = r_tex2d_format_bytes_per_pixel_table[texture->format]; - Vec2S32 dim = v2s32(subrect.x1 - subrect.x0, subrect.y1 - subrect.y0); - D3D11_BOX dst_box = - { - (UINT)subrect.x0, (UINT)subrect.y0, 0, - (UINT)subrect.x1, (UINT)subrect.y1, 1, - }; - r_d3d11_state->device_ctx->lpVtbl->UpdateSubresource(r_d3d11_state->device_ctx, (ID3D11Resource *)texture->texture, 0, &dst_box, data, dim.x*bytes_per_pixel, 0); + R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); + if(texture != &r_d3d11_tex2d_nil) + { + Assert(texture->kind == R_ResourceKind_Dynamic && "only dynamic texture can update region"); + U64 bytes_per_pixel = r_tex2d_format_bytes_per_pixel_table[texture->format]; + Vec2S32 dim = v2s32(subrect.x1 - subrect.x0, subrect.y1 - subrect.y0); + D3D11_BOX dst_box = + { + (UINT)subrect.x0, (UINT)subrect.y0, 0, + (UINT)subrect.x1, (UINT)subrect.y1, 1, + }; + r_d3d11_state->device_ctx->lpVtbl->UpdateSubresource(r_d3d11_state->device_ctx, (ID3D11Resource *)texture->texture, 0, &dst_box, data, dim.x*bytes_per_pixel, 0); + } } ProfEnd(); } @@ -820,8 +826,10 @@ r_end_frame(void) tex = next) { next = tex->next; - tex->view->lpVtbl->Release(tex->view); - tex->texture->lpVtbl->Release(tex->texture); + tex->view->lpVtbl->Release(tex->view); + tex->texture->lpVtbl->Release(tex->texture); + tex->view = 0; + tex->texture = 0; tex->generation += 1; SLLStackPush(r_d3d11_state->first_free_tex2d, tex); } @@ -888,7 +896,7 @@ r_window_begin_frame(OS_Handle window, R_Handle window_equip) D3D11_TEXTURE2D_DESC color_desc = zero_struct; { wnd->framebuffer->lpVtbl->GetDesc(wnd->framebuffer, &color_desc); - color_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + color_desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; color_desc.BindFlags = D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE; } D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = zero_struct; @@ -898,7 +906,7 @@ r_window_begin_frame(OS_Handle window, R_Handle window_equip) } D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = zero_struct; { - srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srv_desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srv_desc.Texture2D.MipLevels = -1; } diff --git a/src/render/d3d11/render_d3d11.h b/src/render/d3d11/render_d3d11.h index 5bdec2ab..aba28899 100644 --- a/src/render/d3d11/render_d3d11.h +++ b/src/render/d3d11/render_d3d11.h @@ -171,9 +171,9 @@ struct R_D3D11_State //~ rjf: Globals global R_D3D11_State *r_d3d11_state = 0; -global R_D3D11_Window r_d3d11_window_nil = {&r_d3d11_window_nil}; -global R_D3D11_Tex2D r_d3d11_tex2d_nil = {&r_d3d11_tex2d_nil}; -global R_D3D11_Buffer r_d3d11_buffer_nil = {&r_d3d11_buffer_nil}; +global read_only R_D3D11_Window r_d3d11_window_nil = {&r_d3d11_window_nil}; +global read_only R_D3D11_Tex2D r_d3d11_tex2d_nil = {&r_d3d11_tex2d_nil}; +global read_only R_D3D11_Buffer r_d3d11_buffer_nil = {&r_d3d11_buffer_nil}; //////////////////////////////// //~ rjf: Helpers diff --git a/src/render/d3d11/render_d3d11.mdesk b/src/render/d3d11/render_d3d11.mdesk index d05aad0f..1c78b56b 100644 --- a/src/render/d3d11/render_d3d11.mdesk +++ b/src/render/d3d11/render_d3d11.mdesk @@ -81,6 +81,20 @@ float rect_sdf(float2 sample_pos, float2 rect_half_size, float r) return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r; } +float linear_from_srgb_f32(float x) +{ + return x < 0.0404482362771082 ? x / 12.92 : pow((x + 0.055) / 1.055, 2.4); +} + +float4 linear_from_srgba(float4 v) +{ + float4 result = float4(linear_from_srgb_f32(v.x), + linear_from_srgb_f32(v.y), + linear_from_srgb_f32(v.z), + v.w); + return result; +} + //- rjf: vertex shader Vertex2Pixel @@ -120,7 +134,8 @@ vs_main(CPU2Vertex cpu2vertex) cpu2vertex.corner_radii_px.w, cpu2vertex.corner_radii_px.z, }; - float4 src_color[] = { + float4 src_color[] = + { cpu2vertex.color01, cpu2vertex.color00, cpu2vertex.color11, @@ -162,6 +177,7 @@ ps_main(Vertex2Pixel vertex2pixel) : SV_TARGET if(vertex2pixel.omit_texture < 1) { albedo_sample = mul(main_t2d.Sample(main_sampler, vertex2pixel.texcoord_pct), texture_sample_channel_map); + albedo_sample = linear_from_srgba(albedo_sample); } // rjf: determine SDF sample position diff --git a/src/text_cache/text_cache.c b/src/text_cache/text_cache.c index 377ee516..7a1fae94 100644 --- a/src/text_cache/text_cache.c +++ b/src/text_cache/text_cache.c @@ -2313,6 +2313,7 @@ ASYNC_WORK_DEF(txt_parse_work) { if(u128_match(n->hash, hash) && n->lang == lang) { + hs_hash_downstream_inc(n->hash); n->arena = info_arena; info.bytes_processed = n->info.bytes_processed; info.bytes_to_process = n->info.bytes_to_process; @@ -2340,7 +2341,7 @@ txt_evictor_thread__entry_point(void *p) { U64 check_time_us = os_now_microseconds(); U64 check_time_user_clocks = update_tick_idx(); - U64 evict_threshold_us = 10*1000000; + U64 evict_threshold_us = 2*1000000; U64 evict_threshold_user_clocks = 10; for(U64 slot_idx = 0; slot_idx < txt_shared->slots_count; slot_idx += 1) { @@ -2375,6 +2376,7 @@ txt_evictor_thread__entry_point(void *p) n->is_working == 0) { DLLRemove(slot->first, slot->last, n); + hs_hash_downstream_dec(n->hash); if(n->arena != 0) { arena_release(n->arena); @@ -2383,8 +2385,7 @@ txt_evictor_thread__entry_point(void *p) } } } - os_sleep_milliseconds(5); } - os_sleep_milliseconds(1000); + os_sleep_milliseconds(500); } } diff --git a/src/ui/generated/ui.meta.c b/src/ui/generated/ui.meta.c index f1490347..4748e2a6 100644 --- a/src/ui/generated/ui.meta.c +++ b/src/ui/generated/ui.meta.c @@ -14,12 +14,15 @@ #define UI_PrefHeight(v) DeferLoop(ui_push_pref_height(v), ui_pop_pref_height()) #define UI_PermissionFlags(v) DeferLoop(ui_push_permission_flags(v), ui_pop_permission_flags()) #define UI_Flags(v) DeferLoop(ui_push_flags(v), ui_pop_flags()) +#define UI_OmitFlags(v) DeferLoop(ui_push_omit_flags(v), ui_pop_omit_flags()) #define UI_FocusHot(v) DeferLoop(ui_push_focus_hot(v), ui_pop_focus_hot()) #define UI_FocusActive(v) DeferLoop(ui_push_focus_active(v), ui_pop_focus_active()) #define UI_FastpathCodepoint(v) DeferLoop(ui_push_fastpath_codepoint(v), ui_pop_fastpath_codepoint()) #define UI_GroupKey(v) DeferLoop(ui_push_group_key(v), ui_pop_group_key()) #define UI_Transparency(v) DeferLoop(ui_push_transparency(v), ui_pop_transparency()) -#define UI_Palette(v) DeferLoop(ui_push_palette(v), ui_pop_palette()) +#define UI_Tag(v) DeferLoop(ui_push_tag(v), ui_pop_tag()) +#define UI_BackgroundColor(v) DeferLoop(ui_push_background_color(v), ui_pop_background_color()) +#define UI_TextColor(v) DeferLoop(ui_push_text_color(v), ui_pop_text_color()) #define UI_Squish(v) DeferLoop(ui_push_squish(v), ui_pop_squish()) #define UI_HoverCursor(v) DeferLoop(ui_push_hover_cursor(v), ui_pop_hover_cursor()) #define UI_Font(v) DeferLoop(ui_push_font(v), ui_pop_font()) @@ -44,12 +47,14 @@ internal UI_Size ui_top_pref_width(void) { UI_StackTopImpl(ui_state, PrefWidth, internal UI_Size ui_top_pref_height(void) { UI_StackTopImpl(ui_state, PrefHeight, pref_height) } internal UI_PermissionFlags ui_top_permission_flags(void) { UI_StackTopImpl(ui_state, PermissionFlags, permission_flags) } internal UI_BoxFlags ui_top_flags(void) { UI_StackTopImpl(ui_state, Flags, flags) } +internal UI_BoxFlags ui_top_omit_flags(void) { UI_StackTopImpl(ui_state, OmitFlags, omit_flags) } internal UI_FocusKind ui_top_focus_hot(void) { UI_StackTopImpl(ui_state, FocusHot, focus_hot) } internal UI_FocusKind ui_top_focus_active(void) { UI_StackTopImpl(ui_state, FocusActive, focus_active) } internal U32 ui_top_fastpath_codepoint(void) { UI_StackTopImpl(ui_state, FastpathCodepoint, fastpath_codepoint) } internal UI_Key ui_top_group_key(void) { UI_StackTopImpl(ui_state, GroupKey, group_key) } internal F32 ui_top_transparency(void) { UI_StackTopImpl(ui_state, Transparency, transparency) } -internal UI_Palette* ui_top_palette(void) { UI_StackTopImpl(ui_state, Palette, palette) } +internal Vec4F32 ui_top_background_color(void) { UI_StackTopImpl(ui_state, BackgroundColor, background_color) } +internal Vec4F32 ui_top_text_color(void) { UI_StackTopImpl(ui_state, TextColor, text_color) } internal F32 ui_top_squish(void) { UI_StackTopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_top_hover_cursor(void) { UI_StackTopImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_top_font(void) { UI_StackTopImpl(ui_state, Font, font) } @@ -73,12 +78,14 @@ internal UI_Size ui_bottom_pref_width(void) { UI_StackBottomImpl(ui_state, PrefW internal UI_Size ui_bottom_pref_height(void) { UI_StackBottomImpl(ui_state, PrefHeight, pref_height) } internal UI_PermissionFlags ui_bottom_permission_flags(void) { UI_StackBottomImpl(ui_state, PermissionFlags, permission_flags) } internal UI_BoxFlags ui_bottom_flags(void) { UI_StackBottomImpl(ui_state, Flags, flags) } +internal UI_BoxFlags ui_bottom_omit_flags(void) { UI_StackBottomImpl(ui_state, OmitFlags, omit_flags) } internal UI_FocusKind ui_bottom_focus_hot(void) { UI_StackBottomImpl(ui_state, FocusHot, focus_hot) } internal UI_FocusKind ui_bottom_focus_active(void) { UI_StackBottomImpl(ui_state, FocusActive, focus_active) } internal U32 ui_bottom_fastpath_codepoint(void) { UI_StackBottomImpl(ui_state, FastpathCodepoint, fastpath_codepoint) } internal UI_Key ui_bottom_group_key(void) { UI_StackBottomImpl(ui_state, GroupKey, group_key) } internal F32 ui_bottom_transparency(void) { UI_StackBottomImpl(ui_state, Transparency, transparency) } -internal UI_Palette* ui_bottom_palette(void) { UI_StackBottomImpl(ui_state, Palette, palette) } +internal Vec4F32 ui_bottom_background_color(void) { UI_StackBottomImpl(ui_state, BackgroundColor, background_color) } +internal Vec4F32 ui_bottom_text_color(void) { UI_StackBottomImpl(ui_state, TextColor, text_color) } internal F32 ui_bottom_squish(void) { UI_StackBottomImpl(ui_state, Squish, squish) } internal OS_Cursor ui_bottom_hover_cursor(void) { UI_StackBottomImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_bottom_font(void) { UI_StackBottomImpl(ui_state, Font, font) } @@ -102,12 +109,14 @@ internal UI_Size ui_push_pref_width(UI_Size v) { UI_StackPushImpl(ui_state, Pref internal UI_Size ui_push_pref_height(UI_Size v) { UI_StackPushImpl(ui_state, PrefHeight, pref_height, UI_Size, v) } internal UI_PermissionFlags ui_push_permission_flags(UI_PermissionFlags v) { UI_StackPushImpl(ui_state, PermissionFlags, permission_flags, UI_PermissionFlags, v) } internal UI_BoxFlags ui_push_flags(UI_BoxFlags v) { UI_StackPushImpl(ui_state, Flags, flags, UI_BoxFlags, v) } +internal UI_BoxFlags ui_push_omit_flags(UI_BoxFlags v) { UI_StackPushImpl(ui_state, OmitFlags, omit_flags, UI_BoxFlags, v) } internal UI_FocusKind ui_push_focus_hot(UI_FocusKind v) { UI_StackPushImpl(ui_state, FocusHot, focus_hot, UI_FocusKind, v) } internal UI_FocusKind ui_push_focus_active(UI_FocusKind v) { UI_StackPushImpl(ui_state, FocusActive, focus_active, UI_FocusKind, v) } internal U32 ui_push_fastpath_codepoint(U32 v) { UI_StackPushImpl(ui_state, FastpathCodepoint, fastpath_codepoint, U32, v) } internal UI_Key ui_push_group_key(UI_Key v) { UI_StackPushImpl(ui_state, GroupKey, group_key, UI_Key, v) } internal F32 ui_push_transparency(F32 v) { UI_StackPushImpl(ui_state, Transparency, transparency, F32, v) } -internal UI_Palette* ui_push_palette(UI_Palette* v) { UI_StackPushImpl(ui_state, Palette, palette, UI_Palette* , v) } +internal Vec4F32 ui_push_background_color(Vec4F32 v) { UI_StackPushImpl(ui_state, BackgroundColor, background_color, Vec4F32, v) } +internal Vec4F32 ui_push_text_color(Vec4F32 v) { UI_StackPushImpl(ui_state, TextColor, text_color, Vec4F32, v) } internal F32 ui_push_squish(F32 v) { UI_StackPushImpl(ui_state, Squish, squish, F32, v) } internal OS_Cursor ui_push_hover_cursor(OS_Cursor v) { UI_StackPushImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal FNT_Tag ui_push_font(FNT_Tag v) { UI_StackPushImpl(ui_state, Font, font, FNT_Tag, v) } @@ -131,12 +140,14 @@ internal UI_Size ui_pop_pref_width(void) { UI_StackPopImpl(ui_state, PrefWidth, internal UI_Size ui_pop_pref_height(void) { UI_StackPopImpl(ui_state, PrefHeight, pref_height) } internal UI_PermissionFlags ui_pop_permission_flags(void) { UI_StackPopImpl(ui_state, PermissionFlags, permission_flags) } internal UI_BoxFlags ui_pop_flags(void) { UI_StackPopImpl(ui_state, Flags, flags) } +internal UI_BoxFlags ui_pop_omit_flags(void) { UI_StackPopImpl(ui_state, OmitFlags, omit_flags) } internal UI_FocusKind ui_pop_focus_hot(void) { UI_StackPopImpl(ui_state, FocusHot, focus_hot) } internal UI_FocusKind ui_pop_focus_active(void) { UI_StackPopImpl(ui_state, FocusActive, focus_active) } internal U32 ui_pop_fastpath_codepoint(void) { UI_StackPopImpl(ui_state, FastpathCodepoint, fastpath_codepoint) } internal UI_Key ui_pop_group_key(void) { UI_StackPopImpl(ui_state, GroupKey, group_key) } internal F32 ui_pop_transparency(void) { UI_StackPopImpl(ui_state, Transparency, transparency) } -internal UI_Palette* ui_pop_palette(void) { UI_StackPopImpl(ui_state, Palette, palette) } +internal Vec4F32 ui_pop_background_color(void) { UI_StackPopImpl(ui_state, BackgroundColor, background_color) } +internal Vec4F32 ui_pop_text_color(void) { UI_StackPopImpl(ui_state, TextColor, text_color) } internal F32 ui_pop_squish(void) { UI_StackPopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_pop_hover_cursor(void) { UI_StackPopImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_pop_font(void) { UI_StackPopImpl(ui_state, Font, font) } @@ -160,12 +171,14 @@ internal UI_Size ui_set_next_pref_width(UI_Size v) { UI_StackSetNextImpl(ui_stat internal UI_Size ui_set_next_pref_height(UI_Size v) { UI_StackSetNextImpl(ui_state, PrefHeight, pref_height, UI_Size, v) } internal UI_PermissionFlags ui_set_next_permission_flags(UI_PermissionFlags v) { UI_StackSetNextImpl(ui_state, PermissionFlags, permission_flags, UI_PermissionFlags, v) } internal UI_BoxFlags ui_set_next_flags(UI_BoxFlags v) { UI_StackSetNextImpl(ui_state, Flags, flags, UI_BoxFlags, v) } +internal UI_BoxFlags ui_set_next_omit_flags(UI_BoxFlags v) { UI_StackSetNextImpl(ui_state, OmitFlags, omit_flags, UI_BoxFlags, v) } internal UI_FocusKind ui_set_next_focus_hot(UI_FocusKind v) { UI_StackSetNextImpl(ui_state, FocusHot, focus_hot, UI_FocusKind, v) } internal UI_FocusKind ui_set_next_focus_active(UI_FocusKind v) { UI_StackSetNextImpl(ui_state, FocusActive, focus_active, UI_FocusKind, v) } internal U32 ui_set_next_fastpath_codepoint(U32 v) { UI_StackSetNextImpl(ui_state, FastpathCodepoint, fastpath_codepoint, U32, v) } internal UI_Key ui_set_next_group_key(UI_Key v) { UI_StackSetNextImpl(ui_state, GroupKey, group_key, UI_Key, v) } internal F32 ui_set_next_transparency(F32 v) { UI_StackSetNextImpl(ui_state, Transparency, transparency, F32, v) } -internal UI_Palette* ui_set_next_palette(UI_Palette* v) { UI_StackSetNextImpl(ui_state, Palette, palette, UI_Palette* , v) } +internal Vec4F32 ui_set_next_background_color(Vec4F32 v) { UI_StackSetNextImpl(ui_state, BackgroundColor, background_color, Vec4F32, v) } +internal Vec4F32 ui_set_next_text_color(Vec4F32 v) { UI_StackSetNextImpl(ui_state, TextColor, text_color, Vec4F32, v) } internal F32 ui_set_next_squish(F32 v) { UI_StackSetNextImpl(ui_state, Squish, squish, F32, v) } internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v) { UI_StackSetNextImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal FNT_Tag ui_set_next_font(FNT_Tag v) { UI_StackSetNextImpl(ui_state, Font, font, FNT_Tag, v) } diff --git a/src/ui/generated/ui.meta.h b/src/ui/generated/ui.meta.h index 28c38de8..3148b82e 100644 --- a/src/ui/generated/ui.meta.h +++ b/src/ui/generated/ui.meta.h @@ -16,12 +16,15 @@ typedef struct UI_PrefWidthNode UI_PrefWidthNode; struct UI_PrefWidthNode{UI_Pre typedef struct UI_PrefHeightNode UI_PrefHeightNode; struct UI_PrefHeightNode{UI_PrefHeightNode *next; UI_Size v;}; typedef struct UI_PermissionFlagsNode UI_PermissionFlagsNode; struct UI_PermissionFlagsNode{UI_PermissionFlagsNode *next; UI_PermissionFlags v;}; typedef struct UI_FlagsNode UI_FlagsNode; struct UI_FlagsNode{UI_FlagsNode *next; UI_BoxFlags v;}; +typedef struct UI_OmitFlagsNode UI_OmitFlagsNode; struct UI_OmitFlagsNode{UI_OmitFlagsNode *next; UI_BoxFlags v;}; typedef struct UI_FocusHotNode UI_FocusHotNode; struct UI_FocusHotNode{UI_FocusHotNode *next; UI_FocusKind v;}; typedef struct UI_FocusActiveNode UI_FocusActiveNode; struct UI_FocusActiveNode{UI_FocusActiveNode *next; UI_FocusKind v;}; typedef struct UI_FastpathCodepointNode UI_FastpathCodepointNode; struct UI_FastpathCodepointNode{UI_FastpathCodepointNode *next; U32 v;}; typedef struct UI_GroupKeyNode UI_GroupKeyNode; struct UI_GroupKeyNode{UI_GroupKeyNode *next; UI_Key v;}; typedef struct UI_TransparencyNode UI_TransparencyNode; struct UI_TransparencyNode{UI_TransparencyNode *next; F32 v;}; -typedef struct UI_PaletteNode UI_PaletteNode; struct UI_PaletteNode{UI_PaletteNode *next; UI_Palette* v;}; +typedef struct UI_TagNode UI_TagNode; struct UI_TagNode{UI_TagNode *next; String8 v;}; +typedef struct UI_BackgroundColorNode UI_BackgroundColorNode; struct UI_BackgroundColorNode{UI_BackgroundColorNode *next; Vec4F32 v;}; +typedef struct UI_TextColorNode UI_TextColorNode; struct UI_TextColorNode{UI_TextColorNode *next; Vec4F32 v;}; typedef struct UI_SquishNode UI_SquishNode; struct UI_SquishNode{UI_SquishNode *next; F32 v;}; typedef struct UI_HoverCursorNode UI_HoverCursorNode; struct UI_HoverCursorNode{UI_HoverCursorNode *next; OS_Cursor v;}; typedef struct UI_FontNode UI_FontNode; struct UI_FontNode{UI_FontNode *next; FNT_Tag v;}; @@ -48,12 +51,15 @@ UI_PrefWidthNode pref_width_nil_stack_top;\ UI_PrefHeightNode pref_height_nil_stack_top;\ UI_PermissionFlagsNode permission_flags_nil_stack_top;\ UI_FlagsNode flags_nil_stack_top;\ +UI_OmitFlagsNode omit_flags_nil_stack_top;\ UI_FocusHotNode focus_hot_nil_stack_top;\ UI_FocusActiveNode focus_active_nil_stack_top;\ UI_FastpathCodepointNode fastpath_codepoint_nil_stack_top;\ UI_GroupKeyNode group_key_nil_stack_top;\ UI_TransparencyNode transparency_nil_stack_top;\ -UI_PaletteNode palette_nil_stack_top;\ +UI_TagNode tag_nil_stack_top;\ +UI_BackgroundColorNode background_color_nil_stack_top;\ +UI_TextColorNode text_color_nil_stack_top;\ UI_SquishNode squish_nil_stack_top;\ UI_HoverCursorNode hover_cursor_nil_stack_top;\ UI_FontNode font_nil_stack_top;\ @@ -79,12 +85,15 @@ state->pref_width_nil_stack_top.v = ui_px(250.f, 1.f);\ state->pref_height_nil_stack_top.v = ui_px(30.f, 1.f);\ state->permission_flags_nil_stack_top.v = UI_PermissionFlag_All;\ state->flags_nil_stack_top.v = 0;\ +state->omit_flags_nil_stack_top.v = 0;\ state->focus_hot_nil_stack_top.v = UI_FocusKind_Null;\ state->focus_active_nil_stack_top.v = UI_FocusKind_Null;\ state->fastpath_codepoint_nil_stack_top.v = 0;\ state->group_key_nil_stack_top.v = ui_key_zero();\ state->transparency_nil_stack_top.v = 0;\ -state->palette_nil_stack_top.v = &ui_g_nil_palette;\ +state->tag_nil_stack_top.v = str8_lit("");\ +state->background_color_nil_stack_top.v = v4f32(0, 0, 0, 0);\ +state->text_color_nil_stack_top.v = v4f32(0, 0, 0, 0);\ state->squish_nil_stack_top.v = 0;\ state->hover_cursor_nil_stack_top.v = OS_Cursor_Pointer;\ state->font_nil_stack_top.v = fnt_tag_zero();\ @@ -102,35 +111,38 @@ state->text_alignment_nil_stack_top.v = UI_TextAlign_Left;\ #define UI_DeclStacks \ struct\ {\ -struct { UI_ParentNode *top; UI_Box * bottom_val; UI_ParentNode *free; B32 auto_pop; } parent_stack;\ -struct { UI_ChildLayoutAxisNode *top; Axis2 bottom_val; UI_ChildLayoutAxisNode *free; B32 auto_pop; } child_layout_axis_stack;\ -struct { UI_FixedXNode *top; F32 bottom_val; UI_FixedXNode *free; B32 auto_pop; } fixed_x_stack;\ -struct { UI_FixedYNode *top; F32 bottom_val; UI_FixedYNode *free; B32 auto_pop; } fixed_y_stack;\ -struct { UI_FixedWidthNode *top; F32 bottom_val; UI_FixedWidthNode *free; B32 auto_pop; } fixed_width_stack;\ -struct { UI_FixedHeightNode *top; F32 bottom_val; UI_FixedHeightNode *free; B32 auto_pop; } fixed_height_stack;\ -struct { UI_PrefWidthNode *top; UI_Size bottom_val; UI_PrefWidthNode *free; B32 auto_pop; } pref_width_stack;\ -struct { UI_PrefHeightNode *top; UI_Size bottom_val; UI_PrefHeightNode *free; B32 auto_pop; } pref_height_stack;\ -struct { UI_PermissionFlagsNode *top; UI_PermissionFlags bottom_val; UI_PermissionFlagsNode *free; B32 auto_pop; } permission_flags_stack;\ -struct { UI_FlagsNode *top; UI_BoxFlags bottom_val; UI_FlagsNode *free; B32 auto_pop; } flags_stack;\ -struct { UI_FocusHotNode *top; UI_FocusKind bottom_val; UI_FocusHotNode *free; B32 auto_pop; } focus_hot_stack;\ -struct { UI_FocusActiveNode *top; UI_FocusKind bottom_val; UI_FocusActiveNode *free; B32 auto_pop; } focus_active_stack;\ -struct { UI_FastpathCodepointNode *top; U32 bottom_val; UI_FastpathCodepointNode *free; B32 auto_pop; } fastpath_codepoint_stack;\ -struct { UI_GroupKeyNode *top; UI_Key bottom_val; UI_GroupKeyNode *free; B32 auto_pop; } group_key_stack;\ -struct { UI_TransparencyNode *top; F32 bottom_val; UI_TransparencyNode *free; B32 auto_pop; } transparency_stack;\ -struct { UI_PaletteNode *top; UI_Palette* bottom_val; UI_PaletteNode *free; B32 auto_pop; } palette_stack;\ -struct { UI_SquishNode *top; F32 bottom_val; UI_SquishNode *free; B32 auto_pop; } squish_stack;\ -struct { UI_HoverCursorNode *top; OS_Cursor bottom_val; UI_HoverCursorNode *free; B32 auto_pop; } hover_cursor_stack;\ -struct { UI_FontNode *top; FNT_Tag bottom_val; UI_FontNode *free; B32 auto_pop; } font_stack;\ -struct { UI_FontSizeNode *top; F32 bottom_val; UI_FontSizeNode *free; B32 auto_pop; } font_size_stack;\ -struct { UI_TextRasterFlagsNode *top; FNT_RasterFlags bottom_val; UI_TextRasterFlagsNode *free; B32 auto_pop; } text_raster_flags_stack;\ -struct { UI_TabSizeNode *top; F32 bottom_val; UI_TabSizeNode *free; B32 auto_pop; } tab_size_stack;\ -struct { UI_CornerRadius00Node *top; F32 bottom_val; UI_CornerRadius00Node *free; B32 auto_pop; } corner_radius_00_stack;\ -struct { UI_CornerRadius01Node *top; F32 bottom_val; UI_CornerRadius01Node *free; B32 auto_pop; } corner_radius_01_stack;\ -struct { UI_CornerRadius10Node *top; F32 bottom_val; UI_CornerRadius10Node *free; B32 auto_pop; } corner_radius_10_stack;\ -struct { UI_CornerRadius11Node *top; F32 bottom_val; UI_CornerRadius11Node *free; B32 auto_pop; } corner_radius_11_stack;\ -struct { UI_BlurSizeNode *top; F32 bottom_val; UI_BlurSizeNode *free; B32 auto_pop; } blur_size_stack;\ -struct { UI_TextPaddingNode *top; F32 bottom_val; UI_TextPaddingNode *free; B32 auto_pop; } text_padding_stack;\ -struct { UI_TextAlignmentNode *top; UI_TextAlign bottom_val; UI_TextAlignmentNode *free; B32 auto_pop; } text_alignment_stack;\ +struct { UI_ParentNode *top; UI_Box * bottom_val; UI_ParentNode *free; U64 gen; B32 auto_pop; } parent_stack;\ +struct { UI_ChildLayoutAxisNode *top; Axis2 bottom_val; UI_ChildLayoutAxisNode *free; U64 gen; B32 auto_pop; } child_layout_axis_stack;\ +struct { UI_FixedXNode *top; F32 bottom_val; UI_FixedXNode *free; U64 gen; B32 auto_pop; } fixed_x_stack;\ +struct { UI_FixedYNode *top; F32 bottom_val; UI_FixedYNode *free; U64 gen; B32 auto_pop; } fixed_y_stack;\ +struct { UI_FixedWidthNode *top; F32 bottom_val; UI_FixedWidthNode *free; U64 gen; B32 auto_pop; } fixed_width_stack;\ +struct { UI_FixedHeightNode *top; F32 bottom_val; UI_FixedHeightNode *free; U64 gen; B32 auto_pop; } fixed_height_stack;\ +struct { UI_PrefWidthNode *top; UI_Size bottom_val; UI_PrefWidthNode *free; U64 gen; B32 auto_pop; } pref_width_stack;\ +struct { UI_PrefHeightNode *top; UI_Size bottom_val; UI_PrefHeightNode *free; U64 gen; B32 auto_pop; } pref_height_stack;\ +struct { UI_PermissionFlagsNode *top; UI_PermissionFlags bottom_val; UI_PermissionFlagsNode *free; U64 gen; B32 auto_pop; } permission_flags_stack;\ +struct { UI_FlagsNode *top; UI_BoxFlags bottom_val; UI_FlagsNode *free; U64 gen; B32 auto_pop; } flags_stack;\ +struct { UI_OmitFlagsNode *top; UI_BoxFlags bottom_val; UI_OmitFlagsNode *free; U64 gen; B32 auto_pop; } omit_flags_stack;\ +struct { UI_FocusHotNode *top; UI_FocusKind bottom_val; UI_FocusHotNode *free; U64 gen; B32 auto_pop; } focus_hot_stack;\ +struct { UI_FocusActiveNode *top; UI_FocusKind bottom_val; UI_FocusActiveNode *free; U64 gen; B32 auto_pop; } focus_active_stack;\ +struct { UI_FastpathCodepointNode *top; U32 bottom_val; UI_FastpathCodepointNode *free; U64 gen; B32 auto_pop; } fastpath_codepoint_stack;\ +struct { UI_GroupKeyNode *top; UI_Key bottom_val; UI_GroupKeyNode *free; U64 gen; B32 auto_pop; } group_key_stack;\ +struct { UI_TransparencyNode *top; F32 bottom_val; UI_TransparencyNode *free; U64 gen; B32 auto_pop; } transparency_stack;\ +struct { UI_TagNode *top; String8 bottom_val; UI_TagNode *free; U64 gen; B32 auto_pop; } tag_stack;\ +struct { UI_BackgroundColorNode *top; Vec4F32 bottom_val; UI_BackgroundColorNode *free; U64 gen; B32 auto_pop; } background_color_stack;\ +struct { UI_TextColorNode *top; Vec4F32 bottom_val; UI_TextColorNode *free; U64 gen; B32 auto_pop; } text_color_stack;\ +struct { UI_SquishNode *top; F32 bottom_val; UI_SquishNode *free; U64 gen; B32 auto_pop; } squish_stack;\ +struct { UI_HoverCursorNode *top; OS_Cursor bottom_val; UI_HoverCursorNode *free; U64 gen; B32 auto_pop; } hover_cursor_stack;\ +struct { UI_FontNode *top; FNT_Tag bottom_val; UI_FontNode *free; U64 gen; B32 auto_pop; } font_stack;\ +struct { UI_FontSizeNode *top; F32 bottom_val; UI_FontSizeNode *free; U64 gen; B32 auto_pop; } font_size_stack;\ +struct { UI_TextRasterFlagsNode *top; FNT_RasterFlags bottom_val; UI_TextRasterFlagsNode *free; U64 gen; B32 auto_pop; } text_raster_flags_stack;\ +struct { UI_TabSizeNode *top; F32 bottom_val; UI_TabSizeNode *free; U64 gen; B32 auto_pop; } tab_size_stack;\ +struct { UI_CornerRadius00Node *top; F32 bottom_val; UI_CornerRadius00Node *free; U64 gen; B32 auto_pop; } corner_radius_00_stack;\ +struct { UI_CornerRadius01Node *top; F32 bottom_val; UI_CornerRadius01Node *free; U64 gen; B32 auto_pop; } corner_radius_01_stack;\ +struct { UI_CornerRadius10Node *top; F32 bottom_val; UI_CornerRadius10Node *free; U64 gen; B32 auto_pop; } corner_radius_10_stack;\ +struct { UI_CornerRadius11Node *top; F32 bottom_val; UI_CornerRadius11Node *free; U64 gen; B32 auto_pop; } corner_radius_11_stack;\ +struct { UI_BlurSizeNode *top; F32 bottom_val; UI_BlurSizeNode *free; U64 gen; B32 auto_pop; } blur_size_stack;\ +struct { UI_TextPaddingNode *top; F32 bottom_val; UI_TextPaddingNode *free; U64 gen; B32 auto_pop; } text_padding_stack;\ +struct { UI_TextAlignmentNode *top; UI_TextAlign bottom_val; UI_TextAlignmentNode *free; U64 gen; B32 auto_pop; } text_alignment_stack;\ } #define UI_InitStacks(state) \ state->parent_stack.top = &state->parent_nil_stack_top; state->parent_stack.bottom_val = &ui_nil_box; state->parent_stack.free = 0; state->parent_stack.auto_pop = 0;\ @@ -143,12 +155,15 @@ state->pref_width_stack.top = &state->pref_width_nil_stack_top; state->pref_widt state->pref_height_stack.top = &state->pref_height_nil_stack_top; state->pref_height_stack.bottom_val = ui_px(30.f, 1.f); state->pref_height_stack.free = 0; state->pref_height_stack.auto_pop = 0;\ state->permission_flags_stack.top = &state->permission_flags_nil_stack_top; state->permission_flags_stack.bottom_val = UI_PermissionFlag_All; state->permission_flags_stack.free = 0; state->permission_flags_stack.auto_pop = 0;\ state->flags_stack.top = &state->flags_nil_stack_top; state->flags_stack.bottom_val = 0; state->flags_stack.free = 0; state->flags_stack.auto_pop = 0;\ +state->omit_flags_stack.top = &state->omit_flags_nil_stack_top; state->omit_flags_stack.bottom_val = 0; state->omit_flags_stack.free = 0; state->omit_flags_stack.auto_pop = 0;\ state->focus_hot_stack.top = &state->focus_hot_nil_stack_top; state->focus_hot_stack.bottom_val = UI_FocusKind_Null; state->focus_hot_stack.free = 0; state->focus_hot_stack.auto_pop = 0;\ state->focus_active_stack.top = &state->focus_active_nil_stack_top; state->focus_active_stack.bottom_val = UI_FocusKind_Null; state->focus_active_stack.free = 0; state->focus_active_stack.auto_pop = 0;\ state->fastpath_codepoint_stack.top = &state->fastpath_codepoint_nil_stack_top; state->fastpath_codepoint_stack.bottom_val = 0; state->fastpath_codepoint_stack.free = 0; state->fastpath_codepoint_stack.auto_pop = 0;\ state->group_key_stack.top = &state->group_key_nil_stack_top; state->group_key_stack.bottom_val = ui_key_zero(); state->group_key_stack.free = 0; state->group_key_stack.auto_pop = 0;\ state->transparency_stack.top = &state->transparency_nil_stack_top; state->transparency_stack.bottom_val = 0; state->transparency_stack.free = 0; state->transparency_stack.auto_pop = 0;\ -state->palette_stack.top = &state->palette_nil_stack_top; state->palette_stack.bottom_val = &ui_g_nil_palette; state->palette_stack.free = 0; state->palette_stack.auto_pop = 0;\ +state->tag_stack.top = &state->tag_nil_stack_top; state->tag_stack.bottom_val = str8_lit(""); state->tag_stack.free = 0; state->tag_stack.auto_pop = 0;\ +state->background_color_stack.top = &state->background_color_nil_stack_top; state->background_color_stack.bottom_val = v4f32(0, 0, 0, 0); state->background_color_stack.free = 0; state->background_color_stack.auto_pop = 0;\ +state->text_color_stack.top = &state->text_color_nil_stack_top; state->text_color_stack.bottom_val = v4f32(0, 0, 0, 0); state->text_color_stack.free = 0; state->text_color_stack.auto_pop = 0;\ state->squish_stack.top = &state->squish_nil_stack_top; state->squish_stack.bottom_val = 0; state->squish_stack.free = 0; state->squish_stack.auto_pop = 0;\ state->hover_cursor_stack.top = &state->hover_cursor_nil_stack_top; state->hover_cursor_stack.bottom_val = OS_Cursor_Pointer; state->hover_cursor_stack.free = 0; state->hover_cursor_stack.auto_pop = 0;\ state->font_stack.top = &state->font_nil_stack_top; state->font_stack.bottom_val = fnt_tag_zero(); state->font_stack.free = 0; state->font_stack.auto_pop = 0;\ @@ -174,12 +189,15 @@ if(state->pref_width_stack.auto_pop) { ui_pop_pref_width(); state->pref_width_st if(state->pref_height_stack.auto_pop) { ui_pop_pref_height(); state->pref_height_stack.auto_pop = 0; }\ if(state->permission_flags_stack.auto_pop) { ui_pop_permission_flags(); state->permission_flags_stack.auto_pop = 0; }\ if(state->flags_stack.auto_pop) { ui_pop_flags(); state->flags_stack.auto_pop = 0; }\ +if(state->omit_flags_stack.auto_pop) { ui_pop_omit_flags(); state->omit_flags_stack.auto_pop = 0; }\ if(state->focus_hot_stack.auto_pop) { ui_pop_focus_hot(); state->focus_hot_stack.auto_pop = 0; }\ if(state->focus_active_stack.auto_pop) { ui_pop_focus_active(); state->focus_active_stack.auto_pop = 0; }\ if(state->fastpath_codepoint_stack.auto_pop) { ui_pop_fastpath_codepoint(); state->fastpath_codepoint_stack.auto_pop = 0; }\ if(state->group_key_stack.auto_pop) { ui_pop_group_key(); state->group_key_stack.auto_pop = 0; }\ if(state->transparency_stack.auto_pop) { ui_pop_transparency(); state->transparency_stack.auto_pop = 0; }\ -if(state->palette_stack.auto_pop) { ui_pop_palette(); state->palette_stack.auto_pop = 0; }\ +if(state->tag_stack.auto_pop) { ui_pop_tag(); state->tag_stack.auto_pop = 0; }\ +if(state->background_color_stack.auto_pop) { ui_pop_background_color(); state->background_color_stack.auto_pop = 0; }\ +if(state->text_color_stack.auto_pop) { ui_pop_text_color(); state->text_color_stack.auto_pop = 0; }\ if(state->squish_stack.auto_pop) { ui_pop_squish(); state->squish_stack.auto_pop = 0; }\ if(state->hover_cursor_stack.auto_pop) { ui_pop_hover_cursor(); state->hover_cursor_stack.auto_pop = 0; }\ if(state->font_stack.auto_pop) { ui_pop_font(); state->font_stack.auto_pop = 0; }\ @@ -204,12 +222,15 @@ internal UI_Size ui_top_pref_width(void); internal UI_Size ui_top_pref_height(void); internal UI_PermissionFlags ui_top_permission_flags(void); internal UI_BoxFlags ui_top_flags(void); +internal UI_BoxFlags ui_top_omit_flags(void); internal UI_FocusKind ui_top_focus_hot(void); internal UI_FocusKind ui_top_focus_active(void); internal U32 ui_top_fastpath_codepoint(void); internal UI_Key ui_top_group_key(void); internal F32 ui_top_transparency(void); -internal UI_Palette* ui_top_palette(void); +internal String8 ui_top_tag(void); +internal Vec4F32 ui_top_background_color(void); +internal Vec4F32 ui_top_text_color(void); internal F32 ui_top_squish(void); internal OS_Cursor ui_top_hover_cursor(void); internal FNT_Tag ui_top_font(void); @@ -233,12 +254,15 @@ internal UI_Size ui_bottom_pref_width(void); internal UI_Size ui_bottom_pref_height(void); internal UI_PermissionFlags ui_bottom_permission_flags(void); internal UI_BoxFlags ui_bottom_flags(void); +internal UI_BoxFlags ui_bottom_omit_flags(void); internal UI_FocusKind ui_bottom_focus_hot(void); internal UI_FocusKind ui_bottom_focus_active(void); internal U32 ui_bottom_fastpath_codepoint(void); internal UI_Key ui_bottom_group_key(void); internal F32 ui_bottom_transparency(void); -internal UI_Palette* ui_bottom_palette(void); +internal String8 ui_bottom_tag(void); +internal Vec4F32 ui_bottom_background_color(void); +internal Vec4F32 ui_bottom_text_color(void); internal F32 ui_bottom_squish(void); internal OS_Cursor ui_bottom_hover_cursor(void); internal FNT_Tag ui_bottom_font(void); @@ -262,12 +286,15 @@ internal UI_Size ui_push_pref_width(UI_Size v); internal UI_Size ui_push_pref_height(UI_Size v); internal UI_PermissionFlags ui_push_permission_flags(UI_PermissionFlags v); internal UI_BoxFlags ui_push_flags(UI_BoxFlags v); +internal UI_BoxFlags ui_push_omit_flags(UI_BoxFlags v); internal UI_FocusKind ui_push_focus_hot(UI_FocusKind v); internal UI_FocusKind ui_push_focus_active(UI_FocusKind v); internal U32 ui_push_fastpath_codepoint(U32 v); internal UI_Key ui_push_group_key(UI_Key v); internal F32 ui_push_transparency(F32 v); -internal UI_Palette* ui_push_palette(UI_Palette* v); +internal String8 ui_push_tag(String8 v); +internal Vec4F32 ui_push_background_color(Vec4F32 v); +internal Vec4F32 ui_push_text_color(Vec4F32 v); internal F32 ui_push_squish(F32 v); internal OS_Cursor ui_push_hover_cursor(OS_Cursor v); internal FNT_Tag ui_push_font(FNT_Tag v); @@ -291,12 +318,15 @@ internal UI_Size ui_pop_pref_width(void); internal UI_Size ui_pop_pref_height(void); internal UI_PermissionFlags ui_pop_permission_flags(void); internal UI_BoxFlags ui_pop_flags(void); +internal UI_BoxFlags ui_pop_omit_flags(void); internal UI_FocusKind ui_pop_focus_hot(void); internal UI_FocusKind ui_pop_focus_active(void); internal U32 ui_pop_fastpath_codepoint(void); internal UI_Key ui_pop_group_key(void); internal F32 ui_pop_transparency(void); -internal UI_Palette* ui_pop_palette(void); +internal String8 ui_pop_tag(void); +internal Vec4F32 ui_pop_background_color(void); +internal Vec4F32 ui_pop_text_color(void); internal F32 ui_pop_squish(void); internal OS_Cursor ui_pop_hover_cursor(void); internal FNT_Tag ui_pop_font(void); @@ -320,12 +350,15 @@ internal UI_Size ui_set_next_pref_width(UI_Size v); internal UI_Size ui_set_next_pref_height(UI_Size v); internal UI_PermissionFlags ui_set_next_permission_flags(UI_PermissionFlags v); internal UI_BoxFlags ui_set_next_flags(UI_BoxFlags v); +internal UI_BoxFlags ui_set_next_omit_flags(UI_BoxFlags v); internal UI_FocusKind ui_set_next_focus_hot(UI_FocusKind v); internal UI_FocusKind ui_set_next_focus_active(UI_FocusKind v); internal U32 ui_set_next_fastpath_codepoint(U32 v); internal UI_Key ui_set_next_group_key(UI_Key v); internal F32 ui_set_next_transparency(F32 v); -internal UI_Palette* ui_set_next_palette(UI_Palette* v); +internal String8 ui_set_next_tag(String8 v); +internal Vec4F32 ui_set_next_background_color(Vec4F32 v); +internal Vec4F32 ui_set_next_text_color(Vec4F32 v); internal F32 ui_set_next_squish(F32 v); internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v); internal FNT_Tag ui_set_next_font(FNT_Tag v); diff --git a/src/ui/ui.mdesk b/src/ui/ui.mdesk index 07978b11..b5945493 100644 --- a/src/ui/ui.mdesk +++ b/src/ui/ui.mdesk @@ -3,11 +3,11 @@ //- rjf: stack table -@table(name, name_lower, type, default) +@table(name, name_lower, type, default, manual_impl) UI_StackTable: { //- rjf: parents - { Parent parent `UI_Box *` `&ui_nil_box` } + { Parent parent `UI_Box *` `&ui_nil_box` } //- rjf: layout params { ChildLayoutAxis child_layout_axis Axis2 `Axis2_X` } @@ -23,6 +23,7 @@ UI_StackTable: //- rjf: flags { PermissionFlags permission_flags UI_PermissionFlags UI_PermissionFlag_All } { Flags flags UI_BoxFlags 0 } + { OmitFlags omit_flags UI_BoxFlags 0 } //- rjf: interaction { FocusHot focus_hot UI_FocusKind UI_FocusKind_Null } @@ -32,7 +33,9 @@ UI_StackTable: //- rjf: colors { Transparency transparency F32 0 } - { Palette palette `UI_Palette* ` `&ui_g_nil_palette` } + { Tag tag String8 `str8_lit("")` 1 } + { BackgroundColor background_color Vec4F32 `v4f32(0, 0, 0, 0)` } + { TextColor text_color Vec4F32 `v4f32(0, 0, 0, 0)` } //- rjf: squish { Squish squish F32 0 } @@ -94,7 +97,7 @@ UI_StackTable: `#define UI_DeclStacks \\`; `struct\\`; `{\\`; - @expand(UI_StackTable a) `struct { UI_$(a.name)Node *top; $(a.type) bottom_val; UI_$(a.name)Node *free; B32 auto_pop; } $(a.name_lower)_stack;\\`; + @expand(UI_StackTable a) `struct { UI_$(a.name)Node *top; $(a.type) bottom_val; UI_$(a.name)Node *free; U64 gen; B32 auto_pop; } $(a.name_lower)_stack;\\`; `}`; } @@ -148,13 +151,13 @@ UI_StackTable: @gen @c_file { @expand(UI_StackTable a) - `internal $(a.type) ui_top_$(a.name_lower)(void) { UI_StackTopImpl(ui_state, $(a.name), $(a.name_lower)) }`; + `$(a.manual_impl == "" -> "internal " .. a.type .. " ui_top_" .. a.name_lower .. "(void) { UI_StackTopImpl(ui_state, " .. a.name .. ", " .. a.name_lower .. ") }")`; @expand(UI_StackTable a) - `internal $(a.type) ui_bottom_$(a.name_lower)(void) { UI_StackBottomImpl(ui_state, $(a.name), $(a.name_lower)) }`; + `$(a.manual_impl == "" -> "internal " .. a.type .. " ui_bottom_" .. a.name_lower .. "(void) { UI_StackBottomImpl(ui_state, " .. a.name .. ", " .. a.name_lower .. ") }")`; @expand(UI_StackTable a) - `internal $(a.type) ui_push_$(a.name_lower)($(a.type) v) { UI_StackPushImpl(ui_state, $(a.name), $(a.name_lower), $(a.type), v) }`; + `$(a.manual_impl == "" -> "internal " .. a.type .. " ui_push_" .. a.name_lower .. "(" .. a.type .. " v) { UI_StackPushImpl(ui_state, " .. a.name .. ", " .. a.name_lower .. ", " .. a.type .. ", v) }")`; @expand(UI_StackTable a) - `internal $(a.type) ui_pop_$(a.name_lower)(void) { UI_StackPopImpl(ui_state, $(a.name), $(a.name_lower)) }`; + `$(a.manual_impl == "" -> "internal " .. a.type .. " ui_pop_" .. a.name_lower .. "(void) { UI_StackPopImpl(ui_state, " .. a.name .. ", " .. a.name_lower .. ") }")`; @expand(UI_StackTable a) - `internal $(a.type) ui_set_next_$(a.name_lower)($(a.type) v) { UI_StackSetNextImpl(ui_state, $(a.name), $(a.name_lower), $(a.type), v) }`; + `$(a.manual_impl == "" -> "internal " .. a.type .. " ui_set_next_" .. a.name_lower .. "(" .. a.type .. " v) { UI_StackSetNextImpl(ui_state, " .. a.name .. ", " .. a.name_lower .. ", " .. a.type .. ", v) }")`; } diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 22c61052..09cf9a42 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -134,10 +134,10 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) FNT_Tag font = box->font; F32 font_size = box->font_size; F32 tab_size = box->tab_size; - Vec4F32 cursor_color = box->palette->colors[UI_ColorCode_Cursor]; + Vec4F32 cursor_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("cursor")); cursor_color.w *= box->parent->parent->focus_active_t; - Vec4F32 select_color = box->palette->colors[UI_ColorCode_Selection]; - select_color.w *= (box->parent->parent->focus_active_t*0.2f + 0.8f); + Vec4F32 select_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("selection")); + select_color.w *= 0.1f*(box->parent->parent->focus_active_t*0.2f + 0.8f); Vec2F32 text_position = ui_box_text_position(box); String8 edited_string = draw_data->edited_string; TxtPt cursor = draw_data->cursor; @@ -148,16 +148,16 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) Rng2F32 cursor_rect = { text_position.x + cursor_pixel_off - cursor_thickness*0.50f, - box->rect.y0+4.f, + box->rect.y0+ui_top_font_size()*0.5f, text_position.x + cursor_pixel_off + cursor_thickness*0.50f, - box->rect.y1-4.f, + box->rect.y1-ui_top_font_size()*0.5f, }; Rng2F32 mark_rect = { text_position.x + mark_pixel_off - cursor_thickness*0.50f, - box->rect.y0+2.f, + box->rect.y0+ui_top_font_size()*0.5f, text_position.x + mark_pixel_off + cursor_thickness*0.50f, - box->rect.y1-2.f, + box->rect.y1-ui_top_font_size()*0.5f, }; Rng2F32 select_rect = union_2f32(cursor_rect, mark_rect); dr_rect(select_rect, select_color, font_size/2.f, 0, 1.f); @@ -480,7 +480,7 @@ ui_do_color_tooltip_hsv(Vec3F32 hsv) { UI_PrefWidth(ui_em(22.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) UI_Row UI_Padding(ui_pct(1, 0)) { - UI_Palette(ui_build_palette(ui_top_palette(), .background = v4f32(rgb.x, rgb.y, rgb.z, 1.f))) + UI_BackgroundColor(v4f32(rgb.x, rgb.y, rgb.z, 1.f)) UI_CornerRadius(4.f) UI_PrefWidth(ui_em(6.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) ui_build_box_from_string(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, str8_lit("")); @@ -519,7 +519,7 @@ ui_do_color_tooltip_hsva(Vec4F32 hsva) { UI_PrefWidth(ui_em(22.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) UI_Row UI_Padding(ui_pct(1, 0)) { - UI_Palette(ui_build_palette(ui_top_palette(), .background = rgba)) + UI_BackgroundColor(rgba) UI_CornerRadius(4.f) UI_PrefWidth(ui_em(6.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) ui_build_box_from_string(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, str8_lit("")); @@ -1212,7 +1212,7 @@ ui_scroll_list_item_from_row(UI_ScrollListRowBlockArray *blocks, U64 row) internal UI_ScrollPt ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_range, S64 view_num_indices) { - ui_push_palette(ui_state->widget_palette_info.scrollbar_palette); + ui_push_tag(str8_lit("scroll_bar")); //- rjf: unpack S64 idx_range_dim = Max(dim_1s64(idx_range), 1); @@ -1264,7 +1264,7 @@ ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_ran } // rjf: scroller - UI_Flags(disabled_flags) UI_PrefSize(axis, ui_pct(Clamp(0.01f, (F32)((F64)Max(view_num_indices, 1)/(F64)idx_range_dim), 1.f), 0.f)) + UI_Flags(disabled_flags) UI_PrefSize(axis, ui_pct(Clamp(0.05f, (F32)((F64)Max(view_num_indices, 1)/(F64)idx_range_dim), 1.f), 0.f)) { scroller_sig = ui_buttonf("##_scroller_%i", axis); scroller_box = scroller_sig.box; @@ -1332,7 +1332,7 @@ ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_ran } } - ui_pop_palette(); + ui_pop_tag(); return new_pt; } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 532ed66f..8bf53e7b 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -717,17 +717,10 @@ ui_string_hover_begin_time_us(void) return ui_state->string_hover_begin_us; } -internal String8 -ui_string_hover_string(Arena *arena) +internal DR_FStrList +ui_string_hover_fstrs(Arena *arena) { - String8 result = push_str8_copy(arena, ui_state->string_hover_string); - return result; -} - -internal DR_FancyRunList -ui_string_hover_runs(Arena *arena) -{ - DR_FancyRunList result = dr_fancy_run_list_copy(arena, &ui_state->string_hover_fancy_runs); + DR_FStrList result = dr_fstrs_copy(arena, &ui_state->string_hover_fstrs); return result; } @@ -789,7 +782,7 @@ ui_box_from_key(UI_Key key) //~ rjf: Top-Level Building API internal void -ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_WidgetPaletteInfo *widget_palette_info, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt) +ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_Theme *theme, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt) { //- rjf: reset per-build ui state { @@ -802,7 +795,13 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->build_box_count = 0; ui_state->tooltip_open = 0; ui_state->ctx_menu_changed = 0; - ui_state->default_animation_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); + ui_state->default_animation_rate = 1 - pow_f32(2, (-60.f * ui_state->animation_dt)); + ui_state->tooltip_can_overflow_window = 0; + ui_state->tags_key_stack_top = ui_state->tags_key_stack_free = 0; + ui_state->tags_cache_slots_count = 512; + ui_state->tags_cache_slots = push_array(ui_build_arena(), UI_TagsCacheSlot, ui_state->tags_cache_slots_count); + ui_state->theme_pattern_cache_slots_count = 512; + ui_state->theme_pattern_cache_slots = push_array(ui_build_arena(), UI_ThemePatternCacheSlot, ui_state->theme_pattern_cache_slots_count); } //- rjf: prune unused animation nodes @@ -811,7 +810,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U for(UI_AnimNode *n = ui_state->lru_anim_node, *next = &ui_nil_anim_node; n != &ui_nil_anim_node && n != 0; n = next) { next = n->lru_next; - if(n->last_touched_build_index+1 < ui_state->build_index) + if(n->last_touched_build_index+2 < ui_state->build_index) { U64 slot_idx = n->key.u64[0]%ui_state->anim_slots_count; UI_AnimSlot *slot = &ui_state->anim_slots[slot_idx]; @@ -850,6 +849,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U //- rjf: fill build phase parameters { + ui_state->theme = theme; ui_state->events = events; ui_state->window = window; ui_state->mouse = (os_window_is_focused(window) || ui_state->last_time_mousemoved_us+500000 >= os_now_microseconds()) ? os_mouse_from_window(window) : v2f32(-100, -100); @@ -862,7 +862,6 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U { ui_state->icon_info.icon_kind_text_map[icon_kind] = push_str8_copy(ui_build_arena(), icon_info->icon_kind_text_map[icon_kind]); } - MemoryCopyStruct(&ui_state->widget_palette_info, widget_palette_info); MemoryCopyStruct(&ui_state->animation_info, animation_info); } @@ -1118,11 +1117,15 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U Vec2F32 anchor = add_2f32(ui_state->ctx_menu_anchor_box_last_pos, ui_state->ctx_menu_anchor_off); UI_FixedX(anchor.x) UI_FixedY(anchor.y) UI_PrefWidth(ui_children_sum(1.f)) UI_PrefHeight(ui_children_sum(1.f)) UI_Focus(UI_FocusKind_On) - UI_Squish(0.25f-ui_state->ctx_menu_open_t*0.25f) + UI_Squish(0.1f-ui_state->ctx_menu_open_t*0.1f) UI_Transparency(1-ui_state->ctx_menu_open_t) { ui_set_next_child_layout_axis(Axis2_Y); - ui_state->ctx_menu_root = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_DrawDropShadow|(ui_state->ctx_menu_open*UI_BoxFlag_DefaultFocusNavY), "###ctx_menu_%I64x", window.u64[0]); + ui_state->ctx_menu_root = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_SquishAnchored| + UI_BoxFlag_DrawDropShadow| + (ui_state->ctx_menu_open*UI_BoxFlag_DefaultFocusNavY), + "###ctx_menu_%I64x", window.u64[0]); } } @@ -1169,6 +1172,12 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->active_box_key[k] = ui_key_zero(); } } + + //- rjf: escape -> close context menu + if(ui_any_ctx_menu_is_open() && ui_slot_press(UI_EventActionSlot_Cancel)) + { + ui_ctx_menu_close(); + } } internal void @@ -1176,12 +1185,6 @@ ui_end_build(void) { ProfBeginFunction(); - //- rjf: escape -> close context menu - if(ui_state->ctx_menu_open != 0 && ui_slot_press(UI_EventActionSlot_Cancel)) - { - ui_ctx_menu_close(); - } - //- rjf: prune untouched or transient boxes in the cache ProfScope("ui prune unused boxes") { @@ -1241,9 +1244,7 @@ ui_end_build(void) UI_Box *floating_roots[] = {ui_state->tooltip_root, ui_state->ctx_menu_root}; B32 force_contain[] = { - (ui_key_match(ui_active_key(UI_MouseButtonKind_Left), ui_key_zero()) && - ui_key_match(ui_active_key(UI_MouseButtonKind_Right), ui_key_zero()) && - ui_key_match(ui_active_key(UI_MouseButtonKind_Middle), ui_key_zero())), + !ui_state->tooltip_can_overflow_window, 1, }; for(U64 idx = 0; idx < ArrayCount(floating_roots); idx += 1) @@ -1288,9 +1289,31 @@ ui_end_build(void) !ui_box_is_nil(box); box = box->hash_next) { - if(box->flags & UI_BoxFlag_RoundChildrenByParent && - !ui_box_is_nil(box->first) && !ui_box_is_nil(box->last)) + if(box->flags & UI_BoxFlag_RoundChildrenByParent) { + for(UI_Box *b = box; !ui_box_is_nil(b); b = ui_box_rec_df_pre(b, box).next) + { + if(floor_f32(b->rect.x0) <= floor_f32(box->rect.x0) && + floor_f32(b->rect.y0) <= floor_f32(box->rect.y0)) + { + b->corner_radii[Corner_00] = box->corner_radii[Corner_00]; + } + if(floor_f32(b->rect.x1) >= floor_f32(box->rect.x1) && + floor_f32(b->rect.y0) <= floor_f32(box->rect.y0)) + { + b->corner_radii[Corner_10] = box->corner_radii[Corner_10]; + } + if(floor_f32(b->rect.x0) <= floor_f32(box->rect.x0) && + floor_f32(b->rect.y1) >= floor_f32(box->rect.y1)) + { + b->corner_radii[Corner_01] = box->corner_radii[Corner_01]; + } + if(floor_f32(b->rect.x1) >= floor_f32(box->rect.x1) && + floor_f32(b->rect.y1) >= floor_f32(box->rect.y1)) + { + b->corner_radii[Corner_11] = box->corner_radii[Corner_11]; + } + } box->first->corner_radii[Corner_00] = box->corner_radii[Corner_00]; box->first->corner_radii[Corner_10] = box->corner_radii[Corner_10]; box->last->corner_radii[Corner_01] = box->corner_radii[Corner_01]; @@ -1313,19 +1336,15 @@ ui_end_build(void) ui_state->is_animating = (ui_state->is_animating || abs_f32(n->params.target - n->current) > n->params.epsilon); } } - F32 vast_rate = 1 - pow_f32(2, (-60.f * ui_state->animation_dt)); - F32 fast_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); - F32 fish_rate = 1 - pow_f32(2, (-40.f * ui_state->animation_dt)); + F32 fast_rate = ui_state->default_animation_rate; F32 slow_rate = 1 - pow_f32(2, (-30.f * ui_state->animation_dt)); - F32 slug_rate = 1 - pow_f32(2, (-15.f * ui_state->animation_dt)); - F32 slaf_rate = 1 - pow_f32(2, (-8.f * ui_state->animation_dt)); - ui_state->ctx_menu_open_t += ((F32)!!ui_state->ctx_menu_open - ui_state->ctx_menu_open_t) * (ui_state->animation_info.flags & UI_AnimationInfoFlag_ContextMenuAnimations ? vast_rate : 1); + ui_state->ctx_menu_open_t += ((F32)!!ui_state->ctx_menu_open - ui_state->ctx_menu_open_t) * (ui_state->animation_info.flags & UI_AnimationInfoFlag_ContextMenuAnimations ? fast_rate : 1); ui_state->is_animating = (ui_state->is_animating || abs_f32((F32)!!ui_state->ctx_menu_open - ui_state->ctx_menu_open_t) > 0.01f); if(ui_state->ctx_menu_open_t >= 0.99f && ui_state->ctx_menu_open) { ui_state->ctx_menu_open_t = 1.f; } - ui_state->tooltip_open_t += ((F32)!!ui_state->tooltip_open - ui_state->tooltip_open_t) * (ui_state->animation_info.flags & UI_AnimationInfoFlag_TooltipAnimations ? vast_rate : 1); + ui_state->tooltip_open_t += ((F32)!!ui_state->tooltip_open - ui_state->tooltip_open_t) * (ui_state->animation_info.flags & UI_AnimationInfoFlag_TooltipAnimations ? fast_rate : 1); ui_state->is_animating = (ui_state->is_animating || abs_f32((F32)!!ui_state->tooltip_open - ui_state->tooltip_open_t) > 0.01f); if(ui_state->tooltip_open_t >= 0.99f && ui_state->tooltip_open) { @@ -1338,7 +1357,8 @@ ui_end_build(void) box = box->hash_next) { // rjf: grab states informing animation - B32 is_hot = ui_key_match(box->key, ui_state->hot_box_key); + B32 is_hot = (ui_key_match(box->key, ui_state->hot_box_key) || + ui_key_match(box->key, ui_state->drop_hot_box_key)); B32 is_active = ui_key_match(box->key, ui_state->active_box_key[UI_MouseButtonKind_Left]); B32 is_disabled = !!(box->flags & UI_BoxFlag_Disabled) && (box->first_disabled_build_index+2 < ui_state->build_index || box->first_touched_build_index == box->first_disabled_build_index); @@ -1381,7 +1401,7 @@ ui_end_build(void) // rjf: animate interaction transition states box->hot_t += hot_rate * ((F32)is_hot - box->hot_t); - box->active_t += active_rate * ((F32)is_active - box->active_t); + box->active_t = is_active ? 1.f : box->active_t + (active_rate * ((F32)is_active - box->active_t)); box->disabled_t += disabled_rate * ((F32)is_disabled - box->disabled_t); box->focus_hot_t += focus_rate * ((F32)is_focus_hot - box->focus_hot_t); box->focus_active_t += focus_rate * ((F32)is_focus_active - box->focus_active_t); @@ -1430,12 +1450,14 @@ ui_end_build(void) } } - //- rjf: animate context menu - if(ui_state->ctx_menu_open && !ui_box_is_nil(ui_state->ctx_menu_root) && !ui_state->ctx_menu_changed) + //- rjf: use group keys for box animation data if possible + for(UI_Box *b = ui_state->root; !ui_box_is_nil(b); b = ui_box_rec_df_pre(b, ui_state->root).next) { - UI_Box *root = ui_state->ctx_menu_root; - Rng2F32 rect = root->rect; - root->rect.y1 = root->rect.y0 + dim_2f32(rect).y * ui_state->ctx_menu_open_t; + if(ui_key_match(b->key, ui_key_zero()) && !ui_key_match(b->group_key, ui_key_zero())) + { + UI_Box *group_box = ui_box_from_key(b->group_key); + b->hot_t = group_box->hot_t; + } } //- rjf: fall-through interact with context menu @@ -1533,7 +1555,13 @@ ui_end_build(void) } String8 box_display_string = ui_box_display_string(b); Vec2F32 text_pos = ui_box_text_position(b); - Vec2F32 drawn_text_dim = b->display_string_runs.dim; + Vec2F32 drawn_text_dim = {0}; + { + Temp scratch = scratch_begin(0, 0); + DR_FRunList fruns = dr_fruns_from_fstrs(scratch.arena, b->tab_size, &b->display_fstrs); + drawn_text_dim = fruns.dim; + scratch_end(scratch); + } B32 text_is_truncated = (drawn_text_dim.x + text_pos.x > rect.x1); B32 mouse_is_hovering = contains_2f32(r2f32p(text_pos.x, rect.y0, @@ -1542,11 +1570,12 @@ ui_end_build(void) ui_state->mouse); if(text_is_truncated && mouse_is_hovering && !(b->flags & UI_BoxFlag_DisableTruncatedHover)) { - if(!str8_match(box_display_string, ui_state->string_hover_string, 0)) + if(!str8_match(box_display_string, ui_state->string_hover_string, 0) || box->font_size != ui_state->string_hover_size) { arena_clear(ui_state->string_hover_arena); ui_state->string_hover_string = push_str8_copy(ui_state->string_hover_arena, box_display_string); - ui_state->string_hover_fancy_runs = dr_fancy_run_list_copy(ui_state->string_hover_arena, &b->display_string_runs); + ui_state->string_hover_size = box->font_size; + ui_state->string_hover_fstrs = dr_fstrs_copy(ui_state->string_hover_arena, &b->display_fstrs); ui_state->string_hover_begin_us = os_now_microseconds(); } ui_state->string_hover_build_index = ui_state->build_index; @@ -1599,7 +1628,7 @@ ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis) case UI_SizeKind_TextContent: { F32 padding = root->pref_size[axis].value; - F32 text_size = root->display_string_runs.dim.x; + F32 text_size = root->display_fruns.dim.x; root->fixed_size.v[axis] = padding + text_size + root->text_padding*2; }break; } @@ -1911,13 +1940,15 @@ ui_tooltip_begin_base(void) ui_push_parent(ui_state->tooltip_root); ui_push_flags(0); ui_push_text_raster_flags(ui_bottom_text_raster_flags()); - ui_push_palette(ui_bottom_palette()); + ui_push_tag(str8_lit(".")); + ui_push_tag(str8_lit("floating")); } internal void ui_tooltip_end_base(void) { - ui_pop_palette(); + ui_pop_tag(); + ui_pop_tag(); ui_pop_text_raster_flags(); ui_pop_flags(); ui_pop_parent(); @@ -1928,10 +1959,9 @@ internal void ui_tooltip_begin(void) { ui_tooltip_begin_base(); - ui_push_palette(ui_state->widget_palette_info.tooltip_palette); - ui_set_next_squish(0.25f-ui_state->tooltip_open_t*0.25f); + ui_set_next_squish(0.1f-ui_state->tooltip_open_t*0.1f); ui_set_next_transparency(1-ui_state->tooltip_open_t); - UI_Flags(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_DrawDropShadow) + UI_Flags(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_DrawDropShadow|UI_BoxFlag_SquishAnchored) UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_children_sum(1)) UI_CornerRadius(ui_top_font_size()*0.25f) @@ -1960,7 +1990,6 @@ ui_tooltip_end(void) ui_row_end(); UI_PrefWidth(ui_px(0, 1)) ui_spacer(ui_em(1.f, 1.f)); ui_column_end(); - ui_pop_palette(); ui_tooltip_end_base(); } @@ -1998,9 +2027,9 @@ ui_begin_ctx_menu(UI_Key key) ui_push_pref_height(ui_bottom_pref_height()); ui_push_focus_hot(UI_FocusKind_Root); ui_push_focus_active(UI_FocusKind_Root); - ui_push_palette(ui_state->widget_palette_info.ctx_menu_palette); + ui_push_tag(str8_lit(".")); B32 is_open = ui_key_match(key, ui_state->ctx_menu_key) && ui_state->ctx_menu_open; - if(is_open != 0) + if(is_open != 0) UI_TagF("floating") { ui_state->ctx_menu_touched_this_frame = 1; ui_state->ctx_menu_root->flags |= UI_BoxFlag_RoundChildrenByParent; @@ -2011,8 +2040,10 @@ ui_begin_ctx_menu(UI_Key key) ui_state->ctx_menu_root->flags |= UI_BoxFlag_Clip; ui_state->ctx_menu_root->flags |= UI_BoxFlag_Clickable; ui_state->ctx_menu_root->corner_radii[Corner_00] = ui_state->ctx_menu_root->corner_radii[Corner_01] = ui_state->ctx_menu_root->corner_radii[Corner_10] = ui_state->ctx_menu_root->corner_radii[Corner_11] = ui_top_font_size()*0.25f; - ui_state->ctx_menu_root->palette = ui_top_palette(); + ui_state->ctx_menu_root->tags_key = ui_top_tags_key(); ui_state->ctx_menu_root->blur_size = ui_top_blur_size(); + ui_state->ctx_menu_root->text_color = ui_color_from_name(str8_lit("text")); + ui_state->ctx_menu_root->background_color = ui_color_from_name(str8_lit("background")); ui_spacer(ui_em(1.f, 1.f)); } ui_state->is_in_open_ctx_menu = is_open; @@ -2027,7 +2058,7 @@ ui_end_ctx_menu(void) ui_state->is_in_open_ctx_menu = 0; ui_spacer(ui_em(1.f, 1.f)); } - ui_pop_palette(); + ui_pop_tag(); ui_pop_focus_active(); ui_pop_focus_hot(); ui_pop_pref_width(); @@ -2161,27 +2192,115 @@ ui_set_auto_focus_hot_key(UI_Key key) } } -//- rjf: palette forming +//- rjf: current style tags key -internal UI_Palette * -ui_build_palette_(UI_Palette *base, UI_Palette *overrides) +internal UI_Key +ui_top_tags_key(void) { - UI_Palette *palette = push_array(ui_build_arena(), UI_Palette, 1); - if(base != 0) + UI_Key key = ui_key_zero(); + if(ui_state->tags_key_stack_top != 0) { - MemoryCopyStruct(palette, base); + key = ui_state->tags_key_stack_top->key; } - for EachEnumVal(UI_ColorCode, code) + return key; +} + +//- rjf: theme color lookups + +internal Vec4F32 +ui_color_from_name(String8 name) +{ + Vec4F32 result = ui_color_from_tags_key_name(ui_top_tags_key(), name); + return result; +} + +internal Vec4F32 +ui_color_from_tags_key_name(UI_Key key, String8 name) +{ + Vec4F32 result = {0}; { - if(overrides->colors[code].x != 0 || - overrides->colors[code].y != 0 || - overrides->colors[code].z != 0 || - overrides->colors[code].w != 0) + //- rjf: compute final key, mixing (tags_key, name) + UI_Key final_key = ui_key_from_string(key, name); + + //- rjf: map to existing node + U64 slot_idx = final_key.u64[0]%ui_state->theme_pattern_cache_slots_count; + UI_ThemePatternCacheSlot *slot = &ui_state->theme_pattern_cache_slots[slot_idx]; + UI_ThemePatternCacheNode *node = 0; + for(UI_ThemePatternCacheNode *n = slot->first; + n != 0; + n = n->next) { - palette->colors[code] = overrides->colors[code]; + if(ui_key_match(n->key, final_key)) + { + node = n; + } + } + + //- rjf: no node? create + if(node == 0) + { + // rjf: map tags_key (without name) -> full list of tags + String8Array tags = {0}; + { + U64 tags_cache_slot_idx = key.u64[0]%ui_state->tags_cache_slots_count; + UI_TagsCacheSlot *tags_cache_slot = &ui_state->tags_cache_slots[tags_cache_slot_idx]; + for(UI_TagsCacheNode *n = tags_cache_slot->first; n != 0; n = n->next) + { + if(ui_key_match(n->key, key)) + { + tags = n->tags; + break; + } + } + } + + // rjf: map tags to theme pattern + UI_Theme *theme = ui_state->theme; + UI_ThemePattern *pattern = 0; + U64 best_match_count = 0; + for(U64 idx = 0; idx < theme->patterns_count; idx += 1) + { + UI_ThemePattern *p = &theme->patterns[idx]; + U64 match_count = 0; + B32 name_matches = 0; + for EachIndex(key_tags_idx, tags.count+1) + { + String8 key_string = key_tags_idx < tags.count ? tags.v[key_tags_idx] : name; + for EachIndex(p_tags_idx, p->tags.count) + { + if(str8_match(p->tags.v[p_tags_idx], key_string, 0)) + { + name_matches = (key_tags_idx == tags.count); + match_count += 1; + break; + } + } + } + if(name_matches && match_count > best_match_count) + { + pattern = p; + best_match_count = match_count; + } + if(match_count == tags.count+1) + { + break; + } + } + + // rjf: store in (key, name) -> (pattern) cache + node = push_array(ui_build_arena(), UI_ThemePatternCacheNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->key = final_key; + node->pattern = pattern; + } + + //- rjf: grab resultant color + if(node != 0 && node->pattern != 0) + { + result = node->pattern->linear; } } - return palette; + return result; } //- rjf: box node construction @@ -2256,7 +2375,7 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) //- rjf: fill box { box->key = key; - box->flags = flags|ui_state->flags_stack.top->v; + box->flags = (flags | ui_state->flags_stack.top->v) & ~ui_state->omit_flags_stack.top->v; box->fastpath_codepoint = ui_state->fastpath_codepoint_stack.top->v; box->group_key = ui_state->group_key_stack.top->v; @@ -2329,7 +2448,6 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) box->text_align = ui_state->text_alignment_stack.top->v; box->child_layout_axis = ui_state->child_layout_axis_stack.top->v; - box->palette = ui_state->palette_stack.top->v; box->font = ui_state->font_stack.top->v; box->font_size = ui_state->font_size_stack.top->v; box->tab_size = ui_state->tab_size_stack.top->v; @@ -2344,6 +2462,27 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) box->text_padding = ui_state->text_padding_stack.top->v; box->hover_cursor = ui_state->hover_cursor_stack.top->v; box->custom_draw = 0; + box->tags_key = ui_key_zero(); + if(ui_state->tags_key_stack_top != 0) + { + box->tags_key = ui_state->tags_key_stack_top->key; + } + if(ui_state->background_color_stack.top != &ui_state->background_color_nil_stack_top) + { + box->background_color = ui_state->background_color_stack.top->v; + } + else + { + box->background_color = ui_color_from_name(str8_lit("background")); + } + if(ui_state->text_color_stack.top != &ui_state->text_color_nil_stack_top) + { + box->text_color = ui_state->text_color_stack.top->v; + } + else + { + box->text_color = ui_color_from_name(str8_lit("text")); + } } //- rjf: auto-pop all stacks @@ -2417,13 +2556,14 @@ ui_box_equip_display_string(UI_Box *box, String8 string) ProfBeginFunction(); box->string = push_str8_copy(ui_build_arena(), string); box->flags |= UI_BoxFlag_HasDisplayString; - UI_ColorCode text_color_code = (box->flags & UI_BoxFlag_DrawTextWeak ? UI_ColorCode_TextWeak : UI_ColorCode_Text); + Vec4F32 text_color = box->text_color; if(box->flags & UI_BoxFlag_DrawText && (box->fastpath_codepoint == 0 || !(box->flags & UI_BoxFlag_DrawTextFastpathCodepoint))) { String8 display_string = ui_box_display_string(box); - DR_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->palette->colors[text_color_code], box->font_size, 0, 0}}; - DR_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_string_runs = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &fancy_strings); + DR_FStrNode fstr_n = {0, {display_string, {box->font, box->text_raster_flags, text_color, box->font_size, 0, 0}}}; + DR_FStrList fstrs = {&fstr_n, &fstr_n, 1}; + box->display_fstrs = dr_fstrs_copy(ui_build_arena(), &fstrs); + box->display_fruns = dr_fruns_from_fstrs(ui_build_arena(), box->tab_size, &box->display_fstrs); } else if(box->flags & UI_BoxFlag_DrawText && box->flags & UI_BoxFlag_DrawTextFastpathCodepoint && box->fastpath_codepoint != 0) { @@ -2434,17 +2574,19 @@ ui_box_equip_display_string(UI_Box *box, String8 string) U64 fpcp_pos = str8_find_needle(display_string, 0, fpcp, StringMatchFlag_CaseInsensitive); if(fpcp_pos < display_string.size) { - DR_FancyStringNode pst_fancy_string_n = {0, {box->font, str8_skip(display_string, fpcp_pos+fpcp.size), box->palette->colors[text_color_code], box->font_size, 0, 0}}; - DR_FancyStringNode cdp_fancy_string_n = {&pst_fancy_string_n, {box->font, str8_substr(display_string, r1u64(fpcp_pos, fpcp_pos+fpcp.size)), box->palette->colors[text_color_code], box->font_size, 3.f, 0}}; - DR_FancyStringNode pre_fancy_string_n = {&cdp_fancy_string_n, {box->font, str8_prefix(display_string, fpcp_pos), box->palette->colors[text_color_code], box->font_size, 0, 0}}; - DR_FancyStringList fancy_strings = {&pre_fancy_string_n, &pst_fancy_string_n, 3}; - box->display_string_runs = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &fancy_strings); + DR_FStrNode pst_fstr_n = {0, {str8_skip(display_string, fpcp_pos+fpcp.size), {box->font, box->text_raster_flags, text_color, box->font_size, 0, 0}}}; + DR_FStrNode cdp_fstr_n = {&pst_fstr_n, {str8_substr(display_string, r1u64(fpcp_pos, fpcp_pos+fpcp.size)), {box->font, box->text_raster_flags, text_color, box->font_size, 3.f, 0}}}; + DR_FStrNode pre_fstr_n = {&cdp_fstr_n, {str8_prefix(display_string, fpcp_pos), {box->font, box->text_raster_flags, text_color, box->font_size, 0, 0}}}; + DR_FStrList fstrs = {&pre_fstr_n, &pst_fstr_n, 3}; + box->display_fstrs = dr_fstrs_copy(ui_build_arena(), &fstrs); + box->display_fruns = dr_fruns_from_fstrs(ui_build_arena(), box->tab_size, &box->display_fstrs); } else { - DR_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->palette->colors[UI_ColorCode_Text], box->font_size, 0, 0}}; - DR_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_string_runs = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &fancy_strings); + DR_FStrNode fstr_n = {0, {display_string, {box->font, box->text_raster_flags, text_color, box->font_size, 0, 0}}}; + DR_FStrList fstrs = {&fstr_n, &fstr_n, 1}; + box->display_fstrs = dr_fstrs_copy(ui_build_arena(), &fstrs); + box->display_fruns = dr_fruns_from_fstrs(ui_build_arena(), box->tab_size, &box->display_fstrs); } scratch_end(scratch); } @@ -2452,19 +2594,12 @@ ui_box_equip_display_string(UI_Box *box, String8 string) } internal void -ui_box_equip_display_fancy_strings(UI_Box *box, DR_FancyStringList *strings) +ui_box_equip_display_fstrs(UI_Box *box, DR_FStrList *strings) { box->flags |= UI_BoxFlag_HasDisplayString; - box->string = dr_string_from_fancy_string_list(ui_build_arena(), strings); - box->display_string_runs = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, strings); -} - -internal inline void -ui_box_equip_display_string_fancy_runs(UI_Box *box, String8 string, DR_FancyRunList *runs) -{ - box->flags |= UI_BoxFlag_HasDisplayString; - box->string = push_str8_copy(ui_build_arena(), string); - box->display_string_runs = dr_fancy_run_list_copy(ui_build_arena(), runs); + box->string = dr_string_from_fstrs(ui_build_arena(), strings); + box->display_fstrs = dr_fstrs_copy(ui_build_arena(), strings); + box->display_fruns = dr_fruns_from_fstrs(ui_build_arena(), box->tab_size, &box->display_fstrs); } internal inline void @@ -2529,13 +2664,13 @@ ui_box_text_position(UI_Box *box) }break; case UI_TextAlign_Center: { - Vec2F32 text_dim = box->display_string_runs.dim; + Vec2F32 text_dim = box->display_fruns.dim; result.x = round_f32((box->rect.p0.x + box->rect.p1.x)/2 - text_dim.x/2); result.x = ClampBot(result.x, box->rect.x0); }break; case UI_TextAlign_Right: { - Vec2F32 text_dim = box->display_string_runs.dim; + Vec2F32 text_dim = box->display_fruns.dim; result.x = round_f32((box->rect.p1.x) - text_dim.x - box->text_padding); result.x = ClampBot(result.x, box->rect.x0); }break; @@ -2979,6 +3114,7 @@ ui_anim_(UI_Key key, UI_AnimParams *params) { // rjf: get animation cache node UI_AnimNode *node = &ui_nil_anim_node; + if(ui_state != 0) { U64 slot_idx = key.u64[0]%ui_state->anim_slots_count; UI_AnimSlot *slot = &ui_state->anim_slots[slot_idx]; @@ -3014,16 +3150,23 @@ ui_anim_(UI_Key key, UI_AnimParams *params) } // rjf: touch node & update parameters - grab current - node->last_touched_build_index = ui_state->build_index; - DLLPushBack_NPZ(&ui_nil_anim_node, ui_state->lru_anim_node, ui_state->mru_anim_node, node, lru_next, lru_prev); - MemoryCopyStruct(&node->params, params); - if(node->params.epsilon == 0) + if(node != &ui_nil_anim_node) { - node->params.epsilon = 0.01f; - } - if(node->params.rate == 1) - { - node->current = node->params.target; + node->last_touched_build_index = ui_state->build_index; + DLLPushBack_NPZ(&ui_nil_anim_node, ui_state->lru_anim_node, ui_state->mru_anim_node, node, lru_next, lru_prev); + if(params->reset) + { + node->current = params->initial; + } + MemoryCopyStruct(&node->params, params); + if(node->params.epsilon == 0) + { + node->params.epsilon = 0.005f; + } + if(node->params.rate == 1) + { + node->current = node->params.target; + } } return node->current; } @@ -3031,6 +3174,168 @@ ui_anim_(UI_Key key, UI_AnimParams *params) //////////////////////////////// //~ rjf: Stacks +#define UI_StackTopImpl(state, name_upper, name_lower) \ +return state->name_lower##_stack.top->v; + +#define UI_StackBottomImpl(state, name_upper, name_lower) \ +return state->name_lower##_stack.bottom_val; + +#define UI_StackPushImpl(state, name_upper, name_lower, type, new_value) \ +UI_##name_upper##Node *node = state->name_lower##_stack.free;\ +if(node != 0) {SLLStackPop(state->name_lower##_stack.free);}\ +else {node = push_array(ui_build_arena(), UI_##name_upper##Node, 1);}\ +type old_value = state->name_lower##_stack.top->v;\ +node->v = new_value;\ +SLLStackPush(state->name_lower##_stack.top, node);\ +if(node->next == &state->name_lower##_nil_stack_top)\ +{\ +state->name_lower##_stack.bottom_val = (node->v);\ +}\ +state->name_lower##_stack.auto_pop = 0;\ +state->name_lower##_stack.gen += 1;\ +return old_value; + +#define UI_StackPopImpl(state, name_upper, name_lower) \ +UI_##name_upper##Node *popped = state->name_lower##_stack.top;\ +if(popped != &state->name_lower##_nil_stack_top)\ +{\ +SLLStackPop(state->name_lower##_stack.top);\ +SLLStackPush(state->name_lower##_stack.free, popped);\ +state->name_lower##_stack.auto_pop = 0;\ +state->name_lower##_stack.gen += 1;\ +}\ +return popped->v;\ + +#define UI_StackSetNextImpl(state, name_upper, name_lower, type, new_value) \ +UI_##name_upper##Node *node = state->name_lower##_stack.free;\ +if(node != 0) {SLLStackPop(state->name_lower##_stack.free);}\ +else {node = push_array(ui_build_arena(), UI_##name_upper##Node, 1);}\ +type old_value = state->name_lower##_stack.top->v;\ +node->v = new_value;\ +SLLStackPush(state->name_lower##_stack.top, node);\ +state->name_lower##_stack.auto_pop = 1;\ +state->name_lower##_stack.gen += 1;\ +return old_value; + +internal void +ui__push_tags_key_from_appended_string(String8 string) +{ + // rjf: generate new key, by combining hash of this new string with the top + // of the tags key stack + UI_Key seed_key = {0}; + if(ui_state->tags_key_stack_top != 0) + { + seed_key = ui_state->tags_key_stack_top->key; + } + UI_Key key = seed_key; + if(!str8_match(str8_lit("."), string, 0) && string.size > 0) + { + key = ui_key_from_string(seed_key, string); + } + + // rjf: push this new key onto the stack + { + UI_TagsKeyStackNode *node = ui_state->tags_key_stack_free; + if(node != 0) + { + SLLStackPop(ui_state->tags_key_stack_free); + } + else + { + node = push_array(ui_build_arena(), UI_TagsKeyStackNode, 1); + } + SLLStackPush(ui_state->tags_key_stack_top, node); + node->key = key; + } + + // rjf: store in tags cache + U64 slot_idx = key.u64[0] % ui_state->tags_cache_slots_count; + UI_TagsCacheSlot *slot = &ui_state->tags_cache_slots[slot_idx]; + UI_TagsCacheNode *node = 0; + for(UI_TagsCacheNode *n = slot->first; n != 0; n = n->next) + { + if(ui_key_match(n->key, key)) + { + node = n; + break; + } + } + if(node == 0) + { + Temp scratch = scratch_begin(0, 0); + String8List tags = {0}; + if(!str8_match(string, str8_lit("."), 0)) + { + if(string.size != 0) + { + str8_list_push(scratch.arena, &tags, push_str8_copy(ui_build_arena(), string)); + } + for(UI_TagNode *n = ui_state->tag_stack.top; n != 0; n = n->next) + { + if(n->v.size == 1 && n->v.str[0] == '.') + { + break; + } + if(n->v.size != 0) + { + str8_list_push(scratch.arena, &tags, push_str8_copy(ui_build_arena(), n->v)); + } + } + } + node = push_array(ui_build_arena(), UI_TagsCacheNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->key = key; + node->tags = str8_array_from_list(ui_build_arena(), &tags); + scratch_end(scratch); + } +} + +internal void +ui__pop_tags_key(void) +{ + if(ui_state->tags_key_stack_top != 0) + { + UI_TagsKeyStackNode *popped = ui_state->tags_key_stack_top; + SLLStackPop(ui_state->tags_key_stack_top); + SLLStackPush(ui_state->tags_key_stack_free, popped); + } +} + +//- rjf: manual implementations + +internal String8 +ui_top_tag(void) +{ + UI_StackTopImpl(ui_state, Tag, tag) +} + +internal String8 +ui_bottom_tag(void) +{ + UI_StackBottomImpl(ui_state, Tag, tag) +} + +internal String8 +ui_push_tag(String8 v) +{ + ui__push_tags_key_from_appended_string(v); + UI_StackPushImpl(ui_state, Tag, tag, String8, push_str8_copy(ui_build_arena(), v)) +} + +internal String8 +ui_pop_tag(void) +{ + ui__pop_tags_key(); + UI_StackPopImpl(ui_state, Tag, tag) +} + +internal String8 +ui_set_next_tag(String8 v) +{ + ui__push_tags_key_from_appended_string(v); + UI_StackSetNextImpl(ui_state, Tag, tag, String8, push_str8_copy(ui_build_arena(), v)) +} + //- rjf: helpers internal Rng2F32 @@ -3116,47 +3421,34 @@ ui_pop_corner_radius(void) ui_pop_corner_radius_11(); } +internal void +ui_push_tagf(char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + ui_push_tag(string); + va_end(args); + scratch_end(scratch); +} + +internal F32 +ui_top_px_height(void) +{ + F32 result = ui_top_font_size(); + for(UI_PrefHeightNode *n = ui_state->pref_height_stack.top; n != 0; n = n->next) + { + if(n->v.kind == UI_SizeKind_Pixels) + { + result = n->v.value; + break; + } + } + return result; +} + //////////////////////////////// //~ rjf: Generated Code -#define UI_StackTopImpl(state, name_upper, name_lower) \ -return state->name_lower##_stack.top->v; - -#define UI_StackBottomImpl(state, name_upper, name_lower) \ -return state->name_lower##_stack.bottom_val; - -#define UI_StackPushImpl(state, name_upper, name_lower, type, new_value) \ -UI_##name_upper##Node *node = state->name_lower##_stack.free;\ -if(node != 0) {SLLStackPop(state->name_lower##_stack.free);}\ -else {node = push_array(ui_build_arena(), UI_##name_upper##Node, 1);}\ -type old_value = state->name_lower##_stack.top->v;\ -node->v = new_value;\ -SLLStackPush(state->name_lower##_stack.top, node);\ -if(node->next == &state->name_lower##_nil_stack_top)\ -{\ -state->name_lower##_stack.bottom_val = (new_value);\ -}\ -state->name_lower##_stack.auto_pop = 0;\ -return old_value; - -#define UI_StackPopImpl(state, name_upper, name_lower) \ -UI_##name_upper##Node *popped = state->name_lower##_stack.top;\ -if(popped != &state->name_lower##_nil_stack_top)\ -{\ -SLLStackPop(state->name_lower##_stack.top);\ -SLLStackPush(state->name_lower##_stack.free, popped);\ -state->name_lower##_stack.auto_pop = 0;\ -}\ -return popped->v;\ - -#define UI_StackSetNextImpl(state, name_upper, name_lower, type, new_value) \ -UI_##name_upper##Node *node = state->name_lower##_stack.free;\ -if(node != 0) {SLLStackPop(state->name_lower##_stack.free);}\ -else {node = push_array(ui_build_arena(), UI_##name_upper##Node, 1);}\ -type old_value = state->name_lower##_stack.top->v;\ -node->v = new_value;\ -SLLStackPush(state->name_lower##_stack.top, node);\ -state->name_lower##_stack.auto_pop = 1;\ -return old_value; - #include "generated/ui.meta.c" diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 45c9c8b2..579c8051 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -217,48 +217,20 @@ struct UI_Size }; //////////////////////////////// -//~ rjf: Palettes +//~ rjf: Themes -typedef enum UI_ColorCode +typedef struct UI_ThemePattern UI_ThemePattern; +struct UI_ThemePattern { - UI_ColorCode_Null, - UI_ColorCode_Background, - UI_ColorCode_Text, - UI_ColorCode_TextWeak, - UI_ColorCode_Border, - UI_ColorCode_Overlay, - UI_ColorCode_Cursor, - UI_ColorCode_Selection, - UI_ColorCode_COUNT -} -UI_ColorCode; - -typedef struct UI_Palette UI_Palette; -struct UI_Palette -{ - union - { - Vec4F32 colors[UI_ColorCode_COUNT]; - struct - { - Vec4F32 null; - Vec4F32 background; - Vec4F32 text; - Vec4F32 text_weak; - Vec4F32 border; - Vec4F32 overlay; - Vec4F32 cursor; - Vec4F32 selection; - }; - }; + String8Array tags; + Vec4F32 linear; }; -typedef struct UI_WidgetPaletteInfo UI_WidgetPaletteInfo; -struct UI_WidgetPaletteInfo +typedef struct UI_Theme UI_Theme; +struct UI_Theme { - UI_Palette *tooltip_palette; - UI_Palette *ctx_menu_palette; - UI_Palette *scrollbar_palette; + UI_ThemePattern *patterns; + U64 patterns_count; }; //////////////////////////////// @@ -378,6 +350,10 @@ typedef U64 UI_BoxFlags; # define UI_BoxFlag_HasDisplayString (UI_BoxFlags)(1ull<<49) # define UI_BoxFlag_HasFuzzyMatchRanges (UI_BoxFlags)(1ull<<50) # define UI_BoxFlag_RoundChildrenByParent (UI_BoxFlags)(1ull<<51) +# define UI_BoxFlag_SquishAnchored (UI_BoxFlags)(1ull<<52) + +//- rjf: debug +# define UI_BoxFlag_Debug (UI_BoxFlags)(1ull<<53) //- rjf: bundles # define UI_BoxFlag_Clickable (UI_BoxFlag_MouseClickable|UI_BoxFlag_KeyboardClickable) @@ -409,6 +385,7 @@ struct UI_Box //- rjf: per-build equipment UI_Key key; UI_BoxFlags flags; + UI_Key tags_key; String8 string; UI_TextAlign text_align; Vec2F32 fixed_position; @@ -421,7 +398,8 @@ struct UI_Box DR_Bucket *draw_bucket; UI_BoxCustomDrawFunctionType *custom_draw; void *custom_draw_user_data; - UI_Palette *palette; + Vec4F32 background_color; + Vec4F32 text_color; FNT_Tag font; F32 font_size; F32 tab_size; @@ -433,7 +411,8 @@ struct UI_Box F32 text_padding; //- rjf: per-build artifacts - DR_FancyRunList display_string_runs; + DR_FStrList display_fstrs; + DR_FRunList display_fruns; Rng2F32 rect; Vec2F32 fixed_position_animated; Vec2F32 position_delta; @@ -581,6 +560,7 @@ struct UI_AnimParams F32 target; F32 rate; F32 epsilon; + B32 reset; }; typedef struct UI_AnimNode UI_AnimNode; @@ -612,6 +592,49 @@ struct UI_AnimSlot //////////////////////////////// //~ rjf: State Types +//- rjf: cache for mapping 64-bit key -> array of tags + +typedef struct UI_TagsCacheNode UI_TagsCacheNode; +struct UI_TagsCacheNode +{ + UI_TagsCacheNode *next; + UI_Key key; + String8Array tags; +}; + +typedef struct UI_TagsCacheSlot UI_TagsCacheSlot; +struct UI_TagsCacheSlot +{ + UI_TagsCacheNode *first; + UI_TagsCacheNode *last; +}; + +typedef struct UI_TagsKeyStackNode UI_TagsKeyStackNode; +struct UI_TagsKeyStackNode +{ + UI_TagsKeyStackNode *next; + UI_Key key; +}; + +//- rjf: cache for mapping 64-bit key * string -> theme pattern + +typedef struct UI_ThemePatternCacheNode UI_ThemePatternCacheNode; +struct UI_ThemePatternCacheNode +{ + UI_ThemePatternCacheNode *next; + UI_Key key; + UI_ThemePattern *pattern; +}; + +typedef struct UI_ThemePatternCacheSlot UI_ThemePatternCacheSlot; +struct UI_ThemePatternCacheSlot +{ + UI_ThemePatternCacheNode *first; + UI_ThemePatternCacheNode *last; +}; + +//- rjf: cache for mapping 64-bit key -> box + typedef struct UI_BoxHashSlot UI_BoxHashSlot; struct UI_BoxHashSlot { @@ -619,6 +642,8 @@ struct UI_BoxHashSlot UI_Box *hash_last; }; +//- rjf: main state bundle + typedef struct UI_State UI_State; struct UI_State { @@ -646,6 +671,15 @@ struct UI_State //- rjf: build state machine state B32 is_in_open_ctx_menu; + B32 tooltip_can_overflow_window; + String8Array current_gen_tags; + U64 current_gen_tags_gen; + UI_TagsKeyStackNode *tags_key_stack_top; + UI_TagsKeyStackNode *tags_key_stack_free; + U64 tags_cache_slots_count; + UI_TagsCacheSlot *tags_cache_slots; + U64 theme_pattern_cache_slots_count; + UI_ThemePatternCacheSlot *theme_pattern_cache_slots; //- rjf: build phase output UI_Box *root; @@ -659,7 +693,7 @@ struct UI_State //- rjf: build parameters UI_IconInfo icon_info; - UI_WidgetPaletteInfo widget_palette_info; + UI_Theme *theme; UI_AnimationInfo animation_info; OS_Handle window; UI_EventList *events; @@ -680,7 +714,8 @@ struct UI_State String8 drag_state_data; Arena *string_hover_arena; String8 string_hover_string; - DR_FancyRunList string_hover_fancy_runs; + F32 string_hover_size; + DR_FStrList string_hover_fstrs; U64 string_hover_begin_us; U64 string_hover_build_index; U64 last_time_mousemoved_us; @@ -741,11 +776,6 @@ internal UI_Size ui_size(UI_SizeKind kind, F32 value, F32 strictness); #define ui_pct(value, strictness) ui_size(UI_SizeKind_ParentPct, value, strictness) #define ui_children_sum(strictness) ui_size(UI_SizeKind_ChildrenSum, 0.f, strictness) -//////////////////////////////// -//~ rjf: Color Scheme Type Functions - -read_only global UI_Palette ui_g_nil_palette = {0}; - //////////////////////////////// //~ rjf: Scroll Point Type Functions @@ -812,8 +842,8 @@ internal String8 ui_get_drag_data(U64 min_required_size); #define ui_get_drag_struct(type) ((type *)ui_get_drag_data(sizeof(type)).str) //- rjf: hovered string info -internal B32 ui_string_hover_active(void); -internal DR_FancyRunList ui_string_hover_runs(Arena *arena); +internal B32 ui_string_hover_active(void); +internal DR_FStrList ui_string_hover_fstrs(Arena *arena); //- rjf: interaction keys internal UI_Key ui_hot_key(void); @@ -829,7 +859,7 @@ internal UI_Box * ui_box_from_key(UI_Key key); //////////////////////////////// //~ rjf: Top-Level Building API -internal void ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_WidgetPaletteInfo *widget_palette_info, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt); +internal void ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_Theme *theme, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt); internal void ui_end_build(void); internal void ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis); internal void ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis); @@ -868,9 +898,12 @@ internal B32 ui_is_key_auto_focus_hot(UI_Key key); internal void ui_set_auto_focus_active_key(UI_Key key); internal void ui_set_auto_focus_hot_key(UI_Key key); -//- rjf: palette forming -internal UI_Palette * ui_build_palette_(UI_Palette *base, UI_Palette *overrides); -#define ui_build_palette(base, ...) ui_build_palette_((base), &(UI_Palette){.text = v4f32(0, 0, 0, 0), __VA_ARGS__}) +//- rjf: current style tags key +internal UI_Key ui_top_tags_key(void); + +//- rjf: theme color lookups +internal Vec4F32 ui_color_from_name(String8 name); +internal Vec4F32 ui_color_from_tags_key_name(UI_Key key, String8 name); //- rjf: box node construction internal UI_Box * ui_build_box_from_key(UI_BoxFlags flags, UI_Key key); @@ -880,8 +913,7 @@ internal UI_Box * ui_build_box_from_stringf(UI_BoxFlags flags, char *fm //- rjf: box node equipment internal inline void ui_box_equip_display_string(UI_Box *box, String8 string); -internal inline void ui_box_equip_display_fancy_strings(UI_Box *box, DR_FancyStringList *strings); -internal inline void ui_box_equip_display_string_fancy_runs(UI_Box *box, String8 string, DR_FancyRunList *runs); +internal inline void ui_box_equip_display_fstrs(UI_Box *box, DR_FStrList *strings); internal inline void ui_box_equip_fuzzy_match_ranges(UI_Box *box, FuzzyMatchRangeList *matches); internal inline void ui_box_equip_draw_bucket(UI_Box *box, DR_Bucket *bucket); internal inline void ui_box_equip_custom_draw(UI_Box *box, UI_BoxCustomDrawFunctionType *custom_draw, void *user_data); @@ -922,12 +954,15 @@ internal UI_Size ui_top_pref_width(void); internal UI_Size ui_top_pref_height(void); internal UI_PermissionFlags ui_top_permission_flags(void); internal UI_BoxFlags ui_top_flags(void); +internal UI_BoxFlags ui_top_omit_flags(void); internal UI_FocusKind ui_top_focus_hot(void); internal UI_FocusKind ui_top_focus_active(void); internal U32 ui_top_fastpath_codepoint(void); internal UI_Key ui_top_group_key(void); internal F32 ui_top_transparency(void); -internal UI_Palette* ui_top_palette(void); +internal String8 ui_top_tag(void); +internal Vec4F32 ui_top_background_color(void); +internal Vec4F32 ui_top_text_color(void); internal F32 ui_top_squish(void); internal OS_Cursor ui_top_hover_cursor(void); internal FNT_Tag ui_top_font(void); @@ -951,12 +986,15 @@ internal UI_Size ui_bottom_pref_width(void); internal UI_Size ui_bottom_pref_height(void); internal UI_PermissionFlags ui_bottom_permission_flags(void); internal UI_BoxFlags ui_bottom_flags(void); +internal UI_BoxFlags ui_bottom_omit_flags(void); internal UI_FocusKind ui_bottom_focus_hot(void); internal UI_FocusKind ui_bottom_focus_active(void); internal U32 ui_bottom_fastpath_codepoint(void); internal UI_Key ui_bottom_group_key(void); internal F32 ui_bottom_transparency(void); -internal UI_Palette* ui_bottom_palette(void); +internal String8 ui_bottom_tag(void); +internal Vec4F32 ui_bottom_background_color(void); +internal Vec4F32 ui_bottom_text_color(void); internal F32 ui_bottom_squish(void); internal OS_Cursor ui_bottom_hover_cursor(void); internal FNT_Tag ui_bottom_font(void); @@ -980,12 +1018,15 @@ internal UI_Size ui_push_pref_width(UI_Size v); internal UI_Size ui_push_pref_height(UI_Size v); internal UI_PermissionFlags ui_push_permission_flags(UI_PermissionFlags v); internal UI_BoxFlags ui_push_flags(UI_BoxFlags v); +internal UI_BoxFlags ui_push_omit_flags(UI_BoxFlags v); internal UI_FocusKind ui_push_focus_hot(UI_FocusKind v); internal UI_FocusKind ui_push_focus_active(UI_FocusKind v); internal U32 ui_push_fastpath_codepoint(U32 v); internal UI_Key ui_push_group_key(UI_Key v); internal F32 ui_push_transparency(F32 v); -internal UI_Palette* ui_push_palette(UI_Palette* v); +internal String8 ui_push_tag(String8 v); +internal Vec4F32 ui_push_background_color(Vec4F32 v); +internal Vec4F32 ui_push_text_color(Vec4F32 v); internal F32 ui_push_squish(F32 v); internal OS_Cursor ui_push_hover_cursor(OS_Cursor v); internal FNT_Tag ui_push_font(FNT_Tag v); @@ -1009,12 +1050,15 @@ internal UI_Size ui_pop_pref_width(void); internal UI_Size ui_pop_pref_height(void); internal UI_PermissionFlags ui_pop_permission_flags(void); internal UI_BoxFlags ui_pop_flags(void); +internal UI_BoxFlags ui_pop_omit_flags(void); internal UI_FocusKind ui_pop_focus_hot(void); internal UI_FocusKind ui_pop_focus_active(void); internal U32 ui_pop_fastpath_codepoint(void); internal UI_Key ui_pop_group_key(void); internal F32 ui_pop_transparency(void); -internal UI_Palette* ui_pop_palette(void); +internal String8 ui_pop_tag(void); +internal Vec4F32 ui_pop_background_color(void); +internal Vec4F32 ui_pop_text_color(void); internal F32 ui_pop_squish(void); internal OS_Cursor ui_pop_hover_cursor(void); internal FNT_Tag ui_pop_font(void); @@ -1038,12 +1082,15 @@ internal UI_Size ui_set_next_pref_width(UI_Size v); internal UI_Size ui_set_next_pref_height(UI_Size v); internal UI_PermissionFlags ui_set_next_permission_flags(UI_PermissionFlags v); internal UI_BoxFlags ui_set_next_flags(UI_BoxFlags v); +internal UI_BoxFlags ui_set_next_omit_flags(UI_BoxFlags v); internal UI_FocusKind ui_set_next_focus_hot(UI_FocusKind v); internal UI_FocusKind ui_set_next_focus_active(UI_FocusKind v); internal U32 ui_set_next_fastpath_codepoint(U32 v); internal UI_Key ui_set_next_group_key(UI_Key v); internal F32 ui_set_next_transparency(F32 v); -internal UI_Palette* ui_set_next_palette(UI_Palette* v); +internal String8 ui_set_next_tag(String8 v); +internal Vec4F32 ui_set_next_background_color(Vec4F32 v); +internal Vec4F32 ui_set_next_text_color(Vec4F32 v); internal F32 ui_set_next_squish(F32 v); internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v); internal FNT_Tag ui_set_next_font(FNT_Tag v); @@ -1067,6 +1114,8 @@ internal UI_Size ui_pop_pref_size(Axis2 axis); internal UI_Size ui_set_next_pref_size(Axis2 axis, UI_Size v); internal void ui_push_corner_radius(F32 v); internal void ui_pop_corner_radius(void); +internal void ui_push_tagf(char *fmt, ...); +internal F32 ui_top_px_height(void); //////////////////////////////// //~ rjf: Macro Loop Wrappers @@ -1082,12 +1131,15 @@ internal void ui_pop_corner_radius(void); #define UI_PrefHeight(v) DeferLoop(ui_push_pref_height(v), ui_pop_pref_height()) #define UI_PermissionFlags(v) DeferLoop(ui_push_permission_flags(v), ui_pop_permission_flags()) #define UI_Flags(v) DeferLoop(ui_push_flags(v), ui_pop_flags()) +#define UI_OmitFlags(v) DeferLoop(ui_push_omit_flags(v), ui_pop_omit_flags()) #define UI_FocusHot(v) DeferLoop(ui_push_focus_hot(v), ui_pop_focus_hot()) #define UI_FocusActive(v) DeferLoop(ui_push_focus_active(v), ui_pop_focus_active()) #define UI_FastpathCodepoint(v) DeferLoop(ui_push_fastpath_codepoint(v), ui_pop_fastpath_codepoint()) #define UI_GroupKey(v) DeferLoop(ui_push_group_key(v), ui_pop_group_key()) #define UI_Transparency(v) DeferLoop(ui_push_transparency(v), ui_pop_transparency()) -#define UI_Palette(v) DeferLoop(ui_push_palette(v), ui_pop_palette()) +#define UI_Tag(v) DeferLoop(ui_push_tag(v), ui_pop_tag()) +#define UI_BackgroundColor(v) DeferLoop(ui_push_background_color(v), ui_pop_background_color()) +#define UI_TextColor(v) DeferLoop(ui_push_text_color(v), ui_pop_text_color()) #define UI_Squish(v) DeferLoop(ui_push_squish(v), ui_pop_squish()) #define UI_HoverCursor(v) DeferLoop(ui_push_hover_cursor(v), ui_pop_hover_cursor()) #define UI_Font(v) DeferLoop(ui_push_font(v), ui_pop_font()) @@ -1112,6 +1164,7 @@ internal void ui_pop_corner_radius(void); #define UI_CornerRadius(v) DeferLoop(ui_push_corner_radius(v), ui_pop_corner_radius()) #define UI_Focus(kind) DeferLoop((ui_push_focus_hot(kind), ui_push_focus_active(kind)), (ui_pop_focus_hot(), ui_pop_focus_active())) #define UI_FlagsAdd(v) DeferLoop(ui_push_flags(ui_top_flags()|(v)), ui_pop_flags()) +#define UI_TagF(...) DeferLoop(ui_push_tagf(__VA_ARGS__), ui_pop_tag()) //- rjf: tooltip #define UI_TooltipBase DeferLoop(ui_tooltip_begin_base(), ui_tooltip_end_base())