-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
timer.dart
167 lines (159 loc) · 5.58 KB
/
timer.dart
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of dart.async;
/// A countdown timer that can be configured to fire once or repeatedly.
///
/// The timer counts down from the specified duration to 0.
/// When the timer reaches 0, the timer invokes the specified callback function.
/// Use a periodic timer to repeatedly count down the same interval.
///
/// A negative duration is treated the same as a duration of 0.
/// If the duration is statically known to be 0, consider using [run].
///
/// ```dart
/// void main() {
/// Timer(const Duration(seconds: 5), handleTimeout);
/// }
///
/// void handleTimeout() { // callback function
/// // Do some work.
/// }
/// ```
/// **Note:** If Dart code using [Timer] is compiled to JavaScript, the finest
/// granularity available in the browser is 4 milliseconds.
///
/// See also:
/// * [Stopwatch] for measuring elapsed time.
@vmIsolateUnsendable
abstract interface class Timer {
/// Creates a new timer.
///
/// The [callback] function is invoked after the given [duration].
///
/// Example:
/// ```dart
/// final timer =
/// Timer(const Duration(seconds: 5), () => print('Timer finished'));
/// // Outputs after 5 seconds: "Timer finished".
/// ```
factory Timer(Duration duration, void Function() callback) {
if (Zone.current == Zone.root) {
// No need to bind the callback. We know that the root's timer will
// be invoked in the root zone.
return Zone.current.createTimer(duration, callback);
}
return Zone.current
.createTimer(duration, Zone.current.bindCallbackGuarded(callback));
}
/// Creates a new repeating timer.
///
/// The [callback] is invoked repeatedly with [duration] intervals until
/// canceled with the [cancel] function.
///
/// The exact timing depends on the underlying timer implementation.
/// No more than `n` callbacks will be made in `duration * n` time,
/// but the time between two consecutive callbacks
/// can be shorter and longer than `duration`.
///
/// In particular, an implementation may schedule the next callback, e.g.,
/// a `duration` after either when the previous callback ended,
/// when the previous callback started, or when the previous callback was
/// scheduled for - even if the actual callback was delayed.
///
/// [duration] must a non-negative [Duration].
///
/// Example:
/// ```dart
/// var counter = 3;
/// Timer.periodic(const Duration(seconds: 2), (timer) {
/// print(timer.tick);
/// counter--;
/// if (counter == 0) {
/// print('Cancel timer');
/// timer.cancel();
/// }
/// });
/// // Outputs:
/// // 1
/// // 2
/// // 3
/// // "Cancel timer"
/// ```
factory Timer.periodic(Duration duration, void callback(Timer timer)) {
if (Zone.current == Zone.root) {
// No need to bind the callback. We know that the root's timer will
// be invoked in the root zone.
return Zone.current.createPeriodicTimer(duration, callback);
}
var boundCallback = Zone.current.bindUnaryCallbackGuarded<Timer>(callback);
return Zone.current.createPeriodicTimer(duration, boundCallback);
}
/// Runs the given [callback] asynchronously as soon as possible.
///
/// This function is equivalent to `new Timer(Duration.zero, callback)`.
///
/// Example:
/// ```dart
/// Timer.run(() => print('timer run'));
/// ```
static void run(void Function() callback) {
new Timer(Duration.zero, callback);
}
/// Cancels the timer.
///
/// Once a [Timer] has been canceled, the callback function will not be called
/// by the timer. Calling [cancel] more than once on a [Timer] is allowed, and
/// will have no further effect.
///
/// Example:
/// ```dart
/// final timer =
/// Timer(const Duration(seconds: 5), () => print('Timer finished'));
/// // Cancel timer, callback never called.
/// timer.cancel();
/// ```
void cancel();
/// The number of durations preceding the most recent timer event.
///
/// The value starts at zero and is incremented each time a timer event
/// occurs, so each callback will see a larger value than the previous one.
///
/// If a periodic timer with a non-zero duration is delayed too much,
/// so more than one tick should have happened,
/// all but the last tick in the past are considered "missed",
/// and no callback is invoked for them.
/// The [tick] count reflects the number of durations that have passed and
/// not the number of callback invocations that have happened.
///
/// Example:
/// ```dart
/// final stopwatch = Stopwatch()..start();
/// Timer.periodic(const Duration(seconds: 1), (timer) {
/// print(timer.tick);
/// if (timer.tick == 1) {
/// while (stopwatch.elapsedMilliseconds < 4500) {
/// // Run uninterrupted for another 3.5 seconds!
/// // The latest due tick after that is the 4-second tick.
/// }
/// } else {
/// timer.cancel();
/// }
/// });
/// // Outputs:
/// // 1
/// // 4
/// ```
int get tick;
/// Returns whether the timer is still active.
///
/// A non-periodic timer is active if the callback has not been executed,
/// and the timer has not been canceled.
///
/// A periodic timer is active if it has not been canceled.
bool get isActive;
external static Timer _createTimer(
Duration duration, void Function() callback);
external static Timer _createPeriodicTimer(
Duration duration, void callback(Timer timer));
}