diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2020-11-23 12:38:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-23 12:38:17 +0100 |
commit | 50db0e66ac8c00f176c706cee0c3a5469453acce (patch) | |
tree | 8ef45399f10c32b5dad742cf30180b569519cb70 /platform/javascript/js/engine/preloader.js | |
parent | 18023cc3ede6fd84842db77019085c383e807016 (diff) | |
parent | 4617a7fa9cea323978f14053ef2726c84e9bd267 (diff) | |
download | redot-engine-50db0e66ac8c00f176c706cee0c3a5469453acce.tar.gz |
Merge pull request #43747 from Faless/js/4.0_lint
[HTML5] Linting, fixes.
Diffstat (limited to 'platform/javascript/js/engine/preloader.js')
-rw-r--r-- | platform/javascript/js/engine/preloader.js | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/platform/javascript/js/engine/preloader.js b/platform/javascript/js/engine/preloader.js new file mode 100644 index 0000000000..ec34fb93f2 --- /dev/null +++ b/platform/javascript/js/engine/preloader.js @@ -0,0 +1,127 @@ +const Preloader = /** @constructor */ function () { // eslint-disable-line no-unused-vars + const loadXHR = function (resolve, reject, file, tracker, attempts) { + const xhr = new XMLHttpRequest(); + tracker[file] = { + total: 0, + loaded: 0, + final: false, + }; + xhr.onerror = function () { + if (attempts <= 1) { + reject(new Error(`Failed loading file '${file}'`)); + } else { + setTimeout(function () { + loadXHR(resolve, reject, file, tracker, attempts - 1); + }, 1000); + } + }; + xhr.onabort = function () { + tracker[file].final = true; + reject(new Error(`Loading file '${file}' was aborted.`)); + }; + xhr.onloadstart = function (ev) { + tracker[file].total = ev.total; + tracker[file].loaded = ev.loaded; + }; + xhr.onprogress = function (ev) { + tracker[file].loaded = ev.loaded; + tracker[file].total = ev.total; + }; + xhr.onload = function () { + if (xhr.status >= 400) { + if (xhr.status < 500 || attempts <= 1) { + reject(new Error(`Failed loading file '${file}': ${xhr.statusText}`)); + xhr.abort(); + } else { + setTimeout(function () { + loadXHR(resolve, reject, file, tracker, attempts - 1); + }, 1000); + } + } else { + tracker[file].final = true; + resolve(xhr); + } + }; + // Make request. + xhr.open('GET', file); + if (!file.endsWith('.js')) { + xhr.responseType = 'arraybuffer'; + } + xhr.send(); + }; + + const DOWNLOAD_ATTEMPTS_MAX = 4; + const loadingFiles = {}; + const lastProgress = { loaded: 0, total: 0 }; + let progressFunc = null; + + const animateProgress = function () { + let loaded = 0; + let total = 0; + let totalIsValid = true; + let progressIsFinal = true; + + Object.keys(loadingFiles).forEach(function (file) { + const stat = loadingFiles[file]; + if (!stat.final) { + progressIsFinal = false; + } + if (!totalIsValid || stat.total === 0) { + totalIsValid = false; + total = 0; + } else { + total += stat.total; + } + loaded += stat.loaded; + }); + if (loaded !== lastProgress.loaded || total !== lastProgress.total) { + lastProgress.loaded = loaded; + lastProgress.total = total; + if (typeof progressFunc === 'function') { + progressFunc(loaded, total); + } + } + if (!progressIsFinal) { + requestAnimationFrame(animateProgress); + } + }; + + this.animateProgress = animateProgress; + + this.setProgressFunc = function (callback) { + progressFunc = callback; + }; + + this.loadPromise = function (file) { + return new Promise(function (resolve, reject) { + loadXHR(resolve, reject, file, loadingFiles, DOWNLOAD_ATTEMPTS_MAX); + }); + }; + + this.preloadedFiles = []; + this.preload = function (pathOrBuffer, destPath) { + let buffer = null; + if (typeof pathOrBuffer === 'string') { + const me = this; + return this.loadPromise(pathOrBuffer).then(function (xhr) { + me.preloadedFiles.push({ + path: destPath || pathOrBuffer, + buffer: xhr.response, + }); + return Promise.resolve(); + }); + } else if (pathOrBuffer instanceof ArrayBuffer) { + buffer = new Uint8Array(pathOrBuffer); + } else if (ArrayBuffer.isView(pathOrBuffer)) { + buffer = new Uint8Array(pathOrBuffer.buffer); + } + if (buffer) { + this.preloadedFiles.push({ + path: destPath, + buffer: pathOrBuffer, + }); + return Promise.resolve(); + } + return Promise.reject(new Error('Invalid object for preloading')); + }; +}; |