You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
1.4 KiB
JavaScript

class InputQueue {
#queue = [];
#listeners = [];
#object_timeout;
#get_timeout;
constructor(object_timeout, get_timeout){
this.#object_timeout = object_timeout;
this.#get_timeout = get_timeout;
}
get length() {
return this.#queue.length;
}
clear() {
this.#queue.clear();
}
put(type, data) {
const timer = setTimeout(() => {
Array_remove(this.#queue, value);
}, this.#object_timeout);
const value = { type, data, timer };
this.#queue.push(value);
this.#flush();
return this.length;
}
async get(types) {
let timed_out = false;
let release = () => {};
setTimeout(() => {
timed_out = true;
release();
}, this.#get_timeout);
while (!timed_out) {
const value = this.#getIfMatches(types);
if (value) return [value.type, value.data];
const e = makeWaiter();
release = e.resolve;
this.#listeners.push(release);
await e.wait;
}
throw new TimeoutError();
}
#getIfMatches(types) {
for (let i = 0; i < this.#queue.length; i++) {
const value = this.#queue[i];
if (types.includes(value.type)) {
this.#queue.splice(i, 1);
clearTimeout(value.timer);
return value;
}
}
return undefined;
}
#flush() {
while (this.#listeners.length > 0) {
this.#listeners.shift()();
}
}
}