|
47 | 47 | }
|
48 | 48 | }
|
49 | 49 | #endif
|
50 |
| - |
51 |
| -#if canImport(_Concurrency) && compiler(>=5.5.2) |
52 |
| - import Foundation |
53 |
| - import ReactiveSwift |
54 |
| - |
55 |
| - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, *) |
56 |
| - extension DateScheduler { |
57 |
| - |
58 |
| - /// Suspends the current task for at least the given duration. |
59 |
| - /// |
60 |
| - /// If the task is cancelled before the time ends, this function throws `CancellationError`. |
61 |
| - /// |
62 |
| - /// This function doesn't block the scheduler. |
63 |
| - /// |
64 |
| - /// ``` |
65 |
| - /// try await in scheduler.sleep(for: .seconds(1)) |
66 |
| - /// ``` |
67 |
| - /// |
68 |
| - /// - Parameters: |
69 |
| - /// - duration: The time interval on which to sleep between yielding. |
70 |
| - /// - leeway: The allowed timing variance when emitting events. Defaults to `.seconds(0)`. |
71 |
| - public func sleep( |
72 |
| - for interval: DispatchTimeInterval, |
73 |
| - leeway: DispatchTimeInterval = .seconds(0) |
74 |
| - ) async throws { |
75 |
| - try Task.checkCancellation() |
76 |
| - _ = await self.timer(interval: interval, leeway: leeway) |
77 |
| - .first { _ in true } |
78 |
| - try Task.checkCancellation() |
79 |
| - } |
80 |
| - |
81 |
| - /// Suspend task execution until a given deadline within a tolerance. |
82 |
| - /// |
83 |
| - /// If the task is cancelled before the time ends, this function throws `CancellationError`. |
84 |
| - /// |
85 |
| - /// This function doesn't block the scheduler. |
86 |
| - /// |
87 |
| - /// ``` |
88 |
| - /// try await in scheduler.sleep(until: scheduler.now + .seconds(1)) |
89 |
| - /// ``` |
90 |
| - /// - Parameters: |
91 |
| - /// - deadline: An instant of time to suspend until. |
92 |
| - /// - leeway: The allowed timing variance when emitting events. Defaults to `.seconds(0)`. |
93 |
| - public func sleep( |
94 |
| - until deadline: Date, |
95 |
| - leeway: DispatchTimeInterval = .seconds(0) |
96 |
| - ) async throws { |
97 |
| - precondition(deadline > currentDate) |
98 |
| - try await self.sleep( |
99 |
| - for: deadline.timeIntervalSince(currentDate).dispatchTimeInterval, |
100 |
| - leeway: leeway |
101 |
| - ) |
102 |
| - } |
103 |
| - |
104 |
| - /// Returns a stream that repeatedly yields the current time of the scheduler on a given interval. |
105 |
| - /// |
106 |
| - /// If the task is cancelled, the sequence will terminate. |
107 |
| - /// |
108 |
| - /// ``` |
109 |
| - /// for await instant in scheduler.timer(interval: .seconds(1)) { |
110 |
| - /// print("now:", instant) |
111 |
| - /// } |
112 |
| - /// ``` |
113 |
| - /// |
114 |
| - /// - Parameters: |
115 |
| - /// - interval: The time interval on which to sleep between yielding the current instant in |
116 |
| - /// time. For example, a value of `0.5` yields an instant approximately every half-second. |
117 |
| - /// - leeway: The allowed timing variance when emitting events. Defaults to `.seconds(0)`. |
118 |
| - /// - Returns: A stream that repeatedly yields the current time. |
119 |
| - public func timer( |
120 |
| - interval: DispatchTimeInterval, |
121 |
| - leeway: DispatchTimeInterval = .seconds(0) |
122 |
| - ) -> AsyncStream<Date> { |
123 |
| - .init { continuation in |
124 |
| - let disposable = self.schedule( |
125 |
| - after: currentDate.addingTimeInterval(interval.timeInterval), |
126 |
| - interval: interval, |
127 |
| - leeway: leeway |
128 |
| - ) { |
129 |
| - continuation.yield(self.currentDate) |
130 |
| - } |
131 |
| - continuation.onTermination = |
132 |
| - { _ in |
133 |
| - disposable?.dispose() |
134 |
| - } |
135 |
| - // NB: This explicit cast is needed to work around a compiler bug in Swift 5.5.2 |
136 |
| - as @Sendable (AsyncStream<Date>.Continuation.Termination) -> Void |
137 |
| - } |
138 |
| - } |
139 |
| - } |
140 |
| - |
141 |
| - extension DispatchTimeInterval { |
142 |
| - |
143 |
| - var timeInterval: TimeInterval { |
144 |
| - switch self { |
145 |
| - case let .seconds(s): |
146 |
| - return TimeInterval(s) |
147 |
| - case let .milliseconds(ms): |
148 |
| - return TimeInterval(TimeInterval(ms) / 1000.0) |
149 |
| - case let .microseconds(us): |
150 |
| - return TimeInterval(Int64(us)) * TimeInterval(NSEC_PER_USEC) / TimeInterval(NSEC_PER_SEC) |
151 |
| - case let .nanoseconds(ns): |
152 |
| - return TimeInterval(ns) / TimeInterval(NSEC_PER_SEC) |
153 |
| - case .never: |
154 |
| - return .infinity |
155 |
| - @unknown default: |
156 |
| - return .infinity |
157 |
| - } |
158 |
| - } |
159 |
| - } |
160 |
| - |
161 |
| - extension TimeInterval { |
162 |
| - |
163 |
| - var dispatchTimeInterval: DispatchTimeInterval { |
164 |
| - .nanoseconds(Int(self * TimeInterval(NSEC_PER_SEC))) |
165 |
| - } |
166 |
| - } |
167 |
| -#endif |
0 commit comments