@colyseus/schema 3.0.0-alpha.49 → 3.0.0-alpha.50
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 +18 -46
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +18 -46
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +18 -46
- package/lib/encoder/Encoder.js +18 -46
- package/lib/encoder/Encoder.js.map +1 -1
- package/package.json +1 -1
- package/src/encoder/Encoder.ts +19 -59
package/build/umd/index.js
CHANGED
|
@@ -3800,20 +3800,12 @@
|
|
|
3800
3800
|
const changeTrees = this.root[changeSetName];
|
|
3801
3801
|
for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
|
|
3802
3802
|
const changeTree = changeTrees[i];
|
|
3803
|
-
// // Root#removeChangeFromChangeSet() is now removing instead of setting to "undefined"
|
|
3804
|
-
// if (changeTree === undefined) { continue; }
|
|
3805
3803
|
const operations = changeTree[changeSetName];
|
|
3806
3804
|
const ref = changeTree.ref;
|
|
3807
3805
|
const ctor = ref.constructor;
|
|
3808
3806
|
const encoder = ctor[$encoder];
|
|
3809
3807
|
const filter = ctor[$filter];
|
|
3810
3808
|
const metadata = ctor[Symbol.metadata];
|
|
3811
|
-
// try { throw new Error(); } catch (e) {
|
|
3812
|
-
// // only print if not coming from Reflection.ts
|
|
3813
|
-
// if (!e.stack.includes("src/Reflection.ts")) {
|
|
3814
|
-
// console.log("ChangeTree:", { refId: changeTree.refId, ref: ref.constructor.name });
|
|
3815
|
-
// }
|
|
3816
|
-
// }
|
|
3817
3809
|
if (hasView) {
|
|
3818
3810
|
if (!view.items.has(changeTree)) {
|
|
3819
3811
|
view.invisible.add(changeTree);
|
|
@@ -3848,24 +3840,12 @@
|
|
|
3848
3840
|
// view?.invisible.add(changeTree);
|
|
3849
3841
|
continue;
|
|
3850
3842
|
}
|
|
3851
|
-
// try { throw new Error(); } catch (e) {
|
|
3852
|
-
// // only print if not coming from Reflection.ts
|
|
3853
|
-
// if (!e.stack.includes("src/Reflection.ts")) {
|
|
3854
|
-
// console.log("WILL ENCODE", {
|
|
3855
|
-
// ref: changeTree.ref.constructor.name,
|
|
3856
|
-
// fieldIndex,
|
|
3857
|
-
// operation: OPERATION[operation],
|
|
3858
|
-
// });
|
|
3859
|
-
// }
|
|
3860
|
-
// }
|
|
3861
|
-
// console.log("encode...", { ref: changeTree.ref.constructor.name, refId: changeTree.refId, fieldIndex, operation });
|
|
3862
3843
|
encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView, metadata);
|
|
3863
3844
|
}
|
|
3864
|
-
if (shouldDiscardChanges) {
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
}
|
|
3845
|
+
// if (shouldDiscardChanges) {
|
|
3846
|
+
// changeTree.discard();
|
|
3847
|
+
// changeTree.isNew = false; // Not a new instance anymore
|
|
3848
|
+
// }
|
|
3869
3849
|
}
|
|
3870
3850
|
if (it.offset > buffer.byteLength) {
|
|
3871
3851
|
const newSize = getNextPowerOf2(buffer.byteLength * 2);
|
|
@@ -3877,7 +3857,7 @@
|
|
|
3877
3857
|
//
|
|
3878
3858
|
// resize buffer and re-encode (TODO: can we avoid re-encoding here?)
|
|
3879
3859
|
//
|
|
3880
|
-
buffer = Buffer.
|
|
3860
|
+
buffer = Buffer.alloc(newSize);
|
|
3881
3861
|
// assign resized buffer to local sharedBuffer
|
|
3882
3862
|
if (buffer === this.sharedBuffer) {
|
|
3883
3863
|
this.sharedBuffer = buffer;
|
|
@@ -3885,28 +3865,27 @@
|
|
|
3885
3865
|
return this.encode({ offset: initialOffset }, view, buffer, changeSetName, isEncodeAll);
|
|
3886
3866
|
}
|
|
3887
3867
|
else {
|
|
3888
|
-
//
|
|
3889
|
-
//
|
|
3890
|
-
//
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3868
|
+
//
|
|
3869
|
+
// only clear changes after making sure buffer resize is not required.
|
|
3870
|
+
//
|
|
3871
|
+
if (shouldDiscardChanges) {
|
|
3872
|
+
//
|
|
3873
|
+
// TODO: avoid iterating over change trees twice.
|
|
3874
|
+
//
|
|
3875
|
+
for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
|
|
3876
|
+
const changeTree = changeTrees[i];
|
|
3877
|
+
changeTree.discard();
|
|
3878
|
+
changeTree.isNew = false; // Not a new instance anymore
|
|
3879
|
+
}
|
|
3880
|
+
}
|
|
3897
3881
|
return buffer.subarray(0, it.offset);
|
|
3898
3882
|
}
|
|
3899
3883
|
}
|
|
3900
3884
|
encodeAll(it = { offset: 0 }, buffer = this.sharedBuffer) {
|
|
3901
|
-
// console.log(`\nencodeAll(), this.root.allChanges (${(Object.keys(this.root.allChanges).length)})`);
|
|
3902
|
-
// this.debugChanges("allChanges");
|
|
3903
3885
|
return this.encode(it, undefined, buffer, "allChanges", true);
|
|
3904
3886
|
}
|
|
3905
3887
|
encodeAllView(view, sharedOffset, it, bytes = this.sharedBuffer) {
|
|
3906
3888
|
const viewOffset = it.offset;
|
|
3907
|
-
// console.log(`\nencodeAllView(), this.root.allFilteredChanges (${(Object.keys(this.root.allFilteredChanges).length)})`);
|
|
3908
|
-
// this.debugChanges("allFilteredChanges");
|
|
3909
|
-
// console.log("\n\nENCODE ALL FOR VIEW...\n\n")
|
|
3910
3889
|
// try to encode "filtered" changes
|
|
3911
3890
|
this.encode(it, view, bytes, "allFilteredChanges", true, viewOffset);
|
|
3912
3891
|
return Buffer.concat([
|
|
@@ -3934,13 +3913,8 @@
|
|
|
3934
3913
|
}
|
|
3935
3914
|
encodeView(view, sharedOffset, it, bytes = this.sharedBuffer) {
|
|
3936
3915
|
const viewOffset = it.offset;
|
|
3937
|
-
// console.log(`\nencodeView(), view.changes (${view.changes.size})`);
|
|
3938
|
-
// this.debugChanges(view.changes);
|
|
3939
|
-
// console.log(`\nencodeView(), this.root.filteredChanges (${this.root.filteredChanges.size})`);
|
|
3940
|
-
// this.debugChanges("filteredChanges");
|
|
3941
3916
|
// encode visibility changes (add/remove for this view)
|
|
3942
3917
|
const refIds = Object.keys(view.changes);
|
|
3943
|
-
// console.log("ENCODE VIEW:", refIds);
|
|
3944
3918
|
for (let i = 0, numRefIds = refIds.length; i < numRefIds; i++) {
|
|
3945
3919
|
const refId = refIds[i];
|
|
3946
3920
|
const changes = view.changes[refId];
|
|
@@ -3972,7 +3946,6 @@
|
|
|
3972
3946
|
//
|
|
3973
3947
|
// clear "view" changes after encoding
|
|
3974
3948
|
view.changes = {};
|
|
3975
|
-
// console.log("FILTERED CHANGES:", this.root.filteredChanges);
|
|
3976
3949
|
// try to encode "filtered" changes
|
|
3977
3950
|
this.encode(it, view, bytes, "filteredChanges", false, viewOffset);
|
|
3978
3951
|
return Buffer.concat([
|
|
@@ -3995,7 +3968,6 @@
|
|
|
3995
3968
|
// }
|
|
3996
3969
|
}
|
|
3997
3970
|
discardChanges() {
|
|
3998
|
-
// console.log("DISCARD CHANGES!");
|
|
3999
3971
|
// discard shared changes
|
|
4000
3972
|
let length = this.root.changes.length;
|
|
4001
3973
|
if (length > 0) {
|
package/lib/encoder/Encoder.js
CHANGED
|
@@ -35,20 +35,12 @@ class Encoder {
|
|
|
35
35
|
const changeTrees = this.root[changeSetName];
|
|
36
36
|
for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
|
|
37
37
|
const changeTree = changeTrees[i];
|
|
38
|
-
// // Root#removeChangeFromChangeSet() is now removing instead of setting to "undefined"
|
|
39
|
-
// if (changeTree === undefined) { continue; }
|
|
40
38
|
const operations = changeTree[changeSetName];
|
|
41
39
|
const ref = changeTree.ref;
|
|
42
40
|
const ctor = ref.constructor;
|
|
43
41
|
const encoder = ctor[symbols_1.$encoder];
|
|
44
42
|
const filter = ctor[symbols_1.$filter];
|
|
45
43
|
const metadata = ctor[Symbol.metadata];
|
|
46
|
-
// try { throw new Error(); } catch (e) {
|
|
47
|
-
// // only print if not coming from Reflection.ts
|
|
48
|
-
// if (!e.stack.includes("src/Reflection.ts")) {
|
|
49
|
-
// console.log("ChangeTree:", { refId: changeTree.refId, ref: ref.constructor.name });
|
|
50
|
-
// }
|
|
51
|
-
// }
|
|
52
44
|
if (hasView) {
|
|
53
45
|
if (!view.items.has(changeTree)) {
|
|
54
46
|
view.invisible.add(changeTree);
|
|
@@ -83,24 +75,12 @@ class Encoder {
|
|
|
83
75
|
// view?.invisible.add(changeTree);
|
|
84
76
|
continue;
|
|
85
77
|
}
|
|
86
|
-
// try { throw new Error(); } catch (e) {
|
|
87
|
-
// // only print if not coming from Reflection.ts
|
|
88
|
-
// if (!e.stack.includes("src/Reflection.ts")) {
|
|
89
|
-
// console.log("WILL ENCODE", {
|
|
90
|
-
// ref: changeTree.ref.constructor.name,
|
|
91
|
-
// fieldIndex,
|
|
92
|
-
// operation: OPERATION[operation],
|
|
93
|
-
// });
|
|
94
|
-
// }
|
|
95
|
-
// }
|
|
96
|
-
// console.log("encode...", { ref: changeTree.ref.constructor.name, refId: changeTree.refId, fieldIndex, operation });
|
|
97
78
|
encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView, metadata);
|
|
98
79
|
}
|
|
99
|
-
if (shouldDiscardChanges) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
80
|
+
// if (shouldDiscardChanges) {
|
|
81
|
+
// changeTree.discard();
|
|
82
|
+
// changeTree.isNew = false; // Not a new instance anymore
|
|
83
|
+
// }
|
|
104
84
|
}
|
|
105
85
|
if (it.offset > buffer.byteLength) {
|
|
106
86
|
const newSize = (0, utils_1.getNextPowerOf2)(buffer.byteLength * 2);
|
|
@@ -112,7 +92,7 @@ class Encoder {
|
|
|
112
92
|
//
|
|
113
93
|
// resize buffer and re-encode (TODO: can we avoid re-encoding here?)
|
|
114
94
|
//
|
|
115
|
-
buffer = Buffer.
|
|
95
|
+
buffer = Buffer.alloc(newSize);
|
|
116
96
|
// assign resized buffer to local sharedBuffer
|
|
117
97
|
if (buffer === this.sharedBuffer) {
|
|
118
98
|
this.sharedBuffer = buffer;
|
|
@@ -120,28 +100,27 @@ class Encoder {
|
|
|
120
100
|
return this.encode({ offset: initialOffset }, view, buffer, changeSetName, isEncodeAll);
|
|
121
101
|
}
|
|
122
102
|
else {
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
//
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
103
|
+
//
|
|
104
|
+
// only clear changes after making sure buffer resize is not required.
|
|
105
|
+
//
|
|
106
|
+
if (shouldDiscardChanges) {
|
|
107
|
+
//
|
|
108
|
+
// TODO: avoid iterating over change trees twice.
|
|
109
|
+
//
|
|
110
|
+
for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
|
|
111
|
+
const changeTree = changeTrees[i];
|
|
112
|
+
changeTree.discard();
|
|
113
|
+
changeTree.isNew = false; // Not a new instance anymore
|
|
114
|
+
}
|
|
115
|
+
}
|
|
132
116
|
return buffer.subarray(0, it.offset);
|
|
133
117
|
}
|
|
134
118
|
}
|
|
135
119
|
encodeAll(it = { offset: 0 }, buffer = this.sharedBuffer) {
|
|
136
|
-
// console.log(`\nencodeAll(), this.root.allChanges (${(Object.keys(this.root.allChanges).length)})`);
|
|
137
|
-
// this.debugChanges("allChanges");
|
|
138
120
|
return this.encode(it, undefined, buffer, "allChanges", true);
|
|
139
121
|
}
|
|
140
122
|
encodeAllView(view, sharedOffset, it, bytes = this.sharedBuffer) {
|
|
141
123
|
const viewOffset = it.offset;
|
|
142
|
-
// console.log(`\nencodeAllView(), this.root.allFilteredChanges (${(Object.keys(this.root.allFilteredChanges).length)})`);
|
|
143
|
-
// this.debugChanges("allFilteredChanges");
|
|
144
|
-
// console.log("\n\nENCODE ALL FOR VIEW...\n\n")
|
|
145
124
|
// try to encode "filtered" changes
|
|
146
125
|
this.encode(it, view, bytes, "allFilteredChanges", true, viewOffset);
|
|
147
126
|
return Buffer.concat([
|
|
@@ -169,13 +148,8 @@ class Encoder {
|
|
|
169
148
|
}
|
|
170
149
|
encodeView(view, sharedOffset, it, bytes = this.sharedBuffer) {
|
|
171
150
|
const viewOffset = it.offset;
|
|
172
|
-
// console.log(`\nencodeView(), view.changes (${view.changes.size})`);
|
|
173
|
-
// this.debugChanges(view.changes);
|
|
174
|
-
// console.log(`\nencodeView(), this.root.filteredChanges (${this.root.filteredChanges.size})`);
|
|
175
|
-
// this.debugChanges("filteredChanges");
|
|
176
151
|
// encode visibility changes (add/remove for this view)
|
|
177
152
|
const refIds = Object.keys(view.changes);
|
|
178
|
-
// console.log("ENCODE VIEW:", refIds);
|
|
179
153
|
for (let i = 0, numRefIds = refIds.length; i < numRefIds; i++) {
|
|
180
154
|
const refId = refIds[i];
|
|
181
155
|
const changes = view.changes[refId];
|
|
@@ -207,7 +181,6 @@ class Encoder {
|
|
|
207
181
|
//
|
|
208
182
|
// clear "view" changes after encoding
|
|
209
183
|
view.changes = {};
|
|
210
|
-
// console.log("FILTERED CHANGES:", this.root.filteredChanges);
|
|
211
184
|
// try to encode "filtered" changes
|
|
212
185
|
this.encode(it, view, bytes, "filteredChanges", false, viewOffset);
|
|
213
186
|
return Buffer.concat([
|
|
@@ -230,7 +203,6 @@ class Encoder {
|
|
|
230
203
|
// }
|
|
231
204
|
}
|
|
232
205
|
discardChanges() {
|
|
233
|
-
// console.log("DISCARD CHANGES!");
|
|
234
206
|
// discard shared changes
|
|
235
207
|
let length = this.root.changes.length;
|
|
236
208
|
if (length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Encoder.js","sourceRoot":"","sources":["../../src/encoder/Encoder.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Schema } from \"../Schema\";\nimport { TypeContext } from \"../types/TypeContext\";\nimport { $changes, $encoder, $filter, $onEncodeEnd } from \"../types/symbols\";\n\nimport { encode } from \"../encoding/encode\";\nimport type { Iterator } from \"../encoding/decode\";\n\nimport { OPERATION, SWITCH_TO_STRUCTURE, TYPE_ID } from '../encoding/spec';\nimport { Root } from \"./Root\";\nimport { getNextPowerOf2 } from \"../utils\";\n\nimport type { StateView } from \"./StateView\";\nimport type { Metadata } from \"../Metadata\";\n\nexport class Encoder<T extends Schema = any> {\n static BUFFER_SIZE = 8 * 1024;// 8KB\n sharedBuffer = Buffer.allocUnsafeSlow(Encoder.BUFFER_SIZE);\n\n context: TypeContext;\n state: T;\n\n root: Root;\n\n constructor(state: T) {\n\n //\n // TODO: cache and restore \"Context\" based on root schema\n // (to avoid creating a new context for every new room)\n //\n this.context = new TypeContext(state.constructor as typeof Schema);\n this.root = new Root(this.context);\n\n this.setState(state);\n\n // console.log(\">>>>>>>>>>>>>>>> Encoder types\");\n // this.context.schemas.forEach((id, schema) => {\n // console.log(\"type:\", id, schema.name, Object.keys(schema[Symbol.metadata]));\n // });\n }\n\n protected setState(state: T) {\n this.state = state;\n this.state[$changes].setRoot(this.root);\n }\n\n encode(\n it: Iterator = { offset: 0 },\n view?: StateView,\n buffer = this.sharedBuffer,\n changeSetName: \"changes\" | \"allChanges\" | \"filteredChanges\" | \"allFilteredChanges\" = \"changes\",\n isEncodeAll = changeSetName === \"allChanges\",\n initialOffset = it.offset // cache current offset in case we need to resize the buffer\n ): Buffer {\n const hasView = (view !== undefined);\n const rootChangeTree = this.state[$changes];\n\n const shouldDiscardChanges = !isEncodeAll && !hasView;\n const changeTrees = this.root[changeSetName];\n\n for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {\n const changeTree = changeTrees[i];\n\n // // Root#removeChangeFromChangeSet() is now removing instead of setting to \"undefined\"\n // if (changeTree === undefined) { continue; }\n\n const operations = changeTree[changeSetName];\n const ref = changeTree.ref;\n\n const ctor = ref.constructor;\n const encoder = ctor[$encoder];\n const filter = ctor[$filter];\n const metadata = ctor[Symbol.metadata];\n\n // try { throw new Error(); } catch (e) {\n // // only print if not coming from Reflection.ts\n // if (!e.stack.includes(\"src/Reflection.ts\")) {\n // console.log(\"ChangeTree:\", { refId: changeTree.refId, ref: ref.constructor.name });\n // }\n // }\n\n if (hasView) {\n if (!view.items.has(changeTree)) {\n view.invisible.add(changeTree);\n continue; // skip this change tree\n\n } else if (view.invisible.has(changeTree)) {\n view.invisible.delete(changeTree); // remove from invisible list\n }\n }\n\n // skip root `refId` if it's the first change tree\n // (unless it \"hasView\", which will need to revisit the root)\n if (hasView || it.offset > initialOffset || changeTree !== rootChangeTree) {\n buffer[it.offset++] = SWITCH_TO_STRUCTURE & 255;\n encode.number(buffer, changeTree.refId, it);\n }\n\n for (let j = 0, numChanges = operations.operations.length; j < numChanges; j++) {\n const fieldIndex = operations.operations[j];\n\n const operation = (fieldIndex < 0)\n ? Math.abs(fieldIndex) // \"pure\" operation without fieldIndex (e.g. CLEAR, REVERSE, etc.)\n : (isEncodeAll)\n ? OPERATION.ADD\n : changeTree.indexedOperations[fieldIndex];\n\n //\n // first pass (encodeAll), identify \"filtered\" operations without encoding them\n // they will be encoded per client, based on their view.\n //\n // TODO: how can we optimize filtering out \"encode all\" operations?\n // TODO: avoid checking if no view tags were defined\n //\n if (fieldIndex === undefined || operation === undefined || (filter && !filter(ref, fieldIndex, view))) {\n // console.log(\"ADD AS INVISIBLE:\", fieldIndex, changeTree.ref.constructor.name)\n // view?.invisible.add(changeTree);\n continue;\n }\n\n // try { throw new Error(); } catch (e) {\n // // only print if not coming from Reflection.ts\n // if (!e.stack.includes(\"src/Reflection.ts\")) {\n // console.log(\"WILL ENCODE\", {\n // ref: changeTree.ref.constructor.name,\n // fieldIndex,\n // operation: OPERATION[operation],\n // });\n // }\n // }\n\n // console.log(\"encode...\", { ref: changeTree.ref.constructor.name, refId: changeTree.refId, fieldIndex, operation });\n\n encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView, metadata);\n }\n\n if (shouldDiscardChanges) {\n changeTree.discard();\n\n // Not a new instance anymore\n changeTree.isNew = false;\n }\n }\n\n if (it.offset > buffer.byteLength) {\n const newSize = getNextPowerOf2(buffer.byteLength * 2);\n console.warn(`@colyseus/schema buffer overflow. Encoded state is higher than default BUFFER_SIZE. Use the following to increase default BUFFER_SIZE:\n\n import { Encoder } from \"@colyseus/schema\";\n Encoder.BUFFER_SIZE = ${Math.round(newSize / 1024)} * 1024; // ${Math.round(newSize / 1024)} KB\n`);\n\n //\n // resize buffer and re-encode (TODO: can we avoid re-encoding here?)\n //\n buffer = Buffer.allocUnsafeSlow(newSize);\n\n // assign resized buffer to local sharedBuffer\n if (buffer === this.sharedBuffer) {\n this.sharedBuffer = buffer;\n }\n\n return this.encode({ offset: initialOffset }, view, buffer, changeSetName, isEncodeAll);\n\n } else {\n // //\n // // only clear changes after making sure buffer resize is not required.\n // //\n // if (shouldClearChanges) {\n // //\n // // FIXME: avoid iterating over change trees twice.\n // //\n // this.onEndEncode(changeTrees);\n // }\n\n return buffer.subarray(0, it.offset);\n }\n }\n\n encodeAll(it: Iterator = { offset: 0 }, buffer: Buffer = this.sharedBuffer) {\n // console.log(`\\nencodeAll(), this.root.allChanges (${(Object.keys(this.root.allChanges).length)})`);\n // this.debugChanges(\"allChanges\");\n\n return this.encode(it, undefined, buffer, \"allChanges\", true);\n }\n\n encodeAllView(view: StateView, sharedOffset: number, it: Iterator, bytes = this.sharedBuffer) {\n const viewOffset = it.offset;\n\n // console.log(`\\nencodeAllView(), this.root.allFilteredChanges (${(Object.keys(this.root.allFilteredChanges).length)})`);\n // this.debugChanges(\"allFilteredChanges\");\n\n // console.log(\"\\n\\nENCODE ALL FOR VIEW...\\n\\n\")\n\n // try to encode \"filtered\" changes\n this.encode(it, view, bytes, \"allFilteredChanges\", true, viewOffset);\n\n return Buffer.concat([\n bytes.subarray(0, sharedOffset),\n bytes.subarray(viewOffset, it.offset)\n ]);\n }\n\n debugChanges(field: \"changes\" | \"allFilteredChanges\" | \"allChanges\" | \"filteredChanges\") {\n const rootChangeSet = (typeof (field) === \"string\")\n ? this.root[field]\n : field;\n\n rootChangeSet.forEach((changeTree) => {\n const changeSet = changeTree[field];\n\n const metadata: Metadata = changeTree.ref.constructor[Symbol.metadata];\n console.log(\"->\", { ref: changeTree.ref.constructor.name, refId: changeTree.refId, changes: Object.keys(changeSet).length });\n for (const index in changeSet) {\n const op = changeSet[index];\n console.log(\" ->\", {\n index,\n field: metadata?.[index],\n op: OPERATION[op],\n });\n }\n });\n }\n\n encodeView(view: StateView, sharedOffset: number, it: Iterator, bytes = this.sharedBuffer) {\n const viewOffset = it.offset;\n\n // console.log(`\\nencodeView(), view.changes (${view.changes.size})`);\n // this.debugChanges(view.changes);\n\n // console.log(`\\nencodeView(), this.root.filteredChanges (${this.root.filteredChanges.size})`);\n // this.debugChanges(\"filteredChanges\");\n\n // encode visibility changes (add/remove for this view)\n const refIds = Object.keys(view.changes);\n // console.log(\"ENCODE VIEW:\", refIds);\n for (let i = 0, numRefIds = refIds.length; i < numRefIds; i++) {\n const refId = refIds[i];\n const changes = view.changes[refId];\n const changeTree = this.root.changeTrees[refId];\n\n if (\n changeTree === undefined ||\n Object.keys(changes).length === 0 // FIXME: avoid having empty changes if no changes were made\n ) {\n // console.log(\"changes.size === 0, skip\", changeTree.ref.constructor.name);\n continue;\n }\n\n const ref = changeTree.ref;\n\n const ctor = ref.constructor;\n const encoder = ctor[$encoder];\n const metadata = ctor[Symbol.metadata];\n\n bytes[it.offset++] = SWITCH_TO_STRUCTURE & 255;\n encode.number(bytes, changeTree.refId, it);\n\n const keys = Object.keys(changes);\n for (let i = 0, numChanges = keys.length; i < numChanges; i++) {\n const key = keys[i];\n const operation = changes[key];\n\n // isEncodeAll = false\n // hasView = true\n encoder(this, bytes, changeTree, Number(key), operation, it, false, true, metadata);\n }\n }\n\n //\n // TODO: only clear view changes after all views are encoded\n // (to allow re-using StateView's for multiple clients)\n //\n // clear \"view\" changes after encoding\n view.changes = {};\n\n // console.log(\"FILTERED CHANGES:\", this.root.filteredChanges);\n\n // try to encode \"filtered\" changes\n this.encode(it, view, bytes, \"filteredChanges\", false, viewOffset);\n\n return Buffer.concat([\n bytes.subarray(0, sharedOffset),\n bytes.subarray(viewOffset, it.offset)\n ]);\n }\n\n onEndEncode(changeTrees = this.root.changes) {\n // changeTrees.forEach(function(changeTree) {\n // changeTree.endEncode();\n // });\n\n\n // for (const refId in changeTrees) {\n // const changeTree = this.root.changeTrees[refId];\n // changeTree.endEncode();\n\n // // changeTree.changes.clear();\n\n // // // ArraySchema and MapSchema have a custom \"encode end\" method\n // // changeTree.ref[$onEncodeEnd]?.();\n\n // // // Not a new instance anymore\n // // delete changeTree[$isNew];\n // }\n }\n\n discardChanges() {\n // console.log(\"DISCARD CHANGES!\");\n\n // discard shared changes\n let length = this.root.changes.length;\n if (length > 0) {\n while (length--) {\n this.root.changes[length]?.endEncode();\n }\n this.root.changes.length = 0;\n }\n\n // discard filtered changes\n length = this.root.filteredChanges.length;\n if (length > 0) {\n while (length--) {\n this.root.filteredChanges[length]?.endEncode();\n }\n this.root.filteredChanges.length = 0;\n }\n }\n\n tryEncodeTypeId (bytes: Buffer, baseType: typeof Schema, targetType: typeof Schema, it: Iterator) {\n const baseTypeId = this.context.getTypeId(baseType);\n const targetTypeId = this.context.getTypeId(targetType);\n\n if (targetTypeId === undefined) {\n console.warn(`@colyseus/schema WARNING: Class \"${targetType.name}\" is not registered on TypeRegistry - Please either tag the class with @entity or define a @type() field.`);\n return;\n }\n\n if (baseTypeId !== targetTypeId) {\n bytes[it.offset++] = TYPE_ID & 255;\n encode.number(bytes, targetTypeId, it);\n }\n }\n\n get hasChanges() {\n return (\n this.root.changes.length > 0 ||\n this.root.filteredChanges.length > 0\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Encoder.js","sourceRoot":"","sources":["../../src/encoder/Encoder.ts"],"names":[],"mappings":";;;AACA,sDAAmD;AACnD,8CAA6E;AAE7E,+CAA4C;AAG5C,2CAA2E;AAC3E,iCAA8B;AAC9B,oCAA2C;AAK3C,MAAa,OAAO;aACT,gBAAW,GAAG,CAAC,GAAG,IAAI,AAAX,CAAY,GAAA,MAAM;IAQpC,YAAY,KAAQ;QAPpB,iBAAY,GAAG,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAQvD,EAAE;QACF,yDAAyD;QACzD,uDAAuD;QACvD,EAAE;QACF,IAAI,CAAC,OAAO,GAAG,IAAI,yBAAW,CAAC,KAAK,CAAC,WAA4B,CAAC,CAAC;QACnE,IAAI,CAAC,IAAI,GAAG,IAAI,WAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEnC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAErB,iDAAiD;QACjD,iDAAiD;QACjD,mFAAmF;QACnF,MAAM;IACV,CAAC;IAES,QAAQ,CAAC,KAAQ;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,CAAC,kBAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,CACF,KAAe,EAAE,MAAM,EAAE,CAAC,EAAE,EAC5B,IAAgB,EAChB,MAAM,GAAG,IAAI,CAAC,YAAY,EAC1B,gBAAqF,SAAS,EAC9F,WAAW,GAAG,aAAa,KAAK,YAAY,EAC5C,aAAa,GAAG,EAAE,CAAC,MAAM,CAAC,4DAA4D;;QAEtF,MAAM,OAAO,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QACrC,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAQ,CAAC,CAAC;QAE5C,MAAM,oBAAoB,GAAG,CAAC,WAAW,IAAI,CAAC,OAAO,CAAC;QACtD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3E,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAElC,MAAM,UAAU,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;YAC7C,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC;YAE3B,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC;YAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAQ,CAAC,CAAC;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAO,CAAC,CAAC;YAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAEvC,IAAI,OAAO,EAAE,CAAC;gBACV,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC9B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBAC/B,SAAS,CAAC,wBAAwB;gBAEtC,CAAC;qBAAM,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;oBACxC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,6BAA6B;gBACpE,CAAC;YACL,CAAC;YAED,kDAAkD;YAClD,6DAA6D;YAC7D,IAAI,OAAO,IAAI,EAAE,CAAC,MAAM,GAAG,aAAa,IAAI,UAAU,KAAK,cAAc,EAAE,CAAC;gBACxE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG,0BAAmB,GAAG,GAAG,CAAC;gBAChD,eAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAChD,CAAC;YAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7E,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAE5C,MAAM,SAAS,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC;oBAC9B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,kEAAkE;oBACzF,CAAC,CAAC,CAAC,WAAW,CAAC;wBACX,CAAC,CAAC,gBAAS,CAAC,GAAG;wBACf,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;gBAEnD,EAAE;gBACF,+EAA+E;gBAC/E,wDAAwD;gBACxD,EAAE;gBACF,mEAAmE;gBACnE,oDAAoD;gBACpD,EAAE;gBACF,IAAI,UAAU,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;oBACpG,gFAAgF;oBAChF,mCAAmC;oBACnC,SAAS;gBACb,CAAC;gBAED,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YACjG,CAAC;YAED,8BAA8B;YAC9B,4BAA4B;YAC5B,8DAA8D;YAC9D,IAAI;QACR,CAAC;QAED,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,IAAA,uBAAe,EAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC;;;4BAGG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,eAAe,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;CAC9F,CAAC,CAAC;YAES,EAAE;YACF,qEAAqE;YACrE,EAAE;YACF,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAE/B,8CAA8C;YAC9C,IAAI,MAAM,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC/B,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;YAC/B,CAAC;YAED,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAE5F,CAAC;aAAM,CAAC;YACJ,EAAE;YACF,sEAAsE;YACtE,EAAE;YACF,IAAI,oBAAoB,EAAE,CAAC;gBACvB,EAAE;gBACF,iDAAiD;gBACjD,EAAE;gBACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC3E,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;oBAClC,UAAU,CAAC,OAAO,EAAE,CAAC;oBACrB,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,6BAA6B;gBAC3D,CAAC;YACL,CAAC;YAED,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,KAAe,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,SAAiB,IAAI,CAAC,YAAY;QACtE,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;IAClE,CAAC;IAED,aAAa,CAAC,IAAe,EAAE,YAAoB,EAAE,EAAY,EAAE,KAAK,GAAG,IAAI,CAAC,YAAY;QACxF,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC;QAE7B,mCAAmC;QACnC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,oBAAoB,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QAErE,OAAO,MAAM,CAAC,MAAM,CAAC;YACjB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,YAAY,CAAC;YAC/B,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC;SACxC,CAAC,CAAC;IACP,CAAC;IAED,YAAY,CAAC,KAA0E;QACnF,MAAM,aAAa,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC;YAC/C,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YAClB,CAAC,CAAC,KAAK,CAAC;QAEZ,aAAa,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE;YACjC,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YAEpC,MAAM,QAAQ,GAAa,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7H,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;gBAC5B,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE;oBAChB,KAAK;oBACL,KAAK,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC;oBACxB,EAAE,EAAE,gBAAS,CAAC,EAAE,CAAC;iBACpB,CAAC,CAAC;YACP,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED,UAAU,CAAC,IAAe,EAAE,YAAoB,EAAE,EAAY,EAAE,KAAK,GAAG,IAAI,CAAC,YAAY;QACrF,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC;QAE7B,uDAAuD;QACvD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACpC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAEhD,IACI,UAAU,KAAK,SAAS;gBACxB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,4DAA4D;cAChG,CAAC;gBACC,4EAA4E;gBAC5E,SAAS;YACb,CAAC;YAED,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC;YAE3B,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC;YAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAQ,CAAC,CAAC;YAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAEvC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG,0BAAmB,GAAG,GAAG,CAAC;YAC/C,eAAM,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAE3C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBACpB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;gBAE/B,sBAAsB;gBACtB,iBAAiB;gBACjB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YACxF,CAAC;QACL,CAAC;QAED,EAAE;QACF,4DAA4D;QAC5D,uDAAuD;QACvD,EAAE;QACF,sCAAsC;QACtC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAElB,mCAAmC;QACnC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;QAEnE,OAAO,MAAM,CAAC,MAAM,CAAC;YACjB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,YAAY,CAAC;YAC/B,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC;SACxC,CAAC,CAAC;IACP,CAAC;IAED,WAAW,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO;QACvC,6CAA6C;QAC7C,8BAA8B;QAC9B,MAAM;QAGN,qCAAqC;QACrC,uDAAuD;QACvD,8BAA8B;QAE9B,qCAAqC;QAErC,wEAAwE;QACxE,2CAA2C;QAE3C,uCAAuC;QACvC,oCAAoC;QACpC,IAAI;IACR,CAAC;IAED,cAAc;QACV,yBAAyB;QACzB,IAAI,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACtC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACb,OAAO,MAAM,EAAE,EAAE,CAAC;gBACd,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;YAC3C,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACjC,CAAC;QAED,2BAA2B;QAC3B,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;QAC1C,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACb,OAAO,MAAM,EAAE,EAAE,CAAC;gBACd,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;YACnD,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC;QACzC,CAAC;IACL,CAAC;IAED,eAAe,CAAE,KAAa,EAAE,QAAuB,EAAE,UAAyB,EAAE,EAAY;QAC5F,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAExD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,oCAAoC,UAAU,CAAC,IAAI,2GAA2G,CAAC,CAAC;YAC7K,OAAO;QACX,CAAC;QAED,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;YAC9B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG,cAAO,GAAG,GAAG,CAAC;YACnC,eAAM,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC;QAC3C,CAAC;IACL,CAAC;IAED,IAAI,UAAU;QACV,OAAO,CACH,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CACvC,CAAC;IACN,CAAC;;AAtSL,0BAuSC","sourcesContent":["import type { Schema } from \"../Schema\";\nimport { TypeContext } from \"../types/TypeContext\";\nimport { $changes, $encoder, $filter, $onEncodeEnd } from \"../types/symbols\";\n\nimport { encode } from \"../encoding/encode\";\nimport type { Iterator } from \"../encoding/decode\";\n\nimport { OPERATION, SWITCH_TO_STRUCTURE, TYPE_ID } from '../encoding/spec';\nimport { Root } from \"./Root\";\nimport { getNextPowerOf2 } from \"../utils\";\n\nimport type { StateView } from \"./StateView\";\nimport type { Metadata } from \"../Metadata\";\n\nexport class Encoder<T extends Schema = any> {\n static BUFFER_SIZE = 8 * 1024;// 8KB\n sharedBuffer = Buffer.allocUnsafeSlow(Encoder.BUFFER_SIZE);\n\n context: TypeContext;\n state: T;\n\n root: Root;\n\n constructor(state: T) {\n //\n // TODO: cache and restore \"Context\" based on root schema\n // (to avoid creating a new context for every new room)\n //\n this.context = new TypeContext(state.constructor as typeof Schema);\n this.root = new Root(this.context);\n\n this.setState(state);\n\n // console.log(\">>>>>>>>>>>>>>>> Encoder types\");\n // this.context.schemas.forEach((id, schema) => {\n // console.log(\"type:\", id, schema.name, Object.keys(schema[Symbol.metadata]));\n // });\n }\n\n protected setState(state: T) {\n this.state = state;\n this.state[$changes].setRoot(this.root);\n }\n\n encode(\n it: Iterator = { offset: 0 },\n view?: StateView,\n buffer = this.sharedBuffer,\n changeSetName: \"changes\" | \"allChanges\" | \"filteredChanges\" | \"allFilteredChanges\" = \"changes\",\n isEncodeAll = changeSetName === \"allChanges\",\n initialOffset = it.offset // cache current offset in case we need to resize the buffer\n ): Buffer {\n const hasView = (view !== undefined);\n const rootChangeTree = this.state[$changes];\n\n const shouldDiscardChanges = !isEncodeAll && !hasView;\n const changeTrees = this.root[changeSetName];\n\n for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {\n const changeTree = changeTrees[i];\n\n const operations = changeTree[changeSetName];\n const ref = changeTree.ref;\n\n const ctor = ref.constructor;\n const encoder = ctor[$encoder];\n const filter = ctor[$filter];\n const metadata = ctor[Symbol.metadata];\n\n if (hasView) {\n if (!view.items.has(changeTree)) {\n view.invisible.add(changeTree);\n continue; // skip this change tree\n\n } else if (view.invisible.has(changeTree)) {\n view.invisible.delete(changeTree); // remove from invisible list\n }\n }\n\n // skip root `refId` if it's the first change tree\n // (unless it \"hasView\", which will need to revisit the root)\n if (hasView || it.offset > initialOffset || changeTree !== rootChangeTree) {\n buffer[it.offset++] = SWITCH_TO_STRUCTURE & 255;\n encode.number(buffer, changeTree.refId, it);\n }\n\n for (let j = 0, numChanges = operations.operations.length; j < numChanges; j++) {\n const fieldIndex = operations.operations[j];\n\n const operation = (fieldIndex < 0)\n ? Math.abs(fieldIndex) // \"pure\" operation without fieldIndex (e.g. CLEAR, REVERSE, etc.)\n : (isEncodeAll)\n ? OPERATION.ADD\n : changeTree.indexedOperations[fieldIndex];\n\n //\n // first pass (encodeAll), identify \"filtered\" operations without encoding them\n // they will be encoded per client, based on their view.\n //\n // TODO: how can we optimize filtering out \"encode all\" operations?\n // TODO: avoid checking if no view tags were defined\n //\n if (fieldIndex === undefined || operation === undefined || (filter && !filter(ref, fieldIndex, view))) {\n // console.log(\"ADD AS INVISIBLE:\", fieldIndex, changeTree.ref.constructor.name)\n // view?.invisible.add(changeTree);\n continue;\n }\n\n encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView, metadata);\n }\n\n // if (shouldDiscardChanges) {\n // changeTree.discard();\n // changeTree.isNew = false; // Not a new instance anymore\n // }\n }\n\n if (it.offset > buffer.byteLength) {\n const newSize = getNextPowerOf2(buffer.byteLength * 2);\n console.warn(`@colyseus/schema buffer overflow. Encoded state is higher than default BUFFER_SIZE. Use the following to increase default BUFFER_SIZE:\n\n import { Encoder } from \"@colyseus/schema\";\n Encoder.BUFFER_SIZE = ${Math.round(newSize / 1024)} * 1024; // ${Math.round(newSize / 1024)} KB\n`);\n\n //\n // resize buffer and re-encode (TODO: can we avoid re-encoding here?)\n //\n buffer = Buffer.alloc(newSize);\n\n // assign resized buffer to local sharedBuffer\n if (buffer === this.sharedBuffer) {\n this.sharedBuffer = buffer;\n }\n\n return this.encode({ offset: initialOffset }, view, buffer, changeSetName, isEncodeAll);\n\n } else {\n //\n // only clear changes after making sure buffer resize is not required.\n //\n if (shouldDiscardChanges) {\n //\n // TODO: avoid iterating over change trees twice.\n //\n for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {\n const changeTree = changeTrees[i];\n changeTree.discard();\n changeTree.isNew = false; // Not a new instance anymore\n }\n }\n\n return buffer.subarray(0, it.offset);\n }\n }\n\n encodeAll(it: Iterator = { offset: 0 }, buffer: Buffer = this.sharedBuffer) {\n return this.encode(it, undefined, buffer, \"allChanges\", true);\n }\n\n encodeAllView(view: StateView, sharedOffset: number, it: Iterator, bytes = this.sharedBuffer) {\n const viewOffset = it.offset;\n\n // try to encode \"filtered\" changes\n this.encode(it, view, bytes, \"allFilteredChanges\", true, viewOffset);\n\n return Buffer.concat([\n bytes.subarray(0, sharedOffset),\n bytes.subarray(viewOffset, it.offset)\n ]);\n }\n\n debugChanges(field: \"changes\" | \"allFilteredChanges\" | \"allChanges\" | \"filteredChanges\") {\n const rootChangeSet = (typeof (field) === \"string\")\n ? this.root[field]\n : field;\n\n rootChangeSet.forEach((changeTree) => {\n const changeSet = changeTree[field];\n\n const metadata: Metadata = changeTree.ref.constructor[Symbol.metadata];\n console.log(\"->\", { ref: changeTree.ref.constructor.name, refId: changeTree.refId, changes: Object.keys(changeSet).length });\n for (const index in changeSet) {\n const op = changeSet[index];\n console.log(\" ->\", {\n index,\n field: metadata?.[index],\n op: OPERATION[op],\n });\n }\n });\n }\n\n encodeView(view: StateView, sharedOffset: number, it: Iterator, bytes = this.sharedBuffer) {\n const viewOffset = it.offset;\n\n // encode visibility changes (add/remove for this view)\n const refIds = Object.keys(view.changes);\n\n for (let i = 0, numRefIds = refIds.length; i < numRefIds; i++) {\n const refId = refIds[i];\n const changes = view.changes[refId];\n const changeTree = this.root.changeTrees[refId];\n\n if (\n changeTree === undefined ||\n Object.keys(changes).length === 0 // FIXME: avoid having empty changes if no changes were made\n ) {\n // console.log(\"changes.size === 0, skip\", changeTree.ref.constructor.name);\n continue;\n }\n\n const ref = changeTree.ref;\n\n const ctor = ref.constructor;\n const encoder = ctor[$encoder];\n const metadata = ctor[Symbol.metadata];\n\n bytes[it.offset++] = SWITCH_TO_STRUCTURE & 255;\n encode.number(bytes, changeTree.refId, it);\n\n const keys = Object.keys(changes);\n for (let i = 0, numChanges = keys.length; i < numChanges; i++) {\n const key = keys[i];\n const operation = changes[key];\n\n // isEncodeAll = false\n // hasView = true\n encoder(this, bytes, changeTree, Number(key), operation, it, false, true, metadata);\n }\n }\n\n //\n // TODO: only clear view changes after all views are encoded\n // (to allow re-using StateView's for multiple clients)\n //\n // clear \"view\" changes after encoding\n view.changes = {};\n\n // try to encode \"filtered\" changes\n this.encode(it, view, bytes, \"filteredChanges\", false, viewOffset);\n\n return Buffer.concat([\n bytes.subarray(0, sharedOffset),\n bytes.subarray(viewOffset, it.offset)\n ]);\n }\n\n onEndEncode(changeTrees = this.root.changes) {\n // changeTrees.forEach(function(changeTree) {\n // changeTree.endEncode();\n // });\n\n\n // for (const refId in changeTrees) {\n // const changeTree = this.root.changeTrees[refId];\n // changeTree.endEncode();\n\n // // changeTree.changes.clear();\n\n // // // ArraySchema and MapSchema have a custom \"encode end\" method\n // // changeTree.ref[$onEncodeEnd]?.();\n\n // // // Not a new instance anymore\n // // delete changeTree[$isNew];\n // }\n }\n\n discardChanges() {\n // discard shared changes\n let length = this.root.changes.length;\n if (length > 0) {\n while (length--) {\n this.root.changes[length]?.endEncode();\n }\n this.root.changes.length = 0;\n }\n\n // discard filtered changes\n length = this.root.filteredChanges.length;\n if (length > 0) {\n while (length--) {\n this.root.filteredChanges[length]?.endEncode();\n }\n this.root.filteredChanges.length = 0;\n }\n }\n\n tryEncodeTypeId (bytes: Buffer, baseType: typeof Schema, targetType: typeof Schema, it: Iterator) {\n const baseTypeId = this.context.getTypeId(baseType);\n const targetTypeId = this.context.getTypeId(targetType);\n\n if (targetTypeId === undefined) {\n console.warn(`@colyseus/schema WARNING: Class \"${targetType.name}\" is not registered on TypeRegistry - Please either tag the class with @entity or define a @type() field.`);\n return;\n }\n\n if (baseTypeId !== targetTypeId) {\n bytes[it.offset++] = TYPE_ID & 255;\n encode.number(bytes, targetTypeId, it);\n }\n }\n\n get hasChanges() {\n return (\n this.root.changes.length > 0 ||\n this.root.filteredChanges.length > 0\n );\n }\n}\n"]}
|
package/package.json
CHANGED
package/src/encoder/Encoder.ts
CHANGED
|
@@ -22,7 +22,6 @@ export class Encoder<T extends Schema = any> {
|
|
|
22
22
|
root: Root;
|
|
23
23
|
|
|
24
24
|
constructor(state: T) {
|
|
25
|
-
|
|
26
25
|
//
|
|
27
26
|
// TODO: cache and restore "Context" based on root schema
|
|
28
27
|
// (to avoid creating a new context for every new room)
|
|
@@ -60,9 +59,6 @@ export class Encoder<T extends Schema = any> {
|
|
|
60
59
|
for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
|
|
61
60
|
const changeTree = changeTrees[i];
|
|
62
61
|
|
|
63
|
-
// // Root#removeChangeFromChangeSet() is now removing instead of setting to "undefined"
|
|
64
|
-
// if (changeTree === undefined) { continue; }
|
|
65
|
-
|
|
66
62
|
const operations = changeTree[changeSetName];
|
|
67
63
|
const ref = changeTree.ref;
|
|
68
64
|
|
|
@@ -71,13 +67,6 @@ export class Encoder<T extends Schema = any> {
|
|
|
71
67
|
const filter = ctor[$filter];
|
|
72
68
|
const metadata = ctor[Symbol.metadata];
|
|
73
69
|
|
|
74
|
-
// try { throw new Error(); } catch (e) {
|
|
75
|
-
// // only print if not coming from Reflection.ts
|
|
76
|
-
// if (!e.stack.includes("src/Reflection.ts")) {
|
|
77
|
-
// console.log("ChangeTree:", { refId: changeTree.refId, ref: ref.constructor.name });
|
|
78
|
-
// }
|
|
79
|
-
// }
|
|
80
|
-
|
|
81
70
|
if (hasView) {
|
|
82
71
|
if (!view.items.has(changeTree)) {
|
|
83
72
|
view.invisible.add(changeTree);
|
|
@@ -117,28 +106,13 @@ export class Encoder<T extends Schema = any> {
|
|
|
117
106
|
continue;
|
|
118
107
|
}
|
|
119
108
|
|
|
120
|
-
// try { throw new Error(); } catch (e) {
|
|
121
|
-
// // only print if not coming from Reflection.ts
|
|
122
|
-
// if (!e.stack.includes("src/Reflection.ts")) {
|
|
123
|
-
// console.log("WILL ENCODE", {
|
|
124
|
-
// ref: changeTree.ref.constructor.name,
|
|
125
|
-
// fieldIndex,
|
|
126
|
-
// operation: OPERATION[operation],
|
|
127
|
-
// });
|
|
128
|
-
// }
|
|
129
|
-
// }
|
|
130
|
-
|
|
131
|
-
// console.log("encode...", { ref: changeTree.ref.constructor.name, refId: changeTree.refId, fieldIndex, operation });
|
|
132
|
-
|
|
133
109
|
encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView, metadata);
|
|
134
110
|
}
|
|
135
111
|
|
|
136
|
-
if (shouldDiscardChanges) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
changeTree.isNew = false;
|
|
141
|
-
}
|
|
112
|
+
// if (shouldDiscardChanges) {
|
|
113
|
+
// changeTree.discard();
|
|
114
|
+
// changeTree.isNew = false; // Not a new instance anymore
|
|
115
|
+
// }
|
|
142
116
|
}
|
|
143
117
|
|
|
144
118
|
if (it.offset > buffer.byteLength) {
|
|
@@ -152,7 +126,7 @@ export class Encoder<T extends Schema = any> {
|
|
|
152
126
|
//
|
|
153
127
|
// resize buffer and re-encode (TODO: can we avoid re-encoding here?)
|
|
154
128
|
//
|
|
155
|
-
buffer = Buffer.
|
|
129
|
+
buffer = Buffer.alloc(newSize);
|
|
156
130
|
|
|
157
131
|
// assign resized buffer to local sharedBuffer
|
|
158
132
|
if (buffer === this.sharedBuffer) {
|
|
@@ -162,35 +136,31 @@ export class Encoder<T extends Schema = any> {
|
|
|
162
136
|
return this.encode({ offset: initialOffset }, view, buffer, changeSetName, isEncodeAll);
|
|
163
137
|
|
|
164
138
|
} else {
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
139
|
+
//
|
|
140
|
+
// only clear changes after making sure buffer resize is not required.
|
|
141
|
+
//
|
|
142
|
+
if (shouldDiscardChanges) {
|
|
143
|
+
//
|
|
144
|
+
// TODO: avoid iterating over change trees twice.
|
|
145
|
+
//
|
|
146
|
+
for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
|
|
147
|
+
const changeTree = changeTrees[i];
|
|
148
|
+
changeTree.discard();
|
|
149
|
+
changeTree.isNew = false; // Not a new instance anymore
|
|
150
|
+
}
|
|
151
|
+
}
|
|
174
152
|
|
|
175
153
|
return buffer.subarray(0, it.offset);
|
|
176
154
|
}
|
|
177
155
|
}
|
|
178
156
|
|
|
179
157
|
encodeAll(it: Iterator = { offset: 0 }, buffer: Buffer = this.sharedBuffer) {
|
|
180
|
-
// console.log(`\nencodeAll(), this.root.allChanges (${(Object.keys(this.root.allChanges).length)})`);
|
|
181
|
-
// this.debugChanges("allChanges");
|
|
182
|
-
|
|
183
158
|
return this.encode(it, undefined, buffer, "allChanges", true);
|
|
184
159
|
}
|
|
185
160
|
|
|
186
161
|
encodeAllView(view: StateView, sharedOffset: number, it: Iterator, bytes = this.sharedBuffer) {
|
|
187
162
|
const viewOffset = it.offset;
|
|
188
163
|
|
|
189
|
-
// console.log(`\nencodeAllView(), this.root.allFilteredChanges (${(Object.keys(this.root.allFilteredChanges).length)})`);
|
|
190
|
-
// this.debugChanges("allFilteredChanges");
|
|
191
|
-
|
|
192
|
-
// console.log("\n\nENCODE ALL FOR VIEW...\n\n")
|
|
193
|
-
|
|
194
164
|
// try to encode "filtered" changes
|
|
195
165
|
this.encode(it, view, bytes, "allFilteredChanges", true, viewOffset);
|
|
196
166
|
|
|
@@ -224,15 +194,9 @@ export class Encoder<T extends Schema = any> {
|
|
|
224
194
|
encodeView(view: StateView, sharedOffset: number, it: Iterator, bytes = this.sharedBuffer) {
|
|
225
195
|
const viewOffset = it.offset;
|
|
226
196
|
|
|
227
|
-
// console.log(`\nencodeView(), view.changes (${view.changes.size})`);
|
|
228
|
-
// this.debugChanges(view.changes);
|
|
229
|
-
|
|
230
|
-
// console.log(`\nencodeView(), this.root.filteredChanges (${this.root.filteredChanges.size})`);
|
|
231
|
-
// this.debugChanges("filteredChanges");
|
|
232
|
-
|
|
233
197
|
// encode visibility changes (add/remove for this view)
|
|
234
198
|
const refIds = Object.keys(view.changes);
|
|
235
|
-
|
|
199
|
+
|
|
236
200
|
for (let i = 0, numRefIds = refIds.length; i < numRefIds; i++) {
|
|
237
201
|
const refId = refIds[i];
|
|
238
202
|
const changes = view.changes[refId];
|
|
@@ -273,8 +237,6 @@ export class Encoder<T extends Schema = any> {
|
|
|
273
237
|
// clear "view" changes after encoding
|
|
274
238
|
view.changes = {};
|
|
275
239
|
|
|
276
|
-
// console.log("FILTERED CHANGES:", this.root.filteredChanges);
|
|
277
|
-
|
|
278
240
|
// try to encode "filtered" changes
|
|
279
241
|
this.encode(it, view, bytes, "filteredChanges", false, viewOffset);
|
|
280
242
|
|
|
@@ -305,8 +267,6 @@ export class Encoder<T extends Schema = any> {
|
|
|
305
267
|
}
|
|
306
268
|
|
|
307
269
|
discardChanges() {
|
|
308
|
-
// console.log("DISCARD CHANGES!");
|
|
309
|
-
|
|
310
270
|
// discard shared changes
|
|
311
271
|
let length = this.root.changes.length;
|
|
312
272
|
if (length > 0) {
|