CabinGame/Luxe/math/event.wren

103 lines
No EOL
2.2 KiB
Text

import "math/util" for Util
//my own event class because Events does too much with its tags and too little with disposing
class Event{
construct new(){
_listeners = {}
_listenersOnce = {}
_index = -1
}
listen(fn){
_index = _index + 1
_listeners[_index] = fn
return ListenerToken.new(this, _index)
}
listenOnce(fn){
_index = _index + 1
_listenersOnce[_index] = fn
return ListenerToken.new(this, _index)
}
unlisten(id){
if(id is Num) {
var removed = false
removed = removed || _listeners.remove(id)
removed = removed || _listenersOnce.remove(id)
if(!removed){
Log.print("[warn] tried to remove unknown listener id")
}
} else if(id is Fn){
var removed = false
for(index in _listeners.keys){
if(_listeners[index] == id){
//! this might lead to problems because I'm modifying the thing I'm iterating over
//in that case we need to defer the removal
_listeners.remove(index)
removed = true
}
}
if(!removed){
Log.print("[warn] tried to remove unknown listener fn")
}
} else if(id is ListenerToken) {
id.discard()
} else {
Log.print("[warn] how is a %(id.type.name) related to the listener? pass the listener index or function.")
}
}
emit(arguments){
_listeners.each{|val|
Util.call_arg_list(val.value, arguments)
}
_listenersOnce.each{|val|
Util.call_arg_list(val.value, arguments)
}
_listenersOnce.clear()
}
}
class ListenerToken{
event{_event}
index{_index}
construct new(event, index){
_event = event
_index = index
}
discard(){
event.unlisten(index)
}
}
class MultiListenerToken{
events{_events}
indices{_indices}
construct new(){
_events = []
_indices = []
}
construct new(tokens){
_events = []
_indices = []
tokens.each{|token| add(token)}
}
add(token){
_events.add(token.event)
_indices.add(token.index)
}
discard(){
Util.for_all([events, indices]) {|event, index|
event.unlisten(index)
}
events.clear()
indices.clear()
}
}