@colyseus/schema 3.0.0 → 3.0.1
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 +1 -1
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +1 -1
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +1 -1
- package/lib/encoder/Encoder.js +1 -1
- package/lib/encoder/Encoder.js.map +1 -1
- package/package.json +1 -1
- package/src/encoder/Encoder.ts +2 -3
- package/lib/Decoder.d.ts +0 -16
- package/lib/Decoder.js +0 -182
- package/lib/Decoder.js.map +0 -1
- package/lib/Encoder.d.ts +0 -13
- package/lib/Encoder.js +0 -79
- package/lib/Encoder.js.map +0 -1
- package/lib/bench_encode.d.ts +0 -1
- package/lib/bench_encode.js +0 -130
- package/lib/bench_encode.js.map +0 -1
- package/lib/changes/ChangeSet.d.ts +0 -12
- package/lib/changes/ChangeSet.js +0 -35
- package/lib/changes/ChangeSet.js.map +0 -1
- package/lib/changes/ChangeTree.d.ts +0 -53
- package/lib/changes/ChangeTree.js +0 -202
- package/lib/changes/ChangeTree.js.map +0 -1
- package/lib/changes/DecodeOperation.d.ts +0 -15
- package/lib/changes/DecodeOperation.js +0 -186
- package/lib/changes/DecodeOperation.js.map +0 -1
- package/lib/changes/EncodeOperation.d.ts +0 -18
- package/lib/changes/EncodeOperation.js +0 -130
- package/lib/changes/EncodeOperation.js.map +0 -1
- package/lib/changes/ReferenceTracker.d.ts +0 -14
- package/lib/changes/ReferenceTracker.js +0 -83
- package/lib/changes/ReferenceTracker.js.map +0 -1
- package/lib/changes/consts.d.ts +0 -14
- package/lib/changes/consts.js +0 -18
- package/lib/changes/consts.js.map +0 -1
- package/lib/debug.d.ts +0 -1
- package/lib/debug.js +0 -51
- package/lib/debug.js.map +0 -1
- package/lib/decoding/decode.d.ts +0 -48
- package/lib/decoding/decode.js +0 -267
- package/lib/decoding/decode.js.map +0 -1
- package/lib/ecs.d.ts +0 -11
- package/lib/ecs.js +0 -160
- package/lib/ecs.js.map +0 -1
- package/lib/filters/index.d.ts +0 -8
- package/lib/filters/index.js +0 -24
- package/lib/filters/index.js.map +0 -1
- package/lib/spec.d.ts +0 -13
- package/lib/spec.js +0 -42
- package/lib/spec.js.map +0 -1
- package/lib/types/ArraySchema.d.ts +0 -238
- package/lib/types/ArraySchema.js +0 -555
- package/lib/types/ArraySchema.js.map +0 -1
- package/lib/types/CollectionSchema.d.ts +0 -35
- package/lib/types/CollectionSchema.js +0 -150
- package/lib/types/CollectionSchema.js.map +0 -1
- package/lib/types/MapSchema.d.ts +0 -38
- package/lib/types/MapSchema.js +0 -215
- package/lib/types/MapSchema.js.map +0 -1
- package/lib/types/SetSchema.d.ts +0 -32
- package/lib/types/SetSchema.js +0 -162
- package/lib/types/SetSchema.js.map +0 -1
- package/lib/types/typeRegistry.d.ts +0 -5
- package/lib/types/typeRegistry.js +0 -13
- package/lib/types/typeRegistry.js.map +0 -1
- package/lib/usage.d.ts +0 -1
- package/lib/usage.js +0 -22
- package/lib/usage.js.map +0 -1
- package/lib/v3.d.ts +0 -1
- package/lib/v3.js +0 -427
- package/lib/v3.js.map +0 -1
- package/lib/v3_experiment.d.ts +0 -1
- package/lib/v3_experiment.js +0 -407
- package/lib/v3_experiment.js.map +0 -1
- package/src/bench_encode.ts +0 -108
- package/src/debug.ts +0 -55
package/build/umd/index.js
CHANGED
|
@@ -3759,7 +3759,7 @@
|
|
|
3759
3759
|
}
|
|
3760
3760
|
|
|
3761
3761
|
class Encoder {
|
|
3762
|
-
static { this.BUFFER_SIZE = Buffer.poolSize
|
|
3762
|
+
static { this.BUFFER_SIZE = (typeof (Buffer) !== "undefined") && Buffer.poolSize || 8 * 1024; } // 8KB
|
|
3763
3763
|
constructor(state) {
|
|
3764
3764
|
this.sharedBuffer = Buffer.allocUnsafe(Encoder.BUFFER_SIZE);
|
|
3765
3765
|
//
|
package/lib/encoder/Encoder.js
CHANGED
|
@@ -7,7 +7,7 @@ const encode_1 = require("../encoding/encode");
|
|
|
7
7
|
const spec_1 = require("../encoding/spec");
|
|
8
8
|
const Root_1 = require("./Root");
|
|
9
9
|
class Encoder {
|
|
10
|
-
static { this.BUFFER_SIZE = Buffer.poolSize
|
|
10
|
+
static { this.BUFFER_SIZE = (typeof (Buffer) !== "undefined") && Buffer.poolSize || 8 * 1024; } // 8KB
|
|
11
11
|
constructor(state) {
|
|
12
12
|
this.sharedBuffer = Buffer.allocUnsafe(Encoder.BUFFER_SIZE);
|
|
13
13
|
//
|
|
@@ -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 = Buffer.poolSize ?? 8 * 1024; // 8KB\n sharedBuffer = Buffer.allocUnsafe(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 // we can assume that n + 1 poolSize will suffice given that we are likely done with encoding at this point\n // multiples of poolSize are faster to allocate than arbitrary sizes\n // if we are on an older platform that doesn't implement pooling use 8kb as poolSize (that's the default for node)\n const newSize = Math.ceil(it.offset / (Buffer.poolSize ?? 8 * 1024)) * (Buffer.poolSize ?? 8 * 1024); \n\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 // -> No we probably can't unless we catch the need for resize before encoding which is likely more computationally expensive than resizing on demand\n //\n buffer = Buffer.alloc(newSize, buffer); // fill with buffer here to memcpy previous encoding steps beyond the initialOffset\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"]}
|
|
1
|
+
{"version":3,"file":"Encoder.js","sourceRoot":"","sources":["../../src/encoder/Encoder.ts"],"names":[],"mappings":";;;AACA,sDAAmD;AACnD,8CAA6E;AAE7E,+CAA4C;AAG5C,2CAA2E;AAC3E,iCAA8B;AAK9B,MAAa,OAAO;aACT,gBAAW,GAAG,CAAC,OAAM,CAAC,MAAM,CAAC,KAAK,WAAW,CAAC,IAAI,MAAM,CAAC,QAAQ,IAAI,CAAC,GAAG,IAAI,AAAlE,CAAmE,GAAC,MAAM;IAQ5F,YAAY,KAAQ;QAPpB,iBAAY,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAQnD,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,2GAA2G;YAC3G,oEAAoE;YACpE,kHAAkH;YAClH,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;YAErG,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,qJAAqJ;YACrJ,EAAE;YACF,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,mFAAmF;YAE3H,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;;AA3SL,0BA4SC","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\";\n\nimport type { StateView } from \"./StateView\";\nimport type { Metadata } from \"../Metadata\";\n\nexport class Encoder<T extends Schema = any> {\n static BUFFER_SIZE = (typeof(Buffer) !== \"undefined\") && Buffer.poolSize || 8 * 1024; // 8KB\n sharedBuffer = Buffer.allocUnsafe(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 // we can assume that n + 1 poolSize will suffice given that we are likely done with encoding at this point\n // multiples of poolSize are faster to allocate than arbitrary sizes\n // if we are on an older platform that doesn't implement pooling use 8kb as poolSize (that's the default for node)\n const newSize = Math.ceil(it.offset / (Buffer.poolSize ?? 8 * 1024)) * (Buffer.poolSize ?? 8 * 1024);\n\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 // -> No we probably can't unless we catch the need for resize before encoding which is likely more computationally expensive than resizing on demand\n //\n buffer = Buffer.alloc(newSize, buffer); // fill with buffer here to memcpy previous encoding steps beyond the initialOffset\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
|
@@ -7,13 +7,12 @@ import type { Iterator } from "../encoding/decode";
|
|
|
7
7
|
|
|
8
8
|
import { OPERATION, SWITCH_TO_STRUCTURE, TYPE_ID } from '../encoding/spec';
|
|
9
9
|
import { Root } from "./Root";
|
|
10
|
-
import { getNextPowerOf2 } from "../utils";
|
|
11
10
|
|
|
12
11
|
import type { StateView } from "./StateView";
|
|
13
12
|
import type { Metadata } from "../Metadata";
|
|
14
13
|
|
|
15
14
|
export class Encoder<T extends Schema = any> {
|
|
16
|
-
static BUFFER_SIZE = Buffer.poolSize
|
|
15
|
+
static BUFFER_SIZE = (typeof(Buffer) !== "undefined") && Buffer.poolSize || 8 * 1024; // 8KB
|
|
17
16
|
sharedBuffer = Buffer.allocUnsafe(Encoder.BUFFER_SIZE);
|
|
18
17
|
|
|
19
18
|
context: TypeContext;
|
|
@@ -119,7 +118,7 @@ export class Encoder<T extends Schema = any> {
|
|
|
119
118
|
// we can assume that n + 1 poolSize will suffice given that we are likely done with encoding at this point
|
|
120
119
|
// multiples of poolSize are faster to allocate than arbitrary sizes
|
|
121
120
|
// if we are on an older platform that doesn't implement pooling use 8kb as poolSize (that's the default for node)
|
|
122
|
-
const newSize = Math.ceil(it.offset / (Buffer.poolSize ?? 8 * 1024)) * (Buffer.poolSize ?? 8 * 1024);
|
|
121
|
+
const newSize = Math.ceil(it.offset / (Buffer.poolSize ?? 8 * 1024)) * (Buffer.poolSize ?? 8 * 1024);
|
|
123
122
|
|
|
124
123
|
console.warn(`@colyseus/schema buffer overflow. Encoded state is higher than default BUFFER_SIZE. Use the following to increase default BUFFER_SIZE:
|
|
125
124
|
|
package/lib/Decoder.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { TypeContext } from "./annotations";
|
|
2
|
-
import { DataChange, Schema } from "./Schema";
|
|
3
|
-
import { Ref } from "./changes/ChangeTree";
|
|
4
|
-
import { Iterator } from "./encoding/decode";
|
|
5
|
-
import { ReferenceTracker } from "./changes/ReferenceTracker";
|
|
6
|
-
export declare class Decoder<T extends Schema = any> {
|
|
7
|
-
context: TypeContext;
|
|
8
|
-
root: T;
|
|
9
|
-
refs: ReferenceTracker;
|
|
10
|
-
currentRefId: number;
|
|
11
|
-
constructor(root: T, context?: TypeContext);
|
|
12
|
-
protected setRoot(root: T): void;
|
|
13
|
-
decode(bytes: number[], it?: Iterator, ref?: Ref): DataChange<any, string>[];
|
|
14
|
-
getInstanceType(bytes: number[], it: Iterator, defaultType: typeof Schema): typeof Schema;
|
|
15
|
-
createInstanceOfType(type: typeof Schema): Schema;
|
|
16
|
-
}
|
package/lib/Decoder.js
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Decoder = void 0;
|
|
4
|
-
const annotations_1 = require("./annotations");
|
|
5
|
-
const consts_1 = require("./changes/consts");
|
|
6
|
-
const decode = require("./encoding/decode");
|
|
7
|
-
const spec_1 = require("./spec");
|
|
8
|
-
const ReferenceTracker_1 = require("./changes/ReferenceTracker");
|
|
9
|
-
const DecodeOperation_1 = require("./changes/DecodeOperation");
|
|
10
|
-
class Decoder {
|
|
11
|
-
constructor(root, context) {
|
|
12
|
-
this.currentRefId = 0;
|
|
13
|
-
this.setRoot(root);
|
|
14
|
-
this.context = context || new annotations_1.TypeContext(root.constructor);
|
|
15
|
-
// console.log(">>>>>>>>>>>>>>>> Decoder types");
|
|
16
|
-
// this.context.schemas.forEach((id, schema) => {
|
|
17
|
-
// console.log("type:", id, schema.name, Object.keys(schema[Symbol.metadata]));
|
|
18
|
-
// });
|
|
19
|
-
}
|
|
20
|
-
setRoot(root) {
|
|
21
|
-
this.root = root;
|
|
22
|
-
this.refs = new ReferenceTracker_1.ReferenceTracker();
|
|
23
|
-
this.refs.addRef(0, root);
|
|
24
|
-
}
|
|
25
|
-
decode(bytes, it = { offset: 0 }, ref = this.root) {
|
|
26
|
-
// console.log("------------------- DECODE -------------------");
|
|
27
|
-
const allChanges = [];
|
|
28
|
-
const $root = this.refs;
|
|
29
|
-
const totalBytes = bytes.length;
|
|
30
|
-
this.currentRefId = 0;
|
|
31
|
-
while (it.offset < totalBytes) {
|
|
32
|
-
//
|
|
33
|
-
// Peek ahead, check if it's a switch to a different structure
|
|
34
|
-
//
|
|
35
|
-
if (bytes[it.offset] == spec_1.SWITCH_TO_STRUCTURE) {
|
|
36
|
-
it.offset++;
|
|
37
|
-
this.currentRefId = decode.number(bytes, it);
|
|
38
|
-
const nextRef = $root.refs.get(this.currentRefId);
|
|
39
|
-
//
|
|
40
|
-
// Trying to access a reference that haven't been decoded yet.
|
|
41
|
-
//
|
|
42
|
-
if (!nextRef) {
|
|
43
|
-
throw new Error(`"refId" not found: ${this.currentRefId}`);
|
|
44
|
-
}
|
|
45
|
-
ref = nextRef;
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
const decoder = ref['constructor'][consts_1.$decoder];
|
|
49
|
-
const result = decoder(this, bytes, it, ref, allChanges);
|
|
50
|
-
if (result === DecodeOperation_1.DecodeState.DEFINITION_MISMATCH) {
|
|
51
|
-
console.warn("@colyseus/schema: definition mismatch");
|
|
52
|
-
//
|
|
53
|
-
// keep skipping next bytes until reaches a known structure
|
|
54
|
-
// by local decoder.
|
|
55
|
-
//
|
|
56
|
-
const nextIterator = { offset: it.offset };
|
|
57
|
-
while (it.offset < totalBytes) {
|
|
58
|
-
if (decode.switchStructureCheck(bytes, it)) {
|
|
59
|
-
nextIterator.offset = it.offset + 1;
|
|
60
|
-
if ($root.refs.has(decode.number(bytes, nextIterator))) {
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
it.offset++;
|
|
65
|
-
}
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
// FIXME: trigger callbacks
|
|
70
|
-
// this._triggerChanges(allChanges);
|
|
71
|
-
// drop references of unused schemas
|
|
72
|
-
$root.garbageCollectDeletedRefs();
|
|
73
|
-
return allChanges;
|
|
74
|
-
}
|
|
75
|
-
/*
|
|
76
|
-
private _triggerChanges(changes: DataChange[]) {
|
|
77
|
-
const uniqueRefIds = new Set<number>();
|
|
78
|
-
const $refs = this.refs.refs;
|
|
79
|
-
|
|
80
|
-
for (let i = 0; i < changes.length; i++) {
|
|
81
|
-
const change = changes[i];
|
|
82
|
-
const refId = change.refId;
|
|
83
|
-
const ref = $refs.get(refId);
|
|
84
|
-
const $callbacks: Schema['$callbacks'] | SchemaDecoderCallbacks['$callbacks'] = ref['$callbacks'];
|
|
85
|
-
|
|
86
|
-
//
|
|
87
|
-
// trigger onRemove on child structure.
|
|
88
|
-
//
|
|
89
|
-
if (
|
|
90
|
-
(change.op & OPERATION.DELETE) === OPERATION.DELETE &&
|
|
91
|
-
change.previousValue instanceof Schema
|
|
92
|
-
) {
|
|
93
|
-
change.previousValue['$callbacks']?.[OPERATION.DELETE]?.forEach(callback => callback());
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// no callbacks defined, skip this structure!
|
|
97
|
-
if (!$callbacks) { continue; }
|
|
98
|
-
|
|
99
|
-
if (ref instanceof Schema) {
|
|
100
|
-
if (!uniqueRefIds.has(refId)) {
|
|
101
|
-
try {
|
|
102
|
-
// trigger onChange
|
|
103
|
-
($callbacks as Schema['$callbacks'])?.[OPERATION.REPLACE]?.forEach(callback =>
|
|
104
|
-
callback());
|
|
105
|
-
|
|
106
|
-
} catch (e) {
|
|
107
|
-
Schema.onError(e);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
if ($callbacks.hasOwnProperty(change.field)) {
|
|
113
|
-
$callbacks[change.field]?.forEach((callback) =>
|
|
114
|
-
callback(change.value, change.previousValue));
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
} catch (e) {
|
|
118
|
-
Schema.onError(e);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
} else {
|
|
122
|
-
// is a collection of items
|
|
123
|
-
|
|
124
|
-
if (change.op === OPERATION.ADD && change.previousValue === undefined) {
|
|
125
|
-
// triger onAdd
|
|
126
|
-
$callbacks[OPERATION.ADD]?.forEach(callback =>
|
|
127
|
-
callback(change.value, change.dynamicIndex ?? change.field));
|
|
128
|
-
|
|
129
|
-
} else if (change.op === OPERATION.DELETE) {
|
|
130
|
-
//
|
|
131
|
-
// FIXME: `previousValue` should always be available.
|
|
132
|
-
// ADD + DELETE operations are still encoding DELETE operation.
|
|
133
|
-
//
|
|
134
|
-
if (change.previousValue !== undefined) {
|
|
135
|
-
// triger onRemove
|
|
136
|
-
$callbacks[OPERATION.DELETE]?.forEach(callback =>
|
|
137
|
-
callback(change.previousValue, change.dynamicIndex ?? change.field));
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
} else if (change.op === OPERATION.DELETE_AND_ADD) {
|
|
141
|
-
// triger onRemove
|
|
142
|
-
if (change.previousValue !== undefined) {
|
|
143
|
-
$callbacks[OPERATION.DELETE]?.forEach(callback =>
|
|
144
|
-
callback(change.previousValue, change.dynamicIndex ?? change.field));
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// triger onAdd
|
|
148
|
-
$callbacks[OPERATION.ADD]?.forEach(callback =>
|
|
149
|
-
callback(change.value, change.dynamicIndex ?? change.field));
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// trigger onChange
|
|
153
|
-
if (change.value !== change.previousValue) {
|
|
154
|
-
$callbacks[OPERATION.REPLACE]?.forEach(callback =>
|
|
155
|
-
callback(change.value, change.dynamicIndex ?? change.field));
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
uniqueRefIds.add(refId);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
*/
|
|
164
|
-
getInstanceType(bytes, it, defaultType) {
|
|
165
|
-
let type;
|
|
166
|
-
if (bytes[it.offset] === spec_1.TYPE_ID) {
|
|
167
|
-
it.offset++;
|
|
168
|
-
const type_id = decode.number(bytes, it);
|
|
169
|
-
type = this.context.get(type_id);
|
|
170
|
-
}
|
|
171
|
-
return type || defaultType;
|
|
172
|
-
}
|
|
173
|
-
createInstanceOfType(type) {
|
|
174
|
-
// let instance: Schema = new (type as any)();
|
|
175
|
-
// // assign root on $changes
|
|
176
|
-
// instance[$changes].root = this.root[$changes].root;
|
|
177
|
-
// return instance;
|
|
178
|
-
return new type();
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
exports.Decoder = Decoder;
|
|
182
|
-
//# sourceMappingURL=Decoder.js.map
|
package/lib/Decoder.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Decoder.js","sourceRoot":"","sources":["../src/Decoder.ts"],"names":[],"mappings":"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","sourcesContent":["import { Metadata } from \"./Metadata\";\nimport { TypeContext } from \"./annotations\";\nimport { $childType, $decoder } from \"./changes/consts\";\nimport { DataChange, Schema, SchemaDecoderCallbacks } from \"./Schema\";\nimport { CollectionSchema } from \"./types/CollectionSchema\";\nimport { MapSchema } from \"./types/MapSchema\";\nimport { SetSchema } from \"./types/SetSchema\";\nimport { ArraySchema } from \"./types/ArraySchema\";\n\nimport * as decode from \"./encoding/decode\";\nimport { getType } from './types/typeRegistry';\nimport { SWITCH_TO_STRUCTURE, TYPE_ID, OPERATION } from './spec';\nimport { Ref } from \"./changes/ChangeTree\";\nimport { Iterator } from \"./encoding/decode\";\nimport { ReferenceTracker } from \"./changes/ReferenceTracker\";\nimport { DecodeState } from \"./changes/DecodeOperation\";\n\nexport class Decoder<T extends Schema = any> {\n context: TypeContext;\n\n root: T;\n refs: ReferenceTracker;\n\n currentRefId: number = 0;\n\n constructor(root: T, context?: TypeContext) {\n this.setRoot(root);\n this.context = context || new TypeContext(root.constructor as typeof Schema);\n\n // console.log(\">>>>>>>>>>>>>>>> Decoder 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 setRoot(root: T) {\n this.root = root;\n this.refs = new ReferenceTracker();\n this.refs.addRef(0, root);\n }\n\n decode(\n bytes: number[],\n it: Iterator = { offset: 0 },\n ref: Ref = this.root,\n ) {\n // console.log(\"------------------- DECODE -------------------\");\n const allChanges: DataChange[] = [];\n\n const $root = this.refs;\n const totalBytes = bytes.length;\n\n this.currentRefId = 0;\n\n while (it.offset < totalBytes) {\n //\n // Peek ahead, check if it's a switch to a different structure\n //\n if (bytes[it.offset] == SWITCH_TO_STRUCTURE) {\n it.offset++;\n\n this.currentRefId = decode.number(bytes, it);\n const nextRef = $root.refs.get(this.currentRefId) as Schema;\n\n //\n // Trying to access a reference that haven't been decoded yet.\n //\n if (!nextRef) { throw new Error(`\"refId\" not found: ${this.currentRefId}`); }\n ref = nextRef;\n\n continue;\n }\n\n const decoder = ref['constructor'][$decoder];\n const result = decoder(this, bytes, it, ref, allChanges);\n\n if (result === DecodeState.DEFINITION_MISMATCH) {\n console.warn(\"@colyseus/schema: definition mismatch\");\n\n //\n // keep skipping next bytes until reaches a known structure\n // by local decoder.\n //\n const nextIterator: decode.Iterator = { offset: it.offset };\n while (it.offset < totalBytes) {\n if (decode.switchStructureCheck(bytes, it)) {\n nextIterator.offset = it.offset + 1;\n if ($root.refs.has(decode.number(bytes, nextIterator))) {\n break;\n }\n }\n\n it.offset++;\n }\n continue;\n }\n }\n\n // FIXME: trigger callbacks\n // this._triggerChanges(allChanges);\n\n // drop references of unused schemas\n $root.garbageCollectDeletedRefs();\n\n return allChanges;\n }\n\n /*\n private _triggerChanges(changes: DataChange[]) {\n const uniqueRefIds = new Set<number>();\n const $refs = this.refs.refs;\n\n for (let i = 0; i < changes.length; i++) {\n const change = changes[i];\n const refId = change.refId;\n const ref = $refs.get(refId);\n const $callbacks: Schema['$callbacks'] | SchemaDecoderCallbacks['$callbacks'] = ref['$callbacks'];\n\n //\n // trigger onRemove on child structure.\n //\n if (\n (change.op & OPERATION.DELETE) === OPERATION.DELETE &&\n change.previousValue instanceof Schema\n ) {\n change.previousValue['$callbacks']?.[OPERATION.DELETE]?.forEach(callback => callback());\n }\n\n // no callbacks defined, skip this structure!\n if (!$callbacks) { continue; }\n\n if (ref instanceof Schema) {\n if (!uniqueRefIds.has(refId)) {\n try {\n // trigger onChange\n ($callbacks as Schema['$callbacks'])?.[OPERATION.REPLACE]?.forEach(callback =>\n callback());\n\n } catch (e) {\n Schema.onError(e);\n }\n }\n\n try {\n if ($callbacks.hasOwnProperty(change.field)) {\n $callbacks[change.field]?.forEach((callback) =>\n callback(change.value, change.previousValue));\n }\n\n } catch (e) {\n Schema.onError(e);\n }\n\n } else {\n // is a collection of items\n\n if (change.op === OPERATION.ADD && change.previousValue === undefined) {\n // triger onAdd\n $callbacks[OPERATION.ADD]?.forEach(callback =>\n callback(change.value, change.dynamicIndex ?? change.field));\n\n } else if (change.op === OPERATION.DELETE) {\n //\n // FIXME: `previousValue` should always be available.\n // ADD + DELETE operations are still encoding DELETE operation.\n //\n if (change.previousValue !== undefined) {\n // triger onRemove\n $callbacks[OPERATION.DELETE]?.forEach(callback =>\n callback(change.previousValue, change.dynamicIndex ?? change.field));\n }\n\n } else if (change.op === OPERATION.DELETE_AND_ADD) {\n // triger onRemove\n if (change.previousValue !== undefined) {\n $callbacks[OPERATION.DELETE]?.forEach(callback =>\n callback(change.previousValue, change.dynamicIndex ?? change.field));\n }\n\n // triger onAdd\n $callbacks[OPERATION.ADD]?.forEach(callback =>\n callback(change.value, change.dynamicIndex ?? change.field));\n }\n\n // trigger onChange\n if (change.value !== change.previousValue) {\n $callbacks[OPERATION.REPLACE]?.forEach(callback =>\n callback(change.value, change.dynamicIndex ?? change.field));\n }\n }\n\n uniqueRefIds.add(refId);\n }\n\n }\n */\n\n getInstanceType(bytes: number[], it: Iterator, defaultType: typeof Schema): typeof Schema {\n let type: typeof Schema;\n\n if (bytes[it.offset] === TYPE_ID) {\n it.offset++;\n const type_id = decode.number(bytes, it);\n type = this.context.get(type_id);\n }\n\n return type || defaultType;\n }\n\n createInstanceOfType (type: typeof Schema): Schema {\n // let instance: Schema = new (type as any)();\n\n // // assign root on $changes\n // instance[$changes].root = this.root[$changes].root;\n\n // return instance;\n return new (type as any)();\n }\n\n}\n\n"]}
|
package/lib/Encoder.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { Schema } from "./Schema";
|
|
2
|
-
import { TypeContext } from "./annotations";
|
|
3
|
-
import { Root } from "./changes/ChangeTree";
|
|
4
|
-
export declare class Encoder<T extends Schema = any> {
|
|
5
|
-
context: TypeContext;
|
|
6
|
-
root: T;
|
|
7
|
-
$root: Root;
|
|
8
|
-
constructor(root: T);
|
|
9
|
-
protected setRoot(root: T): void;
|
|
10
|
-
encode(encodeAll?: boolean, bytes?: number[], useFilters?: boolean): number[];
|
|
11
|
-
encodeAll(useFilters?: boolean): number[];
|
|
12
|
-
tryEncodeTypeId(bytes: number[], baseType: typeof Schema, targetType: typeof Schema): void;
|
|
13
|
-
}
|
package/lib/Encoder.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Encoder = void 0;
|
|
4
|
-
const annotations_1 = require("./annotations");
|
|
5
|
-
const consts_1 = require("./changes/consts");
|
|
6
|
-
const encode = require("./encoding/encode");
|
|
7
|
-
const spec_1 = require("./spec");
|
|
8
|
-
const ChangeTree_1 = require("./changes/ChangeTree");
|
|
9
|
-
class Encoder {
|
|
10
|
-
constructor(root) {
|
|
11
|
-
this.setRoot(root);
|
|
12
|
-
//
|
|
13
|
-
// TODO: cache and restore "Context" based on root schema
|
|
14
|
-
// (to avoid creating a new context for each new room)
|
|
15
|
-
//
|
|
16
|
-
this.context = new annotations_1.TypeContext(root.constructor);
|
|
17
|
-
// console.log(">>>>>>>>>>>>>>>> Encoder types");
|
|
18
|
-
// this.context.schemas.forEach((id, schema) => {
|
|
19
|
-
// console.log("type:", id, schema.name, Object.keys(schema[Symbol.metadata]));
|
|
20
|
-
// });
|
|
21
|
-
}
|
|
22
|
-
setRoot(root) {
|
|
23
|
-
this.$root = new ChangeTree_1.Root();
|
|
24
|
-
this.root = root;
|
|
25
|
-
root[consts_1.$changes].setRoot(this.$root);
|
|
26
|
-
}
|
|
27
|
-
encode(encodeAll = false, bytes = [], useFilters = false) {
|
|
28
|
-
const rootChangeTree = this.root[consts_1.$changes];
|
|
29
|
-
// const changeTrees: ChangeTracker[] = Array.from(this.$root['currentQueue']);
|
|
30
|
-
const changeTrees = this.$root.changes;
|
|
31
|
-
const numChangeTrees = changeTrees.length;
|
|
32
|
-
// let numChangeTrees = 1;
|
|
33
|
-
// console.log("--------------------- ENCODE ----------------");
|
|
34
|
-
// console.log("Encode order:", changeTrees.map((c) => c.ref['constructor'].name));
|
|
35
|
-
for (let i = 0; i < numChangeTrees; i++) {
|
|
36
|
-
const changeTree = changeTrees[i];
|
|
37
|
-
const ref = changeTree.ref;
|
|
38
|
-
// Generate unique refId for the ChangeTree.
|
|
39
|
-
changeTree.ensureRefId();
|
|
40
|
-
// root `refId` is skipped.
|
|
41
|
-
if (changeTree !== rootChangeTree &&
|
|
42
|
-
(changeTree.changed || encodeAll)) {
|
|
43
|
-
encode.uint8(bytes, spec_1.SWITCH_TO_STRUCTURE);
|
|
44
|
-
encode.number(bytes, changeTree.refId);
|
|
45
|
-
}
|
|
46
|
-
const changes = (encodeAll)
|
|
47
|
-
? changeTree.allChanges.values()
|
|
48
|
-
: changeTree.changes.values();
|
|
49
|
-
let change;
|
|
50
|
-
while (!(change = changes.next()).done) {
|
|
51
|
-
const operation = (encodeAll)
|
|
52
|
-
? spec_1.OPERATION.ADD
|
|
53
|
-
: change.value.op;
|
|
54
|
-
const fieldIndex = (encodeAll)
|
|
55
|
-
? change.value
|
|
56
|
-
: change.value.index;
|
|
57
|
-
const encoder = ref['constructor'][consts_1.$encoder];
|
|
58
|
-
encoder(this, bytes, changeTree, fieldIndex, operation);
|
|
59
|
-
}
|
|
60
|
-
if (!encodeAll && !useFilters) {
|
|
61
|
-
changeTree.discard();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return bytes;
|
|
65
|
-
}
|
|
66
|
-
encodeAll(useFilters) {
|
|
67
|
-
return this.encode(true, [], useFilters);
|
|
68
|
-
}
|
|
69
|
-
tryEncodeTypeId(bytes, baseType, targetType) {
|
|
70
|
-
const baseTypeId = this.context.getTypeId(baseType);
|
|
71
|
-
const targetTypeId = this.context.getTypeId(targetType);
|
|
72
|
-
if (baseTypeId !== targetTypeId) {
|
|
73
|
-
encode.uint8(bytes, spec_1.TYPE_ID);
|
|
74
|
-
encode.number(bytes, targetTypeId);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
exports.Encoder = Encoder;
|
|
79
|
-
//# sourceMappingURL=Encoder.js.map
|
package/lib/Encoder.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Encoder.js","sourceRoot":"","sources":["../src/Encoder.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Schema } from \"./Schema\";\nimport { TypeContext } from \"./annotations\";\nimport { $changes, $encoder } from \"./changes/consts\";\n\nimport * as encode from \"./encoding/encode\";\nimport { SWITCH_TO_STRUCTURE, TYPE_ID, OPERATION } from './spec';\nimport { ChangeOperation, ChangeTracker, Root } from \"./changes/ChangeTree\";\nimport { encodeKeyValueOperation, encodeSchemaOperation } from \"./changes/EncodeOperation\";\n\nexport class Encoder<T extends Schema = any> {\n context: TypeContext;\n\n root: T;\n $root: Root;\n\n constructor(root: T) {\n this.setRoot(root);\n\n //\n // TODO: cache and restore \"Context\" based on root schema\n // (to avoid creating a new context for each new room)\n //\n this.context = new TypeContext(root.constructor as typeof Schema);\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 setRoot(root: T) {\n this.$root = new Root();\n this.root = root;\n root[$changes].setRoot(this.$root);\n }\n\n encode(\n encodeAll = false,\n bytes: number[] = [],\n useFilters: boolean = false,\n ) {\n const rootChangeTree = this.root[$changes];\n\n // const changeTrees: ChangeTracker[] = Array.from(this.$root['currentQueue']);\n const changeTrees: ChangeTracker[] = this.$root.changes;\n const numChangeTrees = changeTrees.length;\n // let numChangeTrees = 1;\n\n // console.log(\"--------------------- ENCODE ----------------\");\n // console.log(\"Encode order:\", changeTrees.map((c) => c.ref['constructor'].name));\n for (let i = 0; i < numChangeTrees; i++) {\n const changeTree = changeTrees[i];\n const ref = changeTree.ref;\n\n // Generate unique refId for the ChangeTree.\n changeTree.ensureRefId();\n\n // root `refId` is skipped.\n if (\n changeTree !== rootChangeTree &&\n (changeTree.changed || encodeAll)\n ) {\n encode.uint8(bytes, SWITCH_TO_STRUCTURE);\n encode.number(bytes, changeTree.refId);\n }\n\n const changes: IterableIterator<ChangeOperation | number> = (encodeAll)\n ? changeTree.allChanges.values()\n : changeTree.changes.values();\n\n let change: IteratorResult<ChangeOperation | number>;\n while (!(change = changes.next()).done) {\n const operation = (encodeAll)\n ? OPERATION.ADD\n : change.value.op;\n\n const fieldIndex = (encodeAll)\n ? change.value\n : change.value.index;\n\n const encoder = ref['constructor'][$encoder];\n encoder(this, bytes, changeTree, fieldIndex, operation);\n }\n\n if (!encodeAll && !useFilters) {\n changeTree.discard();\n }\n }\n\n return bytes;\n }\n\n encodeAll (useFilters?: boolean) {\n return this.encode(true, [], useFilters);\n }\n\n tryEncodeTypeId (bytes: number[], baseType: typeof Schema, targetType: typeof Schema) {\n const baseTypeId = this.context.getTypeId(baseType);\n const targetTypeId = this.context.getTypeId(targetType);\n\n if (baseTypeId !== targetTypeId) {\n encode.uint8(bytes, TYPE_ID);\n encode.number(bytes, targetTypeId);\n }\n }\n\n}"]}
|
package/lib/bench_encode.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/lib/bench_encode.js
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
const nanoid_1 = require("nanoid");
|
|
10
|
-
const _1 = require(".");
|
|
11
|
-
class Attribute extends _1.Schema {
|
|
12
|
-
}
|
|
13
|
-
__decorate([
|
|
14
|
-
(0, _1.type)("string")
|
|
15
|
-
], Attribute.prototype, "name", void 0);
|
|
16
|
-
__decorate([
|
|
17
|
-
(0, _1.type)("number")
|
|
18
|
-
], Attribute.prototype, "value", void 0);
|
|
19
|
-
class Item extends _1.Schema {
|
|
20
|
-
constructor() {
|
|
21
|
-
super(...arguments);
|
|
22
|
-
this.attributes = new _1.ArraySchema();
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
__decorate([
|
|
26
|
-
(0, _1.type)("number")
|
|
27
|
-
], Item.prototype, "price", void 0);
|
|
28
|
-
__decorate([
|
|
29
|
-
(0, _1.type)([Attribute])
|
|
30
|
-
], Item.prototype, "attributes", void 0);
|
|
31
|
-
class Position extends _1.Schema {
|
|
32
|
-
}
|
|
33
|
-
__decorate([
|
|
34
|
-
(0, _1.type)("number")
|
|
35
|
-
], Position.prototype, "x", void 0);
|
|
36
|
-
__decorate([
|
|
37
|
-
(0, _1.type)("number")
|
|
38
|
-
], Position.prototype, "y", void 0);
|
|
39
|
-
class Player extends _1.Schema {
|
|
40
|
-
constructor() {
|
|
41
|
-
super(...arguments);
|
|
42
|
-
this.position = new Position();
|
|
43
|
-
this.items = new _1.MapSchema();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
__decorate([
|
|
47
|
-
(0, _1.type)(Position)
|
|
48
|
-
], Player.prototype, "position", void 0);
|
|
49
|
-
__decorate([
|
|
50
|
-
(0, _1.type)({ map: Item })
|
|
51
|
-
], Player.prototype, "items", void 0);
|
|
52
|
-
class State extends _1.Schema {
|
|
53
|
-
constructor() {
|
|
54
|
-
super(...arguments);
|
|
55
|
-
this.players = new _1.MapSchema();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
__decorate([
|
|
59
|
-
(0, _1.type)({ map: Player })
|
|
60
|
-
], State.prototype, "players", void 0);
|
|
61
|
-
__decorate([
|
|
62
|
-
(0, _1.type)("string")
|
|
63
|
-
], State.prototype, "currentTurn", void 0);
|
|
64
|
-
const state = new State();
|
|
65
|
-
_1.Encoder.BUFFER_SIZE = 4096 * 4096;
|
|
66
|
-
const encoder = new _1.Encoder(state);
|
|
67
|
-
let now = Date.now();
|
|
68
|
-
// for (let i = 0; i < 10000; i++) {
|
|
69
|
-
// const player = new Player();
|
|
70
|
-
// state.players.set(`p-${nanoid()}`, player);
|
|
71
|
-
//
|
|
72
|
-
// player.position.x = (i + 1) * 100;
|
|
73
|
-
// player.position.y = (i + 1) * 100;
|
|
74
|
-
// for (let j = 0; j < 10; j++) {
|
|
75
|
-
// const item = new Item();
|
|
76
|
-
// player.items.set(`item-${j}`, item);
|
|
77
|
-
// item.price = (i + 1) * 50;
|
|
78
|
-
// for (let k = 0; k < 5; k++) {
|
|
79
|
-
// const attr = new Attribute();
|
|
80
|
-
// attr.name = `Attribute ${k}`;
|
|
81
|
-
// attr.value = k;
|
|
82
|
-
// item.attributes.push(attr);
|
|
83
|
-
// }
|
|
84
|
-
// }
|
|
85
|
-
// }
|
|
86
|
-
// console.log("time to make changes:", Date.now() - now);
|
|
87
|
-
// measure time to .encodeAll()
|
|
88
|
-
now = Date.now();
|
|
89
|
-
// for (let i = 0; i < 1000; i++) {
|
|
90
|
-
// encoder.encodeAll();
|
|
91
|
-
// }
|
|
92
|
-
// console.log(Date.now() - now);
|
|
93
|
-
const total = 100;
|
|
94
|
-
const allEncodes = Date.now();
|
|
95
|
-
let avgTimeToEncode = 0;
|
|
96
|
-
let avgTimeToMakeChanges = 0;
|
|
97
|
-
for (let i = 0; i < total; i++) {
|
|
98
|
-
now = Date.now();
|
|
99
|
-
for (let j = 0; j < 50; j++) {
|
|
100
|
-
const player = new Player();
|
|
101
|
-
state.players.set(`p-${(0, nanoid_1.nanoid)()}`, player);
|
|
102
|
-
player.position.x = (j + 1) * 100;
|
|
103
|
-
player.position.y = (j + 1) * 100;
|
|
104
|
-
for (let k = 0; k < 10; k++) {
|
|
105
|
-
const item = new Item();
|
|
106
|
-
item.price = (j + 1) * 50;
|
|
107
|
-
for (let l = 0; l < 5; l++) {
|
|
108
|
-
const attr = new Attribute();
|
|
109
|
-
attr.name = `Attribute ${l}`;
|
|
110
|
-
attr.value = l;
|
|
111
|
-
item.attributes.push(attr);
|
|
112
|
-
}
|
|
113
|
-
player.items.set(`item-${k}`, item);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
const timeToMakeChanges = Date.now() - now;
|
|
117
|
-
console.log("time to make changes:", timeToMakeChanges);
|
|
118
|
-
avgTimeToMakeChanges += timeToMakeChanges;
|
|
119
|
-
now = Date.now();
|
|
120
|
-
encoder.encode();
|
|
121
|
-
encoder.discardChanges();
|
|
122
|
-
const timeToEncode = Date.now() - now;
|
|
123
|
-
console.log("time to encode:", timeToEncode);
|
|
124
|
-
avgTimeToEncode += timeToEncode;
|
|
125
|
-
}
|
|
126
|
-
console.log("avg time to encode:", (avgTimeToEncode) / total);
|
|
127
|
-
console.log("avg time to make changes:", (avgTimeToMakeChanges) / total);
|
|
128
|
-
console.log("time for all encodes:", Date.now() - allEncodes);
|
|
129
|
-
console.log(Array.from(encoder.encodeAll()).length, "bytes");
|
|
130
|
-
//# sourceMappingURL=bench_encode.js.map
|