diff options
| author | dam <dam@gudinoff> | 2024-05-09 11:43:31 +0100 |
|---|---|---|
| committer | dam <dam@gudinoff> | 2024-05-09 11:43:31 +0100 |
| commit | f5fc7f6e700d272c2d60e4a1da219c993f01cad3 (patch) | |
| tree | 8a87cab9f000dc889b32679792106ecb51cabff5 | |
| parent | cfd38fe13acd19c9326264766cfe94e5534db739 (diff) | |
| download | task-time-tracker-f5fc7f6e700d272c2d60e4a1da219c993f01cad3.tar.zst task-time-tracker-f5fc7f6e700d272c2d60e4a1da219c993f01cad3.zip | |
Fixed TUI module to allow returning results in temporary memory.
| -rw-r--r-- | modules/TUI/module.jai | 58 | ||||
| -rw-r--r-- | ttt.jai | 20 | ||||
| -rw-r--r-- | unused.jai | 1 |
3 files changed, 43 insertions, 36 deletions
diff --git a/modules/TUI/module.jai b/modules/TUI/module.jai index 112c666..f8e745e 100644 --- a/modules/TUI/module.jai +++ b/modules/TUI/module.jai @@ -33,7 +33,7 @@ #load "key_map.jai"; #add_context tui_style : Style; // This contains the last style applied by the module. -#add_context tui_buffer : *String_Builder; // If set, this buffer will be used as output target of module procedures. +#add_context tui_builder : *String_Builder; // If set, this will serve as an output buffer for this module procedures. KEY_SIZE :: #run type_info(Key).runtime_size; #assert(input_buffer.count >= KEY_SIZE); // The input buffer size must be capable to hold an entire Key. @@ -42,7 +42,7 @@ active := false; input_override : Key; input_string : string; input_buffer : [1024] u8; -temp_buffer := String_Builder.{ allocator = temporary_allocator }; +temp_builder := String_Builder.{ allocator = temporary_allocator }; #scope_module @@ -176,11 +176,13 @@ Style :: struct { } set_style :: (style: Style) { - - auto_release_temp(); // TODO Does this breaks if the context.tui_buffer is a temporary buffer... and we're writting to it? - - // TODO If context.tui_buffer is temporary... this will fail.... right? - builder := ifx context.tui_buffer != null then context.tui_buffer else *temp_buffer; + // If no tui_builder is provided, use a temporary one and discard it afterwards. + builder := context.tui_builder; + temp_mark: Temporary_Storage_State = ---; + if context.tui_builder == null { + builder = *temp_builder; + temp_mark = get_temporary_storage_mark(); + } #if COLOR_MODE_BITS == { case 4; @@ -211,8 +213,9 @@ set_style :: (style: Style) { append(builder, #run sprint(Commands.SetGraphicsRendition, "49")); } - if context.tui_buffer == null { + if context.tui_builder == null { write_builder(builder); + set_temporary_storage_mark(temp_mark); } context.tui_style = style; @@ -497,9 +500,9 @@ read_input :: (count_limit: int = -1, terminators: .. u8) -> string { read_input_line :: (count_limit: int, is_visible: bool = true) -> string, Key { assert_is_active(); assert(count_limit >= 0, "Invalid arguments passed to read_input_line(): 'count_limit' must be greater-than or equal to 0."); - - builder := temp_buffer; - + + // The returned memory must be allocated before we start to use temporary memory. + // Otherwise, the returned memory would be invalid on calls of type (,, temporary_allocator). str := alloc_string(count_limit); str.count = 0; idx := 0; @@ -510,6 +513,8 @@ read_input_line :: (count_limit: int, is_visible: bool = true) -> string, Key { write_strings(Commands.ShowCursor, Commands.StartBlinking, Commands.BlinkingBarShape); while true { + builder := temp_builder; + auto_release_temp(); chars_count := count_characters(str); @@ -601,9 +606,13 @@ draw_box :: (x: int, y: int, width: int, height: int) { assert_is_active(); assert(x > 0 && y > 0 && width > 1 && height > 1, "Invalid arguments passed to draw_box(): 'x' and 'y' must be greater-than 0; 'width' and 'height' must be greater-than 1."); - auto_release_temp(); // TODO Does this breaks if the context.tui_buffer is a temporary buffer... and we're writting to it? - - builder := ifx context.tui_buffer != null then context.tui_buffer else *temp_buffer; + // If no tui_builder is provided, use a temporary one and discard it afterwards. + builder := context.tui_builder; + temp_mark: Temporary_Storage_State = ---; + if context.tui_builder == null { + builder = *temp_builder; + temp_mark = get_temporary_storage_mark(); + } append(builder, Commands.DrawingMode); @@ -633,8 +642,9 @@ draw_box :: (x: int, y: int, width: int, height: int) { append(builder, Commands.TextMode); - if context.tui_buffer == null { + if context.tui_builder == null { write_builder(builder); + set_temporary_storage_mark(temp_mark); } } @@ -692,11 +702,11 @@ get_terminal_size :: () -> width: int, height: int { set_cursor_position :: inline (x: int, y: int) { assert_is_active(); - if context.tui_buffer == null { + if context.tui_builder == null { print(Commands.SetCursorPosition, y, x); } else { - print_to_builder(context.tui_buffer, Commands.SetCursorPosition, y, x); + print_to_builder(context.tui_builder, Commands.SetCursorPosition, y, x); } } @@ -740,27 +750,27 @@ set_terminal_title :: inline (title: string) { } using_buffer :: (buffer: *String_Builder) #expand { - __buffer := context.tui_buffer; - context.tui_buffer = buffer; - `defer context.tui_buffer = __buffer; + __buffer := context.tui_builder; + context.tui_builder = buffer; + `defer context.tui_builder = __buffer; } // TODO Maybe we should have a different name for this...? tui_print :: inline (format_string: string, args: .. Any) { - if context.tui_buffer == null { + if context.tui_builder == null { print(format_string, ..args, to_standard_error = false); } else { - print_to_builder(context.tui_buffer, format_string, ..args); + print_to_builder(context.tui_builder, format_string, ..args); } } // TODO Maybe we should have a different name for this...? tui_write :: inline (format_string: string) { - if context.tui_buffer == null { + if context.tui_builder == null { write_string(format_string); } else { - append(context.tui_buffer, format_string); + append(context.tui_builder, format_string); } } @@ -214,13 +214,12 @@ print_time :: (y: int, x: int, time: s64, space: int) -> int { left_padding := (space - TIME_CHARS) / 2; right_padding := space - TIME_CHARS - left_padding; - print_padding :: (size: int, char: u8 = #char " ") { + print_padding :: (size: int) { assert(size >= 0, "Cannot print negative padding values. The procedure accepts signed values just for convenience."); - auto_release_temp(); - padding := talloc_string(size); - padding.count = size; - memset(padding.data, char, size); - TUI.tui_write(padding); + while size > 0 { + TUI.tui_write(" "); + size -= 1; + } } TUI.set_cursor_position(x, y); @@ -908,9 +907,9 @@ draw_user_interface :: (db: *Database, layout: *Layout) { empty_line := talloc_string(size_x); memset(empty_line.data, #char " ", size_x); - init_string_builder(*buffer, 100000); - // builder := String_Builder.{ allocator = temporary_allocator }; - builder := buffer; + // init_string_builder(*buffer, 100000); + // builder := buffer; + builder := String_Builder.{ allocator = temporary_allocator }; TUI.using_buffer(*builder); adjust_first_day_of_week := int.[ @@ -1194,9 +1193,6 @@ prompt_user_key :: (y: int, message: string) -> TUI.Key { main :: () { -// TODO WIP WIP WIP WIP WIP WIP WIP WIP - make some tests to see how auto_release_temporary works... check if something allocated right before are kept or discarddled... and how temp allocated StringBuilder behaves... - - #if DEBUG_MEMORY { defer report_memory_leaks(); // TODO Remove after final debug sessions. } @@ -1,6 +1,7 @@ auto_release_temp(); // automatically release temporary memory. print(">%<", S64_MIN + delta, to_standard_error = true); print_to_builder(*builder, "Average % us (% / % bytes) ---------", dbg_average/1000, context.temporary_storage.total_bytes_occupied, context.temporary_storage.high_water_mark); // DEBUG +print("temp [% .. % .. %] \n", context.temporary_storage.data, get_temporary_storage_mark(), context.temporary_storage.data + context.temporary_storage.size-1); // MEASURE PERFORMANCE |
