@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.
@@ -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
- changeTree.discard();
3866
- // Not a new instance anymore
3867
- changeTree.isNew = false;
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.allocUnsafeSlow(newSize);
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
- // // only clear changes after making sure buffer resize is not required.
3890
- // //
3891
- // if (shouldClearChanges) {
3892
- // //
3893
- // // FIXME: avoid iterating over change trees twice.
3894
- // //
3895
- // this.onEndEncode(changeTrees);
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) {
@@ -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
- changeTree.discard();
101
- // Not a new instance anymore
102
- changeTree.isNew = false;
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.allocUnsafeSlow(newSize);
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
- // // only clear changes after making sure buffer resize is not required.
125
- // //
126
- // if (shouldClearChanges) {
127
- // //
128
- // // FIXME: avoid iterating over change trees twice.
129
- // //
130
- // this.onEndEncode(changeTrees);
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":"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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 // 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colyseus/schema",
3
- "version": "3.0.0-alpha.49",
3
+ "version": "3.0.0-alpha.50",
4
4
  "description": "Binary state serializer with delta encoding for games",
5
5
  "bin": {
6
6
  "schema-codegen": "./bin/schema-codegen",
@@ -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
- changeTree.discard();
138
-
139
- // Not a new instance anymore
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.allocUnsafeSlow(newSize);
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
- // // only clear changes after making sure buffer resize is not required.
167
- // //
168
- // if (shouldClearChanges) {
169
- // //
170
- // // FIXME: avoid iterating over change trees twice.
171
- // //
172
- // this.onEndEncode(changeTrees);
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
- // console.log("ENCODE VIEW:", refIds);
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) {