aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordam <dam@gudinoff>2024-05-05 04:19:06 +0100
committerdam <dam@gudinoff>2024-05-05 04:19:06 +0100
commit54103773365e06d6da8518d135c396949e683960 (patch)
tree464f1f1c04fd1d418c2f13bee79737b7e2a6958d
parent1ae2933bcbda43d16d2583a28c3c5a74adaaa9e4 (diff)
downloadtask-time-tracker-54103773365e06d6da8518d135c396949e683960.tar.zst
task-time-tracker-54103773365e06d6da8518d135c396949e683960.zip
Fixed memory leaks.
-rw-r--r--modules/TUI/module.jai26
-rw-r--r--ttt.jai32
2 files changed, 31 insertions, 27 deletions
diff --git a/modules/TUI/module.jai b/modules/TUI/module.jai
index 3f824a4..dc9643c 100644
--- a/modules/TUI/module.jai
+++ b/modules/TUI/module.jai
@@ -511,17 +511,17 @@ read_input_line :: (count_limit: int, is_visible: bool = true) -> string, Key {
// Draw preview.
if is_visible {
- append(*builder, tprint(Commands.SetCursorPosition, y, x));
+ print_to_builder(*builder, Commands.SetCursorPosition, y, x);
append(*builder, str);
for chars_count..count_limit-1 append(*builder, " ");
}
else {
- append(*builder, tprint(Commands.SetCursorPosition, y, x));
+ print_to_builder(*builder, Commands.SetCursorPosition, y, x);
for 1..chars_count append(*builder, "*");
for chars_count..count_limit-1 append(*builder, " ");
}
- append(*builder, tprint(Commands.SetCursorPosition, y, x+idx));
- write_string(builder_to_string(*builder));
+ print_to_builder(*builder, Commands.SetCursorPosition, y, x+idx);
+ write_string(builder_to_string(*builder,, allocator = temporary_allocator));
// Process input key.
key = get_key();
@@ -600,7 +600,7 @@ draw_box :: (x: int, y: int, width: int, height: int) {
append(*builder, Commands.DrawingMode);
// Draw top line
- append(*builder, tprint(Commands.SetCursorPosition, y, x));
+ print_to_builder(*builder, Commands.SetCursorPosition, y, x);
append(*builder, Drawings.CornerTL);
for 1..width-2 {
append(*builder, Drawings.LineH);
@@ -609,14 +609,14 @@ draw_box :: (x: int, y: int, width: int, height: int) {
// Draw left and right sides.
for idx: y+1..y+height-2 {
- append(*builder, tprint(Commands.SetCursorPosition, idx, x));
+ print_to_builder(*builder, Commands.SetCursorPosition, idx, x);
append(*builder, Drawings.LineV);
- append(*builder, tprint(Commands.SetCursorPosition, idx, x+width-1));
+ print_to_builder(*builder, Commands.SetCursorPosition, idx, x+width-1);
append(*builder, Drawings.LineV);
}
// Draw bottom line.
- append(*builder, tprint(Commands.SetCursorPosition, y+height-1, x));
+ print_to_builder(*builder, Commands.SetCursorPosition, y+height-1, x);
append(*builder, Drawings.CornerBL);
for 1..width-2 {
append(*builder, Drawings.LineH);
@@ -625,7 +625,7 @@ draw_box :: (x: int, y: int, width: int, height: int) {
append(*builder, Commands.TextMode);
- write_string(builder_to_string(*builder));
+ write_string(builder_to_string(*builder,, allocator = temporary_allocator));
}
clear_terminal :: inline () {
@@ -647,7 +647,7 @@ get_terminal_size :: () -> width: int, height: int {
// Expected response format: \e[8;<r>;<c>t
// where <r> is the number of rows and <c> of columns.
FORMAT :: "\e[8;<r>;<c>t";
- input := read_input(64, #char "t",, temporary_allocator);
+ input := read_input(64, #char "t",, allocator = temporary_allocator);
// Discard head noise.
while input.count >= 3 && (input[0] != FORMAT[0] || input[1] != FORMAT[1] || input[2] != FORMAT[2]) {
@@ -663,7 +663,7 @@ get_terminal_size :: () -> width: int, height: int {
input[0] == FORMAT[0] && input[1] == FORMAT[1] && input[2] == FORMAT[2] && input[input.count-1] == FORMAT[FORMAT.count-1],
"Failed to query window size: invalid response.");
- parts := split(input, ";",, temporary_allocator);
+ parts := split(input, ";",, allocator = temporary_allocator);
rows = parse_int(*parts[1]);
columns = parse_int(*parts[2]);
}
@@ -696,7 +696,7 @@ get_cursor_position :: () -> x: int, y: int {
// Expected response format: \e[<r>;<c>R
// where <r> is the number of rows and <c> of columns.
FORMAT :: "\e[<r>;<c>R";
- input := read_input(64, #char "R");
+ input := read_input(64, #char "R",, allocator = temporary_allocator);
// Discard head noise.
while input.count >= 2 && (input[0] != FORMAT[0] || input[1] != FORMAT[1]) {
@@ -713,7 +713,7 @@ get_cursor_position :: () -> x: int, y: int {
"Failed to query cursor position: invalid response.");
advance(*input, 2);
- parts := split(input, ";",, temporary_allocator);
+ parts := split(input, ";",, allocator = temporary_allocator);
row := parse_int(*parts[0]);
column := parse_int(*parts[1]);
return column, row;
diff --git a/ttt.jai b/ttt.jai
index 0715544..929a736 100644
--- a/ttt.jai
+++ b/ttt.jai
@@ -590,12 +590,14 @@ load_database :: (db: *Database, path: string) -> success: bool {
// Returns success.
export_to_csv :: (db: Database, path: string) -> success: bool {
assert(xx path, ASSERT_NOT_EMPTY, "path");
+
+ auto_release_temp();
builder: String_Builder;
defer reset(*builder);
CSV_HEADER :: string.[ "task", "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ];
- print_to_builder(*builder, "%\n", join(..CSV_HEADER, separator = ","));
+ print_to_builder(*builder, "%\n", join(..CSV_HEADER, separator = ",",, temporary_allocator));
buffer: [Task.name.count] u8;
name: string = xx buffer;
@@ -701,15 +703,16 @@ import_from_csv :: (db: *Database, path: string) -> bool {
}
{ // Parse CSV lines.
- auto_release_temp(); // TODO Needs to be tested.
line := csv;
while (true) {
+ auto_release_temp();
+
line, success := consume_next_line(*csv);
// line, success := next_line(*csv);
if success == false break;
task: Task;
- csv_values := split(line, ",",, temporary_allocator); // TODO Temporary memory... if file is too big this may break.
+ csv_values := split(line, ",",, temporary_allocator);
// Import task name.
name_length := min(task.name.count, csv_values[0].count);
@@ -891,6 +894,8 @@ update_layout :: () {
draw_tui :: (db: *Database, layout: *Layout) {
+ // TODO During dirty_flag revamp...we may also start using the String_Builder.
+
adjust_first_day_of_week := int.[
(0 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS,
(1 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS,
@@ -990,7 +995,6 @@ draw_tui :: (db: *Database, layout: *Layout) {
// 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 {
- auto_release_temp(); // TODO Temporary memory being trashed?!
task := *db.tasks[task_idx];
y += 1;
x = 1;
@@ -1138,7 +1142,7 @@ read_input_int :: (y: int, message: string) -> value: int, success: bool {
input_pos_x := x + message.count + 2;
input_width := size_x - input_pos_x;
- str := read_input_string(input_pos_x, y, input_width);
+ str := read_input_string(input_pos_x, y, input_width,, temporary_allocator);
value, success := parse_int(*str);
return value, success;
@@ -1170,7 +1174,6 @@ main :: () {
defer free_memory();
{ // Initialize app directory.
- auto_release_temp();
home_dir, success_dir := get_home_directory(); // Returns system owned memory.
if success_dir == false {
home_dir = ".";
@@ -1195,7 +1198,6 @@ main :: () {
}
{ // Initialize database and archive files if needed.
- auto_release_temp();
if (file_exists(db_file_path) == false) {
if (store_database(database, db_file_path) == false) {
print_error("Failed to initialize database.");
@@ -1333,7 +1335,8 @@ main :: () {
}
if is_exit_requested {
- exit(0);
+ // exit(0); // TODO fucking exit does not report memory leaks.
+ return;
}
}
@@ -1353,7 +1356,9 @@ main :: () {
TUI.flush_input();
TUI.set_next_key(TUI.Keys.Resize);
while (true) {
-
+
+ reset_temporary_storage();
+
TUI.set_style(style_default);
if (is_terminal_too_small) {
@@ -1366,7 +1371,6 @@ main :: () {
draw_error_window();
}
- reset_temporary_storage();
key := TUI.get_key(INPUT_TIMEOUT_MS);
if key == #char "q" || key == #char "Q" break;
update_times(*database);
@@ -1456,7 +1460,7 @@ main :: () {
// Change task name.
TUI.using_style(action_style);
- input := read_input_string(2, selected_task_row, Task.name.count, size_x - 2 - Task.name.count);
+ input := read_input_string(2, selected_task_row, Task.name.count, size_x - 2 - Task.name.count,, temporary_allocator);
if is_empty_string(input) == false {
replace_chars(input, "\t\x0B\x0C\r", #char " "); // Replace weird spaces with space.
memset(selected_task.name.data, 0, Task.name.count);
@@ -1492,9 +1496,9 @@ main :: () {
case #char "6"; #through;
case #char "7";
if (selected_task == null) continue;
-
+
// Prepare position to input time operation.
- selected_day := cast(int)(key - #char "1"); // TODO DAM this cast...
+ selected_day := cast(int)(key - #char "1");
input_width := layout.columns[L_DAYS_IDX + selected_day].width;
input_pos_x := 2 + layout.columns[L_TITLE_IDX].width;
for 0..selected_day-1 {
@@ -1504,7 +1508,7 @@ main :: () {
// Get input string.
TUI.using_style(action_style);
- input := read_input_string(input_pos_x, selected_task_row, input_width); // TODO Temp stringzes.
+ input := read_input_string(input_pos_x, selected_task_row, input_width,, temporary_allocator);
// Abort if input if empty.
if is_empty_string(input) continue;