| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 | ( function () {	/** * @author Deepkolos / https://github.com/deepkolos */	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;		}	}	THREE.WorkerPool = WorkerPool;} )();
 |