summaryrefslogtreecommitdiff
path: root/timer.ha
diff options
context:
space:
mode:
authorJulian Hurst <ark@mansus.space>2025-03-01 16:27:17 +0100
committerJulian Hurst <ark@mansus.space>2025-03-01 16:30:05 +0100
commit8dbcb04ce93dd32e80c37da3ca2c486802213858 (patch)
treee465a66ebafbec949037bdfb0e1d5dfe7df03ab5 /timer.ha
downloadtimer-8dbcb04ce93dd32e80c37da3ca2c486802213858.tar.gz
Initial commit
Diffstat (limited to 'timer.ha')
-rw-r--r--timer.ha72
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()!;
+};