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 { DrawParameters } from "../core/draw_parameters";
|
||||
import { gItemRegistry } from "../core/global_registries";
|
||||
import { createLogger } from "../core/logging";
|
||||
import { Rectangle } from "../core/rectangle";
|
||||
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 { BaseItem } from "./base_item";
|
||||
import { Entity } from "./entity";
|
||||
import { GameRoot, enumLayer } from "./root";
|
||||
import { typeItemSingleton } from "./item_resolver";
|
||||
import { enumLayer, GameRoot } from "./root";
|
||||
|
||||
const logger = createLogger("belt_path");
|
||||
|
||||
@ -29,7 +29,7 @@ export class BeltPath extends BasicSerializableObject {
|
||||
static getSchema() {
|
||||
return {
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import { gItemRegistry } from "../../core/global_registries";
|
||||
import { types } from "../../savegame/serialization";
|
||||
import { Component } from "../component";
|
||||
import { BaseItem } from "../base_item";
|
||||
import { typeItemSingleton } from "../item_resolver";
|
||||
|
||||
export class ConstantSignalComponent extends Component {
|
||||
static getId() {
|
||||
@ -10,7 +11,7 @@ export class ConstantSignalComponent extends Component {
|
||||
|
||||
static getSchema() {
|
||||
return {
|
||||
signal: types.nullable(types.obj(gItemRegistry)),
|
||||
signal: types.nullable(typeItemSingleton),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { Vector, enumDirection, enumDirectionToVector } from "../../core/vector";
|
||||
import { BaseItem } from "../base_item";
|
||||
import { Component } from "../component";
|
||||
import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector";
|
||||
import { types } from "../../savegame/serialization";
|
||||
import { gItemRegistry } from "../../core/global_registries";
|
||||
import { Entity } from "../entity";
|
||||
import { enumLayer } from "../root";
|
||||
import { BaseItem } from "../base_item";
|
||||
import { BeltPath } from "../belt_path";
|
||||
import { Component } from "../component";
|
||||
import { Entity } from "../entity";
|
||||
import { typeItemSingleton } from "../item_resolver";
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
@ -29,7 +28,7 @@ export class ItemEjectorComponent extends Component {
|
||||
return {
|
||||
slots: types.array(
|
||||
types.structured({
|
||||
item: types.nullable(types.obj(gItemRegistry)),
|
||||
item: types.nullable(typeItemSingleton),
|
||||
progress: types.float,
|
||||
})
|
||||
),
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { gItemRegistry } from "../../core/global_registries";
|
||||
import { types } from "../../savegame/serialization";
|
||||
import { BaseItem } from "../base_item";
|
||||
import { Component } from "../component";
|
||||
import { typeItemSingleton } from "../item_resolver";
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumItemProcessorTypes = {
|
||||
@ -32,13 +32,13 @@ export class ItemProcessorComponent extends Component {
|
||||
nextOutputSlot: types.uint,
|
||||
inputSlots: types.array(
|
||||
types.structured({
|
||||
item: types.obj(gItemRegistry),
|
||||
item: typeItemSingleton,
|
||||
sourceSlot: types.uint,
|
||||
})
|
||||
),
|
||||
itemsToEject: types.array(
|
||||
types.structured({
|
||||
item: types.obj(gItemRegistry),
|
||||
item: typeItemSingleton,
|
||||
requiredSlot: types.nullable(types.uint),
|
||||
preferredSlot: types.nullable(types.uint),
|
||||
})
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { globalConfig } from "../../core/config";
|
||||
import { types } from "../../savegame/serialization";
|
||||
import { Component } from "../component";
|
||||
import { BaseItem } from "../base_item";
|
||||
import { gItemRegistry } from "../../core/global_registries";
|
||||
import { Component } from "../component";
|
||||
import { typeItemSingleton } from "../item_resolver";
|
||||
|
||||
const chainBufferSize = 3;
|
||||
|
||||
@ -15,7 +14,7 @@ export class MinerComponent extends Component {
|
||||
// cachedMinedItem is not serialized.
|
||||
return {
|
||||
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 { gItemRegistry } from "../../core/global_registries";
|
||||
import { BaseItem, enumItemType } from "../base_item";
|
||||
import { ColorItem } from "../items/color_item";
|
||||
import { ShapeItem } from "../items/shape_item";
|
||||
import { Component } from "../component";
|
||||
import { typeItemSingleton } from "../item_resolver";
|
||||
|
||||
export class StorageComponent extends Component {
|
||||
static getId() {
|
||||
@ -13,7 +11,7 @@ export class StorageComponent extends Component {
|
||||
static getSchema() {
|
||||
return {
|
||||
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 { types } from "../../savegame/serialization";
|
||||
import { gItemRegistry } from "../../core/global_registries";
|
||||
import { BaseItem } from "../base_item";
|
||||
import { Component } from "../component";
|
||||
import { Entity } from "../entity";
|
||||
import { enumLayer } from "../root";
|
||||
import { typeItemSingleton } from "../item_resolver";
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumUndergroundBeltMode = {
|
||||
@ -26,7 +25,7 @@ export class UndergroundBeltComponent extends Component {
|
||||
|
||||
static getSchema() {
|
||||
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 { Savegame } from "../savegame/savegame";
|
||||
import { SavegameSerializer } from "../savegame/savegame_serializer";
|
||||
import { InGameState } from "../states/ingame";
|
||||
import { AutomaticSave } from "./automatic_save";
|
||||
import { MetaHubBuilding } from "./buildings/hub";
|
||||
import { Camera } from "./camera";
|
||||
@ -67,7 +66,7 @@ export class GameCore {
|
||||
/**
|
||||
* Initializes the root object which stores all game related data. The state
|
||||
* is required as a back reference (used sometimes)
|
||||
* @param {InGameState} parentState
|
||||
* @param {import("../states/ingame").InGameState} parentState
|
||||
* @param {Savegame} 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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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
|
||||
|
@ -6,7 +6,7 @@ import { Vector } from "../core/vector";
|
||||
import { BaseItem } from "./base_item";
|
||||
import { enumColors } from "./colors";
|
||||
import { Entity } from "./entity";
|
||||
import { ColorItem } from "./items/color_item";
|
||||
import { COLOR_ITEM_SINGLETONS } from "./items/color_item";
|
||||
import { enumLayer, GameRoot } from "./root";
|
||||
import { enumSubShape } from "./shape_definition";
|
||||
|
||||
@ -139,7 +139,7 @@ export class MapChunk {
|
||||
if (distanceToOriginInChunks > 2) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
if (this.x === -1 && this.y === 0) {
|
||||
@ -283,7 +283,7 @@ export class MapChunk {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,14 @@
|
||||
import { ConstantSignalComponent } from "../components/constant_signal";
|
||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
import { Entity } from "../entity";
|
||||
import trim from "trim";
|
||||
import { DialogWithForm } from "../../core/modal_dialog_elements";
|
||||
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 { 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 {
|
||||
constructor(root) {
|
||||
@ -111,7 +110,7 @@ export class ConstantSignalSystem extends GameSystemWithFilter {
|
||||
const codeLower = code.toLowerCase();
|
||||
|
||||
if (enumColors[codeLower]) {
|
||||
return new ColorItem(codeLower);
|
||||
return COLOR_ITEM_SINGLETONS[codeLower];
|
||||
}
|
||||
if (code === "1" || codeLower === "true") {
|
||||
return BOOL_TRUE_SINGLETON;
|
||||
@ -122,7 +121,7 @@ export class ConstantSignalSystem extends GameSystemWithFilter {
|
||||
}
|
||||
|
||||
if (ShapeDefinition.isValidShortKey(code)) {
|
||||
return new ShapeItem(this.root.shapeDefinitionMgr.getShapeFromShortKey(code));
|
||||
return this.root.shapeDefinitionMgr.getShapeItemFromShortKey(code);
|
||||
}
|
||||
|
||||
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 { Entity } from "../entity";
|
||||
import { formatBigNumber } from "../../core/utils";
|
||||
import { Loader } from "../../core/loader";
|
||||
import { formatBigNumber } from "../../core/utils";
|
||||
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 {
|
||||
constructor(root) {
|
||||
@ -23,7 +22,9 @@ export class HubSystem extends GameSystemWithFilter {
|
||||
// Set hub goal
|
||||
const entity = this.allEntities[i];
|
||||
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 { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
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";
|
||||
|
||||
export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
@ -134,7 +134,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
const definition = cutDefinitions[i];
|
||||
if (!definition.isEntirelyEmpty()) {
|
||||
outItems.push({
|
||||
item: new ShapeItem(definition),
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
|
||||
requiredSlot: i,
|
||||
});
|
||||
}
|
||||
@ -155,7 +155,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
const definition = cutDefinitions[i];
|
||||
if (!definition.isEntirelyEmpty()) {
|
||||
outItems.push({
|
||||
item: new ShapeItem(definition),
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
|
||||
requiredSlot: i,
|
||||
});
|
||||
}
|
||||
@ -172,7 +172,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
|
||||
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW(inputDefinition);
|
||||
outItems.push({
|
||||
item: new ShapeItem(rotatedDefinition),
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -185,7 +185,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
|
||||
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCCW(inputDefinition);
|
||||
outItems.push({
|
||||
item: new ShapeItem(rotatedDefinition),
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -198,7 +198,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
|
||||
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateFL(inputDefinition);
|
||||
outItems.push({
|
||||
item: new ShapeItem(rotatedDefinition),
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -217,7 +217,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
upperItem.definition
|
||||
);
|
||||
outItems.push({
|
||||
item: new ShapeItem(stackedDefinition),
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(stackedDefinition),
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -248,7 +248,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
resultColor = mixedColor;
|
||||
}
|
||||
outItems.push({
|
||||
item: new ColorItem(resultColor),
|
||||
item: COLOR_ITEM_SINGLETONS[resultColor],
|
||||
});
|
||||
|
||||
break;
|
||||
@ -266,7 +266,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
);
|
||||
|
||||
outItems.push({
|
||||
item: new ShapeItem(colorizedDefinition),
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition),
|
||||
});
|
||||
|
||||
break;
|
||||
@ -293,11 +293,11 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
colorItem.color
|
||||
);
|
||||
outItems.push({
|
||||
item: new ShapeItem(colorizedDefinition1),
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition1),
|
||||
});
|
||||
|
||||
outItems.push({
|
||||
item: new ShapeItem(colorizedDefinition2),
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition2),
|
||||
});
|
||||
|
||||
break;
|
||||
@ -324,7 +324,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
);
|
||||
|
||||
outItems.push({
|
||||
item: new ShapeItem(colorizedDefinition),
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition),
|
||||
});
|
||||
|
||||
break;
|
||||
|
@ -1,8 +1,11 @@
|
||||
import { createLogger } from "../core/logging";
|
||||
import {
|
||||
BaseDataType,
|
||||
TypeArray,
|
||||
TypeBoolean,
|
||||
TypeClass,
|
||||
TypeClassData,
|
||||
TypeClassFromMetaclass,
|
||||
TypeClassId,
|
||||
TypeEntity,
|
||||
TypeEntityWeakref,
|
||||
@ -17,12 +20,9 @@ import {
|
||||
TypePositiveInteger,
|
||||
TypePositiveNumber,
|
||||
TypeString,
|
||||
TypeVector,
|
||||
TypeClassFromMetaclass,
|
||||
TypeClassData,
|
||||
TypeStructuredObject,
|
||||
TypeVector,
|
||||
} from "./serialization_data_types";
|
||||
import { createLogger } from "../core/logging";
|
||||
|
||||
const logger = createLogger("serialization");
|
||||
|
||||
@ -69,9 +69,10 @@ export const types = {
|
||||
|
||||
/**
|
||||
* @param {FactoryTemplate<*>} registry
|
||||
* @param {(GameRoot, any) => object=} resolver
|
||||
*/
|
||||
obj(registry) {
|
||||
return new TypeClass(registry);
|
||||
obj(registry, resolver = null) {
|
||||
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(
|
||||
this,
|
||||
/** @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 {object} data The serialized data
|
||||
* @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
|
||||
*/
|
||||
export function deserializeSchema(obj, schema, data, baseclassErrorResult = null) {
|
||||
export function deserializeSchema(obj, schema, data, baseclassErrorResult = null, root) {
|
||||
if (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;
|
||||
}
|
||||
|
||||
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) {
|
||||
logger.error(
|
||||
"Deserialization failed with error '" + errorStatus + "' on object",
|
||||
|
@ -595,10 +595,12 @@ export class TypeClass extends BaseDataType {
|
||||
/**
|
||||
*
|
||||
* @param {FactoryTemplate<*>} registry
|
||||
* @param {(GameRoot, object) => object} customResolver
|
||||
*/
|
||||
constructor(registry) {
|
||||
constructor(registry, customResolver = null) {
|
||||
super();
|
||||
this.registry = registry;
|
||||
this.customResolver = customResolver;
|
||||
}
|
||||
|
||||
serialize(value) {
|
||||
@ -640,14 +642,23 @@ export class TypeClass extends BaseDataType {
|
||||
* @returns {string|void} String error code or null on success
|
||||
*/
|
||||
deserialize(value, targetObject, targetKey, root) {
|
||||
const instanceClass = this.registry.findById(value.$);
|
||||
if (!instanceClass || !instanceClass.prototype) {
|
||||
return "Invalid class id (runtime-err): " + value.$ + "->" + instanceClass;
|
||||
}
|
||||
const instance = Object.create(instanceClass.prototype);
|
||||
const errorState = instance.deserialize(value.data);
|
||||
if (errorState) {
|
||||
return errorState;
|
||||
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.$);
|
||||
if (!instanceClass || !instanceClass.prototype) {
|
||||
return "Invalid class id (runtime-err): " + value.$ + "->" + instanceClass;
|
||||
}
|
||||
instance = Object.create(instanceClass.prototype);
|
||||
const errorState = instance.deserialize(value.data);
|
||||
if (errorState) {
|
||||
return errorState;
|
||||
}
|
||||
}
|
||||
targetObject[targetKey] = instance;
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ export class SerializerInternal {
|
||||
|
||||
entity.uid = payload.uid;
|
||||
|
||||
this.deserializeComponents(entity, payload.components);
|
||||
this.deserializeComponents(root, entity, payload.components);
|
||||
|
||||
root.entityMgr.registerEntity(entity, payload.uid);
|
||||
root.map.placeStaticEntity(entity);
|
||||
@ -70,18 +70,19 @@ export class SerializerInternal {
|
||||
|
||||
/**
|
||||
* Deserializes components of an entity
|
||||
* @param {GameRoot} root
|
||||
* @param {Entity} entity
|
||||
* @param {Object.<string, any>} data
|
||||
* @returns {string|void}
|
||||
*/
|
||||
deserializeComponents(entity, data) {
|
||||
deserializeComponents(root, entity, data) {
|
||||
for (const componentId in data) {
|
||||
if (!entity.components[componentId]) {
|
||||
logger.warn("Entity no longer has component:", componentId);
|
||||
continue;
|
||||
}
|
||||
|
||||
const errorStatus = entity.components[componentId].deserialize(data[componentId]);
|
||||
const errorStatus = entity.components[componentId].deserialize(data[componentId], root);
|
||||
if (errorStatus) {
|
||||
return errorStatus;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user