From 741f56de2c1bd4bce52dd35bc921111284e995ab Mon Sep 17 00:00:00 2001 From: Julian Hurst Date: Mon, 10 Mar 2025 01:44:11 +0100 Subject: Make countdown more human readable Countdown used to be just seconds. Now a hh:mm:ss format is used. This commit also improves the countdown by printing the initial second. --- timer.ha | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/timer.ha b/timer.ha index d3b5c62..75d99b4 100644 --- a/timer.ha +++ b/timer.ha @@ -13,15 +13,50 @@ fn timer_handler(file: *ev::file) void = { const loop = ev::getloop(file); const t = ev::getuser(file): *time::instant; const t = *t; + if (print_countdown(t)) { + ev::stop(loop); + }; +}; + +fn print_countdown(instant: time::instant) bool = { const tn = time::now(time::clock::MONOTONIC); - const currentduration = time::diff(tn, t); + const currentduration = time::diff(tn, instant); // man page console_codes(4) is useful fmt::fprint(os::stderr, "\x1B[1K\r")!; - fmt::fprint(os::stderr, math::ceilf64(currentduration: f64 / time::SECOND: f64): u64)!; - if (currentduration <= 0) { - ev::stop(loop); + const count = human_readable(currentduration); + defer free(count); + fmt::fprint(os::stderr, count)!; + return currentduration <= 0; +}; + +// Transform a duration to a human readable string representation. +fn human_readable(duration: time::duration) str = { + const hours = if (duration > time::HOUR) { + let hours = math::floorf64(duration: f64 / time::HOUR: f64): u64; + duration = (duration % time::HOUR); + yield hours; + } else { + yield 0u64; + }; + const mins = if (duration > time::MINUTE) { + let mins = math::floorf64(duration: f64 / time::MINUTE: f64): u64; + duration = (duration % time::MINUTE); + yield mins; + } else { + yield 0u64; + }; + const secs = if (duration > time::SECOND) { + yield math::floorf64(duration: f64 / time::SECOND: f64): u64; + } else { + yield 0u64; + }; + const mods = &fmt::mods { + pad = '0', + width = 2, + ... }; + return fmt::asprintf("{%}:{%}:{%}", hours, mods, mins, mods, secs, mods); }; fn parse_duration(duration: const str) (time::duration | uniterror | strconv::invalid | strconv::overflow) = { @@ -65,6 +100,7 @@ export fn main() void = { const f = ev::newtimer(&loop, &timer_handler, time::clock::MONOTONIC)!; ev::setuser(f, &t); + print_countdown(t); ev::timer_configure(f, 1 * time::SECOND, 1 * time::SECOND); -- cgit v1.2.3