From 98d89dd5cb622805c48bc065f8ac27bd0484a359 Mon Sep 17 00:00:00 2001 From: dam Date: Fri, 10 May 2024 15:05:43 +0100 Subject: Reduced draw calls when no input is happening. --- ttt.jai | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 110 insertions(+), 31 deletions(-) (limited to 'ttt.jai') diff --git a/ttt.jai b/ttt.jai index 08d4bbd..acc1599 100644 --- a/ttt.jai +++ b/ttt.jai @@ -903,15 +903,35 @@ update_layout :: () { dbg_average := 0; // DEBUG dbg_count := 0; // DEBUG buffer: String_Builder; // TODO -draw_user_interface :: (db: *Database, layout: *Layout) { - - start := current_time_monotonic(); // DEBUG +draw_user_interface :: (db: *Database, layout: *Layout, redraw_all: bool = true) { + // Pagination based on currently selected task (show page where selected task is). + // Display up to rows allowed by the layout, or less if reached end of database. + get_visible_tasks_indices :: (db: Database) -> first_visible_index: int, last_visible_index: int { + first_visible_index := + (db.selected_idx / layout_tasks_rows) * layout_tasks_rows; + + last_visible_index := + first_visible_index + + (ifx layout_tasks_rows > db.tasks.count - first_visible_index + then db.tasks.count - first_visible_index + else layout_tasks_rows); + + return first_visible_index, last_visible_index; + } + + get_day_index_from_layout_index :: inline (layout_index: int) -> int { + return (layout_index + FIRST_DAY_OF_WEEK) % 7; + } + + // Convert indices to allow using different days as the first-day-of-the-week. + get_layout_index_from_day_index :: inline (day_index: int) -> int { + return (day_index - FIRST_DAY_OF_WEEK + 7) % 7; + } + + auto_release_temp(); - empty_line := talloc_string(size_x); - memset(empty_line.data, #char " ", size_x); - /* TODO It's not safe to use temporary memory here because the console resolution may increase and use more than what we have in temporary memory. And temporary memory is configured at compile time. @@ -932,17 +952,66 @@ draw_user_interface :: (db: *Database, layout: *Layout) { (5 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS, (6 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS, ]; - - x: int; - y: int; - col: *Column; // Get context information. active_task := get_active_task(db); selected_task := get_selected_task(db); now_utc := current_time_consensus(); now_week_day := to_calendar(now_utc, .LOCAL).day_of_week_starting_at_0; + + // Calculate indices of visible tasks. + start_idx, stop_idx := get_visible_tasks_indices(db); + + // If not much is happening, we may just update the active task and it's times. + if redraw_all == false { + if active_task == null then return; + + layout_idx := get_layout_index_from_day_index(now_week_day); + + x_today_offset := 1 + 1 + layout.columns[L_TITLE_IDX].width + 1; + for 0..layout_idx-1 { + x_today_offset += 1 + layout.columns[L_DAYS_IDX + it].width; + } + + x_total_offset := size_x - layout.columns[L_TOTAL_IDX].width; + + // Calculate active task times. + task_time := active_task.times[now_week_day]; + total_task_time := 0; + for 0..6 { + total_task_time = add(total_task_time, active_task.times[it]); + } + + // Draw active task times. + if db.active_idx >= start_idx && db.active_idx <= stop_idx { + TUI.using_style(ifx db.active_idx == db.selected_idx then style_active_selected else style_active); + y := 1 + 1 + (db.active_idx - start_idx); + print_time(y, x_today_offset, task_time, layout.columns[L_DAYS_IDX + layout_idx].width); + print_time(y, x_total_offset, total_task_time, layout.columns[L_TOTAL_IDX].width); + } + + // Calculate daily totals. + daily_time := db.total_times[now_week_day]; + total_time := 0; + for 0..6 { + total_time = add(total_time, db.total_times[it]); + } + // Draw daily totals. + TUI.set_style(style_active); + print_time(size_y, x_today_offset, daily_time, layout.columns[L_DAYS_IDX + layout_idx].width); + TUI.set_style(style_default); + print_time(size_y, x_total_offset, total_time, layout.columns[L_TOTAL_IDX].width); + + write_builder(*builder); + + return; + } + + x: int; + y: int; + col: *Column; + // Reset theme and clear screen. TUI.clear_terminal(); @@ -1015,14 +1084,12 @@ draw_user_interface :: (db: *Database, layout: *Layout) { total_time := 0; column_width: int; + + empty_line := talloc_string(size_x); + memset(empty_line.data, #char " ", size_x); y = 1; - // Pagination based on currently selected task (show page where selected task is). - idx_start := (db.selected_idx / layout_tasks_rows) * layout_tasks_rows; - // Display up to rows allowed by the layout, or less if reached end of database. - idx_stop := idx_start + (ifx layout_tasks_rows > db.tasks.count - idx_start then db.tasks.count - idx_start else layout_tasks_rows); - - for task_idx: idx_start..idx_stop-1 { + for task_idx: start_idx..stop_idx-1 { task := *db.tasks[task_idx]; y += 1; x = 1; @@ -1118,14 +1185,7 @@ draw_user_interface :: (db: *Database, layout: *Layout) { TUI.set_style(style_default); x += 1; print_time(y, x, total_time, layout.columns[L_TOTAL_IDX].width); - - stop := current_time_monotonic(); // DEBUG - dbg_sample := to_nanoseconds(stop-start); // DEBUG - dbg_average = (dbg_sample + dbg_count * dbg_average) / (dbg_count + 1); // DEBUG - dbg_count += 1; // DEBUG - TUI.set_cursor_position(3, 1); - TUI.tui_print("Average % us (% / % : % bytes) ---------", dbg_average/1000, context.temporary_storage.total_bytes_occupied, context.temporary_storage.high_water_mark, context.temporary_storage.size); // DEBUG - // write_string(builder_to_string(*builder,, allocator = temporary_allocator)); + write_builder(*builder); } @@ -1384,11 +1444,10 @@ main :: () { initialize_tui(); - db := *database; - layout := *layouts[Layouts.COMPACT]; - - action_style: TUI.Style; - + db := *database; + layout := *layouts[Layouts.COMPACT]; + redraw_all := true; + action_style : TUI.Style; TUI.flush_input(); TUI.set_next_key(TUI.Keys.Resize); @@ -1404,15 +1463,35 @@ main :: () { write_strings(INVALID_WINDOW_MESSAGE); } else { - draw_user_interface(db, layout); +start := current_time_monotonic(); // DEBUG + + draw_user_interface(db, layout, redraw_all); + +stop := current_time_monotonic(); // DEBUG +dbg_sample := to_nanoseconds(stop-start); // DEBUG +dbg_average = (dbg_sample + dbg_count * dbg_average) / (dbg_count + 1); // DEBUG +dbg_count += 1; // DEBUG +TUI.set_cursor_position(3, 1); +TUI.tui_print("Average % us (% / % : % bytes) ---------", dbg_average/1000, context.temporary_storage.total_bytes_occupied, context.temporary_storage.high_water_mark, context.temporary_storage.size); // DEBUG + // write_string(builder_to_string(*builder,, allocator = temporary_allocator)); + draw_error_window(); + TUI.set_cursor_position(40, 1); + TUI.tui_print(">%<", redraw_all); } key := TUI.get_key(INPUT_TIMEOUT_MS); + if key == #char "q" || key == #char "Q" break; + + redraw_all = key != TUI.Keys.None; + update_times(*database); - //timeout(INPUT_AWAIT_INF); TODO DAM + + if key == #char "k" { dbg_average = 0; dbg_count = 0; redraw_all = false; continue; } // DEBUG + + /* TODO Remove `selected_task` and `active_task` and helper functions. Every time we add or remove tasks to the database, it may be reallocated, thus making the selected_task and active_task pointers invalid. Check if this is messing up the app. -- cgit v1.2.3