@@ -48,16 +48,23 @@ public struct FlutterWindow {
4848 // MARK: - CFRunLoop API
4949
5050 private func _allocTimer( ) -> Timer {
51+ precondition ( viewController. view. frameRate != 0 )
5152 // note: frame rate is not in Hz, rather it's 1000*Hz (i.e. 60000 for 60Hz)
52- Timer (
53- timeInterval: TimeInterval ( 1000.0 ) / TimeInterval( viewController. view. frameRate) ,
53+ let framePeriod = TimeInterval ( 1000.0 ) / TimeInterval( viewController. view. frameRate)
54+
55+ return Timer (
56+ timeInterval: framePeriod,
5457 repeats: true
5558 ) { [ self ] timer in
5659 let waitDurationNS = viewController. engine. processMessages ( )
57- if waitDurationNS != Int64 . max {
60+
61+ if waitDurationNS > UInt64 ( framePeriod * TimeInterval( NanosecondsPerSecond) ) &&
62+ waitDurationNS < Int64 . max
63+ {
5864 timer. fireDate = Date . now
5965 . addingTimeInterval ( TimeInterval ( waitDurationNS) / TimeInterval( NanosecondsPerSecond) )
6066 }
67+
6168 guard viewController. view. dispatchEvent ( ) else {
6269 timer. invalidate ( )
6370 return
@@ -82,17 +89,20 @@ public struct FlutterWindow {
8289
8390 @MainActor
8491 public func run( ) async throws {
92+ precondition ( viewController. view. frameRate != 0 )
8593 let framePeriodNS =
8694 Int ( Double ( NanosecondsPerSecond) / ( Double ( viewController. view. frameRate) / 1000.0 ) )
8795
8896 repeat {
8997 var deadline : ContinuousClock . Instant = . now
9098 let waitDurationNS = viewController. engine. processMessages ( )
91- if waitDurationNS != Int64 . max {
99+
100+ if waitDurationNS > framePeriodNS && waitDurationNS < Int64 . max {
92101 deadline += . nanoseconds( waitDurationNS)
93102 } else {
94103 deadline += . nanoseconds( framePeriodNS)
95104 }
105+
96106 try await Task . sleep ( until: deadline)
97107 } while viewController. view. dispatchEvent ( )
98108 }
0 commit comments