pixel/js/worker-client.js

53 lines
1.5 KiB
JavaScript
Raw Normal View History

2026-06-04 16:40:45 +09:00
(function () {
'use strict';
const root = window.PixelIslandModules ||= {};
let worker = null;
let nextId = 1;
const pending = new Map();
function canUseWorkers() {
return typeof Worker === 'function';
}
function getWorker() {
if (!canUseWorkers()) return null;
if (worker) return worker;
worker = new Worker('./js/pixel-worker.js');
worker.onmessage = (event) => {
const { id, ok, result, error } = event.data || {};
const entry = pending.get(id);
if (!entry) return;
pending.delete(id);
if (ok) entry.resolve(result);
else entry.reject(new Error(error || 'worker_error'));
};
worker.onerror = (event) => {
const error = new Error(event.message || 'worker_error');
for (const entry of pending.values()) entry.reject(error);
pending.clear();
worker?.terminate();
worker = null;
};
return worker;
}
function request(type, payload) {
const target = getWorker();
if (!target) return Promise.reject(new Error('workers_unavailable'));
const id = nextId++;
const promise = new Promise((resolve, reject) => pending.set(id, { resolve, reject }));
target.postMessage({ id, type, payload });
return promise;
}
function buildPixelBlobs(assets) {
return request('buildPixelBlobs', {
assets,
palette: root.Palette?.PALETTE || [],
defaultColorCode: root.Palette?.DEFAULT_SELECTED_COLOR_CODE || 'a'
});
}
root.WorkerClient = { canUseWorkers, buildPixelBlobs };
})();