UNPKG

@xeokit/xeokit-sdk

Version:

3D BIM IFC Viewer SDK for AEC engineering applications. Open Source JavaScript Toolkit based on pure WebGL for top performance, real-world coordinates and full double precision

74 lines (61 loc) 1.97 kB
/** * @author Deepkolos / https://github.com/deepkolos */ export class WorkerPool { constructor(pool = 4) { this.pool = pool; this.queue = []; this.workers = []; this.workersResolve = []; this.workerStatus = 0; } _initWorker(workerId) { if (!this.workers[workerId]) { const worker = this.workerCreator(); worker.addEventListener('message', this._onMessage.bind(this, workerId)); this.workers[workerId] = worker; } } _getIdleWorker() { for (let i = 0; i < this.pool; i++) if (!(this.workerStatus & (1 << i))) return i; return -1; } _onMessage(workerId, msg) { const resolve = this.workersResolve[workerId]; resolve && resolve(msg); if (this.queue.length) { const {resolve, msg, transfer} = this.queue.shift(); this.workersResolve[workerId] = resolve; this.workers[workerId].postMessage(msg, transfer); } else { this.workerStatus ^= 1 << workerId; } } setWorkerCreator(workerCreator) { this.workerCreator = workerCreator; } setWorkerLimit(pool) { this.pool = pool; } postMessage(msg, transfer) { return new Promise((resolve) => { const workerId = this._getIdleWorker(); if (workerId !== -1) { this._initWorker(workerId); this.workerStatus |= 1 << workerId; this.workersResolve[workerId] = resolve; this.workers[workerId].postMessage(msg, transfer); } else { this.queue.push({resolve, msg, transfer}); } }); } destroy() { this.workers.forEach((worker) => worker.terminate()); this.workersResolve.length = 0; this.workers.length = 0; this.queue.length = 0; this.workerStatus = 0; } }