d
This commit is contained in:
@@ -22,73 +22,3 @@ class AppDelegate: UIResponder, UIApplicationDelegate
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Bus.Pipe.swift
|
|
||||||
public extension Bus {
|
|
||||||
final class BindingPipe<T: Equatable>: ObservableObject {
|
|
||||||
public let input = PassthroughSubject<T, Never>()
|
|
||||||
public let output = PassthroughSubject<T, Never>()
|
|
||||||
@Published var value: T
|
|
||||||
var isInput = false
|
|
||||||
var subscriptions = [AnyCancellable]()
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
print("ИГР BusBP.DEinit(\(Unmanaged.passUnretained(self).toOpaque()))")
|
|
||||||
}
|
|
||||||
|
|
||||||
init(
|
|
||||||
_ defaultValue: T,
|
|
||||||
_ keyApp: String,
|
|
||||||
_ keyUI: String
|
|
||||||
) {
|
|
||||||
value = defaultValue
|
|
||||||
/**/dbg("ИГР BusBP.init(\(Unmanaged.passUnretained(self).toOpaque())) keyA: '\(keyApp)'")
|
|
||||||
|
|
||||||
// TextField -> output.
|
|
||||||
$value
|
|
||||||
.sink { [weak self] v in
|
|
||||||
assert(Thread.isMainThread)
|
|
||||||
// Ignore values received from input.
|
|
||||||
// Only accept UI provided values.
|
|
||||||
guard
|
|
||||||
let self,
|
|
||||||
!self.isInput
|
|
||||||
else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
self.output.send(v)
|
|
||||||
}
|
|
||||||
.store(in: &subscriptions)
|
|
||||||
|
|
||||||
// input -> TextField.
|
|
||||||
input
|
|
||||||
.sink { [weak self] v in
|
|
||||||
assert(Thread.isMainThread)
|
|
||||||
guard let self else { return }
|
|
||||||
/**/dbg("ИГР BusBP.init input: '\(v)'")
|
|
||||||
self.isInput = true
|
|
||||||
self.value = v
|
|
||||||
self.isInput = false
|
|
||||||
}
|
|
||||||
.store(in: &subscriptions)
|
|
||||||
|
|
||||||
// Оповещаем в мир об изменениях от UI.
|
|
||||||
Bus.sendAsync(
|
|
||||||
&subscriptions,
|
|
||||||
keyUI,
|
|
||||||
output.eraseToAnyPublisher()
|
|
||||||
)
|
|
||||||
|
|
||||||
Bus.receive(
|
|
||||||
&subscriptions,
|
|
||||||
[keyApp],
|
|
||||||
{ [weak self] _, v in
|
|
||||||
self?.input.send(v)
|
|
||||||
/**/print("ИГР BusBP.init receive: '\(v)'")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -24,25 +24,6 @@ extension Bus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public extension Bus {
|
public extension Bus {
|
||||||
static func receive<T>(
|
|
||||||
_ subscriptions: inout Set<AnyCancellable>,
|
|
||||||
_ keys: Set<String>,
|
|
||||||
_ handler: @escaping ((String, T) -> Void)
|
|
||||||
) {
|
|
||||||
Service.singleton?.broadcaster
|
|
||||||
.compactMap { v -> (String, T)? in
|
|
||||||
guard
|
|
||||||
keys.contains(v.key),
|
|
||||||
let value = v.value as? T
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return (v.key, value)
|
|
||||||
}
|
|
||||||
.sink { v in handler(v.0, v.1) }
|
|
||||||
.store(in: &subscriptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func receiveAsync<T>(
|
static func receiveAsync<T>(
|
||||||
_ subscriptions: inout Set<AnyCancellable>,
|
_ subscriptions: inout Set<AnyCancellable>,
|
||||||
_ keys: Set<String>,
|
_ keys: Set<String>,
|
||||||
@@ -63,13 +44,26 @@ public extension Bus {
|
|||||||
.store(in: &subscriptions)
|
.store(in: &subscriptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func send(_ key: String, _ value: Any) {
|
static func receiveSync<T>(
|
||||||
Service.singleton?.send(key, value)
|
_ subscriptions: inout Set<AnyCancellable>,
|
||||||
|
_ keys: Set<String>,
|
||||||
|
_ handler: @escaping ((String, T) -> Void)
|
||||||
|
) {
|
||||||
|
Service.singleton?.broadcaster
|
||||||
|
.compactMap { v -> (String, T)? in
|
||||||
|
guard
|
||||||
|
keys.contains(v.key),
|
||||||
|
let value = v.value as? T
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return (v.key, value)
|
||||||
|
}
|
||||||
|
.sink { v in handler(v.0, v.1) }
|
||||||
|
.store(in: &subscriptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func sendAsync<T>(
|
||||||
/*
|
|
||||||
static func sendAsync<T: Equatable>(
|
|
||||||
_ subscriptions: inout Set<AnyCancellable>,
|
_ subscriptions: inout Set<AnyCancellable>,
|
||||||
_ key: String,
|
_ key: String,
|
||||||
_ node: AnyPublisher<T, Never>
|
_ node: AnyPublisher<T, Never>
|
||||||
@@ -79,5 +73,36 @@ public extension Bus {
|
|||||||
.sink { v in Service.singleton?.send(key, v) }
|
.sink { v in Service.singleton?.send(key, v) }
|
||||||
.store(in: &subscriptions)
|
.store(in: &subscriptions)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func sendOnce(_ key: String, _ value: Any) {
|
||||||
|
Service.singleton?.send(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension Bus {
|
||||||
|
static func registerProcessing<Src, Dst>(
|
||||||
|
_ subscriptions: inout Set<AnyCancellable>,
|
||||||
|
_ keyIn: String,
|
||||||
|
_ keyOut: String,
|
||||||
|
_ handler: @escaping ((Src) -> Dst?)
|
||||||
|
) {
|
||||||
|
Service.singleton?.broadcaster
|
||||||
|
.filter { $0.key == keyIn }
|
||||||
|
.compactMap {
|
||||||
|
guard let vIn = $0.value as? Src else { return nil }
|
||||||
|
return handler(vIn)
|
||||||
|
}
|
||||||
|
.sink { vOut in Service.singleton?.send(keyOut, vOut) }
|
||||||
|
.store(in: &subscriptions)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ enum MeetupId {
|
|||||||
r += "-"
|
r += "-"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if r.hasSuffix("-") {
|
||||||
|
r = String(r.dropLast(1))
|
||||||
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,36 +32,13 @@ enum MeetupId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
Bus.receive(
|
Bus.registerProcessing(
|
||||||
&subscriptions,
|
&subscriptions,
|
||||||
[Keys.meetupIdTextUI.rawValue],
|
Keys.meetupIdTextUI.rawValue,
|
||||||
Self.handleFormatting
|
Keys.meetupIdTextApp.rawValue,
|
||||||
|
MeetupId.shouldFormat
|
||||||
)
|
)
|
||||||
/**/print("ИГР MeetupIF.init")
|
/**/print("ИГР MeetupIF.init")
|
||||||
}
|
}
|
||||||
|
|
||||||
static func handleFormatting(_: String, _ value: String) {
|
|
||||||
let out = MeetupId.shouldFormat(value)
|
|
||||||
/**/print("ИГР MeetupIF.handleF out/dt: '\(out)'/'\(Date())'")
|
|
||||||
Bus.send(Keys.meetupIdTextApp.rawValue, out)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/*
|
|
||||||
struct V: View {
|
|
||||||
/*@StateObject*/ var fmt = MeetupIdFormatter()
|
|
||||||
@StateObject var txt = Bus.BindingPipe("", Keys.meetupIdTextApp.rawValue, Keys.meetupIdTextUI.rawValue)
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
VStack {
|
|
||||||
Text("Hi, the text is: '\(txt.value)'")
|
|
||||||
.fontWeight(.bold)
|
|
||||||
TextField("Placeholder", text: $txt.value)
|
|
||||||
.padding(8)
|
|
||||||
.border(Color.blue, width: 2)
|
|
||||||
}
|
|
||||||
.frame(width: 320)
|
|
||||||
.padding()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ final class VM: ObservableObject {
|
|||||||
var subscriptions = Set<AnyCancellable>()
|
var subscriptions = Set<AnyCancellable>()
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
Bus.sendSync(
|
||||||
|
&subscriptions,
|
||||||
|
MeetupId.Keys.meetupIdTextUI.rawValue,
|
||||||
$text
|
$text
|
||||||
// Исключаем конфликты от UI и App путём игнорирования спама.
|
// Исключаем конфликты от UI и App путём игнорирования спама.
|
||||||
.debounce(for: .seconds(0.3), scheduler: DispatchQueue.main)
|
.debounce(for: .seconds(0.3), scheduler: DispatchQueue.main)
|
||||||
@@ -14,8 +17,8 @@ final class VM: ObservableObject {
|
|||||||
.filter { $0.hasPrefix("u:") }
|
.filter { $0.hasPrefix("u:") }
|
||||||
// Убираем источник.
|
// Убираем источник.
|
||||||
.map { String($0.dropFirst(2)) }
|
.map { String($0.dropFirst(2)) }
|
||||||
.sink { Bus.send(MeetupId.Keys.meetupIdTextUI.rawValue, $0) }
|
.eraseToAnyPublisher()
|
||||||
.store(in: &subscriptions)
|
)
|
||||||
|
|
||||||
Bus.receiveAsync(
|
Bus.receiveAsync(
|
||||||
&subscriptions,
|
&subscriptions,
|
||||||
|
|||||||
Reference in New Issue
Block a user