@colyseus/schema 3.0.24 → 3.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/index.js +48 -55
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +48 -55
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +48 -55
- package/lib/encoder/ChangeTree.d.ts +1 -1
- package/lib/encoder/ChangeTree.js +23 -20
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/Encoder.js +5 -20
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/Root.js +7 -3
- package/lib/encoder/Root.js.map +1 -1
- package/package.json +1 -1
- package/src/encoder/ChangeTree.ts +28 -21
- package/src/encoder/Encoder.ts +3 -22
- package/src/encoder/Root.ts +9 -2
package/lib/encoder/Root.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Root = void 0;
|
|
4
4
|
const spec_1 = require("../encoding/spec");
|
|
5
|
-
const utils_1 = require("../types/utils");
|
|
6
5
|
const ChangeTree_1 = require("./ChangeTree");
|
|
7
6
|
class Root {
|
|
8
7
|
constructor(types) {
|
|
@@ -84,11 +83,16 @@ class Root {
|
|
|
84
83
|
}
|
|
85
84
|
removeChangeFromChangeSet(changeSetName, changeTree) {
|
|
86
85
|
const changeSet = this[changeSetName];
|
|
87
|
-
|
|
86
|
+
const changeSetIndex = changeSet.indexOf(changeTree);
|
|
87
|
+
if (changeSetIndex !== -1) {
|
|
88
88
|
changeTree[changeSetName].queueRootIndex = -1;
|
|
89
|
-
|
|
89
|
+
changeSet[changeSetIndex] = undefined;
|
|
90
90
|
return true;
|
|
91
91
|
}
|
|
92
|
+
// if (spliceOne(changeSet, changeSet.indexOf(changeTree))) {
|
|
93
|
+
// changeTree[changeSetName].queueRootIndex = -1;
|
|
94
|
+
// return true;
|
|
95
|
+
// }
|
|
92
96
|
}
|
|
93
97
|
clear() {
|
|
94
98
|
this.changes.length = 0;
|
package/lib/encoder/Root.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Root.js","sourceRoot":"","sources":["../../src/encoder/Root.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;
|
|
1
|
+
{"version":3,"file":"Root.js","sourceRoot":"","sources":["../../src/encoder/Root.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { TypeContext } from \"../types/TypeContext\";\nimport { spliceOne } from \"../types/utils\";\nimport { ChangeTree, enqueueChangeTree, setOperationAtIndex } from \"./ChangeTree\";\n\nexport class Root {\n protected nextUniqueId: number = 0;\n\n refCount: {[id: number]: number} = {};\n changeTrees: {[refId: number]: ChangeTree} = {};\n\n // all changes\n allChanges: ChangeTree[] = [];\n allFilteredChanges: ChangeTree[] = [];// TODO: do not initialize it if filters are not used\n\n // pending changes to be encoded\n changes: ChangeTree[] = [];\n filteredChanges: ChangeTree[] = [];// TODO: do not initialize it if filters are not used\n\n constructor(public types: TypeContext) { }\n\n getNextUniqueId() {\n return this.nextUniqueId++;\n }\n\n add(changeTree: ChangeTree) {\n // FIXME: move implementation of `ensureRefId` to `Root` class\n changeTree.ensureRefId();\n\n const isNewChangeTree = (this.changeTrees[changeTree.refId] === undefined);\n if (isNewChangeTree) { this.changeTrees[changeTree.refId] = changeTree; }\n\n const previousRefCount = this.refCount[changeTree.refId];\n if (previousRefCount === 0) {\n //\n // When a ChangeTree is re-added, it means that it was previously removed.\n // We need to re-add all changes to the `changes` map.\n //\n const ops = changeTree.allChanges.operations;\n let len = ops.length;\n while (len--) {\n changeTree.indexedOperations[ops[len]] = OPERATION.ADD;\n setOperationAtIndex(changeTree.changes, len);\n }\n }\n\n this.refCount[changeTree.refId] = (previousRefCount || 0) + 1;\n\n return isNewChangeTree;\n }\n\n remove(changeTree: ChangeTree) {\n const refCount = (this.refCount[changeTree.refId]) - 1;\n\n if (refCount <= 0) {\n //\n // Only remove \"root\" reference if it's the last reference\n //\n changeTree.root = undefined;\n delete this.changeTrees[changeTree.refId];\n\n this.removeChangeFromChangeSet(\"allChanges\", changeTree);\n this.removeChangeFromChangeSet(\"changes\", changeTree);\n\n if (changeTree.filteredChanges) {\n this.removeChangeFromChangeSet(\"allFilteredChanges\", changeTree);\n this.removeChangeFromChangeSet(\"filteredChanges\", changeTree);\n }\n\n this.refCount[changeTree.refId] = 0;\n\n } else {\n this.refCount[changeTree.refId] = refCount;\n\n //\n // When losing a reference to an instance, it is best to move the\n // ChangeTree to the end of the encoding queue.\n //\n // This way, at decoding time, the instance that contains the\n // ChangeTree will be available before the ChangeTree itself. If the\n // containing instance is not available, the Decoder will throw\n // \"refId not found\" error.\n //\n if (changeTree.filteredChanges !== undefined) {\n this.removeChangeFromChangeSet(\"filteredChanges\", changeTree);\n enqueueChangeTree(this, changeTree, \"filteredChanges\");\n } else {\n this.removeChangeFromChangeSet(\"changes\", changeTree);\n enqueueChangeTree(this, changeTree, \"changes\");\n }\n }\n\n changeTree.forEachChild((child, _) => this.remove(child));\n\n return refCount;\n }\n\n removeChangeFromChangeSet(changeSetName: \"allChanges\" | \"changes\" | \"filteredChanges\" | \"allFilteredChanges\", changeTree: ChangeTree) {\n const changeSet = this[changeSetName];\n const changeSetIndex = changeSet.indexOf(changeTree);\n\n if (changeSetIndex !== -1) {\n changeTree[changeSetName].queueRootIndex = -1;\n changeSet[changeSetIndex] = undefined;\n return true;\n }\n\n // if (spliceOne(changeSet, changeSet.indexOf(changeTree))) {\n // changeTree[changeSetName].queueRootIndex = -1;\n // return true;\n // }\n }\n\n clear() {\n this.changes.length = 0;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -43,6 +43,10 @@ export interface ChangeSet {
|
|
|
43
43
|
queueRootIndex?: number; // index of ChangeTree structure in `root.changes` or `root.filteredChanges`
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
function createChangeSet(): ChangeSet {
|
|
47
|
+
return { indexes: {}, operations: [] };
|
|
48
|
+
}
|
|
49
|
+
|
|
46
50
|
export function setOperationAtIndex(changeSet: ChangeSet, index: number) {
|
|
47
51
|
const operationsIndex = changeSet.indexes[index];
|
|
48
52
|
if (operationsIndex === undefined) {
|
|
@@ -66,7 +70,11 @@ export function enqueueChangeTree(
|
|
|
66
70
|
changeSet: 'changes' | 'filteredChanges' | 'allFilteredChanges',
|
|
67
71
|
queueRootIndex = changeTree[changeSet].queueRootIndex
|
|
68
72
|
) {
|
|
69
|
-
if (root
|
|
73
|
+
if (!root) {
|
|
74
|
+
// skip
|
|
75
|
+
return;
|
|
76
|
+
|
|
77
|
+
} else if (root[changeSet][queueRootIndex] !== changeTree) {
|
|
70
78
|
changeTree[changeSet].queueRootIndex = root[changeSet].push(changeTree) - 1;
|
|
71
79
|
}
|
|
72
80
|
}
|
|
@@ -398,12 +406,13 @@ export class ChangeTree<T extends Ref=any> {
|
|
|
398
406
|
return previousValue;
|
|
399
407
|
}
|
|
400
408
|
|
|
401
|
-
endEncode() {
|
|
409
|
+
endEncode(changeSetName: ChangeSetName) {
|
|
402
410
|
this.indexedOperations = {};
|
|
403
411
|
|
|
404
|
-
//
|
|
405
|
-
|
|
406
|
-
|
|
412
|
+
// clear changeset
|
|
413
|
+
this[changeSetName].indexes = {};
|
|
414
|
+
this[changeSetName].operations.length = 0;
|
|
415
|
+
this[changeSetName].queueRootIndex = undefined;
|
|
407
416
|
|
|
408
417
|
// ArraySchema and MapSchema have a custom "encode end" method
|
|
409
418
|
this.ref[$onEncodeEnd]?.();
|
|
@@ -535,26 +544,24 @@ export class ChangeTree<T extends Ref=any> {
|
|
|
535
544
|
|| parentConstructor?.[Symbol.metadata]?.[$viewFieldIndexes]?.includes(parentIndex);
|
|
536
545
|
|
|
537
546
|
//
|
|
538
|
-
//
|
|
539
|
-
//
|
|
540
|
-
// swapping `changes` and `filteredChanges` is required here
|
|
541
|
-
// because "isFiltered" may not be imedialely available on `change()`
|
|
542
|
-
// (this happens when instance is detached from root or parent)
|
|
547
|
+
// "isFiltered" may not be imedialely available during `change()` due to the instance not being attached to the root yet.
|
|
548
|
+
// when it's available, we need to enqueue the "changes" changeset into the "filteredChanges" changeset.
|
|
543
549
|
//
|
|
544
550
|
if (this.isFiltered) {
|
|
545
|
-
this.filteredChanges
|
|
546
|
-
|
|
551
|
+
if (!this.filteredChanges) {
|
|
552
|
+
this.filteredChanges = createChangeSet();
|
|
553
|
+
this.allFilteredChanges = createChangeSet();
|
|
554
|
+
}
|
|
547
555
|
|
|
548
556
|
if (this.changes.operations.length > 0) {
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
this.
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
this.
|
|
557
|
-
this.allChanges = allFilteredChanges;
|
|
557
|
+
this.changes.operations.forEach((index) =>
|
|
558
|
+
setOperationAtIndex(this.filteredChanges, index));
|
|
559
|
+
|
|
560
|
+
this.allChanges.operations.forEach((index) =>
|
|
561
|
+
setOperationAtIndex(this.allFilteredChanges, index));
|
|
562
|
+
|
|
563
|
+
this.changes = createChangeSet();
|
|
564
|
+
this.allChanges = createChangeSet();
|
|
558
565
|
}
|
|
559
566
|
}
|
|
560
567
|
}
|
package/src/encoder/Encoder.ts
CHANGED
|
@@ -54,12 +54,11 @@ export class Encoder<T extends Schema = any> {
|
|
|
54
54
|
): Buffer {
|
|
55
55
|
const hasView = (view !== undefined);
|
|
56
56
|
const rootChangeTree = this.state[$changes];
|
|
57
|
-
|
|
58
|
-
const shouldDiscardChanges = !isEncodeAll && !hasView;
|
|
59
57
|
const changeTrees = this.root[changeSetName];
|
|
60
58
|
|
|
61
59
|
for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
|
|
62
60
|
const changeTree = changeTrees[i];
|
|
61
|
+
if (!changeTree) { continue; }
|
|
63
62
|
|
|
64
63
|
if (hasView) {
|
|
65
64
|
if (!view.visible.has(changeTree)) {
|
|
@@ -114,11 +113,6 @@ export class Encoder<T extends Schema = any> {
|
|
|
114
113
|
|
|
115
114
|
encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView, metadata);
|
|
116
115
|
}
|
|
117
|
-
|
|
118
|
-
// if (shouldDiscardChanges) {
|
|
119
|
-
// changeTree.discard();
|
|
120
|
-
// changeTree.isNew = false; // Not a new instance anymore
|
|
121
|
-
// }
|
|
122
116
|
}
|
|
123
117
|
|
|
124
118
|
if (it.offset > buffer.byteLength) {
|
|
@@ -147,19 +141,6 @@ export class Encoder<T extends Schema = any> {
|
|
|
147
141
|
return this.encode({ offset: initialOffset }, view, buffer, changeSetName, isEncodeAll);
|
|
148
142
|
|
|
149
143
|
} else {
|
|
150
|
-
//
|
|
151
|
-
// only clear changes after making sure buffer resize is not required.
|
|
152
|
-
//
|
|
153
|
-
if (shouldDiscardChanges) {
|
|
154
|
-
//
|
|
155
|
-
// TODO: avoid iterating over change trees twice.
|
|
156
|
-
//
|
|
157
|
-
for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
|
|
158
|
-
const changeTree = changeTrees[i];
|
|
159
|
-
changeTree.discard();
|
|
160
|
-
changeTree.isNew = false; // Not a new instance anymore
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
144
|
|
|
164
145
|
return buffer.subarray(0, it.offset);
|
|
165
146
|
}
|
|
@@ -265,7 +246,7 @@ export class Encoder<T extends Schema = any> {
|
|
|
265
246
|
let length = this.root.changes.length;
|
|
266
247
|
if (length > 0) {
|
|
267
248
|
while (length--) {
|
|
268
|
-
this.root.changes[length]?.endEncode();
|
|
249
|
+
this.root.changes[length]?.endEncode('changes');
|
|
269
250
|
}
|
|
270
251
|
this.root.changes.length = 0;
|
|
271
252
|
}
|
|
@@ -274,7 +255,7 @@ export class Encoder<T extends Schema = any> {
|
|
|
274
255
|
length = this.root.filteredChanges.length;
|
|
275
256
|
if (length > 0) {
|
|
276
257
|
while (length--) {
|
|
277
|
-
this.root.filteredChanges[length]?.endEncode();
|
|
258
|
+
this.root.filteredChanges[length]?.endEncode('filteredChanges');
|
|
278
259
|
}
|
|
279
260
|
this.root.filteredChanges.length = 0;
|
|
280
261
|
}
|
package/src/encoder/Root.ts
CHANGED
|
@@ -97,11 +97,18 @@ export class Root {
|
|
|
97
97
|
|
|
98
98
|
removeChangeFromChangeSet(changeSetName: "allChanges" | "changes" | "filteredChanges" | "allFilteredChanges", changeTree: ChangeTree) {
|
|
99
99
|
const changeSet = this[changeSetName];
|
|
100
|
-
|
|
100
|
+
const changeSetIndex = changeSet.indexOf(changeTree);
|
|
101
|
+
|
|
102
|
+
if (changeSetIndex !== -1) {
|
|
101
103
|
changeTree[changeSetName].queueRootIndex = -1;
|
|
102
|
-
|
|
104
|
+
changeSet[changeSetIndex] = undefined;
|
|
103
105
|
return true;
|
|
104
106
|
}
|
|
107
|
+
|
|
108
|
+
// if (spliceOne(changeSet, changeSet.indexOf(changeTree))) {
|
|
109
|
+
// changeTree[changeSetName].queueRootIndex = -1;
|
|
110
|
+
// return true;
|
|
111
|
+
// }
|
|
105
112
|
}
|
|
106
113
|
|
|
107
114
|
clear() {
|