UNPKG

@soapbox.pub/wasmboy

Version:

Soapbox fork of Wasmboy.

99 lines (83 loc) 3.12 kB
// WasmBoy Modules import { WasmBoyGraphics } from '../graphics/graphics'; import { WasmBoyAudio } from '../audio/audio'; import { WasmBoyController } from '../controller/controller'; import { WasmBoyMemory } from '../memory/memory'; // Import our Smart Worker Interface import { SmartWorker } from './smartworker'; import { WORKER_MESSAGE_TYPE, WORKER_ID } from './constants'; export const instantiateWorkers = async () => { const libWorker = new SmartWorker( new Worker(new URL('worker/wasmboy.wasm.worker.js', import.meta.url), { type: 'module' }), WORKER_ID.LIB ); const graphicsWorker = new SmartWorker( new Worker(new URL('worker/graphics.worker.js', import.meta.url), { type: 'module' }), WORKER_ID.GRAPHICS ); const audioWorker = new SmartWorker(new Worker(new URL('worker/audio.worker.js', import.meta.url), { type: 'module' }), WORKER_ID.AUDIO); const controllerWorker = new SmartWorker( new Worker(new URL('worker/controller.worker.js', import.meta.url), { type: 'module' }), WORKER_ID.CONTROLLER ); const memoryWorker = new SmartWorker( new Worker(new URL('worker/memory.worker.js', import.meta.url), { type: 'module' }), WORKER_ID.MEMORY ); // Create an array of promises for when each worker is ready const workerReadyPromises = []; // Add our workers to an array, const childWorkers = [graphicsWorker, audioWorker, controllerWorker, memoryWorker]; // Create a messaging channel between our main lib worker, // And all of the children workers childWorkers.forEach(childWorker => { // Create our message channel // https://stackoverflow.com/questions/14191394/web-workers-communication-using-messagechannel-html5 const messageChannel = new MessageChannel(); const workerReadyPromise = new Promise(resolve => { // Our resolve function let messagesReceived = 0; const tryResolveWorkerReady = () => { messagesReceived++; if (messagesReceived >= 2) { resolve(); } }; // Post our connect messages libWorker .postMessage( { type: WORKER_MESSAGE_TYPE.CONNECT, workerId: childWorker.id, ports: [messageChannel.port1] }, [messageChannel.port1] ) .then(() => { tryResolveWorkerReady(); }); childWorker .postMessage( { type: WORKER_MESSAGE_TYPE.CONNECT, workerId: libWorker.id, ports: [messageChannel.port2] }, [messageChannel.port2] ) .then(() => { tryResolveWorkerReady(); }); }); workerReadyPromises.push(workerReadyPromise); }); // Wait for all workers to be ready await Promise.all(workerReadyPromises); // Finally, pass the ready workers to all of our children lib WasmBoyGraphics.setWorker(graphicsWorker); WasmBoyAudio.setWorker(audioWorker); WasmBoyController.setWorker(controllerWorker); WasmBoyMemory.setWorker(memoryWorker); // Return the main worker for the main lib return libWorker; };