From be67657aed14bf5ecf7334499657c2054db1514a Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 2 Mar 2016 11:18:10 -0500 Subject: [PATCH] double-LL allocation for panels --- 4ed.cpp | 567 ++++++++++++++++++++------------------------- 4ed_app_target.cpp | 1 + 4ed_file_view.cpp | 58 +---- 4ed_layout.cpp | 412 ++++++++++++++++---------------- 4ed_template.cpp | 41 ++++ 5 files changed, 502 insertions(+), 577 deletions(-) create mode 100644 4ed_template.cpp diff --git a/4ed.cpp b/4ed.cpp index fa861119..dd7ad514 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -244,27 +244,22 @@ panel_make_empty(System_Functions *system, Exchange *exchange, App_Vars *vars, Style *style, Panel *panel){ Mem_Options *mem = &vars->mem; - Live_Views *live_set = &vars->live_set; Editing_Layout *layout = &vars->layout; Working_Set *working_set = &vars->working_set; - - // TODO(allen): vars->delay pointer for directing all delayed actions to appropriate place Delay *delay = &vars->delay1; - View *new_view; File_View *file_view; - - new_view = live_set_alloc_view(live_set, mem); - if (panel->view){ - view_replace_major(system, exchange, new_view, panel, live_set); - } - else{ - view_set_first(new_view, panel); - } - file_view = file_view_init(new_view, layout, working_set, delay, + View_And_ID new_view; + + Assert(panel->view == 0); + new_view = live_set_alloc_view(&vars->live_set, mem); + panel->view = new_view.view; + panel->view->panel = panel; + + file_view = file_view_init(panel->view, layout, working_set, delay, &vars->settings, &vars->hot_directory, mem, &vars->styles); view_set_file(file_view, 0, vars->font_set, style, 0, 0, 0); - new_view->map = app_get_map(vars, mapid_global); + panel->view->map = app_get_map(vars, mapid_global); return(file_view); } @@ -699,12 +694,10 @@ COMMAND_DECL(paste){ USE_LAYOUT(layout); USE_MEM(mem); - Panel *current_panel; + Panel *panel, *used_panels; String *src; File_View *current_view; i32 pos_left, next_cursor_pos; - i32 panel_count; - i32 i; if (working_set->clipboard_size > 0){ view->next_mode.rewrite = 1; @@ -718,12 +711,11 @@ COMMAND_DECL(paste){ view_cursor_move(view, next_cursor_pos); view->mark = pos_left; - current_panel = layout->panels; - panel_count = layout->panel_count; - for (i = 0; i < panel_count; ++i, ++current_panel){ - current_view = view_to_file_view(current_panel->view); - - if (current_view && current_view->file == file){ + used_panels = &layout->used_sentinel; + for (dll_items(panel, used_panels)){ + current_view = view_to_file_view(panel->view); + + if (current_view->file == file){ view_post_paste_effect(current_view, 20, pos_left, src->size, current_view->style->main.paste_color); } @@ -738,6 +730,8 @@ COMMAND_DECL(paste_next){ USE_WORKING_SET(working_set); USE_LAYOUT(layout); USE_MEM(mem); + + Panel *panel, *used_panels; if (working_set->clipboard_size > 0 && view->mode.rewrite == 1){ view->next_mode.rewrite = 1; @@ -751,15 +745,12 @@ COMMAND_DECL(paste_next){ view_cursor_move(view, next_cursor_pos); view->mark = range.start; + + used_panels = &layout->used_sentinel; + for (dll_items(panel, used_panels)){ + File_View *current_view = view_to_file_view(panel->view); - Editing_Layout *layout = command->layout; - Panel *panels = layout->panels; - i32 panel_count = layout->panel_count; - for (i32 i = 0; i < panel_count; ++i){ - Panel *current_panel = panels + i; - File_View *current_view = view_to_file_view(current_panel->view); - - if (current_view && current_view->file == file){ + if (current_view->file == file){ view_post_paste_effect(current_view, 20, range.start, src->size, current_view->style->main.paste_color); } @@ -852,14 +843,7 @@ COMMAND_DECL(interactive_new){ ProfileMomentFunction(); USE_FILE_VIEW(fview); USE_VARS(vars); - USE_PANEL(panel); - USE_STYLE(style); - USE_EXCHANGE(exchange); - - if (!fview){ - fview = panel_make_empty(system, exchange, vars, style, panel); - } - + view_show_interactive(system, fview, &vars->map_ui, IAct_New, IInt_Sys_File_List, make_lit_string("New: ")); } @@ -916,9 +900,7 @@ COMMAND_DECL(interactive_open){ ProfileMomentFunction(); USE_VARS(vars); USE_PANEL(panel); - USE_STYLE(style); USE_DELAY(delay); - USE_EXCHANGE(exchange); char *filename = 0; int filename_len = 0; @@ -954,10 +936,6 @@ COMMAND_DECL(interactive_open){ File_View *fview = view_to_file_view(view); - if (!fview){ - fview = panel_make_empty(system, exchange, vars, style, panel); - } - view_show_interactive(system, fview, &vars->map_ui, IAct_Open, IInt_Sys_File_List, make_lit_string("Open: ")); } @@ -965,9 +943,7 @@ COMMAND_DECL(interactive_open){ internal void view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){ - Live_Views *live_set = cmd->live_set; Mem_Options *mem = cmd->mem; - Exchange *exchange = cmd->exchange; System_Functions *system = cmd->system; Editing_Layout *layout = cmd->layout; App_Vars *vars = cmd->vars; @@ -977,17 +953,14 @@ view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){ Partition old_part; Temp_Memory temp; - View *new_view, *old_view; + View *old_view; File_View *file_view; - - new_view = live_set_alloc_view(live_set, mem); - view_replace_major(system, exchange, new_view, panel, live_set); - file_view = file_view_init(new_view, layout, working_set, delay, + file_view = file_view_init(panel->view, layout, working_set, delay, &vars->settings, &vars->hot_directory, mem, &vars->styles); old_view = cmd->view; - cmd->view = new_view; + cmd->view = panel->view; old_part = cmd->part; temp = begin_temp_memory(&mem->part); @@ -1000,7 +973,7 @@ view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){ end_temp_memory(temp); cmd->view = old_view; - new_view->map = app_get_map(vars, file->settings.base_map_id); + panel->view->map = app_get_map(vars, file->settings.base_map_id); } // TODO(allen): Improvements to reopen @@ -1086,14 +1059,7 @@ COMMAND_DECL(interactive_save_as){ ProfileMomentFunction(); USE_FILE_VIEW(fview); USE_VARS(vars); - USE_PANEL(panel); - USE_STYLE(style); - USE_EXCHANGE(exchange); - - if (!fview){ - fview = panel_make_empty(system, exchange, vars, style, panel); - } - + view_show_interactive(system, fview, &vars->map_ui, IAct_Save_As, IInt_Sys_File_List, make_lit_string("Save As: ")); } @@ -1101,25 +1067,19 @@ COMMAND_DECL(interactive_save_as){ COMMAND_DECL(change_active_panel){ ProfileMomentFunction(); USE_LAYOUT(layout); - if (layout->panel_count > 1){ - ++layout->active_panel; - if (layout->active_panel >= layout->panel_count){ - layout->active_panel = 0; - } + USE_PANEL(panel); + + panel = panel->next; + if (panel == &layout->used_sentinel){ + panel = panel->next; } + layout->active_panel = (i32)(panel - layout->panels); } COMMAND_DECL(interactive_switch_buffer){ ProfileMomentFunction(); USE_FILE_VIEW(fview); USE_VARS(vars); - USE_PANEL(panel); - USE_STYLE(style); - USE_EXCHANGE(exchange); - - if (!fview){ - fview = panel_make_empty(system, exchange, vars, style, panel); - } view_show_interactive(system, fview, &vars->map_ui, IAct_Switch, IInt_Live_File_List, make_lit_string("Switch Buffer: ")); @@ -1129,13 +1089,6 @@ COMMAND_DECL(interactive_kill_buffer){ ProfileMomentFunction(); USE_FILE_VIEW(fview); USE_VARS(vars); - USE_PANEL(panel); - USE_STYLE(style); - USE_EXCHANGE(exchange); - - if (!fview){ - fview = panel_make_empty(system, exchange, vars, style, panel); - } view_show_interactive(system, fview, &vars->map_ui, IAct_Kill, IInt_Live_File_List, make_lit_string("Kill Buffer: ")); @@ -1360,20 +1313,20 @@ COMMAND_DECL(open_panel_vsplit){ if (layout->panel_count < layout->panel_max_count){ Split_Result split = layout_split_panel(layout, panel, 1); - + Panel *panel1 = panel; Panel *panel2 = split.panel; - + panel2->screen_region = panel1->screen_region; - + panel2->full.x0 = split.divider->pos; panel2->full.x1 = panel1->full.x1; panel1->full.x1 = split.divider->pos; - + panel_fix_internal_area(panel1); panel_fix_internal_area(panel2); panel2->prev_inner = panel2->inner; - + layout->active_panel = (i32)(panel2 - layout->panels); panel_make_empty(system, exchange, vars, style, panel2); } @@ -1386,23 +1339,23 @@ COMMAND_DECL(open_panel_hsplit){ USE_EXCHANGE(exchange); USE_VARS(vars); USE_STYLE(style); - + if (layout->panel_count < layout->panel_max_count){ Split_Result split = layout_split_panel(layout, panel, 0); - + Panel *panel1 = panel; Panel *panel2 = split.panel; - + panel2->screen_region = panel1->screen_region; - + panel2->full.y0 = split.divider->pos; panel2->full.y1 = panel1->full.y1; panel1->full.y1 = split.divider->pos; - + panel_fix_internal_area(panel1); panel_fix_internal_area(panel2); panel2->prev_inner = panel2->inner; - + layout->active_panel = (i32)(panel2 - layout->panels); panel_make_empty(system, exchange, vars, style, panel2); } @@ -1414,67 +1367,77 @@ COMMAND_DECL(close_panel){ USE_PANEL(panel); USE_VIEW(view); USE_EXCHANGE(exchange); - + + Panel *panel_ptr, *used_panels; + Divider_And_ID div, parent_div, child_div; + i32 child; + i32 parent; + i32 which_child; + i32 active; + if (layout->panel_count > 1){ - if (view){ - live_set_free_view(system, exchange, command->live_set, view); - panel->view = 0; - } - - Divider_And_ID div = layout_get_divider(layout, panel->parent); + live_set_free_view(system, exchange, command->live_set, view); + panel->view = 0; + + div = layout_get_divider(layout, panel->parent); + + // This divider cannot have two child dividers. Assert(div.divider->child1 == -1 || div.divider->child2 == -1); - - i32 child; - if (div.divider->child1 == -1){ - child = div.divider->child2; - } - else{ - child = div.divider->child1; - } - - i32 parent = div.divider->parent; - i32 which_child = div.divider->which_child; - if (parent != -1){ - Divider_And_ID par = layout_get_divider(layout, parent); - if (which_child == -1){ - par.divider->child1 = child; - } - else{ - par.divider->child2 = child; - } - } - else{ + + // Get the child who needs to fill in this node's spot + child = div.divider->child1; + if (child == -1) child = div.divider->child2; + + parent = div.divider->parent; + which_child = div.divider->which_child; + + // Fill the child in the slot this node use to hold + if (parent == -1){ Assert(layout->root == div.id); layout->root = child; } - - if (child != -1){ - Divider_And_ID chi = layout_get_divider(layout, child); - chi.divider->parent = parent; - chi.divider->which_child = div.divider->which_child; + else{ + parent_div = layout_get_divider(layout, parent); + if (which_child == -1){ + parent_div.divider->child1 = child; + } + else{ + parent_div.divider->child2 = child; + } } - - layout_free_divider(layout, div.divider); - layout_free_panel(layout, panel); - + + // If there was a child divider, give it information about it's new parent. + if (child != -1){ + child_div = layout_get_divider(layout, child); + child_div.divider->parent = parent; + child_div.divider->which_child = div.divider->which_child; + } + + // What is the new active panel? + active = -1; if (child == -1){ - panel = layout->panels; - layout->active_panel = -1; - for (i32 i = 0; i < layout->panel_count; ++i){ - if (panel->parent == div.id){ - panel->parent = parent; - panel->which_child = which_child; - layout->active_panel = i; + used_panels = &layout->used_sentinel; + for (dll_items(panel_ptr, used_panels)){ + if (panel_ptr != panel && panel_ptr->parent == div.id){ + panel_ptr->parent = parent; + panel_ptr->which_child = which_child; + active = (i32)(panel_ptr - layout->panels); break; } - ++panel; } - Assert(layout->active_panel != -1); } else{ - layout->active_panel = layout->active_panel % layout->panel_count; + panel_ptr = panel->next; + if (panel_ptr == &layout->used_sentinel) panel_ptr = panel_ptr->next; + Assert(panel_ptr != panel); + active = (i32)(panel_ptr - layout->panels); } - + + Assert(active != -1 && panel != layout->panels + active); + layout->active_panel = active; + + layout_free_divider(layout, div.divider); + layout_free_panel(layout, panel); layout_fix_all_panels(layout); } } @@ -1619,40 +1582,9 @@ COMMAND_DECL(page_up){ } COMMAND_DECL(open_color_tweaker){ -#if 0 - ProfileMomentFunction(); - USE_VARS(vars); - USE_LIVE_SET(live_set); - USE_MEM(mem); - USE_PANEL(panel); - USE_EXCHANGE(exchange); - - { - View *new_view = live_set_alloc_view(live_set, mem); - view_replace_minor(system, exchange, new_view, panel, live_set); - - new_view->map = &vars->map_ui; - - Color_View *color_view = color_view_init(new_view, &vars->working_set); - color_view->hot_directory = &vars->hot_directory; - color_view->main_style = &vars->style; - color_view->styles = &vars->styles; - color_view->palette = vars->palette; - color_view->palette_size = vars->palette_size; - color_view->font_set = vars->font_set; - } -#endif - ProfileMomentFunction(); USE_FILE_VIEW(fview); USE_VARS(vars); - USE_PANEL(panel); - USE_STYLE(style); - USE_EXCHANGE(exchange); - - if (!fview){ - fview = panel_make_empty(system, exchange, vars, style, panel); - } view_show_theme(fview, &vars->map_ui); } @@ -1661,13 +1593,6 @@ COMMAND_DECL(open_config){ ProfileMomentFunction(); USE_FILE_VIEW(fview); USE_VARS(vars); - USE_PANEL(panel); - USE_STYLE(style); - USE_EXCHANGE(exchange); - - if (!fview){ - fview = panel_make_empty(system, exchange, vars, style, panel); - } view_show_config(fview, &vars->map_ui); } @@ -1676,13 +1601,6 @@ COMMAND_DECL(open_menu){ ProfileMomentFunction(); USE_FILE_VIEW(fview); USE_VARS(vars); - USE_PANEL(panel); - USE_STYLE(style); - USE_EXCHANGE(exchange); - - if (!fview){ - fview = panel_make_empty(system, exchange, vars, style, panel); - } view_show_menu(fview, &vars->map_ui); } @@ -3036,61 +2954,63 @@ App_Init_Sig(app_init){ Partition *partition = &vars->mem.part; target->partition = partition; - Panel *panels; + Panel *panels, *panel; Panel_Divider *dividers, *div; i32 panel_max_count; i32 divider_max_count; - panel_max_count = vars->layout.panel_max_count = 16; - divider_max_count = panel_max_count - 1; - vars->layout.panel_count = 1; - - panels = push_array(partition, Panel, panel_max_count); - vars->layout.panels = panels; - - dividers = push_array(partition, Panel_Divider, divider_max_count); - vars->layout.dividers = dividers; - - div = dividers; - for (i32 i = 0; i < divider_max_count-1; ++i, ++div){ - div->next = (div + 1); + { + i32 i; + + panel_max_count = vars->layout.panel_max_count = 16; + divider_max_count = panel_max_count - 1; + vars->layout.panel_count = 0; + + panels = push_array(partition, Panel, panel_max_count); + vars->layout.panels = panels; + + dll_init_sentinel(&vars->layout.free_sentinel); + dll_init_sentinel(&vars->layout.used_sentinel); + + panel = panels; + for (i = 0; i < panel_max_count; ++i, ++panel){ + dll_insert(&vars->layout.free_sentinel, panel); + } + + dividers = push_array(partition, Panel_Divider, divider_max_count); + vars->layout.dividers = dividers; + + div = dividers; + for (i = 0; i < divider_max_count-1; ++i, ++div){ + div->next = (div + 1); + } + div->next = 0; + vars->layout.free_divider = dividers; } - div->next = 0; - vars->layout.free_divider = dividers; - i32 view_chunk_size = 0; - i32 view_sizes[] = { - sizeof(File_View) - }; - { char *vptr = 0; - View *v = 0, *n = 0; - i32 i = 0, max = 0; + View *v = 0; + i32 i = 0; + i32 max = 0; + i32 view_size = sizeof(File_View); vars->live_set.count = 0; vars->live_set.max = panel_max_count; - - for (i = 0; i < ArrayCount(view_sizes); ++i){ - view_chunk_size = Max(view_chunk_size, view_sizes[i]); - } - vars->live_set.stride = view_chunk_size; - vars->live_set.views = push_block(partition, view_chunk_size*vars->live_set.max); + + vars->live_set.stride = view_size; + vars->live_set.views = push_block(partition, view_size*vars->live_set.max); + + dll_init_sentinel(&vars->live_set.free_sentinel); max = vars->live_set.max; vptr = (char*)vars->live_set.views; - vars->live_set.free_view = (View*)vptr; - for (i = 0; i < max; ++i){ + for (i = 0; i < max; ++i, vptr += view_size){ v = (View*)(vptr); - n = (View*)(vptr + view_chunk_size); - v->next_free = n; - vptr = (char*)n; + dll_insert(&vars->live_set.free_sentinel, v); } - v->next_free = 0; } - - - + setup_command_table(); Command_Map *global = &vars->map_top; @@ -3302,16 +3222,17 @@ App_Init_Sig(app_init){ vars->palette_size = 40; vars->palette = push_array(partition, u32, vars->palette_size); - + // NOTE(allen): init first panel - panel_init(&panels[0]); - panel_make_empty(system, exchange, vars, &vars->style, &panels[0]); - + Panel_And_ID p = layout_alloc_panel(&vars->layout); + panel_make_empty(system, exchange, vars, &vars->style, p.panel); + vars->layout.active_panel = p.id; + String hdbase = make_fixed_width_string(vars->hot_dir_base_); hot_directory_init(&vars->hot_directory, hdbase, current_directory, system->slash); - + vars->mini_str = make_string((char*)vars->mini_buffer, 0, 512); - + // NOTE(allen): child proc list setup i32 max_children = 16; partition_align(partition, 8); @@ -3325,6 +3246,21 @@ App_Init_Sig(app_init){ vars->sys_app_bindings = (Sys_App_Binding*)push_array(partition, Sys_App_Binding, vars->sys_app_max); } +// NOTE(allen): while I transition away from this view system to something that has +// more unified behavior, I will use this to add checks to the program's state so that I +// can make sure it behaving well. +internal void +correctness_check(App_Vars *vars){ + Panel *panel, *used_panels; + used_panels = &vars->layout.used_sentinel; + for (dll_items(panel, used_panels)){ + Assert(panel->view); + Assert(panel->parent != -1 || vars->layout.panel_count == 1); + } + panel = vars->layout.panels + vars->layout.active_panel; + Assert(panel->ALLOCED); +} + App_Step_Sig(app_step){ ProfileStart(OS_syncing); Application_Step_Result app_result = *result; @@ -3361,7 +3297,6 @@ App_Step_Sig(app_step){ } // NOTE(allen): update child processes - Panel *panels = vars->layout.panels; if (time_step){ Temp_Memory temp = begin_temp_memory(&vars->mem.part); u32 max = Kbytes(32); @@ -3416,11 +3351,14 @@ App_Step_Sig(app_step){ new_cursor = spec.step.post_pos; } - Panel *panel = panels; - i32 panel_count = vars->layout.panel_count; - for (i32 i = 0; i < panel_count; ++i, ++panel){ - View *view = panel->view; - File_View *fview = view_to_file_view(view); + Panel *panel, *used_panels; + View *view; + File_View *fview; + + used_panels = &vars->layout.used_sentinel; + for (dll_items(panel, used_panels)){ + view = panel->view; + fview = view_to_file_view(view); Assert(fview); if (fview->file == out_file){ view_cursor_move(fview, new_cursor); @@ -3428,7 +3366,7 @@ App_Step_Sig(app_step){ } } } - + vars->cli_processes.count = count; end_temp_memory(temp); } @@ -3439,20 +3377,18 @@ App_Step_Sig(app_step){ i32 prev_height = vars->layout.full_height; i32 current_width = target->width; i32 current_height = target->height; - - Panel *panel; + + Panel *panel, *used_panels; File_View *fview; - i32 i, count; vars->layout.full_width = current_width; vars->layout.full_height = current_height; if (prev_width != current_width || prev_height != current_height){ layout_refit(&vars->layout, prev_width, prev_height); - - count = vars->layout.panel_count; - panel = panels; - for (i = 0; i < count; ++i, ++panel){ + + used_panels = &vars->layout.used_sentinel; + for (dll_items(panel, used_panels)){ fview = view_to_file_view(panel->view); Assert(fview); // TODO(allen): All responses to a panel changing size should @@ -3477,18 +3413,7 @@ App_Step_Sig(app_step){ ProfileEnd(OS_syncing); - // NOTE(allen): while I transition away from this view system to something that has - // more unified behavior, I will use this to add checks to the program's state so that I - // can make sure it behaving well. - ProfileStart(correctness_checks); - { - Panel *panel = panels; - i32 panel_count = vars->layout.panel_count; - for (i32 i = 0; i < panel_count; ++i, ++panel){ - Assert(panel->view); - } - } - ProfileEnd(correctness_checks); + correctness_check(vars); ProfileStart(hover_status); // NOTE(allen): detect mouse hover status @@ -3496,12 +3421,10 @@ App_Step_Sig(app_step){ i32 my = mouse->y; b32 mouse_in_edit_area = 0; b32 mouse_in_margin_area = 0; - Panel *mouse_panel = 0; - i32 mouse_panel_i = 0; - i32 panel_count = vars->layout.panel_count; - - mouse_panel = panels; - for (mouse_panel_i = 0; mouse_panel_i < panel_count; ++mouse_panel_i, ++mouse_panel){ + Panel *mouse_panel, *used_panels; + + used_panels = &vars->layout.used_sentinel; + for (dll_items(mouse_panel, used_panels)){ if (hit_check(mx, my, mouse_panel->inner)){ mouse_in_edit_area = 1; break; @@ -3514,7 +3437,6 @@ App_Step_Sig(app_step){ if (!(mouse_in_edit_area || mouse_in_margin_area)){ mouse_panel = 0; - mouse_panel_i = 0; } b32 mouse_on_divider = 0; @@ -3572,13 +3494,15 @@ App_Step_Sig(app_step){ } ProfileEnd(hover_status); + correctness_check(vars); + // NOTE(allen): prepare to start executing commands - ProfileStart(command_coroutine); + ProfileStart(prepare_commands); Command_Data *cmd = &vars->command_data; - + cmd->mem = &vars->mem; - cmd->panel = panels + vars->layout.active_panel; + cmd->panel = vars->layout.panels + vars->layout.active_panel; cmd->view = cmd->panel->view; cmd->working_set = &vars->working_set; cmd->layout = &vars->layout; @@ -3590,16 +3514,16 @@ App_Step_Sig(app_step){ cmd->screen_width = target->width; cmd->screen_height = target->height; cmd->system = system; - + Temp_Memory param_stack_temp = begin_temp_memory(&vars->mem.part); cmd->part = partition_sub_part(&vars->mem.part, 16 << 10); - + if (first_step){ if (vars->hooks[hook_start]){ vars->hooks[hook_start](&app_links); cmd->part.pos = 0; } - + i32 i; String file_name; Panel *panel = vars->layout.panels; @@ -3617,7 +3541,7 @@ App_Step_Sig(app_step){ } } } - ProfileEnd(hover_status); + ProfileEnd(prepare_commands); // NOTE(allen): process the command_coroutine if it is unfinished ProfileStart(command_coroutine); @@ -3753,6 +3677,8 @@ App_Step_Sig(app_step){ ProfileEnd(command_coroutine); + correctness_check(vars); + // NOTE(allen): pass raw input to the panels ProfileStart(step); @@ -3794,22 +3720,21 @@ App_Step_Sig(app_step){ if (consumed_input[5]){ mouse_state.wheel = 0; } - + { - Panel *panel = panels; - for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){ + Panel *panel, *used_panels; + used_panels = &vars->layout.used_sentinel; + for (dll_items(panel, used_panels)){ View *view_ = panel->view; - if (view_){ - Assert(view_->do_view); - b32 active = (panel == cmd->panel); - Input_Summary input = (active)?(active_input):(dead_input); - if (panel == mouse_panel && !mouse->out_of_window){ - input.mouse = mouse_state; - } - if (view_->do_view(system, exchange, view_, panel->inner, cmd->view, - VMSG_STEP, 0, &input, &active_input)){ - app_result.redraw = 1; - } + Assert(view_->do_view); + b32 active = (panel == cmd->panel); + Input_Summary input = (active)?(active_input):(dead_input); + if (panel == mouse_panel && !mouse->out_of_window){ + input.mouse = mouse_state; + } + if (view_->do_view(system, exchange, view_, panel->inner, cmd->view, + VMSG_STEP, 0, &input, &active_input)){ + app_result.redraw = 1; } } } @@ -3817,6 +3742,8 @@ App_Step_Sig(app_step){ update_command_data(vars, cmd); ProfileEnd(step); + correctness_check(vars); + // NOTE(allen): command execution ProfileStart(command); if (!consumed_input[0] || !consumed_input[1]){ @@ -3877,7 +3804,9 @@ App_Step_Sig(app_step){ update_command_data(vars, cmd); ProfileEnd(command); - + + correctness_check(vars); + ProfileStart(resizing); // NOTE(allen): panel resizing switch (vars->state){ @@ -3976,13 +3905,15 @@ App_Step_Sig(app_step){ } if (mouse_in_edit_area && mouse_panel != 0 && mouse->press_l){ - vars->layout.active_panel = mouse_panel_i; + vars->layout.active_panel = (i32)(mouse_panel - vars->layout.panels); app_result.redraw = 1; } update_command_data(vars, cmd); ProfileEnd(resizing); + correctness_check(vars); + // NOTE(allen): processing sys app bindings ProfileStart(sys_app_bind_processing); { @@ -4227,17 +4158,13 @@ App_Step_Sig(app_step){ file_create_empty(system, mem, working_set, file.file, string.str, vars->font_set, style->font_id); table_add(&working_set->table, file.file->name.source_path, file.index); - - View *new_view = live_set_alloc_view(live_set, mem); - view_replace_major(system, exchange, new_view, panel, live_set); - - File_View *file_view = file_view_init( - new_view, &vars->layout, working_set, &vars->delay2, - &vars->settings, &vars->hot_directory, mem, &vars->styles); - cmd->view = (View*)file_view; - view_set_file(file_view, file.file, vars->font_set, style, + + View *view = panel->view; + File_View *fview = view_to_file_view(view); + + view_set_file(fview, file.file, vars->font_set, style, system, vars->hooks[hook_open_file], &app_links); - new_view->map = app_get_map(vars, file.file->settings.base_map_id); + view->map = app_get_map(vars, file.file->settings.base_map_id); #if BUFFER_EXPERIMENT_SCALPEL <= 0 if (file.file->settings.tokens_exist) file_first_lex_parallel(system, general, file.file); @@ -4248,18 +4175,12 @@ App_Step_Sig(app_step){ { Editing_File *file = working_set_lookup_file(working_set, string); if (file){ - View *new_view = live_set_alloc_view(live_set, mem); - view_replace_major(system, exchange, new_view, panel, live_set); - - File_View *file_view = file_view_init( - new_view, &vars->layout, working_set, &vars->delay2, - &vars->settings, &vars->hot_directory, mem, &vars->styles); - cmd->view = (View*)file_view; - - view_set_file(file_view, file, vars->font_set, style, + View *view = panel->view; + File_View *fview = view_to_file_view(view); + + view_set_file(fview, file, vars->font_set, style, system, vars->hooks[hook_open_file], &app_links); - - new_view->map = app_get_map(vars, file->settings.base_map_id); + view->map = app_get_map(vars, file->settings.base_map_id); } }break; @@ -4308,15 +4229,18 @@ App_Step_Sig(app_step){ } Swap(vars->delay1, vars->delay2); } + + end_temp_memory(param_stack_temp); ProfileEnd(delayed_actions); - end_temp_memory(param_stack_temp); + correctness_check(vars); ProfileStart(resize); // NOTE(allen): send resize messages to panels that have changed size { - Panel *panel = panels; - for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){ + Panel *panel, *used_panels; + used_panels = &vars->layout.used_sentinel; + for (dll_items(panel, used_panels)){ i32_Rect prev = panel->prev_inner; i32_Rect inner = panel->inner; if (prev.x0 != inner.x0 || prev.y0 != inner.y0 || @@ -4349,10 +4273,10 @@ App_Step_Sig(app_step){ &file->state.buffer, advance_data); } } - - Panel *panel = panels; - i32 count = vars->layout.panel_count; - for (i32 i = 0; i < count; ++i, ++panel){ + + Panel *panel, *used_panels; + used_panels = &vars->layout.used_sentinel; + for (dll_items(panel, used_panels)){ View *view = panel->view; if (view){ view->do_view(system, exchange, @@ -4362,6 +4286,8 @@ App_Step_Sig(app_step){ } } ProfileEnd(style_change); + + correctness_check(vars); ProfileStart(redraw); if (mouse_panel != vars->prev_mouse_panel) app_result.redraw = 1; @@ -4372,11 +4298,12 @@ App_Step_Sig(app_step){ draw_push_clip(target, rect_from_target(target)); // NOTE(allen): render the panels - Panel *panel = panels; - for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){ + Panel *panel, *used_panels; + used_panels = &vars->layout.used_sentinel; + for (dll_items(panel, used_panels)){ i32_Rect full = panel->full; i32_Rect inner = panel->inner; - + View *view = panel->view; Style *style = &vars->style; @@ -4416,13 +4343,7 @@ App_Step_Sig(app_step){ ProfileStart(get_cursor); // NOTE(allen): get cursor type if (mouse_in_edit_area){ - View *view = mouse_panel->view; - if (view){ - app_result.mouse_cursor_type = view->mouse_cursor_type; - } - else{ app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; - } } else if (mouse_in_margin_area){ if (mouse_on_divider){ @@ -4443,6 +4364,8 @@ App_Step_Sig(app_step){ *result = app_result; result->lctrl_lalt_is_altgr = vars->settings.lctrl_lalt_is_altgr; + correctness_check(vars); + // end-of-app_step } diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index 7fe48439..3fd36292 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -35,6 +35,7 @@ #define FCPP_LEXER_IMPLEMENTATION #include "4cpp_lexer.h" +#include "4ed_template.cpp" #include "4ed_exchange.cpp" #include "4ed_font_set.cpp" #include "4ed_rendering_helper.cpp" diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index e7226152..8827a6e5 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -414,27 +414,6 @@ get_opaque_font_advance(Render_Font *font){ return result; } -#if 0 -internal void -file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){ - i32 line_count = buffer->line_count; - if (line_count > buffer->widths_max || buffer->widths_max == 0){ - i32 new_max = LargeRoundUp(line_count, Kbytes(1)); - if (new_max < Kbytes(1)) new_max = Kbytes(1); - if (buffer->line_widths){ - buffer->line_widths = (f32*) - general_memory_reallocate(general, buffer->line_widths, - sizeof(f32)*buffer->widths_count, sizeof(f32)*new_max, BUBBLE_WIDTHS); - } - else{ - buffer->line_widths = (f32*) - general_memory_allocate(general, sizeof(f32)*new_max, BUBBLE_WIDTHS); - } - buffer->widths_max = new_max; - } -} -#endif - internal void file_remeasure_widths_(System_Functions *system, General_Memory *general, Buffer_Type *buffer, Render_Font *font, @@ -1498,25 +1477,6 @@ view_set_widget(File_View *view, File_View_Widget_Type type){ } -#if 0 -inline i32 -view_widget_height(File_View *view, i32 font_height){ - i32 result = 0; - switch (view->widget.type){ - case FWIDG_NONE: - { - Query_Slot *slot; - for (slot = view->query_set.used_slot; slot != 0; slot = slot->next){ - result += view->font_height + 2; - } - } - break; - case FWIDG_TIMELINES: result = view->widget.height; break; - } - return result; -} -#endif - inline i32_Rect view_widget_rect(File_View *view, i32 font_height){ Panel *panel = view->view_base.panel; @@ -1526,13 +1486,6 @@ view_widget_rect(File_View *view, i32 font_height){ result.y0 = result.y0 + font_height + 2; } -#if 0 - if (view->file){ - result.y0 = result.y0 + font_height + 2; - } - result.y1 = result.y0 + view_widget_height(view, font_height); -#endif - return(result); } @@ -2869,7 +2822,6 @@ interactive_view_complete(File_View *view){ case IAct_Save_As: delayed_save_as(view->delay, view->hot_directory->string, panel); - view_show_file(view, 0); break; case IAct_New: @@ -2899,9 +2851,9 @@ interactive_view_complete(File_View *view){ delayed_kill(view->delay, view->dest, panel); break; } - view_show_file(view, 0); break; } + view_show_file(view, 0); } internal void @@ -3513,7 +3465,6 @@ config_shit(File_View *view, UI_State *state, UI_Layout *layout){ internal i32 step_file_view(System_Functions *system, Exchange *exchange, View *view_, i32_Rect rect, b32 is_active, Input_Summary *user_input){ - view_->mouse_cursor_type = APP_MOUSE_CURSOR_IBEAM; i32 result = 0; File_View *view = (File_View*)view_; @@ -3565,13 +3516,6 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view_, i32_Re f32 extra_top = (f32)widget_height; f32 taken_top_space = line_height + extra_top; - if (user_input->mouse.y < rect.y0 + taken_top_space){ - view_->mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; - } - else{ - view_->mouse_cursor_type = APP_MOUSE_CURSOR_IBEAM; - } - if (user_input->mouse.wheel != 0){ f32 wheel_multiplier = 3.f; f32 delta_target_y = delta_y*user_input->mouse.wheel*wheel_multiplier; diff --git a/4ed_layout.cpp b/4ed_layout.cpp index 05becd9d..aee86581 100644 --- a/4ed_layout.cpp +++ b/4ed_layout.cpp @@ -9,55 +9,6 @@ // TOP -struct Interactive_Style{ - u32 bar_color; - u32 bar_active_color; - u32 base_color; - u32 pop1_color; - u32 pop2_color; -}; - -struct Interactive_Bar{ - Interactive_Style style; - f32 pos_x, pos_y; - f32 text_shift_x, text_shift_y; - i32_Rect rect; - i16 font_id; -}; - -enum View_Message{ - VMSG_STEP, - VMSG_DRAW, - VMSG_RESIZE, - VMSG_STYLE_CHANGE, - VMSG_FREE -}; - -struct View; -#define Do_View_Sig(name) \ - i32 (name)(System_Functions *system, Exchange *exchange, \ - View *view, i32_Rect rect, View *active, \ - View_Message message, Render_Target *target, \ - Input_Summary *user_input, Input_Summary *active_input) - -typedef Do_View_Sig(Do_View_Function); - -struct Panel; -struct View{ - View *next_free; - Panel *panel; - Command_Map *map; - Do_View_Function *do_view; - Application_Mouse_Cursor mouse_cursor_type; -}; - -struct Live_Views{ - void *views; - View *free_view; - i32 count, max; - i32 stride; -}; - struct Panel_Divider{ Panel_Divider *next; i32 parent; @@ -76,9 +27,15 @@ struct Screen_Region{ }; struct Panel{ - View *view; + Panel *next; + Panel *prev; + + struct View *view; i32 parent; i32 which_child; + + int ALLOCED; + union{ struct{ i32_Rect full; @@ -93,6 +50,8 @@ struct Panel{ struct Editing_Layout{ Panel *panels; + Panel free_sentinel; + Panel used_sentinel; Panel_Divider *dividers; Panel_Divider *free_divider; i32 panel_count, panel_max_count; @@ -101,86 +60,30 @@ struct Editing_Layout{ i32 full_width, full_height; }; -internal void -intbar_draw_string(Render_Target *target, - Interactive_Bar *bar, u8 *str, u32 char_color){ - i16 font_id = bar->font_id; +struct Divider_And_ID{ + Panel_Divider* divider; + i32 id; +}; - draw_string(target, font_id, (char*)str, - (i32)(bar->pos_x + bar->text_shift_x), - (i32)(bar->pos_y + bar->text_shift_y), - char_color); - bar->pos_x += font_string_width(target, font_id, (char*)str); -} - -internal void -intbar_draw_string(Render_Target *target, Interactive_Bar *bar, - String str, u32 char_color){ - i16 font_id = bar->font_id; - - draw_string(target, font_id, str, - (i32)(bar->pos_x + bar->text_shift_x), - (i32)(bar->pos_y + bar->text_shift_y), - char_color); - bar->pos_x += font_string_width(target, font_id, str); -} +struct Panel_And_ID{ + Panel* panel; + i32 id; +}; internal void panel_init(Panel *panel){ - *panel = {}; + panel->view = 0; panel->parent = -1; + panel->which_child = 0; + panel->screen_region.full = {}; + panel->screen_region.inner = {}; + panel->screen_region.prev_inner = {}; panel->l_margin = 3; panel->r_margin = 3; panel->t_margin = 3; panel->b_margin = 3; } -internal View* -live_set_get_view(Live_Views *live_set, i32 i){ - void *result = ((char*)live_set->views + i*live_set->stride); - return (View*)result; -} - -internal View* -live_set_alloc_view(Live_Views *live_set, Mem_Options *mem){ - Assert(live_set->count < live_set->max); - View *result = 0; - result = live_set->free_view; - live_set->free_view = result->next_free; - memset(result, 0, live_set->stride); - ++live_set->count; - return result; -} - -inline void -live_set_free_view(System_Functions *system, Exchange *exchange, Live_Views *live_set, View *view){ - Assert(live_set->count > 0); - view->do_view(system, exchange, view, {}, 0, VMSG_FREE, 0, {}, 0); - view->next_free = live_set->free_view; - live_set->free_view = view; - --live_set->count; -} - -inline void -view_set_first(View *new_view, Panel *panel){ - new_view->panel = panel; - panel->view = new_view; -} - -inline void -view_replace_major(System_Functions *system, Exchange *exchange, - View *new_view, Panel *panel, Live_Views *live_set){ - View *view = panel->view; - live_set_free_view(system, exchange, live_set, view); - new_view->panel = panel; - panel->view = new_view; -} - -struct Divider_And_ID{ - Panel_Divider* divider; - i32 id; -}; - internal Divider_And_ID layout_alloc_divider(Editing_Layout *layout){ Divider_And_ID result; @@ -203,20 +106,13 @@ layout_alloc_divider(Editing_Layout *layout){ internal Divider_And_ID layout_get_divider(Editing_Layout *layout, i32 id){ - Assert(id >= 0 && id < layout->panel_max_count-1); Divider_And_ID result; + + Assert(id >= 0 && id < layout->panel_max_count-1); result.id = id; result.divider = layout->dividers + id; - return result; -} - -internal Panel* -layout_alloc_panel(Editing_Layout *layout){ - Assert(layout->panel_count < layout->panel_max_count); - Panel *result = layout->panels + layout->panel_count; - *result = {}; - ++layout->panel_count; - return result; + + return(result); } internal void @@ -225,19 +121,33 @@ layout_free_divider(Editing_Layout *layout, Panel_Divider *divider){ layout->free_divider = divider; } +internal Panel_And_ID +layout_alloc_panel(Editing_Layout *layout){ + Panel_And_ID result = {}; + + Assert(layout->panel_count < layout->panel_max_count); + ++layout->panel_count; + + result.panel = layout->free_sentinel.next; + dll_remove(result.panel); + dll_insert(&layout->used_sentinel, result.panel); + + panel_init(result.panel); + + result.id = (i32)(result.panel - layout->panels); + + result.panel->ALLOCED = 1; + + return(result); +} + internal void layout_free_panel(Editing_Layout *layout, Panel *panel){ - Panel *p, *panels; - i32 panel_count, i; + dll_remove(panel); + dll_insert(&layout->free_sentinel, panel); + --layout->panel_count; - panels = layout->panels; - panel_count = --layout->panel_count; - - p = panel; - for (i = (i32)(panel - layout->panels); i < panel_count; ++i, ++p){ - *p = panels[i+1]; - p->view->panel = p; - } + panel->ALLOCED = 0; } internal Divider_And_ID @@ -257,7 +167,7 @@ internal Split_Result layout_split_panel(Editing_Layout *layout, Panel *panel, b32 vertical){ Split_Result result = {}; Divider_And_ID div = {}, parent_div = {}; - Panel *new_panel = 0; + Panel_And_ID new_panel = {}; div = layout_alloc_divider(layout); if (panel->parent != -1){ @@ -284,71 +194,67 @@ layout_split_panel(Editing_Layout *layout, Panel *panel, b32 vertical){ new_panel = layout_alloc_panel(layout); panel->parent = div.id; panel->which_child = -1; - new_panel->parent = div.id; - new_panel->which_child = 1; + new_panel.panel->parent = div.id; + new_panel.panel->which_child = 1; result.divider = div.divider; - result.panel = new_panel; + result.panel = new_panel.panel; + return result; } internal void panel_fix_internal_area(Panel *panel){ - i32 left, right, top, bottom; - left = panel->l_margin; - right = panel->r_margin; - top = panel->t_margin; - bottom = panel->b_margin; - - panel->inner.x0 = panel->full.x0 + left; - panel->inner.x1 = panel->full.x1 - right; - panel->inner.y0 = panel->full.y0 + top; - panel->inner.y1 = panel->full.y1 - bottom; + panel->inner.x0 = panel->full.x0 + panel->l_margin; + panel->inner.x1 = panel->full.x1 - panel->r_margin; + panel->inner.y0 = panel->full.y0 + panel->t_margin; + panel->inner.y1 = panel->full.y1 - panel->b_margin; } internal void layout_fix_all_panels(Editing_Layout *layout){ - Panel *panels = layout->panels; - if (layout->panel_count > 1){ - Panel_Divider *dividers = layout->dividers; - int panel_count = layout->panel_count; - - Panel *panel = panels; - for (i32 i = 0; i < panel_count; ++i){ - i32 x0, x1, y0, y1; - x0 = 0; - x1 = x0 + layout->full_width; - y0 = 0; - y1 = y0 + layout->full_height; - - i32 pos; - i32 which_child = panel->which_child; - Divider_And_ID div; + Panel *panel; + Panel_Divider *dividers = layout->dividers; + i32 panel_count = layout->panel_count; + i32_Rect r; + i32 pos, which_child, action; + Divider_And_ID div; + + if (panel_count > 1){ + for (panel = layout->used_sentinel.next; + panel != &layout->used_sentinel; + panel = panel->next){ + + r.x0 = 0; + r.x1 = r.x0 + layout->full_width; + r.y0 = 0; + r.y1 = r.y0 + layout->full_height; + + which_child = panel->which_child; + div.id = panel->parent; - + for (;;){ + Assert(div.id != -1); div.divider = dividers + div.id; pos = div.divider->pos; - div.divider = dividers + div.id; - // NOTE(allen): sorry if this is hard to read through, there are - // two binary conditionals that combine into four possible cases. - // Why am I appologizing to you? IF YOU CANT HANDLE MY CODE GET OUT! - i32 action = (div.divider->v_divider << 1) | (which_child > 0); + + action = (div.divider->v_divider << 1) | (which_child > 0); switch (action){ case 0: // v_divider : 0, which_child : -1 - if (pos < y1) y1 = pos; + if (pos < r.y1) r.y1 = pos; break; case 1: // v_divider : 0, which_child : 1 - if (pos > y0) y0 = pos; + if (pos > r.y0) r.y0 = pos; break; case 2: // v_divider : 1, which_child : -1 - if (pos < x1) x1 = pos; + if (pos < r.x1) r.x1 = pos; break; case 3: // v_divider : 1, which_child : 1 - if (pos > x0) x0 = pos; + if (pos > r.x0) r.x0 = pos; break; } - + if (div.id != layout->root){ div.id = div.divider->parent; which_child = div.divider->which_child; @@ -357,22 +263,19 @@ layout_fix_all_panels(Editing_Layout *layout){ break; } } - - panel->full.x0 = x0; - panel->full.y0 = y0; - panel->full.x1 = x1; - panel->full.y1 = y1; + + panel->full = r; panel_fix_internal_area(panel); - ++panel; } } else{ - panels[0].full.x0 = 0; - panels[0].full.y0 = 0; - panels[0].full.x1 = layout->full_width; - panels[0].full.y1 = layout->full_height; - panel_fix_internal_area(panels); + panel = layout->used_sentinel.next; + panel->full.x0 = 0; + panel->full.y0 = 0; + panel->full.x1 = layout->full_width; + panel->full.y1 = layout->full_height; + panel_fix_internal_area(panel); } } @@ -406,20 +309,133 @@ layout_refit(Editing_Layout *layout, i32 prev_width, i32 prev_height){ layout_fix_all_panels(layout); } -inline real32 -view_base_compute_width(View *view){ - Panel *panel = view->panel; - return (real32)(panel->inner.x1 - panel->inner.x0); +enum View_Message{ + VMSG_STEP, + VMSG_DRAW, + VMSG_RESIZE, + VMSG_STYLE_CHANGE, + VMSG_FREE +}; + +struct View; +#define Do_View_Sig(name) \ + i32 (name)(System_Functions *system, Exchange *exchange, \ + View *view, i32_Rect rect, View *active, \ + View_Message message, Render_Target *target, \ + Input_Summary *user_input, Input_Summary *active_input) + +typedef Do_View_Sig(Do_View_Function); + +struct View{ + View *next, *prev; + + Panel *panel; + Command_Map *map; + Do_View_Function *do_view; +}; + +struct Live_Views{ + void *views; + View free_sentinel; + i32 count, max; + i32 stride; +}; + +struct View_And_ID{ + View *view; + i32 id; +}; + +internal View* +live_set_get_view(Live_Views *live_set, i32 id){ + void *result = ((char*)live_set->views + id); + return (View*)result; } -inline real32 +internal View_And_ID +live_set_alloc_view(Live_Views *live_set, Mem_Options *mem){ + View_And_ID result = {}; + + Assert(live_set->count < live_set->max); + ++live_set->count; + + result.view = live_set->free_sentinel.next; + result.id = (i32)((char*)result.view - (char*)live_set->views); + + dll_remove(result.view); + memset(result.view, 0, live_set->stride); + + return(result); +} + +inline void +live_set_free_view(System_Functions *system, Exchange *exchange, Live_Views *live_set, View *view){ + Assert(live_set->count > 0); + --live_set->count; + view->do_view(system, exchange, view, {}, 0, VMSG_FREE, 0, {}, 0); + dll_insert(&live_set->free_sentinel, view); +} + +inline void +view_set_first(View *new_view, Panel *panel){ + new_view->panel = panel; + panel->view = new_view; +} + +inline f32 +view_base_compute_width(View *view){ + Panel *panel = view->panel; + return (f32)(panel->inner.x1 - panel->inner.x0); +} + +inline f32 view_base_compute_height(View *view){ Panel *panel = view->panel; - return (real32)(panel->inner.y1 - panel->inner.y0); + return (f32)(panel->inner.y1 - panel->inner.y0); } #define view_compute_width(view) (view_base_compute_width(&(view)->view_base)) #define view_compute_height(view) (view_base_compute_height(&(view)->view_base)) +struct Interactive_Style{ + u32 bar_color; + u32 bar_active_color; + u32 base_color; + u32 pop1_color; + u32 pop2_color; +}; + +struct Interactive_Bar{ + Interactive_Style style; + f32 pos_x, pos_y; + f32 text_shift_x, text_shift_y; + i32_Rect rect; + i16 font_id; +}; + +internal void +intbar_draw_string(Render_Target *target, + Interactive_Bar *bar, u8 *str, u32 char_color){ + i16 font_id = bar->font_id; + + draw_string(target, font_id, (char*)str, + (i32)(bar->pos_x + bar->text_shift_x), + (i32)(bar->pos_y + bar->text_shift_y), + char_color); + bar->pos_x += font_string_width(target, font_id, (char*)str); +} + +internal void +intbar_draw_string(Render_Target *target, Interactive_Bar *bar, + String str, u32 char_color){ + i16 font_id = bar->font_id; + + draw_string(target, font_id, str, + (i32)(bar->pos_x + bar->text_shift_x), + (i32)(bar->pos_y + bar->text_shift_y), + char_color); + bar->pos_x += font_string_width(target, font_id, str); +} + // BOTTOM diff --git a/4ed_template.cpp b/4ed_template.cpp new file mode 100644 index 00000000..a73bd02a --- /dev/null +++ b/4ed_template.cpp @@ -0,0 +1,41 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 01.03.2016 + * + * Templated code. + * + */ + +// TOP + +// NOTE(allen): This is an experiment, BUT remember a lot of people shit on templates. +// So if you start getting a wiff of stupidity from this back out immediately! + +template +inline void +dll_init_sentinel(T *sentinel){ + sentinel->next = sentinel; + sentinel->prev = sentinel; +} + +template +inline void +dll_insert(T *pos, T *v){ + v->next = pos->next; + v->prev = pos; + pos->next = v; + v->next->prev = v; +} + +template +inline void +dll_remove(T *v){ + v->next->prev = v->prev; + v->prev->next = v->next; +} + +#define dll_items(it, st) ((it) = (st)->next); ((it) != (st)); ((it) = (it)->next) + +// BOTTOM +