Path: blob/master/platform/web/js/engine/preloader.js
10279 views
const Preloader = /** @constructor */ function () { // eslint-disable-line no-unused-vars1function getTrackedResponse(response, load_status) {2function onloadprogress(reader, controller) {3return reader.read().then(function (result) {4if (load_status.done) {5return Promise.resolve();6}7if (result.value) {8controller.enqueue(result.value);9load_status.loaded += result.value.length;10}11if (!result.done) {12return onloadprogress(reader, controller);13}14load_status.done = true;15return Promise.resolve();16});17}18const reader = response.body.getReader();19return new Response(new ReadableStream({20start: function (controller) {21onloadprogress(reader, controller).then(function () {22controller.close();23});24},25}), { headers: response.headers });26}2728function loadFetch(file, tracker, fileSize, raw) {29tracker[file] = {30total: fileSize || 0,31loaded: 0,32done: false,33};34return fetch(file).then(function (response) {35if (!response.ok) {36return Promise.reject(new Error(`Failed loading file '${file}'`));37}38const tr = getTrackedResponse(response, tracker[file]);39if (raw) {40return Promise.resolve(tr);41}42return tr.arrayBuffer();43});44}4546function retry(func, attempts = 1) {47function onerror(err) {48if (attempts <= 1) {49return Promise.reject(err);50}51return new Promise(function (resolve, reject) {52setTimeout(function () {53retry(func, attempts - 1).then(resolve).catch(reject);54}, 1000);55});56}57return func().catch(onerror);58}5960const DOWNLOAD_ATTEMPTS_MAX = 4;61const loadingFiles = {};62const lastProgress = { loaded: 0, total: 0 };63let progressFunc = null;6465const animateProgress = function () {66let loaded = 0;67let total = 0;68let totalIsValid = true;69let progressIsFinal = true;7071Object.keys(loadingFiles).forEach(function (file) {72const stat = loadingFiles[file];73if (!stat.done) {74progressIsFinal = false;75}76if (!totalIsValid || stat.total === 0) {77totalIsValid = false;78total = 0;79} else {80total += stat.total;81}82loaded += stat.loaded;83});84if (loaded !== lastProgress.loaded || total !== lastProgress.total) {85lastProgress.loaded = loaded;86lastProgress.total = total;87if (typeof progressFunc === 'function') {88progressFunc(loaded, total);89}90}91if (!progressIsFinal) {92requestAnimationFrame(animateProgress);93}94};9596this.animateProgress = animateProgress;9798this.setProgressFunc = function (callback) {99progressFunc = callback;100};101102this.loadPromise = function (file, fileSize, raw = false) {103return retry(loadFetch.bind(null, file, loadingFiles, fileSize, raw), DOWNLOAD_ATTEMPTS_MAX);104};105106this.preloadedFiles = [];107this.preload = function (pathOrBuffer, destPath, fileSize) {108let buffer = null;109if (typeof pathOrBuffer === 'string') {110const me = this;111return this.loadPromise(pathOrBuffer, fileSize).then(function (buf) {112me.preloadedFiles.push({113path: destPath || pathOrBuffer,114buffer: buf,115});116return Promise.resolve();117});118} else if (pathOrBuffer instanceof ArrayBuffer) {119buffer = new Uint8Array(pathOrBuffer);120} else if (ArrayBuffer.isView(pathOrBuffer)) {121buffer = new Uint8Array(pathOrBuffer.buffer);122}123if (buffer) {124this.preloadedFiles.push({125path: destPath,126buffer: pathOrBuffer,127});128return Promise.resolve();129}130return Promise.reject(new Error('Invalid object for preloading'));131};132};133134135