diff --git a/src/core/packet/proto/NapProto.ts b/src/core/packet/proto/NapProto.ts index 7a42b22f..06593487 100644 --- a/src/core/packet/proto/NapProto.ts +++ b/src/core/packet/proto/NapProto.ts @@ -91,15 +91,12 @@ export type NapProtoEncodeStructType = NapProtoStructType; export type NapProtoDecodeStructType = NapProtoStructType; -const NapProtoMsgCache = new Map>>(); - -export class NapProtoMsg { - private readonly _msg: T; +class NapProtoRealMsg { private readonly _field: PartialFieldInfo[]; private readonly _proto_msg: MessageType>; + private static cache = new WeakMap>(); - constructor(fields: T) { - this._msg = fields; + private constructor(fields: T) { this._field = Object.keys(fields).map(key => { const field = fields[key]; if (field.kind === 'scalar') { @@ -122,13 +119,22 @@ export class NapProtoMsg { name: key, kind: 'message', repeat: field.repeat ? RepeatType.PACKED : RepeatType.NO, - T: () => new NapProtoMsg(field.type())._proto_msg, + T: () => NapProtoRealMsg.getInstance(field.type())._proto_msg, }; } }) as PartialFieldInfo[]; this._proto_msg = new MessageType>('nya', this._field); } + static getInstance(fields: T): NapProtoRealMsg { + let instance = this.cache.get(fields); + if (!instance) { + instance = new NapProtoRealMsg(fields); + this.cache.set(fields, instance); + } + return instance; + } + encode(data: NapProtoEncodeStructType): Uint8Array { return this._proto_msg.toBinary(this._proto_msg.create(data as PartialMessage>)); } @@ -137,3 +143,19 @@ export class NapProtoMsg { return this._proto_msg.fromBinary(data) as NapProtoDecodeStructType; } } + +export class NapProtoMsg { + private realMsg: NapProtoRealMsg; + + constructor(fields: T) { + this.realMsg = NapProtoRealMsg.getInstance(fields); + } + + encode(data: NapProtoEncodeStructType): Uint8Array { + return this.realMsg.encode(data); + } + + decode(data: Uint8Array): NapProtoDecodeStructType { + return this.realMsg.decode(data); + } +}