From a4ea8e529d4aaff460e46e076e06b14f2ba18a84 Mon Sep 17 00:00:00 2001 From: Krunoslav Zaher Date: Sun, 14 Apr 2019 15:44:53 +0200 Subject: [PATCH] Migrates `Scheduler` API to `DispatchTimeInterval` and deprecate versions using `Foundation.TimeInterval`. --- Rx.xcodeproj/project.pbxproj | 4 + RxBlocking/BlockingObservable.swift | 3 +- .../ObservableConvertibleType+Blocking.swift | 3 +- RxBlocking/RunLoopLock.swift | 6 +- RxCocoa/Deprecated.swift | 85 +++++ RxSwift/Date+Dispatch.swift | 65 ++++ RxSwift/Deprecated.swift | 317 ++++++++++++++++++ RxSwift/Observables/Delay.swift | 5 +- RxSwift/Observables/Throttle.swift | 13 +- RxSwift/SchedulerType.swift | 4 +- .../ConcurrentDispatchQueueScheduler.swift | 4 +- .../Schedulers/ConcurrentMainScheduler.swift | 4 +- .../HistoricalSchedulerTimeConverter.swift | 8 +- .../Internal/DispatchQueueConfiguration.swift | 17 +- .../SerialDispatchQueueScheduler.swift | 4 +- .../Schedulers/VirtualTimeConverterType.swift | 6 +- RxSwift/Schedulers/VirtualTimeScheduler.swift | 4 +- RxSwift/Traits/Single.swift | 31 +- .../TestSchedulerVirtualTimeConverter.swift | 10 +- Tests/RxSwiftTests/Anomalies.swift | 8 +- .../HistoricalSchedulerTest.swift | 28 +- Tests/RxSwiftTests/Observable+AmbTests.swift | 8 +- .../RxSwiftTests/Observable+DelayTests.swift | 6 +- .../Observable+GroupByTests.swift | 4 +- .../Observable+RetryWhenTests.swift | 2 +- .../Observable+SkipUntilTests.swift | 8 +- Tests/RxSwiftTests/SchedulerTests.swift | 8 +- .../TestVirtualScheduler.swift | 8 +- Tests/RxSwiftTests/VirtualSchedulerTest.swift | 30 +- 29 files changed, 568 insertions(+), 135 deletions(-) create mode 100644 RxSwift/Date+Dispatch.swift diff --git a/Rx.xcodeproj/project.pbxproj b/Rx.xcodeproj/project.pbxproj index 7a2667dc6..e7e9a02bc 100644 --- a/Rx.xcodeproj/project.pbxproj +++ b/Rx.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ 1E3079AC21FB52330072A7E6 /* AtomicTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E3079AB21FB52330072A7E6 /* AtomicTests.swift */; }; 1E3079AD21FB52330072A7E6 /* AtomicTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E3079AB21FB52330072A7E6 /* AtomicTests.swift */; }; 1E3079AE21FB52330072A7E6 /* AtomicTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E3079AB21FB52330072A7E6 /* AtomicTests.swift */; }; + 1E3EDF65226356A000B631B9 /* Date+Dispatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E3EDF64226356A000B631B9 /* Date+Dispatch.swift */; }; 1E9DA0C522006858000EB80A /* Synchronized.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9DA0C422006858000EB80A /* Synchronized.swift */; }; 1E9DA0C622006858000EB80A /* Synchronized.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9DA0C422006858000EB80A /* Synchronized.swift */; }; 1E9DA0C722006858000EB80A /* Synchronized.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9DA0C422006858000EB80A /* Synchronized.swift */; }; @@ -927,6 +928,7 @@ 1AF67DA11CED420A00C310FA /* PublishSubjectTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PublishSubjectTest.swift; sourceTree = ""; }; 1AF67DA51CED430100C310FA /* ReplaySubjectTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplaySubjectTest.swift; sourceTree = ""; }; 1E3079AB21FB52330072A7E6 /* AtomicTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicTests.swift; sourceTree = ""; }; + 1E3EDF64226356A000B631B9 /* Date+Dispatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+Dispatch.swift"; sourceTree = ""; }; 1E9DA0C422006858000EB80A /* Synchronized.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Synchronized.swift; sourceTree = ""; }; 25F6ECBB1F48C366008552FA /* Maybe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Maybe.swift; sourceTree = ""; }; 25F6ECBD1F48C373008552FA /* Completable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Completable.swift; sourceTree = ""; }; @@ -1569,6 +1571,7 @@ C81A09851E6C701700900B3B /* Traits */, C8093C661B8A72BE0088E94D /* Info.plist */, C81A09801E6C6B2400900B3B /* Deprecated.swift */, + 1E3EDF64226356A000B631B9 /* Date+Dispatch.swift */, ); path = RxSwift; sourceTree = ""; @@ -3678,6 +3681,7 @@ C820A87C1EB4DA5A00D431BC /* TakeWhile.swift in Sources */, C8093D6B1B8A72BE0088E94D /* AnonymousObserver.swift in Sources */, C8093DA11B8A72BE0088E94D /* PublishSubject.swift in Sources */, + 1E3EDF65226356A000B631B9 /* Date+Dispatch.swift in Sources */, C83D73C81C1DBAEE003DC470 /* ScheduledItemType.swift in Sources */, C820A8C41EB4DA5A00D431BC /* CombineLatest+Collection.swift in Sources */, C820A9301EB4DA5A00D431BC /* Producer.swift in Sources */, diff --git a/RxBlocking/BlockingObservable.swift b/RxBlocking/BlockingObservable.swift index 74f6e8858..5e3f170fb 100644 --- a/RxBlocking/BlockingObservable.swift +++ b/RxBlocking/BlockingObservable.swift @@ -6,6 +6,7 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // +import Foundation import RxSwift /** @@ -17,6 +18,6 @@ If you think you need to use a `BlockingObservable` this is usually a sign that design. */ public struct BlockingObservable { - let timeout: RxTimeInterval? + let timeout: TimeInterval? let source: Observable } diff --git a/RxBlocking/ObservableConvertibleType+Blocking.swift b/RxBlocking/ObservableConvertibleType+Blocking.swift index b6d43cf50..7f3ade733 100644 --- a/RxBlocking/ObservableConvertibleType+Blocking.swift +++ b/RxBlocking/ObservableConvertibleType+Blocking.swift @@ -7,13 +7,14 @@ // import RxSwift +import Foundation extension ObservableConvertibleType { /// Converts an Observable into a `BlockingObservable` (an Observable with blocking operators). /// /// - parameter timeout: Maximal time interval BlockingObservable can block without throwing `RxError.timeout`. /// - returns: `BlockingObservable` version of `self` - public func toBlocking(timeout: RxTimeInterval? = nil) -> BlockingObservable { + public func toBlocking(timeout: TimeInterval? = nil) -> BlockingObservable { return BlockingObservable(timeout: timeout, source: self.asObservable()) } } diff --git a/RxBlocking/RunLoopLock.swift b/RxBlocking/RunLoopLock.swift index a6ac32e6d..f86668e69 100644 --- a/RxBlocking/RunLoopLock.swift +++ b/RxBlocking/RunLoopLock.swift @@ -7,7 +7,7 @@ // import CoreFoundation - +import Foundation import RxSwift #if os(Linux) @@ -29,9 +29,9 @@ final class RunLoopLock { let _calledRun = AtomicInt(0) let _calledStop = AtomicInt(0) - var _timeout: RxTimeInterval? + var _timeout: TimeInterval? - init(timeout: RxTimeInterval?) { + init(timeout: TimeInterval?) { self._timeout = timeout self._currentRunLoop = CFRunLoopGetCurrent() } diff --git a/RxCocoa/Deprecated.swift b/RxCocoa/Deprecated.swift index 560319255..809f13806 100644 --- a/RxCocoa/Deprecated.swift +++ b/RxCocoa/Deprecated.swift @@ -499,4 +499,89 @@ extension ObservableType { } } +// MARK: throttle +extension SharedSequenceConvertibleType { + /** + Returns an Observable that emits the first and the latest item emitted by the source Observable during sequential time windows of a specified duration. + + This operator makes sure that no two elements are emitted in less then dueTime. + + - seealso: [debounce operator on reactivex.io](http://reactivex.io/documentation/operators/debounce.html) + + - parameter dueTime: Throttling duration for each element. + - parameter latest: Should latest element received in a dueTime wide time window since last element emission be emitted. + - returns: The throttled sequence. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "timeout(_:latest:)") + public func throttle(_ dueTime: Foundation.TimeInterval, latest: Bool = true) + -> SharedSequence { + return throttle(.milliseconds(Int(dueTime * 1000.0)), latest: latest) + } + + /** + Ignores elements from an observable sequence which are followed by another element within a specified relative time duration, using the specified scheduler to run throttling timers. + + - parameter dueTime: Throttling duration for each element. + - returns: The throttled sequence. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "debounce(_:)") + public func debounce(_ dueTime: Foundation.TimeInterval) + -> SharedSequence { + return debounce(.milliseconds(Int(dueTime * 1000.0))) + } +} + +// MARK: delay +extension SharedSequenceConvertibleType { + + /** + Returns an observable sequence by the source observable sequence shifted forward in time by a specified delay. Error events from the source observable sequence are not delayed. + + - seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html) + + - parameter dueTime: Relative time shift of the source by. + - parameter scheduler: Scheduler to run the subscription delay timer on. + - returns: the source Observable shifted in time by the specified delay. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "delay(_:)") + public func delay(_ dueTime: Foundation.TimeInterval) + -> SharedSequence { + return delay(.milliseconds(Int(dueTime * 1000.0))) + } +} + +extension SharedSequence where Element : RxAbstractInteger { + /** + Returns an observable sequence that produces a value after each period, using the specified scheduler to run timers and to send out observer messages. + + - seealso: [interval operator on reactivex.io](http://reactivex.io/documentation/operators/interval.html) + + - parameter period: Period for producing the values in the resulting sequence. + - returns: An observable sequence that produces a value after each period. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "interval(_:)") + public static func interval(_ period: Foundation.TimeInterval) + -> SharedSequence { + return interval(.milliseconds(Int(period * 1000.0))) + } +} + +// MARK: timer + +extension SharedSequence where Element: RxAbstractInteger { + /** + Returns an observable sequence that periodically produces a value after the specified initial relative due time has elapsed, using the specified scheduler to run timers. + + - seealso: [timer operator on reactivex.io](http://reactivex.io/documentation/operators/timer.html) + + - parameter dueTime: Relative time at which to produce the first value. + - parameter period: Period to produce subsequent values. + - returns: An observable sequence that produces a value after due time has elapsed and then each period. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "timer(_:)") + public static func timer(_ dueTime: Foundation.TimeInterval, period: Foundation.TimeInterval) + -> SharedSequence { + return timer(.milliseconds(Int(dueTime * 1000.0)), period: .milliseconds(Int(period * 1000.0))) + } +} diff --git a/RxSwift/Date+Dispatch.swift b/RxSwift/Date+Dispatch.swift new file mode 100644 index 000000000..d8282ec7a --- /dev/null +++ b/RxSwift/Date+Dispatch.swift @@ -0,0 +1,65 @@ +// +// Date+Dispatch.swift +// RxSwift +// +// Created by Krunoslav Zaher on 4/14/19. +// Copyright © 2019 Krunoslav Zaher. All rights reserved. +// + +import struct Foundation.Date +import struct Foundation.TimeInterval +import enum Dispatch.DispatchTimeInterval + +extension DispatchTimeInterval { + var convertToSecondsFactor: Double { + switch self { + case .nanoseconds: return 1_000_000_000.0 + case .microseconds: return 1_000_000.0 + case .milliseconds: return 1_000.0 + case .seconds: return 1.0 + case .never: fatalError() + @unknown default: fatalError() + } + } + + func map(_ transform: (Int, Double) -> Int) -> DispatchTimeInterval { + switch self { + case .nanoseconds(let value): return .nanoseconds(transform(value, 1_000_000_000.0)) + case .microseconds(let value): return .microseconds(transform(value, 1_000_000.0)) + case .milliseconds(let value): return .milliseconds(transform(value, 1_000.0)) + case .seconds(let value): return .seconds(transform(value, 1.0)) + case .never: return .never + @unknown default: fatalError() + } + } + + var isNow: Bool { + switch self { + case .nanoseconds(let value), .microseconds(let value), .milliseconds(let value), .seconds(let value): return value == 0 + case .never: return false + @unknown default: fatalError() + } + } + + internal func reduceWithSpanBetween(earlierDate: Date, laterDate: Date) -> DispatchTimeInterval { + return self.map { value, factor in + let interval = laterDate.timeIntervalSince(earlierDate) + let remainder = Double(value) - interval * factor + guard remainder > 0 else { return 0 } + return Int(remainder) + } + } +} + +extension Date { + + internal func addingDispatchInterval(_ dispatchInterval: DispatchTimeInterval) -> Date { + switch dispatchInterval { + case .nanoseconds(let value), .microseconds(let value), .milliseconds(let value), .seconds(let value): + return self.addingTimeInterval(TimeInterval(value) / dispatchInterval.convertToSecondsFactor) + case .never: return Date.distantFuture + @unknown default: fatalError() + } + } + +} diff --git a/RxSwift/Deprecated.swift b/RxSwift/Deprecated.swift index 57ac62f36..830a64dd4 100644 --- a/RxSwift/Deprecated.swift +++ b/RxSwift/Deprecated.swift @@ -6,6 +6,8 @@ // Copyright © 2017 Krunoslav Zaher. All rights reserved. // +import Foundation + extension Observable { /** Converts a optional to an observable sequence. @@ -223,3 +225,318 @@ public final class Variable { self._subject.on(.completed) } } + +extension ObservableType { + /** + Returns an observable sequence by the source observable sequence shifted forward in time by a specified delay. Error events from the source observable sequence are not delayed. + + - seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html) + + - parameter dueTime: Relative time shift of the source by. + - parameter scheduler: Scheduler to run the subscription delay timer on. + - returns: the source Observable shifted in time by the specified delay. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "delay(_:scheduler:)") + public func delay(_ dueTime: Foundation.TimeInterval, scheduler: SchedulerType) + -> Observable { + return self.delay(.milliseconds(Int(dueTime * 1000.0)), scheduler: scheduler) + } +} + +extension ObservableType { + + /** + Applies a timeout policy for each element in the observable sequence. If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutError is propagated to the observer. + + - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) + + - parameter dueTime: Maximum duration between values before a timeout occurs. + - parameter scheduler: Scheduler to run the timeout timer on. + - returns: An observable sequence with a `RxError.timeout` in case of a timeout. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "timeout(_:scheduler:)") + public func timeout(_ dueTime: Foundation.TimeInterval, scheduler: SchedulerType) + -> Observable { + return timeout(.milliseconds(Int(dueTime * 1000.0)), scheduler: scheduler) + } + + /** + Applies a timeout policy for each element in the observable sequence, using the specified scheduler to run timeout timers. If the next element isn't received within the specified timeout duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on. + + - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) + + - parameter dueTime: Maximum duration between values before a timeout occurs. + - parameter other: Sequence to return in case of a timeout. + - parameter scheduler: Scheduler to run the timeout timer on. + - returns: The source sequence switching to the other sequence in case of a timeout. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "timeout(_:other:scheduler:)") + public func timeout(_ dueTime: Foundation.TimeInterval, other: O, scheduler: SchedulerType) + -> Observable where E == O.E { + return timeout(.milliseconds(Int(dueTime * 1000.0)), other: other, scheduler: scheduler) + } +} + +extension ObservableType { + + /** + Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers. + + - seealso: [skip operator on reactivex.io](http://reactivex.io/documentation/operators/skip.html) + + - parameter duration: Duration for skipping elements from the start of the sequence. + - parameter scheduler: Scheduler to run the timer on. + - returns: An observable sequence with the elements skipped during the specified duration from the start of the source sequence. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "skip(_:scheduler:)") + public func skip(_ duration: Foundation.TimeInterval, scheduler: SchedulerType) + -> Observable { + return skip(.milliseconds(Int(duration * 1000.0)), scheduler: scheduler) + } +} + +extension ObservableType where E : RxAbstractInteger { + /** + Returns an observable sequence that produces a value after each period, using the specified scheduler to run timers and to send out observer messages. + + - seealso: [interval operator on reactivex.io](http://reactivex.io/documentation/operators/interval.html) + + - parameter period: Period for producing the values in the resulting sequence. + - parameter scheduler: Scheduler to run the timer on. + - returns: An observable sequence that produces a value after each period. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "interval(_:scheduler:)") + public static func interval(_ period: Foundation.TimeInterval, scheduler: SchedulerType) + -> Observable { + return interval(.milliseconds(Int(period * 1000.0)), scheduler: scheduler) + } +} + +extension ObservableType where E: RxAbstractInteger { + /** + Returns an observable sequence that periodically produces a value after the specified initial relative due time has elapsed, using the specified scheduler to run timers. + + - seealso: [timer operator on reactivex.io](http://reactivex.io/documentation/operators/timer.html) + + - parameter dueTime: Relative time at which to produce the first value. + - parameter period: Period to produce subsequent values. + - parameter scheduler: Scheduler to run timers on. + - returns: An observable sequence that produces a value after due time has elapsed and then each period. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "timer(_:period:scheduler:)") + public static func timer(_ dueTime: Foundation.TimeInterval, period: Foundation.TimeInterval? = nil, scheduler: SchedulerType) + -> Observable { + return timer(.milliseconds(Int(dueTime * 1000.0)), period: period.map { .milliseconds(Int($0 * 1000.0)) }, scheduler: scheduler) + } +} + +extension ObservableType { + + /** + Returns an Observable that emits the first and the latest item emitted by the source Observable during sequential time windows of a specified duration. + + This operator makes sure that no two elements are emitted in less then dueTime. + + - seealso: [debounce operator on reactivex.io](http://reactivex.io/documentation/operators/debounce.html) + + - parameter dueTime: Throttling duration for each element. + - parameter latest: Should latest element received in a dueTime wide time window since last element emission be emitted. + - parameter scheduler: Scheduler to run the throttle timers on. + - returns: The throttled sequence. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "throttle(_:latest:scheduler:)") + public func throttle(_ dueTime: Foundation.TimeInterval, latest: Bool = true, scheduler: SchedulerType) + -> Observable { + return throttle(.milliseconds(Int(dueTime * 1000.0)), latest: latest, scheduler: scheduler) + } +} + +extension ObservableType { + + /** + Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers. + + - seealso: [take operator on reactivex.io](http://reactivex.io/documentation/operators/take.html) + + - parameter duration: Duration for taking elements from the start of the sequence. + - parameter scheduler: Scheduler to run the timer on. + - returns: An observable sequence with the elements taken during the specified duration from the start of the source sequence. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "take(_:scheduler:)") + public func take(_ duration: Foundation.TimeInterval, scheduler: SchedulerType) + -> Observable { + return take(.milliseconds(Int(duration * 1000.0)), scheduler: scheduler) + } +} + + +extension ObservableType { + + /** + Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers. + + - seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html) + + - parameter dueTime: Relative time shift of the subscription. + - parameter scheduler: Scheduler to run the subscription delay timer on. + - returns: Time-shifted sequence. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "delaySubscription(_:scheduler:)") + public func delaySubscription(_ dueTime: Foundation.TimeInterval, scheduler: SchedulerType) + -> Observable { + return delaySubscription(.milliseconds(Int(dueTime * 1000.0)), scheduler: scheduler) + } +} + +extension ObservableType { + + /** + Projects each element of an observable sequence into a window that is completed when either it’s full or a given amount of time has elapsed. + + - seealso: [window operator on reactivex.io](http://reactivex.io/documentation/operators/window.html) + + - parameter timeSpan: Maximum time length of a window. + - parameter count: Maximum element count of a window. + - parameter scheduler: Scheduler to run windowing timers on. + - returns: An observable sequence of windows (instances of `Observable`). + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "window(_:)") + public func window(timeSpan: Foundation.TimeInterval, count: Int, scheduler: SchedulerType) + -> Observable> { + return window(timeSpan: .milliseconds(Int(timeSpan * 1000.0)), count: count, scheduler: scheduler) + } +} + + +extension PrimitiveSequence { + /** + Returns an observable sequence by the source observable sequence shifted forward in time by a specified delay. Error events from the source observable sequence are not delayed. + + - seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html) + + - parameter dueTime: Relative time shift of the source by. + - parameter scheduler: Scheduler to run the subscription delay timer on. + - returns: the source Observable shifted in time by the specified delay. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "delay(_:scheduler:)") + public func delay(_ dueTime: Foundation.TimeInterval, scheduler: SchedulerType) + -> PrimitiveSequence { + return delay(.milliseconds(Int(dueTime * 1000.0)), scheduler: scheduler) + } + + /** + Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers. + + - seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html) + + - parameter dueTime: Relative time shift of the subscription. + - parameter scheduler: Scheduler to run the subscription delay timer on. + - returns: Time-shifted sequence. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "delaySubscription(_:scheduler:)") + public func delaySubscription(_ dueTime: Foundation.TimeInterval, scheduler: SchedulerType) + -> PrimitiveSequence { + return delaySubscription(.milliseconds(Int(dueTime * 1000.0)), scheduler: scheduler) + } + + /** + Applies a timeout policy for each element in the observable sequence. If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutError is propagated to the observer. + + - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) + + - parameter dueTime: Maximum duration between values before a timeout occurs. + - parameter scheduler: Scheduler to run the timeout timer on. + - returns: An observable sequence with a `RxError.timeout` in case of a timeout. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "timeout(_:scheduler:)") + public func timeout(_ dueTime: Foundation.TimeInterval, scheduler: SchedulerType) + -> PrimitiveSequence { + return timeout(.milliseconds(Int(dueTime * 1000.0)), scheduler: scheduler) + } + + /** + Applies a timeout policy for each element in the observable sequence, using the specified scheduler to run timeout timers. If the next element isn't received within the specified timeout duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on. + + - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) + + - parameter dueTime: Maximum duration between values before a timeout occurs. + - parameter other: Sequence to return in case of a timeout. + - parameter scheduler: Scheduler to run the timeout timer on. + - returns: The source sequence switching to the other sequence in case of a timeout. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "timeout(_:other:scheduler:)") + public func timeout(_ dueTime: Foundation.TimeInterval, + other: PrimitiveSequence, + scheduler: SchedulerType) -> PrimitiveSequence { + return timeout(.milliseconds(Int(dueTime * 1000.0)), other: other, scheduler: scheduler) + } +} + +extension PrimitiveSequenceType where TraitType == SingleTrait { + + /** + Invokes an action for each event in the observable sequence, and propagates all observer messages through the result sequence. + + - seealso: [do operator on reactivex.io](http://reactivex.io/documentation/operators/do.html) + + - parameter onNext: Action to invoke for each element in the observable sequence. + - parameter onError: Action to invoke upon errored termination of the observable sequence. + - parameter onSubscribe: Action to invoke before subscribing to source observable sequence. + - parameter onSubscribed: Action to invoke after subscribing to source observable sequence. + - parameter onDispose: Action to invoke after subscription to source observable has been disposed for any reason. It can be either because sequence terminates for some reason or observer subscription being disposed. + - returns: The source sequence with the side-effecting behavior applied. + */ + @available(*, deprecated, renamed: "do(onSuccess:onError:onSubscribe:onSubscribed:onDispose:)") + public func `do`(onNext: ((ElementType) throws -> Void)?, + onError: ((Swift.Error) throws -> Void)? = nil, + onSubscribe: (() -> Void)? = nil, + onSubscribed: (() -> Void)? = nil, + onDispose: (() -> Void)? = nil) + -> Single { + return self.`do`( + onSuccess: onNext, + onError: onError, + onSubscribe: onSubscribe, + onSubscribed: onSubscribed, + onDispose: onDispose + ) + } +} + +extension ObservableType { + /** + Projects each element of an observable sequence into a buffer that's sent out when either it's full or a given amount of time has elapsed, using the specified scheduler to run timers. + + A useful real-world analogy of this overload is the behavior of a ferry leaving the dock when all seats are taken, or at the scheduled time of departure, whichever event occurs first. + + - seealso: [buffer operator on reactivex.io](http://reactivex.io/documentation/operators/buffer.html) + + - parameter timeSpan: Maximum time length of a buffer. + - parameter count: Maximum element count of a buffer. + - parameter scheduler: Scheduler to run buffering timers on. + - returns: An observable sequence of buffers. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "buffer(timeSpan:count:scheduler:)") + public func buffer(timeSpan: Foundation.TimeInterval, count: Int, scheduler: SchedulerType) + -> Observable<[E]> { + return buffer(timeSpan: .milliseconds(Int(timeSpan * 1000.0)), count: count, scheduler: scheduler) + } +} + +extension PrimitiveSequenceType where ElementType: RxAbstractInteger +{ + /** + Returns an observable sequence that periodically produces a value after the specified initial relative due time has elapsed, using the specified scheduler to run timers. + + - seealso: [timer operator on reactivex.io](http://reactivex.io/documentation/operators/timer.html) + + - parameter dueTime: Relative time at which to produce the first value. + - parameter scheduler: Scheduler to run timers on. + - returns: An observable sequence that produces a value after due time has elapsed and then each period. + */ + @available(*, deprecated, message: "Use DispatchTimeInterval overload instead.", renamed: "timer(_:scheduler:)") + public static func timer(_ dueTime: Foundation.TimeInterval, scheduler: SchedulerType) + -> PrimitiveSequence { + return timer(.milliseconds(Int(dueTime * 1000.0)), scheduler: scheduler) + } +} diff --git a/RxSwift/Observables/Delay.swift b/RxSwift/Observables/Delay.swift index 61969d5cf..b60e281c9 100644 --- a/RxSwift/Observables/Delay.swift +++ b/RxSwift/Observables/Delay.swift @@ -111,10 +111,7 @@ final private class DelaySink } } else if let nextEventToScheduleOriginalTime = nextEventToScheduleOriginalTime { - let elapsedTime = self._scheduler.now.timeIntervalSince(nextEventToScheduleOriginalTime) - let interval = self._dueTime - elapsedTime - let normalizedInterval = interval < 0.0 ? 0.0 : interval - scheduler.schedule((), dueTime: normalizedInterval) + scheduler.schedule((), dueTime: self._dueTime.reduceWithSpanBetween(earlierDate: nextEventToScheduleOriginalTime, laterDate: self._scheduler.now)) return } else { diff --git a/RxSwift/Observables/Throttle.swift b/RxSwift/Observables/Throttle.swift index c31ae7469..17d9c13cd 100644 --- a/RxSwift/Observables/Throttle.swift +++ b/RxSwift/Observables/Throttle.swift @@ -68,18 +68,16 @@ final private class ThrottleSink case .next(let element): let now = self._parent._scheduler.now - let timeIntervalSinceLast: RxTimeInterval + let reducedScheduledTime: RxTimeInterval if let lastSendingTime = self._lastSentTime { - timeIntervalSinceLast = now.timeIntervalSince(lastSendingTime) + reducedScheduledTime = self._parent._dueTime.reduceWithSpanBetween(earlierDate: lastSendingTime, laterDate: now) } else { - timeIntervalSinceLast = self._parent._dueTime + reducedScheduledTime = .nanoseconds(0) } - let couldSendNow = timeIntervalSinceLast >= self._parent._dueTime - - if couldSendNow { + if reducedScheduledTime.isNow { self.sendNow(element: element) return } @@ -97,12 +95,11 @@ final private class ThrottleSink } let scheduler = self._parent._scheduler - let dueTime = self._parent._dueTime let d = SingleAssignmentDisposable() self.cancellable.disposable = d - d.setDisposable(scheduler.scheduleRelative(0, dueTime: dueTime - timeIntervalSinceLast, action: self.propagate)) + d.setDisposable(scheduler.scheduleRelative(0, dueTime: reducedScheduledTime, action: self.propagate)) case .error: self._lastUnsentElement = nil self.forwardOn(event) diff --git a/RxSwift/SchedulerType.swift b/RxSwift/SchedulerType.swift index e09c499de..96664b492 100644 --- a/RxSwift/SchedulerType.swift +++ b/RxSwift/SchedulerType.swift @@ -6,11 +6,11 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import struct Foundation.TimeInterval +import enum Dispatch.DispatchTimeInterval import struct Foundation.Date // Type that represents time interval in the context of RxSwift. -public typealias RxTimeInterval = TimeInterval +public typealias RxTimeInterval = DispatchTimeInterval /// Type that represents absolute time in the context of RxSwift. public typealias RxTime = Date diff --git a/RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift b/RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift index ed2efbb16..ac51324bc 100644 --- a/RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift +++ b/RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift @@ -65,7 +65,7 @@ public class ConcurrentDispatchQueueScheduler: SchedulerType { - parameter action: Action to be executed. - returns: The disposable object used to cancel the scheduled action (best effort). */ - public final func scheduleRelative(_ state: StateType, dueTime: Foundation.TimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { + public final func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { return self.configuration.scheduleRelative(state, dueTime: dueTime, action: action) } @@ -78,7 +78,7 @@ public class ConcurrentDispatchQueueScheduler: SchedulerType { - parameter action: Action to be executed. - returns: The disposable object used to cancel the scheduled action (best effort). */ - public func schedulePeriodic(_ state: StateType, startAfter: TimeInterval, period: TimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { + public func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { return self.configuration.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) } } diff --git a/RxSwift/Schedulers/ConcurrentMainScheduler.swift b/RxSwift/Schedulers/ConcurrentMainScheduler.swift index 0d65b6cab..f535a2282 100644 --- a/RxSwift/Schedulers/ConcurrentMainScheduler.swift +++ b/RxSwift/Schedulers/ConcurrentMainScheduler.swift @@ -69,7 +69,7 @@ public final class ConcurrentMainScheduler : SchedulerType { - parameter action: Action to be executed. - returns: The disposable object used to cancel the scheduled action (best effort). */ - public final func scheduleRelative(_ state: StateType, dueTime: Foundation.TimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { + public final func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { return self._mainScheduler.scheduleRelative(state, dueTime: dueTime, action: action) } @@ -82,7 +82,7 @@ public final class ConcurrentMainScheduler : SchedulerType { - parameter action: Action to be executed. - returns: The disposable object used to cancel the scheduled action (best effort). */ - public func schedulePeriodic(_ state: StateType, startAfter: TimeInterval, period: TimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { + public func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { return self._mainScheduler.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) } } diff --git a/RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift b/RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift index 930ca3776..12eeb5c5c 100644 --- a/RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift +++ b/RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift @@ -6,7 +6,7 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import struct Foundation.Date +import Foundation /// Converts historical virtual time into real time. /// @@ -16,7 +16,7 @@ public struct HistoricalSchedulerTimeConverter : VirtualTimeConverterType { public typealias VirtualTimeUnit = RxTime /// Virtual time unit used to represent differences of virtual times. - public typealias VirtualTimeIntervalUnit = RxTimeInterval + public typealias VirtualTimeIntervalUnit = TimeInterval /// Returns identical value of argument passed because historical virtual time is equal to real time, just /// decoupled from local machine clock. @@ -32,13 +32,13 @@ public struct HistoricalSchedulerTimeConverter : VirtualTimeConverterType { /// Returns identical value of argument passed because historical virtual time is equal to real time, just /// decoupled from local machine clock. - public func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> RxTimeInterval { + public func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> TimeInterval { return virtualTimeInterval } /// Returns identical value of argument passed because historical virtual time is equal to real time, just /// decoupled from local machine clock. - public func convertToVirtualTimeInterval(_ timeInterval: RxTimeInterval) -> VirtualTimeIntervalUnit { + public func convertToVirtualTimeInterval(_ timeInterval: TimeInterval) -> VirtualTimeIntervalUnit { return timeInterval } diff --git a/RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift b/RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift index 792a0be29..bac5e9a18 100644 --- a/RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift +++ b/RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift @@ -14,13 +14,6 @@ struct DispatchQueueConfiguration { let leeway: DispatchTimeInterval } -private func dispatchInterval(_ interval: Foundation.TimeInterval) -> DispatchTimeInterval { - precondition(interval >= 0.0) - // TODO: Replace 1000 with something that actually works - // NSEC_PER_MSEC returns 1000000 - return DispatchTimeInterval.milliseconds(Int(interval * 1000.0)) -} - extension DispatchQueueConfiguration { func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { let cancel = SingleAssignmentDisposable() @@ -37,8 +30,8 @@ extension DispatchQueueConfiguration { return cancel } - func scheduleRelative(_ state: StateType, dueTime: Foundation.TimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { - let deadline = DispatchTime.now() + dispatchInterval(dueTime) + func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { + let deadline = DispatchTime.now() + dueTime let compositeDisposable = CompositeDisposable() @@ -71,13 +64,13 @@ extension DispatchQueueConfiguration { return compositeDisposable } - func schedulePeriodic(_ state: StateType, startAfter: TimeInterval, period: TimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { - let initial = DispatchTime.now() + dispatchInterval(startAfter) + func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { + let initial = DispatchTime.now() + startAfter var timerState = state let timer = DispatchSource.makeTimerSource(queue: self.queue) - timer.schedule(deadline: initial, repeating: dispatchInterval(period), leeway: self.leeway) + timer.schedule(deadline: initial, repeating: period, leeway: self.leeway) // TODO: // This looks horrible, and yes, it is. diff --git a/RxSwift/Schedulers/SerialDispatchQueueScheduler.swift b/RxSwift/Schedulers/SerialDispatchQueueScheduler.swift index 8adb57b30..57ae8bd93 100644 --- a/RxSwift/Schedulers/SerialDispatchQueueScheduler.swift +++ b/RxSwift/Schedulers/SerialDispatchQueueScheduler.swift @@ -113,7 +113,7 @@ public class SerialDispatchQueueScheduler : SchedulerType { - parameter action: Action to be executed. - returns: The disposable object used to cancel the scheduled action (best effort). */ - public final func scheduleRelative(_ state: StateType, dueTime: Foundation.TimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { + public final func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { return self.configuration.scheduleRelative(state, dueTime: dueTime, action: action) } @@ -126,7 +126,7 @@ public class SerialDispatchQueueScheduler : SchedulerType { - parameter action: Action to be executed. - returns: The disposable object used to cancel the scheduled action (best effort). */ - public func schedulePeriodic(_ state: StateType, startAfter: TimeInterval, period: TimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { + public func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { return self.configuration.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) } } diff --git a/RxSwift/Schedulers/VirtualTimeConverterType.swift b/RxSwift/Schedulers/VirtualTimeConverterType.swift index a17475ab8..7069b00b2 100644 --- a/RxSwift/Schedulers/VirtualTimeConverterType.swift +++ b/RxSwift/Schedulers/VirtualTimeConverterType.swift @@ -6,6 +6,8 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // +import Foundation + /// Parametrization for virtual time used by `VirtualTimeScheduler`s. public protocol VirtualTimeConverterType { /// Virtual time unit used that represents ticks of virtual clock. @@ -36,7 +38,7 @@ public protocol VirtualTimeConverterType { - parameter virtualTimeInterval: Virtual time interval to convert to `NSTimeInterval`. - returns: `NSTimeInterval` corresponding to virtual time interval. */ - func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> RxTimeInterval + func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> TimeInterval /** Converts from `NSTimeInterval` to virtual time interval. @@ -44,7 +46,7 @@ public protocol VirtualTimeConverterType { - parameter timeInterval: `NSTimeInterval` to convert to virtual time interval. - returns: Virtual time interval corresponding to time interval. */ - func convertToVirtualTimeInterval(_ timeInterval: RxTimeInterval) -> VirtualTimeIntervalUnit + func convertToVirtualTimeInterval(_ timeInterval: TimeInterval) -> VirtualTimeIntervalUnit /** Offsets virtual time by virtual time interval. diff --git a/RxSwift/Schedulers/VirtualTimeScheduler.swift b/RxSwift/Schedulers/VirtualTimeScheduler.swift index 037df95a0..e63ceceac 100644 --- a/RxSwift/Schedulers/VirtualTimeScheduler.swift +++ b/RxSwift/Schedulers/VirtualTimeScheduler.swift @@ -62,7 +62,7 @@ open class VirtualTimeScheduler - returns: The disposable object used to cancel the scheduled action (best effort). */ public func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - return self.scheduleRelative(state, dueTime: 0.0) { a in + return self.scheduleRelative(state, dueTime: .microseconds(0)) { a in return action(a) } } @@ -76,7 +76,7 @@ open class VirtualTimeScheduler - returns: The disposable object used to cancel the scheduled action (best effort). */ public func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { - let time = self.now.addingTimeInterval(dueTime) + let time = self.now.addingDispatchInterval(dueTime) let absoluteTime = self._converter.convertToVirtualTime(time) let adjustedTime = self.adjustScheduledTime(absoluteTime) return self.scheduleAbsoluteVirtual(state, time: adjustedTime, action: action) diff --git a/RxSwift/Traits/Single.swift b/RxSwift/Traits/Single.swift index 735cbedfe..d52da644f 100644 --- a/RxSwift/Traits/Single.swift +++ b/RxSwift/Traits/Single.swift @@ -186,34 +186,6 @@ extension PrimitiveSequenceType where TraitType == SingleTrait { ) } - /** - Invokes an action for each event in the observable sequence, and propagates all observer messages through the result sequence. - - - seealso: [do operator on reactivex.io](http://reactivex.io/documentation/operators/do.html) - - - parameter onNext: Action to invoke for each element in the observable sequence. - - parameter onError: Action to invoke upon errored termination of the observable sequence. - - parameter onSubscribe: Action to invoke before subscribing to source observable sequence. - - parameter onSubscribed: Action to invoke after subscribing to source observable sequence. - - parameter onDispose: Action to invoke after subscription to source observable has been disposed for any reason. It can be either because sequence terminates for some reason or observer subscription being disposed. - - returns: The source sequence with the side-effecting behavior applied. - */ - @available(*, deprecated, renamed: "do(onSuccess:onError:onSubscribe:onSubscribed:onDispose:)") - public func `do`(onNext: ((ElementType) throws -> Void)?, - onError: ((Swift.Error) throws -> Void)? = nil, - onSubscribe: (() -> Void)? = nil, - onSubscribed: (() -> Void)? = nil, - onDispose: (() -> Void)? = nil) - -> Single { - return self.`do`( - onSuccess: onNext, - onError: onError, - onSubscribe: onSubscribe, - onSubscribed: onSubscribed, - onDispose: onDispose - ) - } - /** Filters the elements of an observable sequence based on a predicate. @@ -226,8 +198,7 @@ extension PrimitiveSequenceType where TraitType == SingleTrait { -> Maybe { return Maybe(raw: self.primitiveSequence.source.filter(predicate)) } - - + /** Projects each element of an observable sequence into a new form. diff --git a/RxTest/Schedulers/TestSchedulerVirtualTimeConverter.swift b/RxTest/Schedulers/TestSchedulerVirtualTimeConverter.swift index 8711b09fe..34a7c38cd 100644 --- a/RxTest/Schedulers/TestSchedulerVirtualTimeConverter.swift +++ b/RxTest/Schedulers/TestSchedulerVirtualTimeConverter.swift @@ -6,7 +6,7 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import struct Foundation.Date +import Foundation import RxSwift /// Converter from virtual time and time interval measured in `Int`s to `Date` and `NSTimeInterval`. @@ -29,7 +29,7 @@ public struct TestSchedulerVirtualTimeConverter : VirtualTimeConverterType { /// - parameter virtualTime: Virtual time to convert to `Date`. /// - returns: `Date` corresponding to virtual time. public func convertFromVirtualTime(_ virtualTime: VirtualTimeUnit) -> RxTime { - return Date(timeIntervalSince1970: RxTimeInterval(virtualTime) * self._resolution) + return Date(timeIntervalSince1970: TimeInterval(virtualTime) * self._resolution) } /// Converts real time to virtual time. @@ -44,15 +44,15 @@ public struct TestSchedulerVirtualTimeConverter : VirtualTimeConverterType { /// /// - parameter virtualTimeInterval: Virtual time interval to convert to `NSTimeInterval`. /// - returns: `NSTimeInterval` corresponding to virtual time interval. - public func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> RxTimeInterval { - return RxTimeInterval(virtualTimeInterval) * self._resolution + public func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> TimeInterval { + return TimeInterval(virtualTimeInterval) * self._resolution } /// Converts from virtual time interval to `NSTimeInterval`. /// /// - parameter timeInterval: `NSTimeInterval` to convert to virtual time interval. /// - returns: Virtual time interval corresponding to time interval. - public func convertToVirtualTimeInterval(_ timeInterval: RxTimeInterval) -> VirtualTimeIntervalUnit { + public func convertToVirtualTimeInterval(_ timeInterval: TimeInterval) -> VirtualTimeIntervalUnit { return VirtualTimeIntervalUnit(timeInterval / self._resolution + 0.5) } diff --git a/Tests/RxSwiftTests/Anomalies.swift b/Tests/RxSwiftTests/Anomalies.swift index a6d8c19e8..0c5b38058 100644 --- a/Tests/RxSwiftTests/Anomalies.swift +++ b/Tests/RxSwiftTests/Anomalies.swift @@ -38,9 +38,9 @@ extension AnomaliesTest { return share(Observable.interval(period, scheduler: scheduler)) } - _ = makeSequence(label: "main", period: 0.1) + _ = makeSequence(label: "main", period: .milliseconds(100)) .flatMapLatest { (index: Int) -> Observable<(Int, Int)> in - return makeSequence(label: "nested", period: 0.02).map { (index, $0) } + return makeSequence(label: "nested", period: .milliseconds(20)).map { (index, $0) } } .take(10) .enumerated().map { ($0, $1.0, $1.1) } @@ -145,8 +145,8 @@ extension AnomaliesTest { } _ = Observable.of( - makeSequence(label: "main", period: 0.2), - makeSequence(label: "nested", period: 0.3) + makeSequence(label: "main", period: .milliseconds(200)), + makeSequence(label: "nested", period: .milliseconds(300)) ).merge() .take(1) .subscribe( diff --git a/Tests/RxSwiftTests/HistoricalSchedulerTest.swift b/Tests/RxSwiftTests/HistoricalSchedulerTest.swift index 3fe5d020e..74982c290 100644 --- a/Tests/RxSwiftTests/HistoricalSchedulerTest.swift +++ b/Tests/RxSwiftTests/HistoricalSchedulerTest.swift @@ -26,9 +26,9 @@ extension HistoricalSchedulerTest { var times: [Date] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { _ in times.append(scheduler.now) - _ = scheduler.scheduleRelative((), dueTime: 20.0) { _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler.now) return Disposables.create() } @@ -52,9 +52,9 @@ extension HistoricalSchedulerTest { var times: [Date] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { _ in times.append(scheduler.now) - let d = scheduler.scheduleRelative((), dueTime: 20.0) { _ in + let d = scheduler.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler.now) return Disposables.create() } @@ -80,9 +80,9 @@ extension HistoricalSchedulerTest { var times: [Date] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { _ in times.append(scheduler.now) - _ = scheduler.scheduleRelative((), dueTime: 20.0) { _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler.now) return Disposables.create() } @@ -106,9 +106,9 @@ extension HistoricalSchedulerTest { var times: [Date] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { [weak scheduler] _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { [weak scheduler] _ in times.append(scheduler!.now) - _ = scheduler!.scheduleRelative((), dueTime: 20.0) { _ in + _ = scheduler!.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler!.now) return Disposables.create() } @@ -131,9 +131,9 @@ extension HistoricalSchedulerTest { var times: [Date] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { [weak scheduler] _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { [weak scheduler] _ in times.append(scheduler!.now) - let d1 = scheduler!.scheduleRelative((), dueTime: 20.0) { _ in + let d1 = scheduler!.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler!.now) return Disposables.create() } @@ -159,9 +159,9 @@ extension HistoricalSchedulerTest { var times: [Date] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { [weak scheduler] _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { [weak scheduler] _ in times.append(scheduler!.now) - _ = scheduler!.scheduleRelative((), dueTime: 20.0) { _ in + _ = scheduler!.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler!.now) return Disposables.create() } @@ -187,11 +187,11 @@ extension HistoricalSchedulerTest { var times: [Date] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { [weak scheduler] _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { [weak scheduler] _ in times.append(scheduler!.now) _ = scheduler!.sleep(100) - _ = scheduler!.scheduleRelative((), dueTime: 20.0) { _ in + _ = scheduler!.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler!.now) return Disposables.create() } diff --git a/Tests/RxSwiftTests/Observable+AmbTests.swift b/Tests/RxSwiftTests/Observable+AmbTests.swift index 072e86b44..c934c5f74 100644 --- a/Tests/RxSwiftTests/Observable+AmbTests.swift +++ b/Tests/RxSwiftTests/Observable+AmbTests.swift @@ -270,25 +270,25 @@ extension ObservableAmbTest { #if TRACE_RESOURCES func testAmb1ReleasesResourcesOnComplete() { let scheduler = TestScheduler(initialClock: 0) - _ = Observable.just(1).delay(10, scheduler: scheduler).amb(Observable.just(1)).subscribe() + _ = Observable.just(1).delay(.seconds(10), scheduler: scheduler).amb(Observable.just(1)).subscribe() scheduler.start() } func testAmb2ReleasesResourcesOnComplete() { let scheduler = TestScheduler(initialClock: 0) - _ = Observable.just(1).amb(Observable.just(1).delay(10, scheduler: scheduler)).subscribe() + _ = Observable.just(1).amb(Observable.just(1).delay(.seconds(10), scheduler: scheduler)).subscribe() scheduler.start() } func testAmb1ReleasesResourcesOnError() { let scheduler = TestScheduler(initialClock: 0) - _ = Observable.never().timeout(20, scheduler: scheduler).amb(Observable.never()).subscribe() + _ = Observable.never().timeout(.seconds(20), scheduler: scheduler).amb(Observable.never()).subscribe() scheduler.start() } func testAmb2ReleasesResourcesOnError() { let scheduler = TestScheduler(initialClock: 0) - _ = Observable.never().amb(Observable.never().timeout(20, scheduler: scheduler)).subscribe() + _ = Observable.never().amb(Observable.never().timeout(.seconds(20), scheduler: scheduler)).subscribe() scheduler.start() } #endif diff --git a/Tests/RxSwiftTests/Observable+DelayTests.swift b/Tests/RxSwiftTests/Observable+DelayTests.swift index 5034047fc..c47f297fd 100644 --- a/Tests/RxSwiftTests/Observable+DelayTests.swift +++ b/Tests/RxSwiftTests/Observable+DelayTests.swift @@ -348,13 +348,13 @@ extension ObservableDelayTest { let xs = scheduler.createHotObservable(msgs) - let delay: RxTimeInterval = 42 + let delay = 42 let res = scheduler.start { - xs.delay(delay, scheduler: scheduler) + xs.delay(.seconds(delay), scheduler: scheduler) } XCTAssertEqual(res.events, - msgs.map { Recorded(time: $0.time + Int(delay), value: $0.value) } + msgs.map { Recorded(time: $0.time + delay, value: $0.value) } .filter { $0.time > 200 }) } diff --git a/Tests/RxSwiftTests/Observable+GroupByTests.swift b/Tests/RxSwiftTests/Observable+GroupByTests.swift index 35182b2c1..4edf71127 100644 --- a/Tests/RxSwiftTests/Observable+GroupByTests.swift +++ b/Tests/RxSwiftTests/Observable+GroupByTests.swift @@ -313,7 +313,7 @@ extension ObservableGroupByTest { inners[group.key] = group results[group.key] = result - innerSubscriptions[group.key] = scheduler.scheduleRelative((), dueTime: 100, action: { _ in + innerSubscriptions[group.key] = scheduler.scheduleRelative((), dueTime: .seconds(100), action: { _ in group.subscribe(result) }) }) @@ -476,7 +476,7 @@ extension ObservableGroupByTest { inners[group.key] = group results[group.key] = result - innerSubscriptions[group.key] = scheduler.scheduleRelative((), dueTime: 100, action: { _ in + innerSubscriptions[group.key] = scheduler.scheduleRelative((), dueTime: .seconds(100), action: { _ in group.subscribe(result) }) }) diff --git a/Tests/RxSwiftTests/Observable+RetryWhenTests.swift b/Tests/RxSwiftTests/Observable+RetryWhenTests.swift index c024ef2b4..9f11dd6ea 100644 --- a/Tests/RxSwiftTests/Observable+RetryWhenTests.swift +++ b/Tests/RxSwiftTests/Observable+RetryWhenTests.swift @@ -339,7 +339,7 @@ extension ObservableRetryWhenTest { return Observable.error(e) } - return Observable.timer(RxTimeInterval((a + 1) * 50), scheduler: scheduler) + return Observable.timer(.seconds((a + 1) * 50), scheduler: scheduler) } } } diff --git a/Tests/RxSwiftTests/Observable+SkipUntilTests.swift b/Tests/RxSwiftTests/Observable+SkipUntilTests.swift index 541fa1d19..e892c4d24 100644 --- a/Tests/RxSwiftTests/Observable+SkipUntilTests.swift +++ b/Tests/RxSwiftTests/Observable+SkipUntilTests.swift @@ -362,25 +362,25 @@ extension ObservableSkipUntilTest { #if TRACE_RESOURCES func testSkipUntilReleasesResourcesOnComplete1() { let scheduler = TestScheduler(initialClock: 0) - _ = Observable.just(1).delay(20, scheduler: scheduler).skipUntil(Observable.just(1)).subscribe() + _ = Observable.just(1).delay(.seconds(20), scheduler: scheduler).skipUntil(Observable.just(1)).subscribe() scheduler.start() } func testSkipUntilReleasesResourcesOnComplete2() { let scheduler = TestScheduler(initialClock: 0) - _ = Observable.just(1).skipUntil(Observable.just(1).delay(20, scheduler: scheduler)).subscribe() + _ = Observable.just(1).skipUntil(Observable.just(1).delay(.seconds(20), scheduler: scheduler)).subscribe() scheduler.start() } func testSkipUntilReleasesResourcesOnError1() { let scheduler = TestScheduler(initialClock: 0) - _ = Observable.never().timeout(20, scheduler: scheduler).skipUntil(Observable.just(1)).subscribe() + _ = Observable.never().timeout(.seconds(20), scheduler: scheduler).skipUntil(Observable.just(1)).subscribe() scheduler.start() } func testSkipUntilReleasesResourcesOnError2() { let scheduler = TestScheduler(initialClock: 0) - _ = Observable.just(1).skipUntil(Observable.never().timeout(20, scheduler: scheduler)).subscribe() + _ = Observable.just(1).skipUntil(Observable.never().timeout(.seconds(20), scheduler: scheduler)).subscribe() scheduler.start() } #endif diff --git a/Tests/RxSwiftTests/SchedulerTests.swift b/Tests/RxSwiftTests/SchedulerTests.swift index 83e19b865..ea837ac14 100644 --- a/Tests/RxSwiftTests/SchedulerTests.swift +++ b/Tests/RxSwiftTests/SchedulerTests.swift @@ -39,7 +39,7 @@ extension ConcurrentDispatchQueueSchedulerTests { let scheduler = self.createScheduler() - _ = scheduler.scheduleRelative(1, dueTime: 0.5) { _ -> Disposable in + _ = scheduler.scheduleRelative(1, dueTime: .milliseconds(500)) { _ -> Disposable in interval = Date().timeIntervalSince(start) expectScheduling.fulfill() return Disposables.create() @@ -60,7 +60,7 @@ extension ConcurrentDispatchQueueSchedulerTests { let scheduler = self.createScheduler() - let disposable = scheduler.scheduleRelative(1, dueTime: 0.1) { _ -> Disposable in + let disposable = scheduler.scheduleRelative(1, dueTime: .milliseconds(100)) { _ -> Disposable in interval = Date().timeIntervalSince(start) expectScheduling.fulfill() return Disposables.create() @@ -85,7 +85,7 @@ extension ConcurrentDispatchQueueSchedulerTests { let scheduler = self.createScheduler() - let disposable = scheduler.schedulePeriodic(0, startAfter: 0.2, period: 0.3) { state -> Int in + let disposable = scheduler.schedulePeriodic(0, startAfter: .milliseconds(200), period: .milliseconds(300)) { state -> Int in times.mutate { $0.append(Date()) } if state == 1 { expectScheduling.fulfill() @@ -110,7 +110,7 @@ extension ConcurrentDispatchQueueSchedulerTests { let scheduler = self.createScheduler() - let disposable = scheduler.schedulePeriodic(0, startAfter: 0.2, period: 0.3) { state -> Int in + let disposable = scheduler.schedulePeriodic(0, startAfter: .milliseconds(200), period: .milliseconds(300)) { state -> Int in times.append(Date()) return state + 1 } diff --git a/Tests/RxSwiftTests/TestImplementations/TestVirtualScheduler.swift b/Tests/RxSwiftTests/TestImplementations/TestVirtualScheduler.swift index 1c74b115d..ec5a95666 100644 --- a/Tests/RxSwiftTests/TestImplementations/TestVirtualScheduler.swift +++ b/Tests/RxSwiftTests/TestImplementations/TestVirtualScheduler.swift @@ -27,18 +27,18 @@ struct TestVirtualSchedulerVirtualTimeConverter : VirtualTimeConverterType { typealias VirtualTimeIntervalUnit = Int func convertFromVirtualTime(_ virtualTime: VirtualTimeUnit) -> RxTime { - return Date(timeIntervalSince1970: RxTimeInterval(virtualTime) * 10.0) + return Date(timeIntervalSince1970: Foundation.TimeInterval(virtualTime) * 10.0) } func convertToVirtualTime(_ time: RxTime) -> VirtualTimeUnit { return Int(time.timeIntervalSince1970 / 10.0) } - func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> RxTimeInterval { - return RxTimeInterval(virtualTimeInterval * 10) + func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> Foundation.TimeInterval { + return Foundation.TimeInterval(virtualTimeInterval * 10) } - func convertToVirtualTimeInterval(_ timeInterval: RxTimeInterval) -> VirtualTimeIntervalUnit { + func convertToVirtualTimeInterval(_ timeInterval: Foundation.TimeInterval) -> VirtualTimeIntervalUnit { return Int(timeInterval / 10.0) } diff --git a/Tests/RxSwiftTests/VirtualSchedulerTest.swift b/Tests/RxSwiftTests/VirtualSchedulerTest.swift index 6df9cab24..f290038d0 100644 --- a/Tests/RxSwiftTests/VirtualSchedulerTest.swift +++ b/Tests/RxSwiftTests/VirtualSchedulerTest.swift @@ -30,9 +30,9 @@ extension VirtualSchedulerTest { var times: [Int] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { _ in times.append(scheduler.clock) - _ = scheduler.scheduleRelative((), dueTime: 20.0) { _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler.clock) return Disposables.create() } @@ -56,9 +56,9 @@ extension VirtualSchedulerTest { var times: [Int] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { _ in times.append(scheduler.clock) - let d = scheduler.scheduleRelative((), dueTime: 20.0) { _ in + let d = scheduler.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler.clock) return Disposables.create() } @@ -84,9 +84,9 @@ extension VirtualSchedulerTest { var times: [Int] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { _ in times.append(scheduler.clock) - _ = scheduler.scheduleRelative((), dueTime: 20.0) { _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler.clock) return Disposables.create() } @@ -110,9 +110,9 @@ extension VirtualSchedulerTest { var times: [Int] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { [weak scheduler] _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { [weak scheduler] _ in times.append(scheduler!.clock) - _ = scheduler!.scheduleRelative((), dueTime: 20.0) { _ in + _ = scheduler!.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler!.clock) return Disposables.create() } @@ -135,9 +135,9 @@ extension VirtualSchedulerTest { var times: [Int] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { [weak scheduler] _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { [weak scheduler] _ in times.append(scheduler!.clock) - let d1 = scheduler!.scheduleRelative((), dueTime: 20.0) { _ in + let d1 = scheduler!.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler!.clock) return Disposables.create() } @@ -163,9 +163,9 @@ extension VirtualSchedulerTest { var times: [Int] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { [weak scheduler] _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { [weak scheduler] _ in times.append(scheduler!.clock) - _ = scheduler!.scheduleRelative((), dueTime: 20.0) { _ in + _ = scheduler!.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler!.clock) return Disposables.create() } @@ -191,10 +191,10 @@ extension VirtualSchedulerTest { var times: [Int] = [] - _ = scheduler.scheduleRelative((), dueTime: 10.0) { [weak scheduler] _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10)) { [weak scheduler] _ in times.append(scheduler!.clock) scheduler!.sleep(10) - _ = scheduler!.scheduleRelative((), dueTime: 20.0) { _ in + _ = scheduler!.scheduleRelative((), dueTime: .seconds(20)) { _ in times.append(scheduler!.clock) return Disposables.create() } @@ -227,7 +227,7 @@ extension VirtualSchedulerTest { let random = Int(arc4random() % 10000) #endif times.append(random) - _ = scheduler.scheduleRelative((), dueTime: RxTimeInterval(10 * random)) { [weak scheduler] _ in + _ = scheduler.scheduleRelative((), dueTime: .seconds(10 * random)) { [weak scheduler] _ in ticks.append(scheduler!.clock) return Disposables.create() }