mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Optimize performance by using singletons for items
This commit is contained in:
parent
3c34227c24
commit
8c39d31c5b
@ -1,14 +1,14 @@
|
|||||||
import { globalConfig } from "../core/config";
|
import { globalConfig } from "../core/config";
|
||||||
import { DrawParameters } from "../core/draw_parameters";
|
import { DrawParameters } from "../core/draw_parameters";
|
||||||
import { gItemRegistry } from "../core/global_registries";
|
|
||||||
import { createLogger } from "../core/logging";
|
import { createLogger } from "../core/logging";
|
||||||
import { Rectangle } from "../core/rectangle";
|
import { Rectangle } from "../core/rectangle";
|
||||||
import { epsilonCompare, round4Digits } from "../core/utils";
|
import { epsilonCompare, round4Digits } from "../core/utils";
|
||||||
import { enumDirection, enumDirectionToVector, Vector, enumInvertedDirections } from "../core/vector";
|
import { enumDirection, enumDirectionToVector, enumInvertedDirections, Vector } from "../core/vector";
|
||||||
import { BasicSerializableObject, types } from "../savegame/serialization";
|
import { BasicSerializableObject, types } from "../savegame/serialization";
|
||||||
import { BaseItem } from "./base_item";
|
import { BaseItem } from "./base_item";
|
||||||
import { Entity } from "./entity";
|
import { Entity } from "./entity";
|
||||||
import { GameRoot, enumLayer } from "./root";
|
import { typeItemSingleton } from "./item_resolver";
|
||||||
|
import { enumLayer, GameRoot } from "./root";
|
||||||
|
|
||||||
const logger = createLogger("belt_path");
|
const logger = createLogger("belt_path");
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ export class BeltPath extends BasicSerializableObject {
|
|||||||
static getSchema() {
|
static getSchema() {
|
||||||
return {
|
return {
|
||||||
entityPath: types.array(types.entity),
|
entityPath: types.array(types.entity),
|
||||||
items: types.array(types.pair(types.ufloat, types.obj(gItemRegistry))),
|
items: types.array(types.pair(types.ufloat, typeItemSingleton)),
|
||||||
spacingToFirstItem: types.ufloat,
|
spacingToFirstItem: types.ufloat,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { gItemRegistry } from "../../core/global_registries";
|
|||||||
import { types } from "../../savegame/serialization";
|
import { types } from "../../savegame/serialization";
|
||||||
import { Component } from "../component";
|
import { Component } from "../component";
|
||||||
import { BaseItem } from "../base_item";
|
import { BaseItem } from "../base_item";
|
||||||
|
import { typeItemSingleton } from "../item_resolver";
|
||||||
|
|
||||||
export class ConstantSignalComponent extends Component {
|
export class ConstantSignalComponent extends Component {
|
||||||
static getId() {
|
static getId() {
|
||||||
@ -10,7 +11,7 @@ export class ConstantSignalComponent extends Component {
|
|||||||
|
|
||||||
static getSchema() {
|
static getSchema() {
|
||||||
return {
|
return {
|
||||||
signal: types.nullable(types.obj(gItemRegistry)),
|
signal: types.nullable(typeItemSingleton),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Vector, enumDirection, enumDirectionToVector } from "../../core/vector";
|
import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector";
|
||||||
import { BaseItem } from "../base_item";
|
|
||||||
import { Component } from "../component";
|
|
||||||
import { types } from "../../savegame/serialization";
|
import { types } from "../../savegame/serialization";
|
||||||
import { gItemRegistry } from "../../core/global_registries";
|
import { BaseItem } from "../base_item";
|
||||||
import { Entity } from "../entity";
|
|
||||||
import { enumLayer } from "../root";
|
|
||||||
import { BeltPath } from "../belt_path";
|
import { BeltPath } from "../belt_path";
|
||||||
|
import { Component } from "../component";
|
||||||
|
import { Entity } from "../entity";
|
||||||
|
import { typeItemSingleton } from "../item_resolver";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
@ -29,7 +28,7 @@ export class ItemEjectorComponent extends Component {
|
|||||||
return {
|
return {
|
||||||
slots: types.array(
|
slots: types.array(
|
||||||
types.structured({
|
types.structured({
|
||||||
item: types.nullable(types.obj(gItemRegistry)),
|
item: types.nullable(typeItemSingleton),
|
||||||
progress: types.float,
|
progress: types.float,
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { gItemRegistry } from "../../core/global_registries";
|
|
||||||
import { types } from "../../savegame/serialization";
|
import { types } from "../../savegame/serialization";
|
||||||
import { BaseItem } from "../base_item";
|
import { BaseItem } from "../base_item";
|
||||||
import { Component } from "../component";
|
import { Component } from "../component";
|
||||||
|
import { typeItemSingleton } from "../item_resolver";
|
||||||
|
|
||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
export const enumItemProcessorTypes = {
|
export const enumItemProcessorTypes = {
|
||||||
@ -32,13 +32,13 @@ export class ItemProcessorComponent extends Component {
|
|||||||
nextOutputSlot: types.uint,
|
nextOutputSlot: types.uint,
|
||||||
inputSlots: types.array(
|
inputSlots: types.array(
|
||||||
types.structured({
|
types.structured({
|
||||||
item: types.obj(gItemRegistry),
|
item: typeItemSingleton,
|
||||||
sourceSlot: types.uint,
|
sourceSlot: types.uint,
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
itemsToEject: types.array(
|
itemsToEject: types.array(
|
||||||
types.structured({
|
types.structured({
|
||||||
item: types.obj(gItemRegistry),
|
item: typeItemSingleton,
|
||||||
requiredSlot: types.nullable(types.uint),
|
requiredSlot: types.nullable(types.uint),
|
||||||
preferredSlot: types.nullable(types.uint),
|
preferredSlot: types.nullable(types.uint),
|
||||||
})
|
})
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { globalConfig } from "../../core/config";
|
|
||||||
import { types } from "../../savegame/serialization";
|
import { types } from "../../savegame/serialization";
|
||||||
import { Component } from "../component";
|
|
||||||
import { BaseItem } from "../base_item";
|
import { BaseItem } from "../base_item";
|
||||||
import { gItemRegistry } from "../../core/global_registries";
|
import { Component } from "../component";
|
||||||
|
import { typeItemSingleton } from "../item_resolver";
|
||||||
|
|
||||||
const chainBufferSize = 3;
|
const chainBufferSize = 3;
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ export class MinerComponent extends Component {
|
|||||||
// cachedMinedItem is not serialized.
|
// cachedMinedItem is not serialized.
|
||||||
return {
|
return {
|
||||||
lastMiningTime: types.ufloat,
|
lastMiningTime: types.ufloat,
|
||||||
itemChainBuffer: types.array(types.obj(gItemRegistry)),
|
itemChainBuffer: types.array(typeItemSingleton),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { Component } from "../component";
|
|
||||||
import { types } from "../../savegame/serialization";
|
import { types } from "../../savegame/serialization";
|
||||||
import { gItemRegistry } from "../../core/global_registries";
|
|
||||||
import { BaseItem, enumItemType } from "../base_item";
|
import { BaseItem, enumItemType } from "../base_item";
|
||||||
import { ColorItem } from "../items/color_item";
|
import { Component } from "../component";
|
||||||
import { ShapeItem } from "../items/shape_item";
|
import { typeItemSingleton } from "../item_resolver";
|
||||||
|
|
||||||
export class StorageComponent extends Component {
|
export class StorageComponent extends Component {
|
||||||
static getId() {
|
static getId() {
|
||||||
@ -13,7 +11,7 @@ export class StorageComponent extends Component {
|
|||||||
static getSchema() {
|
static getSchema() {
|
||||||
return {
|
return {
|
||||||
storedCount: types.uint,
|
storedCount: types.uint,
|
||||||
storedItem: types.nullable(types.obj(gItemRegistry)),
|
storedItem: types.nullable(typeItemSingleton),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { BaseItem } from "../base_item";
|
|
||||||
import { Component } from "../component";
|
|
||||||
import { globalConfig } from "../../core/config";
|
import { globalConfig } from "../../core/config";
|
||||||
import { types } from "../../savegame/serialization";
|
import { types } from "../../savegame/serialization";
|
||||||
import { gItemRegistry } from "../../core/global_registries";
|
import { BaseItem } from "../base_item";
|
||||||
|
import { Component } from "../component";
|
||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { enumLayer } from "../root";
|
import { typeItemSingleton } from "../item_resolver";
|
||||||
|
|
||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
export const enumUndergroundBeltMode = {
|
export const enumUndergroundBeltMode = {
|
||||||
@ -26,7 +25,7 @@ export class UndergroundBeltComponent extends Component {
|
|||||||
|
|
||||||
static getSchema() {
|
static getSchema() {
|
||||||
return {
|
return {
|
||||||
pendingItems: types.array(types.pair(types.obj(gItemRegistry), types.float)),
|
pendingItems: types.array(types.pair(typeItemSingleton, types.float)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ import { randomInt, round2Digits } from "../core/utils";
|
|||||||
import { Vector } from "../core/vector";
|
import { Vector } from "../core/vector";
|
||||||
import { Savegame } from "../savegame/savegame";
|
import { Savegame } from "../savegame/savegame";
|
||||||
import { SavegameSerializer } from "../savegame/savegame_serializer";
|
import { SavegameSerializer } from "../savegame/savegame_serializer";
|
||||||
import { InGameState } from "../states/ingame";
|
|
||||||
import { AutomaticSave } from "./automatic_save";
|
import { AutomaticSave } from "./automatic_save";
|
||||||
import { MetaHubBuilding } from "./buildings/hub";
|
import { MetaHubBuilding } from "./buildings/hub";
|
||||||
import { Camera } from "./camera";
|
import { Camera } from "./camera";
|
||||||
@ -67,7 +66,7 @@ export class GameCore {
|
|||||||
/**
|
/**
|
||||||
* Initializes the root object which stores all game related data. The state
|
* Initializes the root object which stores all game related data. The state
|
||||||
* is required as a back reference (used sometimes)
|
* is required as a back reference (used sometimes)
|
||||||
* @param {InGameState} parentState
|
* @param {import("../states/ingame").InGameState} parentState
|
||||||
* @param {Savegame} savegame
|
* @param {Savegame} savegame
|
||||||
*/
|
*/
|
||||||
initializeRoot(parentState, savegame) {
|
initializeRoot(parentState, savegame) {
|
||||||
|
33
src/js/game/item_resolver.js
Normal file
33
src/js/game/item_resolver.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { types } from "../savegame/serialization";
|
||||||
|
import { gItemRegistry } from "../core/global_registries";
|
||||||
|
import { BooleanItem, BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON } from "./items/boolean_item";
|
||||||
|
import { ShapeItem } from "./items/shape_item";
|
||||||
|
import { ColorItem, COLOR_ITEM_SINGLETONS } from "./items/color_item";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves items so we share instances
|
||||||
|
* @param {import("../savegame/savegame_serializer").GameRoot} root
|
||||||
|
* @param {{$: string, data: any }} data
|
||||||
|
*/
|
||||||
|
export function itemResolverSingleton(root, data) {
|
||||||
|
const itemType = data.$;
|
||||||
|
const itemData = data.data;
|
||||||
|
|
||||||
|
switch (itemType) {
|
||||||
|
case BooleanItem.getId(): {
|
||||||
|
return itemData ? BOOL_TRUE_SINGLETON : BOOL_FALSE_SINGLETON;
|
||||||
|
}
|
||||||
|
case ShapeItem.getId(): {
|
||||||
|
return root.shapeDefinitionMgr.getShapeItemFromShortKey(itemData);
|
||||||
|
}
|
||||||
|
case ColorItem.getId(): {
|
||||||
|
return COLOR_ITEM_SINGLETONS[itemData];
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
assertAlways(false, "Unknown item type: " + itemType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const typeItemSingleton = types.obj(gItemRegistry, itemResolverSingleton);
|
@ -98,3 +98,13 @@ export class ColorItem extends BaseItem {
|
|||||||
context.fill();
|
context.fill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton instances
|
||||||
|
* @type {Object<enumColors, ColorItem>}
|
||||||
|
*/
|
||||||
|
export const COLOR_ITEM_SINGLETONS = {};
|
||||||
|
|
||||||
|
for (const color in enumColors) {
|
||||||
|
COLOR_ITEM_SINGLETONS[color] = new ColorItem(color);
|
||||||
|
}
|
||||||
|
@ -37,7 +37,6 @@ export class ShapeItem extends BaseItem {
|
|||||||
*/
|
*/
|
||||||
constructor(definition) {
|
constructor(definition) {
|
||||||
super();
|
super();
|
||||||
// logger.log("New shape item for shape definition", definition.generateId(), "created");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This property must not be modified on runtime, you have to clone the class in order to change the definition
|
* This property must not be modified on runtime, you have to clone the class in order to change the definition
|
||||||
|
@ -6,7 +6,7 @@ import { Vector } from "../core/vector";
|
|||||||
import { BaseItem } from "./base_item";
|
import { BaseItem } from "./base_item";
|
||||||
import { enumColors } from "./colors";
|
import { enumColors } from "./colors";
|
||||||
import { Entity } from "./entity";
|
import { Entity } from "./entity";
|
||||||
import { ColorItem } from "./items/color_item";
|
import { COLOR_ITEM_SINGLETONS } from "./items/color_item";
|
||||||
import { enumLayer, GameRoot } from "./root";
|
import { enumLayer, GameRoot } from "./root";
|
||||||
import { enumSubShape } from "./shape_definition";
|
import { enumSubShape } from "./shape_definition";
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ export class MapChunk {
|
|||||||
if (distanceToOriginInChunks > 2) {
|
if (distanceToOriginInChunks > 2) {
|
||||||
availableColors.push(enumColors.blue);
|
availableColors.push(enumColors.blue);
|
||||||
}
|
}
|
||||||
this.internalGeneratePatch(rng, colorPatchSize, new ColorItem(rng.choice(availableColors)));
|
this.internalGeneratePatch(rng, colorPatchSize, COLOR_ITEM_SINGLETONS[rng.choice(availableColors)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -268,7 +268,7 @@ export class MapChunk {
|
|||||||
*/
|
*/
|
||||||
generatePredefined(rng) {
|
generatePredefined(rng) {
|
||||||
if (this.x === 0 && this.y === 0) {
|
if (this.x === 0 && this.y === 0) {
|
||||||
this.internalGeneratePatch(rng, 2, new ColorItem(enumColors.red), 7, 7);
|
this.internalGeneratePatch(rng, 2, COLOR_ITEM_SINGLETONS[enumColors.red], 7, 7);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (this.x === -1 && this.y === 0) {
|
if (this.x === -1 && this.y === 0) {
|
||||||
@ -283,7 +283,7 @@ export class MapChunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.x === -1 && this.y === -1) {
|
if (this.x === -1 && this.y === -1) {
|
||||||
this.internalGeneratePatch(rng, 2, new ColorItem(enumColors.green));
|
this.internalGeneratePatch(rng, 2, COLOR_ITEM_SINGLETONS[enumColors.green]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import { ConstantSignalComponent } from "../components/constant_signal";
|
import trim from "trim";
|
||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
|
||||||
import { Entity } from "../entity";
|
|
||||||
import { DialogWithForm } from "../../core/modal_dialog_elements";
|
import { DialogWithForm } from "../../core/modal_dialog_elements";
|
||||||
import { FormElementInput } from "../../core/modal_dialog_forms";
|
import { FormElementInput } from "../../core/modal_dialog_forms";
|
||||||
import { enumColors } from "../colors";
|
|
||||||
import { ColorItem } from "../items/color_item";
|
|
||||||
import trim from "trim";
|
|
||||||
import { BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON } from "../items/boolean_item";
|
|
||||||
import { ShapeDefinition } from "../shape_definition";
|
|
||||||
import { ShapeItem } from "../items/shape_item";
|
|
||||||
import { BaseItem } from "../base_item";
|
import { BaseItem } from "../base_item";
|
||||||
|
import { enumColors } from "../colors";
|
||||||
|
import { ConstantSignalComponent } from "../components/constant_signal";
|
||||||
|
import { Entity } from "../entity";
|
||||||
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
|
import { BOOL_FALSE_SINGLETON, BOOL_TRUE_SINGLETON } from "../items/boolean_item";
|
||||||
|
import { COLOR_ITEM_SINGLETONS } from "../items/color_item";
|
||||||
|
import { ShapeDefinition } from "../shape_definition";
|
||||||
|
|
||||||
export class ConstantSignalSystem extends GameSystemWithFilter {
|
export class ConstantSignalSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -111,7 +110,7 @@ export class ConstantSignalSystem extends GameSystemWithFilter {
|
|||||||
const codeLower = code.toLowerCase();
|
const codeLower = code.toLowerCase();
|
||||||
|
|
||||||
if (enumColors[codeLower]) {
|
if (enumColors[codeLower]) {
|
||||||
return new ColorItem(codeLower);
|
return COLOR_ITEM_SINGLETONS[codeLower];
|
||||||
}
|
}
|
||||||
if (code === "1" || codeLower === "true") {
|
if (code === "1" || codeLower === "true") {
|
||||||
return BOOL_TRUE_SINGLETON;
|
return BOOL_TRUE_SINGLETON;
|
||||||
@ -122,7 +121,7 @@ export class ConstantSignalSystem extends GameSystemWithFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ShapeDefinition.isValidShortKey(code)) {
|
if (ShapeDefinition.isValidShortKey(code)) {
|
||||||
return new ShapeItem(this.root.shapeDefinitionMgr.getShapeFromShortKey(code));
|
return this.root.shapeDefinitionMgr.getShapeItemFromShortKey(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
|
||||||
import { HubComponent } from "../components/hub";
|
|
||||||
import { DrawParameters } from "../../core/draw_parameters";
|
import { DrawParameters } from "../../core/draw_parameters";
|
||||||
import { Entity } from "../entity";
|
|
||||||
import { formatBigNumber } from "../../core/utils";
|
|
||||||
import { Loader } from "../../core/loader";
|
import { Loader } from "../../core/loader";
|
||||||
|
import { formatBigNumber } from "../../core/utils";
|
||||||
import { T } from "../../translations";
|
import { T } from "../../translations";
|
||||||
import { ShapeItem } from "../items/shape_item";
|
import { HubComponent } from "../components/hub";
|
||||||
|
import { Entity } from "../entity";
|
||||||
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
|
|
||||||
export class HubSystem extends GameSystemWithFilter {
|
export class HubSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -23,7 +22,9 @@ export class HubSystem extends GameSystemWithFilter {
|
|||||||
// Set hub goal
|
// Set hub goal
|
||||||
const entity = this.allEntities[i];
|
const entity = this.allEntities[i];
|
||||||
const pinsComp = entity.components.WiredPins;
|
const pinsComp = entity.components.WiredPins;
|
||||||
pinsComp.slots[0].value = new ShapeItem(this.root.hubGoals.currentGoal.definition);
|
pinsComp.slots[0].value = this.root.shapeDefinitionMgr.getShapeItemFromDefinition(
|
||||||
|
this.root.hubGoals.currentGoal.definition
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/it
|
|||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
import { BOOL_TRUE_SINGLETON } from "../items/boolean_item";
|
import { BOOL_TRUE_SINGLETON } from "../items/boolean_item";
|
||||||
import { ColorItem } from "../items/color_item";
|
import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item";
|
||||||
import { ShapeItem } from "../items/shape_item";
|
import { ShapeItem } from "../items/shape_item";
|
||||||
|
|
||||||
export class ItemProcessorSystem extends GameSystemWithFilter {
|
export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||||
@ -134,7 +134,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
const definition = cutDefinitions[i];
|
const definition = cutDefinitions[i];
|
||||||
if (!definition.isEntirelyEmpty()) {
|
if (!definition.isEntirelyEmpty()) {
|
||||||
outItems.push({
|
outItems.push({
|
||||||
item: new ShapeItem(definition),
|
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
|
||||||
requiredSlot: i,
|
requiredSlot: i,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
const definition = cutDefinitions[i];
|
const definition = cutDefinitions[i];
|
||||||
if (!definition.isEntirelyEmpty()) {
|
if (!definition.isEntirelyEmpty()) {
|
||||||
outItems.push({
|
outItems.push({
|
||||||
item: new ShapeItem(definition),
|
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
|
||||||
requiredSlot: i,
|
requiredSlot: i,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -172,7 +172,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW(inputDefinition);
|
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW(inputDefinition);
|
||||||
outItems.push({
|
outItems.push({
|
||||||
item: new ShapeItem(rotatedDefinition),
|
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCCW(inputDefinition);
|
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCCW(inputDefinition);
|
||||||
outItems.push({
|
outItems.push({
|
||||||
item: new ShapeItem(rotatedDefinition),
|
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -198,7 +198,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateFL(inputDefinition);
|
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateFL(inputDefinition);
|
||||||
outItems.push({
|
outItems.push({
|
||||||
item: new ShapeItem(rotatedDefinition),
|
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -217,7 +217,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
upperItem.definition
|
upperItem.definition
|
||||||
);
|
);
|
||||||
outItems.push({
|
outItems.push({
|
||||||
item: new ShapeItem(stackedDefinition),
|
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(stackedDefinition),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -248,7 +248,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
resultColor = mixedColor;
|
resultColor = mixedColor;
|
||||||
}
|
}
|
||||||
outItems.push({
|
outItems.push({
|
||||||
item: new ColorItem(resultColor),
|
item: COLOR_ITEM_SINGLETONS[resultColor],
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -266,7 +266,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
);
|
);
|
||||||
|
|
||||||
outItems.push({
|
outItems.push({
|
||||||
item: new ShapeItem(colorizedDefinition),
|
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition),
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -293,11 +293,11 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
colorItem.color
|
colorItem.color
|
||||||
);
|
);
|
||||||
outItems.push({
|
outItems.push({
|
||||||
item: new ShapeItem(colorizedDefinition1),
|
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition1),
|
||||||
});
|
});
|
||||||
|
|
||||||
outItems.push({
|
outItems.push({
|
||||||
item: new ShapeItem(colorizedDefinition2),
|
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition2),
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -324,7 +324,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
);
|
);
|
||||||
|
|
||||||
outItems.push({
|
outItems.push({
|
||||||
item: new ShapeItem(colorizedDefinition),
|
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition),
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
|
import { createLogger } from "../core/logging";
|
||||||
import {
|
import {
|
||||||
BaseDataType,
|
BaseDataType,
|
||||||
TypeArray,
|
TypeArray,
|
||||||
TypeBoolean,
|
TypeBoolean,
|
||||||
TypeClass,
|
TypeClass,
|
||||||
|
TypeClassData,
|
||||||
|
TypeClassFromMetaclass,
|
||||||
TypeClassId,
|
TypeClassId,
|
||||||
TypeEntity,
|
TypeEntity,
|
||||||
TypeEntityWeakref,
|
TypeEntityWeakref,
|
||||||
@ -17,12 +20,9 @@ import {
|
|||||||
TypePositiveInteger,
|
TypePositiveInteger,
|
||||||
TypePositiveNumber,
|
TypePositiveNumber,
|
||||||
TypeString,
|
TypeString,
|
||||||
TypeVector,
|
|
||||||
TypeClassFromMetaclass,
|
|
||||||
TypeClassData,
|
|
||||||
TypeStructuredObject,
|
TypeStructuredObject,
|
||||||
|
TypeVector,
|
||||||
} from "./serialization_data_types";
|
} from "./serialization_data_types";
|
||||||
import { createLogger } from "../core/logging";
|
|
||||||
|
|
||||||
const logger = createLogger("serialization");
|
const logger = createLogger("serialization");
|
||||||
|
|
||||||
@ -69,9 +69,10 @@ export const types = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {FactoryTemplate<*>} registry
|
* @param {FactoryTemplate<*>} registry
|
||||||
|
* @param {(GameRoot, any) => object=} resolver
|
||||||
*/
|
*/
|
||||||
obj(registry) {
|
obj(registry, resolver = null) {
|
||||||
return new TypeClass(registry);
|
return new TypeClass(registry, resolver);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,12 +191,18 @@ export class BasicSerializableObject {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {string|void} */
|
/**
|
||||||
deserialize(data) {
|
* @param {any} data
|
||||||
|
* @param {import("./savegame_serializer").GameRoot} root
|
||||||
|
* @returns {string|void}
|
||||||
|
*/
|
||||||
|
deserialize(data, root = null) {
|
||||||
return deserializeSchema(
|
return deserializeSchema(
|
||||||
this,
|
this,
|
||||||
/** @type {typeof BasicSerializableObject} */ (this.constructor).getCachedSchema(),
|
/** @type {typeof BasicSerializableObject} */ (this.constructor).getCachedSchema(),
|
||||||
data
|
data,
|
||||||
|
null,
|
||||||
|
root
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,9 +260,10 @@ export function serializeSchema(obj, schema, mergeWith = {}) {
|
|||||||
* @param {Schema} schema The schema to use
|
* @param {Schema} schema The schema to use
|
||||||
* @param {object} data The serialized data
|
* @param {object} data The serialized data
|
||||||
* @param {string|void|null=} baseclassErrorResult Convenience, if this is a string error code, do nothing and return it
|
* @param {string|void|null=} baseclassErrorResult Convenience, if this is a string error code, do nothing and return it
|
||||||
|
* @param {import("../game/root").GameRoot=} root Optional game root reference
|
||||||
* @returns {string|void} String error code or nothing on success
|
* @returns {string|void} String error code or nothing on success
|
||||||
*/
|
*/
|
||||||
export function deserializeSchema(obj, schema, data, baseclassErrorResult = null) {
|
export function deserializeSchema(obj, schema, data, baseclassErrorResult = null, root) {
|
||||||
if (baseclassErrorResult) {
|
if (baseclassErrorResult) {
|
||||||
return baseclassErrorResult;
|
return baseclassErrorResult;
|
||||||
}
|
}
|
||||||
@ -275,7 +283,7 @@ export function deserializeSchema(obj, schema, data, baseclassErrorResult = null
|
|||||||
return "Non-nullable entry is null: " + key + " of class " + obj.constructor.name;
|
return "Non-nullable entry is null: " + key + " of class " + obj.constructor.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const errorStatus = schema[key].deserializeWithVerify(data[key], obj, key, obj.root);
|
const errorStatus = schema[key].deserializeWithVerify(data[key], obj, key, obj.root || root);
|
||||||
if (errorStatus) {
|
if (errorStatus) {
|
||||||
logger.error(
|
logger.error(
|
||||||
"Deserialization failed with error '" + errorStatus + "' on object",
|
"Deserialization failed with error '" + errorStatus + "' on object",
|
||||||
|
@ -595,10 +595,12 @@ export class TypeClass extends BaseDataType {
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {FactoryTemplate<*>} registry
|
* @param {FactoryTemplate<*>} registry
|
||||||
|
* @param {(GameRoot, object) => object} customResolver
|
||||||
*/
|
*/
|
||||||
constructor(registry) {
|
constructor(registry, customResolver = null) {
|
||||||
super();
|
super();
|
||||||
this.registry = registry;
|
this.registry = registry;
|
||||||
|
this.customResolver = customResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
serialize(value) {
|
serialize(value) {
|
||||||
@ -640,15 +642,24 @@ export class TypeClass extends BaseDataType {
|
|||||||
* @returns {string|void} String error code or null on success
|
* @returns {string|void} String error code or null on success
|
||||||
*/
|
*/
|
||||||
deserialize(value, targetObject, targetKey, root) {
|
deserialize(value, targetObject, targetKey, root) {
|
||||||
|
let instance;
|
||||||
|
|
||||||
|
if (this.customResolver) {
|
||||||
|
instance = this.customResolver(root, value);
|
||||||
|
if (!instance) {
|
||||||
|
return "Failed to call custom resolver";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
const instanceClass = this.registry.findById(value.$);
|
const instanceClass = this.registry.findById(value.$);
|
||||||
if (!instanceClass || !instanceClass.prototype) {
|
if (!instanceClass || !instanceClass.prototype) {
|
||||||
return "Invalid class id (runtime-err): " + value.$ + "->" + instanceClass;
|
return "Invalid class id (runtime-err): " + value.$ + "->" + instanceClass;
|
||||||
}
|
}
|
||||||
const instance = Object.create(instanceClass.prototype);
|
instance = Object.create(instanceClass.prototype);
|
||||||
const errorState = instance.deserialize(value.data);
|
const errorState = instance.deserialize(value.data);
|
||||||
if (errorState) {
|
if (errorState) {
|
||||||
return errorState;
|
return errorState;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
targetObject[targetKey] = instance;
|
targetObject[targetKey] = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ export class SerializerInternal {
|
|||||||
|
|
||||||
entity.uid = payload.uid;
|
entity.uid = payload.uid;
|
||||||
|
|
||||||
this.deserializeComponents(entity, payload.components);
|
this.deserializeComponents(root, entity, payload.components);
|
||||||
|
|
||||||
root.entityMgr.registerEntity(entity, payload.uid);
|
root.entityMgr.registerEntity(entity, payload.uid);
|
||||||
root.map.placeStaticEntity(entity);
|
root.map.placeStaticEntity(entity);
|
||||||
@ -70,18 +70,19 @@ export class SerializerInternal {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Deserializes components of an entity
|
* Deserializes components of an entity
|
||||||
|
* @param {GameRoot} root
|
||||||
* @param {Entity} entity
|
* @param {Entity} entity
|
||||||
* @param {Object.<string, any>} data
|
* @param {Object.<string, any>} data
|
||||||
* @returns {string|void}
|
* @returns {string|void}
|
||||||
*/
|
*/
|
||||||
deserializeComponents(entity, data) {
|
deserializeComponents(root, entity, data) {
|
||||||
for (const componentId in data) {
|
for (const componentId in data) {
|
||||||
if (!entity.components[componentId]) {
|
if (!entity.components[componentId]) {
|
||||||
logger.warn("Entity no longer has component:", componentId);
|
logger.warn("Entity no longer has component:", componentId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const errorStatus = entity.components[componentId].deserialize(data[componentId]);
|
const errorStatus = entity.components[componentId].deserialize(data[componentId], root);
|
||||||
if (errorStatus) {
|
if (errorStatus) {
|
||||||
return errorStatus;
|
return errorStatus;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user