1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-03-02 03:39:21 +00:00

Optimize performance by using singletons for items

This commit is contained in:
tobspr
2020-08-14 13:09:10 +02:00
parent 3c34227c24
commit 8c39d31c5b
18 changed files with 145 additions and 88 deletions

View File

@@ -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",

View File

@@ -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;
}

View File

@@ -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;
}