This commit is contained in:
Михаил Капелько
2023-12-25 18:54:25 +03:00
parent 06c143efb4
commit 880c4f3dee
2 changed files with 74 additions and 45 deletions

View File

@@ -3,11 +3,17 @@ 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 = Set<AnyCancellable>()
var subscriptions = [AnyCancellable]()
func send(_ key: String, _ value: Any) {
/**/print("ИГР BusS.send key/value: '\(key)'/'\(value)'")
@@ -17,48 +23,56 @@ extension Bus {
}
public extension Bus {
static func receiveAsync<T>(
_ subscriptions: inout Set<AnyCancellable>,
static func receive<T>(
_ keys: Set<String>,
_ handler: @escaping ((String, T) -> Void)
_ handler: @escaping ((String, T) -> Void),
opt: [Option] = [],
sub: UnsafeMutablePointer<[AnyCancellable]>? = nil
) {
Service.singleton.events
.compactMap { convertKeyValue(keys, $0) }
.receive(on: DispatchQueue.main)
.sink { v in handler(v.0, v.1) }
.store(in: &subscriptions)
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 receiveSync<T>(
_ subscriptions: inout Set<AnyCancellable>,
_ keys: Set<String>,
_ handler: @escaping ((String, T) -> Void)
) {
Service.singleton.events
.compactMap { convertKeyValue(keys, $0) }
.sink { v in handler(v.0, v.1) }
.store(in: &subscriptions)
}
static func sendAsync<T>(
_ subscriptions: inout Set<AnyCancellable>,
static func send<T>(
_ key: String,
_ node: AnyPublisher<T, Never>
_ node: AnyPublisher<T, Never>,
opt: [Option] = [],
sub: UnsafeMutablePointer<[AnyCancellable]>? = nil
) {
node
.receive(on: DispatchQueue.main)
.sink { v in Service.singleton.send(key, v) }
.store(in: &subscriptions)
}
var subscription: AnyCancellable?
let isAsync = opt.contains(.async)
static func sendSync<T>(
_ subscriptions: inout Set<AnyCancellable>,
_ key: String,
_ node: AnyPublisher<T, Never>
) {
node
.sink { v in Service.singleton.send(key, v) }
.store(in: &subscriptions)
// 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) {
@@ -66,9 +80,23 @@ public extension Bus {
}
}
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 processSync<Src, Dst>(
_ subscriptions: inout Set<AnyCancellable>,
_ subscriptions: inout [AnyCancellable],
_ handler: @escaping ((Src) -> Dst?),
_ keyIn: String,
_ keyOut: String

View File

@@ -4,11 +4,10 @@ import SwiftUI
final class VM: ObservableObject {
@Published var text = "a:"
var subscriptions = Set<AnyCancellable>()
var subscriptions = [AnyCancellable]()
init() {
Bus.sendSync(
&subscriptions,
Bus.send(
MeetupId.K.meetupIdTextUI.rawValue,
$text
// Исключаем конфликты от UI и App путём игнорирования спама.
@@ -17,13 +16,15 @@ final class VM: ObservableObject {
.filter { $0.hasPrefix("u:") }
// Убираем источник.
.map { String($0.dropFirst(2)) }
.eraseToAnyPublisher()
.eraseToAnyPublisher(),
sub: &subscriptions
)
Bus.receiveAsync(
&subscriptions,
Bus.receive(
[MeetupId.K.meetupIdTextApp.rawValue],
{ [weak self] (_, v: String) in self?.text = "a:\(v)" }
{ [weak self] (_, v: String) in self?.text = "a:\(v)" },
opt: [.async],
sub: &subscriptions
)
}
}