Merge pull request #213 from ReactiveX/feature/performance-optimizations
Innovating to zero
This commit is contained in:
commit
28efa9d827
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import Foundation
|
|||
|
||||
// MARK: debug
|
||||
|
||||
extension ObservableConvertibleType {
|
||||
extension ObservableType {
|
||||
|
||||
/**
|
||||
Prints received events for all observers on standard output.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public extension ObserverType {
|
|||
/**
|
||||
Convienence method equivalent to `on(.Completed)`
|
||||
*/
|
||||
final func onComplete() {
|
||||
final func onCompleted() {
|
||||
on(.Completed)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ extension ObserverTests {
|
|||
observer.onNext(0)
|
||||
XCTAssertEqual(elements, [0])
|
||||
|
||||
observer.onComplete()
|
||||
observer.onCompleted()
|
||||
|
||||
observer.onNext(1)
|
||||
XCTAssertEqual(elements, [0])
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue