UNPKG

io3fix

Version:

toolkit for interior apps

118 lines (102 loc) 2.83 kB
// configs var maxConcurrentQueuedRequests = 15 // not queued requests are not limited in running parallel var queuesByPriority = [ 'architectureGeometries', 'architectureTexturesLoRes', 'interiorGeometries', 'interiorTexturesLoRes', 'architectureTexturesHiRes', 'interiorTexturesHiRes' ] var queueFences = [ false, false, true, false, false ] // internals var queues = {} var queueFences = {} var queuesChanged = false var queueInfo = {} var queuesLength = queuesByPriority.length var concurrentRequests = 0 var concurrentPerQueue = {} var queueName for (var i = 0, l = queuesLength; i < l; i++) { queueName = queuesByPriority[i] queues[queueName] = [] queueFences[queueName] = queueFences[i] queueInfo[queueName] = {requestCount: 0} concurrentPerQueue[queueName] = 0 } // private methods function startRequest(queueName) { // Update queue tracking information var info = queueInfo[queueName]; var time = performance.now() / 1000; if (info.timeFirst) { info.timeFirst = time; info.timeLast = time; } else info.timeLast = time; info.requestCount++; // Update concurrent request counts concurrentPerQueue[queueName] += 1; concurrentRequests++; // set flag queuesChanged = true; // Start request var queue = queues[queueName]; var request = queue.shift(); request.start(); } function processQueue() { var anchorStage = null; for (var i = 0; i < queuesLength; i++) { var queueName = queuesByPriority[i]; while (queues[queueName].length > 0 && concurrentRequests < maxConcurrentQueuedRequests) startRequest(queueName) if (anchorStage === null && concurrentPerQueue[queueName] !== 0) anchorStage = i; if (anchorStage !== null && (queueFences[queueName] || (i - anchorStage > 0))) break; } } // public methods function enqueue(queueName, url){ // fallback to first queue if (!queues[queueName]) { if (queueName) console.error('onknown queue ', queueName) queueName = queuesByPriority[0] } // create promise and add to queue return new Promise(function(resolve, reject){ // has to be asynchronous in order to decouple queue processing from synchronous code setTimeout(function(){ var queue = queues[queueName] queue[ queue.length ] = { url: url, start: resolve } processQueue() },1) }) } function dequeue(queueName, url) { var info = queueInfo[queueName]; if (!info) { if (queueName) console.warn('Queue info not found for queue name "'+queueName+'"') return } info.timeLastFinished = performance.now() / 1000; concurrentPerQueue[queueName] -= 1 concurrentRequests -= 1 queuesChanged = true; processQueue() } // expose API var queueManager = { enqueue: enqueue, dequeue: dequeue, info: queueInfo } export default queueManager