22import Foundation
33import UIKit
44
5- public typealias Timer = DispatchTimer
5+ open class DispatcherTimer {
66
7- public class DispatchTimer {
8-
9- public convenience init ( _ delay: CGFloat , _ callback: Void -> Void ) {
7+ public convenience init ( _ delay: CGFloat , _ callback: @escaping ( Void ) -> Void ) {
108 self . init ( delay, 0 , callback)
119 }
1210
13- public init ( _ delay: CGFloat , _ tolerance: CGFloat , _ callback: Void -> Void ) {
11+ public init ( _ delay: CGFloat , _ tolerance: CGFloat , _ callback: @escaping ( Void ) -> Void ) {
1412 self . callback = callback
1513 self . tolerance = tolerance
1614
@@ -20,57 +18,65 @@ public class DispatchTimer {
2018 }
2119
2220 self . callbackQueue = gcd. current
23- self . timer = dispatch_source_create ( DISPATCH_SOURCE_TYPE_TIMER , 0 , 0 , queue. dispatch_queue)
21+ self . timer = DispatchSource . makeTimerSource ( flags : DispatchSource . TimerFlags ( rawValue : 0 ) , queue : queue. dispatch_queue)
2422
25- if !gcd. main. isCurrent { dispatch_set_target_queue ( queue. dispatch_queue, gcd. current. dispatch_queue) }
23+ if !gcd. main. isCurrent {
24+ if let dispatch_queue = gcd. current? . dispatch_queue {
25+ queue. dispatch_queue. setTarget ( queue: dispatch_queue)
26+ }
27+ }
2628
2729 let delay_ns = delay * CGFloat( NSEC_PER_SEC)
28- let time = dispatch_time ( DISPATCH_TIME_NOW, Int64 ( delay_ns) )
29- dispatch_source_set_timer ( timer, time, UInt64 ( delay_ns) , UInt64 ( tolerance * CGFloat( NSEC_PER_SEC) ) )
30- dispatch_source_set_event_handler ( timer) { [ weak self] in let _ = self ? . fire ( ) }
31- dispatch_resume ( timer)
30+ let time = DispatchTime . now ( ) + Double( delay)
31+
32+ let interval = DispatchTimeInterval . nanoseconds ( Int ( delay_ns) )
33+ let leeway = DispatchTimeInterval . nanoseconds ( Int ( UInt64 ( tolerance * CGFloat( NSEC_PER_SEC) ) ) )
34+
35+ timer? . scheduleRepeating ( deadline: time, interval: interval, leeway: leeway)
36+ timer? . setEventHandler { [ weak self] in let _ = self ? . fire ( ) }
37+ timer? . resume ( )
3238 }
3339
3440 // MARK: Read-only
3541
36- public let tolerance : CGFloat
42+ open let tolerance : CGFloat
3743
38- public let callback : Void -> Void
44+ open let callback : ( Void ) -> Void
3945
4046 // MARK: Instance methods
4147
42- public func doRepeat ( times: UInt ! = nil ) {
48+ open func doRepeat ( _ times: UInt ! = nil ) {
4349 isRepeating = true
4450 repeatsLeft = times != nil ? Int ( times) : - 1
4551 }
4652
47- public func autorelease ( ) {
53+ open func autorelease ( ) {
4854 isAutoReleased = true
4955 autoReleasedTimers [ ObjectIdentifier ( self ) ] = self
5056 }
5157
52- public func fire ( ) {
58+ open func fire ( ) {
5359 if OSAtomicAnd32OrigBarrier ( 1 , & invalidated) == 1 { return }
54- callbackQueue. sync ( callback)
60+ callbackQueue? . sync ( callback)
5561 if isRepeating && repeatsLeft > 0 {
5662 repeatsLeft -= 1
5763 }
5864 if !isRepeating || repeatsLeft == 0 { stop ( ) }
5965 }
6066
61- public func stop ( ) {
67+ open func stop ( ) {
6268 if OSAtomicTestAndSetBarrier ( 7 , & invalidated) { return }
63- queue. sync ( { dispatch_source_cancel ( self . timer) } )
69+ queue. sync ( { self . timer? . cancel ( ) } )
6470 if isAutoReleased { autoReleasedTimers [ ObjectIdentifier ( self ) ] = nil }
6571 }
6672
6773 // MARK: Internal
6874
69- var timer : dispatch_source_t !
75+ var timer : DispatchSourceTimer ?
7076
71- let queue : DispatchQueue = gcd. serial ( )
77+ let queue : DispatcherQueue = gcd. serial ( )
7278
73- var callbackQueue : DispatchQueue !
79+ var callbackQueue : DispatcherQueue ?
7480
7581 var invalidated : UInt32 = 0
7682
@@ -85,4 +91,4 @@ public class DispatchTimer {
8591 }
8692}
8793
88- var autoReleasedTimers = [ ObjectIdentifier: Timer ] ( )
94+ var autoReleasedTimers = [ ObjectIdentifier: DispatcherTimer ] ( )
0 commit comments