1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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();
}
}
|