Work on profiler; cleaned up the API types file

This commit is contained in:
Allen Webster 2019-10-22 15:07:05 -07:00
parent b807950233
commit 9f986493a1
12 changed files with 473 additions and 114 deletions

View File

@ -66,6 +66,8 @@ async_task_thread(void *thread_ptr){
Thread_Context *tctx = &tctx_; Thread_Context *tctx = &tctx_;
thread_ctx_init(tctx, ThreadKind_AsyncTasks, allocator, allocator); thread_ctx_init(tctx, ThreadKind_AsyncTasks, allocator, allocator);
ProfileThreadName(tctx, string_u8_litexpr("async"));
Async_Thread *thread = (Async_Thread*)thread_ptr; Async_Thread *thread = (Async_Thread*)thread_ptr;
Async_System *async_system = thread->async_system; Async_System *async_system = thread->async_system;

View File

@ -1544,6 +1544,20 @@ unlerp(f32 a, f32 x, f32 b){
return(r); return(r);
} }
internal f32
unlerp(u64 a, u64 x, u64 b){
f32 r = 0.f;
if (b <= x){
r = 1.f;
}
else if (a < x){
u64 n = x - a;
u64 d = b - a;
r = (f32)(((f64)n)/((f64)d));
}
return(r);
}
internal f32 internal f32
lerp(Range_f32 range, f32 t){ lerp(Range_f32 range, f32 t){
return(lerp(range.min, t, range.max)); return(lerp(range.min, t, range.max));

View File

@ -1148,6 +1148,7 @@ struct Profile_Thread{
Profile_Record *last_record; Profile_Record *last_record;
i32 record_count; i32 record_count;
i32 thread_id; i32 thread_id;
String_Const_u8 name;
}; };
typedef u32 Profile_Enable_Flag; typedef u32 Profile_Enable_Flag;

View File

@ -20,6 +20,8 @@ custom_layer_init(Application_Links *app){
setup_default_mapping(&framework_mapping); setup_default_mapping(&framework_mapping);
global_prof_init(); global_prof_init();
async_task_handler_init(app, &global_async_system); async_task_handler_init(app, &global_async_system);
ProfileThreadName(tctx, string_u8_litexpr("main"));
} }
#endif #endif

View File

@ -56,8 +56,15 @@ CUSTOM_DOC("Default command for responding to a try-exit event")
CUSTOM_COMMAND_SIG(default_view_input_handler) CUSTOM_COMMAND_SIG(default_view_input_handler)
CUSTOM_DOC("Input consumption loop for default view behavior") CUSTOM_DOC("Input consumption loop for default view behavior")
{ {
Thread_Context *tctx = get_thread_context(app);
Scratch_Block scratch(tctx);
{ {
View_ID view = get_active_view(app, Access_Always); View_ID view = get_active_view(app, Access_Always);
String_Const_u8 name = push_u8_stringf(scratch, "view %d", view);
ProfileThreadName(tctx, name);
View_Context ctx = view_current_context(app, view); View_Context ctx = view_current_context(app, view);
ctx.mapping = &framework_mapping; ctx.mapping = &framework_mapping;
ctx.map_id = mapid_global; ctx.map_id = mapid_global;

View File

@ -104,6 +104,12 @@ get_modifiers(Input_Event *event){
return(result); return(result);
} }
function b32
has_modifier(Input_Event *event, Key_Code modifier){
Input_Modifier_Set *set = get_modifiers(event);
return(has_modifier(set, modifier));
}
function b32 function b32
is_unmodified_key(Input_Event *event){ is_unmodified_key(Input_Event *event){
b32 result = false; b32 result = false;

View File

@ -7,15 +7,6 @@
#if !defined(FCODER_FANCY_H) #if !defined(FCODER_FANCY_H)
#define FCODER_FANCY_H #define FCODER_FANCY_H
/* TODO(casey): This warrants a lot of thought.
Since you want to be able to edit colors after they have already been stored away in
internal structures, you want to capture as much as possible where the colors came
from. In the current set-up, you can blend any two ids, but that's it. If you
go beyond that, it collapses down to just RGBA. Maybe there should be more than
that. It's hard to say. I don't know.
*/
struct Fancy_Color{ struct Fancy_Color{
union{ union{
struct{ struct{

View File

@ -81,6 +81,14 @@ thread_profile_flush(Thread_Context *tctx){
} }
} }
function void
thread_set_name(Thread_Context *tctx, String_Const_u8 name){
Profile_Thread* thread = global_prof_get_thread(system_thread_get_id());
thread->name = name;
}
#define ProfileThreadName(tctx,name) thread_set_name((tctx), (name))
function void function void
global_prof_set_enabled(b32 value, Profile_Enable_Flag flag){ global_prof_set_enabled(b32 value, Profile_Enable_Flag flag){
Mutex_Lock lock(global_prof_mutex); Mutex_Lock lock(global_prof_mutex);

View File

@ -50,6 +50,8 @@ profile_parse_record(Arena *arena, Profile_Inspection *insp,
Profile_Node *node = push_array(arena, Profile_Node, 1); Profile_Node *node = push_array(arena, Profile_Node, 1);
sll_queue_push(parent->first_child, parent->last_child, node); sll_queue_push(parent->first_child, parent->last_child, node);
parent->child_count += 1; parent->child_count += 1;
node->parent = parent;
node->thread = parent->thread;
String_Const_u8 location = record->location; String_Const_u8 location = record->location;
String_Const_u8 name = record->name; String_Const_u8 name = record->name;
@ -107,7 +109,12 @@ profile_parse_record(Arena *arena, Profile_Inspection *insp,
slot->corrupted_time = true; slot->corrupted_time = true;
} }
} }
slot->hit_count += 1; {
Profile_Node_Ptr *node_ptr = push_array(arena, Profile_Node_Ptr, 1);
sll_queue_push(slot->first_hit, slot->last_hit, node_ptr);
slot->hit_count += 1;
node_ptr->ptr = node;
}
if (quit_loop){ if (quit_loop){
break; break;
@ -133,14 +140,23 @@ profile_parse(Arena *arena){
node != 0; node != 0;
node = node->next, counter += 1, insp_thread += 1){ node = node->next, counter += 1, insp_thread += 1){
insp_thread->thread_id = node->thread_id; insp_thread->thread_id = node->thread_id;
insp_thread->name = node->name;
// NOTE(allen): This is the "negative infinity" range. // NOTE(allen): This is the "negative infinity" range.
// We will be "maxing" it against all the ranges durring the parse, // We will be "maxing" it against all the ranges durring the parse,
// to get the root range. // to get the root range.
Range_u64 time_range = {max_u64, 0}; Range_u64 time_range = {max_u64, 0};
insp_thread->root.thread = insp_thread;
profile_parse_record(arena, &result, &insp_thread->root, node->first_record, profile_parse_record(arena, &result, &insp_thread->root, node->first_record,
&time_range); &time_range);
insp_thread->root.time = time_range; insp_thread->root.time = time_range;
insp_thread->root.closed = true;
for (Profile_Node *prof_node = insp_thread->root.first_child;
prof_node != 0;
prof_node = prof_node->next){
insp_thread->active_time += range_size(prof_node->time);
}
} }
return(result); return(result);
@ -189,6 +205,183 @@ profile_draw_tab(Application_Links *app, Tab_State *state, Profile_Inspection *i
state->p.x += state->x_half_padding; state->p.x += state->x_half_padding;
} }
function void
profile_select_thread(Profile_Inspection *inspect, Profile_Inspection_Thread *thread){
inspect->tab_id = ProfileInspectTab_Selection;
inspect->selected_thread = thread;
inspect->selected_slot = 0;
inspect->selected_node = 0;
}
function void
profile_select_slot(Profile_Inspection *inspect, Profile_Slot *slot){
inspect->tab_id = ProfileInspectTab_Selection;
inspect->selected_thread = 0;
inspect->selected_slot = slot;
inspect->selected_node = 0;
}
function void
profile_select_node(Profile_Inspection *inspect, Profile_Node *node){
inspect->tab_id = ProfileInspectTab_Selection;
inspect->selected_thread = 0;
inspect->selected_slot = 0;
inspect->selected_node = node;
}
function String_Const_u8
profile_node_thread_name(Profile_Node *node){
String_Const_u8 result = {};
if (node->thread != 0){
result = node->thread->name;
}
return(result);
}
function String_Const_u8
profile_node_name(Profile_Node *node){
String_Const_u8 result = string_u8_litexpr("*root*");
if (node->slot != 0){
result = node->slot->name;
}
return(result);
}
function void
profile_draw_node(Application_Links *app, View_ID view, Face_ID face_id,
Profile_Node *node, Rect_f32 rect,
Profile_Inspection *insp, Vec2_f32 m_p){
Range_f32 x = rect_range_x(rect);
Range_f32 y = rect_range_y(rect);
// TODO(allen): share this shit
Face_Metrics metrics = get_face_metrics(app, face_id);
f32 line_height = metrics.line_height;
f32 normal_advance = metrics.normal_advance;
f32 x_padding = normal_advance*1.5f;
f32 x_half_padding = x_padding*0.5f;
int_color colors[] = {
Stag_Back_Cycle_1, Stag_Back_Cycle_2, Stag_Back_Cycle_3, Stag_Back_Cycle_4,
};
Scratch_Block scratch(app);
f32 x_pos = x.min + x_half_padding;
f32 nav_bar_w = 0.f;
Range_f32 nav_bar_y = {};
nav_bar_y.min = y.min;
String_Const_u8 thread_name = profile_node_thread_name(node);
if (thread_name.size > 0){
Fancy_String_List list = {};
push_fancy_string(scratch, &list, fancy_id(Stag_Pop1), thread_name);
Vec2_f32 p = V2f32(x_pos, y.min + 1.f);
draw_fancy_string(app, face_id, list.first, p, 0, 0);
f32 w = get_fancy_string_advance(app, face_id, list.first);
nav_bar_w = max(nav_bar_w, w);
}
y.min += line_height + 2.f;
String_Const_u8 name = profile_node_name(node);
if (name.size > 0){
Fancy_String_List list = {};
push_fancy_string(scratch, &list, fancy_id(Stag_Default), name);
Vec2_f32 p = V2f32(x_pos, y.min + 1.f);
draw_fancy_string(app, face_id, list.first, p, 0, 0);
f32 w = get_fancy_string_advance(app, face_id, list.first);
nav_bar_w = max(nav_bar_w, w);
}
y.min += line_height + 2.f;
nav_bar_y.max = y.min;
x_pos += nav_bar_w + x_half_padding;
if (node->parent != 0){
Fancy_String_List list = {};
push_fancy_string(scratch, &list, fancy_pass_through(),
string_u8_litexpr("to parent"));
f32 w = get_fancy_string_advance(app, face_id, list.first) + x_padding;
Range_f32 btn_x = If32_size(x_pos, w);
Rect_f32 box = Rf32(btn_x, nav_bar_y);
int_color color = Stag_Default;
if (rect_contains_point(box, m_p)){
draw_rectangle(app, box, 0.f, Stag_Margin);
color = Stag_Pop1;
insp->hover_node = node->parent;
}
Vec2_f32 p = V2f32(box.x0 + x_half_padding,
(box.y0 + box.y1 - line_height)*0.5f);
draw_fancy_string(app, face_id, list.first, p, color, 0);
x_pos = btn_x.max;
}
Range_u64 top_time = node->time;
Rect_f32_Pair side_by_side = rect_split_left_right_lerp(Rf32(x, y), 0.5f);
Rect_f32 time_slice_box = side_by_side.min;
time_slice_box = rect_inner(time_slice_box, 3.f);
draw_rectangle_outline(app, time_slice_box, 0.f, 3.f,
0xFFFFFFFF);
time_slice_box = rect_inner(time_slice_box, 3.f);
if (node->closed){
x = rect_range_x(time_slice_box);
y = rect_range_y(time_slice_box);
i32 cycle_counter = 0;
i32 count = ArrayCount(colors);
for (Profile_Node *child = node->first_child;
child != 0;
child = child->next){
if (child->closed){
Range_u64 child_time = child->time;
Range_f32 child_y = {};
child_y.min = unlerp(top_time.min, child_time.min, top_time.max);
child_y.max = unlerp(top_time.min, child_time.max, top_time.max);
child_y.min = lerp(y.min, child_y.min, y.max);
child_y.max = lerp(y.min, child_y.max, y.max);
Rect_f32 box = Rf32(x, child_y);
draw_rectangle(app, box, 0.f, colors[cycle_counter%count]);
cycle_counter += 1;
if (rect_contains_point(box, m_p)){
insp->full_name_hovered = profile_node_name(child);
insp->hover_node = child;
}
}
}
}
Rect_f32 info_box = side_by_side.max;
{
x = rect_range_x(info_box);
y = rect_range_y(info_box);
x_pos = x.min + x_half_padding;
f32 y_pos = y.min;
// NOTE(allen): duration
{
f32 duration = ((f32)range_size(node->time))/1000000.f;
Fancy_String_List list = {};
push_fancy_stringf(scratch, &list, fancy_id(Stag_Default),
"time: %11.9f", duration);
draw_fancy_string(app, face_id, list.first,
V2f32(x_pos, y_pos + 1.f),
0, 0);
y_pos += line_height + 2.f;
}
}
}
function void function void
profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
Scratch_Block scratch(app); Scratch_Block scratch(app);
@ -197,10 +390,13 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
Rect_f32 prev_clip = draw_set_clip(app, region); Rect_f32 prev_clip = draw_set_clip(app, region);
Face_ID face_id = get_face_id(app, 0); Face_ID face_id = get_face_id(app, 0);
// TODO(allen): share this shit
Face_Metrics metrics = get_face_metrics(app, face_id); Face_Metrics metrics = get_face_metrics(app, face_id);
f32 line_height = metrics.line_height; f32 line_height = metrics.line_height;
f32 normal_advance = metrics.normal_advance; f32 normal_advance = metrics.normal_advance;
f32 block_height = line_height*2.f; f32 block_height = line_height*2.f;
f32 x_padding = normal_advance*1.5f;
f32 x_half_padding = x_padding*0.5f;
Mouse_State mouse = get_mouse_state(app); Mouse_State mouse = get_mouse_state(app);
Vec2_f32 m_p = V2f32(mouse.p); Vec2_f32 m_p = V2f32(mouse.p);
@ -221,12 +417,12 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
Rect_f32_Pair tabs_body = rect_split_top_bottom(region, line_height + 2.f); Rect_f32_Pair tabs_body = rect_split_top_bottom(region, line_height + 2.f);
Range_f32 tabs_y = rect_range_y(tabs_body.min); Range_f32 tabs_y = rect_range_y(tabs_body.min);
f32 x_padding = normal_advance*1.5f;
f32 x_half_padding = x_padding*0.5f;
inspect->tab_id_hovered = ProfileInspectTab_None; inspect->tab_id_hovered = ProfileInspectTab_None;
block_zero_struct(&inspect->full_name_hovered); block_zero_struct(&inspect->full_name_hovered);
block_zero_struct(&inspect->location_jump_hovered); block_zero_struct(&inspect->location_jump_hovered);
inspect->hover_thread = 0;
inspect->hover_slot = 0;
inspect->hover_node = 0;
// NOTE(allen): tabs // NOTE(allen): tabs
{ {
@ -252,8 +448,8 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
if (inspect->slot_count > 0){ if (inspect->slot_count > 0){
profile_draw_tab(app, &tab_state, inspect, profile_draw_tab(app, &tab_state, inspect,
string_u8_litexpr("slots"), string_u8_litexpr("blocks"),
ProfileInspectTab_Slots); ProfileInspectTab_Blocks);
} }
if (inspect->error_count > 0){ if (inspect->error_count > 0){
@ -261,12 +457,75 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
string_u8_litexpr("errors"), string_u8_litexpr("errors"),
ProfileInspectTab_Errors); ProfileInspectTab_Errors);
} }
if (inspect->tab_id == ProfileInspectTab_Selection){
String_Const_u8 string = {};
if (inspect->selected_thread != 0){
String_Const_u8 name = inspect->selected_thread->name;
string = push_u8_stringf(scratch, "%.*s (%d)",
string_expand(name),
inspect->selected_thread->thread_id);
}
else if (inspect->selected_slot != 0){
String_Const_u8 name = inspect->selected_slot->name;
string = push_u8_stringf(scratch, "block %.*s",
string_expand(name));
}
else if (inspect->selected_node != 0){
String_Const_u8 name = profile_node_name(inspect->selected_node);
string = push_u8_stringf(scratch, "node %.*s",
string_expand(name));
}
else{
inspect->tab_id = ProfileInspectTab_Threads;
}
if (string.str != 0){
profile_draw_tab(app, &tab_state, inspect,
string, ProfileInspectTab_Selection);
}
}
} }
draw_set_clip(app, tabs_body.max);
switch (inspect->tab_id){ switch (inspect->tab_id){
case ProfileInspectTab_Slots: case ProfileInspectTab_Threads:
{
Range_f32 x = rect_range_x(tabs_body.max);
f32 y_pos = tabs_body.max.y0;
i32 count = inspect->thread_count;
Profile_Inspection_Thread *thread = inspect->threads;
for (i32 i = 0; i < count; i += 1, thread += 1){
Range_f32 y = If32_size(y_pos, block_height);
Fancy_String_List list = {};
push_fancy_stringf(scratch, &list, fancy_id(Stag_Pop1),
"%-20.*s (%6d) ",
string_expand(thread->name),
thread->thread_id);
f32 active_time = ((f32)thread->active_time)/1000000.f;
push_fancy_stringf(scratch, &list, fancy_id(Stag_Pop2),
"active time %11.9f",
active_time);
Vec2_f32 p = V2f32(x.min + x_half_padding,
(y.min + y.max - line_height)*0.5f);
draw_fancy_string(app, face_id, list.first, p, 0, 0);
Rect_f32 box = Rf32(x, y);
int_color margin = Stag_Margin;
if (rect_contains_point(box, m_p)){
inspect->hover_thread = thread;
margin = Stag_Margin_Hover;
}
draw_rectangle_outline(app, box, 6.f, 3.f, margin);
y_pos = y.max;
}
}break;
case ProfileInspectTab_Blocks:
{ {
draw_set_clip(app, tabs_body.max);
Range_f32 x = rect_range_x(tabs_body.max); Range_f32 x = rect_range_x(tabs_body.max);
f32 y_pos = tabs_body.max.y0; f32 y_pos = tabs_body.max.y0;
for (Profile_Slot *node = inspect->first_slot; for (Profile_Slot *node = inspect->first_slot;
@ -314,6 +573,7 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
inspect->full_name_hovered = node->name; inspect->full_name_hovered = node->name;
} }
inspect->location_jump_hovered = node->location; inspect->location_jump_hovered = node->location;
inspect->hover_slot = node;
margin = Stag_Margin_Hover; margin = Stag_Margin_Hover;
} }
draw_rectangle_outline(app, box, 6.f, 3.f, margin); draw_rectangle_outline(app, box, 6.f, 3.f, margin);
@ -351,6 +611,23 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
y_pos = y.max; y_pos = y.max;
} }
}break; }break;
case ProfileInspectTab_Selection:
{
if (inspect->selected_thread != 0){
profile_draw_node(app, view, face_id,
&inspect->selected_thread->root, tabs_body.max,
inspect, m_p);
}
else if (inspect->selected_slot != 0){
}
else if (inspect->selected_node != 0){
profile_draw_node(app, view, face_id,
inspect->selected_node, tabs_body.max,
inspect, m_p);
}
}break;
} }
if (!rect_contains_point(region, m_p)){ if (!rect_contains_point(region, m_p)){
@ -374,7 +651,7 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
} }
if (inspect->location_jump_hovered.size > 0){ if (inspect->location_jump_hovered.size > 0){
line_count += 1; line_count += 1;
push_fancy_stringf(scratch, &list[1], color, "jump to: '%.*s'", push_fancy_stringf(scratch, &list[1], color, "[shift] '%.*s'",
string_expand(inspect->location_jump_hovered)); string_expand(inspect->location_jump_hovered));
f32 l_width = get_fancy_string_advance(app, face_id, list[1].first); f32 l_width = get_fancy_string_advance(app, face_id, list[1].first);
width = max(width, l_width); width = max(width, l_width);
@ -405,6 +682,34 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
draw_set_clip(app, prev_clip); draw_set_clip(app, prev_clip);
} }
function void
profile_inspect__left_click(Application_Links *app, View_ID view,
Profile_Inspection *insp, Input_Event *event){
if (has_modifier(event, KeyCode_Shift)){
if (insp->location_jump_hovered.size != 0){
View_ID target_view = view;
target_view = get_next_view_looped_primary_panels(app, target_view,
Access_Always);
String_Const_u8 location = insp->location_jump_hovered;
jump_to_location(app, target_view, location);
}
}
else{
if (insp->tab_id_hovered != ProfileInspectTab_None){
insp->tab_id = insp->tab_id_hovered;
}
else if (insp->hover_thread != 0){
profile_select_thread(insp, insp->hover_thread);
}
else if (insp->hover_slot != 0){
profile_select_slot(insp, insp->hover_slot);
}
else if (insp->hover_node != 0){
profile_select_node(insp, insp->hover_node);
}
}
}
CUSTOM_UI_COMMAND_SIG(profile_inspect) CUSTOM_UI_COMMAND_SIG(profile_inspect)
CUSTOM_DOC("Inspect all currently collected profiling information in 4coder's self profiler.") CUSTOM_DOC("Inspect all currently collected profiling information in 4coder's self profiler.")
{ {
@ -437,15 +742,7 @@ CUSTOM_DOC("Inspect all currently collected profiling information in 4coder's se
switch (in.event.mouse.code){ switch (in.event.mouse.code){
case MouseCode_Left: case MouseCode_Left:
{ {
if (insp->tab_id_hovered != ProfileInspectTab_None){ profile_inspect__left_click(app, view, insp, &in.event);
insp->tab_id = insp->tab_id_hovered;
}
else if (insp->location_jump_hovered.size != 0){
View_ID target_view = view;
target_view = get_next_view_looped_primary_panels(app, target_view, Access_Always);
String_Const_u8 location = insp->location_jump_hovered;
jump_to_location(app, target_view, location);
}
}break; }break;
} }
}break; }break;

View File

@ -7,19 +7,29 @@
#if !defined(FCODER_PROFILE_INSPECT_H) #if !defined(FCODER_PROFILE_INSPECT_H)
#define FCODER_PROFILE_INSPECT_H #define FCODER_PROFILE_INSPECT_H
struct Profile_Node_Ptr{
Profile_Node_Ptr *next;
struct Profile_Node *ptr;
};
struct Profile_Slot{ struct Profile_Slot{
Profile_Slot *next; Profile_Slot *next;
String_Const_u8 location; String_Const_u8 location;
String_Const_u8 name; String_Const_u8 name;
b32 corrupted_time;
u64 total_time; u64 total_time;
b32 corrupted_time;
i32 hit_count; i32 hit_count;
Profile_Node_Ptr *first_hit;
Profile_Node_Ptr *last_hit;
}; };
struct Profile_Node{ struct Profile_Node{
Profile_Node *next; Profile_Node *next;
Profile_Node *parent;
Profile_Slot *slot; Profile_Slot *slot;
struct Profile_Inspection_Thread *thread;
Range_u64 time; Range_u64 time;
Profile_ID id; Profile_ID id;
@ -32,7 +42,9 @@ struct Profile_Node{
struct Profile_Inspection_Thread{ struct Profile_Inspection_Thread{
i32 thread_id; i32 thread_id;
String_Const_u8 name;
Profile_Node root; Profile_Node root;
u64 active_time;
}; };
struct Profile_Error{ struct Profile_Error{
@ -45,8 +57,9 @@ typedef i32 Profile_Inspection_Tab;
enum{ enum{
ProfileInspectTab_None, ProfileInspectTab_None,
ProfileInspectTab_Threads, ProfileInspectTab_Threads,
ProfileInspectTab_Slots, ProfileInspectTab_Blocks,
ProfileInspectTab_Errors ProfileInspectTab_Errors,
ProfileInspectTab_Selection,
}; };
struct Profile_Inspection{ struct Profile_Inspection{
@ -60,10 +73,16 @@ struct Profile_Inspection{
i32 error_count; i32 error_count;
Profile_Inspection_Tab tab_id; Profile_Inspection_Tab tab_id;
Profile_Inspection_Tab tab_id_hovered; Profile_Inspection_Thread *selected_thread;
Profile_Slot *selected_slot;
Profile_Node *selected_node;
Profile_Inspection_Tab tab_id_hovered;
String_Const_u8 full_name_hovered; String_Const_u8 full_name_hovered;
String_Const_u8 location_jump_hovered; String_Const_u8 location_jump_hovered;
Profile_Inspection_Thread *hover_thread;
Profile_Slot *hover_slot;
Profile_Node *hover_node;
}; };
global Profile_Inspection global_profile_inspection = {}; global Profile_Inspection global_profile_inspection = {};

View File

@ -1,18 +1,6 @@
#if !defined(FCODER_TYPES_H) #if !defined(FCODER_TYPES_H)
#define FCODER_TYPES_H #define FCODER_TYPES_H
#if !defined(FCODER_META_TAGS)
#define FCODER_META_TAGS
# define ENUM(type,name) typedef type name; enum name##_
# define TYPEDEF typedef
# define TYPEDEF_FUNC typedef
# define STRUCT struct
# define UNION union
# define GLOBAL_VAR static
#endif
struct Thread_Context_Extra_Info{ struct Thread_Context_Extra_Info{
void *coroutine; void *coroutine;
void *async_thread; void *async_thread;
@ -30,21 +18,21 @@ typedef Custom_Layer_Init_Type *_Init_APIs_Type(struct API_VTable_custom *custom
//////////////////////////////// ////////////////////////////////
TYPEDEF u32 argb_color; typedef u32 argb_color;
TYPEDEF u32 int_color; typedef u32 int_color;
TYPEDEF u16 id_color; typedef u16 id_color;
TYPEDEF u32 Child_Process_ID; typedef u32 Child_Process_ID;
TYPEDEF i32 Buffer_ID; typedef i32 Buffer_ID;
TYPEDEF i32 View_ID; typedef i32 View_ID;
TYPEDEF i32 Panel_ID; typedef i32 Panel_ID;
TYPEDEF u32 Text_Layout_ID; typedef u32 Text_Layout_ID;
typedef i32 UI_Highlight_Level; typedef i32 UI_Highlight_Level;
enum{ enum{
@ -53,53 +41,58 @@ enum{
UIHighlight_Active, UIHighlight_Active,
}; };
STRUCT Buffer_Point{ struct Buffer_Point{
i64 line_number; i64 line_number;
Vec2 pixel_shift; Vec2 pixel_shift;
}; };
STRUCT Line_Shift_Vertical{ struct Line_Shift_Vertical{
i64 line; i64 line;
f32 y_delta; f32 y_delta;
}; };
STRUCT Line_Shift_Character{ struct Line_Shift_Character{
i64 line; i64 line;
i64 character_delta; i64 character_delta;
}; };
ENUM(u32, Child_Process_Set_Target_Flags){ typedef u32 Child_Process_Set_Target_Flags;
enum{
ChildProcessSet_FailIfBufferAlreadyAttachedToAProcess = 1, ChildProcessSet_FailIfBufferAlreadyAttachedToAProcess = 1,
ChildProcessSet_FailIfProcessAlreadyAttachedToABuffer = 2, ChildProcessSet_FailIfProcessAlreadyAttachedToABuffer = 2,
ChildProcessSet_NeverOverrideExistingAttachment = 3, ChildProcessSet_NeverOverrideExistingAttachment = 3,
ChildProcessSet_CursorAtEnd = 4, ChildProcessSet_CursorAtEnd = 4,
}; };
ENUM(u32, Memory_Protect_Flags){ typedef u32 Memory_Protect_Flags;
enum{
MemProtect_Read = 0x1, MemProtect_Read = 0x1,
MemProtect_Write = 0x2, MemProtect_Write = 0x2,
MemProtect_Execute = 0x4, MemProtect_Execute = 0x4,
}; };
ENUM(i32, Wrap_Indicator_Mode){ typedef i32 Wrap_Indicator_Mode;
enum{
WrapIndicator_Hide, WrapIndicator_Hide,
WrapIndicator_Show_After_Line, WrapIndicator_Show_After_Line,
WrapIndicator_Show_At_Wrap_Edge, WrapIndicator_Show_At_Wrap_Edge,
}; };
ENUM(i32, Global_Setting_ID){ typedef i32 Global_Setting_ID;
enum{
GlobalSetting_Null, GlobalSetting_Null,
GlobalSetting_LAltLCtrlIsAltGr, GlobalSetting_LAltLCtrlIsAltGr,
}; };
ENUM(i32, Buffer_Setting_ID){ typedef i32 Buffer_Setting_ID;
enum{
BufferSetting_Null, BufferSetting_Null,
BufferSetting_Unimportant, BufferSetting_Unimportant,
BufferSetting_ReadOnly, BufferSetting_ReadOnly,
BufferSetting_RecordsHistory, BufferSetting_RecordsHistory,
}; };
STRUCT Character_Predicate{ struct Character_Predicate{
u8 b[32]; u8 b[32];
}; };
@ -109,14 +102,16 @@ struct Frame_Info{
f32 animation_dt; f32 animation_dt;
}; };
ENUM(i32, View_Setting_ID){ typedef i32 View_Setting_ID;
enum{
ViewSetting_Null, ViewSetting_Null,
ViewSetting_ShowWhitespace, ViewSetting_ShowWhitespace,
ViewSetting_ShowScrollbar, ViewSetting_ShowScrollbar,
ViewSetting_ShowFileBar, ViewSetting_ShowFileBar,
}; };
ENUM(u32, Buffer_Create_Flag){ typedef u32 Buffer_Create_Flag;
enum{
BufferCreate_Background = 0x1, BufferCreate_Background = 0x1,
BufferCreate_AlwaysNew = 0x2, BufferCreate_AlwaysNew = 0x2,
BufferCreate_NeverNew = 0x4, BufferCreate_NeverNew = 0x4,
@ -126,24 +121,29 @@ ENUM(u32, Buffer_Create_Flag){
BufferCreate_SuppressNewFileHook = 0x40, BufferCreate_SuppressNewFileHook = 0x40,
}; };
ENUM(u32, Buffer_Save_Flag){ typedef u32 Buffer_Save_Flag;
enum{
BufferSave_IgnoreDirtyFlag = 0x1, BufferSave_IgnoreDirtyFlag = 0x1,
}; };
ENUM(u32, Buffer_Kill_Flag){ typedef u32 Buffer_Kill_Flag;
enum{
BufferKill_AlwaysKill = 0x2, BufferKill_AlwaysKill = 0x2,
}; };
ENUM(u32, Buffer_Reopen_Flag){}; typedef u32 Buffer_Reopen_Flag;
enum{};
ENUM(i32, Buffer_Kill_Result){ typedef u32 Buffer_Kill_Result;
enum{
BufferKillResult_Killed = 0, BufferKillResult_Killed = 0,
BufferKillResult_Dirty = 1, BufferKillResult_Dirty = 1,
BufferKillResult_Unkillable = 2, BufferKillResult_Unkillable = 2,
BufferKillResult_DoesNotExist = 3, BufferKillResult_DoesNotExist = 3,
}; };
ENUM(i32, Buffer_Reopen_Result){ typedef u32 Buffer_Reopen_Result;
enum{
BufferReopenResult_Reopened = 0, BufferReopenResult_Reopened = 0,
BufferReopenResult_Failed = 1, BufferReopenResult_Failed = 1,
}; };
@ -161,46 +161,52 @@ enum{
Access_ReadWriteVisible = Access_Write|Access_Read|Access_Visible, Access_ReadWriteVisible = Access_Write|Access_Read|Access_Visible,
}; };
ENUM(u32, Dirty_State){ typedef i32 Dirty_State;
enum{
DirtyState_UpToDate = 0, DirtyState_UpToDate = 0,
DirtyState_UnsavedChanges = 1, DirtyState_UnsavedChanges = 1,
DirtyState_UnloadedChanges = 2, DirtyState_UnloadedChanges = 2,
DirtyState_UnsavedChangesAndUnloadedChanges = 3, DirtyState_UnsavedChangesAndUnloadedChanges = 3,
}; };
ENUM(u32, Command_Line_Interface_Flag){ typedef u32 Command_Line_Interface_Flag;
enum{
CLI_OverlapWithConflict = 0x1, CLI_OverlapWithConflict = 0x1,
CLI_AlwaysBindToView = 0x2, CLI_AlwaysBindToView = 0x2,
CLI_CursorAtEnd = 0x4, CLI_CursorAtEnd = 0x4,
CLI_SendEndSignal = 0x8, CLI_SendEndSignal = 0x8,
}; };
ENUM(u32, Set_Buffer_Flag){ typedef u32 Set_Buffer_Flag;
enum{
SetBuffer_KeepOriginalGUI = 0x1 SetBuffer_KeepOriginalGUI = 0x1
}; };
ENUM(i32, Mouse_Cursor_Show_Type){ typedef i32 Mouse_Cursor_Show_Type;
enum{
MouseCursorShow_Never, MouseCursorShow_Never,
MouseCursorShow_Always, MouseCursorShow_Always,
}; };
ENUM(i32, View_Split_Position){ typedef i32 View_Split_Position;
enum{
ViewSplit_Top, ViewSplit_Top,
ViewSplit_Bottom, ViewSplit_Bottom,
ViewSplit_Left, ViewSplit_Left,
ViewSplit_Right, ViewSplit_Right,
}; };
ENUM(i32, Panel_Split_Kind){ typedef i32 Panel_Split_Kind;
enum{
PanelSplitKind_Ratio_Min = 0, PanelSplitKind_Ratio_Min = 0,
PanelSplitKind_Ratio_Max = 1, PanelSplitKind_Ratio_Max = 1,
PanelSplitKind_FixedPixels_Min = 2, PanelSplitKind_FixedPixels_Min = 2,
PanelSplitKind_FixedPixels_Max = 3, PanelSplitKind_FixedPixels_Max = 3,
}; };
TYPEDEF u8 Key_Modifier; typedef u8 Key_Modifier;
STRUCT Mouse_State{ struct Mouse_State{
b8 l; b8 l;
b8 r; b8 r;
b8 press_l; b8 press_l;
@ -209,8 +215,8 @@ STRUCT Mouse_State{
b8 release_r; b8 release_r;
b8 out_of_window; b8 out_of_window;
i32 wheel; i32 wheel;
UNION{ union{
STRUCT{ struct{
i32 x; i32 x;
i32 y; i32 y;
}; };
@ -218,34 +224,35 @@ STRUCT Mouse_State{
}; };
}; };
STRUCT Parser_String_And_Type{ struct Parser_String_And_Type{
char *str; char *str;
u32 length; u32 length;
u32 type; u32 type;
}; };
ENUM(u32, File_Attribute_Flag){ typedef u32 File_Attribute_Flag;
enum{
FileAttribute_IsDirectory = 1, FileAttribute_IsDirectory = 1,
}; };
STRUCT File_Attributes{ struct File_Attributes{
u64 size; u64 size;
u64 last_write_time; u64 last_write_time;
File_Attribute_Flag flags; File_Attribute_Flag flags;
}; };
STRUCT File_Info{ struct File_Info{
File_Info *next; File_Info *next;
String_Const_u8 file_name; String_Const_u8 file_name;
File_Attributes attributes; File_Attributes attributes;
}; };
STRUCT File_List{ struct File_List{
File_Info **infos; File_Info **infos;
u32 count; u32 count;
}; };
STRUCT Buffer_Identifier{ struct Buffer_Identifier{
char *name; char *name;
i32 name_len; i32 name_len;
Buffer_ID id; Buffer_ID id;
@ -267,31 +274,32 @@ struct Basic_Scroll{
Vec2_f32 target; Vec2_f32 target;
}; };
ENUM(i32, Buffer_Seek_Type){ typedef i32 Buffer_Seek_Type;
enum{
buffer_seek_pos, buffer_seek_pos,
buffer_seek_line_col, buffer_seek_line_col,
}; };
STRUCT Buffer_Seek{ struct Buffer_Seek{
Buffer_Seek_Type type; Buffer_Seek_Type type;
UNION{ union{
STRUCT{ struct{
i64 pos; i64 pos;
}; };
STRUCT{ struct{
i64 line; i64 line;
i64 col; i64 col;
}; };
}; };
}; };
STRUCT Buffer_Cursor{ struct Buffer_Cursor{
i64 pos; i64 pos;
i64 line; i64 line;
i64 col; i64 col;
}; };
STRUCT Range_Cursor{ struct Range_Cursor{
struct{ struct{
Buffer_Cursor min; Buffer_Cursor min;
Buffer_Cursor max; Buffer_Cursor max;
@ -310,14 +318,13 @@ STRUCT Range_Cursor{
}; };
}; };
STRUCT Marker{ struct Marker{
i64 pos; i64 pos;
b32 lean_right; b32 lean_right;
}; };
typedef i32 Managed_Object_Type;
ENUM(i32, Managed_Object_Type) enum{
{
ManagedObjectType_Error = 0, ManagedObjectType_Error = 0,
ManagedObjectType_Memory = 1, ManagedObjectType_Memory = 1,
ManagedObjectType_Markers = 2, ManagedObjectType_Markers = 2,
@ -326,23 +333,24 @@ ENUM(i32, Managed_Object_Type)
}; };
TYPEDEF u64 Managed_ID; typedef u64 Managed_ID;
TYPEDEF u64 Managed_Scope; typedef u64 Managed_Scope;
TYPEDEF u64 Managed_Object; typedef u64 Managed_Object;
static Managed_Scope ManagedScope_NULL = 0; static Managed_Scope ManagedScope_NULL = 0;
static Managed_Object ManagedObject_NULL = 0; static Managed_Object ManagedObject_NULL = 0;
static Managed_ID ManagedIndex_ERROR = 0; static Managed_ID ManagedIndex_ERROR = 0;
STRUCT Marker_Visual{ struct Marker_Visual{
Managed_Scope scope; Managed_Scope scope;
u32 slot_id; u32 slot_id;
u32 gen_id; u32 gen_id;
}; };
ENUM(u32, Glyph_Flag){ typedef u32 Glyph_Flag;
enum{
GlyphFlag_None = 0x0, GlyphFlag_None = 0x0,
GlyphFlag_Rotate90 = 0x1, GlyphFlag_Rotate90 = 0x1,
}; };
@ -367,12 +375,12 @@ struct Query_Bar_Group{
~Query_Bar_Group(); ~Query_Bar_Group();
}; };
STRUCT Theme_Color{ struct Theme_Color{
id_color tag; id_color tag;
argb_color color; argb_color color;
}; };
//STRUCT Theme{ //struct Theme{
//int_color colors[Stag_COUNT]; //int_color colors[Stag_COUNT];
//}; //};
@ -416,12 +424,14 @@ struct Batch_Edit{
Edit edit; Edit edit;
}; };
ENUM(i32, Record_Kind){ typedef i32 Record_Kind;
enum{
RecordKind_Single, RecordKind_Single,
RecordKind_Group, RecordKind_Group,
}; };
ENUM(i32, Record_Error){ typedef i32 Record_Error;
enum{
RecordError_NoError, RecordError_NoError,
RecordError_InvalidBuffer, RecordError_InvalidBuffer,
RecordError_NoHistoryAttached, RecordError_NoHistoryAttached,
@ -431,15 +441,16 @@ ENUM(i32, Record_Error){
RecordError_WrongRecordTypeAtIndex, RecordError_WrongRecordTypeAtIndex,
}; };
ENUM(u32, Record_Merge_Flag){ typedef u32 Record_Merge_Flag;
enum{
RecordMergeFlag_StateInRange_MoveStateForward = 0x0, RecordMergeFlag_StateInRange_MoveStateForward = 0x0,
RecordMergeFlag_StateInRange_MoveStateBackward = 0x1, RecordMergeFlag_StateInRange_MoveStateBackward = 0x1,
RecordMergeFlag_StateInRange_ErrorOut = 0x2, RecordMergeFlag_StateInRange_ErrorOut = 0x2,
}; };
TYPEDEF i32 History_Record_Index; typedef i32 History_Record_Index;
STRUCT Record_Info{ struct Record_Info{
Record_Error error; Record_Error error;
Record_Kind kind; Record_Kind kind;
i32 edit_number; i32 edit_number;
@ -455,7 +466,7 @@ STRUCT Record_Info{
}; };
}; };
TYPEDEF void Custom_Command_Function(struct Application_Links *app); typedef void Custom_Command_Function(struct Application_Links *app);
#if defined(CUSTOM_COMMAND_SIG) || defined(CUSTOM_UI_COMMAND_SIG) || defined(CUSTOM_DOC) || defined(CUSTOM_COMMAND) #if defined(CUSTOM_COMMAND_SIG) || defined(CUSTOM_UI_COMMAND_SIG) || defined(CUSTOM_DOC) || defined(CUSTOM_COMMAND)
#error Please do not define CUSTOM_COMMAND_SIG, CUSTOM_DOC, CUSTOM_UI_COMMAND_SIG, or CUSTOM_COMMAND #error Please do not define CUSTOM_COMMAND_SIG, CUSTOM_DOC, CUSTOM_UI_COMMAND_SIG, or CUSTOM_COMMAND
@ -472,7 +483,7 @@ TYPEDEF void Custom_Command_Function(struct Application_Links *app);
#endif #endif
// TODO(allen): rename // TODO(allen): rename
STRUCT User_Input{ struct User_Input{
Input_Event event; Input_Event event;
b32 abort; b32 abort;
}; };
@ -589,13 +600,14 @@ struct View_Context{
Command_Map_ID map_id; Command_Map_ID map_id;
}; };
STRUCT Color_Picker{ struct Color_Picker{
String_Const_u8 title; String_Const_u8 title;
argb_color *dest; argb_color *dest;
b32 *finished; b32 *finished;
}; };
ENUM(u32, String_Match_Flag){ typedef u32 String_Match_Flag;
enum{
StringMatch_CaseSensitive = 1, StringMatch_CaseSensitive = 1,
StringMatch_LeftSideSloppy = 2, StringMatch_LeftSideSloppy = 2,
StringMatch_RightSideSloppy = 4, StringMatch_RightSideSloppy = 4,

View File

@ -234,9 +234,9 @@ i32 line_number;
}; };
static Command_Metadata fcoder_metacmd_table[211] = { static Command_Metadata fcoder_metacmd_table[211] = {
{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 56 }, { PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 56 },
{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 196 }, { PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 204 },
{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 202 }, { PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 210 },
{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 208 }, { PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 216 },
{ PROC_LINKS(seek_beginning_of_textual_line, 0), false, "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2106 }, { PROC_LINKS(seek_beginning_of_textual_line, 0), false, "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2106 },
{ PROC_LINKS(seek_end_of_textual_line, 0), false, "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2112 }, { PROC_LINKS(seek_end_of_textual_line, 0), false, "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2112 },
{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2118 }, { PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2118 },
@ -441,7 +441,7 @@ static Command_Metadata fcoder_metacmd_table[211] = {
{ PROC_LINKS(miblo_decrement_time_stamp, 0), false, "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 237 }, { PROC_LINKS(miblo_decrement_time_stamp, 0), false, "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 237 },
{ PROC_LINKS(miblo_increment_time_stamp_minute, 0), false, "miblo_increment_time_stamp_minute", 33, "Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 243 }, { PROC_LINKS(miblo_increment_time_stamp_minute, 0), false, "miblo_increment_time_stamp_minute", 33, "Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 243 },
{ PROC_LINKS(miblo_decrement_time_stamp_minute, 0), false, "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 249 }, { PROC_LINKS(miblo_decrement_time_stamp_minute, 0), false, "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 249 },
{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "w:\\4ed\\code\\custom\\4coder_profile_inspect.cpp", 45, 408 }, { PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "w:\\4ed\\code\\custom\\4coder_profile_inspect.cpp", 45, 713 },
{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 7 }, { PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 7 },
{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 21 }, { PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 21 },
}; };