diff options
| -rw-r--r-- | ttt.jai | 122 |
1 files changed, 60 insertions, 62 deletions
@@ -360,24 +360,13 @@ delete_task :: (using db: *Database, index: s64) -> bool { // TODO Maybe use `us } // Try to shrink database capacity if using more than 2MB. - TODO WIP WIP WIP Coalescing is failing because of this... - // if (tasks.allocated >> 2) > tasks.count && tasks.allocated * SIZE_OF_TASK > 2_000_000 { - print("> A <"); new_capacity := tasks.allocated >> 1; - msg := tprint("shrinking from % to %\n", tasks.allocated, new_capacity); - print_error(msg); - // if !tasks.allocator.proc remember_allocators(*tasks); new_tasks_data := realloc(tasks.data, new_capacity * SIZE_OF_TASK, tasks.allocated * SIZE_OF_TASK, tasks.allocator); if new_tasks_data != null { - msg = tprint("OH NOEWS"); - print_error(msg); tasks.data = new_tasks_data; tasks.allocated = new_capacity; } - msg = tprint("ALL OK"); - print_error(msg); - print("> B <"); } return true; @@ -421,6 +410,26 @@ move_task :: (db: *Database, source: s64, target: s64) { // TODO Maybe `using db db.selected_idx = target; } +// Find similar task and return it's index, or -1 if not found. +find_similar_task :: (db: *Database, task: Task) -> idx: s64 { + compare_array :: (a: [] $T, b: [] T) -> int { + for 0..min(a.count, b.count)-1 { + if a[it] > b[it] return 1; + if a[it] < b[it] return -1; + } + if a.count > b.count return 1; + if a.count < b.count return -1; + return 0; + } + + for db.tasks { + if compare(xx task.name, xx it.name) == 0 && compare_array(task.times, it.times) == 0 { + return it_index; + } + } + return -1; +} + // Updates the times on the active task (and adjusts database totals). update_times :: (db: *Database) { assert(db != null, ASSERT_NOT_NULL, "db"); @@ -1616,22 +1625,18 @@ main :: () { case #char "s"; #through; case #char "S"; // TODO The initial part should only decide what's the sorting procedure... then we would would all in a single place. - active_task: Task = ifx db.active_idx >= 0 then db.tasks[db.active_idx] else .{}; sort_by := read_input_char(selected_task_row, action_style, " Sort by (n) name, (1..7) day, or (t) total time. "); + sort_procedure: (a: Task, b: Task) -> s64; + active_task: Task = ifx db.active_idx >= 0 then db.tasks[db.active_idx] else .{}; if sort_by == { case #char "n"; #through; case #char "N"; - quick_sort(db.tasks, (x, y) => compare_strings(xx x.name, xx y.name)); + sort_procedure = (x, y) => compare_strings(xx x.name, xx y.name); case #char "t"; #through; case #char "T"; - compare_tasks :: (x: Task, y: Task) -> s64 { - total_x, total_y: s64; - for x.times { total_x = add(total_x, it); }; - for y.times { total_y = add(total_y, it); }; - return sub(total_x, total_y); - }; - quick_sort(db.tasks, compare_tasks); + sum_total :: inline (t: Task) -> s64 { total: s64; for t.times { total = add(total, it); } return total; } + sort_procedure = (x, y) => sum_total(x) - sum_total(y); case #char "1"; #through; case #char "2"; #through; @@ -1643,33 +1648,22 @@ main :: () { sort_by_idx := sort_by - #char "1"; day := (sort_by_idx + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS; if day == { - case 0; quick_sort(db.tasks, (x, y) => x.times[0] - y.times[0]); - case 1; quick_sort(db.tasks, (x, y) => x.times[1] - y.times[1]); - case 2; quick_sort(db.tasks, (x, y) => x.times[2] - y.times[2]); - case 3; quick_sort(db.tasks, (x, y) => x.times[3] - y.times[3]); - case 4; quick_sort(db.tasks, (x, y) => x.times[4] - y.times[4]); - case 5; quick_sort(db.tasks, (x, y) => x.times[5] - y.times[5]); - case 6; quick_sort(db.tasks, (x, y) => x.times[6] - y.times[6]); + case 0; sort_procedure = (x, y) => x.times[0] - y.times[0]; + case 1; sort_procedure = (x, y) => x.times[1] - y.times[1]; + case 2; sort_procedure = (x, y) => x.times[2] - y.times[2]; + case 3; sort_procedure = (x, y) => x.times[3] - y.times[3]; + case 4; sort_procedure = (x, y) => x.times[4] - y.times[4]; + case 5; sort_procedure = (x, y) => x.times[5] - y.times[5]; + case 6; sort_procedure = (x, y) => x.times[6] - y.times[6]; } + + case; + continue; } + quick_sort(db.tasks, sort_procedure); + if db.active_idx >= 0 { - - compare_array :: (a: [] $T, b: [] T) -> int { - for 0..min(a.count, b.count)-1 { - if a[it] > b[it] return 1; - if a[it] < b[it] return -1; - } - if a.count > b.count return 1; - if a.count < b.count return -1; - return 0; - } - - for db.tasks { - if compare(xx active_task.name, xx it.name) == 0 && compare_array(active_task.times, it.times) == 0 { - db.active_idx = it_index; - break; - } - } + db.active_idx = find_similar_task(db, active_task); } trigger_autosave(); @@ -1691,28 +1685,32 @@ main :: () { case #char "c"; #through; case #char "C"; if (db.tasks.count <= 0) continue; - if (read_enter_confirmation(selected_task_row, action_style, " Press enter to coalesce similar tasks. ") == true) { - // TODO Coalesce stuff. - print_error(" REQUIRES CODE CLEANUP AND TESTING "); - tasks_to_process := db.tasks.count - 1; - idx := 0; - while tasks_to_process > 0 { - task := *db.tasks[idx]; - for < i : db.tasks.count-1..idx+1 { - if compare_strings(xx task.name, xx db.tasks[i].name) == 0 { - for item, index: db.tasks[i].times { - task.times[index] = add(task.times[index], item); - } - delete_task(db, i); - tasks_to_process -= 1; + if (read_enter_confirmation(selected_task_row, action_style, " Press enter to coalesce similar tasks. ") == false) continue; + + active_task: Task = ifx db.active_idx >= 0 then db.tasks[db.active_idx] else .{}; + + head_idx := 0; + while head_idx < db.tasks.count - 1 { + tail_idx := db.tasks.count - 1; + while tail_idx > head_idx { + t_head := *db.tasks[head_idx]; + t_tail := *db.tasks[tail_idx]; + if compare(xx t_head.name, xx t_tail.name) == 0 { + for 0..6 { + t_head.times[it] = add(t_head.times[it], t_tail.times[it]); } + delete_task(db, tail_idx); } - - idx += 1; - tasks_to_process -= 1; + tail_idx -= 1; } - trigger_autosave(); + head_idx += 1; + } + update_total_times(db); // TODO Can we make this so that we don't need to do this? I bet we can... + + if db.active_idx >= 0 { + db.active_idx = find_similar_task(db, active_task); } + trigger_autosave(); case KEY_HOME; select_task(db, 0); |
