- Notifications
You must be signed in to change notification settings - Fork 162
/
Copy pathAsyncTimerSequence.swift
91 lines (79 loc) · 2.92 KB
/
AsyncTimerSequence.swift
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
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Async Algorithms open source project
//
// Copyright (c) 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//
/// An `AsyncSequence` that produces elements at regular intervals.
@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0,*)
publicstructAsyncTimerSequence<C:Clock>:AsyncSequence{
publictypealiasElement=C.Instant
/// The iterator for an `AsyncTimerSequence` instance.
publicstructIterator:AsyncIteratorProtocol{
varclock:C?
letinterval:C.Instant.Duration
lettolerance:C.Instant.Duration?
varlast:C.Instant?
init(interval:C.Instant.Duration, tolerance:C.Instant.Duration?, clock:C){
self.clock = clock
self.interval = interval
self.tolerance = tolerance
}
publicmutatingfunc next()async->C.Instant?{
guardlet clock =self.clock else{
returnnil
}
letnext=(self.last ?? clock.now).advanced(by:self.interval)
do{
tryawait clock.sleep(until: next, tolerance:self.tolerance)
}catch{
self.clock =nil
returnnil
}
letnow= clock.now
self.last = next
return now
}
}
letclock:C
letinterval:C.Instant.Duration
lettolerance:C.Instant.Duration?
/// Create an `AsyncTimerSequence` with a given repeating interval.
publicinit(interval:C.Instant.Duration, tolerance:C.Instant.Duration?=nil, clock:C){
self.clock = clock
self.interval = interval
self.tolerance = tolerance
}
publicfunc makeAsyncIterator()->Iterator{
Iterator(interval: interval, tolerance: tolerance, clock: clock)
}
}
@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0,*)
extensionAsyncTimerSequence{
/// Create an `AsyncTimerSequence` with a given repeating interval.
publicstaticfunc repeating(
every interval:C.Instant.Duration,
tolerance:C.Instant.Duration?=nil,
clock:C
)->AsyncTimerSequence<C>{
returnAsyncTimerSequence(interval: interval, tolerance: tolerance, clock: clock)
}
}
@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0,*)
extensionAsyncTimerSequencewhere C ==SuspendingClock{
/// Create an `AsyncTimerSequence` with a given repeating interval.
publicstaticfunc repeating(
every interval:Duration,
tolerance:Duration?=nil
)->AsyncTimerSequence<SuspendingClock>{
returnAsyncTimerSequence(interval: interval, tolerance: tolerance, clock:SuspendingClock())
}
}
@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0,*)
extensionAsyncTimerSequence:Sendable{}
@available(*, unavailable)
extensionAsyncTimerSequence.Iterator:Sendable{}