diff --git a/src/js/game/belt_path.js b/src/js/game/belt_path.js index 896b4ecd..99511d5a 100644 --- a/src/js/game/belt_path.js +++ b/src/js/game/belt_path.js @@ -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, }; } diff --git a/src/js/game/components/constant_signal.js b/src/js/game/components/constant_signal.js index b2b37e44..b51277a1 100644 --- a/src/js/game/components/constant_signal.js +++ b/src/js/game/components/constant_signal.js @@ -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), }; } diff --git a/src/js/game/components/item_ejector.js b/src/js/game/components/item_ejector.js index 281cf91e..b9a23c38 100644 --- a/src/js/game/components/item_ejector.js +++ b/src/js/game/components/item_ejector.js @@ -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, }) ), diff --git a/src/js/game/components/item_processor.js b/src/js/game/components/item_processor.js index 80617136..02b742d4 100644 --- a/src/js/game/components/item_processor.js +++ b/src/js/game/components/item_processor.js @@ -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), }) diff --git a/src/js/game/components/miner.js b/src/js/game/components/miner.js index 411e49b9..a7515678 100644 --- a/src/js/game/components/miner.js +++ b/src/js/game/components/miner.js @@ -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), }; } diff --git a/src/js/game/components/storage.js b/src/js/game/components/storage.js index acc68a51..a7fd365a 100644 --- a/src/js/game/components/storage.js +++ b/src/js/game/components/storage.js @@ -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), }; } diff --git a/src/js/game/components/underground_belt.js b/src/js/game/components/underground_belt.js index b09927ce..74351aac 100644 --- a/src/js/game/components/underground_belt.js +++ b/src/js/game/components/underground_belt.js @@ -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)), }; } diff --git a/src/js/game/core.js b/src/js/game/core.js index 12b97c71..7f28e638 100644 --- a/src/js/game/core.js +++ b/src/js/game/core.js @@ -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) { diff --git a/src/js/game/item_resolver.js b/src/js/game/item_resolver.js new file mode 100644 index 00000000..da15fa0c --- /dev/null +++ b/src/js/game/item_resolver.js @@ -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); diff --git a/src/js/game/items/color_item.js b/src/js/game/items/color_item.js index 5cdcecaf..009b310b 100644 --- a/src/js/game/items/color_item.js +++ b/src/js/game/items/color_item.js @@ -98,3 +98,13 @@ export class ColorItem extends BaseItem { context.fill(); } } + +/** + * Singleton instances + * @type {Object} + */ +export const COLOR_ITEM_SINGLETONS = {}; + +for (const color in enumColors) { + COLOR_ITEM_SINGLETONS[color] = new ColorItem(color); +} diff --git a/src/js/game/items/shape_item.js b/src/js/game/items/shape_item.js index 8ebf1d34..44a0a3ad 100644 --- a/src/js/game/items/shape_item.js +++ b/src/js/game/items/shape_item.js @@ -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 diff --git a/src/js/game/map_chunk.js b/src/js/game/map_chunk.js index 138f423f..189a62cd 100644 --- a/src/js/game/map_chunk.js +++ b/src/js/game/map_chunk.js @@ -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; } diff --git a/src/js/game/systems/constant_signal.js b/src/js/game/systems/constant_signal.js index e0c67e9e..f1ea9f48 100644 --- a/src/js/game/systems/constant_signal.js +++ b/src/js/game/systems/constant_signal.js @@ -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; diff --git a/src/js/game/systems/hub.js b/src/js/game/systems/hub.js index dafdb498..b8968655 100644 --- a/src/js/game/systems/hub.js +++ b/src/js/game/systems/hub.js @@ -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 + ); } } diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js index ad4a7ae8..9943594c 100644 --- a/src/js/game/systems/item_processor.js +++ b/src/js/game/systems/item_processor.js @@ -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; diff --git a/src/js/savegame/serialization.js b/src/js/savegame/serialization.js index aea2f944..9f998a0f 100644 --- a/src/js/savegame/serialization.js +++ b/src/js/savegame/serialization.js @@ -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", diff --git a/src/js/savegame/serialization_data_types.js b/src/js/savegame/serialization_data_types.js index c9ab570d..033acda1 100644 --- a/src/js/savegame/serialization_data_types.js +++ b/src/js/savegame/serialization_data_types.js @@ -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; } diff --git a/src/js/savegame/serializer_internal.js b/src/js/savegame/serializer_internal.js index 5d0c3bfc..ee32dff6 100644 --- a/src/js/savegame/serializer_internal.js +++ b/src/js/savegame/serializer_internal.js @@ -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.} 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; }