Created
April 1, 2016 02:08
-
-
Save loganwright/c2db2d6ec7c4ca4a8a4ed8df604d0af6 to your computer and use it in GitHub Desktop.
Simple Events
This file contains hidden or 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
/** | |
This class is used to keep a subscription to an event active. | |
Set all references to `nil` to no longer receive events | |
*/ | |
public final class Subscription { | |
/** | |
Completiont to run on deinit. | |
- Warning: This should only be used by an event to clear the subscription on deinitialization | |
*/ | |
private var completion: Void -> Void = {} | |
deinit { | |
completion() | |
} | |
} | |
/** | |
This class can be used to create event hubs where data | |
can be posted to multiple subscribers. | |
First create a global event hub or associate it with | |
a specific class | |
let BatteryEvent = Event<BatteryLevel>() | |
Then, subscribe to that event | |
// Must retain subscription to keep receiving events! | |
self.subscription = BatteryEvent.subscribe { level in | |
print("Battery level is now: \(level) | |
} | |
Whenever someone has access to the event, they can post data to it like so: | |
BatteryEvent.post(80) | |
*/ | |
public final class Event<T> { | |
/// Closure called when event emits | |
public typealias Handler = T -> Void | |
/// A subscriber tuple | |
private typealias Subscriber = (token: Subscription, handler: Handler) | |
/// The current subscribers for this event | |
private var subscribers: [Subscriber] = [] | |
/** | |
Adds a subscriber for this event with a handler to fire on post. | |
- Warning: subscription returned from this function must be retained to receive events | |
- returns: as long as the subscription is retained, the passed handler will fire | |
*/ | |
@warn_unused_result(message="subscription must be retained to receive events") | |
public func subscribe(handler: Handler) -> Subscription { | |
let newToken = Subscription() | |
subscribers.append((newToken, handler)) | |
newToken.completion = { [weak self] in | |
guard let welf = self else { return } | |
welf.subscribers = welf.subscribers.filter { token, _ in | |
return token !== newToken | |
} | |
} | |
return newToken | |
} | |
/** | |
Post an event to all subscribers. | |
- parameter data: the data to be passed to subscribers | |
*/ | |
public func post(data: T) { | |
subscribers.forEach { _, handler in handler(data) } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment