hydrogen-web/src/utils/EventEmitter.js

81 lines
2.1 KiB
JavaScript

export class EventEmitter {
constructor() {
this._handlersByName = {};
}
emit(name, ...values) {
const handlers = this._handlersByName[name];
if (handlers) {
for(const h of handlers) {
h(...values);
}
}
}
disposableOn(name, callback) {
this.on(name, callback);
return () => {
this.off(name, callback);
}
}
on(name, callback) {
let handlers = this._handlersByName[name];
if (!handlers) {
this.onFirstSubscriptionAdded(name);
this._handlersByName[name] = handlers = new Set();
}
handlers.add(callback);
}
off(name, callback) {
const handlers = this._handlersByName[name];
if (handlers) {
handlers.delete(callback);
if (handlers.length === 0) {
delete this._handlersByName[name];
this.onLastSubscriptionRemoved(name);
}
}
}
onFirstSubscriptionAdded(name) {}
onLastSubscriptionRemoved(name) {}
}
export function tests() {
return {
test_on_off(assert) {
let counter = 0;
const e = new EventEmitter();
const callback = () => counter += 1;
e.on("change", callback);
e.emit("change");
e.off("change", callback);
e.emit("change");
assert.equal(counter, 1);
},
test_emit_value(assert) {
let value = 0;
const e = new EventEmitter();
const callback = (v) => value = v;
e.on("change", callback);
e.emit("change", 5);
e.off("change", callback);
assert.equal(value, 5);
},
test_double_on(assert) {
let counter = 0;
const e = new EventEmitter();
const callback = () => counter += 1;
e.on("change", callback);
e.on("change", callback);
e.emit("change");
e.off("change", callback);
assert.equal(counter, 1);
}
};
}