mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-13 07:32:23 -07:00
first pass at mutable text layer, which allows debugger-produced/controlled buffers to be fed into text visualization systems; start pulling out code view into single path, which will be used for disassembly/source/output
This commit is contained in:
@@ -33,6 +33,9 @@ main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **argum
|
||||
#if defined(TEXT_CACHE_H) && !defined(TXT_INIT_MANUAL)
|
||||
txt_init();
|
||||
#endif
|
||||
#if defined(MUTABLE_TEXT_H) && !defined(MTX_INIT_MANUAL)
|
||||
mtx_init();
|
||||
#endif
|
||||
#if defined(DASM_CACHE_H) && !defined(DASM_INIT_MANUAL)
|
||||
dasm_init();
|
||||
#endif
|
||||
|
||||
@@ -7129,6 +7129,9 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
|
||||
|
||||
case CTRL_EventKind_DebugString:
|
||||
{
|
||||
//MTX_Op op = {r1u64(max_U64, max_U64), event->string};
|
||||
//mtx_push_op(u128_zero(), op);
|
||||
#if 1
|
||||
String8 string = event->string;
|
||||
DF_Entity *root = df_entity_root();
|
||||
DF_Entity *thread = df_entity_from_ctrl_handle(event->machine_id, event->entity);
|
||||
@@ -7146,6 +7149,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
|
||||
txti_append(thread_log_handle, string);
|
||||
txti_append(process_log_handle, string);
|
||||
txti_append(machine_log_handle, string);
|
||||
#endif
|
||||
}break;
|
||||
|
||||
case CTRL_EventKind_ThreadName:
|
||||
|
||||
@@ -30,9 +30,6 @@ DF_EntityKindTable:
|
||||
//- rjf: auto view rules
|
||||
{AutoViewRule auto_view_rule 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 "Label" Binoculars "Auto View Rule" }
|
||||
|
||||
//- rjf: text attachments
|
||||
{FlashMarker flash_marker 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" Null "Flash Marker" }
|
||||
|
||||
//- rjf: watch pins
|
||||
{WatchPin watch_pin 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 1 "Expression" Pin "Watch Pin" }
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Rng1U64 df_g_cmd_param_slot_range_table[24] =
|
||||
{OffsetOf(DF_CmdParams, inline_unwind_index), OffsetOf(DF_CmdParams, inline_unwind_index) + sizeof(U64)},
|
||||
};
|
||||
|
||||
DF_IconKind df_g_entity_kind_icon_kind_table[26] =
|
||||
DF_IconKind df_g_entity_kind_icon_kind_table[25] =
|
||||
{
|
||||
DF_IconKind_Null,
|
||||
DF_IconKind_Null,
|
||||
@@ -40,7 +40,6 @@ DF_IconKind_Machine,
|
||||
DF_IconKind_FileOutline,
|
||||
DF_IconKind_FileOutline,
|
||||
DF_IconKind_Binoculars,
|
||||
DF_IconKind_Null,
|
||||
DF_IconKind_Pin,
|
||||
DF_IconKind_CircleFilled,
|
||||
DF_IconKind_CircleFilled,
|
||||
@@ -62,7 +61,7 @@ DF_IconKind_Null,
|
||||
DF_IconKind_Null,
|
||||
};
|
||||
|
||||
String8 df_g_entity_kind_display_string_table[26] =
|
||||
String8 df_g_entity_kind_display_string_table[25] =
|
||||
{
|
||||
str8_lit_comp("Nil"),
|
||||
str8_lit_comp("Root"),
|
||||
@@ -70,7 +69,6 @@ str8_lit_comp("Machine"),
|
||||
str8_lit_comp("File"),
|
||||
str8_lit_comp("Override File Link"),
|
||||
str8_lit_comp("Auto View Rule"),
|
||||
str8_lit_comp("Flash Marker"),
|
||||
str8_lit_comp("Watch Pin"),
|
||||
str8_lit_comp("Breakpoint"),
|
||||
str8_lit_comp("Condition"),
|
||||
@@ -92,7 +90,7 @@ str8_lit_comp("Conversion Failure"),
|
||||
str8_lit_comp("EndedProcess"),
|
||||
};
|
||||
|
||||
String8 df_g_entity_kind_name_label_table[26] =
|
||||
String8 df_g_entity_kind_name_label_table[25] =
|
||||
{
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
@@ -100,7 +98,6 @@ str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Expression"),
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Expression"),
|
||||
@@ -122,7 +119,7 @@ str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
};
|
||||
|
||||
DF_EntityKindFlags df_g_entity_kind_flags_table[26] =
|
||||
DF_EntityKindFlags df_g_entity_kind_flags_table[25] =
|
||||
{
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
@@ -130,7 +127,6 @@ DF_EntityKindFlags df_g_entity_kind_flags_table[26] =
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(1*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 1*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 1*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 1*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
@@ -152,7 +148,7 @@ DF_EntityKindFlags df_g_entity_kind_flags_table[26] =
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
};
|
||||
|
||||
DF_EntityOpFlags df_g_entity_kind_op_flags_table[26] =
|
||||
DF_EntityOpFlags df_g_entity_kind_op_flags_table[25] =
|
||||
{
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
@@ -160,7 +156,6 @@ DF_EntityOpFlags df_g_entity_kind_op_flags_table[26] =
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
(1*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (1*DF_EntityOpFlag_Duplicate),
|
||||
(1*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (1*DF_EntityOpFlag_Enable) | (1*DF_EntityOpFlag_Condition) | (1*DF_EntityOpFlag_Duplicate),
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
|
||||
@@ -23,7 +23,6 @@ DF_EntityKind_Machine,
|
||||
DF_EntityKind_File,
|
||||
DF_EntityKind_OverrideFileLink,
|
||||
DF_EntityKind_AutoViewRule,
|
||||
DF_EntityKind_FlashMarker,
|
||||
DF_EntityKind_WatchPin,
|
||||
DF_EntityKind_Breakpoint,
|
||||
DF_EntityKind_Condition,
|
||||
@@ -1532,11 +1531,11 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =
|
||||
};
|
||||
C_LINKAGE_BEGIN
|
||||
extern Rng1U64 df_g_cmd_param_slot_range_table[24];
|
||||
extern DF_IconKind df_g_entity_kind_icon_kind_table[26];
|
||||
extern String8 df_g_entity_kind_display_string_table[26];
|
||||
extern String8 df_g_entity_kind_name_label_table[26];
|
||||
extern DF_EntityKindFlags df_g_entity_kind_flags_table[26];
|
||||
extern DF_EntityOpFlags df_g_entity_kind_op_flags_table[26];
|
||||
extern DF_IconKind df_g_entity_kind_icon_kind_table[25];
|
||||
extern String8 df_g_entity_kind_display_string_table[25];
|
||||
extern String8 df_g_entity_kind_name_label_table[25];
|
||||
extern DF_EntityKindFlags df_g_entity_kind_flags_table[25];
|
||||
extern DF_EntityOpFlags df_g_entity_kind_op_flags_table[25];
|
||||
extern String8 df_g_cfg_src_string_table[4];
|
||||
extern DF_CoreCmdKind df_g_cfg_src_load_cmd_kind_table[4];
|
||||
extern DF_CoreCmdKind df_g_cfg_src_write_cmd_kind_table[4];
|
||||
|
||||
+12
-15
@@ -11737,21 +11737,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
SLLQueuePush(first_txt_rng_color_pair, last_txt_rng_color_pair, n);
|
||||
}
|
||||
|
||||
// rjf: push for flash ranges
|
||||
for(DF_EntityNode *n = params->flash_ranges.first; n != 0; n = n->next)
|
||||
{
|
||||
DF_Entity *flash_range = n->entity;
|
||||
if(flash_range->flags & DF_EntityFlag_HasTextPoint &&
|
||||
flash_range->flags & DF_EntityFlag_HasTextPointAlt)
|
||||
{
|
||||
TxtRngColorPairNode *pair = push_array(scratch.arena, TxtRngColorPairNode, 1);
|
||||
pair->rng = txt_rng(flash_range->text_point, flash_range->text_point_alt);
|
||||
pair->color = df_rgba_from_entity(flash_range);
|
||||
pair->color.w *= ClampTop(flash_range->life_left, 1.f);
|
||||
SLLQueuePush(first_txt_rng_color_pair, last_txt_rng_color_pair, pair);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: push for ctrlified mouse expr
|
||||
if(ctrlified && !txt_pt_match(result.mouse_expr_rng.max, result.mouse_expr_rng.min))
|
||||
{
|
||||
@@ -14252,6 +14237,18 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds)
|
||||
df_gfx_state->cfg_palettes[DF_PaletteCode_DropSiteOverlay].text = current->colors[DF_ThemeColor_DropSiteOverlay];
|
||||
df_gfx_state->cfg_palettes[DF_PaletteCode_DropSiteOverlay].text_weak = current->colors[DF_ThemeColor_DropSiteOverlay];
|
||||
df_gfx_state->cfg_palettes[DF_PaletteCode_DropSiteOverlay].border = current->colors[DF_ThemeColor_DropSiteOverlay];
|
||||
if(df_setting_val_from_code(DF_SettingCode_OpaqueBackgrounds).s32)
|
||||
{
|
||||
for(EachEnumVal(DF_PaletteCode, code))
|
||||
{
|
||||
if(df_gfx_state->cfg_palettes[code].background.x != 0 ||
|
||||
df_gfx_state->cfg_palettes[code].background.y != 0 ||
|
||||
df_gfx_state->cfg_palettes[code].background.z != 0)
|
||||
{
|
||||
df_gfx_state->cfg_palettes[code].background.w = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: animate alive-transitions for entities
|
||||
|
||||
@@ -458,7 +458,6 @@ struct DF_CodeSliceParams
|
||||
F32 catchall_margin_width_px;
|
||||
F32 line_num_width_px;
|
||||
F32 line_text_max_width_px;
|
||||
DF_EntityList flash_ranges;
|
||||
F32 margin_float_off_px;
|
||||
};
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ DF_GfxViewTable:
|
||||
{ Types "types" "Types" Null Binoculars 0 0 1 0 1 1 1 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" Null Binoculars 0 0 1 0 1 1 1 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." }
|
||||
{ Output "output" "Output" Null List 0 0 1 0 0 0 0 1 "Displays textual output from the selected thread's containing process." }
|
||||
{ Memory "memory" "Memory" Null Grid 0 0 1 1 0 0 0 1 "A familiar hex-editor-like interface for viewing memory of attached processes." }
|
||||
{ Memory "memory" "Memory" Null Grid 0 0 1 0 0 0 0 1 "A familiar hex-editor-like interface for viewing memory of attached processes." }
|
||||
{ Breakpoints "breakpoints" "Breakpoints" Null CircleFilled 0 0 1 0 1 0 1 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" Null Pin 0 0 1 0 1 1 1 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." }
|
||||
{ ExceptionFilters "exception_filters" "Exception Filters" Null Gear 0 0 1 0 1 0 1 1 "An interface which controls whether or not the debugger will halt attached processes upon encountering specific exception codes for the first time." }
|
||||
@@ -625,6 +625,7 @@ DF_SettingTable:
|
||||
{MenuAnimations menu_animations "Menu Animations" 1 0 1 }
|
||||
{ScrollingAnimations scrolling_animations "Scrolling Animations" 1 0 1 }
|
||||
{BackgroundBlur background_blur "Background Blur" 1 0 1 }
|
||||
{OpaqueBackgrounds opaque_backgrounds "Opaque Backgrounds" 0 0 1 }
|
||||
{TabWidth tab_width "Tab Width" 4 0 32 }
|
||||
}
|
||||
|
||||
|
||||
+730
-7
@@ -369,6 +369,718 @@ df_entity_lister_item_array_sort_by_strength__in_place(DF_EntityListerItemArray
|
||||
quick_sort(array.v, array.count, sizeof(DF_EntityListerItem), df_qsort_compare_entity_lister__strength);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Code Views
|
||||
|
||||
internal void
|
||||
df_code_view_init(DF_CodeViewState *cv, DF_View *view)
|
||||
{
|
||||
if(cv->initialized == 0)
|
||||
{
|
||||
cv->initialized = 1;
|
||||
cv->cursor = cv->mark = txt_pt(1, 1);
|
||||
cv->preferred_column = 1;
|
||||
cv->find_text_arena = df_view_push_arena_ext(view);
|
||||
}
|
||||
df_view_equip_loading_info(view, 1, 0, 0);
|
||||
view->loading_t = view->loading_t_target = 1.f;
|
||||
}
|
||||
|
||||
internal void
|
||||
df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CmdList *cmds, U128 key, TXT_LangKind lang_kind)
|
||||
{
|
||||
for(DF_CmdNode *n = cmds->first; n != 0; n = n->next)
|
||||
{
|
||||
DF_Cmd *cmd = &n->cmd;
|
||||
|
||||
// rjf: mismatched window/panel => skip
|
||||
if(df_window_from_handle(cmd->params.window) != ws ||
|
||||
df_panel_from_handle(cmd->params.panel) != panel)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// rjf: process
|
||||
DF_CoreCmdKind core_cmd_kind = df_core_cmd_kind_from_string(cmd->spec->info.string);
|
||||
switch(core_cmd_kind)
|
||||
{
|
||||
default: break;
|
||||
case DF_CoreCmdKind_GoToLine:
|
||||
{
|
||||
cv->goto_line_num = cmd->params.text_point.line;
|
||||
}break;
|
||||
case DF_CoreCmdKind_CenterCursor:
|
||||
{
|
||||
cv->center_cursor = 1;
|
||||
}break;
|
||||
case DF_CoreCmdKind_ContainCursor:
|
||||
{
|
||||
cv->contain_cursor = 1;
|
||||
}break;
|
||||
case DF_CoreCmdKind_FindTextForward:
|
||||
{
|
||||
arena_clear(cv->find_text_arena);
|
||||
cv->find_text_fwd = push_str8_copy(cv->find_text_arena, cmd->params.string);
|
||||
}break;
|
||||
case DF_CoreCmdKind_FindTextBackward:
|
||||
{
|
||||
arena_clear(cv->find_text_arena);
|
||||
cv->find_text_bwd = push_str8_copy(cv->find_text_arena, cmd->params.string);
|
||||
}break;
|
||||
case DF_CoreCmdKind_GoToNameAtCursor:
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
TXT_Scope *txt_scope = txt_scope_open();
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
{
|
||||
// rjf: unpack entity info
|
||||
U128 hash = {0};
|
||||
TXT_TextInfo text_info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
|
||||
// rjf: determine expression range
|
||||
Rng1U64 expr_range = {0};
|
||||
{
|
||||
TxtRng selection_range = txt_rng(cv->cursor, cv->mark);
|
||||
if(txt_pt_match(selection_range.min, selection_range.max))
|
||||
{
|
||||
expr_range = txt_expr_off_range_from_info_data_pt(&text_info, data, cv->cursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
expr_range = r1u64(txt_off_from_info_pt(&text_info, selection_range.min), txt_off_from_info_pt(&text_info, selection_range.max));
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: expression range -> text
|
||||
String8 expr_text = str8_substr(data, expr_range);
|
||||
|
||||
// rjf: go to name
|
||||
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
|
||||
params.string = expr_text;
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_GoToName));
|
||||
}
|
||||
hs_scope_close(hs_scope);
|
||||
txt_scope_close(txt_scope);
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
case DF_CoreCmdKind_ToggleWatchExpressionAtCursor:
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
TXT_Scope *txt_scope = txt_scope_open();
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
{
|
||||
// rjf: unpack entity info
|
||||
U128 hash = {0};
|
||||
TXT_TextInfo text_info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
|
||||
// rjf: determine expression range
|
||||
Rng1U64 expr_range = {0};
|
||||
{
|
||||
TxtRng selection_range = txt_rng(cv->cursor, cv->mark);
|
||||
if(txt_pt_match(selection_range.min, selection_range.max))
|
||||
{
|
||||
expr_range = txt_expr_off_range_from_info_data_pt(&text_info, data, cv->cursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
expr_range = r1u64(txt_off_from_info_pt(&text_info, selection_range.min), txt_off_from_info_pt(&text_info, selection_range.max));
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: expression range -> text
|
||||
String8 expr_text = str8_substr(data, expr_range);
|
||||
|
||||
// rjf: toggle watch expr
|
||||
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
|
||||
params.string = expr_text;
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ToggleWatchExpression));
|
||||
scratch_end(scratch);
|
||||
}
|
||||
hs_scope_close(hs_scope);
|
||||
txt_scope_close(txt_scope);
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, Rng2F32 rect, U128 key, TXT_LangKind lang_kind)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
TXT_Scope *txt_scope = txt_scope_open();
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: extract invariants
|
||||
//
|
||||
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view);
|
||||
F_Tag code_font = df_font_from_slot(DF_FontSlot_Code);
|
||||
F32 code_font_size = df_font_size_from_slot(ws, DF_FontSlot_Code);
|
||||
F32 code_tab_size = f_column_size_from_tag_size(code_font, code_font_size)*df_setting_val_from_code(DF_SettingCode_TabWidth).s32;
|
||||
F_Metrics code_font_metrics = f_metrics_from_tag_size(code_font, code_font_size);
|
||||
F32 code_line_height = ceil_f32(f_line_height_from_metrics(&code_font_metrics) * 1.5f);
|
||||
F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x;
|
||||
Vec2F32 panel_box_dim = dim_2f32(rect);
|
||||
Vec2F32 bottom_bar_dim = {panel_box_dim.x, ui_em(1.8f, 0).value};
|
||||
F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f);
|
||||
Vec2F32 code_area_dim = v2f32(panel_box_dim.x - scroll_bar_dim, panel_box_dim.y - scroll_bar_dim - bottom_bar_dim.y);
|
||||
S64 num_possible_visible_lines = (S64)(code_area_dim.y/code_line_height)+1;
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: unpack ctrl ctx & make parse ctx
|
||||
//
|
||||
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
|
||||
U64 unwind_count = ctrl_ctx.unwind_count;
|
||||
U64 rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(di_scope, process, rip_vaddr);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: unpack text info
|
||||
//
|
||||
U128 hash = {0};
|
||||
TXT_TextInfo text_info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
B32 text_info_is_ready = (text_info.lines_count != 0);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: buffer is pending -> equip view with loading information
|
||||
//
|
||||
if(!text_info_is_ready)
|
||||
{
|
||||
df_view_equip_loading_info(view, 1, text_info.bytes_processed, text_info.bytes_to_process);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: determine visible line range / count
|
||||
//
|
||||
Rng1S64 visible_line_num_range = r1s64(view->scroll_pos.y.idx + (S64)(view->scroll_pos.y.off) + 1 - !!(view->scroll_pos.y.off < 0),
|
||||
view->scroll_pos.y.idx + (S64)(view->scroll_pos.y.off) + 1 + num_possible_visible_lines);
|
||||
Rng1S64 target_visible_line_num_range = r1s64(view->scroll_pos.y.idx + 1,
|
||||
view->scroll_pos.y.idx + 1 + num_possible_visible_lines);
|
||||
U64 visible_line_count = 0;
|
||||
{
|
||||
visible_line_num_range.min = Clamp(1, visible_line_num_range.min, (S64)text_info.lines_count);
|
||||
visible_line_num_range.max = Clamp(1, visible_line_num_range.max, (S64)text_info.lines_count);
|
||||
visible_line_num_range.min = Max(1, visible_line_num_range.min);
|
||||
visible_line_num_range.max = Max(1, visible_line_num_range.max);
|
||||
target_visible_line_num_range.min = Clamp(1, target_visible_line_num_range.min, (S64)text_info.lines_count);
|
||||
target_visible_line_num_range.max = Clamp(1, target_visible_line_num_range.max, (S64)text_info.lines_count);
|
||||
target_visible_line_num_range.min = Max(1, target_visible_line_num_range.min);
|
||||
target_visible_line_num_range.max = Max(1, target_visible_line_num_range.max);
|
||||
visible_line_count = (U64)dim_1s64(visible_line_num_range)+1;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: calculate scroll bounds
|
||||
//
|
||||
S64 line_size_x = 0;
|
||||
Rng1S64 scroll_idx_rng[Axis2_COUNT] = {0};
|
||||
{
|
||||
line_size_x = (text_info.lines_max_size*big_glyph_advance*3)/2;
|
||||
line_size_x = ClampBot(line_size_x, (S64)big_glyph_advance*120);
|
||||
line_size_x = ClampBot(line_size_x, (S64)code_area_dim.x);
|
||||
scroll_idx_rng[Axis2_X] = r1s64(0, line_size_x-(S64)code_area_dim.x);
|
||||
scroll_idx_rng[Axis2_Y] = r1s64(0, (S64)text_info.lines_count-1);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: calculate line-range-dependent info
|
||||
//
|
||||
F32 priority_margin_width_px = big_glyph_advance*3.5f;
|
||||
F32 catchall_margin_width_px = big_glyph_advance*3.5f;
|
||||
F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3);
|
||||
TXT_LineTokensSlice slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, &text_info, data, visible_line_num_range);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: get active search query
|
||||
//
|
||||
String8 search_query = {0};
|
||||
Side search_query_side = Side_Invalid;
|
||||
B32 search_query_is_active = 0;
|
||||
{
|
||||
DF_CoreCmdKind query_cmd_kind = df_core_cmd_kind_from_string(ws->query_cmd_spec->info.string);
|
||||
if(query_cmd_kind == DF_CoreCmdKind_FindTextForward ||
|
||||
query_cmd_kind == DF_CoreCmdKind_FindTextBackward)
|
||||
{
|
||||
search_query = str8(ws->query_view_stack_top->query_buffer, ws->query_view_stack_top->query_string_size);
|
||||
search_query_is_active = 1;
|
||||
search_query_side = (query_cmd_kind == DF_CoreCmdKind_FindTextForward) ? Side_Max : Side_Min;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: prepare code slice info bundle, for the viewable region of text
|
||||
//
|
||||
DF_CodeSliceParams code_slice_params = {0};
|
||||
if(text_info_is_ready)
|
||||
{
|
||||
// rjf: fill basics
|
||||
code_slice_params.flags = DF_CodeSliceFlag_PriorityMargin|DF_CodeSliceFlag_CatchallMargin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable;
|
||||
code_slice_params.line_num_range = visible_line_num_range;
|
||||
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, DF_EntityList, visible_line_count);
|
||||
code_slice_params.line_ips = push_array(scratch.arena, DF_EntityList, visible_line_count);
|
||||
code_slice_params.line_pins = push_array(scratch.arena, DF_EntityList, visible_line_count);
|
||||
code_slice_params.line_dasm2src = push_array(scratch.arena, DF_TextLineDasm2SrcInfoList, visible_line_count);
|
||||
code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, visible_line_count);
|
||||
code_slice_params.font = code_font;
|
||||
code_slice_params.font_size = code_font_size;
|
||||
code_slice_params.tab_size = code_tab_size;
|
||||
code_slice_params.line_height_px = code_line_height;
|
||||
code_slice_params.search_query = search_query;
|
||||
code_slice_params.priority_margin_width_px = priority_margin_width_px;
|
||||
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 = view->scroll_pos.x.idx + view->scroll_pos.x.off;
|
||||
|
||||
// rjf: fill text info
|
||||
{
|
||||
S64 line_num = visible_line_num_range.min;
|
||||
U64 line_idx = visible_line_num_range.min-1;
|
||||
for(U64 visible_line_idx = 0; visible_line_idx < visible_line_count; visible_line_idx += 1, line_idx += 1, line_num += 1)
|
||||
{
|
||||
code_slice_params.line_text[visible_line_idx] = str8_substr(data, text_info.lines_ranges[line_idx]);
|
||||
code_slice_params.line_ranges[visible_line_idx] = text_info.lines_ranges[line_idx];
|
||||
code_slice_params.line_tokens[visible_line_idx] = slice.line_tokens[visible_line_idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: build container
|
||||
//
|
||||
UI_Box *container_box = &ui_g_nil_box;
|
||||
if(text_info_is_ready)
|
||||
{
|
||||
ui_set_next_pref_width(ui_px(code_area_dim.x, 1));
|
||||
ui_set_next_pref_height(ui_px(code_area_dim.y, 1));
|
||||
ui_set_next_child_layout_axis(Axis2_Y);
|
||||
container_box = ui_build_box_from_stringf(UI_BoxFlag_Clip|
|
||||
UI_BoxFlag_Scroll|
|
||||
UI_BoxFlag_AllowOverflowX|
|
||||
UI_BoxFlag_AllowOverflowY,
|
||||
"###code_area_%p", view);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: cancelled search query -> center cursor
|
||||
//
|
||||
if(!search_query_is_active && cv->drifted_for_search)
|
||||
{
|
||||
cv->drifted_for_search = 0;
|
||||
cv->center_cursor = 1;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: do searching operations
|
||||
//
|
||||
if(text_info_is_ready)
|
||||
{
|
||||
//- rjf: find text (forward)
|
||||
if(cv->find_text_fwd.size != 0)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
B32 found = 0;
|
||||
B32 first = 1;
|
||||
S64 line_num_start = cv->cursor.line;
|
||||
S64 line_num_last = (S64)text_info.lines_count;
|
||||
for(S64 line_num = line_num_start;; first = 0)
|
||||
{
|
||||
// rjf: pop scratch
|
||||
temp_end(scratch);
|
||||
|
||||
// rjf: gather line info
|
||||
String8 line_string = str8_substr(data, text_info.lines_ranges[line_num-1]);
|
||||
U64 search_start = 0;
|
||||
if(cv->cursor.line == line_num && first)
|
||||
{
|
||||
search_start = cv->cursor.column;
|
||||
}
|
||||
|
||||
// rjf: search string
|
||||
U64 needle_pos = str8_find_needle(line_string, search_start, cv->find_text_fwd, StringMatchFlag_CaseInsensitive);
|
||||
if(needle_pos < line_string.size)
|
||||
{
|
||||
cv->cursor.line = line_num;
|
||||
cv->cursor.column = needle_pos+1;
|
||||
cv->mark = cv->cursor;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// rjf: break if circled back around to cursor
|
||||
else if(line_num == line_num_start && !first)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// rjf: increment
|
||||
line_num += 1;
|
||||
if(line_num > line_num_last)
|
||||
{
|
||||
line_num = 1;
|
||||
}
|
||||
}
|
||||
cv->center_cursor = found;
|
||||
if(found == 0)
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
|
||||
params.string = push_str8f(scratch.arena, "Could not find \"%S\"", cv->find_text_fwd);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error));
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
//- rjf: find text (backward)
|
||||
if(cv->find_text_bwd.size != 0)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
B32 found = 0;
|
||||
B32 first = 1;
|
||||
S64 line_num_start = cv->cursor.line;
|
||||
S64 line_num_last = (S64)text_info.lines_count;
|
||||
for(S64 line_num = line_num_start;; first = 0)
|
||||
{
|
||||
// rjf: pop scratch
|
||||
temp_end(scratch);
|
||||
|
||||
// rjf: gather line info
|
||||
String8 line_string = str8_substr(data, text_info.lines_ranges[line_num-1]);
|
||||
if(cv->cursor.line == line_num && first)
|
||||
{
|
||||
line_string = str8_prefix(line_string, cv->cursor.column-1);
|
||||
}
|
||||
|
||||
// rjf: search string
|
||||
U64 next_needle_pos = line_string.size;
|
||||
for(U64 needle_pos = 0; needle_pos < line_string.size;)
|
||||
{
|
||||
needle_pos = str8_find_needle(line_string, needle_pos, cv->find_text_bwd, StringMatchFlag_CaseInsensitive);
|
||||
if(needle_pos < line_string.size)
|
||||
{
|
||||
next_needle_pos = needle_pos;
|
||||
needle_pos += 1;
|
||||
}
|
||||
}
|
||||
if(next_needle_pos < line_string.size)
|
||||
{
|
||||
cv->cursor.line = line_num;
|
||||
cv->cursor.column = next_needle_pos+1;
|
||||
cv->mark = cv->cursor;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// rjf: break if circled back around to cursor line
|
||||
else if(line_num == line_num_start && !first)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// rjf: increment
|
||||
line_num -= 1;
|
||||
if(line_num == 0)
|
||||
{
|
||||
line_num = line_num_last;
|
||||
}
|
||||
}
|
||||
cv->center_cursor = found;
|
||||
if(found == 0)
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
|
||||
params.string = push_str8f(scratch.arena, "Could not find \"%S\"", cv->find_text_bwd);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error));
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
MemoryZeroStruct(&cv->find_text_fwd);
|
||||
MemoryZeroStruct(&cv->find_text_bwd);
|
||||
arena_clear(cv->find_text_arena);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: do goto line
|
||||
//
|
||||
if(text_info_is_ready) if(cv->goto_line_num != 0)
|
||||
{
|
||||
S64 line_num = cv->goto_line_num;
|
||||
cv->goto_line_num = 0;
|
||||
line_num = Clamp(1, line_num, text_info.lines_count);
|
||||
cv->cursor = cv->mark = txt_pt(line_num, 1);
|
||||
cv->center_cursor = !cv->contain_cursor || (line_num < target_visible_line_num_range.min+4 || target_visible_line_num_range.max-4 < line_num);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: do keyboard interaction
|
||||
//
|
||||
B32 snap[Axis2_COUNT] = {0};
|
||||
UI_Focus(UI_FocusKind_On)
|
||||
{
|
||||
if(ui_is_focus_active() && text_info_is_ready && visible_line_num_range.max >= visible_line_num_range.min)
|
||||
{
|
||||
snap[Axis2_X] = snap[Axis2_Y] = df_do_txt_controls(&text_info, data, ClampBot(num_possible_visible_lines, 10) - 10, &cv->cursor, &cv->mark, &cv->preferred_column);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: build container contents
|
||||
//
|
||||
if(text_info_is_ready) UI_Parent(container_box)
|
||||
{
|
||||
//- rjf: build fractional space
|
||||
container_box->view_off.x = container_box->view_off_target.x = view->scroll_pos.x.idx + view->scroll_pos.x.off;
|
||||
container_box->view_off.y = container_box->view_off_target.y = code_line_height*mod_f32(view->scroll_pos.y.off, 1.f) + code_line_height*(view->scroll_pos.y.off < 0) - code_line_height*(view->scroll_pos.y.off == -1.f && view->scroll_pos.y.idx == 1);
|
||||
|
||||
//- rjf: build code slice
|
||||
DF_CodeSliceSignal sig = {0};
|
||||
UI_Focus(UI_FocusKind_On)
|
||||
{
|
||||
sig = df_code_slicef(ws, &ctrl_ctx, &parse_ctx, &code_slice_params, &cv->cursor, &cv->mark, &cv->preferred_column, "txt_view_%p", view);
|
||||
}
|
||||
|
||||
//- rjf: press code slice? -> focus panel
|
||||
if(ui_pressed(sig.base))
|
||||
{
|
||||
DF_CmdParams p = df_cmd_params_from_panel(ws, panel);
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FocusPanel));
|
||||
}
|
||||
|
||||
//- rjf: dragging & outside region? -> contain cursor
|
||||
if(ui_dragging(sig.base) && sig.base.event_flags == 0)
|
||||
{
|
||||
if(!contains_2f32(sig.base.box->rect, ui_mouse()))
|
||||
{
|
||||
cv->contain_cursor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
snap[Axis2_X] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: ctrl+pressed? -> go to name
|
||||
if(ui_pressed(sig.base) && sig.base.event_flags & OS_EventFlag_Ctrl)
|
||||
{
|
||||
ui_kill_action();
|
||||
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
|
||||
params.string = txt_string_from_info_data_txt_rng(&text_info, data, sig.mouse_expr_rng);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_GoToName));
|
||||
}
|
||||
|
||||
//- rjf: copy text
|
||||
if(!txt_pt_match(sig.copy_range.min, sig.copy_range.max))
|
||||
{
|
||||
String8 text = txt_string_from_info_data_txt_rng(&text_info, data, sig.copy_range);
|
||||
os_set_clipboard_text(text);
|
||||
}
|
||||
|
||||
//- rjf: selected text on single line, no query? -> set search text
|
||||
if(!txt_pt_match(cv->cursor, cv->mark) && cv->cursor.line == cv->mark.line && search_query.size == 0)
|
||||
{
|
||||
String8 text = txt_string_from_info_data_txt_rng(&text_info, data, txt_rng(cv->cursor, cv->mark));
|
||||
df_set_search_string(text);
|
||||
}
|
||||
|
||||
//- rjf: toggle cursor watch
|
||||
if(sig.toggle_cursor_watch)
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ToggleWatchExpressionAtCursor));
|
||||
}
|
||||
|
||||
//- rjf: set next statement
|
||||
if(sig.set_next_statement_line_num != 0 && contains_1s64(visible_line_num_range, sig.set_next_statement_line_num))
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
|
||||
params.text_point = txt_pt(sig.set_next_statement_line_num, 1);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SetNextStatement));
|
||||
}
|
||||
|
||||
//- rjf: go to disasm
|
||||
if(sig.goto_disasm_line_num != 0 && contains_1s64(visible_line_num_range, sig.goto_disasm_line_num))
|
||||
{
|
||||
U64 line_idx = (sig.goto_disasm_line_num-visible_line_num_range.min);
|
||||
DF_TextLineSrc2DasmInfoList *src2dasm_list = &code_slice_params.line_src2dasm[line_idx];
|
||||
if(src2dasm_list->first != 0)
|
||||
{
|
||||
Rng1U64 voff_rng = src2dasm_list->first->v.voff_range;
|
||||
DI_Key dbgi_key = src2dasm_list->first->v.dbgi_key;
|
||||
DF_EntityList possible_modules = df_modules_from_dbgi_key(scratch.arena, &dbgi_key);
|
||||
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
|
||||
DF_Entity *thread_dst_module = df_module_from_thread_candidates(thread, &possible_modules);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
DF_Entity *module = thread_dst_module;
|
||||
if(df_entity_is_nil(module))
|
||||
{
|
||||
module = df_first_entity_from_list(&possible_modules);
|
||||
}
|
||||
U64 voff = voff_rng.min;
|
||||
if(!df_entity_is_nil(module) && voff != 0)
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(ws);
|
||||
params.entity = df_handle_from_entity(process);
|
||||
params.vaddr = df_vaddr_from_voff(module, voff);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_VirtualAddr);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindCodeLocation));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: apply post-build view snapping rules
|
||||
//
|
||||
if(text_info_is_ready)
|
||||
{
|
||||
// rjf: contain => snap
|
||||
if(cv->contain_cursor)
|
||||
{
|
||||
cv->contain_cursor = 0;
|
||||
snap[Axis2_X] = 1;
|
||||
snap[Axis2_Y] = 1;
|
||||
}
|
||||
|
||||
// rjf: center cursor
|
||||
if(cv->center_cursor)
|
||||
{
|
||||
cv->center_cursor = 0;
|
||||
String8 cursor_line = str8_substr(data, text_info.lines_ranges[cv->cursor.line-1]);
|
||||
F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, cv->cursor.column-1)).x;
|
||||
|
||||
// rjf: scroll x
|
||||
{
|
||||
S64 new_idx = (S64)(cursor_advance - code_area_dim.x/2);
|
||||
new_idx = Clamp(scroll_idx_rng[Axis2_X].min, new_idx, scroll_idx_rng[Axis2_X].max);
|
||||
ui_scroll_pt_target_idx(&view->scroll_pos.x, new_idx);
|
||||
snap[Axis2_X] = 0;
|
||||
}
|
||||
|
||||
// rjf: scroll y
|
||||
{
|
||||
S64 new_idx = (cv->cursor.line-1) - num_possible_visible_lines/2 + 2;
|
||||
new_idx = Clamp(scroll_idx_rng[Axis2_Y].min, new_idx, scroll_idx_rng[Axis2_Y].max);
|
||||
ui_scroll_pt_target_idx(&view->scroll_pos.y, new_idx);
|
||||
snap[Axis2_Y] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: snap in X
|
||||
if(snap[Axis2_X])
|
||||
{
|
||||
String8 cursor_line = str8_substr(data, text_info.lines_ranges[cv->cursor.line-1]);
|
||||
S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, cv->cursor.column-1)).x + priority_margin_width_px + catchall_margin_width_px + line_num_width_px);
|
||||
Rng1S64 visible_pixel_range =
|
||||
{
|
||||
view->scroll_pos.x.idx,
|
||||
view->scroll_pos.x.idx + (S64)code_area_dim.x,
|
||||
};
|
||||
Rng1S64 cursor_pixel_range =
|
||||
{
|
||||
cursor_off - (S64)(big_glyph_advance*4) - (S64)(priority_margin_width_px + catchall_margin_width_px + line_num_width_px),
|
||||
cursor_off + (S64)(big_glyph_advance*4),
|
||||
};
|
||||
S64 min_delta = Min(0, cursor_pixel_range.min - visible_pixel_range.min);
|
||||
S64 max_delta = Max(0, cursor_pixel_range.max - visible_pixel_range.max);
|
||||
S64 new_idx = view->scroll_pos.x.idx+min_delta+max_delta;
|
||||
new_idx = Clamp(scroll_idx_rng[Axis2_X].min, new_idx, scroll_idx_rng[Axis2_X].max);
|
||||
ui_scroll_pt_target_idx(&view->scroll_pos.x, new_idx);
|
||||
}
|
||||
|
||||
// rjf: snap in Y
|
||||
if(snap[Axis2_Y])
|
||||
{
|
||||
Rng1S64 cursor_visibility_range = r1s64(cv->cursor.line-4, cv->cursor.line+4);
|
||||
cursor_visibility_range.min = ClampBot(0, cursor_visibility_range.min);
|
||||
cursor_visibility_range.max = ClampBot(0, cursor_visibility_range.max);
|
||||
S64 min_delta = Min(0, cursor_visibility_range.min-(target_visible_line_num_range.min));
|
||||
S64 max_delta = Max(0, cursor_visibility_range.max-(target_visible_line_num_range.min+num_possible_visible_lines));
|
||||
S64 new_idx = view->scroll_pos.y.idx+min_delta+max_delta;
|
||||
new_idx = Clamp(0, new_idx, (S64)text_info.lines_count-1);
|
||||
ui_scroll_pt_target_idx(&view->scroll_pos.y, new_idx);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: build horizontal scroll bar
|
||||
//
|
||||
if(text_info_is_ready)
|
||||
{
|
||||
ui_set_next_fixed_x(0);
|
||||
ui_set_next_fixed_y(code_area_dim.y);
|
||||
ui_set_next_fixed_width(panel_box_dim.x - scroll_bar_dim);
|
||||
ui_set_next_fixed_height(scroll_bar_dim);
|
||||
{
|
||||
view->scroll_pos.x = ui_scroll_bar(Axis2_X,
|
||||
ui_px(scroll_bar_dim, 1.f),
|
||||
view->scroll_pos.x,
|
||||
scroll_idx_rng[Axis2_X],
|
||||
(S64)code_area_dim.x);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: build vertical scroll bar
|
||||
//
|
||||
if(text_info_is_ready)
|
||||
{
|
||||
ui_set_next_fixed_x(code_area_dim.x);
|
||||
ui_set_next_fixed_y(0);
|
||||
ui_set_next_fixed_width(scroll_bar_dim);
|
||||
ui_set_next_fixed_height(panel_box_dim.y - bottom_bar_dim.y - scroll_bar_dim);
|
||||
{
|
||||
view->scroll_pos.y = ui_scroll_bar(Axis2_Y,
|
||||
ui_px(scroll_bar_dim, 1.f),
|
||||
view->scroll_pos.y,
|
||||
scroll_idx_rng[Axis2_Y],
|
||||
num_possible_visible_lines);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: top-level container interaction (scrolling)
|
||||
//
|
||||
if(text_info_is_ready)
|
||||
{
|
||||
UI_Signal sig = ui_signal_from_box(container_box);
|
||||
if(sig.scroll.x != 0)
|
||||
{
|
||||
S64 new_idx = view->scroll_pos.x.idx+sig.scroll.x*big_glyph_advance;
|
||||
new_idx = clamp_1s64(scroll_idx_rng[Axis2_X], new_idx);
|
||||
ui_scroll_pt_target_idx(&view->scroll_pos.x, new_idx);
|
||||
}
|
||||
if(sig.scroll.y != 0)
|
||||
{
|
||||
S64 new_idx = view->scroll_pos.y.idx + sig.scroll.y;
|
||||
new_idx = clamp_1s64(scroll_idx_rng[Axis2_Y], new_idx);
|
||||
ui_scroll_pt_target_idx(&view->scroll_pos.y, new_idx);
|
||||
}
|
||||
ui_scroll_pt_clamp_idx(&view->scroll_pos.x, scroll_idx_rng[Axis2_X]);
|
||||
ui_scroll_pt_clamp_idx(&view->scroll_pos.y, scroll_idx_rng[Axis2_Y]);
|
||||
}
|
||||
|
||||
txt_scope_close(txt_scope);
|
||||
di_scope_close(di_scope);
|
||||
hs_scope_close(hs_scope);
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Watch Views
|
||||
|
||||
@@ -5888,7 +6600,6 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
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.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, entity, DF_EntityKind_FlashMarker);
|
||||
code_slice_params.margin_float_off_px = view->scroll_pos.x.idx + view->scroll_pos.x.off;
|
||||
|
||||
// rjf: fill text info
|
||||
@@ -6224,9 +6935,16 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
}
|
||||
|
||||
//- rjf: dragging & outside region? -> contain cursor
|
||||
if(ui_dragging(sig.base) && !contains_2f32(sig.base.box->rect, ui_mouse()) && sig.base.event_flags == 0)
|
||||
if(ui_dragging(sig.base) && sig.base.event_flags == 0)
|
||||
{
|
||||
tv->contain_cursor = 1;
|
||||
if(!contains_2f32(sig.base.box->rect, ui_mouse()))
|
||||
{
|
||||
tv->contain_cursor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
snap[Axis2_X] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: ctrl+pressed? -> go to name
|
||||
@@ -6983,7 +7701,6 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
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.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, process, DF_EntityKind_FlashMarker);
|
||||
code_slice_params.margin_float_off_px = view->scroll_pos.x.idx + view->scroll_pos.x.off;
|
||||
|
||||
di_key_list_push(scratch.arena, &code_slice_params.relevant_dbgi_keys, &dbgi_key);
|
||||
@@ -7165,9 +7882,16 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
}
|
||||
|
||||
//- rjf: dragging & outside region? -> contain cursor
|
||||
if(ui_dragging(sig.base) && !contains_2f32(sig.base.box->rect, ui_mouse()) && sig.base.event_flags == 0)
|
||||
if(ui_dragging(sig.base) && sig.base.event_flags == 0)
|
||||
{
|
||||
dv->contain_cursor = 1;
|
||||
if(!contains_2f32(sig.base.box->rect, ui_mouse()))
|
||||
{
|
||||
dv->contain_cursor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
snap[Axis2_X] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: clicked margin? -> place breakpoint
|
||||
@@ -7823,7 +8547,6 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
|
||||
code_slice_params.catchall_margin_width_px = 0.f;
|
||||
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.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, entity, DF_EntityKind_FlashMarker);
|
||||
code_slice_params.margin_float_off_px = view->scroll_pos.x.idx + view->scroll_pos.x.off;
|
||||
}
|
||||
|
||||
|
||||
@@ -467,6 +467,13 @@ internal DF_EntityListerItemList df_entity_lister_item_list_from_needle(Arena *a
|
||||
internal DF_EntityListerItemArray df_entity_lister_item_array_from_list(Arena *arena, DF_EntityListerItemList list);
|
||||
internal void df_entity_lister_item_array_sort_by_strength__in_place(DF_EntityListerItemArray array);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Code Views
|
||||
|
||||
internal void df_code_view_init(DF_CodeViewState *cv, DF_View *view);
|
||||
internal void df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CmdList *cmds, U128 key, TXT_LangKind lang_kind);
|
||||
internal void df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, Rng2F32 rect, U128 key, TXT_LangKind lang_kind);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Watch Views
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[31] =
|
||||
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("types"), str8_lit_comp("Types"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Types), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Types), DF_VIEW_CMD_FUNCTION_NAME(Types), DF_VIEW_UI_FUNCTION_NAME(Types)},
|
||||
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("procedures"), str8_lit_comp("Procedures"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Procedures), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Procedures), DF_VIEW_CMD_FUNCTION_NAME(Procedures), DF_VIEW_UI_FUNCTION_NAME(Procedures)},
|
||||
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("output"), str8_lit_comp("Output"), DF_NameKind_Null, DF_IconKind_List, DF_VIEW_SETUP_FUNCTION_NAME(Output), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Output), DF_VIEW_CMD_FUNCTION_NAME(Output), DF_VIEW_UI_FUNCTION_NAME(Output)},
|
||||
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|1*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("memory"), str8_lit_comp("Memory"), DF_NameKind_Null, DF_IconKind_Grid, DF_VIEW_SETUP_FUNCTION_NAME(Memory), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Memory), DF_VIEW_CMD_FUNCTION_NAME(Memory), DF_VIEW_UI_FUNCTION_NAME(Memory)},
|
||||
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("memory"), str8_lit_comp("Memory"), DF_NameKind_Null, DF_IconKind_Grid, DF_VIEW_SETUP_FUNCTION_NAME(Memory), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Memory), DF_VIEW_CMD_FUNCTION_NAME(Memory), DF_VIEW_UI_FUNCTION_NAME(Memory)},
|
||||
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("breakpoints"), str8_lit_comp("Breakpoints"), DF_NameKind_Null, DF_IconKind_CircleFilled, DF_VIEW_SETUP_FUNCTION_NAME(Breakpoints), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Breakpoints), DF_VIEW_CMD_FUNCTION_NAME(Breakpoints), DF_VIEW_UI_FUNCTION_NAME(Breakpoints)},
|
||||
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("watch_pins"), str8_lit_comp("Watch Pins"), DF_NameKind_Null, DF_IconKind_Pin, DF_VIEW_SETUP_FUNCTION_NAME(WatchPins), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(WatchPins), DF_VIEW_CMD_FUNCTION_NAME(WatchPins), DF_VIEW_UI_FUNCTION_NAME(WatchPins)},
|
||||
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("exception_filters"), str8_lit_comp("Exception Filters"), DF_NameKind_Null, DF_IconKind_Gear, DF_VIEW_SETUP_FUNCTION_NAME(ExceptionFilters), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(ExceptionFilters), DF_VIEW_CMD_FUNCTION_NAME(ExceptionFilters), DF_VIEW_UI_FUNCTION_NAME(ExceptionFilters)},
|
||||
@@ -1201,7 +1201,7 @@ str8_lit_comp("thread_error"),
|
||||
str8_lit_comp("breakpoint"),
|
||||
};
|
||||
|
||||
String8 df_g_setting_code_display_string_table[8] =
|
||||
String8 df_g_setting_code_display_string_table[9] =
|
||||
{
|
||||
str8_lit_comp("Hover Animations"),
|
||||
str8_lit_comp("Press Animations"),
|
||||
@@ -1210,10 +1210,11 @@ str8_lit_comp("Tooltip Animations"),
|
||||
str8_lit_comp("Menu Animations"),
|
||||
str8_lit_comp("Scrolling Animations"),
|
||||
str8_lit_comp("Background Blur"),
|
||||
str8_lit_comp("Opaque Backgrounds"),
|
||||
str8_lit_comp("Tab Width"),
|
||||
};
|
||||
|
||||
String8 df_g_setting_code_lower_string_table[8] =
|
||||
String8 df_g_setting_code_lower_string_table[9] =
|
||||
{
|
||||
str8_lit_comp("hover_animations"),
|
||||
str8_lit_comp("press_animations"),
|
||||
@@ -1222,10 +1223,11 @@ str8_lit_comp("tooltip_animations"),
|
||||
str8_lit_comp("menu_animations"),
|
||||
str8_lit_comp("scrolling_animations"),
|
||||
str8_lit_comp("background_blur"),
|
||||
str8_lit_comp("opaque_backgrounds"),
|
||||
str8_lit_comp("tab_width"),
|
||||
};
|
||||
|
||||
DF_SettingVal df_g_setting_code_default_val_table[8] =
|
||||
DF_SettingVal df_g_setting_code_default_val_table[9] =
|
||||
{
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
@@ -1234,10 +1236,11 @@ DF_SettingVal df_g_setting_code_default_val_table[8] =
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
{1, 0},
|
||||
{1, 4},
|
||||
};
|
||||
|
||||
Rng1S32 df_g_setting_code_s32_range_table[8] =
|
||||
Rng1S32 df_g_setting_code_s32_range_table[9] =
|
||||
{
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
@@ -1246,6 +1249,7 @@ Rng1S32 df_g_setting_code_s32_range_table[8] =
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 1},
|
||||
{0, 32},
|
||||
};
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@ DF_SettingCode_TooltipAnimations,
|
||||
DF_SettingCode_MenuAnimations,
|
||||
DF_SettingCode_ScrollingAnimations,
|
||||
DF_SettingCode_BackgroundBlur,
|
||||
DF_SettingCode_OpaqueBackgrounds,
|
||||
DF_SettingCode_TabWidth,
|
||||
DF_SettingCode_COUNT,
|
||||
} DF_SettingCode;
|
||||
@@ -332,10 +333,10 @@ extern Vec4F32 df_g_theme_preset_colors__far_manager[75];
|
||||
extern Vec4F32* df_g_theme_preset_colors_table[9];
|
||||
extern String8 df_g_theme_color_display_string_table[75];
|
||||
extern String8 df_g_theme_color_cfg_string_table[75];
|
||||
extern String8 df_g_setting_code_display_string_table[8];
|
||||
extern String8 df_g_setting_code_lower_string_table[8];
|
||||
extern DF_SettingVal df_g_setting_code_default_val_table[8];
|
||||
extern Rng1S32 df_g_setting_code_s32_range_table[8];
|
||||
extern String8 df_g_setting_code_display_string_table[9];
|
||||
extern String8 df_g_setting_code_lower_string_table[9];
|
||||
extern DF_SettingVal df_g_setting_code_default_val_table[9];
|
||||
extern Rng1S32 df_g_setting_code_s32_range_table[9];
|
||||
read_only global U8 df_g_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,
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Main Layer Initialization
|
||||
|
||||
internal void
|
||||
mtx_init(void)
|
||||
{
|
||||
Arena *arena = arena_alloc();
|
||||
mtx_shared = push_array(arena, MTX_Shared, 1);
|
||||
mtx_shared->arena = arena;
|
||||
mtx_shared->slots_count = 256;
|
||||
mtx_shared->stripes_count = Min(mtx_shared->slots_count, os_logical_core_count());
|
||||
mtx_shared->slots = push_array(arena, MTX_Slot, mtx_shared->slots_count);
|
||||
mtx_shared->stripes = push_array(arena, MTX_Stripe, mtx_shared->stripes_count);
|
||||
for(U64 idx = 0; idx < mtx_shared->stripes_count; idx += 1)
|
||||
{
|
||||
mtx_shared->stripes[idx].arena = arena_alloc();
|
||||
mtx_shared->stripes[idx].rw_mutex = os_rw_mutex_alloc();
|
||||
}
|
||||
mtx_shared->mut_threads_count = Min(os_logical_core_count(), 4);
|
||||
mtx_shared->mut_threads = push_array(arena, MTX_MutThread, mtx_shared->mut_threads_count);
|
||||
for(U64 idx = 0; idx < mtx_shared->mut_threads_count; idx += 1)
|
||||
{
|
||||
mtx_shared->mut_threads[idx].ring_size = KB(64);
|
||||
mtx_shared->mut_threads[idx].ring_base = push_array_no_zero(arena, U8, mtx_shared->mut_threads[idx].ring_size);
|
||||
mtx_shared->mut_threads[idx].cv = os_condition_variable_alloc();
|
||||
mtx_shared->mut_threads[idx].mutex = os_mutex_alloc();
|
||||
mtx_shared->mut_threads[idx].thread = os_launch_thread(mtx_mut_thread__entry_point, &mtx_shared->mut_threads[idx], 0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Buffer Operations
|
||||
|
||||
internal void
|
||||
mtx_push_op(U128 buffer_key, MTX_Op op)
|
||||
{
|
||||
MTX_MutThread *thread = &mtx_shared->mut_threads[buffer_key.u64[1]%mtx_shared->mut_threads_count];
|
||||
mtx_enqueue_op(thread, buffer_key, op);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Mutation Threads
|
||||
|
||||
internal void
|
||||
mtx_enqueue_op(MTX_MutThread *thread, U128 buffer_key, MTX_Op op)
|
||||
{
|
||||
// TODO(rjf): if op.replace is too big, need to split into multiple edits
|
||||
OS_MutexScope(thread->mutex) for(;;)
|
||||
{
|
||||
U64 unconsumed_size = thread->ring_write_pos - thread->ring_read_pos;
|
||||
U64 available_size = thread->ring_size - unconsumed_size;
|
||||
if(available_size >= sizeof(buffer_key) + sizeof(op.range) + sizeof(op.replace.size) + op.replace.size)
|
||||
{
|
||||
thread->ring_write_pos += ring_write_struct(thread->ring_base, thread->ring_size, thread->ring_write_pos, &buffer_key);
|
||||
thread->ring_write_pos += ring_write_struct(thread->ring_base, thread->ring_size, thread->ring_write_pos, &op.range);
|
||||
thread->ring_write_pos += ring_write_struct(thread->ring_base, thread->ring_size, thread->ring_write_pos, &op.replace.size);
|
||||
thread->ring_write_pos += ring_write(thread->ring_base, thread->ring_size, thread->ring_write_pos, op.replace.str, op.replace.size);
|
||||
thread->ring_write_pos += 7;
|
||||
thread->ring_write_pos -= thread->ring_write_pos%8;
|
||||
break;
|
||||
}
|
||||
os_condition_variable_wait(thread->cv, thread->mutex, max_U64);
|
||||
}
|
||||
os_condition_variable_broadcast(thread->cv);
|
||||
}
|
||||
|
||||
internal void
|
||||
mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, U128 *buffer_key_out, MTX_Op *op_out)
|
||||
{
|
||||
OS_MutexScope(thread->mutex) for(;;)
|
||||
{
|
||||
U64 unconsumed_size = thread->ring_write_pos - thread->ring_read_pos;
|
||||
if(unconsumed_size >= sizeof(*buffer_key_out) + sizeof(op_out->range) + sizeof(op_out->replace.size))
|
||||
{
|
||||
thread->ring_read_pos += ring_read_struct(thread->ring_base, thread->ring_size, thread->ring_read_pos, buffer_key_out);
|
||||
thread->ring_read_pos += ring_read_struct(thread->ring_base, thread->ring_size, thread->ring_read_pos, &op_out->range);
|
||||
thread->ring_read_pos += ring_read_struct(thread->ring_base, thread->ring_size, thread->ring_read_pos, &op_out->replace.size);
|
||||
op_out->replace.str = push_array_no_zero(arena, U8, op_out->replace.size);
|
||||
thread->ring_read_pos += ring_read(thread->ring_base, thread->ring_size, thread->ring_read_pos, op_out->replace.str, op_out->replace.size);
|
||||
thread->ring_read_pos += 7;
|
||||
thread->ring_read_pos -= thread->ring_read_pos%8;
|
||||
break;
|
||||
}
|
||||
os_condition_variable_wait(thread->cv, thread->mutex, max_U64);
|
||||
}
|
||||
os_condition_variable_broadcast(thread->cv);
|
||||
}
|
||||
|
||||
internal void
|
||||
mtx_mut_thread__entry_point(void *p)
|
||||
{
|
||||
MTX_MutThread *mut_thread = (MTX_MutThread *)p;
|
||||
ThreadNameF("[mtx] mut thread #%I64u", (U64)(mut_thread - mtx_shared->mut_threads));
|
||||
for(;;)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
|
||||
//- rjf: get next op
|
||||
U128 buffer_key = {0};
|
||||
MTX_Op op = {0};
|
||||
mtx_dequeue_op(scratch.arena, mut_thread, &buffer_key, &op);
|
||||
|
||||
//- rjf: get buffer's current data
|
||||
U128 hash = hs_hash_from_key(buffer_key, 0);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
|
||||
//- rjf: clamp op by data
|
||||
op.range.min = Min(op.range.min, data.size);
|
||||
op.range.max = Min(op.range.max, data.size);
|
||||
|
||||
//- rjf: construct new buffer
|
||||
if(op.range.max != op.range.min || op.replace.size != 0)
|
||||
{
|
||||
Arena *arena = arena_alloc();
|
||||
U64 new_data_size = data.size + op.replace.size - dim_1u64(op.range);
|
||||
U8 *new_data_base = push_array_no_zero(arena, U8, new_data_size);
|
||||
String8 pre_replace_data = str8_substr(data, r1u64(0, op.range.min));
|
||||
String8 post_replace_data = str8_substr(data, r1u64(op.range.max, data.size));
|
||||
if(pre_replace_data.size != 0)
|
||||
{
|
||||
MemoryCopy(new_data_base+0, pre_replace_data.str, pre_replace_data.size);
|
||||
}
|
||||
if(op.replace.size != 0)
|
||||
{
|
||||
MemoryCopy(new_data_base+pre_replace_data.size, op.replace.str, op.replace.size);
|
||||
}
|
||||
if(post_replace_data.size != 0)
|
||||
{
|
||||
MemoryCopy(new_data_base+pre_replace_data.size+op.replace.size, post_replace_data.str, post_replace_data.size);
|
||||
}
|
||||
String8 new_data = str8(new_data_base, new_data_size);
|
||||
hs_submit_data(buffer_key, &arena, new_data);
|
||||
}
|
||||
|
||||
hs_scope_close(hs_scope);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef MUTABLE_TEXT_H
|
||||
#define MUTABLE_TEXT_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Types
|
||||
|
||||
typedef struct MTX_Node MTX_Node;
|
||||
struct MTX_Node
|
||||
{
|
||||
MTX_Node *next;
|
||||
MTX_Node *prev;
|
||||
U128 key;
|
||||
};
|
||||
|
||||
typedef struct MTX_Slot MTX_Slot;
|
||||
struct MTX_Slot
|
||||
{
|
||||
MTX_Node *first;
|
||||
MTX_Node *last;
|
||||
};
|
||||
|
||||
typedef struct MTX_Stripe MTX_Stripe;
|
||||
struct MTX_Stripe
|
||||
{
|
||||
Arena *arena;
|
||||
MTX_Node *free_node;
|
||||
OS_Handle rw_mutex;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Mutation Thread Types
|
||||
|
||||
typedef struct MTX_Op MTX_Op;
|
||||
struct MTX_Op
|
||||
{
|
||||
Rng1U64 range;
|
||||
String8 replace;
|
||||
};
|
||||
|
||||
typedef struct MTX_MutThread MTX_MutThread;
|
||||
struct MTX_MutThread
|
||||
{
|
||||
U64 ring_size;
|
||||
U8 *ring_base;
|
||||
U64 ring_read_pos;
|
||||
U64 ring_write_pos;
|
||||
OS_Handle cv;
|
||||
OS_Handle mutex;
|
||||
OS_Handle thread;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Shared State
|
||||
|
||||
typedef struct MTX_Shared MTX_Shared;
|
||||
struct MTX_Shared
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
// rjf: buffer cache
|
||||
U64 slots_count;
|
||||
U64 stripes_count;
|
||||
MTX_Slot *slots;
|
||||
MTX_Stripe *stripes;
|
||||
|
||||
// rjf: mut threads
|
||||
U64 mut_threads_count;
|
||||
MTX_MutThread *mut_threads;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global MTX_Shared *mtx_shared = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Main Layer Initialization
|
||||
|
||||
internal void mtx_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Buffer Operations
|
||||
|
||||
internal void mtx_push_op(U128 buffer_key, MTX_Op op);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Mutation Threads
|
||||
|
||||
internal void mtx_enqueue_op(MTX_MutThread *thread, U128 buffer_key, MTX_Op op);
|
||||
internal void mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, U128 *buffer_key_out, MTX_Op *op_out);
|
||||
internal void mtx_mut_thread__entry_point(void *p);
|
||||
|
||||
#endif // MUTABLE_TEXT_H
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "hash_store/hash_store.h"
|
||||
#include "file_stream/file_stream.h"
|
||||
#include "text_cache/text_cache.h"
|
||||
#include "mutable_text/mutable_text.h"
|
||||
#include "path/path.h"
|
||||
#include "txti/txti.h"
|
||||
#include "coff/coff.h"
|
||||
@@ -76,6 +77,7 @@
|
||||
#include "hash_store/hash_store.c"
|
||||
#include "file_stream/file_stream.c"
|
||||
#include "text_cache/text_cache.c"
|
||||
#include "mutable_text/mutable_text.c"
|
||||
#include "path/path.c"
|
||||
#include "txti/txti.c"
|
||||
#include "coff/coff.c"
|
||||
|
||||
Reference in New Issue
Block a user