|
- import Combine
- import Foundation
-
- public enum Bus {
- private static let e = PassthroughSubject<(key: String, value: Any), Never>()
-
- public static var events: AnyPublisher<(key: String, value: Any), Never> {
- e.eraseToAnyPublisher()
- }
- }
-
- public extension Bus {
- /// Асинхронно обрабатываем входящие события из шины.
- static func receiveAsync<T>(
- _ keys: Set<String>,
- _ handler: @escaping ((String, T) -> Void),
- _ subscriptions: inout [AnyCancellable]
- ) {
- e
- .compactMap { convertKeyValue(keys, $0) }
- .receive(on: DispatchQueue.main)
- .sink { v in handler(v.0, v.1) }
- .store(in: &subscriptions)
- }
-
- /// Синхронно обрабатываем входящие события из шины.
- static func receiveSync<T>(
- _ keys: Set<String>,
- _ handler: @escaping ((String, T) -> Void),
- _ subscriptions: inout [AnyCancellable]
- ) {
- e
- .compactMap { convertKeyValue(keys, $0) }
- .sink { v in handler(v.0, v.1) }
- .store(in: &subscriptions)
- }
-
- /// Синхронно отправляем события из узла в шину.
- ///
- /// Для асинхронной отправки достаточно добавить оператор `receive(on:)`
- /// в цепочке параметра `node`
- static func sendSync<T>(
- _ key: String,
- _ node: AnyPublisher<T, Never>,
- _ subscriptions: inout [AnyCancellable]
- ) {
- node
- .sink { v in e.send((key, v)) }
- .store(in: &subscriptions)
- }
-
- /// Единоразово синхронно отправляем событие в шину.
- static func send(_ key: String, _ value: Any) {
- e.send((key, value))
- }
- }
|