UNPKG

@colyseus/schema

Version:

Binary state serializer with delta encoding for games

130 lines 4.78 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.encodeKeyValueOperation = exports.encodeSchemaOperation = exports.encodeValue = exports.encodePrimitiveType = void 0; const spec_1 = require("../spec"); const consts_1 = require("./consts"); const typeRegistry_1 = require("../types/typeRegistry"); const encode = require("../encoding/encode"); const assert_1 = require("../encoding/assert"); const MapSchema_1 = require("../types/MapSchema"); function encodePrimitiveType(type, bytes, value, klass, field) { (0, assert_1.assertType)(value, type, klass, field); const encodeFunc = encode[type]; if (encodeFunc) { encodeFunc(bytes, value); } else { throw new assert_1.EncodeSchemaError(`a '${type}' was expected, but ${value} was provided in ${klass.constructor.name}#${field}`); } } exports.encodePrimitiveType = encodePrimitiveType; function encodeValue(encoder, bytes, ref, type, value, field, operation) { if (type[Symbol.metadata] !== undefined) { (0, assert_1.assertInstanceType)(value, type, ref, field); // // Encode refId for this instance. // The actual instance is going to be encoded on next `changeTree` iteration. // encode.number(bytes, value[consts_1.$changes].refId); // Try to encode inherited TYPE_ID if it's an ADD operation. if ((operation & spec_1.OPERATION.ADD) === spec_1.OPERATION.ADD) { encoder.tryEncodeTypeId(bytes, type, value.constructor); } } else if (typeof (type) === "string") { // // Primitive values // encodePrimitiveType(type, bytes, value, ref, field); } else { // // Custom type (MapSchema, ArraySchema, etc) // const definition = (0, typeRegistry_1.getType)(Object.keys(type)[0]); // // ensure a ArraySchema has been provided // (0, assert_1.assertInstanceType)(ref[field], definition.constructor, ref, field); // // Encode refId for this instance. // The actual instance is going to be encoded on next `changeTree` iteration. // encode.number(bytes, value[consts_1.$changes].refId); } } exports.encodeValue = encodeValue; /** * Used for Schema instances. * @private */ const encodeSchemaOperation = function (encoder, bytes, changeTree, index, operation) { const ref = changeTree.ref; const metadata = ref['constructor'][Symbol.metadata]; const field = metadata[index]; const type = metadata[field].type; const value = ref[field]; // "compress" field index + operation encode.uint8(bytes, (index | operation)); // ensure refId for the value if (value && value[consts_1.$changes]) { value[consts_1.$changes].ensureRefId(); } if (operation === spec_1.OPERATION.TOUCH) { return; } // TODO: inline this function call small performance gain encodeValue(encoder, bytes, ref, type, value, field, operation); }; exports.encodeSchemaOperation = encodeSchemaOperation; /** * Used for collections (MapSchema, ArraySchema, etc.) * @private */ const encodeKeyValueOperation = function (encoder, bytes, changeTree, field, operation) { const ref = changeTree.ref; // encode field index + operation if (operation !== spec_1.OPERATION.TOUCH) { encode.uint8(bytes, operation); // custom operations if (operation === spec_1.OPERATION.CLEAR) { return; } // indexed operations encode.number(bytes, field); } // // encode "alias" for dynamic fields (maps) // if ((operation & spec_1.OPERATION.ADD) == spec_1.OPERATION.ADD) { // ADD or DELETE_AND_ADD if (ref instanceof MapSchema_1.MapSchema) { // // MapSchema dynamic key // const dynamicIndex = changeTree.ref['$indexes'].get(field); encode.string(bytes, dynamicIndex); } } if (operation === spec_1.OPERATION.DELETE) { // // TODO: delete from filter cache data. // // if (useFilters) { // delete changeTree.caches[fieldIndex]; // } return; } const type = changeTree.getType(field); const value = changeTree.getValue(field); // ensure refId for the value if (value && value[consts_1.$changes]) { value[consts_1.$changes].ensureRefId(); } if (operation === spec_1.OPERATION.TOUCH) { return; } // TODO: inline this function call small performance gain encodeValue(encoder, bytes, ref, type, value, field, operation); }; exports.encodeKeyValueOperation = encodeKeyValueOperation; //# sourceMappingURL=EncodeOperation.js.map