diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/typescript/CodeGenerateTypeScript.java b/protocol/src/main/java/com/zfoo/protocol/serializer/typescript/CodeGenerateTypeScript.java index 4b7f8072..b1076180 100644 --- a/protocol/src/main/java/com/zfoo/protocol/serializer/typescript/CodeGenerateTypeScript.java +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/typescript/CodeGenerateTypeScript.java @@ -86,11 +86,12 @@ public class CodeGenerateTypeScript implements ICodeGenerate { var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolManagerTemplate.ts"); var protocol_imports_manager = new StringBuilder(); var protocol_manager_registrations = new StringBuilder(); - protocol_imports_manager.append("import Protocols from './Protocols';").append(LS); + protocol_imports_manager.append("import * as Protocols from './Protocols';").append(LS); for (var registration : registrations) { var protocol_id = registration.protocolId(); var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); - protocol_manager_registrations.append(StringUtils.format("protocols.set({}, Protocols.{});", protocol_id, protocol_name)).append(LS); + protocol_manager_registrations.append(StringUtils.format("protocols.set({}, new Protocols.{}Registration());", protocol_id, protocol_name)).append(LS); + protocol_manager_registrations.append(StringUtils.format("protocolIdMap.set(Protocols.{}, {});", protocol_name, protocol_id)).append(LS); } var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports_manager.toString() , CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString()); @@ -102,28 +103,18 @@ public class CodeGenerateTypeScript implements ICodeGenerate { var protocol_imports_protocols = new StringBuilder(); protocol_imports_protocols.append("import IByteBuffer from './IByteBuffer';").append(LS); + protocol_imports_protocols.append("import IProtocolRegistration from './IProtocolRegistration';").append(LS); var protocol_class = new StringBuilder(); var protocol_registration = new StringBuilder(); for (var registration : registrations) { - var protocol_id = registration.protocolId(); - var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); - var protocolTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolClassTemplate.ts"); - var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of( - CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id) - , CodeTemplatePlaceholder.protocol_name, protocol_name - , CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.TypeScript) - , CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration) - , CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration) - , CodeTemplatePlaceholder.protocol_read_deserialization, protocol_read_deserialization(registration) - )); - protocol_class.append(formatProtocolTemplate).append(LS); - protocol_registration.append(StringUtils.format("static {} = {}", protocol_name, protocol_name)).append(LS); + protocol_class.append(protocol_class(registration).replace("class ", "export class ")).append(LS); + protocol_registration.append(protocol_registration(registration)).append(LS); } var protocolTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolsTemplate.ts"); var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of( CodeTemplatePlaceholder.protocol_imports, protocol_imports_protocols.toString() - ,CodeTemplatePlaceholder.protocol_class, protocol_class.toString() - , CodeTemplatePlaceholder.protocol_registration, protocol_registration.toString() + , CodeTemplatePlaceholder.protocol_class, protocol_class.toString() + , CodeTemplatePlaceholder.protocol_registration, protocol_registration.toString() )); var outputPath = StringUtils.format("{}/Protocols.ts", protocolOutputPath); var file = new File(outputPath); @@ -144,7 +135,9 @@ public class CodeGenerateTypeScript implements ICodeGenerate { var protocol_id = registration.protocolId(); var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); protocol_imports.append(StringUtils.format("import {} from './{}/{}';", protocol_name, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name)).append(LS); - protocol_manager_registrations.append(StringUtils.format("protocols.set({}, {});", protocol_id, protocol_name)).append(LS); + protocol_imports.append(StringUtils.format("import { {}Registration } from './{}/{}';", protocol_name, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name)).append(LS); + protocol_manager_registrations.append(StringUtils.format("protocols.set({}, new {}Registration());", protocol_id, protocol_name)).append(LS); + protocol_manager_registrations.append(StringUtils.format("protocolIdMap.set({}, {});", protocol_name, protocol_id)).append(LS); } var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString() , CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString()); @@ -161,11 +154,9 @@ public class CodeGenerateTypeScript implements ICodeGenerate { var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of( CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id) , CodeTemplatePlaceholder.protocol_name, protocol_name - , CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.TypeScript) , CodeTemplatePlaceholder.protocol_imports, protocol_imports_fold(registration) - , CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration) - , CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration) - , CodeTemplatePlaceholder.protocol_read_deserialization, protocol_read_deserialization(registration) + , CodeTemplatePlaceholder.protocol_class, protocol_class(registration) + , CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration) )); var outputPath = StringUtils.format("{}/{}/{}.ts", protocolOutputPath, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name); var file = new File(outputPath); @@ -187,7 +178,9 @@ public class CodeGenerateTypeScript implements ICodeGenerate { var protocol_id = registration.protocolId(); var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); protocol_imports.append(StringUtils.format("import {} from './{}';", protocol_name, protocol_name)).append(LS); - protocol_manager_registrations.append(StringUtils.format("protocols.set({}, {});", protocol_id, protocol_name)).append(LS); + protocol_imports.append(StringUtils.format("import { {}Registration } from './{}';", protocol_name, protocol_name)).append(LS); + protocol_manager_registrations.append(StringUtils.format("protocols.set({}, new {}Registration());", protocol_id, protocol_name)).append(LS); + protocol_manager_registrations.append(StringUtils.format("protocolIdMap.set({}, {});", protocol_name, protocol_id)).append(LS); } var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString() , CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString()); @@ -202,13 +195,10 @@ public class CodeGenerateTypeScript implements ICodeGenerate { var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); var protocolTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolTemplate.ts"); var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of( - CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id) - , CodeTemplatePlaceholder.protocol_name, protocol_name - , CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.TypeScript) + CodeTemplatePlaceholder.protocol_name, protocol_name , CodeTemplatePlaceholder.protocol_imports, protocol_imports_default(registration) - , CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration) - , CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration) - , CodeTemplatePlaceholder.protocol_read_deserialization, protocol_read_deserialization(registration) + , CodeTemplatePlaceholder.protocol_class, protocol_class(registration) + , CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration) )); var outputPath = StringUtils.format("{}/{}.ts", protocolOutputPath, protocol_name); var file = new File(outputPath); @@ -218,7 +208,8 @@ public class CodeGenerateTypeScript implements ICodeGenerate { } private void createTemplateFile() throws IOException { - var list = List.of("typescript/IByteBuffer.ts", "typescript/buffer/ByteBuffer.ts", "typescript/buffer/Long.ts", "typescript/buffer/Longbits.ts"); + var list = List.of("typescript/IProtocolRegistration.ts", "typescript/IByteBuffer.ts", "typescript/buffer/ByteBuffer.ts" + , "typescript/buffer/Long.ts", "typescript/buffer/Longbits.ts"); for (var fileName : list) { var fileInputStream = ClassUtils.getFileFromClassPath(fileName); var createFile = new File(StringUtils.format("{}/{}", protocolOutputPath, StringUtils.substringAfterFirst(fileName, "typescript/"))); @@ -226,6 +217,32 @@ public class CodeGenerateTypeScript implements ICodeGenerate { } } + private String protocol_class(ProtocolRegistration registration) { + var protocol_id = registration.protocolId(); + var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); + var protocolTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolClassTemplate.ts"); + var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of( + CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.TypeScript) + , CodeTemplatePlaceholder.protocol_name, protocol_name + , CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id) + , CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration) + )); + return formatProtocolTemplate; + } + + private String protocol_registration(ProtocolRegistration registration) { + var protocol_id = registration.protocolId(); + var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); + var protocolTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolRegistrationTemplate.ts"); + var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of( + CodeTemplatePlaceholder.protocol_name, protocol_name + , CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id) + , CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration) + , CodeTemplatePlaceholder.protocol_read_deserialization, protocol_read_deserialization(registration) + )); + return formatProtocolTemplate; + } + private String protocol_imports_fold(ProtocolRegistration registration) { // import IByteBuffer first var protocolId = registration.getId(); @@ -233,6 +250,7 @@ public class CodeGenerateTypeScript implements ICodeGenerate { var protocolPath = GenerateProtocolPath.protocolPathPeriod(protocolId); var splits = protocolPath.split(StringUtils.PERIOD_REGEX); importBuilder.append(StringUtils.format("import IByteBuffer from '{}IByteBuffer';", "../".repeat(splits.length))).append(LS); + importBuilder.append(StringUtils.format("import IProtocolRegistration from '{}IProtocolRegistration';", "../".repeat(splits.length))).append(LS); var subProtocols = ProtocolAnalysis.getFirstSubProtocolIds(protocolId); // import other sub protocols @@ -249,6 +267,7 @@ public class CodeGenerateTypeScript implements ICodeGenerate { var protocolId = registration.getId(); var importBuilder = new StringBuilder(); importBuilder.append(StringUtils.format("import IByteBuffer from './IByteBuffer';")).append(LS); + importBuilder.append(StringUtils.format("import IProtocolRegistration from './IProtocolRegistration';")).append(LS); // import other sub protocols var subProtocols = ProtocolAnalysis.getFirstSubProtocolIds(protocolId); diff --git a/protocol/src/main/resources/typescript/IProtocolRegistration.ts b/protocol/src/main/resources/typescript/IProtocolRegistration.ts new file mode 100644 index 00000000..ef4256d3 --- /dev/null +++ b/protocol/src/main/resources/typescript/IProtocolRegistration.ts @@ -0,0 +1,11 @@ +import IByteBuffer from "./IByteBuffer"; + +interface IProtocolRegistration { + protocolId(): number; + + write(buffer: IByteBuffer, packet: T | null): void; + + read(buffer: IByteBuffer): T | null; +} + +export default IProtocolRegistration; \ No newline at end of file diff --git a/protocol/src/main/resources/typescript/ProtocolClassTemplate.ts b/protocol/src/main/resources/typescript/ProtocolClassTemplate.ts index 3ca38047..c80081c2 100644 --- a/protocol/src/main/resources/typescript/ProtocolClassTemplate.ts +++ b/protocol/src/main/resources/typescript/ProtocolClassTemplate.ts @@ -1,32 +1,4 @@ ${protocol_note} class ${protocol_name} { ${protocol_field_definition} - - static PROTOCOL_ID: number = ${protocol_id}; - - protocolId(): number { - return ${protocol_name}.PROTOCOL_ID; - } - - static write(buffer: IByteBuffer, packet: ${protocol_name} | null) { - if (packet === null) { - buffer.writeInt(0); - return; - } - ${protocol_write_serialization} - } - - static read(buffer: IByteBuffer): ${protocol_name} | null { - const length = buffer.readInt(); - if (length === 0) { - return null; - } - const beforeReadIndex = buffer.getReadOffset(); - const packet = new ${protocol_name}(); - ${protocol_read_deserialization} - if (length > 0) { - buffer.setReadOffset(beforeReadIndex + length); - } - return packet; - } } \ No newline at end of file diff --git a/protocol/src/main/resources/typescript/ProtocolManagerTemplate.ts b/protocol/src/main/resources/typescript/ProtocolManagerTemplate.ts index ccbca950..05c5dcaf 100644 --- a/protocol/src/main/resources/typescript/ProtocolManagerTemplate.ts +++ b/protocol/src/main/resources/typescript/ProtocolManagerTemplate.ts @@ -1,22 +1,32 @@ ${protocol_imports} import IByteBuffer from "./IByteBuffer"; +import IProtocolRegistration from "./IProtocolRegistration"; -const protocols = new Map(); +const protocols = new Map>(); +const protocolIdMap = new Map(); // initProtocol ${protocol_manager_registrations} class ProtocolManager { - static getProtocol(protocolId: number): any { + static getProtocolId(clazz: any): number { + const protocolId = protocolIdMap.get(clazz); + if (protocolId === null || protocolId === undefined) { + throw '[protocol:' + clazz + '] not exist'; + } + return protocolId; + } + + static getProtocol(protocolId: number): IProtocolRegistration { const protocol = protocols.get(protocolId); - if (protocol === null) { + if (protocol === null || protocol === undefined) { throw '[protocolId:' + protocolId + '] not exist'; } return protocol; } static write(buffer: IByteBuffer, packet: any): void { - const protocolId = packet.protocolId(); + const protocolId = ProtocolManager.getProtocolId(packet.constructor); buffer.writeShort(protocolId); const protocol = ProtocolManager.getProtocol(protocolId); protocol.write(buffer, packet); diff --git a/protocol/src/main/resources/typescript/ProtocolRegistrationTemplate.ts b/protocol/src/main/resources/typescript/ProtocolRegistrationTemplate.ts new file mode 100644 index 00000000..d9702fb6 --- /dev/null +++ b/protocol/src/main/resources/typescript/ProtocolRegistrationTemplate.ts @@ -0,0 +1,27 @@ +export class ${protocol_name}Registration implements IProtocolRegistration<${protocol_name}> { + protocolId(): number { + return ${protocol_id}; + } + + write(buffer: IByteBuffer, packet: ${protocol_name} | null) { + if (packet === null) { + buffer.writeInt(0); + return; + } + ${protocol_write_serialization} + } + + read(buffer: IByteBuffer): ${protocol_name} | null { + const length = buffer.readInt(); + if (length === 0) { + return null; + } + const beforeReadIndex = buffer.getReadOffset(); + const packet = new ${protocol_name}(); + ${protocol_read_deserialization} + if (length > 0) { + buffer.setReadOffset(beforeReadIndex + length); + } + return packet; + } +} \ No newline at end of file diff --git a/protocol/src/main/resources/typescript/ProtocolTemplate.ts b/protocol/src/main/resources/typescript/ProtocolTemplate.ts index 52362b7a..9d09b445 100644 --- a/protocol/src/main/resources/typescript/ProtocolTemplate.ts +++ b/protocol/src/main/resources/typescript/ProtocolTemplate.ts @@ -1,35 +1,7 @@ ${protocol_imports} -${protocol_note} -class ${protocol_name} { - ${protocol_field_definition} - static PROTOCOL_ID: number = ${protocol_id}; +${protocol_class} - protocolId(): number { - return ${protocol_name}.PROTOCOL_ID; - } - - static write(buffer: IByteBuffer, packet: ${protocol_name} | null) { - if (packet === null) { - buffer.writeInt(0); - return; - } - ${protocol_write_serialization} - } - - static read(buffer: IByteBuffer): ${protocol_name} | null { - const length = buffer.readInt(); - if (length === 0) { - return null; - } - const beforeReadIndex = buffer.getReadOffset(); - const packet = new ${protocol_name}(); - ${protocol_read_deserialization} - if (length > 0) { - buffer.setReadOffset(beforeReadIndex + length); - } - return packet; - } -} +${protocol_registration} export default ${protocol_name}; \ No newline at end of file diff --git a/protocol/src/main/resources/typescript/ProtocolsTemplate.ts b/protocol/src/main/resources/typescript/ProtocolsTemplate.ts index 4b89921a..dd81a0dd 100644 --- a/protocol/src/main/resources/typescript/ProtocolsTemplate.ts +++ b/protocol/src/main/resources/typescript/ProtocolsTemplate.ts @@ -2,8 +2,4 @@ ${protocol_imports} ${protocol_class} -class Protocols { - ${protocol_registration} -} - -export default Protocols; +${protocol_registration} \ No newline at end of file