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() } }