Work on profiler; cleaned up the API types file
							parent
							
								
									b807950233
								
							
						
					
					
						commit
						9f986493a1
					
				| 
						 | 
				
			
			@ -66,6 +66,8 @@ async_task_thread(void *thread_ptr){
 | 
			
		|||
    Thread_Context *tctx = &tctx_;
 | 
			
		||||
    thread_ctx_init(tctx, ThreadKind_AsyncTasks, allocator, allocator);
 | 
			
		||||
    
 | 
			
		||||
    ProfileThreadName(tctx, string_u8_litexpr("async"));
 | 
			
		||||
    
 | 
			
		||||
    Async_Thread *thread = (Async_Thread*)thread_ptr;
 | 
			
		||||
    Async_System *async_system = thread->async_system;
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1544,6 +1544,20 @@ unlerp(f32 a, f32 x, f32 b){
 | 
			
		|||
    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
 | 
			
		||||
lerp(Range_f32 range, f32 t){
 | 
			
		||||
    return(lerp(range.min, t, range.max));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1148,6 +1148,7 @@ struct Profile_Thread{
 | 
			
		|||
    Profile_Record *last_record;
 | 
			
		||||
    i32 record_count;
 | 
			
		||||
    i32 thread_id;
 | 
			
		||||
    String_Const_u8 name;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef u32 Profile_Enable_Flag;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,8 @@ custom_layer_init(Application_Links *app){
 | 
			
		|||
    setup_default_mapping(&framework_mapping);
 | 
			
		||||
    global_prof_init();
 | 
			
		||||
    async_task_handler_init(app, &global_async_system);
 | 
			
		||||
    
 | 
			
		||||
    ProfileThreadName(tctx, string_u8_litexpr("main"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,8 +56,15 @@ CUSTOM_DOC("Default command for responding to a try-exit event")
 | 
			
		|||
CUSTOM_COMMAND_SIG(default_view_input_handler)
 | 
			
		||||
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);
 | 
			
		||||
        String_Const_u8 name = push_u8_stringf(scratch, "view %d", view);
 | 
			
		||||
        ProfileThreadName(tctx, name);
 | 
			
		||||
        
 | 
			
		||||
        View_Context ctx = view_current_context(app, view);
 | 
			
		||||
        ctx.mapping = &framework_mapping;
 | 
			
		||||
        ctx.map_id = mapid_global;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,6 +104,12 @@ get_modifiers(Input_Event *event){
 | 
			
		|||
    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
 | 
			
		||||
is_unmodified_key(Input_Event *event){
 | 
			
		||||
    b32 result = false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,15 +7,6 @@
 | 
			
		|||
#if !defined(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{
 | 
			
		||||
    union{
 | 
			
		||||
        struct{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
global_prof_set_enabled(b32 value, Profile_Enable_Flag flag){
 | 
			
		||||
    Mutex_Lock lock(global_prof_mutex);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,6 +50,8 @@ profile_parse_record(Arena *arena, Profile_Inspection *insp,
 | 
			
		|||
        Profile_Node *node = push_array(arena, Profile_Node, 1);
 | 
			
		||||
        sll_queue_push(parent->first_child, parent->last_child, node);
 | 
			
		||||
        parent->child_count += 1;
 | 
			
		||||
        node->parent = parent;
 | 
			
		||||
        node->thread = parent->thread;
 | 
			
		||||
        
 | 
			
		||||
        String_Const_u8 location = record->location;
 | 
			
		||||
        String_Const_u8 name = record->name;
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +109,12 @@ profile_parse_record(Arena *arena, Profile_Inspection *insp,
 | 
			
		|||
                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){
 | 
			
		||||
            break;
 | 
			
		||||
| 
						 | 
				
			
			@ -133,14 +140,23 @@ profile_parse(Arena *arena){
 | 
			
		|||
         node != 0;
 | 
			
		||||
         node = node->next, counter += 1, insp_thread += 1){
 | 
			
		||||
        insp_thread->thread_id = node->thread_id;
 | 
			
		||||
        insp_thread->name = node->name;
 | 
			
		||||
        
 | 
			
		||||
        // NOTE(allen): This is the "negative infinity" range.
 | 
			
		||||
        // We will be "maxing" it against all the ranges durring the parse,
 | 
			
		||||
        // to get the root range.
 | 
			
		||||
        Range_u64 time_range = {max_u64, 0};
 | 
			
		||||
        insp_thread->root.thread = insp_thread;
 | 
			
		||||
        profile_parse_record(arena, &result, &insp_thread->root, node->first_record,
 | 
			
		||||
                             &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);
 | 
			
		||||
| 
						 | 
				
			
			@ -189,6 +205,183 @@ profile_draw_tab(Application_Links *app, Tab_State *state, Profile_Inspection *i
 | 
			
		|||
    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
 | 
			
		||||
profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
 | 
			
		||||
    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);
 | 
			
		||||
    
 | 
			
		||||
    Face_ID face_id = get_face_id(app, 0);
 | 
			
		||||
    // 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 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);
 | 
			
		||||
    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);
 | 
			
		||||
        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;
 | 
			
		||||
        block_zero_struct(&inspect->full_name_hovered);
 | 
			
		||||
        block_zero_struct(&inspect->location_jump_hovered);
 | 
			
		||||
        inspect->hover_thread = 0;
 | 
			
		||||
        inspect->hover_slot = 0;
 | 
			
		||||
        inspect->hover_node = 0;
 | 
			
		||||
        
 | 
			
		||||
        // NOTE(allen): tabs
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -252,8 +448,8 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
 | 
			
		|||
            
 | 
			
		||||
            if (inspect->slot_count > 0){
 | 
			
		||||
                profile_draw_tab(app, &tab_state, inspect,
 | 
			
		||||
                                 string_u8_litexpr("slots"),
 | 
			
		||||
                                 ProfileInspectTab_Slots);
 | 
			
		||||
                                 string_u8_litexpr("blocks"),
 | 
			
		||||
                                 ProfileInspectTab_Blocks);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            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"),
 | 
			
		||||
                                 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){
 | 
			
		||||
            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);
 | 
			
		||||
                f32 y_pos = tabs_body.max.y0;
 | 
			
		||||
                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->location_jump_hovered = node->location;
 | 
			
		||||
                        inspect->hover_slot = node;
 | 
			
		||||
                        margin = Stag_Margin_Hover;
 | 
			
		||||
                    }
 | 
			
		||||
                    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;
 | 
			
		||||
                }
 | 
			
		||||
            }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)){
 | 
			
		||||
| 
						 | 
				
			
			@ -374,7 +651,7 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
 | 
			
		|||
            }
 | 
			
		||||
            if (inspect->location_jump_hovered.size > 0){
 | 
			
		||||
                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));
 | 
			
		||||
                f32 l_width = get_fancy_string_advance(app, face_id, list[1].first);
 | 
			
		||||
                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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_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){
 | 
			
		||||
                    case MouseCode_Left:
 | 
			
		||||
                    {
 | 
			
		||||
                        if (insp->tab_id_hovered != ProfileInspectTab_None){
 | 
			
		||||
                            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);
 | 
			
		||||
                        }
 | 
			
		||||
                        profile_inspect__left_click(app, view, insp, &in.event);
 | 
			
		||||
                    }break;
 | 
			
		||||
                }
 | 
			
		||||
            }break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,19 +7,29 @@
 | 
			
		|||
#if !defined(FCODER_PROFILE_INSPECT_H)
 | 
			
		||||
#define FCODER_PROFILE_INSPECT_H
 | 
			
		||||
 | 
			
		||||
struct Profile_Node_Ptr{
 | 
			
		||||
    Profile_Node_Ptr *next;
 | 
			
		||||
    struct Profile_Node *ptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Profile_Slot{
 | 
			
		||||
    Profile_Slot *next;
 | 
			
		||||
    String_Const_u8 location;
 | 
			
		||||
    String_Const_u8 name;
 | 
			
		||||
    
 | 
			
		||||
    b32 corrupted_time;
 | 
			
		||||
    u64 total_time;
 | 
			
		||||
    b32 corrupted_time;
 | 
			
		||||
    
 | 
			
		||||
    i32 hit_count;
 | 
			
		||||
    Profile_Node_Ptr *first_hit;
 | 
			
		||||
    Profile_Node_Ptr *last_hit;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Profile_Node{
 | 
			
		||||
    Profile_Node *next;
 | 
			
		||||
    Profile_Node *parent;
 | 
			
		||||
    Profile_Slot *slot;
 | 
			
		||||
    struct Profile_Inspection_Thread *thread;
 | 
			
		||||
    Range_u64 time;
 | 
			
		||||
    Profile_ID id;
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +42,9 @@ struct Profile_Node{
 | 
			
		|||
 | 
			
		||||
struct Profile_Inspection_Thread{
 | 
			
		||||
    i32 thread_id;
 | 
			
		||||
    String_Const_u8 name;
 | 
			
		||||
    Profile_Node root;
 | 
			
		||||
    u64 active_time;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Profile_Error{
 | 
			
		||||
| 
						 | 
				
			
			@ -45,8 +57,9 @@ typedef i32 Profile_Inspection_Tab;
 | 
			
		|||
enum{
 | 
			
		||||
    ProfileInspectTab_None,
 | 
			
		||||
    ProfileInspectTab_Threads,
 | 
			
		||||
    ProfileInspectTab_Slots,
 | 
			
		||||
    ProfileInspectTab_Errors
 | 
			
		||||
    ProfileInspectTab_Blocks,
 | 
			
		||||
    ProfileInspectTab_Errors,
 | 
			
		||||
    ProfileInspectTab_Selection,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Profile_Inspection{
 | 
			
		||||
| 
						 | 
				
			
			@ -60,10 +73,16 @@ struct Profile_Inspection{
 | 
			
		|||
    i32 error_count;
 | 
			
		||||
    
 | 
			
		||||
    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 location_jump_hovered;
 | 
			
		||||
    Profile_Inspection_Thread *hover_thread;
 | 
			
		||||
    Profile_Slot *hover_slot;
 | 
			
		||||
    Profile_Node *hover_node;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
global Profile_Inspection global_profile_inspection = {};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,18 +1,6 @@
 | 
			
		|||
#if !defined(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{
 | 
			
		||||
    void *coroutine;
 | 
			
		||||
    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;
 | 
			
		||||
enum{
 | 
			
		||||
| 
						 | 
				
			
			@ -53,53 +41,58 @@ enum{
 | 
			
		|||
    UIHighlight_Active,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Buffer_Point{
 | 
			
		||||
struct Buffer_Point{
 | 
			
		||||
    i64 line_number;
 | 
			
		||||
    Vec2 pixel_shift;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Line_Shift_Vertical{
 | 
			
		||||
struct Line_Shift_Vertical{
 | 
			
		||||
    i64 line;
 | 
			
		||||
    f32 y_delta;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Line_Shift_Character{
 | 
			
		||||
struct Line_Shift_Character{
 | 
			
		||||
    i64 line;
 | 
			
		||||
    i64 character_delta;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, Child_Process_Set_Target_Flags){
 | 
			
		||||
typedef u32 Child_Process_Set_Target_Flags;
 | 
			
		||||
enum{
 | 
			
		||||
    ChildProcessSet_FailIfBufferAlreadyAttachedToAProcess = 1,
 | 
			
		||||
    ChildProcessSet_FailIfProcessAlreadyAttachedToABuffer = 2,
 | 
			
		||||
    ChildProcessSet_NeverOverrideExistingAttachment = 3,
 | 
			
		||||
    ChildProcessSet_CursorAtEnd = 4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, Memory_Protect_Flags){
 | 
			
		||||
typedef u32 Memory_Protect_Flags;
 | 
			
		||||
enum{
 | 
			
		||||
    MemProtect_Read    = 0x1,
 | 
			
		||||
    MemProtect_Write   = 0x2,
 | 
			
		||||
    MemProtect_Execute = 0x4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(i32, Wrap_Indicator_Mode){
 | 
			
		||||
typedef i32 Wrap_Indicator_Mode;
 | 
			
		||||
enum{
 | 
			
		||||
    WrapIndicator_Hide,
 | 
			
		||||
    WrapIndicator_Show_After_Line,
 | 
			
		||||
    WrapIndicator_Show_At_Wrap_Edge,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(i32, Global_Setting_ID){
 | 
			
		||||
typedef i32 Global_Setting_ID;
 | 
			
		||||
enum{
 | 
			
		||||
    GlobalSetting_Null,
 | 
			
		||||
    GlobalSetting_LAltLCtrlIsAltGr,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(i32, Buffer_Setting_ID){
 | 
			
		||||
typedef i32 Buffer_Setting_ID;
 | 
			
		||||
enum{
 | 
			
		||||
    BufferSetting_Null,
 | 
			
		||||
    BufferSetting_Unimportant,
 | 
			
		||||
    BufferSetting_ReadOnly,
 | 
			
		||||
    BufferSetting_RecordsHistory,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Character_Predicate{
 | 
			
		||||
struct Character_Predicate{
 | 
			
		||||
    u8 b[32];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -109,14 +102,16 @@ struct Frame_Info{
 | 
			
		|||
    f32 animation_dt;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(i32, View_Setting_ID){
 | 
			
		||||
typedef i32 View_Setting_ID;
 | 
			
		||||
enum{
 | 
			
		||||
    ViewSetting_Null,
 | 
			
		||||
    ViewSetting_ShowWhitespace,
 | 
			
		||||
    ViewSetting_ShowScrollbar,
 | 
			
		||||
    ViewSetting_ShowFileBar,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, Buffer_Create_Flag){
 | 
			
		||||
typedef u32 Buffer_Create_Flag;
 | 
			
		||||
enum{
 | 
			
		||||
    BufferCreate_Background = 0x1,
 | 
			
		||||
    BufferCreate_AlwaysNew  = 0x2,
 | 
			
		||||
    BufferCreate_NeverNew   = 0x4,
 | 
			
		||||
| 
						 | 
				
			
			@ -126,24 +121,29 @@ ENUM(u32, Buffer_Create_Flag){
 | 
			
		|||
    BufferCreate_SuppressNewFileHook = 0x40,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, Buffer_Save_Flag){
 | 
			
		||||
typedef u32 Buffer_Save_Flag;
 | 
			
		||||
enum{
 | 
			
		||||
    BufferSave_IgnoreDirtyFlag = 0x1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, Buffer_Kill_Flag){
 | 
			
		||||
typedef u32 Buffer_Kill_Flag;
 | 
			
		||||
enum{
 | 
			
		||||
    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_Dirty = 1,
 | 
			
		||||
    BufferKillResult_Unkillable = 2,
 | 
			
		||||
    BufferKillResult_DoesNotExist = 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(i32, Buffer_Reopen_Result){
 | 
			
		||||
typedef u32 Buffer_Reopen_Result;
 | 
			
		||||
enum{
 | 
			
		||||
    BufferReopenResult_Reopened = 0,
 | 
			
		||||
    BufferReopenResult_Failed = 1,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -161,46 +161,52 @@ enum{
 | 
			
		|||
    Access_ReadWriteVisible = Access_Write|Access_Read|Access_Visible,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, Dirty_State){
 | 
			
		||||
typedef i32 Dirty_State;
 | 
			
		||||
enum{
 | 
			
		||||
    DirtyState_UpToDate = 0,
 | 
			
		||||
    DirtyState_UnsavedChanges = 1,
 | 
			
		||||
    DirtyState_UnloadedChanges = 2,
 | 
			
		||||
    DirtyState_UnsavedChangesAndUnloadedChanges = 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, Command_Line_Interface_Flag){
 | 
			
		||||
typedef u32 Command_Line_Interface_Flag;
 | 
			
		||||
enum{
 | 
			
		||||
    CLI_OverlapWithConflict = 0x1,
 | 
			
		||||
    CLI_AlwaysBindToView    = 0x2,
 | 
			
		||||
    CLI_CursorAtEnd         = 0x4,
 | 
			
		||||
    CLI_SendEndSignal       = 0x8,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, Set_Buffer_Flag){
 | 
			
		||||
typedef u32 Set_Buffer_Flag;
 | 
			
		||||
enum{
 | 
			
		||||
    SetBuffer_KeepOriginalGUI = 0x1
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(i32, Mouse_Cursor_Show_Type){
 | 
			
		||||
typedef i32 Mouse_Cursor_Show_Type;
 | 
			
		||||
enum{
 | 
			
		||||
    MouseCursorShow_Never,
 | 
			
		||||
    MouseCursorShow_Always,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(i32, View_Split_Position){
 | 
			
		||||
typedef i32 View_Split_Position;
 | 
			
		||||
enum{
 | 
			
		||||
    ViewSplit_Top,
 | 
			
		||||
    ViewSplit_Bottom,
 | 
			
		||||
    ViewSplit_Left,
 | 
			
		||||
    ViewSplit_Right,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(i32, Panel_Split_Kind){
 | 
			
		||||
typedef i32 Panel_Split_Kind;
 | 
			
		||||
enum{
 | 
			
		||||
    PanelSplitKind_Ratio_Min = 0,
 | 
			
		||||
    PanelSplitKind_Ratio_Max = 1,
 | 
			
		||||
    PanelSplitKind_FixedPixels_Min = 2,
 | 
			
		||||
    PanelSplitKind_FixedPixels_Max = 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
TYPEDEF u8 Key_Modifier;
 | 
			
		||||
typedef u8 Key_Modifier;
 | 
			
		||||
 | 
			
		||||
STRUCT Mouse_State{
 | 
			
		||||
struct Mouse_State{
 | 
			
		||||
    b8 l;
 | 
			
		||||
    b8 r;
 | 
			
		||||
    b8 press_l;
 | 
			
		||||
| 
						 | 
				
			
			@ -209,8 +215,8 @@ STRUCT Mouse_State{
 | 
			
		|||
    b8 release_r;
 | 
			
		||||
    b8 out_of_window;
 | 
			
		||||
    i32 wheel;
 | 
			
		||||
    UNION{
 | 
			
		||||
        STRUCT{
 | 
			
		||||
    union{
 | 
			
		||||
        struct{
 | 
			
		||||
            i32 x;
 | 
			
		||||
            i32 y;
 | 
			
		||||
        };
 | 
			
		||||
| 
						 | 
				
			
			@ -218,34 +224,35 @@ STRUCT Mouse_State{
 | 
			
		|||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Parser_String_And_Type{
 | 
			
		||||
struct Parser_String_And_Type{
 | 
			
		||||
    char *str;
 | 
			
		||||
    u32 length;
 | 
			
		||||
    u32 type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, File_Attribute_Flag){
 | 
			
		||||
typedef u32 File_Attribute_Flag;
 | 
			
		||||
enum{
 | 
			
		||||
    FileAttribute_IsDirectory = 1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT File_Attributes{
 | 
			
		||||
struct File_Attributes{
 | 
			
		||||
    u64 size;
 | 
			
		||||
    u64 last_write_time;
 | 
			
		||||
    File_Attribute_Flag flags;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT File_Info{
 | 
			
		||||
struct File_Info{
 | 
			
		||||
    File_Info *next;
 | 
			
		||||
    String_Const_u8 file_name;
 | 
			
		||||
    File_Attributes attributes;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT File_List{
 | 
			
		||||
struct File_List{
 | 
			
		||||
    File_Info **infos;
 | 
			
		||||
    u32 count;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Buffer_Identifier{
 | 
			
		||||
struct Buffer_Identifier{
 | 
			
		||||
    char *name;
 | 
			
		||||
    i32 name_len;
 | 
			
		||||
    Buffer_ID id;
 | 
			
		||||
| 
						 | 
				
			
			@ -267,31 +274,32 @@ struct Basic_Scroll{
 | 
			
		|||
    Vec2_f32 target;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(i32, Buffer_Seek_Type){
 | 
			
		||||
typedef i32 Buffer_Seek_Type;
 | 
			
		||||
enum{
 | 
			
		||||
    buffer_seek_pos,
 | 
			
		||||
    buffer_seek_line_col,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Buffer_Seek{
 | 
			
		||||
struct Buffer_Seek{
 | 
			
		||||
    Buffer_Seek_Type type;
 | 
			
		||||
    UNION{
 | 
			
		||||
        STRUCT{
 | 
			
		||||
    union{
 | 
			
		||||
        struct{
 | 
			
		||||
            i64 pos;
 | 
			
		||||
        };
 | 
			
		||||
        STRUCT{
 | 
			
		||||
        struct{
 | 
			
		||||
            i64 line;
 | 
			
		||||
            i64 col;
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Buffer_Cursor{
 | 
			
		||||
struct Buffer_Cursor{
 | 
			
		||||
    i64 pos;
 | 
			
		||||
    i64 line;
 | 
			
		||||
    i64 col;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Range_Cursor{
 | 
			
		||||
struct Range_Cursor{
 | 
			
		||||
    struct{
 | 
			
		||||
        Buffer_Cursor min;
 | 
			
		||||
        Buffer_Cursor max;
 | 
			
		||||
| 
						 | 
				
			
			@ -310,14 +318,13 @@ STRUCT Range_Cursor{
 | 
			
		|||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Marker{
 | 
			
		||||
struct Marker{
 | 
			
		||||
    i64 pos;
 | 
			
		||||
    b32 lean_right;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ENUM(i32, Managed_Object_Type)
 | 
			
		||||
{
 | 
			
		||||
typedef i32 Managed_Object_Type;
 | 
			
		||||
enum{
 | 
			
		||||
    ManagedObjectType_Error = 0,
 | 
			
		||||
    ManagedObjectType_Memory = 1,
 | 
			
		||||
    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_Object;
 | 
			
		||||
typedef u64 Managed_Scope;
 | 
			
		||||
typedef u64 Managed_Object;
 | 
			
		||||
 | 
			
		||||
static Managed_Scope ManagedScope_NULL = 0;
 | 
			
		||||
static Managed_Object ManagedObject_NULL = 0;
 | 
			
		||||
 | 
			
		||||
static Managed_ID ManagedIndex_ERROR = 0;
 | 
			
		||||
 | 
			
		||||
STRUCT Marker_Visual{
 | 
			
		||||
struct Marker_Visual{
 | 
			
		||||
    Managed_Scope scope;
 | 
			
		||||
    u32 slot_id;
 | 
			
		||||
    u32 gen_id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, Glyph_Flag){
 | 
			
		||||
typedef u32 Glyph_Flag;
 | 
			
		||||
enum{
 | 
			
		||||
    GlyphFlag_None = 0x0,
 | 
			
		||||
    GlyphFlag_Rotate90 = 0x1,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -367,12 +375,12 @@ struct Query_Bar_Group{
 | 
			
		|||
    ~Query_Bar_Group();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Theme_Color{
 | 
			
		||||
struct Theme_Color{
 | 
			
		||||
    id_color tag;
 | 
			
		||||
    argb_color color;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//STRUCT Theme{
 | 
			
		||||
//struct Theme{
 | 
			
		||||
//int_color colors[Stag_COUNT];
 | 
			
		||||
//};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -416,12 +424,14 @@ struct Batch_Edit{
 | 
			
		|||
    Edit edit;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(i32, Record_Kind){
 | 
			
		||||
typedef i32 Record_Kind;
 | 
			
		||||
enum{
 | 
			
		||||
    RecordKind_Single,
 | 
			
		||||
    RecordKind_Group,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(i32, Record_Error){
 | 
			
		||||
typedef i32 Record_Error;
 | 
			
		||||
enum{
 | 
			
		||||
    RecordError_NoError,
 | 
			
		||||
    RecordError_InvalidBuffer,
 | 
			
		||||
    RecordError_NoHistoryAttached,
 | 
			
		||||
| 
						 | 
				
			
			@ -431,15 +441,16 @@ ENUM(i32, Record_Error){
 | 
			
		|||
    RecordError_WrongRecordTypeAtIndex,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, Record_Merge_Flag){
 | 
			
		||||
typedef u32 Record_Merge_Flag;
 | 
			
		||||
enum{
 | 
			
		||||
    RecordMergeFlag_StateInRange_MoveStateForward = 0x0,
 | 
			
		||||
    RecordMergeFlag_StateInRange_MoveStateBackward = 0x1,
 | 
			
		||||
    RecordMergeFlag_StateInRange_ErrorOut = 0x2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
TYPEDEF i32 History_Record_Index;
 | 
			
		||||
typedef i32 History_Record_Index;
 | 
			
		||||
 | 
			
		||||
STRUCT Record_Info{
 | 
			
		||||
struct Record_Info{
 | 
			
		||||
    Record_Error error;
 | 
			
		||||
    Record_Kind kind;
 | 
			
		||||
    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)
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
// TODO(allen): rename
 | 
			
		||||
STRUCT User_Input{
 | 
			
		||||
struct User_Input{
 | 
			
		||||
    Input_Event event;
 | 
			
		||||
    b32 abort;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -589,13 +600,14 @@ struct View_Context{
 | 
			
		|||
    Command_Map_ID map_id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STRUCT Color_Picker{
 | 
			
		||||
struct Color_Picker{
 | 
			
		||||
    String_Const_u8 title;
 | 
			
		||||
    argb_color *dest;
 | 
			
		||||
    b32 *finished;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ENUM(u32, String_Match_Flag){
 | 
			
		||||
typedef u32 String_Match_Flag;
 | 
			
		||||
enum{
 | 
			
		||||
    StringMatch_CaseSensitive = 1,
 | 
			
		||||
    StringMatch_LeftSideSloppy = 2,
 | 
			
		||||
    StringMatch_RightSideSloppy = 4,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -234,9 +234,9 @@ i32 line_number;
 | 
			
		|||
};
 | 
			
		||||
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(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_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_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_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, 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, 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_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 },
 | 
			
		||||
| 
						 | 
				
			
			@ -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_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(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_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 },
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue