import Foundation public enum SignalFeedbackLoopState { case initial case loop(T) } public func feedbackLoop(once: @escaping (SignalFeedbackLoopState) -> Signal?, reduce: @escaping (R1, R1) -> R1) -> Signal { return Signal { subscriber in let currentDisposable = MetaDisposable() let state = Atomic(value: nil) var loopAgain: (() -> Void)? let loopOnce: (MetaDisposable?) -> Void = { disposable in if let signal = once(.initial) { disposable?.set(signal.start(next: { next in let _ = state.modify { value in if let value = value { return reduce(value, next) } else { return value } } }, error: { error in subscriber.putError(error) }, completed: { loopAgain?() })) } else { subscriber.putCompletion() } } loopAgain = { [weak currentDisposable] in loopOnce(currentDisposable) } loopOnce(currentDisposable) return ActionDisposable { currentDisposable.dispose() } } }