Merge pull request #213 from ReactiveX/feature/performance-optimizations

Innovating to zero
This commit is contained in:
Krunoslav Zaher 2015-11-02 01:03:20 +01:00
commit 28efa9d827
103 changed files with 2429 additions and 1874 deletions

View File

@ -298,6 +298,30 @@
C84CC5411BDC3B3E00E06A64 /* ElementAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC53F1BDC3B3700E06A64 /* ElementAt.swift */; };
C84CC5421BDC3B3E00E06A64 /* ElementAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC53F1BDC3B3700E06A64 /* ElementAt.swift */; };
C84CC5431BDC3B3E00E06A64 /* ElementAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC53F1BDC3B3700E06A64 /* ElementAt.swift */; };
C84CC54E1BDCF48200E06A64 /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC54D1BDCF48200E06A64 /* LockOwnerType.swift */; };
C84CC54F1BDCF48200E06A64 /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC54D1BDCF48200E06A64 /* LockOwnerType.swift */; };
C84CC5501BDCF48200E06A64 /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC54D1BDCF48200E06A64 /* LockOwnerType.swift */; };
C84CC5511BDCF48200E06A64 /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC54D1BDCF48200E06A64 /* LockOwnerType.swift */; };
C84CC5531BDCF49300E06A64 /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5521BDCF49300E06A64 /* SynchronizedOnType.swift */; };
C84CC5541BDCF49300E06A64 /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5521BDCF49300E06A64 /* SynchronizedOnType.swift */; };
C84CC5551BDCF49300E06A64 /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5521BDCF49300E06A64 /* SynchronizedOnType.swift */; };
C84CC5561BDCF49300E06A64 /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5521BDCF49300E06A64 /* SynchronizedOnType.swift */; };
C84CC5581BDCF51200E06A64 /* SynchronizedSubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5571BDCF51200E06A64 /* SynchronizedSubscribeType.swift */; };
C84CC5591BDCF51200E06A64 /* SynchronizedSubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5571BDCF51200E06A64 /* SynchronizedSubscribeType.swift */; };
C84CC55A1BDCF51200E06A64 /* SynchronizedSubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5571BDCF51200E06A64 /* SynchronizedSubscribeType.swift */; };
C84CC55B1BDCF51200E06A64 /* SynchronizedSubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5571BDCF51200E06A64 /* SynchronizedSubscribeType.swift */; };
C84CC55D1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC55C1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift */; };
C84CC55E1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC55C1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift */; };
C84CC55F1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC55C1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift */; };
C84CC5601BDD010800E06A64 /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC55C1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift */; };
C84CC5621BDD037900E06A64 /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5611BDD037900E06A64 /* SynchronizedDisposeType.swift */; };
C84CC5631BDD037900E06A64 /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5611BDD037900E06A64 /* SynchronizedDisposeType.swift */; };
C84CC5641BDD037900E06A64 /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5611BDD037900E06A64 /* SynchronizedDisposeType.swift */; };
C84CC5651BDD037900E06A64 /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5611BDD037900E06A64 /* SynchronizedDisposeType.swift */; };
C84CC5671BDD08A500E06A64 /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5661BDD08A500E06A64 /* SubscriptionDisposable.swift */; };
C84CC5681BDD08A500E06A64 /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5661BDD08A500E06A64 /* SubscriptionDisposable.swift */; };
C84CC5691BDD08A500E06A64 /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5661BDD08A500E06A64 /* SubscriptionDisposable.swift */; };
C84CC56A1BDD08A500E06A64 /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5661BDD08A500E06A64 /* SubscriptionDisposable.swift */; };
C86409FC1BA593F500D3C4E8 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86409FB1BA593F500D3C4E8 /* Range.swift */; };
C86409FD1BA593F500D3C4E8 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86409FB1BA593F500D3C4E8 /* Range.swift */; };
C8640A031BA5B12A00D3C4E8 /* Repeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8640A021BA5B12A00D3C4E8 /* Repeat.swift */; };
@ -936,6 +960,12 @@
C84B38E71BA43380001B7D88 /* ScheduledItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduledItem.swift; sourceTree = "<group>"; };
C84B38ED1BA433CD001B7D88 /* Generate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Generate.swift; sourceTree = "<group>"; };
C84CC53F1BDC3B3700E06A64 /* ElementAt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElementAt.swift; sourceTree = "<group>"; };
C84CC54D1BDCF48200E06A64 /* LockOwnerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockOwnerType.swift; sourceTree = "<group>"; };
C84CC5521BDCF49300E06A64 /* SynchronizedOnType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedOnType.swift; sourceTree = "<group>"; };
C84CC5571BDCF51200E06A64 /* SynchronizedSubscribeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedSubscribeType.swift; sourceTree = "<group>"; };
C84CC55C1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedUnsubscribeType.swift; sourceTree = "<group>"; };
C84CC5611BDD037900E06A64 /* SynchronizedDisposeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedDisposeType.swift; sourceTree = "<group>"; };
C84CC5661BDD08A500E06A64 /* SubscriptionDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscriptionDisposable.swift; sourceTree = "<group>"; };
C86409FB1BA593F500D3C4E8 /* Range.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Range.swift; sourceTree = "<group>"; };
C8640A021BA5B12A00D3C4E8 /* Repeat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Repeat.swift; sourceTree = "<group>"; };
C88253F11B8A752B00B02D69 /* RxCollectionViewReactiveArrayDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewReactiveArrayDataSource.swift; sourceTree = "<group>"; };
@ -1122,6 +1152,11 @@
children = (
C8093C4B1B8A72BE0088E94D /* AsyncLock.swift */,
C8093C4C1B8A72BE0088E94D /* Lock.swift */,
C84CC54D1BDCF48200E06A64 /* LockOwnerType.swift */,
C84CC5521BDCF49300E06A64 /* SynchronizedOnType.swift */,
C84CC5571BDCF51200E06A64 /* SynchronizedSubscribeType.swift */,
C84CC55C1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift */,
C84CC5611BDD037900E06A64 /* SynchronizedDisposeType.swift */,
);
path = Concurrency;
sourceTree = "<group>";
@ -1144,6 +1179,7 @@
C8093C571B8A72BE0088E94D /* CompositeDisposable.swift */,
C8093C581B8A72BE0088E94D /* DisposeBag.swift */,
C8093C591B8A72BE0088E94D /* DisposeBase.swift */,
C84CC5661BDD08A500E06A64 /* SubscriptionDisposable.swift */,
C8093C5A1B8A72BE0088E94D /* NAryDisposable.swift */,
C8093C5B1B8A72BE0088E94D /* NAryDisposable.tt */,
C8093C5C1B8A72BE0088E94D /* NopDisposable.swift */,
@ -2150,7 +2186,9 @@
C89CDB371BCB0DD7002063D9 /* ShareReplay1.swift in Sources */,
C8093D2A1B8A72BE0088E94D /* ObserveOn.swift in Sources */,
C8093D361B8A72BE0088E94D /* Sample.swift in Sources */,
C84CC54F1BDCF48200E06A64 /* LockOwnerType.swift in Sources */,
D2752D621BC5551A0070C418 /* SkipUntil.swift in Sources */,
C84CC5541BDCF49300E06A64 /* SynchronizedOnType.swift in Sources */,
C8093CEA1B8A72BE0088E94D /* ScopedDisposable.swift in Sources */,
C8093D261B8A72BE0088E94D /* Multicast.swift in Sources */,
C8C3DA101B939767004D233E /* CurrentThreadScheduler.swift in Sources */,
@ -2165,6 +2203,7 @@
C8093D241B8A72BE0088E94D /* Merge.swift in Sources */,
C8093D8E1B8A72BE0088E94D /* SchedulerType.swift in Sources */,
C8093DA81B8A72BE0088E94D /* Variable.swift in Sources */,
C84CC5631BDD037900E06A64 /* SynchronizedDisposeType.swift in Sources */,
C8093D961B8A72BE0088E94D /* OperationQueueScheduler.swift in Sources */,
C8093D921B8A72BE0088E94D /* DispatchQueueSchedulerPriority.swift in Sources */,
C8093D081B8A72BE0088E94D /* CombineLatest+arity.swift in Sources */,
@ -2197,6 +2236,7 @@
C8093D0E1B8A72BE0088E94D /* Concat.swift in Sources */,
C8093CCA1B8A72BE0088E94D /* Lock.swift in Sources */,
C8093D441B8A72BE0088E94D /* Take.swift in Sources */,
C84CC5591BDCF51200E06A64 /* SynchronizedSubscribeType.swift in Sources */,
C8093D321B8A72BE0088E94D /* Reduce.swift in Sources */,
C84B38EA1BA43380001B7D88 /* ScheduledItem.swift in Sources */,
C8640A041BA5B12A00D3C4E8 /* Repeat.swift in Sources */,
@ -2214,10 +2254,12 @@
C8093D401B8A72BE0088E94D /* SubscribeOn.swift in Sources */,
CBEE77201BD649A000AD584C /* ToArray.swift in Sources */,
C8093CFE1B8A72BE0088E94D /* Observable.swift in Sources */,
C84CC55E1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift in Sources */,
C8093CE21B8A72BE0088E94D /* NAryDisposable.swift in Sources */,
C8093CEC1B8A72BE0088E94D /* SerialDisposable.swift in Sources */,
C8C3DA0D1B93959F004D233E /* Never.swift in Sources */,
C8093D7C1B8A72BE0088E94D /* ObserverType+Extensions.swift in Sources */,
C84CC5681BDD08A500E06A64 /* SubscriptionDisposable.swift in Sources */,
C8093CF61B8A72BE0088E94D /* Event.swift in Sources */,
C8093D521B8A72BE0088E94D /* Zip.swift in Sources */,
);
@ -2272,7 +2314,9 @@
C89CDB361BCB0DD7002063D9 /* ShareReplay1.swift in Sources */,
C8093D291B8A72BE0088E94D /* ObserveOn.swift in Sources */,
C8093D351B8A72BE0088E94D /* Sample.swift in Sources */,
C84CC54E1BDCF48200E06A64 /* LockOwnerType.swift in Sources */,
D285BAC41BC0231000B3F602 /* SkipUntil.swift in Sources */,
C84CC5531BDCF49300E06A64 /* SynchronizedOnType.swift in Sources */,
C8093CE91B8A72BE0088E94D /* ScopedDisposable.swift in Sources */,
C8093D251B8A72BE0088E94D /* Multicast.swift in Sources */,
C8C3DA0F1B939767004D233E /* CurrentThreadScheduler.swift in Sources */,
@ -2287,6 +2331,7 @@
C8093D231B8A72BE0088E94D /* Merge.swift in Sources */,
C8093D8D1B8A72BE0088E94D /* SchedulerType.swift in Sources */,
C8093DA71B8A72BE0088E94D /* Variable.swift in Sources */,
C84CC5621BDD037900E06A64 /* SynchronizedDisposeType.swift in Sources */,
C8093D951B8A72BE0088E94D /* OperationQueueScheduler.swift in Sources */,
C8093D911B8A72BE0088E94D /* DispatchQueueSchedulerPriority.swift in Sources */,
C8093D071B8A72BE0088E94D /* CombineLatest+arity.swift in Sources */,
@ -2319,6 +2364,7 @@
C8093D0D1B8A72BE0088E94D /* Concat.swift in Sources */,
C8093CC91B8A72BE0088E94D /* Lock.swift in Sources */,
C8093D431B8A72BE0088E94D /* Take.swift in Sources */,
C84CC5581BDCF51200E06A64 /* SynchronizedSubscribeType.swift in Sources */,
C8093D311B8A72BE0088E94D /* Reduce.swift in Sources */,
C84B38E91BA43380001B7D88 /* ScheduledItem.swift in Sources */,
C8640A031BA5B12A00D3C4E8 /* Repeat.swift in Sources */,
@ -2336,10 +2382,12 @@
C8093D3F1B8A72BE0088E94D /* SubscribeOn.swift in Sources */,
CBEE771F1BD649A000AD584C /* ToArray.swift in Sources */,
C8093CFD1B8A72BE0088E94D /* Observable.swift in Sources */,
C84CC55D1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift in Sources */,
C8093CE11B8A72BE0088E94D /* NAryDisposable.swift in Sources */,
C8093CEB1B8A72BE0088E94D /* SerialDisposable.swift in Sources */,
C8C3DA0C1B93959F004D233E /* Never.swift in Sources */,
C8093D7B1B8A72BE0088E94D /* ObserverType+Extensions.swift in Sources */,
C84CC5671BDD08A500E06A64 /* SubscriptionDisposable.swift in Sources */,
C8093CF51B8A72BE0088E94D /* Event.swift in Sources */,
C8093D511B8A72BE0088E94D /* Zip.swift in Sources */,
);
@ -2394,7 +2442,9 @@
C89CDB391BCB0DD7002063D9 /* ShareReplay1.swift in Sources */,
C8F0BFB71BBBFB8B001B112F /* ObserveOn.swift in Sources */,
C8F0BFB81BBBFB8B001B112F /* Sample.swift in Sources */,
C84CC5511BDCF48200E06A64 /* LockOwnerType.swift in Sources */,
D21C29311BC6A1C300448E70 /* SkipUntil.swift in Sources */,
C84CC5561BDCF49300E06A64 /* SynchronizedOnType.swift in Sources */,
C8F0BFB91BBBFB8B001B112F /* ScopedDisposable.swift in Sources */,
C8F0BFBA1BBBFB8B001B112F /* Multicast.swift in Sources */,
C8F0BFBB1BBBFB8B001B112F /* CurrentThreadScheduler.swift in Sources */,
@ -2409,6 +2459,7 @@
C8F0BFC31BBBFB8B001B112F /* Merge.swift in Sources */,
C8F0BFC41BBBFB8B001B112F /* SchedulerType.swift in Sources */,
C8F0BFC51BBBFB8B001B112F /* Variable.swift in Sources */,
C84CC5651BDD037900E06A64 /* SynchronizedDisposeType.swift in Sources */,
C8F0BFC61BBBFB8B001B112F /* OperationQueueScheduler.swift in Sources */,
C8F0BFC71BBBFB8B001B112F /* DispatchQueueSchedulerPriority.swift in Sources */,
C8F0BFC81BBBFB8B001B112F /* CombineLatest+arity.swift in Sources */,
@ -2441,6 +2492,7 @@
C8F0BFE21BBBFB8B001B112F /* Concat.swift in Sources */,
C8F0BFE31BBBFB8B001B112F /* Lock.swift in Sources */,
C8F0BFE41BBBFB8B001B112F /* Take.swift in Sources */,
C84CC55B1BDCF51200E06A64 /* SynchronizedSubscribeType.swift in Sources */,
C8F0BFE51BBBFB8B001B112F /* Reduce.swift in Sources */,
C8F0BFE61BBBFB8B001B112F /* ScheduledItem.swift in Sources */,
C8F0BFE71BBBFB8B001B112F /* Repeat.swift in Sources */,
@ -2458,10 +2510,12 @@
C8F0BFF31BBBFB8B001B112F /* SubscribeOn.swift in Sources */,
CBEE77221BD649A000AD584C /* ToArray.swift in Sources */,
C8F0BFF41BBBFB8B001B112F /* Observable.swift in Sources */,
C84CC5601BDD010800E06A64 /* SynchronizedUnsubscribeType.swift in Sources */,
C8F0BFF51BBBFB8B001B112F /* NAryDisposable.swift in Sources */,
C8F0BFF61BBBFB8B001B112F /* SerialDisposable.swift in Sources */,
C8F0BFF71BBBFB8B001B112F /* Never.swift in Sources */,
C8F0BFF81BBBFB8B001B112F /* ObserverType+Extensions.swift in Sources */,
C84CC56A1BDD08A500E06A64 /* SubscriptionDisposable.swift in Sources */,
C8F0BFF91BBBFB8B001B112F /* Event.swift in Sources */,
C8F0BFFA1BBBFB8B001B112F /* Zip.swift in Sources */,
);
@ -2666,7 +2720,9 @@
D2EBEB2A1BB9B6C5003A27DC /* Zip+CollectionType.swift in Sources */,
C89CDB381BCB0DD7002063D9 /* ShareReplay1.swift in Sources */,
D2EBEB401BB9B6DE003A27DC /* BehaviorSubject.swift in Sources */,
C84CC5501BDCF48200E06A64 /* LockOwnerType.swift in Sources */,
D2EBEB271BB9B6C1003A27DC /* Timer.swift in Sources */,
C84CC5551BDCF49300E06A64 /* SynchronizedOnType.swift in Sources */,
D2752D631BC5551B0070C418 /* SkipUntil.swift in Sources */,
D2EBEB351BB9B6D2003A27DC /* ObserverBase.swift in Sources */,
D2EBEB0F1BB9B6C1003A27DC /* Generate.swift in Sources */,
@ -2681,6 +2737,7 @@
D2EBEAFB1BB9B6B2003A27DC /* StableCompositeDisposable.swift in Sources */,
D2EBEB011BB9B6BA003A27DC /* CombineLatest.swift in Sources */,
D2EBEB021BB9B6BA003A27DC /* CombineLatest+arity.swift in Sources */,
C84CC5641BDD037900E06A64 /* SynchronizedDisposeType.swift in Sources */,
D2EBEB211BB9B6C1003A27DC /* SubscribeOn.swift in Sources */,
D2EBEB251BB9B6C1003A27DC /* TakeWhile.swift in Sources */,
D2EBEB221BB9B6C1003A27DC /* Switch.swift in Sources */,
@ -2713,6 +2770,7 @@
D2EBEB2B1BB9B6CA003A27DC /* Observable+Aggregate.swift in Sources */,
D2EBEB291BB9B6C1003A27DC /* Zip+arity.swift in Sources */,
D2EBEB241BB9B6C1003A27DC /* TakeUntil.swift in Sources */,
C84CC55A1BDCF51200E06A64 /* SynchronizedSubscribeType.swift in Sources */,
D2EBEB3B1BB9B6D8003A27DC /* OperationQueueScheduler.swift in Sources */,
D2EBEAE51BB9B697003A27DC /* AnyObserver.swift in Sources */,
D2EBEB3D1BB9B6D8003A27DC /* SchedulerServices+Emulation.swift in Sources */,
@ -2730,10 +2788,12 @@
D2EBEAF41BB9B6AE003A27DC /* DisposeBase.swift in Sources */,
CBEE77211BD649A000AD584C /* ToArray.swift in Sources */,
D2EBEB3F1BB9B6D8003A27DC /* CurrentThreadScheduler.swift in Sources */,
C84CC55F1BDD010800E06A64 /* SynchronizedUnsubscribeType.swift in Sources */,
D2EBEAF21BB9B6AE003A27DC /* CompositeDisposable.swift in Sources */,
D2EBEB0E1BB9B6C1003A27DC /* FlatMap.swift in Sources */,
D2EBEB171BB9B6C1003A27DC /* Producer.swift in Sources */,
D2EBEAF91BB9B6B2003A27DC /* SerialDisposable.swift in Sources */,
C84CC5691BDD08A500E06A64 /* SubscriptionDisposable.swift in Sources */,
D2EBEB0A1BB9B6C1003A27DC /* Do.swift in Sources */,
D2EBEB2E1BB9B6CA003A27DC /* Observable+Creation.swift in Sources */,
);
@ -3036,6 +3096,7 @@
ENABLE_BITCODE = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = "TRACE_RESOURCES=1";
@ -3051,6 +3112,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_SWIFT_FLAGS = "-D TRACE_RESOURCES";
SDKROOT = "";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@ -3225,6 +3287,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.9;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = "";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";

View File

@ -11,8 +11,11 @@ import Foundation
import RxSwift
#endif
class KVOObservable<Element> : _Producer<Element?>
, KVOObservableProtocol {
class KVOObservable<Element>
: ObservableType
, KVOObservableProtocol {
typealias E = Element?
unowned var target: AnyObject
var strongTarget: AnyObject?
@ -30,7 +33,7 @@ class KVOObservable<Element> : _Producer<Element?>
}
}
override func run<O : ObserverType where O.E == Element?>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
func subscribe<O : ObserverType where O.E == Element?>(observer: O) -> Disposable {
let observer = KVOObserver(parent: self) { (value) in
if value as? NSNull != nil {
observer.on(.Next(nil))

View File

@ -59,7 +59,7 @@ extension NSObject {
- returns: Observable sequence of objects on `keyPath`.
*/
public func rx_observe<Element>(keyPath: String, options: NSKeyValueObservingOptions = [.New, .Initial], retainSelf: Bool = true) -> Observable<Element?> {
return KVOObservable(object: self, keyPath: keyPath, options: options, retainTarget: retainSelf)
return KVOObservable(object: self, keyPath: keyPath, options: options, retainTarget: retainSelf).asObservable()
}
}

View File

@ -113,6 +113,13 @@
C84B913C1B8A282000C9CCCF /* RxCollectionViewSectionedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C859B9A71B45C83700D012D7 /* RxCollectionViewSectionedDataSource.swift */; };
C84B913D1B8A282000C9CCCF /* RxCollectionViewSectionedAnimatedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C859B9A91B45CB0900D012D7 /* RxCollectionViewSectionedAnimatedDataSource.swift */; };
C84CC52E1BDC344100E06A64 /* ElementAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC52D1BDC344100E06A64 /* ElementAt.swift */; };
C84CC58B1BDD486300E06A64 /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC56B1BDD08F500E06A64 /* LockOwnerType.swift */; };
C84CC58C1BDD486300E06A64 /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC56C1BDD08F500E06A64 /* SynchronizedDisposeType.swift */; };
C84CC58D1BDD486300E06A64 /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC56D1BDD08F500E06A64 /* SynchronizedOnType.swift */; };
C84CC58E1BDD486300E06A64 /* SynchronizedSubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC56E1BDD08F500E06A64 /* SynchronizedSubscribeType.swift */; };
C84CC58F1BDD486300E06A64 /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC56F1BDD08F500E06A64 /* SynchronizedUnsubscribeType.swift */; };
C84CC5901BDD486300E06A64 /* AsyncLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C894642A1BC6C2B00055219D /* AsyncLock.swift */; };
C84CC5911BDD48B800E06A64 /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84CC5831BDD484400E06A64 /* SubscriptionDisposable.swift */; };
C859B9A41B45C5D900D012D7 /* PartialUpdatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C859B9A31B45C5D900D012D7 /* PartialUpdatesViewController.swift */; };
C859B9AC1B45CF9100D012D7 /* NumberCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C859B9AB1B45CF9100D012D7 /* NumberCell.swift */; };
C859B9AE1B45CFAB00D012D7 /* NumberSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C859B9AD1B45CFAB00D012D7 /* NumberSectionView.swift */; };
@ -140,7 +147,6 @@
C890A65A1AEBD28A00AFF7E6 /* GitHubAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C890A6591AEBD28A00AFF7E6 /* GitHubAPI.swift */; };
C890A65D1AEC084100AFF7E6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C890A65C1AEC084100AFF7E6 /* ViewController.swift */; };
C894649E1BC6C2B00055219D /* Cancelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89464281BC6C2B00055219D /* Cancelable.swift */; };
C894649F1BC6C2B00055219D /* AsyncLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C894642A1BC6C2B00055219D /* AsyncLock.swift */; };
C89464A01BC6C2B00055219D /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C894642B1BC6C2B00055219D /* Lock.swift */; };
C89464A11BC6C2B00055219D /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C894642C1BC6C2B00055219D /* ConnectableObservableType.swift */; };
C89464A21BC6C2B00055219D /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = C894642E1BC6C2B00055219D /* Bag.swift */; };
@ -501,6 +507,12 @@
C83367111AD029AE00C668A7 /* HtmlParsing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HtmlParsing.swift; sourceTree = "<group>"; };
C83367121AD029AE00C668A7 /* ImageService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageService.swift; sourceTree = "<group>"; };
C84CC52D1BDC344100E06A64 /* ElementAt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElementAt.swift; sourceTree = "<group>"; };
C84CC56B1BDD08F500E06A64 /* LockOwnerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockOwnerType.swift; sourceTree = "<group>"; };
C84CC56C1BDD08F500E06A64 /* SynchronizedDisposeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedDisposeType.swift; sourceTree = "<group>"; };
C84CC56D1BDD08F500E06A64 /* SynchronizedOnType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedOnType.swift; sourceTree = "<group>"; };
C84CC56E1BDD08F500E06A64 /* SynchronizedSubscribeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedSubscribeType.swift; sourceTree = "<group>"; };
C84CC56F1BDD08F500E06A64 /* SynchronizedUnsubscribeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedUnsubscribeType.swift; sourceTree = "<group>"; };
C84CC5831BDD484400E06A64 /* SubscriptionDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscriptionDisposable.swift; sourceTree = "<group>"; };
C859B9A31B45C5D900D012D7 /* PartialUpdatesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PartialUpdatesViewController.swift; sourceTree = "<group>"; };
C859B9A51B45C80700D012D7 /* RxCollectionViewSectionedReloadDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewSectionedReloadDataSource.swift; sourceTree = "<group>"; };
C859B9A71B45C83700D012D7 /* RxCollectionViewSectionedDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewSectionedDataSource.swift; sourceTree = "<group>"; };
@ -1066,6 +1078,11 @@
C89464291BC6C2B00055219D /* Concurrency */ = {
isa = PBXGroup;
children = (
C84CC56B1BDD08F500E06A64 /* LockOwnerType.swift */,
C84CC56C1BDD08F500E06A64 /* SynchronizedDisposeType.swift */,
C84CC56D1BDD08F500E06A64 /* SynchronizedOnType.swift */,
C84CC56E1BDD08F500E06A64 /* SynchronizedSubscribeType.swift */,
C84CC56F1BDD08F500E06A64 /* SynchronizedUnsubscribeType.swift */,
C894642A1BC6C2B00055219D /* AsyncLock.swift */,
C894642B1BC6C2B00055219D /* Lock.swift */,
);
@ -1085,6 +1102,7 @@
C89464321BC6C2B00055219D /* Disposables */ = {
isa = PBXGroup;
children = (
C84CC5831BDD484400E06A64 /* SubscriptionDisposable.swift */,
C89464331BC6C2B00055219D /* AnonymousDisposable.swift */,
C89464341BC6C2B00055219D /* BinaryDisposable.swift */,
C89464351BC6C2B00055219D /* CompositeDisposable.swift */,
@ -1644,6 +1662,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C84CC58B1BDD486300E06A64 /* LockOwnerType.swift in Sources */,
C89465971BC6C2BC0055219D /* UIScrollView+Rx.swift in Sources */,
C8297E2F1B6CF905000589EA /* RxTableViewSectionedAnimatedDataSource.swift in Sources */,
C89464FF1BC6C2B00055219D /* DispatchQueueSchedulerPriority.swift in Sources */,
@ -1661,6 +1680,7 @@
C89465731BC6C2BC0055219D /* Deallocating.swift in Sources */,
C89464A51BC6C2B00055219D /* Disposable.swift in Sources */,
C89464F91BC6C2B00055219D /* ObserverType+Extensions.swift in Sources */,
C84CC58D1BDD486300E06A64 /* SynchronizedOnType.swift in Sources */,
C89464DC1BC6C2B00055219D /* Scan.swift in Sources */,
C89464B21BC6C2B00055219D /* StableCompositeDisposable.swift in Sources */,
C89464AE1BC6C2B00055219D /* ScheduledDisposable.swift in Sources */,
@ -1681,6 +1701,7 @@
C89465961BC6C2BC0055219D /* UILabel+Rx.swift in Sources */,
C894659C1BC6C2BC0055219D /* UISwitch+Rx.swift in Sources */,
C89464F81BC6C2B00055219D /* TailRecursiveSink.swift in Sources */,
C84CC58C1BDD486300E06A64 /* SynchronizedDisposeType.swift in Sources */,
C89464BF1BC6C2B00055219D /* CombineLatest+arity.swift in Sources */,
C89465751BC6C2BC0055219D /* KVOObservable.swift in Sources */,
C89464CB1BC6C2B00055219D /* FailWith.swift in Sources */,
@ -1761,10 +1782,12 @@
C8297E3F1B6CF905000589EA /* SectionModelType.swift in Sources */,
C8297E401B6CF905000589EA /* ImageService.swift in Sources */,
C89464AD1BC6C2B00055219D /* NopDisposable.swift in Sources */,
C84CC5901BDD486300E06A64 /* AsyncLock.swift in Sources */,
CBEE77541BD8C7B700AD584C /* ToArray.swift in Sources */,
C89465771BC6C2BC0055219D /* NSNotificationCenter+Rx.swift in Sources */,
C89465091BC6C2B00055219D /* ReplaySubject.swift in Sources */,
C8297E411B6CF905000589EA /* RxCollectionViewSectionedReloadDataSource.swift in Sources */,
C84CC58E1BDD486300E06A64 /* SynchronizedSubscribeType.swift in Sources */,
C89464A81BC6C2B00055219D /* CompositeDisposable.swift in Sources */,
C89464D21BC6C2B00055219D /* Multicast.swift in Sources */,
C89465821BC6C2BC0055219D /* RxCollectionViewDataSourceType.swift in Sources */,
@ -1808,6 +1831,7 @@
C89464E31BC6C2B00055219D /* TakeUntil.swift in Sources */,
C89464FB1BC6C2B00055219D /* Rx.swift in Sources */,
C89464FD1BC6C2B00055219D /* ConcurrentDispatchQueueScheduler.swift in Sources */,
C84CC5911BDD48B800E06A64 /* SubscriptionDisposable.swift in Sources */,
C89464C71BC6C2B00055219D /* DelaySubscription.swift in Sources */,
C8297E481B6CF905000589EA /* Differentiator.swift in Sources */,
C8297E491B6CF905000589EA /* WikipediaSearchCell.swift in Sources */,
@ -1820,6 +1844,7 @@
C89464D31BC6C2B00055219D /* Never.swift in Sources */,
C8297E4D1B6CF905000589EA /* RxTableViewSectionedReloadDataSource.swift in Sources */,
C89465931BC6C2BC0055219D /* UIDatePicker+Rx.swift in Sources */,
C84CC58F1BDD486300E06A64 /* SynchronizedUnsubscribeType.swift in Sources */,
C8297E4E1B6CF905000589EA /* RxCollectionViewSectionedAnimatedDataSource.swift in Sources */,
C89CDB711BCC45E5002063D9 /* ShareReplay1.swift in Sources */,
C89464BD1BC6C2B00055219D /* Buffer.swift in Sources */,
@ -1838,7 +1863,6 @@
D2AF91981BD3D95900A008C1 /* Using.swift in Sources */,
C8297E501B6CF905000589EA /* TableViewController.swift in Sources */,
C8297E511B6CF905000589EA /* PartialUpdatesViewController.swift in Sources */,
C894649F1BC6C2B00055219D /* AsyncLock.swift in Sources */,
C8B145141BD2E4D000267DCE /* ConcurrentMainScheduler.swift in Sources */,
C8297E521B6CF905000589EA /* Dependencies.swift in Sources */,
C80DDED91BCE9046006A1832 /* ObservableConvertibleType+Driver.swift in Sources */,

View File

@ -48,7 +48,7 @@ extension ObservableConvertibleType {
}
func retryOnBecomesReachable(valueOnFailure:E, reachabilityService:ReachabilityService, orExternalTrigger: Observable<Void>) -> Observable<E>{
return self
return self.asObservable()
.catchError { (e) -> Observable<E> in
let retryBecauseOfNeworkAvailability = reachabilityService.reachabilityChanged
.flatMap { event -> Observable<Void> in

View File

@ -8,6 +8,11 @@
import Foundation
protocol Lock {
func lock()
func unlock()
}
/**
Simple wrapper for spin lock.
*/
@ -17,6 +22,14 @@ struct SpinLock {
init() {
}
mutating func lock() {
OSSpinLockLock(&_lock)
}
mutating func unlock() {
OSSpinLockUnlock(&_lock)
}
mutating func performLocked(@noescape action: () -> Void) {
OSSpinLockLock(&_lock)
@ -41,7 +54,7 @@ struct SpinLock {
}
}
extension NSRecursiveLock {
extension NSRecursiveLock : Lock {
func performLocked(@noescape action: () -> Void) {
self.lock()
action()

View File

@ -0,0 +1,23 @@
//
// LockOwnerType.swift
// Rx
//
// Created by Krunoslav Zaher on 10/25/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
protocol LockOwnerType : class, Lock {
var _lock: NSRecursiveLock { get }
}
extension LockOwnerType {
func lock() {
_lock.lock()
}
func unlock() {
_lock.unlock()
}
}

View File

@ -0,0 +1,20 @@
//
// SynchronizedDisposeType.swift
// Rx
//
// Created by Krunoslav Zaher on 10/25/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
protocol SynchronizedDisposeType : class, Disposable, Lock {
func _synchronized_dispose()
}
extension SynchronizedDisposeType {
func synchronizedDispose() {
lock(); defer { unlock() }
_synchronized_dispose()
}
}

View File

@ -0,0 +1,20 @@
//
// SynchronizedOnType.swift
// Rx
//
// Created by Krunoslav Zaher on 10/25/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
protocol SynchronizedOnType : class, ObserverType, Lock {
func _synchronized_on(event: Event<E>)
}
extension SynchronizedOnType {
func synchronizedOn(event: Event<E>) {
lock(); defer { unlock() }
_synchronized_on(event)
}
}

View File

@ -0,0 +1,20 @@
//
// SynchronizedSubscribeType.swift
// Rx
//
// Created by Krunoslav Zaher on 10/25/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
protocol SynchronizedSubscribeType : class, ObservableType, Lock {
func _synchronized_subscribe<O: ObserverType where O.E == E>(observer: O) -> Disposable
}
extension SynchronizedSubscribeType {
func synchronizedSubscribe<O: ObserverType where O.E == E>(observer: O) -> Disposable {
lock(); defer { unlock() }
return _synchronized_subscribe(observer)
}
}

View File

@ -0,0 +1,22 @@
//
// SynchronizedUnsubscribeType.swift
// Rx
//
// Created by Krunoslav Zaher on 10/25/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
protocol SynchronizedUnsubscribeType : class, Lock {
typealias DisposeKey
func _synchronized_unsubscribe(disposeKey: DisposeKey)
}
extension SynchronizedUnsubscribeType {
func synchronizedUnsubscribe(disposeKey: DisposeKey) {
lock(); defer { unlock() }
_synchronized_unsubscribe(disposeKey)
}
}

View File

@ -7,6 +7,9 @@
//
import Foundation
import Swift
let arrayDictionaryMaxSize = 30
/**
Class that enables using memory allocations as a means to uniquely identify objects.
@ -16,12 +19,31 @@ class Identity {
var _forceAllocation: Int32 = 0
}
func hash(_x: Int) -> Int {
var x = _x
x = ((x >> 16) ^ x) &* 0x45d9f3b;
x = ((x >> 16) ^ x) &* 0x45d9f3b;
x = ((x >> 16) ^ x);
return x;
}
/**
Unique identifier for object added to `Bag`.
*/
public struct BagKey : Equatable {
public struct BagKey : Hashable {
let uniqueIdentity: Identity?
let key: Int
public var hashValue: Int {
get {
if let uniqueIdentity = uniqueIdentity {
return hash(key) ^ (unsafeAddressOf(uniqueIdentity).hashValue)
}
else {
return hash(key)
}
}
}
}
/**
@ -52,8 +74,21 @@ public struct Bag<T> : CustomStringConvertible {
private var _uniqueIdentity: Identity?
private var _nextKey: ScopeUniqueTokenType = 0
var pairs = [Entry]()
// data
// first fill inline variables
private var _key0: BagKey? = nil
private var _value0: T? = nil
private var _key1: BagKey? = nil
private var _value1: T? = nil
// then fill "array dictionary"
private var _pairs = ContiguousArray<Entry>()
// last is sparse dictionary
private var _dictionary: [BagKey : T]? = nil
/**
Creates new empty `Bag`.
@ -69,7 +104,7 @@ public struct Bag<T> : CustomStringConvertible {
return "\(self.count) elements in Bag"
}
}
/**
Inserts `value` into bag.
@ -86,10 +121,36 @@ public struct Bag<T> : CustomStringConvertible {
if _nextKey == 0 {
_uniqueIdentity = Identity()
}
let key = BagKey(uniqueIdentity: _uniqueIdentity, key: _nextKey)
pairs.append(key: key, value: element)
if _key0 == nil {
_key0 = key
_value0 = element
return key
}
if _key1 == nil {
_key1 = key
_value1 = element
return key
}
if _dictionary != nil {
_dictionary![key] = element
return key
}
if _pairs.count < arrayDictionaryMaxSize {
_pairs.append(key: key, value: element)
return key
}
if _dictionary == nil {
_dictionary = [:]
}
_dictionary![key] = element
return key
}
@ -98,14 +159,20 @@ public struct Bag<T> : CustomStringConvertible {
- returns: Number of elements in bag.
*/
public var count: Int {
return pairs.count
return _pairs.count + (_value0 != nil ? 1 : 0) + (_value1 != nil ? 1 : 0) + (_dictionary?.count ?? 0)
}
/**
Removes all elements from bag and clears capacity.
*/
public mutating func removeAll() {
pairs.removeAll(keepCapacity: false)
_key0 = nil
_value0 = nil
_key1 = nil
_value1 = nil
_pairs.removeAll(keepCapacity: false)
_dictionary?.removeAll(keepCapacity: false)
}
/**
@ -115,18 +182,38 @@ public struct Bag<T> : CustomStringConvertible {
- returns: Element that bag contained, or nil in case element was already removed.
*/
public mutating func removeKey(key: BagKey) -> T? {
for i in 0 ..< pairs.count {
if pairs[i].key == key {
let value = pairs[i].value
pairs.removeAtIndex(i)
if _key0 == key {
_key0 = nil
let value = _value0!
_value0 = nil
return value
}
if _key1 == key {
_key1 = nil
let value = _value1!
_value1 = nil
return value
}
if let existingObject = _dictionary?.removeValueForKey(key) {
return existingObject
}
for i in 0 ..< _pairs.count {
if _pairs[i].key == key {
let value = _pairs[i].value
_pairs.removeAtIndex(i)
return value
}
}
return nil
}
}
// MARK: forEach
extension Bag {
/**
Enumerates elements inside the bag.
@ -134,10 +221,87 @@ extension Bag {
- parameter action: Enumeration closure.
*/
public func forEach(@noescape action: (T) -> Void) {
let pairs = self.pairs
let pairs = _pairs
let value0 = _value0
let value1 = _value1
let dictionary = _dictionary
if let value0 = value0 {
action(value0)
}
if let value1 = value1 {
action(value1)
}
for i in 0 ..< pairs.count {
action(pairs[i].value)
}
if dictionary?.count ?? 0 > 0 {
for element in dictionary!.values {
action(element)
}
}
}
}
}
extension Bag where T: ObserverType {
/**
Dispatches `event` to app observers contained inside bag.
- parameter action: Enumeration closure.
*/
public func on(event: Event<T.E>) {
let pairs = self._pairs
let value0 = _value0
let value1 = _value1
let dictionary = _dictionary
if let value0 = value0 {
value0.on(event)
}
if let value1 = value1 {
value1.on(event)
}
for i in 0 ..< pairs.count {
pairs[i].value.on(event)
}
if dictionary?.count ?? 0 > 0 {
for element in dictionary!.values {
element.on(event)
}
}
}
}
/**
Dispatches `dispose` to all disposables contained inside bag.
*/
public func disposeAllIn(bag: Bag<Disposable>) {
let pairs = bag._pairs
let value0 = bag._value0
let value1 = bag._value1
let dictionary = bag._dictionary
if let value0 = value0 {
value0.dispose()
}
if let value1 = value1 {
value1.dispose()
}
for i in 0 ..< pairs.count {
pairs[i].value.dispose()
}
if dictionary?.count ?? 0 > 0 {
for element in dictionary!.values {
element.dispose()
}
}
}

View File

@ -24,7 +24,7 @@ public struct Queue<T>: SequenceType {
private let _resizeFactor = 2
private var _storage: [T?]
private var _storage: ContiguousArray<T?>
private var _count: Int
private var _pushNextIndex: Int
private var _initialCapacity: Int
@ -41,10 +41,10 @@ public struct Queue<T>: SequenceType {
_pushNextIndex = 0
if capacity > 0 {
_storage = [T?](count: capacity, repeatedValue: nil)
_storage = ContiguousArray<T?>(count: capacity, repeatedValue: nil)
}
else {
_storage = []
_storage = ContiguousArray<T?>()
}
}
@ -83,7 +83,7 @@ public struct Queue<T>: SequenceType {
}
mutating private func resizeTo(size: Int) {
var newStorage = [T?](count: size, repeatedValue: nil)
var newStorage = ContiguousArray<T?>(count: size, repeatedValue: nil)
let count = _count

View File

@ -45,6 +45,8 @@ public final class AnonymousDisposable : DisposeBase, Cancelable {
*/
public func dispose() {
if OSAtomicCompareAndSwap32(0, 1, &_disposed) {
assert(_disposed == 1)
if let action = _disposeAction {
_disposeAction = nil
action()

View File

@ -21,9 +21,8 @@ public class CompositeDisposable : DisposeBase, Disposable, Cancelable {
public var disposed: Bool {
get {
return _lock.calculateLocked {
return _disposables == nil
}
_lock.lock(); defer { _lock.unlock() }
return _disposables == nil
}
}
@ -55,7 +54,7 @@ public class CompositeDisposable : DisposeBase, Disposable, Cancelable {
_disposables!.insert(disposable)
}
}
/**
Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
@ -64,27 +63,28 @@ public class CompositeDisposable : DisposeBase, Disposable, Cancelable {
disposed `nil` will be returned.
*/
public func addDisposable(disposable: Disposable) -> DisposeKey? {
// this should be let
// bucause of compiler bug it's var
let key = _lock.calculateLocked { () -> DisposeKey? in
return _disposables?.insert(disposable)
}
let key = _addDisposable(disposable)
if key == nil {
disposable.dispose()
}
return key
}
private func _addDisposable(disposable: Disposable) -> DisposeKey? {
_lock.lock(); defer { _lock.unlock() }
return _disposables?.insert(disposable)
}
/**
- returns: Gets the number of disposables contained in the `CompositeDisposable`.
*/
public var count: Int {
get {
return _lock.calculateLocked {
return _disposables?.count ?? 0
}
_lock.lock(); defer { _lock.unlock() }
return _disposables?.count ?? 0
}
}
@ -94,30 +94,29 @@ public class CompositeDisposable : DisposeBase, Disposable, Cancelable {
- parameter disposeKey: Key used to identify disposable to be removed.
*/
public func removeDisposable(disposeKey: DisposeKey) {
let disposable = _lock.calculateLocked { () -> Disposable? in
return _disposables?.removeKey(disposeKey)
}
if let disposable = disposable {
disposable.dispose()
}
_removeDisposable(disposeKey)?.dispose()
}
private func _removeDisposable(disposeKey: DisposeKey) -> Disposable? {
_lock.lock(); defer { _lock.unlock() }
return _disposables?.removeKey(disposeKey)
}
/**
Disposes all disposables in the group and removes them from the group.
*/
public func dispose() {
let oldDisposables = _lock.calculateLocked { () -> Bag<Disposable>? in
let disposeBag = _disposables
_disposables = nil
return disposeBag
}
if let oldDisposables = oldDisposables {
oldDisposables.forEach { d in
d.dispose()
}
if let disposables = _dispose() {
disposeAllIn(disposables)
}
}
private func _dispose() -> Bag<Disposable>? {
_lock.lock(); defer { _lock.unlock() }
let disposeBag = _disposables
_disposables = nil
return disposeBag
}
}

View File

@ -52,38 +52,41 @@ public class DisposeBag: DisposeBase {
- parameter disposable: Disposable to add.
*/
public func addDisposable(disposable: Disposable) {
let dispose = _lock.calculateLocked { () -> Bool in
if _disposed {
return true
}
_disposables.append(disposable)
return false
}
if dispose {
disposable.dispose()
_addDisposable(disposable)?.dispose()
}
private func _addDisposable(disposable: Disposable) -> Disposable? {
_lock.lock(); defer { _lock.unlock() }
if _disposed {
return disposable
}
_disposables.append(disposable)
return nil
}
/**
This is internal on purpose, take a look at `CompositeDisposable` instead.
*/
func dispose() {
let oldDisposables = _lock.calculateLocked { () -> [Disposable] in
let disposables = _disposables
_disposables.removeAll(keepCapacity: false)
_disposed = true
return disposables
}
private func dispose() {
let oldDisposables = _dispose()
for disposable in oldDisposables {
disposable.dispose()
}
}
private func _dispose() -> [Disposable] {
_lock.lock(); defer { _lock.unlock() }
let disposables = _disposables
_disposables.removeAll(keepCapacity: false)
_disposed = true
return disposables
}
deinit {
dispose()

View File

@ -8,6 +8,11 @@
import Foundation
private let disposeScheduledDisposable: ScheduledDisposable -> Disposable = { sd in
sd.disposeInner()
return NopDisposable.instance
}
/**
Represents a disposable resource whose disposal invocation will be scheduled on the specified scheduler.
*/
@ -43,10 +48,7 @@ public class ScheduledDisposable : Cancelable {
Disposes the wrapped disposable on the provided scheduler.
*/
public func dispose() {
scheduler.schedule(()) {
self.disposeInner()
return NopDisposable.instance
}
scheduler.schedule(self, action: disposeScheduledDisposable)
}
func disposeInner() {

View File

@ -69,18 +69,19 @@ public class SerialDisposable : DisposeBase, Cancelable {
Disposes the underlying disposable as well as all future replacements.
*/
public func dispose() {
let disposable: Disposable? = _lock.calculateLocked {
if _disposed {
return nil
}
else {
_disposed = true
return _current
}
_dispose()?.dispose()
}
private func _dispose() -> Disposable? {
_lock.lock(); defer { _lock.unlock() }
if _disposed {
return nil
}
if let disposable = disposable {
disposable.dispose()
else {
_disposed = true
let current = _current
_current = nil
return current
}
}
}

View File

@ -26,9 +26,7 @@ public class SingleAssignmentDisposable : DisposeBase, Disposable, Cancelable {
*/
public var disposed: Bool {
get {
return _lock.calculateLocked {
return _disposed
}
return _disposed
}
}
@ -46,47 +44,47 @@ public class SingleAssignmentDisposable : DisposeBase, Disposable, Cancelable {
*/
public var disposable: Disposable {
get {
return _lock.calculateLocked {
return _disposable ?? NopDisposable.instance
}
_lock.lock(); defer { _lock.unlock() }
return _disposable ?? NopDisposable.instance
}
set {
let disposable: Disposable? = _lock.calculateLocked {
if _disposableSet {
rxFatalError("oldState.disposable != nil")
}
_disposableSet = true
if _disposed {
return newValue
}
_disposable = newValue
return nil
}
if let disposable = disposable {
disposable.dispose()
}
_setDisposable(newValue)?.dispose()
}
}
private func _setDisposable(newValue: Disposable) -> Disposable? {
if _disposableSet {
rxFatalError("oldState.disposable != nil")
}
_disposableSet = true
if _disposed {
return newValue
}
_disposable = newValue
return nil
}
/**
Disposes the underlying disposable.
*/
public func dispose() {
let disposable: Disposable? = _lock.calculateLocked {
_disposed = true
let dispose = _disposable
_disposable = nil
return dispose
if _disposed {
return
}
_dispose()?.dispose()
}
if let disposable = disposable {
disposable.dispose()
}
private func _dispose() -> Disposable? {
_lock.lock(); defer { _lock.unlock() }
_disposed = true
let disposable = _disposable
_disposable = nil
return disposable
}
}

View File

@ -0,0 +1,23 @@
//
// SubscriptionDisposable.swift
// Rx
//
// Created by Krunoslav Zaher on 10/25/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
struct SubscriptionDisposable<T: SynchronizedUnsubscribeType> : Disposable {
private let _key: T.DisposeKey
private weak var _owner: T?
init(owner: T, key: T.DisposeKey) {
_owner = owner
_key = key
}
func dispose() {
_owner?.synchronizedUnsubscribe(_key)
}
}

View File

@ -58,9 +58,9 @@ class AmbSink<ElementType, O: ObserverType where O.E == ElementType> : Sink<O> {
// state
private var _choice = AmbState.Neither
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
@ -69,7 +69,7 @@ class AmbSink<ElementType, O: ObserverType where O.E == ElementType> : Sink<O> {
let disposeAll = StableCompositeDisposable.create(subscription1, subscription2)
let forwardEvent = { (o: AmbObserverType, event: Event<ElementType>) -> Void in
self.observer?.on(event)
self.forwardOn(event)
}
let decide = { (o: AmbObserverType, event: Event<ElementType>, me: AmbState, otherSubscription: Disposable) in
@ -82,7 +82,7 @@ class AmbSink<ElementType, O: ObserverType where O.E == ElementType> : Sink<O> {
}
if self._choice == me {
self.observer?.on(event)
self.forwardOn(event)
if event.isStopEvent {
self.dispose()
}
@ -114,9 +114,9 @@ class Amb<Element>: Producer<Element> {
_right = right
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = AmbSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = AmbSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -16,8 +16,8 @@ class AnonymousObservableSink<O: ObserverType> : Sink<O>, ObserverType {
// state
private var _isStopped: Int32 = 0
override init(observer: O, cancel: Disposable) {
super.init(observer: observer, cancel: cancel)
override init(observer: O) {
super.init(observer: observer)
}
func on(event: Event<E>) {
@ -26,10 +26,10 @@ class AnonymousObservableSink<O: ObserverType> : Sink<O>, ObserverType {
if _isStopped == 1 {
return
}
observer?.on(event)
forwardOn(event)
case .Error, .Completed:
if OSAtomicCompareAndSwap32(0, 1, &_isStopped) {
self.observer?.on(event)
self.forwardOn(event)
self.dispose()
}
}
@ -49,9 +49,9 @@ public class AnonymousObservable<Element> : Producer<Element> {
_subscribeHandler = subscribeHandler
}
public override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
setSink(sink)
return sink.run(self)
public override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = AnonymousObservableSink(observer: observer)
sink.disposable = sink.run(self)
return sink
}
}

View File

@ -1,42 +0,0 @@
//
// AsObservable.swift
// Rx
//
// Created by Krunoslav Zaher on 2/27/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
class AsObservableSink<O: ObserverType> : Sink<O>, ObserverType {
typealias Element = O.E
override init(observer: O, cancel: Disposable) {
super.init(observer: observer, cancel: cancel)
}
func on(event: Event<Element>) {
observer?.on(event)
switch event {
case .Error, .Completed:
dispose()
default: break
}
}
}
class AsObservable<Element> : Producer<Element> {
private let _source: Observable<Element>
init(source: Observable<Element>) {
_source = source
}
override func run<O: ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = AsObservableSink(observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribeSafe(sink)
}
}

View File

@ -22,29 +22,33 @@ class BufferTimeCount<Element, S: SchedulerType> : Producer<[Element]> {
_scheduler = scheduler
}
override func run<O : ObserverType where O.E == [Element]>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = BufferTimeCountSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == [Element]>(observer: O) -> Disposable {
let sink = BufferTimeCountSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
class BufferTimeCountSink<S: SchedulerType, Element, O: ObserverType where O.E == [Element]> : Sink<O>, ObserverType {
class BufferTimeCountSink<S: SchedulerType, Element, O: ObserverType where O.E == [Element]>
: Sink<O>
, LockOwnerType
, ObserverType
, SynchronizedOnType {
typealias Parent = BufferTimeCount<Element, S>
typealias E = Element
private let _parent: Parent
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
// state
private let _timerD = SerialDisposable()
private var _buffer = [Element]()
private var _windowID = 0
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
@ -58,30 +62,32 @@ class BufferTimeCountSink<S: SchedulerType, Element, O: ObserverType where O.E =
let buffer = _buffer
_buffer = []
observer?.on(.Next(buffer))
forwardOn(.Next(buffer))
createTimer(windowID)
}
func on(event: Event<E>) {
_lock.performLocked {
switch event {
case .Next(let element):
_buffer.append(element)
if _buffer.count == _parent._count {
startNewWindowAndSendCurrentOne()
}
case .Error(let error):
_buffer = []
observer?.on(.Error(error))
dispose()
case .Completed:
observer?.on(.Next(_buffer))
observer?.on(.Completed)
dispose()
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next(let element):
_buffer.append(element)
if _buffer.count == _parent._count {
startNewWindowAndSendCurrentOne()
}
case .Error(let error):
_buffer = []
forwardOn(.Error(error))
dispose()
case .Completed:
forwardOn(.Next(_buffer))
forwardOn(.Completed)
dispose()
}
}

View File

@ -21,7 +21,7 @@ class CatchSinkProxy<O: ObserverType> : ObserverType {
}
func on(event: Event<E>) {
_parent.observer?.on(event)
_parent.forwardOn(event)
switch event {
case .Next:
@ -39,9 +39,9 @@ class CatchSink<O: ObserverType> : Sink<O>, ObserverType {
private let _parent: Parent
private let _subscription = SerialDisposable()
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
@ -55,9 +55,9 @@ class CatchSink<O: ObserverType> : Sink<O>, ObserverType {
func on(event: Event<E>) {
switch event {
case .Next:
observer?.on(event)
forwardOn(event)
case .Completed:
observer?.on(event)
forwardOn(event)
dispose()
case .Error(let error):
do {
@ -68,7 +68,7 @@ class CatchSink<O: ObserverType> : Sink<O>, ObserverType {
_subscription.disposable = catchSequence.subscribe(observer)
}
catch let e {
observer?.on(.Error(e))
forwardOn(.Error(e))
dispose()
}
}
@ -86,10 +86,10 @@ class Catch<Element> : Producer<Element> {
_handler = handler
}
override func run<O: ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = CatchSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = CatchSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -101,29 +101,29 @@ class CatchSequenceSink<S: SequenceType, O: ObserverType where S.Generator.Eleme
private var _lastError: ErrorType?
override init(observer: O, cancel: Disposable) {
super.init(observer: observer, cancel: cancel)
override init(observer: O) {
super.init(observer: observer)
}
override func on(event: Event<Element>) {
switch event {
case .Next:
observer?.on(event)
forwardOn(event)
case .Error(let error):
_lastError = error
scheduleMoveNext()
case .Completed:
observer?.on(event)
forwardOn(event)
dispose()
}
}
override func done() {
if let lastError = _lastError {
observer?.on(.Error(lastError))
forwardOn(.Error(lastError))
}
else {
observer?.on(.Completed)
forwardOn(.Completed)
}
self.dispose()
@ -148,9 +148,9 @@ class CatchSequence<S: SequenceType where S.Generator.Element : ObservableConver
self.sources = sources
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = CatchSequenceSink<S, O>(observer: observer, cancel: cancel)
setSink(sink)
return sink.run(self.sources.generate())
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = CatchSequenceSink<S, O>(observer: observer)
sink.disposable = sink.run(self.sources.generate())
return sink
}
}

View File

@ -8,117 +8,118 @@
import Foundation
class CombineLatestCollectionTypeSink<C: CollectionType, R, O: ObserverType where C.Generator.Element : ObservableConvertibleType, O.E == R> : Sink<O> {
class CombineLatestCollectionTypeSink<C: CollectionType, R, O: ObserverType where C.Generator.Element : ObservableConvertibleType, O.E == R>
: Sink<O> {
typealias Parent = CombineLatestCollectionType<C, R>
typealias SourceElement = C.Generator.Element.E
let parent: Parent
let lock = NSRecursiveLock()
let _parent: Parent
let _lock = NSRecursiveLock()
// 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: Disposable) {
self.parent = parent
self.values = [SourceElement?](count: parent.count, repeatedValue: nil)
self.isDone = [Bool](count: parent.count, repeatedValue: false)
self.subscriptions = Array<SingleAssignmentDisposable>()
self.subscriptions.reserveCapacity(parent.count)
init(parent: Parent, observer: O) {
_parent = parent
_values = [SourceElement?](count: parent._count, repeatedValue: nil)
_isDone = [Bool](count: parent._count, repeatedValue: false)
_subscriptions = Array<SingleAssignmentDisposable>()
_subscriptions.reserveCapacity(parent._count)
for _ in 0 ..< parent.count {
self.subscriptions.append(SingleAssignmentDisposable())
for _ in 0 ..< parent._count {
_subscriptions.append(SingleAssignmentDisposable())
}
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<SourceElement>, atIndex: Int) {
lock.performLocked {
_lock.lock(); defer { _lock.unlock() } // {
switch event {
case .Next(let element):
if values[atIndex] == nil {
numberOfValues++
if _values[atIndex] == nil {
_numberOfValues++
}
values[atIndex] = element
_values[atIndex] = element
if numberOfValues < parent.count {
let numberOfOthersThatAreDone = self.numberOfDone - (isDone[atIndex] ? 1 : 0)
if numberOfOthersThatAreDone == self.parent.count - 1 {
observer?.on(.Completed)
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! })
observer?.on(.Next(result))
let result = try _parent._resultSelector(_values.map { $0! })
forwardOn(.Next(result))
}
catch let error {
observer?.on(.Error(error))
forwardOn(.Error(error))
dispose()
}
case .Error(let error):
observer?.on(.Error(error))
forwardOn(.Error(error))
dispose()
case .Completed:
if isDone[atIndex] {
if _isDone[atIndex] {
return
}
isDone[atIndex] = true
numberOfDone++
_isDone[atIndex] = true
_numberOfDone++
if numberOfDone == self.parent.count {
observer?.on(.Completed)
if _numberOfDone == self._parent._count {
forwardOn(.Completed)
dispose()
}
else {
subscriptions[atIndex].dispose()
_subscriptions[atIndex].dispose()
}
}
}
// }
}
func run() -> Disposable {
var j = 0
for i in parent.sources.startIndex ..< parent.sources.endIndex {
for i in _parent._sources.startIndex ..< _parent._sources.endIndex {
let index = j
let source = self.parent.sources[i].asObservable()
self.subscriptions[j].disposable = source.subscribe(AnyObserver { event in
let source = _parent._sources[i].asObservable()
_subscriptions[j].disposable = source.subscribe(AnyObserver { event in
self.on(event, atIndex: index)
})
j++
}
return CompositeDisposable(disposables: self.subscriptions.map { $0 })
return CompositeDisposable(disposables: _subscriptions.map { $0 })
}
}
class CombineLatestCollectionType<C: CollectionType, R where C.Generator.Element : ObservableConvertibleType> : Producer<R> {
typealias ResultSelector = [C.Generator.Element.E] throws -> R
let sources: C
let resultSelector: ResultSelector
let count: Int
let _sources: C
let _resultSelector: ResultSelector
let _count: Int
init(sources: C, resultSelector: ResultSelector) {
self.sources = sources
self.resultSelector = resultSelector
self.count = Int(self.sources.count.toIntMax())
_sources = sources
_resultSelector = resultSelector
_count = Int(self._sources.count.toIntMax())
}
override func run<O : ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = CombineLatestCollectionTypeSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = CombineLatestCollectionTypeSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -39,17 +39,17 @@ class CombineLatestSink2_<E1, E2, O: ObserverType> : CombineLatestSink<O> {
var _latestElement1: E1! = nil
var _latestElement2: E2! = nil
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 2, observer: observer, cancel: cancel)
super.init(arity: 2, observer: observer)
}
func run() -> Disposable {
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: _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)
subscription1.disposable = _parent._source1.subscribe(observer1)
subscription2.disposable = _parent._source2.subscribe(observer2)
@ -80,10 +80,10 @@ class CombineLatest2<E1, E2, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = CombineLatestSink2_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = CombineLatestSink2_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -117,9 +117,9 @@ class CombineLatestSink3_<E1, E2, E3, O: ObserverType> : CombineLatestSink<O> {
var _latestElement2: E2! = nil
var _latestElement3: E3! = nil
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 3, observer: observer, cancel: cancel)
super.init(arity: 3, observer: observer)
}
func run() -> Disposable {
@ -127,9 +127,9 @@ class CombineLatestSink3_<E1, E2, E3, O: ObserverType> : CombineLatestSink<O> {
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: _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)
subscription1.disposable = _parent._source1.subscribe(observer1)
subscription2.disposable = _parent._source2.subscribe(observer2)
@ -164,10 +164,10 @@ class CombineLatest3<E1, E2, E3, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = CombineLatestSink3_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = CombineLatestSink3_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -202,9 +202,9 @@ class CombineLatestSink4_<E1, E2, E3, E4, O: ObserverType> : CombineLatestSink<O
var _latestElement3: E3! = nil
var _latestElement4: E4! = nil
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 4, observer: observer, cancel: cancel)
super.init(arity: 4, observer: observer)
}
func run() -> Disposable {
@ -213,10 +213,10 @@ class CombineLatestSink4_<E1, E2, E3, E4, O: ObserverType> : CombineLatestSink<O
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: _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)
subscription1.disposable = _parent._source1.subscribe(observer1)
subscription2.disposable = _parent._source2.subscribe(observer2)
@ -255,10 +255,10 @@ class CombineLatest4<E1, E2, E3, E4, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = CombineLatestSink4_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = CombineLatestSink4_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -294,9 +294,9 @@ class CombineLatestSink5_<E1, E2, E3, E4, E5, O: ObserverType> : CombineLatestSi
var _latestElement4: E4! = nil
var _latestElement5: E5! = nil
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 5, observer: observer, cancel: cancel)
super.init(arity: 5, observer: observer)
}
func run() -> Disposable {
@ -306,11 +306,11 @@ class CombineLatestSink5_<E1, E2, E3, E4, E5, O: ObserverType> : CombineLatestSi
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: _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)
subscription1.disposable = _parent._source1.subscribe(observer1)
subscription2.disposable = _parent._source2.subscribe(observer2)
@ -353,10 +353,10 @@ class CombineLatest5<E1, E2, E3, E4, E5, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = CombineLatestSink5_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = CombineLatestSink5_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -393,9 +393,9 @@ class CombineLatestSink6_<E1, E2, E3, E4, E5, E6, O: ObserverType> : CombineLate
var _latestElement5: E5! = nil
var _latestElement6: E6! = nil
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 6, observer: observer, cancel: cancel)
super.init(arity: 6, observer: observer)
}
func run() -> Disposable {
@ -406,12 +406,12 @@ class CombineLatestSink6_<E1, E2, E3, E4, E5, E6, O: ObserverType> : CombineLate
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: _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)
subscription1.disposable = _parent._source1.subscribe(observer1)
subscription2.disposable = _parent._source2.subscribe(observer2)
@ -458,10 +458,10 @@ class CombineLatest6<E1, E2, E3, E4, E5, E6, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = CombineLatestSink6_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = CombineLatestSink6_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -499,9 +499,9 @@ class CombineLatestSink7_<E1, E2, E3, E4, E5, E6, E7, O: ObserverType> : Combine
var _latestElement6: E6! = nil
var _latestElement7: E7! = nil
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 7, observer: observer, cancel: cancel)
super.init(arity: 7, observer: observer)
}
func run() -> Disposable {
@ -513,13 +513,13 @@ class CombineLatestSink7_<E1, E2, E3, E4, E5, E6, E7, O: ObserverType> : Combine
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)
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.disposable = _parent._source1.subscribe(observer1)
subscription2.disposable = _parent._source2.subscribe(observer2)
@ -570,10 +570,10 @@ class CombineLatest7<E1, E2, E3, E4, E5, E6, E7, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = CombineLatestSink7_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = CombineLatestSink7_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -612,9 +612,9 @@ class CombineLatestSink8_<E1, E2, E3, E4, E5, E6, E7, E8, O: ObserverType> : Com
var _latestElement7: E7! = nil
var _latestElement8: E8! = nil
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 8, observer: observer, cancel: cancel)
super.init(arity: 8, observer: observer)
}
func run() -> Disposable {
@ -627,14 +627,14 @@ class CombineLatestSink8_<E1, E2, E3, E4, E5, E6, E7, E8, O: ObserverType> : Com
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)
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.disposable = _parent._source1.subscribe(observer1)
subscription2.disposable = _parent._source2.subscribe(observer2)
@ -689,10 +689,10 @@ class CombineLatest8<E1, E2, E3, E4, E5, E6, E7, E8, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = CombineLatestSink8_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = CombineLatestSink8_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -38,9 +38,9 @@ class CombineLatestSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joinWithSep
" var _latestElement\($0): E\($0)! = nil"
}).joinWithSeparator("\n") %>
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: <%= i %>, observer: observer, cancel: cancel)
super.init(arity: <%= i %>, observer: observer)
}
func run() -> Disposable {
@ -49,7 +49,7 @@ class CombineLatestSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joinWithSep
}).joinWithSeparator("\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: _lock, parent: self, index: \($0 - 1), setLatestValue: { (e: E\($0)) -> Void in self._latestElement\($0) = e }, this: subscription\($0))"
}).joinWithSeparator("\n") %>
<%= (Array(1...i).map {
@ -83,10 +83,10 @@ class CombineLatest<%= i %><<%= (Array(1...i).map { "E\($0)" }).joinWithSeparato
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = CombineLatestSink<%= i %>_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = CombineLatestSink<%= i %>_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -14,10 +14,12 @@ protocol CombineLatestProtocol : class {
func done(index: Int)
}
class CombineLatestSink<O: ObserverType> : Sink<O>, CombineLatestProtocol {
class CombineLatestSink<O: ObserverType>
: Sink<O>
, CombineLatestProtocol {
typealias Element = O.E
let lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
private let _arity: Int
private var _numberOfValues = 0
@ -25,12 +27,12 @@ class CombineLatestSink<O: ObserverType> : Sink<O>, CombineLatestProtocol {
private var _hasValue: [Bool]
private var _isDone: [Bool]
init(arity: Int, observer: O, cancel: Disposable) {
init(arity: Int, observer: O) {
_arity = arity
_hasValue = [Bool](count: arity, repeatedValue: false)
_isDone = [Bool](count: arity, repeatedValue: false)
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func getResult() throws -> Element {
@ -46,10 +48,10 @@ class CombineLatestSink<O: ObserverType> : Sink<O>, CombineLatestProtocol {
if _numberOfValues == _arity {
do {
let result = try getResult()
observer?.on(.Next(result))
forwardOn(.Next(result))
}
catch let e {
observer?.on(.Error(e))
forwardOn(.Error(e))
dispose()
}
}
@ -64,14 +66,14 @@ class CombineLatestSink<O: ObserverType> : Sink<O>, CombineLatestProtocol {
}
if allOthersDone {
observer?.on(.Completed)
forwardOn(.Completed)
dispose()
}
}
}
func fail(error: ErrorType) {
observer?.on(.Error(error))
forwardOn(.Error(error))
dispose()
}
@ -84,19 +86,22 @@ class CombineLatestSink<O: ObserverType> : Sink<O>, CombineLatestProtocol {
_numberOfDone++
if _numberOfDone == _arity {
observer?.on(.Completed)
forwardOn(.Completed)
dispose()
}
}
}
class CombineLatestObserver<ElementType> : ObserverType {
class CombineLatestObserver<ElementType>
: ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias Element = ElementType
typealias ValueSetter = (Element) -> Void
private let _parent: CombineLatestProtocol
private let _lock: NSRecursiveLock
let _lock: NSRecursiveLock
private let _index: Int
private let _this: Disposable
private let _setLatestValue: ValueSetter
@ -110,18 +115,20 @@ class CombineLatestObserver<ElementType> : ObserverType {
}
func on(event: Event<Element>) {
_lock.performLocked {
switch event {
case .Next(let value):
_setLatestValue(value)
_parent.next(_index)
case .Error(let error):
_this.dispose()
_parent.fail(error)
case .Completed:
_this.dispose()
_parent.done(_index)
}
synchronizedOn(event)
}
func _synchronized_on(event: Event<Element>) {
switch event {
case .Next(let value):
_setLatestValue(value)
_parent.next(_index)
case .Error(let error):
_this.dispose()
_parent.fail(error)
case .Completed:
_this.dispose()
_parent.done(_index)
}
}
}

View File

@ -12,16 +12,16 @@ import Foundation
class ConcatSink<S: SequenceType, O: ObserverType where S.Generator.Element : ObservableConvertibleType, S.Generator.Element.E == O.E> : TailRecursiveSink<S, O> {
typealias Element = O.E
override init(observer: O, cancel: Disposable) {
super.init(observer: observer, cancel: cancel)
override init(observer: O) {
super.init(observer: observer)
}
override func on(event: Event<Element>){
switch event {
case .Next:
observer?.on(event)
forwardOn(event)
case .Error:
observer?.on(event)
forwardOn(event)
dispose()
case .Completed:
scheduleMoveNext()
@ -47,11 +47,9 @@ class Concat<S: SequenceType where S.Generator.Element : ObservableConvertibleTy
_sources = sources
}
override func run<O: ObserverType where O.E == Element>
(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ConcatSink<S, O>(observer: observer, cancel: cancel)
setSink(sink)
return sink.run(_sources.generate())
override func run<O: ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = ConcatSink<S, O>(observer: observer)
sink.disposable = sink.run(_sources.generate())
return sink
}
}

View File

@ -14,9 +14,9 @@ class Debug_<O: ObserverType> : Sink<O>, ObserverType {
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<Element>) {
@ -26,7 +26,7 @@ class Debug_<O: ObserverType> : Sink<O>, ObserverType {
? String(eventText.characters.prefix(maxEventTextLength / 2)) + "..." + String(eventText.characters.suffix(maxEventTextLength / 2))
: eventText
print("[\(_parent._identifier)] -> Event \(eventNormalized)")
observer?.on(event)
forwardOn(event)
}
override func dispose() {
@ -45,10 +45,10 @@ class Debug<Element> : Producer<Element> {
_source = source
}
override func run<O: ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func run<O: ObserverType where O.E == Element>(observer: O) -> Disposable {
print("[\(_identifier)] subscribed")
let sink = Debug_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
let sink = Debug_(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}

View File

@ -14,9 +14,9 @@ class DeferredSink<O: ObserverType> : Sink<O>, ObserverType {
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
@ -25,14 +25,14 @@ class DeferredSink<O: ObserverType> : Sink<O>, ObserverType {
return result.subscribe(self)
}
catch let e {
observer?.on(.Error(e))
forwardOn(.Error(e))
dispose()
return NopDisposable.instance
}
}
func on(event: Event<E>) {
observer?.on(event)
forwardOn(event)
switch event {
case .Next:
@ -54,10 +54,10 @@ class Deferred<Element> : Producer<Element> {
_observableFactory = observableFactory
}
override func run<O: ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = DeferredSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = DeferredSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
func eval() throws -> Observable<Element> {

View File

@ -8,19 +8,21 @@
import Foundation
class DelaySubscriptionSink<ElementType, O: ObserverType, S: SchedulerType where O.E == ElementType> : Sink<O>, ObserverType {
class DelaySubscriptionSink<ElementType, O: ObserverType, S: SchedulerType where O.E == ElementType>
: Sink<O>
, ObserverType {
typealias Parent = DelaySubscription<ElementType, S>
typealias E = O.E
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<E>) {
observer?.on(event)
forwardOn(event)
if event.isStopEvent {
dispose()
}
@ -41,11 +43,12 @@ class DelaySubscription<Element, S: SchedulerType>: Producer<Element> {
_scheduler = scheduler
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = DelaySubscriptionSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _scheduler.scheduleRelative((), dueTime: _dueTime) { _ in
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = DelaySubscriptionSink(parent: self, observer: observer)
sink.disposable = _scheduler.scheduleRelative((), dueTime: _dueTime) { _ in
return self._source.subscribe(sink)
}
return sink
}
}

View File

@ -14,14 +14,12 @@ class DistinctUntilChangedSink<O: ObserverType, Key>: Sink<O>, ObserverType {
private let _parent: DistinctUntilChanged<E, Key>
private var _currentKey: Key? = nil
init(parent: DistinctUntilChanged<E, Key>, observer: O, cancel: Disposable) {
init(parent: DistinctUntilChanged<E, Key>, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<E>) {
let observer = super.observer
switch event {
case .Next(let value):
do {
@ -37,14 +35,14 @@ class DistinctUntilChangedSink<O: ObserverType, Key>: Sink<O>, ObserverType {
_currentKey = key
observer?.on(event)
forwardOn(event)
}
catch let error {
observer?.on(.Error(error))
forwardOn(.Error(error))
dispose()
}
case .Error, .Completed:
observer?.on(event)
forwardOn(event)
dispose()
}
}
@ -64,9 +62,9 @@ class DistinctUntilChanged<Element, Key>: Producer<Element> {
_comparer = comparer
}
override func run<O: ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = DistinctUntilChangedSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
override func run<O: ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = DistinctUntilChangedSink(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}

View File

@ -14,21 +14,21 @@ class DoSink<O: ObserverType> : Sink<O>, ObserverType {
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<Element>) {
do {
try _parent._eventHandler(event)
observer?.on(event)
forwardOn(event)
if event.isStopEvent {
dispose()
}
}
catch let error {
observer?.on(.Error(error))
forwardOn(.Error(error))
dispose()
}
}
@ -45,11 +45,9 @@ class Do<Element> : Producer<Element> {
_eventHandler = eventHandler
}
override func run<O: ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = DoSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
override func run<O: ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = DoSink(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}

View File

@ -15,11 +15,11 @@ class ElementAtSink<SourceType, O: ObserverType where O.E == SourceType> : Sink<
let _parent: Parent
var _i: Int
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
_i = parent._index
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<SourceType>) {
@ -27,27 +27,27 @@ class ElementAtSink<SourceType, O: ObserverType where O.E == SourceType> : Sink<
case .Next(_):
if (_i == 0) {
observer?.on(event)
observer?.on(.Completed)
forwardOn(event)
forwardOn(.Completed)
self.dispose()
}
do {
try decrementChecked(&_i)
} catch(let e) {
observer?.onError(e)
forwardOn(.Error(e))
dispose()
return
}
case .Error(let e):
observer?.on(.Error(e))
forwardOn(.Error(e))
self.dispose()
case .Completed:
if (_parent._throwOnEmpty) {
observer?.onError(RxError.ArgumentOutOfRange)
forwardOn(.Error(RxError.ArgumentOutOfRange))
} else {
observer?.on(.Completed)
forwardOn(.Completed)
}
self.dispose()
@ -71,9 +71,9 @@ class ElementAt<SourceType> : Producer<SourceType> {
self._throwOnEmpty = throwOnEmpty
}
override func run<O: ObserverType where O.E == SourceType>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ElementAtSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribeSafe(sink)
override func run<O: ObserverType where O.E == SourceType>(observer: O) -> Disposable {
let sink = ElementAtSink(parent: self, observer: observer)
sink.disposable = _source.subscribeSafe(sink)
return sink
}
}

View File

@ -9,7 +9,7 @@
import Foundation
class Empty<Element> : Producer<Element> {
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func subscribe<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
observer.on(.Completed)
return NopDisposable.instance
}

View File

@ -15,7 +15,7 @@ class FailWith<Element> : Producer<Element> {
_error = error
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func subscribe<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
observer.on(.Error(_error))
return NopDisposable.instance
}

View File

@ -15,9 +15,9 @@ class FilterSink<O : ObserverType>: Sink<O>, ObserverType {
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<Element>) {
@ -26,15 +26,15 @@ class FilterSink<O : ObserverType>: Sink<O>, ObserverType {
do {
let satisfies = try _parent._predicate(value)
if satisfies {
observer?.on(.Next(value))
forwardOn(.Next(value))
}
}
catch let e {
observer?.on(.Error(e))
forwardOn(.Error(e))
dispose()
}
case .Completed, .Error:
observer?.on(event)
forwardOn(event)
dispose()
}
}
@ -51,9 +51,9 @@ class Filter<Element> : Producer<Element> {
_predicate = predicate
}
override func run<O: ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = FilterSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
override func run<O: ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = FilterSink(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}

View File

@ -27,14 +27,14 @@ class FlatMapSinkIter<SourceType, S: ObservableConvertibleType, O: ObserverType
func on(event: Event<E>) {
switch event {
case .Next(let value):
_parent._lock.performLocked {
_parent.observer?.on(.Next(value))
}
_parent._lock.lock(); defer { _parent._lock.unlock() } // lock {
_parent.forwardOn(.Next(value))
// }
case .Error(let error):
_parent._lock.performLocked {
_parent.observer?.on(.Error(error))
_parent._lock.lock(); defer { _parent._lock.unlock() } // lock {
_parent.forwardOn(.Error(error))
_parent.dispose()
}
// }
case .Completed:
_parent._group.removeDisposable(_disposeKey)
// If this has returned true that means that `Completed` should be sent.
@ -43,10 +43,10 @@ class FlatMapSinkIter<SourceType, S: ObservableConvertibleType, O: ObserverType
// it will set observer to nil, and thus prevent further complete messages
// to be sent, and thus preserving the sequence grammar.
if _parent._stopped && _parent._group.count == FlatMapNoIterators {
_parent._lock.performLocked {
_parent.observer?.on(.Completed)
_parent._lock.lock(); defer { _parent._lock.unlock() } // lock {
_parent.forwardOn(.Completed)
_parent.dispose()
}
// }
}
}
}
@ -67,9 +67,9 @@ class FlatMapSink<SourceType, S: ObservableConvertibleType, O: ObserverType wher
private var _stopped = false
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func performMap(element: SourceType) throws -> S {
@ -77,8 +77,6 @@ class FlatMapSink<SourceType, S: ObservableConvertibleType, O: ObserverType wher
}
func on(event: Event<SourceType>) {
let observer = super.observer
switch event {
case .Next(let element):
do {
@ -86,31 +84,25 @@ class FlatMapSink<SourceType, S: ObservableConvertibleType, O: ObserverType wher
subscribeInner(value.asObservable())
}
catch let e {
observer?.on(.Error(e))
forwardOn(.Error(e))
dispose()
}
case .Error(let error):
_lock.performLocked {
observer?.on(.Error(error))
_lock.lock(); defer { _lock.unlock() } // lock {
forwardOn(.Error(error))
dispose()
}
// }
case .Completed:
_lock.performLocked {
final()
}
}
}
func final() {
_stopped = true
if _group.count == FlatMapNoIterators {
_lock.performLocked {
observer?.on(.Completed)
dispose()
}
}
else {
_sourceSubscription.dispose()
_lock.lock(); defer { _lock.unlock() } // lock {
_stopped = true
if _group.count == FlatMapNoIterators {
forwardOn(.Completed)
dispose()
}
else {
_sourceSubscription.dispose()
}
//}
}
}
@ -134,8 +126,8 @@ class FlatMapSink<SourceType, S: ObservableConvertibleType, O: ObserverType wher
}
class FlatMapSink1<SourceType, S: ObservableConvertibleType, O : ObserverType where S.E == O.E> : FlatMapSink<SourceType, S, O> {
override init(parent: Parent, observer: O, cancel: Disposable) {
super.init(parent: parent, observer: observer, cancel: cancel)
override init(parent: Parent, observer: O) {
super.init(parent: parent, observer: observer)
}
override func performMap(element: SourceType) throws -> S {
@ -146,8 +138,8 @@ class FlatMapSink1<SourceType, S: ObservableConvertibleType, O : ObserverType wh
class FlatMapSink2<SourceType, S: ObservableConvertibleType, O: ObserverType where S.E == O.E> : FlatMapSink<SourceType, S, O> {
private var _index = 0
override init(parent: Parent, observer: O, cancel: Disposable) {
super.init(parent: parent, observer: observer, cancel: cancel)
override init(parent: Parent, observer: O) {
super.init(parent: parent, observer: observer)
}
override func performMap(element: SourceType) throws -> S {
@ -176,17 +168,18 @@ class FlatMap<SourceType, S: ObservableConvertibleType>: Producer<S.E> {
_selector1 = nil
}
override func run<O: ObserverType where O.E == S.E>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func run<O: ObserverType where O.E == S.E>(observer: O) -> Disposable {
let sink: FlatMapSink<SourceType, S, O>
if let _ = _selector1 {
let sink = FlatMapSink1(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
sink = FlatMapSink1(parent: self, observer: observer)
}
else {
let sink = FlatMapSink2(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
sink = FlatMapSink2(parent: self, observer: observer)
}
let subscription = sink.run()
sink.disposable = subscription
return sink
}
}

View File

@ -15,10 +15,10 @@ class GenerateSink<S, O: ObserverType> : Sink<O> {
private var _state: S
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
_state = parent._initialState
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
@ -30,17 +30,17 @@ class GenerateSink<S, O: ObserverType> : Sink<O> {
if try self._parent._condition(self._state) {
let result = try self._parent._resultSelector(self._state)
self.observer?.on(.Next(result))
self.forwardOn(.Next(result))
recurse(false)
}
else {
self.observer?.on(.Completed)
self.forwardOn(.Completed)
self.dispose()
}
}
catch let error {
self.observer?.on(.Error(error))
self.forwardOn(.Error(error))
self.dispose()
}
}
@ -63,9 +63,9 @@ class Generate<S, E> : Producer<E> {
super.init()
}
override func run<O : ObserverType where O.E == E>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = GenerateSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == E>(observer: O) -> Disposable {
let sink = GenerateSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -15,7 +15,7 @@ class Just<Element> : Producer<Element> {
_element = element
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func subscribe<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
observer.on(.Next(_element))
observer.on(.Completed)
return NopDisposable.instance

View File

@ -15,9 +15,9 @@ class MapSink<SourceType, O : ObserverType> : Sink<O>, ObserverType {
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func performMap(element: SourceType) throws -> ResultType {
@ -25,23 +25,21 @@ class MapSink<SourceType, O : ObserverType> : Sink<O>, ObserverType {
}
func on(event: Event<SourceType>) {
let observer = super.observer
switch event {
case .Next(let element):
do {
let mappedElement = try performMap(element)
observer?.on(.Next(mappedElement))
forwardOn(.Next(mappedElement))
}
catch let e {
observer?.on(.Error(e))
forwardOn(.Error(e))
dispose()
}
case .Error(let error):
observer?.on(.Error(error))
forwardOn(.Error(error))
dispose()
case .Completed:
observer?.on(.Completed)
forwardOn(.Completed)
dispose()
}
}
@ -50,8 +48,8 @@ class MapSink<SourceType, O : ObserverType> : Sink<O>, ObserverType {
class MapSink1<SourceType, O: ObserverType> : MapSink<SourceType, O> {
typealias ResultType = O.E
override init(parent: Map<SourceType, ResultType>, observer: O, cancel: Disposable) {
super.init(parent: parent, observer: observer, cancel: cancel)
override init(parent: Map<SourceType, ResultType>, observer: O) {
super.init(parent: parent, observer: observer)
}
override func performMap(element: SourceType) throws -> ResultType {
@ -64,8 +62,8 @@ class MapSink2<SourceType, O: ObserverType> : MapSink<SourceType, O> {
private var _index = 0
override init(parent: Map<SourceType, ResultType>, observer: O, cancel: Disposable) {
super.init(parent: parent, observer: observer, cancel: cancel)
override init(parent: Map<SourceType, ResultType>, observer: O) {
super.init(parent: parent, observer: observer)
}
override func performMap(element: SourceType) throws -> ResultType {
return try _parent._selector2!(element, try incrementChecked(&_index))
@ -93,16 +91,16 @@ class Map<SourceType, ResultType>: Producer<ResultType> {
_selector1 = nil
}
override func run<O: ObserverType where O.E == ResultType>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func run<O: ObserverType where O.E == ResultType>(observer: O) -> Disposable {
if let _ = _selector1 {
let sink = MapSink1(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
let sink = MapSink1(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
else {
let sink = MapSink2(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
let sink = MapSink2(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}

View File

@ -10,46 +10,59 @@ import Foundation
// sequential
class MergeSinkIter<S: ObservableConvertibleType, O: ObserverType where O.E == S.E> : ObserverType {
class MergeSinkIter<S: ObservableConvertibleType, O: ObserverType where O.E == S.E>
: ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias E = O.E
typealias DisposeKey = Bag<Disposable>.KeyType
typealias Parent = MergeSink<S, O>
private let _parent: Parent
private let _disposeKey: DisposeKey
var _lock: NSRecursiveLock {
return _parent._lock
}
init(parent: Parent, disposeKey: DisposeKey) {
_parent = parent
_disposeKey = disposeKey
}
func on(event: Event<E>) {
_parent._lock.performLocked {
switch event {
case .Next:
_parent.observer?.on(event)
case .Error:
_parent.observer?.on(event)
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next:
_parent.forwardOn(event)
case .Error:
_parent.forwardOn(event)
_parent.dispose()
case .Completed:
_parent._group.removeDisposable(_disposeKey)
if _parent._stopped && _parent._group.count == 1 {
_parent.forwardOn(.Completed)
_parent.dispose()
case .Completed:
_parent._group.removeDisposable(_disposeKey)
if _parent._stopped && _parent._group.count == 1 {
_parent.observer?.on(.Completed)
_parent.dispose()
}
}
}
}
}
class MergeSink<S: ObservableConvertibleType, O: ObserverType where O.E == S.E> : Sink<O>, ObserverType {
class MergeSink<S: ObservableConvertibleType, O: ObserverType where O.E == S.E>
: Sink<O>
, ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias E = S
typealias Parent = Merge<S>
private let _parent: Parent
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
// state
private var _stopped = false
@ -57,10 +70,10 @@ class MergeSink<S: ObservableConvertibleType, O: ObserverType where O.E == S.E>
private let _group = CompositeDisposable()
private let _sourceSubscription = SingleAssignmentDisposable()
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
@ -73,8 +86,7 @@ class MergeSink<S: ObservableConvertibleType, O: ObserverType where O.E == S.E>
}
func on(event: Event<E>) {
switch event {
case .Next(let value):
if case .Next(let value) = event {
let innerSubscription = SingleAssignmentDisposable()
let maybeKey = _group.addDisposable(innerSubscription)
@ -83,22 +95,29 @@ class MergeSink<S: ObservableConvertibleType, O: ObserverType where O.E == S.E>
let disposable = value.asObservable().subscribe(observer)
innerSubscription.disposable = disposable
}
return
}
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next:
rxFatalError("Next should have been handled")
case .Error(let error):
_lock.performLocked {
observer?.on(.Error(error))
forwardOn(.Error(error))
dispose()
case .Completed:
_stopped = true
if _group.count == 1 {
forwardOn(.Completed)
dispose()
}
case .Completed:
_lock.performLocked {
_stopped = true
if _group.count == 1 {
observer?.on(.Completed)
dispose()
}
else {
_sourceSubscription.dispose()
}
else {
_sourceSubscription.dispose()
}
}
}
@ -106,13 +125,20 @@ class MergeSink<S: ObservableConvertibleType, O: ObserverType where O.E == S.E>
// concurrent
class MergeConcurrentSinkIter<S: ObservableConvertibleType, O: ObserverType where S.E == O.E> : ObserverType {
class MergeConcurrentSinkIter<S: ObservableConvertibleType, O: ObserverType where S.E == O.E>
: ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias E = O.E
typealias DisposeKey = Bag<Disposable>.KeyType
typealias Parent = MergeConcurrentSink<S, O>
private let _parent: Parent
private let _disposeKey: DisposeKey
var _lock: NSRecursiveLock {
return _parent._lock
}
init(parent: Parent, disposeKey: DisposeKey) {
_parent = parent
@ -120,42 +146,48 @@ class MergeConcurrentSinkIter<S: ObservableConvertibleType, O: ObserverType wher
}
func on(event: Event<E>) {
_parent._lock.performLocked {
switch event {
case .Next:
_parent.observer?.on(event)
case .Error:
_parent.observer?.on(event)
_parent.dispose()
case .Completed:
_parent._group.removeDisposable(_disposeKey)
let queue = _parent._queue
if queue.value.count > 0 {
let s = queue.value.dequeue()
_parent.subscribe(s, group: _parent._group)
}
else {
_parent._activeCount = _parent._activeCount - 1
if _parent._stopped && _parent._activeCount == 0 {
_parent.observer?.on(.Completed)
_parent.dispose()
}
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next:
_parent.forwardOn(event)
case .Error:
_parent.forwardOn(event)
_parent.dispose()
case .Completed:
_parent._group.removeDisposable(_disposeKey)
let queue = _parent._queue
if queue.value.count > 0 {
let s = queue.value.dequeue()
_parent.subscribe(s, group: _parent._group)
}
else {
_parent._activeCount = _parent._activeCount - 1
if _parent._stopped && _parent._activeCount == 0 {
_parent.forwardOn(.Completed)
_parent.dispose()
}
}
}
}
}
class MergeConcurrentSink<S: ObservableConvertibleType, O: ObserverType where S.E == O.E> : Sink<O>, ObserverType {
class MergeConcurrentSink<S: ObservableConvertibleType, O: ObserverType where S.E == O.E>
: Sink<O>
, ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias E = S
typealias Parent = Merge<S>
typealias QueueType = Queue<S>
private let _parent: Parent
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
// state
private var _stopped = false
private var _activeCount = 0
@ -164,11 +196,11 @@ class MergeConcurrentSink<S: ObservableConvertibleType, O: ObserverType where S.
private let _sourceSubscription = SingleAssignmentDisposable()
private let _group = CompositeDisposable()
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
_group.addDisposable(_sourceSubscription)
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
@ -193,39 +225,38 @@ class MergeConcurrentSink<S: ObservableConvertibleType, O: ObserverType where S.
}
func on(event: Event<E>) {
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next(let value):
let subscribe = _lock.calculateLocked { () -> Bool in
if _activeCount < _parent._maxConcurrent {
_activeCount += 1
return true
}
else {
_queue.value.enqueue(value)
return false
}
let subscribe: Bool
if _activeCount < _parent._maxConcurrent {
_activeCount += 1
subscribe = true
}
else {
_queue.value.enqueue(value)
subscribe = false
}
if subscribe {
self.subscribe(value, group: _group)
}
case .Error(let error):
_lock.performLocked {
observer?.on(.Error(error))
forwardOn(.Error(error))
dispose()
case .Completed:
if _activeCount == 0 {
forwardOn(.Completed)
dispose()
}
case .Completed:
_lock.performLocked {
if _activeCount == 0 {
observer?.on(.Completed)
dispose()
}
else {
_sourceSubscription.dispose()
}
_stopped = true
else {
_sourceSubscription.dispose()
}
_stopped = true
}
}
}
@ -239,16 +270,16 @@ class Merge<S: ObservableConvertibleType> : Producer<S.E> {
_maxConcurrent = maxConcurrent
}
override func run<O: ObserverType where O.E == S.E>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func run<O: ObserverType where O.E == S.E>(observer: O) -> Disposable {
if _maxConcurrent > 0 {
let sink = MergeConcurrentSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
let sink = MergeConcurrentSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
else {
let sink = MergeSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
let sink = MergeSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
}

View File

@ -15,9 +15,9 @@ class MulticastSink<S: SubjectType, O: ObserverType>: Sink<O>, ObserverType {
private let _parent: MutlicastType
init(parent: MutlicastType, observer: O, cancel: Disposable) {
init(parent: MutlicastType, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
@ -33,14 +33,14 @@ class MulticastSink<S: SubjectType, O: ObserverType>: Sink<O>, ObserverType {
return BinaryDisposable(subscription, connection)
}
catch let e {
observer?.on(.Error(e))
forwardOn(.Error(e))
dispose()
return NopDisposable.instance
}
}
func on(event: Event<ResultType>) {
observer?.on(event)
forwardOn(event)
switch event {
case .Next: break
case .Error, .Completed:
@ -63,9 +63,9 @@ class Multicast<S: SubjectType, R>: Producer<R> {
_selector = selector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = MulticastSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = MulticastSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -9,7 +9,7 @@
import Foundation
class Never<Element> : Producer<Element> {
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func subscribe<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
return NopDisposable.instance
}
}

View File

@ -21,10 +21,10 @@ class ObserveOn<E> : Producer<E> {
#endif
}
override func run<O : ObserverType where O.E == E>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ObserveOnSink(scheduler: scheduler, observer: observer, cancel: cancel)
setSink(sink)
return source.subscribe(sink)
override func run<O : ObserverType where O.E == E>(observer: O) -> Disposable {
let sink = ObserveOnSink(scheduler: scheduler, observer: observer)
sink._subscription.disposable = source.subscribe(sink)
return sink
}
#if TRACE_RESOURCES
@ -44,31 +44,30 @@ enum ObserveOnState : Int32 {
class ObserveOnSink<O: ObserverType> : ObserverBase<O.E> {
typealias E = O.E
var cancel: Disposable
var lock = SpinLock()
let scheduler: ImmediateSchedulerType
var observer: O?
var state = ObserveOnState.Stopped
var queue = Queue<Event<E>>(capacity: 10)
let scheduleDisposable = SerialDisposable()
init(scheduler: ImmediateSchedulerType, observer: O, cancel: Disposable) {
self.cancel = cancel
self.scheduler = scheduler
self.observer = observer
let _scheduler: ImmediateSchedulerType
var _lock = SpinLock()
// state
var _state = ObserveOnState.Stopped
var _observer: O?
var _queue = Queue<Event<E>>(capacity: 10)
let _scheduleDisposable = SerialDisposable()
let _subscription = SingleAssignmentDisposable()
init(scheduler: ImmediateSchedulerType, observer: O) {
_scheduler = scheduler
_observer = observer
}
override func onCore(event: Event<E>) {
let shouldStart = lock.calculateLocked { () -> Bool in
self.queue.enqueue(event)
let shouldStart = _lock.calculateLocked { () -> Bool in
self._queue.enqueue(event)
switch self.state {
switch self._state {
case .Stopped:
self.state = .Running
self._state = .Running
return true
case .Running:
return false
@ -76,18 +75,18 @@ class ObserveOnSink<O: ObserverType> : ObserverBase<O.E> {
}
if shouldStart {
scheduleDisposable.disposable = self.scheduler.scheduleRecursive((), action: self.run)
_scheduleDisposable.disposable = self._scheduler.scheduleRecursive((), action: self.run)
}
}
func run(state: Void, recurse: Void -> Void) {
let (nextEvent, observer) = self.lock.calculateLocked { () -> (Event<E>?, O?) in
if self.queue.count > 0 {
return (self.queue.dequeue(), self.observer)
let (nextEvent, observer) = self._lock.calculateLocked { () -> (Event<E>?, O?) in
if self._queue.count > 0 {
return (self._queue.dequeue(), self._observer)
}
else {
self.state = .Stopped
return (nil, self.observer)
self._state = .Stopped
return (nil, self._observer)
}
}
@ -101,32 +100,34 @@ class ObserveOnSink<O: ObserverType> : ObserverBase<O.E> {
return
}
let shouldContinue = self.lock.calculateLocked { () -> Bool in
if self.queue.count > 0 {
return true
}
else {
self.state = .Stopped
return false
}
}
let shouldContinue = _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
}
// }
}
override func dispose() {
super.dispose()
_subscription.dispose()
_scheduleDisposable.dispose()
_lock.lock(); defer { _lock.unlock() } // {
_observer = nil
let toDispose = lock.calculateLocked { () -> Disposable in
let originalCancel = self.cancel
self.cancel = NopDisposable.instance
self.scheduleDisposable.dispose()
self.observer = nil
return originalCancel
}
toDispose.dispose()
// }
}
}

View File

@ -18,43 +18,37 @@ public var numberOfSerialDispatchQueueObservables: Int32 = 0
#endif
class ObserveOnSerialDispatchQueueSink<O: ObserverType> : ObserverBase<O.E> {
let scheduler: SerialDispatchQueueScheduler
let observer: O
var disposeLock = SpinLock()
var cancel: Disposable
init(scheduler: SerialDispatchQueueScheduler, observer: O, cancel: Disposable) {
self.cancel = cancel
let subscription = SingleAssignmentDisposable()
var cachedScheduleLambda: ((ObserveOnSerialDispatchQueueSink<O>, Event<E>) -> Disposable)!
init(scheduler: SerialDispatchQueueScheduler, observer: O) {
self.scheduler = scheduler
self.observer = observer
super.init()
cachedScheduleLambda = { sink, event in
sink.observer.on(event)
if event.isStopEvent {
sink.dispose()
}
return NopDisposable.instance
}
}
override func onCore(event: Event<E>) {
self.scheduler.schedule(()) { (_) -> Disposable in
self.observer.on(event)
if event.isStopEvent {
self.dispose()
}
return NopDisposable.instance
}
self.scheduler.schedule((self, event), action: cachedScheduleLambda)
}
override func dispose() {
super.dispose()
let toDispose = disposeLock.calculateLocked { () -> Disposable in
let originalCancel = self.cancel
self.cancel = NopDisposable.instance
return originalCancel
}
toDispose.dispose()
subscription.dispose()
}
}
@ -72,10 +66,10 @@ class ObserveOnSerialDispatchQueue<E> : Producer<E> {
#endif
}
override func run<O : ObserverType where O.E == E>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ObserveOnSerialDispatchQueueSink(scheduler: scheduler, observer: observer, cancel: cancel)
setSink(sink)
return source.subscribe(sink)
override func run<O : ObserverType where O.E == E>(observer: O) -> Disposable {
let sink = ObserveOnSerialDispatchQueueSink(scheduler: scheduler, observer: observer)
sink.subscription.disposable = source.subscribe(sink)
return sink
}
#if TRACE_RESOURCES

View File

@ -8,42 +8,23 @@
import Foundation
public class _Producer<Element> : Producer<Element> {
public override init() {
super.init()
}
}
public class Producer<Element> : Observable<Element> {
class Producer<Element> : Observable<Element> {
override init() {
super.init()
}
public override func subscribe<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = SingleAssignmentDisposable()
let subscription = SingleAssignmentDisposable()
let d = BinaryDisposable(sink, subscription)
let setSink: (Disposable) -> Void = { d in sink.disposable = d }
override func subscribe<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
if !CurrentThreadScheduler.isScheduleRequired {
let disposable = run(observer, cancel: subscription, setSink: setSink)
subscription.disposable = disposable
return run(observer)
}
else {
CurrentThreadScheduler.instance.schedule(sink) { sink in
let disposable = self.run(observer, cancel: subscription, setSink: setSink)
subscription.disposable = disposable
return NopDisposable.instance
return CurrentThreadScheduler.instance.schedule(()) { _ in
return self.run(observer)
}
}
return d
}
public func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
abstractMethod()
}
}

View File

@ -27,10 +27,10 @@ class RangeProducer<_CompilerWorkaround> : Producer<Int> {
_scheduler = scheduler
}
override func run<O : ObserverType where O.E == Int>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = RangeSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == Int>(observer: O) -> Disposable {
let sink = RangeSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -39,19 +39,19 @@ class RangeSink<_CompilerWorkaround, O: ObserverType where O.E == Int> : Sink<O>
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
return _parent._scheduler.scheduleRecursive(0) { i, recurse in
if i < self._parent._count {
self.observer?.on(.Next(self._parent._start + i))
self.forwardOn(.Next(self._parent._start + i))
recurse(i + 1)
}
else {
self.observer?.on(.Completed)
self.forwardOn(.Completed)
self.dispose()
}
}

View File

@ -15,11 +15,11 @@ class ReduceSink<SourceType, AccumulateType, O: ObserverType> : Sink<O>, Observe
private let _parent: Parent
private var _accumulation: AccumulateType
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
_accumulation = parent._seed
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<SourceType>) {
@ -29,21 +29,21 @@ class ReduceSink<SourceType, AccumulateType, O: ObserverType> : Sink<O>, Observe
_accumulation = try _parent._accumulator(_accumulation, value)
}
catch let e {
observer?.on(.Error(e))
forwardOn(.Error(e))
dispose()
}
case .Error(let e):
observer?.on(.Error(e))
forwardOn(.Error(e))
dispose()
case .Completed:
do {
let result = try _parent._mapResult(_accumulation)
observer?.on(.Next(result))
observer?.on(.Completed)
forwardOn(.Next(result))
forwardOn(.Completed)
dispose()
}
catch let e {
observer?.on(.Error(e))
forwardOn(.Error(e))
dispose()
}
}
@ -66,9 +66,9 @@ class Reduce<SourceType, AccumulateType, ResultType> : Producer<ResultType> {
_mapResult = mapResult
}
override func run<O: ObserverType where O.E == ResultType>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ReduceSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
override func run<O: ObserverType where O.E == ResultType>(observer: O) -> Disposable {
let sink = ReduceSink(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}

View File

@ -8,21 +8,23 @@
import Foundation
class RefCountSink<CO: ConnectableObservableType, O: ObserverType where CO.E == O.E> : Sink<O>, ObserverType {
class RefCountSink<CO: ConnectableObservableType, O: ObserverType where CO.E == O.E>
: Sink<O>
, ObserverType {
typealias Element = O.E
typealias Parent = RefCount<CO>
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
let subscription = _parent._source.subscribeSafe(self)
_parent._lock.performLocked {
_parent._lock.lock(); defer { _parent._lock.unlock() } // {
if _parent._count == 0 {
_parent._count = 1
_parent._connectableSubscription = _parent._source.connect()
@ -30,11 +32,11 @@ class RefCountSink<CO: ConnectableObservableType, O: ObserverType where CO.E ==
else {
_parent._count = _parent._count + 1
}
}
// }
return AnonymousDisposable {
subscription.dispose()
self._parent._lock.performLocked {
self._parent._lock.lock(); defer { self._parent._lock.unlock() } // {
if self._parent._count == 1 {
self._parent._connectableSubscription!.dispose()
self._parent._count = 0
@ -46,16 +48,16 @@ class RefCountSink<CO: ConnectableObservableType, O: ObserverType where CO.E ==
else {
rxFatalError("Something went wrong with RefCount disposing mechanism")
}
}
// }
}
}
func on(event: Event<Element>) {
switch event {
case .Next:
observer?.on(event)
forwardOn(event)
case .Error, .Completed:
observer?.on(event)
forwardOn(event)
dispose()
}
}
@ -74,9 +76,9 @@ class RefCount<CO: ConnectableObservableType>: Producer<CO.E> {
_source = source
}
override func run<O: ObserverType where O.E == CO.E>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = RefCountSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == CO.E>(observer: O) -> Disposable {
let sink = RefCountSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -17,10 +17,11 @@ class RepeatElement<Element> : Producer<Element> {
_scheduler = scheduler
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = RepeatElementSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = RepeatElementSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -29,14 +30,14 @@ class RepeatElementSink<O: ObserverType> : Sink<O> {
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
return _parent._scheduler.scheduleRecursive(_parent._element) { e, recurse in
self.observer?.on(.Next(e))
self.forwardOn(.Next(e))
recurse(e)
}
}

View File

@ -8,57 +8,70 @@
import Foundation
class SamplerSink<O: ObserverType, ElementType, SampleType where O.E == ElementType> : ObserverType {
class SamplerSink<O: ObserverType, ElementType, SampleType where O.E == ElementType>
: ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias E = SampleType
typealias Parent = SampleSequenceSink<O, SampleType>
private let _parent: Parent
var _lock: NSRecursiveLock {
return _parent._lock
}
init(parent: Parent) {
_parent = parent
}
func on(event: Event<E>) {
_parent._lock.performLocked {
switch event {
case .Next:
if let element = _parent._element {
if _parent._parent._onlyNew {
_parent._element = nil
}
_parent.observer?.on(.Next(element))
}
synchronizedOn(event)
}
if _parent._atEnd {
_parent.observer?.on(.Completed)
_parent.dispose()
}
case .Error(let e):
_parent.observer?.on(.Error(e))
_parent.dispose()
case .Completed:
if let element = _parent._element {
func _synchronized_on(event: Event<E>) {
switch event {
case .Next:
if let element = _parent._element {
if _parent._parent._onlyNew {
_parent._element = nil
_parent.observer?.on(.Next(element))
}
if _parent._atEnd {
_parent.observer?.on(.Completed)
_parent.dispose()
}
_parent.forwardOn(.Next(element))
}
if _parent._atEnd {
_parent.forwardOn(.Completed)
_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()
}
}
}
}
class SampleSequenceSink<O: ObserverType, SampleType> : Sink<O>, ObserverType {
class SampleSequenceSink<O: ObserverType, SampleType>
: Sink<O>
, ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias Element = O.E
typealias Parent = Sample<Element, SampleType>
private let _parent: Parent
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
// state
private var _element = nil as Element?
@ -66,30 +79,32 @@ class SampleSequenceSink<O: ObserverType, SampleType> : Sink<O>, ObserverType {
private let _sourceSubscription = SingleAssignmentDisposable()
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
_sourceSubscription.disposable = _parent._source.subscribe(self)
let samplerSubscription = _parent._sampler.subscribe(SamplerSink(parent: self))
return CompositeDisposable(_sourceSubscription, samplerSubscription)
return StableCompositeDisposable.create(_sourceSubscription, samplerSubscription)
}
func on(event: Event<Element>) {
_lock.performLocked {
switch event {
case .Next(let element):
_element = element
case .Error:
observer?.on(event)
dispose()
case .Completed:
_atEnd = true
_sourceSubscription.dispose()
}
synchronizedOn(event)
}
func _synchronized_on(event: Event<Element>) {
switch event {
case .Next(let element):
_element = element
case .Error:
forwardOn(event)
dispose()
case .Completed:
_atEnd = true
_sourceSubscription.dispose()
}
}
@ -106,9 +121,9 @@ class Sample<Element, SampleType> : Producer<Element> {
_onlyNew = onlyNew
}
override func run<O: ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = SampleSequenceSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = SampleSequenceSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -15,10 +15,10 @@ class ScanSink<ElementType, Accumulate, O: ObserverType where O.E == Accumulate>
private let _parent: Parent
private var _accumulate: Accumulate
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
_accumulate = parent._seed
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<ElementType>) {
@ -26,17 +26,17 @@ class ScanSink<ElementType, Accumulate, O: ObserverType where O.E == Accumulate>
case .Next(let element):
do {
_accumulate = try _parent._accumulator(_accumulate, element)
observer?.on(.Next(_accumulate))
forwardOn(.Next(_accumulate))
}
catch let error {
observer?.on(.Error(error))
forwardOn(.Error(error))
dispose()
}
case .Error(let error):
observer?.on(.Error(error))
forwardOn(.Error(error))
dispose()
case .Completed:
observer?.on(.Completed)
forwardOn(.Completed)
dispose()
}
}
@ -56,9 +56,9 @@ class Scan<Element, Accumulate>: Producer<Accumulate> {
_accumulator = accumulator
}
override func run<O : ObserverType where O.E == Accumulate>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ScanSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
override func run<O : ObserverType where O.E == Accumulate>(observer: O) -> Disposable {
let sink = ScanSink(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}

View File

@ -9,12 +9,21 @@
import Foundation
// optimized version of share replay for most common case
class ShareReplay1<Element> : Observable<Element>, ObserverType {
class ShareReplay1<Element>
: Observable<Element>
, ObserverType
, LockOwnerType
, SynchronizedOnType
, SynchronizedSubscribeType
, SynchronizedUnsubscribeType {
typealias DisposeKey = Bag<AnyObserver<Element>>.KeyType
private let _source: Observable<Element>
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
private var _subscription: Disposable?
private var _connection: SingleAssignmentDisposable?
private var _element: Element?
private var _stopEvent = nil as Event<Element>?
private var _observers = Bag<AnyObserver<Element>>()
@ -24,54 +33,64 @@ class ShareReplay1<Element> : Observable<Element>, ObserverType {
}
override func subscribe<O : ObserverType where O.E == E>(observer: O) -> Disposable {
return _lock.calculateLocked {
if let element = self._element {
observer.on(.Next(element))
}
return synchronizedSubscribe(observer)
}
if let stopEvent = self._stopEvent {
observer.on(stopEvent)
return NopDisposable.instance
}
func _synchronized_subscribe<O : ObserverType where O.E == E>(observer: O) -> Disposable {
if let element = self._element {
observer.on(.Next(element))
}
let initialCount = self._observers.count
if let stopEvent = self._stopEvent {
observer.on(stopEvent)
return NopDisposable.instance
}
let observerKey = self._observers.insert(AnyObserver(observer))
let initialCount = self._observers.count
if initialCount == 0 {
self._subscription = self._source.subscribe(self)
}
let disposeKey = self._observers.insert(AnyObserver(observer))
return AnonymousDisposable {
self._lock.performLocked {
self._observers.removeKey(observerKey)
if initialCount == 0 {
let connection = SingleAssignmentDisposable()
_connection = connection
if self._observers.count == 0 {
self._subscription?.dispose()
self._subscription = nil
}
}
}
connection.disposable = self._source.subscribe(self)
}
return SubscriptionDisposable(owner: self, key: disposeKey)
}
func _synchronized_unsubscribe(disposeKey: DisposeKey) {
// if already unsubscribed, just return
if self._observers.removeKey(disposeKey) == nil {
return
}
if _observers.count == 0 {
_connection?.dispose()
_connection = nil
}
}
func on(event: Event<E>) {
_lock.performLocked {
if self._stopEvent != nil {
return
}
synchronizedOn(event)
}
if case .Next(let element) = event {
self._element = element
}
if event.isStopEvent {
self._stopEvent = event
}
_observers.forEach { o in
o.on(event)
}
func _synchronized_on(event: Event<E>) {
if _stopEvent != nil {
return
}
if case .Next(let element) = event {
_element = element
}
if event.isStopEvent {
_stopEvent = event
_connection?.dispose()
_connection = nil
}
_observers.on(event)
}
}

View File

@ -8,54 +8,23 @@
import Foundation
class Sink<O : ObserverType> : Disposable {
private var _lock = SpinLock()
// state
private var _observer: O?
private var _cancel: Disposable
private var _disposed: Bool = false
var observer: O? {
get {
return _lock.calculateLocked { _observer }
class Sink<O : ObserverType> : SingleAssignmentDisposable {
private let _observer: O
func forwardOn(event: Event<O.E>) {
if disposed {
return
}
_observer.on(event)
}
var cancel: Disposable {
get {
return _lock.calculateLocked { _cancel }
}
}
init(observer: O, cancel: Disposable) {
init(observer: O) {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
#endif
_observer = observer
_cancel = cancel
}
func dispose() {
let cancel: Disposable? = _lock.calculateLocked {
if _disposed {
return nil
}
let cancel = _cancel
_disposed = true
_observer = nil
_cancel = NopDisposable.instance
return cancel
}
if let cancel = cancel {
cancel.dispose()
}
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)

View File

@ -18,10 +18,10 @@ class SkipCountSink<ElementType, O: ObserverType where O.E == ElementType> : Sin
var remaining: Int
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
self.parent = parent
self.remaining = parent.count
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<Element>) {
@ -29,16 +29,16 @@ class SkipCountSink<ElementType, O: ObserverType where O.E == ElementType> : Sin
case .Next(let value):
if remaining <= 0 {
observer?.on(.Next(value))
forwardOn(.Next(value))
}
else {
remaining--
}
case .Error:
observer?.on(event)
forwardOn(event)
self.dispose()
case .Completed:
observer?.on(event)
forwardOn(event)
self.dispose()
}
}
@ -54,10 +54,11 @@ class SkipCount<Element>: Producer<Element> {
self.count = count
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = SkipCountSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return source.subscribe(sink)
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = SkipCountSink(parent: self, observer: observer)
sink.disposable = source.subscribe(sink)
return sink
}
}
@ -72,22 +73,22 @@ class SkipTimeSink<ElementType, S: SchedulerType, O: ObserverType where O.E == E
// state
var open = false
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
self.parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<Element>) {
switch event {
case .Next(let value):
if open {
observer?.on(.Next(value))
forwardOn(.Next(value))
}
case .Error:
observer?.on(event)
forwardOn(event)
self.dispose()
case .Completed:
observer?.on(event)
forwardOn(event)
self.dispose()
}
}
@ -121,9 +122,9 @@ class SkipTime<Element, S: SchedulerType>: Producer<Element> {
self.duration = duration
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = SkipTimeSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = SkipTimeSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -8,22 +8,20 @@
import Foundation
class SkipUntilSinkOther<ElementType, Other, O: ObserverType where O.E == ElementType> : ObserverType {
class SkipUntilSinkOther<ElementType, Other, O: ObserverType where O.E == ElementType>
: ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias Parent = SkipUntilSink<ElementType, Other, O>
typealias E = Other
private let _parent: Parent
private let _singleAssignmentDisposable = SingleAssignmentDisposable()
var disposable: Disposable {
get {
abstractMethod()
}
set {
_singleAssignmentDisposable.disposable = newValue
}
var _lock: NSRecursiveLock {
return _parent._lock
}
let _subscription = SingleAssignmentDisposable()
init(parent: Parent) {
_parent = parent
@ -33,19 +31,19 @@ class SkipUntilSinkOther<ElementType, Other, O: ObserverType where O.E == Elemen
}
func on(event: Event<E>) {
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next:
_parent._lock.performLocked {
_parent._forwardElements = true
_singleAssignmentDisposable.dispose()
}
_parent._forwardElements = true
_subscription.dispose()
case .Error(let e):
_parent._lock.performLocked {
_parent.observer?.onError(e)
_parent.dispose()
}
_parent.forwardOn(.Error(e))
_parent.dispose()
case .Completed:
_singleAssignmentDisposable.dispose()
_subscription.dispose()
}
}
@ -58,46 +56,43 @@ class SkipUntilSinkOther<ElementType, Other, O: ObserverType where O.E == Elemen
}
class SkipUntilSink<ElementType, Other, O: ObserverType where O.E == ElementType> : Sink<O>, ObserverType {
class SkipUntilSink<ElementType, Other, O: ObserverType where O.E == ElementType>
: Sink<O>
, ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias E = ElementType
typealias Parent = SkipUntil<E, Other>
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
private let _parent: Parent
private var _forwardElements = false
private let _singleAssignmentDisposable = SingleAssignmentDisposable()
var disposable: Disposable {
get {
abstractMethod()
}
set {
_singleAssignmentDisposable.disposable = newValue
}
}
init(parent: Parent, observer: O, cancel: Disposable) {
private let _sourceSubscription = SingleAssignmentDisposable()
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<E>) {
_lock.performLocked {
switch event {
case .Next:
if _forwardElements {
observer?.on(event)
}
case .Error:
observer?.on(event)
dispose()
case .Completed:
if _forwardElements {
observer?.on(event)
}
_singleAssignmentDisposable.dispose()
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next:
if _forwardElements {
forwardOn(event)
}
case .Error:
forwardOn(event)
dispose()
case .Completed:
if _forwardElements {
forwardOn(event)
}
_sourceSubscription.dispose()
}
}
@ -105,10 +100,10 @@ class SkipUntilSink<ElementType, Other, O: ObserverType where O.E == ElementType
let sourceSubscription = _parent._source.subscribe(self)
let otherObserver = SkipUntilSinkOther(parent: self)
let otherSubscription = _parent._other.subscribe(otherObserver)
disposable = sourceSubscription
otherObserver.disposable = otherSubscription
_sourceSubscription.disposable = sourceSubscription
otherObserver._subscription.disposable = otherSubscription
return BinaryDisposable(sourceSubscription, otherSubscription)
return StableCompositeDisposable.create(_sourceSubscription, otherObserver._subscription)
}
}
@ -122,9 +117,9 @@ class SkipUntil<Element, Other>: Producer<Element> {
_other = other
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = SkipUntilSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = SkipUntilSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -14,9 +14,9 @@ class SkipWhileSink<ElementType, O: ObserverType where O.E == ElementType> : Sin
private let _parent: Parent
private var _running = false
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<Element>) {
@ -26,17 +26,17 @@ class SkipWhileSink<ElementType, O: ObserverType where O.E == ElementType> : Sin
do {
_running = try !_parent._predicate(value)
} catch let e {
observer?.onError(e)
forwardOn(.Error(e))
dispose()
return
}
}
if _running {
observer?.onNext(value)
forwardOn(.Next(value))
}
case .Error, .Completed:
observer?.on(event)
forwardOn(event)
dispose()
}
}
@ -51,9 +51,9 @@ class SkipWhileSinkWithIndex<ElementType, O: ObserverType where O.E == ElementTy
private var _index = 0
private var _running = false
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<Element>) {
@ -64,17 +64,17 @@ class SkipWhileSinkWithIndex<ElementType, O: ObserverType where O.E == ElementTy
_running = try !_parent._predicateWithIndex(value, _index)
try incrementChecked(&_index)
} catch let e {
observer?.onError(e)
forwardOn(.Error(e))
dispose()
return
}
}
if _running {
observer?.onNext(value)
forwardOn(.Next(value))
}
case .Error, .Completed:
observer?.on(event)
forwardOn(event)
dispose()
}
}
@ -100,16 +100,16 @@ class SkipWhile<Element>: Producer<Element> {
_predicateWithIndex = predicate
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
if let _ = _predicate {
let sink = SkipWhileSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
let sink = SkipWhileSink(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
else {
let sink = SkipWhileSinkWithIndex(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
let sink = SkipWhileSinkWithIndex(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}
}

View File

@ -18,7 +18,7 @@ class StartWith<Element>: Producer<Element> {
super.init()
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
for e in elements {
observer.on(.Next(e))
}

View File

@ -14,13 +14,13 @@ class SubscribeOnSink<Ob: ObservableType, O: ObserverType where Ob.E == O.E> : S
let parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
self.parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<Element>) {
observer?.on(event)
forwardOn(event)
if event.isStopEvent {
self.dispose()
@ -52,9 +52,9 @@ class SubscribeOn<Ob: ObservableType> : Producer<Ob.E> {
self.scheduler = scheduler
}
override func run<O : ObserverType where O.E == Ob.E>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = SubscribeOnSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == Ob.E>(observer: O) -> Disposable {
let sink = SubscribeOnSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -8,7 +8,11 @@
import Foundation
class SwitchSink<S: ObservableConvertibleType, O: ObserverType where S.E == O.E> : Sink<O>, ObserverType {
class SwitchSink<S: ObservableConvertibleType, O: ObserverType where S.E == O.E>
: Sink<O>
, ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias E = S
typealias Parent = Switch<S>
@ -16,34 +20,36 @@ class SwitchSink<S: ObservableConvertibleType, O: ObserverType where S.E == O.E>
private let _innerSubscription: SerialDisposable = SerialDisposable()
private let _parent: Parent
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
// state
private var _stopped = false
private var _latest = 0
private var _hasLatest = false
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
let subscription = _parent._sources.subscribe(self)
_subscriptions.disposable = subscription
return CompositeDisposable(_subscriptions, _innerSubscription)
return StableCompositeDisposable.create(_subscriptions, _innerSubscription)
}
func on(event: Event<E>) {
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next(let observable):
let latest: Int = _lock.calculateLocked {
_hasLatest = true
_latest = _latest &+ 1
return _latest
}
_hasLatest = true
_latest = _latest &+ 1
let latest = _latest
let d = SingleAssignmentDisposable()
_innerSubscription.disposable = d
@ -51,33 +57,36 @@ class SwitchSink<S: ObservableConvertibleType, O: ObserverType where S.E == O.E>
let disposable = observable.asObservable().subscribe(observer)
d.disposable = disposable
case .Error(let error):
_lock.performLocked {
observer?.on(.Error(error))
dispose()
}
forwardOn(.Error(error))
dispose()
case .Completed:
_lock.performLocked {
_stopped = true
_subscriptions.dispose()
if !_hasLatest {
observer?.on(.Completed)
dispose()
}
_stopped = true
_subscriptions.dispose()
if !_hasLatest {
forwardOn(.Completed)
dispose()
}
}
}
}
class SwitchSinkIter<S: ObservableConvertibleType, O: ObserverType where S.E == O.E> : ObserverType {
class SwitchSinkIter<S: ObservableConvertibleType, O: ObserverType where S.E == O.E>
: ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias E = O.E
typealias Parent = SwitchSink<S, O>
private let _parent: Parent
private let _id: Int
private let _self: Disposable
var _lock: NSRecursiveLock {
return _parent._lock
}
init(parent: Parent, id: Int, _self: Disposable) {
_parent = parent
_id = id
@ -85,32 +94,31 @@ class SwitchSinkIter<S: ObservableConvertibleType, O: ObserverType where S.E ==
}
func on(event: Event<E>) {
return _parent._lock.calculateLocked {
switch event {
case .Next: break
case .Error, .Completed:
_self.dispose()
}
if _parent._latest != _id {
return
}
let observer = _parent.observer
switch event {
case .Next:
observer?.on(event)
case .Error:
observer?.on(event)
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next: break
case .Error, .Completed:
_self.dispose()
}
if _parent._latest != _id {
return
}
switch event {
case .Next:
_parent.forwardOn(event)
case .Error:
_parent.forwardOn(event)
_parent.dispose()
case .Completed:
_parent._hasLatest = false
if _parent._stopped {
_parent.forwardOn(event)
_parent.dispose()
case .Completed:
_parent._hasLatest = false
if _parent._stopped {
observer?.on(event)
_parent.dispose()
}
}
}
}
@ -123,9 +131,9 @@ class Switch<S: ObservableConvertibleType> : Producer<S.E> {
_sources = sources
}
override func run<O : ObserverType where O.E == S.E>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = SwitchSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == S.E>(observer: O) -> Disposable {
let sink = SwitchSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -18,10 +18,10 @@ class TakeCountSink<ElementType, O: ObserverType where O.E == ElementType> : Sin
private var _remaining: Int
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
_remaining = parent._count
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<E>) {
@ -31,18 +31,18 @@ class TakeCountSink<ElementType, O: ObserverType where O.E == ElementType> : Sin
if _remaining > 0 {
_remaining--
observer?.on(.Next(value))
forwardOn(.Next(value))
if _remaining == 0 {
observer?.on(.Completed)
forwardOn(.Completed)
dispose()
}
}
case .Error:
observer?.on(event)
forwardOn(event)
dispose()
case .Completed:
observer?.on(event)
forwardOn(event)
dispose()
}
}
@ -61,48 +61,54 @@ class TakeCount<Element>: Producer<Element> {
_count = count
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = TakeCountSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = TakeCountSink(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}
// time version
class TakeTimeSink<ElementType, S: SchedulerType, O: ObserverType where O.E == ElementType> : Sink<O>, ObserverType {
class TakeTimeSink<ElementType, S: SchedulerType, O: ObserverType where O.E == ElementType>
: Sink<O>
, LockOwnerType
, ObserverType
, SynchronizedOnType {
typealias Parent = TakeTime<ElementType, S>
typealias E = ElementType
private let _parent: Parent
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<E>) {
_lock.performLocked {
switch event {
case .Next(let value):
observer?.on(.Next(value))
case .Error:
observer?.on(event)
dispose()
case .Completed:
observer?.on(event)
dispose()
}
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next(let value):
forwardOn(.Next(value))
case .Error:
forwardOn(event)
dispose()
case .Completed:
forwardOn(event)
dispose()
}
}
func tick() {
_lock.performLocked {
observer?.on(.Completed)
dispose()
}
_lock.lock(); defer { _lock.unlock() }
forwardOn(.Completed)
dispose()
}
func run() -> Disposable {
@ -130,9 +136,9 @@ class TakeTime<Element, S: SchedulerType>: Producer<Element> {
_duration = duration
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = TakeTimeSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = TakeTimeSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -17,10 +17,10 @@ class TakeLastSink<ElementType, O: ObserverType where O.E == ElementType> : Sink
private var _elements: Queue<ElementType>
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
_elements = Queue<ElementType>(capacity: parent._count + 1)
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<E>) {
@ -31,13 +31,13 @@ class TakeLastSink<ElementType, O: ObserverType where O.E == ElementType> : Sink
_elements.dequeue()
}
case .Error:
observer?.on(event)
forwardOn(event)
dispose()
case .Completed:
for e in _elements {
observer?.on(.Next(e))
forwardOn(.Next(e))
}
observer?.on(.Completed)
forwardOn(.Completed)
dispose()
}
}
@ -55,9 +55,9 @@ class TakeLast<Element>: Producer<Element> {
_count = count
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = TakeLastSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = TakeLastSink(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}

View File

@ -8,23 +8,21 @@
import Foundation
class TakeUntilSinkOther<ElementType, Other, O: ObserverType where O.E == ElementType> : ObserverType {
class TakeUntilSinkOther<ElementType, Other, O: ObserverType where O.E == ElementType>
: ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias Parent = TakeUntilSink<ElementType, Other, O>
typealias E = Other
private let _parent: Parent
private let _singleAssignmentDisposable = SingleAssignmentDisposable()
var disposable: Disposable {
get {
abstractMethod()
}
set(value) {
_singleAssignmentDisposable.disposable = value
}
var _lock: NSRecursiveLock {
return _parent._lock
}
private let _subscription = SingleAssignmentDisposable()
init(parent: Parent) {
_parent = parent
#if TRACE_RESOURCES
@ -33,18 +31,20 @@ class TakeUntilSinkOther<ElementType, Other, O: ObserverType where O.E == Elemen
}
func on(event: Event<E>) {
_parent._lock.performLocked {
switch event {
case .Next:
_parent.observer?.on(.Completed)
_parent.dispose()
case .Error(let e):
_parent.observer?.on(.Error(e))
_parent.dispose()
case .Completed:
_parent._open = true
_singleAssignmentDisposable.dispose()
}
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next:
_parent.forwardOn(.Completed)
_parent.dispose()
case .Error(let e):
_parent.forwardOn(.Error(e))
_parent.dispose()
case .Completed:
_parent._open = true
_subscription.dispose()
}
}
@ -55,53 +55,50 @@ class TakeUntilSinkOther<ElementType, Other, O: ObserverType where O.E == Elemen
#endif
}
class TakeUntilSink<ElementType, Other, O: ObserverType where O.E == ElementType> : Sink<O>, ObserverType {
class TakeUntilSink<ElementType, Other, O: ObserverType where O.E == ElementType>
: Sink<O>
, LockOwnerType
, ObserverType
, SynchronizedOnType {
typealias E = ElementType
typealias Parent = TakeUntil<E, Other>
private let _parent: Parent
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
// state
private var _open = false
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<E>) {
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next:
if _open {
observer?.on(event)
}
else {
_lock.performLocked {
observer?.on(event)
}
}
forwardOn(event)
case .Error:
_lock.performLocked {
observer?.on(event)
dispose()
}
forwardOn(event)
dispose()
case .Completed:
_lock.performLocked {
observer?.on(event)
dispose()
}
forwardOn(event)
dispose()
}
}
func run() -> Disposable {
let otherObserver = TakeUntilSinkOther(parent: self)
let otherSubscription = _parent._other.subscribe(otherObserver)
otherObserver.disposable = otherSubscription
otherObserver._subscription.disposable = otherSubscription
let sourceSubscription = _parent._source.subscribe(self)
return CompositeDisposable(sourceSubscription, otherSubscription)
return StableCompositeDisposable.create(sourceSubscription, otherObserver._subscription)
}
}
@ -115,9 +112,9 @@ class TakeUntil<Element, Other>: Producer<Element> {
_other = other
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = TakeUntilSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = TakeUntilSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -8,7 +8,9 @@
import Foundation
class TakeWhileSink<ElementType, O: ObserverType where O.E == ElementType> : Sink<O>, ObserverType {
class TakeWhileSink<ElementType, O: ObserverType where O.E == ElementType>
: Sink<O>
, ObserverType {
typealias Parent = TakeWhile<ElementType>
typealias Element = ElementType
@ -16,9 +18,9 @@ class TakeWhileSink<ElementType, O: ObserverType where O.E == ElementType> : Sin
private var _running = true
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<Element>) {
@ -31,26 +33,28 @@ class TakeWhileSink<ElementType, O: ObserverType where O.E == ElementType> : Sin
do {
_running = try _parent._predicate(value)
} catch let e {
observer?.onError(e)
forwardOn(.Error(e))
dispose()
return
}
if _running {
observer?.onNext(value)
forwardOn(.Next(value))
} else {
observer?.onComplete()
forwardOn(.Completed)
dispose()
}
case .Error, .Completed:
observer?.on(event)
forwardOn(event)
dispose()
}
}
}
class TakeWhileSinkWithIndex<ElementType, O: ObserverType where O.E == ElementType> : Sink<O>, ObserverType {
class TakeWhileSinkWithIndex<ElementType, O: ObserverType where O.E == ElementType>
: Sink<O>
, ObserverType {
typealias Parent = TakeWhile<ElementType>
typealias Element = ElementType
@ -59,9 +63,9 @@ class TakeWhileSinkWithIndex<ElementType, O: ObserverType where O.E == ElementTy
private var _running = true
private var _index = 0
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<Element>) {
@ -75,19 +79,19 @@ class TakeWhileSinkWithIndex<ElementType, O: ObserverType where O.E == ElementTy
_running = try _parent._predicateWithIndex(value, _index)
try incrementChecked(&_index)
} catch let e {
observer?.onError(e)
forwardOn(.Error(e))
dispose()
return
}
if _running {
observer?.onNext(value)
forwardOn(.Next(value))
} else {
observer?.onComplete()
forwardOn(.Completed)
dispose()
}
case .Error, .Completed:
observer?.on(event)
forwardOn(event)
dispose()
}
}
@ -114,15 +118,15 @@ class TakeWhile<Element>: Producer<Element> {
_predicateWithIndex = predicate
}
override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func run<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
if let _ = _predicate {
let sink = TakeWhileSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
let sink = TakeWhileSink(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
} else {
let sink = TakeWhileSinkWithIndex(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
let sink = TakeWhileSinkWithIndex(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}
}

View File

@ -8,13 +8,17 @@
import Foundation
class ThrottleSink<O: ObserverType, Scheduler: SchedulerType> : Sink<O>, ObserverType {
class ThrottleSink<O: ObserverType, Scheduler: SchedulerType>
: Sink<O>
, ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias Element = O.E
typealias ParentType = Throttle<Element, Scheduler>
private let _parent: ParentType
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
// state
private var _id = 0 as UInt64
@ -22,81 +26,60 @@ class ThrottleSink<O: ObserverType, Scheduler: SchedulerType> : Sink<O>, Observe
let cancellable = SerialDisposable()
init(parent: ParentType, observer: O, cancel: Disposable) {
init(parent: ParentType, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
let subscription = _parent._source.subscribe(self)
return CompositeDisposable(subscription, cancellable)
return StableCompositeDisposable.create(subscription, cancellable)
}
func on(event: Event<Element>) {
synchronizedOn(event)
}
func _synchronized_on(event: Event<Element>) {
switch event {
case .Next:
break
case .Error, .Completed:
cancellable.dispose()
}
let latestId = _lock.calculateLocked { () -> UInt64 in
let observer = self.observer
let oldValue = _value
case .Next(let element):
_id = _id &+ 1
switch event {
case .Next(let element):
_value = element
case .Error:
_value = nil
observer?.on(event)
dispose()
case .Completed:
_value = nil
if let value = oldValue {
observer?.on(.Next(value))
}
observer?.on(.Completed)
dispose()
}
return _id
}
switch event {
case .Next:
let d = SingleAssignmentDisposable()
self.cancellable.disposable = d
let currentId = _id
_value = element
let scheduler = _parent._scheduler
let dueTime = _parent._dueTime
let disposeTimer = scheduler.scheduleRelative(latestId, dueTime: dueTime) { (id) in
self.propagate()
return NopDisposable.instance
let d = SingleAssignmentDisposable()
self.cancellable.disposable = d
d.disposable = scheduler.scheduleRelative(currentId, dueTime: dueTime, action: self.propagate)
case .Error:
_value = nil
forwardOn(event)
dispose()
case .Completed:
if let value = _value {
_value = nil
forwardOn(.Next(value))
}
d.disposable = disposeTimer
default: break
forwardOn(.Completed)
dispose()
}
}
func propagate() {
let originalValue: Element? = _lock.calculateLocked {
func propagate(currentId: UInt64) -> Disposable {
_lock.lock(); defer { _lock.unlock() } // {
let originalValue = _value
_value = nil
return originalValue
}
if let value = originalValue {
observer?.on(.Next(value))
}
if let value = originalValue where _id == currentId {
_value = nil
forwardOn(.Next(value))
}
// }
return NopDisposable.instance
}
}
@ -112,10 +95,10 @@ class Throttle<Element, Scheduler: SchedulerType> : Producer<Element> {
_scheduler = scheduler
}
override func run<O: ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ThrottleSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == Element>(observer: O) -> Disposable {
let sink = ThrottleSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -13,14 +13,14 @@ class TimerSink<S: SchedulerType, O: ObserverType where O.E == Int64> : Sink<O>
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
return _parent._scheduler.schedulePeriodic(0 as Int64, startAfter: _parent._dueTime, period: _parent._period!) { state in
self.observer?.on(.Next(state))
self.forwardOn(.Next(state))
return state &+ 1
}
}
@ -31,15 +31,15 @@ class TimerOneOffSink<S: SchedulerType, O: ObserverType where O.E == Int64> : Si
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
return _parent._scheduler.scheduleRelative((), dueTime: _parent._dueTime) { (_) -> Disposable in
self.observer?.on(.Next(0))
self.observer?.on(.Completed)
self.forwardOn(.Next(0))
self.forwardOn(.Completed)
return NopDisposable.instance
}
@ -59,16 +59,16 @@ class Timer<S: SchedulerType>: Producer<Int64> {
_period = period
}
override func run<O : ObserverType where O.E == Int64>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func run<O : ObserverType where O.E == Int64>(observer: O) -> Disposable {
if let _ = _period {
let sink = TimerSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
let sink = TimerSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
else {
let sink = TimerOneOffSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
let sink = TimerOneOffSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
}

View File

@ -14,10 +14,10 @@ class ToArraySink<SourceType, O: ObserverType where O.E == [SourceType]> : Sink<
let _parent: Parent
var _list = Array<SourceType>()
init(parent: Parent, observer: O, cancel: Disposable) {
self._parent = parent
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<SourceType>) {
@ -25,11 +25,11 @@ class ToArraySink<SourceType, O: ObserverType where O.E == [SourceType]> : Sink<
case .Next(let value):
self._list.append(value)
case .Error(let e):
observer?.on(.Error(e))
forwardOn(.Error(e))
self.dispose()
case .Completed:
observer?.on(.Next(_list))
observer?.on(.Completed)
forwardOn(.Next(_list))
forwardOn(.Completed)
self.dispose()
}
}
@ -42,9 +42,9 @@ class ToArray<SourceType> : Producer<[SourceType]> {
_source = source
}
override func run<O: ObserverType where O.E == [SourceType]>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ToArraySink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return _source.subscribe(sink)
override func run<O: ObserverType where O.E == [SourceType]>(observer: O) -> Disposable {
let sink = ToArraySink(parent: self, observer: observer)
sink.disposable = _source.subscribe(sink)
return sink
}
}

View File

@ -15,9 +15,9 @@ class UsingSink<SourceType, ResourceType: Disposable, O: ObserverType where O.E
private let _parent: Parent
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
@ -43,12 +43,12 @@ class UsingSink<SourceType, ResourceType: Disposable, O: ObserverType where O.E
func on(event: Event<E>) {
switch event {
case let .Next(value):
observer?.onNext(value)
forwardOn(.Next(value))
case let .Error(error):
observer?.onError(error)
forwardOn(.Error(error))
dispose()
case .Completed:
observer?.onComplete()
forwardOn(.Completed)
dispose()
}
}
@ -70,9 +70,9 @@ class Using<SourceType, ResourceType: Disposable>: Producer<SourceType> {
_observableFactory = observableFactory
}
override func run<O : ObserverType where O.E == E>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = UsingSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == E>(observer: O) -> Disposable {
let sink = UsingSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -8,21 +8,24 @@
import Foundation
class WithLatestFromSink<FirstType, SecondType, ResultType, O: ObserverType where O.E == ResultType > : Sink<O>, ObserverType {
class WithLatestFromSink<FirstType, SecondType, ResultType, O: ObserverType where O.E == ResultType>
: Sink<O>
, ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias Parent = WithLatestFrom<FirstType, SecondType, ResultType>
typealias E = FirstType
private let _parent: Parent
private var _lock = NSRecursiveLock()
var _lock = NSRecursiveLock()
private var _latest: SecondType?
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func run() -> Disposable {
@ -34,60 +37,70 @@ class WithLatestFromSink<FirstType, SecondType, ResultType, O: ObserverType wher
return StableCompositeDisposable.create(fstSubscription, sndSubscription)
}
func on(event: Event<E>) {
_lock.performLocked {
switch event {
case let .Next(value):
guard let latest = _latest else { return }
do {
let res = try _parent._resultSelector(value, latest)
observer?.onNext(res)
} catch let e {
observer?.onError(e)
dispose()
}
case .Completed:
observer?.onComplete()
dispose()
case let .Error(error):
observer?.onError(error)
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case let .Next(value):
guard let latest = _latest else { return }
do {
let res = try _parent._resultSelector(value, latest)
forwardOn(.Next(res))
} catch let e {
forwardOn(.Error(e))
dispose()
}
case .Completed:
forwardOn(.Completed)
dispose()
case let .Error(error):
forwardOn(.Error(error))
dispose()
}
}
}
class WithLatestFromSecond<FirstType, SecondType, ResultType, O: ObserverType where O.E == ResultType>: ObserverType {
class WithLatestFromSecond<FirstType, SecondType, ResultType, O: ObserverType where O.E == ResultType>
: ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias Parent = WithLatestFromSink<FirstType, SecondType, ResultType, O>
typealias E = SecondType
private let _parent: Parent
private let _disposable: Disposable
var _lock: NSRecursiveLock {
get {
return _parent._lock
}
}
init(parent: Parent, disposable: Disposable) {
_parent = parent
_disposable = disposable
}
func on(event: Event<E>) {
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case let .Next(value):
_parent._lock.performLocked {
_parent._latest = value
}
_parent._latest = value
case .Completed:
_disposable.dispose()
case let .Error(error):
_parent._lock.performLocked {
_parent.observer?.onError(error)
_parent.dispose()
}
_parent.forwardOn(.Error(error))
_parent.dispose()
}
}
}
class WithLatestFrom<FirstType, SecondType, ResultType>: Producer<ResultType> {
@ -103,10 +116,9 @@ class WithLatestFrom<FirstType, SecondType, ResultType>: Producer<ResultType> {
_resultSelector = resultSelector
}
override func run<O : ObserverType where O.E == ResultType>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = WithLatestFromSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == ResultType>(observer: O) -> Disposable {
let sink = WithLatestFromSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -8,7 +8,8 @@
import Foundation
class ZipCollectionTypeSink<C: CollectionType, R, O: ObserverType where C.Generator.Element : ObservableConvertibleType, O.E == R> : Sink<O> {
class ZipCollectionTypeSink<C: CollectionType, R, O: ObserverType where C.Generator.Element : ObservableConvertibleType, O.E == R>
: Sink<O> {
typealias Parent = ZipCollectionType<C, R>
typealias SourceElement = C.Generator.Element.E
@ -23,7 +24,7 @@ class ZipCollectionTypeSink<C: CollectionType, R, O: ObserverType where C.Genera
private var _numberOfDone = 0
private var _subscriptions: [SingleAssignmentDisposable]
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
_values = [Queue<SourceElement>](count: parent.count, repeatedValue: Queue(capacity: 4))
_isDone = [Bool](count: parent.count, repeatedValue: false)
@ -34,11 +35,11 @@ class ZipCollectionTypeSink<C: CollectionType, R, O: ObserverType where C.Genera
_subscriptions.append(SingleAssignmentDisposable())
}
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func on(event: Event<SourceElement>, atIndex: Int) {
_lock.performLocked {
_lock.lock(); defer { _lock.unlock() } // {
switch event {
case .Next(let element):
_values[atIndex].enqueue(element)
@ -50,7 +51,7 @@ class ZipCollectionTypeSink<C: CollectionType, R, O: ObserverType where C.Genera
if _numberOfValues < _parent.count {
let numberOfOthersThatAreDone = _numberOfDone - (_isDone[atIndex] ? 1 : 0)
if numberOfOthersThatAreDone == _parent.count - 1 {
self.observer?.on(.Completed)
self.forwardOn(.Completed)
self.dispose()
}
return
@ -71,15 +72,15 @@ class ZipCollectionTypeSink<C: CollectionType, R, O: ObserverType where C.Genera
}
let result = try _parent.resultSelector(arguments)
self.observer?.on(.Next(result))
self.forwardOn(.Next(result))
}
catch let error {
self.observer?.on(.Error(error))
self.forwardOn(.Error(error))
self.dispose()
}
case .Error(let error):
self.observer?.on(.Error(error))
self.forwardOn(.Error(error))
self.dispose()
case .Completed:
if _isDone[atIndex] {
@ -90,14 +91,14 @@ class ZipCollectionTypeSink<C: CollectionType, R, O: ObserverType where C.Genera
_numberOfDone++
if _numberOfDone == _parent.count {
self.observer?.on(.Completed)
self.forwardOn(.Completed)
self.dispose()
}
else {
_subscriptions[atIndex].dispose()
}
}
}
// }
}
func run() -> Disposable {
@ -128,9 +129,9 @@ class ZipCollectionType<C: CollectionType, R where C.Generator.Element : Observa
self.count = Int(self.sources.count.toIntMax())
}
override func run<O : ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ZipCollectionTypeSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O : ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = ZipCollectionTypeSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -39,9 +39,9 @@ class ZipSink2_<E1, E2, O: ObserverType> : ZipSink<O> {
var _values1: Queue<E1> = Queue(capacity: 2)
var _values2: Queue<E2> = Queue(capacity: 2)
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 2, observer: observer, cancel: cancel)
super.init(arity: 2, observer: observer)
}
override func hasElements(index: Int) -> Bool {
@ -60,8 +60,8 @@ class ZipSink2_<E1, E2, O: ObserverType> : ZipSink<O> {
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: _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)
subscription1.disposable = _parent.source1.subscribe(observer1)
subscription2.disposable = _parent.source2.subscribe(observer2)
@ -92,10 +92,10 @@ class Zip2<E1, E2, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ZipSink2_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = ZipSink2_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -129,9 +129,9 @@ class ZipSink3_<E1, E2, E3, O: ObserverType> : ZipSink<O> {
var _values2: Queue<E2> = Queue(capacity: 2)
var _values3: Queue<E3> = Queue(capacity: 2)
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 3, observer: observer, cancel: cancel)
super.init(arity: 3, observer: observer)
}
override func hasElements(index: Int) -> Bool {
@ -152,9 +152,9 @@ class ZipSink3_<E1, E2, E3, O: ObserverType> : ZipSink<O> {
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: _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)
subscription1.disposable = _parent.source1.subscribe(observer1)
subscription2.disposable = _parent.source2.subscribe(observer2)
@ -189,10 +189,10 @@ class Zip3<E1, E2, E3, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ZipSink3_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = ZipSink3_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -227,9 +227,9 @@ class ZipSink4_<E1, E2, E3, E4, O: ObserverType> : ZipSink<O> {
var _values3: Queue<E3> = Queue(capacity: 2)
var _values4: Queue<E4> = Queue(capacity: 2)
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 4, observer: observer, cancel: cancel)
super.init(arity: 4, observer: observer)
}
override func hasElements(index: Int) -> Bool {
@ -252,10 +252,10 @@ class ZipSink4_<E1, E2, E3, E4, O: ObserverType> : ZipSink<O> {
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: _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)
subscription1.disposable = _parent.source1.subscribe(observer1)
subscription2.disposable = _parent.source2.subscribe(observer2)
@ -294,10 +294,10 @@ class Zip4<E1, E2, E3, E4, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ZipSink4_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = ZipSink4_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -333,9 +333,9 @@ class ZipSink5_<E1, E2, E3, E4, E5, O: ObserverType> : ZipSink<O> {
var _values4: Queue<E4> = Queue(capacity: 2)
var _values5: Queue<E5> = Queue(capacity: 2)
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 5, observer: observer, cancel: cancel)
super.init(arity: 5, observer: observer)
}
override func hasElements(index: Int) -> Bool {
@ -360,11 +360,11 @@ class ZipSink5_<E1, E2, E3, E4, E5, O: ObserverType> : ZipSink<O> {
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: _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)
subscription1.disposable = _parent.source1.subscribe(observer1)
subscription2.disposable = _parent.source2.subscribe(observer2)
@ -407,10 +407,10 @@ class Zip5<E1, E2, E3, E4, E5, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ZipSink5_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = ZipSink5_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -447,9 +447,9 @@ class ZipSink6_<E1, E2, E3, E4, E5, E6, O: ObserverType> : ZipSink<O> {
var _values5: Queue<E5> = Queue(capacity: 2)
var _values6: Queue<E6> = Queue(capacity: 2)
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 6, observer: observer, cancel: cancel)
super.init(arity: 6, observer: observer)
}
override func hasElements(index: Int) -> Bool {
@ -476,12 +476,12 @@ class ZipSink6_<E1, E2, E3, E4, E5, E6, O: ObserverType> : ZipSink<O> {
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: _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)
subscription1.disposable = _parent.source1.subscribe(observer1)
subscription2.disposable = _parent.source2.subscribe(observer2)
@ -528,10 +528,10 @@ class Zip6<E1, E2, E3, E4, E5, E6, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ZipSink6_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = ZipSink6_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -569,9 +569,9 @@ class ZipSink7_<E1, E2, E3, E4, E5, E6, E7, O: ObserverType> : ZipSink<O> {
var _values6: Queue<E6> = Queue(capacity: 2)
var _values7: Queue<E7> = Queue(capacity: 2)
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 7, observer: observer, cancel: cancel)
super.init(arity: 7, observer: observer)
}
override func hasElements(index: Int) -> Bool {
@ -600,13 +600,13 @@ class ZipSink7_<E1, E2, E3, E4, E5, E6, E7, O: ObserverType> : ZipSink<O> {
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)
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.disposable = _parent.source1.subscribe(observer1)
subscription2.disposable = _parent.source2.subscribe(observer2)
@ -657,10 +657,10 @@ class Zip7<E1, E2, E3, E4, E5, E6, E7, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ZipSink7_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = ZipSink7_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}
@ -699,9 +699,9 @@ class ZipSink8_<E1, E2, E3, E4, E5, E6, E7, E8, O: ObserverType> : ZipSink<O> {
var _values7: Queue<E7> = Queue(capacity: 2)
var _values8: Queue<E8> = Queue(capacity: 2)
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: 8, observer: observer, cancel: cancel)
super.init(arity: 8, observer: observer)
}
override func hasElements(index: Int) -> Bool {
@ -732,14 +732,14 @@ class ZipSink8_<E1, E2, E3, E4, E5, E6, E7, E8, O: ObserverType> : ZipSink<O> {
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)
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.disposable = _parent.source1.subscribe(observer1)
subscription2.disposable = _parent.source2.subscribe(observer2)
@ -794,10 +794,10 @@ class Zip8<E1, E2, E3, E4, E5, E6, E7, E8, R> : Producer<R> {
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ZipSink8_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = ZipSink8_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -38,9 +38,9 @@ class ZipSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joinWithSeparator(",
" var _values\($0): Queue<E\($0)> = Queue(capacity: 2)"
}).joinWithSeparator("\n") %>
init(parent: Parent, observer: O, cancel: Disposable) {
init(parent: Parent, observer: O) {
_parent = parent
super.init(arity: <%= i %>, observer: observer, cancel: cancel)
super.init(arity: <%= i %>, observer: observer)
}
override func hasElements(index: Int) -> Bool {
@ -61,7 +61,7 @@ class ZipSink<%= i %>_<<%= (Array(1...i).map { "E\($0)" }).joinWithSeparator(",
}).joinWithSeparator("\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: _lock, parent: self, index: \($0 - 1), setNextValue: { self._values\($0).enqueue($0) }, this: subscription\($0))"
}).joinWithSeparator("\n") %>
<%= (Array(1...i).map {
@ -93,10 +93,10 @@ class Zip<%= i %><<%= (Array(1...i).map { "E\($0)" }).joinWithSeparator(", ") %>
_resultSelector = resultSelector
}
override func run<O: ObserverType where O.E == R>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = ZipSink<%= i %>_(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
override func run<O: ObserverType where O.E == R>(observer: O) -> Disposable {
let sink = ZipSink<%= i %>_(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}

View File

@ -18,18 +18,18 @@ protocol ZipSinkProtocol : class
class ZipSink<O: ObserverType> : Sink<O>, ZipSinkProtocol {
typealias Element = O.E
let arity: Int
let lock = NSRecursiveLock()
let _arity: Int
let _lock = NSRecursiveLock()
// state
private var _isDone: [Bool]
init(arity: Int, observer: O, cancel: Disposable) {
init(arity: Int, observer: O) {
_isDone = [Bool](count: arity, repeatedValue: false)
self.arity = arity
_arity = arity
super.init(observer: observer, cancel: cancel)
super.init(observer: observer)
}
func getResult() throws -> Element {
@ -43,7 +43,7 @@ class ZipSink<O: ObserverType> : Sink<O>, ZipSinkProtocol {
func next(index: Int) {
var hasValueAll = true
for i in 0 ..< arity {
for i in 0 ..< _arity {
if !hasElements(i) {
hasValueAll = false;
break;
@ -53,10 +53,10 @@ class ZipSink<O: ObserverType> : Sink<O>, ZipSinkProtocol {
if hasValueAll {
do {
let result = try getResult()
self.observer?.on(.Next(result))
self.forwardOn(.Next(result))
}
catch let e {
self.observer?.on(.Error(e))
self.forwardOn(.Error(e))
dispose()
}
}
@ -72,14 +72,14 @@ class ZipSink<O: ObserverType> : Sink<O>, ZipSinkProtocol {
}
if allOthersDone {
observer?.on(.Completed)
forwardOn(.Completed)
self.dispose()
}
}
}
func fail(error: ErrorType) {
observer?.on(.Error(error))
forwardOn(.Error(error))
dispose()
}
@ -96,19 +96,22 @@ class ZipSink<O: ObserverType> : Sink<O>, ZipSinkProtocol {
}
if allDone {
observer?.on(.Completed)
forwardOn(.Completed)
dispose()
}
}
}
class ZipObserver<ElementType> : ObserverType {
class ZipObserver<ElementType>
: ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias E = ElementType
typealias ValueSetter = (ElementType) -> ()
private var _parent: ZipSinkProtocol?
private let _lock: NSRecursiveLock
let _lock: NSRecursiveLock
// state
private let _index: Int
@ -124,7 +127,10 @@ class ZipObserver<ElementType> : ObserverType {
}
func on(event: Event<E>) {
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
if let _ = _parent {
switch event {
case .Next(_):
@ -136,17 +142,15 @@ class ZipObserver<ElementType> : ObserverType {
}
}
_lock.performLocked {
if let parent = _parent {
switch event {
case .Next(let value):
_setNextValue(value)
parent.next(_index)
case .Error(let error):
parent.fail(error)
case .Completed:
parent.done(_index)
}
if let parent = _parent {
switch event {
case .Next(let value):
_setNextValue(value)
parent.next(_index)
case .Error(let error):
parent.fail(error)
case .Completed:
parent.done(_index)
}
}
}

View File

@ -10,7 +10,7 @@ import Foundation
// MARK: reduce
extension ObservableConvertibleType {
extension ObservableType {
/**
Applies an `accumulator` function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified `seed` value is used as the initial accumulator value.

View File

@ -10,7 +10,7 @@ import Foundation
// MARK: multicast
extension ObservableConvertibleType {
extension ObservableType {
/**
Multicasts the source sequence notifications through the specified subject to the resulting connectable observable.
@ -52,7 +52,7 @@ extension ObservableConvertibleType {
// MARK: publish
extension ObservableConvertibleType {
extension ObservableType {
/**
Returns a connectable observable sequence that shares a single subscription to the underlying sequence.
@ -69,7 +69,7 @@ extension ObservableConvertibleType {
// MARK: replay
extension ObservableConvertibleType {
extension ObservableType {
/**
Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying bufferSize elements.
@ -103,7 +103,7 @@ extension ConnectableObservableType {
// MARK: share
extension ObservableConvertibleType {
extension ObservableType {
/**
Returns an observable sequence that shares a single subscription to the underlying sequence.
@ -120,7 +120,7 @@ extension ObservableConvertibleType {
// MARK: shareReplay
extension ObservableConvertibleType {
extension ObservableType {
/**
Returns an observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer.

View File

@ -10,7 +10,7 @@ import Foundation
// MARK: observeOn
extension ObservableConvertibleType {
extension ObservableType {
/**
Wraps the source sequence in order to run its observer callbacks on the specified scheduler.

View File

@ -10,7 +10,7 @@ import Foundation
// MARK: debug
extension ObservableConvertibleType {
extension ObservableType {
/**
Prints received events for all observers on standard output.

View File

@ -42,7 +42,7 @@ extension CollectionType where Generator.Element : ObservableConvertibleType {
// MARK: switch
extension ObservableConvertibleType where E : ObservableConvertibleType {
extension ObservableType where E : ObservableConvertibleType {
/**
Transforms an observable sequence of observable sequences into an observable sequence
@ -61,7 +61,7 @@ extension ObservableConvertibleType where E : ObservableConvertibleType {
// MARK: concat
extension ObservableConvertibleType {
extension ObservableType {
/**
Concatenates the second observable sequence to `self` upon successful termination of `self`.
@ -89,7 +89,7 @@ extension SequenceType where Generator.Element : ObservableConvertibleType {
}
}
extension ObservableConvertibleType where E : ObservableConvertibleType {
extension ObservableType where E : ObservableConvertibleType {
/**
Concatenates all inner observable sequences, as long as the previous observable sequence terminated successfully.
@ -104,7 +104,7 @@ extension ObservableConvertibleType where E : ObservableConvertibleType {
// MARK: merge
extension ObservableConvertibleType where E : ObservableConvertibleType {
extension ObservableType where E : ObservableConvertibleType {
/**
Merges elements from all observable sequences in the given enumerable sequence into a single observable sequence.
@ -131,7 +131,7 @@ extension ObservableConvertibleType where E : ObservableConvertibleType {
// MARK: catch
extension ObservableConvertibleType {
extension ObservableType {
/**
Continues an observable sequence that is terminated by an error with the observable sequence produced by the handler.
@ -174,7 +174,7 @@ extension SequenceType where Generator.Element : ObservableConvertibleType {
// MARK: takeUntil
extension ObservableConvertibleType {
extension ObservableType {
/**
Returns the elements from the source observable sequence until the other observable sequence produces an element.
@ -191,7 +191,7 @@ extension ObservableConvertibleType {
// MARK: skipUntil
extension ObservableConvertibleType {
extension ObservableType {
/**
Returns the elements from the source observable sequence until the other observable sequence produces an element.
@ -208,7 +208,7 @@ extension ObservableConvertibleType {
// MARK: amb
extension ObservableConvertibleType {
extension ObservableType {
/**
Propagates the observable sequence that reacts first.
@ -242,7 +242,7 @@ extension SequenceType where Generator.Element : ObservableConvertibleType {
// withLatestFrom
extension ObservableConvertibleType {
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.

View File

@ -10,7 +10,7 @@ import Foundation
// MARK: distinct until changed
extension ObservableConvertibleType where E: Equatable {
extension ObservableType where E: Equatable {
/**
Returns an observable sequence that contains only distinct contiguous elements according to equality operator.
@ -24,7 +24,7 @@ extension ObservableConvertibleType where E: Equatable {
}
}
extension ObservableConvertibleType {
extension ObservableType {
/**
Returns an observable sequence that contains only distinct contiguous elements according to the `keySelector`.
@ -65,7 +65,7 @@ extension ObservableConvertibleType {
// MARK: do
extension ObservableConvertibleType {
extension ObservableType {
/**
Invokes an action for each event in the observable sequence, and propagates all observer messages through the result sequence.
@ -105,7 +105,7 @@ extension ObservableConvertibleType {
// MARK: startWith
extension ObservableConvertibleType {
extension ObservableType {
/**
Prepends a sequence of values to an observable sequence.
@ -122,7 +122,7 @@ extension ObservableConvertibleType {
// MARK: retry
extension ObservableConvertibleType {
extension ObservableType {
/**
Repeats the source observable sequence until it successfully terminates.
@ -153,7 +153,7 @@ extension ObservableConvertibleType {
// MARK: scan
extension ObservableConvertibleType {
extension ObservableType {
/**
Applies an accumulator function over an observable sequence and returns each intermediate result. The specified seed value is used as the initial accumulator value.

View File

@ -10,7 +10,7 @@ import Foundation
// MARK: filter aka where
extension ObservableConvertibleType {
extension ObservableType {
/**
Filters the elements of an observable sequence based on a predicate.
@ -27,7 +27,7 @@ extension ObservableConvertibleType {
// MARK: takeWhile
extension ObservableConvertibleType {
extension ObservableType {
/**
Returns elements from an observable sequence as long as a specified condition is true.
@ -58,7 +58,7 @@ extension ObservableConvertibleType {
// MARK: take
extension ObservableConvertibleType {
extension ObservableType {
/**
Returns a specified number of contiguous elements from the start of an observable sequence.
@ -80,7 +80,7 @@ extension ObservableConvertibleType {
// MARK: takeLast
extension ObservableConvertibleType {
extension ObservableType {
/**
Returns a specified number of contiguous elements from the end of an observable sequence.
@ -100,7 +100,7 @@ extension ObservableConvertibleType {
// MARK: skip
extension ObservableConvertibleType {
extension ObservableType {
/**
Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
@ -117,7 +117,7 @@ extension ObservableConvertibleType {
// MARK: SkipWhile
extension ObservableConvertibleType {
extension ObservableType {
/**
Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
@ -145,7 +145,7 @@ extension ObservableConvertibleType {
// MARK: map aka select
extension ObservableConvertibleType {
extension ObservableType {
/**
Projects each element of an observable sequence into a new form.
@ -174,7 +174,7 @@ extension ObservableConvertibleType {
// MARK: flatMap
extension ObservableConvertibleType {
extension ObservableType {
/**
Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
@ -203,7 +203,7 @@ extension ObservableConvertibleType {
// elementAt
extension ObservableConvertibleType {
extension ObservableType {
/**
Returns a sequence emitting only item _n_ emitted by an Observable

View File

@ -9,7 +9,7 @@
import Foundation
// MARK: throttle
extension ObservableConvertibleType {
extension ObservableType {
/**
Ignores elements from an observable sequence which are followed by another element within a specified relative time duration, using the specified scheduler to run throttling timers.
@ -44,7 +44,7 @@ extension ObservableConvertibleType {
// MARK: sample
extension ObservableConvertibleType {
extension ObservableType {
/**
Samples the source observable sequence using a samper observable sequence producing sampling ticks.
@ -136,7 +136,7 @@ public func timer<S: SchedulerType>(dueTime: S.TimeInterval, _ scheduler: S)
// MARK: take
extension ObservableConvertibleType {
extension ObservableType {
/**
Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
@ -154,7 +154,7 @@ extension ObservableConvertibleType {
// MARK: skip
extension ObservableConvertibleType {
extension ObservableType {
/**
Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
@ -173,7 +173,7 @@ extension ObservableConvertibleType {
// MARK: delaySubscription
extension ObservableConvertibleType {
extension ObservableType {
/**
Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers.
@ -191,7 +191,7 @@ extension ObservableConvertibleType {
// MARK: buffer
extension ObservableConvertibleType {
extension ObservableType {
/**
Projects each element of an observable sequence into a buffer that's sent out when either it's full or a given amount of time has elapsed, using the specified scheduler to run timers.

View File

@ -42,7 +42,7 @@ public extension ObserverType {
/**
Convienence method equivalent to `on(.Completed)`
*/
final func onComplete() {
final func onCompleted() {
on(.Completed)
}

View File

@ -19,8 +19,8 @@ class TailRecursiveSink<S: SequenceType, O: ObserverType where S.Generator.Eleme
// this is thread safe object
var _gate = AsyncLock()
override init(observer: O, cancel: Disposable) {
super.init(observer: observer, cancel: cancel)
override init(observer: O) {
super.init(observer: observer)
}
func run(sources: S.Generator) -> Disposable {
@ -49,7 +49,7 @@ class TailRecursiveSink<S: SequenceType, O: ObserverType where S.Generator.Eleme
}
func done() {
observer?.on(.Completed)
forwardOn(.Completed)
dispose()
}

View File

@ -9,6 +9,7 @@
import Foundation
let CurrentThreadSchedulerKeyInstance = CurrentThreadSchedulerKey()
let CurrentThreadSchedulerQueueKeyInstance = CurrentThreadSchedulerQueueKey()
class CurrentThreadSchedulerKey : NSObject, NSCopying {
override func isEqual(object: AnyObject?) -> Bool {
@ -26,6 +27,22 @@ class CurrentThreadSchedulerKey : NSObject, NSCopying {
}
}
class CurrentThreadSchedulerQueueKey : NSObject, NSCopying {
override func isEqual(object: AnyObject?) -> Bool {
return object === CurrentThreadSchedulerQueueKeyInstance
}
override var hashValue: Int { return -904739207 }
override func copy() -> AnyObject {
return CurrentThreadSchedulerQueueKeyInstance
}
func copyWithZone(zone: NSZone) -> AnyObject {
return CurrentThreadSchedulerQueueKeyInstance
}
}
/**
Represents an object that schedules units of work on the current thread.
@ -43,15 +60,15 @@ public class CurrentThreadScheduler : ImmediateSchedulerType {
static var queue : ScheduleQueue? {
get {
return NSThread.currentThread().threadDictionary[CurrentThreadSchedulerKeyInstance] as? ScheduleQueue
return NSThread.currentThread().threadDictionary[CurrentThreadSchedulerQueueKeyInstance] as? ScheduleQueue
}
set {
let threadDictionary = NSThread.currentThread().threadDictionary
if let newValue = newValue {
threadDictionary[CurrentThreadSchedulerKeyInstance] = newValue
threadDictionary[CurrentThreadSchedulerQueueKeyInstance] = newValue
}
else {
threadDictionary.removeObjectForKey(CurrentThreadSchedulerKeyInstance)
threadDictionary.removeObjectForKey(CurrentThreadSchedulerQueueKeyInstance)
}
}
}
@ -59,8 +76,18 @@ public class CurrentThreadScheduler : ImmediateSchedulerType {
/**
Gets a value that indicates whether the caller must call a `schedule` method.
*/
public static var isScheduleRequired: Bool {
return NSThread.currentThread().threadDictionary[CurrentThreadSchedulerKeyInstance] == nil
public static private(set) var isScheduleRequired: Bool {
get {
return NSThread.currentThread().threadDictionary[CurrentThreadSchedulerKeyInstance] == nil
}
set(value) {
if value {
NSThread.currentThread().threadDictionary.removeObjectForKey(CurrentThreadSchedulerKeyInstance)
}
else {
NSThread.currentThread().threadDictionary[CurrentThreadSchedulerKeyInstance] = CurrentThreadSchedulerKeyInstance
}
}
}
/**
@ -74,28 +101,43 @@ public class CurrentThreadScheduler : ImmediateSchedulerType {
- returns: The disposable object used to cancel the scheduled action (best effort).
*/
public func schedule<StateType>(state: StateType, action: (StateType) -> Disposable) -> Disposable {
let queue = CurrentThreadScheduler.queue
if let queue = queue {
let scheduledItem = ScheduledItem(action: action, state: state, time: 0)
queue.value.enqueue(scheduledItem)
return scheduledItem
}
let newQueue = RxMutableBox(Queue<ScheduledItemType>(capacity: 0))
CurrentThreadScheduler.queue = newQueue
action(state)
while let latest = newQueue.value.tryDequeue() {
if latest.disposed {
continue
if CurrentThreadScheduler.isScheduleRequired {
CurrentThreadScheduler.isScheduleRequired = false
let disposable = action(state)
defer {
CurrentThreadScheduler.isScheduleRequired = true
CurrentThreadScheduler.queue = nil
}
latest.invoke()
guard let queue = CurrentThreadScheduler.queue else {
return disposable
}
while let latest = queue.value.tryDequeue() {
if latest.disposed {
continue
}
latest.invoke()
}
return disposable
}
CurrentThreadScheduler.queue = nil
return NopDisposable.instance
let existingQueue = CurrentThreadScheduler.queue
let queue: RxMutableBox<Queue<ScheduledItemType>>
if let existingQueue = existingQueue {
queue = existingQueue
}
else {
queue = RxMutableBox(Queue<ScheduledItemType>(capacity: 1))
CurrentThreadScheduler.queue = queue
}
let scheduledItem = ScheduledItem(action: action, state: state, time: 0)
queue.value.enqueue(scheduledItem)
return scheduledItem
}
}

View File

@ -8,37 +8,24 @@
import Foundation
private class BehaviorSubjectSubscription<Element> : Disposable {
typealias Parent = BehaviorSubject<Element>
typealias DisposeKey = Bag<AnyObserver<Element>>.KeyType
private let _parent: Parent
private var _disposeKey: DisposeKey?
init(parent: BehaviorSubject<Element>, disposeKey: DisposeKey) {
_parent = parent
_disposeKey = disposeKey
}
func dispose() {
_parent._lock.performLocked {
if let disposeKey = _disposeKey {
_parent._observers.removeKey(disposeKey)
_disposeKey = nil
}
}
}
}
/**
Represents a value that changes over time.
Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
*/
public final class BehaviorSubject<Element> : Observable<Element>, SubjectType, ObserverType, Disposable {
public final class BehaviorSubject<Element>
: Observable<Element>
, SubjectType
, ObserverType
, LockOwnerType
, SynchronizedOnType
, SynchronizedSubscribeType
, SynchronizedUnsubscribeType
, Disposable {
public typealias SubjectObserverType = BehaviorSubject<Element>
typealias DisposeKey = Bag<AnyObserver<Element>>.KeyType
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
// state
private var _disposed = false
@ -50,9 +37,7 @@ public final class BehaviorSubject<Element> : Observable<Element>, SubjectType,
Indicates whether the subject has been disposed.
*/
public var disposed: Bool {
return _lock.calculateLocked {
return _disposed
}
return _disposed
}
/**
@ -70,7 +55,7 @@ public final class BehaviorSubject<Element> : Observable<Element>, SubjectType,
- returns: Latest value.
*/
public func value() throws -> Element {
return try _lock.calculateLockedOrFail {
_lock.lock(); defer { _lock.unlock() } // {
if _disposed {
throw RxError.DisposedError
}
@ -82,7 +67,7 @@ public final class BehaviorSubject<Element> : Observable<Element>, SubjectType,
else {
return _value
}
}
//}
}
/**
@ -91,20 +76,22 @@ public final class BehaviorSubject<Element> : Observable<Element>, SubjectType,
- parameter event: Event to send to the observers.
*/
public func on(event: Event<E>) {
_lock.performLocked {
if _stoppedEvent != nil || _disposed {
return
}
switch event {
case .Next(let value):
_value = value
case .Error, .Completed:
_stoppedEvent = event
}
_observers.forEach { $0.on(event) }
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
if _stoppedEvent != nil || _disposed {
return
}
switch event {
case .Next(let value):
_value = value
case .Error, .Completed:
_stoppedEvent = event
}
_observers.on(event)
}
/**
@ -114,22 +101,32 @@ public final class BehaviorSubject<Element> : Observable<Element>, SubjectType,
- returns: Disposable object that can be used to unsubscribe the observer from the subject.
*/
public override func subscribe<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
return _lock.calculateLocked {
if _disposed {
observer.on(.Error(RxError.DisposedError))
return NopDisposable.instance
}
if let stoppedEvent = _stoppedEvent {
observer.on(stoppedEvent)
return NopDisposable.instance
}
let key = _observers.insert(observer.asObserver())
observer.on(.Next(_value))
return BehaviorSubjectSubscription(parent: self, disposeKey: key)
return synchronizedSubscribe(observer)
}
func _synchronized_subscribe<O : ObserverType where O.E == E>(observer: O) -> Disposable {
if _disposed {
observer.on(.Error(RxError.DisposedError))
return NopDisposable.instance
}
if let stoppedEvent = _stoppedEvent {
observer.on(stoppedEvent)
return NopDisposable.instance
}
let key = _observers.insert(observer.asObserver())
observer.on(.Next(_value))
return SubscriptionDisposable(owner: self, key: key)
}
func _synchronized_unsubscribe(disposeKey: DisposeKey) {
if _disposed {
return
}
_ = _observers.removeKey(disposeKey)
}
/**

View File

@ -8,46 +8,26 @@
import Foundation
class Subscription<Element> : Disposable {
typealias KeyType = Bag<AnyObserver<Element>>.KeyType
private var _lock = SpinLock()
// state
private var _subject: PublishSubject<Element>?
private var _key: KeyType?
init(subject: PublishSubject<Element>, key: KeyType) {
_key = key
_subject = subject
}
func dispose() {
_lock.performLocked {
guard let subject = _subject,
let key = _key else {
return
}
_subject = nil
_key = nil
subject.unsubscribe(key)
}
}
}
/**
Represents an object that is both an observable sequence as well as an observer.
Each notification is broadcasted to all subscribed observers.
*/
public class PublishSubject<Element> : Observable<Element>, SubjectType, Cancelable, ObserverType {
public class PublishSubject<Element>
: Observable<Element>
, SubjectType
, Cancelable
, ObserverType
, LockOwnerType
, SynchronizedOnType
, SynchronizedSubscribeType
, SynchronizedUnsubscribeType
, SynchronizedDisposeType {
public typealias SubjectObserverType = PublishSubject<Element>
typealias DisposeKey = Bag<AnyObserver<Element>>.KeyType
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
// state
private var _disposed = false
@ -59,9 +39,7 @@ public class PublishSubject<Element> : Observable<Element>, SubjectType, Cancela
*/
public var disposed: Bool {
get {
return _lock.calculateLocked {
return _disposed
}
return _disposed
}
}
@ -78,20 +56,22 @@ public class PublishSubject<Element> : Observable<Element>, SubjectType, Cancela
- parameter event: Event to send to the observers.
*/
public func on(event: Event<Element>) {
_lock.performLocked {
switch event {
case .Next(_):
if disposed || _stoppedEvent != nil {
return
}
_observers.forEach { $0.on(event) }
case .Completed, .Error:
if _stoppedEvent == nil {
_stoppedEvent = event
_observers.forEach { $0.on(event) }
_observers.removeAll()
}
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
switch event {
case .Next(_):
if _disposed || _stoppedEvent != nil {
return
}
_observers.on(event)
case .Completed, .Error:
if _stoppedEvent == nil {
_stoppedEvent = event
_observers.on(event)
_observers.removeAll()
}
}
}
@ -103,26 +83,27 @@ public class PublishSubject<Element> : Observable<Element>, SubjectType, Cancela
- returns: Disposable object that can be used to unsubscribe the observer from the subject.
*/
public override func subscribe<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
return _lock.calculateLocked {
if let stoppedEvent = _stoppedEvent {
observer.on(stoppedEvent)
return NopDisposable.instance
}
if disposed {
observer.on(.Error(RxError.DisposedError))
return NopDisposable.instance
}
let key = _observers.insert(observer.asObserver())
return Subscription(subject: self, key: key)
}
return synchronizedSubscribe(observer)
}
func unsubscribe(key: DisposeKey) {
_lock.performLocked {
_ = _observers.removeKey(key)
func _synchronized_subscribe<O : ObserverType where O.E == E>(observer: O) -> Disposable {
if let stoppedEvent = _stoppedEvent {
observer.on(stoppedEvent)
return NopDisposable.instance
}
if _disposed {
observer.on(.Error(RxError.DisposedError))
return NopDisposable.instance
}
let key = _observers.insert(observer.asObserver())
return SubscriptionDisposable(owner: self, key: key)
}
func _synchronized_unsubscribe(disposeKey: DisposeKey) {
_ = _observers.removeKey(disposeKey)
}
/**
@ -136,10 +117,12 @@ public class PublishSubject<Element> : Observable<Element>, SubjectType, Cancela
Unsubscribe all observers and release resources.
*/
public func dispose() {
_lock.performLocked {
_disposed = true
_observers.removeAll()
_stoppedEvent = nil
}
synchronizedDispose()
}
func _synchronized_dispose() {
_disposed = true
_observers.removeAll()
_stoppedEvent = nil
}
}

View File

@ -13,7 +13,11 @@ Represents an object that is both an observable sequence as well as an observer.
Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
*/
public class ReplaySubject<Element> : Observable<Element>, SubjectType, ObserverType, Disposable {
public class ReplaySubject<Element>
: Observable<Element>
, SubjectType
, ObserverType
, Disposable {
public typealias SubjectObserverType = ReplaySubject<Element>
typealias DisposeKey = Bag<AnyObserver<Element>>.KeyType
@ -60,9 +64,15 @@ public class ReplaySubject<Element> : Observable<Element>, SubjectType, Observer
}
}
class ReplayBufferBase<Element> : ReplaySubject<Element> {
class ReplayBufferBase<Element>
: ReplaySubject<Element>
, LockOwnerType
, SynchronizedOnType
, SynchronizedSubscribeType
, SynchronizedUnsubscribeType
, SynchronizedDisposeType {
private let _lock = NSRecursiveLock()
let _lock = NSRecursiveLock()
// state
private var _disposed = false
@ -86,73 +96,72 @@ class ReplayBufferBase<Element> : ReplaySubject<Element> {
}
override func on(event: Event<Element>) {
_lock.performLocked {
if _disposed {
return
}
if _stoppedEvent != nil {
return
}
switch event {
case .Next(let value):
addValueToBuffer(value)
trim()
_observers.forEach { $0.on(event) }
case .Error, .Completed:
_stoppedEvent = event
trim()
_observers.forEach { $0.on(event) }
_observers.removeAll()
}
synchronizedOn(event)
}
func _synchronized_on(event: Event<E>) {
if _disposed {
return
}
if _stoppedEvent != nil {
return
}
switch event {
case .Next(let value):
addValueToBuffer(value)
trim()
_observers.on(event)
case .Error, .Completed:
_stoppedEvent = event
trim()
_observers.on(event)
_observers.removeAll()
}
}
override func subscribe<O : ObserverType where O.E == Element>(observer: O) -> Disposable {
return _lock.calculateLocked {
if _disposed {
observer.on(.Error(RxError.DisposedError))
return NopDisposable.instance
}
let AnyObserver = observer.asObserver()
replayBuffer(AnyObserver)
if let stoppedEvent = _stoppedEvent {
observer.on(stoppedEvent)
return NopDisposable.instance
}
else {
let key = _observers.insert(AnyObserver)
return ReplaySubscription(subject: self, disposeKey: key)
}
}
return synchronizedSubscribe(observer)
}
override func unsubscribe(key: DisposeKey) {
_lock.performLocked {
if _disposed {
return
}
_ = _observers.removeKey(key)
func _synchronized_subscribe<O : ObserverType where O.E == E>(observer: O) -> Disposable {
if _disposed {
observer.on(.Error(RxError.DisposedError))
return NopDisposable.instance
}
let AnyObserver = observer.asObserver()
replayBuffer(AnyObserver)
if let stoppedEvent = _stoppedEvent {
observer.on(stoppedEvent)
return NopDisposable.instance
}
else {
let key = _observers.insert(AnyObserver)
return SubscriptionDisposable(owner: self, key: key)
}
}
func lockedDispose() {
_disposed = true
_stoppedEvent = nil
_observers.removeAll()
func _synchronized_unsubscribe(disposeKey: DisposeKey) {
if _disposed {
return
}
_ = _observers.removeKey(disposeKey)
}
override func dispose() {
super.dispose()
_lock.performLocked {
lockedDispose()
}
synchronizedDispose()
}
func _synchronized_dispose() {
_disposed = true
_stoppedEvent = nil
_observers.removeAll()
}
}
@ -176,10 +185,9 @@ class ReplayOne<Element> : ReplayBufferBase<Element> {
observer.on(.Next(value))
}
}
override func lockedDispose() {
super.lockedDispose()
override func _synchronized_dispose() {
super._synchronized_dispose()
_value = nil
}
}
@ -200,9 +208,9 @@ class ReplayManyBase<Element> : ReplayBufferBase<Element> {
observer.on(.Next(item))
}
}
override func lockedDispose() {
super.lockedDispose()
override func _synchronized_dispose() {
super._synchronized_dispose()
_queue = Queue(capacity: 0)
}
}
@ -231,34 +239,4 @@ class ReplayAll<Element> : ReplayManyBase<Element> {
override func trim() {
}
}
class ReplaySubscription<Element> : Disposable {
typealias Subject = ReplaySubject<Element>
typealias DisposeKey = ReplayBufferBase<Element>.DisposeKey
private var _lock = SpinLock()
// state
private var _subject: Subject?
private var _disposeKey: DisposeKey?
init(subject: Subject, disposeKey: DisposeKey) {
_subject = subject
_disposeKey = disposeKey
}
func dispose() {
let oldState = _lock.calculateLocked { () -> (Subject?, DisposeKey?) in
let state = (self._subject, self._disposeKey)
self._subject = nil
self._disposeKey = nil
return state
}
if let subject = oldState.0, let disposeKey = oldState.1 {
subject.unsubscribe(disposeKey)
}
}
}
}

View File

@ -32,14 +32,14 @@ public class Variable<Element> : ObservableType {
*/
public var value: E {
get {
return _lock.calculateLocked {
return _value
}
_lock.lock(); defer { _lock.unlock() }
return _value
}
set(newValue) {
_lock.performLocked {
_value = newValue
}
_lock.lock()
_value = newValue
_lock.unlock()
_subject.on(.Next(newValue))
}
}

View File

@ -12,88 +12,26 @@ import RxCocoa
import AppKit
import CoreLocation
let NumberOfIterations = 1000
func approxValuePerIteration(total: Int) -> UInt64 {
return UInt64(round(Double(total) / Double(NumberOfIterations)))
}
func approxValuePerIteration(total: UInt64) -> UInt64 {
return UInt64(round(Double(total) / Double(NumberOfIterations)))
}
func measureTime(@noescape work: () -> ()) -> UInt64 {
var timebaseInfo: mach_timebase_info = mach_timebase_info()
let res = mach_timebase_info(&timebaseInfo)
assert(res == 0)
let start = mach_absolute_time()
for _ in 0 ..< NumberOfIterations {
work()
}
let timeInNano = (mach_absolute_time() - start) * UInt64(timebaseInfo.numer) / UInt64(timebaseInfo.denom)
return approxValuePerIteration(timeInNano) / UInt64(NumberOfIterations)
}
func measureMemoryUsage(@noescape work: () -> ()) -> (bytesAllocated: UInt64, allocations: UInt64) {
let (bytes, allocations) = getMemoryInfo()
for _ in 0 ..< NumberOfIterations {
work()
}
let (bytesAfter, allocationsAfter) = getMemoryInfo()
return (approxValuePerIteration(bytesAfter - bytes), approxValuePerIteration(allocationsAfter - allocations))
}
let bechmarkTime = true
func compareTwoImplementations(@noescape first first: () -> (), @noescape second: () -> ()) {
// first warm up to keep it fair
first()
second()
let time1: UInt64
let time2: UInt64
if bechmarkTime {
time1 = measureTime(first)
time2 = measureTime(second)
}
else {
time1 = 0
time2 = 0
}
registerMallocHooks()
let memory1 = measureMemoryUsage(first)
let memory2 = measureMemoryUsage(second)
// this is good enough
print(String(format: "#1 implementation %8d bytes %4d allocations %5d useconds", arguments: [
memory1.bytesAllocated,
memory1.allocations,
time1
]))
print(String(format: "#2 implementation %8d bytes %4d allocations %5d useconds", arguments: [
memory2.bytesAllocated,
memory2.allocations,
time2
]))
func allocation() {
}
compareTwoImplementations(first: {
compareTwoImplementations(benchmarkTime: true, first: {
let publishSubject = PublishSubject<Int>()
publishSubject
//let a = just(1)
//combineLatest(a,
publishSubject//.asDriver(onErrorJustReturn: -1)
.shareReplay(1)
//.map { $0 }
//.filter { _ in true }// ){ x, _ in x }
//.map { $0 }
.map { $0 }
.filter { _ in true }//){ x, _ in x }
.map { $0 }
.flatMap { just($0) }
.subscribeNext { _ in
}

View File

@ -30,7 +30,7 @@ class HotObservable<Element : Equatable> : ObservableType, ObservableConvertible
for recordedEvent in recordedEvents {
testScheduler.schedule((), time: recordedEvent.time) { t in
self.observers.forEach { $0.on(recordedEvent.event) }
self.observers.on(recordedEvent.event)
return NopDisposable.instance
}
}

View File

@ -29,7 +29,7 @@ class PrimitiveHotObservable<ElementType : Equatable> : ObservableType {
}
func on(event: Event<E>) {
observers.forEach { $0.on(event) }
observers.on(event)
}
func subscribe<O : ObserverType where O.E == E>(observer: O) -> Disposable {

View File

@ -20,92 +20,202 @@ extension BagTest {
typealias DoSomething = () -> Void
typealias KeyType = Bag<DoSomething>.KeyType
func numberOfActionsAfter(nInsertions: Int, deletionsFromStart: Int) {
var increment = 0
var bag = Bag<DoSomething>()
func numberOfActionsAfter<T>(nInsertions: Int, deletionsFromStart: Int, createNew: () -> T, bagAction: (RxMutableBox<Bag<T>>) -> ()) {
let bag = RxMutableBox(Bag<T>())
var keys = [KeyType]()
for _ in 0 ..< nInsertions {
keys.append(bag.insert({
increment++
}))
keys.append(bag.value.insert(createNew()))
}
for i in 0 ..< deletionsFromStart {
let key = keys[i]
bag.removeKey(key)
XCTAssertTrue(bag.value.removeKey(key) != nil)
}
bag.forEach { $0() }
XCTAssertTrue(increment == nInsertions - deletionsFromStart)
bagAction(bag)
}
func testBag_deletionsFromStart() {
for i in 0 ..< 50 {
for j in 0 ... i {
numberOfActionsAfter(i, deletionsFromStart: j)
var numberForEachActions = 0
var numberObservers = 0
var numberDisposables = 0
numberOfActionsAfter(i,
deletionsFromStart: j,
createNew: { () -> DoSomething in { () -> () in numberForEachActions++ } },
bagAction: { (bag: RxMutableBox<Bag<DoSomething>>) in bag.value.forEach { $0() }; XCTAssertTrue(bag.value.count == i - j) }
)
numberOfActionsAfter(i,
deletionsFromStart: j,
createNew: { () -> AnyObserver<Int> in AnyObserver { _ in numberObservers++ } },
bagAction: { (bag: RxMutableBox<Bag<AnyObserver<Int>>>) in bag.value.on(.Next(1)); XCTAssertTrue(bag.value.count == i - j) }
)
numberOfActionsAfter(i,
deletionsFromStart: j,
createNew: { () -> Disposable in AnonymousDisposable { numberDisposables++ } },
bagAction: { (bag: RxMutableBox<Bag<Disposable>>) in disposeAllIn(bag.value); XCTAssertTrue(bag.value.count == i - j) }
)
XCTAssertTrue(numberForEachActions == i - j)
XCTAssertTrue(numberObservers == i - j)
XCTAssertTrue(numberDisposables == i - j)
}
}
}
func numberOfActionsAfter(nInsertions: Int, deletionsFromEnd: Int) {
var increment = 0
var bag = Bag<DoSomething>()
func numberOfActionsAfter<T>(nInsertions: Int, deletionsFromEnd: Int, createNew: () -> T, bagAction: (RxMutableBox<Bag<T>>) -> ()) {
let bag = RxMutableBox(Bag<T>())
var keys = [KeyType]()
for _ in 0 ..< nInsertions {
keys.append(bag.insert({
increment++
}))
keys.append(bag.value.insert(createNew()))
}
for i in 0 ..< deletionsFromEnd {
let key = keys[keys.count - 1 - i]
bag.removeKey(key)
XCTAssertTrue(bag.value.removeKey(key) != nil)
}
bag.forEach { $0() }
XCTAssertTrue(increment == nInsertions - deletionsFromEnd)
bagAction(bag)
}
func testBag_deletionsFromEnd() {
for i in 0 ..< 50 {
for j in 0 ... i {
numberOfActionsAfter(i, deletionsFromEnd: j)
var numberForEachActions = 0
var numberObservers = 0
var numberDisposables = 0
numberOfActionsAfter(i,
deletionsFromStart: j,
createNew: { () -> DoSomething in { () -> () in numberForEachActions++ } },
bagAction: { (bag: RxMutableBox<Bag<DoSomething>>) in bag.value.forEach { $0() }; XCTAssertTrue(bag.value.count == i - j) }
)
numberOfActionsAfter(i,
deletionsFromStart: j,
createNew: { () -> AnyObserver<Int> in AnyObserver { _ in numberObservers++ } },
bagAction: { (bag: RxMutableBox<Bag<AnyObserver<Int>>>) in bag.value.on(.Next(1)); XCTAssertTrue(bag.value.count == i - j) }
)
numberOfActionsAfter(i,
deletionsFromStart: j,
createNew: { () -> Disposable in AnonymousDisposable { numberDisposables++ } },
bagAction: { (bag: RxMutableBox<Bag<Disposable>>) in disposeAllIn(bag.value); XCTAssertTrue(bag.value.count == i - j) }
)
XCTAssertTrue(numberForEachActions == i - j)
XCTAssertTrue(numberObservers == i - j)
XCTAssertTrue(numberDisposables == i - j)
}
}
}
func testBag_immutableForeach() {
var increment = 0
var bag = Bag<DoSomething>()
var keys = [KeyType]()
for _ in 0 ..< 10 {
keys.append(bag.insert({
increment++
}))
}
for _ in 0 ..< 2 {
var j = 0
bag.forEach { c in
j++
if j == 5 {
bag.removeAll()
}
c()
for breakAt in 0 ..< 50 {
var increment1 = 0
var increment2 = 0
var increment3 = 0
let bag1 = RxMutableBox(Bag<DoSomething>())
let bag2 = RxMutableBox(Bag<AnyObserver<Int>>())
let bag3 = RxMutableBox(Bag<Disposable>())
for _ in 0 ..< 50 {
bag1.value.insert({
if increment1 == breakAt {
bag1.value.removeAll()
}
increment1++
})
bag2.value.insert(AnyObserver { _ in
if increment2 == breakAt {
bag2.value.removeAll()
}
increment2++
})
bag3.value.insert(AnonymousDisposable { _ in
if increment3 == breakAt {
bag3.value.removeAll()
}
increment3++
})
}
for _ in 0 ..< 2 {
bag1.value.forEach { c in
c()
}
bag2.value.on(.Next(1))
disposeAllIn(bag3.value)
}
XCTAssertEqual(increment1, 50)
}
}
func testBag_removeAll() {
var numberForEachActions = 0
var numberObservers = 0
var numberDisposables = 0
numberOfActionsAfter(100,
deletionsFromStart: 0,
createNew: { () -> DoSomething in { () -> () in numberForEachActions++ } },
bagAction: { (bag: RxMutableBox<Bag<DoSomething>>) in bag.value.removeAll(); bag.value.forEach { $0() } }
)
numberOfActionsAfter(100,
deletionsFromStart: 0,
createNew: { () -> AnyObserver<Int> in AnyObserver { _ in numberObservers++ } },
bagAction: { (bag: RxMutableBox<Bag<AnyObserver<Int>>>) in bag.value.removeAll(); bag.value.on(.Next(1)); }
)
numberOfActionsAfter(100,
deletionsFromStart: 0,
createNew: { () -> Disposable in AnonymousDisposable { numberDisposables++ } },
bagAction: { (bag: RxMutableBox<Bag<Disposable>>) in bag.value.removeAll(); disposeAllIn(bag.value); }
)
XCTAssertTrue(numberForEachActions == 0)
XCTAssertTrue(numberObservers == 0)
XCTAssertTrue(numberDisposables == 0)
}
func testBag_complexityTestFromFront() {
var bag = Bag<Disposable>()
let limit = 100000
var increment = 0
var keys: [Bag<Disposable>.KeyType] = []
for _ in 0..<limit {
keys.append(bag.insert(AnonymousDisposable { increment++ }))
}
for i in 0..<limit {
bag.removeKey(keys[i])
}
}
func testBag_complexityTestFromEnd() {
var bag = Bag<Disposable>()
let limit = 100000
var increment = 0
var keys: [Bag<Disposable>.KeyType] = []
for _ in 0..<limit {
keys.append(bag.insert(AnonymousDisposable { increment++ }))
}
for i in 0..<limit {
bag.removeKey(keys[limit - 1 - i])
}
XCTAssertTrue(increment == 10)
}
}

View File

@ -3057,12 +3057,16 @@ extension ObservableStandardSequenceOperatorsTest {
func testTakeLast_DecrementCountsFirst() {
let k = BehaviorSubject(value: false)
var elements = [Bool]()
_ = k.takeLast(1).subscribeNext { n in
elements.append(n)
k.on(.Next(!n))
}
k.on(.Completed)
XCTAssertEqual(elements, [false])
}
}

View File

@ -80,7 +80,7 @@ extension ObserverTests {
observer.onNext(0)
XCTAssertEqual(elements, [0])
observer.onComplete()
observer.onCompleted()
observer.onNext(1)
XCTAssertEqual(elements, [0])

View File

@ -107,7 +107,7 @@ class RxTest: XCTestCase {
#if TRACE_RESOURCES
// give 5 sec to clean up resources
for var i = 0; i < 100; ++i {
for var i = 0; i < 10; ++i {
if self.startResourceCount < resourceCount {
// main schedulers need to finish work
NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate(timeIntervalSinceNow: 0.05))

View File

@ -1026,6 +1026,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_LDFLAGS = "";
OTHER_SWIFT_FLAGS = "$(inherits) -D ALLOC_HOOK";
PRODUCT_BUNDLE_IDENTIFIER = "Krunoslav-Zaher.PerformanceTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
@ -1070,9 +1071,11 @@
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_LDFLAGS = "";
OTHER_SWIFT_FLAGS = "$(inherits) -D ALLOC_HOOK";
PRODUCT_BUNDLE_IDENTIFIER = "Krunoslav-Zaher.PerformanceTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Release;
};
@ -1113,9 +1116,11 @@
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_LDFLAGS = "";
OTHER_SWIFT_FLAGS = "$(inherits) -D ALLOC_HOOK";
PRODUCT_BUNDLE_IDENTIFIER = "Krunoslav-Zaher.PerformanceTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = "Release-Tests";
};

View File

@ -52,7 +52,7 @@
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"

Some files were not shown because too many files have changed in this diff Show More