|
13 | 13 | @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
|
14 | 14 | public struct AsyncTimerSequence<C: Clock>: AsyncSequence {
|
15 | 15 | public typealias Element = C.Instant
|
16 |
| - |
| 16 | + |
17 | 17 | /// The iterator for an `AsyncTimerSequence` instance.
|
18 | 18 | public struct Iterator: AsyncIteratorProtocol {
|
19 | 19 | var clock: C?
|
20 | 20 | let interval: C.Instant.Duration
|
21 | 21 | let tolerance: C.Instant.Duration?
|
22 | 22 | var last: C.Instant?
|
23 |
| - |
| 23 | + |
24 | 24 | init(interval: C.Instant.Duration, tolerance: C.Instant.Duration?, clock: C) {
|
25 | 25 | self.clock = clock
|
26 | 26 | self.interval = interval
|
27 | 27 | self.tolerance = tolerance
|
28 | 28 | }
|
29 |
| - |
30 |
| - func nextDeadline(_ clock: C) -> C.Instant { |
31 |
| - let now = clock.now |
32 |
| - let last = self.last ?? now |
33 |
| - let next = last.advanced(by: interval) |
34 |
| - if next < now { |
35 |
| - return last.advanced(by: interval * Int(((next.duration(to: now)) / interval).rounded(.up))) |
36 |
| - } else { |
37 |
| - return next |
38 |
| - } |
39 |
| - } |
40 |
| - |
| 29 | + |
41 | 30 | public mutating func next() async -> C.Instant? {
|
42 |
| - guard let clock = clock else { |
| 31 | + guard let clock = self.clock else { |
43 | 32 | return nil
|
44 | 33 | }
|
45 |
| - let next = nextDeadline(clock) |
| 34 | + |
| 35 | + let next = (self.last ?? clock.now).advanced(by: self.interval) |
46 | 36 | do {
|
47 |
| - try await clock.sleep(until: next, tolerance: tolerance) |
| 37 | + try await clock.sleep(until: next, tolerance: self.tolerance) |
48 | 38 | } catch {
|
49 | 39 | self.clock = nil
|
50 | 40 | return nil
|
51 | 41 | }
|
52 | 42 | let now = clock.now
|
53 |
| - last = next |
| 43 | + self.last = next |
54 | 44 | return now
|
55 | 45 | }
|
56 | 46 | }
|
57 |
| - |
| 47 | + |
58 | 48 | let clock: C
|
59 | 49 | let interval: C.Instant.Duration
|
60 | 50 | let tolerance: C.Instant.Duration?
|
61 |
| - |
| 51 | + |
62 | 52 | /// Create an `AsyncTimerSequence` with a given repeating interval.
|
63 | 53 | public init(interval: C.Instant.Duration, tolerance: C.Instant.Duration? = nil, clock: C) {
|
64 | 54 | self.clock = clock
|
65 | 55 | self.interval = interval
|
66 | 56 | self.tolerance = tolerance
|
67 | 57 | }
|
68 |
| - |
| 58 | + |
69 | 59 | public func makeAsyncIterator() -> Iterator {
|
70 | 60 | Iterator(interval: interval, tolerance: tolerance, clock: clock)
|
71 | 61 | }
|
|
0 commit comments