@logic-pad/core
Version:
55 lines (54 loc) • 1.92 kB
JavaScript
import { Serializer } from '../serializer/allSerializers.js';
import Solver from './solver.js';
import { EventIterator } from 'event-iterator';
export default class EventIteratingSolver extends Solver {
supportsCancellation = true;
isEnvironmentSupported() {
try {
const worker = this.createWorker();
worker.terminate();
return Promise.resolve(true);
}
catch (_ex) {
return Promise.resolve(false);
}
}
async *solve(grid, abortSignal) {
const worker = this.createWorker();
let terminateHandler;
try {
const iterator = new EventIterator(({ push, stop, fail }) => {
terminateHandler = () => {
worker.terminate();
stop();
};
abortSignal?.addEventListener('abort', terminateHandler);
worker.postMessage(Serializer.stringifyGrid(grid.resetTiles()));
worker.addEventListener('message', (e) => {
if (e.data) {
push(Serializer.parseGrid(e.data));
}
else if (e.data === null) {
push(null);
stop(); // Stop after the first signal for out of solutions
}
else {
stop();
}
});
worker.addEventListener('error', (e) => {
alert(`Error while solving!\n${e.message}`);
fail(e);
});
});
for await (const solution of iterator) {
yield solution;
}
}
finally {
worker.terminate();
if (terminateHandler)
abortSignal?.removeEventListener('abort', terminateHandler);
}
}
}