iwmlib/lib/pixi/deepzoom/tileloader.js

77 lines
2.3 KiB
JavaScript
Raw Normal View History

2019-03-21 09:57:27 +01:00
let loadQueue = []
let requestPool = []
2019-03-21 09:57:27 +01:00
let pendingRequests = new Map()
let requestCount = 0
2019-03-21 09:57:27 +01:00
const batchSize = 8
const debug = false
function recycledXMLHttpRequest() {
// https://nullprogram.com/blog/2013/02/08/
if (requestPool.length > 0) {
return requestPool.pop()
}
requestCount += 1
if (debug) console.log('create XMLHttpRequest', requestCount)
let xhr = new XMLHttpRequest()
return xhr
}
2019-03-21 09:57:27 +01:00
function load() {
2019-08-06 15:34:57 +02:00
while (loadQueue.length > 0 && pendingRequests.size < batchSize) {
2019-03-21 09:57:27 +01:00
let tile = loadQueue.shift()
let [col, row, url] = tile
let xhr = recycledXMLHttpRequest()
xhr.onload = event => {
2019-03-21 09:57:27 +01:00
let buffer = xhr.response
2019-08-06 15:34:57 +02:00
postMessage({ success: true, url, col, row, buffer }, [buffer])
2019-03-21 09:57:27 +01:00
pendingRequests.delete(url)
}
xhr.onerror = event => {
2019-03-21 09:57:27 +01:00
let buffer = null
2019-08-06 15:34:57 +02:00
postMessage({ success: false, url, col, row, buffer })
pendingRequests.delete(url)
2019-03-21 09:57:27 +01:00
}
xhr.onreadystatechange = () => {
// In local files, status is 0 upon success in Mozilla Firefox
if (xhr.readyState === XMLHttpRequest.DONE) {
pendingRequests.delete(url)
requestPool.push(xhr)
if (debug) console.log('resuse XMLHttpRequest')
}
}
if (debug) console.log('open XMLHttpRequest')
2019-03-21 09:57:27 +01:00
xhr.open('GET', url, true)
xhr.responseType = 'arraybuffer'
if (debug) console.log('send XMLHttpRequest')
2019-03-21 09:57:27 +01:00
xhr.send()
pendingRequests.set(url, xhr)
}
2019-08-06 15:34:57 +02:00
if (loadQueue.length > 0) setTimeout(load, 1000 / 120)
2019-03-21 09:57:27 +01:00
else {
if (debug) console.log('tileloader ready')
2019-03-21 09:57:27 +01:00
}
}
self.onmessage = event => {
2019-03-21 09:57:27 +01:00
let msg = event.data
2019-08-06 15:34:57 +02:00
switch (msg.command) {
2019-03-21 09:57:27 +01:00
case 'load':
2019-08-06 15:34:57 +02:00
for (let tile of msg.tiles) {
2019-03-21 09:57:27 +01:00
loadQueue.push(tile)
}
load()
break
case 'abort':
loadQueue = []
requestPool = []
2019-08-06 15:34:57 +02:00
for (let xhr of pendingRequests.values()) {
2019-03-21 09:57:27 +01:00
xhr.abort()
}
pendingRequests.clear()
if (debug) console.log('tileloader aborted')
2019-03-21 09:57:27 +01:00
break
default:
2019-08-06 15:34:57 +02:00
console.warn('Unknown worker command: ' + msg.command)
2019-03-21 09:57:27 +01:00
}
}