// // ModelHanlderPublisher.swift // VDS // // Created by Matt Bruce on 8/12/22. // import Foundation import Combine extension Publishers { public struct ModelHandlerPublisher: Publisher { public typealias Output = ModelHandlerType.ModelType public typealias Failure = Never private let modelHandler: ModelHandlerType public init(modelHandler: ModelHandlerType) { self.modelHandler = modelHandler } public func receive(subscriber: S) where S : Subscriber, Never == S.Failure, ModelHandlerType.ModelType == S.Input { let subscription = ModelHandlerSubscription(subscriber: subscriber, modelHandler: modelHandler) subscriber.receive(subscription: subscription) } } public class ModelHandlerSubscription: Subscription where S.Input == ModelHandlerType.ModelType, S.Failure == Never { private var subscriber: S? private var modelHandler: ModelHandlerType? public var subscribers = Set() public init(subscriber: S, modelHandler: ModelHandlerType) { self.subscriber = subscriber self.modelHandler = modelHandler subscribe() } public func request(_ demand: Subscribers.Demand) { } public func cancel() { subscriber = nil modelHandler = nil } private func subscribe() { guard let publisher = modelHandler?.modelPublisher else { return } publisher .debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main) .sink { [weak self] viewModel in _ = self?.subscriber?.receive(viewModel) } .store(in: &subscribers) } } } extension ModelHandlerable { public func handlerPublisher() -> AnyPublisher { return Publishers.ModelHandlerPublisher(modelHandler: self).eraseToAnyPublisher() } public func createBinding(with subject: CurrentValueSubject, storeIn subscriptions: inout Set) { handlerPublisher() .sink { (value) in subject.send(value) } .store(in: &subscriptions) } }