|
- import Combine
- import Foundation
-
- public enum Bus { }
-
- public extension Bus {
- enum Option {
- case async
- }
- }
-
- extension Bus {
- final class Service {
- static let singleton = Service()
- let events = PassthroughSubject<(key: String, value: Any), Never>()
- var subscriptions = [AnyCancellable]()
-
- func send(_ key: String, _ value: Any) {
- /**/print("ИГР BusS.send key/value: '\(key)'/'\(value)'")
- events.send((key, value))
- }
- }
- }
-
- private extension Bus {
- static func subscribe(
- _ subscription: AnyCancellable?,
- _ sub: UnsafeMutablePointer<[AnyCancellable]>?
- ) {
- guard let subscription else { return }
- if let sub = sub {
- sub.pointee.append(subscription)
- } else {
- Service.singleton.subscriptions.append(subscription)
- }
- }
- }
-
- public extension Bus {
- static func receive<T>(
- _ keys: Set<String>,
- _ handler: @escaping ((String, T) -> Void),
- opt: [Option] = [],
- sub: UnsafeMutablePointer<[AnyCancellable]>? = nil
- ) {
- var subscription: AnyCancellable?
- let isAsync = opt.contains(.async)
-
- // Async.
- if isAsync {
- subscription = Service.singleton.events
- .compactMap { convertKeyValue(keys, $0) }
- .receive(on: DispatchQueue.main)
- .sink { v in handler(v.0, v.1) }
- }
-
- // Async.
- if !isAsync {
- subscription = Service.singleton.events
- .compactMap { convertKeyValue(keys, $0) }
- .sink { v in handler(v.0, v.1) }
- }
-
- subscribe(subscription, sub)
- }
-
- static func send<T>(
- _ key: String,
- _ node: AnyPublisher<T, Never>,
- opt: [Option] = [],
- sub: UnsafeMutablePointer<[AnyCancellable]>? = nil
- ) {
- var subscription: AnyCancellable?
- let isAsync = opt.contains(.async)
-
- // Async.
- if isAsync {
- subscription = node
- .receive(on: DispatchQueue.main)
- .sink { v in Service.singleton.send(key, v) }
- }
-
- // Sync.
- if !isAsync {
- subscription = node
- .sink { v in Service.singleton.send(key, v) }
- }
-
- subscribe(subscription, sub)
- }
-
- static func send(_ key: String, _ value: Any) {
- Service.singleton.send(key, value)
- }
- }
-
- public extension Bus {
- static func process<Src, Dst>(
- _ keysIn: Set<String>,
- _ keyOut: String,
- _ handler: @escaping ((Src) -> Dst?),
- opt: [Option] = [],
- sub: UnsafeMutablePointer<[AnyCancellable]>? = nil
- ) {
- var subscription: AnyCancellable?
- let isAsync = opt.contains(.async)
-
- // Async.
- if isAsync {
- subscription = Service.singleton.events
- .compactMap { processKeysValue($0, keysIn, handler) }
- .receive(on: DispatchQueue.main)
- .sink { vOut in Service.singleton.send(keyOut, vOut) }
- }
-
- // Sync.
- if !isAsync {
- subscription = Service.singleton.events
- .compactMap { processKeysValue($0, keysIn, handler) }
- .sink { vOut in Service.singleton.send(keyOut, vOut) }
- }
-
- subscribe(subscription, sub)
- }
- }
|