mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-06-07 10:03:59 +00:00
Further performance improvements, show indicator while game is saving
This commit is contained in:
parent
bba29b8a8b
commit
1ebfafd8de
@ -56,6 +56,17 @@
|
|||||||
transform: scale(1.1, 1.1);
|
transform: scale(1.1, 1.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.saving {
|
||||||
|
@include InlineAnimation(0.4s ease-in-out infinite) {
|
||||||
|
50% {
|
||||||
|
opacity: 0.5;
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pointer-events: none;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.settings {
|
&.settings {
|
||||||
|
@ -25,21 +25,27 @@ export const gBuildingVariants = {
|
|||||||
// Set later
|
// Set later
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping from 'metaBuildingId/variant/rotationVariant' to building code
|
||||||
|
* @type {Map<string, number>}
|
||||||
|
*/
|
||||||
|
const variantsCache = new Map();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a new variant
|
* Registers a new variant
|
||||||
* @param {number} id
|
* @param {number} code
|
||||||
* @param {typeof MetaBuilding} meta
|
* @param {typeof MetaBuilding} meta
|
||||||
* @param {string} variant
|
* @param {string} variant
|
||||||
* @param {number} rotationVariant
|
* @param {number} rotationVariant
|
||||||
*/
|
*/
|
||||||
export function registerBuildingVariant(
|
export function registerBuildingVariant(
|
||||||
id,
|
code,
|
||||||
meta,
|
meta,
|
||||||
variant = "default" /* FIXME: Circular dependency, actually its defaultBuildingVariant */,
|
variant = "default" /* FIXME: Circular dependency, actually its defaultBuildingVariant */,
|
||||||
rotationVariant = 0
|
rotationVariant = 0
|
||||||
) {
|
) {
|
||||||
assert(!gBuildingVariants[id], "Duplicate id: " + id);
|
assert(!gBuildingVariants[code], "Duplicate id: " + code);
|
||||||
gBuildingVariants[id] = {
|
gBuildingVariants[code] = {
|
||||||
metaClass: meta,
|
metaClass: meta,
|
||||||
variant,
|
variant,
|
||||||
rotationVariant,
|
rotationVariant,
|
||||||
@ -58,26 +64,29 @@ export function getBuildingDataFromCode(code) {
|
|||||||
return gBuildingVariants[code];
|
return gBuildingVariants[code];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the cache for the codes
|
||||||
|
*/
|
||||||
|
export function buildBuildingCodeCache() {
|
||||||
|
for (const code in gBuildingVariants) {
|
||||||
|
const data = gBuildingVariants[code];
|
||||||
|
const hash = data.metaInstance.getId() + "/" + data.variant + "/" + data.rotationVariant;
|
||||||
|
variantsCache.set(hash, +code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the code for a given variant
|
* Finds the code for a given variant
|
||||||
* @param {MetaBuilding} metaBuilding
|
* @param {MetaBuilding} metaBuilding
|
||||||
* @param {string} variant
|
* @param {string} variant
|
||||||
* @param {number} rotationVariant
|
* @param {number} rotationVariant
|
||||||
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
export function getCodeFromBuildingData(metaBuilding, variant, rotationVariant) {
|
export function getCodeFromBuildingData(metaBuilding, variant, rotationVariant) {
|
||||||
for (const key in gBuildingVariants) {
|
const hash = metaBuilding.getId() + "/" + variant + "/" + rotationVariant;
|
||||||
const data = gBuildingVariants[key];
|
const result = variantsCache.get(hash);
|
||||||
if (
|
if (G_IS_DEV) {
|
||||||
data.metaInstance.getId() === metaBuilding.getId() &&
|
assertAlways(!!result, "Building not found by data: " + hash);
|
||||||
data.variant === variant &&
|
|
||||||
data.rotationVariant === rotationVariant
|
|
||||||
) {
|
|
||||||
return +key;
|
|
||||||
}
|
}
|
||||||
}
|
return result;
|
||||||
assertAlways(
|
|
||||||
false,
|
|
||||||
"Building not found by data: " + metaBuilding.getId() + " / " + variant + " / " + rotationVariant
|
|
||||||
);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@ -67,11 +67,8 @@ export class EntityManager extends BasicSerializableObject {
|
|||||||
}
|
}
|
||||||
assert(!entity.destroyed, `Attempting to register destroyed entity ${entity}`);
|
assert(!entity.destroyed, `Attempting to register destroyed entity ${entity}`);
|
||||||
|
|
||||||
if (G_IS_DEV && uid !== null) {
|
if (G_IS_DEV && !globalConfig.debug.disableSlowAsserts && uid !== null) {
|
||||||
assert(!this.findByUid(uid, false), "Entity uid already taken: " + uid);
|
assert(!this.findByUid(uid, false), "Entity uid already taken: " + uid);
|
||||||
}
|
|
||||||
|
|
||||||
if (uid !== null) {
|
|
||||||
assert(uid >= 0 && uid < Number.MAX_SAFE_INTEGER, "Invalid uid passed: " + uid);
|
assert(uid >= 0 && uid < Number.MAX_SAFE_INTEGER, "Invalid uid passed: " + uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import { enumNotificationType } from "./notifications";
|
|||||||
import { T } from "../../../translations";
|
import { T } from "../../../translations";
|
||||||
import { KEYMAPPINGS } from "../../key_action_mapper";
|
import { KEYMAPPINGS } from "../../key_action_mapper";
|
||||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||||
|
import { TrackedState } from "../../../core/tracked_state";
|
||||||
|
|
||||||
export class HUDGameMenu extends BaseHUDPart {
|
export class HUDGameMenu extends BaseHUDPart {
|
||||||
createElements(parent) {
|
createElements(parent) {
|
||||||
@ -97,12 +98,17 @@ export class HUDGameMenu extends BaseHUDPart {
|
|||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
this.root.signals.gameSaved.add(this.onGameSaved, this);
|
this.root.signals.gameSaved.add(this.onGameSaved, this);
|
||||||
|
|
||||||
|
this.trackedIsSaving = new TrackedState(this.onIsSavingChanged, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
let playSound = false;
|
let playSound = false;
|
||||||
let notifications = new Set();
|
let notifications = new Set();
|
||||||
|
|
||||||
|
// Check whether we are saving
|
||||||
|
this.trackedIsSaving.set(!!this.root.gameState.currentSavePromise);
|
||||||
|
|
||||||
// Update visibility of buttons
|
// Update visibility of buttons
|
||||||
for (let i = 0; i < this.visibilityToUpdate.length; ++i) {
|
for (let i = 0; i < this.visibilityToUpdate.length; ++i) {
|
||||||
const { condition, domAttach } = this.visibilityToUpdate[i];
|
const { condition, domAttach } = this.visibilityToUpdate[i];
|
||||||
@ -154,6 +160,10 @@ export class HUDGameMenu extends BaseHUDPart {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onIsSavingChanged(isSaving) {
|
||||||
|
this.saveButton.classList.toggle("saving", isSaving);
|
||||||
|
}
|
||||||
|
|
||||||
onGameSaved() {
|
onGameSaved() {
|
||||||
this.saveButton.classList.toggle("animEven");
|
this.saveButton.classList.toggle("animEven");
|
||||||
this.saveButton.classList.toggle("animOdd");
|
this.saveButton.classList.toggle("animOdd");
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { BaseHUDPart } from "../base_hud_part";
|
|
||||||
import { makeDiv } from "../../../core/utils";
|
import { makeDiv } from "../../../core/utils";
|
||||||
import { T } from "../../../translations";
|
import { T } from "../../../translations";
|
||||||
import { IS_DEMO } from "../../../core/config";
|
import { BaseHUDPart } from "../base_hud_part";
|
||||||
|
|
||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
export const enumNotificationType = {
|
export const enumNotificationType = {
|
||||||
|
@ -66,6 +66,7 @@ export class MapView extends BaseMap {
|
|||||||
* @param {DrawParameters} drawParameters
|
* @param {DrawParameters} drawParameters
|
||||||
*/
|
*/
|
||||||
drawStaticEntityDebugOverlays(drawParameters) {
|
drawStaticEntityDebugOverlays(drawParameters) {
|
||||||
|
if (G_IS_DEV && (globalConfig.debug.showAcceptorEjectors || globalConfig.debug.showEntityBounds)) {
|
||||||
const cullRange = drawParameters.visibleRect.toTileCullRectangle();
|
const cullRange = drawParameters.visibleRect.toTileCullRectangle();
|
||||||
const top = cullRange.top();
|
const top = cullRange.top();
|
||||||
const right = cullRange.right();
|
const right = cullRange.right();
|
||||||
@ -97,6 +98,7 @@ export class MapView extends BaseMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes all canvases used for background rendering
|
* Initializes all canvases used for background rendering
|
||||||
|
@ -12,7 +12,7 @@ import { MetaStackerBuilding } from "./buildings/stacker";
|
|||||||
import { enumTrashVariants, MetaTrashBuilding } from "./buildings/trash";
|
import { enumTrashVariants, MetaTrashBuilding } from "./buildings/trash";
|
||||||
import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
|
import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
|
||||||
import { MetaWireBuilding } from "./buildings/wire";
|
import { MetaWireBuilding } from "./buildings/wire";
|
||||||
import { gBuildingVariants, registerBuildingVariant } from "./building_codes";
|
import { buildBuildingCodeCache, gBuildingVariants, registerBuildingVariant } from "./building_codes";
|
||||||
import { defaultBuildingVariant } from "./meta_building";
|
import { defaultBuildingVariant } from "./meta_building";
|
||||||
import { MetaConstantSignalBuilding } from "./buildings/constant_signal";
|
import { MetaConstantSignalBuilding } from "./buildings/constant_signal";
|
||||||
import { MetaLogicGateBuilding, enumLogicGateVariants } from "./buildings/logic_gate";
|
import { MetaLogicGateBuilding, enumLogicGateVariants } from "./buildings/logic_gate";
|
||||||
@ -174,4 +174,7 @@ export function initBuildingCodesAfterResourcesLoaded() {
|
|||||||
);
|
);
|
||||||
variant.silhouetteColor = variant.metaInstance.getSilhouetteColor();
|
variant.silhouetteColor = variant.metaInstance.getSilhouetteColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update caches
|
||||||
|
buildBuildingCodeCache();
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,15 @@ export class InGameState extends GameState {
|
|||||||
this.loadingOverlay = null;
|
this.loadingOverlay = null;
|
||||||
|
|
||||||
/** @type {Savegame} */
|
/** @type {Savegame} */
|
||||||
this.savegame;
|
this.savegame = null;
|
||||||
|
|
||||||
this.boundInputFilter = this.filterInput.bind(this);
|
this.boundInputFilter = this.filterInput.bind(this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether we are currently saving the game
|
||||||
|
* @TODO: This doesn't realy fit here
|
||||||
|
*/
|
||||||
|
this.currentSavePromise = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -427,12 +433,26 @@ export class InGameState extends GameState {
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
// First update the game data
|
if (this.currentSavePromise) {
|
||||||
|
logger.warn("Skipping double save and returning same promise");
|
||||||
|
return this.currentSavePromise;
|
||||||
|
}
|
||||||
logger.log("Starting to save game ...");
|
logger.log("Starting to save game ...");
|
||||||
this.core.root.signals.gameSaved.dispatch();
|
|
||||||
this.savegame.updateData(this.core.root);
|
this.savegame.updateData(this.core.root);
|
||||||
return this.savegame.writeSavegameAndMetadata().catch(err => {
|
|
||||||
|
this.currentSavePromise = this.savegame
|
||||||
|
.writeSavegameAndMetadata()
|
||||||
|
.catch(err => {
|
||||||
|
// Catch errors
|
||||||
logger.warn("Failed to save:", err);
|
logger.warn("Failed to save:", err);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
// Clear promise
|
||||||
|
logger.log("Saved!");
|
||||||
|
this.core.root.signals.gameSaved.dispatch();
|
||||||
|
this.currentSavePromise = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return this.currentSavePromise;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user