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:
Ryan Fleury
2024-06-25 11:09:02 -07:00
parent c10ac170a8
commit d12c5ec2e8
15 changed files with 1022 additions and 52 deletions
+3
View File
@@ -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
+4
View File
@@ -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:
-3
View File
@@ -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" }
+5 -10
View File
@@ -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),
+5 -6
View File
@@ -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
View File
@@ -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
-1
View File
@@ -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;
};
+2 -1
View File
@@ -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
View File
@@ -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(&params, DF_CmdParamSlot_String);
df_push_cmd__root(&params, 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(&params, DF_CmdParamSlot_String);
df_push_cmd__root(&params, 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(&params, DF_CmdParamSlot_String);
df_push_cmd__root(&params, 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(&params, DF_CmdParamSlot_String);
df_push_cmd__root(&params, 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(&params, DF_CmdParamSlot_String);
df_push_cmd__root(&params, 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(&params, 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(&params, 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(&params, DF_CmdParamSlot_Entity);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_VirtualAddr);
df_push_cmd__root(&params, 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;
}
+7
View File
@@ -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
+9 -5
View File
@@ -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},
};
+5 -4
View File
@@ -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,
+142
View File
@@ -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);
}
}
+96
View File
@@ -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
+2
View File
@@ -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"