mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Multiple preload-adjustments
This commit is contained in:
parent
e870317a4f
commit
7c77944d43
@ -5,7 +5,32 @@
|
|||||||
// Catch load errors
|
// Catch load errors
|
||||||
|
|
||||||
function errorHandler(event, source, lineno, colno, error) {
|
function errorHandler(event, source, lineno, colno, error) {
|
||||||
console.error("👀 Init Error:", event, source, lineno, colno, error);
|
if (("" + event).indexOf("Script error.") >= 0) {
|
||||||
|
console.warn("Thirdparty script error:", event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (("" + event).indexOf("NS_ERROR_FAILURE") >= 0) {
|
||||||
|
console.warn("Firefox NS_ERROR_FAILURE error:", event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (("" + event).indexOf("Cannot read property 'postMessage' of null") >= 0) {
|
||||||
|
console.warn("Safari can not read post message error:", event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (("" + event).indexOf("Possible side-effect in debug-evaluate") >= 0) {
|
||||||
|
console.warn("Chrome debug-evaluate error:", event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (("" + source).indexOf("shapez.io") < 0) {
|
||||||
|
console.warn("Thirdparty error:", event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error("👀 App Error:", event, source, lineno, colno, error);
|
||||||
var element = document.createElement("div");
|
var element = document.createElement("div");
|
||||||
element.id = "ll_preload_error";
|
element.id = "ll_preload_error";
|
||||||
|
|
||||||
@ -38,9 +63,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.documentElement.appendChild(element);
|
document.documentElement.appendChild(element);
|
||||||
|
|
||||||
|
window.APP_ERROR_OCCURED = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("error", errorHandler);
|
window.onerror = errorHandler;
|
||||||
|
|
||||||
function expectJsParsed() {
|
function expectJsParsed() {
|
||||||
if (!callbackDone) {
|
if (!callbackDone) {
|
||||||
@ -81,10 +108,10 @@
|
|||||||
xhr.responseType = "arraybuffer";
|
xhr.responseType = "arraybuffer";
|
||||||
xhr.onprogress = function (ev) {
|
xhr.onprogress = function (ev) {
|
||||||
if (ev.lengthComputable) {
|
if (ev.lengthComputable) {
|
||||||
console.log(ev.total);
|
|
||||||
progressHandler(ev.loaded / ev.total);
|
progressHandler(ev.loaded / ev.total);
|
||||||
} else {
|
} else {
|
||||||
progressHandler(Math.min(1, ev.loaded / 1250000));
|
// Hardcoded length
|
||||||
|
progressHandler(Math.min(1, ev.loaded / 2349009));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,6 +33,12 @@ const INGAME_ASSETS = {
|
|||||||
|
|
||||||
const LOADER_TIMEOUT_PER_RESOURCE = 180000;
|
const LOADER_TIMEOUT_PER_RESOURCE = 180000;
|
||||||
|
|
||||||
|
// Cloudflare does not send content-length headers with brotli compression,
|
||||||
|
// so store the actual (compressed) file sizes so we can show a progress bar.
|
||||||
|
const HARDCODED_FILE_SIZES = {
|
||||||
|
"async-resources.css": 2216145,
|
||||||
|
};
|
||||||
|
|
||||||
export class BackgroundResourcesLoader {
|
export class BackgroundResourcesLoader {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -135,25 +141,24 @@ export class BackgroundResourcesLoader {
|
|||||||
let progress = 0;
|
let progress = 0;
|
||||||
this.resourceStateChangedSignal.dispatch({ progress });
|
this.resourceStateChangedSignal.dispatch({ progress });
|
||||||
let promises = [];
|
let promises = [];
|
||||||
|
|
||||||
for (let i = 0; i < promiseFunctions.length; i++) {
|
for (let i = 0; i < promiseFunctions.length; i++) {
|
||||||
let lastIndividualProgress = 0;
|
let lastIndividualProgress = 0;
|
||||||
const progressHandler = individualProgress => {
|
const progressHandler = individualProgress => {
|
||||||
const delta = clamp(individualProgress) - lastIndividualProgress;
|
const delta = clamp(individualProgress) - lastIndividualProgress;
|
||||||
lastIndividualProgress = individualProgress;
|
lastIndividualProgress = clamp(individualProgress);
|
||||||
progress += delta / originalAmount;
|
progress += delta / originalAmount;
|
||||||
this.resourceStateChangedSignal.dispatch({ progress });
|
this.resourceStateChangedSignal.dispatch({ progress });
|
||||||
};
|
};
|
||||||
promises.push(
|
promises.push(
|
||||||
promiseFunctions
|
promiseFunctions[i](progressHandler).then(() => {
|
||||||
.shift()(progressHandler)
|
progressHandler(1);
|
||||||
.then(() => {
|
})
|
||||||
progressHandler(1);
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
|
|
||||||
logger.log("⏰ Preloaded assets in", Math.round((performance.now() - start) / 1000.0), "ms");
|
logger.log("⏰ Preloaded assets in", Math.round(performance.now() - start), "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -189,23 +194,32 @@ export class BackgroundResourcesLoader {
|
|||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
let notifiedNotComputable = false;
|
let notifiedNotComputable = false;
|
||||||
|
|
||||||
xhr.open("GET", src, true);
|
const fullUrl = cachebust(src);
|
||||||
|
xhr.open("GET", fullUrl, true);
|
||||||
xhr.responseType = "arraybuffer";
|
xhr.responseType = "arraybuffer";
|
||||||
xhr.onprogress = function (ev) {
|
xhr.onprogress = function (ev) {
|
||||||
if (ev.lengthComputable) {
|
if (ev.lengthComputable) {
|
||||||
progressHandler(ev.loaded / ev.total);
|
progressHandler(ev.loaded / ev.total);
|
||||||
} else {
|
} else {
|
||||||
if (!notifiedNotComputable) {
|
if (window.location.search.includes("alwaysLogFileSize")) {
|
||||||
notifiedNotComputable = true;
|
console.warn("Progress:", src, ev.loaded);
|
||||||
console.warn("Progress not computable:", src, ev);
|
}
|
||||||
progressHandler(0);
|
|
||||||
|
if (HARDCODED_FILE_SIZES[src]) {
|
||||||
|
progressHandler(clamp(ev.loaded / HARDCODED_FILE_SIZES[src]));
|
||||||
|
} else {
|
||||||
|
if (!notifiedNotComputable) {
|
||||||
|
notifiedNotComputable = true;
|
||||||
|
console.warn("Progress not computable:", src, ev.loaded);
|
||||||
|
progressHandler(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.onloadend = function () {
|
xhr.onloadend = function () {
|
||||||
if (!xhr.status.toString().match(/^2/)) {
|
if (!xhr.status.toString().match(/^2/)) {
|
||||||
reject(src + ": " + xhr.status + " " + xhr.statusText);
|
reject(fullUrl + ": " + xhr.status + " " + xhr.statusText);
|
||||||
} else {
|
} else {
|
||||||
if (!notifiedNotComputable) {
|
if (!notifiedNotComputable) {
|
||||||
progressHandler(1);
|
progressHandler(1);
|
||||||
@ -226,7 +240,7 @@ export class BackgroundResourcesLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internalPreloadCss(src, progressHandler) {
|
internalPreloadCss(src, progressHandler) {
|
||||||
return this.preloadWithProgress(cachebust(src), progressHandler).then(blobSrc => {
|
return this.preloadWithProgress(src, progressHandler).then(blobSrc => {
|
||||||
var styleElement = document.createElement("link");
|
var styleElement = document.createElement("link");
|
||||||
styleElement.href = blobSrc;
|
styleElement.href = blobSrc;
|
||||||
styleElement.rel = "stylesheet";
|
styleElement.rel = "stylesheet";
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
export let APPLICATION_ERROR_OCCURED = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {Event|string} message
|
|
||||||
* @param {string} source
|
|
||||||
* @param {number} lineno
|
|
||||||
* @param {number} colno
|
|
||||||
* @param {Error} source
|
|
||||||
*/
|
|
||||||
function catchErrors(message, source, lineno, colno, error) {
|
|
||||||
APPLICATION_ERROR_OCCURED = true;
|
|
||||||
console.error(message, source, lineno, colno, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener("error", catchErrors);
|
|
@ -80,15 +80,13 @@ class LoaderImpl {
|
|||||||
* @returns {Promise<HTMLImageElement|null>}
|
* @returns {Promise<HTMLImageElement|null>}
|
||||||
*/
|
*/
|
||||||
internalPreloadImage(key, progressHandler) {
|
internalPreloadImage(key, progressHandler) {
|
||||||
const url = cachebust("res/" + key);
|
|
||||||
const image = new Image();
|
|
||||||
|
|
||||||
return this.app.backgroundResourceLoader
|
return this.app.backgroundResourceLoader
|
||||||
.preloadWithProgress(url, progress => {
|
.preloadWithProgress("res/" + key, progress => {
|
||||||
progressHandler(progress);
|
progressHandler(progress);
|
||||||
})
|
})
|
||||||
.then(url => {
|
.then(url => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
const image = new Image();
|
||||||
image.addEventListener("load", () => resolve(image));
|
image.addEventListener("load", () => resolve(image));
|
||||||
image.addEventListener("error", err =>
|
image.addEventListener("error", err =>
|
||||||
reject("Failed to load sprite " + key + ": " + err)
|
reject("Failed to load sprite " + key + ": " + err)
|
||||||
|
@ -4,7 +4,6 @@ import { Application } from "../application";
|
|||||||
|
|
||||||
import { GameState } from "./game_state";
|
import { GameState } from "./game_state";
|
||||||
import { createLogger } from "./logging";
|
import { createLogger } from "./logging";
|
||||||
import { APPLICATION_ERROR_OCCURED } from "./error_handler";
|
|
||||||
import { waitNextFrame, removeAllChildren } from "./utils";
|
import { waitNextFrame, removeAllChildren } from "./utils";
|
||||||
import { MOD_SIGNALS } from "../mods/mod_signals";
|
import { MOD_SIGNALS } from "../mods/mod_signals";
|
||||||
|
|
||||||
@ -56,7 +55,7 @@ export class StateManager {
|
|||||||
* @param {string} key State Key
|
* @param {string} key State Key
|
||||||
*/
|
*/
|
||||||
moveToState(key, payload = {}) {
|
moveToState(key, payload = {}) {
|
||||||
if (APPLICATION_ERROR_OCCURED) {
|
if (window.APP_ERROR_OCCURED) {
|
||||||
console.warn("Skipping state transition because of application crash");
|
console.warn("Skipping state transition because of application crash");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
2
src/js/globals.d.ts
vendored
2
src/js/globals.d.ts
vendored
@ -100,6 +100,8 @@ declare interface Window {
|
|||||||
|
|
||||||
shapez: any;
|
shapez: any;
|
||||||
|
|
||||||
|
APP_ERROR_OCCURED?: boolean;
|
||||||
|
|
||||||
webkitRequestAnimationFrame();
|
webkitRequestAnimationFrame();
|
||||||
|
|
||||||
assert(condition: boolean, failureMessage: string);
|
assert(condition: boolean, failureMessage: string);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import "./core/polyfills";
|
import "./core/polyfills";
|
||||||
import "./core/assert";
|
import "./core/assert";
|
||||||
import "./core/error_handler";
|
|
||||||
|
|
||||||
import "./mods/modloader";
|
import "./mods/modloader";
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { APPLICATION_ERROR_OCCURED } from "../core/error_handler";
|
|
||||||
import { GameState } from "../core/game_state";
|
import { GameState } from "../core/game_state";
|
||||||
import { logSection, createLogger } from "../core/logging";
|
import { logSection, createLogger } from "../core/logging";
|
||||||
import { waitNextFrame } from "../core/utils";
|
import { waitNextFrame } from "../core/utils";
|
||||||
@ -419,7 +418,7 @@ export class InGameState extends GameState {
|
|||||||
* @param {number} dt
|
* @param {number} dt
|
||||||
*/
|
*/
|
||||||
onRender(dt) {
|
onRender(dt) {
|
||||||
if (APPLICATION_ERROR_OCCURED) {
|
if (window.APP_ERROR_OCCURED) {
|
||||||
// Application somehow crashed, do not do anything
|
// Application somehow crashed, do not do anything
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -465,7 +464,7 @@ export class InGameState extends GameState {
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (APPLICATION_ERROR_OCCURED) {
|
if (window.APP_ERROR_OCCURED) {
|
||||||
logger.warn("skipping save because application crashed");
|
logger.warn("skipping save because application crashed");
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user