| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 | /** * @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 } );			}		} );	}	dispose () {		this.workers.forEach( ( worker ) => worker.terminate() );		this.workersResolve.length = 0;		this.workers.length = 0;		this.queue.length = 0;		this.workerStatus = 0;	}}
 |