This commit is contained in:
Михаил Капелько
2023-12-28 12:43:44 +03:00
parent ea661935b5
commit d66e42964d
14 changed files with 47 additions and 1 deletions

14
mod/BusX/BusX.podspec Normal file
View File

@@ -0,0 +1,14 @@
Pod::Spec.new do |s|
s.name = 'BusX'
s.version = '2023.12.28'
s.license = 'IVCS'
s.summary = 'Шина общения элементов приложения'
s.homepage = 'IVCS'
s.author = 'IVCS'
s.source = { :git => 'https://fake.com/FAKE.git', :tag => s.version }
s.source_files = 'src/**/*.swift'
s.swift_version = '5.2'
s.ios.deployment_target = '14.0'
end

View File

@@ -0,0 +1,30 @@
extension Bus {
/// Пропускаем далее предоставленные ключи.
static func convertKeyValue<T>(
_ keys: Set<String>,
_ v: (key: String, value: Any)
) -> (String, T)? {
guard
keys.contains(v.key),
let value = v.value as? T
else {
return nil
}
return (v.key, value)
}
/// Обрабатываем.
static func processKeysValue<Src, Dst>(
_ v: (key: String, value: Any),
_ keysIn: Set<String>,
_ handler: @escaping ((Src) -> Dst?)
) -> Dst? {
guard
keysIn.contains(v.key),
let vIn = v.value as? Src
else {
return nil
}
return handler(vIn)
}
}

View File

@@ -0,0 +1,25 @@
import Combine
public extension Bus {
final class Processor<Src, Dst> {
var subscriptions = [AnyCancellable]()
public init(
_ keyIn: String,
_ keyOut: String,
_ handler: @escaping ((Src) -> Dst?),
opt: [Option] = []
) {
Bus.process([keyIn], keyOut, handler, opt: opt, sub: &subscriptions)
}
public init(
_ keysIn: Set<String>,
_ keyOut: String,
_ handler: @escaping ((Src) -> Dst?),
opt: [Option] = []
) {
Bus.process(keysIn, keyOut, handler, opt: opt, sub: &subscriptions)
}
}
}

View File

@@ -0,0 +1,15 @@
import Combine
public extension Bus {
final class Receiver<T> {
var subscriptions = [AnyCancellable]()
public init(
_ keys: Set<String>,
_ handler: @escaping ((String, T) -> Void),
opt: [Option] = []
) {
Bus.receive(keys, handler, opt: opt, sub: &subscriptions)
}
}
}

View File

@@ -0,0 +1,15 @@
import Combine
public extension Bus {
final class Sender<T> {
var subscriptions = [AnyCancellable]()
public init(
_ key: String,
_ node: AnyPublisher<T, Never>,
opt: [Option] = []
) {
Bus.send(key, node, opt: opt, sub: &subscriptions)
}
}
}

125
mod/BusX/src/Bus.swift Normal file
View File

@@ -0,0 +1,125 @@
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)
}
}