diff options
| author | Julian Hurst <ark@mansus.space> | 2025-03-10 01:44:11 +0100 |
|---|---|---|
| committer | Julian Hurst <ark@mansus.space> | 2025-03-10 01:51:55 +0100 |
| commit | 741f56de2c1bd4bce52dd35bc921111284e995ab (patch) | |
| tree | ed88aa194c3f03e5a1ac71d1f33f8c95f5fc43c3 | |
| parent | 45900e4c135624378e46dbf93f80885e2a5cb525 (diff) | |
| download | timer-741f56de2c1bd4bce52dd35bc921111284e995ab.tar.gz | |
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.
| -rw-r--r-- | timer.ha | 44 |
1 files changed, 40 insertions, 4 deletions
@@ -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); |
