diff --git a/iOS/.gitignore b/iOS/.gitignore index 571ce497..4be3f8b5 100644 --- a/iOS/.gitignore +++ b/iOS/.gitignore @@ -1,7 +1,7 @@ # Created by https://www.gitignore.io/api/xcode ## Build generated -#build/ +build/ DerivedData/ ## Various settings diff --git a/iOS/MultiPlatformBLEAdapter.xcodeproj/project.pbxproj b/iOS/MultiPlatformBLEAdapter.xcodeproj/project.pbxproj index 0d0ac27c..4033b27c 100644 --- a/iOS/MultiPlatformBLEAdapter.xcodeproj/project.pbxproj +++ b/iOS/MultiPlatformBLEAdapter.xcodeproj/project.pbxproj @@ -9,6 +9,173 @@ /* Begin PBXBuildFile section */ 816FE39B234F29B3008BF70D /* BleAdapterFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 816FE39A234F29B3008BF70D /* BleAdapterFactory.swift */; }; 81B95B92234B256000D96D28 /* BleAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81B95B91234B256000D96D28 /* BleAdapter.swift */; }; + 8E63F2D12AB0CE9B0010A0CB /* AtomicInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2D02AB0CE9B0010A0CB /* AtomicInt.swift */; }; + 8E63F2D32AB0CEEC0010A0CB /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2D22AB0CEEC0010A0CB /* DispatchQueue+Extensions.swift */; }; + 8E63F2D52AB0CF050010A0CB /* Platform.Darwin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2D42AB0CF050010A0CB /* Platform.Darwin.swift */; }; + 8E63F2D72AB0CF1E0010A0CB /* Platform.Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2D62AB0CF1E0010A0CB /* Platform.Linux.swift */; }; + 8E63F2D92AB0CF400010A0CB /* RecursiveLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2D82AB0CF400010A0CB /* RecursiveLock.swift */; }; + 8E63F2DB2AB0CF730010A0CB /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2DA2AB0CF730010A0CB /* Bag.swift */; }; + 8E63F2DD2AB0CF830010A0CB /* InfiniteSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2DC2AB0CF830010A0CB /* InfiniteSequence.swift */; }; + 8E63F2DF2AB0CFB10010A0CB /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2DE2AB0CFB10010A0CB /* PriorityQueue.swift */; }; + 8E63F2E12AB0CFC30010A0CB /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2E02AB0CFC30010A0CB /* Queue.swift */; }; + 8E63F32B2AB0D6390010A0CB /* DefaultIfEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2E32AB0D6340010A0CB /* DefaultIfEmpty.swift */; }; + 8E63F32C2AB0D6390010A0CB /* Never.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2E42AB0D6340010A0CB /* Never.swift */; }; + 8E63F32D2AB0D6390010A0CB /* GroupBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2E62AB0D6340010A0CB /* GroupBy.swift */; }; + 8E63F32E2AB0D6390010A0CB /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2E72AB0D6340010A0CB /* Switch.swift */; }; + 8E63F32F2AB0D6390010A0CB /* WithUnretained.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2E82AB0D6340010A0CB /* WithUnretained.swift */; }; + 8E63F3302AB0D6390010A0CB /* Producer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2E92AB0D6340010A0CB /* Producer.swift */; }; + 8E63F3312AB0D6390010A0CB /* RetryWhen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2EA2AB0D6340010A0CB /* RetryWhen.swift */; }; + 8E63F3322AB0D6390010A0CB /* StartWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2EB2AB0D6340010A0CB /* StartWith.swift */; }; + 8E63F3332AB0D6390010A0CB /* Scan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2EC2AB0D6340010A0CB /* Scan.swift */; }; + 8E63F3342AB0D6390010A0CB /* Using.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2ED2AB0D6350010A0CB /* Using.swift */; }; + 8E63F3352AB0D6390010A0CB /* Concat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2EE2AB0D6350010A0CB /* Concat.swift */; }; + 8E63F3362AB0D6390010A0CB /* Do.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2EF2AB0D6350010A0CB /* Do.swift */; }; + 8E63F3372AB0D6390010A0CB /* SwitchIfEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2F02AB0D6350010A0CB /* SwitchIfEmpty.swift */; }; + 8E63F3382AB0D6390010A0CB /* Throttle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2F12AB0D6350010A0CB /* Throttle.swift */; }; + 8E63F3392AB0D6390010A0CB /* WithLatestFrom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2F22AB0D6350010A0CB /* WithLatestFrom.swift */; }; + 8E63F33A2AB0D6390010A0CB /* Debounce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2F32AB0D6350010A0CB /* Debounce.swift */; }; + 8E63F33B2AB0D6390010A0CB /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2F42AB0D6350010A0CB /* Deferred.swift */; }; + 8E63F33C2AB0D6390010A0CB /* Enumerated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2F52AB0D6350010A0CB /* Enumerated.swift */; }; + 8E63F33D2AB0D6390010A0CB /* Buffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2F62AB0D6350010A0CB /* Buffer.swift */; }; + 8E63F33E2AB0D6390010A0CB /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2F72AB0D6350010A0CB /* Range.swift */; }; + 8E63F33F2AB0D6390010A0CB /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2F82AB0D6350010A0CB /* Sequence.swift */; }; + 8E63F3402AB0D6390010A0CB /* SkipWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2F92AB0D6350010A0CB /* SkipWhile.swift */; }; + 8E63F3412AB0D6390010A0CB /* ObserveOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2FA2AB0D6350010A0CB /* ObserveOn.swift */; }; + 8E63F3422AB0D6390010A0CB /* ElementAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2FB2AB0D6350010A0CB /* ElementAt.swift */; }; + 8E63F3432AB0D6390010A0CB /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2FC2AB0D6350010A0CB /* Filter.swift */; }; + 8E63F3442AB0D6390010A0CB /* SingleAsync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2FD2AB0D6350010A0CB /* SingleAsync.swift */; }; + 8E63F3452AB0D6390010A0CB /* Timeout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2FE2AB0D6350010A0CB /* Timeout.swift */; }; + 8E63F3462AB0D6390010A0CB /* AddRef.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F2FF2AB0D6360010A0CB /* AddRef.swift */; }; + 8E63F3472AB0D6390010A0CB /* AsSingle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3002AB0D6360010A0CB /* AsSingle.swift */; }; + 8E63F3482AB0D6390010A0CB /* CombineLatest+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3012AB0D6360010A0CB /* CombineLatest+Collection.swift */; }; + 8E63F3492AB0D6390010A0CB /* Decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3022AB0D6360010A0CB /* Decode.swift */; }; + 8E63F34A2AB0D6390010A0CB /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3032AB0D6360010A0CB /* Window.swift */; }; + 8E63F34B2AB0D6390010A0CB /* CompactMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3042AB0D6360010A0CB /* CompactMap.swift */; }; + 8E63F34C2AB0D6390010A0CB /* DelaySubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3052AB0D6360010A0CB /* DelaySubscription.swift */; }; + 8E63F34D2AB0D6390010A0CB /* DistinctUntilChanged.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3062AB0D6360010A0CB /* DistinctUntilChanged.swift */; }; + 8E63F34E2AB0D6390010A0CB /* First.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3072AB0D6360010A0CB /* First.swift */; }; + 8E63F34F2AB0D6390010A0CB /* Amb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3082AB0D6360010A0CB /* Amb.swift */; }; + 8E63F3502AB0D6390010A0CB /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3092AB0D6360010A0CB /* Error.swift */; }; + 8E63F3512AB0D6390010A0CB /* Generate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F30A2AB0D6360010A0CB /* Generate.swift */; }; + 8E63F3522AB0D6390010A0CB /* Materialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F30B2AB0D6370010A0CB /* Materialize.swift */; }; + 8E63F3532AB0D6390010A0CB /* SubscribeOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F30C2AB0D6370010A0CB /* SubscribeOn.swift */; }; + 8E63F3542AB0D6390010A0CB /* Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F30D2AB0D6370010A0CB /* Debug.swift */; }; + 8E63F3552AB0D6390010A0CB /* Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F30E2AB0D6370010A0CB /* Create.swift */; }; + 8E63F3562AB0D6390010A0CB /* Sample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F30F2AB0D6370010A0CB /* Sample.swift */; }; + 8E63F3572AB0D6390010A0CB /* Take.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3102AB0D6370010A0CB /* Take.swift */; }; + 8E63F3582AB0D6390010A0CB /* Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3112AB0D6370010A0CB /* Merge.swift */; }; + 8E63F3592AB0D6390010A0CB /* Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3122AB0D6370010A0CB /* Empty.swift */; }; + 8E63F35A2AB0D6390010A0CB /* Dematerialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3132AB0D6370010A0CB /* Dematerialize.swift */; }; + 8E63F35B2AB0D6390010A0CB /* Zip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3142AB0D6370010A0CB /* Zip.swift */; }; + 8E63F35C2AB0D6390010A0CB /* CombineLatest+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3152AB0D6370010A0CB /* CombineLatest+arity.swift */; }; + 8E63F35D2AB0D6390010A0CB /* Skip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3162AB0D6370010A0CB /* Skip.swift */; }; + 8E63F35E2AB0D6390010A0CB /* TakeLast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3172AB0D6370010A0CB /* TakeLast.swift */; }; + 8E63F35F2AB0D6390010A0CB /* CombineLatest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3182AB0D6370010A0CB /* CombineLatest.swift */; }; + 8E63F3602AB0D6390010A0CB /* Zip+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3192AB0D6370010A0CB /* Zip+Collection.swift */; }; + 8E63F3612AB0D6390010A0CB /* ShareReplayScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F31A2AB0D6370010A0CB /* ShareReplayScope.swift */; }; + 8E63F3622AB0D6390010A0CB /* Sink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F31B2AB0D6380010A0CB /* Sink.swift */; }; + 8E63F3632AB0D6390010A0CB /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F31C2AB0D6380010A0CB /* Delay.swift */; }; + 8E63F3642AB0D6390010A0CB /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F31D2AB0D6380010A0CB /* Optional.swift */; }; + 8E63F3652AB0D6390010A0CB /* Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F31E2AB0D6380010A0CB /* Reduce.swift */; }; + 8E63F3662AB0D6390010A0CB /* Catch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F31F2AB0D6380010A0CB /* Catch.swift */; }; + 8E63F3672AB0D6390010A0CB /* Just.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3202AB0D6380010A0CB /* Just.swift */; }; + 8E63F3682AB0D6390010A0CB /* Repeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3212AB0D6380010A0CB /* Repeat.swift */; }; + 8E63F3692AB0D6390010A0CB /* Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3222AB0D6380010A0CB /* Zip+arity.swift */; }; + 8E63F36A2AB0D6390010A0CB /* Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3232AB0D6380010A0CB /* Map.swift */; }; + 8E63F36B2AB0D6390010A0CB /* TakeWithPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3242AB0D6380010A0CB /* TakeWithPredicate.swift */; }; + 8E63F36C2AB0D6390010A0CB /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3252AB0D6380010A0CB /* Timer.swift */; }; + 8E63F36D2AB0D6390010A0CB /* SkipUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3262AB0D6380010A0CB /* SkipUntil.swift */; }; + 8E63F36E2AB0D6390010A0CB /* Multicast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3272AB0D6380010A0CB /* Multicast.swift */; }; + 8E63F36F2AB0D6390010A0CB /* AsMaybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F3292AB0D6380010A0CB /* AsMaybe.swift */; }; + 8E63F3702AB0D6390010A0CB /* ToArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E63F32A2AB0D6380010A0CB /* ToArray.swift */; }; + 8EF49F392AB1CCF30019E5F9 /* Array+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EF49F382AB1CCF30019E5F9 /* Array+Utils.swift */; }; + 8EF49F3B2AB1CD3E0019E5F9 /* CBCentral+Uuid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EF49F3A2AB1CD3E0019E5F9 /* CBCentral+Uuid.swift */; }; + 8EF49F3D2AB1CD720019E5F9 /* CBCentralManagerDelegateWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EF49F3C2AB1CD720019E5F9 /* CBCentralManagerDelegateWrapper.swift */; }; + 8EF49F412AB1CDDE0019E5F9 /* CBPeripheralDelegateWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EF49F402AB1CDDE0019E5F9 /* CBPeripheralDelegateWrapper.swift */; }; + 8EF49F492AB1CE400019E5F9 /* ManagerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EF49F482AB1CE400019E5F9 /* ManagerType.swift */; }; + 8EFF12592AB0C09600399069 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11E92AB0C09500399069 /* Disposable.swift */; }; + 8EFF125A2AB0C09600399069 /* Date+Dispatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11EA2AB0C09500399069 /* Date+Dispatch.swift */; }; + 8EFF125B2AB0C09600399069 /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11EB2AB0C09500399069 /* Event.swift */; }; + 8EFF125C2AB0C09600399069 /* Cancelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11EC2AB0C09500399069 /* Cancelable.swift */; }; + 8EFF125D2AB0C09600399069 /* DisposeBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11EE2AB0C09500399069 /* DisposeBase.swift */; }; + 8EFF125E2AB0C09600399069 /* DisposeBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11EF2AB0C09500399069 /* DisposeBag.swift */; }; + 8EFF125F2AB0C09600399069 /* ScheduledDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11F02AB0C09500399069 /* ScheduledDisposable.swift */; }; + 8EFF12602AB0C09600399069 /* NopDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11F12AB0C09500399069 /* NopDisposable.swift */; }; + 8EFF12612AB0C09600399069 /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11F22AB0C09500399069 /* SubscriptionDisposable.swift */; }; + 8EFF12622AB0C09600399069 /* RefCountDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11F32AB0C09500399069 /* RefCountDisposable.swift */; }; + 8EFF12632AB0C09600399069 /* CompositeDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11F42AB0C09500399069 /* CompositeDisposable.swift */; }; + 8EFF12642AB0C09600399069 /* SingleAssignmentDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11F52AB0C09500399069 /* SingleAssignmentDisposable.swift */; }; + 8EFF12652AB0C09600399069 /* SerialDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11F62AB0C09500399069 /* SerialDisposable.swift */; }; + 8EFF12662AB0C09600399069 /* BinaryDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11F72AB0C09500399069 /* BinaryDisposable.swift */; }; + 8EFF12672AB0C09600399069 /* AnonymousDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11F82AB0C09500399069 /* AnonymousDisposable.swift */; }; + 8EFF12682AB0C09600399069 /* BooleanDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11F92AB0C09500399069 /* BooleanDisposable.swift */; }; + 8EFF12692AB0C09600399069 /* Disposables.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11FA2AB0C09500399069 /* Disposables.swift */; }; + 8EFF126A2AB0C09600399069 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF11FB2AB0C09500399069 /* Errors.swift */; }; + 8EFF12B12AB0C09600399069 /* ObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12452AB0C09500399069 /* ObservableType.swift */; }; + 8EFF12B22AB0C09600399069 /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12472AB0C09500399069 /* LockOwnerType.swift */; }; + 8EFF12B32AB0C09600399069 /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12482AB0C09500399069 /* SynchronizedDisposeType.swift */; }; + 8EFF12B42AB0C09600399069 /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12492AB0C09500399069 /* SynchronizedOnType.swift */; }; + 8EFF12B52AB0C09600399069 /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF124A2AB0C09500399069 /* Lock.swift */; }; + 8EFF12B62AB0C09600399069 /* AsyncLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF124B2AB0C09500399069 /* AsyncLock.swift */; }; + 8EFF12B72AB0C09600399069 /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF124C2AB0C09500399069 /* SynchronizedUnsubscribeType.swift */; }; + 8EFF12B82AB0C09600399069 /* Observable+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF124E2AB0C09500399069 /* Observable+Concurrency.swift */; }; + 8EFF12B92AB0C09600399069 /* ImmediateSchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF124F2AB0C09500399069 /* ImmediateSchedulerType.swift */; }; + 8EFF12BA2AB0C09600399069 /* ObservableType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12502AB0C09500399069 /* ObservableType+Extensions.swift */; }; + 8EFF12BB2AB0C09600399069 /* Bag+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12522AB0C09600399069 /* Bag+Rx.swift */; }; + 8EFF12BC2AB0C09600399069 /* AnyObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12532AB0C09600399069 /* AnyObserver.swift */; }; + 8EFF12BD2AB0C09600399069 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12542AB0C09600399069 /* Observable.swift */; }; + 8EFF12BE2AB0C09600399069 /* Binder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12552AB0C09600399069 /* Binder.swift */; }; + 8EFF12BF2AB0C09600399069 /* GroupedObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12562AB0C09600399069 /* GroupedObservable.swift */; }; + 8EFF12C02AB0C09600399069 /* ObservableConvertibleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12572AB0C09600399069 /* ObservableConvertibleType.swift */; }; + 8EFF12C12AB0C09600399069 /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12582AB0C09600399069 /* ConnectableObservableType.swift */; }; + 8EFF12C72AB0C0A200399069 /* ObserverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12C22AB0C0A200399069 /* ObserverType.swift */; }; + 8EFF12C82AB0C0A200399069 /* ObserverBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12C42AB0C0A200399069 /* ObserverBase.swift */; }; + 8EFF12C92AB0C0A200399069 /* TailRecursiveSink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12C52AB0C0A200399069 /* TailRecursiveSink.swift */; }; + 8EFF12CA2AB0C0A200399069 /* AnonymousObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12C62AB0C0A200399069 /* AnonymousObserver.swift */; }; + 8EFF12E22AB0C0F200399069 /* Completable+AndThen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12CD2AB0C0F200399069 /* Completable+AndThen.swift */; }; + 8EFF12E32AB0C0F200399069 /* Completable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12CF2AB0C0F200399069 /* Completable.swift */; }; + 8EFF12E42AB0C0F200399069 /* Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12D02AB0C0F200399069 /* Single.swift */; }; + 8EFF12E52AB0C0F200399069 /* PrimitiveSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12D12AB0C0F200399069 /* PrimitiveSequence.swift */; }; + 8EFF12E62AB0C0F200399069 /* Maybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12D22AB0C0F200399069 /* Maybe.swift */; }; + 8EFF12E72AB0C0F200399069 /* ObservableType+PrimitiveSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12D32AB0C0F200399069 /* ObservableType+PrimitiveSequence.swift */; }; + 8EFF12E82AB0C0F200399069 /* PrimitiveSequence+Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12D42AB0C0F200399069 /* PrimitiveSequence+Zip+arity.swift */; }; + 8EFF12E92AB0C0F200399069 /* PrimitiveSequence+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12D52AB0C0F200399069 /* PrimitiveSequence+Concurrency.swift */; }; + 8EFF12EA2AB0C0F200399069 /* Infallible+Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12D72AB0C0F200399069 /* Infallible+Zip+arity.swift */; }; + 8EFF12EB2AB0C0F200399069 /* Infallible+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12D82AB0C0F200399069 /* Infallible+Concurrency.swift */; }; + 8EFF12EC2AB0C0F200399069 /* Infallible+Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12DA2AB0C0F200399069 /* Infallible+Create.swift */; }; + 8EFF12ED2AB0C0F200399069 /* Infallible+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12DB2AB0C0F200399069 /* Infallible+Operators.swift */; }; + 8EFF12EE2AB0C0F200399069 /* Infallible+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12DC2AB0C0F200399069 /* Infallible+Debug.swift */; }; + 8EFF12EF2AB0C0F200399069 /* Infallible+CombineLatest+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12DE2AB0C0F200399069 /* Infallible+CombineLatest+arity.swift */; }; + 8EFF12F02AB0C0F200399069 /* Infallible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12DF2AB0C0F200399069 /* Infallible.swift */; }; + 8EFF12F12AB0C0F200399069 /* Infallible+CombineLatest+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12E02AB0C0F200399069 /* Infallible+CombineLatest+Collection.swift */; }; + 8EFF12F22AB0C0F200399069 /* ObservableConvertibleType+Infallible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12E12AB0C0F200399069 /* ObservableConvertibleType+Infallible.swift */; }; + 8EFF12F52AB0C0FF00399069 /* SwiftSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12F42AB0C0FF00399069 /* SwiftSupport.swift */; }; + 8EFF12FC2AB0C10D00399069 /* SubjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12F72AB0C10D00399069 /* SubjectType.swift */; }; + 8EFF12FD2AB0C10D00399069 /* BehaviorSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12F82AB0C10D00399069 /* BehaviorSubject.swift */; }; + 8EFF12FE2AB0C10D00399069 /* AsyncSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12F92AB0C10D00399069 /* AsyncSubject.swift */; }; + 8EFF12FF2AB0C10D00399069 /* ReplaySubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12FA2AB0C10D00399069 /* ReplaySubject.swift */; }; + 8EFF13002AB0C10D00399069 /* PublishSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF12FB2AB0C10D00399069 /* PublishSubject.swift */; }; + 8EFF13142AB0C15500399069 /* RecursiveScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13022AB0C15500399069 /* RecursiveScheduler.swift */; }; + 8EFF13152AB0C15500399069 /* OperationQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13032AB0C15500399069 /* OperationQueueScheduler.swift */; }; + 8EFF13162AB0C15500399069 /* VirtualTimeScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13042AB0C15500399069 /* VirtualTimeScheduler.swift */; }; + 8EFF13172AB0C15500399069 /* SchedulerServices+Emulation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13052AB0C15500399069 /* SchedulerServices+Emulation.swift */; }; + 8EFF13182AB0C15500399069 /* CurrentThreadScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13062AB0C15500399069 /* CurrentThreadScheduler.swift */; }; + 8EFF13192AB0C15500399069 /* MainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13072AB0C15500399069 /* MainScheduler.swift */; }; + 8EFF131A2AB0C15500399069 /* ConcurrentDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13082AB0C15500399069 /* ConcurrentDispatchQueueScheduler.swift */; }; + 8EFF131B2AB0C15500399069 /* ScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF130A2AB0C15500399069 /* ScheduledItem.swift */; }; + 8EFF131C2AB0C15500399069 /* InvocableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF130B2AB0C15500399069 /* InvocableType.swift */; }; + 8EFF131D2AB0C15500399069 /* InvocableScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF130C2AB0C15500399069 /* InvocableScheduledItem.swift */; }; + 8EFF131E2AB0C15500399069 /* DispatchQueueConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF130D2AB0C15500399069 /* DispatchQueueConfiguration.swift */; }; + 8EFF131F2AB0C15500399069 /* ScheduledItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF130E2AB0C15500399069 /* ScheduledItemType.swift */; }; + 8EFF13202AB0C15500399069 /* ConcurrentMainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF130F2AB0C15500399069 /* ConcurrentMainScheduler.swift */; }; + 8EFF13212AB0C15500399069 /* SerialDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13102AB0C15500399069 /* SerialDispatchQueueScheduler.swift */; }; + 8EFF13222AB0C15500399069 /* HistoricalScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13112AB0C15500399069 /* HistoricalScheduler.swift */; }; + 8EFF13232AB0C15500399069 /* VirtualTimeConverterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13122AB0C15500399069 /* VirtualTimeConverterType.swift */; }; + 8EFF13242AB0C15500399069 /* HistoricalSchedulerTimeConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13132AB0C15500399069 /* HistoricalSchedulerTimeConverter.swift */; }; + 8EFF133C2AB0C17800399069 /* RxMutableBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF13392AB0C17800399069 /* RxMutableBox.swift */; }; + 8EFF133D2AB0C17800399069 /* Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF133A2AB0C17800399069 /* Reactive.swift */; }; + 8EFF133E2AB0C17800399069 /* Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF133B2AB0C17800399069 /* Rx.swift */; }; + 8EFF13402AB0C21F00399069 /* SchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EFF133F2AB0C21F00399069 /* SchedulerType.swift */; }; A8F13C2A2316ADE700A70E91 /* MultiPlatformBLEAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C292316ADE700A70E91 /* MultiPlatformBLEAdapter.m */; }; A8F13C2B2316ADE700A70E91 /* MultiPlatformBLEAdapter.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A8F13C282316ADE700A70E91 /* MultiPlatformBLEAdapter.h */; }; A8F13D072316AF7600A70E91 /* RxCBCharacteristic.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C442316AF7600A70E91 /* RxCBCharacteristic.swift */; }; @@ -40,155 +207,6 @@ A8F13D212316AF7600A70E91 /* Unimplemented.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C5F2316AF7600A70E91 /* Unimplemented.swift */; }; A8F13D222316AF7600A70E91 /* RxCBPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C602316AF7600A70E91 /* RxCBPeripheral.swift */; }; A8F13D232316AF7600A70E91 /* RxPeripheralType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C612316AF7600A70E91 /* RxPeripheralType.swift */; }; - A8F13D242316AF7600A70E91 /* Cancelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C632316AF7600A70E91 /* Cancelable.swift */; }; - A8F13D252316AF7600A70E91 /* GroupedObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C642316AF7600A70E91 /* GroupedObservable.swift */; }; - A8F13D262316AF7600A70E91 /* RxMutableBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C652316AF7600A70E91 /* RxMutableBox.swift */; }; - A8F13D272316AF7600A70E91 /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C662316AF7600A70E91 /* Event.swift */; }; - A8F13D282316AF7700A70E91 /* Completable+AndThen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C682316AF7600A70E91 /* Completable+AndThen.swift */; }; - A8F13D292316AF7700A70E91 /* Completable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C6A2316AF7600A70E91 /* Completable.swift */; }; - A8F13D2A2316AF7700A70E91 /* Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C6B2316AF7600A70E91 /* Single.swift */; }; - A8F13D2B2316AF7700A70E91 /* PrimitiveSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C6C2316AF7600A70E91 /* PrimitiveSequence.swift */; }; - A8F13D2C2316AF7700A70E91 /* Maybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C6D2316AF7600A70E91 /* Maybe.swift */; }; - A8F13D2D2316AF7700A70E91 /* ObservableType+PrimitiveSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C6E2316AF7600A70E91 /* ObservableType+PrimitiveSequence.swift */; }; - A8F13D2E2316AF7700A70E91 /* PrimitiveSequence+Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C6F2316AF7600A70E91 /* PrimitiveSequence+Zip+arity.swift */; }; - A8F13D2F2316AF7700A70E91 /* AnyObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C702316AF7600A70E91 /* AnyObserver.swift */; }; - A8F13D302316AF7700A70E91 /* Platform.Darwin.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C722316AF7600A70E91 /* Platform.Darwin.swift */; }; - A8F13D312316AF7700A70E91 /* DeprecationWarner.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C732316AF7600A70E91 /* DeprecationWarner.swift */; }; - A8F13D322316AF7700A70E91 /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C742316AF7600A70E91 /* DispatchQueue+Extensions.swift */; }; - A8F13D332316AF7700A70E91 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C762316AF7600A70E91 /* Bag.swift */; }; - A8F13D342316AF7700A70E91 /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C772316AF7600A70E91 /* PriorityQueue.swift */; }; - A8F13D352316AF7700A70E91 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C782316AF7600A70E91 /* Queue.swift */; }; - A8F13D362316AF7700A70E91 /* InfiniteSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C792316AF7600A70E91 /* InfiniteSequence.swift */; }; - A8F13D372316AF7700A70E91 /* Platform.Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C7A2316AF7600A70E91 /* Platform.Linux.swift */; }; - A8F13D382316AF7700A70E91 /* RecursiveLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C7B2316AF7600A70E91 /* RecursiveLock.swift */; }; - A8F13D392316AF7700A70E91 /* DisposeBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C7D2316AF7600A70E91 /* DisposeBase.swift */; }; - A8F13D3A2316AF7700A70E91 /* DisposeBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C7E2316AF7600A70E91 /* DisposeBag.swift */; }; - A8F13D3B2316AF7700A70E91 /* ScheduledDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C7F2316AF7600A70E91 /* ScheduledDisposable.swift */; }; - A8F13D3C2316AF7700A70E91 /* NopDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C802316AF7600A70E91 /* NopDisposable.swift */; }; - A8F13D3D2316AF7700A70E91 /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C812316AF7600A70E91 /* SubscriptionDisposable.swift */; }; - A8F13D3E2316AF7700A70E91 /* RefCountDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C822316AF7600A70E91 /* RefCountDisposable.swift */; }; - A8F13D3F2316AF7700A70E91 /* CompositeDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C832316AF7600A70E91 /* CompositeDisposable.swift */; }; - A8F13D402316AF7700A70E91 /* SingleAssignmentDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C842316AF7600A70E91 /* SingleAssignmentDisposable.swift */; }; - A8F13D412316AF7700A70E91 /* SerialDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C852316AF7600A70E91 /* SerialDisposable.swift */; }; - A8F13D422316AF7700A70E91 /* BinaryDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C862316AF7600A70E91 /* BinaryDisposable.swift */; }; - A8F13D432316AF7700A70E91 /* AnonymousDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C872316AF7600A70E91 /* AnonymousDisposable.swift */; }; - A8F13D442316AF7700A70E91 /* BooleanDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C882316AF7600A70E91 /* BooleanDisposable.swift */; }; - A8F13D452316AF7700A70E91 /* Disposables.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C892316AF7600A70E91 /* Disposables.swift */; }; - A8F13D462316AF7700A70E91 /* AsMaybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C8B2316AF7600A70E91 /* AsMaybe.swift */; }; - A8F13D472316AF7700A70E91 /* Timeout.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C8C2316AF7600A70E91 /* Timeout.swift */; }; - A8F13D482316AF7700A70E91 /* Never.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C8D2316AF7600A70E91 /* Never.swift */; }; - A8F13D492316AF7700A70E91 /* RetryWhen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C8E2316AF7600A70E91 /* RetryWhen.swift */; }; - A8F13D4A2316AF7700A70E91 /* Do.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C8F2316AF7600A70E91 /* Do.swift */; }; - A8F13D4B2316AF7700A70E91 /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C902316AF7600A70E91 /* Deferred.swift */; }; - A8F13D4C2316AF7700A70E91 /* Buffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C912316AF7600A70E91 /* Buffer.swift */; }; - A8F13D4D2316AF7700A70E91 /* SubscribeOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C922316AF7600A70E91 /* SubscribeOn.swift */; }; - A8F13D4E2316AF7700A70E91 /* DefaultIfEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C932316AF7600A70E91 /* DefaultIfEmpty.swift */; }; - A8F13D4F2316AF7700A70E91 /* Using.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C942316AF7600A70E91 /* Using.swift */; }; - A8F13D502316AF7700A70E91 /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C952316AF7600A70E91 /* Delay.swift */; }; - A8F13D512316AF7700A70E91 /* Producer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C962316AF7600A70E91 /* Producer.swift */; }; - A8F13D522316AF7700A70E91 /* GroupBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C972316AF7600A70E91 /* GroupBy.swift */; }; - A8F13D532316AF7700A70E91 /* Concat.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C982316AF7600A70E91 /* Concat.swift */; }; - A8F13D542316AF7700A70E91 /* Take.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C992316AF7600A70E91 /* Take.swift */; }; - A8F13D552316AF7700A70E91 /* TakeWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C9A2316AF7600A70E91 /* TakeWhile.swift */; }; - A8F13D562316AF7700A70E91 /* TakeLast.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C9B2316AF7600A70E91 /* TakeLast.swift */; }; - A8F13D572316AF7700A70E91 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C9C2316AF7600A70E91 /* Error.swift */; }; - A8F13D582316AF7700A70E91 /* CombineLatest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C9D2316AF7600A70E91 /* CombineLatest.swift */; }; - A8F13D592316AF7700A70E91 /* Sample.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C9E2316AF7600A70E91 /* Sample.swift */; }; - A8F13D5A2316AF7700A70E91 /* AsSingle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13C9F2316AF7600A70E91 /* AsSingle.swift */; }; - A8F13D5B2316AF7700A70E91 /* Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CA02316AF7600A70E91 /* Empty.swift */; }; - A8F13D5C2316AF7700A70E91 /* Enumerated.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CA12316AF7600A70E91 /* Enumerated.swift */; }; - A8F13D5D2316AF7700A70E91 /* DistinctUntilChanged.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CA22316AF7600A70E91 /* DistinctUntilChanged.swift */; }; - A8F13D5E2316AF7700A70E91 /* First.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CA32316AF7600A70E91 /* First.swift */; }; - A8F13D5F2316AF7700A70E91 /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CA42316AF7600A70E91 /* Timer.swift */; }; - A8F13D602316AF7700A70E91 /* AddRef.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CA52316AF7600A70E91 /* AddRef.swift */; }; - A8F13D612316AF7700A70E91 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CA62316AF7600A70E91 /* Sequence.swift */; }; - A8F13D622316AF7700A70E91 /* Sink.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CA72316AF7600A70E91 /* Sink.swift */; }; - A8F13D632316AF7700A70E91 /* Throttle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CA82316AF7600A70E91 /* Throttle.swift */; }; - A8F13D642316AF7700A70E91 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CA92316AF7600A70E91 /* Range.swift */; }; - A8F13D652316AF7700A70E91 /* WithLatestFrom.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CAA2316AF7600A70E91 /* WithLatestFrom.swift */; }; - A8F13D662316AF7700A70E91 /* ObserveOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CAB2316AF7600A70E91 /* ObserveOn.swift */; }; - A8F13D672316AF7700A70E91 /* CombineLatest+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CAC2316AF7600A70E91 /* CombineLatest+Collection.swift */; }; - A8F13D682316AF7700A70E91 /* Multicast.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CAD2316AF7600A70E91 /* Multicast.swift */; }; - A8F13D692316AF7700A70E91 /* SkipWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CAE2316AF7600A70E91 /* SkipWhile.swift */; }; - A8F13D6A2316AF7700A70E91 /* DelaySubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CAF2316AF7600A70E91 /* DelaySubscription.swift */; }; - A8F13D6B2316AF7700A70E91 /* Repeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CB02316AF7600A70E91 /* Repeat.swift */; }; - A8F13D6C2316AF7700A70E91 /* ToArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CB12316AF7600A70E91 /* ToArray.swift */; }; - A8F13D6D2316AF7700A70E91 /* TakeUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CB22316AF7600A70E91 /* TakeUntil.swift */; }; - A8F13D6E2316AF7700A70E91 /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CB42316AF7600A70E91 /* Switch.swift */; }; - A8F13D6F2316AF7700A70E91 /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CB52316AF7600A70E91 /* Window.swift */; }; - A8F13D702316AF7700A70E91 /* Debounce.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CB62316AF7600A70E91 /* Debounce.swift */; }; - A8F13D712316AF7700A70E91 /* Dematerialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CB72316AF7600A70E91 /* Dematerialize.swift */; }; - A8F13D722316AF7700A70E91 /* Zip+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CB82316AF7600A70E91 /* Zip+Collection.swift */; }; - A8F13D732316AF7700A70E91 /* Catch.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CB92316AF7600A70E91 /* Catch.swift */; }; - A8F13D742316AF7700A70E91 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CBA2316AF7600A70E91 /* Filter.swift */; }; - A8F13D752316AF7700A70E91 /* Amb.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CBB2316AF7600A70E91 /* Amb.swift */; }; - A8F13D762316AF7700A70E91 /* Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CBC2316AF7600A70E91 /* Reduce.swift */; }; - A8F13D772316AF7700A70E91 /* CombineLatest+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CBD2316AF7600A70E91 /* CombineLatest+arity.swift */; }; - A8F13D782316AF7700A70E91 /* Zip.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CBF2316AF7600A70E91 /* Zip.swift */; }; - A8F13D792316AF7700A70E91 /* Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CC02316AF7600A70E91 /* Debug.swift */; }; - A8F13D7A2316AF7700A70E91 /* Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CC12316AF7600A70E91 /* Merge.swift */; }; - A8F13D7B2316AF7700A70E91 /* Skip.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CC22316AF7600A70E91 /* Skip.swift */; }; - A8F13D7C2316AF7700A70E91 /* Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CC32316AF7600A70E91 /* Map.swift */; }; - A8F13D7D2316AF7700A70E91 /* SkipUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CC42316AF7600A70E91 /* SkipUntil.swift */; }; - A8F13D7E2316AF7700A70E91 /* StartWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CC52316AF7600A70E91 /* StartWith.swift */; }; - A8F13D7F2316AF7700A70E91 /* Just.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CC62316AF7600A70E91 /* Just.swift */; }; - A8F13D802316AF7700A70E91 /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CC72316AF7600A70E91 /* Optional.swift */; }; - A8F13D812316AF7700A70E91 /* Generate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CC82316AF7600A70E91 /* Generate.swift */; }; - A8F13D822316AF7700A70E91 /* ShareReplayScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CC92316AF7600A70E91 /* ShareReplayScope.swift */; }; - A8F13D832316AF7700A70E91 /* Scan.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CCA2316AF7600A70E91 /* Scan.swift */; }; - A8F13D842316AF7700A70E91 /* Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CCB2316AF7600A70E91 /* Zip+arity.swift */; }; - A8F13D852316AF7700A70E91 /* SwitchIfEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CCC2316AF7600A70E91 /* SwitchIfEmpty.swift */; }; - A8F13D862316AF7700A70E91 /* ElementAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CCD2316AF7600A70E91 /* ElementAt.swift */; }; - A8F13D872316AF7700A70E91 /* Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CCE2316AF7600A70E91 /* Create.swift */; }; - A8F13D882316AF7700A70E91 /* Materialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CCF2316AF7600A70E91 /* Materialize.swift */; }; - A8F13D892316AF7700A70E91 /* SingleAsync.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CD02316AF7600A70E91 /* SingleAsync.swift */; }; - A8F13D8A2316AF7700A70E91 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CD12316AF7600A70E91 /* Disposable.swift */; }; - A8F13D8B2316AF7700A70E91 /* SwiftSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CD32316AF7600A70E91 /* SwiftSupport.swift */; }; - A8F13D8C2316AF7700A70E91 /* ObservableType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CD42316AF7600A70E91 /* ObservableType+Extensions.swift */; }; - A8F13D8D2316AF7700A70E91 /* Bag+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CD62316AF7600A70E91 /* Bag+Rx.swift */; }; - A8F13D8E2316AF7700A70E91 /* String+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CD72316AF7600A70E91 /* String+Rx.swift */; }; - A8F13D8F2316AF7700A70E91 /* ObserverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CD82316AF7600A70E91 /* ObserverType.swift */; }; - A8F13D902316AF7700A70E91 /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CDA2316AF7600A70E91 /* LockOwnerType.swift */; }; - A8F13D912316AF7700A70E91 /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CDB2316AF7600A70E91 /* SynchronizedDisposeType.swift */; }; - A8F13D922316AF7700A70E91 /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CDC2316AF7600A70E91 /* SynchronizedOnType.swift */; }; - A8F13D932316AF7700A70E91 /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CDD2316AF7600A70E91 /* Lock.swift */; }; - A8F13D942316AF7700A70E91 /* AsyncLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CDE2316AF7600A70E91 /* AsyncLock.swift */; }; - A8F13D952316AF7700A70E91 /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CDF2316AF7600A70E91 /* SynchronizedUnsubscribeType.swift */; }; - A8F13D962316AF7700A70E91 /* Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CE02316AF7600A70E91 /* Reactive.swift */; }; - A8F13D972316AF7700A70E91 /* Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CE12316AF7600A70E91 /* Deprecated.swift */; }; - A8F13D982316AF7700A70E91 /* SubjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CE32316AF7600A70E91 /* SubjectType.swift */; }; - A8F13D992316AF7700A70E91 /* BehaviorSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CE42316AF7600A70E91 /* BehaviorSubject.swift */; }; - A8F13D9A2316AF7700A70E91 /* AsyncSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CE52316AF7600A70E91 /* AsyncSubject.swift */; }; - A8F13D9B2316AF7700A70E91 /* ReplaySubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CE62316AF7600A70E91 /* ReplaySubject.swift */; }; - A8F13D9C2316AF7700A70E91 /* PublishSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CE72316AF7600A70E91 /* PublishSubject.swift */; }; - A8F13D9D2316AF7700A70E91 /* ObservableConvertibleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CE82316AF7600A70E91 /* ObservableConvertibleType.swift */; }; - A8F13D9E2316AF7700A70E91 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CE92316AF7600A70E91 /* Observable.swift */; }; - A8F13D9F2316AF7700A70E91 /* SchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CEA2316AF7600A70E91 /* SchedulerType.swift */; }; - A8F13DA02316AF7700A70E91 /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CEB2316AF7600A70E91 /* ConnectableObservableType.swift */; }; - A8F13DA12316AF7700A70E91 /* ObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CEC2316AF7600A70E91 /* ObservableType.swift */; }; - A8F13DA22316AF7700A70E91 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CED2316AF7600A70E91 /* Errors.swift */; }; - A8F13DA32316AF7700A70E91 /* Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CEE2316AF7600A70E91 /* Rx.swift */; }; - A8F13DA42316AF7700A70E91 /* ObserverBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CF02316AF7600A70E91 /* ObserverBase.swift */; }; - A8F13DA52316AF7700A70E91 /* TailRecursiveSink.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CF12316AF7600A70E91 /* TailRecursiveSink.swift */; }; - A8F13DA62316AF7700A70E91 /* AnonymousObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CF22316AF7600A70E91 /* AnonymousObserver.swift */; }; - A8F13DA72316AF7700A70E91 /* RecursiveScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CF42316AF7600A70E91 /* RecursiveScheduler.swift */; }; - A8F13DA82316AF7700A70E91 /* OperationQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CF52316AF7600A70E91 /* OperationQueueScheduler.swift */; }; - A8F13DA92316AF7700A70E91 /* VirtualTimeScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CF62316AF7600A70E91 /* VirtualTimeScheduler.swift */; }; - A8F13DAA2316AF7700A70E91 /* SchedulerServices+Emulation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CF72316AF7600A70E91 /* SchedulerServices+Emulation.swift */; }; - A8F13DAB2316AF7700A70E91 /* CurrentThreadScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CF82316AF7600A70E91 /* CurrentThreadScheduler.swift */; }; - A8F13DAC2316AF7700A70E91 /* MainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CF92316AF7600A70E91 /* MainScheduler.swift */; }; - A8F13DAD2316AF7700A70E91 /* ConcurrentDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CFA2316AF7600A70E91 /* ConcurrentDispatchQueueScheduler.swift */; }; - A8F13DAE2316AF7700A70E91 /* ScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CFC2316AF7600A70E91 /* ScheduledItem.swift */; }; - A8F13DAF2316AF7700A70E91 /* InvocableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CFD2316AF7600A70E91 /* InvocableType.swift */; }; - A8F13DB02316AF7700A70E91 /* InvocableScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CFE2316AF7600A70E91 /* InvocableScheduledItem.swift */; }; - A8F13DB12316AF7700A70E91 /* DispatchQueueConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13CFF2316AF7600A70E91 /* DispatchQueueConfiguration.swift */; }; - A8F13DB22316AF7700A70E91 /* ScheduledItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13D002316AF7600A70E91 /* ScheduledItemType.swift */; }; - A8F13DB32316AF7700A70E91 /* ConcurrentMainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13D012316AF7600A70E91 /* ConcurrentMainScheduler.swift */; }; - A8F13DB42316AF7700A70E91 /* SerialDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13D022316AF7600A70E91 /* SerialDispatchQueueScheduler.swift */; }; - A8F13DB52316AF7700A70E91 /* HistoricalScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13D032316AF7600A70E91 /* HistoricalScheduler.swift */; }; - A8F13DB62316AF7700A70E91 /* VirtualTimeConverterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13D042316AF7600A70E91 /* VirtualTimeConverterType.swift */; }; - A8F13DB72316AF7700A70E91 /* HistoricalSchedulerTimeConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13D052316AF7600A70E91 /* HistoricalSchedulerTimeConverter.swift */; }; - A8F13DB82316AF7700A70E91 /* ImmediateSchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13D062316AF7600A70E91 /* ImmediateSchedulerType.swift */; }; A8F13DFB2316BDFB00A70E91 /* BleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13DF52316BDFA00A70E91 /* BleEvent.swift */; }; A8F13DFC2316BDFB00A70E91 /* BleError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13DF62316BDFA00A70E91 /* BleError.swift */; }; A8F13DFD2316BDFB00A70E91 /* BleUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F13DF72316BDFA00A70E91 /* BleUtils.swift */; }; @@ -214,6 +232,179 @@ /* Begin PBXFileReference section */ 816FE39A234F29B3008BF70D /* BleAdapterFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BleAdapterFactory.swift; sourceTree = ""; }; 81B95B91234B256000D96D28 /* BleAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BleAdapter.swift; sourceTree = ""; }; + 8E63F2D02AB0CE9B0010A0CB /* AtomicInt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicInt.swift; sourceTree = ""; }; + 8E63F2D22AB0CEEC0010A0CB /* DispatchQueue+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+Extensions.swift"; sourceTree = ""; }; + 8E63F2D42AB0CF050010A0CB /* Platform.Darwin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Platform.Darwin.swift; sourceTree = ""; }; + 8E63F2D62AB0CF1E0010A0CB /* Platform.Linux.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Platform.Linux.swift; sourceTree = ""; }; + 8E63F2D82AB0CF400010A0CB /* RecursiveLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecursiveLock.swift; sourceTree = ""; }; + 8E63F2DA2AB0CF730010A0CB /* Bag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bag.swift; sourceTree = ""; }; + 8E63F2DC2AB0CF830010A0CB /* InfiniteSequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfiniteSequence.swift; sourceTree = ""; }; + 8E63F2DE2AB0CFB10010A0CB /* PriorityQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PriorityQueue.swift; sourceTree = ""; }; + 8E63F2E02AB0CFC30010A0CB /* Queue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Queue.swift; sourceTree = ""; }; + 8E63F2E32AB0D6340010A0CB /* DefaultIfEmpty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultIfEmpty.swift; sourceTree = ""; }; + 8E63F2E42AB0D6340010A0CB /* Never.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Never.swift; sourceTree = ""; }; + 8E63F2E52AB0D6340010A0CB /* CombineLatest+arity.tt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "CombineLatest+arity.tt"; sourceTree = ""; }; + 8E63F2E62AB0D6340010A0CB /* GroupBy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupBy.swift; sourceTree = ""; }; + 8E63F2E72AB0D6340010A0CB /* Switch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Switch.swift; sourceTree = ""; }; + 8E63F2E82AB0D6340010A0CB /* WithUnretained.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WithUnretained.swift; sourceTree = ""; }; + 8E63F2E92AB0D6340010A0CB /* Producer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Producer.swift; sourceTree = ""; }; + 8E63F2EA2AB0D6340010A0CB /* RetryWhen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RetryWhen.swift; sourceTree = ""; }; + 8E63F2EB2AB0D6340010A0CB /* StartWith.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartWith.swift; sourceTree = ""; }; + 8E63F2EC2AB0D6340010A0CB /* Scan.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scan.swift; sourceTree = ""; }; + 8E63F2ED2AB0D6350010A0CB /* Using.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Using.swift; sourceTree = ""; }; + 8E63F2EE2AB0D6350010A0CB /* Concat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Concat.swift; sourceTree = ""; }; + 8E63F2EF2AB0D6350010A0CB /* Do.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Do.swift; sourceTree = ""; }; + 8E63F2F02AB0D6350010A0CB /* SwitchIfEmpty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchIfEmpty.swift; sourceTree = ""; }; + 8E63F2F12AB0D6350010A0CB /* Throttle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Throttle.swift; sourceTree = ""; }; + 8E63F2F22AB0D6350010A0CB /* WithLatestFrom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WithLatestFrom.swift; sourceTree = ""; }; + 8E63F2F32AB0D6350010A0CB /* Debounce.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Debounce.swift; sourceTree = ""; }; + 8E63F2F42AB0D6350010A0CB /* Deferred.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Deferred.swift; sourceTree = ""; }; + 8E63F2F52AB0D6350010A0CB /* Enumerated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Enumerated.swift; sourceTree = ""; }; + 8E63F2F62AB0D6350010A0CB /* Buffer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Buffer.swift; sourceTree = ""; }; + 8E63F2F72AB0D6350010A0CB /* Range.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Range.swift; sourceTree = ""; }; + 8E63F2F82AB0D6350010A0CB /* Sequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sequence.swift; sourceTree = ""; }; + 8E63F2F92AB0D6350010A0CB /* SkipWhile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SkipWhile.swift; sourceTree = ""; }; + 8E63F2FA2AB0D6350010A0CB /* ObserveOn.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserveOn.swift; sourceTree = ""; }; + 8E63F2FB2AB0D6350010A0CB /* ElementAt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElementAt.swift; sourceTree = ""; }; + 8E63F2FC2AB0D6350010A0CB /* Filter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Filter.swift; sourceTree = ""; }; + 8E63F2FD2AB0D6350010A0CB /* SingleAsync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleAsync.swift; sourceTree = ""; }; + 8E63F2FE2AB0D6350010A0CB /* Timeout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Timeout.swift; sourceTree = ""; }; + 8E63F2FF2AB0D6360010A0CB /* AddRef.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddRef.swift; sourceTree = ""; }; + 8E63F3002AB0D6360010A0CB /* AsSingle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsSingle.swift; sourceTree = ""; }; + 8E63F3012AB0D6360010A0CB /* CombineLatest+Collection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CombineLatest+Collection.swift"; sourceTree = ""; }; + 8E63F3022AB0D6360010A0CB /* Decode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Decode.swift; sourceTree = ""; }; + 8E63F3032AB0D6360010A0CB /* Window.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Window.swift; sourceTree = ""; }; + 8E63F3042AB0D6360010A0CB /* CompactMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompactMap.swift; sourceTree = ""; }; + 8E63F3052AB0D6360010A0CB /* DelaySubscription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DelaySubscription.swift; sourceTree = ""; }; + 8E63F3062AB0D6360010A0CB /* DistinctUntilChanged.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DistinctUntilChanged.swift; sourceTree = ""; }; + 8E63F3072AB0D6360010A0CB /* First.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = First.swift; sourceTree = ""; }; + 8E63F3082AB0D6360010A0CB /* Amb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Amb.swift; sourceTree = ""; }; + 8E63F3092AB0D6360010A0CB /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Error.swift; sourceTree = ""; }; + 8E63F30A2AB0D6360010A0CB /* Generate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Generate.swift; sourceTree = ""; }; + 8E63F30B2AB0D6370010A0CB /* Materialize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Materialize.swift; sourceTree = ""; }; + 8E63F30C2AB0D6370010A0CB /* SubscribeOn.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscribeOn.swift; sourceTree = ""; }; + 8E63F30D2AB0D6370010A0CB /* Debug.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Debug.swift; sourceTree = ""; }; + 8E63F30E2AB0D6370010A0CB /* Create.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Create.swift; sourceTree = ""; }; + 8E63F30F2AB0D6370010A0CB /* Sample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sample.swift; sourceTree = ""; }; + 8E63F3102AB0D6370010A0CB /* Take.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Take.swift; sourceTree = ""; }; + 8E63F3112AB0D6370010A0CB /* Merge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Merge.swift; sourceTree = ""; }; + 8E63F3122AB0D6370010A0CB /* Empty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Empty.swift; sourceTree = ""; }; + 8E63F3132AB0D6370010A0CB /* Dematerialize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dematerialize.swift; sourceTree = ""; }; + 8E63F3142AB0D6370010A0CB /* Zip.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Zip.swift; sourceTree = ""; }; + 8E63F3152AB0D6370010A0CB /* CombineLatest+arity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CombineLatest+arity.swift"; sourceTree = ""; }; + 8E63F3162AB0D6370010A0CB /* Skip.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Skip.swift; sourceTree = ""; }; + 8E63F3172AB0D6370010A0CB /* TakeLast.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TakeLast.swift; sourceTree = ""; }; + 8E63F3182AB0D6370010A0CB /* CombineLatest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CombineLatest.swift; sourceTree = ""; }; + 8E63F3192AB0D6370010A0CB /* Zip+Collection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Zip+Collection.swift"; sourceTree = ""; }; + 8E63F31A2AB0D6370010A0CB /* ShareReplayScope.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareReplayScope.swift; sourceTree = ""; }; + 8E63F31B2AB0D6380010A0CB /* Sink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sink.swift; sourceTree = ""; }; + 8E63F31C2AB0D6380010A0CB /* Delay.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Delay.swift; sourceTree = ""; }; + 8E63F31D2AB0D6380010A0CB /* Optional.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Optional.swift; sourceTree = ""; }; + 8E63F31E2AB0D6380010A0CB /* Reduce.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reduce.swift; sourceTree = ""; }; + 8E63F31F2AB0D6380010A0CB /* Catch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Catch.swift; sourceTree = ""; }; + 8E63F3202AB0D6380010A0CB /* Just.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Just.swift; sourceTree = ""; }; + 8E63F3212AB0D6380010A0CB /* Repeat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Repeat.swift; sourceTree = ""; }; + 8E63F3222AB0D6380010A0CB /* Zip+arity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Zip+arity.swift"; sourceTree = ""; }; + 8E63F3232AB0D6380010A0CB /* Map.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Map.swift; sourceTree = ""; }; + 8E63F3242AB0D6380010A0CB /* TakeWithPredicate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TakeWithPredicate.swift; sourceTree = ""; }; + 8E63F3252AB0D6380010A0CB /* Timer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Timer.swift; sourceTree = ""; }; + 8E63F3262AB0D6380010A0CB /* SkipUntil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SkipUntil.swift; sourceTree = ""; }; + 8E63F3272AB0D6380010A0CB /* Multicast.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Multicast.swift; sourceTree = ""; }; + 8E63F3282AB0D6380010A0CB /* Zip+arity.tt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Zip+arity.tt"; sourceTree = ""; }; + 8E63F3292AB0D6380010A0CB /* AsMaybe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsMaybe.swift; sourceTree = ""; }; + 8E63F32A2AB0D6380010A0CB /* ToArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToArray.swift; sourceTree = ""; }; + 8EF49F382AB1CCF30019E5F9 /* Array+Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+Utils.swift"; sourceTree = ""; }; + 8EF49F3A2AB1CD3E0019E5F9 /* CBCentral+Uuid.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CBCentral+Uuid.swift"; sourceTree = ""; }; + 8EF49F3C2AB1CD720019E5F9 /* CBCentralManagerDelegateWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CBCentralManagerDelegateWrapper.swift; sourceTree = ""; }; + 8EF49F402AB1CDDE0019E5F9 /* CBPeripheralDelegateWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CBPeripheralDelegateWrapper.swift; sourceTree = ""; }; + 8EF49F482AB1CE400019E5F9 /* ManagerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagerType.swift; sourceTree = ""; }; + 8EFF11E92AB0C09500399069 /* Disposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Disposable.swift; sourceTree = ""; }; + 8EFF11EA2AB0C09500399069 /* Date+Dispatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Date+Dispatch.swift"; path = "../../../Downloads/RxSwift-6.6.0 6/RxSwift/Date+Dispatch.swift"; sourceTree = ""; }; + 8EFF11EB2AB0C09500399069 /* Event.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = ""; }; + 8EFF11EC2AB0C09500399069 /* Cancelable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cancelable.swift; sourceTree = ""; }; + 8EFF11EE2AB0C09500399069 /* DisposeBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisposeBase.swift; sourceTree = ""; }; + 8EFF11EF2AB0C09500399069 /* DisposeBag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisposeBag.swift; sourceTree = ""; }; + 8EFF11F02AB0C09500399069 /* ScheduledDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduledDisposable.swift; sourceTree = ""; }; + 8EFF11F12AB0C09500399069 /* NopDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NopDisposable.swift; sourceTree = ""; }; + 8EFF11F22AB0C09500399069 /* SubscriptionDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscriptionDisposable.swift; sourceTree = ""; }; + 8EFF11F32AB0C09500399069 /* RefCountDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefCountDisposable.swift; sourceTree = ""; }; + 8EFF11F42AB0C09500399069 /* CompositeDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompositeDisposable.swift; sourceTree = ""; }; + 8EFF11F52AB0C09500399069 /* SingleAssignmentDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleAssignmentDisposable.swift; sourceTree = ""; }; + 8EFF11F62AB0C09500399069 /* SerialDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SerialDisposable.swift; sourceTree = ""; }; + 8EFF11F72AB0C09500399069 /* BinaryDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BinaryDisposable.swift; sourceTree = ""; }; + 8EFF11F82AB0C09500399069 /* AnonymousDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnonymousDisposable.swift; sourceTree = ""; }; + 8EFF11F92AB0C09500399069 /* BooleanDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BooleanDisposable.swift; sourceTree = ""; }; + 8EFF11FA2AB0C09500399069 /* Disposables.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Disposables.swift; sourceTree = ""; }; + 8EFF11FB2AB0C09500399069 /* Errors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; + 8EFF12452AB0C09500399069 /* ObservableType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObservableType.swift; sourceTree = ""; }; + 8EFF12472AB0C09500399069 /* LockOwnerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockOwnerType.swift; sourceTree = ""; }; + 8EFF12482AB0C09500399069 /* SynchronizedDisposeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedDisposeType.swift; sourceTree = ""; }; + 8EFF12492AB0C09500399069 /* SynchronizedOnType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedOnType.swift; sourceTree = ""; }; + 8EFF124A2AB0C09500399069 /* Lock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Lock.swift; sourceTree = ""; }; + 8EFF124B2AB0C09500399069 /* AsyncLock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncLock.swift; sourceTree = ""; }; + 8EFF124C2AB0C09500399069 /* SynchronizedUnsubscribeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedUnsubscribeType.swift; sourceTree = ""; }; + 8EFF124D2AB0C09500399069 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = "../../../Downloads/RxSwift-6.6.0 6/RxSwift/Info.plist"; sourceTree = ""; }; + 8EFF124E2AB0C09500399069 /* Observable+Concurrency.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Observable+Concurrency.swift"; path = "../../../Downloads/RxSwift-6.6.0 6/RxSwift/Observable+Concurrency.swift"; sourceTree = ""; }; + 8EFF124F2AB0C09500399069 /* ImmediateSchedulerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImmediateSchedulerType.swift; sourceTree = ""; }; + 8EFF12502AB0C09500399069 /* ObservableType+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ObservableType+Extensions.swift"; sourceTree = ""; }; + 8EFF12522AB0C09600399069 /* Bag+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bag+Rx.swift"; sourceTree = ""; }; + 8EFF12532AB0C09600399069 /* AnyObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyObserver.swift; sourceTree = ""; }; + 8EFF12542AB0C09600399069 /* Observable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Observable.swift; sourceTree = ""; }; + 8EFF12552AB0C09600399069 /* Binder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Binder.swift; path = "../../../Downloads/RxSwift-6.6.0 6/RxSwift/Binder.swift"; sourceTree = ""; }; + 8EFF12562AB0C09600399069 /* GroupedObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupedObservable.swift; sourceTree = ""; }; + 8EFF12572AB0C09600399069 /* ObservableConvertibleType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObservableConvertibleType.swift; sourceTree = ""; }; + 8EFF12582AB0C09600399069 /* ConnectableObservableType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectableObservableType.swift; sourceTree = ""; }; + 8EFF12C22AB0C0A200399069 /* ObserverType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserverType.swift; sourceTree = ""; }; + 8EFF12C42AB0C0A200399069 /* ObserverBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserverBase.swift; sourceTree = ""; }; + 8EFF12C52AB0C0A200399069 /* TailRecursiveSink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TailRecursiveSink.swift; sourceTree = ""; }; + 8EFF12C62AB0C0A200399069 /* AnonymousObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnonymousObserver.swift; sourceTree = ""; }; + 8EFF12CD2AB0C0F200399069 /* Completable+AndThen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Completable+AndThen.swift"; sourceTree = ""; }; + 8EFF12CE2AB0C0F200399069 /* PrimitiveSequence+Zip+arity.tt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "PrimitiveSequence+Zip+arity.tt"; sourceTree = ""; }; + 8EFF12CF2AB0C0F200399069 /* Completable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Completable.swift; sourceTree = ""; }; + 8EFF12D02AB0C0F200399069 /* Single.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Single.swift; sourceTree = ""; }; + 8EFF12D12AB0C0F200399069 /* PrimitiveSequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrimitiveSequence.swift; sourceTree = ""; }; + 8EFF12D22AB0C0F200399069 /* Maybe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Maybe.swift; sourceTree = ""; }; + 8EFF12D32AB0C0F200399069 /* ObservableType+PrimitiveSequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ObservableType+PrimitiveSequence.swift"; sourceTree = ""; }; + 8EFF12D42AB0C0F200399069 /* PrimitiveSequence+Zip+arity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PrimitiveSequence+Zip+arity.swift"; sourceTree = ""; }; + 8EFF12D52AB0C0F200399069 /* PrimitiveSequence+Concurrency.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PrimitiveSequence+Concurrency.swift"; sourceTree = ""; }; + 8EFF12D72AB0C0F200399069 /* Infallible+Zip+arity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Infallible+Zip+arity.swift"; sourceTree = ""; }; + 8EFF12D82AB0C0F200399069 /* Infallible+Concurrency.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Infallible+Concurrency.swift"; sourceTree = ""; }; + 8EFF12D92AB0C0F200399069 /* Infallible+Zip+arity.tt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Infallible+Zip+arity.tt"; sourceTree = ""; }; + 8EFF12DA2AB0C0F200399069 /* Infallible+Create.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Infallible+Create.swift"; sourceTree = ""; }; + 8EFF12DB2AB0C0F200399069 /* Infallible+Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Infallible+Operators.swift"; sourceTree = ""; }; + 8EFF12DC2AB0C0F200399069 /* Infallible+Debug.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Infallible+Debug.swift"; sourceTree = ""; }; + 8EFF12DD2AB0C0F200399069 /* Infallible+CombineLatest+arity.tt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Infallible+CombineLatest+arity.tt"; sourceTree = ""; }; + 8EFF12DE2AB0C0F200399069 /* Infallible+CombineLatest+arity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Infallible+CombineLatest+arity.swift"; sourceTree = ""; }; + 8EFF12DF2AB0C0F200399069 /* Infallible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Infallible.swift; sourceTree = ""; }; + 8EFF12E02AB0C0F200399069 /* Infallible+CombineLatest+Collection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Infallible+CombineLatest+Collection.swift"; sourceTree = ""; }; + 8EFF12E12AB0C0F200399069 /* ObservableConvertibleType+Infallible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ObservableConvertibleType+Infallible.swift"; sourceTree = ""; }; + 8EFF12F42AB0C0FF00399069 /* SwiftSupport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSupport.swift; sourceTree = ""; }; + 8EFF12F72AB0C10D00399069 /* SubjectType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubjectType.swift; sourceTree = ""; }; + 8EFF12F82AB0C10D00399069 /* BehaviorSubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BehaviorSubject.swift; sourceTree = ""; }; + 8EFF12F92AB0C10D00399069 /* AsyncSubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncSubject.swift; sourceTree = ""; }; + 8EFF12FA2AB0C10D00399069 /* ReplaySubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplaySubject.swift; sourceTree = ""; }; + 8EFF12FB2AB0C10D00399069 /* PublishSubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PublishSubject.swift; sourceTree = ""; }; + 8EFF13022AB0C15500399069 /* RecursiveScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecursiveScheduler.swift; sourceTree = ""; }; + 8EFF13032AB0C15500399069 /* OperationQueueScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OperationQueueScheduler.swift; sourceTree = ""; }; + 8EFF13042AB0C15500399069 /* VirtualTimeScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VirtualTimeScheduler.swift; sourceTree = ""; }; + 8EFF13052AB0C15500399069 /* SchedulerServices+Emulation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SchedulerServices+Emulation.swift"; sourceTree = ""; }; + 8EFF13062AB0C15500399069 /* CurrentThreadScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrentThreadScheduler.swift; sourceTree = ""; }; + 8EFF13072AB0C15500399069 /* MainScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainScheduler.swift; sourceTree = ""; }; + 8EFF13082AB0C15500399069 /* ConcurrentDispatchQueueScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentDispatchQueueScheduler.swift; sourceTree = ""; }; + 8EFF130A2AB0C15500399069 /* ScheduledItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduledItem.swift; sourceTree = ""; }; + 8EFF130B2AB0C15500399069 /* InvocableType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvocableType.swift; sourceTree = ""; }; + 8EFF130C2AB0C15500399069 /* InvocableScheduledItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvocableScheduledItem.swift; sourceTree = ""; }; + 8EFF130D2AB0C15500399069 /* DispatchQueueConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DispatchQueueConfiguration.swift; sourceTree = ""; }; + 8EFF130E2AB0C15500399069 /* ScheduledItemType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduledItemType.swift; sourceTree = ""; }; + 8EFF130F2AB0C15500399069 /* ConcurrentMainScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentMainScheduler.swift; sourceTree = ""; }; + 8EFF13102AB0C15500399069 /* SerialDispatchQueueScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SerialDispatchQueueScheduler.swift; sourceTree = ""; }; + 8EFF13112AB0C15500399069 /* HistoricalScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HistoricalScheduler.swift; sourceTree = ""; }; + 8EFF13122AB0C15500399069 /* VirtualTimeConverterType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VirtualTimeConverterType.swift; sourceTree = ""; }; + 8EFF13132AB0C15500399069 /* HistoricalSchedulerTimeConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HistoricalSchedulerTimeConverter.swift; sourceTree = ""; }; + 8EFF13392AB0C17800399069 /* RxMutableBox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxMutableBox.swift; sourceTree = ""; }; + 8EFF133A2AB0C17800399069 /* Reactive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reactive.swift; sourceTree = ""; }; + 8EFF133B2AB0C17800399069 /* Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Rx.swift; sourceTree = ""; }; + 8EFF133F2AB0C21F00399069 /* SchedulerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchedulerType.swift; sourceTree = ""; }; A8F13C252316ADE700A70E91 /* libMultiPlatformBLEAdapter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMultiPlatformBLEAdapter.a; sourceTree = BUILT_PRODUCTS_DIR; }; A8F13C282316ADE700A70E91 /* MultiPlatformBLEAdapter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MultiPlatformBLEAdapter.h; sourceTree = ""; }; A8F13C292316ADE700A70E91 /* MultiPlatformBLEAdapter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MultiPlatformBLEAdapter.m; sourceTree = ""; }; @@ -248,158 +439,6 @@ A8F13C5F2316AF7600A70E91 /* Unimplemented.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Unimplemented.swift; sourceTree = ""; }; A8F13C602316AF7600A70E91 /* RxCBPeripheral.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCBPeripheral.swift; sourceTree = ""; }; A8F13C612316AF7600A70E91 /* RxPeripheralType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxPeripheralType.swift; sourceTree = ""; }; - A8F13C632316AF7600A70E91 /* Cancelable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cancelable.swift; sourceTree = ""; }; - A8F13C642316AF7600A70E91 /* GroupedObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupedObservable.swift; sourceTree = ""; }; - A8F13C652316AF7600A70E91 /* RxMutableBox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxMutableBox.swift; sourceTree = ""; }; - A8F13C662316AF7600A70E91 /* Event.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = ""; }; - A8F13C682316AF7600A70E91 /* Completable+AndThen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Completable+AndThen.swift"; sourceTree = ""; }; - A8F13C692316AF7600A70E91 /* PrimitiveSequence+Zip+arity.tt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "PrimitiveSequence+Zip+arity.tt"; sourceTree = ""; }; - A8F13C6A2316AF7600A70E91 /* Completable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Completable.swift; sourceTree = ""; }; - A8F13C6B2316AF7600A70E91 /* Single.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Single.swift; sourceTree = ""; }; - A8F13C6C2316AF7600A70E91 /* PrimitiveSequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrimitiveSequence.swift; sourceTree = ""; }; - A8F13C6D2316AF7600A70E91 /* Maybe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Maybe.swift; sourceTree = ""; }; - A8F13C6E2316AF7600A70E91 /* ObservableType+PrimitiveSequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ObservableType+PrimitiveSequence.swift"; sourceTree = ""; }; - A8F13C6F2316AF7600A70E91 /* PrimitiveSequence+Zip+arity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PrimitiveSequence+Zip+arity.swift"; sourceTree = ""; }; - A8F13C702316AF7600A70E91 /* AnyObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyObserver.swift; sourceTree = ""; }; - A8F13C722316AF7600A70E91 /* Platform.Darwin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Platform.Darwin.swift; sourceTree = ""; }; - A8F13C732316AF7600A70E91 /* DeprecationWarner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeprecationWarner.swift; sourceTree = ""; }; - A8F13C742316AF7600A70E91 /* DispatchQueue+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+Extensions.swift"; sourceTree = ""; }; - A8F13C762316AF7600A70E91 /* Bag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bag.swift; sourceTree = ""; }; - A8F13C772316AF7600A70E91 /* PriorityQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PriorityQueue.swift; sourceTree = ""; }; - A8F13C782316AF7600A70E91 /* Queue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Queue.swift; sourceTree = ""; }; - A8F13C792316AF7600A70E91 /* InfiniteSequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InfiniteSequence.swift; sourceTree = ""; }; - A8F13C7A2316AF7600A70E91 /* Platform.Linux.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Platform.Linux.swift; sourceTree = ""; }; - A8F13C7B2316AF7600A70E91 /* RecursiveLock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecursiveLock.swift; sourceTree = ""; }; - A8F13C7D2316AF7600A70E91 /* DisposeBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisposeBase.swift; sourceTree = ""; }; - A8F13C7E2316AF7600A70E91 /* DisposeBag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisposeBag.swift; sourceTree = ""; }; - A8F13C7F2316AF7600A70E91 /* ScheduledDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduledDisposable.swift; sourceTree = ""; }; - A8F13C802316AF7600A70E91 /* NopDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NopDisposable.swift; sourceTree = ""; }; - A8F13C812316AF7600A70E91 /* SubscriptionDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscriptionDisposable.swift; sourceTree = ""; }; - A8F13C822316AF7600A70E91 /* RefCountDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefCountDisposable.swift; sourceTree = ""; }; - A8F13C832316AF7600A70E91 /* CompositeDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompositeDisposable.swift; sourceTree = ""; }; - A8F13C842316AF7600A70E91 /* SingleAssignmentDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleAssignmentDisposable.swift; sourceTree = ""; }; - A8F13C852316AF7600A70E91 /* SerialDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SerialDisposable.swift; sourceTree = ""; }; - A8F13C862316AF7600A70E91 /* BinaryDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BinaryDisposable.swift; sourceTree = ""; }; - A8F13C872316AF7600A70E91 /* AnonymousDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnonymousDisposable.swift; sourceTree = ""; }; - A8F13C882316AF7600A70E91 /* BooleanDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BooleanDisposable.swift; sourceTree = ""; }; - A8F13C892316AF7600A70E91 /* Disposables.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Disposables.swift; sourceTree = ""; }; - A8F13C8B2316AF7600A70E91 /* AsMaybe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsMaybe.swift; sourceTree = ""; }; - A8F13C8C2316AF7600A70E91 /* Timeout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Timeout.swift; sourceTree = ""; }; - A8F13C8D2316AF7600A70E91 /* Never.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Never.swift; sourceTree = ""; }; - A8F13C8E2316AF7600A70E91 /* RetryWhen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RetryWhen.swift; sourceTree = ""; }; - A8F13C8F2316AF7600A70E91 /* Do.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Do.swift; sourceTree = ""; }; - A8F13C902316AF7600A70E91 /* Deferred.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Deferred.swift; sourceTree = ""; }; - A8F13C912316AF7600A70E91 /* Buffer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Buffer.swift; sourceTree = ""; }; - A8F13C922316AF7600A70E91 /* SubscribeOn.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscribeOn.swift; sourceTree = ""; }; - A8F13C932316AF7600A70E91 /* DefaultIfEmpty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultIfEmpty.swift; sourceTree = ""; }; - A8F13C942316AF7600A70E91 /* Using.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Using.swift; sourceTree = ""; }; - A8F13C952316AF7600A70E91 /* Delay.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Delay.swift; sourceTree = ""; }; - A8F13C962316AF7600A70E91 /* Producer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Producer.swift; sourceTree = ""; }; - A8F13C972316AF7600A70E91 /* GroupBy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupBy.swift; sourceTree = ""; }; - A8F13C982316AF7600A70E91 /* Concat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Concat.swift; sourceTree = ""; }; - A8F13C992316AF7600A70E91 /* Take.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Take.swift; sourceTree = ""; }; - A8F13C9A2316AF7600A70E91 /* TakeWhile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TakeWhile.swift; sourceTree = ""; }; - A8F13C9B2316AF7600A70E91 /* TakeLast.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TakeLast.swift; sourceTree = ""; }; - A8F13C9C2316AF7600A70E91 /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Error.swift; sourceTree = ""; }; - A8F13C9D2316AF7600A70E91 /* CombineLatest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CombineLatest.swift; sourceTree = ""; }; - A8F13C9E2316AF7600A70E91 /* Sample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sample.swift; sourceTree = ""; }; - A8F13C9F2316AF7600A70E91 /* AsSingle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsSingle.swift; sourceTree = ""; }; - A8F13CA02316AF7600A70E91 /* Empty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Empty.swift; sourceTree = ""; }; - A8F13CA12316AF7600A70E91 /* Enumerated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Enumerated.swift; sourceTree = ""; }; - A8F13CA22316AF7600A70E91 /* DistinctUntilChanged.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DistinctUntilChanged.swift; sourceTree = ""; }; - A8F13CA32316AF7600A70E91 /* First.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = First.swift; sourceTree = ""; }; - A8F13CA42316AF7600A70E91 /* Timer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Timer.swift; sourceTree = ""; }; - A8F13CA52316AF7600A70E91 /* AddRef.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddRef.swift; sourceTree = ""; }; - A8F13CA62316AF7600A70E91 /* Sequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sequence.swift; sourceTree = ""; }; - A8F13CA72316AF7600A70E91 /* Sink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sink.swift; sourceTree = ""; }; - A8F13CA82316AF7600A70E91 /* Throttle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Throttle.swift; sourceTree = ""; }; - A8F13CA92316AF7600A70E91 /* Range.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Range.swift; sourceTree = ""; }; - A8F13CAA2316AF7600A70E91 /* WithLatestFrom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WithLatestFrom.swift; sourceTree = ""; }; - A8F13CAB2316AF7600A70E91 /* ObserveOn.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserveOn.swift; sourceTree = ""; }; - A8F13CAC2316AF7600A70E91 /* CombineLatest+Collection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CombineLatest+Collection.swift"; sourceTree = ""; }; - A8F13CAD2316AF7600A70E91 /* Multicast.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Multicast.swift; sourceTree = ""; }; - A8F13CAE2316AF7600A70E91 /* SkipWhile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SkipWhile.swift; sourceTree = ""; }; - A8F13CAF2316AF7600A70E91 /* DelaySubscription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DelaySubscription.swift; sourceTree = ""; }; - A8F13CB02316AF7600A70E91 /* Repeat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Repeat.swift; sourceTree = ""; }; - A8F13CB12316AF7600A70E91 /* ToArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToArray.swift; sourceTree = ""; }; - A8F13CB22316AF7600A70E91 /* TakeUntil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TakeUntil.swift; sourceTree = ""; }; - A8F13CB32316AF7600A70E91 /* Zip+arity.tt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Zip+arity.tt"; sourceTree = ""; }; - A8F13CB42316AF7600A70E91 /* Switch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Switch.swift; sourceTree = ""; }; - A8F13CB52316AF7600A70E91 /* Window.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Window.swift; sourceTree = ""; }; - A8F13CB62316AF7600A70E91 /* Debounce.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Debounce.swift; sourceTree = ""; }; - A8F13CB72316AF7600A70E91 /* Dematerialize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dematerialize.swift; sourceTree = ""; }; - A8F13CB82316AF7600A70E91 /* Zip+Collection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Zip+Collection.swift"; sourceTree = ""; }; - A8F13CB92316AF7600A70E91 /* Catch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Catch.swift; sourceTree = ""; }; - A8F13CBA2316AF7600A70E91 /* Filter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Filter.swift; sourceTree = ""; }; - A8F13CBB2316AF7600A70E91 /* Amb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Amb.swift; sourceTree = ""; }; - A8F13CBC2316AF7600A70E91 /* Reduce.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reduce.swift; sourceTree = ""; }; - A8F13CBD2316AF7600A70E91 /* CombineLatest+arity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CombineLatest+arity.swift"; sourceTree = ""; }; - A8F13CBE2316AF7600A70E91 /* CombineLatest+arity.tt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "CombineLatest+arity.tt"; sourceTree = ""; }; - A8F13CBF2316AF7600A70E91 /* Zip.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Zip.swift; sourceTree = ""; }; - A8F13CC02316AF7600A70E91 /* Debug.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Debug.swift; sourceTree = ""; }; - A8F13CC12316AF7600A70E91 /* Merge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Merge.swift; sourceTree = ""; }; - A8F13CC22316AF7600A70E91 /* Skip.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Skip.swift; sourceTree = ""; }; - A8F13CC32316AF7600A70E91 /* Map.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Map.swift; sourceTree = ""; }; - A8F13CC42316AF7600A70E91 /* SkipUntil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SkipUntil.swift; sourceTree = ""; }; - A8F13CC52316AF7600A70E91 /* StartWith.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartWith.swift; sourceTree = ""; }; - A8F13CC62316AF7600A70E91 /* Just.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Just.swift; sourceTree = ""; }; - A8F13CC72316AF7600A70E91 /* Optional.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Optional.swift; sourceTree = ""; }; - A8F13CC82316AF7600A70E91 /* Generate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Generate.swift; sourceTree = ""; }; - A8F13CC92316AF7600A70E91 /* ShareReplayScope.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareReplayScope.swift; sourceTree = ""; }; - A8F13CCA2316AF7600A70E91 /* Scan.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scan.swift; sourceTree = ""; }; - A8F13CCB2316AF7600A70E91 /* Zip+arity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Zip+arity.swift"; sourceTree = ""; }; - A8F13CCC2316AF7600A70E91 /* SwitchIfEmpty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchIfEmpty.swift; sourceTree = ""; }; - A8F13CCD2316AF7600A70E91 /* ElementAt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElementAt.swift; sourceTree = ""; }; - A8F13CCE2316AF7600A70E91 /* Create.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Create.swift; sourceTree = ""; }; - A8F13CCF2316AF7600A70E91 /* Materialize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Materialize.swift; sourceTree = ""; }; - A8F13CD02316AF7600A70E91 /* SingleAsync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleAsync.swift; sourceTree = ""; }; - A8F13CD12316AF7600A70E91 /* Disposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Disposable.swift; sourceTree = ""; }; - A8F13CD32316AF7600A70E91 /* SwiftSupport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSupport.swift; sourceTree = ""; }; - A8F13CD42316AF7600A70E91 /* ObservableType+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ObservableType+Extensions.swift"; sourceTree = ""; }; - A8F13CD62316AF7600A70E91 /* Bag+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bag+Rx.swift"; sourceTree = ""; }; - A8F13CD72316AF7600A70E91 /* String+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Rx.swift"; sourceTree = ""; }; - A8F13CD82316AF7600A70E91 /* ObserverType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserverType.swift; sourceTree = ""; }; - A8F13CDA2316AF7600A70E91 /* LockOwnerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockOwnerType.swift; sourceTree = ""; }; - A8F13CDB2316AF7600A70E91 /* SynchronizedDisposeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedDisposeType.swift; sourceTree = ""; }; - A8F13CDC2316AF7600A70E91 /* SynchronizedOnType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedOnType.swift; sourceTree = ""; }; - A8F13CDD2316AF7600A70E91 /* Lock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Lock.swift; sourceTree = ""; }; - A8F13CDE2316AF7600A70E91 /* AsyncLock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncLock.swift; sourceTree = ""; }; - A8F13CDF2316AF7600A70E91 /* SynchronizedUnsubscribeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedUnsubscribeType.swift; sourceTree = ""; }; - A8F13CE02316AF7600A70E91 /* Reactive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reactive.swift; sourceTree = ""; }; - A8F13CE12316AF7600A70E91 /* Deprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Deprecated.swift; sourceTree = ""; }; - A8F13CE32316AF7600A70E91 /* SubjectType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubjectType.swift; sourceTree = ""; }; - A8F13CE42316AF7600A70E91 /* BehaviorSubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BehaviorSubject.swift; sourceTree = ""; }; - A8F13CE52316AF7600A70E91 /* AsyncSubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncSubject.swift; sourceTree = ""; }; - A8F13CE62316AF7600A70E91 /* ReplaySubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplaySubject.swift; sourceTree = ""; }; - A8F13CE72316AF7600A70E91 /* PublishSubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PublishSubject.swift; sourceTree = ""; }; - A8F13CE82316AF7600A70E91 /* ObservableConvertibleType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObservableConvertibleType.swift; sourceTree = ""; }; - A8F13CE92316AF7600A70E91 /* Observable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Observable.swift; sourceTree = ""; }; - A8F13CEA2316AF7600A70E91 /* SchedulerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchedulerType.swift; sourceTree = ""; }; - A8F13CEB2316AF7600A70E91 /* ConnectableObservableType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectableObservableType.swift; sourceTree = ""; }; - A8F13CEC2316AF7600A70E91 /* ObservableType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObservableType.swift; sourceTree = ""; }; - A8F13CED2316AF7600A70E91 /* Errors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; - A8F13CEE2316AF7600A70E91 /* Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Rx.swift; sourceTree = ""; }; - A8F13CF02316AF7600A70E91 /* ObserverBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserverBase.swift; sourceTree = ""; }; - A8F13CF12316AF7600A70E91 /* TailRecursiveSink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TailRecursiveSink.swift; sourceTree = ""; }; - A8F13CF22316AF7600A70E91 /* AnonymousObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnonymousObserver.swift; sourceTree = ""; }; - A8F13CF42316AF7600A70E91 /* RecursiveScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecursiveScheduler.swift; sourceTree = ""; }; - A8F13CF52316AF7600A70E91 /* OperationQueueScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OperationQueueScheduler.swift; sourceTree = ""; }; - A8F13CF62316AF7600A70E91 /* VirtualTimeScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VirtualTimeScheduler.swift; sourceTree = ""; }; - A8F13CF72316AF7600A70E91 /* SchedulerServices+Emulation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SchedulerServices+Emulation.swift"; sourceTree = ""; }; - A8F13CF82316AF7600A70E91 /* CurrentThreadScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrentThreadScheduler.swift; sourceTree = ""; }; - A8F13CF92316AF7600A70E91 /* MainScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainScheduler.swift; sourceTree = ""; }; - A8F13CFA2316AF7600A70E91 /* ConcurrentDispatchQueueScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentDispatchQueueScheduler.swift; sourceTree = ""; }; - A8F13CFC2316AF7600A70E91 /* ScheduledItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduledItem.swift; sourceTree = ""; }; - A8F13CFD2316AF7600A70E91 /* InvocableType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvocableType.swift; sourceTree = ""; }; - A8F13CFE2316AF7600A70E91 /* InvocableScheduledItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvocableScheduledItem.swift; sourceTree = ""; }; - A8F13CFF2316AF7600A70E91 /* DispatchQueueConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DispatchQueueConfiguration.swift; sourceTree = ""; }; - A8F13D002316AF7600A70E91 /* ScheduledItemType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduledItemType.swift; sourceTree = ""; }; - A8F13D012316AF7600A70E91 /* ConcurrentMainScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentMainScheduler.swift; sourceTree = ""; }; - A8F13D022316AF7600A70E91 /* SerialDispatchQueueScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SerialDispatchQueueScheduler.swift; sourceTree = ""; }; - A8F13D032316AF7600A70E91 /* HistoricalScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HistoricalScheduler.swift; sourceTree = ""; }; - A8F13D042316AF7600A70E91 /* VirtualTimeConverterType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VirtualTimeConverterType.swift; sourceTree = ""; }; - A8F13D052316AF7600A70E91 /* HistoricalSchedulerTimeConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HistoricalSchedulerTimeConverter.swift; sourceTree = ""; }; - A8F13D062316AF7600A70E91 /* ImmediateSchedulerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImmediateSchedulerType.swift; sourceTree = ""; }; A8F13DF52316BDFA00A70E91 /* BleEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BleEvent.swift; sourceTree = ""; }; A8F13DF62316BDFA00A70E91 /* BleError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BleError.swift; sourceTree = ""; }; A8F13DF72316BDFA00A70E91 /* BleUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BleUtils.swift; sourceTree = ""; }; @@ -421,333 +460,370 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - A8F13C1C2316ADE700A70E91 = { + 8E63F2CE2AB0CE770010A0CB /* Platform */ = { isa = PBXGroup; children = ( - A8F13C312316AE3600A70E91 /* MultiPlatformBLEAdapter-Bridging-Header.h */, - A8F13C432316AF7600A70E91 /* RxBluetoothKit */, - A8F13C622316AF7600A70E91 /* RxSwift */, - A8F13C272316ADE700A70E91 /* classes */, - A8F13C262316ADE700A70E91 /* Products */, + 8E63F2CF2AB0CE830010A0CB /* DataStructures */, + 8E63F2D02AB0CE9B0010A0CB /* AtomicInt.swift */, + 8E63F2D22AB0CEEC0010A0CB /* DispatchQueue+Extensions.swift */, + 8E63F2D42AB0CF050010A0CB /* Platform.Darwin.swift */, + 8E63F2D62AB0CF1E0010A0CB /* Platform.Linux.swift */, + 8E63F2D82AB0CF400010A0CB /* RecursiveLock.swift */, ); + path = Platform; sourceTree = ""; }; - A8F13C262316ADE700A70E91 /* Products */ = { + 8E63F2CF2AB0CE830010A0CB /* DataStructures */ = { isa = PBXGroup; children = ( - A8F13C252316ADE700A70E91 /* libMultiPlatformBLEAdapter.a */, + 8E63F2DA2AB0CF730010A0CB /* Bag.swift */, + 8E63F2DC2AB0CF830010A0CB /* InfiniteSequence.swift */, + 8E63F2DE2AB0CFB10010A0CB /* PriorityQueue.swift */, + 8E63F2E02AB0CFC30010A0CB /* Queue.swift */, ); - name = Products; + path = DataStructures; sourceTree = ""; }; - A8F13C272316ADE700A70E91 /* classes */ = { + 8E63F2E22AB0D5D60010A0CB /* Observables */ = { isa = PBXGroup; children = ( - A8F13E012316BE2F00A70E91 /* Utils */, - A8F13DF92316BDFB00A70E91 /* BleClientManager.h */, - A8F13DF62316BDFA00A70E91 /* BleError.swift */, - A8F13DF52316BDFA00A70E91 /* BleEvent.swift */, - A8F13DF82316BDFA00A70E91 /* BleExtensions.swift */, - A8F13DFA2316BDFB00A70E91 /* BleModule.swift */, - A8F13DF72316BDFA00A70E91 /* BleUtils.swift */, - A8F13C282316ADE700A70E91 /* MultiPlatformBLEAdapter.h */, - A8F13C292316ADE700A70E91 /* MultiPlatformBLEAdapter.m */, - 81B95B91234B256000D96D28 /* BleAdapter.swift */, - 816FE39A234F29B3008BF70D /* BleAdapterFactory.swift */, + 8E63F2FF2AB0D6360010A0CB /* AddRef.swift */, + 8E63F3082AB0D6360010A0CB /* Amb.swift */, + 8E63F3292AB0D6380010A0CB /* AsMaybe.swift */, + 8E63F3002AB0D6360010A0CB /* AsSingle.swift */, + 8E63F2F62AB0D6350010A0CB /* Buffer.swift */, + 8E63F31F2AB0D6380010A0CB /* Catch.swift */, + 8E63F3182AB0D6370010A0CB /* CombineLatest.swift */, + 8E63F3152AB0D6370010A0CB /* CombineLatest+arity.swift */, + 8E63F2E52AB0D6340010A0CB /* CombineLatest+arity.tt */, + 8E63F3012AB0D6360010A0CB /* CombineLatest+Collection.swift */, + 8E63F3042AB0D6360010A0CB /* CompactMap.swift */, + 8E63F2EE2AB0D6350010A0CB /* Concat.swift */, + 8E63F30E2AB0D6370010A0CB /* Create.swift */, + 8E63F2F32AB0D6350010A0CB /* Debounce.swift */, + 8E63F30D2AB0D6370010A0CB /* Debug.swift */, + 8E63F3022AB0D6360010A0CB /* Decode.swift */, + 8E63F2E32AB0D6340010A0CB /* DefaultIfEmpty.swift */, + 8E63F2F42AB0D6350010A0CB /* Deferred.swift */, + 8E63F31C2AB0D6380010A0CB /* Delay.swift */, + 8E63F3052AB0D6360010A0CB /* DelaySubscription.swift */, + 8E63F3132AB0D6370010A0CB /* Dematerialize.swift */, + 8E63F3062AB0D6360010A0CB /* DistinctUntilChanged.swift */, + 8E63F2EF2AB0D6350010A0CB /* Do.swift */, + 8E63F2FB2AB0D6350010A0CB /* ElementAt.swift */, + 8E63F3122AB0D6370010A0CB /* Empty.swift */, + 8E63F2F52AB0D6350010A0CB /* Enumerated.swift */, + 8E63F3092AB0D6360010A0CB /* Error.swift */, + 8E63F2FC2AB0D6350010A0CB /* Filter.swift */, + 8E63F3072AB0D6360010A0CB /* First.swift */, + 8E63F30A2AB0D6360010A0CB /* Generate.swift */, + 8E63F2E62AB0D6340010A0CB /* GroupBy.swift */, + 8E63F3202AB0D6380010A0CB /* Just.swift */, + 8E63F3232AB0D6380010A0CB /* Map.swift */, + 8E63F30B2AB0D6370010A0CB /* Materialize.swift */, + 8E63F3112AB0D6370010A0CB /* Merge.swift */, + 8E63F3272AB0D6380010A0CB /* Multicast.swift */, + 8E63F2E42AB0D6340010A0CB /* Never.swift */, + 8E63F2FA2AB0D6350010A0CB /* ObserveOn.swift */, + 8E63F31D2AB0D6380010A0CB /* Optional.swift */, + 8E63F2E92AB0D6340010A0CB /* Producer.swift */, + 8E63F2F72AB0D6350010A0CB /* Range.swift */, + 8E63F31E2AB0D6380010A0CB /* Reduce.swift */, + 8E63F3212AB0D6380010A0CB /* Repeat.swift */, + 8E63F2EA2AB0D6340010A0CB /* RetryWhen.swift */, + 8E63F30F2AB0D6370010A0CB /* Sample.swift */, + 8E63F2EC2AB0D6340010A0CB /* Scan.swift */, + 8E63F2F82AB0D6350010A0CB /* Sequence.swift */, + 8E63F31A2AB0D6370010A0CB /* ShareReplayScope.swift */, + 8E63F2FD2AB0D6350010A0CB /* SingleAsync.swift */, + 8E63F31B2AB0D6380010A0CB /* Sink.swift */, + 8E63F3162AB0D6370010A0CB /* Skip.swift */, + 8E63F3262AB0D6380010A0CB /* SkipUntil.swift */, + 8E63F2F92AB0D6350010A0CB /* SkipWhile.swift */, + 8E63F2EB2AB0D6340010A0CB /* StartWith.swift */, + 8E63F30C2AB0D6370010A0CB /* SubscribeOn.swift */, + 8E63F2E72AB0D6340010A0CB /* Switch.swift */, + 8E63F2F02AB0D6350010A0CB /* SwitchIfEmpty.swift */, + 8E63F3102AB0D6370010A0CB /* Take.swift */, + 8E63F3172AB0D6370010A0CB /* TakeLast.swift */, + 8E63F3242AB0D6380010A0CB /* TakeWithPredicate.swift */, + 8E63F2F12AB0D6350010A0CB /* Throttle.swift */, + 8E63F2FE2AB0D6350010A0CB /* Timeout.swift */, + 8E63F3252AB0D6380010A0CB /* Timer.swift */, + 8E63F32A2AB0D6380010A0CB /* ToArray.swift */, + 8E63F2ED2AB0D6350010A0CB /* Using.swift */, + 8E63F3032AB0D6360010A0CB /* Window.swift */, + 8E63F2F22AB0D6350010A0CB /* WithLatestFrom.swift */, + 8E63F2E82AB0D6340010A0CB /* WithUnretained.swift */, + 8E63F3142AB0D6370010A0CB /* Zip.swift */, + 8E63F3222AB0D6380010A0CB /* Zip+arity.swift */, + 8E63F3282AB0D6380010A0CB /* Zip+arity.tt */, + 8E63F3192AB0D6370010A0CB /* Zip+Collection.swift */, ); - path = classes; + path = Observables; sourceTree = ""; }; - A8F13C432316AF7600A70E91 /* RxBluetoothKit */ = { + 8EFF11ED2AB0C09500399069 /* Disposables */ = { isa = PBXGroup; children = ( - A8F13C442316AF7600A70E91 /* RxCBCharacteristic.swift */, - A8F13C452316AF7600A70E91 /* RxCBService.swift */, - A8F13C462316AF7600A70E91 /* RxDescriptorType.swift */, - A8F13C472316AF7600A70E91 /* BluetoothState.swift */, - A8F13C482316AF7600A70E91 /* Peripheral.swift */, - A8F13C492316AF7600A70E91 /* Logging.swift */, - A8F13C4A2316AF7600A70E91 /* RxCharacteristicType.swift */, - A8F13C4B2316AF7600A70E91 /* DeviceIdentifiers.swift */, - A8F13C4C2316AF7600A70E91 /* Service.swift */, - A8F13C4D2316AF7600A70E91 /* RxServiceType.swift */, - A8F13C4E2316AF7600A70E91 /* BluetoothManager.swift */, - A8F13C4F2316AF7600A70E91 /* BluetoothError.swift */, - A8F13C502316AF7600A70E91 /* Peripheral+Convenience.swift */, - A8F13C512316AF7600A70E91 /* AdvertisementData.swift */, - A8F13C522316AF7600A70E91 /* RxBluetoothKit.h */, - A8F13C532316AF7600A70E91 /* RxCentralManagerType.swift */, - A8F13C542316AF7600A70E91 /* RxCBCentralManager.swift */, - A8F13C552316AF7600A70E91 /* RestoredState.swift */, - A8F13C562316AF7600A70E91 /* Descriptor.swift */, - A8F13C572316AF7600A70E91 /* Boxes.swift */, - A8F13C582316AF7600A70E91 /* RxCBDescriptor.swift */, - A8F13C592316AF7600A70E91 /* Observable+Absorb.swift */, - A8F13C5A2316AF7600A70E91 /* UUIDIdentifiable.swift */, - A8F13C5B2316AF7600A70E91 /* ScanOperation.swift */, - A8F13C5C2316AF7600A70E91 /* ScannedPeripheral.swift */, - A8F13C5D2316AF7600A70E91 /* Observable+QueueSubscribeOn.swift */, - A8F13C5E2316AF7600A70E91 /* Characteristic.swift */, - A8F13C5F2316AF7600A70E91 /* Unimplemented.swift */, - A8F13C602316AF7600A70E91 /* RxCBPeripheral.swift */, - A8F13C612316AF7600A70E91 /* RxPeripheralType.swift */, + 8EFF11EE2AB0C09500399069 /* DisposeBase.swift */, + 8EFF11EF2AB0C09500399069 /* DisposeBag.swift */, + 8EFF11F02AB0C09500399069 /* ScheduledDisposable.swift */, + 8EFF11F12AB0C09500399069 /* NopDisposable.swift */, + 8EFF11F22AB0C09500399069 /* SubscriptionDisposable.swift */, + 8EFF11F32AB0C09500399069 /* RefCountDisposable.swift */, + 8EFF11F42AB0C09500399069 /* CompositeDisposable.swift */, + 8EFF11F52AB0C09500399069 /* SingleAssignmentDisposable.swift */, + 8EFF11F62AB0C09500399069 /* SerialDisposable.swift */, + 8EFF11F72AB0C09500399069 /* BinaryDisposable.swift */, + 8EFF11F82AB0C09500399069 /* AnonymousDisposable.swift */, + 8EFF11F92AB0C09500399069 /* BooleanDisposable.swift */, + 8EFF11FA2AB0C09500399069 /* Disposables.swift */, ); - path = RxBluetoothKit; + path = Disposables; sourceTree = ""; }; - A8F13C622316AF7600A70E91 /* RxSwift */ = { + 8EFF12462AB0C09500399069 /* Concurrency */ = { isa = PBXGroup; children = ( - A8F13C632316AF7600A70E91 /* Cancelable.swift */, - A8F13C642316AF7600A70E91 /* GroupedObservable.swift */, - A8F13C652316AF7600A70E91 /* RxMutableBox.swift */, - A8F13C662316AF7600A70E91 /* Event.swift */, - A8F13C672316AF7600A70E91 /* Traits */, - A8F13C702316AF7600A70E91 /* AnyObserver.swift */, - A8F13C712316AF7600A70E91 /* Platform */, - A8F13C7C2316AF7600A70E91 /* Disposables */, - A8F13C8A2316AF7600A70E91 /* Observables */, - A8F13CD12316AF7600A70E91 /* Disposable.swift */, - A8F13CD22316AF7600A70E91 /* SwiftSupport */, - A8F13CD42316AF7600A70E91 /* ObservableType+Extensions.swift */, - A8F13CD52316AF7600A70E91 /* Extensions */, - A8F13CD82316AF7600A70E91 /* ObserverType.swift */, - A8F13CD92316AF7600A70E91 /* Concurrency */, - A8F13CE02316AF7600A70E91 /* Reactive.swift */, - A8F13CE12316AF7600A70E91 /* Deprecated.swift */, - A8F13CE22316AF7600A70E91 /* Subjects */, - A8F13CE82316AF7600A70E91 /* ObservableConvertibleType.swift */, - A8F13CE92316AF7600A70E91 /* Observable.swift */, - A8F13CEA2316AF7600A70E91 /* SchedulerType.swift */, - A8F13CEB2316AF7600A70E91 /* ConnectableObservableType.swift */, - A8F13CEC2316AF7600A70E91 /* ObservableType.swift */, - A8F13CED2316AF7600A70E91 /* Errors.swift */, - A8F13CEE2316AF7600A70E91 /* Rx.swift */, - A8F13CEF2316AF7600A70E91 /* Observers */, - A8F13CF32316AF7600A70E91 /* Schedulers */, - A8F13D062316AF7600A70E91 /* ImmediateSchedulerType.swift */, + 8EFF12472AB0C09500399069 /* LockOwnerType.swift */, + 8EFF12482AB0C09500399069 /* SynchronizedDisposeType.swift */, + 8EFF12492AB0C09500399069 /* SynchronizedOnType.swift */, + 8EFF124A2AB0C09500399069 /* Lock.swift */, + 8EFF124B2AB0C09500399069 /* AsyncLock.swift */, + 8EFF124C2AB0C09500399069 /* SynchronizedUnsubscribeType.swift */, ); - path = RxSwift; + path = Concurrency; sourceTree = ""; }; - A8F13C672316AF7600A70E91 /* Traits */ = { + 8EFF12512AB0C09600399069 /* Extensions */ = { isa = PBXGroup; children = ( - A8F13C682316AF7600A70E91 /* Completable+AndThen.swift */, - A8F13C692316AF7600A70E91 /* PrimitiveSequence+Zip+arity.tt */, - A8F13C6A2316AF7600A70E91 /* Completable.swift */, - A8F13C6B2316AF7600A70E91 /* Single.swift */, - A8F13C6C2316AF7600A70E91 /* PrimitiveSequence.swift */, - A8F13C6D2316AF7600A70E91 /* Maybe.swift */, - A8F13C6E2316AF7600A70E91 /* ObservableType+PrimitiveSequence.swift */, - A8F13C6F2316AF7600A70E91 /* PrimitiveSequence+Zip+arity.swift */, + 8EFF12522AB0C09600399069 /* Bag+Rx.swift */, ); - path = Traits; + path = Extensions; sourceTree = ""; }; - A8F13C712316AF7600A70E91 /* Platform */ = { + 8EFF12C32AB0C0A200399069 /* Observers */ = { isa = PBXGroup; children = ( - A8F13C722316AF7600A70E91 /* Platform.Darwin.swift */, - A8F13C732316AF7600A70E91 /* DeprecationWarner.swift */, - A8F13C742316AF7600A70E91 /* DispatchQueue+Extensions.swift */, - A8F13C752316AF7600A70E91 /* DataStructures */, - A8F13C7A2316AF7600A70E91 /* Platform.Linux.swift */, - A8F13C7B2316AF7600A70E91 /* RecursiveLock.swift */, + 8EFF12C42AB0C0A200399069 /* ObserverBase.swift */, + 8EFF12C52AB0C0A200399069 /* TailRecursiveSink.swift */, + 8EFF12C62AB0C0A200399069 /* AnonymousObserver.swift */, ); - path = Platform; + path = Observers; sourceTree = ""; }; - A8F13C752316AF7600A70E91 /* DataStructures */ = { + 8EFF12CB2AB0C0F200399069 /* Traits */ = { isa = PBXGroup; children = ( - A8F13C762316AF7600A70E91 /* Bag.swift */, - A8F13C772316AF7600A70E91 /* PriorityQueue.swift */, - A8F13C782316AF7600A70E91 /* Queue.swift */, - A8F13C792316AF7600A70E91 /* InfiniteSequence.swift */, + 8EFF12CC2AB0C0F200399069 /* PrimitiveSequence */, + 8EFF12D62AB0C0F200399069 /* Infallible */, ); - path = DataStructures; + path = Traits; sourceTree = ""; }; - A8F13C7C2316AF7600A70E91 /* Disposables */ = { + 8EFF12CC2AB0C0F200399069 /* PrimitiveSequence */ = { isa = PBXGroup; children = ( - A8F13C7D2316AF7600A70E91 /* DisposeBase.swift */, - A8F13C7E2316AF7600A70E91 /* DisposeBag.swift */, - A8F13C7F2316AF7600A70E91 /* ScheduledDisposable.swift */, - A8F13C802316AF7600A70E91 /* NopDisposable.swift */, - A8F13C812316AF7600A70E91 /* SubscriptionDisposable.swift */, - A8F13C822316AF7600A70E91 /* RefCountDisposable.swift */, - A8F13C832316AF7600A70E91 /* CompositeDisposable.swift */, - A8F13C842316AF7600A70E91 /* SingleAssignmentDisposable.swift */, - A8F13C852316AF7600A70E91 /* SerialDisposable.swift */, - A8F13C862316AF7600A70E91 /* BinaryDisposable.swift */, - A8F13C872316AF7600A70E91 /* AnonymousDisposable.swift */, - A8F13C882316AF7600A70E91 /* BooleanDisposable.swift */, - A8F13C892316AF7600A70E91 /* Disposables.swift */, + 8EFF12CD2AB0C0F200399069 /* Completable+AndThen.swift */, + 8EFF12CE2AB0C0F200399069 /* PrimitiveSequence+Zip+arity.tt */, + 8EFF12CF2AB0C0F200399069 /* Completable.swift */, + 8EFF12D02AB0C0F200399069 /* Single.swift */, + 8EFF12D12AB0C0F200399069 /* PrimitiveSequence.swift */, + 8EFF12D22AB0C0F200399069 /* Maybe.swift */, + 8EFF12D32AB0C0F200399069 /* ObservableType+PrimitiveSequence.swift */, + 8EFF12D42AB0C0F200399069 /* PrimitiveSequence+Zip+arity.swift */, + 8EFF12D52AB0C0F200399069 /* PrimitiveSequence+Concurrency.swift */, ); - path = Disposables; + path = PrimitiveSequence; sourceTree = ""; }; - A8F13C8A2316AF7600A70E91 /* Observables */ = { + 8EFF12D62AB0C0F200399069 /* Infallible */ = { isa = PBXGroup; children = ( - A8F13C8B2316AF7600A70E91 /* AsMaybe.swift */, - A8F13C8C2316AF7600A70E91 /* Timeout.swift */, - A8F13C8D2316AF7600A70E91 /* Never.swift */, - A8F13C8E2316AF7600A70E91 /* RetryWhen.swift */, - A8F13C8F2316AF7600A70E91 /* Do.swift */, - A8F13C902316AF7600A70E91 /* Deferred.swift */, - A8F13C912316AF7600A70E91 /* Buffer.swift */, - A8F13C922316AF7600A70E91 /* SubscribeOn.swift */, - A8F13C932316AF7600A70E91 /* DefaultIfEmpty.swift */, - A8F13C942316AF7600A70E91 /* Using.swift */, - A8F13C952316AF7600A70E91 /* Delay.swift */, - A8F13C962316AF7600A70E91 /* Producer.swift */, - A8F13C972316AF7600A70E91 /* GroupBy.swift */, - A8F13C982316AF7600A70E91 /* Concat.swift */, - A8F13C992316AF7600A70E91 /* Take.swift */, - A8F13C9A2316AF7600A70E91 /* TakeWhile.swift */, - A8F13C9B2316AF7600A70E91 /* TakeLast.swift */, - A8F13C9C2316AF7600A70E91 /* Error.swift */, - A8F13C9D2316AF7600A70E91 /* CombineLatest.swift */, - A8F13C9E2316AF7600A70E91 /* Sample.swift */, - A8F13C9F2316AF7600A70E91 /* AsSingle.swift */, - A8F13CA02316AF7600A70E91 /* Empty.swift */, - A8F13CA12316AF7600A70E91 /* Enumerated.swift */, - A8F13CA22316AF7600A70E91 /* DistinctUntilChanged.swift */, - A8F13CA32316AF7600A70E91 /* First.swift */, - A8F13CA42316AF7600A70E91 /* Timer.swift */, - A8F13CA52316AF7600A70E91 /* AddRef.swift */, - A8F13CA62316AF7600A70E91 /* Sequence.swift */, - A8F13CA72316AF7600A70E91 /* Sink.swift */, - A8F13CA82316AF7600A70E91 /* Throttle.swift */, - A8F13CA92316AF7600A70E91 /* Range.swift */, - A8F13CAA2316AF7600A70E91 /* WithLatestFrom.swift */, - A8F13CAB2316AF7600A70E91 /* ObserveOn.swift */, - A8F13CAC2316AF7600A70E91 /* CombineLatest+Collection.swift */, - A8F13CAD2316AF7600A70E91 /* Multicast.swift */, - A8F13CAE2316AF7600A70E91 /* SkipWhile.swift */, - A8F13CAF2316AF7600A70E91 /* DelaySubscription.swift */, - A8F13CB02316AF7600A70E91 /* Repeat.swift */, - A8F13CB12316AF7600A70E91 /* ToArray.swift */, - A8F13CB22316AF7600A70E91 /* TakeUntil.swift */, - A8F13CB32316AF7600A70E91 /* Zip+arity.tt */, - A8F13CB42316AF7600A70E91 /* Switch.swift */, - A8F13CB52316AF7600A70E91 /* Window.swift */, - A8F13CB62316AF7600A70E91 /* Debounce.swift */, - A8F13CB72316AF7600A70E91 /* Dematerialize.swift */, - A8F13CB82316AF7600A70E91 /* Zip+Collection.swift */, - A8F13CB92316AF7600A70E91 /* Catch.swift */, - A8F13CBA2316AF7600A70E91 /* Filter.swift */, - A8F13CBB2316AF7600A70E91 /* Amb.swift */, - A8F13CBC2316AF7600A70E91 /* Reduce.swift */, - A8F13CBD2316AF7600A70E91 /* CombineLatest+arity.swift */, - A8F13CBE2316AF7600A70E91 /* CombineLatest+arity.tt */, - A8F13CBF2316AF7600A70E91 /* Zip.swift */, - A8F13CC02316AF7600A70E91 /* Debug.swift */, - A8F13CC12316AF7600A70E91 /* Merge.swift */, - A8F13CC22316AF7600A70E91 /* Skip.swift */, - A8F13CC32316AF7600A70E91 /* Map.swift */, - A8F13CC42316AF7600A70E91 /* SkipUntil.swift */, - A8F13CC52316AF7600A70E91 /* StartWith.swift */, - A8F13CC62316AF7600A70E91 /* Just.swift */, - A8F13CC72316AF7600A70E91 /* Optional.swift */, - A8F13CC82316AF7600A70E91 /* Generate.swift */, - A8F13CC92316AF7600A70E91 /* ShareReplayScope.swift */, - A8F13CCA2316AF7600A70E91 /* Scan.swift */, - A8F13CCB2316AF7600A70E91 /* Zip+arity.swift */, - A8F13CCC2316AF7600A70E91 /* SwitchIfEmpty.swift */, - A8F13CCD2316AF7600A70E91 /* ElementAt.swift */, - A8F13CCE2316AF7600A70E91 /* Create.swift */, - A8F13CCF2316AF7600A70E91 /* Materialize.swift */, - A8F13CD02316AF7600A70E91 /* SingleAsync.swift */, + 8EFF12D72AB0C0F200399069 /* Infallible+Zip+arity.swift */, + 8EFF12D82AB0C0F200399069 /* Infallible+Concurrency.swift */, + 8EFF12D92AB0C0F200399069 /* Infallible+Zip+arity.tt */, + 8EFF12DA2AB0C0F200399069 /* Infallible+Create.swift */, + 8EFF12DB2AB0C0F200399069 /* Infallible+Operators.swift */, + 8EFF12DC2AB0C0F200399069 /* Infallible+Debug.swift */, + 8EFF12DD2AB0C0F200399069 /* Infallible+CombineLatest+arity.tt */, + 8EFF12DE2AB0C0F200399069 /* Infallible+CombineLatest+arity.swift */, + 8EFF12DF2AB0C0F200399069 /* Infallible.swift */, + 8EFF12E02AB0C0F200399069 /* Infallible+CombineLatest+Collection.swift */, + 8EFF12E12AB0C0F200399069 /* ObservableConvertibleType+Infallible.swift */, ); - path = Observables; + path = Infallible; sourceTree = ""; }; - A8F13CD22316AF7600A70E91 /* SwiftSupport */ = { + 8EFF12F32AB0C0FF00399069 /* SwiftSupport */ = { isa = PBXGroup; children = ( - A8F13CD32316AF7600A70E91 /* SwiftSupport.swift */, + 8EFF12F42AB0C0FF00399069 /* SwiftSupport.swift */, ); path = SwiftSupport; sourceTree = ""; }; - A8F13CD52316AF7600A70E91 /* Extensions */ = { + 8EFF12F62AB0C10D00399069 /* Subjects */ = { isa = PBXGroup; children = ( - A8F13CD62316AF7600A70E91 /* Bag+Rx.swift */, - A8F13CD72316AF7600A70E91 /* String+Rx.swift */, + 8EFF12F72AB0C10D00399069 /* SubjectType.swift */, + 8EFF12F82AB0C10D00399069 /* BehaviorSubject.swift */, + 8EFF12F92AB0C10D00399069 /* AsyncSubject.swift */, + 8EFF12FA2AB0C10D00399069 /* ReplaySubject.swift */, + 8EFF12FB2AB0C10D00399069 /* PublishSubject.swift */, ); - path = Extensions; + path = Subjects; sourceTree = ""; }; - A8F13CD92316AF7600A70E91 /* Concurrency */ = { + 8EFF13012AB0C15500399069 /* Schedulers */ = { isa = PBXGroup; children = ( - A8F13CDA2316AF7600A70E91 /* LockOwnerType.swift */, - A8F13CDB2316AF7600A70E91 /* SynchronizedDisposeType.swift */, - A8F13CDC2316AF7600A70E91 /* SynchronizedOnType.swift */, - A8F13CDD2316AF7600A70E91 /* Lock.swift */, - A8F13CDE2316AF7600A70E91 /* AsyncLock.swift */, - A8F13CDF2316AF7600A70E91 /* SynchronizedUnsubscribeType.swift */, + 8EFF13022AB0C15500399069 /* RecursiveScheduler.swift */, + 8EFF13032AB0C15500399069 /* OperationQueueScheduler.swift */, + 8EFF13042AB0C15500399069 /* VirtualTimeScheduler.swift */, + 8EFF13052AB0C15500399069 /* SchedulerServices+Emulation.swift */, + 8EFF13062AB0C15500399069 /* CurrentThreadScheduler.swift */, + 8EFF13072AB0C15500399069 /* MainScheduler.swift */, + 8EFF13082AB0C15500399069 /* ConcurrentDispatchQueueScheduler.swift */, + 8EFF13092AB0C15500399069 /* Internal */, + 8EFF130F2AB0C15500399069 /* ConcurrentMainScheduler.swift */, + 8EFF13102AB0C15500399069 /* SerialDispatchQueueScheduler.swift */, + 8EFF13112AB0C15500399069 /* HistoricalScheduler.swift */, + 8EFF13122AB0C15500399069 /* VirtualTimeConverterType.swift */, + 8EFF13132AB0C15500399069 /* HistoricalSchedulerTimeConverter.swift */, ); - path = Concurrency; + path = Schedulers; sourceTree = ""; }; - A8F13CE22316AF7600A70E91 /* Subjects */ = { + 8EFF13092AB0C15500399069 /* Internal */ = { isa = PBXGroup; children = ( - A8F13CE32316AF7600A70E91 /* SubjectType.swift */, - A8F13CE42316AF7600A70E91 /* BehaviorSubject.swift */, - A8F13CE52316AF7600A70E91 /* AsyncSubject.swift */, - A8F13CE62316AF7600A70E91 /* ReplaySubject.swift */, - A8F13CE72316AF7600A70E91 /* PublishSubject.swift */, + 8EFF130A2AB0C15500399069 /* ScheduledItem.swift */, + 8EFF130B2AB0C15500399069 /* InvocableType.swift */, + 8EFF130C2AB0C15500399069 /* InvocableScheduledItem.swift */, + 8EFF130D2AB0C15500399069 /* DispatchQueueConfiguration.swift */, + 8EFF130E2AB0C15500399069 /* ScheduledItemType.swift */, ); - path = Subjects; + path = Internal; sourceTree = ""; }; - A8F13CEF2316AF7600A70E91 /* Observers */ = { + A8F13C1C2316ADE700A70E91 = { isa = PBXGroup; children = ( - A8F13CF02316AF7600A70E91 /* ObserverBase.swift */, - A8F13CF12316AF7600A70E91 /* TailRecursiveSink.swift */, - A8F13CF22316AF7600A70E91 /* AnonymousObserver.swift */, + A8F13C312316AE3600A70E91 /* MultiPlatformBLEAdapter-Bridging-Header.h */, + A8F13C432316AF7600A70E91 /* RxBluetoothKit */, + A8F13C622316AF7600A70E91 /* RxSwift */, + A8F13C272316ADE700A70E91 /* classes */, + A8F13C262316ADE700A70E91 /* Products */, ); - path = Observers; sourceTree = ""; }; - A8F13CF32316AF7600A70E91 /* Schedulers */ = { + A8F13C262316ADE700A70E91 /* Products */ = { isa = PBXGroup; children = ( - A8F13CF42316AF7600A70E91 /* RecursiveScheduler.swift */, - A8F13CF52316AF7600A70E91 /* OperationQueueScheduler.swift */, - A8F13CF62316AF7600A70E91 /* VirtualTimeScheduler.swift */, - A8F13CF72316AF7600A70E91 /* SchedulerServices+Emulation.swift */, - A8F13CF82316AF7600A70E91 /* CurrentThreadScheduler.swift */, - A8F13CF92316AF7600A70E91 /* MainScheduler.swift */, - A8F13CFA2316AF7600A70E91 /* ConcurrentDispatchQueueScheduler.swift */, - A8F13CFB2316AF7600A70E91 /* Internal */, - A8F13D012316AF7600A70E91 /* ConcurrentMainScheduler.swift */, - A8F13D022316AF7600A70E91 /* SerialDispatchQueueScheduler.swift */, - A8F13D032316AF7600A70E91 /* HistoricalScheduler.swift */, - A8F13D042316AF7600A70E91 /* VirtualTimeConverterType.swift */, - A8F13D052316AF7600A70E91 /* HistoricalSchedulerTimeConverter.swift */, + A8F13C252316ADE700A70E91 /* libMultiPlatformBLEAdapter.a */, ); - path = Schedulers; + name = Products; sourceTree = ""; }; - A8F13CFB2316AF7600A70E91 /* Internal */ = { + A8F13C272316ADE700A70E91 /* classes */ = { isa = PBXGroup; children = ( - A8F13CFC2316AF7600A70E91 /* ScheduledItem.swift */, - A8F13CFD2316AF7600A70E91 /* InvocableType.swift */, - A8F13CFE2316AF7600A70E91 /* InvocableScheduledItem.swift */, - A8F13CFF2316AF7600A70E91 /* DispatchQueueConfiguration.swift */, - A8F13D002316AF7600A70E91 /* ScheduledItemType.swift */, + A8F13E012316BE2F00A70E91 /* Utils */, + A8F13DF92316BDFB00A70E91 /* BleClientManager.h */, + A8F13DF62316BDFA00A70E91 /* BleError.swift */, + A8F13DF52316BDFA00A70E91 /* BleEvent.swift */, + A8F13DF82316BDFA00A70E91 /* BleExtensions.swift */, + A8F13DFA2316BDFB00A70E91 /* BleModule.swift */, + A8F13DF72316BDFA00A70E91 /* BleUtils.swift */, + A8F13C282316ADE700A70E91 /* MultiPlatformBLEAdapter.h */, + A8F13C292316ADE700A70E91 /* MultiPlatformBLEAdapter.m */, + 81B95B91234B256000D96D28 /* BleAdapter.swift */, + 816FE39A234F29B3008BF70D /* BleAdapterFactory.swift */, ); - path = Internal; + path = classes; + sourceTree = ""; + }; + A8F13C432316AF7600A70E91 /* RxBluetoothKit */ = { + isa = PBXGroup; + children = ( + 8EF49F482AB1CE400019E5F9 /* ManagerType.swift */, + 8EF49F3A2AB1CD3E0019E5F9 /* CBCentral+Uuid.swift */, + 8EF49F3C2AB1CD720019E5F9 /* CBCentralManagerDelegateWrapper.swift */, + 8EF49F402AB1CDDE0019E5F9 /* CBPeripheralDelegateWrapper.swift */, + 8EF49F382AB1CCF30019E5F9 /* Array+Utils.swift */, + A8F13C442316AF7600A70E91 /* RxCBCharacteristic.swift */, + A8F13C452316AF7600A70E91 /* RxCBService.swift */, + A8F13C462316AF7600A70E91 /* RxDescriptorType.swift */, + A8F13C472316AF7600A70E91 /* BluetoothState.swift */, + A8F13C482316AF7600A70E91 /* Peripheral.swift */, + A8F13C492316AF7600A70E91 /* Logging.swift */, + A8F13C4A2316AF7600A70E91 /* RxCharacteristicType.swift */, + A8F13C4B2316AF7600A70E91 /* DeviceIdentifiers.swift */, + A8F13C4C2316AF7600A70E91 /* Service.swift */, + A8F13C4D2316AF7600A70E91 /* RxServiceType.swift */, + A8F13C4E2316AF7600A70E91 /* BluetoothManager.swift */, + A8F13C4F2316AF7600A70E91 /* BluetoothError.swift */, + A8F13C502316AF7600A70E91 /* Peripheral+Convenience.swift */, + A8F13C512316AF7600A70E91 /* AdvertisementData.swift */, + A8F13C522316AF7600A70E91 /* RxBluetoothKit.h */, + A8F13C532316AF7600A70E91 /* RxCentralManagerType.swift */, + A8F13C542316AF7600A70E91 /* RxCBCentralManager.swift */, + A8F13C552316AF7600A70E91 /* RestoredState.swift */, + A8F13C562316AF7600A70E91 /* Descriptor.swift */, + A8F13C572316AF7600A70E91 /* Boxes.swift */, + A8F13C582316AF7600A70E91 /* RxCBDescriptor.swift */, + A8F13C592316AF7600A70E91 /* Observable+Absorb.swift */, + A8F13C5A2316AF7600A70E91 /* UUIDIdentifiable.swift */, + A8F13C5B2316AF7600A70E91 /* ScanOperation.swift */, + A8F13C5C2316AF7600A70E91 /* ScannedPeripheral.swift */, + A8F13C5D2316AF7600A70E91 /* Observable+QueueSubscribeOn.swift */, + A8F13C5E2316AF7600A70E91 /* Characteristic.swift */, + A8F13C5F2316AF7600A70E91 /* Unimplemented.swift */, + A8F13C602316AF7600A70E91 /* RxCBPeripheral.swift */, + A8F13C612316AF7600A70E91 /* RxPeripheralType.swift */, + ); + path = RxBluetoothKit; + sourceTree = ""; + }; + A8F13C622316AF7600A70E91 /* RxSwift */ = { + isa = PBXGroup; + children = ( + 8E63F2E22AB0D5D60010A0CB /* Observables */, + 8E63F2CE2AB0CE770010A0CB /* Platform */, + 8EFF133F2AB0C21F00399069 /* SchedulerType.swift */, + 8EFF133A2AB0C17800399069 /* Reactive.swift */, + 8EFF133B2AB0C17800399069 /* Rx.swift */, + 8EFF13392AB0C17800399069 /* RxMutableBox.swift */, + 8EFF13012AB0C15500399069 /* Schedulers */, + 8EFF12F62AB0C10D00399069 /* Subjects */, + 8EFF12F32AB0C0FF00399069 /* SwiftSupport */, + 8EFF12CB2AB0C0F200399069 /* Traits */, + 8EFF12C32AB0C0A200399069 /* Observers */, + 8EFF12C22AB0C0A200399069 /* ObserverType.swift */, + 8EFF12532AB0C09600399069 /* AnyObserver.swift */, + 8EFF12552AB0C09600399069 /* Binder.swift */, + 8EFF11EC2AB0C09500399069 /* Cancelable.swift */, + 8EFF12462AB0C09500399069 /* Concurrency */, + 8EFF12582AB0C09600399069 /* ConnectableObservableType.swift */, + 8EFF11EA2AB0C09500399069 /* Date+Dispatch.swift */, + 8EFF11E92AB0C09500399069 /* Disposable.swift */, + 8EFF11ED2AB0C09500399069 /* Disposables */, + 8EFF11FB2AB0C09500399069 /* Errors.swift */, + 8EFF11EB2AB0C09500399069 /* Event.swift */, + 8EFF12512AB0C09600399069 /* Extensions */, + 8EFF12562AB0C09600399069 /* GroupedObservable.swift */, + 8EFF124F2AB0C09500399069 /* ImmediateSchedulerType.swift */, + 8EFF124D2AB0C09500399069 /* Info.plist */, + 8EFF12542AB0C09600399069 /* Observable.swift */, + 8EFF124E2AB0C09500399069 /* Observable+Concurrency.swift */, + 8EFF12572AB0C09600399069 /* ObservableConvertibleType.swift */, + 8EFF12452AB0C09500399069 /* ObservableType.swift */, + 8EFF12502AB0C09500399069 /* ObservableType+Extensions.swift */, + ); + path = RxSwift; sourceTree = ""; }; A8F13E012316BE2F00A70E91 /* Utils */ = { @@ -816,194 +892,212 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8EFF12602AB0C09600399069 /* NopDisposable.swift in Sources */, + 8EFF12BB2AB0C09600399069 /* Bag+Rx.swift in Sources */, + 8E63F35D2AB0D6390010A0CB /* Skip.swift in Sources */, + 8EFF12FF2AB0C10D00399069 /* ReplaySubject.swift in Sources */, + 8E63F3382AB0D6390010A0CB /* Throttle.swift in Sources */, + 8EFF13162AB0C15500399069 /* VirtualTimeScheduler.swift in Sources */, + 8EFF133D2AB0C17800399069 /* Reactive.swift in Sources */, + 8EFF131E2AB0C15500399069 /* DispatchQueueConfiguration.swift in Sources */, + 8EFF12BA2AB0C09600399069 /* ObservableType+Extensions.swift in Sources */, + 8EFF131F2AB0C15500399069 /* ScheduledItemType.swift in Sources */, A8F13D0A2316AF7600A70E91 /* BluetoothState.swift in Sources */, - A8F13D292316AF7700A70E91 /* Completable.swift in Sources */, - A8F13D392316AF7700A70E91 /* DisposeBase.swift in Sources */, + 8EFF12642AB0C09600399069 /* SingleAssignmentDisposable.swift in Sources */, A8F13D0B2316AF7600A70E91 /* Peripheral.swift in Sources */, - A8F13D462316AF7700A70E91 /* AsMaybe.swift in Sources */, - A8F13D422316AF7700A70E91 /* BinaryDisposable.swift in Sources */, - A8F13D852316AF7700A70E91 /* SwitchIfEmpty.swift in Sources */, - A8F13D312316AF7700A70E91 /* DeprecationWarner.swift in Sources */, - A8F13D3B2316AF7700A70E91 /* ScheduledDisposable.swift in Sources */, - A8F13D7E2316AF7700A70E91 /* StartWith.swift in Sources */, - A8F13D5F2316AF7700A70E91 /* Timer.swift in Sources */, - A8F13DA62316AF7700A70E91 /* AnonymousObserver.swift in Sources */, - A8F13DA52316AF7700A70E91 /* TailRecursiveSink.swift in Sources */, - A8F13D722316AF7700A70E91 /* Zip+Collection.swift in Sources */, A8F13D182316AF7600A70E91 /* Descriptor.swift in Sources */, - A8F13D612316AF7700A70E91 /* Sequence.swift in Sources */, - A8F13D4F2316AF7700A70E91 /* Using.swift in Sources */, - A8F13D442316AF7700A70E91 /* BooleanDisposable.swift in Sources */, - A8F13D7A2316AF7700A70E91 /* Merge.swift in Sources */, + 8E63F33C2AB0D6390010A0CB /* Enumerated.swift in Sources */, A8F13D0F2316AF7600A70E91 /* Service.swift in Sources */, - A8F13D252316AF7600A70E91 /* GroupedObservable.swift in Sources */, - A8F13D7F2316AF7700A70E91 /* Just.swift in Sources */, - A8F13D9F2316AF7700A70E91 /* SchedulerType.swift in Sources */, - A8F13D2E2316AF7700A70E91 /* PrimitiveSequence+Zip+arity.swift in Sources */, - A8F13D892316AF7700A70E91 /* SingleAsync.swift in Sources */, - A8F13D912316AF7700A70E91 /* SynchronizedDisposeType.swift in Sources */, - A8F13D4B2316AF7700A70E91 /* Deferred.swift in Sources */, A8F13D1E2316AF7600A70E91 /* ScannedPeripheral.swift in Sources */, + 8EFF126A2AB0C09600399069 /* Errors.swift in Sources */, + 8EFF12CA2AB0C0A200399069 /* AnonymousObserver.swift in Sources */, + 8EFF12B32AB0C09600399069 /* SynchronizedDisposeType.swift in Sources */, + 8EFF12EA2AB0C0F200399069 /* Infallible+Zip+arity.swift in Sources */, 81B95B92234B256000D96D28 /* BleAdapter.swift in Sources */, - A8F13D622316AF7700A70E91 /* Sink.swift in Sources */, - A8F13D302316AF7700A70E91 /* Platform.Darwin.swift in Sources */, - A8F13D7C2316AF7700A70E91 /* Map.swift in Sources */, - A8F13DA12316AF7700A70E91 /* ObservableType.swift in Sources */, - A8F13D9B2316AF7700A70E91 /* ReplaySubject.swift in Sources */, A8F13E042316BE2F00A70E91 /* DisposableMap.swift in Sources */, + 8E63F3612AB0D6390010A0CB /* ShareReplayScope.swift in Sources */, + 8EFF12BE2AB0C09600399069 /* Binder.swift in Sources */, + 8E63F35F2AB0D6390010A0CB /* CombineLatest.swift in Sources */, + 8E63F35B2AB0D6390010A0CB /* Zip.swift in Sources */, + 8EFF12EB2AB0C0F200399069 /* Infallible+Concurrency.swift in Sources */, A8F13D142316AF7600A70E91 /* AdvertisementData.swift in Sources */, - A8F13D692316AF7700A70E91 /* SkipWhile.swift in Sources */, - A8F13D782316AF7700A70E91 /* Zip.swift in Sources */, - A8F13D352316AF7700A70E91 /* Queue.swift in Sources */, - A8F13D412316AF7700A70E91 /* SerialDisposable.swift in Sources */, - A8F13DAC2316AF7700A70E91 /* MainScheduler.swift in Sources */, - A8F13DB82316AF7700A70E91 /* ImmediateSchedulerType.swift in Sources */, - A8F13D832316AF7700A70E91 /* Scan.swift in Sources */, - A8F13D2C2316AF7700A70E91 /* Maybe.swift in Sources */, - A8F13D3A2316AF7700A70E91 /* DisposeBag.swift in Sources */, + 8E63F3592AB0D6390010A0CB /* Empty.swift in Sources */, + 8E63F3452AB0D6390010A0CB /* Timeout.swift in Sources */, + 8E63F3572AB0D6390010A0CB /* Take.swift in Sources */, + 8EFF12EF2AB0C0F200399069 /* Infallible+CombineLatest+arity.swift in Sources */, + 8EFF12B12AB0C09600399069 /* ObservableType.swift in Sources */, + 8EFF12E32AB0C0F200399069 /* Completable.swift in Sources */, + 8E63F3332AB0D6390010A0CB /* Scan.swift in Sources */, + 8EFF13142AB0C15500399069 /* RecursiveScheduler.swift in Sources */, + 8EFF12662AB0C09600399069 /* BinaryDisposable.swift in Sources */, + 8E63F3642AB0D6390010A0CB /* Optional.swift in Sources */, + 8E63F3692AB0D6390010A0CB /* Zip+arity.swift in Sources */, + 8E63F3582AB0D6390010A0CB /* Merge.swift in Sources */, + 8E63F3422AB0D6390010A0CB /* ElementAt.swift in Sources */, + 8E63F3352AB0D6390010A0CB /* Concat.swift in Sources */, + 8EFF12EC2AB0C0F200399069 /* Infallible+Create.swift in Sources */, A8F13DFF2316BDFB00A70E91 /* BleModule.swift in Sources */, + 8E63F3462AB0D6390010A0CB /* AddRef.swift in Sources */, + 8EF49F412AB1CDDE0019E5F9 /* CBPeripheralDelegateWrapper.swift in Sources */, + 8E63F32C2AB0D6390010A0CB /* Never.swift in Sources */, + 8EFF12E92AB0C0F200399069 /* PrimitiveSequence+Concurrency.swift in Sources */, + 8EFF12B72AB0C09600399069 /* SynchronizedUnsubscribeType.swift in Sources */, + 8EFF13222AB0C15500399069 /* HistoricalScheduler.swift in Sources */, + 8E63F3362AB0D6390010A0CB /* Do.swift in Sources */, + 8EFF125F2AB0C09600399069 /* ScheduledDisposable.swift in Sources */, A8F13D162316AF7600A70E91 /* RxCBCentralManager.swift in Sources */, - A8F13D9E2316AF7700A70E91 /* Observable.swift in Sources */, - A8F13D902316AF7700A70E91 /* LockOwnerType.swift in Sources */, + 8EFF131C2AB0C15500399069 /* InvocableType.swift in Sources */, A8F13D212316AF7600A70E91 /* Unimplemented.swift in Sources */, - A8F13D732316AF7700A70E91 /* Catch.swift in Sources */, + 8EFF12682AB0C09600399069 /* BooleanDisposable.swift in Sources */, + 8E63F32E2AB0D6390010A0CB /* Switch.swift in Sources */, + 8E63F3392AB0D6390010A0CB /* WithLatestFrom.swift in Sources */, + 8E63F3322AB0D6390010A0CB /* StartWith.swift in Sources */, + 8E63F35E2AB0D6390010A0CB /* TakeLast.swift in Sources */, + 8E63F32B2AB0D6390010A0CB /* DefaultIfEmpty.swift in Sources */, + 8E63F3432AB0D6390010A0CB /* Filter.swift in Sources */, A8F13DFC2316BDFB00A70E91 /* BleError.swift in Sources */, - A8F13D482316AF7700A70E91 /* Never.swift in Sources */, - A8F13D8F2316AF7700A70E91 /* ObserverType.swift in Sources */, - A8F13DB32316AF7700A70E91 /* ConcurrentMainScheduler.swift in Sources */, - A8F13DB12316AF7700A70E91 /* DispatchQueueConfiguration.swift in Sources */, A8F13D0E2316AF7600A70E91 /* DeviceIdentifiers.swift in Sources */, - A8F13D862316AF7700A70E91 /* ElementAt.swift in Sources */, - A8F13D542316AF7700A70E91 /* Take.swift in Sources */, - A8F13DA72316AF7700A70E91 /* RecursiveScheduler.swift in Sources */, - A8F13DA92316AF7700A70E91 /* VirtualTimeScheduler.swift in Sources */, - A8F13D762316AF7700A70E91 /* Reduce.swift in Sources */, - A8F13D982316AF7700A70E91 /* SubjectType.swift in Sources */, - A8F13D552316AF7700A70E91 /* TakeWhile.swift in Sources */, - A8F13D842316AF7700A70E91 /* Zip+arity.swift in Sources */, - A8F13DB02316AF7700A70E91 /* InvocableScheduledItem.swift in Sources */, + 8E63F3622AB0D6390010A0CB /* Sink.swift in Sources */, + 8E63F3542AB0D6390010A0CB /* Debug.swift in Sources */, + 8EFF12F22AB0C0F200399069 /* ObservableConvertibleType+Infallible.swift in Sources */, + 8EFF12632AB0C09600399069 /* CompositeDisposable.swift in Sources */, + 8E63F3602AB0D6390010A0CB /* Zip+Collection.swift in Sources */, A8F13D0D2316AF7600A70E91 /* RxCharacteristicType.swift in Sources */, + 8E63F33D2AB0D6390010A0CB /* Buffer.swift in Sources */, + 8EFF13402AB0C21F00399069 /* SchedulerType.swift in Sources */, + 8EFF12BF2AB0C09600399069 /* GroupedObservable.swift in Sources */, + 8E63F34B2AB0D6390010A0CB /* CompactMap.swift in Sources */, + 8E63F36F2AB0D6390010A0CB /* AsMaybe.swift in Sources */, + 8E63F33B2AB0D6390010A0CB /* Deferred.swift in Sources */, + 8EFF12E52AB0C0F200399069 /* PrimitiveSequence.swift in Sources */, + 8E63F3672AB0D6390010A0CB /* Just.swift in Sources */, + 8EFF125D2AB0C09600399069 /* DisposeBase.swift in Sources */, + 8E63F3522AB0D6390010A0CB /* Materialize.swift in Sources */, + 8E63F2DF2AB0CFB10010A0CB /* PriorityQueue.swift in Sources */, + 8E63F2D72AB0CF1E0010A0CB /* Platform.Linux.swift in Sources */, + 8EFF133C2AB0C17800399069 /* RxMutableBox.swift in Sources */, + 8EFF12FE2AB0C10D00399069 /* AsyncSubject.swift in Sources */, + 8E63F3402AB0D6390010A0CB /* SkipWhile.swift in Sources */, A8F13E052316BE2F00A70E91 /* SafePromise.swift in Sources */, - A8F13DB22316AF7700A70E91 /* ScheduledItemType.swift in Sources */, + 8E63F3482AB0D6390010A0CB /* CombineLatest+Collection.swift in Sources */, + 8EF49F492AB1CE400019E5F9 /* ManagerType.swift in Sources */, + 8EFF12612AB0C09600399069 /* SubscriptionDisposable.swift in Sources */, + 8E63F36D2AB0D6390010A0CB /* SkipUntil.swift in Sources */, + 8E63F2D92AB0CF400010A0CB /* RecursiveLock.swift in Sources */, + 8E63F3552AB0D6390010A0CB /* Create.swift in Sources */, A8F13D092316AF7600A70E91 /* RxDescriptorType.swift in Sources */, - A8F13D472316AF7700A70E91 /* Timeout.swift in Sources */, + 8EFF13182AB0C15500399069 /* CurrentThreadScheduler.swift in Sources */, + 8EFF125C2AB0C09600399069 /* Cancelable.swift in Sources */, A8F13D112316AF7600A70E91 /* BluetoothManager.swift in Sources */, + 8EFF13172AB0C15500399069 /* SchedulerServices+Emulation.swift in Sources */, + 8EFF12C92AB0C0A200399069 /* TailRecursiveSink.swift in Sources */, + 8EFF125A2AB0C09600399069 /* Date+Dispatch.swift in Sources */, + 8E63F2DD2AB0CF830010A0CB /* InfiniteSequence.swift in Sources */, + 8E63F3702AB0D6390010A0CB /* ToArray.swift in Sources */, + 8EFF12E62AB0C0F200399069 /* Maybe.swift in Sources */, + 8EFF12592AB0C09600399069 /* Disposable.swift in Sources */, + 8E63F34E2AB0D6390010A0CB /* First.swift in Sources */, + 8E63F35C2AB0D6390010A0CB /* CombineLatest+arity.swift in Sources */, + 8E63F34F2AB0D6390010A0CB /* Amb.swift in Sources */, A8F13D1B2316AF7600A70E91 /* Observable+Absorb.swift in Sources */, - A8F13D992316AF7700A70E91 /* BehaviorSubject.swift in Sources */, - A8F13D2B2316AF7700A70E91 /* PrimitiveSequence.swift in Sources */, - A8F13D8C2316AF7700A70E91 /* ObservableType+Extensions.swift in Sources */, - A8F13D802316AF7700A70E91 /* Optional.swift in Sources */, - A8F13D772316AF7700A70E91 /* CombineLatest+arity.swift in Sources */, - A8F13D792316AF7700A70E91 /* Debug.swift in Sources */, - A8F13D682316AF7700A70E91 /* Multicast.swift in Sources */, - A8F13DB42316AF7700A70E91 /* SerialDispatchQueueScheduler.swift in Sources */, - A8F13D6C2316AF7700A70E91 /* ToArray.swift in Sources */, - A8F13D952316AF7700A70E91 /* SynchronizedUnsubscribeType.swift in Sources */, - A8F13D3F2316AF7700A70E91 /* CompositeDisposable.swift in Sources */, - A8F13D882316AF7700A70E91 /* Materialize.swift in Sources */, + 8EFF12652AB0C09600399069 /* SerialDisposable.swift in Sources */, + 8E63F34D2AB0D6390010A0CB /* DistinctUntilChanged.swift in Sources */, + 8E63F2E12AB0CFC30010A0CB /* Queue.swift in Sources */, + 8E63F33A2AB0D6390010A0CB /* Debounce.swift in Sources */, + 8E63F3412AB0D6390010A0CB /* ObserveOn.swift in Sources */, A8F13D1A2316AF7600A70E91 /* RxCBDescriptor.swift in Sources */, + 8EFF12B82AB0C09600399069 /* Observable+Concurrency.swift in Sources */, + 8EFF12C82AB0C0A200399069 /* ObserverBase.swift in Sources */, + 8EFF13202AB0C15500399069 /* ConcurrentMainScheduler.swift in Sources */, + 8EF49F392AB1CCF30019E5F9 /* Array+Utils.swift in Sources */, + 8EFF13242AB0C15500399069 /* HistoricalSchedulerTimeConverter.swift in Sources */, A8F13D072316AF7600A70E91 /* RxCBCharacteristic.swift in Sources */, - A8F13DA82316AF7700A70E91 /* OperationQueueScheduler.swift in Sources */, - A8F13DAF2316AF7700A70E91 /* InvocableType.swift in Sources */, - A8F13D342316AF7700A70E91 /* PriorityQueue.swift in Sources */, - A8F13D8D2316AF7700A70E91 /* Bag+Rx.swift in Sources */, + 8EFF13002AB0C10D00399069 /* PublishSubject.swift in Sources */, A8F13D122316AF7600A70E91 /* BluetoothError.swift in Sources */, - A8F13D9C2316AF7700A70E91 /* PublishSubject.swift in Sources */, + 8EFF12C12AB0C09600399069 /* ConnectableObservableType.swift in Sources */, + 8EF49F3B2AB1CD3E0019E5F9 /* CBCentral+Uuid.swift in Sources */, + 8E63F3472AB0D6390010A0CB /* AsSingle.swift in Sources */, + 8EFF12F02AB0C0F200399069 /* Infallible.swift in Sources */, + 8E63F34A2AB0D6390010A0CB /* Window.swift in Sources */, + 8E63F3632AB0D6390010A0CB /* Delay.swift in Sources */, A8F13D232316AF7600A70E91 /* RxPeripheralType.swift in Sources */, - A8F13D712316AF7700A70E91 /* Dematerialize.swift in Sources */, - A8F13D632316AF7700A70E91 /* Throttle.swift in Sources */, - A8F13D932316AF7700A70E91 /* Lock.swift in Sources */, - A8F13D2D2316AF7700A70E91 /* ObservableType+PrimitiveSequence.swift in Sources */, - A8F13D602316AF7700A70E91 /* AddRef.swift in Sources */, + 8EFF133E2AB0C17800399069 /* Rx.swift in Sources */, A8F13D0C2316AF7600A70E91 /* Logging.swift in Sources */, - A8F13D5C2316AF7700A70E91 /* Enumerated.swift in Sources */, - A8F13D7B2316AF7700A70E91 /* Skip.swift in Sources */, - A8F13D5E2316AF7700A70E91 /* First.swift in Sources */, - A8F13DAD2316AF7700A70E91 /* ConcurrentDispatchQueueScheduler.swift in Sources */, - A8F13DA22316AF7700A70E91 /* Errors.swift in Sources */, - A8F13D4D2316AF7700A70E91 /* SubscribeOn.swift in Sources */, - A8F13D2F2316AF7700A70E91 /* AnyObserver.swift in Sources */, + 8E63F32D2AB0D6390010A0CB /* GroupBy.swift in Sources */, + 8E63F3502AB0D6390010A0CB /* Error.swift in Sources */, + 8EFF12B92AB0C09600399069 /* ImmediateSchedulerType.swift in Sources */, A8F13D152316AF7600A70E91 /* RxCentralManagerType.swift in Sources */, - A8F13D672316AF7700A70E91 /* CombineLatest+Collection.swift in Sources */, - A8F13D6D2316AF7700A70E91 /* TakeUntil.swift in Sources */, + 8EF49F3D2AB1CD720019E5F9 /* CBCentralManagerDelegateWrapper.swift in Sources */, + 8EFF12F52AB0C0FF00399069 /* SwiftSupport.swift in Sources */, + 8EFF12B52AB0C09600399069 /* Lock.swift in Sources */, + 8EFF12ED2AB0C0F200399069 /* Infallible+Operators.swift in Sources */, A8F13D132316AF7600A70E91 /* Peripheral+Convenience.swift in Sources */, - A8F13D372316AF7700A70E91 /* Platform.Linux.swift in Sources */, - A8F13D702316AF7700A70E91 /* Debounce.swift in Sources */, - A8F13DA02316AF7700A70E91 /* ConnectableObservableType.swift in Sources */, + 8E63F3372AB0D6390010A0CB /* SwitchIfEmpty.swift in Sources */, + 8EFF13212AB0C15500399069 /* SerialDispatchQueueScheduler.swift in Sources */, A8F13D222316AF7600A70E91 /* RxCBPeripheral.swift in Sources */, - A8F13D812316AF7700A70E91 /* Generate.swift in Sources */, - A8F13D972316AF7700A70E91 /* Deprecated.swift in Sources */, - A8F13D322316AF7700A70E91 /* DispatchQueue+Extensions.swift in Sources */, - A8F13D662316AF7700A70E91 /* ObserveOn.swift in Sources */, - A8F13D282316AF7700A70E91 /* Completable+AndThen.swift in Sources */, - A8F13D6A2316AF7700A70E91 /* DelaySubscription.swift in Sources */, - A8F13D272316AF7600A70E91 /* Event.swift in Sources */, - A8F13D562316AF7700A70E91 /* TakeLast.swift in Sources */, - A8F13DAB2316AF7700A70E91 /* CurrentThreadScheduler.swift in Sources */, - A8F13DAA2316AF7700A70E91 /* SchedulerServices+Emulation.swift in Sources */, - A8F13D6E2316AF7700A70E91 /* Switch.swift in Sources */, + 8EFF131A2AB0C15500399069 /* ConcurrentDispatchQueueScheduler.swift in Sources */, + 8EFF12B42AB0C09600399069 /* SynchronizedOnType.swift in Sources */, + 8EFF131D2AB0C15500399069 /* InvocableScheduledItem.swift in Sources */, + 8EFF12C02AB0C09600399069 /* ObservableConvertibleType.swift in Sources */, + 8E63F3312AB0D6390010A0CB /* RetryWhen.swift in Sources */, A8F13D1D2316AF7600A70E91 /* ScanOperation.swift in Sources */, - A8F13DB72316AF7700A70E91 /* HistoricalSchedulerTimeConverter.swift in Sources */, - A8F13D242316AF7600A70E91 /* Cancelable.swift in Sources */, + 8E63F3302AB0D6390010A0CB /* Producer.swift in Sources */, + 8EFF13192AB0C15500399069 /* MainScheduler.swift in Sources */, + 8E63F2D32AB0CEEC0010A0CB /* DispatchQueue+Extensions.swift in Sources */, + 8E63F3532AB0D6390010A0CB /* SubscribeOn.swift in Sources */, + 8E63F36A2AB0D6390010A0CB /* Map.swift in Sources */, + 8E63F34C2AB0D6390010A0CB /* DelaySubscription.swift in Sources */, + 8EFF12C72AB0C0A200399069 /* ObserverType.swift in Sources */, + 8E63F36B2AB0D6390010A0CB /* TakeWithPredicate.swift in Sources */, + 8E63F3492AB0D6390010A0CB /* Decode.swift in Sources */, + 8E63F2D52AB0CF050010A0CB /* Platform.Darwin.swift in Sources */, + 8EFF12E42AB0C0F200399069 /* Single.swift in Sources */, A8F13D1C2316AF7600A70E91 /* UUIDIdentifiable.swift in Sources */, A8F13D102316AF7600A70E91 /* RxServiceType.swift in Sources */, - A8F13D6F2316AF7700A70E91 /* Window.swift in Sources */, - A8F13D3D2316AF7700A70E91 /* SubscriptionDisposable.swift in Sources */, - A8F13D332316AF7700A70E91 /* Bag.swift in Sources */, - A8F13D5B2316AF7700A70E91 /* Empty.swift in Sources */, A8F13DFB2316BDFB00A70E91 /* BleEvent.swift in Sources */, - A8F13D522316AF7700A70E91 /* GroupBy.swift in Sources */, + 8EFF12BC2AB0C09600399069 /* AnyObserver.swift in Sources */, + 8E63F2D12AB0CE9B0010A0CB /* AtomicInt.swift in Sources */, A8F13D202316AF7600A70E91 /* Characteristic.swift in Sources */, - A8F13D872316AF7700A70E91 /* Create.swift in Sources */, A8F13D082316AF7600A70E91 /* RxCBService.swift in Sources */, + 8E63F3662AB0D6390010A0CB /* Catch.swift in Sources */, + 8E63F3652AB0D6390010A0CB /* Reduce.swift in Sources */, + 8EFF12FD2AB0C10D00399069 /* BehaviorSubject.swift in Sources */, + 8EFF12E82AB0C0F200399069 /* PrimitiveSequence+Zip+arity.swift in Sources */, A8F13DFE2316BDFB00A70E91 /* BleExtensions.swift in Sources */, - A8F13DA42316AF7700A70E91 /* ObserverBase.swift in Sources */, + 8E63F3562AB0D6390010A0CB /* Sample.swift in Sources */, + 8EFF12B62AB0C09600399069 /* AsyncLock.swift in Sources */, + 8E63F3512AB0D6390010A0CB /* Generate.swift in Sources */, 816FE39B234F29B3008BF70D /* BleAdapterFactory.swift in Sources */, - A8F13D582316AF7700A70E91 /* CombineLatest.swift in Sources */, - A8F13D8E2316AF7700A70E91 /* String+Rx.swift in Sources */, - A8F13D3C2316AF7700A70E91 /* NopDisposable.swift in Sources */, - A8F13D6B2316AF7700A70E91 /* Repeat.swift in Sources */, - A8F13D742316AF7700A70E91 /* Filter.swift in Sources */, - A8F13D362316AF7700A70E91 /* InfiniteSequence.swift in Sources */, - A8F13D9D2316AF7700A70E91 /* ObservableConvertibleType.swift in Sources */, - A8F13D8A2316AF7700A70E91 /* Disposable.swift in Sources */, - A8F13D4C2316AF7700A70E91 /* Buffer.swift in Sources */, - A8F13D8B2316AF7700A70E91 /* SwiftSupport.swift in Sources */, - A8F13D822316AF7700A70E91 /* ShareReplayScope.swift in Sources */, - A8F13DAE2316AF7700A70E91 /* ScheduledItem.swift in Sources */, - A8F13D4A2316AF7700A70E91 /* Do.swift in Sources */, - A8F13D922316AF7700A70E91 /* SynchronizedOnType.swift in Sources */, + 8EFF125E2AB0C09600399069 /* DisposeBag.swift in Sources */, A8F13D1F2316AF7600A70E91 /* Observable+QueueSubscribeOn.swift in Sources */, - A8F13D642316AF7700A70E91 /* Range.swift in Sources */, - A8F13D532316AF7700A70E91 /* Concat.swift in Sources */, A8F13D192316AF7600A70E91 /* Boxes.swift in Sources */, - A8F13DB52316AF7700A70E91 /* HistoricalScheduler.swift in Sources */, - A8F13D592316AF7700A70E91 /* Sample.swift in Sources */, - A8F13D402316AF7700A70E91 /* SingleAssignmentDisposable.swift in Sources */, - A8F13DA32316AF7700A70E91 /* Rx.swift in Sources */, - A8F13D752316AF7700A70E91 /* Amb.swift in Sources */, - A8F13D5A2316AF7700A70E91 /* AsSingle.swift in Sources */, - A8F13D3E2316AF7700A70E91 /* RefCountDisposable.swift in Sources */, - A8F13D502316AF7700A70E91 /* Delay.swift in Sources */, - A8F13D652316AF7700A70E91 /* WithLatestFrom.swift in Sources */, - A8F13D942316AF7700A70E91 /* AsyncLock.swift in Sources */, - A8F13D4E2316AF7700A70E91 /* DefaultIfEmpty.swift in Sources */, - A8F13D262316AF7600A70E91 /* RxMutableBox.swift in Sources */, - A8F13D492316AF7700A70E91 /* RetryWhen.swift in Sources */, + 8E63F33F2AB0D6390010A0CB /* Sequence.swift in Sources */, A8F13C2A2316ADE700A70E91 /* MultiPlatformBLEAdapter.m in Sources */, - A8F13DB62316AF7700A70E91 /* VirtualTimeConverterType.swift in Sources */, - A8F13D572316AF7700A70E91 /* Error.swift in Sources */, - A8F13D2A2316AF7700A70E91 /* Single.swift in Sources */, - A8F13D5D2316AF7700A70E91 /* DistinctUntilChanged.swift in Sources */, + 8EFF12FC2AB0C10D00399069 /* SubjectType.swift in Sources */, + 8EFF12672AB0C09600399069 /* AnonymousDisposable.swift in Sources */, + 8EFF12E22AB0C0F200399069 /* Completable+AndThen.swift in Sources */, + 8EFF12622AB0C09600399069 /* RefCountDisposable.swift in Sources */, + 8E63F3342AB0D6390010A0CB /* Using.swift in Sources */, + 8E63F36C2AB0D6390010A0CB /* Timer.swift in Sources */, + 8E63F2DB2AB0CF730010A0CB /* Bag.swift in Sources */, A8F13D172316AF7600A70E91 /* RestoredState.swift in Sources */, - A8F13D962316AF7700A70E91 /* Reactive.swift in Sources */, - A8F13D432316AF7700A70E91 /* AnonymousDisposable.swift in Sources */, - A8F13D9A2316AF7700A70E91 /* AsyncSubject.swift in Sources */, - A8F13D512316AF7700A70E91 /* Producer.swift in Sources */, - A8F13D7D2316AF7700A70E91 /* SkipUntil.swift in Sources */, + 8EFF131B2AB0C15500399069 /* ScheduledItem.swift in Sources */, + 8EFF12692AB0C09600399069 /* Disposables.swift in Sources */, + 8EFF12E72AB0C0F200399069 /* ObservableType+PrimitiveSequence.swift in Sources */, + 8EFF125B2AB0C09600399069 /* Event.swift in Sources */, + 8EFF12BD2AB0C09600399069 /* Observable.swift in Sources */, + 8EFF12EE2AB0C0F200399069 /* Infallible+Debug.swift in Sources */, + 8E63F3682AB0D6390010A0CB /* Repeat.swift in Sources */, + 8E63F3442AB0D6390010A0CB /* SingleAsync.swift in Sources */, + 8E63F32F2AB0D6390010A0CB /* WithUnretained.swift in Sources */, + 8EFF12B22AB0C09600399069 /* LockOwnerType.swift in Sources */, + 8EFF13152AB0C15500399069 /* OperationQueueScheduler.swift in Sources */, + 8E63F35A2AB0D6390010A0CB /* Dematerialize.swift in Sources */, + 8E63F33E2AB0D6390010A0CB /* Range.swift in Sources */, + 8EFF13232AB0C15500399069 /* VirtualTimeConverterType.swift in Sources */, A8F13DFD2316BDFB00A70E91 /* BleUtils.swift in Sources */, - A8F13D452316AF7700A70E91 /* Disposables.swift in Sources */, - A8F13D382316AF7700A70E91 /* RecursiveLock.swift in Sources */, + 8EFF12F12AB0C0F200399069 /* Infallible+CombineLatest+Collection.swift in Sources */, + 8E63F36E2AB0D6390010A0CB /* Multicast.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/iOS/RxBluetoothKit/Array+Utils.swift b/iOS/RxBluetoothKit/Array+Utils.swift new file mode 100644 index 00000000..c2d864ba --- /dev/null +++ b/iOS/RxBluetoothKit/Array+Utils.swift @@ -0,0 +1,11 @@ +import Foundation + +extension Array where Element: Equatable { + @discardableResult mutating func remove(object: Element) -> Bool { + if let index = firstIndex(of: object) { + self.remove(at: index) + return true + } + return false + } +} diff --git a/iOS/RxBluetoothKit/BluetoothError.swift b/iOS/RxBluetoothKit/BluetoothError.swift index 84639d6a..d18e5268 100644 --- a/iOS/RxBluetoothKit/BluetoothError.swift +++ b/iOS/RxBluetoothKit/BluetoothError.swift @@ -1,25 +1,3 @@ -// The MIT License (MIT) -// -// Copyright (c) 2016 Polidea -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - import Foundation import CoreBluetooth @@ -29,6 +7,11 @@ public enum BluetoothError: Error { /// To mitigate it dispose all of your subscriptions before deinitializing /// object that created Observables that subscriptions are made to. case destroyed + // Emitted when `CentralManager.scanForPeripherals` called and there is already ongoing scan + case scanInProgress + // Emitted when `PeripheralManager.startAdvertising` called and there is already ongoing advertisement + case advertisingInProgress + case advertisingStartFailed(Error) // States case bluetoothUnsupported case bluetoothUnauthorized @@ -36,21 +19,31 @@ public enum BluetoothError: Error { case bluetoothInUnknownState case bluetoothResetting // Peripheral + case peripheralIsAlreadyObservingConnection(Peripheral) + @available(*, deprecated, renamed: "BluetoothError.peripheralIsAlreadyObservingConnection") + case peripheralIsConnectingOrAlreadyConnected(Peripheral) case peripheralConnectionFailed(Peripheral, Error?) case peripheralDisconnected(Peripheral, Error?) case peripheralRSSIReadFailed(Peripheral, Error?) // Services case servicesDiscoveryFailed(Peripheral, Error?) - case includedServicesDiscoveryFailed(Service, Error?) + case includedServicesDiscoveryFailed(Peripheral, Error?) + case addingServiceFailed(CBService, Error?) // Characteristics case characteristicsDiscoveryFailed(Service, Error?) case characteristicWriteFailed(Characteristic, Error?) case characteristicReadFailed(Characteristic, Error?) case characteristicNotifyChangeFailed(Characteristic, Error?) + case characteristicSetNotifyValueFailed(Characteristic, Error?) // Descriptors case descriptorsDiscoveryFailed(Characteristic, Error?) case descriptorWriteFailed(Descriptor, Error?) case descriptorReadFailed(Descriptor, Error?) + // L2CAP + case openingL2CAPChannelFailed(Peripheral, Error?) + case publishingL2CAPChannelFailed(CBL2CAPPSM, Error?) + // Unknown + case unknownWriteType } extension BluetoothError: CustomStringConvertible { @@ -60,9 +53,21 @@ extension BluetoothError: CustomStringConvertible { switch self { case .destroyed: return """ - The object that is the source of this Observable was destroyed. - It's programmer's error, please check documentation of error for more details - """ + The object that is the source of this Observable was destroyed. + It's programmer's error, please check documentation of error for more details + """ + case .scanInProgress: + return """ + Tried to scan for peripheral when there is already ongoing scan. + You can have only 1 ongoing scanning, please check documentation of CentralManager for more details + """ + case .advertisingInProgress: + return """ + Tried to advertise when there is already advertising ongoing. + You can have only 1 ongoing advertising, please check documentation of PeripheralManager for more details + """ + case let .advertisingStartFailed(err): + return "Start advertising error occured: \(err.localizedDescription)" case .bluetoothUnsupported: return "Bluetooth is unsupported" case .bluetoothUnauthorized: @@ -73,19 +78,27 @@ extension BluetoothError: CustomStringConvertible { return "Bluetooth is in unknown state" case .bluetoothResetting: return "Bluetooth is resetting" - // Peripheral + // Peripheral + case .peripheralIsAlreadyObservingConnection, .peripheralIsConnectingOrAlreadyConnected: + return """ + Peripheral connection is already being observed. + You cannot try to establishConnection to peripheral when you have ongoing + connection (previously establishConnection subscription was not disposed). + """ case let .peripheralConnectionFailed(_, err): return "Connection error has occured: \(err?.localizedDescription ?? "-")" case let .peripheralDisconnected(_, err): return "Connection error has occured: \(err?.localizedDescription ?? "-")" case let .peripheralRSSIReadFailed(_, err): return "RSSI read failed : \(err?.localizedDescription ?? "-")" - // Services + // Services case let .servicesDiscoveryFailed(_, err): return "Services discovery error has occured: \(err?.localizedDescription ?? "-")" case let .includedServicesDiscoveryFailed(_, err): return "Included services discovery error has occured: \(err?.localizedDescription ?? "-")" - // Characteristics + case let .addingServiceFailed(_, err): + return "Adding PeripheralManager service error has occured: \(err?.localizedDescription ?? "-")" + // Characteristics case let .characteristicsDiscoveryFailed(_, err): return "Characteristics discovery error has occured: \(err?.localizedDescription ?? "-")" case let .characteristicWriteFailed(_, err): @@ -94,13 +107,22 @@ extension BluetoothError: CustomStringConvertible { return "Characteristic read error has occured: \(err?.localizedDescription ?? "-")" case let .characteristicNotifyChangeFailed(_, err): return "Characteristic notify change error has occured: \(err?.localizedDescription ?? "-")" - // Descriptors + case let .characteristicSetNotifyValueFailed(_, err): + return "Characteristic isNotyfing value change error has occured: \(err?.localizedDescription ?? "-")" + // Descriptors case let .descriptorsDiscoveryFailed(_, err): return "Descriptor discovery error has occured: \(err?.localizedDescription ?? "-")" case let .descriptorWriteFailed(_, err): return "Descriptor write error has occured: \(err?.localizedDescription ?? "-")" case let .descriptorReadFailed(_, err): return "Descriptor read error has occured: \(err?.localizedDescription ?? "-")" + case let .openingL2CAPChannelFailed(_, err): + return "Opening L2CAP channel error has occured: \(err?.localizedDescription ?? "-")" + case let .publishingL2CAPChannelFailed(_, err): + return "Publishing L2CAP channel error has occured: \(err?.localizedDescription ?? "-")" + // Unknown + case .unknownWriteType: + return "Unknown write type" } } } @@ -130,27 +152,42 @@ extension BluetoothError: Equatable {} public func == (lhs: BluetoothError, rhs: BluetoothError) -> Bool { switch (lhs, rhs) { + case (.scanInProgress, .scanInProgress): return true + case (.advertisingInProgress, .advertisingInProgress): return true + case (.advertisingStartFailed, .advertisingStartFailed): return true + // States case (.bluetoothUnsupported, .bluetoothUnsupported): return true case (.bluetoothUnauthorized, .bluetoothUnauthorized): return true case (.bluetoothPoweredOff, .bluetoothPoweredOff): return true case (.bluetoothInUnknownState, .bluetoothInUnknownState): return true case (.bluetoothResetting, .bluetoothResetting): return true - // Services + // Services case let (.servicesDiscoveryFailed(l, _), .servicesDiscoveryFailed(r, _)): return l == r case let (.includedServicesDiscoveryFailed(l, _), .includedServicesDiscoveryFailed(r, _)): return l == r - // Peripherals + case let (.addingServiceFailed(l, _), .addingServiceFailed(r, _)): return l == r + // Peripherals + case let (.peripheralIsAlreadyObservingConnection(l), .peripheralIsAlreadyObservingConnection(r)): return l == r + case let (.peripheralIsConnectingOrAlreadyConnected(l), .peripheralIsConnectingOrAlreadyConnected(r)): return l == r + case let (.peripheralIsAlreadyObservingConnection(l), .peripheralIsConnectingOrAlreadyConnected(r)): return l == r + case let (.peripheralIsConnectingOrAlreadyConnected(l), .peripheralIsAlreadyObservingConnection(r)): return l == r case let (.peripheralConnectionFailed(l, _), .peripheralConnectionFailed(r, _)): return l == r case let (.peripheralDisconnected(l, _), .peripheralDisconnected(r, _)): return l == r case let (.peripheralRSSIReadFailed(l, _), .peripheralRSSIReadFailed(r, _)): return l == r - // Characteristics + // Characteristics case let (.characteristicsDiscoveryFailed(l, _), .characteristicsDiscoveryFailed(r, _)): return l == r case let (.characteristicWriteFailed(l, _), .characteristicWriteFailed(r, _)): return l == r case let (.characteristicReadFailed(l, _), .characteristicReadFailed(r, _)): return l == r case let (.characteristicNotifyChangeFailed(l, _), .characteristicNotifyChangeFailed(r, _)): return l == r - // Descriptors + case let (.characteristicSetNotifyValueFailed(l, _), .characteristicSetNotifyValueFailed(r, _)): return l == r + // Descriptors case let (.descriptorsDiscoveryFailed(l, _), .descriptorsDiscoveryFailed(r, _)): return l == r case let (.descriptorWriteFailed(l, _), .descriptorWriteFailed(r, _)): return l == r case let (.descriptorReadFailed(l, _), .descriptorReadFailed(r, _)): return l == r + // L2CAP + case let (.openingL2CAPChannelFailed(l, _), .openingL2CAPChannelFailed(r, _)): return l == r + case let (.publishingL2CAPChannelFailed(l, _), .publishingL2CAPChannelFailed(r, _)): return l == r + // Unknown + case (.unknownWriteType, .unknownWriteType): return true default: return false } } diff --git a/iOS/RxBluetoothKit/BluetoothState.swift b/iOS/RxBluetoothKit/BluetoothState.swift index ee2d82ce..ac867e3d 100644 --- a/iOS/RxBluetoothKit/BluetoothState.swift +++ b/iOS/RxBluetoothKit/BluetoothState.swift @@ -1,27 +1,7 @@ -// The MIT License (MIT) -// -// Copyright (c) 2016 Polidea -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - import Foundation +/// Type describing bluetooth state, equivalent to +/// [CBManagerState](https://developer.apple.com/documentation/corebluetooth/cbmanagerstate). public enum BluetoothState: Int { case unknown case resetting diff --git a/iOS/RxBluetoothKit/Boxes.swift b/iOS/RxBluetoothKit/Boxes.swift index bb95fa41..486feee0 100644 --- a/iOS/RxBluetoothKit/Boxes.swift +++ b/iOS/RxBluetoothKit/Boxes.swift @@ -1,25 +1,3 @@ -// The MIT License (MIT) -// -// Copyright (c) 2016 Polidea -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - import Foundation class WeakBox: CustomDebugStringConvertible { @@ -35,3 +13,51 @@ extension WeakBox { return "WeakBox(\(String(describing: value)))" } } + +/// `ThreadSafeBox` is a helper class that allows use of resource (value) in a thread safe manner. +/// All read and write calls are wrapped in concurrent `DispatchQueue` which protects writing to +/// resource from more than 1 thread at a time. +class ThreadSafeBox: CustomDebugStringConvertible { + private let queue = DispatchQueue(label: "com.polidea.RxBluetoothKit.ThreadSafeBox") + fileprivate var value: T + init(value: T) { + self.value = value + } + + func read(_ block: (T) -> Result) -> Result { + var result: Result! = nil + queue.sync { + result = block(value) + } + return result + } + + func write(_ block: @escaping (inout T) -> Void) { + queue.async { + block(&self.value) + } + } + + func writeSync(_ block: @escaping (inout T) -> Void) { + queue.sync { + block(&self.value) + } + } + + @discardableResult func compareAndSet(compare: (T) -> Bool, set: @escaping (inout T) -> Void) -> Bool { + var result: Bool = false + queue.sync { + result = compare(value) + if result { + set(&self.value) + } + } + return result + } +} + +extension ThreadSafeBox { + var debugDescription: String { + return "ThreadSafeBox(\(String(describing: value)))" + } +} diff --git a/iOS/RxBluetoothKit/CBCentral+Uuid.swift b/iOS/RxBluetoothKit/CBCentral+Uuid.swift new file mode 100644 index 00000000..223daedf --- /dev/null +++ b/iOS/RxBluetoothKit/CBCentral+Uuid.swift @@ -0,0 +1,9 @@ +import Foundation +import CoreBluetooth + +extension CBCentral { + /// There is still no identifier property for macOS, that's why we need to retrieve it by value method + var uuidIdentifier: UUID { + return value(forKey: "identifier") as! NSUUID as UUID + } +} diff --git a/iOS/RxBluetoothKit/CBCentralManagerDelegateWrapper.swift b/iOS/RxBluetoothKit/CBCentralManagerDelegateWrapper.swift new file mode 100644 index 00000000..e0362288 --- /dev/null +++ b/iOS/RxBluetoothKit/CBCentralManagerDelegateWrapper.swift @@ -0,0 +1,75 @@ +import Foundation +import CoreBluetooth + + +class CBCentralManagerDelegateWrapper: NSObject, CBCentralManagerDelegate { + + let didUpdateState = PublishSubject() + let willRestoreState = ReplaySubject<[String: Any]>.create(bufferSize: 1) + let didDiscoverPeripheral = PublishSubject<(CBPeripheral, [String: Any], NSNumber)>() + let didConnectPeripheral = PublishSubject() + let didFailToConnectPeripheral = PublishSubject<(CBPeripheral, Error?)>() + let didDisconnectPeripheral = PublishSubject<(CBPeripheral, Error?)>() + let didUpdateANCSAuthorizationForPeripheral = PublishSubject<(CBPeripheral)>() + + func centralManagerDidUpdateState(_ central: CBCentralManager) { + guard let bleState = BluetoothState(rawValue: central.state.rawValue) else { return } + RxBluetoothKitLog.d("\(central.logDescription) didUpdateState(state: \(bleState.logDescription))") + didUpdateState.onNext(bleState) + } + + func centralManager(_ central: CBCentralManager, willRestoreState dict: [String: Any]) { + RxBluetoothKitLog.d("\(central.logDescription) willRestoreState(restoredState: \(dict))") + willRestoreState.onNext(dict) + } + + func centralManager(_ central: CBCentralManager, + didDiscover peripheral: CBPeripheral, + advertisementData: [String: Any], + rssi: NSNumber) { + RxBluetoothKitLog.d(""" + \(central.logDescription) didDiscover(peripheral: \(peripheral.logDescription), + rssi: \(rssi)) + """) + didDiscoverPeripheral.onNext((peripheral, advertisementData, rssi)) + } + + func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { + RxBluetoothKitLog.d(""" + \(central.logDescription) didConnect(to: \(peripheral.logDescription)) + """) + didConnectPeripheral.onNext(peripheral) + } + + func centralManager(_ central: CBCentralManager, + didFailToConnect peripheral: CBPeripheral, + error: Error?) { + RxBluetoothKitLog.d(""" + \(central.logDescription) didFailToConnect(to: \(peripheral.logDescription), + error: \(String(describing: error))) + """) + didFailToConnectPeripheral.onNext((peripheral, error)) + } + + func centralManager(_ central: CBCentralManager, + didDisconnectPeripheral peripheral: CBPeripheral, + error: Error?) { + RxBluetoothKitLog.d(""" + \(central.logDescription) didDisconnect(from: \(peripheral.logDescription), + error: \(String(describing: error))) + """) + didDisconnectPeripheral.onNext((peripheral, error)) + } + + #if !os(macOS) + @available(iOS 13.0, watchOS 6.0, tvOS 13.0, *) + func centralManager(_ central: CBCentralManager, + didUpdateANCSAuthorizationFor peripheral: CBPeripheral) { + RxBluetoothKitLog.d(""" + \(central.logDescription) didUpdateANCSAuthorizationFor + (peripheral: \(peripheral.logDescription) + """) + didUpdateANCSAuthorizationForPeripheral.onNext(peripheral) + } + #endif +} diff --git a/iOS/RxBluetoothKit/CBPeripheralDelegateWrapper.swift b/iOS/RxBluetoothKit/CBPeripheralDelegateWrapper.swift new file mode 100644 index 00000000..6ebaf6ad --- /dev/null +++ b/iOS/RxBluetoothKit/CBPeripheralDelegateWrapper.swift @@ -0,0 +1,163 @@ +import Foundation +import CoreBluetooth + +class CBPeripheralDelegateWrapper: NSObject, CBPeripheralDelegate { + + let peripheralDidUpdateName = PublishSubject() + let peripheralDidModifyServices = PublishSubject<([CBService])>() + let peripheralDidReadRSSI = PublishSubject<(Int, Error?)>() + let peripheralDidDiscoverServices = PublishSubject<([CBService]?, Error?)>() + let peripheralDidDiscoverIncludedServicesForService = PublishSubject<(CBService, Error?)>() + let peripheralDidDiscoverCharacteristicsForService = PublishSubject<(CBService, Error?)>() + let peripheralDidUpdateValueForCharacteristic = PublishSubject<(CBCharacteristic, Error?)>() + let peripheralDidWriteValueForCharacteristic = PublishSubject<(CBCharacteristic, Error?)>() + let peripheralDidUpdateNotificationStateForCharacteristic = + PublishSubject<(CBCharacteristic, Error?)>() + let peripheralDidDiscoverDescriptorsForCharacteristic = + PublishSubject<(CBCharacteristic, Error?)>() + let peripheralDidUpdateValueForDescriptor = PublishSubject<(CBDescriptor, Error?)>() + let peripheralDidWriteValueForDescriptor = PublishSubject<(CBDescriptor, Error?)>() + let peripheralIsReadyToSendWriteWithoutResponse = PublishSubject() + let peripheralDidOpenL2CAPChannel = PublishSubject<(Any?, Error?)>() + + func peripheralDidUpdateName(_ peripheral: CBPeripheral) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didUpdateName(name: \(String(describing: peripheral.name))) + """) + peripheralDidUpdateName.onNext(peripheral.name) + } + + func peripheral(_ peripheral: CBPeripheral, didModifyServices invalidatedServices: [CBService]) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didModifyServices(services: + [\(invalidatedServices.logDescription))] + """) + peripheralDidModifyServices.onNext(invalidatedServices) + } + + func peripheral(_ peripheral: CBPeripheral, didReadRSSI rssi: NSNumber, error: Error?) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didReadRSSI(rssi: \(rssi), + error: \(String(describing: error))) + """) + peripheralDidReadRSSI.onNext((rssi.intValue, error)) + } + + func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didDiscoverServices(services + : \(String(describing: peripheral.services?.logDescription)), + error: \(String(describing: error))) + """) + peripheralDidDiscoverServices.onNext((peripheral.services, error)) + } + + func peripheral(_ peripheral: CBPeripheral, + didDiscoverIncludedServicesFor service: CBService, + error: Error?) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didDiscoverIncludedServices(for: + \(service.logDescription), includedServices: + \(String(describing: service.includedServices?.logDescription)), + error: \(String(describing: error))) + """) + peripheralDidDiscoverIncludedServicesForService.onNext((service, error)) + } + + func peripheral(_ peripheral: CBPeripheral, + didDiscoverCharacteristicsFor service: CBService, + error: Error?) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didDiscoverCharacteristicsFor(for: + \(service.logDescription), characteristics: + \(String(describing: service.characteristics?.logDescription)), + error: \(String(describing: error))) + """) + peripheralDidDiscoverCharacteristicsForService.onNext((service, error)) + } + + func peripheral(_ peripheral: CBPeripheral, + didUpdateValueFor characteristic: CBCharacteristic, + error: Error?) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didUpdateValueFor(for:\(characteristic.logDescription), + value: \(String(describing: characteristic.value?.logDescription)), + error: \(String(describing: error))) + """) + peripheralDidUpdateValueForCharacteristic + .onNext((characteristic, error)) + } + + func peripheral(_ peripheral: CBPeripheral, + didWriteValueFor characteristic: CBCharacteristic, + error: Error?) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didWriteValueFor(for:\(characteristic.logDescription), + value: \(String(describing: characteristic.value?.logDescription)), + error: \(String(describing: error))) + """) + peripheralDidWriteValueForCharacteristic + .onNext((characteristic, error)) + } + + func peripheral(_ peripheral: CBPeripheral, + didUpdateNotificationStateFor characteristic: CBCharacteristic, + error: Error?) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didUpdateNotificationStateFor( + for:\(characteristic.logDescription), isNotifying: \(characteristic.isNotifying), + error: \(String(describing: error))) + """) + peripheralDidUpdateNotificationStateForCharacteristic + .onNext((characteristic, error)) + } + + func peripheral(_ peripheral: CBPeripheral, + didDiscoverDescriptorsFor characteristic: CBCharacteristic, + error: Error?) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didDiscoverDescriptorsFor + (for:\(characteristic.logDescription), descriptors: + \(String(describing: characteristic.descriptors?.logDescription)), + error: \(String(describing: error))) + """) + peripheralDidDiscoverDescriptorsForCharacteristic + .onNext((characteristic, error)) + } + + func peripheral(_ peripheral: CBPeripheral, + didUpdateValueFor descriptor: CBDescriptor, + error: Error?) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didUpdateValueFor(for:\(descriptor.logDescription), + value: \(String(describing: descriptor.value)), error: \(String(describing: error))) + """) + peripheralDidUpdateValueForDescriptor.onNext((descriptor, error)) + } + + func peripheral(_ peripheral: CBPeripheral, + didWriteValueFor descriptor: CBDescriptor, + error: Error?) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didWriteValueFor(for:\(descriptor.logDescription), + error: \(String(describing: error))) + """) + peripheralDidWriteValueForDescriptor.onNext((descriptor, error)) + } + + func peripheralIsReady(toSendWriteWithoutResponse peripheral: CBPeripheral) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) peripheralIsReady(toSendWriteWithoutResponse) + """) + peripheralIsReadyToSendWriteWithoutResponse.onNext(()) + } + + @available(OSX 10.13, iOS 11, *) + func peripheral(_ peripheral: CBPeripheral, didOpen channel: CBL2CAPChannel?, error: Error?) { + RxBluetoothKitLog.d(""" + \(peripheral.logDescription) didOpenL2CAPChannel(for:\(peripheral.logDescription), + error: \(String(describing: error))) + """) + peripheralDidOpenL2CAPChannel.onNext((channel, error)) + } +} diff --git a/iOS/RxBluetoothKit/ManagerType.swift b/iOS/RxBluetoothKit/ManagerType.swift new file mode 100644 index 00000000..cd4b1d1a --- /dev/null +++ b/iOS/RxBluetoothKit/ManagerType.swift @@ -0,0 +1,41 @@ +import Foundation +import CoreBluetooth + +public protocol ManagerType: AnyObject { + associatedtype Manager + + /// Implementation of CBManager + var manager: Manager { get } + /// Current state of `CentralManager` instance described by `BluetoothState` which is equivalent to + /// [CBManagerState](https://developer.apple.com/documentation/corebluetooth/cbmanagerstate). + var state: BluetoothState { get } + + /// Continuous state of `CBManager` instance described by `BluetoothState` which is equivalent to [CBManagerState](https://developer.apple.com/documentation/corebluetooth/cbmanagerstate). + /// - returns: Observable that emits `next` event whenever state changes. + /// + /// It's **infinite** stream, so `.complete` is never called. + func observeState() -> Observable + + /// Continuous state of `CBManager` instance described by `BluetoothState` which is equivalent to [CBManagerState](https://developer.apple.com/documentation/corebluetooth/cbmanagerstate). + /// - returns: Observable that emits `next` event starting with current state and whenever state changes. + /// + /// It's **infinite** stream, so `.complete` is never called. + func observeStateWithInitialValue() -> Observable +} + +public extension ManagerType { + /// Ensure that `state` is and will be the only state of `CentralManager` during subscription. + /// Otherwise error is emitted. + /// - parameter state: `BluetoothState` which should be present during subscription. + /// - parameter observable: Observable into which potential errors should be merged. + /// - returns: New observable which merges errors with source observable. + func ensure(_ state: BluetoothState, observable: Observable) -> Observable { + return .deferred { [weak self] in + guard let strongSelf = self else { throw BluetoothError.destroyed } + let statesObservable = strongSelf.observeStateWithInitialValue() + .filter { $0 != state && BluetoothError(state: $0) != nil } + .map { state -> T in throw BluetoothError(state: state)! } + return .absorb(statesObservable, observable) + } + } +} diff --git a/iOS/RxBluetoothKit/Observable+Absorb.swift b/iOS/RxBluetoothKit/Observable+Absorb.swift index db5aeaf4..ec55930a 100644 --- a/iOS/RxBluetoothKit/Observable+Absorb.swift +++ b/iOS/RxBluetoothKit/Observable+Absorb.swift @@ -27,10 +27,10 @@ extension ObservableType { /// - parameter b: Second observable /// - returns: New observable which emits all of events from a and b observables. /// If error or complete is received on any of the observables, it's propagates immediately to result observable - static func absorb(_ a: Observable, _ b: Observable) -> Observable { + static func absorb(_ a: Observable, _ b: Observable) -> Observable { return .create { observer in let disposable = CompositeDisposable() - let innerObserver: AnyObserver = AnyObserver { event in + let innerObserver: AnyObserver = AnyObserver { event in observer.on(event) if event.isStopEvent { disposable.dispose() diff --git a/iOS/RxBluetoothKit/Observable+QueueSubscribeOn.swift b/iOS/RxBluetoothKit/Observable+QueueSubscribeOn.swift index 68debde7..3261e027 100644 --- a/iOS/RxBluetoothKit/Observable+QueueSubscribeOn.swift +++ b/iOS/RxBluetoothKit/Observable+QueueSubscribeOn.swift @@ -98,7 +98,7 @@ class QueueSubscribeOn: Cancelable, ObservableType, ObserverType, Delay /// Part of producer implementation. We need to make sure that we can optimize /// scheduling of a work (taken from RxSwift source code) - func subscribe(_ observer: O) -> Disposable where O.E == Element { + func subscribe(_ observer: O) -> Disposable where O.Element == Element { if !CurrentThreadScheduler.isScheduleRequired { return run(observer: observer) } @@ -108,7 +108,7 @@ class QueueSubscribeOn: Cancelable, ObservableType, ObserverType, Delay } /// After original subscription we need to place it on queue for delayed execution if required. - func run(observer: O) -> Disposable where O.E == Element { + func run(observer: O) -> Disposable where O.Element == Element { self.observer = observer.asObserver() queue.queueSubscription(observable: self) return self @@ -139,7 +139,7 @@ extension ObservableType { /// - parameter queue: Queue on which scheduled subscriptions will be executed in sequentially. /// - returns: The source which will be subscribe when queue is empty or previous /// observable was completed or disposed. - func queueSubscribe(on queue: SerializedSubscriptionQueue) -> Observable { + func queueSubscribe(on queue: SerializedSubscriptionQueue) -> Observable { return QueueSubscribeOn(source: asObservable(), queue: queue).asObservable() } diff --git a/iOS/RxBluetoothKit/Peripheral.swift b/iOS/RxBluetoothKit/Peripheral.swift index 8cee4681..5a868065 100644 --- a/iOS/RxBluetoothKit/Peripheral.swift +++ b/iOS/RxBluetoothKit/Peripheral.swift @@ -156,7 +156,7 @@ public class Peripheral { .flatMap { [weak self] (rxservice, error) -> Observable<[Service]> in guard let strongSelf = self else { throw BluetoothError.destroyed } guard let includedRxServices = rxservice.includedServices, error == nil else { - throw BluetoothError.includedServicesDiscoveryFailed(service, error) + throw BluetoothError.includedServicesDiscoveryFailed(strongSelf, error) } let includedServices = includedRxServices.map { Service(peripheral: strongSelf, service: $0) } if let filteredServices = filterUUIDItems(uuids: includedServiceUUIDs, items: includedServices) { diff --git a/iOS/RxSwift/AnyObserver.swift b/iOS/RxSwift/AnyObserver.swift index dd4f9c40..e92cc816 100644 --- a/iOS/RxSwift/AnyObserver.swift +++ b/iOS/RxSwift/AnyObserver.swift @@ -10,9 +10,6 @@ /// /// Forwards operations to an arbitrary underlying observer with the same `Element` type, hiding the specifics of the underlying observer type. public struct AnyObserver : ObserverType { - /// The type of elements in sequence that observer can observe. - public typealias E = Element - /// Anonymous event handler type. public typealias EventHandler = (Event) -> Void @@ -28,7 +25,7 @@ public struct AnyObserver : ObserverType { /// Construct an instance whose `on(event)` calls `observer.on(event)` /// /// - parameter observer: Observer that receives sequence events. - public init(_ observer: O) where O.E == Element { + public init(_ observer: Observer) where Observer.Element == Element { self.observer = observer.on } @@ -36,36 +33,36 @@ public struct AnyObserver : ObserverType { /// /// - parameter event: Event instance. public func on(_ event: Event) { - return self.observer(event) + self.observer(event) } /// Erases type of observer and returns canonical observer. /// /// - returns: type erased observer. - public func asObserver() -> AnyObserver { - return self + public func asObserver() -> AnyObserver { + self } } extension AnyObserver { /// Collection of `AnyObserver`s - typealias s = Bag<(Event) -> ()> + typealias s = Bag<(Event) -> Void> } extension ObserverType { /// Erases type of observer and returns canonical observer. /// /// - returns: type erased observer. - public func asObserver() -> AnyObserver { - return AnyObserver(self) + public func asObserver() -> AnyObserver { + AnyObserver(self) } /// Transforms observer of type R to type E using custom transform method. /// Each event sent to result observer is transformed and sent to `self`. /// /// - returns: observer that transforms events. - public func mapObserver(_ transform: @escaping (R) throws -> E) -> AnyObserver { - return AnyObserver { e in + public func mapObserver(_ transform: @escaping (Result) throws -> Element) -> AnyObserver { + AnyObserver { e in self.on(e.map(transform)) } } diff --git a/iOS/RxSwift/Binder.swift b/iOS/RxSwift/Binder.swift new file mode 100644 index 00000000..1aae0959 --- /dev/null +++ b/iOS/RxSwift/Binder.swift @@ -0,0 +1,59 @@ +// +// Binder.swift +// RxSwift +// +// Created by Krunoslav Zaher on 9/17/17. +// Copyright © 2017 Krunoslav Zaher. All rights reserved. +// + +/** + Observer that enforces interface binding rules: + * can't bind errors (in debug builds binding of errors causes `fatalError` in release builds errors are being logged) + * ensures binding is performed on a specific scheduler + + `Binder` doesn't retain target and in case target is released, element isn't bound. + + By default it binds elements on main scheduler. + */ +public struct Binder: ObserverType { + public typealias Element = Value + + private let binding: (Event) -> Void + + /// Initializes `Binder` + /// + /// - parameter target: Target object. + /// - parameter scheduler: Scheduler used to bind the events. + /// - parameter binding: Binding logic. + public init(_ target: Target, scheduler: ImmediateSchedulerType = MainScheduler(), binding: @escaping (Target, Value) -> Void) { + weak var weakTarget = target + + self.binding = { event in + switch event { + case .next(let element): + _ = scheduler.schedule(element) { element in + if let target = weakTarget { + binding(target, element) + } + return Disposables.create() + } + case .error(let error): + rxFatalErrorInDebug("Binding error: \(error)") + case .completed: + break + } + } + } + + /// Binds next element to owner view as described in `binding`. + public func on(_ event: Event) { + self.binding(event) + } + + /// Erases type of observer. + /// + /// - returns: type erased observer. + public func asObserver() -> AnyObserver { + AnyObserver(eventHandler: self.on) + } +} diff --git a/iOS/RxSwift/Concurrency/AsyncLock.swift b/iOS/RxSwift/Concurrency/AsyncLock.swift index 25970781..502597e9 100644 --- a/iOS/RxSwift/Concurrency/AsyncLock.swift +++ b/iOS/RxSwift/Concurrency/AsyncLock.swift @@ -22,54 +22,52 @@ final class AsyncLock , SynchronizedDisposeType { typealias Action = () -> Void - var _lock = SpinLock() + private var _lock = SpinLock() - private var _queue: Queue = Queue(capacity: 0) + private var queue: Queue = Queue(capacity: 0) - private var _isExecuting: Bool = false - private var _hasFaulted: Bool = false + private var isExecuting: Bool = false + private var hasFaulted: Bool = false // lock { func lock() { - _lock.lock() + self._lock.lock() } func unlock() { - _lock.unlock() + self._lock.unlock() } // } private func enqueue(_ action: I) -> I? { - _lock.lock(); defer { _lock.unlock() } // { - if _hasFaulted { - return nil - } - - if _isExecuting { - _queue.enqueue(action) - return nil - } - - _isExecuting = true - - return action - // } + self.lock(); defer { self.unlock() } + if self.hasFaulted { + return nil + } + + if self.isExecuting { + self.queue.enqueue(action) + return nil + } + + self.isExecuting = true + + return action } private func dequeue() -> I? { - _lock.lock(); defer { _lock.unlock() } // { - if _queue.count > 0 { - return _queue.dequeue() - } - else { - _isExecuting = false - return nil - } - // } + self.lock(); defer { self.unlock() } + if !self.queue.isEmpty { + return self.queue.dequeue() + } + else { + self.isExecuting = false + return nil + } } func invoke(_ action: I) { - let firstEnqueuedAction = enqueue(action) + let firstEnqueuedAction = self.enqueue(action) if let firstEnqueuedAction = firstEnqueuedAction { firstEnqueuedAction.invoke() @@ -80,7 +78,7 @@ final class AsyncLock } while true { - let nextAction = dequeue() + let nextAction = self.dequeue() if let nextAction = nextAction { nextAction.invoke() @@ -92,11 +90,11 @@ final class AsyncLock } func dispose() { - synchronizedDispose() + self.synchronizedDispose() } - func _synchronized_dispose() { - _queue = Queue(capacity: 0) - _hasFaulted = true + func synchronized_dispose() { + self.queue = Queue(capacity: 0) + self.hasFaulted = true } } diff --git a/iOS/RxSwift/Concurrency/Lock.swift b/iOS/RxSwift/Concurrency/Lock.swift index 52afc1cb..7232f23f 100644 --- a/iOS/RxSwift/Concurrency/Lock.swift +++ b/iOS/RxSwift/Concurrency/Lock.swift @@ -16,21 +16,8 @@ typealias SpinLock = RecursiveLock extension RecursiveLock : Lock { @inline(__always) - final func performLocked(_ action: () -> Void) { - lock(); defer { unlock() } - action() - } - - @inline(__always) - final func calculateLocked(_ action: () -> T) -> T { - lock(); defer { unlock() } + final func performLocked(_ action: () -> T) -> T { + self.lock(); defer { self.unlock() } return action() } - - @inline(__always) - final func calculateLockedOrFail(_ action: () throws -> T) throws -> T { - lock(); defer { unlock() } - let result = try action() - return result - } } diff --git a/iOS/RxSwift/Concurrency/LockOwnerType.swift b/iOS/RxSwift/Concurrency/LockOwnerType.swift index eca8d8e1..8a98007d 100644 --- a/iOS/RxSwift/Concurrency/LockOwnerType.swift +++ b/iOS/RxSwift/Concurrency/LockOwnerType.swift @@ -6,16 +6,11 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -protocol LockOwnerType : class, Lock { - var _lock: RecursiveLock { get } +protocol LockOwnerType: AnyObject, Lock { + var lock: RecursiveLock { get } } extension LockOwnerType { - func lock() { - _lock.lock() - } - - func unlock() { - _lock.unlock() - } + func lock() { self.lock.lock() } + func unlock() { self.lock.unlock() } } diff --git a/iOS/RxSwift/Concurrency/SynchronizedDisposeType.swift b/iOS/RxSwift/Concurrency/SynchronizedDisposeType.swift index af9548f6..527a2fbe 100644 --- a/iOS/RxSwift/Concurrency/SynchronizedDisposeType.swift +++ b/iOS/RxSwift/Concurrency/SynchronizedDisposeType.swift @@ -6,13 +6,13 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -protocol SynchronizedDisposeType : class, Disposable, Lock { - func _synchronized_dispose() +protocol SynchronizedDisposeType: AnyObject, Disposable, Lock { + func synchronized_dispose() } extension SynchronizedDisposeType { func synchronizedDispose() { - lock(); defer { unlock() } - _synchronized_dispose() + self.lock(); defer { self.unlock() } + self.synchronized_dispose() } } diff --git a/iOS/RxSwift/Concurrency/SynchronizedOnType.swift b/iOS/RxSwift/Concurrency/SynchronizedOnType.swift index 8dfc5568..19168d77 100644 --- a/iOS/RxSwift/Concurrency/SynchronizedOnType.swift +++ b/iOS/RxSwift/Concurrency/SynchronizedOnType.swift @@ -6,13 +6,13 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -protocol SynchronizedOnType : class, ObserverType, Lock { - func _synchronized_on(_ event: Event) +protocol SynchronizedOnType: AnyObject, ObserverType, Lock { + func synchronized_on(_ event: Event) } extension SynchronizedOnType { - func synchronizedOn(_ event: Event) { - lock(); defer { unlock() } - _synchronized_on(event) + func synchronizedOn(_ event: Event) { + self.lock(); defer { self.unlock() } + self.synchronized_on(event) } } diff --git a/iOS/RxSwift/Concurrency/SynchronizedUnsubscribeType.swift b/iOS/RxSwift/Concurrency/SynchronizedUnsubscribeType.swift index bb1aa7e4..988b86f4 100644 --- a/iOS/RxSwift/Concurrency/SynchronizedUnsubscribeType.swift +++ b/iOS/RxSwift/Concurrency/SynchronizedUnsubscribeType.swift @@ -6,7 +6,7 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -protocol SynchronizedUnsubscribeType : class { +protocol SynchronizedUnsubscribeType: AnyObject { associatedtype DisposeKey func synchronizedUnsubscribe(_ disposeKey: DisposeKey) diff --git a/iOS/RxSwift/Date+Dispatch.swift b/iOS/RxSwift/Date+Dispatch.swift new file mode 100644 index 00000000..90f70c56 --- /dev/null +++ b/iOS/RxSwift/Date+Dispatch.swift @@ -0,0 +1,64 @@ +// +// Date+Dispatch.swift +// RxSwift +// +// Created by Krunoslav Zaher on 4/14/19. +// Copyright © 2019 Krunoslav Zaher. All rights reserved. +// + +import Dispatch +import Foundation + +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.rounded(.toNearestOrAwayFromZero)) + } + } +} + +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/iOS/RxSwift/Deprecated.swift b/iOS/RxSwift/Deprecated.swift deleted file mode 100644 index cc673c70..00000000 --- a/iOS/RxSwift/Deprecated.swift +++ /dev/null @@ -1,228 +0,0 @@ -// -// Deprecated.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/5/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -extension Observable { - /** - Converts a optional to an observable sequence. - - - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - - - parameter optional: Optional element in the resulting observable sequence. - - returns: An observable sequence containing the wrapped value or not from given optional. - */ - @available(*, deprecated, message: "Implicit conversions from any type to optional type are allowed and that is causing issues with `from` operator overloading.", renamed: "from(optional:)") - public static func from(_ optional: E?) -> Observable { - return Observable.from(optional: optional) - } - - /** - Converts a optional to an observable sequence. - - - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - - - parameter optional: Optional element in the resulting observable sequence. - - parameter: Scheduler to send the optional element on. - - returns: An observable sequence containing the wrapped value or not from given optional. - */ - @available(*, deprecated, message: "Implicit conversions from any type to optional type are allowed and that is causing issues with `from` operator overloading.", renamed: "from(optional:scheduler:)") - public static func from(_ optional: E?, scheduler: ImmediateSchedulerType) -> Observable { - return Observable.from(optional: optional, scheduler: scheduler) - } -} - -extension ObservableType { - /** - - Projects each element of an observable sequence into a new form by incorporating the element's index. - - - seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html) - - - parameter selector: A transform function to apply to each source element; the second parameter of the function represents the index of the source element. - - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source. - */ - @available(*, deprecated, message: "Please use enumerated().map()") - public func mapWithIndex(_ selector: @escaping (E, Int) throws -> R) - -> Observable { - return enumerated().map { try selector($0.element, $0.index) } - } - - - /** - - Projects each element of an observable sequence to an observable sequence by incorporating the element's index and merges the resulting observable sequences into one observable sequence. - - - seealso: [flatMap operator on reactivex.io](http://reactivex.io/documentation/operators/flatmap.html) - - - parameter selector: A transform function to apply to each element; the second parameter of the function represents the index of the source element. - - returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence. - */ - @available(*, deprecated, message: "Please use enumerated().flatMap()") - public func flatMapWithIndex(_ selector: @escaping (E, Int) throws -> O) - -> Observable { - return enumerated().flatMap { try selector($0.element, $0.index) } - } - - /** - - Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements. - The element's index is used in the logic of the predicate function. - - - seealso: [skipWhile operator on reactivex.io](http://reactivex.io/documentation/operators/skipwhile.html) - - - parameter predicate: A function to test each element for a condition; the second parameter of the function represents the index of the source element. - - returns: An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate. - */ - @available(*, deprecated, message: "Please use enumerated().skipWhile().map()") - public func skipWhileWithIndex(_ predicate: @escaping (E, Int) throws -> Bool) -> Observable { - return enumerated().skipWhile { try predicate($0.element, $0.index) }.map { $0.element } - } - - - /** - - Returns elements from an observable sequence as long as a specified condition is true. - - The element's index is used in the logic of the predicate function. - - - seealso: [takeWhile operator on reactivex.io](http://reactivex.io/documentation/operators/takewhile.html) - - - parameter predicate: A function to test each element for a condition; the second parameter of the function represents the index of the source element. - - returns: An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes. - */ - @available(*, deprecated, message: "Please use enumerated().takeWhile().map()") - public func takeWhileWithIndex(_ predicate: @escaping (E, Int) throws -> Bool) -> Observable { - return enumerated().takeWhile { try predicate($0.element, $0.index) }.map { $0.element } - } -} - -extension Disposable { - /// Deprecated in favor of `disposed(by:)` - /// - /// - /// Adds `self` to `bag`. - /// - /// - parameter bag: `DisposeBag` to add `self` to. - @available(*, deprecated, message: "use disposed(by:) instead", renamed: "disposed(by:)") - public func addDisposableTo(_ bag: DisposeBag) { - disposed(by: bag) - } -} - - -extension ObservableType { - - /** - Returns an observable sequence that shares a single subscription to the underlying sequence, and immediately upon subscription replays latest element in buffer. - - This operator is a specialization of replay which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed. - - - seealso: [shareReplay operator on reactivex.io](http://reactivex.io/documentation/operators/replay.html) - - - returns: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence. - */ - @available(*, deprecated, message: "use share(replay: 1) instead", renamed: "share(replay:)") - public func shareReplayLatestWhileConnected() - -> Observable { - return share(replay: 1, scope: .whileConnected) - } -} - - -extension ObservableType { - - /** - Returns an observable sequence that shares a single subscription to the underlying sequence, and immediately upon subscription replays maximum number of elements in buffer. - - This operator is a specialization of replay which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed. - - - seealso: [shareReplay operator on reactivex.io](http://reactivex.io/documentation/operators/replay.html) - - - parameter bufferSize: Maximum element count of the replay buffer. - - returns: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence. - */ - @available(*, deprecated, message: "Suggested replacement is `share(replay: 1)`. In case old 3.x behavior of `shareReplay` is required please use `share(replay: 1, scope: .forever)` instead.", renamed: "share(replay:)") - public func shareReplay(_ bufferSize: Int) - -> Observable { - return self.share(replay: bufferSize, scope: .forever) - } -} - -/// Variable is a wrapper for `BehaviorSubject`. -/// -/// Unlike `BehaviorSubject` it can't terminate with error, and when variable is deallocated -/// it will complete its observable sequence (`asObservable`). -/// -/// **This concept will be deprecated from RxSwift but offical migration path hasn't been decided yet.** -/// https://github.com/ReactiveX/RxSwift/issues/1501 -/// -/// Current recommended replacement for this API is `RxCocoa.BehaviorRelay` because: -/// * `Variable` isn't a standard cross platform concept, hence it's out of place in RxSwift target. -/// * It doesn't have a counterpart for handling events (`PublishRelay`). It models state only. -/// * It doesn't have a consistent naming with *Relay or other Rx concepts. -/// * It has an inconsistent memory management model compared to other parts of RxSwift (completes on `deinit`). -/// -/// Once plans are finalized, official availability attribute will be added in one of upcoming versions. -public final class Variable { - - public typealias E = Element - - private let _subject: BehaviorSubject - - private var _lock = SpinLock() - - // state - private var _value: E - - #if DEBUG - fileprivate let _synchronizationTracker = SynchronizationTracker() - #endif - - /// Gets or sets current value of variable. - /// - /// Whenever a new value is set, all the observers are notified of the change. - /// - /// Even if the newly set value is same as the old value, observers are still notified for change. - public var value: E { - get { - _lock.lock(); defer { _lock.unlock() } - return _value - } - set(newValue) { - #if DEBUG - _synchronizationTracker.register(synchronizationErrorMessage: .variable) - defer { _synchronizationTracker.unregister() } - #endif - _lock.lock() - _value = newValue - _lock.unlock() - - _subject.on(.next(newValue)) - } - } - - /// Initializes variable with initial value. - /// - /// - parameter value: Initial variable value. - public init(_ value: Element) { - #if DEBUG - DeprecationWarner.warnIfNeeded(.variable) - #endif - - _value = value - _subject = BehaviorSubject(value: value) - } - - /// - returns: Canonical interface for push style sequence - public func asObservable() -> Observable { - return _subject - } - - deinit { - _subject.on(.completed) - } -} diff --git a/iOS/RxSwift/Disposables/AnonymousDisposable.swift b/iOS/RxSwift/Disposables/AnonymousDisposable.swift index e54532b9..591aafa5 100644 --- a/iOS/RxSwift/Disposables/AnonymousDisposable.swift +++ b/iOS/RxSwift/Disposables/AnonymousDisposable.swift @@ -9,40 +9,38 @@ /// Represents an Action-based disposable. /// /// When dispose method is called, disposal action will be dereferenced. -fileprivate final class AnonymousDisposable : DisposeBase, Cancelable { +private final class AnonymousDisposable : DisposeBase, Cancelable { public typealias DisposeAction = () -> Void - private var _isDisposed: AtomicInt = 0 - private var _disposeAction: DisposeAction? + private let disposed = AtomicInt(0) + private var disposeAction: DisposeAction? /// - returns: Was resource disposed. public var isDisposed: Bool { - return _isDisposed == 1 + isFlagSet(self.disposed, 1) } /// Constructs a new disposable with the given action used for disposal. /// /// - parameter disposeAction: Disposal action which will be run upon calling `dispose`. - fileprivate init(_ disposeAction: @escaping DisposeAction) { - _disposeAction = disposeAction + private init(_ disposeAction: @escaping DisposeAction) { + self.disposeAction = disposeAction super.init() } - + // Non-deprecated version of the constructor, used by `Disposables.create(with:)` fileprivate init(disposeAction: @escaping DisposeAction) { - _disposeAction = disposeAction + self.disposeAction = disposeAction super.init() } - + /// Calls the disposal action if and only if the current instance hasn't been disposed yet. /// /// After invoking disposal action, disposal action will be dereferenced. fileprivate func dispose() { - if AtomicCompareAndSwap(0, 1, &_isDisposed) { - assert(_isDisposed == 1) - - if let action = _disposeAction { - _disposeAction = nil + if fetchOr(self.disposed, 1) == 0 { + if let action = self.disposeAction { + self.disposeAction = nil action() } } @@ -50,12 +48,12 @@ fileprivate final class AnonymousDisposable : DisposeBase, Cancelable { } extension Disposables { - + /// Constructs a new disposable with the given action used for disposal. /// /// - parameter dispose: Disposal action which will be run upon calling `dispose`. - public static func create(with dispose: @escaping () -> ()) -> Cancelable { - return AnonymousDisposable(disposeAction: dispose) + public static func create(with dispose: @escaping () -> Void) -> Cancelable { + AnonymousDisposable(disposeAction: dispose) } - + } diff --git a/iOS/RxSwift/Disposables/BinaryDisposable.swift b/iOS/RxSwift/Disposables/BinaryDisposable.swift index 8a518f00..a3d49370 100644 --- a/iOS/RxSwift/Disposables/BinaryDisposable.swift +++ b/iOS/RxSwift/Disposables/BinaryDisposable.swift @@ -9,15 +9,15 @@ /// Represents two disposable resources that are disposed together. private final class BinaryDisposable : DisposeBase, Cancelable { - private var _isDisposed: AtomicInt = 0 + private let disposed = AtomicInt(0) // state - private var _disposable1: Disposable? - private var _disposable2: Disposable? + private var disposable1: Disposable? + private var disposable2: Disposable? /// - returns: Was resource disposed. var isDisposed: Bool { - return _isDisposed > 0 + isFlagSet(self.disposed, 1) } /// Constructs new binary disposable from two disposables. @@ -25,8 +25,8 @@ private final class BinaryDisposable : DisposeBase, Cancelable { /// - parameter disposable1: First disposable /// - parameter disposable2: Second disposable init(_ disposable1: Disposable, _ disposable2: Disposable) { - _disposable1 = disposable1 - _disposable2 = disposable2 + self.disposable1 = disposable1 + self.disposable2 = disposable2 super.init() } @@ -34,20 +34,20 @@ private final class BinaryDisposable : DisposeBase, Cancelable { /// /// After invoking disposal action, disposal action will be dereferenced. func dispose() { - if AtomicCompareAndSwap(0, 1, &_isDisposed) { - _disposable1?.dispose() - _disposable2?.dispose() - _disposable1 = nil - _disposable2 = nil + if fetchOr(self.disposed, 1) == 0 { + self.disposable1?.dispose() + self.disposable2?.dispose() + self.disposable1 = nil + self.disposable2 = nil } } } extension Disposables { - + /// Creates a disposable with the given disposables. public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable { - return BinaryDisposable(disposable1, disposable2) + BinaryDisposable(disposable1, disposable2) } - + } diff --git a/iOS/RxSwift/Disposables/BooleanDisposable.swift b/iOS/RxSwift/Disposables/BooleanDisposable.swift index efae55e4..5efcbea2 100644 --- a/iOS/RxSwift/Disposables/BooleanDisposable.swift +++ b/iOS/RxSwift/Disposables/BooleanDisposable.swift @@ -10,24 +10,25 @@ public final class BooleanDisposable : Cancelable { internal static let BooleanDisposableTrue = BooleanDisposable(isDisposed: true) - private var _isDisposed = false + private let disposed: AtomicInt /// Initializes a new instance of the `BooleanDisposable` class public init() { + disposed = AtomicInt(0) } /// Initializes a new instance of the `BooleanDisposable` class with given value public init(isDisposed: Bool) { - self._isDisposed = isDisposed + self.disposed = AtomicInt(isDisposed ? 1 : 0) } /// - returns: Was resource disposed. public var isDisposed: Bool { - return _isDisposed + isFlagSet(self.disposed, 1) } /// Sets the status to disposed, which can be observer through the `isDisposed` property. public func dispose() { - _isDisposed = true + fetchOr(self.disposed, 1) } } diff --git a/iOS/RxSwift/Disposables/CompositeDisposable.swift b/iOS/RxSwift/Disposables/CompositeDisposable.swift index b0578172..bb4efe6a 100644 --- a/iOS/RxSwift/Disposables/CompositeDisposable.swift +++ b/iOS/RxSwift/Disposables/CompositeDisposable.swift @@ -16,14 +16,13 @@ public final class CompositeDisposable : DisposeBase, Cancelable { } } - private var _lock = SpinLock() + private var lock = SpinLock() // state - private var _disposables: Bag? = Bag() + private var disposables: Bag? = Bag() public var isDisposed: Bool { - _lock.lock(); defer { _lock.unlock() } - return _disposables == nil + self.lock.performLocked { self.disposables == nil } } public override init() { @@ -32,35 +31,35 @@ public final class CompositeDisposable : DisposeBase, Cancelable { /// Initializes a new instance of composite disposable with the specified number of disposables. public init(_ disposable1: Disposable, _ disposable2: Disposable) { // This overload is here to make sure we are using optimized version up to 4 arguments. - let _ = _disposables!.insert(disposable1) - let _ = _disposables!.insert(disposable2) + _ = self.disposables!.insert(disposable1) + _ = self.disposables!.insert(disposable2) } /// Initializes a new instance of composite disposable with the specified number of disposables. public init(_ disposable1: Disposable, _ disposable2: Disposable, _ disposable3: Disposable) { // This overload is here to make sure we are using optimized version up to 4 arguments. - let _ = _disposables!.insert(disposable1) - let _ = _disposables!.insert(disposable2) - let _ = _disposables!.insert(disposable3) + _ = self.disposables!.insert(disposable1) + _ = self.disposables!.insert(disposable2) + _ = self.disposables!.insert(disposable3) } /// Initializes a new instance of composite disposable with the specified number of disposables. public init(_ disposable1: Disposable, _ disposable2: Disposable, _ disposable3: Disposable, _ disposable4: Disposable, _ disposables: Disposable...) { // This overload is here to make sure we are using optimized version up to 4 arguments. - let _ = _disposables!.insert(disposable1) - let _ = _disposables!.insert(disposable2) - let _ = _disposables!.insert(disposable3) - let _ = _disposables!.insert(disposable4) + _ = self.disposables!.insert(disposable1) + _ = self.disposables!.insert(disposable2) + _ = self.disposables!.insert(disposable3) + _ = self.disposables!.insert(disposable4) for disposable in disposables { - let _ = _disposables!.insert(disposable) + _ = self.disposables!.insert(disposable) } } /// Initializes a new instance of composite disposable with the specified number of disposables. public init(disposables: [Disposable]) { for disposable in disposables { - let _ = _disposables!.insert(disposable) + _ = self.disposables!.insert(disposable) } } @@ -72,7 +71,7 @@ public final class CompositeDisposable : DisposeBase, Cancelable { disposed `nil` will be returned. */ public func insert(_ disposable: Disposable) -> DisposeKey? { - let key = _insert(disposable) + let key = self._insert(disposable) if key == nil { disposable.dispose() @@ -82,44 +81,41 @@ public final class CompositeDisposable : DisposeBase, Cancelable { } private func _insert(_ disposable: Disposable) -> DisposeKey? { - _lock.lock(); defer { _lock.unlock() } - - let bagKey = _disposables?.insert(disposable) - return bagKey.map(DisposeKey.init) + self.lock.performLocked { + let bagKey = self.disposables?.insert(disposable) + return bagKey.map(DisposeKey.init) + } } /// - returns: Gets the number of disposables contained in the `CompositeDisposable`. public var count: Int { - _lock.lock(); defer { _lock.unlock() } - return _disposables?.count ?? 0 + self.lock.performLocked { self.disposables?.count ?? 0 } } /// Removes and disposes the disposable identified by `disposeKey` from the CompositeDisposable. /// /// - parameter disposeKey: Key used to identify disposable to be removed. public func remove(for disposeKey: DisposeKey) { - _remove(for: disposeKey)?.dispose() + self._remove(for: disposeKey)?.dispose() } private func _remove(for disposeKey: DisposeKey) -> Disposable? { - _lock.lock(); defer { _lock.unlock() } - return _disposables?.removeKey(disposeKey.key) + self.lock.performLocked { self.disposables?.removeKey(disposeKey.key) } } /// Disposes all disposables in the group and removes them from the group. public func dispose() { - if let disposables = _dispose() { + if let disposables = self._dispose() { disposeAll(in: disposables) } } private func _dispose() -> Bag? { - _lock.lock(); defer { _lock.unlock() } - - let disposeBag = _disposables - _disposables = nil - - return disposeBag + self.lock.performLocked { + let current = self.disposables + self.disposables = nil + return current + } } } @@ -127,7 +123,7 @@ extension Disposables { /// Creates a disposable with the given disposables. public static func create(_ disposable1: Disposable, _ disposable2: Disposable, _ disposable3: Disposable) -> Cancelable { - return CompositeDisposable(disposable1, disposable2, disposable3) + CompositeDisposable(disposable1, disposable2, disposable3) } /// Creates a disposable with the given disposables. diff --git a/iOS/RxSwift/Disposables/DisposeBag.swift b/iOS/RxSwift/Disposables/DisposeBag.swift index d5e3b029..1a673bcc 100644 --- a/iOS/RxSwift/Disposables/DisposeBag.swift +++ b/iOS/RxSwift/Disposables/DisposeBag.swift @@ -29,38 +29,39 @@ In case explicit disposal is necessary, there is also `CompositeDisposable`. */ public final class DisposeBag: DisposeBase { - private var _lock = SpinLock() + private var lock = SpinLock() // state - private var _disposables = [Disposable]() - private var _isDisposed = false + private var disposables = [Disposable]() + private var isDisposed = false /// Constructs new empty dispose bag. public override init() { super.init() } - + /// Adds `disposable` to be disposed when dispose bag is being deinited. /// /// - parameter disposable: Disposable to add. public func insert(_ disposable: Disposable) { - _insert(disposable)?.dispose() + self._insert(disposable)?.dispose() } private func _insert(_ disposable: Disposable) -> Disposable? { - _lock.lock(); defer { _lock.unlock() } - if _isDisposed { - return disposable - } + self.lock.performLocked { + if self.isDisposed { + return disposable + } - _disposables.append(disposable) + self.disposables.append(disposable) - return nil + return nil + } } /// This is internal on purpose, take a look at `CompositeDisposable` instead. private func dispose() { - let oldDisposables = _dispose() + let oldDisposables = self._dispose() for disposable in oldDisposables { disposable.dispose() @@ -68,17 +69,76 @@ public final class DisposeBag: DisposeBase { } private func _dispose() -> [Disposable] { - _lock.lock(); defer { _lock.unlock() } - - let disposables = _disposables - - _disposables.removeAll(keepingCapacity: false) - _isDisposed = true - - return disposables + self.lock.performLocked { + let disposables = self.disposables + + self.disposables.removeAll(keepingCapacity: false) + self.isDisposed = true + + return disposables + } } deinit { - dispose() + self.dispose() + } +} + +extension DisposeBag { + /// Convenience init allows a list of disposables to be gathered for disposal. + public convenience init(disposing disposables: Disposable...) { + self.init() + self.disposables += disposables + } + + /// Convenience init which utilizes a function builder to let you pass in a list of + /// disposables to make a DisposeBag of. + public convenience init(@DisposableBuilder builder: () -> [Disposable]) { + self.init(disposing: builder()) + } + + /// Convenience init allows an array of disposables to be gathered for disposal. + public convenience init(disposing disposables: [Disposable]) { + self.init() + self.disposables += disposables } + + /// Convenience function allows a list of disposables to be gathered for disposal. + public func insert(_ disposables: Disposable...) { + self.insert(disposables) + } + + /// Convenience function allows a list of disposables to be gathered for disposal. + public func insert(@DisposableBuilder builder: () -> [Disposable]) { + self.insert(builder()) + } + + /// Convenience function allows an array of disposables to be gathered for disposal. + public func insert(_ disposables: [Disposable]) { + self.lock.performLocked { + if self.isDisposed { + disposables.forEach { $0.dispose() } + } else { + self.disposables += disposables + } + } + } + + /// A function builder accepting a list of Disposables and returning them as an array. + #if swift(>=5.4) + @resultBuilder + public struct DisposableBuilder { + public static func buildBlock(_ disposables: Disposable...) -> [Disposable] { + return disposables + } + } + #else + @_functionBuilder + public struct DisposableBuilder { + public static func buildBlock(_ disposables: Disposable...) -> [Disposable] { + return disposables + } + } + #endif + } diff --git a/iOS/RxSwift/Disposables/DisposeBase.swift b/iOS/RxSwift/Disposables/DisposeBase.swift index 8c6a44f0..0d4b2fb7 100644 --- a/iOS/RxSwift/Disposables/DisposeBase.swift +++ b/iOS/RxSwift/Disposables/DisposeBase.swift @@ -10,13 +10,13 @@ public class DisposeBase { init() { #if TRACE_RESOURCES - let _ = Resources.incrementTotal() + _ = Resources.incrementTotal() #endif } deinit { #if TRACE_RESOURCES - let _ = Resources.decrementTotal() + _ = Resources.decrementTotal() #endif } } diff --git a/iOS/RxSwift/Disposables/NopDisposable.swift b/iOS/RxSwift/Disposables/NopDisposable.swift index 149f8664..dd436ba9 100644 --- a/iOS/RxSwift/Disposables/NopDisposable.swift +++ b/iOS/RxSwift/Disposables/NopDisposable.swift @@ -9,11 +9,11 @@ /// Represents a disposable that does nothing on disposal. /// /// Nop = No Operation -fileprivate struct NopDisposable : Disposable { +private struct NopDisposable : Disposable { fileprivate static let noOp: Disposable = NopDisposable() - fileprivate init() { + private init() { } @@ -26,7 +26,5 @@ extension Disposables { /** Creates a disposable that does nothing on disposal. */ - static public func create() -> Disposable { - return NopDisposable.noOp - } + static public func create() -> Disposable { NopDisposable.noOp } } diff --git a/iOS/RxSwift/Disposables/RefCountDisposable.swift b/iOS/RxSwift/Disposables/RefCountDisposable.swift index a21662ab..a59f7789 100644 --- a/iOS/RxSwift/Disposables/RefCountDisposable.swift +++ b/iOS/RxSwift/Disposables/RefCountDisposable.swift @@ -8,20 +8,19 @@ /// Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed. public final class RefCountDisposable : DisposeBase, Cancelable { - private var _lock = SpinLock() - private var _disposable = nil as Disposable? - private var _primaryDisposed = false - private var _count = 0 + private var lock = SpinLock() + private var disposable = nil as Disposable? + private var primaryDisposed = false + private var count = 0 /// - returns: Was resource disposed. public var isDisposed: Bool { - _lock.lock(); defer { _lock.unlock() } - return _disposable == nil + self.lock.performLocked { self.disposable == nil } } /// Initializes a new instance of the `RefCountDisposable`. public init(disposable: Disposable) { - _disposable = disposable + self.disposable = disposable super.init() } @@ -31,12 +30,11 @@ public final class RefCountDisposable : DisposeBase, Cancelable { When getter is called, a dependent disposable contributing to the reference count that manages the underlying disposable's lifetime is returned. */ public func retain() -> Disposable { - return _lock.calculateLocked { - if let _ = _disposable { - + self.lock.performLocked { + if self.disposable != nil { do { - let _ = try incrementChecked(&_count) - } catch (_) { + _ = try incrementChecked(&self.count) + } catch { rxFatalError("RefCountDisposable increment failed") } @@ -49,14 +47,12 @@ public final class RefCountDisposable : DisposeBase, Cancelable { /// Disposes the underlying disposable only when all dependent disposables have been disposed. public func dispose() { - let oldDisposable: Disposable? = _lock.calculateLocked { - if let oldDisposable = _disposable, !_primaryDisposed - { - _primaryDisposed = true - - if (_count == 0) - { - _disposable = nil + let oldDisposable: Disposable? = self.lock.performLocked { + if let oldDisposable = self.disposable, !self.primaryDisposed { + self.primaryDisposed = true + + if self.count == 0 { + self.disposable = nil return oldDisposable } } @@ -70,20 +66,20 @@ public final class RefCountDisposable : DisposeBase, Cancelable { } fileprivate func release() { - let oldDisposable: Disposable? = _lock.calculateLocked { - if let oldDisposable = _disposable { + let oldDisposable: Disposable? = self.lock.performLocked { + if let oldDisposable = self.disposable { do { - let _ = try decrementChecked(&_count) - } catch (_) { + _ = try decrementChecked(&self.count) + } catch { rxFatalError("RefCountDisposable decrement on release failed") } - guard _count >= 0 else { + guard self.count >= 0 else { rxFatalError("RefCountDisposable counter is lower than 0") } - if _primaryDisposed && _count == 0 { - _disposable = nil + if self.primaryDisposed && self.count == 0 { + self.disposable = nil return oldDisposable } } @@ -99,19 +95,18 @@ public final class RefCountDisposable : DisposeBase, Cancelable { internal final class RefCountInnerDisposable: DisposeBase, Disposable { - private let _parent: RefCountDisposable - private var _isDisposed: AtomicInt = 0 + private let parent: RefCountDisposable + private let isDisposed = AtomicInt(0) - init(_ parent: RefCountDisposable) - { - _parent = parent + init(_ parent: RefCountDisposable) { + self.parent = parent super.init() } internal func dispose() { - if AtomicCompareAndSwap(0, 1, &_isDisposed) { - _parent.release() + if fetchOr(self.isDisposed, 1) == 0 { + self.parent.release() } } } diff --git a/iOS/RxSwift/Disposables/ScheduledDisposable.swift b/iOS/RxSwift/Disposables/ScheduledDisposable.swift index 92c220df..2cf997bc 100644 --- a/iOS/RxSwift/Disposables/ScheduledDisposable.swift +++ b/iOS/RxSwift/Disposables/ScheduledDisposable.swift @@ -15,14 +15,14 @@ private let disposeScheduledDisposable: (ScheduledDisposable) -> Disposable = { public final class ScheduledDisposable : Cancelable { public let scheduler: ImmediateSchedulerType - private var _isDisposed: AtomicInt = 0 + private let disposed = AtomicInt(0) // state - private var _disposable: Disposable? + private var disposable: Disposable? /// - returns: Was resource disposed. public var isDisposed: Bool { - return _isDisposed == 1 + isFlagSet(self.disposed, 1) } /** @@ -33,18 +33,18 @@ public final class ScheduledDisposable : Cancelable { */ public init(scheduler: ImmediateSchedulerType, disposable: Disposable) { self.scheduler = scheduler - _disposable = disposable + self.disposable = disposable } /// Disposes the wrapped disposable on the provided scheduler. public func dispose() { - let _ = scheduler.schedule(self, action: disposeScheduledDisposable) + _ = self.scheduler.schedule(self, action: disposeScheduledDisposable) } func disposeInner() { - if AtomicCompareAndSwap(0, 1, &_isDisposed) { - _disposable!.dispose() - _disposable = nil + if fetchOr(self.disposed, 1) == 0 { + self.disposable!.dispose() + self.disposable = nil } } } diff --git a/iOS/RxSwift/Disposables/SerialDisposable.swift b/iOS/RxSwift/Disposables/SerialDisposable.swift index 6373d2bb..ef4690d3 100644 --- a/iOS/RxSwift/Disposables/SerialDisposable.swift +++ b/iOS/RxSwift/Disposables/SerialDisposable.swift @@ -8,15 +8,15 @@ /// Represents a disposable resource whose underlying disposable resource can be replaced by another disposable resource, causing automatic disposal of the previous underlying disposable resource. public final class SerialDisposable : DisposeBase, Cancelable { - private var _lock = SpinLock() + private var lock = SpinLock() // state - private var _current = nil as Disposable? - private var _isDisposed = false + private var current = nil as Disposable? + private var disposed = false /// - returns: Was resource disposed. public var isDisposed: Bool { - return _isDisposed + self.disposed } /// Initializes a new instance of the `SerialDisposable`. @@ -33,18 +33,18 @@ public final class SerialDisposable : DisposeBase, Cancelable { */ public var disposable: Disposable { get { - return _lock.calculateLocked { - return _current ?? Disposables.create() + self.lock.performLocked { + self.current ?? Disposables.create() } } set (newDisposable) { - let disposable: Disposable? = _lock.calculateLocked { - if _isDisposed { + let disposable: Disposable? = self.lock.performLocked { + if self.isDisposed { return newDisposable } else { - let toDispose = _current - _current = newDisposable + let toDispose = self.current + self.current = newDisposable return toDispose } } @@ -57,18 +57,16 @@ public final class SerialDisposable : DisposeBase, Cancelable { /// Disposes the underlying disposable as well as all future replacements. public func dispose() { - _dispose()?.dispose() + self._dispose()?.dispose() } private func _dispose() -> Disposable? { - _lock.lock(); defer { _lock.unlock() } - if _isDisposed { - return nil - } - else { - _isDisposed = true - let current = _current - _current = nil + self.lock.performLocked { + guard !self.isDisposed else { return nil } + + self.disposed = true + let current = self.current + self.current = nil return current } } diff --git a/iOS/RxSwift/Disposables/SingleAssignmentDisposable.swift b/iOS/RxSwift/Disposables/SingleAssignmentDisposable.swift index e8ef67dc..4a5fb866 100644 --- a/iOS/RxSwift/Disposables/SingleAssignmentDisposable.swift +++ b/iOS/RxSwift/Disposables/SingleAssignmentDisposable.swift @@ -13,24 +13,20 @@ If an underlying disposable resource has already been set, future attempts to se */ public final class SingleAssignmentDisposable : DisposeBase, Cancelable { - fileprivate enum DisposeState: UInt32 { - case disposed = 1 - case disposableSet = 2 - } - - // Jeej, swift API consistency rules - fileprivate enum DisposeStateInt32: Int32 { - case disposed = 1 - case disposableSet = 2 + private struct DisposeState: OptionSet { + let rawValue: Int32 + + static let disposed = DisposeState(rawValue: 1 << 0) + static let disposableSet = DisposeState(rawValue: 1 << 1) } // state - private var _state: AtomicInt = 0 - private var _disposable = nil as Disposable? + private let state = AtomicInt(0) + private var disposable = nil as Disposable? /// - returns: A value that indicates whether the object is disposed. public var isDisposed: Bool { - return AtomicFlagSet(DisposeState.disposed.rawValue, &_state) + isFlagSet(self.state, DisposeState.disposed.rawValue) } /// Initializes a new instance of the `SingleAssignmentDisposable`. @@ -42,34 +38,34 @@ public final class SingleAssignmentDisposable : DisposeBase, Cancelable { /// /// **Throws exception if the `SingleAssignmentDisposable` has already been assigned to.** public func setDisposable(_ disposable: Disposable) { - _disposable = disposable + self.disposable = disposable - let previousState = AtomicOr(DisposeState.disposableSet.rawValue, &_state) - - if (previousState & DisposeStateInt32.disposableSet.rawValue) != 0 { + let previousState = fetchOr(self.state, DisposeState.disposableSet.rawValue) + + if (previousState & DisposeState.disposableSet.rawValue) != 0 { rxFatalError("oldState.disposable != nil") } - if (previousState & DisposeStateInt32.disposed.rawValue) != 0 { + if (previousState & DisposeState.disposed.rawValue) != 0 { disposable.dispose() - _disposable = nil + self.disposable = nil } } /// Disposes the underlying disposable. public func dispose() { - let previousState = AtomicOr(DisposeState.disposed.rawValue, &_state) + let previousState = fetchOr(self.state, DisposeState.disposed.rawValue) - if (previousState & DisposeStateInt32.disposed.rawValue) != 0 { + if (previousState & DisposeState.disposed.rawValue) != 0 { return } - if (previousState & DisposeStateInt32.disposableSet.rawValue) != 0 { - guard let disposable = _disposable else { + if (previousState & DisposeState.disposableSet.rawValue) != 0 { + guard let disposable = self.disposable else { rxFatalError("Disposable not set") } disposable.dispose() - _disposable = nil + self.disposable = nil } } diff --git a/iOS/RxSwift/Disposables/SubscriptionDisposable.swift b/iOS/RxSwift/Disposables/SubscriptionDisposable.swift index 3ae138a8..a406c84c 100644 --- a/iOS/RxSwift/Disposables/SubscriptionDisposable.swift +++ b/iOS/RxSwift/Disposables/SubscriptionDisposable.swift @@ -7,15 +7,15 @@ // struct SubscriptionDisposable : Disposable { - private let _key: T.DisposeKey - private weak var _owner: T? + private let key: T.DisposeKey + private weak var owner: T? init(owner: T, key: T.DisposeKey) { - _owner = owner - _key = key + self.owner = owner + self.key = key } func dispose() { - _owner?.synchronizedUnsubscribe(_key) + self.owner?.synchronizedUnsubscribe(self.key) } } diff --git a/iOS/RxSwift/Errors.swift b/iOS/RxSwift/Errors.swift index f17b52d8..d2d2917e 100644 --- a/iOS/RxSwift/Errors.swift +++ b/iOS/RxSwift/Errors.swift @@ -17,7 +17,7 @@ public enum RxError case unknown /// Performing an action on disposed object. case disposed(object: AnyObject) - /// Aritmetic overflow error. + /// Arithmetic overflow error. case overflow /// Argument out of range error. case argumentOutOfRange diff --git a/iOS/RxSwift/Event.swift b/iOS/RxSwift/Event.swift index 377877b6..01861a85 100644 --- a/iOS/RxSwift/Event.swift +++ b/iOS/RxSwift/Event.swift @@ -10,7 +10,7 @@ /// /// Sequence grammar: /// **next\* (error | completed)** -public enum Event { +@frozen public enum Event { /// Next element is produced. case next(Element) @@ -21,8 +21,8 @@ public enum Event { case completed } -extension Event : CustomDebugStringConvertible { - /// - returns: Description of event. +extension Event: CustomDebugStringConvertible { + /// Description of event. public var debugDescription: String { switch self { case .next(let value): @@ -60,7 +60,7 @@ extension Event { return nil } - /// If `completed` event, returns true. + /// If `completed` event, returns `true`. public var isCompleted: Bool { if case .completed = self { return true @@ -70,8 +70,8 @@ extension Event { } extension Event { - /// Maps sequence elements using transform. If error happens during the transform .error - /// will be returned as value + /// Maps sequence elements using transform. If error happens during the transform, `.error` + /// will be returned as value. public func map(_ transform: (Element) throws -> Result) -> Event { do { switch self { @@ -92,15 +92,13 @@ extension Event { /// A type that can be converted to `Event`. public protocol EventConvertible { /// Type of element in event - associatedtype ElementType + associatedtype Element /// Event representation of this instance - var event: Event { get } + var event: Event { get } } -extension Event : EventConvertible { +extension Event: EventConvertible { /// Event representation of this instance - public var event: Event { - return self - } + public var event: Event { self } } diff --git a/iOS/RxSwift/Extensions/Bag+Rx.swift b/iOS/RxSwift/Extensions/Bag+Rx.swift index 895333cd..97946837 100644 --- a/iOS/RxSwift/Extensions/Bag+Rx.swift +++ b/iOS/RxSwift/Extensions/Bag+Rx.swift @@ -10,25 +10,19 @@ // MARK: forEach @inline(__always) -func dispatch(_ bag: Bag<(Event) -> ()>, _ event: Event) { +func dispatch(_ bag: Bag<(Event) -> Void>, _ event: Event) { + bag._value0?(event) + if bag._onlyFastPath { - bag._value0?(event) return } - let value0 = bag._value0 - let dictionary = bag._dictionary - - if let value0 = value0 { - value0(event) - } - let pairs = bag._pairs for i in 0 ..< pairs.count { pairs[i].value(event) } - if let dictionary = dictionary { + if let dictionary = bag._dictionary { for element in dictionary.values { element(event) } @@ -37,24 +31,18 @@ func dispatch(_ bag: Bag<(Event) -> ()>, _ event: Event) { /// Dispatches `dispose` to all disposables contained inside bag. func disposeAll(in bag: Bag) { + bag._value0?.dispose() + if bag._onlyFastPath { - bag._value0?.dispose() return } - let value0 = bag._value0 - let dictionary = bag._dictionary - - if let value0 = value0 { - value0.dispose() - } - let pairs = bag._pairs for i in 0 ..< pairs.count { pairs[i].value.dispose() } - if let dictionary = dictionary { + if let dictionary = bag._dictionary { for element in dictionary.values { element.dispose() } diff --git a/iOS/RxSwift/Extensions/String+Rx.swift b/iOS/RxSwift/Extensions/String+Rx.swift deleted file mode 100644 index 42ef636c..00000000 --- a/iOS/RxSwift/Extensions/String+Rx.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// String+Rx.swift -// RxSwift -// -// Created by Krunoslav Zaher on 12/25/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension String { - /// This is needed because on Linux Swift doesn't have `rangeOfString(..., options: .BackwardsSearch)` - func lastIndexOf(_ character: Character) -> Index? { - var index = endIndex - while index > startIndex { - index = self.index(before: index) - if self[index] == character { - return index - } - } - - return nil - } -} diff --git a/iOS/RxSwift/GroupedObservable.swift b/iOS/RxSwift/GroupedObservable.swift index d87e0bad..189a8c46 100644 --- a/iOS/RxSwift/GroupedObservable.swift +++ b/iOS/RxSwift/GroupedObservable.swift @@ -8,8 +8,6 @@ /// Represents an observable sequence of elements that have a common key. public struct GroupedObservable : ObservableType { - public typealias E = Element - /// Gets the common key. public let key: Key @@ -26,12 +24,12 @@ public struct GroupedObservable : ObservableType { } /// Subscribes `observer` to receive events for this sequence. - public func subscribe(_ observer: O) -> Disposable where O.E == E { - return self.source.subscribe(observer) + public func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { + self.source.subscribe(observer) } /// Converts `self` to `Observable` sequence. public func asObservable() -> Observable { - return source + self.source } } diff --git a/iOS/RxSwift/ImmediateSchedulerType.swift b/iOS/RxSwift/ImmediateSchedulerType.swift index 8dc2a85c..954fbf04 100644 --- a/iOS/RxSwift/ImmediateSchedulerType.swift +++ b/iOS/RxSwift/ImmediateSchedulerType.swift @@ -26,7 +26,7 @@ extension ImmediateSchedulerType { - parameter action: Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state. - returns: The disposable object used to cancel the scheduled action (best effort). */ - public func scheduleRecursive(_ state: State, action: @escaping (_ state: State, _ recurse: (State) -> ()) -> ()) -> Disposable { + public func scheduleRecursive(_ state: State, action: @escaping (_ state: State, _ recurse: (State) -> Void) -> Void) -> Disposable { let recursiveScheduler = RecursiveImmediateScheduler(action: action, scheduler: self) recursiveScheduler.schedule(state) diff --git a/iOS/RxSwift/Info.plist b/iOS/RxSwift/Info.plist new file mode 100644 index 00000000..c44f11c6 --- /dev/null +++ b/iOS/RxSwift/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 6.5.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/iOS/RxSwift/Observable+Concurrency.swift b/iOS/RxSwift/Observable+Concurrency.swift new file mode 100644 index 00000000..45ad05ed --- /dev/null +++ b/iOS/RxSwift/Observable+Concurrency.swift @@ -0,0 +1,79 @@ +// +// Observable+Concurrency.swift +// RxSwift +// +// Created by Shai Mishali on 22/09/2021. +// Copyright © 2021 Krunoslav Zaher. All rights reserved. +// + +#if swift(>=5.6) && canImport(_Concurrency) +import Foundation + +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) +public extension ObservableConvertibleType { + /// Allows iterating over the values of an Observable + /// asynchronously via Swift's concurrency features (`async/await`) + /// + /// A sample usage would look like so: + /// + /// ```swift + /// do { + /// for try await value in observable.values { + /// // Handle emitted values + /// } + /// } catch { + /// // Handle error + /// } + /// ``` + var values: AsyncThrowingStream { + AsyncThrowingStream { continuation in + var isFinished = false + let disposable = asObservable().subscribe( + onNext: { value in continuation.yield(value) }, + onError: { error in + isFinished = true + continuation.finish(throwing: error) + }, + onCompleted: { + isFinished = true + continuation.finish() + }, + onDisposed: { + guard !isFinished else { return } + continuation.finish(throwing: CancellationError() ) + } + ) + continuation.onTermination = { @Sendable termination in + if case .cancelled = termination { + disposable.dispose() + } + } + } + } +} + +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) +public extension AsyncSequence { + /// Convert an `AsyncSequence` to an `Observable` emitting + /// values of the asynchronous sequence's type + /// + /// - returns: An `Observable` of the async sequence's type + func asObservable() -> Observable { + Observable.create { observer in + let task = Task { + do { + for try await value in self { + observer.onNext(value) + } + + observer.onCompleted() + } catch { + observer.onError(error) + } + } + + return Disposables.create { task.cancel() } + } + } +} +#endif diff --git a/iOS/RxSwift/Observable.swift b/iOS/RxSwift/Observable.swift index f0c55af7..93a3ed78 100644 --- a/iOS/RxSwift/Observable.swift +++ b/iOS/RxSwift/Observable.swift @@ -10,35 +10,22 @@ /// /// It represents a push style sequence. public class Observable : ObservableType { - /// Type of elements in sequence. - public typealias E = Element - init() { #if TRACE_RESOURCES - let _ = Resources.incrementTotal() + _ = Resources.incrementTotal() #endif } - public func subscribe(_ observer: O) -> Disposable where O.E == E { + public func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { rxAbstractMethod() } - public func asObservable() -> Observable { - return self - } + public func asObservable() -> Observable { self } deinit { #if TRACE_RESOURCES - let _ = Resources.decrementTotal() + _ = Resources.decrementTotal() #endif } - - // this is kind of ugly I know :( - // Swift compiler reports "Not supported yet" when trying to override protocol extensions, so ¯\_(ツ)_/¯ - - /// Optimizations for map operator - internal func composeMap(_ transform: @escaping (Element) throws -> R) -> Observable { - return _map(source: self, transform: transform) - } } diff --git a/iOS/RxSwift/ObservableConvertibleType.swift b/iOS/RxSwift/ObservableConvertibleType.swift index d89c5aa7..0f56a816 100644 --- a/iOS/RxSwift/ObservableConvertibleType.swift +++ b/iOS/RxSwift/ObservableConvertibleType.swift @@ -6,13 +6,13 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -/// Type that can be converted to observable sequence (`Observable`). +/// Type that can be converted to observable sequence (`Observable`). public protocol ObservableConvertibleType { /// Type of elements in sequence. - associatedtype E + associatedtype Element /// Converts `self` to `Observable` sequence. /// /// - returns: Observable sequence that represents `self`. - func asObservable() -> Observable + func asObservable() -> Observable } diff --git a/iOS/RxSwift/ObservableType+Extensions.swift b/iOS/RxSwift/ObservableType+Extensions.swift index d558cca0..ac850c3b 100644 --- a/iOS/RxSwift/ObservableType+Extensions.swift +++ b/iOS/RxSwift/ObservableType+Extensions.swift @@ -17,14 +17,54 @@ extension ObservableType { - parameter on: Action to invoke for each event in the observable sequence. - returns: Subscription object used to unsubscribe from the observable sequence. */ - public func subscribe(_ on: @escaping (Event) -> Void) - -> Disposable { - let observer = AnonymousObserver { e in - on(e) - } - return self.asObservable().subscribe(observer) + public func subscribe(_ on: @escaping (Event) -> Void) -> Disposable { + let observer = AnonymousObserver { e in + on(e) + } + return self.asObservable().subscribe(observer) } + /** + Subscribes an element handler, an error handler, a completion handler and disposed handler to an observable sequence. + + Also, take in an object and provide an unretained, safe to use (i.e. not implicitly unwrapped), reference to it along with the events emitted by the sequence. + + - Note: If `object` can't be retained, none of the other closures will be invoked. + + - parameter object: The object to provide an unretained reference on. + - 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 onCompleted: Action to invoke upon graceful termination of the observable sequence. + - parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has + gracefully completed, errored, or if the generation is canceled by disposing subscription). + - returns: Subscription object used to unsubscribe from the observable sequence. + */ + public func subscribe( + with object: Object, + onNext: ((Object, Element) -> Void)? = nil, + onError: ((Object, Swift.Error) -> Void)? = nil, + onCompleted: ((Object) -> Void)? = nil, + onDisposed: ((Object) -> Void)? = nil + ) -> Disposable { + subscribe( + onNext: { [weak object] in + guard let object = object else { return } + onNext?(object, $0) + }, + onError: { [weak object] in + guard let object = object else { return } + onError?(object, $0) + }, + onCompleted: { [weak object] in + guard let object = object else { return } + onCompleted?(object) + }, + onDisposed: { [weak object] in + guard let object = object else { return } + onDisposed?(object) + } + ) + } /** Subscribes an element handler, an error handler, a completion handler and disposed handler to an observable sequence. @@ -36,105 +76,98 @@ extension ObservableType { gracefully completed, errored, or if the generation is canceled by disposing subscription). - returns: Subscription object used to unsubscribe from the observable sequence. */ - public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil) - -> Disposable { + public func subscribe( + onNext: ((Element) -> Void)? = nil, + onError: ((Swift.Error) -> Void)? = nil, + onCompleted: (() -> Void)? = nil, + onDisposed: (() -> Void)? = nil + ) -> Disposable { + let disposable: Disposable + + if let disposed = onDisposed { + disposable = Disposables.create(with: disposed) + } + else { + disposable = Disposables.create() + } + #if DEBUG - let disposable: Disposable - - if let disposed = onDisposed { - disposable = Disposables.create(with: disposed) - } - else { - disposable = Disposables.create() - } - let synchronizationTracker = SynchronizationTracker() - - let callStack = Hooks.recordCallStackOnError ? Thread.callStackSymbols : [] - - let observer = AnonymousObserver { event in - + #endif + + let callStack = Hooks.recordCallStackOnError ? Hooks.customCaptureSubscriptionCallstack() : [] + + let observer = AnonymousObserver { event in + + #if DEBUG synchronizationTracker.register(synchronizationErrorMessage: .default) defer { synchronizationTracker.unregister() } - - switch event { - case .next(let value): - onNext?(value) - case .error(let error): - if let onError = onError { - onError(error) - } - else { - Hooks.defaultErrorHandler(callStack, error) - } - disposable.dispose() - case .completed: - onCompleted?() - disposable.dispose() - } - } - return Disposables.create( - self.asObservable().subscribe(observer), - disposable - ) - #else - let disposable: Disposable - - if let disposed = onDisposed { - disposable = Disposables.create(with: disposed) - } - else { - disposable = Disposables.create() - } + #endif - let observer = AnonymousObserver { event in - switch event { - case .next(let value): - onNext?(value) - case .error(let error): - if let onError = onError { - onError(error) - } - else { - Hooks.defaultErrorHandler([], error) - } - disposable.dispose() - case .completed: - onCompleted?() - disposable.dispose() + switch event { + case .next(let value): + onNext?(value) + case .error(let error): + if let onError = onError { + onError(error) + } + else { + Hooks.defaultErrorHandler(callStack, error) } + disposable.dispose() + case .completed: + onCompleted?() + disposable.dispose() } - return Disposables.create( - self.asObservable().subscribe(observer), - disposable - ) - #endif - + } + return Disposables.create( + self.asObservable().subscribe(observer), + disposable + ) } } -import class Foundation.NSRecursiveLock +import Foundation extension Hooks { - public typealias DefaultErrorHandler = (_ subscriptionCallStack: [String], _ error: Error) -> () + public typealias DefaultErrorHandler = (_ subscriptionCallStack: [String], _ error: Error) -> Void + public typealias CustomCaptureSubscriptionCallstack = () -> [String] - fileprivate static let _lock = RecursiveLock() - fileprivate static var _defaultErrorHandler: DefaultErrorHandler = { subscriptionCallStack, error in + private static let lock = RecursiveLock() + private static var _defaultErrorHandler: DefaultErrorHandler = { subscriptionCallStack, error in #if DEBUG let serializedCallStack = subscriptionCallStack.joined(separator: "\n") - print("Unhandled error happened: \(error)\n subscription called from:\n\(serializedCallStack)") + print("Unhandled error happened: \(error)") + if !serializedCallStack.isEmpty { + print("subscription called from:\n\(serializedCallStack)") + } + #endif + } + private static var _customCaptureSubscriptionCallstack: CustomCaptureSubscriptionCallstack = { + #if DEBUG + return Thread.callStackSymbols + #else + return [] #endif } /// Error handler called in case onError handler wasn't provided. public static var defaultErrorHandler: DefaultErrorHandler { get { - _lock.lock(); defer { _lock.unlock() } - return _defaultErrorHandler + lock.performLocked { _defaultErrorHandler } + } + set { + lock.performLocked { _defaultErrorHandler = newValue } + } + } + + /// Subscription callstack block to fetch custom callstack information. + public static var customCaptureSubscriptionCallstack: CustomCaptureSubscriptionCallstack { + get { + lock.performLocked { _customCaptureSubscriptionCallstack } } set { - _lock.lock(); defer { _lock.unlock() } - _defaultErrorHandler = newValue + lock.performLocked { _customCaptureSubscriptionCallstack = newValue } } } } diff --git a/iOS/RxSwift/ObservableType.swift b/iOS/RxSwift/ObservableType.swift index e41a36a1..279bf7f4 100644 --- a/iOS/RxSwift/ObservableType.swift +++ b/iOS/RxSwift/ObservableType.swift @@ -7,7 +7,7 @@ // /// Represents a push style sequence. -public protocol ObservableType : ObservableConvertibleType { +public protocol ObservableType: ObservableConvertibleType { /** Subscribes `observer` to receive events for this sequence. @@ -31,17 +31,15 @@ public protocol ObservableType : ObservableConvertibleType { - returns: Subscription for `observer` that can be used to cancel production of sequence elements and free resources. */ - func subscribe(_ observer: O) -> Disposable where O.E == E + func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element } extension ObservableType { /// Default implementation of converting `ObservableType` to `Observable`. - public func asObservable() -> Observable { + public func asObservable() -> Observable { // temporary workaround //return Observable.create(subscribe: self.subscribe) - return Observable.create { o in - return self.subscribe(o) - } + Observable.create { o in self.subscribe(o) } } } diff --git a/iOS/RxSwift/Observables/AddRef.swift b/iOS/RxSwift/Observables/AddRef.swift index b782c13f..a96dfcb0 100644 --- a/iOS/RxSwift/Observables/AddRef.swift +++ b/iOS/RxSwift/Observables/AddRef.swift @@ -6,39 +6,38 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -final class AddRefSink : Sink, ObserverType { - typealias Element = O.E +final class AddRefSink : Sink, ObserverType { + typealias Element = Observer.Element - override init(observer: O, cancel: Cancelable) { + override init(observer: Observer, cancel: Cancelable) { super.init(observer: observer, cancel: cancel) } func on(_ event: Event) { switch event { - case .next(_): - forwardOn(event) - case .completed, .error(_): - forwardOn(event) - dispose() + case .next: + self.forwardOn(event) + case .completed, .error: + self.forwardOn(event) + self.dispose() } } } final class AddRef : Producer { - typealias EventHandler = (Event) throws -> Void - private let _source: Observable - private let _refCount: RefCountDisposable + private let source: Observable + private let refCount: RefCountDisposable init(source: Observable, refCount: RefCountDisposable) { - _source = source - _refCount = refCount + self.source = source + self.refCount = refCount } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - let releaseDisposable = _refCount.retain() + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let releaseDisposable = self.refCount.retain() let sink = AddRefSink(observer: observer, cancel: cancel) - let subscription = Disposables.create(releaseDisposable, _source.subscribe(sink)) + let subscription = Disposables.create(releaseDisposable, self.source.subscribe(sink)) return (sink: sink, subscription: subscription) } diff --git a/iOS/RxSwift/Observables/Amb.swift b/iOS/RxSwift/Observables/Amb.swift index 08ec04e1..efc17a8d 100644 --- a/iOS/RxSwift/Observables/Amb.swift +++ b/iOS/RxSwift/Observables/Amb.swift @@ -14,11 +14,11 @@ extension ObservableType { - returns: An observable sequence that surfaces any of the given sequences, whichever reacted first. */ - public static func amb(_ sequence: S) -> Observable - where S.Iterator.Element == Observable { - return sequence.reduce(Observable.never()) { a, o in - return a.amb(o.asObservable()) - } + public static func amb(_ sequence: Sequence) -> Observable + where Sequence.Element == Observable { + sequence.reduce(Observable.never()) { a, o in + a.amb(o.asObservable()) + } } } @@ -34,64 +34,64 @@ extension ObservableType { */ public func amb (_ right: O2) - -> Observable where O2.E == E { - return Amb(left: asObservable(), right: right.asObservable()) + -> Observable where O2.Element == Element { + Amb(left: self.asObservable(), right: right.asObservable()) } } -fileprivate enum AmbState { +private enum AmbState { case neither case left case right } -final fileprivate class AmbObserver : ObserverType { - typealias Element = O.E - typealias Parent = AmbSink - typealias This = AmbObserver +final private class AmbObserver: ObserverType { + typealias Element = Observer.Element + typealias Parent = AmbSink + typealias This = AmbObserver typealias Sink = (This, Event) -> Void - fileprivate let _parent: Parent - fileprivate var _sink: Sink - fileprivate var _cancel: Disposable + private let parent: Parent + fileprivate var sink: Sink + fileprivate var cancel: Disposable init(parent: Parent, cancel: Disposable, sink: @escaping Sink) { #if TRACE_RESOURCES - let _ = Resources.incrementTotal() + _ = Resources.incrementTotal() #endif - _parent = parent - _sink = sink - _cancel = cancel + self.parent = parent + self.sink = sink + self.cancel = cancel } func on(_ event: Event) { - _sink(self, event) + self.sink(self, event) if event.isStopEvent { - _cancel.dispose() + self.cancel.dispose() } } deinit { #if TRACE_RESOURCES - let _ = Resources.decrementTotal() + _ = Resources.decrementTotal() #endif } } -final fileprivate class AmbSink : Sink { - typealias ElementType = O.E - typealias Parent = Amb - typealias AmbObserverType = AmbObserver +final private class AmbSink: Sink { + typealias Element = Observer.Element + typealias Parent = Amb + typealias AmbObserverType = AmbObserver - private let _parent: Parent + private let parent: Parent - private let _lock = RecursiveLock() + private let lock = RecursiveLock() // state - private var _choice = AmbState.neither + private var choice = AmbState.neither - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } @@ -100,23 +100,23 @@ final fileprivate class AmbSink : Sink { let subscription2 = SingleAssignmentDisposable() let disposeAll = Disposables.create(subscription1, subscription2) - let forwardEvent = { (o: AmbObserverType, event: Event) -> Void in + let forwardEvent = { (o: AmbObserverType, event: Event) -> Void in self.forwardOn(event) if event.isStopEvent { self.dispose() } } - let decide = { (o: AmbObserverType, event: Event, me: AmbState, otherSubscription: Disposable) in - self._lock.performLocked { - if self._choice == .neither { - self._choice = me - o._sink = forwardEvent - o._cancel = disposeAll + let decide = { (o: AmbObserverType, event: Event, me: AmbState, otherSubscription: Disposable) in + self.lock.performLocked { + if self.choice == .neither { + self.choice = me + o.sink = forwardEvent + o.cancel = disposeAll otherSubscription.dispose() } - if self._choice == me { + if self.choice == me { self.forwardOn(event) if event.isStopEvent { self.dispose() @@ -133,23 +133,23 @@ final fileprivate class AmbSink : Sink { decide(o, e, .right, subscription1) } - subscription1.setDisposable(_parent._left.subscribe(sink1)) - subscription2.setDisposable(_parent._right.subscribe(sink2)) + subscription1.setDisposable(self.parent.left.subscribe(sink1)) + subscription2.setDisposable(self.parent.right.subscribe(sink2)) return disposeAll } } -final fileprivate class Amb: Producer { - fileprivate let _left: Observable - fileprivate let _right: Observable +final private class Amb: Producer { + fileprivate let left: Observable + fileprivate let right: Observable init(left: Observable, right: Observable) { - _left = left - _right = right + self.left = left + self.right = right } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = AmbSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/AsMaybe.swift b/iOS/RxSwift/Observables/AsMaybe.swift index 36fa685f..6fa62578 100644 --- a/iOS/RxSwift/Observables/AsMaybe.swift +++ b/iOS/RxSwift/Observables/AsMaybe.swift @@ -6,44 +6,43 @@ // Copyright © 2017 Krunoslav Zaher. All rights reserved. // -fileprivate final class AsMaybeSink : Sink, ObserverType { - typealias ElementType = O.E - typealias E = ElementType +private final class AsMaybeSink : Sink, ObserverType { + typealias Element = Observer.Element - private var _element: Event? = nil + private var element: Event? - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next: - if _element != nil { - forwardOn(.error(RxError.moreThanOneElement)) - dispose() + if self.element != nil { + self.forwardOn(.error(RxError.moreThanOneElement)) + self.dispose() } - _element = event + self.element = event case .error: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() case .completed: - if let element = _element { - forwardOn(element) + if let element = self.element { + self.forwardOn(element) } - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() } } } final class AsMaybe: Producer { - fileprivate let _source: Observable + private let source: Observable init(source: Observable) { - _source = source + self.source = source } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = AsMaybeSink(observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/AsSingle.swift b/iOS/RxSwift/Observables/AsSingle.swift index 080aa8e1..b39932f1 100644 --- a/iOS/RxSwift/Observables/AsSingle.swift +++ b/iOS/RxSwift/Observables/AsSingle.swift @@ -6,47 +6,46 @@ // Copyright © 2017 Krunoslav Zaher. All rights reserved. // -fileprivate final class AsSingleSink : Sink, ObserverType { - typealias ElementType = O.E - typealias E = ElementType +private final class AsSingleSink : Sink, ObserverType { + typealias Element = Observer.Element - private var _element: Event? = nil + private var element: Event? - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next: - if _element != nil { - forwardOn(.error(RxError.moreThanOneElement)) - dispose() + if self.element != nil { + self.forwardOn(.error(RxError.moreThanOneElement)) + self.dispose() } - _element = event + self.element = event case .error: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() case .completed: - if let element = _element { - forwardOn(element) - forwardOn(.completed) + if let element = self.element { + self.forwardOn(element) + self.forwardOn(.completed) } else { - forwardOn(.error(RxError.noElements)) + self.forwardOn(.error(RxError.noElements)) } - dispose() + self.dispose() } } } final class AsSingle: Producer { - fileprivate let _source: Observable + private let source: Observable init(source: Observable) { - _source = source + self.source = source } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = AsSingleSink(observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Buffer.swift b/iOS/RxSwift/Observables/Buffer.swift index b8c33ae8..087c4cf5 100644 --- a/iOS/RxSwift/Observables/Buffer.swift +++ b/iOS/RxSwift/Observables/Buffer.swift @@ -21,110 +21,109 @@ extension ObservableType { - returns: An observable sequence of buffers. */ public func buffer(timeSpan: RxTimeInterval, count: Int, scheduler: SchedulerType) - -> Observable<[E]> { - return BufferTimeCount(source: self.asObservable(), timeSpan: timeSpan, count: count, scheduler: scheduler) + -> Observable<[Element]> { + BufferTimeCount(source: self.asObservable(), timeSpan: timeSpan, count: count, scheduler: scheduler) } } -final fileprivate class BufferTimeCount : Producer<[Element]> { +final private class BufferTimeCount: Producer<[Element]> { - fileprivate let _timeSpan: RxTimeInterval - fileprivate let _count: Int - fileprivate let _scheduler: SchedulerType - fileprivate let _source: Observable + fileprivate let timeSpan: RxTimeInterval + fileprivate let count: Int + fileprivate let scheduler: SchedulerType + fileprivate let source: Observable init(source: Observable, timeSpan: RxTimeInterval, count: Int, scheduler: SchedulerType) { - _source = source - _timeSpan = timeSpan - _count = count - _scheduler = scheduler + self.source = source + self.timeSpan = timeSpan + self.count = count + self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == [Element] { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == [Element] { let sink = BufferTimeCountSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) } } -final fileprivate class BufferTimeCountSink - : Sink +final private class BufferTimeCountSink + : Sink , LockOwnerType , ObserverType - , SynchronizedOnType where O.E == [Element] { + , SynchronizedOnType where Observer.Element == [Element] { typealias Parent = BufferTimeCount - typealias E = Element - private let _parent: Parent + private let parent: Parent - let _lock = RecursiveLock() + let lock = RecursiveLock() // state - private let _timerD = SerialDisposable() - private var _buffer = [Element]() - private var _windowID = 0 + private let timerD = SerialDisposable() + private var buffer = [Element]() + private var windowID = 0 - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - createTimer(_windowID) - return Disposables.create(_timerD, _parent._source.subscribe(self)) + self.createTimer(self.windowID) + return Disposables.create(timerD, parent.source.subscribe(self)) } func startNewWindowAndSendCurrentOne() { - _windowID = _windowID &+ 1 - let windowID = _windowID + self.windowID = self.windowID &+ 1 + let windowID = self.windowID - let buffer = _buffer - _buffer = [] - forwardOn(.next(buffer)) + let buffer = self.buffer + self.buffer = [] + self.forwardOn(.next(buffer)) - createTimer(windowID) + self.createTimer(windowID) } - func on(_ event: Event) { - synchronizedOn(event) + func on(_ event: Event) { + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case .next(let element): - _buffer.append(element) + self.buffer.append(element) - if _buffer.count == _parent._count { - startNewWindowAndSendCurrentOne() + if self.buffer.count == self.parent.count { + self.startNewWindowAndSendCurrentOne() } case .error(let error): - _buffer = [] - forwardOn(.error(error)) - dispose() + self.buffer = [] + self.forwardOn(.error(error)) + self.dispose() case .completed: - forwardOn(.next(_buffer)) - forwardOn(.completed) - dispose() + self.forwardOn(.next(self.buffer)) + self.forwardOn(.completed) + self.dispose() } } func createTimer(_ windowID: Int) { - if _timerD.isDisposed { + if self.timerD.isDisposed { return } - if _windowID != windowID { + if self.windowID != windowID { return } let nextTimer = SingleAssignmentDisposable() - _timerD.disposable = nextTimer + self.timerD.disposable = nextTimer - let disposable = _parent._scheduler.scheduleRelative(windowID, dueTime: _parent._timeSpan) { previousWindowID in - self._lock.performLocked { - if previousWindowID != self._windowID { + let disposable = self.parent.scheduler.scheduleRelative(windowID, dueTime: self.parent.timeSpan) { previousWindowID in + self.lock.performLocked { + if previousWindowID != self.windowID { return } diff --git a/iOS/RxSwift/Observables/Catch.swift b/iOS/RxSwift/Observables/Catch.swift index 187eb8a9..2efd6606 100644 --- a/iOS/RxSwift/Observables/Catch.swift +++ b/iOS/RxSwift/Observables/Catch.swift @@ -16,9 +16,23 @@ extension ObservableType { - parameter handler: Error handler function, producing another observable sequence. - returns: An observable sequence containing the source sequence's elements, followed by the elements produced by the handler's resulting observable sequence in case an error occurred. */ - public func catchError(_ handler: @escaping (Swift.Error) throws -> Observable) - -> Observable { - return Catch(source: asObservable(), handler: handler) + public func `catch`(_ handler: @escaping (Swift.Error) throws -> Observable) + -> Observable { + Catch(source: self.asObservable(), handler: handler) + } + + /** + Continues an observable sequence that is terminated by an error with the observable sequence produced by the handler. + + - seealso: [catch operator on reactivex.io](http://reactivex.io/documentation/operators/catch.html) + + - parameter handler: Error handler function, producing another observable sequence. + - returns: An observable sequence containing the source sequence's elements, followed by the elements produced by the handler's resulting observable sequence in case an error occurred. + */ + @available(*, deprecated, renamed: "catch(_:)") + public func catchError(_ handler: @escaping (Swift.Error) throws -> Observable) + -> Observable { + `catch`(handler) } /** @@ -29,11 +43,24 @@ extension ObservableType { - parameter element: Last element in an observable sequence in case error occurs. - returns: An observable sequence containing the source sequence's elements, followed by the `element` in case an error occurred. */ - public func catchErrorJustReturn(_ element: E) - -> Observable { - return Catch(source: asObservable(), handler: { _ in Observable.just(element) }) + public func catchAndReturn(_ element: Element) + -> Observable { + Catch(source: self.asObservable(), handler: { _ in Observable.just(element) }) + } + + /** + Continues an observable sequence that is terminated by an error with a single element. + + - seealso: [catch operator on reactivex.io](http://reactivex.io/documentation/operators/catch.html) + + - parameter element: Last element in an observable sequence in case error occurs. + - returns: An observable sequence containing the source sequence's elements, followed by the `element` in case an error occurred. + */ + @available(*, deprecated, renamed: "catchAndReturn(_:)") + public func catchErrorJustReturn(_ element: Element) + -> Observable { + catchAndReturn(element) } - } extension ObservableType { @@ -44,9 +71,22 @@ extension ObservableType { - returns: An observable sequence containing elements from consecutive source sequences until a source sequence terminates successfully. */ - public static func catchError(_ sequence: S) -> Observable - where S.Iterator.Element == Observable { - return CatchSequence(sources: sequence) + @available(*, deprecated, renamed: "catch(onSuccess:onFailure:onDisposed:)") + public static func catchError(_ sequence: Sequence) -> Observable + where Sequence.Element == Observable { + `catch`(sequence: sequence) + } + + /** + Continues an observable sequence that is terminated by an error with the next observable sequence. + + - seealso: [catch operator on reactivex.io](http://reactivex.io/documentation/operators/catch.html) + + - returns: An observable sequence containing elements from consecutive source sequences until a source sequence terminates successfully. + */ + public static func `catch`(sequence: Sequence) -> Observable + where Sequence.Element == Observable { + CatchSequence(sources: sequence) } } @@ -61,8 +101,8 @@ extension ObservableType { - returns: Observable sequence to repeat until it successfully terminates. */ - public func retry() -> Observable { - return CatchSequence(sources: InfiniteSequence(repeatedValue: self.asObservable())) + public func retry() -> Observable { + CatchSequence(sources: InfiniteSequence(repeatedValue: self.asObservable())) } /** @@ -76,90 +116,90 @@ extension ObservableType { - returns: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully. */ public func retry(_ maxAttemptCount: Int) - -> Observable { - return CatchSequence(sources: Swift.repeatElement(self.asObservable(), count: maxAttemptCount)) + -> Observable { + CatchSequence(sources: Swift.repeatElement(self.asObservable(), count: maxAttemptCount)) } } // catch with callback -final fileprivate class CatchSinkProxy : ObserverType { - typealias E = O.E - typealias Parent = CatchSink +final private class CatchSinkProxy: ObserverType { + typealias Element = Observer.Element + typealias Parent = CatchSink - private let _parent: Parent + private let parent: Parent init(parent: Parent) { - _parent = parent + self.parent = parent } - func on(_ event: Event) { - _parent.forwardOn(event) + func on(_ event: Event) { + self.parent.forwardOn(event) switch event { case .next: break case .error, .completed: - _parent.dispose() + self.parent.dispose() } } } -final fileprivate class CatchSink : Sink, ObserverType { - typealias E = O.E - typealias Parent = Catch +final private class CatchSink: Sink, ObserverType { + typealias Element = Observer.Element + typealias Parent = Catch - private let _parent: Parent - private let _subscription = SerialDisposable() + private let parent: Parent + private let subscription = SerialDisposable() - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func run() -> Disposable { let d1 = SingleAssignmentDisposable() - _subscription.disposable = d1 - d1.setDisposable(_parent._source.subscribe(self)) + self.subscription.disposable = d1 + d1.setDisposable(self.parent.source.subscribe(self)) - return _subscription + return self.subscription } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next: - forwardOn(event) + self.forwardOn(event) case .completed: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() case .error(let error): do { - let catchSequence = try _parent._handler(error) + let catchSequence = try self.parent.handler(error) let observer = CatchSinkProxy(parent: self) - _subscription.disposable = catchSequence.subscribe(observer) + self.subscription.disposable = catchSequence.subscribe(observer) } catch let e { - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() } } } } -final fileprivate class Catch : Producer { +final private class Catch: Producer { typealias Handler = (Swift.Error) throws -> Observable - fileprivate let _source: Observable - fileprivate let _handler: Handler + fileprivate let source: Observable + fileprivate let handler: Handler init(source: Observable, handler: @escaping Handler) { - _source = source - _handler = handler + self.source = source + self.handler = handler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = CatchSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -168,48 +208,48 @@ final fileprivate class Catch : Producer { // catch enumerable -final fileprivate class CatchSequenceSink - : TailRecursiveSink - , ObserverType where S.Iterator.Element : ObservableConvertibleType, S.Iterator.Element.E == O.E { - typealias Element = O.E - typealias Parent = CatchSequence - - private var _lastError: Swift.Error? +final private class CatchSequenceSink + : TailRecursiveSink + , ObserverType where Sequence.Element: ObservableConvertibleType, Sequence.Element.Element == Observer.Element { + typealias Element = Observer.Element + typealias Parent = CatchSequence + + private var lastError: Swift.Error? - override init(observer: O, cancel: Cancelable) { + override init(observer: Observer, cancel: Cancelable) { super.init(observer: observer, cancel: cancel) } func on(_ event: Event) { switch event { case .next: - forwardOn(event) + self.forwardOn(event) case .error(let error): - _lastError = error - schedule(.moveNext) + self.lastError = error + self.schedule(.moveNext) case .completed: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() } } - override func subscribeToNext(_ source: Observable) -> Disposable { - return source.subscribe(self) + override func subscribeToNext(_ source: Observable) -> Disposable { + source.subscribe(self) } override func done() { - if let lastError = _lastError { - forwardOn(.error(lastError)) + if let lastError = self.lastError { + self.forwardOn(.error(lastError)) } else { - forwardOn(.completed) + self.forwardOn(.completed) } self.dispose() } override func extract(_ observable: Observable) -> SequenceGenerator? { - if let onError = observable as? CatchSequence { + if let onError = observable as? CatchSequence { return (onError.sources.makeIterator(), nil) } else { @@ -218,17 +258,17 @@ final fileprivate class CatchSequenceSink } } -final fileprivate class CatchSequence : Producer where S.Iterator.Element : ObservableConvertibleType { - typealias Element = S.Iterator.Element.E +final private class CatchSequence: Producer where Sequence.Element: ObservableConvertibleType { + typealias Element = Sequence.Element.Element - let sources: S + let sources: Sequence - init(sources: S) { + init(sources: Sequence) { self.sources = sources } - - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - let sink = CatchSequenceSink(observer: observer, cancel: cancel) + + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = CatchSequenceSink(observer: observer, cancel: cancel) let subscription = sink.run((self.sources.makeIterator(), nil)) return (sink: sink, subscription: subscription) } diff --git a/iOS/RxSwift/Observables/CombineLatest+Collection.swift b/iOS/RxSwift/Observables/CombineLatest+Collection.swift index 45e01737..b56d050b 100644 --- a/iOS/RxSwift/Observables/CombineLatest+Collection.swift +++ b/iOS/RxSwift/Observables/CombineLatest+Collection.swift @@ -15,9 +15,9 @@ extension ObservableType { - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ - public static func combineLatest(_ collection: C, _ resultSelector: @escaping ([C.Iterator.Element.E]) throws -> E) -> Observable - where C.Iterator.Element: ObservableType { - return CombineLatestCollectionType(sources: collection, resultSelector: resultSelector) + public static func combineLatest(_ collection: Collection, resultSelector: @escaping ([Collection.Element.Element]) throws -> Element) -> Observable + where Collection.Element: ObservableType { + CombineLatestCollectionType(sources: collection, resultSelector: resultSelector) } /** @@ -27,129 +27,137 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources. */ - public static func combineLatest(_ collection: C) -> Observable<[E]> - where C.Iterator.Element: ObservableType, C.Iterator.Element.E == E { - return CombineLatestCollectionType(sources: collection, resultSelector: { $0 }) + public static func combineLatest(_ collection: Collection) -> Observable<[Element]> + where Collection.Element: ObservableType, Collection.Element.Element == Element { + CombineLatestCollectionType(sources: collection, resultSelector: { $0 }) } } -final fileprivate class CombineLatestCollectionTypeSink - : Sink where C.Iterator.Element : ObservableConvertibleType { - typealias R = O.E - typealias Parent = CombineLatestCollectionType - typealias SourceElement = C.Iterator.Element.E +final class CombineLatestCollectionTypeSink + : Sink where Collection.Element: ObservableConvertibleType { + typealias Result = Observer.Element + typealias Parent = CombineLatestCollectionType + typealias SourceElement = Collection.Element.Element - let _parent: Parent + let parent: Parent - let _lock = RecursiveLock() + let lock = RecursiveLock() // state - var _numberOfValues = 0 - var _values: [SourceElement?] - var _isDone: [Bool] - var _numberOfDone = 0 - var _subscriptions: [SingleAssignmentDisposable] + var numberOfValues = 0 + var values: [SourceElement?] + var isDone: [Bool] + var numberOfDone = 0 + var subscriptions: [SingleAssignmentDisposable] - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - _values = [SourceElement?](repeating: nil, count: parent._count) - _isDone = [Bool](repeating: false, count: parent._count) - _subscriptions = Array() - _subscriptions.reserveCapacity(parent._count) + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + self.values = [SourceElement?](repeating: nil, count: parent.count) + self.isDone = [Bool](repeating: false, count: parent.count) + self.subscriptions = [SingleAssignmentDisposable]() + self.subscriptions.reserveCapacity(parent.count) - for _ in 0 ..< parent._count { - _subscriptions.append(SingleAssignmentDisposable()) + for _ in 0 ..< parent.count { + self.subscriptions.append(SingleAssignmentDisposable()) } super.init(observer: observer, cancel: cancel) } func on(_ event: Event, atIndex: Int) { - _lock.lock(); defer { _lock.unlock() } // { - switch event { - case .next(let element): - if _values[atIndex] == nil { - _numberOfValues += 1 - } - - _values[atIndex] = element - - if _numberOfValues < _parent._count { - let numberOfOthersThatAreDone = self._numberOfDone - (_isDone[atIndex] ? 1 : 0) - if numberOfOthersThatAreDone == self._parent._count - 1 { - forwardOn(.completed) - dispose() - } - return - } - - do { - let result = try _parent._resultSelector(_values.map { $0! }) - forwardOn(.next(result)) - } - catch let error { - forwardOn(.error(error)) - dispose() - } - - case .error(let error): - forwardOn(.error(error)) - dispose() - case .completed: - if _isDone[atIndex] { - return - } - - _isDone[atIndex] = true - _numberOfDone += 1 - - if _numberOfDone == self._parent._count { - forwardOn(.completed) - dispose() - } - else { - _subscriptions[atIndex].dispose() + self.lock.lock(); defer { self.lock.unlock() } + switch event { + case .next(let element): + if self.values[atIndex] == nil { + self.numberOfValues += 1 + } + + self.values[atIndex] = element + + if self.numberOfValues < self.parent.count { + let numberOfOthersThatAreDone = self.numberOfDone - (self.isDone[atIndex] ? 1 : 0) + if numberOfOthersThatAreDone == self.parent.count - 1 { + self.forwardOn(.completed) + self.dispose() } + return + } + + do { + let result = try self.parent.resultSelector(self.values.map { $0! }) + self.forwardOn(.next(result)) } - // } + catch let error { + self.forwardOn(.error(error)) + self.dispose() + } + + case .error(let error): + self.forwardOn(.error(error)) + self.dispose() + case .completed: + if self.isDone[atIndex] { + return + } + + self.isDone[atIndex] = true + self.numberOfDone += 1 + + if self.numberOfDone == self.parent.count { + self.forwardOn(.completed) + self.dispose() + } + else { + self.subscriptions[atIndex].dispose() + } + } } func run() -> Disposable { var j = 0 - for i in _parent._sources { + for i in self.parent.sources { let index = j let source = i.asObservable() let disposable = source.subscribe(AnyObserver { event in self.on(event, atIndex: index) }) - _subscriptions[j].setDisposable(disposable) + self.subscriptions[j].setDisposable(disposable) j += 1 } - if _parent._sources.isEmpty { - self.forwardOn(.completed) + if self.parent.sources.isEmpty { + do { + let result = try self.parent.resultSelector([]) + self.forwardOn(.next(result)) + self.forwardOn(.completed) + self.dispose() + } + catch let error { + self.forwardOn(.error(error)) + self.dispose() + } } - return Disposables.create(_subscriptions) + return Disposables.create(subscriptions) } } -final fileprivate class CombineLatestCollectionType : Producer where C.Iterator.Element : ObservableConvertibleType { - typealias ResultSelector = ([C.Iterator.Element.E]) throws -> R +final class CombineLatestCollectionType: Producer where Collection.Element: ObservableConvertibleType { + typealias ResultSelector = ([Collection.Element.Element]) throws -> Result - let _sources: C - let _resultSelector: ResultSelector - let _count: Int + let sources: Collection + let resultSelector: ResultSelector + let count: Int - init(sources: C, resultSelector: @escaping ResultSelector) { - _sources = sources - _resultSelector = resultSelector - _count = Int(Int64(self._sources.count)) + init(sources: Collection, resultSelector: @escaping ResultSelector) { + self.sources = sources + self.resultSelector = resultSelector + self.count = self.sources.count } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = CombineLatestCollectionTypeSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/CombineLatest+arity.swift b/iOS/RxSwift/Observables/CombineLatest+arity.swift index aad22554..e69bbab4 100644 --- a/iOS/RxSwift/Observables/CombineLatest+arity.swift +++ b/iOS/RxSwift/Observables/CombineLatest+arity.swift @@ -21,8 +21,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func combineLatest - (_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.E, O2.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.Element, O2.Element) throws -> Element) + -> Observable { return CombineLatest2( source1: source1.asObservable(), source2: source2.asObservable(), resultSelector: resultSelector @@ -30,7 +30,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. @@ -40,7 +40,7 @@ extension ObservableType where E == Any { */ public static func combineLatest (_ source1: O1, _ source2: O2) - -> Observable<(O1.E, O2.E)> { + -> Observable<(O1.Element, O2.Element)> { return CombineLatest2( source1: source1.asObservable(), source2: source2.asObservable(), resultSelector: { ($0, $1) } @@ -48,17 +48,17 @@ extension ObservableType where E == Any { } } -final class CombineLatestSink2_ : CombineLatestSink { - typealias R = O.E - typealias Parent = CombineLatest2 +final class CombineLatestSink2_ : CombineLatestSink { + typealias Result = Observer.Element + typealias Parent = CombineLatest2 - let _parent: Parent + let parent: Parent - var _latestElement1: E1! = nil - var _latestElement2: E2! = nil + var latestElement1: E1! = nil + var latestElement2: E2! = nil - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 2, observer: observer, cancel: cancel) } @@ -66,11 +66,11 @@ final class CombineLatestSink2_ : CombineLatestSink let subscription1 = SingleAssignmentDisposable() let subscription2 = SingleAssignmentDisposable() - let observer1 = CombineLatestObserver(lock: _lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self._latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: _lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self._latestElement2 = e }, this: subscription2) + let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) + let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) - subscription1.setDisposable(_parent._source1.subscribe(observer1)) - subscription2.setDisposable(_parent._source2.subscribe(observer2)) + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) return Disposables.create([ subscription1, @@ -78,27 +78,27 @@ final class CombineLatestSink2_ : CombineLatestSink ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_latestElement1, _latestElement2) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.latestElement1, self.latestElement2) } } -final class CombineLatest2 : Producer { - typealias ResultSelector = (E1, E2) throws -> R +final class CombineLatest2 : Producer { + typealias ResultSelector = (E1, E2) throws -> Result - let _source1: Observable - let _source2: Observable + let source1: Observable + let source2: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, resultSelector: @escaping ResultSelector) { - _source1 = source1 - _source2 = source2 + self.source1 = source1 + self.source2 = source2 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = CombineLatestSink2_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -119,8 +119,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.E, O2.E, O3.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.Element, O2.Element, O3.Element) throws -> Element) + -> Observable { return CombineLatest3( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), resultSelector: resultSelector @@ -128,7 +128,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. @@ -138,7 +138,7 @@ extension ObservableType where E == Any { */ public static func combineLatest (_ source1: O1, _ source2: O2, _ source3: O3) - -> Observable<(O1.E, O2.E, O3.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element)> { return CombineLatest3( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), resultSelector: { ($0, $1, $2) } @@ -146,18 +146,18 @@ extension ObservableType where E == Any { } } -final class CombineLatestSink3_ : CombineLatestSink { - typealias R = O.E - typealias Parent = CombineLatest3 +final class CombineLatestSink3_ : CombineLatestSink { + typealias Result = Observer.Element + typealias Parent = CombineLatest3 - let _parent: Parent + let parent: Parent - var _latestElement1: E1! = nil - var _latestElement2: E2! = nil - var _latestElement3: E3! = nil + var latestElement1: E1! = nil + var latestElement2: E2! = nil + var latestElement3: E3! = nil - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 3, observer: observer, cancel: cancel) } @@ -166,13 +166,13 @@ final class CombineLatestSink3_ : CombineLatestSink let subscription2 = SingleAssignmentDisposable() let subscription3 = SingleAssignmentDisposable() - let observer1 = CombineLatestObserver(lock: _lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self._latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: _lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self._latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: _lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self._latestElement3 = e }, this: subscription3) + let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) + let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) + let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) - subscription1.setDisposable(_parent._source1.subscribe(observer1)) - subscription2.setDisposable(_parent._source2.subscribe(observer2)) - subscription3.setDisposable(_parent._source3.subscribe(observer3)) + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) return Disposables.create([ subscription1, @@ -181,29 +181,29 @@ final class CombineLatestSink3_ : CombineLatestSink ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_latestElement1, _latestElement2, _latestElement3) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3) } } -final class CombineLatest3 : Producer { - typealias ResultSelector = (E1, E2, E3) throws -> R +final class CombineLatest3 : Producer { + typealias ResultSelector = (E1, E2, E3) throws -> Result - let _source1: Observable - let _source2: Observable - let _source3: Observable + let source1: Observable + let source2: Observable + let source3: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, resultSelector: @escaping ResultSelector) { - _source1 = source1 - _source2 = source2 - _source3 = source3 + self.source1 = source1 + self.source2 = source2 + self.source3 = source3 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = CombineLatestSink3_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -224,8 +224,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, resultSelector: @escaping (O1.E, O2.E, O3.E, O4.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element) throws -> Element) + -> Observable { return CombineLatest4( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), resultSelector: resultSelector @@ -233,7 +233,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. @@ -243,7 +243,7 @@ extension ObservableType where E == Any { */ public static func combineLatest (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4) - -> Observable<(O1.E, O2.E, O3.E, O4.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element)> { return CombineLatest4( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), resultSelector: { ($0, $1, $2, $3) } @@ -251,19 +251,19 @@ extension ObservableType where E == Any { } } -final class CombineLatestSink4_ : CombineLatestSink { - typealias R = O.E - typealias Parent = CombineLatest4 +final class CombineLatestSink4_ : CombineLatestSink { + typealias Result = Observer.Element + typealias Parent = CombineLatest4 - let _parent: Parent + let parent: Parent - var _latestElement1: E1! = nil - var _latestElement2: E2! = nil - var _latestElement3: E3! = nil - var _latestElement4: E4! = nil + var latestElement1: E1! = nil + var latestElement2: E2! = nil + var latestElement3: E3! = nil + var latestElement4: E4! = nil - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 4, observer: observer, cancel: cancel) } @@ -273,15 +273,15 @@ final class CombineLatestSink4_ : CombineLatest let subscription3 = SingleAssignmentDisposable() let subscription4 = SingleAssignmentDisposable() - let observer1 = CombineLatestObserver(lock: _lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self._latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: _lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self._latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: _lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self._latestElement3 = e }, this: subscription3) - let observer4 = CombineLatestObserver(lock: _lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self._latestElement4 = e }, this: subscription4) + let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) + let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) + let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) + let observer4 = CombineLatestObserver(lock: self.lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self.latestElement4 = e }, this: subscription4) - subscription1.setDisposable(_parent._source1.subscribe(observer1)) - subscription2.setDisposable(_parent._source2.subscribe(observer2)) - subscription3.setDisposable(_parent._source3.subscribe(observer3)) - subscription4.setDisposable(_parent._source4.subscribe(observer4)) + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) + subscription4.setDisposable(self.parent.source4.subscribe(observer4)) return Disposables.create([ subscription1, @@ -291,31 +291,31 @@ final class CombineLatestSink4_ : CombineLatest ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_latestElement1, _latestElement2, _latestElement3, _latestElement4) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3, self.latestElement4) } } -final class CombineLatest4 : Producer { - typealias ResultSelector = (E1, E2, E3, E4) throws -> R +final class CombineLatest4 : Producer { + typealias ResultSelector = (E1, E2, E3, E4) throws -> Result - let _source1: Observable - let _source2: Observable - let _source3: Observable - let _source4: Observable + let source1: Observable + let source2: Observable + let source3: Observable + let source4: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, resultSelector: @escaping ResultSelector) { - _source1 = source1 - _source2 = source2 - _source3 = source3 - _source4 = source4 + self.source1 = source1 + self.source2 = source2 + self.source3 = source3 + self.source4 = source4 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = CombineLatestSink4_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -336,8 +336,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, resultSelector: @escaping (O1.E, O2.E, O3.E, O4.E, O5.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element) throws -> Element) + -> Observable { return CombineLatest5( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), resultSelector: resultSelector @@ -345,7 +345,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. @@ -355,7 +355,7 @@ extension ObservableType where E == Any { */ public static func combineLatest (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5) - -> Observable<(O1.E, O2.E, O3.E, O4.E, O5.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element)> { return CombineLatest5( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), resultSelector: { ($0, $1, $2, $3, $4) } @@ -363,20 +363,20 @@ extension ObservableType where E == Any { } } -final class CombineLatestSink5_ : CombineLatestSink { - typealias R = O.E - typealias Parent = CombineLatest5 +final class CombineLatestSink5_ : CombineLatestSink { + typealias Result = Observer.Element + typealias Parent = CombineLatest5 - let _parent: Parent + let parent: Parent - var _latestElement1: E1! = nil - var _latestElement2: E2! = nil - var _latestElement3: E3! = nil - var _latestElement4: E4! = nil - var _latestElement5: E5! = nil + var latestElement1: E1! = nil + var latestElement2: E2! = nil + var latestElement3: E3! = nil + var latestElement4: E4! = nil + var latestElement5: E5! = nil - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 5, observer: observer, cancel: cancel) } @@ -387,17 +387,17 @@ final class CombineLatestSink5_ : CombineLa let subscription4 = SingleAssignmentDisposable() let subscription5 = SingleAssignmentDisposable() - let observer1 = CombineLatestObserver(lock: _lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self._latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: _lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self._latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: _lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self._latestElement3 = e }, this: subscription3) - let observer4 = CombineLatestObserver(lock: _lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self._latestElement4 = e }, this: subscription4) - let observer5 = CombineLatestObserver(lock: _lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self._latestElement5 = e }, this: subscription5) + let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) + let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) + let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) + let observer4 = CombineLatestObserver(lock: self.lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self.latestElement4 = e }, this: subscription4) + let observer5 = CombineLatestObserver(lock: self.lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self.latestElement5 = e }, this: subscription5) - subscription1.setDisposable(_parent._source1.subscribe(observer1)) - subscription2.setDisposable(_parent._source2.subscribe(observer2)) - subscription3.setDisposable(_parent._source3.subscribe(observer3)) - subscription4.setDisposable(_parent._source4.subscribe(observer4)) - subscription5.setDisposable(_parent._source5.subscribe(observer5)) + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) + subscription4.setDisposable(self.parent.source4.subscribe(observer4)) + subscription5.setDisposable(self.parent.source5.subscribe(observer5)) return Disposables.create([ subscription1, @@ -408,33 +408,33 @@ final class CombineLatestSink5_ : CombineLa ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_latestElement1, _latestElement2, _latestElement3, _latestElement4, _latestElement5) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3, self.latestElement4, self.latestElement5) } } -final class CombineLatest5 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5) throws -> R +final class CombineLatest5 : Producer { + typealias ResultSelector = (E1, E2, E3, E4, E5) throws -> Result - let _source1: Observable - let _source2: Observable - let _source3: Observable - let _source4: Observable - let _source5: Observable + let source1: Observable + let source2: Observable + let source3: Observable + let source4: Observable + let source5: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, resultSelector: @escaping ResultSelector) { - _source1 = source1 - _source2 = source2 - _source3 = source3 - _source4 = source4 - _source5 = source5 + self.source1 = source1 + self.source2 = source2 + self.source3 = source3 + self.source4 = source4 + self.source5 = source5 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = CombineLatestSink5_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -455,8 +455,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, resultSelector: @escaping (O1.E, O2.E, O3.E, O4.E, O5.E, O6.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element) throws -> Element) + -> Observable { return CombineLatest6( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), resultSelector: resultSelector @@ -464,7 +464,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. @@ -474,7 +474,7 @@ extension ObservableType where E == Any { */ public static func combineLatest (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6) - -> Observable<(O1.E, O2.E, O3.E, O4.E, O5.E, O6.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element)> { return CombineLatest6( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), resultSelector: { ($0, $1, $2, $3, $4, $5) } @@ -482,21 +482,21 @@ extension ObservableType where E == Any { } } -final class CombineLatestSink6_ : CombineLatestSink { - typealias R = O.E - typealias Parent = CombineLatest6 +final class CombineLatestSink6_ : CombineLatestSink { + typealias Result = Observer.Element + typealias Parent = CombineLatest6 - let _parent: Parent + let parent: Parent - var _latestElement1: E1! = nil - var _latestElement2: E2! = nil - var _latestElement3: E3! = nil - var _latestElement4: E4! = nil - var _latestElement5: E5! = nil - var _latestElement6: E6! = nil + var latestElement1: E1! = nil + var latestElement2: E2! = nil + var latestElement3: E3! = nil + var latestElement4: E4! = nil + var latestElement5: E5! = nil + var latestElement6: E6! = nil - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 6, observer: observer, cancel: cancel) } @@ -508,19 +508,19 @@ final class CombineLatestSink6_ : Combi let subscription5 = SingleAssignmentDisposable() let subscription6 = SingleAssignmentDisposable() - let observer1 = CombineLatestObserver(lock: _lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self._latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: _lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self._latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: _lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self._latestElement3 = e }, this: subscription3) - let observer4 = CombineLatestObserver(lock: _lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self._latestElement4 = e }, this: subscription4) - let observer5 = CombineLatestObserver(lock: _lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self._latestElement5 = e }, this: subscription5) - let observer6 = CombineLatestObserver(lock: _lock, parent: self, index: 5, setLatestValue: { (e: E6) -> Void in self._latestElement6 = e }, this: subscription6) + let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) + let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) + let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) + let observer4 = CombineLatestObserver(lock: self.lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self.latestElement4 = e }, this: subscription4) + let observer5 = CombineLatestObserver(lock: self.lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self.latestElement5 = e }, this: subscription5) + let observer6 = CombineLatestObserver(lock: self.lock, parent: self, index: 5, setLatestValue: { (e: E6) -> Void in self.latestElement6 = e }, this: subscription6) - subscription1.setDisposable(_parent._source1.subscribe(observer1)) - subscription2.setDisposable(_parent._source2.subscribe(observer2)) - subscription3.setDisposable(_parent._source3.subscribe(observer3)) - subscription4.setDisposable(_parent._source4.subscribe(observer4)) - subscription5.setDisposable(_parent._source5.subscribe(observer5)) - subscription6.setDisposable(_parent._source6.subscribe(observer6)) + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) + subscription4.setDisposable(self.parent.source4.subscribe(observer4)) + subscription5.setDisposable(self.parent.source5.subscribe(observer5)) + subscription6.setDisposable(self.parent.source6.subscribe(observer6)) return Disposables.create([ subscription1, @@ -532,35 +532,35 @@ final class CombineLatestSink6_ : Combi ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_latestElement1, _latestElement2, _latestElement3, _latestElement4, _latestElement5, _latestElement6) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3, self.latestElement4, self.latestElement5, self.latestElement6) } } -final class CombineLatest6 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6) throws -> R +final class CombineLatest6 : Producer { + typealias ResultSelector = (E1, E2, E3, E4, E5, E6) throws -> Result - let _source1: Observable - let _source2: Observable - let _source3: Observable - let _source4: Observable - let _source5: Observable - let _source6: Observable + let source1: Observable + let source2: Observable + let source3: Observable + let source4: Observable + let source5: Observable + let source6: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, resultSelector: @escaping ResultSelector) { - _source1 = source1 - _source2 = source2 - _source3 = source3 - _source4 = source4 - _source5 = source5 - _source6 = source6 + self.source1 = source1 + self.source2 = source2 + self.source3 = source3 + self.source4 = source4 + self.source5 = source5 + self.source6 = source6 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = CombineLatestSink6_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -581,8 +581,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, resultSelector: @escaping (O1.E, O2.E, O3.E, O4.E, O5.E, O6.E, O7.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element) throws -> Element) + -> Observable { return CombineLatest7( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), resultSelector: resultSelector @@ -590,7 +590,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. @@ -600,7 +600,7 @@ extension ObservableType where E == Any { */ public static func combineLatest (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7) - -> Observable<(O1.E, O2.E, O3.E, O4.E, O5.E, O6.E, O7.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element)> { return CombineLatest7( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), resultSelector: { ($0, $1, $2, $3, $4, $5, $6) } @@ -608,22 +608,22 @@ extension ObservableType where E == Any { } } -final class CombineLatestSink7_ : CombineLatestSink { - typealias R = O.E - typealias Parent = CombineLatest7 +final class CombineLatestSink7_ : CombineLatestSink { + typealias Result = Observer.Element + typealias Parent = CombineLatest7 - let _parent: Parent + let parent: Parent - var _latestElement1: E1! = nil - var _latestElement2: E2! = nil - var _latestElement3: E3! = nil - var _latestElement4: E4! = nil - var _latestElement5: E5! = nil - var _latestElement6: E6! = nil - var _latestElement7: E7! = nil + var latestElement1: E1! = nil + var latestElement2: E2! = nil + var latestElement3: E3! = nil + var latestElement4: E4! = nil + var latestElement5: E5! = nil + var latestElement6: E6! = nil + var latestElement7: E7! = nil - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 7, observer: observer, cancel: cancel) } @@ -636,21 +636,21 @@ final class CombineLatestSink7_ : C let subscription6 = SingleAssignmentDisposable() let subscription7 = SingleAssignmentDisposable() - let observer1 = CombineLatestObserver(lock: _lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self._latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: _lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self._latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: _lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self._latestElement3 = e }, this: subscription3) - let observer4 = CombineLatestObserver(lock: _lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self._latestElement4 = e }, this: subscription4) - let observer5 = CombineLatestObserver(lock: _lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self._latestElement5 = e }, this: subscription5) - let observer6 = CombineLatestObserver(lock: _lock, parent: self, index: 5, setLatestValue: { (e: E6) -> Void in self._latestElement6 = e }, this: subscription6) - let observer7 = CombineLatestObserver(lock: _lock, parent: self, index: 6, setLatestValue: { (e: E7) -> Void in self._latestElement7 = e }, this: subscription7) - - subscription1.setDisposable(_parent._source1.subscribe(observer1)) - subscription2.setDisposable(_parent._source2.subscribe(observer2)) - subscription3.setDisposable(_parent._source3.subscribe(observer3)) - subscription4.setDisposable(_parent._source4.subscribe(observer4)) - subscription5.setDisposable(_parent._source5.subscribe(observer5)) - subscription6.setDisposable(_parent._source6.subscribe(observer6)) - subscription7.setDisposable(_parent._source7.subscribe(observer7)) + let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) + let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) + let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) + let observer4 = CombineLatestObserver(lock: self.lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self.latestElement4 = e }, this: subscription4) + let observer5 = CombineLatestObserver(lock: self.lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self.latestElement5 = e }, this: subscription5) + let observer6 = CombineLatestObserver(lock: self.lock, parent: self, index: 5, setLatestValue: { (e: E6) -> Void in self.latestElement6 = e }, this: subscription6) + let observer7 = CombineLatestObserver(lock: self.lock, parent: self, index: 6, setLatestValue: { (e: E7) -> Void in self.latestElement7 = e }, this: subscription7) + + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) + subscription4.setDisposable(self.parent.source4.subscribe(observer4)) + subscription5.setDisposable(self.parent.source5.subscribe(observer5)) + subscription6.setDisposable(self.parent.source6.subscribe(observer6)) + subscription7.setDisposable(self.parent.source7.subscribe(observer7)) return Disposables.create([ subscription1, @@ -663,37 +663,37 @@ final class CombineLatestSink7_ : C ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_latestElement1, _latestElement2, _latestElement3, _latestElement4, _latestElement5, _latestElement6, _latestElement7) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3, self.latestElement4, self.latestElement5, self.latestElement6, self.latestElement7) } } -final class CombineLatest7 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7) throws -> R +final class CombineLatest7 : Producer { + typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7) throws -> Result - let _source1: Observable - let _source2: Observable - let _source3: Observable - let _source4: Observable - let _source5: Observable - let _source6: Observable - let _source7: Observable + let source1: Observable + let source2: Observable + let source3: Observable + let source4: Observable + let source5: Observable + let source6: Observable + let source7: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, source7: Observable, resultSelector: @escaping ResultSelector) { - _source1 = source1 - _source2 = source2 - _source3 = source3 - _source4 = source4 - _source5 = source5 - _source6 = source6 - _source7 = source7 + self.source1 = source1 + self.source2 = source2 + self.source3 = source3 + self.source4 = source4 + self.source5 = source5 + self.source6 = source6 + self.source7 = source7 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = CombineLatestSink7_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -714,8 +714,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8, resultSelector: @escaping (O1.E, O2.E, O3.E, O4.E, O5.E, O6.E, O7.E, O8.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element) throws -> Element) + -> Observable { return CombineLatest8( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), source8: source8.asObservable(), resultSelector: resultSelector @@ -723,7 +723,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. @@ -733,7 +733,7 @@ extension ObservableType where E == Any { */ public static func combineLatest (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8) - -> Observable<(O1.E, O2.E, O3.E, O4.E, O5.E, O6.E, O7.E, O8.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element)> { return CombineLatest8( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), source8: source8.asObservable(), resultSelector: { ($0, $1, $2, $3, $4, $5, $6, $7) } @@ -741,23 +741,23 @@ extension ObservableType where E == Any { } } -final class CombineLatestSink8_ : CombineLatestSink { - typealias R = O.E - typealias Parent = CombineLatest8 +final class CombineLatestSink8_ : CombineLatestSink { + typealias Result = Observer.Element + typealias Parent = CombineLatest8 - let _parent: Parent + let parent: Parent - var _latestElement1: E1! = nil - var _latestElement2: E2! = nil - var _latestElement3: E3! = nil - var _latestElement4: E4! = nil - var _latestElement5: E5! = nil - var _latestElement6: E6! = nil - var _latestElement7: E7! = nil - var _latestElement8: E8! = nil + var latestElement1: E1! = nil + var latestElement2: E2! = nil + var latestElement3: E3! = nil + var latestElement4: E4! = nil + var latestElement5: E5! = nil + var latestElement6: E6! = nil + var latestElement7: E7! = nil + var latestElement8: E8! = nil - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 8, observer: observer, cancel: cancel) } @@ -771,23 +771,23 @@ final class CombineLatestSink8_ let subscription7 = SingleAssignmentDisposable() let subscription8 = SingleAssignmentDisposable() - let observer1 = CombineLatestObserver(lock: _lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self._latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: _lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self._latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: _lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self._latestElement3 = e }, this: subscription3) - let observer4 = CombineLatestObserver(lock: _lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self._latestElement4 = e }, this: subscription4) - let observer5 = CombineLatestObserver(lock: _lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self._latestElement5 = e }, this: subscription5) - let observer6 = CombineLatestObserver(lock: _lock, parent: self, index: 5, setLatestValue: { (e: E6) -> Void in self._latestElement6 = e }, this: subscription6) - let observer7 = CombineLatestObserver(lock: _lock, parent: self, index: 6, setLatestValue: { (e: E7) -> Void in self._latestElement7 = e }, this: subscription7) - let observer8 = CombineLatestObserver(lock: _lock, parent: self, index: 7, setLatestValue: { (e: E8) -> Void in self._latestElement8 = e }, this: subscription8) - - subscription1.setDisposable(_parent._source1.subscribe(observer1)) - subscription2.setDisposable(_parent._source2.subscribe(observer2)) - subscription3.setDisposable(_parent._source3.subscribe(observer3)) - subscription4.setDisposable(_parent._source4.subscribe(observer4)) - subscription5.setDisposable(_parent._source5.subscribe(observer5)) - subscription6.setDisposable(_parent._source6.subscribe(observer6)) - subscription7.setDisposable(_parent._source7.subscribe(observer7)) - subscription8.setDisposable(_parent._source8.subscribe(observer8)) + let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) + let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) + let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) + let observer4 = CombineLatestObserver(lock: self.lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self.latestElement4 = e }, this: subscription4) + let observer5 = CombineLatestObserver(lock: self.lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self.latestElement5 = e }, this: subscription5) + let observer6 = CombineLatestObserver(lock: self.lock, parent: self, index: 5, setLatestValue: { (e: E6) -> Void in self.latestElement6 = e }, this: subscription6) + let observer7 = CombineLatestObserver(lock: self.lock, parent: self, index: 6, setLatestValue: { (e: E7) -> Void in self.latestElement7 = e }, this: subscription7) + let observer8 = CombineLatestObserver(lock: self.lock, parent: self, index: 7, setLatestValue: { (e: E8) -> Void in self.latestElement8 = e }, this: subscription8) + + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) + subscription4.setDisposable(self.parent.source4.subscribe(observer4)) + subscription5.setDisposable(self.parent.source5.subscribe(observer5)) + subscription6.setDisposable(self.parent.source6.subscribe(observer6)) + subscription7.setDisposable(self.parent.source7.subscribe(observer7)) + subscription8.setDisposable(self.parent.source8.subscribe(observer8)) return Disposables.create([ subscription1, @@ -801,39 +801,39 @@ final class CombineLatestSink8_ ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_latestElement1, _latestElement2, _latestElement3, _latestElement4, _latestElement5, _latestElement6, _latestElement7, _latestElement8) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3, self.latestElement4, self.latestElement5, self.latestElement6, self.latestElement7, self.latestElement8) } } -final class CombineLatest8 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7, E8) throws -> R +final class CombineLatest8 : Producer { + typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7, E8) throws -> Result - let _source1: Observable - let _source2: Observable - let _source3: Observable - let _source4: Observable - let _source5: Observable - let _source6: Observable - let _source7: Observable - let _source8: Observable + let source1: Observable + let source2: Observable + let source3: Observable + let source4: Observable + let source5: Observable + let source6: Observable + let source7: Observable + let source8: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, source7: Observable, source8: Observable, resultSelector: @escaping ResultSelector) { - _source1 = source1 - _source2 = source2 - _source3 = source3 - _source4 = source4 - _source5 = source5 - _source6 = source6 - _source7 = source7 - _source8 = source8 + self.source1 = source1 + self.source2 = source2 + self.source3 = source3 + self.source4 = source4 + self.source5 = source5 + self.source6 = source6 + self.source7 = source7 + self.source8 = source8 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = CombineLatestSink8_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/CombineLatest+arity.tt b/iOS/RxSwift/Observables/CombineLatest+arity.tt index 176a067e..86d8e4b9 100644 --- a/iOS/RxSwift/Observables/CombineLatest+arity.tt +++ b/iOS/RxSwift/Observables/CombineLatest+arity.tt @@ -20,8 +20,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func combineLatest<<%= (Array(1...i).map { "O\($0): ObservableType" }).joined(separator: ", ") %>> - (<%= (Array(1...i).map { "_ source\($0): O\($0)" }).joined(separator: ", ") %>, resultSelector: @escaping (<%= (Array(1...i).map { "O\($0).E" }).joined(separator: ", ") %>) throws -> E) - -> Observable { + (<%= (Array(1...i).map { "_ source\($0): O\($0)" }).joined(separator: ", ") %>, resultSelector: @escaping (<%= (Array(1...i).map { "O\($0).Element" }).joined(separator: ", ") %>) throws -> Element) + -> Observable { return CombineLatest<%= i %>( <%= (Array(1...i).map { "source\($0): source\($0).asObservable()" }).joined(separator: ", ") %>, resultSelector: resultSelector @@ -29,7 +29,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. @@ -39,7 +39,7 @@ extension ObservableType where E == Any { */ public static func combineLatest<<%= (Array(1...i).map { "O\($0): ObservableType" }).joined(separator: ", ") %>> (<%= (Array(1...i).map { "_ source\($0): O\($0)" }).joined(separator: ", ") %>) - -> Observable<(<%= (Array(1...i).map { "O\($0).E" }).joined(separator: ", ") %>)> { + -> Observable<(<%= (Array(1...i).map { "O\($0).Element" }).joined(separator: ", ") %>)> { return CombineLatest<%= i %>( <%= (Array(1...i).map { "source\($0): source\($0).asObservable()" }).joined(separator: ", ") %>, resultSelector: { (<%= (Array(0..) } @@ -47,18 +47,18 @@ extension ObservableType where E == Any { } } -final class CombineLatestSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, O: ObserverType> : CombineLatestSink { - typealias R = O.E - typealias Parent = CombineLatest<%= i %><<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, R> +final class CombineLatestSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, Observer: ObserverType> : CombineLatestSink { + typealias Result = Observer.Element + typealias Parent = CombineLatest<%= i %><<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, Result> - let _parent: Parent + let parent: Parent <%= (Array(1...i).map { -" var _latestElement\($0): E\($0)! = nil" +" var latestElement\($0): E\($0)! = nil" }).joined(separator: "\n") %> - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: <%= i %>, observer: observer, cancel: cancel) } @@ -68,11 +68,11 @@ final class CombineLatestSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joine }).joined(separator: "\n") %> <%= (Array(1...i).map { -" let observer\($0) = CombineLatestObserver(lock: _lock, parent: self, index: \($0 - 1), setLatestValue: { (e: E\($0)) -> Void in self._latestElement\($0) = e }, this: subscription\($0))" +" let observer\($0) = CombineLatestObserver(lock: self.lock, parent: self, index: \($0 - 1), setLatestValue: { (e: E\($0)) -> Void in self.latestElement\($0) = e }, this: subscription\($0))" }).joined(separator: "\n") %> <%= (Array(1...i).map { -" subscription\($0).setDisposable(_parent._source\($0).subscribe(observer\($0)))" +" subscription\($0).setDisposable(self.parent.source\($0).subscribe(observer\($0)))" }).joined(separator: "\n") %> return Disposables.create([ @@ -80,29 +80,29 @@ final class CombineLatestSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joine ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(<%= (Array(1...i).map { "_latestElement\($0)" }).joined(separator: ", ") %>) + override func getResult() throws -> Result { + try self.parent.resultSelector(<%= (Array(1...i).map { "self.latestElement\($0)" }).joined(separator: ", ") %>) } } -final class CombineLatest<%= i %><<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, R> : Producer { - typealias ResultSelector = (<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>) throws -> R +final class CombineLatest<%= i %><<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, Result> : Producer { + typealias ResultSelector = (<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>) throws -> Result <%= (Array(1...i).map { -" let _source\($0): Observable" +" let source\($0): Observable" }).joined(separator: "\n") %> - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(<%= (Array(1...i).map { "source\($0): Observable" }).joined(separator: ", ") %>, resultSelector: @escaping ResultSelector) { <%= (Array(1...i).map { -" _source\($0) = source\($0)" +" self.source\($0) = source\($0)" }).joined(separator: "\n") %> - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = CombineLatestSink<%= i %>_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/CombineLatest.swift b/iOS/RxSwift/Observables/CombineLatest.swift index 8c03e8c3..caa02564 100644 --- a/iOS/RxSwift/Observables/CombineLatest.swift +++ b/iOS/RxSwift/Observables/CombineLatest.swift @@ -6,29 +6,29 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -protocol CombineLatestProtocol : class { +protocol CombineLatestProtocol: AnyObject { func next(_ index: Int) func fail(_ error: Swift.Error) func done(_ index: Int) } -class CombineLatestSink - : Sink +class CombineLatestSink + : Sink , CombineLatestProtocol { - typealias Element = O.E + typealias Element = Observer.Element - let _lock = RecursiveLock() + let lock = RecursiveLock() - private let _arity: Int - private var _numberOfValues = 0 - private var _numberOfDone = 0 - private var _hasValue: [Bool] - private var _isDone: [Bool] + private let arity: Int + private var numberOfValues = 0 + private var numberOfDone = 0 + private var hasValue: [Bool] + private var isDone: [Bool] - init(arity: Int, observer: O, cancel: Cancelable) { - _arity = arity - _hasValue = [Bool](repeating: false, count: arity) - _isDone = [Bool](repeating: false, count: arity) + init(arity: Int, observer: Observer, cancel: Cancelable) { + self.arity = arity + self.hasValue = [Bool](repeating: false, count: arity) + self.isDone = [Bool](repeating: false, count: arity) super.init(observer: observer, cancel: cancel) } @@ -38,95 +38,94 @@ class CombineLatestSink } func next(_ index: Int) { - if !_hasValue[index] { - _hasValue[index] = true - _numberOfValues += 1 + if !self.hasValue[index] { + self.hasValue[index] = true + self.numberOfValues += 1 } - if _numberOfValues == _arity { + if self.numberOfValues == self.arity { do { - let result = try getResult() - forwardOn(.next(result)) + let result = try self.getResult() + self.forwardOn(.next(result)) } catch let e { - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() } } else { var allOthersDone = true - for i in 0 ..< _arity { - if i != index && !_isDone[i] { + for i in 0 ..< self.arity { + if i != index && !self.isDone[i] { allOthersDone = false break } } if allOthersDone { - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() } } } func fail(_ error: Swift.Error) { - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() } func done(_ index: Int) { - if _isDone[index] { + if self.isDone[index] { return } - _isDone[index] = true - _numberOfDone += 1 + self.isDone[index] = true + self.numberOfDone += 1 - if _numberOfDone == _arity { - forwardOn(.completed) - dispose() + if self.numberOfDone == self.arity { + self.forwardOn(.completed) + self.dispose() } } } -final class CombineLatestObserver +final class CombineLatestObserver : ObserverType , LockOwnerType , SynchronizedOnType { - typealias Element = ElementType typealias ValueSetter = (Element) -> Void - private let _parent: CombineLatestProtocol + private let parent: CombineLatestProtocol - let _lock: RecursiveLock - private let _index: Int - private let _this: Disposable - private let _setLatestValue: ValueSetter + let lock: RecursiveLock + private let index: Int + private let this: Disposable + private let setLatestValue: ValueSetter init(lock: RecursiveLock, parent: CombineLatestProtocol, index: Int, setLatestValue: @escaping ValueSetter, this: Disposable) { - _lock = lock - _parent = parent - _index = index - _this = this - _setLatestValue = setLatestValue + self.lock = lock + self.parent = parent + self.index = index + self.this = this + self.setLatestValue = setLatestValue } func on(_ event: Event) { - synchronizedOn(event) + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case .next(let value): - _setLatestValue(value) - _parent.next(_index) + self.setLatestValue(value) + self.parent.next(self.index) case .error(let error): - _this.dispose() - _parent.fail(error) + self.this.dispose() + self.parent.fail(error) case .completed: - _this.dispose() - _parent.done(_index) + self.this.dispose() + self.parent.done(self.index) } } } diff --git a/iOS/RxSwift/Observables/CompactMap.swift b/iOS/RxSwift/Observables/CompactMap.swift new file mode 100644 index 00000000..7dbcdfbe --- /dev/null +++ b/iOS/RxSwift/Observables/CompactMap.swift @@ -0,0 +1,76 @@ +// +// CompactMap.swift +// RxSwift +// +// Created by Michael Long on 04/09/2019. +// Copyright © 2015 Krunoslav Zaher. All rights reserved. +// + +extension ObservableType { + + /** + Projects each element of an observable sequence into an optional form and filters all optional results. + + - parameter transform: A transform function to apply to each source element and which returns an element or nil. + - returns: An observable sequence whose elements are the result of filtering the transform function for each element of the source. + + */ + public func compactMap(_ transform: @escaping (Element) throws -> Result?) + -> Observable { + CompactMap(source: self.asObservable(), transform: transform) + } +} + +final private class CompactMapSink: Sink, ObserverType { + typealias Transform = (SourceType) throws -> ResultType? + + typealias ResultType = Observer.Element + typealias Element = SourceType + + private let transform: Transform + + init(transform: @escaping Transform, observer: Observer, cancel: Cancelable) { + self.transform = transform + super.init(observer: observer, cancel: cancel) + } + + func on(_ event: Event) { + switch event { + case .next(let element): + do { + if let mappedElement = try self.transform(element) { + self.forwardOn(.next(mappedElement)) + } + } + catch let e { + self.forwardOn(.error(e)) + self.dispose() + } + case .error(let error): + self.forwardOn(.error(error)) + self.dispose() + case .completed: + self.forwardOn(.completed) + self.dispose() + } + } +} + +final private class CompactMap: Producer { + typealias Transform = (SourceType) throws -> ResultType? + + private let source: Observable + + private let transform: Transform + + init(source: Observable, transform: @escaping Transform) { + self.source = source + self.transform = transform + } + + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == ResultType { + let sink = CompactMapSink(transform: self.transform, observer: observer, cancel: cancel) + let subscription = self.source.subscribe(sink) + return (sink: sink, subscription: subscription) + } +} diff --git a/iOS/RxSwift/Observables/Concat.swift b/iOS/RxSwift/Observables/Concat.swift index 35ef0e1f..b2fb1a2e 100644 --- a/iOS/RxSwift/Observables/Concat.swift +++ b/iOS/RxSwift/Observables/Concat.swift @@ -16,8 +16,8 @@ extension ObservableType { - parameter second: Second observable sequence. - returns: An observable sequence that contains the elements of `self`, followed by those of the second sequence. */ - public func concat(_ second: O) -> Observable where O.E == E { - return Observable.concat([self.asObservable(), second.asObservable()]) + public func concat(_ second: Source) -> Observable where Source.Element == Element { + Observable.concat([self.asObservable(), second.asObservable()]) } } @@ -35,8 +35,8 @@ extension ObservableType { - returns: An observable sequence that contains the elements of each given sequence, in sequential order. */ - public static func concat(_ sequence: S) -> Observable - where S.Iterator.Element == Observable { + public static func concat(_ sequence: Sequence) -> Observable + where Sequence.Element == Observable { return Concat(sources: sequence, count: nil) } @@ -53,8 +53,8 @@ extension ObservableType { - returns: An observable sequence that contains the elements of each given sequence, in sequential order. */ - public static func concat(_ collection: S) -> Observable - where S.Iterator.Element == Observable { + public static func concat(_ collection: Collection) -> Observable + where Collection.Element == Observable { return Concat(sources: collection, count: Int64(collection.count)) } @@ -71,39 +71,39 @@ extension ObservableType { - returns: An observable sequence that contains the elements of each given sequence, in sequential order. */ - public static func concat(_ sources: Observable ...) -> Observable { - return Concat(sources: sources, count: Int64(sources.count)) + public static func concat(_ sources: Observable ...) -> Observable { + Concat(sources: sources, count: Int64(sources.count)) } } -final fileprivate class ConcatSink - : TailRecursiveSink - , ObserverType where S.Iterator.Element : ObservableConvertibleType, S.Iterator.Element.E == O.E { - typealias Element = O.E +final private class ConcatSink + : TailRecursiveSink + , ObserverType where Sequence.Element: ObservableConvertibleType, Sequence.Element.Element == Observer.Element { + typealias Element = Observer.Element - override init(observer: O, cancel: Cancelable) { + override init(observer: Observer, cancel: Cancelable) { super.init(observer: observer, cancel: cancel) } func on(_ event: Event){ switch event { case .next: - forwardOn(event) + self.forwardOn(event) case .error: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() case .completed: - schedule(.moveNext) + self.schedule(.moveNext) } } - override func subscribeToNext(_ source: Observable) -> Disposable { - return source.subscribe(self) + override func subscribeToNext(_ source: Observable) -> Disposable { + source.subscribe(self) } - override func extract(_ observable: Observable) -> SequenceGenerator? { - if let source = observable as? Concat { - return (source._sources.makeIterator(), source._count) + override func extract(_ observable: Observable) -> SequenceGenerator? { + if let source = observable as? Concat { + return (source.sources.makeIterator(), source.count) } else { return nil @@ -111,20 +111,20 @@ final fileprivate class ConcatSink } } -final fileprivate class Concat : Producer where S.Iterator.Element : ObservableConvertibleType { - typealias Element = S.Iterator.Element.E +final private class Concat: Producer where Sequence.Element: ObservableConvertibleType { + typealias Element = Sequence.Element.Element - fileprivate let _sources: S - fileprivate let _count: IntMax? + fileprivate let sources: Sequence + fileprivate let count: IntMax? - init(sources: S, count: IntMax?) { - _sources = sources - _count = count + init(sources: Sequence, count: IntMax?) { + self.sources = sources + self.count = count } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - let sink = ConcatSink(observer: observer, cancel: cancel) - let subscription = sink.run((_sources.makeIterator(), _count)) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = ConcatSink(observer: observer, cancel: cancel) + let subscription = sink.run((self.sources.makeIterator(), self.count)) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Create.swift b/iOS/RxSwift/Observables/Create.swift index 4a1804a7..ca81442c 100644 --- a/iOS/RxSwift/Observables/Create.swift +++ b/iOS/RxSwift/Observables/Create.swift @@ -17,60 +17,60 @@ extension ObservableType { - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method. - returns: The observable sequence with the specified implementation for the `subscribe` method. */ - public static func create(_ subscribe: @escaping (AnyObserver) -> Disposable) -> Observable { - return AnonymousObservable(subscribe) + public static func create(_ subscribe: @escaping (AnyObserver) -> Disposable) -> Observable { + AnonymousObservable(subscribe) } } -final fileprivate class AnonymousObservableSink : Sink, ObserverType { - typealias E = O.E - typealias Parent = AnonymousObservable +final private class AnonymousObservableSink: Sink, ObserverType { + typealias Element = Observer.Element + typealias Parent = AnonymousObservable // state - private var _isStopped: AtomicInt = 0 + private let isStopped = AtomicInt(0) #if DEBUG - fileprivate let _synchronizationTracker = SynchronizationTracker() + private let synchronizationTracker = SynchronizationTracker() #endif - override init(observer: O, cancel: Cancelable) { + override init(observer: Observer, cancel: Cancelable) { super.init(observer: observer, cancel: cancel) } - func on(_ event: Event) { + func on(_ event: Event) { #if DEBUG - _synchronizationTracker.register(synchronizationErrorMessage: .default) - defer { _synchronizationTracker.unregister() } + self.synchronizationTracker.register(synchronizationErrorMessage: .default) + defer { self.synchronizationTracker.unregister() } #endif switch event { case .next: - if _isStopped == 1 { + if load(self.isStopped) == 1 { return } - forwardOn(event) + self.forwardOn(event) case .error, .completed: - if AtomicCompareAndSwap(0, 1, &_isStopped) { - forwardOn(event) - dispose() + if fetchOr(self.isStopped, 1) == 0 { + self.forwardOn(event) + self.dispose() } } } func run(_ parent: Parent) -> Disposable { - return parent._subscribeHandler(AnyObserver(self)) + parent.subscribeHandler(AnyObserver(self)) } } -final fileprivate class AnonymousObservable : Producer { +final private class AnonymousObservable: Producer { typealias SubscribeHandler = (AnyObserver) -> Disposable - let _subscribeHandler: SubscribeHandler + let subscribeHandler: SubscribeHandler init(_ subscribeHandler: @escaping SubscribeHandler) { - _subscribeHandler = subscribeHandler + self.subscribeHandler = subscribeHandler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = AnonymousObservableSink(observer: observer, cancel: cancel) let subscription = sink.run(self) return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/Debounce.swift b/iOS/RxSwift/Observables/Debounce.swift index 866427a0..dfab0045 100644 --- a/iOS/RxSwift/Observables/Debounce.swift +++ b/iOS/RxSwift/Observables/Debounce.swift @@ -18,99 +18,99 @@ extension ObservableType { - returns: The throttled sequence. */ public func debounce(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> Observable { + -> Observable { return Debounce(source: self.asObservable(), dueTime: dueTime, scheduler: scheduler) } } -final fileprivate class DebounceSink - : Sink +final private class DebounceSink + : Sink , ObserverType , LockOwnerType , SynchronizedOnType { - typealias Element = O.E + typealias Element = Observer.Element typealias ParentType = Debounce - private let _parent: ParentType + private let parent: ParentType - let _lock = RecursiveLock() + let lock = RecursiveLock() // state - private var _id = 0 as UInt64 - private var _value: Element? = nil + private var id = 0 as UInt64 + private var value: Element? let cancellable = SerialDisposable() - init(parent: ParentType, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: ParentType, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - let subscription = _parent._source.subscribe(self) + let subscription = self.parent.source.subscribe(self) return Disposables.create(subscription, cancellable) } func on(_ event: Event) { - synchronizedOn(event) + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case .next(let element): - _id = _id &+ 1 - let currentId = _id - _value = element + self.id = self.id &+ 1 + let currentId = self.id + self.value = element - let scheduler = _parent._scheduler - let dueTime = _parent._dueTime + let scheduler = self.parent.scheduler + let dueTime = self.parent.dueTime let d = SingleAssignmentDisposable() self.cancellable.disposable = d d.setDisposable(scheduler.scheduleRelative(currentId, dueTime: dueTime, action: self.propagate)) case .error: - _value = nil - forwardOn(event) - dispose() + self.value = nil + self.forwardOn(event) + self.dispose() case .completed: - if let value = _value { - _value = nil - forwardOn(.next(value)) + if let value = self.value { + self.value = nil + self.forwardOn(.next(value)) } - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() } } func propagate(_ currentId: UInt64) -> Disposable { - _lock.lock(); defer { _lock.unlock() } // { - let originalValue = _value + self.lock.performLocked { + let originalValue = self.value - if let value = originalValue, _id == currentId { - _value = nil - forwardOn(.next(value)) + if let value = originalValue, self.id == currentId { + self.value = nil + self.forwardOn(.next(value)) + } + + return Disposables.create() } - // } - return Disposables.create() } } -final fileprivate class Debounce : Producer { - - fileprivate let _source: Observable - fileprivate let _dueTime: RxTimeInterval - fileprivate let _scheduler: SchedulerType +final private class Debounce: Producer { + fileprivate let source: Observable + fileprivate let dueTime: RxTimeInterval + fileprivate let scheduler: SchedulerType init(source: Observable, dueTime: RxTimeInterval, scheduler: SchedulerType) { - _source = source - _dueTime = dueTime - _scheduler = scheduler + self.source = source + self.dueTime = dueTime + self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = DebounceSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/Debug.swift b/iOS/RxSwift/Observables/Debug.swift index 85b8af75..762e394f 100644 --- a/iOS/RxSwift/Observables/Debug.swift +++ b/iOS/RxSwift/Observables/Debug.swift @@ -6,8 +6,7 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import struct Foundation.Date -import class Foundation.DateFormatter +import Foundation extension ObservableType { @@ -21,29 +20,29 @@ extension ObservableType { - returns: An observable sequence whose events are printed to standard output. */ public func debug(_ identifier: String? = nil, trimOutput: Bool = false, file: String = #file, line: UInt = #line, function: String = #function) - -> Observable { + -> Observable { return Debug(source: self, identifier: identifier, trimOutput: trimOutput, file: file, line: line, function: function) } } -fileprivate let dateFormat = "yyyy-MM-dd HH:mm:ss.SSS" +private let dateFormat = "yyyy-MM-dd HH:mm:ss.SSS" -fileprivate func logEvent(_ identifier: String, dateFormat: DateFormatter, content: String) { +private func logEvent(_ identifier: String, dateFormat: DateFormatter, content: String) { print("\(dateFormat.string(from: Date())): \(identifier) -> \(content)") } -final fileprivate class DebugSink : Sink, ObserverType where O.E == Source.E { - typealias Element = O.E +final private class DebugSink: Sink, ObserverType where Observer.Element == Source.Element { + typealias Element = Observer.Element typealias Parent = Debug - private let _parent: Parent - private let _timestampFormatter = DateFormatter() + private let parent: Parent + private let timestampFormatter = DateFormatter() - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - _timestampFormatter.dateFormat = dateFormat + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + self.timestampFormatter.dateFormat = dateFormat - logEvent(_parent._identifier, dateFormat: _timestampFormatter, content: "subscribed") + logEvent(self.parent.identifier, dateFormat: self.timestampFormatter, content: "subscribed") super.init(observer: observer, cancel: cancel) } @@ -52,52 +51,52 @@ final fileprivate class DebugSink : Sin let maxEventTextLength = 40 let eventText = "\(event)" - let eventNormalized = (eventText.count > maxEventTextLength) && _parent._trimOutput + let eventNormalized = (eventText.count > maxEventTextLength) && self.parent.trimOutput ? String(eventText.prefix(maxEventTextLength / 2)) + "..." + String(eventText.suffix(maxEventTextLength / 2)) : eventText - logEvent(_parent._identifier, dateFormat: _timestampFormatter, content: "Event \(eventNormalized)") + logEvent(self.parent.identifier, dateFormat: self.timestampFormatter, content: "Event \(eventNormalized)") - forwardOn(event) + self.forwardOn(event) if event.isStopEvent { - dispose() + self.dispose() } } override func dispose() { - if !self.disposed { - logEvent(_parent._identifier, dateFormat: _timestampFormatter, content: "isDisposed") + if !self.isDisposed { + logEvent(self.parent.identifier, dateFormat: self.timestampFormatter, content: "isDisposed") } super.dispose() } } -final fileprivate class Debug : Producer { - fileprivate let _identifier: String - fileprivate let _trimOutput: Bool - fileprivate let _source: Source +final private class Debug: Producer { + fileprivate let identifier: String + fileprivate let trimOutput: Bool + private let source: Source init(source: Source, identifier: String?, trimOutput: Bool, file: String, line: UInt, function: String) { - _trimOutput = trimOutput + self.trimOutput = trimOutput if let identifier = identifier { - _identifier = identifier + self.identifier = identifier } else { let trimmedFile: String - if let lastIndex = file.lastIndexOf("/") { + if let lastIndex = file.lastIndex(of: "/") { trimmedFile = String(file[file.index(after: lastIndex) ..< file.endIndex]) } else { trimmedFile = file } - _identifier = "\(trimmedFile):\(line) (\(function))" + self.identifier = "\(trimmedFile):\(line) (\(function))" } - _source = source + self.source = source } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Source.E { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Source.Element { let sink = DebugSink(parent: self, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Decode.swift b/iOS/RxSwift/Observables/Decode.swift new file mode 100644 index 00000000..8bc73425 --- /dev/null +++ b/iOS/RxSwift/Observables/Decode.swift @@ -0,0 +1,34 @@ +// +// Decode.swift +// RxSwift +// +// Created by Shai Mishali on 24/07/2020. +// Copyright © 2020 Krunoslav Zaher. All rights reserved. +// + +import Foundation + +public extension ObservableType where Element == Data { + /// Attempt to decode the emitted `Data` using a provided decoder. + /// + /// - parameter type: A `Decodable`-conforming type to attempt to decode to + /// - parameter decoder: A capable decoder, e.g. `JSONDecoder` or `PropertyListDecoder` + /// + /// - note: If using a custom decoder, it must conform to the `DataDecoder` protocol. + /// + /// - returns: An `Observable` of the decoded type + func decode(type: Item.Type, + decoder: Decoder) -> Observable { + map { try decoder.decode(type, from: $0) } + } +} + +/// Represents an entity capable of decoding raw `Data` +/// into a concrete `Decodable` type +public protocol DataDecoder { + func decode(_ type: Item.Type, from data: Data) throws -> Item +} + +extension JSONDecoder: DataDecoder {} +extension PropertyListDecoder: DataDecoder {} diff --git a/iOS/RxSwift/Observables/DefaultIfEmpty.swift b/iOS/RxSwift/Observables/DefaultIfEmpty.swift index 696361fd..8d133d8f 100644 --- a/iOS/RxSwift/Observables/DefaultIfEmpty.swift +++ b/iOS/RxSwift/Observables/DefaultIfEmpty.swift @@ -16,51 +16,51 @@ extension ObservableType { - parameter default: Default element to be sent if the source does not emit any elements - returns: An observable sequence which emits default element end completes in case the original sequence is empty */ - public func ifEmpty(default: E) -> Observable { - return DefaultIfEmpty(source: self.asObservable(), default: `default`) + public func ifEmpty(default: Element) -> Observable { + DefaultIfEmpty(source: self.asObservable(), default: `default`) } } -final fileprivate class DefaultIfEmptySink: Sink, ObserverType { - typealias E = O.E - private let _default: E - private var _isEmpty = true +final private class DefaultIfEmptySink: Sink, ObserverType { + typealias Element = Observer.Element + private let `default`: Element + private var isEmpty = true - init(default: E, observer: O, cancel: Cancelable) { - _default = `default` + init(default: Element, observer: Observer, cancel: Cancelable) { + self.default = `default` super.init(observer: observer, cancel: cancel) } - func on(_ event: Event) { + func on(_ event: Event) { switch event { - case .next(_): - _isEmpty = false - forwardOn(event) - case .error(_): - forwardOn(event) - dispose() + case .next: + self.isEmpty = false + self.forwardOn(event) + case .error: + self.forwardOn(event) + self.dispose() case .completed: - if _isEmpty { - forwardOn(.next(_default)) + if self.isEmpty { + self.forwardOn(.next(self.default)) } - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() } } } -final fileprivate class DefaultIfEmpty: Producer { - private let _source: Observable - private let _default: SourceType +final private class DefaultIfEmpty: Producer { + private let source: Observable + private let `default`: SourceType init(source: Observable, `default`: SourceType) { - _source = source - _default = `default` + self.source = source + self.default = `default` } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceType { - let sink = DefaultIfEmptySink(default: _default, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceType { + let sink = DefaultIfEmptySink(default: self.default, observer: observer, cancel: cancel) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Deferred.swift b/iOS/RxSwift/Observables/Deferred.swift index 947f604a..b81cb166 100644 --- a/iOS/RxSwift/Observables/Deferred.swift +++ b/iOS/RxSwift/Observables/Deferred.swift @@ -15,59 +15,60 @@ extension ObservableType { - parameter observableFactory: Observable factory function to invoke for each observer that subscribes to the resulting sequence. - returns: An observable sequence whose observers trigger an invocation of the given observable factory function. */ - public static func deferred(_ observableFactory: @escaping () throws -> Observable) - -> Observable { - return Deferred(observableFactory: observableFactory) + public static func deferred(_ observableFactory: @escaping () throws -> Observable) + -> Observable { + Deferred(observableFactory: observableFactory) } } -final fileprivate class DeferredSink : Sink, ObserverType where S.E == O.E { - typealias E = O.E +final private class DeferredSink: Sink, ObserverType where Source.Element == Observer.Element { + typealias Element = Observer.Element - private let _observableFactory: () throws -> S + private let observableFactory: () throws -> Source - init(observableFactory: @escaping () throws -> S, observer: O, cancel: Cancelable) { - _observableFactory = observableFactory + init(observableFactory: @escaping () throws -> Source, observer: Observer, cancel: Cancelable) { + self.observableFactory = observableFactory super.init(observer: observer, cancel: cancel) } func run() -> Disposable { do { - let result = try _observableFactory() + let result = try self.observableFactory() return result.subscribe(self) } catch let e { - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() return Disposables.create() } } - func on(_ event: Event) { - forwardOn(event) + func on(_ event: Event) { + self.forwardOn(event) switch event { case .next: break case .error: - dispose() + self.dispose() case .completed: - dispose() + self.dispose() } } } -final fileprivate class Deferred : Producer { - typealias Factory = () throws -> S +final private class Deferred: Producer { + typealias Factory = () throws -> Source - private let _observableFactory : Factory + private let observableFactory : Factory init(observableFactory: @escaping Factory) { - _observableFactory = observableFactory + self.observableFactory = observableFactory } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == S.E { - let sink = DeferredSink(observableFactory: _observableFactory, observer: observer, cancel: cancel) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) + where Observer.Element == Source.Element { + let sink = DeferredSink(observableFactory: self.observableFactory, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) } diff --git a/iOS/RxSwift/Observables/Delay.swift b/iOS/RxSwift/Observables/Delay.swift index b13ee9cc..9f71c32d 100644 --- a/iOS/RxSwift/Observables/Delay.swift +++ b/iOS/RxSwift/Observables/Delay.swift @@ -6,7 +6,7 @@ // Copyright © 2016 Krunoslav Zaher. All rights reserved. // -import struct Foundation.Date +import Foundation extension ObservableType { @@ -20,39 +20,38 @@ extension ObservableType { - returns: the source Observable shifted in time by the specified delay. */ public func delay(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> Observable { + -> Observable { return Delay(source: self.asObservable(), dueTime: dueTime, scheduler: scheduler) } } -final fileprivate class DelaySink - : Sink +final private class DelaySink + : Sink , ObserverType { - typealias E = O.E - typealias Source = Observable + typealias Element = Observer.Element + typealias Source = Observable typealias DisposeKey = Bag.KeyType - private let _lock = RecursiveLock() + private let lock = RecursiveLock() - private let _dueTime: RxTimeInterval - private let _scheduler: SchedulerType + private let dueTime: RxTimeInterval + private let scheduler: SchedulerType - private let _sourceSubscription = SingleAssignmentDisposable() - private let _cancelable = SerialDisposable() + private let sourceSubscription = SingleAssignmentDisposable() + private let cancelable = SerialDisposable() // is scheduled some action - private var _active = false + private var active = false // is "run loop" on different scheduler running - private var _running = false - private var _errorEvent: Event? = nil + private var running = false + private var errorEvent: Event? // state - private var _queue = Queue<(eventTime: RxTime, event: Event)>(capacity: 0) - private var _disposed = false + private var queue = Queue<(eventTime: RxTime, event: Event)>(capacity: 0) - init(observer: O, dueTime: RxTimeInterval, scheduler: SchedulerType, cancel: Cancelable) { - _dueTime = dueTime - _scheduler = scheduler + init(observer: Observer, dueTime: RxTimeInterval, scheduler: SchedulerType, cancel: Cancelable) { + self.dueTime = dueTime + self.scheduler = scheduler super.init(observer: observer, cancel: cancel) } @@ -62,13 +61,12 @@ final fileprivate class DelaySink // // Another complication is that scheduler is potentially concurrent so internal queue is used. func drainQueue(state: (), scheduler: AnyRecursiveScheduler<()>) { - - _lock.lock() // { - let hasFailed = _errorEvent != nil - if !hasFailed { - _running = true - } - _lock.unlock() // } + self.lock.lock() + let hasFailed = self.errorEvent != nil + if !hasFailed { + self.running = true + } + self.lock.unlock() if hasFailed { return @@ -77,26 +75,24 @@ final fileprivate class DelaySink var ranAtLeastOnce = false while true { - _lock.lock() // { - let errorEvent = _errorEvent + self.lock.lock() + let errorEvent = self.errorEvent - let eventToForwardImmediatelly = ranAtLeastOnce ? nil : _queue.dequeue()?.event - let nextEventToScheduleOriginalTime: Date? = ranAtLeastOnce && !_queue.isEmpty ? _queue.peek().eventTime : nil + let eventToForwardImmediately = ranAtLeastOnce ? nil : self.queue.dequeue()?.event + let nextEventToScheduleOriginalTime: Date? = ranAtLeastOnce && !self.queue.isEmpty ? self.queue.peek().eventTime : nil - if let _ = errorEvent { + if errorEvent == nil { + if eventToForwardImmediately != nil { } - else { - if let _ = eventToForwardImmediatelly { - } - else if let _ = nextEventToScheduleOriginalTime { - _running = false - } - else { - _running = false - _active = false - } + else if nextEventToScheduleOriginalTime != nil { + self.running = false + } + else { + self.running = false + self.active = false } - _lock.unlock() // { + } + self.lock.unlock() if let errorEvent = errorEvent { self.forwardOn(errorEvent) @@ -104,19 +100,16 @@ final fileprivate class DelaySink return } else { - if let eventToForwardImmediatelly = eventToForwardImmediatelly { + if let eventToForwardImmediately = eventToForwardImmediately { ranAtLeastOnce = true - self.forwardOn(eventToForwardImmediatelly) - if case .completed = eventToForwardImmediatelly { + self.forwardOn(eventToForwardImmediately) + if case .completed = eventToForwardImmediately { self.dispose() return } } else if let nextEventToScheduleOriginalTime = nextEventToScheduleOriginalTime { - let elapsedTime = _scheduler.now.timeIntervalSince(nextEventToScheduleOriginalTime) - let interval = _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 { @@ -126,56 +119,56 @@ final fileprivate class DelaySink } } - func on(_ event: Event) { + func on(_ event: Event) { if event.isStopEvent { - _sourceSubscription.dispose() + self.sourceSubscription.dispose() } switch event { - case .error(_): - _lock.lock() // { - let shouldSendImmediatelly = !_running - _queue = Queue(capacity: 0) - _errorEvent = event - _lock.unlock() // } - - if shouldSendImmediatelly { - forwardOn(event) - dispose() + case .error: + self.lock.lock() + let shouldSendImmediately = !self.running + self.queue = Queue(capacity: 0) + self.errorEvent = event + self.lock.unlock() + + if shouldSendImmediately { + self.forwardOn(event) + self.dispose() } default: - _lock.lock() // { - let shouldSchedule = !_active - _active = true - _queue.enqueue((_scheduler.now, event)) - _lock.unlock() // } + self.lock.lock() + let shouldSchedule = !self.active + self.active = true + self.queue.enqueue((self.scheduler.now, event)) + self.lock.unlock() if shouldSchedule { - _cancelable.disposable = _scheduler.scheduleRecursive((), dueTime: _dueTime, action: self.drainQueue) + self.cancelable.disposable = self.scheduler.scheduleRecursive((), dueTime: self.dueTime, action: self.drainQueue) } } } - func run(source: Observable) -> Disposable { - _sourceSubscription.setDisposable(source.subscribe(self)) - return Disposables.create(_sourceSubscription, _cancelable) + func run(source: Observable) -> Disposable { + self.sourceSubscription.setDisposable(source.subscribe(self)) + return Disposables.create(sourceSubscription, cancelable) } } -final fileprivate class Delay: Producer { - private let _source: Observable - private let _dueTime: RxTimeInterval - private let _scheduler: SchedulerType +final private class Delay: Producer { + private let source: Observable + private let dueTime: RxTimeInterval + private let scheduler: SchedulerType init(source: Observable, dueTime: RxTimeInterval, scheduler: SchedulerType) { - _source = source - _dueTime = dueTime - _scheduler = scheduler + self.source = source + self.dueTime = dueTime + self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - let sink = DelaySink(observer: observer, dueTime: _dueTime, scheduler: _scheduler, cancel: cancel) - let subscription = sink.run(source: _source) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = DelaySink(observer: observer, dueTime: self.dueTime, scheduler: self.scheduler, cancel: cancel) + let subscription = sink.run(source: self.source) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/DelaySubscription.swift b/iOS/RxSwift/Observables/DelaySubscription.swift index 9225a196..fd8c4951 100644 --- a/iOS/RxSwift/Observables/DelaySubscription.swift +++ b/iOS/RxSwift/Observables/DelaySubscription.swift @@ -18,47 +18,39 @@ extension ObservableType { - returns: Time-shifted sequence. */ public func delaySubscription(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - return DelaySubscription(source: self.asObservable(), dueTime: dueTime, scheduler: scheduler) + -> Observable { + DelaySubscription(source: self.asObservable(), dueTime: dueTime, scheduler: scheduler) } } -final fileprivate class DelaySubscriptionSink - : Sink, ObserverType { - typealias E = O.E - typealias Parent = DelaySubscription +final private class DelaySubscriptionSink + : Sink, ObserverType { + typealias Element = Observer.Element - private let _parent: Parent - - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - forwardOn(event) + func on(_ event: Event) { + self.forwardOn(event) if event.isStopEvent { - dispose() + self.dispose() } } } -final fileprivate class DelaySubscription: Producer { - private let _source: Observable - private let _dueTime: RxTimeInterval - private let _scheduler: SchedulerType +final private class DelaySubscription: Producer { + private let source: Observable + private let dueTime: RxTimeInterval + private let scheduler: SchedulerType init(source: Observable, dueTime: RxTimeInterval, scheduler: SchedulerType) { - _source = source - _dueTime = dueTime - _scheduler = scheduler + self.source = source + self.dueTime = dueTime + self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - let sink = DelaySubscriptionSink(parent: self, observer: observer, cancel: cancel) - let subscription = _scheduler.scheduleRelative((), dueTime: _dueTime) { _ in - return self._source.subscribe(sink) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = DelaySubscriptionSink(observer: observer, cancel: cancel) + let subscription = self.scheduler.scheduleRelative((), dueTime: self.dueTime) { _ in + return self.source.subscribe(sink) } return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/Dematerialize.swift b/iOS/RxSwift/Observables/Dematerialize.swift index d142249a..2ccd5462 100644 --- a/iOS/RxSwift/Observables/Dematerialize.swift +++ b/iOS/RxSwift/Observables/Dematerialize.swift @@ -6,46 +6,46 @@ // Copyright © 2017 Krunoslav Zaher. All rights reserved. // -extension ObservableType where E: EventConvertible { +extension ObservableType where Element: EventConvertible { /** Convert any previously materialized Observable into it's original form. - seealso: [materialize operator on reactivex.io](http://reactivex.io/documentation/operators/materialize-dematerialize.html) - returns: The dematerialized observable sequence. */ - public func dematerialize() -> Observable { - return Dematerialize(source: self.asObservable()) + public func dematerialize() -> Observable { + Dematerialize(source: self.asObservable()) } } -fileprivate final class DematerializeSink: Sink, ObserverType where O.E == Element.ElementType { - fileprivate func on(_ event: Event) { +private final class DematerializeSink: Sink, ObserverType where Observer.Element == T.Element { + fileprivate func on(_ event: Event) { switch event { case .next(let element): - forwardOn(element.event) + self.forwardOn(element.event) if element.event.isStopEvent { - dispose() + self.dispose() } case .completed: - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() case .error(let error): - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() } } } -final fileprivate class Dematerialize: Producer { - private let _source: Observable - - init(source: Observable) { - _source = source +final private class Dematerialize: Producer { + private let source: Observable + + init(source: Observable) { + self.source = source } - - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element.ElementType { - let sink = DematerializeSink(observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == T.Element { + let sink = DematerializeSink(observer: observer, cancel: cancel) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/DistinctUntilChanged.swift b/iOS/RxSwift/Observables/DistinctUntilChanged.swift index f72f5201..c127b5aa 100644 --- a/iOS/RxSwift/Observables/DistinctUntilChanged.swift +++ b/iOS/RxSwift/Observables/DistinctUntilChanged.swift @@ -6,7 +6,7 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -extension ObservableType where E: Equatable { +extension ObservableType where Element: Equatable { /** Returns an observable sequence that contains only distinct contiguous elements according to equality operator. @@ -16,8 +16,8 @@ extension ObservableType where E: Equatable { - returns: An observable sequence only containing the distinct contiguous elements, based on equality operator, from the source sequence. */ public func distinctUntilChanged() - -> Observable { - return self.distinctUntilChanged({ $0 }, comparer: { ($0 == $1) }) + -> Observable { + self.distinctUntilChanged({ $0 }, comparer: { ($0 == $1) }) } } @@ -30,9 +30,9 @@ extension ObservableType { - parameter keySelector: A function to compute the comparison key for each element. - returns: An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence. */ - public func distinctUntilChanged(_ keySelector: @escaping (E) throws -> K) - -> Observable { - return self.distinctUntilChanged(keySelector, comparer: { $0 == $1 }) + public func distinctUntilChanged(_ keySelector: @escaping (Element) throws -> Key) + -> Observable { + self.distinctUntilChanged(keySelector, comparer: { $0 == $1 }) } /** @@ -43,9 +43,9 @@ extension ObservableType { - parameter comparer: Equality comparer for computed key values. - returns: An observable sequence only containing the distinct contiguous elements, based on `comparer`, from the source sequence. */ - public func distinctUntilChanged(_ comparer: @escaping (E, E) throws -> Bool) - -> Observable { - return self.distinctUntilChanged({ $0 }, comparer: comparer) + public func distinctUntilChanged(_ comparer: @escaping (Element, Element) throws -> Bool) + -> Observable { + self.distinctUntilChanged({ $0 }, comparer: comparer) } /** @@ -57,69 +57,81 @@ extension ObservableType { - parameter comparer: Equality comparer for computed key values. - returns: An observable sequence only containing the distinct contiguous elements, based on a computed key value and the comparer, from the source sequence. */ - public func distinctUntilChanged(_ keySelector: @escaping (E) throws -> K, comparer: @escaping (K, K) throws -> Bool) - -> Observable { + public func distinctUntilChanged(_ keySelector: @escaping (Element) throws -> K, comparer: @escaping (K, K) throws -> Bool) + -> Observable { return DistinctUntilChanged(source: self.asObservable(), selector: keySelector, comparer: comparer) } + + /** + Returns an observable sequence that contains only contiguous elements with distinct values in the provided key path on each object. + + - seealso: [distinct operator on reactivex.io](http://reactivex.io/documentation/operators/distinct.html) + + - returns: An observable sequence only containing the distinct contiguous elements, based on equality operator on the provided key path + */ + public func distinctUntilChanged(at keyPath: KeyPath) -> + Observable { + self.distinctUntilChanged { $0[keyPath: keyPath] == $1[keyPath: keyPath] } + } } -final fileprivate class DistinctUntilChangedSink: Sink, ObserverType { - typealias E = O.E +final private class DistinctUntilChangedSink: Sink, ObserverType { + typealias Element = Observer.Element - private let _parent: DistinctUntilChanged - private var _currentKey: Key? = nil + private let parent: DistinctUntilChanged + private var currentKey: Key? - init(parent: DistinctUntilChanged, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: DistinctUntilChanged, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next(let value): do { - let key = try _parent._selector(value) + let key = try self.parent.selector(value) var areEqual = false - if let currentKey = _currentKey { - areEqual = try _parent._comparer(currentKey, key) + if let currentKey = self.currentKey { + areEqual = try self.parent.comparer(currentKey, key) } if areEqual { return } - _currentKey = key + self.currentKey = key - forwardOn(event) + self.forwardOn(event) } catch let error { - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() } case .error, .completed: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() } } } -final fileprivate class DistinctUntilChanged: Producer { +final private class DistinctUntilChanged: Producer { typealias KeySelector = (Element) throws -> Key typealias EqualityComparer = (Key, Key) throws -> Bool - fileprivate let _source: Observable - fileprivate let _selector: KeySelector - fileprivate let _comparer: EqualityComparer + private let source: Observable + fileprivate let selector: KeySelector + fileprivate let comparer: EqualityComparer init(source: Observable, selector: @escaping KeySelector, comparer: @escaping EqualityComparer) { - _source = source - _selector = selector - _comparer = comparer + self.source = source + self.selector = selector + self.comparer = comparer } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = DistinctUntilChangedSink(parent: self, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Do.swift b/iOS/RxSwift/Observables/Do.swift index 2be6d583..3c8c68b3 100644 --- a/iOS/RxSwift/Observables/Do.swift +++ b/iOS/RxSwift/Observables/Do.swift @@ -13,15 +13,18 @@ extension ObservableType { - 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 afterNext: Action to invoke for each element after the observable has passed an onNext event along to its downstream. - parameter onError: Action to invoke upon errored termination of the observable sequence. + - parameter afterError: Action to invoke after errored termination of the observable sequence. - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. + - parameter afterCompleted: Action to invoke after graceful 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. */ - public func `do`(onNext: ((E) throws -> Void)? = nil, onError: ((Swift.Error) throws -> Void)? = nil, onCompleted: (() throws -> Void)? = nil, onSubscribe: (() -> ())? = nil, onSubscribed: (() -> ())? = nil, onDispose: (() -> ())? = nil) - -> Observable { + public func `do`(onNext: ((Element) throws -> Void)? = nil, afterNext: ((Element) throws -> Void)? = nil, onError: ((Swift.Error) throws -> Void)? = nil, afterError: ((Swift.Error) throws -> Void)? = nil, onCompleted: (() throws -> Void)? = nil, afterCompleted: (() throws -> Void)? = nil, onSubscribe: (() -> Void)? = nil, onSubscribed: (() -> Void)? = nil, onDispose: (() -> Void)? = nil) + -> Observable { return Do(source: self.asObservable(), eventHandler: { e in switch e { case .next(let element): @@ -31,59 +34,75 @@ extension ObservableType { case .completed: try onCompleted?() } + }, afterEventHandler: { e in + switch e { + case .next(let element): + try afterNext?(element) + case .error(let e): + try afterError?(e) + case .completed: + try afterCompleted?() + } }, onSubscribe: onSubscribe, onSubscribed: onSubscribed, onDispose: onDispose) } } -final fileprivate class DoSink : Sink, ObserverType { - typealias Element = O.E +final private class DoSink: Sink, ObserverType { + typealias Element = Observer.Element typealias EventHandler = (Event) throws -> Void + typealias AfterEventHandler = (Event) throws -> Void - private let _eventHandler: EventHandler + private let eventHandler: EventHandler + private let afterEventHandler: AfterEventHandler - init(eventHandler: @escaping EventHandler, observer: O, cancel: Cancelable) { - _eventHandler = eventHandler + init(eventHandler: @escaping EventHandler, afterEventHandler: @escaping AfterEventHandler, observer: Observer, cancel: Cancelable) { + self.eventHandler = eventHandler + self.afterEventHandler = afterEventHandler super.init(observer: observer, cancel: cancel) } func on(_ event: Event) { do { - try _eventHandler(event) - forwardOn(event) + try self.eventHandler(event) + self.forwardOn(event) + try self.afterEventHandler(event) if event.isStopEvent { - dispose() + self.dispose() } } catch let error { - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() } } } -final fileprivate class Do : Producer { +final private class Do: Producer { typealias EventHandler = (Event) throws -> Void + typealias AfterEventHandler = (Event) throws -> Void - fileprivate let _source: Observable - fileprivate let _eventHandler: EventHandler - fileprivate let _onSubscribe: (() -> ())? - fileprivate let _onSubscribed: (() -> ())? - fileprivate let _onDispose: (() -> ())? + private let source: Observable + private let eventHandler: EventHandler + private let afterEventHandler: AfterEventHandler + private let onSubscribe: (() -> Void)? + private let onSubscribed: (() -> Void)? + private let onDispose: (() -> Void)? - init(source: Observable, eventHandler: @escaping EventHandler, onSubscribe: (() -> ())?, onSubscribed: (() -> ())?, onDispose: (() -> ())?) { - _source = source - _eventHandler = eventHandler - _onSubscribe = onSubscribe - _onSubscribed = onSubscribed - _onDispose = onDispose + init(source: Observable, eventHandler: @escaping EventHandler, afterEventHandler: @escaping AfterEventHandler, onSubscribe: (() -> Void)?, onSubscribed: (() -> Void)?, onDispose: (() -> Void)?) { + self.source = source + self.eventHandler = eventHandler + self.afterEventHandler = afterEventHandler + self.onSubscribe = onSubscribe + self.onSubscribed = onSubscribed + self.onDispose = onDispose } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - _onSubscribe?() - let sink = DoSink(eventHandler: _eventHandler, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) - _onSubscribed?() - let onDispose = _onDispose + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + self.onSubscribe?() + let sink = DoSink(eventHandler: self.eventHandler, afterEventHandler: self.afterEventHandler, observer: observer, cancel: cancel) + let subscription = self.source.subscribe(sink) + self.onSubscribed?() + let onDispose = self.onDispose let allSubscriptions = Disposables.create { subscription.dispose() onDispose?() diff --git a/iOS/RxSwift/Observables/ElementAt.swift b/iOS/RxSwift/Observables/ElementAt.swift index 500a0442..3f09c708 100644 --- a/iOS/RxSwift/Observables/ElementAt.swift +++ b/iOS/RxSwift/Observables/ElementAt.swift @@ -7,7 +7,6 @@ // extension ObservableType { - /** Returns a sequence emitting only element _n_ emitted by an Observable @@ -16,52 +15,66 @@ extension ObservableType { - parameter index: The index of the required element (starting from 0). - returns: An observable sequence that emits the desired element as its own sole emission. */ + @available(*, deprecated, renamed: "element(at:)") public func elementAt(_ index: Int) - -> Observable { - return ElementAt(source: asObservable(), index: index, throwOnEmpty: true) + -> Observable { + element(at: index) + } + + /** + Returns a sequence emitting only element _n_ emitted by an Observable + + - seealso: [elementAt operator on reactivex.io](http://reactivex.io/documentation/operators/elementat.html) + + - parameter index: The index of the required element (starting from 0). + - returns: An observable sequence that emits the desired element as its own sole emission. + */ + public func element(at index: Int) + -> Observable { + ElementAt(source: self.asObservable(), index: index, throwOnEmpty: true) } } -final fileprivate class ElementAtSink : Sink, ObserverType { - typealias SourceType = O.E +final private class ElementAtSink: Sink, ObserverType { + typealias SourceType = Observer.Element typealias Parent = ElementAt - let _parent: Parent - var _i: Int + let parent: Parent + var i: Int - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - _i = parent._index + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + self.i = parent.index super.init(observer: observer, cancel: cancel) } func on(_ event: Event) { switch event { - case .next(_): + case .next: - if (_i == 0) { - forwardOn(event) - forwardOn(.completed) + if self.i == 0 { + self.forwardOn(event) + self.forwardOn(.completed) self.dispose() } do { - let _ = try decrementChecked(&_i) - } catch(let e) { - forwardOn(.error(e)) - dispose() + _ = try decrementChecked(&self.i) + } catch let e { + self.forwardOn(.error(e)) + self.dispose() return } case .error(let e): - forwardOn(.error(e)) + self.forwardOn(.error(e)) self.dispose() case .completed: - if (_parent._throwOnEmpty) { - forwardOn(.error(RxError.argumentOutOfRange)) + if self.parent.throwOnEmpty { + self.forwardOn(.error(RxError.argumentOutOfRange)) } else { - forwardOn(.completed) + self.forwardOn(.completed) } self.dispose() @@ -69,25 +82,24 @@ final fileprivate class ElementAtSink : Sink, ObserverType { } } -final fileprivate class ElementAt : Producer { - - let _source: Observable - let _throwOnEmpty: Bool - let _index: Int +final private class ElementAt: Producer { + let source: Observable + let throwOnEmpty: Bool + let index: Int init(source: Observable, index: Int, throwOnEmpty: Bool) { if index < 0 { rxFatalError("index can't be negative") } - self._source = source - self._index = index - self._throwOnEmpty = throwOnEmpty + self.source = source + self.index = index + self.throwOnEmpty = throwOnEmpty } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceType { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceType { let sink = ElementAtSink(parent: self, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Empty.swift b/iOS/RxSwift/Observables/Empty.swift index d2dcdb00..9ca59659 100644 --- a/iOS/RxSwift/Observables/Empty.swift +++ b/iOS/RxSwift/Observables/Empty.swift @@ -14,13 +14,13 @@ extension ObservableType { - returns: An observable sequence with no elements. */ - public static func empty() -> Observable { - return EmptyProducer() + public static func empty() -> Observable { + EmptyProducer() } } -final fileprivate class EmptyProducer : Producer { - override func subscribe(_ observer: O) -> Disposable where O.E == Element { +final private class EmptyProducer: Producer { + override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { observer.on(.completed) return Disposables.create() } diff --git a/iOS/RxSwift/Observables/Enumerated.swift b/iOS/RxSwift/Observables/Enumerated.swift index 2a6cd980..ef8a0ff0 100644 --- a/iOS/RxSwift/Observables/Enumerated.swift +++ b/iOS/RxSwift/Observables/Enumerated.swift @@ -16,47 +16,46 @@ extension ObservableType { - returns: An observable sequence that contains tuples of source sequence elements and their indexes. */ public func enumerated() - -> Observable<(index: Int, element: E)> { - return Enumerated(source: self.asObservable()) + -> Observable<(index: Int, element: Element)> { + Enumerated(source: self.asObservable()) } } -final fileprivate class EnumeratedSink: Sink, ObserverType where O.E == (index: Int, element: Element) { - typealias E = Element +final private class EnumeratedSink: Sink, ObserverType where Observer.Element == (index: Int, element: Element) { var index = 0 func on(_ event: Event) { switch event { case .next(let value): do { - let nextIndex = try incrementChecked(&index) + let nextIndex = try incrementChecked(&self.index) let next = (index: nextIndex, element: value) - forwardOn(.next(next)) + self.forwardOn(.next(next)) } catch let e { - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() } case .completed: - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() case .error(let error): - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() } } } -final fileprivate class Enumerated : Producer<(index: Int, element: Element)> { - private let _source: Observable +final private class Enumerated: Producer<(index: Int, element: Element)> { + private let source: Observable init(source: Observable) { - _source = source + self.source = source } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == (index: Int, element: Element) { - let sink = EnumeratedSink(observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == (index: Int, element: Element) { + let sink = EnumeratedSink(observer: observer, cancel: cancel) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Error.swift b/iOS/RxSwift/Observables/Error.swift index a15942bb..2e722d67 100644 --- a/iOS/RxSwift/Observables/Error.swift +++ b/iOS/RxSwift/Observables/Error.swift @@ -14,20 +14,20 @@ extension ObservableType { - returns: The observable sequence that terminates with specified error. */ - public static func error(_ error: Swift.Error) -> Observable { - return ErrorProducer(error: error) + public static func error(_ error: Swift.Error) -> Observable { + ErrorProducer(error: error) } } -final fileprivate class ErrorProducer : Producer { - private let _error: Swift.Error +final private class ErrorProducer: Producer { + private let error: Swift.Error init(error: Swift.Error) { - _error = error + self.error = error } - override func subscribe(_ observer: O) -> Disposable where O.E == Element { - observer.on(.error(_error)) + override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { + observer.on(.error(self.error)) return Disposables.create() } } diff --git a/iOS/RxSwift/Observables/Filter.swift b/iOS/RxSwift/Observables/Filter.swift index 2a1f496a..61d3ce79 100644 --- a/iOS/RxSwift/Observables/Filter.swift +++ b/iOS/RxSwift/Observables/Filter.swift @@ -16,75 +16,71 @@ extension ObservableType { - parameter predicate: A function to test each source element for a condition. - returns: An observable sequence that contains elements from the input sequence that satisfy the condition. */ - public func filter(_ predicate: @escaping (E) throws -> Bool) - -> Observable { - return Filter(source: asObservable(), predicate: predicate) + public func filter(_ predicate: @escaping (Element) throws -> Bool) + -> Observable { + Filter(source: self.asObservable(), predicate: predicate) } } extension ObservableType { - /** - Skips elements and completes (or errors) when the receiver completes (or errors). Equivalent to filter that always returns false. + Skips elements and completes (or errors) when the observable sequence completes (or errors). Equivalent to filter that always returns false. - seealso: [ignoreElements operator on reactivex.io](http://reactivex.io/documentation/operators/ignoreelements.html) - returns: An observable sequence that skips all elements of the source sequence. */ public func ignoreElements() - -> Completable { - return flatMap { _ in - return Observable.empty() - } - .asCompletable() + -> Observable { + self.flatMap { _ in Observable.empty() } } } -final fileprivate class FilterSink: Sink, ObserverType { +final private class FilterSink: Sink, ObserverType { typealias Predicate = (Element) throws -> Bool - typealias Element = O.E + typealias Element = Observer.Element - private let _predicate: Predicate + private let predicate: Predicate - init(predicate: @escaping Predicate, observer: O, cancel: Cancelable) { - _predicate = predicate + init(predicate: @escaping Predicate, observer: Observer, cancel: Cancelable) { + self.predicate = predicate super.init(observer: observer, cancel: cancel) } func on(_ event: Event) { switch event { - case .next(let value): - do { - let satisfies = try _predicate(value) - if satisfies { - forwardOn(.next(value)) - } - } - catch let e { - forwardOn(.error(e)) - dispose() + case .next(let value): + do { + let satisfies = try self.predicate(value) + if satisfies { + self.forwardOn(.next(value)) } - case .completed, .error: - forwardOn(event) - dispose() + } + catch let e { + self.forwardOn(.error(e)) + self.dispose() + } + case .completed, .error: + self.forwardOn(event) + self.dispose() } } } -final fileprivate class Filter : Producer { +final private class Filter: Producer { typealias Predicate = (Element) throws -> Bool - private let _source: Observable - private let _predicate: Predicate + private let source: Observable + private let predicate: Predicate init(source: Observable, predicate: @escaping Predicate) { - _source = source - _predicate = predicate + self.source = source + self.predicate = predicate } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - let sink = FilterSink(predicate: _predicate, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = FilterSink(predicate: self.predicate, observer: observer, cancel: cancel) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/First.swift b/iOS/RxSwift/Observables/First.swift index 4a72ba0d..00141148 100644 --- a/iOS/RxSwift/Observables/First.swift +++ b/iOS/RxSwift/Observables/First.swift @@ -6,37 +6,36 @@ // Copyright © 2017 Krunoslav Zaher. All rights reserved. // -fileprivate final class FirstSink : Sink, ObserverType where O.E == Element? { - typealias E = Element - typealias Parent = First +private final class FirstSink : Sink, ObserverType where Observer.Element == Element? { + typealias Parent = First - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next(let value): - forwardOn(.next(value)) - forwardOn(.completed) - dispose() + self.forwardOn(.next(value)) + self.forwardOn(.completed) + self.dispose() case .error(let error): - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() case .completed: - forwardOn(.next(nil)) - forwardOn(.completed) - dispose() + self.forwardOn(.next(nil)) + self.forwardOn(.completed) + self.dispose() } } } final class First: Producer { - fileprivate let _source: Observable + private let source: Observable init(source: Observable) { - _source = source + self.source = source } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element? { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element? { let sink = FirstSink(observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Generate.swift b/iOS/RxSwift/Observables/Generate.swift index 6469937d..7b924b38 100644 --- a/iOS/RxSwift/Observables/Generate.swift +++ b/iOS/RxSwift/Observables/Generate.swift @@ -19,33 +19,33 @@ extension ObservableType { - parameter scheduler: Scheduler on which to run the generator loop. - returns: The generated sequence. */ - public static func generate(initialState: E, condition: @escaping (E) throws -> Bool, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance, iterate: @escaping (E) throws -> E) -> Observable { - return Generate(initialState: initialState, condition: condition, iterate: iterate, resultSelector: { $0 }, scheduler: scheduler) + public static func generate(initialState: Element, condition: @escaping (Element) throws -> Bool, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance, iterate: @escaping (Element) throws -> Element) -> Observable { + Generate(initialState: initialState, condition: condition, iterate: iterate, resultSelector: { $0 }, scheduler: scheduler) } } -final fileprivate class GenerateSink : Sink { - typealias Parent = Generate +final private class GenerateSink: Sink { + typealias Parent = Generate - private let _parent: Parent + private let parent: Parent - private var _state: S + private var state: Sequence - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - _state = parent._initialState + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + self.state = parent.initialState super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - return _parent._scheduler.scheduleRecursive(true) { (isFirst, recurse) -> Void in + return self.parent.scheduler.scheduleRecursive(true) { isFirst, recurse -> Void in do { if !isFirst { - self._state = try self._parent._iterate(self._state) + self.state = try self.parent.iterate(self.state) } - if try self._parent._condition(self._state) { - let result = try self._parent._resultSelector(self._state) + if try self.parent.condition(self.state) { + let result = try self.parent.resultSelector(self.state) self.forwardOn(.next(result)) recurse(false) @@ -63,23 +63,23 @@ final fileprivate class GenerateSink : Sink { } } -final fileprivate class Generate : Producer { - fileprivate let _initialState: S - fileprivate let _condition: (S) throws -> Bool - fileprivate let _iterate: (S) throws -> S - fileprivate let _resultSelector: (S) throws -> E - fileprivate let _scheduler: ImmediateSchedulerType +final private class Generate: Producer { + fileprivate let initialState: Sequence + fileprivate let condition: (Sequence) throws -> Bool + fileprivate let iterate: (Sequence) throws -> Sequence + fileprivate let resultSelector: (Sequence) throws -> Element + fileprivate let scheduler: ImmediateSchedulerType - init(initialState: S, condition: @escaping (S) throws -> Bool, iterate: @escaping (S) throws -> S, resultSelector: @escaping (S) throws -> E, scheduler: ImmediateSchedulerType) { - _initialState = initialState - _condition = condition - _iterate = iterate - _resultSelector = resultSelector - _scheduler = scheduler + init(initialState: Sequence, condition: @escaping (Sequence) throws -> Bool, iterate: @escaping (Sequence) throws -> Sequence, resultSelector: @escaping (Sequence) throws -> Element, scheduler: ImmediateSchedulerType) { + self.initialState = initialState + self.condition = condition + self.iterate = iterate + self.resultSelector = resultSelector + self.scheduler = scheduler super.init() } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = GenerateSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/GroupBy.swift b/iOS/RxSwift/Observables/GroupBy.swift index a8a0e78a..88cbda76 100644 --- a/iOS/RxSwift/Observables/GroupBy.swift +++ b/iOS/RxSwift/Observables/GroupBy.swift @@ -15,68 +15,67 @@ extension ObservableType { - parameter keySelector: A function to extract the key for each element. - returns: A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value. */ - public func groupBy(keySelector: @escaping (E) throws -> K) - -> Observable> { - return GroupBy(source: self.asObservable(), selector: keySelector) + public func groupBy(keySelector: @escaping (Element) throws -> Key) + -> Observable> { + GroupBy(source: self.asObservable(), selector: keySelector) } } -final fileprivate class GroupedObservableImpl : Observable { - private var _subject: PublishSubject - private var _refCount: RefCountDisposable +final private class GroupedObservableImpl: Observable { + private var subject: PublishSubject + private var refCount: RefCountDisposable - init(key: Key, subject: PublishSubject, refCount: RefCountDisposable) { - _subject = subject - _refCount = refCount + init(subject: PublishSubject, refCount: RefCountDisposable) { + self.subject = subject + self.refCount = refCount } - override public func subscribe(_ observer: O) -> Disposable where O.E == E { - let release = _refCount.retain() - let subscription = _subject.subscribe(observer) + override public func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { + let release = self.refCount.retain() + let subscription = self.subject.subscribe(observer) return Disposables.create(release, subscription) } } -final fileprivate class GroupBySink - : Sink - , ObserverType where O.E == GroupedObservable { - typealias E = Element - typealias ResultType = O.E +final private class GroupBySink + : Sink + , ObserverType where Observer.Element == GroupedObservable { + typealias ResultType = Observer.Element typealias Parent = GroupBy - private let _parent: Parent - private let _subscription = SingleAssignmentDisposable() - private var _refCountDisposable: RefCountDisposable! - private var _groupedSubjectTable: [Key: PublishSubject] + private let parent: Parent + private let subscription = SingleAssignmentDisposable() + private var refCountDisposable: RefCountDisposable! + private var groupedSubjectTable: [Key: PublishSubject] - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - _groupedSubjectTable = [Key: PublishSubject]() + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + self.groupedSubjectTable = [Key: PublishSubject]() super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - _refCountDisposable = RefCountDisposable(disposable: _subscription) + self.refCountDisposable = RefCountDisposable(disposable: self.subscription) - _subscription.setDisposable(_parent._source.subscribe(self)) + self.subscription.setDisposable(self.parent.source.subscribe(self)) - return _refCountDisposable + return self.refCountDisposable } private func onGroupEvent(key: Key, value: Element) { - if let writer = _groupedSubjectTable[key] { + if let writer = self.groupedSubjectTable[key] { writer.on(.next(value)) } else { let writer = PublishSubject() - _groupedSubjectTable[key] = writer + self.groupedSubjectTable[key] = writer let group = GroupedObservable( key: key, - source: GroupedObservableImpl(key: key, subject: writer, refCount: _refCountDisposable) + source: GroupedObservableImpl(subject: writer, refCount: refCountDisposable) ) - forwardOn(.next(group)) + self.forwardOn(.next(group)) writer.on(.next(value)) } } @@ -85,49 +84,49 @@ final fileprivate class GroupBySink switch event { case let .next(value): do { - let groupKey = try _parent._selector(value) - onGroupEvent(key: groupKey, value: value) + let groupKey = try self.parent.selector(value) + self.onGroupEvent(key: groupKey, value: value) } catch let e { - error(e) + self.error(e) return } case let .error(e): - error(e) + self.error(e) case .completed: - forwardOnGroups(event: .completed) - forwardOn(.completed) - _subscription.dispose() - dispose() + self.forwardOnGroups(event: .completed) + self.forwardOn(.completed) + self.subscription.dispose() + self.dispose() } } final func error(_ error: Swift.Error) { - forwardOnGroups(event: .error(error)) - forwardOn(.error(error)) - _subscription.dispose() - dispose() + self.forwardOnGroups(event: .error(error)) + self.forwardOn(.error(error)) + self.subscription.dispose() + self.dispose() } final func forwardOnGroups(event: Event) { - for writer in _groupedSubjectTable.values { + for writer in self.groupedSubjectTable.values { writer.on(event) } } } -final fileprivate class GroupBy: Producer> { +final private class GroupBy: Producer> { typealias KeySelector = (Element) throws -> Key - fileprivate let _source: Observable - fileprivate let _selector: KeySelector + fileprivate let source: Observable + fileprivate let selector: KeySelector init(source: Observable, selector: @escaping KeySelector) { - _source = source - _selector = selector + self.source = source + self.selector = selector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == GroupedObservable { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == GroupedObservable { let sink = GroupBySink(parent: self, observer: observer, cancel: cancel) return (sink: sink, subscription: sink.run()) } diff --git a/iOS/RxSwift/Observables/Just.swift b/iOS/RxSwift/Observables/Just.swift index 443cdaaf..93490837 100644 --- a/iOS/RxSwift/Observables/Just.swift +++ b/iOS/RxSwift/Observables/Just.swift @@ -15,8 +15,8 @@ extension ObservableType { - parameter element: Single element in the resulting observable sequence. - returns: An observable sequence containing the single specified element. */ - public static func just(_ element: E) -> Observable { - return Just(element: element) + public static func just(_ element: Element) -> Observable { + Just(element: element) } /** @@ -25,27 +25,27 @@ extension ObservableType { - seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html) - parameter element: Single element in the resulting observable sequence. - - parameter: Scheduler to send the single element on. + - parameter scheduler: Scheduler to send the single element on. - returns: An observable sequence containing the single specified element. */ - public static func just(_ element: E, scheduler: ImmediateSchedulerType) -> Observable { - return JustScheduled(element: element, scheduler: scheduler) + public static func just(_ element: Element, scheduler: ImmediateSchedulerType) -> Observable { + JustScheduled(element: element, scheduler: scheduler) } } -final fileprivate class JustScheduledSink : Sink { - typealias Parent = JustScheduled +final private class JustScheduledSink: Sink { + typealias Parent = JustScheduled - private let _parent: Parent + private let parent: Parent - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - let scheduler = _parent._scheduler - return scheduler.schedule(_parent._element) { element in + let scheduler = self.parent.scheduler + return scheduler.schedule(self.parent.element) { element in self.forwardOn(.next(element)) return scheduler.schedule(()) { _ in self.forwardOn(.completed) @@ -56,31 +56,31 @@ final fileprivate class JustScheduledSink : Sink { } } -final fileprivate class JustScheduled : Producer { - fileprivate let _scheduler: ImmediateSchedulerType - fileprivate let _element: Element +final private class JustScheduled: Producer { + fileprivate let scheduler: ImmediateSchedulerType + fileprivate let element: Element init(element: Element, scheduler: ImmediateSchedulerType) { - _scheduler = scheduler - _element = element + self.scheduler = scheduler + self.element = element } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = JustScheduledSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) } } -final fileprivate class Just : Producer { - private let _element: Element +final private class Just: Producer { + private let element: Element init(element: Element) { - _element = element + self.element = element } - override func subscribe(_ observer: O) -> Disposable where O.E == Element { - observer.on(.next(_element)) + override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { + observer.on(.next(self.element)) observer.on(.completed) return Disposables.create() } diff --git a/iOS/RxSwift/Observables/Map.swift b/iOS/RxSwift/Observables/Map.swift index df0e0d1a..69379443 100644 --- a/iOS/RxSwift/Observables/Map.swift +++ b/iOS/RxSwift/Observables/Map.swift @@ -17,22 +17,21 @@ extension ObservableType { - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source. */ - public func map(_ transform: @escaping (E) throws -> R) - -> Observable { - return self.asObservable().composeMap(transform) + public func map(_ transform: @escaping (Element) throws -> Result) + -> Observable { + Map(source: self.asObservable(), transform: transform) } } -final fileprivate class MapSink : Sink, ObserverType { +final private class MapSink: Sink, ObserverType { typealias Transform = (SourceType) throws -> ResultType - typealias ResultType = O.E - typealias Element = SourceType + typealias ResultType = Observer.Element - private let _transform: Transform - - init(transform: @escaping Transform, observer: O, cancel: Cancelable) { - _transform = transform + private let transform: Transform + + init(transform: @escaping Transform, observer: Observer, cancel: Cancelable) { + self.transform = transform super.init(observer: observer, cancel: cancel) } @@ -40,69 +39,38 @@ final fileprivate class MapSink : Sink, Observe switch event { case .next(let element): do { - let mappedElement = try _transform(element) - forwardOn(.next(mappedElement)) + let mappedElement = try self.transform(element) + self.forwardOn(.next(mappedElement)) } catch let e { - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() } case .error(let error): - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() case .completed: - forwardOn(.completed) - dispose() - } - } -} - -#if TRACE_RESOURCES - fileprivate var _numberOfMapOperators: AtomicInt = 0 - extension Resources { - public static var numberOfMapOperators: Int32 { - return _numberOfMapOperators.valueSnapshot() + self.forwardOn(.completed) + self.dispose() } } -#endif - -internal func _map(source: Observable, transform: @escaping (Element) throws -> R) -> Observable { - return Map(source: source, transform: transform) } -final fileprivate class Map: Producer { +final private class Map: Producer { typealias Transform = (SourceType) throws -> ResultType - private let _source: Observable + private let source: Observable - private let _transform: Transform + private let transform: Transform init(source: Observable, transform: @escaping Transform) { - _source = source - _transform = transform - -#if TRACE_RESOURCES - let _ = AtomicIncrement(&_numberOfMapOperators) -#endif + self.source = source + self.transform = transform } - override func composeMap(_ selector: @escaping (ResultType) throws -> R) -> Observable { - let originalSelector = _transform - return Map(source: _source, transform: { (s: SourceType) throws -> R in - let r: ResultType = try originalSelector(s) - return try selector(r) - }) - } - - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == ResultType { - let sink = MapSink(transform: _transform, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == ResultType { + let sink = MapSink(transform: self.transform, observer: observer, cancel: cancel) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } - - #if TRACE_RESOURCES - deinit { - let _ = AtomicDecrement(&_numberOfMapOperators) - } - #endif } diff --git a/iOS/RxSwift/Observables/Materialize.swift b/iOS/RxSwift/Observables/Materialize.swift index cf19b6da..e2577be5 100644 --- a/iOS/RxSwift/Observables/Materialize.swift +++ b/iOS/RxSwift/Observables/Materialize.swift @@ -12,32 +12,32 @@ extension ObservableType { - seealso: [materialize operator on reactivex.io](http://reactivex.io/documentation/operators/materialize-dematerialize.html) - returns: An observable sequence that wraps events in an Event. The returned Observable never errors, but it does complete after observing all of the events of the underlying Observable. */ - public func materialize() -> Observable> { - return Materialize(source: self.asObservable()) + public func materialize() -> Observable> { + Materialize(source: self.asObservable()) } } -fileprivate final class MaterializeSink: Sink, ObserverType where O.E == Event { - +private final class MaterializeSink: Sink, ObserverType where Observer.Element == Event { + func on(_ event: Event) { - forwardOn(.next(event)) + self.forwardOn(.next(event)) if event.isStopEvent { - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() } } } -final fileprivate class Materialize: Producer> { - private let _source: Observable - - init(source: Observable) { - _source = source +final private class Materialize: Producer> { + private let source: Observable + + init(source: Observable) { + self.source = source } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = MaterializeSink(observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } diff --git a/iOS/RxSwift/Observables/Merge.swift b/iOS/RxSwift/Observables/Merge.swift index 7ba17dd5..51a64629 100644 --- a/iOS/RxSwift/Observables/Merge.swift +++ b/iOS/RxSwift/Observables/Merge.swift @@ -16,9 +16,9 @@ extension ObservableType { - parameter selector: A transform function to apply to each element. - returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence. */ - public func flatMap(_ selector: @escaping (E) throws -> O) - -> Observable { - return FlatMap(source: asObservable(), selector: selector) + public func flatMap(_ selector: @escaping (Element) throws -> Source) + -> Observable { + return FlatMap(source: self.asObservable(), selector: selector) } } @@ -34,13 +34,13 @@ extension ObservableType { - parameter selector: A transform function to apply to element that was observed while no observable is executing in parallel. - returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence that was received while no other sequence was being calculated. */ - public func flatMapFirst(_ selector: @escaping (E) throws -> O) - -> Observable { - return FlatMapFirst(source: asObservable(), selector: selector) + public func flatMapFirst(_ selector: @escaping (Element) throws -> Source) + -> Observable { + return FlatMapFirst(source: self.asObservable(), selector: selector) } } -extension ObservableType where E : ObservableConvertibleType { +extension ObservableType where Element: ObservableConvertibleType { /** Merges elements from all observable sequences in the given enumerable sequence into a single observable sequence. @@ -49,8 +49,8 @@ extension ObservableType where E : ObservableConvertibleType { - returns: The observable sequence that merges the elements of the observable sequences. */ - public func merge() -> Observable { - return Merge(source: asObservable()) + public func merge() -> Observable { + Merge(source: self.asObservable()) } /** @@ -62,12 +62,12 @@ extension ObservableType where E : ObservableConvertibleType { - returns: The observable sequence that merges the elements of the inner sequences. */ public func merge(maxConcurrent: Int) - -> Observable { - return MergeLimited(source: asObservable(), maxConcurrent: maxConcurrent) + -> Observable { + MergeLimited(source: self.asObservable(), maxConcurrent: maxConcurrent) } } -extension ObservableType where E : ObservableConvertibleType { +extension ObservableType where Element: ObservableConvertibleType { /** Concatenates all inner observable sequences, as long as the previous observable sequence terminated successfully. @@ -76,8 +76,8 @@ extension ObservableType where E : ObservableConvertibleType { - returns: An observable sequence that contains the elements of each observed inner sequence, in sequential order. */ - public func concat() -> Observable { - return merge(maxConcurrent: 1) + public func concat() -> Observable { + self.merge(maxConcurrent: 1) } } @@ -90,8 +90,8 @@ extension ObservableType { - parameter sources: Collection of observable sequences to merge. - returns: The observable sequence that merges the elements of the observable sequences. */ - public static func merge(_ sources: C) -> Observable where C.Iterator.Element == Observable { - return MergeArray(sources: Array(sources)) + public static func merge(_ sources: Collection) -> Observable where Collection.Element == Observable { + MergeArray(sources: Array(sources)) } /** @@ -102,8 +102,8 @@ extension ObservableType { - parameter sources: Array of observable sequences to merge. - returns: The observable sequence that merges the elements of the observable sequences. */ - public static func merge(_ sources: [Observable]) -> Observable { - return MergeArray(sources: sources) + public static func merge(_ sources: [Observable]) -> Observable { + MergeArray(sources: sources) } /** @@ -114,8 +114,8 @@ extension ObservableType { - parameter sources: Collection of observable sequences to merge. - returns: The observable sequence that merges the elements of the observable sequences. */ - public static func merge(_ sources: Observable...) -> Observable { - return MergeArray(sources: sources) + public static func merge(_ sources: Observable...) -> Observable { + MergeArray(sources: sources) } } @@ -130,112 +130,110 @@ extension ObservableType { - returns: An observable sequence that contains the elements of each observed inner sequence, in sequential order. */ - public func concatMap(_ selector: @escaping (E) throws -> O) - -> Observable { - return ConcatMap(source: asObservable(), selector: selector) + public func concatMap(_ selector: @escaping (Element) throws -> Source) + -> Observable { + return ConcatMap(source: self.asObservable(), selector: selector) } } -fileprivate final class MergeLimitedSinkIter +private final class MergeLimitedSinkIter : ObserverType , LockOwnerType - , SynchronizedOnType where SourceSequence.E == Observer.E { - typealias E = Observer.E + , SynchronizedOnType where SourceSequence.Element == Observer.Element { + typealias Element = Observer.Element typealias DisposeKey = CompositeDisposable.DisposeKey typealias Parent = MergeLimitedSink - private let _parent: Parent - private let _disposeKey: DisposeKey + private let parent: Parent + private let disposeKey: DisposeKey - var _lock: RecursiveLock { - return _parent._lock + var lock: RecursiveLock { + self.parent.lock } init(parent: Parent, disposeKey: DisposeKey) { - _parent = parent - _disposeKey = disposeKey + self.parent = parent + self.disposeKey = disposeKey } - func on(_ event: Event) { - synchronizedOn(event) + func on(_ event: Event) { + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case .next: - _parent.forwardOn(event) + self.parent.forwardOn(event) case .error: - _parent.forwardOn(event) - _parent.dispose() + self.parent.forwardOn(event) + self.parent.dispose() case .completed: - _parent._group.remove(for: _disposeKey) - if let next = _parent._queue.dequeue() { - _parent.subscribe(next, group: _parent._group) + self.parent.group.remove(for: self.disposeKey) + if let next = self.parent.queue.dequeue() { + self.parent.subscribe(next, group: self.parent.group) } else { - _parent._activeCount = _parent._activeCount - 1 + self.parent.activeCount -= 1 - if _parent._stopped && _parent._activeCount == 0 { - _parent.forwardOn(.completed) - _parent.dispose() + if self.parent.stopped && self.parent.activeCount == 0 { + self.parent.forwardOn(.completed) + self.parent.dispose() } } } } } -fileprivate final class ConcatMapSink: MergeLimitedSink where Observer.E == SourceSequence.E { +private final class ConcatMapSink: MergeLimitedSink where Observer.Element == SourceSequence.Element { typealias Selector = (SourceElement) throws -> SourceSequence - private let _selector: Selector + private let selector: Selector init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) { - _selector = selector + self.selector = selector super.init(maxConcurrent: 1, observer: observer, cancel: cancel) } override func performMap(_ element: SourceElement) throws -> SourceSequence { - return try _selector(element) + try self.selector(element) } } -fileprivate final class MergeLimitedBasicSink: MergeLimitedSink where Observer.E == SourceSequence.E { +private final class MergeLimitedBasicSink: MergeLimitedSink where Observer.Element == SourceSequence.Element { override func performMap(_ element: SourceSequence) throws -> SourceSequence { - return element + element } } -fileprivate class MergeLimitedSink +private class MergeLimitedSink : Sink - , ObserverType where Observer.E == SourceSequence.E { + , ObserverType where Observer.Element == SourceSequence.Element { typealias QueueType = Queue - let _maxConcurrent: Int + let maxConcurrent: Int - let _lock = RecursiveLock() + let lock = RecursiveLock() // state - var _stopped = false - var _activeCount = 0 - var _queue = QueueType(capacity: 2) + var stopped = false + var activeCount = 0 + var queue = QueueType(capacity: 2) - let _sourceSubscription = SingleAssignmentDisposable() - let _group = CompositeDisposable() + let sourceSubscription = SingleAssignmentDisposable() + let group = CompositeDisposable() init(maxConcurrent: Int, observer: Observer, cancel: Cancelable) { - _maxConcurrent = maxConcurrent - - let _ = _group.insert(_sourceSubscription) + self.maxConcurrent = maxConcurrent super.init(observer: observer, cancel: cancel) } func run(_ source: Observable) -> Disposable { - let _ = _group.insert(_sourceSubscription) + _ = self.group.insert(self.sourceSubscription) let disposable = source.subscribe(self) - _sourceSubscription.setDisposable(disposable) - return _group + self.sourceSubscription.setDisposable(disposable) + return self.group } func subscribe(_ innerSource: SourceSequence, group: CompositeDisposable) { @@ -257,174 +255,174 @@ fileprivate class MergeLimitedSink SourceSequence? { - _lock.lock(); defer { _lock.unlock() } // { + self.lock.performLocked { let subscribe: Bool - if _activeCount < _maxConcurrent { - _activeCount += 1 + if self.activeCount < self.maxConcurrent { + self.activeCount += 1 subscribe = true } else { do { - let value = try performMap(element) - _queue.enqueue(value) + let value = try self.performMap(element) + self.queue.enqueue(value) } catch { - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() } subscribe = false } if subscribe { do { - return try performMap(element) + return try self.performMap(element) } catch { - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() } } return nil - // } + } } func on(_ event: Event) { switch event { case .next(let element): if let sequence = self.nextElementArrived(element: element) { - self.subscribe(sequence, group: _group) + self.subscribe(sequence, group: self.group) } case .error(let error): - _lock.lock(); defer { _lock.unlock() } - - forwardOn(.error(error)) - dispose() + self.lock.performLocked { + self.forwardOn(.error(error)) + self.dispose() + } case .completed: - _lock.lock(); defer { _lock.unlock() } + self.lock.performLocked { + if self.activeCount == 0 { + self.forwardOn(.completed) + self.dispose() + } + else { + self.sourceSubscription.dispose() + } - if _activeCount == 0 { - forwardOn(.completed) - dispose() + self.stopped = true } - else { - _sourceSubscription.dispose() - } - - _stopped = true } } } -final fileprivate class MergeLimited : Producer { - private let _source: Observable - private let _maxConcurrent: Int +final private class MergeLimited: Producer { + private let source: Observable + private let maxConcurrent: Int init(source: Observable, maxConcurrent: Int) { - _source = source - _maxConcurrent = maxConcurrent + self.source = source + self.maxConcurrent = maxConcurrent } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceSequence.E { - let sink = MergeLimitedBasicSink(maxConcurrent: _maxConcurrent, observer: observer, cancel: cancel) - let subscription = sink.run(_source) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceSequence.Element { + let sink = MergeLimitedBasicSink(maxConcurrent: self.maxConcurrent, observer: observer, cancel: cancel) + let subscription = sink.run(self.source) return (sink: sink, subscription: subscription) } } // MARK: Merge -fileprivate final class MergeBasicSink : MergeSink where O.E == S.E { - override func performMap(_ element: S) throws -> S { - return element +private final class MergeBasicSink : MergeSink where Observer.Element == Source.Element { + override func performMap(_ element: Source) throws -> Source { + element } } // MARK: flatMap -fileprivate final class FlatMapSink : MergeSink where Observer.E == SourceSequence.E { +private final class FlatMapSink : MergeSink where Observer.Element == SourceSequence.Element { typealias Selector = (SourceElement) throws -> SourceSequence - private let _selector: Selector + private let selector: Selector init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) { - _selector = selector + self.selector = selector super.init(observer: observer, cancel: cancel) } override func performMap(_ element: SourceElement) throws -> SourceSequence { - return try _selector(element) + try self.selector(element) } } // MARK: FlatMapFirst -fileprivate final class FlatMapFirstSink : MergeSink where Observer.E == SourceSequence.E { +private final class FlatMapFirstSink : MergeSink where Observer.Element == SourceSequence.Element { typealias Selector = (SourceElement) throws -> SourceSequence - private let _selector: Selector + private let selector: Selector override var subscribeNext: Bool { - return _activeCount == 0 + self.activeCount == 0 } init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) { - _selector = selector + self.selector = selector super.init(observer: observer, cancel: cancel) } override func performMap(_ element: SourceElement) throws -> SourceSequence { - return try _selector(element) + try self.selector(element) } } -fileprivate final class MergeSinkIter : ObserverType where Observer.E == SourceSequence.E { +private final class MergeSinkIter : ObserverType where Observer.Element == SourceSequence.Element { typealias Parent = MergeSink typealias DisposeKey = CompositeDisposable.DisposeKey - typealias E = Observer.E + typealias Element = Observer.Element - private let _parent: Parent - private let _disposeKey: DisposeKey + private let parent: Parent + private let disposeKey: DisposeKey init(parent: Parent, disposeKey: DisposeKey) { - _parent = parent - _disposeKey = disposeKey + self.parent = parent + self.disposeKey = disposeKey } - func on(_ event: Event) { - _parent._lock.lock(); defer { _parent._lock.unlock() } // lock { + func on(_ event: Event) { + self.parent.lock.performLocked { switch event { case .next(let value): - _parent.forwardOn(.next(value)) + self.parent.forwardOn(.next(value)) case .error(let error): - _parent.forwardOn(.error(error)) - _parent.dispose() + self.parent.forwardOn(.error(error)) + self.parent.dispose() case .completed: - _parent._group.remove(for: _disposeKey) - _parent._activeCount -= 1 - _parent.checkCompleted() + self.parent.group.remove(for: self.disposeKey) + self.parent.activeCount -= 1 + self.parent.checkCompleted() } - // } + } } } -fileprivate class MergeSink +private class MergeSink : Sink - , ObserverType where Observer.E == SourceSequence.E { - typealias ResultType = Observer.E + , ObserverType where Observer.Element == SourceSequence.Element { + typealias ResultType = Observer.Element typealias Element = SourceElement - let _lock = RecursiveLock() + let lock = RecursiveLock() var subscribeNext: Bool { - return true + true } // state - let _group = CompositeDisposable() - let _sourceSubscription = SingleAssignmentDisposable() + let group = CompositeDisposable() + let sourceSubscription = SingleAssignmentDisposable() - var _activeCount = 0 - var _stopped = false + var activeCount = 0 + var stopped = false override init(observer: Observer, cancel: Cancelable) { super.init(observer: observer, cancel: cancel) @@ -436,165 +434,167 @@ fileprivate class MergeSink SourceSequence? { - _lock.lock(); defer { _lock.unlock() } // { - if !subscribeNext { + self.lock.performLocked { + if !self.subscribeNext { return nil } do { - let value = try performMap(element) - _activeCount += 1 + let value = try self.performMap(element) + self.activeCount += 1 return value } catch let e { - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() return nil } - // } + } } func on(_ event: Event) { switch event { case .next(let element): - if let value = nextElementArrived(element: element) { - subscribeInner(value.asObservable()) + if let value = self.nextElementArrived(element: element) { + self.subscribeInner(value.asObservable()) } case .error(let error): - _lock.lock(); defer { _lock.unlock() } - forwardOn(.error(error)) - dispose() + self.lock.performLocked { + self.forwardOn(.error(error)) + self.dispose() + } case .completed: - _lock.lock(); defer { _lock.unlock() } - _stopped = true - _sourceSubscription.dispose() - checkCompleted() + self.lock.performLocked { + self.stopped = true + self.sourceSubscription.dispose() + self.checkCompleted() + } } } - func subscribeInner(_ source: Observable) { + func subscribeInner(_ source: Observable) { let iterDisposable = SingleAssignmentDisposable() - if let disposeKey = _group.insert(iterDisposable) { + if let disposeKey = self.group.insert(iterDisposable) { let iter = MergeSinkIter(parent: self, disposeKey: disposeKey) let subscription = source.subscribe(iter) iterDisposable.setDisposable(subscription) } } - func run(_ sources: [Observable]) -> Disposable { - _activeCount += sources.count + func run(_ sources: [Observable]) -> Disposable { + self.activeCount += sources.count for source in sources { - subscribeInner(source) + self.subscribeInner(source) } - _stopped = true + self.stopped = true - checkCompleted() + self.checkCompleted() - return _group + return self.group } @inline(__always) func checkCompleted() { - if _stopped && _activeCount == 0 { + if self.stopped && self.activeCount == 0 { self.forwardOn(.completed) self.dispose() } } func run(_ source: Observable) -> Disposable { - let _ = _group.insert(_sourceSubscription) + _ = self.group.insert(self.sourceSubscription) let subscription = source.subscribe(self) - _sourceSubscription.setDisposable(subscription) + self.sourceSubscription.setDisposable(subscription) - return _group + return self.group } } // MARK: Producers -final fileprivate class FlatMap: Producer { +final private class FlatMap: Producer { typealias Selector = (SourceElement) throws -> SourceSequence - private let _source: Observable + private let source: Observable - private let _selector: Selector + private let selector: Selector init(source: Observable, selector: @escaping Selector) { - _source = source - _selector = selector + self.source = source + self.selector = selector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceSequence.E { - let sink = FlatMapSink(selector: _selector, observer: observer, cancel: cancel) - let subscription = sink.run(_source) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceSequence.Element { + let sink = FlatMapSink(selector: self.selector, observer: observer, cancel: cancel) + let subscription = sink.run(self.source) return (sink: sink, subscription: subscription) } } -final fileprivate class FlatMapFirst: Producer { +final private class FlatMapFirst: Producer { typealias Selector = (SourceElement) throws -> SourceSequence - private let _source: Observable + private let source: Observable - private let _selector: Selector + private let selector: Selector init(source: Observable, selector: @escaping Selector) { - _source = source - _selector = selector + self.source = source + self.selector = selector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceSequence.E { - let sink = FlatMapFirstSink(selector: _selector, observer: observer, cancel: cancel) - let subscription = sink.run(_source) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceSequence.Element { + let sink = FlatMapFirstSink(selector: self.selector, observer: observer, cancel: cancel) + let subscription = sink.run(self.source) return (sink: sink, subscription: subscription) } } -final class ConcatMap: Producer { +final class ConcatMap: Producer { typealias Selector = (SourceElement) throws -> SourceSequence - private let _source: Observable - private let _selector: Selector + private let source: Observable + private let selector: Selector init(source: Observable, selector: @escaping Selector) { - _source = source - _selector = selector + self.source = source + self.selector = selector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceSequence.E { - let sink = ConcatMapSink(selector: _selector, observer: observer, cancel: cancel) - let subscription = sink.run(_source) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceSequence.Element { + let sink = ConcatMapSink(selector: self.selector, observer: observer, cancel: cancel) + let subscription = sink.run(self.source) return (sink: sink, subscription: subscription) } } -final class Merge : Producer { - private let _source: Observable +final class Merge : Producer { + private let source: Observable init(source: Observable) { - _source = source + self.source = source } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceSequence.E { - let sink = MergeBasicSink(observer: observer, cancel: cancel) - let subscription = sink.run(_source) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceSequence.Element { + let sink = MergeBasicSink(observer: observer, cancel: cancel) + let subscription = sink.run(self.source) return (sink: sink, subscription: subscription) } } -final fileprivate class MergeArray : Producer { - private let _sources: [Observable] +final private class MergeArray: Producer { + private let sources: [Observable] init(sources: [Observable]) { - _sources = sources + self.sources = sources } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E { - let sink = MergeBasicSink, O>(observer: observer, cancel: cancel) - let subscription = sink.run(_sources) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = MergeBasicSink, Observer>(observer: observer, cancel: cancel) + let subscription = sink.run(self.sources) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Multicast.swift b/iOS/RxSwift/Observables/Multicast.swift index a027c4f6..1ebcf021 100644 --- a/iOS/RxSwift/Observables/Multicast.swift +++ b/iOS/RxSwift/Observables/Multicast.swift @@ -24,22 +24,22 @@ public class ConnectableObservable } extension ObservableType { - + /** - Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. - + Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. + Each subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's invocation. For specializations with fixed subject types, see `publish` and `replay`. - seealso: [multicast operator on reactivex.io](http://reactivex.io/documentation/operators/publish.html) - + - parameter subjectSelector: Factory function to create an intermediate subject through which the source sequence's elements will be multicast to the selector function. - parameter selector: Selector function which can use the multicasted source sequence subject to the policies enforced by the created subject. - returns: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function. */ - public func multicast(_ subjectSelector: @escaping () throws -> S, selector: @escaping (Observable) throws -> Observable) - -> Observable where S.SubjectObserverType.E == E { + public func multicast(_ subjectSelector: @escaping () throws -> Subject, selector: @escaping (Observable) throws -> Observable) + -> Observable where Subject.Observer.Element == Element { return Multicast( source: self.asObservable(), subjectSelector: subjectSelector, @@ -49,18 +49,18 @@ extension ObservableType { } extension ObservableType { - + /** - Returns a connectable observable sequence that shares a single subscription to the underlying sequence. - + Returns a connectable observable sequence that shares a single subscription to the underlying sequence. + This operator is a specialization of `multicast` using a `PublishSubject`. - seealso: [publish operator on reactivex.io](http://reactivex.io/documentation/operators/publish.html) - + - returns: A connectable observable sequence that shares a single subscription to the underlying sequence. */ - public func publish() -> ConnectableObservable { - return self.multicast { PublishSubject() } + public func publish() -> ConnectableObservable { + self.multicast { PublishSubject() } } } @@ -77,8 +77,8 @@ extension ObservableType { - returns: A connectable observable sequence that shares a single subscription to the underlying sequence. */ public func replay(_ bufferSize: Int) - -> ConnectableObservable { - return self.multicast { ReplaySubject.create(bufferSize: bufferSize) } + -> ConnectableObservable { + self.multicast { ReplaySubject.create(bufferSize: bufferSize) } } /** @@ -91,22 +91,22 @@ extension ObservableType { - returns: A connectable observable sequence that shares a single subscription to the underlying sequence. */ public func replayAll() - -> ConnectableObservable { - return self.multicast { ReplaySubject.createUnbounded() } + -> ConnectableObservable { + self.multicast { ReplaySubject.createUnbounded() } } } extension ConnectableObservableType { - + /** Returns an observable sequence that stays connected to the source as long as there is at least one subscription to the observable sequence. - seealso: [refCount operator on reactivex.io](http://reactivex.io/documentation/operators/refcount.html) - + - returns: An observable sequence that stays connected to the source as long as there is at least one subscription to the observable sequence. */ - public func refCount() -> Observable { - return RefCount(source: self) + public func refCount() -> Observable { + RefCount(source: self) } } @@ -124,16 +124,16 @@ extension ObservableType { - parameter subject: Subject to push source elements into. - returns: A connectable observable sequence that upon connection causes the source sequence to push results into the specified subject. */ - public func multicast(_ subject: S) - -> ConnectableObservable where S.SubjectObserverType.E == E { - return ConnectableObservableAdapter(source: self.asObservable(), makeSubject: { subject }) + public func multicast(_ subject: Subject) + -> ConnectableObservable where Subject.Observer.Element == Element { + ConnectableObservableAdapter(source: self.asObservable(), makeSubject: { subject }) } /** Multicasts the source sequence notifications through an instantiated subject to the resulting connectable observable. Upon connection of the connectable observable, the subject is subscribed to the source exactly one, and messages are forwarded to the observers registered with the connectable observable. - + Subject is cleared on connection disposal or in case source sequence produces terminal event. - seealso: [multicast operator on reactivex.io](http://reactivex.io/documentation/operators/publish.html) @@ -141,266 +141,263 @@ extension ObservableType { - parameter makeSubject: Factory function used to instantiate a subject for each connection. - returns: A connectable observable sequence that upon connection causes the source sequence to push results into the specified subject. */ - public func multicast(makeSubject: @escaping () -> S) - -> ConnectableObservable where S.SubjectObserverType.E == E { - return ConnectableObservableAdapter(source: self.asObservable(), makeSubject: makeSubject) + public func multicast(makeSubject: @escaping () -> Subject) + -> ConnectableObservable where Subject.Observer.Element == Element { + ConnectableObservableAdapter(source: self.asObservable(), makeSubject: makeSubject) } } -final fileprivate class Connection : ObserverType, Disposable { - typealias E = S.SubjectObserverType.E +final private class Connection: ObserverType, Disposable { + typealias Element = Subject.Observer.Element - private var _lock: RecursiveLock + private var lock: RecursiveLock // state - private var _parent: ConnectableObservableAdapter? - private var _subscription : Disposable? - private var _subjectObserver: S.SubjectObserverType + private var parent: ConnectableObservableAdapter? + private var subscription : Disposable? + private var subjectObserver: Subject.Observer - private var _disposed: Bool = false + private let disposed = AtomicInt(0) - init(parent: ConnectableObservableAdapter, subjectObserver: S.SubjectObserverType, lock: RecursiveLock, subscription: Disposable) { - _parent = parent - _subscription = subscription - _lock = lock - _subjectObserver = subjectObserver + init(parent: ConnectableObservableAdapter, subjectObserver: Subject.Observer, lock: RecursiveLock, subscription: Disposable) { + self.parent = parent + self.subscription = subscription + self.lock = lock + self.subjectObserver = subjectObserver } - func on(_ event: Event) { - if _disposed { + func on(_ event: Event) { + if isFlagSet(self.disposed, 1) { return } if event.isStopEvent { self.dispose() } - _subjectObserver.on(event) + self.subjectObserver.on(event) } func dispose() { - _lock.lock(); defer { _lock.unlock() } // { - _disposed = true - guard let parent = _parent else { + lock.lock(); defer { lock.unlock() } + fetchOr(self.disposed, 1) + guard let parent = self.parent else { return } - if parent._connection === self { - parent._connection = nil - parent._subject = nil + if parent.connection === self { + parent.connection = nil + parent.subject = nil } - _parent = nil + self.parent = nil - _subscription?.dispose() - _subscription = nil - // } + self.subscription?.dispose() + self.subscription = nil } } -final fileprivate class ConnectableObservableAdapter - : ConnectableObservable { - typealias ConnectionType = Connection +final private class ConnectableObservableAdapter + : ConnectableObservable { + typealias ConnectionType = Connection - fileprivate let _source: Observable - fileprivate let _makeSubject: () -> S + private let source: Observable + private let makeSubject: () -> Subject - fileprivate let _lock = RecursiveLock() - fileprivate var _subject: S? + fileprivate let lock = RecursiveLock() + fileprivate var subject: Subject? // state - fileprivate var _connection: ConnectionType? + fileprivate var connection: ConnectionType? - init(source: Observable, makeSubject: @escaping () -> S) { - _source = source - _makeSubject = makeSubject - _subject = nil - _connection = nil + init(source: Observable, makeSubject: @escaping () -> Subject) { + self.source = source + self.makeSubject = makeSubject + self.subject = nil + self.connection = nil } override func connect() -> Disposable { - return _lock.calculateLocked { - if let connection = _connection { + return self.lock.performLocked { + if let connection = self.connection { return connection } let singleAssignmentDisposable = SingleAssignmentDisposable() - let connection = Connection(parent: self, subjectObserver: self.lazySubject.asObserver(), lock: _lock, subscription: singleAssignmentDisposable) - _connection = connection - let subscription = _source.subscribe(connection) + let connection = Connection(parent: self, subjectObserver: self.lazySubject.asObserver(), lock: self.lock, subscription: singleAssignmentDisposable) + self.connection = connection + let subscription = self.source.subscribe(connection) singleAssignmentDisposable.setDisposable(subscription) return connection } } - fileprivate var lazySubject: S { - if let subject = self._subject { + private var lazySubject: Subject { + if let subject = self.subject { return subject } - let subject = _makeSubject() - self._subject = subject + let subject = self.makeSubject() + self.subject = subject return subject } - override func subscribe(_ observer: O) -> Disposable where O.E == S.E { - return self.lazySubject.subscribe(observer) + override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Subject.Element { + self.lazySubject.subscribe(observer) } } -final fileprivate class RefCountSink - : Sink - , ObserverType where CO.E == O.E { - typealias Element = O.E - typealias Parent = RefCount +final private class RefCountSink + : Sink + , ObserverType where ConnectableSource.Element == Observer.Element { + typealias Element = Observer.Element + typealias Parent = RefCount - private let _parent: Parent + private let parent: Parent - private var _connectionIdSnapshot: Int64 = -1 + private var connectionIdSnapshot: Int64 = -1 - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - let subscription = _parent._source.subscribe(self) - _parent._lock.lock(); defer { _parent._lock.unlock() } // { + let subscription = self.parent.source.subscribe(self) + self.parent.lock.lock(); defer { self.parent.lock.unlock() } - _connectionIdSnapshot = _parent._connectionId + self.connectionIdSnapshot = self.parent.connectionId - if self.disposed { + if self.isDisposed { return Disposables.create() } - if _parent._count == 0 { - _parent._count = 1 - _parent._connectableSubscription = _parent._source.connect() + if self.parent.count == 0 { + self.parent.count = 1 + self.parent.connectableSubscription = self.parent.source.connect() } else { - _parent._count = _parent._count + 1 + self.parent.count += 1 } - // } return Disposables.create { subscription.dispose() - self._parent._lock.lock(); defer { self._parent._lock.unlock() } // { - if self._parent._connectionId != self._connectionIdSnapshot { + self.parent.lock.lock(); defer { self.parent.lock.unlock() } + if self.parent.connectionId != self.connectionIdSnapshot { return } - if self._parent._count == 1 { - self._parent._count = 0 - guard let connectableSubscription = self._parent._connectableSubscription else { + if self.parent.count == 1 { + self.parent.count = 0 + guard let connectableSubscription = self.parent.connectableSubscription else { return } connectableSubscription.dispose() - self._parent._connectableSubscription = nil + self.parent.connectableSubscription = nil } - else if self._parent._count > 1 { - self._parent._count = self._parent._count - 1 + else if self.parent.count > 1 { + self.parent.count -= 1 } else { rxFatalError("Something went wrong with RefCount disposing mechanism") } - // } } } func on(_ event: Event) { switch event { case .next: - forwardOn(event) + self.forwardOn(event) case .error, .completed: - _parent._lock.lock() // { - if _parent._connectionId == self._connectionIdSnapshot { - let connection = _parent._connectableSubscription - defer { connection?.dispose() } - _parent._count = 0 - _parent._connectionId = _parent._connectionId &+ 1 - _parent._connectableSubscription = nil - } - // } - _parent._lock.unlock() - forwardOn(event) - dispose() + self.parent.lock.lock() + if self.parent.connectionId == self.connectionIdSnapshot { + let connection = self.parent.connectableSubscription + defer { connection?.dispose() } + self.parent.count = 0 + self.parent.connectionId = self.parent.connectionId &+ 1 + self.parent.connectableSubscription = nil + } + self.parent.lock.unlock() + self.forwardOn(event) + self.dispose() } } } -final fileprivate class RefCount: Producer { - fileprivate let _lock = RecursiveLock() +final private class RefCount: Producer { + fileprivate let lock = RecursiveLock() // state - fileprivate var _count = 0 - fileprivate var _connectionId: Int64 = 0 - fileprivate var _connectableSubscription = nil as Disposable? + fileprivate var count = 0 + fileprivate var connectionId: Int64 = 0 + fileprivate var connectableSubscription = nil as Disposable? - fileprivate let _source: CO + fileprivate let source: ConnectableSource - init(source: CO) { - _source = source + init(source: ConnectableSource) { + self.source = source } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == CO.E { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) + where Observer.Element == ConnectableSource.Element { let sink = RefCountSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) } } -final fileprivate class MulticastSink: Sink, ObserverType { - typealias Element = O.E +final private class MulticastSink: Sink, ObserverType { + typealias Element = Observer.Element typealias ResultType = Element - typealias MutlicastType = Multicast - - private let _parent: MutlicastType - - init(parent: MutlicastType, observer: O, cancel: Cancelable) { - _parent = parent + typealias MutlicastType = Multicast + + private let parent: MutlicastType + + init(parent: MutlicastType, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } - + func run() -> Disposable { do { - let subject = try _parent._subjectSelector() - let connectable = ConnectableObservableAdapter(source: _parent._source, makeSubject: { subject }) - - let observable = try _parent._selector(connectable) - + let subject = try self.parent.subjectSelector() + let connectable = ConnectableObservableAdapter(source: self.parent.source, makeSubject: { subject }) + + let observable = try self.parent.selector(connectable) + let subscription = observable.subscribe(self) let connection = connectable.connect() - + return Disposables.create(subscription, connection) } catch let e { - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() return Disposables.create() } } - + func on(_ event: Event) { - forwardOn(event) + self.forwardOn(event) switch event { - case .next: break - case .error, .completed: - dispose() + case .next: break + case .error, .completed: + self.dispose() } } } -final fileprivate class Multicast: Producer { - typealias SubjectSelectorType = () throws -> S - typealias SelectorType = (Observable) throws -> Observable - - fileprivate let _source: Observable - fileprivate let _subjectSelector: SubjectSelectorType - fileprivate let _selector: SelectorType - - init(source: Observable, subjectSelector: @escaping SubjectSelectorType, selector: @escaping SelectorType) { - _source = source - _subjectSelector = subjectSelector - _selector = selector +final private class Multicast: Producer { + typealias SubjectSelectorType = () throws -> Subject + typealias SelectorType = (Observable) throws -> Observable + + fileprivate let source: Observable + fileprivate let subjectSelector: SubjectSelectorType + fileprivate let selector: SelectorType + + init(source: Observable, subjectSelector: @escaping SubjectSelectorType, selector: @escaping SelectorType) { + self.source = source + self.subjectSelector = subjectSelector + self.selector = selector } - - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = MulticastSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/Never.swift b/iOS/RxSwift/Observables/Never.swift index d98a7a8f..7b456eed 100644 --- a/iOS/RxSwift/Observables/Never.swift +++ b/iOS/RxSwift/Observables/Never.swift @@ -15,13 +15,13 @@ extension ObservableType { - returns: An observable sequence whose observers will never get called. */ - public static func never() -> Observable { - return NeverProducer() + public static func never() -> Observable { + NeverProducer() } } -final fileprivate class NeverProducer : Producer { - override func subscribe(_ observer: O) -> Disposable where O.E == Element { - return Disposables.create() +final private class NeverProducer: Producer { + override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { + Disposables.create() } } diff --git a/iOS/RxSwift/Observables/ObserveOn.swift b/iOS/RxSwift/Observables/ObserveOn.swift index ce2a0d45..6b8689e1 100644 --- a/iOS/RxSwift/Observables/ObserveOn.swift +++ b/iOS/RxSwift/Observables/ObserveOn.swift @@ -7,6 +7,26 @@ // extension ObservableType { + /** + Wraps the source sequence in order to run its observer callbacks on the specified scheduler. + + This only invokes observer callbacks on a `scheduler`. In case the subscription and/or unsubscription + actions have side-effects that require to be run on a scheduler, use `subscribeOn`. + + - seealso: [observeOn operator on reactivex.io](http://reactivex.io/documentation/operators/observeon.html) + + - parameter scheduler: Scheduler to notify observers on. + - returns: The source sequence whose observations happen on the specified scheduler. + */ + public func observe(on scheduler: ImmediateSchedulerType) + -> Observable { + guard let serialScheduler = scheduler as? SerialDispatchQueueScheduler else { + return ObserveOn(source: self.asObservable(), scheduler: scheduler) + } + + return ObserveOnSerialDispatchQueue(source: self.asObservable(), + scheduler: serialScheduler) + } /** Wraps the source sequence in order to run its observer callbacks on the specified scheduler. @@ -19,39 +39,35 @@ extension ObservableType { - parameter scheduler: Scheduler to notify observers on. - returns: The source sequence whose observations happen on the specified scheduler. */ + @available(*, deprecated, renamed: "observe(on:)") public func observeOn(_ scheduler: ImmediateSchedulerType) - -> Observable { - if let scheduler = scheduler as? SerialDispatchQueueScheduler { - return ObserveOnSerialDispatchQueue(source: self.asObservable(), scheduler: scheduler) - } - else { - return ObserveOn(source: self.asObservable(), scheduler: scheduler) - } + -> Observable { + observe(on: scheduler) } } -final fileprivate class ObserveOn : Producer { +final private class ObserveOn: Producer { let scheduler: ImmediateSchedulerType - let source: Observable - - init(source: Observable, scheduler: ImmediateSchedulerType) { + let source: Observable + + init(source: Observable, scheduler: ImmediateSchedulerType) { self.scheduler = scheduler self.source = source - + #if TRACE_RESOURCES - let _ = Resources.incrementTotal() + _ = Resources.incrementTotal() #endif } - - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E { - let sink = ObserveOnSink(scheduler: scheduler, observer: observer, cancel: cancel) - let subscription = source.subscribe(sink) + + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = ObserveOnSink(scheduler: self.scheduler, observer: observer, cancel: cancel) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } - + #if TRACE_RESOURCES deinit { - let _ = Resources.decrementTotal() + _ = Resources.decrementTotal() } #endif } @@ -63,95 +79,91 @@ enum ObserveOnState : Int32 { case running = 1 } -final fileprivate class ObserveOnSink : ObserverBase { - typealias E = O.E - - let _scheduler: ImmediateSchedulerType +final private class ObserveOnSink: ObserverBase { + typealias Element = Observer.Element - var _lock = SpinLock() - let _observer: O + let scheduler: ImmediateSchedulerType + + var lock = SpinLock() + let observer: Observer // state - var _state = ObserveOnState.stopped - var _queue = Queue>(capacity: 10) + var state = ObserveOnState.stopped + var queue = Queue>(capacity: 10) - let _scheduleDisposable = SerialDisposable() - let _cancel: Cancelable + let scheduleDisposable = SerialDisposable() + let cancel: Cancelable - init(scheduler: ImmediateSchedulerType, observer: O, cancel: Cancelable) { - _scheduler = scheduler - _observer = observer - _cancel = cancel + init(scheduler: ImmediateSchedulerType, observer: Observer, cancel: Cancelable) { + self.scheduler = scheduler + self.observer = observer + self.cancel = cancel } - override func onCore(_ event: Event) { - let shouldStart = _lock.calculateLocked { () -> Bool in - self._queue.enqueue(event) - - switch self._state { + override func onCore(_ event: Event) { + let shouldStart = self.lock.performLocked { () -> Bool in + self.queue.enqueue(event) + + switch self.state { case .stopped: - self._state = .running + self.state = .running return true case .running: return false } } - + if shouldStart { - _scheduleDisposable.disposable = self._scheduler.scheduleRecursive((), action: self.run) + self.scheduleDisposable.disposable = self.scheduler.scheduleRecursive((), action: self.run) } } - - func run(_ state: (), _ recurse: (()) -> ()) { - let (nextEvent, observer) = self._lock.calculateLocked { () -> (Event?, O) in - if self._queue.count > 0 { - return (self._queue.dequeue(), self._observer) + + func run(_ state: (), _ recurse: (()) -> Void) { + let (nextEvent, observer) = self.lock.performLocked { () -> (Event?, Observer) in + if !self.queue.isEmpty { + return (self.queue.dequeue(), self.observer) } else { - self._state = .stopped - return (nil, self._observer) + self.state = .stopped + return (nil, self.observer) } } - if let nextEvent = nextEvent, !_cancel.isDisposed { + if let nextEvent = nextEvent, !self.cancel.isDisposed { observer.on(nextEvent) if nextEvent.isStopEvent { - dispose() + self.dispose() } } else { return } - let shouldContinue = _shouldContinue_synchronized() + let shouldContinue = self.shouldContinue_synchronized() if shouldContinue { recurse(()) } } - func _shouldContinue_synchronized() -> Bool { - _lock.lock(); defer { _lock.unlock() } // { - if self._queue.count > 0 { - return true - } - else { - self._state = .stopped - return false - } - // } + func shouldContinue_synchronized() -> Bool { + self.lock.performLocked { + let isEmpty = self.queue.isEmpty + if isEmpty { self.state = .stopped } + return !isEmpty + } } - + override func dispose() { super.dispose() - _cancel.dispose() - _scheduleDisposable.dispose() + self.cancel.dispose() + self.scheduleDisposable.dispose() } } #if TRACE_RESOURCES - fileprivate var _numberOfSerialDispatchQueueObservables: AtomicInt = 0 + private let numberOfSerialDispatchObservables = AtomicInt(0) extension Resources { /** Counts number of `SerialDispatchQueueObservables`. @@ -159,26 +171,28 @@ final fileprivate class ObserveOnSink : ObserverBase { Purposed for unit tests. */ public static var numberOfSerialDispatchQueueObservables: Int32 { - return _numberOfSerialDispatchQueueObservables.valueSnapshot() + return load(numberOfSerialDispatchObservables) } } #endif -final fileprivate class ObserveOnSerialDispatchQueueSink : ObserverBase { +final private class ObserveOnSerialDispatchQueueSink: ObserverBase { let scheduler: SerialDispatchQueueScheduler - let observer: O + let observer: Observer let cancel: Cancelable - var cachedScheduleLambda: (((sink: ObserveOnSerialDispatchQueueSink, event: Event)) -> Disposable)! + var cachedScheduleLambda: (((sink: ObserveOnSerialDispatchQueueSink, event: Event)) -> Disposable)! - init(scheduler: SerialDispatchQueueScheduler, observer: O, cancel: Cancelable) { + init(scheduler: SerialDispatchQueueScheduler, observer: Observer, cancel: Cancelable) { self.scheduler = scheduler self.observer = observer self.cancel = cancel super.init() - cachedScheduleLambda = { pair in + self.cachedScheduleLambda = { pair in + guard !cancel.isDisposed else { return Disposables.create() } + pair.sink.observer.on(pair.event) if pair.event.isStopEvent { @@ -189,41 +203,41 @@ final fileprivate class ObserveOnSerialDispatchQueueSink : Obse } } - override func onCore(_ event: Event) { - let _ = self.scheduler.schedule((self, event), action: cachedScheduleLambda!) + override func onCore(_ event: Event) { + _ = self.scheduler.schedule((self, event), action: self.cachedScheduleLambda!) } override func dispose() { super.dispose() - cancel.dispose() + self.cancel.dispose() } } -final fileprivate class ObserveOnSerialDispatchQueue : Producer { +final private class ObserveOnSerialDispatchQueue: Producer { let scheduler: SerialDispatchQueueScheduler - let source: Observable + let source: Observable - init(source: Observable, scheduler: SerialDispatchQueueScheduler) { + init(source: Observable, scheduler: SerialDispatchQueueScheduler) { self.scheduler = scheduler self.source = source #if TRACE_RESOURCES - let _ = Resources.incrementTotal() - let _ = AtomicIncrement(&_numberOfSerialDispatchQueueObservables) + _ = Resources.incrementTotal() + _ = increment(numberOfSerialDispatchObservables) #endif } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E { - let sink = ObserveOnSerialDispatchQueueSink(scheduler: scheduler, observer: observer, cancel: cancel) - let subscription = source.subscribe(sink) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = ObserveOnSerialDispatchQueueSink(scheduler: self.scheduler, observer: observer, cancel: cancel) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } #if TRACE_RESOURCES deinit { - let _ = Resources.decrementTotal() - let _ = AtomicDecrement(&_numberOfSerialDispatchQueueObservables) + _ = Resources.decrementTotal() + _ = decrement(numberOfSerialDispatchObservables) } #endif } diff --git a/iOS/RxSwift/Observables/Optional.swift b/iOS/RxSwift/Observables/Optional.swift index 52ba0d9d..64f8f1fd 100644 --- a/iOS/RxSwift/Observables/Optional.swift +++ b/iOS/RxSwift/Observables/Optional.swift @@ -15,8 +15,8 @@ extension ObservableType { - parameter optional: Optional element in the resulting observable sequence. - returns: An observable sequence containing the wrapped value or not from given optional. */ - public static func from(optional: E?) -> Observable { - return ObservableOptional(optional: optional) + public static func from(optional: Element?) -> Observable { + ObservableOptional(optional: optional) } /** @@ -25,30 +25,30 @@ extension ObservableType { - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - parameter optional: Optional element in the resulting observable sequence. - - parameter: Scheduler to send the optional element on. + - parameter scheduler: Scheduler to send the optional element on. - returns: An observable sequence containing the wrapped value or not from given optional. */ - public static func from(optional: E?, scheduler: ImmediateSchedulerType) -> Observable { - return ObservableOptionalScheduled(optional: optional, scheduler: scheduler) + public static func from(optional: Element?, scheduler: ImmediateSchedulerType) -> Observable { + ObservableOptionalScheduled(optional: optional, scheduler: scheduler) } } -final fileprivate class ObservableOptionalScheduledSink : Sink { - typealias E = O.E - typealias Parent = ObservableOptionalScheduled +final private class ObservableOptionalScheduledSink: Sink { + typealias Element = Observer.Element + typealias Parent = ObservableOptionalScheduled - private let _parent: Parent + private let parent: Parent - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - return _parent._scheduler.schedule(_parent._optional) { (optional: E?) -> Disposable in + return self.parent.scheduler.schedule(self.parent.optional) { (optional: Element?) -> Disposable in if let next = optional { self.forwardOn(.next(next)) - return self._parent._scheduler.schedule(()) { _ in + return self.parent.scheduler.schedule(()) { _ in self.forwardOn(.completed) self.dispose() return Disposables.create() @@ -62,31 +62,31 @@ final fileprivate class ObservableOptionalScheduledSink : Sink< } } -final fileprivate class ObservableOptionalScheduled : Producer { - fileprivate let _optional: E? - fileprivate let _scheduler: ImmediateSchedulerType +final private class ObservableOptionalScheduled: Producer { + fileprivate let optional: Element? + fileprivate let scheduler: ImmediateSchedulerType - init(optional: E?, scheduler: ImmediateSchedulerType) { - _optional = optional - _scheduler = scheduler + init(optional: Element?, scheduler: ImmediateSchedulerType) { + self.optional = optional + self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = ObservableOptionalScheduledSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) } } -final fileprivate class ObservableOptional: Producer { - private let _optional: E? +final private class ObservableOptional: Producer { + private let optional: Element? - init(optional: E?) { - _optional = optional + init(optional: Element?) { + self.optional = optional } - override func subscribe(_ observer: O) -> Disposable where O.E == E { - if let element = _optional { + override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { + if let element = self.optional { observer.on(.next(element)) } observer.on(.completed) diff --git a/iOS/RxSwift/Observables/Producer.swift b/iOS/RxSwift/Observables/Producer.swift index 996b0110..e611930a 100644 --- a/iOS/RxSwift/Observables/Producer.swift +++ b/iOS/RxSwift/Observables/Producer.swift @@ -6,16 +6,16 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -class Producer : Observable { +class Producer: Observable { override init() { super.init() } - - override func subscribe(_ observer: O) -> Disposable where O.E == Element { + + override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { if !CurrentThreadScheduler.isScheduleRequired { // The returned disposable needs to release all references once it was disposed. let disposer = SinkDisposer() - let sinkAndSubscription = run(observer, cancel: disposer) + let sinkAndSubscription = self.run(observer, cancel: disposer) disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription) return disposer @@ -30,69 +30,63 @@ class Producer : Observable { } } } - - func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + + func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { rxAbstractMethod() } } -fileprivate final class SinkDisposer: Cancelable { - fileprivate enum DisposeState: UInt32 { +private final class SinkDisposer: Cancelable { + private enum DisposeState: Int32 { case disposed = 1 case sinkAndSubscriptionSet = 2 } - // Jeej, swift API consistency rules - fileprivate enum DisposeStateInt32: Int32 { - case disposed = 1 - case sinkAndSubscriptionSet = 2 - } - - private var _state: AtomicInt = 0 - private var _sink: Disposable? = nil - private var _subscription: Disposable? = nil + private let state = AtomicInt(0) + private var sink: Disposable? + private var subscription: Disposable? var isDisposed: Bool { - return AtomicFlagSet(DisposeState.disposed.rawValue, &_state) + isFlagSet(self.state, DisposeState.disposed.rawValue) } func setSinkAndSubscription(sink: Disposable, subscription: Disposable) { - _sink = sink - _subscription = subscription + self.sink = sink + self.subscription = subscription - let previousState = AtomicOr(DisposeState.sinkAndSubscriptionSet.rawValue, &_state) - if (previousState & DisposeStateInt32.sinkAndSubscriptionSet.rawValue) != 0 { + let previousState = fetchOr(self.state, DisposeState.sinkAndSubscriptionSet.rawValue) + if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 { rxFatalError("Sink and subscription were already set") } - if (previousState & DisposeStateInt32.disposed.rawValue) != 0 { + if (previousState & DisposeState.disposed.rawValue) != 0 { sink.dispose() subscription.dispose() - _sink = nil - _subscription = nil + self.sink = nil + self.subscription = nil } } - + func dispose() { - let previousState = AtomicOr(DisposeState.disposed.rawValue, &_state) + let previousState = fetchOr(self.state, DisposeState.disposed.rawValue) - if (previousState & DisposeStateInt32.disposed.rawValue) != 0 { + if (previousState & DisposeState.disposed.rawValue) != 0 { return } - if (previousState & DisposeStateInt32.sinkAndSubscriptionSet.rawValue) != 0 { - guard let sink = _sink else { + if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 { + guard let sink = self.sink else { rxFatalError("Sink not set") } - guard let subscription = _subscription else { + guard let subscription = self.subscription else { rxFatalError("Subscription not set") } sink.dispose() subscription.dispose() - _sink = nil - _subscription = nil + self.sink = nil + self.subscription = nil } } } diff --git a/iOS/RxSwift/Observables/Range.swift b/iOS/RxSwift/Observables/Range.swift index 9b85554e..24535324 100644 --- a/iOS/RxSwift/Observables/Range.swift +++ b/iOS/RxSwift/Observables/Range.swift @@ -6,7 +6,7 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -extension ObservableType where E : RxAbstractInteger { +extension ObservableType where Element: RxAbstractInteger { /** Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to generate and send out observer messages. @@ -17,51 +17,51 @@ extension ObservableType where E : RxAbstractInteger { - parameter scheduler: Scheduler to run the generator loop on. - returns: An observable sequence that contains a range of sequential integral numbers. */ - public static func range(start: E, count: E, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { - return RangeProducer(start: start, count: count, scheduler: scheduler) + public static func range(start: Element, count: Element, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { + RangeProducer(start: start, count: count, scheduler: scheduler) } } -final fileprivate class RangeProducer : Producer { - fileprivate let _start: E - fileprivate let _count: E - fileprivate let _scheduler: ImmediateSchedulerType +final private class RangeProducer: Producer { + fileprivate let start: Element + fileprivate let count: Element + fileprivate let scheduler: ImmediateSchedulerType - init(start: E, count: E, scheduler: ImmediateSchedulerType) { - if count < 0 { + init(start: Element, count: Element, scheduler: ImmediateSchedulerType) { + guard count >= 0 else { rxFatalError("count can't be negative") } - if start &+ (count - 1) < start { + guard start &+ (count - 1) >= start || count == 0 else { rxFatalError("overflow of count") } - _start = start - _count = count - _scheduler = scheduler + self.start = start + self.count = count + self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = RangeSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) } } -final fileprivate class RangeSink : Sink where O.E: RxAbstractInteger { - typealias Parent = RangeProducer +final private class RangeSink: Sink where Observer.Element: RxAbstractInteger { + typealias Parent = RangeProducer - private let _parent: Parent + private let parent: Parent - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - return _parent._scheduler.scheduleRecursive(0 as O.E) { i, recurse in - if i < self._parent._count { - self.forwardOn(.next(self._parent._start + i)) + return self.parent.scheduler.scheduleRecursive(0 as Observer.Element) { i, recurse in + if i < self.parent.count { + self.forwardOn(.next(self.parent.start + i)) recurse(i + 1) } else { diff --git a/iOS/RxSwift/Observables/Reduce.swift b/iOS/RxSwift/Observables/Reduce.swift index 3e4a7b9d..d5fab347 100644 --- a/iOS/RxSwift/Observables/Reduce.swift +++ b/iOS/RxSwift/Observables/Reduce.swift @@ -20,9 +20,9 @@ extension ObservableType { - parameter mapResult: A function to transform the final accumulator value into the result value. - returns: An observable sequence containing a single element with the final accumulator value. */ - public func reduce(_ seed: A, accumulator: @escaping (A, E) throws -> A, mapResult: @escaping (A) throws -> R) - -> Observable { - return Reduce(source: self.asObservable(), seed: seed, accumulator: accumulator, mapResult: mapResult) + public func reduce(_ seed: A, accumulator: @escaping (A, Element) throws -> A, mapResult: @escaping (A) throws -> Result) + -> Observable { + Reduce(source: self.asObservable(), seed: seed, accumulator: accumulator, mapResult: mapResult) } /** @@ -36,22 +36,22 @@ extension ObservableType { - parameter accumulator: A accumulator function to be invoked on each element. - returns: An observable sequence containing a single element with the final accumulator value. */ - public func reduce(_ seed: A, accumulator: @escaping (A, E) throws -> A) + public func reduce(_ seed: A, accumulator: @escaping (A, Element) throws -> A) -> Observable { - return Reduce(source: self.asObservable(), seed: seed, accumulator: accumulator, mapResult: { $0 }) + Reduce(source: self.asObservable(), seed: seed, accumulator: accumulator, mapResult: { $0 }) } } -final fileprivate class ReduceSink : Sink, ObserverType { - typealias ResultType = O.E +final private class ReduceSink: Sink, ObserverType { + typealias ResultType = Observer.Element typealias Parent = Reduce - private let _parent: Parent - private var _accumulation: AccumulateType + private let parent: Parent + private var accumulation: AccumulateType - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - _accumulation = parent._seed + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + self.accumulation = parent.seed super.init(observer: observer, cancel: cancel) } @@ -60,49 +60,49 @@ final fileprivate class ReduceSink switch event { case .next(let value): do { - _accumulation = try _parent._accumulator(_accumulation, value) + self.accumulation = try self.parent.accumulator(self.accumulation, value) } catch let e { - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() } case .error(let e): - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() case .completed: do { - let result = try _parent._mapResult(_accumulation) - forwardOn(.next(result)) - forwardOn(.completed) - dispose() + let result = try self.parent.mapResult(self.accumulation) + self.forwardOn(.next(result)) + self.forwardOn(.completed) + self.dispose() } catch let e { - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() } } } } -final fileprivate class Reduce : Producer { +final private class Reduce: Producer { typealias AccumulatorType = (AccumulateType, SourceType) throws -> AccumulateType typealias ResultSelectorType = (AccumulateType) throws -> ResultType - fileprivate let _source: Observable - fileprivate let _seed: AccumulateType - fileprivate let _accumulator: AccumulatorType - fileprivate let _mapResult: ResultSelectorType + private let source: Observable + fileprivate let seed: AccumulateType + fileprivate let accumulator: AccumulatorType + fileprivate let mapResult: ResultSelectorType init(source: Observable, seed: AccumulateType, accumulator: @escaping AccumulatorType, mapResult: @escaping ResultSelectorType) { - _source = source - _seed = seed - _accumulator = accumulator - _mapResult = mapResult + self.source = source + self.seed = seed + self.accumulator = accumulator + self.mapResult = mapResult } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == ResultType { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == ResultType { let sink = ReduceSink(parent: self, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Repeat.swift b/iOS/RxSwift/Observables/Repeat.swift index 6892ec12..69a3ba02 100644 --- a/iOS/RxSwift/Observables/Repeat.swift +++ b/iOS/RxSwift/Observables/Repeat.swift @@ -16,21 +16,21 @@ extension ObservableType { - parameter scheduler: Scheduler to run the producer loop on. - returns: An observable sequence that repeats the given element infinitely. */ - public static func repeatElement(_ element: E, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { - return RepeatElement(element: element, scheduler: scheduler) + public static func repeatElement(_ element: Element, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { + RepeatElement(element: element, scheduler: scheduler) } } -final fileprivate class RepeatElement : Producer { - fileprivate let _element: Element - fileprivate let _scheduler: ImmediateSchedulerType +final private class RepeatElement: Producer { + fileprivate let element: Element + fileprivate let scheduler: ImmediateSchedulerType init(element: Element, scheduler: ImmediateSchedulerType) { - _element = element - _scheduler = scheduler + self.element = element + self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = RepeatElementSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() @@ -38,18 +38,18 @@ final fileprivate class RepeatElement : Producer { } } -final fileprivate class RepeatElementSink : Sink { - typealias Parent = RepeatElement +final private class RepeatElementSink: Sink { + typealias Parent = RepeatElement - private let _parent: Parent + private let parent: Parent - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - return _parent._scheduler.scheduleRecursive(_parent._element) { e, recurse in + return self.parent.scheduler.scheduleRecursive(self.parent.element) { e, recurse in self.forwardOn(.next(e)) recurse(e) } diff --git a/iOS/RxSwift/Observables/RetryWhen.swift b/iOS/RxSwift/Observables/RetryWhen.swift index 268b399a..1b2a6f13 100644 --- a/iOS/RxSwift/Observables/RetryWhen.swift +++ b/iOS/RxSwift/Observables/RetryWhen.swift @@ -7,6 +7,19 @@ // extension ObservableType { + /** + Repeats the source observable sequence on error when the notifier emits a next value. + If the source observable errors and the notifier completes, it will complete the source sequence. + + - seealso: [retry operator on reactivex.io](http://reactivex.io/documentation/operators/retry.html) + + - parameter notificationHandler: A handler that is passed an observable sequence of errors raised by the source observable and returns and observable that either continues, completes or errors. This behavior is then applied to the source observable. + - returns: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully or is notified to error or complete. + */ + public func retry(when notificationHandler: @escaping (Observable) -> TriggerObservable) + -> Observable { + RetryWhenSequence(sources: InfiniteSequence(repeatedValue: self.asObservable()), notificationHandler: notificationHandler) + } /** Repeats the source observable sequence on error when the notifier emits a next value. @@ -17,9 +30,24 @@ extension ObservableType { - parameter notificationHandler: A handler that is passed an observable sequence of errors raised by the source observable and returns and observable that either continues, completes or errors. This behavior is then applied to the source observable. - returns: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully or is notified to error or complete. */ + @available(*, deprecated, renamed: "retry(when:)") public func retryWhen(_ notificationHandler: @escaping (Observable) -> TriggerObservable) - -> Observable { - return RetryWhenSequence(sources: InfiniteSequence(repeatedValue: self.asObservable()), notificationHandler: notificationHandler) + -> Observable { + retry(when: notificationHandler) + } + + /** + Repeats the source observable sequence on error when the notifier emits a next value. + If the source observable errors and the notifier completes, it will complete the source sequence. + + - seealso: [retry operator on reactivex.io](http://reactivex.io/documentation/operators/retry.html) + + - parameter notificationHandler: A handler that is passed an observable sequence of errors raised by the source observable and returns and observable that either continues, completes or errors. This behavior is then applied to the source observable. + - returns: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully or is notified to error or complete. + */ + public func retry(when notificationHandler: @escaping (Observable) -> TriggerObservable) + -> Observable { + RetryWhenSequence(sources: InfiniteSequence(repeatedValue: self.asObservable()), notificationHandler: notificationHandler) } /** @@ -31,125 +59,126 @@ extension ObservableType { - parameter notificationHandler: A handler that is passed an observable sequence of errors raised by the source observable and returns and observable that either continues, completes or errors. This behavior is then applied to the source observable. - returns: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully or is notified to error or complete. */ + @available(*, deprecated, renamed: "retry(when:)") public func retryWhen(_ notificationHandler: @escaping (Observable) -> TriggerObservable) - -> Observable { - return RetryWhenSequence(sources: InfiniteSequence(repeatedValue: self.asObservable()), notificationHandler: notificationHandler) + -> Observable { + RetryWhenSequence(sources: InfiniteSequence(repeatedValue: self.asObservable()), notificationHandler: notificationHandler) } } -final fileprivate class RetryTriggerSink - : ObserverType where S.Iterator.Element : ObservableType, S.Iterator.Element.E == O.E { - typealias E = TriggerObservable.E +final private class RetryTriggerSink + : ObserverType where Sequence.Element: ObservableType, Sequence.Element.Element == Observer.Element { + typealias Element = TriggerObservable.Element - typealias Parent = RetryWhenSequenceSinkIter + typealias Parent = RetryWhenSequenceSinkIter - fileprivate let _parent: Parent + private let parent: Parent init(parent: Parent) { - _parent = parent + self.parent = parent } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next: - _parent._parent._lastError = nil - _parent._parent.schedule(.moveNext) + self.parent.parent.lastError = nil + self.parent.parent.schedule(.moveNext) case .error(let e): - _parent._parent.forwardOn(.error(e)) - _parent._parent.dispose() + self.parent.parent.forwardOn(.error(e)) + self.parent.parent.dispose() case .completed: - _parent._parent.forwardOn(.completed) - _parent._parent.dispose() + self.parent.parent.forwardOn(.completed) + self.parent.parent.dispose() } } } -final fileprivate class RetryWhenSequenceSinkIter +final private class RetryWhenSequenceSinkIter : ObserverType - , Disposable where S.Iterator.Element : ObservableType, S.Iterator.Element.E == O.E { - typealias E = O.E - typealias Parent = RetryWhenSequenceSink + , Disposable where Sequence.Element: ObservableType, Sequence.Element.Element == Observer.Element { + typealias Element = Observer.Element + typealias Parent = RetryWhenSequenceSink - fileprivate let _parent: Parent - fileprivate let _errorHandlerSubscription = SingleAssignmentDisposable() - fileprivate let _subscription: Disposable + fileprivate let parent: Parent + private let errorHandlerSubscription = SingleAssignmentDisposable() + private let subscription: Disposable init(parent: Parent, subscription: Disposable) { - _parent = parent - _subscription = subscription + self.parent = parent + self.subscription = subscription } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next: - _parent.forwardOn(event) + self.parent.forwardOn(event) case .error(let error): - _parent._lastError = error + self.parent.lastError = error if let failedWith = error as? Error { // dispose current subscription - _subscription.dispose() + self.subscription.dispose() - let errorHandlerSubscription = _parent._notifier.subscribe(RetryTriggerSink(parent: self)) - _errorHandlerSubscription.setDisposable(errorHandlerSubscription) - _parent._errorSubject.on(.next(failedWith)) + let errorHandlerSubscription = self.parent.notifier.subscribe(RetryTriggerSink(parent: self)) + self.errorHandlerSubscription.setDisposable(errorHandlerSubscription) + self.parent.errorSubject.on(.next(failedWith)) } else { - _parent.forwardOn(.error(error)) - _parent.dispose() + self.parent.forwardOn(.error(error)) + self.parent.dispose() } case .completed: - _parent.forwardOn(event) - _parent.dispose() + self.parent.forwardOn(event) + self.parent.dispose() } } final func dispose() { - _subscription.dispose() - _errorHandlerSubscription.dispose() + self.subscription.dispose() + self.errorHandlerSubscription.dispose() } } -final fileprivate class RetryWhenSequenceSink - : TailRecursiveSink where S.Iterator.Element : ObservableType, S.Iterator.Element.E == O.E { - typealias Element = O.E - typealias Parent = RetryWhenSequence +final private class RetryWhenSequenceSink + : TailRecursiveSink where Sequence.Element: ObservableType, Sequence.Element.Element == Observer.Element { + typealias Element = Observer.Element + typealias Parent = RetryWhenSequence - let _lock = RecursiveLock() + let lock = RecursiveLock() - fileprivate let _parent: Parent + private let parent: Parent - fileprivate var _lastError: Swift.Error? - fileprivate let _errorSubject = PublishSubject() - fileprivate let _handler: Observable - fileprivate let _notifier = PublishSubject() - - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - _handler = parent._notificationHandler(_errorSubject).asObservable() + fileprivate var lastError: Swift.Error? + fileprivate let errorSubject = PublishSubject() + private let handler: Observable + fileprivate let notifier = PublishSubject() + + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + self.handler = parent.notificationHandler(self.errorSubject).asObservable() super.init(observer: observer, cancel: cancel) } override func done() { - if let lastError = _lastError { - forwardOn(.error(lastError)) - _lastError = nil + if let lastError = self.lastError { + self.forwardOn(.error(lastError)) + self.lastError = nil } else { - forwardOn(.completed) + self.forwardOn(.completed) } - dispose() + self.dispose() } - override func extract(_ observable: Observable) -> SequenceGenerator? { - // It is important to always return `nil` here because there are sideffects in the `run` method + override func extract(_ observable: Observable) -> SequenceGenerator? { + // It is important to always return `nil` here because there are side effects in the `run` method // that are dependant on particular `retryWhen` operator so single operator stack can't be reused in this // case. return nil } - override func subscribeToNext(_ source: Observable) -> Disposable { + override func subscribeToNext(_ source: Observable) -> Disposable { let subscription = SingleAssignmentDisposable() let iter = RetryWhenSequenceSinkIter(parent: self, subscription: subscription) subscription.setDisposable(source.subscribe(iter)) @@ -157,26 +186,26 @@ final fileprivate class RetryWhenSequenceSink Disposable { - let triggerSubscription = _handler.subscribe(_notifier.asObserver()) + let triggerSubscription = self.handler.subscribe(self.notifier.asObserver()) let superSubscription = super.run(sources) return Disposables.create(superSubscription, triggerSubscription) } } -final fileprivate class RetryWhenSequence : Producer where S.Iterator.Element : ObservableType { - typealias Element = S.Iterator.Element.E +final private class RetryWhenSequence: Producer where Sequence.Element: ObservableType { + typealias Element = Sequence.Element.Element - fileprivate let _sources: S - fileprivate let _notificationHandler: (Observable) -> TriggerObservable + private let sources: Sequence + fileprivate let notificationHandler: (Observable) -> TriggerObservable - init(sources: S, notificationHandler: @escaping (Observable) -> TriggerObservable) { - _sources = sources - _notificationHandler = notificationHandler + init(sources: Sequence, notificationHandler: @escaping (Observable) -> TriggerObservable) { + self.sources = sources + self.notificationHandler = notificationHandler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - let sink = RetryWhenSequenceSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run((self._sources.makeIterator(), nil)) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = RetryWhenSequenceSink(parent: self, observer: observer, cancel: cancel) + let subscription = sink.run((self.sources.makeIterator(), nil)) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Sample.swift b/iOS/RxSwift/Observables/Sample.swift index 31f8b625..9301c9af 100644 --- a/iOS/RxSwift/Observables/Sample.swift +++ b/iOS/RxSwift/Observables/Sample.swift @@ -13,129 +13,126 @@ extension ObservableType { Upon each sampling tick, the latest element (if any) in the source sequence during the last sampling interval is sent to the resulting sequence. - **In case there were no new elements between sampler ticks, no element is sent to the resulting sequence.** + **In case there were no new elements between sampler ticks, you may provide a default value to be emitted, instead + to the resulting sequence otherwise no element is sent.** - seealso: [sample operator on reactivex.io](http://reactivex.io/documentation/operators/sample.html) - parameter sampler: Sampling tick sequence. + - parameter defaultValue: a value to return if there are no new elements between sampler ticks - returns: Sampled observable sequence. */ - public func sample(_ sampler: O) - -> Observable { - return Sample(source: self.asObservable(), sampler: sampler.asObservable()) + public func sample(_ sampler: Source, defaultValue: Element? = nil) + -> Observable { + return Sample(source: self.asObservable(), sampler: sampler.asObservable(), defaultValue: defaultValue) } } -final fileprivate class SamplerSink +final private class SamplerSink : ObserverType , LockOwnerType , SynchronizedOnType { - typealias E = SampleType + typealias Element = SampleType - typealias Parent = SampleSequenceSink + typealias Parent = SampleSequenceSink - fileprivate let _parent: Parent + private let parent: Parent - var _lock: RecursiveLock { - return _parent._lock + var lock: RecursiveLock { + self.parent.lock } init(parent: Parent) { - _parent = parent + self.parent = parent } - func on(_ event: Event) { - synchronizedOn(event) + func on(_ event: Event) { + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { - case .next: - if let element = _parent._element { - _parent._element = nil - _parent.forwardOn(.next(element)) + case .next, .completed: + if let element = parent.element ?? self.parent.defaultValue { + self.parent.element = nil + self.parent.forwardOn(.next(element)) } - if _parent._atEnd { - _parent.forwardOn(.completed) - _parent.dispose() + if self.parent.atEnd { + self.parent.forwardOn(.completed) + self.parent.dispose() } case .error(let e): - _parent.forwardOn(.error(e)) - _parent.dispose() - case .completed: - if let element = _parent._element { - _parent._element = nil - _parent.forwardOn(.next(element)) - } - if _parent._atEnd { - _parent.forwardOn(.completed) - _parent.dispose() - } + self.parent.forwardOn(.error(e)) + self.parent.dispose() } } } -final fileprivate class SampleSequenceSink - : Sink +final private class SampleSequenceSink + : Sink , ObserverType , LockOwnerType , SynchronizedOnType { - typealias Element = O.E + typealias Element = Observer.Element typealias Parent = Sample - fileprivate let _parent: Parent + fileprivate let parent: Parent + fileprivate let defaultValue: Element? - let _lock = RecursiveLock() + let lock = RecursiveLock() // state - fileprivate var _element = nil as Element? - fileprivate var _atEnd = false + fileprivate var element = nil as Element? + fileprivate var atEnd = false - fileprivate let _sourceSubscription = SingleAssignmentDisposable() + private let sourceSubscription = SingleAssignmentDisposable() - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable, defaultValue: Element? = nil) { + self.parent = parent + self.defaultValue = defaultValue super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - _sourceSubscription.setDisposable(_parent._source.subscribe(self)) - let samplerSubscription = _parent._sampler.subscribe(SamplerSink(parent: self)) + self.sourceSubscription.setDisposable(self.parent.source.subscribe(self)) + let samplerSubscription = self.parent.sampler.subscribe(SamplerSink(parent: self)) - return Disposables.create(_sourceSubscription, samplerSubscription) + return Disposables.create(sourceSubscription, samplerSubscription) } func on(_ event: Event) { - synchronizedOn(event) + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case .next(let element): - _element = element + self.element = element case .error: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() case .completed: - _atEnd = true - _sourceSubscription.dispose() + self.atEnd = true + self.sourceSubscription.dispose() } } } -final fileprivate class Sample : Producer { - fileprivate let _source: Observable - fileprivate let _sampler: Observable - - init(source: Observable, sampler: Observable) { - _source = source - _sampler = sampler +final private class Sample: Producer { + fileprivate let source: Observable + fileprivate let sampler: Observable + fileprivate let defaultValue: Element? + + init(source: Observable, sampler: Observable, defaultValue: Element? = nil) { + self.source = source + self.sampler = sampler + self.defaultValue = defaultValue } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - let sink = SampleSequenceSink(parent: self, observer: observer, cancel: cancel) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = SampleSequenceSink(parent: self, observer: observer, cancel: cancel, defaultValue: self.defaultValue) let subscription = sink.run() return (sink: sink, subscription: subscription) } diff --git a/iOS/RxSwift/Observables/Scan.swift b/iOS/RxSwift/Observables/Scan.swift index e94db11b..ecf69c80 100644 --- a/iOS/RxSwift/Observables/Scan.swift +++ b/iOS/RxSwift/Observables/Scan.swift @@ -19,64 +19,82 @@ extension ObservableType { - parameter accumulator: An accumulator function to be invoked on each element. - returns: An observable sequence containing the accumulated values. */ - public func scan(_ seed: A, accumulator: @escaping (A, E) throws -> A) + public func scan(into seed: A, accumulator: @escaping (inout A, Element) throws -> Void) -> Observable { - return Scan(source: self.asObservable(), seed: seed, accumulator: accumulator) + Scan(source: self.asObservable(), seed: seed, accumulator: accumulator) + } + + /** + Applies an accumulator function over an observable sequence and returns each intermediate result. The specified seed value is used as the initial accumulator value. + + For aggregation behavior with no intermediate results, see `reduce`. + + - seealso: [scan operator on reactivex.io](http://reactivex.io/documentation/operators/scan.html) + + - parameter seed: The initial accumulator value. + - parameter accumulator: An accumulator function to be invoked on each element. + - returns: An observable sequence containing the accumulated values. + */ + public func scan(_ seed: A, accumulator: @escaping (A, Element) throws -> A) + -> Observable { + return Scan(source: self.asObservable(), seed: seed) { acc, element in + let currentAcc = acc + acc = try accumulator(currentAcc, element) + } } } -final fileprivate class ScanSink : Sink, ObserverType { - typealias Accumulate = O.E - typealias Parent = Scan - typealias E = ElementType - - fileprivate let _parent: Parent - fileprivate var _accumulate: Accumulate +final private class ScanSink: Sink, ObserverType { + typealias Accumulate = Observer.Element + typealias Parent = Scan + + private let parent: Parent + private var accumulate: Accumulate - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - _accumulate = parent._seed + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + self.accumulate = parent.seed super.init(observer: observer, cancel: cancel) } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next(let element): do { - _accumulate = try _parent._accumulator(_accumulate, element) - forwardOn(.next(_accumulate)) + try self.parent.accumulator(&self.accumulate, element) + self.forwardOn(.next(self.accumulate)) } catch let error { - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() } case .error(let error): - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() case .completed: - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() } } } -final fileprivate class Scan: Producer { - typealias Accumulator = (Accumulate, Element) throws -> Accumulate +final private class Scan: Producer { + typealias Accumulator = (inout Accumulate, Element) throws -> Void - fileprivate let _source: Observable - fileprivate let _seed: Accumulate - fileprivate let _accumulator: Accumulator + private let source: Observable + fileprivate let seed: Accumulate + fileprivate let accumulator: Accumulator init(source: Observable, seed: Accumulate, accumulator: @escaping Accumulator) { - _source = source - _seed = seed - _accumulator = accumulator + self.source = source + self.seed = seed + self.accumulator = accumulator } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Accumulate { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Accumulate { let sink = ScanSink(parent: self, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Sequence.swift b/iOS/RxSwift/Observables/Sequence.swift index e141bc72..c6d10896 100644 --- a/iOS/RxSwift/Observables/Sequence.swift +++ b/iOS/RxSwift/Observables/Sequence.swift @@ -18,8 +18,8 @@ extension ObservableType { - parameter scheduler: Scheduler to send elements on. If `nil`, elements are sent immediately on subscription. - returns: The observable sequence whose elements are pulled from the given arguments. */ - public static func of(_ elements: E ..., scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { - return ObservableSequence(elements: elements, scheduler: scheduler) + public static func of(_ elements: Element ..., scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { + ObservableSequence(elements: elements, scheduler: scheduler) } } @@ -31,8 +31,8 @@ extension ObservableType { - returns: The observable sequence whose elements are pulled from the given enumerable sequence. */ - public static func from(_ array: [E], scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { - return ObservableSequence(elements: array, scheduler: scheduler) + public static func from(_ array: [Element], scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { + ObservableSequence(elements: array, scheduler: scheduler) } /** @@ -42,25 +42,25 @@ extension ObservableType { - returns: The observable sequence whose elements are pulled from the given enumerable sequence. */ - public static func from(_ sequence: S, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable where S.Iterator.Element == E { - return ObservableSequence(elements: sequence, scheduler: scheduler) + public static func from(_ sequence: Sequence, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable where Sequence.Element == Element { + ObservableSequence(elements: sequence, scheduler: scheduler) } } -final fileprivate class ObservableSequenceSink : Sink where S.Iterator.Element == O.E { - typealias Parent = ObservableSequence +final private class ObservableSequenceSink: Sink where Sequence.Element == Observer.Element { + typealias Parent = ObservableSequence - private let _parent: Parent + private let parent: Parent - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - return _parent._scheduler.scheduleRecursive((_parent._elements.makeIterator(), _parent._elements)) { (iterator, recurse) in + return self.parent.scheduler.scheduleRecursive(self.parent.elements.makeIterator()) { iterator, recurse in var mutableIterator = iterator - if let next = mutableIterator.0.next() { + if let next = mutableIterator.next() { self.forwardOn(.next(next)) recurse(mutableIterator) } @@ -72,16 +72,16 @@ final fileprivate class ObservableSequenceSink : S } } -final fileprivate class ObservableSequence : Producer { - fileprivate let _elements: S - fileprivate let _scheduler: ImmediateSchedulerType +final private class ObservableSequence: Producer { + fileprivate let elements: Sequence + fileprivate let scheduler: ImmediateSchedulerType - init(elements: S, scheduler: ImmediateSchedulerType) { - _elements = elements - _scheduler = scheduler + init(elements: Sequence, scheduler: ImmediateSchedulerType) { + self.elements = elements + self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = ObservableSequenceSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/ShareReplayScope.swift b/iOS/RxSwift/Observables/ShareReplayScope.swift index 8ba2898d..59d440dc 100644 --- a/iOS/RxSwift/Observables/ShareReplayScope.swift +++ b/iOS/RxSwift/Observables/ShareReplayScope.swift @@ -77,7 +77,7 @@ public enum SubjectLifetimeScope { continue holding a reference to the same subject. If at some later moment a new observer initiates a new connection to source it can potentially receive some of the stale events received during previous connection. - * After source sequence terminates any new observer will always immediatelly receive replayed elements and terminal event. + * After source sequence terminates any new observer will always immediately receive replayed elements and terminal event. No new subscriptions to source observable sequence will be attempted. ``` @@ -139,7 +139,7 @@ extension ObservableType { - returns: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence. */ public func share(replay: Int = 0, scope: SubjectLifetimeScope = .whileConnected) - -> Observable { + -> Observable { switch scope { case .forever: switch replay { @@ -156,95 +156,90 @@ extension ObservableType { } } -fileprivate final class ShareReplay1WhileConnectedConnection +private final class ShareReplay1WhileConnectedConnection : ObserverType , SynchronizedUnsubscribeType { - typealias E = Element typealias Observers = AnyObserver.s typealias DisposeKey = Observers.KeyType typealias Parent = ShareReplay1WhileConnected - private let _parent: Parent - private let _subscription = SingleAssignmentDisposable() + private let parent: Parent + private let subscription = SingleAssignmentDisposable() - private let _lock: RecursiveLock - private var _disposed: Bool = false - fileprivate var _observers = Observers() - fileprivate var _element: Element? + private let lock: RecursiveLock + private var disposed: Bool = false + fileprivate var observers = Observers() + private var element: Element? init(parent: Parent, lock: RecursiveLock) { - _parent = parent - _lock = lock + self.parent = parent + self.lock = lock #if TRACE_RESOURCES _ = Resources.incrementTotal() #endif } - final func on(_ event: Event) { - _lock.lock() - let observers = _synchronized_on(event) - _lock.unlock() + final func on(_ event: Event) { + let observers = self.lock.performLocked { self.synchronized_on(event) } dispatch(observers, event) } - final private func _synchronized_on(_ event: Event) -> Observers { - if _disposed { + final private func synchronized_on(_ event: Event) -> Observers { + if self.disposed { return Observers() } switch event { case .next(let element): - _element = element - return _observers + self.element = element + return self.observers case .error, .completed: - let observers = _observers - self._synchronized_dispose() + let observers = self.observers + self.synchronized_dispose() return observers } } final func connect() { - _subscription.setDisposable(_parent._source.subscribe(self)) + self.subscription.setDisposable(self.parent.source.subscribe(self)) } - final func _synchronized_subscribe(_ observer: O) -> Disposable where O.E == Element { - _lock.lock(); defer { _lock.unlock() } - if let element = _element { - observer.on(.next(element)) - } + final func synchronized_subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { + self.lock.performLocked { + if let element = self.element { + observer.on(.next(element)) + } - let disposeKey = _observers.insert(observer.on) + let disposeKey = self.observers.insert(observer.on) - return SubscriptionDisposable(owner: self, key: disposeKey) + return SubscriptionDisposable(owner: self, key: disposeKey) + } } - final private func _synchronized_dispose() { - _disposed = true - if _parent._connection === self { - _parent._connection = nil + final private func synchronized_dispose() { + self.disposed = true + if self.parent.connection === self { + self.parent.connection = nil } - _observers = Observers() + self.observers = Observers() } final func synchronizedUnsubscribe(_ disposeKey: DisposeKey) { - _lock.lock() - let shouldDisconnect = _synchronized_unsubscribe(disposeKey) - _lock.unlock() - if shouldDisconnect { - _subscription.dispose() + if self.lock.performLocked({ self.synchronized_unsubscribe(disposeKey) }) { + self.subscription.dispose() } } @inline(__always) - final private func _synchronized_unsubscribe(_ disposeKey: DisposeKey) -> Bool { + final private func synchronized_unsubscribe(_ disposeKey: DisposeKey) -> Bool { // if already unsubscribed, just return - if self._observers.removeKey(disposeKey) == nil { + if self.observers.removeKey(disposeKey) == nil { return false } - if _observers.count == 0 { - _synchronized_dispose() + if self.observers.count == 0 { + self.synchronized_dispose() return true } @@ -259,30 +254,28 @@ fileprivate final class ShareReplay1WhileConnectedConnection } // optimized version of share replay for most common case -final fileprivate class ShareReplay1WhileConnected +final private class ShareReplay1WhileConnected : Observable { fileprivate typealias Connection = ShareReplay1WhileConnectedConnection - fileprivate let _source: Observable + fileprivate let source: Observable - fileprivate let _lock = RecursiveLock() + private let lock = RecursiveLock() - fileprivate var _connection: Connection? + fileprivate var connection: Connection? init(source: Observable) { - self._source = source + self.source = source } - override func subscribe(_ observer: O) -> Disposable where O.E == E { - _lock.lock() - - let connection = _synchronized_subscribe(observer) - let count = connection._observers.count - - let disposable = connection._synchronized_subscribe(observer) + override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { + self.lock.lock() + let connection = self.synchronized_subscribe(observer) + let count = connection.observers.count - _lock.unlock() + let disposable = connection.synchronized_subscribe(observer) + self.lock.unlock() if count == 0 { connection.connect() @@ -292,107 +285,101 @@ final fileprivate class ShareReplay1WhileConnected } @inline(__always) - private func _synchronized_subscribe(_ observer: O) -> Connection where O.E == E { + private func synchronized_subscribe(_ observer: Observer) -> Connection where Observer.Element == Element { let connection: Connection - if let existingConnection = _connection { + if let existingConnection = self.connection { connection = existingConnection } else { connection = ShareReplay1WhileConnectedConnection( parent: self, - lock: _lock) - _connection = connection + lock: self.lock) + self.connection = connection } return connection } } -fileprivate final class ShareWhileConnectedConnection +private final class ShareWhileConnectedConnection : ObserverType , SynchronizedUnsubscribeType { - typealias E = Element typealias Observers = AnyObserver.s typealias DisposeKey = Observers.KeyType typealias Parent = ShareWhileConnected - private let _parent: Parent - private let _subscription = SingleAssignmentDisposable() + private let parent: Parent + private let subscription = SingleAssignmentDisposable() - private let _lock: RecursiveLock - private var _disposed: Bool = false - fileprivate var _observers = Observers() + private let lock: RecursiveLock + private var disposed: Bool = false + fileprivate var observers = Observers() init(parent: Parent, lock: RecursiveLock) { - _parent = parent - _lock = lock + self.parent = parent + self.lock = lock #if TRACE_RESOURCES _ = Resources.incrementTotal() #endif } - final func on(_ event: Event) { - _lock.lock() - let observers = _synchronized_on(event) - _lock.unlock() + final func on(_ event: Event) { + let observers = self.lock.performLocked { self.synchronized_on(event) } dispatch(observers, event) } - final private func _synchronized_on(_ event: Event) -> Observers { - if _disposed { + final private func synchronized_on(_ event: Event) -> Observers { + if self.disposed { return Observers() } switch event { case .next: - return _observers + return self.observers case .error, .completed: - let observers = _observers - self._synchronized_dispose() + let observers = self.observers + self.synchronized_dispose() return observers } } final func connect() { - _subscription.setDisposable(_parent._source.subscribe(self)) + self.subscription.setDisposable(self.parent.source.subscribe(self)) } - final func _synchronized_subscribe(_ observer: O) -> Disposable where O.E == Element { - _lock.lock(); defer { _lock.unlock() } + final func synchronized_subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { + self.lock.performLocked { + let disposeKey = self.observers.insert(observer.on) - let disposeKey = _observers.insert(observer.on) - - return SubscriptionDisposable(owner: self, key: disposeKey) + return SubscriptionDisposable(owner: self, key: disposeKey) + } } - final private func _synchronized_dispose() { - _disposed = true - if _parent._connection === self { - _parent._connection = nil + final private func synchronized_dispose() { + self.disposed = true + if self.parent.connection === self { + self.parent.connection = nil } - _observers = Observers() + self.observers = Observers() } final func synchronizedUnsubscribe(_ disposeKey: DisposeKey) { - _lock.lock() - let shouldDisconnect = _synchronized_unsubscribe(disposeKey) - _lock.unlock() - if shouldDisconnect { - _subscription.dispose() + if self.lock.performLocked({ self.synchronized_unsubscribe(disposeKey) }) { + self.subscription.dispose() } } @inline(__always) - final private func _synchronized_unsubscribe(_ disposeKey: DisposeKey) -> Bool { + final private func synchronized_unsubscribe(_ disposeKey: DisposeKey) -> Bool { // if already unsubscribed, just return - if self._observers.removeKey(disposeKey) == nil { + if self.observers.removeKey(disposeKey) == nil { return false } - if _observers.count == 0 { - _synchronized_dispose() + if self.observers.count == 0 { + self.synchronized_dispose() return true } @@ -407,30 +394,28 @@ fileprivate final class ShareWhileConnectedConnection } // optimized version of share replay for most common case -final fileprivate class ShareWhileConnected +final private class ShareWhileConnected : Observable { fileprivate typealias Connection = ShareWhileConnectedConnection - fileprivate let _source: Observable + fileprivate let source: Observable - fileprivate let _lock = RecursiveLock() + private let lock = RecursiveLock() - fileprivate var _connection: Connection? + fileprivate var connection: Connection? init(source: Observable) { - self._source = source + self.source = source } - override func subscribe(_ observer: O) -> Disposable where O.E == E { - _lock.lock() - - let connection = _synchronized_subscribe(observer) - let count = connection._observers.count - - let disposable = connection._synchronized_subscribe(observer) + override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { + self.lock.lock() + let connection = self.synchronized_subscribe(observer) + let count = connection.observers.count - _lock.unlock() + let disposable = connection.synchronized_subscribe(observer) + self.lock.unlock() if count == 0 { connection.connect() @@ -440,17 +425,17 @@ final fileprivate class ShareWhileConnected } @inline(__always) - private func _synchronized_subscribe(_ observer: O) -> Connection where O.E == E { + private func synchronized_subscribe(_ observer: Observer) -> Connection where Observer.Element == Element { let connection: Connection - if let existingConnection = _connection { + if let existingConnection = self.connection { connection = existingConnection } else { connection = ShareWhileConnectedConnection( parent: self, - lock: _lock) - _connection = connection + lock: self.lock) + self.connection = connection } return connection diff --git a/iOS/RxSwift/Observables/SingleAsync.swift b/iOS/RxSwift/Observables/SingleAsync.swift index 1419a93f..04e22176 100644 --- a/iOS/RxSwift/Observables/SingleAsync.swift +++ b/iOS/RxSwift/Observables/SingleAsync.swift @@ -17,8 +17,8 @@ extension ObservableType { - returns: An observable sequence that emits a single element or throws an exception if more (or none) of them are emitted. */ public func single() - -> Observable { - return SingleAsync(source: asObservable()) + -> Observable { + SingleAsync(source: self.asObservable()) } /** @@ -30,58 +30,57 @@ extension ObservableType { - parameter predicate: A function to test each source element for a condition. - returns: An observable sequence that emits a single element or throws an exception if more (or none) of them are emitted. */ - public func single(_ predicate: @escaping (E) throws -> Bool) - -> Observable { - return SingleAsync(source: asObservable(), predicate: predicate) + public func single(_ predicate: @escaping (Element) throws -> Bool) + -> Observable { + SingleAsync(source: self.asObservable(), predicate: predicate) } } -fileprivate final class SingleAsyncSink : Sink, ObserverType { - typealias ElementType = O.E - typealias Parent = SingleAsync - typealias E = ElementType +private final class SingleAsyncSink : Sink, ObserverType { + typealias Element = Observer.Element + typealias Parent = SingleAsync - private let _parent: Parent - private var _seenValue: Bool = false + private let parent: Parent + private var seenValue: Bool = false - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next(let value): do { - let forward = try _parent._predicate?(value) ?? true + let forward = try self.parent.predicate?(value) ?? true if !forward { return } } catch let error { - forwardOn(.error(error as Swift.Error)) - dispose() + self.forwardOn(.error(error as Swift.Error)) + self.dispose() return } - if _seenValue { - forwardOn(.error(RxError.moreThanOneElement)) - dispose() + if self.seenValue { + self.forwardOn(.error(RxError.moreThanOneElement)) + self.dispose() return } - _seenValue = true - forwardOn(.next(value)) + self.seenValue = true + self.forwardOn(.next(value)) case .error: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() case .completed: - if (_seenValue) { - forwardOn(.completed) + if self.seenValue { + self.forwardOn(.completed) } else { - forwardOn(.error(RxError.noElements)) + self.forwardOn(.error(RxError.noElements)) } - dispose() + self.dispose() } } } @@ -89,17 +88,17 @@ fileprivate final class SingleAsyncSink : Sink, ObserverType final class SingleAsync: Producer { typealias Predicate = (Element) throws -> Bool - fileprivate let _source: Observable - fileprivate let _predicate: Predicate? + private let source: Observable + fileprivate let predicate: Predicate? init(source: Observable, predicate: Predicate? = nil) { - _source = source - _predicate = predicate + self.source = source + self.predicate = predicate } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = SingleAsyncSink(parent: self, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Sink.swift b/iOS/RxSwift/Observables/Sink.swift index 214cfda3..ed4fec01 100644 --- a/iOS/RxSwift/Observables/Sink.swift +++ b/iOS/RxSwift/Observables/Sink.swift @@ -6,71 +6,70 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -class Sink : Disposable { - fileprivate let _observer: O - fileprivate let _cancel: Cancelable - fileprivate var _disposed: Bool +class Sink: Disposable { + fileprivate let observer: Observer + fileprivate let cancel: Cancelable + private let disposed = AtomicInt(0) #if DEBUG - fileprivate let _synchronizationTracker = SynchronizationTracker() + private let synchronizationTracker = SynchronizationTracker() #endif - init(observer: O, cancel: Cancelable) { + init(observer: Observer, cancel: Cancelable) { #if TRACE_RESOURCES - let _ = Resources.incrementTotal() + _ = Resources.incrementTotal() #endif - _observer = observer - _cancel = cancel - _disposed = false + self.observer = observer + self.cancel = cancel } - - final func forwardOn(_ event: Event) { + + final func forwardOn(_ event: Event) { #if DEBUG - _synchronizationTracker.register(synchronizationErrorMessage: .default) - defer { _synchronizationTracker.unregister() } + self.synchronizationTracker.register(synchronizationErrorMessage: .default) + defer { self.synchronizationTracker.unregister() } #endif - if _disposed { + if isFlagSet(self.disposed, 1) { return } - _observer.on(event) + self.observer.on(event) } - - final func forwarder() -> SinkForward { - return SinkForward(forward: self) + + final func forwarder() -> SinkForward { + SinkForward(forward: self) } - final var disposed: Bool { - return _disposed + final var isDisposed: Bool { + isFlagSet(self.disposed, 1) } func dispose() { - _disposed = true - _cancel.dispose() + fetchOr(self.disposed, 1) + self.cancel.dispose() } deinit { #if TRACE_RESOURCES - let _ = Resources.decrementTotal() + _ = Resources.decrementTotal() #endif } } -final class SinkForward: ObserverType { - typealias E = O.E - - private let _forward: Sink - - init(forward: Sink) { - _forward = forward +final class SinkForward: ObserverType { + typealias Element = Observer.Element + + private let forward: Sink + + init(forward: Sink) { + self.forward = forward } - - final func on(_ event: Event) { + + final func on(_ event: Event) { switch event { case .next: - _forward._observer.on(event) + self.forward.observer.on(event) case .error, .completed: - _forward._observer.on(event) - _forward._cancel.dispose() + self.forward.observer.on(event) + self.forward.cancel.dispose() } } } diff --git a/iOS/RxSwift/Observables/Skip.swift b/iOS/RxSwift/Observables/Skip.swift index fcac9d4a..5856f374 100644 --- a/iOS/RxSwift/Observables/Skip.swift +++ b/iOS/RxSwift/Observables/Skip.swift @@ -17,8 +17,8 @@ extension ObservableType { - returns: An observable sequence that contains the elements that occur after the specified index in the input sequence. */ public func skip(_ count: Int) - -> Observable { - return SkipCount(source: asObservable(), count: count) + -> Observable { + SkipCount(source: self.asObservable(), count: count) } } @@ -34,22 +34,22 @@ extension ObservableType { - returns: An observable sequence with the elements skipped during the specified duration from the start of the source sequence. */ public func skip(_ duration: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - return SkipTime(source: self.asObservable(), duration: duration, scheduler: scheduler) + -> Observable { + SkipTime(source: self.asObservable(), duration: duration, scheduler: scheduler) } } // count version -final fileprivate class SkipCountSink : Sink, ObserverType { - typealias Element = O.E +final private class SkipCountSink: Sink, ObserverType { + typealias Element = Observer.Element typealias Parent = SkipCount let parent: Parent var remaining: Int - init(parent: Parent, observer: O, cancel: Cancelable) { + init(parent: Parent, observer: Observer, cancel: Cancelable) { self.parent = parent self.remaining = parent.count super.init(observer: observer, cancel: cancel) @@ -59,24 +59,24 @@ final fileprivate class SkipCountSink : Sink, ObserverType { switch event { case .next(let value): - if remaining <= 0 { - forwardOn(.next(value)) + if self.remaining <= 0 { + self.forwardOn(.next(value)) } else { - remaining -= 1 + self.remaining -= 1 } case .error: - forwardOn(event) + self.forwardOn(event) self.dispose() case .completed: - forwardOn(event) + self.forwardOn(event) self.dispose() } } } -final fileprivate class SkipCount: Producer { +final private class SkipCount: Producer { let source: Observable let count: Int @@ -85,9 +85,9 @@ final fileprivate class SkipCount: Producer { self.count = count } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = SkipCountSink(parent: self, observer: observer, cancel: cancel) - let subscription = source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } @@ -95,16 +95,15 @@ final fileprivate class SkipCount: Producer { // time version -final fileprivate class SkipTimeSink : Sink, ObserverType where O.E == ElementType { - typealias Parent = SkipTime - typealias Element = ElementType +final private class SkipTimeSink: Sink, ObserverType where Observer.Element == Element { + typealias Parent = SkipTime let parent: Parent // state var open = false - init(parent: Parent, observer: O, cancel: Cancelable) { + init(parent: Parent, observer: Observer, cancel: Cancelable) { self.parent = parent super.init(observer: observer, cancel: cancel) } @@ -112,35 +111,35 @@ final fileprivate class SkipTimeSink : Sink, Ob func on(_ event: Event) { switch event { case .next(let value): - if open { - forwardOn(.next(value)) + if self.open { + self.forwardOn(.next(value)) } case .error: - forwardOn(event) + self.forwardOn(event) self.dispose() case .completed: - forwardOn(event) + self.forwardOn(event) self.dispose() } } func tick() { - open = true + self.open = true } func run() -> Disposable { - let disposeTimer = parent.scheduler.scheduleRelative((), dueTime: self.parent.duration) { _ in + let disposeTimer = self.parent.scheduler.scheduleRelative((), dueTime: self.parent.duration) { _ in self.tick() return Disposables.create() } - let disposeSubscription = parent.source.subscribe(self) + let disposeSubscription = self.parent.source.subscribe(self) return Disposables.create(disposeTimer, disposeSubscription) } } -final fileprivate class SkipTime: Producer { +final private class SkipTime: Producer { let source: Observable let duration: RxTimeInterval let scheduler: SchedulerType @@ -151,7 +150,7 @@ final fileprivate class SkipTime: Producer { self.duration = duration } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = SkipTimeSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/SkipUntil.swift b/iOS/RxSwift/Observables/SkipUntil.swift index f35f1fd8..c8fe1934 100644 --- a/iOS/RxSwift/Observables/SkipUntil.swift +++ b/iOS/RxSwift/Observables/SkipUntil.swift @@ -7,6 +7,18 @@ // extension ObservableType { + /** + Returns the elements from the source observable sequence that are emitted after the other observable sequence produces an element. + + - seealso: [skipUntil operator on reactivex.io](http://reactivex.io/documentation/operators/skipuntil.html) + + - parameter other: Observable sequence that starts propagation of elements of the source sequence. + - returns: An observable sequence containing the elements of the source sequence that are emitted after the other sequence emits an item. + */ + public func skip(until other: Source) + -> Observable { + SkipUntil(source: self.asObservable(), other: other.asObservable()) + } /** Returns the elements from the source observable sequence that are emitted after the other observable sequence produces an element. @@ -16,122 +28,123 @@ extension ObservableType { - parameter other: Observable sequence that starts propagation of elements of the source sequence. - returns: An observable sequence containing the elements of the source sequence that are emitted after the other sequence emits an item. */ - public func skipUntil(_ other: O) - -> Observable { - return SkipUntil(source: asObservable(), other: other.asObservable()) + @available(*, deprecated, renamed: "skip(until:)") + public func skipUntil(_ other: Source) + -> Observable { + skip(until: other) } } -final fileprivate class SkipUntilSinkOther +final private class SkipUntilSinkOther : ObserverType , LockOwnerType , SynchronizedOnType { - typealias Parent = SkipUntilSink - typealias E = Other + typealias Parent = SkipUntilSink + typealias Element = Other - fileprivate let _parent: Parent + private let parent: Parent - var _lock: RecursiveLock { - return _parent._lock + var lock: RecursiveLock { + self.parent.lock } - let _subscription = SingleAssignmentDisposable() + let subscription = SingleAssignmentDisposable() init(parent: Parent) { - _parent = parent + self.parent = parent #if TRACE_RESOURCES - let _ = Resources.incrementTotal() + _ = Resources.incrementTotal() #endif } - func on(_ event: Event) { - synchronizedOn(event) + func on(_ event: Event) { + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case .next: - _parent._forwardElements = true - _subscription.dispose() + self.parent.forwardElements = true + self.subscription.dispose() case .error(let e): - _parent.forwardOn(.error(e)) - _parent.dispose() + self.parent.forwardOn(.error(e)) + self.parent.dispose() case .completed: - _subscription.dispose() + self.subscription.dispose() } } #if TRACE_RESOURCES deinit { - let _ = Resources.decrementTotal() + _ = Resources.decrementTotal() } #endif } -final fileprivate class SkipUntilSink - : Sink +final private class SkipUntilSink + : Sink , ObserverType , LockOwnerType , SynchronizedOnType { - typealias E = O.E - typealias Parent = SkipUntil + typealias Element = Observer.Element + typealias Parent = SkipUntil - let _lock = RecursiveLock() - fileprivate let _parent: Parent - fileprivate var _forwardElements = false + let lock = RecursiveLock() + private let parent: Parent + fileprivate var forwardElements = false - fileprivate let _sourceSubscription = SingleAssignmentDisposable() + private let sourceSubscription = SingleAssignmentDisposable() - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } - func on(_ event: Event) { - synchronizedOn(event) + func on(_ event: Event) { + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case .next: - if _forwardElements { - forwardOn(event) + if self.forwardElements { + self.forwardOn(event) } case .error: - forwardOn(event) + self.forwardOn(event) self.dispose() case .completed: - if _forwardElements { - forwardOn(event) + if self.forwardElements { + self.forwardOn(event) } self.dispose() } } func run() -> Disposable { - let sourceSubscription = _parent._source.subscribe(self) + let sourceSubscription = self.parent.source.subscribe(self) let otherObserver = SkipUntilSinkOther(parent: self) - let otherSubscription = _parent._other.subscribe(otherObserver) - _sourceSubscription.setDisposable(sourceSubscription) - otherObserver._subscription.setDisposable(otherSubscription) + let otherSubscription = self.parent.other.subscribe(otherObserver) + self.sourceSubscription.setDisposable(sourceSubscription) + otherObserver.subscription.setDisposable(otherSubscription) - return Disposables.create(_sourceSubscription, otherObserver._subscription) + return Disposables.create(sourceSubscription, otherObserver.subscription) } } -final fileprivate class SkipUntil: Producer { +final private class SkipUntil: Producer { - fileprivate let _source: Observable - fileprivate let _other: Observable + fileprivate let source: Observable + fileprivate let other: Observable init(source: Observable, other: Observable) { - _source = source - _other = other + self.source = source + self.other = other } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = SkipUntilSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/SkipWhile.swift b/iOS/RxSwift/Observables/SkipWhile.swift index 4bb394b9..a62f88dd 100644 --- a/iOS/RxSwift/Observables/SkipWhile.swift +++ b/iOS/RxSwift/Observables/SkipWhile.swift @@ -7,6 +7,17 @@ // extension ObservableType { + /** + Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements. + + - seealso: [skipWhile operator on reactivex.io](http://reactivex.io/documentation/operators/skipwhile.html) + + - parameter predicate: A function to test each element for a condition. + - returns: An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate. + */ + public func skip(while predicate: @escaping (Element) throws -> Bool) -> Observable { + SkipWhile(source: self.asObservable(), predicate: predicate) + } /** Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements. @@ -16,62 +27,61 @@ extension ObservableType { - parameter predicate: A function to test each element for a condition. - returns: An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate. */ - public func skipWhile(_ predicate: @escaping (E) throws -> Bool) -> Observable { - return SkipWhile(source: asObservable(), predicate: predicate) + @available(*, deprecated, renamed: "skip(while:)") + public func skipWhile(_ predicate: @escaping (Element) throws -> Bool) -> Observable { + SkipWhile(source: self.asObservable(), predicate: predicate) } } -final fileprivate class SkipWhileSink : Sink, ObserverType { - - typealias Element = O.E +final private class SkipWhileSink: Sink, ObserverType { + typealias Element = Observer.Element typealias Parent = SkipWhile - fileprivate let _parent: Parent - fileprivate var _running = false + private let parent: Parent + private var running = false - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func on(_ event: Event) { switch event { case .next(let value): - if !_running { + if !self.running { do { - _running = try !_parent._predicate(value) + self.running = try !self.parent.predicate(value) } catch let e { - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() return } } - if _running { - forwardOn(.next(value)) + if self.running { + self.forwardOn(.next(value)) } case .error, .completed: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() } } } -final fileprivate class SkipWhile: Producer { +final private class SkipWhile: Producer { typealias Predicate = (Element) throws -> Bool - typealias PredicateWithIndex = (Element, Int) throws -> Bool - fileprivate let _source: Observable - fileprivate let _predicate: Predicate + private let source: Observable + fileprivate let predicate: Predicate init(source: Observable, predicate: @escaping Predicate) { - _source = source - _predicate = predicate + self.source = source + self.predicate = predicate } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = SkipWhileSink(parent: self, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/StartWith.swift b/iOS/RxSwift/Observables/StartWith.swift index 14776f9e..13fb31d3 100644 --- a/iOS/RxSwift/Observables/StartWith.swift +++ b/iOS/RxSwift/Observables/StartWith.swift @@ -16,13 +16,13 @@ extension ObservableType { - parameter elements: Elements to prepend to the specified sequence. - returns: The source sequence prepended with the specified values. */ - public func startWith(_ elements: E ...) - -> Observable { + public func startWith(_ elements: Element ...) + -> Observable { return StartWith(source: self.asObservable(), elements: elements) } } -final fileprivate class StartWith: Producer { +final private class StartWith: Producer { let elements: [Element] let source: Observable @@ -32,11 +32,11 @@ final fileprivate class StartWith: Producer { super.init() } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - for e in elements { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + for e in self.elements { observer.on(.next(e)) } - return (sink: Disposables.create(), subscription: source.subscribe(observer)) + return (sink: Disposables.create(), subscription: self.source.subscribe(observer)) } } diff --git a/iOS/RxSwift/Observables/SubscribeOn.swift b/iOS/RxSwift/Observables/SubscribeOn.swift index 2a33e03e..e8e41d9c 100644 --- a/iOS/RxSwift/Observables/SubscribeOn.swift +++ b/iOS/RxSwift/Observables/SubscribeOn.swift @@ -7,6 +7,25 @@ // extension ObservableType { + /** + Wraps the source sequence in order to run its subscription and unsubscription logic on the specified + scheduler. + + This operation is not commonly used. + + This only performs the side-effects of subscription and unsubscription on the specified scheduler. + + In order to invoke observer callbacks on a `scheduler`, use `observeOn`. + + - seealso: [subscribeOn operator on reactivex.io](http://reactivex.io/documentation/operators/subscribeon.html) + + - parameter scheduler: Scheduler to perform subscription and unsubscription actions on. + - returns: The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler. + */ + public func subscribe(on scheduler: ImmediateSchedulerType) + -> Observable { + SubscribeOn(source: self, scheduler: scheduler) + } /** Wraps the source sequence in order to run its subscription and unsubscription logic on the specified @@ -23,25 +42,26 @@ extension ObservableType { - parameter scheduler: Scheduler to perform subscription and unsubscription actions on. - returns: The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler. */ + @available(*, deprecated, renamed: "subscribe(on:)") public func subscribeOn(_ scheduler: ImmediateSchedulerType) - -> Observable { - return SubscribeOn(source: self, scheduler: scheduler) + -> Observable { + subscribe(on: scheduler) } } -final fileprivate class SubscribeOnSink : Sink, ObserverType where Ob.E == O.E { - typealias Element = O.E +final private class SubscribeOnSink: Sink, ObserverType where Ob.Element == Observer.Element { + typealias Element = Observer.Element typealias Parent = SubscribeOn let parent: Parent - init(parent: Parent, observer: O, cancel: Cancelable) { + init(parent: Parent, observer: Observer, cancel: Cancelable) { self.parent = parent super.init(observer: observer, cancel: cancel) } func on(_ event: Event) { - forwardOn(event) + self.forwardOn(event) if event.isStopEvent { self.dispose() @@ -54,7 +74,7 @@ final fileprivate class SubscribeOnSink : S disposeEverything.disposable = cancelSchedule - let disposeSchedule = parent.scheduler.schedule(()) { (_) -> Disposable in + let disposeSchedule = self.parent.scheduler.schedule(()) { _ -> Disposable in let subscription = self.parent.source.subscribe(self) disposeEverything.disposable = ScheduledDisposable(scheduler: self.parent.scheduler, disposable: subscription) return Disposables.create() @@ -66,7 +86,7 @@ final fileprivate class SubscribeOnSink : S } } -final fileprivate class SubscribeOn : Producer { +final private class SubscribeOn: Producer { let source: Ob let scheduler: ImmediateSchedulerType @@ -75,7 +95,7 @@ final fileprivate class SubscribeOn : Producer { self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Ob.E { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Ob.Element { let sink = SubscribeOnSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/Switch.swift b/iOS/RxSwift/Observables/Switch.swift index 2da10005..5aa60b97 100644 --- a/iOS/RxSwift/Observables/Switch.swift +++ b/iOS/RxSwift/Observables/Switch.swift @@ -19,13 +19,30 @@ extension ObservableType { - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source producing an Observable of Observable sequences and that at any point in time produces the elements of the most recent inner observable sequence that has been received. */ - public func flatMapLatest(_ selector: @escaping (E) throws -> O) - -> Observable { - return FlatMapLatest(source: asObservable(), selector: selector) + public func flatMapLatest(_ selector: @escaping (Element) throws -> Source) + -> Observable { + return FlatMapLatest(source: self.asObservable(), selector: selector) + } + + /** + Projects each element of an observable sequence into a new sequence of observable sequences and then + transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. + + It is a combination of `map` + `switchLatest` operator + + - seealso: [flatMapLatest operator on reactivex.io](http://reactivex.io/documentation/operators/flatmap.html) + + - parameter selector: A transform function to apply to each element. + - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source producing an + Observable of Observable sequences and that at any point in time produces the elements of the most recent inner observable sequence that has been received. + */ + public func flatMapLatest(_ selector: @escaping (Element) throws -> Source) + -> Infallible { + return Infallible(flatMapLatest(selector)) } } -extension ObservableType where E : ObservableConvertibleType { +extension ObservableType where Element: ObservableConvertibleType { /** Transforms an observable sequence of observable sequences into an observable sequence @@ -38,134 +55,134 @@ extension ObservableType where E : ObservableConvertibleType { - returns: The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received. */ - public func switchLatest() -> Observable { - return Switch(source: asObservable()) + public func switchLatest() -> Observable { + Switch(source: self.asObservable()) } } -fileprivate class SwitchSink - : Sink - , ObserverType where S.E == O.E { - typealias E = SourceType +private class SwitchSink + : Sink + , ObserverType where Source.Element == Observer.Element { + typealias Element = SourceType - fileprivate let _subscriptions: SingleAssignmentDisposable = SingleAssignmentDisposable() - fileprivate let _innerSubscription: SerialDisposable = SerialDisposable() + private let subscriptions: SingleAssignmentDisposable = SingleAssignmentDisposable() + private let innerSubscription: SerialDisposable = SerialDisposable() - let _lock = RecursiveLock() + let lock = RecursiveLock() // state - fileprivate var _stopped = false - fileprivate var _latest = 0 - fileprivate var _hasLatest = false + fileprivate var stopped = false + fileprivate var latest = 0 + fileprivate var hasLatest = false - override init(observer: O, cancel: Cancelable) { + override init(observer: Observer, cancel: Cancelable) { super.init(observer: observer, cancel: cancel) } func run(_ source: Observable) -> Disposable { let subscription = source.subscribe(self) - _subscriptions.setDisposable(subscription) - return Disposables.create(_subscriptions, _innerSubscription) + self.subscriptions.setDisposable(subscription) + return Disposables.create(subscriptions, innerSubscription) } - func performMap(_ element: SourceType) throws -> S { + func performMap(_ element: SourceType) throws -> Source { rxAbstractMethod() } @inline(__always) - final private func nextElementArrived(element: E) -> (Int, Observable)? { - _lock.lock(); defer { _lock.unlock() } // { - do { - let observable = try performMap(element).asObservable() - _hasLatest = true - _latest = _latest &+ 1 - return (_latest, observable) - } - catch let error { - forwardOn(.error(error)) - dispose() - } + final private func nextElementArrived(element: Element) -> (Int, Observable)? { + self.lock.lock(); defer { self.lock.unlock() } + + do { + let observable = try self.performMap(element).asObservable() + self.hasLatest = true + self.latest = self.latest &+ 1 + return (self.latest, observable) + } + catch let error { + self.forwardOn(.error(error)) + self.dispose() + } - return nil - // } + return nil } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next(let element): - if let (latest, observable) = nextElementArrived(element: element) { + if let (latest, observable) = self.nextElementArrived(element: element) { let d = SingleAssignmentDisposable() - _innerSubscription.disposable = d + self.innerSubscription.disposable = d - let observer = SwitchSinkIter(parent: self, id: latest, _self: d) + let observer = SwitchSinkIter(parent: self, id: latest, this: d) let disposable = observable.subscribe(observer) d.setDisposable(disposable) } case .error(let error): - _lock.lock(); defer { _lock.unlock() } - forwardOn(.error(error)) - dispose() + self.lock.lock(); defer { self.lock.unlock() } + self.forwardOn(.error(error)) + self.dispose() case .completed: - _lock.lock(); defer { _lock.unlock() } - _stopped = true + self.lock.lock(); defer { self.lock.unlock() } + self.stopped = true - _subscriptions.dispose() + self.subscriptions.dispose() - if !_hasLatest { - forwardOn(.completed) - dispose() + if !self.hasLatest { + self.forwardOn(.completed) + self.dispose() } } } } -final fileprivate class SwitchSinkIter +final private class SwitchSinkIter : ObserverType , LockOwnerType - , SynchronizedOnType where S.E == O.E { - typealias E = S.E - typealias Parent = SwitchSink + , SynchronizedOnType where Source.Element == Observer.Element { + typealias Element = Source.Element + typealias Parent = SwitchSink - fileprivate let _parent: Parent - fileprivate let _id: Int - fileprivate let _self: Disposable + private let parent: Parent + private let id: Int + private let this: Disposable - var _lock: RecursiveLock { - return _parent._lock + var lock: RecursiveLock { + self.parent.lock } - init(parent: Parent, id: Int, _self: Disposable) { - _parent = parent - _id = id - self._self = _self + init(parent: Parent, id: Int, this: Disposable) { + self.parent = parent + self.id = id + self.this = this } - func on(_ event: Event) { - synchronizedOn(event) + func on(_ event: Event) { + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case .next: break case .error, .completed: - _self.dispose() + self.this.dispose() } - if _parent._latest != _id { + if self.parent.latest != self.id { return } switch event { case .next: - _parent.forwardOn(event) + self.parent.forwardOn(event) case .error: - _parent.forwardOn(event) - _parent.dispose() + self.parent.forwardOn(event) + self.parent.dispose() case .completed: - _parent._hasLatest = false - if _parent._stopped { - _parent.forwardOn(event) - _parent.dispose() + self.parent.hasLatest = false + if self.parent.stopped { + self.parent.forwardOn(event) + self.parent.dispose() } } } @@ -173,61 +190,62 @@ final fileprivate class SwitchSinkIter : SwitchSink where O.E == S.E { - override init(observer: O, cancel: Cancelable) { +final private class SwitchIdentitySink: SwitchSink + where Observer.Element == Source.Element { + override init(observer: Observer, cancel: Cancelable) { super.init(observer: observer, cancel: cancel) } - override func performMap(_ element: S) throws -> S { - return element + override func performMap(_ element: Source) throws -> Source { + element } } -final fileprivate class MapSwitchSink : SwitchSink where O.E == S.E { - typealias Selector = (SourceType) throws -> S +final private class MapSwitchSink: SwitchSink where Observer.Element == Source.Element { + typealias Selector = (SourceType) throws -> Source - fileprivate let _selector: Selector + private let selector: Selector - init(selector: @escaping Selector, observer: O, cancel: Cancelable) { - _selector = selector + init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) { + self.selector = selector super.init(observer: observer, cancel: cancel) } - override func performMap(_ element: SourceType) throws -> S { - return try _selector(element) + override func performMap(_ element: SourceType) throws -> Source { + try self.selector(element) } } // MARK: Producers -final fileprivate class Switch : Producer { - fileprivate let _source: Observable +final private class Switch: Producer { + private let source: Observable - init(source: Observable) { - _source = source + init(source: Observable) { + self.source = source } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == S.E { - let sink = SwitchIdentitySink(observer: observer, cancel: cancel) - let subscription = sink.run(_source) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Source.Element { + let sink = SwitchIdentitySink(observer: observer, cancel: cancel) + let subscription = sink.run(self.source) return (sink: sink, subscription: subscription) } } -final fileprivate class FlatMapLatest : Producer { - typealias Selector = (SourceType) throws -> S +final private class FlatMapLatest: Producer { + typealias Selector = (SourceType) throws -> Source - fileprivate let _source: Observable - fileprivate let _selector: Selector + private let source: Observable + private let selector: Selector init(source: Observable, selector: @escaping Selector) { - _source = source - _selector = selector + self.source = source + self.selector = selector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == S.E { - let sink = MapSwitchSink(selector: _selector, observer: observer, cancel: cancel) - let subscription = sink.run(_source) + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Source.Element { + let sink = MapSwitchSink(selector: self.selector, observer: observer, cancel: cancel) + let subscription = sink.run(self.source) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/SwitchIfEmpty.swift b/iOS/RxSwift/Observables/SwitchIfEmpty.swift index 0b10dc61..037bf697 100644 --- a/iOS/RxSwift/Observables/SwitchIfEmpty.swift +++ b/iOS/RxSwift/Observables/SwitchIfEmpty.swift @@ -12,93 +12,93 @@ extension ObservableType { - seealso: [DefaultIfEmpty operator on reactivex.io](http://reactivex.io/documentation/operators/defaultifempty.html) - - parameter switchTo: Observable sequence being returned when source sequence is empty. + - parameter other: Observable sequence being returned when source sequence is empty. - returns: Observable sequence that contains elements from switchTo sequence if source is empty, otherwise returns source sequence elements. */ - public func ifEmpty(switchTo other: Observable) -> Observable { - return SwitchIfEmpty(source: asObservable(), ifEmpty: other) + public func ifEmpty(switchTo other: Observable) -> Observable { + SwitchIfEmpty(source: self.asObservable(), ifEmpty: other) } } -final fileprivate class SwitchIfEmpty: Producer { +final private class SwitchIfEmpty: Producer { - private let _source: Observable - private let _ifEmpty: Observable + private let source: Observable + private let ifEmpty: Observable - init(source: Observable, ifEmpty: Observable) { - _source = source - _ifEmpty = ifEmpty + init(source: Observable, ifEmpty: Observable) { + self.source = source + self.ifEmpty = ifEmpty } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - let sink = SwitchIfEmptySink(ifEmpty: _ifEmpty, + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = SwitchIfEmptySink(ifEmpty: self.ifEmpty, observer: observer, cancel: cancel) - let subscription = sink.run(_source.asObservable()) + let subscription = sink.run(self.source.asObservable()) return (sink: sink, subscription: subscription) } } -final fileprivate class SwitchIfEmptySink: Sink +final private class SwitchIfEmptySink: Sink , ObserverType { - typealias E = O.E + typealias Element = Observer.Element - private let _ifEmpty: Observable - private var _isEmpty = true - private let _ifEmptySubscription = SingleAssignmentDisposable() + private let ifEmpty: Observable + private var isEmpty = true + private let ifEmptySubscription = SingleAssignmentDisposable() - init(ifEmpty: Observable, observer: O, cancel: Cancelable) { - _ifEmpty = ifEmpty + init(ifEmpty: Observable, observer: Observer, cancel: Cancelable) { + self.ifEmpty = ifEmpty super.init(observer: observer, cancel: cancel) } - func run(_ source: Observable) -> Disposable { + func run(_ source: Observable) -> Disposable { let subscription = source.subscribe(self) - return Disposables.create(subscription, _ifEmptySubscription) + return Disposables.create(subscription, ifEmptySubscription) } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next: - _isEmpty = false - forwardOn(event) + self.isEmpty = false + self.forwardOn(event) case .error: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() case .completed: - guard _isEmpty else { - forwardOn(.completed) - dispose() + guard self.isEmpty else { + self.forwardOn(.completed) + self.dispose() return } let ifEmptySink = SwitchIfEmptySinkIter(parent: self) - _ifEmptySubscription.setDisposable(_ifEmpty.subscribe(ifEmptySink)) + self.ifEmptySubscription.setDisposable(self.ifEmpty.subscribe(ifEmptySink)) } } } -final fileprivate class SwitchIfEmptySinkIter +final private class SwitchIfEmptySinkIter : ObserverType { - typealias E = O.E - typealias Parent = SwitchIfEmptySink + typealias Element = Observer.Element + typealias Parent = SwitchIfEmptySink - private let _parent: Parent + private let parent: Parent init(parent: Parent) { - _parent = parent + self.parent = parent } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next: - _parent.forwardOn(event) + self.parent.forwardOn(event) case .error: - _parent.forwardOn(event) - _parent.dispose() + self.parent.forwardOn(event) + self.parent.dispose() case .completed: - _parent.forwardOn(event) - _parent.dispose() + self.parent.forwardOn(event) + self.parent.dispose() } } } diff --git a/iOS/RxSwift/Observables/Take.swift b/iOS/RxSwift/Observables/Take.swift index 661f8582..e5746880 100644 --- a/iOS/RxSwift/Observables/Take.swift +++ b/iOS/RxSwift/Observables/Take.swift @@ -17,17 +17,30 @@ extension ObservableType { - returns: An observable sequence that contains the specified number of elements from the start of the input sequence. */ public func take(_ count: Int) - -> Observable { + -> Observable { if count == 0 { return Observable.empty() } else { - return TakeCount(source: asObservable(), count: count) + return TakeCount(source: self.asObservable(), count: count) } } } 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. + */ + public func take(for duration: RxTimeInterval, scheduler: SchedulerType) + -> Observable { + TakeTime(source: self.asObservable(), duration: duration, scheduler: scheduler) + } /** Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers. @@ -38,141 +51,141 @@ extension ObservableType { - 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, renamed: "take(for:scheduler:)") public func take(_ duration: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - return TakeTime(source: self.asObservable(), duration: duration, scheduler: scheduler) + -> Observable { + take(for: duration, scheduler: scheduler) } } // count version -final fileprivate class TakeCountSink : Sink, ObserverType { - typealias E = O.E - typealias Parent = TakeCount +final private class TakeCountSink: Sink, ObserverType { + typealias Element = Observer.Element + typealias Parent = TakeCount - private let _parent: Parent + private let parent: Parent - private var _remaining: Int + private var remaining: Int - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - _remaining = parent._count + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + self.remaining = parent.count super.init(observer: observer, cancel: cancel) } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next(let value): - if _remaining > 0 { - _remaining -= 1 + if self.remaining > 0 { + self.remaining -= 1 - forwardOn(.next(value)) + self.forwardOn(.next(value)) - if _remaining == 0 { - forwardOn(.completed) - dispose() + if self.remaining == 0 { + self.forwardOn(.completed) + self.dispose() } } case .error: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() case .completed: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() } } } -final fileprivate class TakeCount: Producer { - fileprivate let _source: Observable - fileprivate let _count: Int +final private class TakeCount: Producer { + private let source: Observable + fileprivate let count: Int init(source: Observable, count: Int) { if count < 0 { rxFatalError("count can't be negative") } - _source = source - _count = count + self.source = source + self.count = count } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = TakeCountSink(parent: self, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } // time version -final fileprivate class TakeTimeSink - : Sink +final private class TakeTimeSink + : Sink , LockOwnerType , ObserverType - , SynchronizedOnType where O.E == ElementType { - typealias Parent = TakeTime - typealias E = ElementType + , SynchronizedOnType where Observer.Element == Element { + typealias Parent = TakeTime - fileprivate let _parent: Parent + private let parent: Parent - let _lock = RecursiveLock() + let lock = RecursiveLock() - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } - func on(_ event: Event) { - synchronizedOn(event) + func on(_ event: Event) { + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case .next(let value): - forwardOn(.next(value)) + self.forwardOn(.next(value)) case .error: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() case .completed: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() } } func tick() { - _lock.lock(); defer { _lock.unlock() } - - forwardOn(.completed) - dispose() + self.lock.performLocked { + self.forwardOn(.completed) + self.dispose() + } } func run() -> Disposable { - let disposeTimer = _parent._scheduler.scheduleRelative((), dueTime: _parent._duration) { _ in + let disposeTimer = self.parent.scheduler.scheduleRelative((), dueTime: self.parent.duration) { _ in self.tick() return Disposables.create() } - let disposeSubscription = _parent._source.subscribe(self) + let disposeSubscription = self.parent.source.subscribe(self) return Disposables.create(disposeTimer, disposeSubscription) } } -final fileprivate class TakeTime : Producer { +final private class TakeTime: Producer { typealias TimeInterval = RxTimeInterval - fileprivate let _source: Observable - fileprivate let _duration: TimeInterval - fileprivate let _scheduler: SchedulerType + fileprivate let source: Observable + fileprivate let duration: TimeInterval + fileprivate let scheduler: SchedulerType init(source: Observable, duration: TimeInterval, scheduler: SchedulerType) { - _source = source - _scheduler = scheduler - _duration = duration + self.source = source + self.scheduler = scheduler + self.duration = duration } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = TakeTimeSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/TakeLast.swift b/iOS/RxSwift/Observables/TakeLast.swift index 7bf1664b..91833872 100644 --- a/iOS/RxSwift/Observables/TakeLast.swift +++ b/iOS/RxSwift/Observables/TakeLast.swift @@ -19,60 +19,60 @@ extension ObservableType { - returns: An observable sequence containing the specified number of elements from the end of the source sequence. */ public func takeLast(_ count: Int) - -> Observable { - return TakeLast(source: asObservable(), count: count) + -> Observable { + TakeLast(source: self.asObservable(), count: count) } } -final fileprivate class TakeLastSink : Sink, ObserverType { - typealias E = O.E - typealias Parent = TakeLast +final private class TakeLastSink: Sink, ObserverType { + typealias Element = Observer.Element + typealias Parent = TakeLast - private let _parent: Parent + private let parent: Parent - private var _elements: Queue + private var elements: Queue - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - _elements = Queue(capacity: parent._count + 1) + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + self.elements = Queue(capacity: parent.count + 1) super.init(observer: observer, cancel: cancel) } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next(let value): - _elements.enqueue(value) - if _elements.count > self._parent._count { - let _ = _elements.dequeue() + self.elements.enqueue(value) + if self.elements.count > self.parent.count { + _ = self.elements.dequeue() } case .error: - forwardOn(event) - dispose() + self.forwardOn(event) + self.dispose() case .completed: - for e in _elements { - forwardOn(.next(e)) + for e in self.elements { + self.forwardOn(.next(e)) } - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() } } } -final fileprivate class TakeLast: Producer { - fileprivate let _source: Observable - fileprivate let _count: Int +final private class TakeLast: Producer { + private let source: Observable + fileprivate let count: Int init(source: Observable, count: Int) { if count < 0 { rxFatalError("count can't be negative") } - _source = source - _count = count + self.source = source + self.count = count } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = TakeLastSink(parent: self, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/TakeUntil.swift b/iOS/RxSwift/Observables/TakeUntil.swift deleted file mode 100644 index f2e5f98b..00000000 --- a/iOS/RxSwift/Observables/TakeUntil.swift +++ /dev/null @@ -1,131 +0,0 @@ -// -// TakeUntil.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/7/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Returns the elements from the source observable sequence until the other observable sequence produces an element. - - - seealso: [takeUntil operator on reactivex.io](http://reactivex.io/documentation/operators/takeuntil.html) - - - parameter other: Observable sequence that terminates propagation of elements of the source sequence. - - returns: An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation. - */ - public func takeUntil(_ other: O) - -> Observable { - return TakeUntil(source: asObservable(), other: other.asObservable()) - } -} - -final fileprivate class TakeUntilSinkOther - : ObserverType - , LockOwnerType - , SynchronizedOnType { - typealias Parent = TakeUntilSink - typealias E = Other - - fileprivate let _parent: Parent - - var _lock: RecursiveLock { - return _parent._lock - } - - fileprivate let _subscription = SingleAssignmentDisposable() - - init(parent: Parent) { - _parent = parent -#if TRACE_RESOURCES - let _ = Resources.incrementTotal() -#endif - } - - func on(_ event: Event) { - synchronizedOn(event) - } - - func _synchronized_on(_ event: Event) { - switch event { - case .next: - _parent.forwardOn(.completed) - _parent.dispose() - case .error(let e): - _parent.forwardOn(.error(e)) - _parent.dispose() - case .completed: - _subscription.dispose() - } - } - -#if TRACE_RESOURCES - deinit { - let _ = Resources.decrementTotal() - } -#endif -} - -final fileprivate class TakeUntilSink - : Sink - , LockOwnerType - , ObserverType - , SynchronizedOnType { - typealias E = O.E - typealias Parent = TakeUntil - - fileprivate let _parent: Parent - - let _lock = RecursiveLock() - - - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - synchronizedOn(event) - } - - func _synchronized_on(_ event: Event) { - switch event { - case .next: - forwardOn(event) - case .error: - forwardOn(event) - dispose() - case .completed: - forwardOn(event) - dispose() - } - } - - func run() -> Disposable { - let otherObserver = TakeUntilSinkOther(parent: self) - let otherSubscription = _parent._other.subscribe(otherObserver) - otherObserver._subscription.setDisposable(otherSubscription) - let sourceSubscription = _parent._source.subscribe(self) - - return Disposables.create(sourceSubscription, otherObserver._subscription) - } -} - -final fileprivate class TakeUntil: Producer { - - fileprivate let _source: Observable - fileprivate let _other: Observable - - init(source: Observable, other: Observable) { - _source = source - _other = other - } - - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - let sink = TakeUntilSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/iOS/RxSwift/Observables/TakeWhile.swift b/iOS/RxSwift/Observables/TakeWhile.swift deleted file mode 100644 index 2b7b5510..00000000 --- a/iOS/RxSwift/Observables/TakeWhile.swift +++ /dev/null @@ -1,85 +0,0 @@ -// -// TakeWhile.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/7/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Returns elements from an observable sequence as long as a specified condition is true. - - - seealso: [takeWhile operator on reactivex.io](http://reactivex.io/documentation/operators/takewhile.html) - - - parameter predicate: A function to test each element for a condition. - - returns: An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes. - */ - public func takeWhile(_ predicate: @escaping (E) throws -> Bool) - -> Observable { - return TakeWhile(source: asObservable(), predicate: predicate) - } -} - -final fileprivate class TakeWhileSink - : Sink - , ObserverType { - typealias Element = O.E - typealias Parent = TakeWhile - - fileprivate let _parent: Parent - - fileprivate var _running = true - - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - if !_running { - return - } - - do { - _running = try _parent._predicate(value) - } catch let e { - forwardOn(.error(e)) - dispose() - return - } - - if _running { - forwardOn(.next(value)) - } else { - forwardOn(.completed) - dispose() - } - case .error, .completed: - forwardOn(event) - dispose() - } - } - -} - -final fileprivate class TakeWhile: Producer { - typealias Predicate = (Element) throws -> Bool - - fileprivate let _source: Observable - fileprivate let _predicate: Predicate - - init(source: Observable, predicate: @escaping Predicate) { - _source = source - _predicate = predicate - } - - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { - let sink = TakeWhileSink(parent: self, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/iOS/RxSwift/Observables/TakeWithPredicate.swift b/iOS/RxSwift/Observables/TakeWithPredicate.swift new file mode 100644 index 00000000..6c28d19b --- /dev/null +++ b/iOS/RxSwift/Observables/TakeWithPredicate.swift @@ -0,0 +1,285 @@ +// +// TakeWithPredicate.swift +// RxSwift +// +// Created by Krunoslav Zaher on 6/7/15. +// Copyright © 2015 Krunoslav Zaher. All rights reserved. +// + +extension ObservableType { + /** + Returns the elements from the source observable sequence until the other observable sequence produces an element. + + - seealso: [takeUntil operator on reactivex.io](http://reactivex.io/documentation/operators/takeuntil.html) + + - parameter other: Observable sequence that terminates propagation of elements of the source sequence. + - returns: An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation. + */ + public func take(until other: Source) + -> Observable { + TakeUntil(source: self.asObservable(), other: other.asObservable()) + } + + /** + Returns elements from an observable sequence until the specified condition is true. + + - seealso: [takeUntil operator on reactivex.io](http://reactivex.io/documentation/operators/takeuntil.html) + + - parameter predicate: A function to test each element for a condition. + - parameter behavior: Whether or not to include the last element matching the predicate. Defaults to `exclusive`. + + - returns: An observable sequence that contains the elements from the input sequence that occur before the element at which the test passes. + */ + public func take(until predicate: @escaping (Element) throws -> Bool, + behavior: TakeBehavior = .exclusive) + -> Observable { + TakeUntilPredicate(source: self.asObservable(), + behavior: behavior, + predicate: predicate) + } + + /** + Returns elements from an observable sequence as long as a specified condition is true. + + - seealso: [takeWhile operator on reactivex.io](http://reactivex.io/documentation/operators/takewhile.html) + + - parameter predicate: A function to test each element for a condition. + - returns: An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes. + */ + public func take(while predicate: @escaping (Element) throws -> Bool, + behavior: TakeBehavior = .exclusive) + -> Observable { + take(until: { try !predicate($0) }, behavior: behavior) + } + + /** + Returns the elements from the source observable sequence until the other observable sequence produces an element. + + - seealso: [takeUntil operator on reactivex.io](http://reactivex.io/documentation/operators/takeuntil.html) + + - parameter other: Observable sequence that terminates propagation of elements of the source sequence. + - returns: An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation. + */ + @available(*, deprecated, renamed: "take(until:)") + public func takeUntil(_ other: Source) + -> Observable { + take(until: other) + } + + /** + Returns elements from an observable sequence until the specified condition is true. + + - seealso: [takeUntil operator on reactivex.io](http://reactivex.io/documentation/operators/takeuntil.html) + + - parameter behavior: Whether or not to include the last element matching the predicate. + - parameter predicate: A function to test each element for a condition. + - returns: An observable sequence that contains the elements from the input sequence that occur before the element at which the test passes. + */ + @available(*, deprecated, renamed: "take(until:behavior:)") + public func takeUntil(_ behavior: TakeBehavior, + predicate: @escaping (Element) throws -> Bool) + -> Observable { + take(until: predicate, behavior: behavior) + } + + /** + Returns elements from an observable sequence as long as a specified condition is true. + + - seealso: [takeWhile operator on reactivex.io](http://reactivex.io/documentation/operators/takewhile.html) + + - parameter predicate: A function to test each element for a condition. + - returns: An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes. + */ + @available(*, deprecated, renamed: "take(while:)") + public func takeWhile(_ predicate: @escaping (Element) throws -> Bool) + -> Observable { + take(until: { try !predicate($0) }, behavior: .exclusive) + } +} + +/// Behaviors for the take operator family. +public enum TakeBehavior { + /// Include the last element matching the predicate. + case inclusive + + /// Exclude the last element matching the predicate. + case exclusive +} + +// MARK: - TakeUntil Observable +final private class TakeUntilSinkOther + : ObserverType + , LockOwnerType + , SynchronizedOnType { + typealias Parent = TakeUntilSink + typealias Element = Other + + private let parent: Parent + + var lock: RecursiveLock { + self.parent.lock + } + + fileprivate let subscription = SingleAssignmentDisposable() + + init(parent: Parent) { + self.parent = parent +#if TRACE_RESOURCES + _ = Resources.incrementTotal() +#endif + } + + func on(_ event: Event) { + self.synchronizedOn(event) + } + + func synchronized_on(_ event: Event) { + switch event { + case .next: + self.parent.forwardOn(.completed) + self.parent.dispose() + case .error(let e): + self.parent.forwardOn(.error(e)) + self.parent.dispose() + case .completed: + self.subscription.dispose() + } + } + +#if TRACE_RESOURCES + deinit { + _ = Resources.decrementTotal() + } +#endif +} + +final private class TakeUntilSink + : Sink + , LockOwnerType + , ObserverType + , SynchronizedOnType { + typealias Element = Observer.Element + typealias Parent = TakeUntil + + private let parent: Parent + + let lock = RecursiveLock() + + + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + super.init(observer: observer, cancel: cancel) + } + + func on(_ event: Event) { + self.synchronizedOn(event) + } + + func synchronized_on(_ event: Event) { + switch event { + case .next: + self.forwardOn(event) + case .error: + self.forwardOn(event) + self.dispose() + case .completed: + self.forwardOn(event) + self.dispose() + } + } + + func run() -> Disposable { + let otherObserver = TakeUntilSinkOther(parent: self) + let otherSubscription = self.parent.other.subscribe(otherObserver) + otherObserver.subscription.setDisposable(otherSubscription) + let sourceSubscription = self.parent.source.subscribe(self) + + return Disposables.create(sourceSubscription, otherObserver.subscription) + } +} + +final private class TakeUntil: Producer { + + fileprivate let source: Observable + fileprivate let other: Observable + + init(source: Observable, other: Observable) { + self.source = source + self.other = other + } + + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = TakeUntilSink(parent: self, observer: observer, cancel: cancel) + let subscription = sink.run() + return (sink: sink, subscription: subscription) + } +} + +// MARK: - TakeUntil Predicate +final private class TakeUntilPredicateSink + : Sink, ObserverType { + typealias Element = Observer.Element + typealias Parent = TakeUntilPredicate + + private let parent: Parent + private var running = true + + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + super.init(observer: observer, cancel: cancel) + } + + func on(_ event: Event) { + switch event { + case .next(let value): + if !self.running { + return + } + + do { + self.running = try !self.parent.predicate(value) + } catch let e { + self.forwardOn(.error(e)) + self.dispose() + return + } + + if self.running { + self.forwardOn(.next(value)) + } else { + if self.parent.behavior == .inclusive { + self.forwardOn(.next(value)) + } + + self.forwardOn(.completed) + self.dispose() + } + case .error, .completed: + self.forwardOn(event) + self.dispose() + } + } + +} + +final private class TakeUntilPredicate: Producer { + typealias Predicate = (Element) throws -> Bool + + private let source: Observable + fileprivate let predicate: Predicate + fileprivate let behavior: TakeBehavior + + init(source: Observable, + behavior: TakeBehavior, + predicate: @escaping Predicate) { + self.source = source + self.behavior = behavior + self.predicate = predicate + } + + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + let sink = TakeUntilPredicateSink(parent: self, observer: observer, cancel: cancel) + let subscription = self.source.subscribe(sink) + return (sink: sink, subscription: subscription) + } +} diff --git a/iOS/RxSwift/Observables/Throttle.swift b/iOS/RxSwift/Observables/Throttle.swift index 0c4ca746..86152a83 100644 --- a/iOS/RxSwift/Observables/Throttle.swift +++ b/iOS/RxSwift/Observables/Throttle.swift @@ -6,7 +6,7 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import struct Foundation.Date +import Foundation extension ObservableType { @@ -23,138 +23,135 @@ extension ObservableType { - returns: The throttled sequence. */ public func throttle(_ dueTime: RxTimeInterval, latest: Bool = true, scheduler: SchedulerType) - -> Observable { - return Throttle(source: self.asObservable(), dueTime: dueTime, latest: latest, scheduler: scheduler) + -> Observable { + Throttle(source: self.asObservable(), dueTime: dueTime, latest: latest, scheduler: scheduler) } } -final fileprivate class ThrottleSink - : Sink +final private class ThrottleSink + : Sink , ObserverType , LockOwnerType , SynchronizedOnType { - typealias Element = O.E + typealias Element = Observer.Element typealias ParentType = Throttle - private let _parent: ParentType + private let parent: ParentType - let _lock = RecursiveLock() + let lock = RecursiveLock() // state - private var _lastUnsentElement: Element? = nil - private var _lastSentTime: Date? = nil - private var _completed: Bool = false + private var lastUnsentElement: Element? + private var lastSentTime: Date? + private var completed: Bool = false let cancellable = SerialDisposable() - init(parent: ParentType, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: ParentType, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - let subscription = _parent._source.subscribe(self) + let subscription = self.parent.source.subscribe(self) return Disposables.create(subscription, cancellable) } func on(_ event: Event) { - synchronizedOn(event) + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case .next(let element): - let now = _parent._scheduler.now + let now = self.parent.scheduler.now - let timeIntervalSinceLast: RxTimeInterval + let reducedScheduledTime: RxTimeInterval - if let lastSendingTime = _lastSentTime { - timeIntervalSinceLast = now.timeIntervalSince(lastSendingTime) + if let lastSendingTime = self.lastSentTime { + reducedScheduledTime = self.parent.dueTime.reduceWithSpanBetween(earlierDate: lastSendingTime, laterDate: now) } else { - timeIntervalSinceLast = _parent._dueTime + reducedScheduledTime = .nanoseconds(0) } - let couldSendNow = timeIntervalSinceLast >= _parent._dueTime - - if couldSendNow { + if reducedScheduledTime.isNow { self.sendNow(element: element) return } - if !_parent._latest { + if !self.parent.latest { return } - let isThereAlreadyInFlightRequest = _lastUnsentElement != nil + let isThereAlreadyInFlightRequest = self.lastUnsentElement != nil - _lastUnsentElement = element + self.lastUnsentElement = element if isThereAlreadyInFlightRequest { return } - let scheduler = _parent._scheduler - let dueTime = _parent._dueTime + let scheduler = self.parent.scheduler 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: - _lastUnsentElement = nil - forwardOn(event) - dispose() + self.lastUnsentElement = nil + self.forwardOn(event) + self.dispose() case .completed: - if let _ = _lastUnsentElement { - _completed = true + if self.lastUnsentElement != nil { + self.completed = true } else { - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() } } } private func sendNow(element: Element) { - _lastUnsentElement = nil + self.lastUnsentElement = nil self.forwardOn(.next(element)) // in case element processing takes a while, this should give some more room - _lastSentTime = _parent._scheduler.now + self.lastSentTime = self.parent.scheduler.now } func propagate(_: Int) -> Disposable { - _lock.lock(); defer { _lock.unlock() } // { - if let lastUnsentElement = _lastUnsentElement { - sendNow(element: lastUnsentElement) + self.lock.performLocked { + if let lastUnsentElement = self.lastUnsentElement { + self.sendNow(element: lastUnsentElement) } - if _completed { - forwardOn(.completed) - dispose() + if self.completed { + self.forwardOn(.completed) + self.dispose() } - // } + } + return Disposables.create() } } -final fileprivate class Throttle : Producer { - - fileprivate let _source: Observable - fileprivate let _dueTime: RxTimeInterval - fileprivate let _latest: Bool - fileprivate let _scheduler: SchedulerType +final private class Throttle: Producer { + fileprivate let source: Observable + fileprivate let dueTime: RxTimeInterval + fileprivate let latest: Bool + fileprivate let scheduler: SchedulerType init(source: Observable, dueTime: RxTimeInterval, latest: Bool, scheduler: SchedulerType) { - _source = source - _dueTime = dueTime - _latest = latest - _scheduler = scheduler + self.source = source + self.dueTime = dueTime + self.latest = latest + self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = ThrottleSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/Timeout.swift b/iOS/RxSwift/Observables/Timeout.swift index 7008de82..efcc7917 100644 --- a/iOS/RxSwift/Observables/Timeout.swift +++ b/iOS/RxSwift/Observables/Timeout.swift @@ -18,7 +18,7 @@ extension ObservableType { - returns: An observable sequence with a `RxError.timeout` in case of a timeout. */ public func timeout(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> Observable { + -> Observable { return Timeout(source: self.asObservable(), dueTime: dueTime, other: Observable.error(RxError.timeout), scheduler: scheduler) } @@ -32,94 +32,94 @@ extension ObservableType { - parameter scheduler: Scheduler to run the timeout timer on. - returns: The source sequence switching to the other sequence in case of a timeout. */ - public func timeout(_ dueTime: RxTimeInterval, other: O, scheduler: SchedulerType) - -> Observable where E == O.E { + public func timeout(_ dueTime: RxTimeInterval, other: Source, scheduler: SchedulerType) + -> Observable where Element == Source.Element { return Timeout(source: self.asObservable(), dueTime: dueTime, other: other.asObservable(), scheduler: scheduler) } } -final fileprivate class TimeoutSink: Sink, LockOwnerType, ObserverType { - typealias E = O.E - typealias Parent = Timeout +final private class TimeoutSink: Sink, LockOwnerType, ObserverType { + typealias Element = Observer.Element + typealias Parent = Timeout - private let _parent: Parent + private let parent: Parent - let _lock = RecursiveLock() + let lock = RecursiveLock() - private let _timerD = SerialDisposable() - private let _subscription = SerialDisposable() + private let timerD = SerialDisposable() + private let subscription = SerialDisposable() - private var _id = 0 - private var _switched = false + private var id = 0 + private var switched = false - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } func run() -> Disposable { let original = SingleAssignmentDisposable() - _subscription.disposable = original + self.subscription.disposable = original - _createTimeoutTimer() + self.createTimeoutTimer() - original.setDisposable(_parent._source.subscribe(self)) + original.setDisposable(self.parent.source.subscribe(self)) - return Disposables.create(_subscription, _timerD) + return Disposables.create(subscription, timerD) } - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next: var onNextWins = false - _lock.performLocked() { - onNextWins = !self._switched + self.lock.performLocked { + onNextWins = !self.switched if onNextWins { - self._id = self._id &+ 1 + self.id = self.id &+ 1 } } if onNextWins { - forwardOn(event) - self._createTimeoutTimer() + self.forwardOn(event) + self.createTimeoutTimer() } case .error, .completed: var onEventWins = false - _lock.performLocked() { - onEventWins = !self._switched + self.lock.performLocked { + onEventWins = !self.switched if onEventWins { - self._id = self._id &+ 1 + self.id = self.id &+ 1 } } if onEventWins { - forwardOn(event) + self.forwardOn(event) self.dispose() } } } - private func _createTimeoutTimer() { - if _timerD.isDisposed { + private func createTimeoutTimer() { + if self.timerD.isDisposed { return } let nextTimer = SingleAssignmentDisposable() - _timerD.disposable = nextTimer + self.timerD.disposable = nextTimer - let disposeSchedule = _parent._scheduler.scheduleRelative(_id, dueTime: _parent._dueTime) { state in + let disposeSchedule = self.parent.scheduler.scheduleRelative(self.id, dueTime: self.parent.dueTime) { state in var timerWins = false - self._lock.performLocked() { - self._switched = (state == self._id) - timerWins = self._switched + self.lock.performLocked { + self.switched = (state == self.id) + timerWins = self.switched } if timerWins { - self._subscription.disposable = self._parent._other.subscribe(self.forwarder()) + self.subscription.disposable = self.parent.other.subscribe(self.forwarder()) } return Disposables.create() @@ -130,21 +130,20 @@ final fileprivate class TimeoutSink: Sink, LockOwnerType, Ob } -final fileprivate class Timeout : Producer { - - fileprivate let _source: Observable - fileprivate let _dueTime: RxTimeInterval - fileprivate let _other: Observable - fileprivate let _scheduler: SchedulerType +final private class Timeout: Producer { + fileprivate let source: Observable + fileprivate let dueTime: RxTimeInterval + fileprivate let other: Observable + fileprivate let scheduler: SchedulerType init(source: Observable, dueTime: RxTimeInterval, other: Observable, scheduler: SchedulerType) { - _source = source - _dueTime = dueTime - _other = other - _scheduler = scheduler + self.source = source + self.dueTime = dueTime + self.other = other + self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = TimeoutSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/Timer.swift b/iOS/RxSwift/Observables/Timer.swift index dec69e12..30bbdf67 100644 --- a/iOS/RxSwift/Observables/Timer.swift +++ b/iOS/RxSwift/Observables/Timer.swift @@ -6,7 +6,7 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -extension ObservableType where E : RxAbstractInteger { +extension ObservableType 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. @@ -17,15 +17,16 @@ extension ObservableType where E : RxAbstractInteger { - returns: An observable sequence that produces a value after each period. */ public static func interval(_ period: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - return Timer(dueTime: period, - period: period, - scheduler: scheduler + -> Observable { + return Timer( + dueTime: period, + period: period, + scheduler: scheduler ) } } -extension ObservableType where E: RxAbstractInteger { +extension ObservableType 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. @@ -37,7 +38,7 @@ extension ObservableType where E: RxAbstractInteger { - returns: An observable sequence that produces a value after due time has elapsed and then each period. */ public static func timer(_ dueTime: RxTimeInterval, period: RxTimeInterval? = nil, scheduler: SchedulerType) - -> Observable { + -> Observable { return Timer( dueTime: dueTime, period: period, @@ -46,36 +47,41 @@ extension ObservableType where E: RxAbstractInteger { } } -final fileprivate class TimerSink : Sink where O.E : RxAbstractInteger { - typealias Parent = Timer - - private let _parent: Parent - - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent +import Foundation + +final private class TimerSink : Sink where Observer.Element : RxAbstractInteger { + typealias Parent = Timer + + private let parent: Parent + private let lock = RecursiveLock() + + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } - + func run() -> Disposable { - return _parent._scheduler.schedulePeriodic(0 as O.E, startAfter: _parent._dueTime, period: _parent._period!) { state in - self.forwardOn(.next(state)) - return state &+ 1 + return self.parent.scheduler.schedulePeriodic(0 as Observer.Element, startAfter: self.parent.dueTime, period: self.parent.period!) { state in + self.lock.performLocked { + self.forwardOn(.next(state)) + return state &+ 1 + } } } } -final fileprivate class TimerOneOffSink : Sink where O.E : RxAbstractInteger { - typealias Parent = Timer - - private let _parent: Parent - - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent +final private class TimerOneOffSink: Sink where Observer.Element: RxAbstractInteger { + typealias Parent = Timer + + private let parent: Parent + + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } - + func run() -> Disposable { - return _parent._scheduler.scheduleRelative(self, dueTime: _parent._dueTime) { (`self`) -> Disposable in + return self.parent.scheduler.scheduleRelative(self, dueTime: self.parent.dueTime) { [unowned self] _ -> Disposable in self.forwardOn(.next(0)) self.forwardOn(.completed) self.dispose() @@ -85,19 +91,19 @@ final fileprivate class TimerOneOffSink : Sink where O.E : R } } -final fileprivate class Timer: Producer { - fileprivate let _scheduler: SchedulerType - fileprivate let _dueTime: RxTimeInterval - fileprivate let _period: RxTimeInterval? - +final private class Timer: Producer { + fileprivate let scheduler: SchedulerType + fileprivate let dueTime: RxTimeInterval + fileprivate let period: RxTimeInterval? + init(dueTime: RxTimeInterval, period: RxTimeInterval?, scheduler: SchedulerType) { - _scheduler = scheduler - _dueTime = dueTime - _period = period + self.scheduler = scheduler + self.dueTime = dueTime + self.period = period } - - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E { - if let _ = _period { + + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { + if self.period != nil { let sink = TimerSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/ToArray.swift b/iOS/RxSwift/Observables/ToArray.swift index 93fcb80e..76c7370a 100644 --- a/iOS/RxSwift/Observables/ToArray.swift +++ b/iOS/RxSwift/Observables/ToArray.swift @@ -6,32 +6,30 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // - extension ObservableType { - /** - Converts an Observable into another Observable that emits the whole sequence as a single array and then terminates. + Converts an Observable into a Single that emits the whole sequence as a single array and then terminates. For aggregation behavior see `reduce`. - seealso: [toArray operator on reactivex.io](http://reactivex.io/documentation/operators/to.html) - - returns: An observable sequence containing all the emitted elements as array. + - returns: A Single sequence containing all the emitted elements as array. */ public func toArray() - -> Observable<[E]> { - return ToArray(source: self.asObservable()) + -> Single<[Element]> { + PrimitiveSequence(raw: ToArray(source: self.asObservable())) } } -final fileprivate class ToArraySink : Sink, ObserverType where O.E == [SourceType] { +final private class ToArraySink: Sink, ObserverType where Observer.Element == [SourceType] { typealias Parent = ToArray - let _parent: Parent - var _list = Array() + let parent: Parent + var list = [SourceType]() - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } @@ -39,28 +37,28 @@ final fileprivate class ToArraySink : Sink, Obse func on(_ event: Event) { switch event { case .next(let value): - self._list.append(value) + self.list.append(value) case .error(let e): - forwardOn(.error(e)) + self.forwardOn(.error(e)) self.dispose() case .completed: - forwardOn(.next(_list)) - forwardOn(.completed) + self.forwardOn(.next(self.list)) + self.forwardOn(.completed) self.dispose() } } } -final fileprivate class ToArray : Producer<[SourceType]> { - let _source: Observable +final private class ToArray: Producer<[SourceType]> { + let source: Observable init(source: Observable) { - _source = source + self.source = source } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == [SourceType] { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == [SourceType] { let sink = ToArraySink(parent: self, observer: observer, cancel: cancel) - let subscription = _source.subscribe(sink) + let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } } diff --git a/iOS/RxSwift/Observables/Using.swift b/iOS/RxSwift/Observables/Using.swift index 8ea83267..ca48d2fb 100644 --- a/iOS/RxSwift/Observables/Using.swift +++ b/iOS/RxSwift/Observables/Using.swift @@ -16,19 +16,19 @@ extension ObservableType { - parameter observableFactory: Factory function to obtain an observable sequence that depends on the obtained resource. - returns: An observable sequence whose lifetime controls the lifetime of the dependent resource object. */ - public static func using(_ resourceFactory: @escaping () throws -> Resource, observableFactory: @escaping (Resource) throws -> Observable) -> Observable { - return Using(resourceFactory: resourceFactory, observableFactory: observableFactory) + public static func using(_ resourceFactory: @escaping () throws -> Resource, observableFactory: @escaping (Resource) throws -> Observable) -> Observable { + Using(resourceFactory: resourceFactory, observableFactory: observableFactory) } } -final fileprivate class UsingSink : Sink, ObserverType { - typealias SourceType = O.E +final private class UsingSink: Sink, ObserverType { + typealias SourceType = Observer.Element typealias Parent = Using - private let _parent: Parent + private let parent: Parent - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } @@ -36,9 +36,9 @@ final fileprivate class UsingSink : S var disposable = Disposables.create() do { - let resource = try _parent._resourceFactory() + let resource = try self.parent.resourceFactory() disposable = resource - let source = try _parent._observableFactory(resource) + let source = try self.parent.observableFactory(resource) return Disposables.create( source.subscribe(self), @@ -55,34 +55,34 @@ final fileprivate class UsingSink : S func on(_ event: Event) { switch event { case let .next(value): - forwardOn(.next(value)) + self.forwardOn(.next(value)) case let .error(error): - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() case .completed: - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() } } } -final fileprivate class Using: Producer { +final private class Using: Producer { - typealias E = SourceType + typealias Element = SourceType typealias ResourceFactory = () throws -> ResourceType typealias ObservableFactory = (ResourceType) throws -> Observable - fileprivate let _resourceFactory: ResourceFactory - fileprivate let _observableFactory: ObservableFactory + fileprivate let resourceFactory: ResourceFactory + fileprivate let observableFactory: ObservableFactory init(resourceFactory: @escaping ResourceFactory, observableFactory: @escaping ObservableFactory) { - _resourceFactory = resourceFactory - _observableFactory = observableFactory + self.resourceFactory = resourceFactory + self.observableFactory = observableFactory } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = UsingSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/Window.swift b/iOS/RxSwift/Observables/Window.swift index c862dfba..b2a37a5c 100644 --- a/iOS/RxSwift/Observables/Window.swift +++ b/iOS/RxSwift/Observables/Window.swift @@ -19,123 +19,122 @@ extension ObservableType { - returns: An observable sequence of windows (instances of `Observable`). */ public func window(timeSpan: RxTimeInterval, count: Int, scheduler: SchedulerType) - -> Observable> { + -> Observable> { return WindowTimeCount(source: self.asObservable(), timeSpan: timeSpan, count: count, scheduler: scheduler) } } -final fileprivate class WindowTimeCountSink - : Sink +final private class WindowTimeCountSink + : Sink , ObserverType , LockOwnerType - , SynchronizedOnType where O.E == Observable { + , SynchronizedOnType where Observer.Element == Observable { typealias Parent = WindowTimeCount - typealias E = Element - private let _parent: Parent + private let parent: Parent - let _lock = RecursiveLock() + let lock = RecursiveLock() - private var _subject = PublishSubject() - private var _count = 0 - private var _windowId = 0 + private var subject = PublishSubject() + private var count = 0 + private var windowId = 0 - private let _timerD = SerialDisposable() - private let _refCountDisposable: RefCountDisposable - private let _groupDisposable = CompositeDisposable() + private let timerD = SerialDisposable() + private let refCountDisposable: RefCountDisposable + private let groupDisposable = CompositeDisposable() - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent - let _ = _groupDisposable.insert(_timerD) + _ = self.groupDisposable.insert(self.timerD) - _refCountDisposable = RefCountDisposable(disposable: _groupDisposable) + self.refCountDisposable = RefCountDisposable(disposable: self.groupDisposable) super.init(observer: observer, cancel: cancel) } func run() -> Disposable { - forwardOn(.next(AddRef(source: _subject, refCount: _refCountDisposable).asObservable())) - createTimer(_windowId) + self.forwardOn(.next(AddRef(source: self.subject, refCount: self.refCountDisposable).asObservable())) + self.createTimer(self.windowId) - let _ = _groupDisposable.insert(_parent._source.subscribe(self)) - return _refCountDisposable + _ = self.groupDisposable.insert(self.parent.source.subscribe(self)) + return self.refCountDisposable } func startNewWindowAndCompleteCurrentOne() { - _subject.on(.completed) - _subject = PublishSubject() + self.subject.on(.completed) + self.subject = PublishSubject() - forwardOn(.next(AddRef(source: _subject, refCount: _refCountDisposable).asObservable())) + self.forwardOn(.next(AddRef(source: self.subject, refCount: self.refCountDisposable).asObservable())) } - func on(_ event: Event) { - synchronizedOn(event) + func on(_ event: Event) { + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { var newWindow = false var newId = 0 switch event { case .next(let element): - _subject.on(.next(element)) + self.subject.on(.next(element)) do { - let _ = try incrementChecked(&_count) - } catch (let e) { - _subject.on(.error(e as Swift.Error)) - dispose() + _ = try incrementChecked(&self.count) + } catch let e { + self.subject.on(.error(e as Swift.Error)) + self.dispose() } - if (_count == _parent._count) { + if self.count == self.parent.count { newWindow = true - _count = 0 - _windowId += 1 - newId = _windowId + self.count = 0 + self.windowId += 1 + newId = self.windowId self.startNewWindowAndCompleteCurrentOne() } case .error(let error): - _subject.on(.error(error)) - forwardOn(.error(error)) - dispose() + self.subject.on(.error(error)) + self.forwardOn(.error(error)) + self.dispose() case .completed: - _subject.on(.completed) - forwardOn(.completed) - dispose() + self.subject.on(.completed) + self.forwardOn(.completed) + self.dispose() } if newWindow { - createTimer(newId) + self.createTimer(newId) } } func createTimer(_ windowId: Int) { - if _timerD.isDisposed { + if self.timerD.isDisposed { return } - if _windowId != windowId { + if self.windowId != windowId { return } let nextTimer = SingleAssignmentDisposable() - _timerD.disposable = nextTimer + self.timerD.disposable = nextTimer - let scheduledRelative = _parent._scheduler.scheduleRelative(windowId, dueTime: _parent._timeSpan) { previousWindowId in + let scheduledRelative = self.parent.scheduler.scheduleRelative(windowId, dueTime: self.parent.timeSpan) { previousWindowId in var newId = 0 - self._lock.performLocked { - if previousWindowId != self._windowId { + self.lock.performLocked { + if previousWindowId != self.windowId { return } - self._count = 0 - self._windowId = self._windowId &+ 1 - newId = self._windowId + self.count = 0 + self.windowId = self.windowId &+ 1 + newId = self.windowId self.startNewWindowAndCompleteCurrentOne() } @@ -148,21 +147,20 @@ final fileprivate class WindowTimeCountSink } } -final fileprivate class WindowTimeCount : Producer> { - - fileprivate let _timeSpan: RxTimeInterval - fileprivate let _count: Int - fileprivate let _scheduler: SchedulerType - fileprivate let _source: Observable +final private class WindowTimeCount: Producer> { + fileprivate let timeSpan: RxTimeInterval + fileprivate let count: Int + fileprivate let scheduler: SchedulerType + fileprivate let source: Observable init(source: Observable, timeSpan: RxTimeInterval, count: Int, scheduler: SchedulerType) { - _source = source - _timeSpan = timeSpan - _count = count - _scheduler = scheduler + self.source = source + self.timeSpan = timeSpan + self.count = count + self.scheduler = scheduler } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Observable { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Observable { let sink = WindowTimeCountSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/WithLatestFrom.swift b/iOS/RxSwift/Observables/WithLatestFrom.swift index bd22e2f0..d2868121 100644 --- a/iOS/RxSwift/Observables/WithLatestFrom.swift +++ b/iOS/RxSwift/Observables/WithLatestFrom.swift @@ -12,44 +12,46 @@ extension ObservableType { Merges two observable sequences into one observable sequence by combining each element from self with the latest element from the second source, if any. - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) + - note: Elements emitted by self before the second source has emitted any values will be omitted. - parameter second: Second observable source. - parameter resultSelector: Function to invoke for each element from the self combined with the latest element from the second source, if any. - returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function. */ - public func withLatestFrom(_ second: SecondO, resultSelector: @escaping (E, SecondO.E) throws -> ResultType) -> Observable { - return WithLatestFrom(first: asObservable(), second: second.asObservable(), resultSelector: resultSelector) + public func withLatestFrom(_ second: Source, resultSelector: @escaping (Element, Source.Element) throws -> ResultType) -> Observable { + WithLatestFrom(first: self.asObservable(), second: second.asObservable(), resultSelector: resultSelector) } /** Merges two observable sequences into one observable sequence by using latest element from the second sequence every time when `self` emits an element. - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) + - note: Elements emitted by self before the second source has emitted any values will be omitted. - parameter second: Second observable source. - returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function. */ - public func withLatestFrom(_ second: SecondO) -> Observable { - return WithLatestFrom(first: asObservable(), second: second.asObservable(), resultSelector: { $1 }) + public func withLatestFrom(_ second: Source) -> Observable { + WithLatestFrom(first: self.asObservable(), second: second.asObservable(), resultSelector: { $1 }) } } -final fileprivate class WithLatestFromSink - : Sink +final private class WithLatestFromSink + : Sink , ObserverType , LockOwnerType , SynchronizedOnType { - typealias ResultType = O.E + typealias ResultType = Observer.Element typealias Parent = WithLatestFrom - typealias E = FirstType + typealias Element = FirstType - fileprivate let _parent: Parent + private let parent: Parent - var _lock = RecursiveLock() - fileprivate var _latest: SecondType? + fileprivate var lock = RecursiveLock() + fileprivate var latest: SecondType? - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(observer: observer, cancel: cancel) } @@ -58,90 +60,90 @@ final fileprivate class WithLatestFromSink) { - synchronizedOn(event) + func on(_ event: Event) { + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case let .next(value): - guard let latest = _latest else { return } + guard let latest = self.latest else { return } do { - let res = try _parent._resultSelector(value, latest) + let res = try self.parent.resultSelector(value, latest) - forwardOn(.next(res)) + self.forwardOn(.next(res)) } catch let e { - forwardOn(.error(e)) - dispose() + self.forwardOn(.error(e)) + self.dispose() } case .completed: - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() case let .error(error): - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() } } } -final fileprivate class WithLatestFromSecond +final private class WithLatestFromSecond : ObserverType , LockOwnerType , SynchronizedOnType { - typealias ResultType = O.E - typealias Parent = WithLatestFromSink - typealias E = SecondType + typealias ResultType = Observer.Element + typealias Parent = WithLatestFromSink + typealias Element = SecondType - private let _parent: Parent - private let _disposable: Disposable + private let parent: Parent + private let disposable: Disposable - var _lock: RecursiveLock { - return _parent._lock + var lock: RecursiveLock { + self.parent.lock } init(parent: Parent, disposable: Disposable) { - _parent = parent - _disposable = disposable + self.parent = parent + self.disposable = disposable } - func on(_ event: Event) { - synchronizedOn(event) + func on(_ event: Event) { + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { + func synchronized_on(_ event: Event) { switch event { case let .next(value): - _parent._latest = value + self.parent.latest = value case .completed: - _disposable.dispose() + self.disposable.dispose() case let .error(error): - _parent.forwardOn(.error(error)) - _parent.dispose() + self.parent.forwardOn(.error(error)) + self.parent.dispose() } } } -final fileprivate class WithLatestFrom: Producer { +final private class WithLatestFrom: Producer { typealias ResultSelector = (FirstType, SecondType) throws -> ResultType - fileprivate let _first: Observable - fileprivate let _second: Observable - fileprivate let _resultSelector: ResultSelector + fileprivate let first: Observable + fileprivate let second: Observable + fileprivate let resultSelector: ResultSelector init(first: Observable, second: Observable, resultSelector: @escaping ResultSelector) { - _first = first - _second = second - _resultSelector = resultSelector + self.first = first + self.second = second + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == ResultType { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == ResultType { let sink = WithLatestFromSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/WithUnretained.swift b/iOS/RxSwift/Observables/WithUnretained.swift new file mode 100644 index 00000000..076f6de8 --- /dev/null +++ b/iOS/RxSwift/Observables/WithUnretained.swift @@ -0,0 +1,58 @@ +// +// WithUnretained.swift +// RxSwift +// +// Created by Vincent Pradeilles on 01/01/2021. +// Copyright © 2020 Krunoslav Zaher. All rights reserved. +// + +extension ObservableType { + /** + Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence. + + In the case the provided object cannot be retained successfully, the sequence will complete. + + - note: Be careful when using this operator in a sequence that has a buffer or replay, for example `share(replay: 1)`, as the sharing buffer will also include the provided object, which could potentially cause a retain cycle. + + - parameter obj: The object to provide an unretained reference on. + - parameter resultSelector: A function to combine the unretained referenced on `obj` and the value of the observable sequence. + - returns: An observable sequence that contains the result of `resultSelector` being called with an unretained reference on `obj` and the values of the original sequence. + */ + public func withUnretained( + _ obj: Object, + resultSelector: @escaping (Object, Element) -> Out + ) -> Observable { + map { [weak obj] element -> Out in + guard let obj = obj else { throw UnretainedError.failedRetaining } + + return resultSelector(obj, element) + } + .catch{ error -> Observable in + guard let unretainedError = error as? UnretainedError, + unretainedError == .failedRetaining else { + return .error(error) + } + + return .empty() + } + } + + + /** + Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence. + + In the case the provided object cannot be retained successfully, the sequence will complete. + + - note: Be careful when using this operator in a sequence that has a buffer or replay, for example `share(replay: 1)`, as the sharing buffer will also include the provided object, which could potentially cause a retain cycle. + + - parameter obj: The object to provide an unretained reference on. + - returns: An observable sequence of tuples that contains both an unretained reference on `obj` and the values of the original sequence. + */ + public func withUnretained(_ obj: Object) -> Observable<(Object, Element)> { + return withUnretained(obj) { ($0, $1) } + } +} + +private enum UnretainedError: Swift.Error { + case failedRetaining +} diff --git a/iOS/RxSwift/Observables/Zip+Collection.swift b/iOS/RxSwift/Observables/Zip+Collection.swift index 11f25fc3..2d7f8877 100644 --- a/iOS/RxSwift/Observables/Zip+Collection.swift +++ b/iOS/RxSwift/Observables/Zip+Collection.swift @@ -15,9 +15,9 @@ extension ObservableType { - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ - public static func zip(_ collection: C, _ resultSelector: @escaping ([C.Iterator.Element.E]) throws -> E) -> Observable - where C.Iterator.Element: ObservableType { - return ZipCollectionType(sources: collection, resultSelector: resultSelector) + public static func zip(_ collection: Collection, resultSelector: @escaping ([Collection.Element.Element]) throws -> Element) -> Observable + where Collection.Element: ObservableType { + ZipCollectionType(sources: collection, resultSelector: resultSelector) } /** @@ -27,141 +27,140 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources. */ - public static func zip(_ collection: C) -> Observable<[E]> - where C.Iterator.Element: ObservableType, C.Iterator.Element.E == E { - return ZipCollectionType(sources: collection, resultSelector: { $0 }) + public static func zip(_ collection: Collection) -> Observable<[Element]> + where Collection.Element: ObservableType, Collection.Element.Element == Element { + ZipCollectionType(sources: collection, resultSelector: { $0 }) } } -final fileprivate class ZipCollectionTypeSink - : Sink where C.Iterator.Element : ObservableConvertibleType { - typealias R = O.E - typealias Parent = ZipCollectionType - typealias SourceElement = C.Iterator.Element.E +final private class ZipCollectionTypeSink + : Sink where Collection.Element: ObservableConvertibleType { + typealias Result = Observer.Element + typealias Parent = ZipCollectionType + typealias SourceElement = Collection.Element.Element - private let _parent: Parent + private let parent: Parent - private let _lock = RecursiveLock() + private let lock = RecursiveLock() // state - private var _numberOfValues = 0 - private var _values: [Queue] - private var _isDone: [Bool] - private var _numberOfDone = 0 - private var _subscriptions: [SingleAssignmentDisposable] + private var numberOfValues = 0 + private var values: [Queue] + private var isDone: [Bool] + private var numberOfDone = 0 + private var subscriptions: [SingleAssignmentDisposable] - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent - _values = [Queue](repeating: Queue(capacity: 4), count: parent.count) - _isDone = [Bool](repeating: false, count: parent.count) - _subscriptions = Array() - _subscriptions.reserveCapacity(parent.count) + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent + self.values = [Queue](repeating: Queue(capacity: 4), count: parent.count) + self.isDone = [Bool](repeating: false, count: parent.count) + self.subscriptions = [SingleAssignmentDisposable]() + self.subscriptions.reserveCapacity(parent.count) for _ in 0 ..< parent.count { - _subscriptions.append(SingleAssignmentDisposable()) + self.subscriptions.append(SingleAssignmentDisposable()) } super.init(observer: observer, cancel: cancel) } func on(_ event: Event, atIndex: Int) { - _lock.lock(); defer { _lock.unlock() } // { - switch event { - case .next(let element): - _values[atIndex].enqueue(element) - - if _values[atIndex].count == 1 { - _numberOfValues += 1 + self.lock.lock(); defer { self.lock.unlock() } + switch event { + case .next(let element): + self.values[atIndex].enqueue(element) + + if self.values[atIndex].count == 1 { + self.numberOfValues += 1 + } + + if self.numberOfValues < self.parent.count { + if self.numberOfDone == self.parent.count - 1 { + self.forwardOn(.completed) + self.dispose() } + return + } + + do { + var arguments = [SourceElement]() + arguments.reserveCapacity(self.parent.count) - if _numberOfValues < _parent.count { - if _numberOfDone == _parent.count - 1 { - self.forwardOn(.completed) - self.dispose() - } - return - } + // recalculate number of values + self.numberOfValues = 0 - do { - var arguments = [SourceElement]() - arguments.reserveCapacity(_parent.count) - - // recalculate number of values - _numberOfValues = 0 - - for i in 0 ..< _values.count { - arguments.append(_values[i].dequeue()!) - if _values[i].count > 0 { - _numberOfValues += 1 - } + for i in 0 ..< self.values.count { + arguments.append(self.values[i].dequeue()!) + if !self.values[i].isEmpty { + self.numberOfValues += 1 } - - let result = try _parent.resultSelector(arguments) - self.forwardOn(.next(result)) - } - catch let error { - self.forwardOn(.error(error)) - self.dispose() } - case .error(let error): + let result = try self.parent.resultSelector(arguments) + self.forwardOn(.next(result)) + } + catch let error { self.forwardOn(.error(error)) self.dispose() - case .completed: - if _isDone[atIndex] { - return - } - - _isDone[atIndex] = true - _numberOfDone += 1 - - if _numberOfDone == _parent.count { - self.forwardOn(.completed) - self.dispose() - } - else { - _subscriptions[atIndex].dispose() - } } - // } + + case .error(let error): + self.forwardOn(.error(error)) + self.dispose() + case .completed: + if self.isDone[atIndex] { + return + } + + self.isDone[atIndex] = true + self.numberOfDone += 1 + + if self.numberOfDone == self.parent.count { + self.forwardOn(.completed) + self.dispose() + } + else { + self.subscriptions[atIndex].dispose() + } + } } func run() -> Disposable { var j = 0 - for i in _parent.sources { + for i in self.parent.sources { let index = j let source = i.asObservable() let disposable = source.subscribe(AnyObserver { event in self.on(event, atIndex: index) }) - _subscriptions[j].setDisposable(disposable) + self.subscriptions[j].setDisposable(disposable) j += 1 } - if _parent.sources.isEmpty { + if self.parent.sources.isEmpty { self.forwardOn(.completed) } - return Disposables.create(_subscriptions) + return Disposables.create(subscriptions) } } -final fileprivate class ZipCollectionType : Producer where C.Iterator.Element : ObservableConvertibleType { - typealias ResultSelector = ([C.Iterator.Element.E]) throws -> R +final private class ZipCollectionType: Producer where Collection.Element: ObservableConvertibleType { + typealias ResultSelector = ([Collection.Element.Element]) throws -> Result - let sources: C + let sources: Collection let resultSelector: ResultSelector let count: Int - init(sources: C, resultSelector: @escaping ResultSelector) { + init(sources: Collection, resultSelector: @escaping ResultSelector) { self.sources = sources self.resultSelector = resultSelector - self.count = Int(Int64(self.sources.count)) + self.count = self.sources.count } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = ZipCollectionTypeSink(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/Zip+arity.swift b/iOS/RxSwift/Observables/Zip+arity.swift index 04bf68f9..b6d876d1 100644 --- a/iOS/RxSwift/Observables/Zip+arity.swift +++ b/iOS/RxSwift/Observables/Zip+arity.swift @@ -21,8 +21,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func zip - (_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.E, O2.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.Element, O2.Element) throws -> Element) + -> Observable { return Zip2( source1: source1.asObservable(), source2: source2.asObservable(), resultSelector: resultSelector @@ -30,7 +30,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. @@ -40,7 +40,7 @@ extension ObservableType where E == Any { */ public static func zip (_ source1: O1, _ source2: O2) - -> Observable<(O1.E, O2.E)> { + -> Observable<(O1.Element, O2.Element)> { return Zip2( source1: source1.asObservable(), source2: source2.asObservable(), resultSelector: { ($0, $1) } @@ -48,41 +48,39 @@ extension ObservableType where E == Any { } } -final class ZipSink2_ : ZipSink { - typealias R = O.E - typealias Parent = Zip2 +final class ZipSink2_ : ZipSink { + typealias Result = Observer.Element + typealias Parent = Zip2 - let _parent: Parent + let parent: Parent - var _values1: Queue = Queue(capacity: 2) - var _values2: Queue = Queue(capacity: 2) + var values1: Queue = Queue(capacity: 2) + var values2: Queue = Queue(capacity: 2) - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 2, observer: observer, cancel: cancel) } override func hasElements(_ index: Int) -> Bool { - switch (index) { - case 0: return _values1.count > 0 - case 1: return _values2.count > 0 + switch index { + case 0: return !self.values1.isEmpty + case 1: return !self.values2.isEmpty default: rxFatalError("Unhandled case (Function)") } - - return false } func run() -> Disposable { let subscription1 = SingleAssignmentDisposable() let subscription2 = SingleAssignmentDisposable() - let observer1 = ZipObserver(lock: _lock, parent: self, index: 0, setNextValue: { self._values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: _lock, parent: self, index: 1, setNextValue: { self._values2.enqueue($0) }, this: subscription2) + let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) + let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) - subscription1.setDisposable(_parent.source1.subscribe(observer1)) - subscription2.setDisposable(_parent.source2.subscribe(observer2)) + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) return Disposables.create([ subscription1, @@ -90,27 +88,27 @@ final class ZipSink2_ : ZipSink { ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_values1.dequeue()!, _values2.dequeue()!) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!) } } -final class Zip2 : Producer { - typealias ResultSelector = (E1, E2) throws -> R +final class Zip2 : Producer { + typealias ResultSelector = (E1, E2) throws -> Result let source1: Observable let source2: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, resultSelector: @escaping ResultSelector) { self.source1 = source1 self.source2 = source2 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = ZipSink2_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -131,8 +129,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.E, O2.E, O3.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.Element, O2.Element, O3.Element) throws -> Element) + -> Observable { return Zip3( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), resultSelector: resultSelector @@ -140,7 +138,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. @@ -150,7 +148,7 @@ extension ObservableType where E == Any { */ public static func zip (_ source1: O1, _ source2: O2, _ source3: O3) - -> Observable<(O1.E, O2.E, O3.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element)> { return Zip3( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), resultSelector: { ($0, $1, $2) } @@ -158,32 +156,30 @@ extension ObservableType where E == Any { } } -final class ZipSink3_ : ZipSink { - typealias R = O.E - typealias Parent = Zip3 +final class ZipSink3_ : ZipSink { + typealias Result = Observer.Element + typealias Parent = Zip3 - let _parent: Parent + let parent: Parent - var _values1: Queue = Queue(capacity: 2) - var _values2: Queue = Queue(capacity: 2) - var _values3: Queue = Queue(capacity: 2) + var values1: Queue = Queue(capacity: 2) + var values2: Queue = Queue(capacity: 2) + var values3: Queue = Queue(capacity: 2) - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 3, observer: observer, cancel: cancel) } override func hasElements(_ index: Int) -> Bool { - switch (index) { - case 0: return _values1.count > 0 - case 1: return _values2.count > 0 - case 2: return _values3.count > 0 + switch index { + case 0: return !self.values1.isEmpty + case 1: return !self.values2.isEmpty + case 2: return !self.values3.isEmpty default: rxFatalError("Unhandled case (Function)") } - - return false } func run() -> Disposable { @@ -191,13 +187,13 @@ final class ZipSink3_ : ZipSink { let subscription2 = SingleAssignmentDisposable() let subscription3 = SingleAssignmentDisposable() - let observer1 = ZipObserver(lock: _lock, parent: self, index: 0, setNextValue: { self._values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: _lock, parent: self, index: 1, setNextValue: { self._values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: _lock, parent: self, index: 2, setNextValue: { self._values3.enqueue($0) }, this: subscription3) + let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) + let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) + let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) - subscription1.setDisposable(_parent.source1.subscribe(observer1)) - subscription2.setDisposable(_parent.source2.subscribe(observer2)) - subscription3.setDisposable(_parent.source3.subscribe(observer3)) + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) return Disposables.create([ subscription1, @@ -206,29 +202,29 @@ final class ZipSink3_ : ZipSink { ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_values1.dequeue()!, _values2.dequeue()!, _values3.dequeue()!) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!) } } -final class Zip3 : Producer { - typealias ResultSelector = (E1, E2, E3) throws -> R +final class Zip3 : Producer { + typealias ResultSelector = (E1, E2, E3) throws -> Result let source1: Observable let source2: Observable let source3: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, resultSelector: @escaping ResultSelector) { self.source1 = source1 self.source2 = source2 self.source3 = source3 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = ZipSink3_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -249,8 +245,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, resultSelector: @escaping (O1.E, O2.E, O3.E, O4.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element) throws -> Element) + -> Observable { return Zip4( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), resultSelector: resultSelector @@ -258,7 +254,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. @@ -268,7 +264,7 @@ extension ObservableType where E == Any { */ public static func zip (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4) - -> Observable<(O1.E, O2.E, O3.E, O4.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element)> { return Zip4( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), resultSelector: { ($0, $1, $2, $3) } @@ -276,34 +272,32 @@ extension ObservableType where E == Any { } } -final class ZipSink4_ : ZipSink { - typealias R = O.E - typealias Parent = Zip4 +final class ZipSink4_ : ZipSink { + typealias Result = Observer.Element + typealias Parent = Zip4 - let _parent: Parent + let parent: Parent - var _values1: Queue = Queue(capacity: 2) - var _values2: Queue = Queue(capacity: 2) - var _values3: Queue = Queue(capacity: 2) - var _values4: Queue = Queue(capacity: 2) + var values1: Queue = Queue(capacity: 2) + var values2: Queue = Queue(capacity: 2) + var values3: Queue = Queue(capacity: 2) + var values4: Queue = Queue(capacity: 2) - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 4, observer: observer, cancel: cancel) } override func hasElements(_ index: Int) -> Bool { - switch (index) { - case 0: return _values1.count > 0 - case 1: return _values2.count > 0 - case 2: return _values3.count > 0 - case 3: return _values4.count > 0 + switch index { + case 0: return !self.values1.isEmpty + case 1: return !self.values2.isEmpty + case 2: return !self.values3.isEmpty + case 3: return !self.values4.isEmpty default: rxFatalError("Unhandled case (Function)") } - - return false } func run() -> Disposable { @@ -312,15 +306,15 @@ final class ZipSink4_ : ZipSink { let subscription3 = SingleAssignmentDisposable() let subscription4 = SingleAssignmentDisposable() - let observer1 = ZipObserver(lock: _lock, parent: self, index: 0, setNextValue: { self._values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: _lock, parent: self, index: 1, setNextValue: { self._values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: _lock, parent: self, index: 2, setNextValue: { self._values3.enqueue($0) }, this: subscription3) - let observer4 = ZipObserver(lock: _lock, parent: self, index: 3, setNextValue: { self._values4.enqueue($0) }, this: subscription4) + let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) + let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) + let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) + let observer4 = ZipObserver(lock: self.lock, parent: self, index: 3, setNextValue: { self.values4.enqueue($0) }, this: subscription4) - subscription1.setDisposable(_parent.source1.subscribe(observer1)) - subscription2.setDisposable(_parent.source2.subscribe(observer2)) - subscription3.setDisposable(_parent.source3.subscribe(observer3)) - subscription4.setDisposable(_parent.source4.subscribe(observer4)) + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) + subscription4.setDisposable(self.parent.source4.subscribe(observer4)) return Disposables.create([ subscription1, @@ -330,20 +324,20 @@ final class ZipSink4_ : ZipSink { ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_values1.dequeue()!, _values2.dequeue()!, _values3.dequeue()!, _values4.dequeue()!) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!, self.values4.dequeue()!) } } -final class Zip4 : Producer { - typealias ResultSelector = (E1, E2, E3, E4) throws -> R +final class Zip4 : Producer { + typealias ResultSelector = (E1, E2, E3, E4) throws -> Result let source1: Observable let source2: Observable let source3: Observable let source4: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, resultSelector: @escaping ResultSelector) { self.source1 = source1 @@ -351,10 +345,10 @@ final class Zip4 : Producer { self.source3 = source3 self.source4 = source4 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = ZipSink4_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -375,8 +369,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, resultSelector: @escaping (O1.E, O2.E, O3.E, O4.E, O5.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element) throws -> Element) + -> Observable { return Zip5( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), resultSelector: resultSelector @@ -384,7 +378,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. @@ -394,7 +388,7 @@ extension ObservableType where E == Any { */ public static func zip (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5) - -> Observable<(O1.E, O2.E, O3.E, O4.E, O5.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element)> { return Zip5( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), resultSelector: { ($0, $1, $2, $3, $4) } @@ -402,36 +396,34 @@ extension ObservableType where E == Any { } } -final class ZipSink5_ : ZipSink { - typealias R = O.E - typealias Parent = Zip5 +final class ZipSink5_ : ZipSink { + typealias Result = Observer.Element + typealias Parent = Zip5 - let _parent: Parent + let parent: Parent - var _values1: Queue = Queue(capacity: 2) - var _values2: Queue = Queue(capacity: 2) - var _values3: Queue = Queue(capacity: 2) - var _values4: Queue = Queue(capacity: 2) - var _values5: Queue = Queue(capacity: 2) + var values1: Queue = Queue(capacity: 2) + var values2: Queue = Queue(capacity: 2) + var values3: Queue = Queue(capacity: 2) + var values4: Queue = Queue(capacity: 2) + var values5: Queue = Queue(capacity: 2) - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 5, observer: observer, cancel: cancel) } override func hasElements(_ index: Int) -> Bool { - switch (index) { - case 0: return _values1.count > 0 - case 1: return _values2.count > 0 - case 2: return _values3.count > 0 - case 3: return _values4.count > 0 - case 4: return _values5.count > 0 + switch index { + case 0: return !self.values1.isEmpty + case 1: return !self.values2.isEmpty + case 2: return !self.values3.isEmpty + case 3: return !self.values4.isEmpty + case 4: return !self.values5.isEmpty default: rxFatalError("Unhandled case (Function)") } - - return false } func run() -> Disposable { @@ -441,17 +433,17 @@ final class ZipSink5_ : ZipSink { let subscription4 = SingleAssignmentDisposable() let subscription5 = SingleAssignmentDisposable() - let observer1 = ZipObserver(lock: _lock, parent: self, index: 0, setNextValue: { self._values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: _lock, parent: self, index: 1, setNextValue: { self._values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: _lock, parent: self, index: 2, setNextValue: { self._values3.enqueue($0) }, this: subscription3) - let observer4 = ZipObserver(lock: _lock, parent: self, index: 3, setNextValue: { self._values4.enqueue($0) }, this: subscription4) - let observer5 = ZipObserver(lock: _lock, parent: self, index: 4, setNextValue: { self._values5.enqueue($0) }, this: subscription5) + let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) + let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) + let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) + let observer4 = ZipObserver(lock: self.lock, parent: self, index: 3, setNextValue: { self.values4.enqueue($0) }, this: subscription4) + let observer5 = ZipObserver(lock: self.lock, parent: self, index: 4, setNextValue: { self.values5.enqueue($0) }, this: subscription5) - subscription1.setDisposable(_parent.source1.subscribe(observer1)) - subscription2.setDisposable(_parent.source2.subscribe(observer2)) - subscription3.setDisposable(_parent.source3.subscribe(observer3)) - subscription4.setDisposable(_parent.source4.subscribe(observer4)) - subscription5.setDisposable(_parent.source5.subscribe(observer5)) + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) + subscription4.setDisposable(self.parent.source4.subscribe(observer4)) + subscription5.setDisposable(self.parent.source5.subscribe(observer5)) return Disposables.create([ subscription1, @@ -462,13 +454,13 @@ final class ZipSink5_ : ZipSink { ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_values1.dequeue()!, _values2.dequeue()!, _values3.dequeue()!, _values4.dequeue()!, _values5.dequeue()!) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!, self.values4.dequeue()!, self.values5.dequeue()!) } } -final class Zip5 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5) throws -> R +final class Zip5 : Producer { + typealias ResultSelector = (E1, E2, E3, E4, E5) throws -> Result let source1: Observable let source2: Observable @@ -476,7 +468,7 @@ final class Zip5 : Producer { let source4: Observable let source5: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, resultSelector: @escaping ResultSelector) { self.source1 = source1 @@ -485,10 +477,10 @@ final class Zip5 : Producer { self.source4 = source4 self.source5 = source5 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = ZipSink5_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -509,8 +501,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, resultSelector: @escaping (O1.E, O2.E, O3.E, O4.E, O5.E, O6.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element) throws -> Element) + -> Observable { return Zip6( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), resultSelector: resultSelector @@ -518,7 +510,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. @@ -528,7 +520,7 @@ extension ObservableType where E == Any { */ public static func zip (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6) - -> Observable<(O1.E, O2.E, O3.E, O4.E, O5.E, O6.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element)> { return Zip6( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), resultSelector: { ($0, $1, $2, $3, $4, $5) } @@ -536,38 +528,36 @@ extension ObservableType where E == Any { } } -final class ZipSink6_ : ZipSink { - typealias R = O.E - typealias Parent = Zip6 +final class ZipSink6_ : ZipSink { + typealias Result = Observer.Element + typealias Parent = Zip6 - let _parent: Parent + let parent: Parent - var _values1: Queue = Queue(capacity: 2) - var _values2: Queue = Queue(capacity: 2) - var _values3: Queue = Queue(capacity: 2) - var _values4: Queue = Queue(capacity: 2) - var _values5: Queue = Queue(capacity: 2) - var _values6: Queue = Queue(capacity: 2) + var values1: Queue = Queue(capacity: 2) + var values2: Queue = Queue(capacity: 2) + var values3: Queue = Queue(capacity: 2) + var values4: Queue = Queue(capacity: 2) + var values5: Queue = Queue(capacity: 2) + var values6: Queue = Queue(capacity: 2) - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 6, observer: observer, cancel: cancel) } override func hasElements(_ index: Int) -> Bool { - switch (index) { - case 0: return _values1.count > 0 - case 1: return _values2.count > 0 - case 2: return _values3.count > 0 - case 3: return _values4.count > 0 - case 4: return _values5.count > 0 - case 5: return _values6.count > 0 + switch index { + case 0: return !self.values1.isEmpty + case 1: return !self.values2.isEmpty + case 2: return !self.values3.isEmpty + case 3: return !self.values4.isEmpty + case 4: return !self.values5.isEmpty + case 5: return !self.values6.isEmpty default: rxFatalError("Unhandled case (Function)") } - - return false } func run() -> Disposable { @@ -578,19 +568,19 @@ final class ZipSink6_ : ZipSink { let subscription5 = SingleAssignmentDisposable() let subscription6 = SingleAssignmentDisposable() - let observer1 = ZipObserver(lock: _lock, parent: self, index: 0, setNextValue: { self._values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: _lock, parent: self, index: 1, setNextValue: { self._values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: _lock, parent: self, index: 2, setNextValue: { self._values3.enqueue($0) }, this: subscription3) - let observer4 = ZipObserver(lock: _lock, parent: self, index: 3, setNextValue: { self._values4.enqueue($0) }, this: subscription4) - let observer5 = ZipObserver(lock: _lock, parent: self, index: 4, setNextValue: { self._values5.enqueue($0) }, this: subscription5) - let observer6 = ZipObserver(lock: _lock, parent: self, index: 5, setNextValue: { self._values6.enqueue($0) }, this: subscription6) + let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) + let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) + let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) + let observer4 = ZipObserver(lock: self.lock, parent: self, index: 3, setNextValue: { self.values4.enqueue($0) }, this: subscription4) + let observer5 = ZipObserver(lock: self.lock, parent: self, index: 4, setNextValue: { self.values5.enqueue($0) }, this: subscription5) + let observer6 = ZipObserver(lock: self.lock, parent: self, index: 5, setNextValue: { self.values6.enqueue($0) }, this: subscription6) - subscription1.setDisposable(_parent.source1.subscribe(observer1)) - subscription2.setDisposable(_parent.source2.subscribe(observer2)) - subscription3.setDisposable(_parent.source3.subscribe(observer3)) - subscription4.setDisposable(_parent.source4.subscribe(observer4)) - subscription5.setDisposable(_parent.source5.subscribe(observer5)) - subscription6.setDisposable(_parent.source6.subscribe(observer6)) + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) + subscription4.setDisposable(self.parent.source4.subscribe(observer4)) + subscription5.setDisposable(self.parent.source5.subscribe(observer5)) + subscription6.setDisposable(self.parent.source6.subscribe(observer6)) return Disposables.create([ subscription1, @@ -602,13 +592,13 @@ final class ZipSink6_ : ZipSink { ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_values1.dequeue()!, _values2.dequeue()!, _values3.dequeue()!, _values4.dequeue()!, _values5.dequeue()!, _values6.dequeue()!) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!, self.values4.dequeue()!, self.values5.dequeue()!, self.values6.dequeue()!) } } -final class Zip6 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6) throws -> R +final class Zip6 : Producer { + typealias ResultSelector = (E1, E2, E3, E4, E5, E6) throws -> Result let source1: Observable let source2: Observable @@ -617,7 +607,7 @@ final class Zip6 : Producer { let source5: Observable let source6: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, resultSelector: @escaping ResultSelector) { self.source1 = source1 @@ -627,10 +617,10 @@ final class Zip6 : Producer { self.source5 = source5 self.source6 = source6 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = ZipSink6_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -651,8 +641,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, resultSelector: @escaping (O1.E, O2.E, O3.E, O4.E, O5.E, O6.E, O7.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element) throws -> Element) + -> Observable { return Zip7( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), resultSelector: resultSelector @@ -660,7 +650,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. @@ -670,7 +660,7 @@ extension ObservableType where E == Any { */ public static func zip (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7) - -> Observable<(O1.E, O2.E, O3.E, O4.E, O5.E, O6.E, O7.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element)> { return Zip7( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), resultSelector: { ($0, $1, $2, $3, $4, $5, $6) } @@ -678,40 +668,38 @@ extension ObservableType where E == Any { } } -final class ZipSink7_ : ZipSink { - typealias R = O.E - typealias Parent = Zip7 +final class ZipSink7_ : ZipSink { + typealias Result = Observer.Element + typealias Parent = Zip7 - let _parent: Parent + let parent: Parent - var _values1: Queue = Queue(capacity: 2) - var _values2: Queue = Queue(capacity: 2) - var _values3: Queue = Queue(capacity: 2) - var _values4: Queue = Queue(capacity: 2) - var _values5: Queue = Queue(capacity: 2) - var _values6: Queue = Queue(capacity: 2) - var _values7: Queue = Queue(capacity: 2) + var values1: Queue = Queue(capacity: 2) + var values2: Queue = Queue(capacity: 2) + var values3: Queue = Queue(capacity: 2) + var values4: Queue = Queue(capacity: 2) + var values5: Queue = Queue(capacity: 2) + var values6: Queue = Queue(capacity: 2) + var values7: Queue = Queue(capacity: 2) - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 7, observer: observer, cancel: cancel) } override func hasElements(_ index: Int) -> Bool { - switch (index) { - case 0: return _values1.count > 0 - case 1: return _values2.count > 0 - case 2: return _values3.count > 0 - case 3: return _values4.count > 0 - case 4: return _values5.count > 0 - case 5: return _values6.count > 0 - case 6: return _values7.count > 0 + switch index { + case 0: return !self.values1.isEmpty + case 1: return !self.values2.isEmpty + case 2: return !self.values3.isEmpty + case 3: return !self.values4.isEmpty + case 4: return !self.values5.isEmpty + case 5: return !self.values6.isEmpty + case 6: return !self.values7.isEmpty default: rxFatalError("Unhandled case (Function)") } - - return false } func run() -> Disposable { @@ -723,21 +711,21 @@ final class ZipSink7_ : ZipSink let subscription6 = SingleAssignmentDisposable() let subscription7 = SingleAssignmentDisposable() - let observer1 = ZipObserver(lock: _lock, parent: self, index: 0, setNextValue: { self._values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: _lock, parent: self, index: 1, setNextValue: { self._values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: _lock, parent: self, index: 2, setNextValue: { self._values3.enqueue($0) }, this: subscription3) - let observer4 = ZipObserver(lock: _lock, parent: self, index: 3, setNextValue: { self._values4.enqueue($0) }, this: subscription4) - let observer5 = ZipObserver(lock: _lock, parent: self, index: 4, setNextValue: { self._values5.enqueue($0) }, this: subscription5) - let observer6 = ZipObserver(lock: _lock, parent: self, index: 5, setNextValue: { self._values6.enqueue($0) }, this: subscription6) - let observer7 = ZipObserver(lock: _lock, parent: self, index: 6, setNextValue: { self._values7.enqueue($0) }, this: subscription7) - - subscription1.setDisposable(_parent.source1.subscribe(observer1)) - subscription2.setDisposable(_parent.source2.subscribe(observer2)) - subscription3.setDisposable(_parent.source3.subscribe(observer3)) - subscription4.setDisposable(_parent.source4.subscribe(observer4)) - subscription5.setDisposable(_parent.source5.subscribe(observer5)) - subscription6.setDisposable(_parent.source6.subscribe(observer6)) - subscription7.setDisposable(_parent.source7.subscribe(observer7)) + let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) + let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) + let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) + let observer4 = ZipObserver(lock: self.lock, parent: self, index: 3, setNextValue: { self.values4.enqueue($0) }, this: subscription4) + let observer5 = ZipObserver(lock: self.lock, parent: self, index: 4, setNextValue: { self.values5.enqueue($0) }, this: subscription5) + let observer6 = ZipObserver(lock: self.lock, parent: self, index: 5, setNextValue: { self.values6.enqueue($0) }, this: subscription6) + let observer7 = ZipObserver(lock: self.lock, parent: self, index: 6, setNextValue: { self.values7.enqueue($0) }, this: subscription7) + + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) + subscription4.setDisposable(self.parent.source4.subscribe(observer4)) + subscription5.setDisposable(self.parent.source5.subscribe(observer5)) + subscription6.setDisposable(self.parent.source6.subscribe(observer6)) + subscription7.setDisposable(self.parent.source7.subscribe(observer7)) return Disposables.create([ subscription1, @@ -750,13 +738,13 @@ final class ZipSink7_ : ZipSink ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_values1.dequeue()!, _values2.dequeue()!, _values3.dequeue()!, _values4.dequeue()!, _values5.dequeue()!, _values6.dequeue()!, _values7.dequeue()!) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!, self.values4.dequeue()!, self.values5.dequeue()!, self.values6.dequeue()!, self.values7.dequeue()!) } } -final class Zip7 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7) throws -> R +final class Zip7 : Producer { + typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7) throws -> Result let source1: Observable let source2: Observable @@ -766,7 +754,7 @@ final class Zip7 : Producer { let source6: Observable let source7: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, source7: Observable, resultSelector: @escaping ResultSelector) { self.source1 = source1 @@ -777,10 +765,10 @@ final class Zip7 : Producer { self.source6 = source6 self.source7 = source7 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = ZipSink7_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) @@ -801,8 +789,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8, resultSelector: @escaping (O1.E, O2.E, O3.E, O4.E, O5.E, O6.E, O7.E, O8.E) throws -> E) - -> Observable { + (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element) throws -> Element) + -> Observable { return Zip8( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), source8: source8.asObservable(), resultSelector: resultSelector @@ -810,7 +798,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. @@ -820,7 +808,7 @@ extension ObservableType where E == Any { */ public static func zip (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8) - -> Observable<(O1.E, O2.E, O3.E, O4.E, O5.E, O6.E, O7.E, O8.E)> { + -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element)> { return Zip8( source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), source8: source8.asObservable(), resultSelector: { ($0, $1, $2, $3, $4, $5, $6, $7) } @@ -828,42 +816,40 @@ extension ObservableType where E == Any { } } -final class ZipSink8_ : ZipSink { - typealias R = O.E - typealias Parent = Zip8 +final class ZipSink8_ : ZipSink { + typealias Result = Observer.Element + typealias Parent = Zip8 - let _parent: Parent + let parent: Parent - var _values1: Queue = Queue(capacity: 2) - var _values2: Queue = Queue(capacity: 2) - var _values3: Queue = Queue(capacity: 2) - var _values4: Queue = Queue(capacity: 2) - var _values5: Queue = Queue(capacity: 2) - var _values6: Queue = Queue(capacity: 2) - var _values7: Queue = Queue(capacity: 2) - var _values8: Queue = Queue(capacity: 2) + var values1: Queue = Queue(capacity: 2) + var values2: Queue = Queue(capacity: 2) + var values3: Queue = Queue(capacity: 2) + var values4: Queue = Queue(capacity: 2) + var values5: Queue = Queue(capacity: 2) + var values6: Queue = Queue(capacity: 2) + var values7: Queue = Queue(capacity: 2) + var values8: Queue = Queue(capacity: 2) - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: 8, observer: observer, cancel: cancel) } override func hasElements(_ index: Int) -> Bool { - switch (index) { - case 0: return _values1.count > 0 - case 1: return _values2.count > 0 - case 2: return _values3.count > 0 - case 3: return _values4.count > 0 - case 4: return _values5.count > 0 - case 5: return _values6.count > 0 - case 6: return _values7.count > 0 - case 7: return _values8.count > 0 + switch index { + case 0: return !self.values1.isEmpty + case 1: return !self.values2.isEmpty + case 2: return !self.values3.isEmpty + case 3: return !self.values4.isEmpty + case 4: return !self.values5.isEmpty + case 5: return !self.values6.isEmpty + case 6: return !self.values7.isEmpty + case 7: return !self.values8.isEmpty default: rxFatalError("Unhandled case (Function)") } - - return false } func run() -> Disposable { @@ -876,23 +862,23 @@ final class ZipSink8_ : ZipSink let subscription7 = SingleAssignmentDisposable() let subscription8 = SingleAssignmentDisposable() - let observer1 = ZipObserver(lock: _lock, parent: self, index: 0, setNextValue: { self._values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: _lock, parent: self, index: 1, setNextValue: { self._values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: _lock, parent: self, index: 2, setNextValue: { self._values3.enqueue($0) }, this: subscription3) - let observer4 = ZipObserver(lock: _lock, parent: self, index: 3, setNextValue: { self._values4.enqueue($0) }, this: subscription4) - let observer5 = ZipObserver(lock: _lock, parent: self, index: 4, setNextValue: { self._values5.enqueue($0) }, this: subscription5) - let observer6 = ZipObserver(lock: _lock, parent: self, index: 5, setNextValue: { self._values6.enqueue($0) }, this: subscription6) - let observer7 = ZipObserver(lock: _lock, parent: self, index: 6, setNextValue: { self._values7.enqueue($0) }, this: subscription7) - let observer8 = ZipObserver(lock: _lock, parent: self, index: 7, setNextValue: { self._values8.enqueue($0) }, this: subscription8) - - subscription1.setDisposable(_parent.source1.subscribe(observer1)) - subscription2.setDisposable(_parent.source2.subscribe(observer2)) - subscription3.setDisposable(_parent.source3.subscribe(observer3)) - subscription4.setDisposable(_parent.source4.subscribe(observer4)) - subscription5.setDisposable(_parent.source5.subscribe(observer5)) - subscription6.setDisposable(_parent.source6.subscribe(observer6)) - subscription7.setDisposable(_parent.source7.subscribe(observer7)) - subscription8.setDisposable(_parent.source8.subscribe(observer8)) + let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) + let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) + let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) + let observer4 = ZipObserver(lock: self.lock, parent: self, index: 3, setNextValue: { self.values4.enqueue($0) }, this: subscription4) + let observer5 = ZipObserver(lock: self.lock, parent: self, index: 4, setNextValue: { self.values5.enqueue($0) }, this: subscription5) + let observer6 = ZipObserver(lock: self.lock, parent: self, index: 5, setNextValue: { self.values6.enqueue($0) }, this: subscription6) + let observer7 = ZipObserver(lock: self.lock, parent: self, index: 6, setNextValue: { self.values7.enqueue($0) }, this: subscription7) + let observer8 = ZipObserver(lock: self.lock, parent: self, index: 7, setNextValue: { self.values8.enqueue($0) }, this: subscription8) + + subscription1.setDisposable(self.parent.source1.subscribe(observer1)) + subscription2.setDisposable(self.parent.source2.subscribe(observer2)) + subscription3.setDisposable(self.parent.source3.subscribe(observer3)) + subscription4.setDisposable(self.parent.source4.subscribe(observer4)) + subscription5.setDisposable(self.parent.source5.subscribe(observer5)) + subscription6.setDisposable(self.parent.source6.subscribe(observer6)) + subscription7.setDisposable(self.parent.source7.subscribe(observer7)) + subscription8.setDisposable(self.parent.source8.subscribe(observer8)) return Disposables.create([ subscription1, @@ -906,13 +892,13 @@ final class ZipSink8_ : ZipSink ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(_values1.dequeue()!, _values2.dequeue()!, _values3.dequeue()!, _values4.dequeue()!, _values5.dequeue()!, _values6.dequeue()!, _values7.dequeue()!, _values8.dequeue()!) + override func getResult() throws -> Result { + try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!, self.values4.dequeue()!, self.values5.dequeue()!, self.values6.dequeue()!, self.values7.dequeue()!, self.values8.dequeue()!) } } -final class Zip8 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7, E8) throws -> R +final class Zip8 : Producer { + typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7, E8) throws -> Result let source1: Observable let source2: Observable @@ -923,7 +909,7 @@ final class Zip8 : Producer { let source7: Observable let source8: Observable - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, source7: Observable, source8: Observable, resultSelector: @escaping ResultSelector) { self.source1 = source1 @@ -935,10 +921,10 @@ final class Zip8 : Producer { self.source7 = source7 self.source8 = source8 - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = ZipSink8_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/Zip+arity.tt b/iOS/RxSwift/Observables/Zip+arity.tt index bcb01167..447073c3 100644 --- a/iOS/RxSwift/Observables/Zip+arity.tt +++ b/iOS/RxSwift/Observables/Zip+arity.tt @@ -20,8 +20,8 @@ extension ObservableType { - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. */ public static func zip<<%= (Array(1...i).map { "O\($0): ObservableType" }).joined(separator: ", ") %>> - (<%= (Array(1...i).map { "_ source\($0): O\($0)" }).joined(separator: ", ") %>, resultSelector: @escaping (<%= (Array(1...i).map { "O\($0).E" }).joined(separator: ", ") %>) throws -> E) - -> Observable { + (<%= (Array(1...i).map { "_ source\($0): O\($0)" }).joined(separator: ", ") %>, resultSelector: @escaping (<%= (Array(1...i).map { "O\($0).Element" }).joined(separator: ", ") %>) throws -> Element) + -> Observable { return Zip<%= i %>( <%= (Array(1...i).map { "source\($0): source\($0).asObservable()" }).joined(separator: ", ") %>, resultSelector: resultSelector @@ -29,7 +29,7 @@ extension ObservableType { } } -extension ObservableType where E == Any { +extension ObservableType where Element == Any { /** Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. @@ -39,7 +39,7 @@ extension ObservableType where E == Any { */ public static func zip<<%= (Array(1...i).map { "O\($0): ObservableType" }).joined(separator: ", ") %>> (<%= (Array(1...i).map { "_ source\($0): O\($0)" }).joined(separator: ", ") %>) - -> Observable<(<%= (Array(1...i).map { "O\($0).E" }).joined(separator: ", ") %>)> { + -> Observable<(<%= (Array(1...i).map { "O\($0).Element" }).joined(separator: ", ") %>)> { return Zip<%= i %>( <%= (Array(1...i).map { "source\($0): source\($0).asObservable()" }).joined(separator: ", ") %>, resultSelector: { (<%= (Array(0..) } @@ -47,31 +47,29 @@ extension ObservableType where E == Any { } } -final class ZipSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, O: ObserverType> : ZipSink { - typealias R = O.E - typealias Parent = Zip<%= i %><<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, R> +final class ZipSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, Observer: ObserverType> : ZipSink { + typealias Result = Observer.Element + typealias Parent = Zip<%= i %><<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, Result> - let _parent: Parent + let parent: Parent <%= (Array(1...i).map { -" var _values\($0): Queue = Queue(capacity: 2)" +" var values\($0): Queue = Queue(capacity: 2)" }).joined(separator: "\n") %> - init(parent: Parent, observer: O, cancel: Cancelable) { - _parent = parent + init(parent: Parent, observer: Observer, cancel: Cancelable) { + self.parent = parent super.init(arity: <%= i %>, observer: observer, cancel: cancel) } override func hasElements(_ index: Int) -> Bool { - switch (index) { + switch index { <%= (Array(0.. 0\n" +" case \($0): return !self.values\($0 + 1).isEmpty\n" }).joined(separator: "") %> default: rxFatalError("Unhandled case \(index)") } - - return false } func run() -> Disposable { @@ -80,11 +78,11 @@ final class ZipSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joined(separato }).joined(separator: "\n") %> <%= (Array(1...i).map { -" let observer\($0) = ZipObserver(lock: _lock, parent: self, index: \($0 - 1), setNextValue: { self._values\($0).enqueue($0) }, this: subscription\($0))" +" let observer\($0) = ZipObserver(lock: self.lock, parent: self, index: \($0 - 1), setNextValue: { self.values\($0).enqueue($0) }, this: subscription\($0))" }).joined(separator: "\n") %> <%= (Array(1...i).map { -" subscription\($0).setDisposable(_parent.source\($0).subscribe(observer\($0)))" }).joined(separator: "\n") +" subscription\($0).setDisposable(self.parent.source\($0).subscribe(observer\($0)))" }).joined(separator: "\n") %> return Disposables.create([ @@ -92,27 +90,27 @@ final class ZipSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joined(separato ]) } - override func getResult() throws -> R { - return try _parent._resultSelector(<%= (Array(1...i).map { "_values\($0).dequeue()!" }).joined(separator: ", ") %>) + override func getResult() throws -> Result { + try self.parent.resultSelector(<%= (Array(1...i).map { "self.values\($0).dequeue()!" }).joined(separator: ", ") %>) } } -final class Zip<%= i %><<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, R> : Producer { - typealias ResultSelector = (<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>) throws -> R +final class Zip<%= i %><<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>, Result> : Producer { + typealias ResultSelector = (<%= (Array(1...i).map { "E\($0)" }).joined(separator: ", ") %>) throws -> Result <%= (Array(1...i).map { " let source\($0): Observable" }).joined(separator: "\n") %> - let _resultSelector: ResultSelector + let resultSelector: ResultSelector init(<%= (Array(1...i).map { "source\($0): Observable" }).joined(separator: ", ") %>, resultSelector: @escaping ResultSelector) { <%= (Array(1...i).map { " self.source\($0) = source\($0)" }).joined(separator: "\n") %> - _resultSelector = resultSelector + self.resultSelector = resultSelector } - override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == R { + override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { let sink = ZipSink<%= i %>_(parent: self, observer: observer, cancel: cancel) let subscription = sink.run() return (sink: sink, subscription: subscription) diff --git a/iOS/RxSwift/Observables/Zip.swift b/iOS/RxSwift/Observables/Zip.swift index a283bf2b..328a40ef 100644 --- a/iOS/RxSwift/Observables/Zip.swift +++ b/iOS/RxSwift/Observables/Zip.swift @@ -6,26 +6,25 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -protocol ZipSinkProtocol : class -{ +protocol ZipSinkProtocol: AnyObject { func next(_ index: Int) func fail(_ error: Swift.Error) func done(_ index: Int) } -class ZipSink : Sink, ZipSinkProtocol { - typealias Element = O.E +class ZipSink : Sink, ZipSinkProtocol { + typealias Element = Observer.Element - let _arity: Int + let arity: Int - let _lock = RecursiveLock() + let lock = RecursiveLock() // state - private var _isDone: [Bool] + private var isDone: [Bool] - init(arity: Int, observer: O, cancel: Cancelable) { - _isDone = [Bool](repeating: false, count: arity) - _arity = arity + init(arity: Int, observer: Observer, cancel: Cancelable) { + self.isDone = [Bool](repeating: false, count: arity) + self.arity = arity super.init(observer: observer, cancel: cancel) } @@ -41,8 +40,8 @@ class ZipSink : Sink, ZipSinkProtocol { func next(_ index: Int) { var hasValueAll = true - for i in 0 ..< _arity { - if !hasElements(i) { + for i in 0 ..< self.arity { + if !self.hasElements(i) { hasValueAll = false break } @@ -50,105 +49,86 @@ class ZipSink : Sink, ZipSinkProtocol { if hasValueAll { do { - let result = try getResult() + let result = try self.getResult() self.forwardOn(.next(result)) } catch let e { self.forwardOn(.error(e)) - dispose() - } - } - else { - var allOthersDone = true - - let arity = _isDone.count - for i in 0 ..< arity { - if i != index && !_isDone[i] { - allOthersDone = false - break - } - } - - if allOthersDone { - forwardOn(.completed) self.dispose() } } } func fail(_ error: Swift.Error) { - forwardOn(.error(error)) - dispose() + self.forwardOn(.error(error)) + self.dispose() } func done(_ index: Int) { - _isDone[index] = true + self.isDone[index] = true var allDone = true - for done in _isDone { - if !done { - allDone = false - break - } + for done in self.isDone where !done { + allDone = false + break } if allDone { - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() } } } -final class ZipObserver +final class ZipObserver : ObserverType , LockOwnerType , SynchronizedOnType { - typealias E = ElementType - typealias ValueSetter = (ElementType) -> () + typealias ValueSetter = (Element) -> Void - private var _parent: ZipSinkProtocol? + private var parent: ZipSinkProtocol? - let _lock: RecursiveLock + let lock: RecursiveLock // state - private let _index: Int - private let _this: Disposable - private let _setNextValue: ValueSetter + private let index: Int + private let this: Disposable + private let setNextValue: ValueSetter init(lock: RecursiveLock, parent: ZipSinkProtocol, index: Int, setNextValue: @escaping ValueSetter, this: Disposable) { - _lock = lock - _parent = parent - _index = index - _this = this - _setNextValue = setNextValue + self.lock = lock + self.parent = parent + self.index = index + self.this = this + self.setNextValue = setNextValue } - func on(_ event: Event) { - synchronizedOn(event) + func on(_ event: Event) { + self.synchronizedOn(event) } - func _synchronized_on(_ event: Event) { - if let _ = _parent { + func synchronized_on(_ event: Event) { + if self.parent != nil { switch event { - case .next(_): + case .next: break - case .error(_): - _this.dispose() + case .error: + self.this.dispose() case .completed: - _this.dispose() + self.this.dispose() } } - if let parent = _parent { + if let parent = self.parent { switch event { case .next(let value): - _setNextValue(value) - parent.next(_index) + self.setNextValue(value) + parent.next(self.index) case .error(let error): parent.fail(error) case .completed: - parent.done(_index) + parent.done(self.index) } } } diff --git a/iOS/RxSwift/ObserverType.swift b/iOS/RxSwift/ObserverType.swift index e3ed7aa8..b7a66480 100644 --- a/iOS/RxSwift/ObserverType.swift +++ b/iOS/RxSwift/ObserverType.swift @@ -9,32 +9,32 @@ /// Supports push-style iteration over an observable sequence. public protocol ObserverType { /// The type of elements in sequence that observer can observe. - associatedtype E + associatedtype Element /// Notify observer about sequence event. /// /// - parameter event: Event that occurred. - func on(_ event: Event) + func on(_ event: Event) } /// Convenience API extensions to provide alternate next, error, completed events extension ObserverType { - /// Convenience method equivalent to `on(.next(element: E))` + /// Convenience method equivalent to `on(.next(element: Element))` /// /// - parameter element: Next element to send to observer(s) - public func onNext(_ element: E) { - on(.next(element)) + public func onNext(_ element: Element) { + self.on(.next(element)) } /// Convenience method equivalent to `on(.completed)` public func onCompleted() { - on(.completed) + self.on(.completed) } /// Convenience method equivalent to `on(.error(Swift.Error))` /// - parameter error: Swift.Error to send to observer(s) public func onError(_ error: Swift.Error) { - on(.error(error)) + self.on(.error(error)) } } diff --git a/iOS/RxSwift/Observers/AnonymousObserver.swift b/iOS/RxSwift/Observers/AnonymousObserver.swift index 54e83f54..cbb42dc8 100644 --- a/iOS/RxSwift/Observers/AnonymousObserver.swift +++ b/iOS/RxSwift/Observers/AnonymousObserver.swift @@ -6,27 +6,25 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -final class AnonymousObserver : ObserverBase { - typealias Element = ElementType - +final class AnonymousObserver: ObserverBase { typealias EventHandler = (Event) -> Void - private let _eventHandler : EventHandler + private let eventHandler : EventHandler init(_ eventHandler: @escaping EventHandler) { #if TRACE_RESOURCES - let _ = Resources.incrementTotal() + _ = Resources.incrementTotal() #endif - _eventHandler = eventHandler + self.eventHandler = eventHandler } override func onCore(_ event: Event) { - return _eventHandler(event) + self.eventHandler(event) } #if TRACE_RESOURCES deinit { - let _ = Resources.decrementTotal() + _ = Resources.decrementTotal() } #endif } diff --git a/iOS/RxSwift/Observers/ObserverBase.swift b/iOS/RxSwift/Observers/ObserverBase.swift index 38115652..48e09868 100644 --- a/iOS/RxSwift/Observers/ObserverBase.swift +++ b/iOS/RxSwift/Observers/ObserverBase.swift @@ -6,29 +6,27 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -class ObserverBase : Disposable, ObserverType { - typealias E = ElementType +class ObserverBase : Disposable, ObserverType { + private let isStopped = AtomicInt(0) - private var _isStopped: AtomicInt = 0 - - func on(_ event: Event) { + func on(_ event: Event) { switch event { case .next: - if _isStopped == 0 { - onCore(event) + if load(self.isStopped) == 0 { + self.onCore(event) } case .error, .completed: - if AtomicCompareAndSwap(0, 1, &_isStopped) { - onCore(event) + if fetchOr(self.isStopped, 1) == 0 { + self.onCore(event) } } } - func onCore(_ event: Event) { + func onCore(_ event: Event) { rxAbstractMethod() } func dispose() { - _ = AtomicCompareAndSwap(0, 1, &_isStopped) + fetchOr(self.isStopped, 1) } } diff --git a/iOS/RxSwift/Observers/TailRecursiveSink.swift b/iOS/RxSwift/Observers/TailRecursiveSink.swift index 48a599dd..fd527001 100644 --- a/iOS/RxSwift/Observers/TailRecursiveSink.swift +++ b/iOS/RxSwift/Observers/TailRecursiveSink.swift @@ -16,70 +16,70 @@ enum TailRecursiveSinkCommand { #endif /// This class is usually used with `Generator` version of the operators. -class TailRecursiveSink - : Sink - , InvocableWithValueType where S.Iterator.Element: ObservableConvertibleType, S.Iterator.Element.E == O.E { +class TailRecursiveSink + : Sink + , InvocableWithValueType where Sequence.Element: ObservableConvertibleType, Sequence.Element.Element == Observer.Element { typealias Value = TailRecursiveSinkCommand - typealias E = O.E - typealias SequenceGenerator = (generator: S.Iterator, remaining: IntMax?) + typealias Element = Observer.Element + typealias SequenceGenerator = (generator: Sequence.Iterator, remaining: IntMax?) - var _generators: [SequenceGenerator] = [] - var _isDisposed = false - var _subscription = SerialDisposable() + var generators: [SequenceGenerator] = [] + var disposed = false + var subscription = SerialDisposable() // this is thread safe object - var _gate = AsyncLock>>() + var gate = AsyncLock>>() - override init(observer: O, cancel: Cancelable) { + override init(observer: Observer, cancel: Cancelable) { super.init(observer: observer, cancel: cancel) } func run(_ sources: SequenceGenerator) -> Disposable { - _generators.append(sources) + self.generators.append(sources) - schedule(.moveNext) + self.schedule(.moveNext) - return _subscription + return self.subscription } func invoke(_ command: TailRecursiveSinkCommand) { switch command { case .dispose: - disposeCommand() + self.disposeCommand() case .moveNext: - moveNextCommand() + self.moveNextCommand() } } // simple implementation for now func schedule(_ command: TailRecursiveSinkCommand) { - _gate.invoke(InvocableScheduledItem(invocable: self, state: command)) + self.gate.invoke(InvocableScheduledItem(invocable: self, state: command)) } func done() { - forwardOn(.completed) - dispose() + self.forwardOn(.completed) + self.dispose() } - func extract(_ observable: Observable) -> SequenceGenerator? { + func extract(_ observable: Observable) -> SequenceGenerator? { rxAbstractMethod() } // should be done on gate locked private func moveNextCommand() { - var next: Observable? = nil + var next: Observable? repeat { - guard let (g, left) = _generators.last else { + guard let (g, left) = self.generators.last else { break } - if _isDisposed { + if self.isDisposed { return } - _generators.removeLast() + self.generators.removeLast() var e = g @@ -98,20 +98,20 @@ class TailRecursiveSink if let knownOriginalLeft = left { // `- 1` because generator.next() has just been called if knownOriginalLeft - 1 >= 1 { - _generators.append((e, knownOriginalLeft - 1)) + self.generators.append((e, knownOriginalLeft - 1)) } } else { - _generators.append((e, nil)) + self.generators.append((e, nil)) } - let nextGenerator = extract(nextCandidate) + let nextGenerator = self.extract(nextCandidate) if let nextGenerator = nextGenerator { - _generators.append(nextGenerator) + self.generators.append(nextGenerator) #if DEBUG || TRACE_RESOURCES - if maxTailRecursiveSinkStackSize < _generators.count { - maxTailRecursiveSinkStackSize = _generators.count + if maxTailRecursiveSinkStackSize < self.generators.count { + maxTailRecursiveSinkStackSize = self.generators.count } #endif } @@ -120,32 +120,32 @@ class TailRecursiveSink } } while next == nil - guard let existingNext = next else { - done() + guard let existingNext = next else { + self.done() return } let disposable = SingleAssignmentDisposable() - _subscription.disposable = disposable - disposable.setDisposable(subscribeToNext(existingNext)) + self.subscription.disposable = disposable + disposable.setDisposable(self.subscribeToNext(existingNext)) } - func subscribeToNext(_ source: Observable) -> Disposable { + func subscribeToNext(_ source: Observable) -> Disposable { rxAbstractMethod() } func disposeCommand() { - _isDisposed = true - _generators.removeAll(keepingCapacity: false) + self.disposed = true + self.generators.removeAll(keepingCapacity: false) } override func dispose() { super.dispose() - _subscription.dispose() - _gate.dispose() + self.subscription.dispose() + self.gate.dispose() - schedule(.dispose) + self.schedule(.dispose) } } diff --git a/iOS/RxSwift/Platform/AtomicInt.swift b/iOS/RxSwift/Platform/AtomicInt.swift new file mode 100644 index 00000000..bf19c5be --- /dev/null +++ b/iOS/RxSwift/Platform/AtomicInt.swift @@ -0,0 +1,72 @@ +// +// AtomicInt.swift +// Platform +// +// Created by Krunoslav Zaher on 10/28/18. +// Copyright © 2018 Krunoslav Zaher. All rights reserved. +// + +import Foundation + +final class AtomicInt: NSLock { + fileprivate var value: Int32 + public init(_ value: Int32 = 0) { + self.value = value + } +} + +@discardableResult +@inline(__always) +func add(_ this: AtomicInt, _ value: Int32) -> Int32 { + this.lock() + let oldValue = this.value + this.value += value + this.unlock() + return oldValue +} + +@discardableResult +@inline(__always) +func sub(_ this: AtomicInt, _ value: Int32) -> Int32 { + this.lock() + let oldValue = this.value + this.value -= value + this.unlock() + return oldValue +} + +@discardableResult +@inline(__always) +func fetchOr(_ this: AtomicInt, _ mask: Int32) -> Int32 { + this.lock() + let oldValue = this.value + this.value |= mask + this.unlock() + return oldValue +} + +@inline(__always) +func load(_ this: AtomicInt) -> Int32 { + this.lock() + let oldValue = this.value + this.unlock() + return oldValue +} + +@discardableResult +@inline(__always) +func increment(_ this: AtomicInt) -> Int32 { + add(this, 1) +} + +@discardableResult +@inline(__always) +func decrement(_ this: AtomicInt) -> Int32 { + sub(this, 1) +} + +@inline(__always) +func isFlagSet(_ this: AtomicInt, _ mask: Int32) -> Bool { + (load(this) & mask) != 0 +} + diff --git a/iOS/RxSwift/Platform/DataStructures/Bag.swift b/iOS/RxSwift/Platform/DataStructures/Bag.swift index 002c3a6c..9f5f0171 100644 --- a/iOS/RxSwift/Platform/DataStructures/Bag.swift +++ b/iOS/RxSwift/Platform/DataStructures/Bag.swift @@ -25,7 +25,7 @@ Data structure that represents a bag of elements typed `T`. Single element can be stored multiple times. -Time and space complexity of insertion an deletion is O(n). +Time and space complexity of insertion and deletion is O(n). It is suitable for storing small number of elements. */ @@ -35,19 +35,19 @@ struct Bag : CustomDebugStringConvertible { typealias Entry = (key: BagKey, value: T) - fileprivate var _nextKey: BagKey = BagKey(rawValue: 0) + private var _nextKey: BagKey = BagKey(rawValue: 0) // data // first fill inline variables - var _key0: BagKey? = nil - var _value0: T? = nil + var _key0: BagKey? + var _value0: T? // then fill "array dictionary" var _pairs = ContiguousArray() // last is sparse dictionary - var _dictionary: [BagKey : T]? = nil + var _dictionary: [BagKey: T]? var _onlyFastPath = true @@ -122,12 +122,10 @@ struct Bag : CustomDebugStringConvertible { return existingObject } - for i in 0 ..< _pairs.count { - if _pairs[i].key == key { - let value = _pairs[i].value - _pairs.remove(at: i) - return value - } + for i in 0 ..< _pairs.count where _pairs[i].key == key { + let value = _pairs[i].value + _pairs.remove(at: i) + return value } return nil @@ -137,7 +135,7 @@ struct Bag : CustomDebugStringConvertible { extension Bag { /// A textual representation of `self`, suitable for debugging. var debugDescription : String { - return "\(self.count) elements in Bag" + "\(self.count) elements in Bag" } } @@ -173,11 +171,11 @@ extension Bag { } extension BagKey: Hashable { - var hashValue: Int { - return rawValue.hashValue + func hash(into hasher: inout Hasher) { + hasher.combine(rawValue) } } func ==(lhs: BagKey, rhs: BagKey) -> Bool { - return lhs.rawValue == rhs.rawValue + lhs.rawValue == rhs.rawValue } diff --git a/iOS/RxSwift/Platform/DataStructures/InfiniteSequence.swift b/iOS/RxSwift/Platform/DataStructures/InfiniteSequence.swift index 5a573a0d..75d7bea7 100644 --- a/iOS/RxSwift/Platform/DataStructures/InfiniteSequence.swift +++ b/iOS/RxSwift/Platform/DataStructures/InfiniteSequence.swift @@ -7,20 +7,17 @@ // /// Sequence that repeats `repeatedValue` infinite number of times. -struct InfiniteSequence : Sequence { - typealias Element = E - typealias Iterator = AnyIterator +struct InfiniteSequence : Sequence { + typealias Iterator = AnyIterator - private let _repeatedValue: E + private let repeatedValue: Element - init(repeatedValue: E) { - _repeatedValue = repeatedValue + init(repeatedValue: Element) { + self.repeatedValue = repeatedValue } func makeIterator() -> Iterator { - let repeatedValue = _repeatedValue - return AnyIterator { - return repeatedValue - } + let repeatedValue = self.repeatedValue + return AnyIterator { repeatedValue } } } diff --git a/iOS/RxSwift/Platform/DataStructures/PriorityQueue.swift b/iOS/RxSwift/Platform/DataStructures/PriorityQueue.swift index 9b2c370e..9ed856b9 100644 --- a/iOS/RxSwift/Platform/DataStructures/PriorityQueue.swift +++ b/iOS/RxSwift/Platform/DataStructures/PriorityQueue.swift @@ -7,27 +7,27 @@ // struct PriorityQueue { - private let _hasHigherPriority: (Element, Element) -> Bool - private let _isEqual: (Element, Element) -> Bool + private let hasHigherPriority: (Element, Element) -> Bool + private let isEqual: (Element, Element) -> Bool - fileprivate var _elements = [Element]() + private var elements = [Element]() init(hasHigherPriority: @escaping (Element, Element) -> Bool, isEqual: @escaping (Element, Element) -> Bool) { - _hasHigherPriority = hasHigherPriority - _isEqual = isEqual + self.hasHigherPriority = hasHigherPriority + self.isEqual = isEqual } mutating func enqueue(_ element: Element) { - _elements.append(element) - bubbleToHigherPriority(_elements.count - 1) + elements.append(element) + bubbleToHigherPriority(elements.count - 1) } func peek() -> Element? { - return _elements.first + elements.first } var isEmpty: Bool { - return _elements.count == 0 + elements.count == 0 } mutating func dequeue() -> Element? { @@ -41,8 +41,8 @@ struct PriorityQueue { } mutating func remove(_ element: Element) { - for i in 0 ..< _elements.count { - if _isEqual(_elements[i], element) { + for i in 0 ..< elements.count { + if self.isEqual(elements[i], element) { removeAt(i) return } @@ -50,16 +50,12 @@ struct PriorityQueue { } private mutating func removeAt(_ index: Int) { - let removingLast = index == _elements.count - 1 + let removingLast = index == elements.count - 1 if !removingLast { - #if swift(>=3.2) - _elements.swapAt(index, _elements.count - 1) - #else - swap(&_elements[index], &_elements[_elements.count - 1]) - #endif + elements.swapAt(index, elements.count - 1) } - _ = _elements.popLast() + _ = elements.popLast() if !removingLast { bubbleToHigherPriority(index) @@ -69,25 +65,21 @@ struct PriorityQueue { private mutating func bubbleToHigherPriority(_ initialUnbalancedIndex: Int) { precondition(initialUnbalancedIndex >= 0) - precondition(initialUnbalancedIndex < _elements.count) + precondition(initialUnbalancedIndex < elements.count) var unbalancedIndex = initialUnbalancedIndex while unbalancedIndex > 0 { let parentIndex = (unbalancedIndex - 1) / 2 - guard _hasHigherPriority(_elements[unbalancedIndex], _elements[parentIndex]) else { break } - #if swift(>=3.2) - _elements.swapAt(unbalancedIndex, parentIndex) - #else - swap(&_elements[unbalancedIndex], &_elements[parentIndex]) - #endif + guard self.hasHigherPriority(elements[unbalancedIndex], elements[parentIndex]) else { break } + elements.swapAt(unbalancedIndex, parentIndex) unbalancedIndex = parentIndex } } private mutating func bubbleToLowerPriority(_ initialUnbalancedIndex: Int) { precondition(initialUnbalancedIndex >= 0) - precondition(initialUnbalancedIndex < _elements.count) + precondition(initialUnbalancedIndex < elements.count) var unbalancedIndex = initialUnbalancedIndex while true { @@ -96,21 +88,17 @@ struct PriorityQueue { var highestPriorityIndex = unbalancedIndex - if leftChildIndex < _elements.count && _hasHigherPriority(_elements[leftChildIndex], _elements[highestPriorityIndex]) { + if leftChildIndex < elements.count && self.hasHigherPriority(elements[leftChildIndex], elements[highestPriorityIndex]) { highestPriorityIndex = leftChildIndex } - if rightChildIndex < _elements.count && _hasHigherPriority(_elements[rightChildIndex], _elements[highestPriorityIndex]) { + if rightChildIndex < elements.count && self.hasHigherPriority(elements[rightChildIndex], elements[highestPriorityIndex]) { highestPriorityIndex = rightChildIndex } guard highestPriorityIndex != unbalancedIndex else { break } + elements.swapAt(highestPriorityIndex, unbalancedIndex) - #if swift(>=3.2) - _elements.swapAt(highestPriorityIndex, unbalancedIndex) - #else - swap(&_elements[highestPriorityIndex], &_elements[unbalancedIndex]) - #endif unbalancedIndex = highestPriorityIndex } } @@ -118,6 +106,6 @@ struct PriorityQueue { extension PriorityQueue : CustomDebugStringConvertible { var debugDescription: String { - return _elements.debugDescription + elements.debugDescription } } diff --git a/iOS/RxSwift/Platform/DataStructures/Queue.swift b/iOS/RxSwift/Platform/DataStructures/Queue.swift index d05726c7..625d4733 100644 --- a/iOS/RxSwift/Platform/DataStructures/Queue.swift +++ b/iOS/RxSwift/Platform/DataStructures/Queue.swift @@ -18,12 +18,12 @@ struct Queue: Sequence { /// Type of generator. typealias Generator = AnyIterator - private let _resizeFactor = 2 + private let resizeFactor = 2 - private var _storage: ContiguousArray - private var _count = 0 - private var _pushNextIndex = 0 - private let _initialCapacity: Int + private var storage: ContiguousArray + private var innerCount = 0 + private var pushNextIndex = 0 + private let initialCapacity: Int /** Creates new queue. @@ -31,68 +31,64 @@ struct Queue: Sequence { - parameter capacity: Capacity of newly created queue. */ init(capacity: Int) { - _initialCapacity = capacity + initialCapacity = capacity - _storage = ContiguousArray(repeating: nil, count: capacity) + storage = ContiguousArray(repeating: nil, count: capacity) } private var dequeueIndex: Int { - let index = _pushNextIndex - count - return index < 0 ? index + _storage.count : index + let index = pushNextIndex - count + return index < 0 ? index + storage.count : index } /// - returns: Is queue empty. - var isEmpty: Bool { - return count == 0 - } + var isEmpty: Bool { count == 0 } /// - returns: Number of elements inside queue. - var count: Int { - return _count - } + var count: Int { innerCount } /// - returns: Element in front of a list of elements to `dequeue`. func peek() -> T { precondition(count > 0) - return _storage[dequeueIndex]! + return storage[dequeueIndex]! } mutating private func resizeTo(_ size: Int) { var newStorage = ContiguousArray(repeating: nil, count: size) - let count = _count + let count = self.count let dequeueIndex = self.dequeueIndex - let spaceToEndOfQueue = _storage.count - dequeueIndex + let spaceToEndOfQueue = storage.count - dequeueIndex // first batch is from dequeue index to end of array let countElementsInFirstBatch = Swift.min(count, spaceToEndOfQueue) // second batch is wrapped from start of array to end of queue let numberOfElementsInSecondBatch = count - countElementsInFirstBatch - newStorage[0 ..< countElementsInFirstBatch] = _storage[dequeueIndex ..< (dequeueIndex + countElementsInFirstBatch)] - newStorage[countElementsInFirstBatch ..< (countElementsInFirstBatch + numberOfElementsInSecondBatch)] = _storage[0 ..< numberOfElementsInSecondBatch] + newStorage[0 ..< countElementsInFirstBatch] = storage[dequeueIndex ..< (dequeueIndex + countElementsInFirstBatch)] + newStorage[countElementsInFirstBatch ..< (countElementsInFirstBatch + numberOfElementsInSecondBatch)] = storage[0 ..< numberOfElementsInSecondBatch] - _count = count - _pushNextIndex = count - _storage = newStorage + self.innerCount = count + pushNextIndex = count + storage = newStorage } /// Enqueues `element`. /// /// - parameter element: Element to enqueue. mutating func enqueue(_ element: T) { - if count == _storage.count { - resizeTo(Swift.max(_storage.count, 1) * _resizeFactor) + if count == storage.count { + resizeTo(Swift.max(storage.count, 1) * resizeFactor) } - _storage[_pushNextIndex] = element - _pushNextIndex += 1 - _count += 1 + storage[pushNextIndex] = element + pushNextIndex += 1 + innerCount += 1 - if _pushNextIndex >= _storage.count { - _pushNextIndex -= _storage.count + if pushNextIndex >= storage.count { + pushNextIndex -= storage.count } } @@ -102,11 +98,11 @@ struct Queue: Sequence { let index = dequeueIndex defer { - _storage[index] = nil - _count -= 1 + storage[index] = nil + innerCount -= 1 } - return _storage[index]! + return storage[index]! } /// Dequeues element or throws an exception in case queue is empty. @@ -118,9 +114,9 @@ struct Queue: Sequence { } defer { - let downsizeLimit = _storage.count / (_resizeFactor * _resizeFactor) - if _count < downsizeLimit && downsizeLimit >= _initialCapacity { - resizeTo(_storage.count / _resizeFactor) + let downsizeLimit = storage.count / (resizeFactor * resizeFactor) + if count < downsizeLimit && downsizeLimit >= initialCapacity { + resizeTo(storage.count / resizeFactor) } } @@ -130,23 +126,23 @@ struct Queue: Sequence { /// - returns: Generator of contained elements. func makeIterator() -> AnyIterator { var i = dequeueIndex - var count = _count + var innerCount = count return AnyIterator { - if count == 0 { + if innerCount == 0 { return nil } defer { - count -= 1 + innerCount -= 1 i += 1 } - if i >= self._storage.count { - i -= self._storage.count + if i >= self.storage.count { + i -= self.storage.count } - return self._storage[i] + return self.storage[i] } } } diff --git a/iOS/RxSwift/Platform/DeprecationWarner.swift b/iOS/RxSwift/Platform/DeprecationWarner.swift deleted file mode 100644 index 863636b7..00000000 --- a/iOS/RxSwift/Platform/DeprecationWarner.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// DeprecationWarner.swift -// Platform -// -// Created by Shai Mishali on 1/9/18. -// Copyright © 2018 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -#if DEBUG - class DeprecationWarner { - private static var warned = Set() - private static var _lock = NSRecursiveLock() - - static func warnIfNeeded(_ kind: Kind) { - _lock.lock(); defer { _lock.unlock() } - guard !warned.contains(kind) else { return } - - warned.insert(kind) - print("ℹ️ [DEPRECATED] \(kind.message)") - } - } - - extension DeprecationWarner { - enum Kind { - case variable - case globalTestFunctionNext - case globalTestFunctionError - case globalTestFunctionCompleted - - var message: String { - switch self { - case .variable: return "`Variable` is planned for future deprecation. Please consider `BehaviorRelay` as a replacement. Read more at: https://git.io/vNqvx" - case .globalTestFunctionNext: return "The `next()` global function is planned for future deprecation. Please use `Recorded.next()` instead." - case .globalTestFunctionError: return "The `error()` global function is planned for future deprecation. Please use `Recorded.error()` instead." - case .globalTestFunctionCompleted: return "The `completed()` global function is planned for future deprecation. Please use `Recorded.completed()` instead." - } - } - } - } -#endif - diff --git a/iOS/RxSwift/Platform/DispatchQueue+Extensions.swift b/iOS/RxSwift/Platform/DispatchQueue+Extensions.swift index 552314a1..aaf24cae 100644 --- a/iOS/RxSwift/Platform/DispatchQueue+Extensions.swift +++ b/iOS/RxSwift/Platform/DispatchQueue+Extensions.swift @@ -16,6 +16,6 @@ extension DispatchQueue { }() static var isMain: Bool { - return DispatchQueue.getSpecific(key: token) != nil + DispatchQueue.getSpecific(key: token) != nil } } diff --git a/iOS/RxSwift/Platform/Platform.Darwin.swift b/iOS/RxSwift/Platform/Platform.Darwin.swift index d9e744fe..eacc1943 100644 --- a/iOS/RxSwift/Platform/Platform.Darwin.swift +++ b/iOS/RxSwift/Platform/Platform.Darwin.swift @@ -9,35 +9,10 @@ #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) import Darwin - import class Foundation.Thread - import func Foundation.OSAtomicCompareAndSwap32Barrier - import func Foundation.OSAtomicIncrement32Barrier - import func Foundation.OSAtomicDecrement32Barrier - import protocol Foundation.NSCopying - - typealias AtomicInt = Int32 - - fileprivate func castToUInt32Pointer(_ pointer: UnsafeMutablePointer) -> UnsafeMutablePointer { - let raw = UnsafeMutableRawPointer(pointer) - return raw.assumingMemoryBound(to: UInt32.self) - } - - let AtomicCompareAndSwap = OSAtomicCompareAndSwap32Barrier - let AtomicIncrement = OSAtomicIncrement32Barrier - let AtomicDecrement = OSAtomicDecrement32Barrier - func AtomicOr(_ mask: UInt32, _ theValue : UnsafeMutablePointer) -> Int32 { - return OSAtomicOr32OrigBarrier(mask, castToUInt32Pointer(theValue)) - } - func AtomicFlagSet(_ mask: UInt32, _ theValue : UnsafeMutablePointer) -> Bool { - // just used to create a barrier - OSAtomicXor32OrigBarrier(0, castToUInt32Pointer(theValue)) - return (theValue.pointee & Int32(mask)) != 0 - } + import Foundation extension Thread { - - static func setThreadLocalStorageValue(_ value: T?, forKey key: NSCopying - ) { + static func setThreadLocalStorageValue(_ value: T?, forKey key: NSCopying) { let currentThread = Thread.current let threadDictionary = currentThread.threadDictionary @@ -47,8 +22,8 @@ else { threadDictionary[key] = nil } - } + static func getThreadLocalStorageValueForKey(_ key: NSCopying) -> T? { let currentThread = Thread.current let threadDictionary = currentThread.threadDictionary @@ -57,10 +32,4 @@ } } - extension AtomicInt { - func valueSnapshot() -> Int32 { - return self - } - } - #endif diff --git a/iOS/RxSwift/Platform/Platform.Linux.swift b/iOS/RxSwift/Platform/Platform.Linux.swift index 5cd07e2c..52a3e3af 100644 --- a/iOS/RxSwift/Platform/Platform.Linux.swift +++ b/iOS/RxSwift/Platform/Platform.Linux.swift @@ -8,90 +8,17 @@ #if os(Linux) - import XCTest - import Glibc - import SwiftShims - import class Foundation.Thread - - final class AtomicInt { - typealias IntegerLiteralType = Int - fileprivate var value: Int32 = 0 - fileprivate var _lock = RecursiveLock() - - func lock() { - _lock.lock() - } - func unlock() { - _lock.unlock() - } - - func valueSnapshot() -> Int32 { - return value - } - } - - extension AtomicInt: ExpressibleByIntegerLiteral { - convenience init(integerLiteral value: Int) { - self.init() - self.value = Int32(value) - } - } - - func >(lhs: AtomicInt, rhs: Int32) -> Bool { - return lhs.value > rhs - } - func ==(lhs: AtomicInt, rhs: Int32) -> Bool { - return lhs.value == rhs - } - - func AtomicFlagSet(_ mask: UInt32, _ atomic: inout AtomicInt) -> Bool { - atomic.lock(); defer { atomic.unlock() } - return (atomic.value & Int32(mask)) != 0 - } - - func AtomicOr(_ mask: UInt32, _ atomic: inout AtomicInt) -> Int32 { - atomic.lock(); defer { atomic.unlock() } - let value = atomic.value - atomic.value |= Int32(mask) - return value - } - - func AtomicIncrement(_ atomic: inout AtomicInt) -> Int32 { - atomic.lock(); defer { atomic.unlock() } - atomic.value += 1 - return atomic.value - } - - func AtomicDecrement(_ atomic: inout AtomicInt) -> Int32 { - atomic.lock(); defer { atomic.unlock() } - atomic.value -= 1 - return atomic.value - } - - func AtomicCompareAndSwap(_ l: Int32, _ r: Int32, _ atomic: inout AtomicInt) -> Bool { - atomic.lock(); defer { atomic.unlock() } - if atomic.value == l { - atomic.value = r - return true - } - - return false - } + import Foundation extension Thread { static func setThreadLocalStorageValue(_ value: T?, forKey key: String) { - let currentThread = Thread.current - var threadDictionary = currentThread.threadDictionary - if let newValue = value { - threadDictionary[key] = newValue + Thread.current.threadDictionary[key] = newValue } else { - threadDictionary[key] = nil + Thread.current.threadDictionary[key] = nil } - - currentThread.threadDictionary = threadDictionary } static func getThreadLocalStorageValueForKey(_ key: String) -> T? { diff --git a/iOS/RxSwift/Platform/RecursiveLock.swift b/iOS/RxSwift/Platform/RecursiveLock.swift index c03471d5..10b9bbb0 100644 --- a/iOS/RxSwift/Platform/RecursiveLock.swift +++ b/iOS/RxSwift/Platform/RecursiveLock.swift @@ -6,7 +6,7 @@ // Copyright © 2016 Krunoslav Zaher. All rights reserved. // -import class Foundation.NSRecursiveLock +import Foundation #if TRACE_RESOURCES class RecursiveLock: NSRecursiveLock { diff --git a/iOS/RxSwift/Reactive.swift b/iOS/RxSwift/Reactive.swift index b8739966..1bf390dc 100644 --- a/iOS/RxSwift/Reactive.swift +++ b/iOS/RxSwift/Reactive.swift @@ -20,8 +20,10 @@ With this approach we can have more specialized methods and properties using `Base` and not just specialized on common base type. + `Binder`s are also automatically synthesized using `@dynamicMemberLookup` for writable reference properties of the reactive base. */ +@dynamicMemberLookup public struct Reactive { /// Base object to extend. public let base: Base @@ -32,43 +34,47 @@ public struct Reactive { public init(_ base: Base) { self.base = base } + + /// Automatically synthesized binder for a key path between the reactive + /// base and one of its properties + public subscript(dynamicMember keyPath: ReferenceWritableKeyPath) -> Binder where Base: AnyObject { + Binder(self.base) { base, value in + base[keyPath: keyPath] = value + } + } } /// A type that has reactive extensions. public protocol ReactiveCompatible { /// Extended type - associatedtype CompatibleType + associatedtype ReactiveBase /// Reactive extensions. - static var rx: Reactive.Type { get set } + static var rx: Reactive.Type { get set } /// Reactive extensions. - var rx: Reactive { get set } + var rx: Reactive { get set } } extension ReactiveCompatible { /// Reactive extensions. public static var rx: Reactive.Type { - get { - return Reactive.self - } - set { - // this enables using Reactive to "mutate" base type - } + get { Reactive.self } + // this enables using Reactive to "mutate" base type + // swiftlint:disable:next unused_setter_value + set { } } /// Reactive extensions. public var rx: Reactive { - get { - return Reactive(self) - } - set { - // this enables using Reactive to "mutate" base object - } + get { Reactive(self) } + // this enables using Reactive to "mutate" base object + // swiftlint:disable:next unused_setter_value + set { } } } -import class Foundation.NSObject +import Foundation /// Extend NSObject with `rx` proxy. extension NSObject: ReactiveCompatible { } diff --git a/iOS/RxSwift/Rx.swift b/iOS/RxSwift/Rx.swift index 99292ca6..bcdd2794 100644 --- a/iOS/RxSwift/Rx.swift +++ b/iOS/RxSwift/Rx.swift @@ -7,27 +7,27 @@ // #if TRACE_RESOURCES - fileprivate var resourceCount: AtomicInt = 0 + private let resourceCount = AtomicInt(0) /// Resource utilization information public struct Resources { /// Counts internal Rx resource allocations (Observables, Observers, Disposables, etc.). This provides a simple way to detect leaks during development. public static var total: Int32 { - return resourceCount.valueSnapshot() + load(resourceCount) } /// Increments `Resources.total` resource count. /// /// - returns: New resource count public static func incrementTotal() -> Int32 { - return AtomicIncrement(&resourceCount) + increment(resourceCount) } /// Decrements `Resources.total` resource count /// /// - returns: New resource count public static func decrementTotal() -> Int32 { - return AtomicDecrement(&resourceCount) + decrement(resourceCount) } } #endif @@ -38,7 +38,6 @@ func rxAbstractMethod(file: StaticString = #file, line: UInt = #line) -> Swift.N } func rxFatalError(_ lastMessage: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) -> Swift.Never { - // The temptation to comment this line is great, but please don't, it's for your own good. The choice is yours. fatalError(lastMessage(), file: file, line: line) } @@ -67,16 +66,16 @@ func decrementChecked(_ i: inout Int) throws -> Int { } #if DEBUG - import class Foundation.Thread + import Foundation final class SynchronizationTracker { - private let _lock = RecursiveLock() + private let lock = RecursiveLock() public enum SynchronizationErrorMessages: String { case variable = "Two different threads are trying to assign the same `Variable.value` unsynchronized.\n This is undefined behavior because the end result (variable value) is nondeterministic and depends on the \n operating system thread scheduler. This will cause random behavior of your program.\n" case `default` = "Two different unsynchronized threads are trying to send some event simultaneously.\n This is undefined behavior because the ordering of the effects caused by these events is nondeterministic and depends on the \n operating system thread scheduler. This will result in a random behavior of your program.\n" } - private var _threads = Dictionary() + private var threads = [UnsafeMutableRawPointer: Int]() private func synchronizationError(_ message: String) { #if FATAL_SYNCHRONIZATION @@ -87,12 +86,12 @@ func decrementChecked(_ i: inout Int) throws -> Int { } func register(synchronizationErrorMessage: SynchronizationErrorMessages) { - _lock.lock(); defer { _lock.unlock() } + self.lock.lock(); defer { self.lock.unlock() } let pointer = Unmanaged.passUnretained(Thread.current).toOpaque() - let count = (_threads[pointer] ?? 0) + 1 + let count = (self.threads[pointer] ?? 0) + 1 if count > 1 { - synchronizationError( + self.synchronizationError( "⚠️ Reentrancy anomaly was detected.\n" + " > Debugging: To debug this issue you can set a breakpoint in \(#file):\(#line) and observe the call stack.\n" + " > Problem: This behavior is breaking the observable sequence grammar. `next (error | completed)?`\n" + @@ -100,33 +99,34 @@ func decrementChecked(_ i: inout Int) throws -> Int { " Observable sequence is trying to send an event before sending of previous event has finished.\n" + " > Interpretation: This could mean that there is some kind of unexpected cyclic dependency in your code,\n" + " or that the system is not behaving in the expected way.\n" + - " > Remedy: If this is the expected behavior this message can be suppressed by adding `.observeOn(MainScheduler.asyncInstance)`\n" + - " or by enqueing sequence events in some other way.\n" + " > Remedy: If this is the expected behavior this message can be suppressed by adding `.observe(on:MainScheduler.asyncInstance)`\n" + + " or by enqueuing sequence events in some other way.\n" ) } - _threads[pointer] = count + self.threads[pointer] = count - if _threads.count > 1 { - synchronizationError( + if self.threads.count > 1 { + self.synchronizationError( "⚠️ Synchronization anomaly was detected.\n" + " > Debugging: To debug this issue you can set a breakpoint in \(#file):\(#line) and observe the call stack.\n" + " > Problem: This behavior is breaking the observable sequence grammar. `next (error | completed)?`\n" + " This behavior breaks the grammar because there is overlapping between sequence events.\n" + " Observable sequence is trying to send an event before sending of previous event has finished.\n" + " > Interpretation: " + synchronizationErrorMessage.rawValue + - " > Remedy: If this is the expected behavior this message can be suppressed by adding `.observeOn(MainScheduler.asyncInstance)`\n" + + " > Remedy: If this is the expected behavior this message can be suppressed by adding `.observe(on:MainScheduler.asyncInstance)`\n" + " or by synchronizing sequence events in some other way.\n" ) } } func unregister() { - _lock.lock(); defer { _lock.unlock() } - let pointer = Unmanaged.passUnretained(Thread.current).toOpaque() - _threads[pointer] = (_threads[pointer] ?? 1) - 1 - if _threads[pointer] == 0 { - _threads[pointer] = nil + self.lock.performLocked { + let pointer = Unmanaged.passUnretained(Thread.current).toOpaque() + self.threads[pointer] = (self.threads[pointer] ?? 1) - 1 + if self.threads[pointer] == 0 { + self.threads[pointer] = nil + } } } } diff --git a/iOS/RxSwift/RxMutableBox.swift b/iOS/RxSwift/RxMutableBox.swift index 7f3c333b..73476c36 100644 --- a/iOS/RxSwift/RxMutableBox.swift +++ b/iOS/RxSwift/RxMutableBox.swift @@ -6,10 +6,35 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // +#if os(Linux) +/// As Swift 5 was released, A patch to `Thread` for Linux +/// changed `threadDictionary` to a `NSMutableDictionary` instead of +/// a `Dictionary`: https://github.com/apple/swift-corelibs-foundation/pull/1762/files +/// +/// This means that on Linux specifically, `RxMutableBox` must be a `NSObject` +/// or it won't be possible to store it in `Thread.threadDictionary`. +/// +/// For more information, read the discussion at: +/// https://github.com/ReactiveX/RxSwift/issues/1911#issuecomment-479723298 +import Foundation + +/// Creates mutable reference wrapper for any type. +final class RxMutableBox: NSObject { + /// Wrapped value + var value: T + + /// Creates reference wrapper for `value`. + /// + /// - parameter value: Value to wrap. + init (_ value: T) { + self.value = value + } +} +#else /// Creates mutable reference wrapper for any type. -final class RxMutableBox : CustomDebugStringConvertible { +final class RxMutableBox: CustomDebugStringConvertible { /// Wrapped value - var value : T + var value: T /// Creates reference wrapper for `value`. /// @@ -22,6 +47,7 @@ final class RxMutableBox : CustomDebugStringConvertible { extension RxMutableBox { /// - returns: Box description. var debugDescription: String { - return "MutatingBox(\(self.value))" + "MutatingBox(\(self.value))" } } +#endif diff --git a/iOS/RxSwift/SchedulerType.swift b/iOS/RxSwift/SchedulerType.swift index bdfcf8b0..6c8fe4a3 100644 --- a/iOS/RxSwift/SchedulerType.swift +++ b/iOS/RxSwift/SchedulerType.swift @@ -6,11 +6,11 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import struct Foundation.TimeInterval -import struct Foundation.Date +import Dispatch +import Foundation // 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 @@ -61,7 +61,7 @@ extension SchedulerType { return schedule.start() } - func scheduleRecursive(_ state: State, dueTime: RxTimeInterval, action: @escaping (State, AnyRecursiveScheduler) -> ()) -> Disposable { + func scheduleRecursive(_ state: State, dueTime: RxTimeInterval, action: @escaping (State, AnyRecursiveScheduler) -> Void) -> Disposable { let scheduler = AnyRecursiveScheduler(scheduler: self, action: action) scheduler.schedule(state, dueTime: dueTime) diff --git a/iOS/RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift b/iOS/RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift index c6acaa19..02c47c91 100644 --- a/iOS/RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift +++ b/iOS/RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift @@ -6,9 +6,8 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import struct Foundation.Date -import struct Foundation.TimeInterval import Dispatch +import Foundation /// Abstracts the work that needs to be performed on a specific `dispatch_queue_t`. You can also pass a serial dispatch queue, it shouldn't cause any problems. /// @@ -18,7 +17,7 @@ public class ConcurrentDispatchQueueScheduler: SchedulerType { public typealias Time = Date public var now : Date { - return Date() + Date() } let configuration: DispatchQueueConfiguration @@ -26,14 +25,15 @@ public class ConcurrentDispatchQueueScheduler: SchedulerType { /// Constructs new `ConcurrentDispatchQueueScheduler` that wraps `queue`. /// /// - parameter queue: Target dispatch queue. + /// - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. public init(queue: DispatchQueue, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { - configuration = DispatchQueueConfiguration(queue: queue, leeway: leeway) + self.configuration = DispatchQueueConfiguration(queue: queue, leeway: leeway) } /// Convenience init for scheduler that wraps one of the global concurrent dispatch queues. /// /// - parameter qos: Target global dispatch queue, by quality of service class. - @available(iOS 8, OSX 10.10, *) + /// - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. public convenience init(qos: DispatchQoS, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { self.init(queue: DispatchQueue( label: "rxswift.queue.\(qos)", @@ -52,7 +52,7 @@ public class ConcurrentDispatchQueueScheduler: SchedulerType { - returns: The disposable object used to cancel the scheduled action (best effort). */ public final func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - return self.configuration.schedule(state, action: action) + self.configuration.schedule(state, action: action) } /** @@ -63,8 +63,8 @@ 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 { - return self.configuration.scheduleRelative(state, dueTime: dueTime, action: action) + public final func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { + self.configuration.scheduleRelative(state, dueTime: dueTime, action: action) } /** @@ -76,7 +76,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 { - return self.configuration.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) + public func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { + self.configuration.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) } } diff --git a/iOS/RxSwift/Schedulers/ConcurrentMainScheduler.swift b/iOS/RxSwift/Schedulers/ConcurrentMainScheduler.swift index a98ad218..c438d7d4 100644 --- a/iOS/RxSwift/Schedulers/ConcurrentMainScheduler.swift +++ b/iOS/RxSwift/Schedulers/ConcurrentMainScheduler.swift @@ -6,9 +6,8 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import struct Foundation.Date -import struct Foundation.TimeInterval import Dispatch +import Foundation /** Abstracts work that needs to be performed on `MainThread`. In case `schedule` methods are called from main thread, it will perform action immediately without scheduling. @@ -20,17 +19,17 @@ public final class ConcurrentMainScheduler : SchedulerType { public typealias TimeInterval = Foundation.TimeInterval public typealias Time = Date - private let _mainScheduler: MainScheduler - private let _mainQueue: DispatchQueue + private let mainScheduler: MainScheduler + private let mainQueue: DispatchQueue /// - returns: Current time. - public var now : Date { - return _mainScheduler.now as Date + public var now: Date { + self.mainScheduler.now as Date } private init(mainScheduler: MainScheduler) { - _mainQueue = DispatchQueue.main - _mainScheduler = mainScheduler + self.mainQueue = DispatchQueue.main + self.mainScheduler = mainScheduler } /// Singleton instance of `ConcurrentMainScheduler` @@ -50,7 +49,7 @@ public final class ConcurrentMainScheduler : SchedulerType { let cancel = SingleAssignmentDisposable() - _mainQueue.async { + self.mainQueue.async { if cancel.isDisposed { return } @@ -69,8 +68,8 @@ 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 { - return _mainScheduler.scheduleRelative(state, dueTime: dueTime, action: action) + public final func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { + self.mainScheduler.scheduleRelative(state, dueTime: dueTime, action: action) } /** @@ -82,7 +81,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 { - return _mainScheduler.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) + public func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { + self.mainScheduler.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) } } diff --git a/iOS/RxSwift/Schedulers/CurrentThreadScheduler.swift b/iOS/RxSwift/Schedulers/CurrentThreadScheduler.swift index 0676444d..16a7dd32 100644 --- a/iOS/RxSwift/Schedulers/CurrentThreadScheduler.swift +++ b/iOS/RxSwift/Schedulers/CurrentThreadScheduler.swift @@ -6,22 +6,15 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import class Foundation.NSObject -import protocol Foundation.NSCopying -import class Foundation.Thread import Dispatch +import Foundation #if os(Linux) - import struct Foundation.pthread_key_t - import func Foundation.pthread_setspecific - import func Foundation.pthread_getspecific - import func Foundation.pthread_key_create - fileprivate enum CurrentThreadSchedulerQueueKey { fileprivate static let instance = "RxSwift.CurrentThreadScheduler.Queue" } #else - fileprivate class CurrentThreadSchedulerQueueKey: NSObject, NSCopying { + private class CurrentThreadSchedulerQueueKey: NSObject, NSCopying { static let instance = CurrentThreadSchedulerQueueKey() private override init() { super.init() @@ -50,13 +43,7 @@ public class CurrentThreadScheduler : ImmediateSchedulerType { private static var isScheduleRequiredKey: pthread_key_t = { () -> pthread_key_t in let key = UnsafeMutablePointer.allocate(capacity: 1) - defer { -#if swift(>=4.1) - key.deallocate() -#else - key.deallocate(capacity: 1) -#endif - } + defer { key.deallocate() } guard pthread_key_create(key, nil) == 0 else { rxFatalError("isScheduleRequired key creation failed") @@ -79,7 +66,7 @@ public class CurrentThreadScheduler : ImmediateSchedulerType { } /// Gets a value that indicates whether the caller must call a `schedule` method. - public static fileprivate(set) var isScheduleRequired: Bool { + public static private(set) var isScheduleRequired: Bool { get { return pthread_getspecific(CurrentThreadScheduler.isScheduleRequiredKey) == nil } diff --git a/iOS/RxSwift/Schedulers/HistoricalScheduler.swift b/iOS/RxSwift/Schedulers/HistoricalScheduler.swift index 11af238a..254a3e83 100644 --- a/iOS/RxSwift/Schedulers/HistoricalScheduler.swift +++ b/iOS/RxSwift/Schedulers/HistoricalScheduler.swift @@ -6,9 +6,9 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import struct Foundation.Date +import Foundation -/// Provides a virtual time scheduler that uses `Date` for absolute time and `NSTimeInterval` for relative time. +/// Provides a virtual time scheduler that uses `Date` for absolute time and `TimeInterval` for relative time. public class HistoricalScheduler : VirtualTimeScheduler { /** diff --git a/iOS/RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift b/iOS/RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift index 3602d2d0..a8fae8a4 100644 --- a/iOS/RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift +++ b/iOS/RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift @@ -6,9 +6,9 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import struct Foundation.Date +import Foundation -/// Converts historial virtual time into real time. +/// Converts historical virtual time into real time. /// /// Since historical virtual time is also measured in `Date`, this converter is identity function. public struct HistoricalSchedulerTimeConverter : VirtualTimeConverterType { @@ -16,30 +16,30 @@ 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. public func convertFromVirtualTime(_ virtualTime: VirtualTimeUnit) -> RxTime { - return virtualTime + virtualTime } /// Returns identical value of argument passed because historical virtual time is equal to real time, just /// decoupled from local machine clock. public func convertToVirtualTime(_ time: RxTime) -> VirtualTimeUnit { - return time + time } /// 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 { - return virtualTimeInterval + public func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> TimeInterval { + 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 { - return timeInterval + public func convertToVirtualTimeInterval(_ timeInterval: TimeInterval) -> VirtualTimeIntervalUnit { + timeInterval } /** @@ -50,7 +50,7 @@ public struct HistoricalSchedulerTimeConverter : VirtualTimeConverterType { - returns: Time offsetted by time interval. */ public func offsetVirtualTime(_ time: VirtualTimeUnit, offset: VirtualTimeIntervalUnit) -> VirtualTimeUnit { - return time.addingTimeInterval(offset) + time.addingTimeInterval(offset) } /// Compares two `Date`s. diff --git a/iOS/RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift b/iOS/RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift index b82f0113..53f148dc 100644 --- a/iOS/RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift +++ b/iOS/RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift @@ -7,25 +7,18 @@ // import Dispatch -import struct Foundation.TimeInterval +import Foundation struct DispatchQueueConfiguration { let queue: DispatchQueue 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() - queue.async { + self.queue.async { if cancel.isDisposed { return } @@ -37,21 +30,17 @@ 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() - let timer = DispatchSource.makeTimerSource(queue: queue) - #if swift(>=4.0) - timer.schedule(deadline: deadline, leeway: leeway) - #else - timer.scheduleOneshot(deadline: deadline, leeway: leeway) - #endif + let timer = DispatchSource.makeTimerSource(queue: self.queue) + timer.schedule(deadline: deadline, leeway: self.leeway) // TODO: // This looks horrible, and yes, it is. - // It looks like Apple has made a conceputal change here, and I'm unsure why. + // It looks like Apple has made a conceptual change here, and I'm unsure why. // Need more info on this. // It looks like just setting timer to fire and not holding a reference to it // until deadline causes timer cancellation. @@ -75,21 +64,17 @@ 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: queue) - #if swift(>=4.0) - timer.schedule(deadline: initial, repeating: dispatchInterval(period), leeway: leeway) - #else - timer.scheduleRepeating(deadline: initial, interval: dispatchInterval(period), leeway: leeway) - #endif + let timer = DispatchSource.makeTimerSource(queue: self.queue) + timer.schedule(deadline: initial, repeating: period, leeway: self.leeway) // TODO: // This looks horrible, and yes, it is. - // It looks like Apple has made a conceputal change here, and I'm unsure why. + // It looks like Apple has made a conceptual change here, and I'm unsure why. // Need more info on this. // It looks like just setting timer to fire and not holding a reference to it // until deadline causes timer cancellation. diff --git a/iOS/RxSwift/Schedulers/Internal/InvocableScheduledItem.swift b/iOS/RxSwift/Schedulers/Internal/InvocableScheduledItem.swift index 90445f8d..0e150561 100644 --- a/iOS/RxSwift/Schedulers/Internal/InvocableScheduledItem.swift +++ b/iOS/RxSwift/Schedulers/Internal/InvocableScheduledItem.swift @@ -8,15 +8,15 @@ struct InvocableScheduledItem : InvocableType { - let _invocable: I - let _state: I.Value + let invocable: I + let state: I.Value init(invocable: I, state: I.Value) { - _invocable = invocable - _state = state + self.invocable = invocable + self.state = state } func invoke() { - _invocable.invoke(_state) + self.invocable.invoke(self.state) } } diff --git a/iOS/RxSwift/Schedulers/Internal/ScheduledItem.swift b/iOS/RxSwift/Schedulers/Internal/ScheduledItem.swift index 454fb34b..3d790d7a 100644 --- a/iOS/RxSwift/Schedulers/Internal/ScheduledItem.swift +++ b/iOS/RxSwift/Schedulers/Internal/ScheduledItem.swift @@ -11,25 +11,25 @@ struct ScheduledItem , InvocableType { typealias Action = (T) -> Disposable - private let _action: Action - private let _state: T + private let action: Action + private let state: T - private let _disposable = SingleAssignmentDisposable() + private let disposable = SingleAssignmentDisposable() var isDisposed: Bool { - return _disposable.isDisposed + self.disposable.isDisposed } init(action: @escaping Action, state: T) { - _action = action - _state = state + self.action = action + self.state = state } func invoke() { - _disposable.setDisposable(_action(_state)) + self.disposable.setDisposable(self.action(self.state)) } func dispose() { - _disposable.dispose() + self.disposable.dispose() } } diff --git a/iOS/RxSwift/Schedulers/MainScheduler.swift b/iOS/RxSwift/Schedulers/MainScheduler.swift index e219e4ec..f6a507f3 100644 --- a/iOS/RxSwift/Schedulers/MainScheduler.swift +++ b/iOS/RxSwift/Schedulers/MainScheduler.swift @@ -7,6 +7,9 @@ // import Dispatch +#if !os(Linux) + import Foundation +#endif /** Abstracts work that needs to be performed on `DispatchQueue.main`. In case `schedule` methods are called from `DispatchQueue.main`, it will perform action immediately without scheduling. @@ -20,14 +23,14 @@ operator please use `ConcurrentMainScheduler` because it is more optimized for t */ public final class MainScheduler : SerialDispatchQueueScheduler { - private let _mainQueue: DispatchQueue + private let mainQueue: DispatchQueue - var numberEnqueued: AtomicInt = 0 + let numberEnqueued = AtomicInt(0) /// Initializes new instance of `MainScheduler`. public init() { - _mainQueue = DispatchQueue.main - super.init(serialQueue: _mainQueue) + self.mainQueue = DispatchQueue.main + super.init(serialQueue: self.mainQueue) } /// Singleton instance of `MainScheduler` @@ -38,29 +41,38 @@ public final class MainScheduler : SerialDispatchQueueScheduler { public static let asyncInstance = SerialDispatchQueueScheduler(serialQueue: DispatchQueue.main) /// In case this method is called on a background thread it will throw an exception. - public class func ensureExecutingOnScheduler(errorMessage: String? = nil) { + public static func ensureExecutingOnScheduler(errorMessage: String? = nil) { if !DispatchQueue.isMain { rxFatalError(errorMessage ?? "Executing on background thread. Please use `MainScheduler.instance.schedule` to schedule work on main thread.") } } + /// In case this method is running on a background thread it will throw an exception. + public static func ensureRunningOnMainThread(errorMessage: String? = nil) { + #if !os(Linux) // isMainThread is not implemented in Linux Foundation + guard Thread.isMainThread else { + rxFatalError(errorMessage ?? "Running on background thread.") + } + #endif + } + override func scheduleInternal(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - let currentNumberEnqueued = AtomicIncrement(&numberEnqueued) + let previousNumberEnqueued = increment(self.numberEnqueued) - if DispatchQueue.isMain && currentNumberEnqueued == 1 { + if DispatchQueue.isMain && previousNumberEnqueued == 0 { let disposable = action(state) - _ = AtomicDecrement(&numberEnqueued) + decrement(self.numberEnqueued) return disposable } let cancel = SingleAssignmentDisposable() - _mainQueue.async { + self.mainQueue.async { if !cancel.isDisposed { - _ = action(state) + cancel.setDisposable(action(state)) } - _ = AtomicDecrement(&self.numberEnqueued) + decrement(self.numberEnqueued) } return cancel diff --git a/iOS/RxSwift/Schedulers/OperationQueueScheduler.swift b/iOS/RxSwift/Schedulers/OperationQueueScheduler.swift index 82d30fbc..f0ad3d3c 100644 --- a/iOS/RxSwift/Schedulers/OperationQueueScheduler.swift +++ b/iOS/RxSwift/Schedulers/OperationQueueScheduler.swift @@ -6,21 +6,23 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import class Foundation.OperationQueue -import class Foundation.BlockOperation import Dispatch +import Foundation /// Abstracts the work that needs to be performed on a specific `NSOperationQueue`. /// /// This scheduler is suitable for cases when there is some bigger chunk of work that needs to be performed in background and you want to fine tune concurrent processing using `maxConcurrentOperationCount`. public class OperationQueueScheduler: ImmediateSchedulerType { public let operationQueue: OperationQueue + public let queuePriority: Operation.QueuePriority /// Constructs new instance of `OperationQueueScheduler` that performs work on `operationQueue`. /// /// - parameter operationQueue: Operation queue targeted to perform work on. - public init(operationQueue: OperationQueue) { + /// - parameter queuePriority: Queue priority which will be assigned to new operations. + public init(operationQueue: OperationQueue, queuePriority: Operation.QueuePriority = .normal) { self.operationQueue = operationQueue + self.queuePriority = queuePriority } /** @@ -42,6 +44,8 @@ public class OperationQueueScheduler: ImmediateSchedulerType { cancel.setDisposable(action(state)) } + operation.queuePriority = self.queuePriority + self.operationQueue.addOperation(operation) return cancel diff --git a/iOS/RxSwift/Schedulers/RecursiveScheduler.swift b/iOS/RxSwift/Schedulers/RecursiveScheduler.swift index 24d19cc6..0ee78cd1 100644 --- a/iOS/RxSwift/Schedulers/RecursiveScheduler.swift +++ b/iOS/RxSwift/Schedulers/RecursiveScheduler.swift @@ -6,7 +6,7 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -fileprivate enum ScheduleState { +private enum ScheduleState { case initial case added(CompositeDisposable.DisposeKey) case done @@ -17,17 +17,17 @@ final class AnyRecursiveScheduler { typealias Action = (State, AnyRecursiveScheduler) -> Void - private let _lock = RecursiveLock() + private let lock = RecursiveLock() // state - private let _group = CompositeDisposable() + private let group = CompositeDisposable() - private var _scheduler: SchedulerType - private var _action: Action? + private var scheduler: SchedulerType + private var action: Action? init(scheduler: SchedulerType, action: @escaping Action) { - _action = action - _scheduler = scheduler + self.action = action + self.scheduler = scheduler } /** @@ -39,16 +39,16 @@ final class AnyRecursiveScheduler { func schedule(_ state: State, dueTime: RxTimeInterval) { var scheduleState: ScheduleState = .initial - let d = _scheduler.scheduleRelative(state, dueTime: dueTime) { (state) -> Disposable in + let d = self.scheduler.scheduleRelative(state, dueTime: dueTime) { state -> Disposable in // best effort - if self._group.isDisposed { + if self.group.isDisposed { return Disposables.create() } - let action = self._lock.calculateLocked { () -> Action? in + let action = self.lock.performLocked { () -> Action? in switch scheduleState { case let .added(removeKey): - self._group.remove(for: removeKey) + self.group.remove(for: removeKey) case .initial: break case .done: @@ -57,7 +57,7 @@ final class AnyRecursiveScheduler { scheduleState = .done - return self._action + return self.action } if let action = action { @@ -67,19 +67,17 @@ final class AnyRecursiveScheduler { return Disposables.create() } - _lock.performLocked { + self.lock.performLocked { switch scheduleState { case .added: rxFatalError("Invalid state") - break case .initial: - if let removeKey = _group.insert(d) { + if let removeKey = self.group.insert(d) { scheduleState = .added(removeKey) } else { scheduleState = .done } - break case .done: break } @@ -92,16 +90,16 @@ final class AnyRecursiveScheduler { func schedule(_ state: State) { var scheduleState: ScheduleState = .initial - let d = _scheduler.schedule(state) { (state) -> Disposable in + let d = self.scheduler.schedule(state) { state -> Disposable in // best effort - if self._group.isDisposed { + if self.group.isDisposed { return Disposables.create() } - let action = self._lock.calculateLocked { () -> Action? in + let action = self.lock.performLocked { () -> Action? in switch scheduleState { case let .added(removeKey): - self._group.remove(for: removeKey) + self.group.remove(for: removeKey) case .initial: break case .done: @@ -110,7 +108,7 @@ final class AnyRecursiveScheduler { scheduleState = .done - return self._action + return self.action } if let action = action { @@ -120,19 +118,17 @@ final class AnyRecursiveScheduler { return Disposables.create() } - _lock.performLocked { + self.lock.performLocked { switch scheduleState { case .added: rxFatalError("Invalid state") - break case .initial: - if let removeKey = _group.insert(d) { + if let removeKey = self.group.insert(d) { scheduleState = .added(removeKey) } else { scheduleState = .done } - break case .done: break } @@ -140,10 +136,10 @@ final class AnyRecursiveScheduler { } func dispose() { - _lock.performLocked { - _action = nil + self.lock.performLocked { + self.action = nil } - _group.dispose() + self.group.dispose() } } @@ -151,15 +147,15 @@ final class AnyRecursiveScheduler { final class RecursiveImmediateScheduler { typealias Action = (_ state: State, _ recurse: (State) -> Void) -> Void - private var _lock = SpinLock() - private let _group = CompositeDisposable() + private var lock = SpinLock() + private let group = CompositeDisposable() - private var _action: Action? - private let _scheduler: ImmediateSchedulerType + private var action: Action? + private let scheduler: ImmediateSchedulerType init(action: @escaping Action, scheduler: ImmediateSchedulerType) { - _action = action - _scheduler = scheduler + self.action = action + self.scheduler = scheduler } // immediate scheduling @@ -170,16 +166,16 @@ final class RecursiveImmediateScheduler { func schedule(_ state: State) { var scheduleState: ScheduleState = .initial - let d = _scheduler.schedule(state) { (state) -> Disposable in + let d = self.scheduler.schedule(state) { state -> Disposable in // best effort - if self._group.isDisposed { + if self.group.isDisposed { return Disposables.create() } - let action = self._lock.calculateLocked { () -> Action? in + let action = self.lock.performLocked { () -> Action? in switch scheduleState { case let .added(removeKey): - self._group.remove(for: removeKey) + self.group.remove(for: removeKey) case .initial: break case .done: @@ -188,7 +184,7 @@ final class RecursiveImmediateScheduler { scheduleState = .done - return self._action + return self.action } if let action = action { @@ -198,19 +194,17 @@ final class RecursiveImmediateScheduler { return Disposables.create() } - _lock.performLocked { + self.lock.performLocked { switch scheduleState { case .added: rxFatalError("Invalid state") - break case .initial: - if let removeKey = _group.insert(d) { + if let removeKey = self.group.insert(d) { scheduleState = .added(removeKey) } else { scheduleState = .done } - break case .done: break } @@ -218,9 +212,9 @@ final class RecursiveImmediateScheduler { } func dispose() { - _lock.performLocked { - _action = nil + self.lock.performLocked { + self.action = nil } - _group.dispose() + self.group.dispose() } } diff --git a/iOS/RxSwift/Schedulers/SchedulerServices+Emulation.swift b/iOS/RxSwift/Schedulers/SchedulerServices+Emulation.swift index 41f2947a..cab2bc8b 100644 --- a/iOS/RxSwift/Schedulers/SchedulerServices+Emulation.swift +++ b/iOS/RxSwift/Schedulers/SchedulerServices+Emulation.swift @@ -15,44 +15,44 @@ final class SchedulePeriodicRecursive { typealias RecursiveAction = (State) -> State typealias RecursiveScheduler = AnyRecursiveScheduler - private let _scheduler: SchedulerType - private let _startAfter: RxTimeInterval - private let _period: RxTimeInterval - private let _action: RecursiveAction + private let scheduler: SchedulerType + private let startAfter: RxTimeInterval + private let period: RxTimeInterval + private let action: RecursiveAction - private var _state: State - private var _pendingTickCount: AtomicInt = 0 + private var state: State + private let pendingTickCount = AtomicInt(0) init(scheduler: SchedulerType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping RecursiveAction, state: State) { - _scheduler = scheduler - _startAfter = startAfter - _period = period - _action = action - _state = state + self.scheduler = scheduler + self.startAfter = startAfter + self.period = period + self.action = action + self.state = state } func start() -> Disposable { - return _scheduler.scheduleRecursive(SchedulePeriodicRecursiveCommand.tick, dueTime: _startAfter, action: self.tick) + self.scheduler.scheduleRecursive(SchedulePeriodicRecursiveCommand.tick, dueTime: self.startAfter, action: self.tick) } - func tick(_ command: SchedulePeriodicRecursiveCommand, scheduler: RecursiveScheduler) -> Void { + func tick(_ command: SchedulePeriodicRecursiveCommand, scheduler: RecursiveScheduler) { // Tries to emulate periodic scheduling as best as possible. // The problem that could arise is if handling periodic ticks take too long, or // tick interval is short. switch command { case .tick: - scheduler.schedule(.tick, dueTime: _period) + scheduler.schedule(.tick, dueTime: self.period) // The idea is that if on tick there wasn't any item enqueued, schedule to perform work immediately. // Else work will be scheduled after previous enqueued work completes. - if AtomicIncrement(&_pendingTickCount) == 1 { + if increment(self.pendingTickCount) == 0 { self.tick(.dispatchStart, scheduler: scheduler) } case .dispatchStart: - _state = _action(_state) + self.state = self.action(self.state) // Start work and schedule check is this last batch of work - if AtomicDecrement(&_pendingTickCount) > 0 { + if decrement(self.pendingTickCount) > 1 { // This gives priority to scheduler emulation, it's not perfect, but helps scheduler.schedule(SchedulePeriodicRecursiveCommand.dispatchStart) } diff --git a/iOS/RxSwift/Schedulers/SerialDispatchQueueScheduler.swift b/iOS/RxSwift/Schedulers/SerialDispatchQueueScheduler.swift index 71733d39..bb0013c8 100644 --- a/iOS/RxSwift/Schedulers/SerialDispatchQueueScheduler.swift +++ b/iOS/RxSwift/Schedulers/SerialDispatchQueueScheduler.swift @@ -6,9 +6,8 @@ // Copyright © 2015 Krunoslav Zaher. All rights reserved. // -import struct Foundation.TimeInterval -import struct Foundation.Date import Dispatch +import Foundation /** Abstracts the work that needs to be performed on a specific `dispatch_queue_t`. It will make sure @@ -33,13 +32,19 @@ public class SerialDispatchQueueScheduler : SchedulerType { /// - returns: Current time. public var now : Date { - return Date() + Date() } let configuration: DispatchQueueConfiguration + /** + Constructs new `SerialDispatchQueueScheduler` that wraps `serialQueue`. + + - parameter serialQueue: Target dispatch queue. + - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. + */ init(serialQueue: DispatchQueue, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { - configuration = DispatchQueueConfiguration(queue: serialQueue, leeway: leeway) + self.configuration = DispatchQueueConfiguration(queue: serialQueue, leeway: leeway) } /** @@ -49,6 +54,7 @@ public class SerialDispatchQueueScheduler : SchedulerType { - parameter internalSerialQueueName: Name of internal serial dispatch queue. - parameter serialQueueConfiguration: Additional configuration of internal serial dispatch queue. + - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. */ public convenience init(internalSerialQueueName: String, serialQueueConfiguration: ((DispatchQueue) -> Void)? = nil, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { let queue = DispatchQueue(label: internalSerialQueueName, attributes: []) @@ -61,6 +67,7 @@ public class SerialDispatchQueueScheduler : SchedulerType { - parameter queue: Possibly concurrent dispatch queue used to perform work. - parameter internalSerialQueueName: Name of internal serial dispatch queue proxy. + - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. */ public convenience init(queue: DispatchQueue, internalSerialQueueName: String, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { // Swift 3.0 IUO @@ -71,12 +78,13 @@ public class SerialDispatchQueueScheduler : SchedulerType { } /** - Constructs new `SerialDispatchQueueScheduler` that wraps on of the global concurrent dispatch queues. + Constructs new `SerialDispatchQueueScheduler` that wraps one of the global concurrent dispatch queues. - parameter qos: Identifier for global dispatch queue with specified quality of service class. - parameter internalSerialQueueName: Custom name for internal serial dispatch queue proxy. + - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. */ - @available(iOS 8, OSX 10.10, *) + @available(macOS 10.10, *) public convenience init(qos: DispatchQoS, internalSerialQueueName: String = "rx.global_dispatch_queue.serial", leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { self.init(queue: DispatchQueue.global(qos: qos.qosClass), internalSerialQueueName: internalSerialQueueName, leeway: leeway) } @@ -89,11 +97,11 @@ public class SerialDispatchQueueScheduler : SchedulerType { - returns: The disposable object used to cancel the scheduled action (best effort). */ public final func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - return self.scheduleInternal(state, action: action) + self.scheduleInternal(state, action: action) } func scheduleInternal(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - return self.configuration.schedule(state, action: action) + self.configuration.schedule(state, action: action) } /** @@ -104,8 +112,8 @@ 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 { - return self.configuration.scheduleRelative(state, dueTime: dueTime, action: action) + public final func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { + self.configuration.scheduleRelative(state, dueTime: dueTime, action: action) } /** @@ -117,7 +125,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 { - return self.configuration.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) + public func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { + self.configuration.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) } } diff --git a/iOS/RxSwift/Schedulers/VirtualTimeConverterType.swift b/iOS/RxSwift/Schedulers/VirtualTimeConverterType.swift index b207836e..9592d6e3 100644 --- a/iOS/RxSwift/Schedulers/VirtualTimeConverterType.swift +++ b/iOS/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. @@ -31,20 +33,20 @@ public protocol VirtualTimeConverterType { func convertToVirtualTime(_ time: RxTime) -> VirtualTimeUnit /** - Converts from virtual time interval to `NSTimeInterval`. + Converts from virtual time interval to `TimeInterval`. - - parameter virtualTimeInterval: Virtual time interval to convert to `NSTimeInterval`. - - returns: `NSTimeInterval` corresponding to virtual time interval. + - parameter virtualTimeInterval: Virtual time interval to convert to `TimeInterval`. + - returns: `TimeInterval` corresponding to virtual time interval. */ - func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> RxTimeInterval + func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> TimeInterval /** - Converts from virtual time interval to `NSTimeInterval`. + Converts from `TimeInterval` to virtual time interval. - - parameter timeInterval: `NSTimeInterval` to convert to virtual time interval. + - parameter timeInterval: `TimeInterval` 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. @@ -56,7 +58,7 @@ public protocol VirtualTimeConverterType { func offsetVirtualTime(_ time: VirtualTimeUnit, offset: VirtualTimeIntervalUnit) -> VirtualTimeUnit /** - This is aditional abstraction because `Date` is unfortunately not comparable. + This is additional abstraction because `Date` is unfortunately not comparable. Extending `Date` with `Comparable` would be too risky because of possible collisions with other libraries. */ func compareVirtualTime(_ lhs: VirtualTimeUnit, _ rhs: VirtualTimeUnit) -> VirtualTimeComparison @@ -65,7 +67,7 @@ public protocol VirtualTimeConverterType { /** Virtual time comparison result. - This is aditional abstraction because `Date` is unfortunately not comparable. + This is additional abstraction because `Date` is unfortunately not comparable. Extending `Date` with `Comparable` would be too risky because of possible collisions with other libraries. */ public enum VirtualTimeComparison { @@ -80,16 +82,16 @@ public enum VirtualTimeComparison { extension VirtualTimeComparison { /// lhs < rhs. var lessThen: Bool { - return self == .lessThan + self == .lessThan } /// lhs > rhs var greaterThan: Bool { - return self == .greaterThan + self == .greaterThan } /// lhs == rhs var equal: Bool { - return self == .equal + self == .equal } } diff --git a/iOS/RxSwift/Schedulers/VirtualTimeScheduler.swift b/iOS/RxSwift/Schedulers/VirtualTimeScheduler.swift index c0e1aa56..e74d5be6 100644 --- a/iOS/RxSwift/Schedulers/VirtualTimeScheduler.swift +++ b/iOS/RxSwift/Schedulers/VirtualTimeScheduler.swift @@ -13,33 +13,33 @@ open class VirtualTimeScheduler public typealias VirtualTime = Converter.VirtualTimeUnit public typealias VirtualTimeInterval = Converter.VirtualTimeIntervalUnit - private var _running : Bool + private var running : Bool - private var _clock: VirtualTime + private var currentClock: VirtualTime - fileprivate var _schedulerQueue : PriorityQueue> - private var _converter: Converter + private var schedulerQueue : PriorityQueue> + private var converter: Converter - private var _nextId = 0 + private var nextId = 0 /// - returns: Current time. public var now: RxTime { - return _converter.convertFromVirtualTime(clock) + self.converter.convertFromVirtualTime(self.clock) } /// - returns: Scheduler's absolute time clock value. public var clock: VirtualTime { - return _clock + self.currentClock } /// Creates a new virtual time scheduler. /// /// - parameter initialClock: Initial value for the clock. public init(initialClock: VirtualTime, converter: Converter) { - _clock = initialClock - _running = false - _converter = converter - _schedulerQueue = PriorityQueue(hasHigherPriority: { + self.currentClock = initialClock + self.running = false + self.converter = converter + self.schedulerQueue = PriorityQueue(hasHigherPriority: { switch converter.compareVirtualTime($0.time, $1.time) { case .lessThan: return true @@ -50,7 +50,7 @@ open class VirtualTimeScheduler } }, isEqual: { $0 === $1 }) #if TRACE_RESOURCES - let _ = Resources.incrementTotal() + _ = Resources.incrementTotal() #endif } @@ -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,10 +76,10 @@ 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 absoluteTime = _converter.convertToVirtualTime(time) + let time = self.now.addingDispatchInterval(dueTime) + let absoluteTime = self.converter.convertToVirtualTime(time) let adjustedTime = self.adjustScheduledTime(absoluteTime) - return scheduleAbsoluteVirtual(state, time: adjustedTime, action: action) + return self.scheduleAbsoluteVirtual(state, time: adjustedTime, action: action) } /** @@ -91,8 +91,8 @@ open class VirtualTimeScheduler - returns: The disposable object used to cancel the scheduled action (best effort). */ public func scheduleRelativeVirtual(_ state: StateType, dueTime: VirtualTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { - let time = _converter.offsetVirtualTime(self.clock, offset: dueTime) - return scheduleAbsoluteVirtual(state, time: time, action: action) + let time = self.converter.offsetVirtualTime(self.clock, offset: dueTime) + return self.scheduleAbsoluteVirtual(state, time: time, action: action) } /** @@ -103,19 +103,18 @@ open class VirtualTimeScheduler - parameter action: Action to be executed. - returns: The disposable object used to cancel the scheduled action (best effort). */ - public func scheduleAbsoluteVirtual(_ state: StateType, time: Converter.VirtualTimeUnit, action: @escaping (StateType) -> Disposable) -> Disposable { + public func scheduleAbsoluteVirtual(_ state: StateType, time: VirtualTime, action: @escaping (StateType) -> Disposable) -> Disposable { MainScheduler.ensureExecutingOnScheduler() let compositeDisposable = CompositeDisposable() let item = VirtualSchedulerItem(action: { - let dispose = action(state) - return dispose - }, time: time, id: _nextId) + return action(state) + }, time: time, id: self.nextId) - _nextId += 1 + self.nextId += 1 - _schedulerQueue.enqueue(item) + self.schedulerQueue.enqueue(item) _ = compositeDisposable.insert(item) @@ -123,39 +122,39 @@ open class VirtualTimeScheduler } /// Adjusts time of scheduling before adding item to schedule queue. - open func adjustScheduledTime(_ time: Converter.VirtualTimeUnit) -> Converter.VirtualTimeUnit { - return time + open func adjustScheduledTime(_ time: VirtualTime) -> VirtualTime { + time } /// Starts the virtual time scheduler. public func start() { MainScheduler.ensureExecutingOnScheduler() - if _running { + if self.running { return } - _running = true + self.running = true repeat { - guard let next = findNext() else { + guard let next = self.findNext() else { break } - if _converter.compareVirtualTime(next.time, self.clock).greaterThan { - _clock = next.time + if self.converter.compareVirtualTime(next.time, self.clock).greaterThan { + self.currentClock = next.time } next.invoke() - _schedulerQueue.remove(next) - } while _running + self.schedulerQueue.remove(next) + } while self.running - _running = false + self.running = false } func findNext() -> VirtualSchedulerItem? { - while let front = _schedulerQueue.peek() { + while let front = self.schedulerQueue.peek() { if front.isDisposed { - _schedulerQueue.remove(front) + self.schedulerQueue.remove(front) continue } @@ -171,49 +170,48 @@ open class VirtualTimeScheduler public func advanceTo(_ virtualTime: VirtualTime) { MainScheduler.ensureExecutingOnScheduler() - if _running { + if self.running { fatalError("Scheduler is already running") } - _running = true + self.running = true repeat { - guard let next = findNext() else { + guard let next = self.findNext() else { break } - if _converter.compareVirtualTime(next.time, virtualTime).greaterThan { + if self.converter.compareVirtualTime(next.time, virtualTime).greaterThan { break } - if _converter.compareVirtualTime(next.time, self.clock).greaterThan { - _clock = next.time + if self.converter.compareVirtualTime(next.time, self.clock).greaterThan { + self.currentClock = next.time } - next.invoke() - _schedulerQueue.remove(next) - } while _running + self.schedulerQueue.remove(next) + } while self.running - _clock = virtualTime - _running = false + self.currentClock = virtualTime + self.running = false } /// Advances the scheduler's clock by the specified relative time. public func sleep(_ virtualInterval: VirtualTimeInterval) { MainScheduler.ensureExecutingOnScheduler() - let sleepTo = _converter.offsetVirtualTime(clock, offset: virtualInterval) - if _converter.compareVirtualTime(sleepTo, clock).lessThen { + let sleepTo = self.converter.offsetVirtualTime(self.clock, offset: virtualInterval) + if self.converter.compareVirtualTime(sleepTo, self.clock).lessThen { fatalError("Can't sleep to past.") } - _clock = sleepTo + self.currentClock = sleepTo } /// Stops the virtual time scheduler. public func stop() { MainScheduler.ensureExecutingOnScheduler() - _running = false + self.running = false } #if TRACE_RESOURCES @@ -228,7 +226,7 @@ open class VirtualTimeScheduler extension VirtualTimeScheduler: CustomDebugStringConvertible { /// A textual representation of `self`, suitable for debugging. public var debugDescription: String { - return self._schedulerQueue.debugDescription + self.schedulerQueue.debugDescription } } @@ -241,7 +239,7 @@ final class VirtualSchedulerItem