2019-03-21 09:57:27 +01:00
|
|
|
let loadQueue = []
|
2024-05-24 10:29:24 +02:00
|
|
|
let requestPool = []
|
2019-03-21 09:57:27 +01:00
|
|
|
let pendingRequests = new Map()
|
2024-05-24 10:29:24 +02:00
|
|
|
let requestCount = 0
|
2019-03-21 09:57:27 +01:00
|
|
|
const batchSize = 8
|
|
|
|
const debug = false
|
|
|
|
|
2024-05-24 10:29:24 +02:00
|
|
|
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
|
2024-05-24 10:29:24 +02:00
|
|
|
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)
|
2024-05-24 10:29:24 +02:00
|
|
|
}
|
|
|
|
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 })
|
2024-05-24 10:29:24 +02:00
|
|
|
pendingRequests.delete(url)
|
2019-03-21 09:57:27 +01:00
|
|
|
}
|
2024-05-24 10:29:24 +02: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)
|
2024-05-24 10:29:24 +02:00
|
|
|
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 {
|
2024-05-24 10:29:24 +02:00
|
|
|
if (debug) console.log('tileloader ready')
|
2019-03-21 09:57:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-24 10:29:24 +02: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 = []
|
2024-05-24 10:29:24 +02:00
|
|
|
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()
|
|
|
|
}
|
2024-05-24 10:29:24 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|