Last active
October 30, 2018 17:38
-
-
Save pankkor/3022bf923ccc78c4a3ddf64edab87162 to your computer and use it in GitHub Desktop.
Quick sketch of 2 Event implementations
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
enum EventTest { | |
// + brain dead simple | |
// - need to manually unsubscribe | |
class Event<Args> { | |
typealias CallbackType = (Args) -> Void | |
private var id: UInt64 = 0 | |
private var callbacks = [UInt64: CallbackType]() | |
func subscribe(_ callback: @escaping CallbackType) -> UInt64 { | |
// next free id | |
while callbacks[id] != nil { | |
id += 1 | |
} | |
callbacks[id] = callback | |
return id | |
} | |
func unsubscribe(_ id: UInt64) { | |
callbacks[id] = nil | |
} | |
func raise(_ args: Args) { | |
callbacks.values.forEach { $0(args) } | |
} | |
} | |
static func testEvent() { | |
let event = Event<(Int, Int)>() | |
let disposableId1 = event.subscribe { v in | |
print("subscriber 1 - \(v.0) \(v.1)") | |
} | |
let disposableId2 = event.subscribe { v in | |
print("subscriber 2 - \(v.0) \(v.1)") | |
} | |
event.raise((13, 42)) | |
event.unsubscribe(disposableId1) | |
event.unsubscribe(disposableId2) | |
} | |
// + brain dead simple | |
// + no need to manually unsubscribe | |
final class AutoDisposable { | |
private var disposeHandler: (() -> ())? | |
init(_ disposeHandler: @escaping () -> ()) { | |
self.disposeHandler = disposeHandler | |
} | |
deinit { | |
dispose() | |
} | |
func dispose() { | |
disposeHandler?() | |
disposeHandler = nil | |
} | |
} | |
class Event2<Args> { | |
typealias CallbackType = (Args) -> Void | |
private var id: UInt64 = 0 | |
private var callbacks = [UInt64: CallbackType]() | |
func subscribe(_ callback: @escaping CallbackType) -> AutoDisposable { | |
// next free id | |
while callbacks[id] != nil { | |
id += 1 | |
} | |
callbacks[id] = callback | |
let callbackID = id // copy callback id to local constant | |
return AutoDisposable { [weak self] in | |
self?.callbacks[callbackID] = nil | |
} | |
} | |
func raise(_ args: Args) { | |
callbacks.values.forEach { $0(args) } | |
} | |
} | |
static func testEvent2() { | |
let event = Event2<(Int, Int)>() | |
do { | |
let disposable1 = event.subscribe { v in | |
print("subscriber 1 - \(v.0) \(v.1)") | |
} | |
} // <- disposable1 leaves scope is deinited and unsubscription happens | |
let disposable2 = event.subscribe { v in | |
print("subscriber 2 - \(v.0) \(v.1)") | |
} | |
event.raise((13, 42)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment