Skip to content

Instantly share code, notes, and snippets.

@Danappelxx
Last active November 19, 2020 16:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Danappelxx/b42730ab47f21ca171ee to your computer and use it in GitHub Desktop.
Save Danappelxx/b42730ab47f21ca171ee to your computer and use it in GitHub Desktop.
class EventListener<T> {
typealias Listener = T -> ()
let listener: Listener
var calls: Int
init(calls: Int, listener: Listener) {
self.calls = calls
self.listener = listener
}
func call(event: T) {
calls -= 1
if calls == 0 { // -1 passes the test
active = false
}
listener(event)
}
var active = true
func stop() {
active = false
}
}
protocol EventEmitter: class {
typealias T
var listeners: [EventListener<T>] { get set }
func listen(times times: Int, listener: T -> Void) -> EventListener<T>
func send(event: T)
}
extension EventEmitter {
func listen(times times: Int = -1, listener: EventListener<T>.Listener) -> EventListener<T> {
let listener = EventListener<T>(calls: times, listener: listener)
listeners.append(listener)
return listener
}
func send(event: T) {
listeners
.filter { $0.active }
.forEach {
$0.call(event)
}
}
}
class Emitter: EventEmitter {
var listeners = [EventListener<Int>]()
}
var emitter = Emitter()
let first = emitter.listen { event in
print("forever:", event)
}
emitter.listen(times: 3) { event in
print("three:", event)
}
emitter.listen(times: 1) { event in
print("once:", event)
}
emitter.send(10) // first, second, third
emitter.send(15) // first, second
emitter.send(20) // first, second
emitter.send(25) // first
emitter.send(30) // first
first.stop()
emitter.send(35) // none
/*
prints:
forever: 10
three: 10
once: 10
forever: 15
three: 15
forever: 20
three: 20
forever: 25
forever: 30
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment