|
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