Михаил Капелько 10 ay önce
ebeveyn
işleme
880c4f3dee
2 değiştirilmiş dosya ile 74 ekleme ve 45 silme
  1. +66
    -38
      src/Bus.swift
  2. +8
    -7
      src/VM.swift

+ 66
- 38
src/Bus.swift Dosyayı Görüntüle

@@ -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)

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>,
_ key: String,
_ node: AnyPublisher<T, Never>
) {
node
.receive(on: DispatchQueue.main)
.sink { v in Service.singleton.send(key, v) }
.store(in: &subscriptions)
// 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 sendSync<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
.sink { v in Service.singleton.send(key, v) }
.store(in: &subscriptions)
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) {
@@ -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


+ 8
- 7
src/VM.swift Dosyayı Görüntüle

@@ -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
)
}
}

Yükleniyor…
İptal
Kaydet