114 lines
3.1 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Foundation
import Combine
/// 线 Bricks/
/// Bricksdispatch/subscribe
@MainActor
public final class BricksEventBus: ObservableObject {
/// : eventName [callback]
private var handlers: [String: [(EventData) async -> Void]] = [:]
///
@Published public var eventLog: [(name: String, data: EventData, timestamp: Date)] = []
private let maxLogSize = 100
public init() {}
// MARK: -
///
public func on(_ eventName: String, handler: @escaping (EventData) async -> Void) {
if handlers[eventName] == nil {
handlers[eventName] = []
}
handlers[eventName]?.append(handler)
}
///
public func off(_ eventName: String) {
handlers.removeValue(forKey: eventName)
}
// MARK: -
///
public func dispatch(_ eventName: String, data: EventData = EventData()) async {
//
eventLog.append((name: eventName, data: data, timestamp: Date()))
if eventLog.count > maxLogSize {
eventLog.removeFirst()
}
// handler
if let callbacks = handlers[eventName] {
for callback in callbacks {
await callback(data)
}
}
}
/// UI
public func dispatchSync(_ eventName: String, data: EventData = EventData()) {
Task { @MainActor in
await dispatch(eventName, data: data)
}
}
// MARK: -
public func hasSubscribers(_ eventName: String) -> Bool {
!(handlers[eventName]?.isEmpty ?? true)
}
public func subscriberCount(_ eventName: String) -> Int {
handlers[eventName]?.count ?? 0
}
}
///
public struct EventData: Sendable {
private var storage: [String: Any]
public init(_ dict: [String: Any] = [:]) {
self.storage = dict
}
public subscript(key: String) -> Any? {
get { storage[key] }
set { storage[key] = newValue }
}
public var asDictionary: [String: Any] { storage }
/// EventData
public func merged(with other: EventData) -> EventData {
var result = EventData()
for (k, v) in storage { result[k] = v }
for (k, v) in other.storage { result[k] = v }
return result
}
///
public static func from(_ dict: [String: Any]) -> EventData {
EventData(dict)
}
}
// MARK: -
public enum BricksEvent {
public static let click = "click"
public static let submit = "submit"
public static let change = "change"
public static let select = "select"
public static let load = "load"
public static let render = "render"
public static let close = "close"
public static let open = "open"
public static let toggle = "toggle"
public static let refresh = "refresh"
public static let navigate = "navigate"
}