0001 // 0002 // TailRecursiveSink.swift 0003 // Rx 0004 // 0005 // Created by Krunoslav Zaher on 3/21/15. 0006 // Copyright © 2015 Krunoslav Zaher. All rights reserved. 0007 // 0008 0009 import Foundation 0010 0011 enum TailRecursiveSinkCommand{ 0012 case MoveNext
TailRecursiveSink.swift:24 typealias Value = TailRecursiveSinkCommandTailRecursiveSink.swift:47 func invoke(command: TailRecursiveSinkCommand) {TailRecursiveSink.swift:57 func schedule(command: TailRecursiveSinkCommand) {0013 case Dispose
Catch.swift:116 schedule(.MoveNext)Concat.swift:29 schedule(.MoveNext)RetryWhen.swift:27 _parent._parent.schedule(.MoveNext)TailRecursiveSink.swift:42 schedule(.MoveNext)TailRecursiveSink.swift:51 case .MoveNext:0014 } 0015 0016 #if DEBUG || TRACE_RESOURCES 0017 public var maxTailRecursiveSinkStackSize = 0 0018 #endif 0019 0020 /// This class is usually used with `Generator` version of the operators. 0021 class TailRecursiveSink
TailRecursiveSink.swift:49 case .Dispose:TailRecursiveSink.swift:149 schedule(.Dispose)<S
Catch.swift:99 : TailRecursiveSink<S, O>Concat.swift:13 : TailRecursiveSink<S, O>RetryWhen.swift:83 : TailRecursiveSink<S, O> {TailRecursiveSink.swift:33 var _gate = AsyncLock<InvocableScheduledItem<TailRecursiveSink<S, O>>>(): SequenceType, O
TailRecursiveSink.swift:26 typealias SequenceGenerator = (generator: S.Generator, remaining: IntMax?)TailRecursiveSink.swift:33 var _gate = AsyncLock<InvocableScheduledItem<TailRecursiveSink<S, O>>>(): ObserverType where S.Generator.Element: ObservableConvertibleType, S.Generator.Element.E == O.E> 0022 : Sink<O> 0023 , InvocableWithValueType { 0024 typealias Value = TailRecursiveSinkCommand 0025 typealias E
TailRecursiveSink.swift:22 : Sink<O>TailRecursiveSink.swift:25 typealias E = O.ETailRecursiveSink.swift:33 var _gate = AsyncLock<InvocableScheduledItem<TailRecursiveSink<S, O>>>()TailRecursiveSink.swift:35 override init(observer: O) {= O.E 0026 typealias SequenceGenerator
Catch.swift:123 override func subscribeToNext(source: Observable<E>) -> Disposable {Concat.swift:33 override func subscribeToNext(source: Observable<E>) -> Disposable {Concat.swift:37 override func extract(observable: Observable<E>) -> SequenceGenerator? {RetryWhen.swift:114 override func extract(observable: Observable<E>) -> SequenceGenerator? {RetryWhen.swift:121 override func subscribeToNext(source: Observable<E>) -> Disposable {TailRecursiveSink.swift:66 func extract(observable: Observable<E>) -> SequenceGenerator? {TailRecursiveSink.swift:73 var next: Observable<E>? = nilTailRecursiveSink.swift:135 func subscribeToNext(source: Observable<E>) -> Disposable {= (generator: S.Generator, remaining: IntMax?) 0027 0028 var _generators
Catch.swift:138 override func extract(observable: Observable<Element>) -> SequenceGenerator? {Concat.swift:37 override func extract(observable: Observable<E>) -> SequenceGenerator? {RetryWhen.swift:114 override func extract(observable: Observable<E>) -> SequenceGenerator? {RetryWhen.swift:127 override func run(sources: SequenceGenerator) -> Disposable {TailRecursiveSink.swift:28 var _generators: [SequenceGenerator] = []TailRecursiveSink.swift:39 func run(sources: SequenceGenerator) -> Disposable {TailRecursiveSink.swift:66 func extract(observable: Observable<E>) -> SequenceGenerator? {: [SequenceGenerator] = [] 0029 var _disposed
TailRecursiveSink.swift:40 _generators.append(sources)TailRecursiveSink.swift:76 if _generators.count == 0 {TailRecursiveSink.swift:84 var (e, left) = _generators.last!TailRecursiveSink.swift:86 _generators.removeLast()TailRecursiveSink.swift:103 _generators.append((e, knownOriginalLeft - 1))TailRecursiveSink.swift:107 _generators.append((e, nil))TailRecursiveSink.swift:113 _generators.append(nextGenerator)TailRecursiveSink.swift:141 _generators.removeAll(keepCapacity: false)= false 0030 var _subscription
TailRecursiveSink.swift:80 if _disposed {TailRecursiveSink.swift:140 _disposed = true= SerialDisposable() 0031 0032 // this is thread safe object 0033 var _gate
TailRecursiveSink.swift:44 return _subscriptionTailRecursiveSink.swift:131 _subscription.disposable = disposableTailRecursiveSink.swift:147 _subscription.dispose()= AsyncLock<InvocableScheduledItem<TailRecursiveSink<S, O>>>() 0034 0035 override init
TailRecursiveSink.swift:58 _gate.invoke(InvocableScheduledItem(invocable: self, state: command))(observer: O) { 0036 super.init(observer: observer) 0037 } 0038 0039 func run
Catch.swift:107 super.init(observer: observer)Concat.swift:18 super.init(observer: observer)RetryWhen.swift:99 super.init(observer: observer)(sources: SequenceGenerator) -> Disposable { 0040 _generators.append(sources) 0041 0042 schedule(.MoveNext) 0043 0044 return _subscription 0045 } 0046 0047 func invoke(command: TailRecursiveSinkCommand) { 0048 switch command { 0049 case .Dispose: 0050 disposeCommand() 0051 case .MoveNext: 0052 moveNextCommand() 0053 } 0054 } 0055 0056 // simple implementation for now 0057 func schedule
Catch.swift:159 sink.disposable = sink.run((self.sources.generate(), nil))Concat.swift:60 sink.disposable = sink.run((_sources.generate(), _count))RetryWhen.swift:129 let superSubscription = super.run(sources)(command: TailRecursiveSinkCommand) { 0058 _gate.invoke(InvocableScheduledItem(invocable: self, state: command)) 0059 } 0060 0061 func done
Catch.swift:116 schedule(.MoveNext)Concat.swift:29 schedule(.MoveNext)RetryWhen.swift:27 _parent._parent.schedule(.MoveNext)TailRecursiveSink.swift:42 schedule(.MoveNext)TailRecursiveSink.swift:149 schedule(.Dispose)() { 0062 forwardOn(.Completed) 0063 dispose() 0064 } 0065 0066 func extract
TailRecursiveSink.swift:126 done()(observable: Observable<E>) -> SequenceGenerator? { 0067 abstractMethod() 0068 } 0069 0070 // should be done on gate locked 0071 0072 private func moveNextCommand
TailRecursiveSink.swift:110 let nextGenerator = extract(nextCandidate)() { 0073 var next: Observable<E>? = nil 0074 0075 repeat { 0076 if _generators.count == 0 { 0077 break 0078 } 0079 0080 if _disposed { 0081 return 0082 } 0083 0084 var (e, left) = _generators.last! 0085 0086 _generators.removeLast() 0087 0088 guard let nextCandidate = e.next()?.asObservable() else { 0089 continue 0090 } 0091 0092 // `left` is a hint of how many elements are left in generator. 0093 // In case this is the last element, then there is no need to push 0094 // that generator on stack. 0095 // 0096 // This is an optimization used to make sure in tail recursive case 0097 // there is no memory leak in case this operator is used to generate non terminating 0098 // sequence. 0099 0100 if let knownOriginalLeft = left { 0101 // `- 1` because generator.next() has just been called 0102 if knownOriginalLeft - 1 >= 1 { 0103 _generators.append((e, knownOriginalLeft - 1)) 0104 } 0105 } 0106 else { 0107 _generators.append((e, nil)) 0108 } 0109 0110 let nextGenerator = extract(nextCandidate) 0111 0112 if let nextGenerator = nextGenerator { 0113 _generators.append(nextGenerator) 0114 #if DEBUG || TRACE_RESOURCES 0115 if maxTailRecursiveSinkStackSize < _generators.count { 0116 maxTailRecursiveSinkStackSize = _generators.count 0117 } 0118 #endif 0119 } 0120 else { 0121 next = nextCandidate 0122 } 0123 } while next == nil 0124 0125 if next == nil { 0126 done() 0127 return 0128 } 0129 0130 let disposable = SingleAssignmentDisposable() 0131 _subscription.disposable = disposable 0132 disposable.disposable = subscribeToNext(next!) 0133 } 0134 0135 func subscribeToNext
TailRecursiveSink.swift:52 moveNextCommand()(source: Observable<E>) -> Disposable { 0136 abstractMethod() 0137 } 0138 0139 func disposeCommand
TailRecursiveSink.swift:132 disposable.disposable = subscribeToNext(next!)() { 0140 _disposed = true 0141 _generators.removeAll(keepCapacity: false) 0142 } 0143 0144 override func dispose
TailRecursiveSink.swift:50 disposeCommand()() { 0145 super.dispose() 0146 0147 _subscription.dispose() 0148 0149 schedule(.Dispose) 0150 } 0151 } 0152 0153
Catch.swift:119 dispose()Catch.swift:135 self.dispose()Concat.swift:27 dispose()RetryWhen.swift:30 _parent._parent.dispose()RetryWhen.swift:33 _parent._parent.dispose()RetryWhen.swift:68 _parent.dispose()RetryWhen.swift:72 _parent.dispose()RetryWhen.swift:111 dispose()TailRecursiveSink.swift:63 dispose()