diff options
Diffstat (limited to 'timer.ha')
| -rw-r--r-- | timer.ha | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/timer.ha b/timer.ha new file mode 100644 index 0000000..016519a --- /dev/null +++ b/timer.ha @@ -0,0 +1,72 @@ +use fmt; +use ev; +use getopt; +use os; +use time; +use strings; +use strconv; +use math; + +type uniterror = !void; + +fn timer_handler(file: *ev::file) void = { + const loop = ev::getloop(file); + const t = ev::getuser(file): *time::instant; + const t = *t; + const tn = time::now(time::clock::MONOTONIC); + const currentduration = time::diff(tn, t); + + 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); + }; +}; + +fn parse_duration(duration: const str) (time::duration | uniterror | strconv::invalid | strconv::overflow) = { + const s = strings::toutf8(duration); + const unit = s[len(s)-1]; + const unit = switch (unit) { + case 's' => + yield time::SECOND; + case 'm' => + yield time::MINUTE; + case 'h' => + yield time::HOUR; + case => + return uniterror; + }; + const d = strconv::stoi(strings::sub(duration, 0, len(duration) - 1))?; + return d * unit; +}; + +export fn main() void = { + const cmd = getopt::parse(os::args, + "timer for alarms", + "duration", + ); + defer getopt::finish(&cmd); + + if (len(cmd.args) != 1) { + getopt::printusage(os::stderr, os::args[0], cmd.help)!; + os::exit(os::status::FAILURE); + }; + + const duration = cmd.args[0]; + const duration = parse_duration(duration)!; + + const loop = ev::newloop()!; + + const t = time::now(time::clock::MONOTONIC); + const t = time::add(t, duration); + + defer ev::finish(&loop); + + const f = ev::newtimer(&loop, &timer_handler, time::clock::MONOTONIC)!; + ev::setuser(f, &t); + + ev::timer_configure(f, 1 * time::SECOND, 1 * time::SECOND); + + for (ev::dispatch(&loop, -1)!) void; + fmt::println()!; +}; |
