summaryrefslogtreecommitdiff
path: root/lib/astal/io/time.vala
diff options
context:
space:
mode:
authorkotontrion <[email protected]>2024-10-29 13:50:41 +0100
committerkotontrion <[email protected]>2024-10-29 13:50:41 +0100
commit57f20666e716fde56579b8aa638eed1264f793de (patch)
tree59b2ebbd770c80049cea4df82109d28f617675fe /lib/astal/io/time.vala
parent4d9ae88b0bab75779876d465f986791d052414ca (diff)
parent7e484188e7492ac7945c854bcc3f26cec1863c91 (diff)
Merge branch 'main' into feat/cava
Diffstat (limited to 'lib/astal/io/time.vala')
-rw-r--r--lib/astal/io/time.vala111
1 files changed, 111 insertions, 0 deletions
diff --git a/lib/astal/io/time.vala b/lib/astal/io/time.vala
new file mode 100644
index 0000000..a799f2b
--- /dev/null
+++ b/lib/astal/io/time.vala
@@ -0,0 +1,111 @@
+/**
+ * `Time` provides shortcuts for GLib timeout functions.
+ */
+public class AstalIO.Time : Object {
+ private Cancellable cancellable;
+ private uint timeout_id;
+ private bool fulfilled = false;
+
+ /**
+ * Emitted when the timer ticks.
+ */
+ public signal void now ();
+
+ /**
+ * Emitted when the timere is cancelled.
+ */
+ public signal void cancelled ();
+
+ construct {
+ cancellable = new Cancellable();
+ cancellable.cancelled.connect(() => {
+ if (!fulfilled) {
+ Source.remove(timeout_id);
+ cancelled();
+ dispose();
+ }
+ });
+ }
+
+ private void connect_closure(Closure? closure) {
+ if (closure == null)
+ return;
+
+ now.connect(() => {
+ Value ret = Value(Type.POINTER); // void
+ closure.invoke(ref ret, {});
+ });
+ }
+
+ /**
+ * Start an interval timer with default Priority.
+ */
+ public Time.interval_prio(uint interval, int prio = Priority.DEFAULT, Closure? fn) {
+ connect_closure(fn);
+ Idle.add_once(() => now());
+ timeout_id = Timeout.add(interval, () => {
+ now();
+ return Source.CONTINUE;
+ }, prio);
+ }
+
+ /**
+ * Start a timeout timer with default Priority.
+ */
+ public Time.timeout_prio(uint timeout, int prio = Priority.DEFAULT, Closure? fn) {
+ connect_closure(fn);
+ timeout_id = Timeout.add(timeout, () => {
+ now();
+ fulfilled = true;
+ return Source.REMOVE;
+ }, prio);
+ }
+
+ /**
+ * Start an idle timer with default priority.
+ */
+ public Time.idle_prio(int prio = Priority.DEFAULT_IDLE, Closure? fn) {
+ connect_closure(fn);
+ timeout_id = Idle.add(() => {
+ now();
+ fulfilled = true;
+ return Source.REMOVE;
+ }, prio);
+ }
+
+ /**
+ * Start an interval timer. Ticks immediately then every `interval` milliseconds.
+ *
+ * @param interval Tick every milliseconds.
+ * @param fn Optional callback.
+ */
+ public static Time interval(uint interval, Closure? fn) {
+ return new Time.interval_prio(interval, Priority.DEFAULT, fn);
+ }
+
+ /**
+ * Start a timeout timer which ticks after `timeout` milliseconds.
+ *
+ * @param timeout Tick after milliseconds.
+ * @param fn Optional callback.
+ */
+ public static Time timeout(uint timeout, Closure? fn) {
+ return new Time.timeout_prio(timeout, Priority.DEFAULT, fn);
+ }
+
+ /**
+ * Start a timer which will tick when there are no higher priority tasks pending.
+ *
+ * @param fn Optional callback.
+ */
+ public static Time idle(Closure? fn) {
+ return new Time.idle_prio(Priority.DEFAULT_IDLE, fn);
+ }
+
+ /**
+ * Cancel timer and emit [[email protected]::cancelled]
+ */
+ public void cancel() {
+ cancellable.cancel();
+ }
+}