Last active
March 22, 2021 20:18
-
-
Save lorenalexm/c987d3237ecceedabad7ecd9773ca972 to your computer and use it in GitHub Desktop.
The work on porting the UnityMessenger (https://github.com/lorenalexm/UnityMessenger) from C# to Swift using Silver.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MARK: Placeholder, replace with real types | |
public enum EventType { | |
case notSet | |
} | |
// MARK: Delegate type aliases | |
public typealias Callback = () -> () | |
public typealias Callback<T> = (arg: T) -> () | |
// MARK: Event exceptions | |
public class HandlerException: Exception { | |
/// Constructor to forward message to base Exception class | |
/// - parameter message: The message to be thrown with the exception | |
init(_ message: String) { | |
super.init(message) | |
} | |
} | |
public class BroadcastException: Exception { | |
/// Constructor to forward message to base Exception class | |
/// - parameter message: The message to be thrown with the exception | |
init(_ message: String) { | |
super.init(message) | |
} | |
} | |
static internal class EventsManager { | |
// MARK: Fields | |
static var eventTable: [EventType:Delegate] = [:] | |
// MARK: Class functions | |
/// Adds event KVP to the table if not already present | |
/// - parameter type: Key for the event | |
/// - parameter handler: Delegate response for the event | |
static func onAdding(_ type: EventType, handler: Delegate) { | |
if eventTable.keys.contains(type) == false { | |
_ = eventTable.updateValue(handler, forKey: type) | |
} | |
var delegate: Delegate = eventTable[type] | |
if delegate != nil && delegate.GetType() != handler.GetType() { | |
throw HandlerException("Attempting to add handler with inconsistent signatures for event type \(type).") | |
} | |
} | |
/// Removes event KVP from table if delegate is no longer assigned | |
/// - parameter type: Key for the event | |
/// - parameter handler: Delegate response for the event | |
static func onRemoved(_ type: EventType, handler: Delegate) { | |
var delegate: Delegate? = eventTable[type] | |
if delegate == nil { | |
_ = eventTable.removeValue(forKey: type) | |
} | |
} | |
/// Checks if the KVP exists within the table, throws a BroadcastException if not | |
/// - parameter type: Key for the event | |
static func onBroadcasting(type: EventType) { | |
if eventTable.keys.contains(type) == false { | |
throw BroadcastException("Broadcasting event \(type), but no listeners are found.") | |
} | |
} | |
/// Creates a new BroadcastException for signature mismatches | |
/// - parameter type: The EventType the broadcast was sent with | |
static public func signatureExceptionFor(_ type: EventType) -> BroadcastException { | |
BroadcastException("Broadcasting event \(type) but listeners have a different signature than the broadcaster.") | |
} | |
} | |
static public class Events { | |
// MARK: Fields | |
static private var eventTable: [EventType:Delegate] = EventsManager.eventTable | |
//MARK: Class functions | |
/// Adds the Callback handler to the event table | |
/// - parameter type: Event to which the handler will be added | |
/// - parameter handler: Handler to be called when event is received | |
public static func addHandler(type: EventType, handler: Callback) { | |
EventsManager.onAdding(type, handler: handler) | |
eventTable[type] += handler | |
} | |
/// Removes the Callback handler from the event table | |
/// - parameter type: Event from which the handler will be removed | |
/// - parameter handler: Handler to be called when event is received | |
public static func removeHandler(type: EventType, handler: Callback) { | |
eventTable[type] -= handler | |
EventsManager.onRemoved(type, handler: handler) | |
} | |
/// Broadcasts an event to all handlers | |
/// - parameter type: Event to broadcast | |
public static func broadcast(type: EventType) { | |
let callback: Callback = eventTable[type] as! Callback | |
if callback != nil { | |
callback() | |
} else { | |
throw EventsManager.signatureExceptionFor(type) | |
} | |
} | |
} | |
static public class Events<T> { | |
// MARK: Fields | |
static private var eventTable: [EventType:Delegate] = EventsManager.eventTable | |
// MARK: Class functions | |
/// Adds the Callback handler to the event table | |
/// - parameter type: Event to which the handler will be added | |
/// - parameter handler: Handler to be called when event is received | |
public static func addHandler(type: EventType, handler: Callback<T>) { | |
EventsManager.onAdding(type, handler: handler) | |
eventTable[type] += handler | |
} | |
/// Removes the Callback handler from the event table | |
/// - parameter type: Event from which the handler will be removed | |
/// - parameter handler: Handler to be called when event is received | |
public static func removeHandler(type: EventType, handler: Callback<T>) { | |
eventTable[type] -= handler | |
EventsManager.onRemoved(type, handler: handler) | |
} | |
/// Broadcasts an event to all handlers | |
/// - parameter type: Event to broadcast | |
/// - parameter argument: Argument to be passed along with the event | |
public static func broadcast(type: EventType, argument: T) { | |
let callback: Callback<T> = eventTable[type] as! Callback<T> | |
if callback != nil { | |
callback(argument) | |
} else { | |
throw EventsManager.signatureExceptionFor(type) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment