d
This commit is contained in:
14
mod/BusX/BusX.podspec
Normal file
14
mod/BusX/BusX.podspec
Normal 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
|
||||
30
mod/BusX/src/Bus.Aux.swift
Normal file
30
mod/BusX/src/Bus.Aux.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
25
mod/BusX/src/Bus.Processor.swift
Normal file
25
mod/BusX/src/Bus.Processor.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
15
mod/BusX/src/Bus.Receiver.swift
Normal file
15
mod/BusX/src/Bus.Receiver.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
15
mod/BusX/src/Bus.Sender.swift
Normal file
15
mod/BusX/src/Bus.Sender.swift
Normal 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
125
mod/BusX/src/Bus.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user