53 lines
1.5 KiB
JavaScript
53 lines
1.5 KiB
JavaScript
|
|
(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 };
|
||
|
|
})();
|