UNPKG

@tamgl/colyseus-schema

Version:

Binary state serializer with delta encoding for games

102 lines 4.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Root = void 0; const spec_1 = require("../encoding/spec"); const ChangeTree_1 = require("./ChangeTree"); class Root { constructor(types) { this.types = types; this.nextUniqueId = 0; this.refCount = {}; this.changeTrees = {}; // all changes this.allChanges = []; this.allFilteredChanges = []; // TODO: do not initialize it if filters are not used // pending changes to be encoded this.changes = []; this.filteredChanges = []; // TODO: do not initialize it if filters are not used } getNextUniqueId() { return this.nextUniqueId++; } add(changeTree) { // FIXME: move implementation of `ensureRefId` to `Root` class changeTree.ensureRefId(); const isNewChangeTree = (this.changeTrees[changeTree.refId] === undefined); if (isNewChangeTree) { this.changeTrees[changeTree.refId] = changeTree; } const previousRefCount = this.refCount[changeTree.refId]; if (previousRefCount === 0) { // // When a ChangeTree is re-added, it means that it was previously removed. // We need to re-add all changes to the `changes` map. // const ops = changeTree.allChanges.operations; let len = ops.length; while (len--) { changeTree.indexedOperations[ops[len]] = spec_1.OPERATION.ADD; (0, ChangeTree_1.setOperationAtIndex)(changeTree.changes, len); } } this.refCount[changeTree.refId] = (previousRefCount || 0) + 1; return isNewChangeTree; } remove(changeTree) { const refCount = (this.refCount[changeTree.refId]) - 1; if (refCount <= 0) { // // Only remove "root" reference if it's the last reference // changeTree.root = undefined; delete this.changeTrees[changeTree.refId]; this.removeChangeFromChangeSet("allChanges", changeTree); this.removeChangeFromChangeSet("changes", changeTree); if (changeTree.filteredChanges) { this.removeChangeFromChangeSet("allFilteredChanges", changeTree); this.removeChangeFromChangeSet("filteredChanges", changeTree); } this.refCount[changeTree.refId] = 0; changeTree.forEachChild((child, _) => this.remove(child)); } else { this.refCount[changeTree.refId] = refCount; // // When losing a reference to an instance, it is best to move the // ChangeTree to the end of the encoding queue. // // This way, at decoding time, the instance that contains the // ChangeTree will be available before the ChangeTree itself. If the // containing instance is not available, the Decoder will throw // "refId not found" error. // if (changeTree.filteredChanges !== undefined) { this.removeChangeFromChangeSet("filteredChanges", changeTree); (0, ChangeTree_1.enqueueChangeTree)(this, changeTree, "filteredChanges"); } else { this.removeChangeFromChangeSet("changes", changeTree); (0, ChangeTree_1.enqueueChangeTree)(this, changeTree, "changes"); } } return refCount; } removeChangeFromChangeSet(changeSetName, changeTree) { const changeSet = this[changeSetName]; const changeSetIndex = changeSet.indexOf(changeTree); if (changeSetIndex !== -1) { changeTree[changeSetName].queueRootIndex = -1; changeSet[changeSetIndex] = undefined; return true; } // if (spliceOne(changeSet, changeSet.indexOf(changeTree))) { // changeTree[changeSetName].queueRootIndex = -1; // return true; // } } clear() { this.changes.length = 0; } } exports.Root = Root; //# sourceMappingURL=Root.js.map