Skip to content

Instantly share code, notes, and snippets.

@pgherveou
Last active August 29, 2015 14:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pgherveou/95c2fea6c2591b124882 to your computer and use it in GitHub Desktop.
Save pgherveou/95c2fea6c2591b124882 to your computer and use it in GitHub Desktop.
event emitter in swift
private var autoId: Int = 1
// MARK: Subscription Protocol
protocol Subscription {
func remove()
}
// MARK: AbstractSubscription<T>
class AbstractSubscription<T>: Subscription {
// MARK: typealias
typealias Handler = (T) -> Void
// MARK: properties
let handler: Handler
private let emitter: Emitter
private let eventType: String
private let key: Int
// MARK: initializers
init(emitter: Emitter, eventType: String, handler: Handler) {
key = autoId++
self.eventType = eventType
self.emitter = emitter
self.eventType = eventType
self.handler = handler
}
// MARK: Methods
func remove() {
emitter.subscriptions[eventType]?.removeValueForKey(key)
}
}
// MARK: Emitter
class Emitter {
// MARK: properties
private var currentSubscription: Subscription?
private var subscriptions: [String: [Int:Subscription]] = [:]
// MARK: methods
func on<T>(eventType: String, handler: (T) -> Void) -> Subscription {
var eventSubscriptions: [Int:Subscription]
if let values = subscriptions[eventType] {
eventSubscriptions = values
} else {
eventSubscriptions = [:]
}
let subscription = AbstractSubscription<T>(
emitter: self,
eventType: eventType,
handler: handler
)
eventSubscriptions[subscription.key] = subscription
subscriptions[eventType] = eventSubscriptions
return subscription
}
func once<T>(event: String, handler: (T) -> Void) {
on(event) { (data: T) -> Void in
self.currentSubscription?.remove()
handler(data)
}
}
func removeAllListeners(eventType: String?) {
if let eventType = eventType {
subscriptions.removeValueForKey(eventType)
} else {
subscriptions.removeAll()
}
}
func emit<T>(event: String, _ data: T) {
if let subscriptions = subscriptions[event] {
for (_, subscription) in subscriptions {
currentSubscription = subscription
(subscription as AbstractSubscription<T>).handler(data)
}
}
}
}
@pgherveou
Copy link
Author

let emitter = Emitter()
let subscription = emitter.on<String>("foo", { println("received foo event: \($0)") })
emitter.emit<String>("foo", "bar")
// print received foo event bar
subscription.remove()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment