From ca8104aa33f166202d390545badb4e2da42bb556 Mon Sep 17 00:00:00 2001 From: walon Date: Sat, 1 May 2021 22:36:59 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E9=87=8D=E6=9E=84=E3=80=91=E3=80=90cf?= =?UTF-8?q?g=E3=80=91=20=E7=95=A5=E5=BE=AE=E9=87=8D=E6=9E=84=20typescript?= =?UTF-8?q?=E8=AF=AD=E8=A8=80=E7=94=9F=E6=88=90=E4=BB=A3=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E5=A4=9A=E6=80=81=E7=B1=BB=E7=9A=84=E6=9E=84=E9=80=A0=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=90=8D=E7=94=B1=20deserialize=E6=94=B9=E4=B8=BA=20c?= =?UTF-8?q?onstructorFrom=EF=BC=8C=E8=AF=AD=E4=B9=89=E6=9B=B4=E6=B8=85?= =?UTF-8?q?=E6=A5=9A=20=E3=80=90=E4=BF=AE=E5=A4=8D=E3=80=91=E3=80=90cfg?= =?UTF-8?q?=E3=80=91=20=E4=BF=AE=E5=A4=8D=20=20typescript=20=E7=94=9F?= =?UTF-8?q?=E6=88=90=E4=BB=A3=E7=A0=81=E8=83=BD=E7=BC=96=E8=AF=91=E4=BD=86?= =?UTF-8?q?=E6=9C=AA=E8=83=BD=E6=AD=A3=E7=A1=AE=E5=AF=BC=E5=87=BA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E7=B1=BB=E7=9A=84bug=20=E3=80=90=E7=89=B9=E6=80=A7?= =?UTF-8?q?=E3=80=91=E3=80=90proto=E3=80=91=20=E5=AF=B9=E4=BA=8E=E4=BD=BF?= =?UTF-8?q?=E7=94=A8puerts=E6=A1=86=E6=9E=B6=E7=9A=84unity=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=EF=BC=8C=E6=94=AF=E6=8C=81=E7=94=9F=E6=88=90=20typesc?= =?UTF-8?q?ript=E7=9A=84=E6=B6=88=E6=81=AF=E4=BB=A3=E7=A0=81=E3=80=82?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E9=80=9A=E8=BF=87=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Luban.Common/Source/Utils/TypeUtil.cs | 5 + .../Source/Defs/TTypeTemplateExtends.cs | 14 +- .../Generate/TypeScriptBinCodeRender.cs | 29 ++- .../Generate/TypeScriptJsonCodeRender.cs | 31 ++- .../Generate/TypescriptCodeRenderBase.cs | 59 ----- .../TypescriptBinConstructorVisitor.cs | 30 +++ ...TypescriptBinUnderingConstructorVisitor.cs | 22 ++ .../TypescriptDeserializeVisitor.cs | 27 -- .../TypescriptJsonConstructorVisitor.cs | 27 ++ ...pescriptJsonUnderingConstructorVisitor.cs} | 6 +- .../Source/Defs/DefTypeBase.cs | 3 + .../Source/Defs/TTypeTemplateCommonExtends.cs | 10 + .../TypescriptBinDeserializeVisitor.cs} | 12 +- .../TypescriptBinSerializeVisitor.cs | 31 +++ ...TypescriptBinUnderingDeserializeVisitor.cs | 22 ++ ...criptBinUnderingDeserializeVisitorBase.cs} | 30 ++- .../TypescriptBinUnderingSerializeVisitor.cs | 171 +++++++++++++ .../Source/Utils/RenderUtil.cs | 38 ++- .../Source/Generate/TypescriptRender.cs | 231 ++++++++++++++++++ src/Luban.Job.Proto/Source/JobController.cs | 129 +++++++++- 20 files changed, 766 insertions(+), 161 deletions(-) delete mode 100644 src/Luban.Job.Cfg/Source/Generate/TypescriptCodeRenderBase.cs create mode 100644 src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptBinConstructorVisitor.cs create mode 100644 src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptBinUnderingConstructorVisitor.cs delete mode 100644 src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptDeserializeVisitor.cs create mode 100644 src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptJsonConstructorVisitor.cs rename src/Luban.Job.Cfg/Source/TypeVisitors/{TypescriptUnderingDeserializeVisitor.cs => TypescriptJsonUnderingConstructorVisitor.cs} (94%) rename src/{Luban.Job.Cfg/Source/TypeVisitors/TypescriptDeserializeBinVisitor.cs => Luban.Job.Common/Source/TypeVisitors/TypescriptBinDeserializeVisitor.cs} (56%) create mode 100644 src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinSerializeVisitor.cs create mode 100644 src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingDeserializeVisitor.cs rename src/{Luban.Job.Cfg/Source/TypeVisitors/TypescriptUnderingDeserializeBinVisitor.cs => Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingDeserializeVisitorBase.cs} (89%) create mode 100644 src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingSerializeVisitor.cs create mode 100644 src/Luban.Job.Proto/Source/Generate/TypescriptRender.cs diff --git a/src/Luban.Common/Source/Utils/TypeUtil.cs b/src/Luban.Common/Source/Utils/TypeUtil.cs index a86be25..325f46b 100644 --- a/src/Luban.Common/Source/Utils/TypeUtil.cs +++ b/src/Luban.Common/Source/Utils/TypeUtil.cs @@ -57,6 +57,11 @@ namespace Luban.Common.Utils return string.Join("", module.Split('.').Select(n => $"{n}_")) + ueName; } + public static string MakeTypescriptNamespaceBegin(string module) + { + return string.Join("", module.Split('.').Select(n => $"export namespace {n} {{")); + } + public static string MakeFullName(string module, string name) { if (string.IsNullOrEmpty(module)) diff --git a/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs b/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs index 761a30b..74dde73 100644 --- a/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs +++ b/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs @@ -98,9 +98,14 @@ namespace Luban.Job.Cfg.Defs } - public static string TsDeserialize(string fieldName, string jsonFieldName, TType type) + public static string TsJsonConstructor(string fieldName, string jsonFieldName, TType type) { - return type.Apply(TypescriptDeserializeVisitor.Ins, $"{jsonFieldName}", fieldName); + return type.Apply(TypescriptJsonConstructorVisitor.Ins, $"{jsonFieldName}", fieldName); + } + + public static string TsBinConstructor(string fieldName, string byteBufName, TType type) + { + return type.Apply(TypescriptBinConstructorVisitor.Ins, $"{byteBufName}", fieldName); } public static string TsRecursiveResolve(DefField field, string tables) @@ -124,11 +129,6 @@ namespace Luban.Job.Cfg.Defs } } - public static string TsDeserializeBin(string fieldName, string byteBufName, TType type) - { - return type.Apply(TypescriptDeserializeBinVisitor.Ins, byteBufName, fieldName); - } - public static string Py3Deserialize(string fieldName, string jsonFieldName, TType type) { return type.Apply(PyDeserializeVisitor.Py3Ins, $"{jsonFieldName}", fieldName); diff --git a/src/Luban.Job.Cfg/Source/Generate/TypeScriptBinCodeRender.cs b/src/Luban.Job.Cfg/Source/Generate/TypeScriptBinCodeRender.cs index 6b664b2..de97176 100644 --- a/src/Luban.Job.Cfg/Source/Generate/TypeScriptBinCodeRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/TypeScriptBinCodeRender.cs @@ -1,14 +1,23 @@ using Luban.Job.Cfg.Defs; using Luban.Job.Common.Defs; +using Luban.Job.Common.Utils; using Scriban; using System; using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { - class TypeScriptBinCodeRender : TypescriptCodeRenderBase + class TypeScriptBinCodeRender : CodeRenderBase { + public override string Render(DefConst c) + { + return RenderUtil.RenderTypescriptConstClass(c); + } + public override string Render(DefEnum e) + { + return RenderUtil.RenderTypescriptEnumClass(e); + } [ThreadStatic] private static Template t_beanRender; @@ -23,11 +32,11 @@ namespace Luban.Job.Cfg.Generate hierarchy_export_fields = x.hierarchy_export_fields }} -namespace {{x.namespace}} { +{{x.typescript_namespace_begin}} export {{if x.is_abstract_type}} abstract {{end}} class {{name}} {{if parent_def_type}} extends {{x.parent}}{{end}} { {{~if x.is_abstract_type~}} - static deserialize(_buf_ : Bright.Serialization.ByteBuf) : {{name}} { + static constructorFrom(_buf_ : Bright.Serialization.ByteBuf) : {{name}} { switch (_buf_.ReadInt()) { case 0 : return null; @@ -44,7 +53,7 @@ export {{if x.is_abstract_type}} abstract {{end}} class {{name}} {{if parent_def super(_buf_); {{~end~}} {{~ for field in export_fields ~}} - {{ts_deserialize_bin ('this.' + field.ts_style_name) '_buf_' field.ctype}} + {{ts_bin_constructor ('this.' + field.ts_style_name) '_buf_' field.ctype}} {{~end~}} } @@ -69,7 +78,7 @@ export {{if x.is_abstract_type}} abstract {{end}} class {{name}} {{if parent_def } } -} +{{x.typescript_namespace_end}} "); var result = template.RenderCode(b); @@ -88,7 +97,7 @@ export {{if x.is_abstract_type}} abstract {{end}} class {{name}} {{if parent_def key_type2 = x.key_ttype2 value_type = x.value_ttype }} -namespace {{x.namespace}} { +{{x.typescript_namespace_begin}} export class {{name}}{ {{~ if x.is_two_key_map_table ~}} private _dataListMap : Map<{{ts_define_type key_type1}}, {{ts_define_type value_type}}[]>; @@ -102,7 +111,7 @@ export class {{name}}{ for(let n = _buf_.ReadInt(); n > 0 ; n--) { let _v : {{ts_define_type value_type}}; - {{ts_deserialize_bin '_v' '_buf_' value_type}} + {{ts_bin_constructor '_v' '_buf_' value_type}} this._dataList.push(_v); var _key = _v.{{x.index_field1.ts_style_name}}; let list : {{ts_define_type value_type}}[] = this._dataListMap.get(_key); @@ -142,7 +151,7 @@ export class {{name}}{ for(let n = _buf_.ReadInt() ; n > 0 ; n--) { let _v : {{ts_define_type value_type}}; - {{ts_deserialize_bin '_v' '_buf_' value_type}} + {{ts_bin_constructor '_v' '_buf_' value_type}} this._dataList.push(_v); this._dataMap.set(_v.{{x.index_field.ts_style_name}}, _v); } @@ -165,7 +174,7 @@ export class {{name}}{ constructor(_buf_ : Bright.Serialization.ByteBuf) { if (_buf_.ReadInt() != 1) throw new Error('table mode=one, but size != 1'); - {{ts_deserialize_bin 'this._data' '_buf_' value_type}} + {{ts_bin_constructor 'this._data' '_buf_' value_type}} } getData() : {{ts_define_type value_type}} { return this._data; } @@ -180,7 +189,7 @@ export class {{name}}{ {{end}} } -} +{{x.typescript_namespace_end}} "); var result = template.RenderCode(p); diff --git a/src/Luban.Job.Cfg/Source/Generate/TypeScriptJsonCodeRender.cs b/src/Luban.Job.Cfg/Source/Generate/TypeScriptJsonCodeRender.cs index 85540b4..3797c75 100644 --- a/src/Luban.Job.Cfg/Source/Generate/TypeScriptJsonCodeRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/TypeScriptJsonCodeRender.cs @@ -1,13 +1,24 @@ using Luban.Job.Cfg.Defs; using Luban.Job.Common.Defs; +using Luban.Job.Common.Utils; using Scriban; using System; using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { - class TypeScriptJsonCodeRender : TypescriptCodeRenderBase + class TypeScriptJsonCodeRender : CodeRenderBase { + public override string Render(DefConst c) + { + return RenderUtil.RenderTypescriptConstClass(c); + } + + public override string Render(DefEnum e) + { + return RenderUtil.RenderTypescriptEnumClass(e); + } + [ThreadStatic] private static Template t_beanRender; public override string Render(DefBean b) @@ -21,11 +32,11 @@ namespace Luban.Job.Cfg.Generate hierarchy_export_fields = x.hierarchy_export_fields }} -namespace {{x.namespace}} { +{{x.typescript_namespace_begin}} export {{if x.is_abstract_type}} abstract {{end}} class {{name}} {{if parent_def_type}} extends {{x.parent}}{{end}} { {{~if x.is_abstract_type~}} - static deserialize(_json_ : any) : {{name}} { + static constructorFrom(_json_ : any) : {{name}} { switch (_json_.__type__) { case null : return null; {{~ for child in x.hierarchy_not_abstract_children~}} @@ -44,7 +55,7 @@ export {{if x.is_abstract_type}} abstract {{end}} class {{name}} {{if parent_def {{~if !field.ctype.is_nullable~}} if (_json_.{{field.name}} == null) { throw new Error(); } {{~end~}} - {{ts_deserialize ('this.' + field.ts_style_name) ( '_json_.' + field.name) field.ctype}} + {{ts_json_constructor ('this.' + field.ts_style_name) ( '_json_.' + field.name) field.ctype}} {{~end~}} } @@ -69,7 +80,7 @@ export {{if x.is_abstract_type}} abstract {{end}} class {{name}} {{if parent_def } } -} +{{x.typescript_namespace_end}} "); var result = template.RenderCode(b); @@ -88,7 +99,7 @@ export {{if x.is_abstract_type}} abstract {{end}} class {{name}} {{if parent_def key_type2 = x.key_ttype2 value_type = x.value_ttype }} -namespace {{x.namespace}} { +{{x.typescript_namespace_begin}} export class {{name}}{ {{~ if x.is_two_key_map_table ~}} private _dataListMap : Map<{{ts_define_type key_type1}}, {{ts_define_type value_type}}[]>; @@ -102,7 +113,7 @@ export class {{name}}{ for(var _json2_ of _json_) { let _v : {{ts_define_type value_type}}; - {{ts_deserialize '_v' '_json2_' value_type}} + {{ts_json_constructor '_v' '_json2_' value_type}} this._dataList.push(_v); var _key = _v.{{x.index_field1.ts_style_name}}; let list : {{ts_define_type value_type}}[] = this._dataListMap.get(_key); @@ -142,7 +153,7 @@ export class {{name}}{ for(var _json2_ of _json_) { let _v : {{ts_define_type value_type}}; - {{ts_deserialize '_v' '_json2_' value_type}} + {{ts_json_constructor '_v' '_json2_' value_type}} this._dataList.push(_v); this._dataMap.set(_v.{{x.index_field.ts_style_name}}, _v); } @@ -165,7 +176,7 @@ export class {{name}}{ constructor(_json_ : any) { if (_json_.length != 1) throw new Error('table mode=one, but size != 1'); - {{ts_deserialize 'this._data' '_json_[0]' value_type}} + {{ts_json_constructor 'this._data' '_json_[0]' value_type}} } getData() : {{ts_define_type value_type}} { return this._data; } @@ -180,7 +191,7 @@ export class {{name}}{ {{end}} } -} +{{x.typescript_namespace_end}} "); var result = template.RenderCode(p); diff --git a/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeRenderBase.cs b/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeRenderBase.cs deleted file mode 100644 index d1b0282..0000000 --- a/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeRenderBase.cs +++ /dev/null @@ -1,59 +0,0 @@ -锘縰sing Luban.Job.Common.Defs; -using Scriban; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Luban.Job.Cfg.Generate -{ - abstract class TypescriptCodeRenderBase : CodeRenderBase - { - [ThreadStatic] - private static Template t_tsConstRender; - public override string Render(DefConst c) - { - var ctx = new TemplateContext(); - var env = new TTypeTemplateCommonExtends - { - ["x"] = c - }; - ctx.PushGlobal(env); - - - var template = t_tsConstRender ??= Template.Parse(@" -namespace {{x.namespace}} { -export class {{x.name}} { - {{~ for item in x.items ~}} - static {{item.name}} = {{ts_const_value item.ctype item.value}}; - {{~end~}} -} -} - -"); - var result = template.Render(ctx); - - return result; - } - - [ThreadStatic] - private static Template t_tsEnumRender; - public override string Render(DefEnum e) - { - var template = t_tsEnumRender ??= Template.Parse(@" -namespace {{namespace}} { -export enum {{name}} { - {{- for item in items }} - {{item.name}} = {{item.value}}, - {{-end}} -} -} - -"); - var result = template.Render(e); - - return result; - } - } -} diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptBinConstructorVisitor.cs b/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptBinConstructorVisitor.cs new file mode 100644 index 0000000..a2a4057 --- /dev/null +++ b/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptBinConstructorVisitor.cs @@ -0,0 +1,30 @@ +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; + +namespace Luban.Job.Common.TypeVisitors +{ + class TypescriptBinConstructorVisitor : DecoratorFuncVisitor + { + public static TypescriptBinConstructorVisitor Ins { get; } = new TypescriptBinConstructorVisitor(); + + public override string DoAccept(TType type, string byteBufName, string fieldName) + { + if (type.IsNullable) + { + return $"if({byteBufName}.ReadBool()) {{ {type.Apply(TypescriptBinUnderingConstructorVisitor.Ins, byteBufName, fieldName)} }} else {{ {fieldName} = null; }}"; + } + else + { + return type.Apply(TypescriptBinUnderingConstructorVisitor.Ins, byteBufName, fieldName); + } + } + + // TODO 设计需要简化,现在造成多态bean的可空与其他字段类型不一样,而需要单独处理 + // 多态bean不浪费一个字段,直接用typeid==0表示空 + // 因此不跟普通字段一样,需要 ReadBool()来区别是否为空 + public override string Accept(TBean type, string bufName, string fieldName) + { + return type.Apply(TypescriptBinUnderingConstructorVisitor.Ins, bufName, fieldName); + } + } +} diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptBinUnderingConstructorVisitor.cs b/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptBinUnderingConstructorVisitor.cs new file mode 100644 index 0000000..d6ea85f --- /dev/null +++ b/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptBinUnderingConstructorVisitor.cs @@ -0,0 +1,22 @@ +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; + +namespace Luban.Job.Common.TypeVisitors +{ + class TypescriptBinUnderingConstructorVisitor : TypescriptBinUnderingDeserializeVisitorBase + { + public static TypescriptBinUnderingConstructorVisitor Ins { get; } = new TypescriptBinUnderingConstructorVisitor(); + + public override string Accept(TBean type, string bufVarName, string fieldName) + { + if (type.Bean.IsAbstractType) + { + return $"{fieldName} = {type.Bean.FullName}.constructorFrom({bufVarName});"; + } + else + { + return $"{fieldName} = new {type.Bean.FullName}({bufVarName});"; + } + } + } +} diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptDeserializeVisitor.cs b/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptDeserializeVisitor.cs deleted file mode 100644 index 9f17ef8..0000000 --- a/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptDeserializeVisitor.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Luban.Job.Common.Types; -using Luban.Job.Common.TypeVisitors; - -namespace Luban.Job.Cfg.TypeVisitors -{ - class TypescriptDeserializeVisitor : DecoratorFuncVisitor - { - public static TypescriptDeserializeVisitor Ins { get; } = new TypescriptDeserializeVisitor(); - - public override string DoAccept(TType type, string jsonFieldName, string fieldName) - { - if (type.IsNullable) - { - return $"if({jsonFieldName} != null) {{ {type.Apply(TypescriptUnderingDeserializeVisitor.Ins, jsonFieldName, fieldName)} }} else {{ {fieldName} = null; }}"; - } - else - { - return type.Apply(TypescriptUnderingDeserializeVisitor.Ins, jsonFieldName, fieldName); - } - } - - public override string Accept(TBean type, string bufName, string fieldName) - { - return type.Apply(TypescriptUnderingDeserializeVisitor.Ins, bufName, fieldName); - } - } -} diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptJsonConstructorVisitor.cs b/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptJsonConstructorVisitor.cs new file mode 100644 index 0000000..e6f88ef --- /dev/null +++ b/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptJsonConstructorVisitor.cs @@ -0,0 +1,27 @@ +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; + +namespace Luban.Job.Cfg.TypeVisitors +{ + class TypescriptJsonConstructorVisitor : DecoratorFuncVisitor + { + public static TypescriptJsonConstructorVisitor Ins { get; } = new TypescriptJsonConstructorVisitor(); + + public override string DoAccept(TType type, string jsonFieldName, string fieldName) + { + if (type.IsNullable) + { + return $"if({jsonFieldName} != null) {{ {type.Apply(TypescriptJsonUnderingConstructorVisitor.Ins, jsonFieldName, fieldName)} }} else {{ {fieldName} = null; }}"; + } + else + { + return type.Apply(TypescriptJsonUnderingConstructorVisitor.Ins, jsonFieldName, fieldName); + } + } + + //public override string Accept(TBean type, string bytebufName, string fieldName) + //{ + // return type.Apply(TypescriptJsonUnderingConstructorVisitor.Ins, bytebufName, fieldName); + //} + } +} diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptUnderingDeserializeVisitor.cs b/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptJsonUnderingConstructorVisitor.cs similarity index 94% rename from src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptUnderingDeserializeVisitor.cs rename to src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptJsonUnderingConstructorVisitor.cs index 5b394e5..28ec9b8 100644 --- a/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptUnderingDeserializeVisitor.cs +++ b/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptJsonUnderingConstructorVisitor.cs @@ -3,9 +3,9 @@ using Luban.Job.Common.TypeVisitors; namespace Luban.Job.Cfg.TypeVisitors { - class TypescriptUnderingDeserializeVisitor : ITypeFuncVisitor + class TypescriptJsonUnderingConstructorVisitor : ITypeFuncVisitor { - public static TypescriptUnderingDeserializeVisitor Ins { get; } = new TypescriptUnderingDeserializeVisitor(); + public static TypescriptJsonUnderingConstructorVisitor Ins { get; } = new TypescriptJsonUnderingConstructorVisitor(); public string Accept(TBool type, string jsonVarName, string fieldName) { @@ -81,7 +81,7 @@ namespace Luban.Job.Cfg.TypeVisitors { if (type.Bean.IsAbstractType) { - return $"{fieldName} = {type.Bean.FullName}.deserialize({jsonVarName});"; + return $"{fieldName} = {type.Bean.FullName}.constructorFrom({jsonVarName});"; } else { diff --git a/src/Luban.Job.Common/Source/Defs/DefTypeBase.cs b/src/Luban.Job.Common/Source/Defs/DefTypeBase.cs index 6343df0..a19316c 100644 --- a/src/Luban.Job.Common/Source/Defs/DefTypeBase.cs +++ b/src/Luban.Job.Common/Source/Defs/DefTypeBase.cs @@ -33,6 +33,9 @@ namespace Luban.Job.Common.Defs public string CppFullNameWithTopModule => TypeUtil.MakeCppFullName(AssemblyBase.TopModule, FullName); + public string TypescriptNamespaceBegin => TypeUtil.MakeTypescriptNamespaceBegin(Namespace); + + public string TypescriptNamespaceEnd => TypeUtil.MakeCppNamespaceEnd(Namespace); public string CppFullName => TypeUtil.MakeCppFullName(Namespace, Name); diff --git a/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs b/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs index adb74b1..8a6c856 100644 --- a/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs +++ b/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs @@ -138,6 +138,16 @@ namespace Luban.Job.Common.Defs return type.Apply(LuaConstValueVisitor.Ins, value); } + public static string TsBinSerialize(string fieldName, string byteBufName, TType type) + { + return type.Apply(TypescriptBinSerializeVisitor.Ins, byteBufName, fieldName); + } + + public static string TsBinDeserialize(string fieldName, string byteBufName, TType type) + { + return type.Apply(TypescriptBinDeserializeVisitor.Ins, byteBufName, fieldName); + } + public static string PyDefineType(TType type) { return type.Apply(PyDefineTypeName.Ins); diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptDeserializeBinVisitor.cs b/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinDeserializeVisitor.cs similarity index 56% rename from src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptDeserializeBinVisitor.cs rename to src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinDeserializeVisitor.cs index be415b3..dc99e43 100644 --- a/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptDeserializeBinVisitor.cs +++ b/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinDeserializeVisitor.cs @@ -1,27 +1,27 @@ using Luban.Job.Common.Types; using Luban.Job.Common.TypeVisitors; -namespace Luban.Job.Cfg.TypeVisitors +namespace Luban.Job.Common.TypeVisitors { - class TypescriptDeserializeBinVisitor : DecoratorFuncVisitor + class TypescriptBinDeserializeVisitor : DecoratorFuncVisitor { - public static TypescriptDeserializeBinVisitor Ins { get; } = new TypescriptDeserializeBinVisitor(); + public static TypescriptBinDeserializeVisitor Ins { get; } = new TypescriptBinDeserializeVisitor(); public override string DoAccept(TType type, string byteBufName, string fieldName) { if (type.IsNullable) { - return $"if({byteBufName}.ReadBool()) {{ {type.Apply(TypescriptUnderingDeserializeBinVisitor.Ins, byteBufName, fieldName)} }} else {{ {fieldName} = null; }}"; + return $"if({byteBufName}.ReadBool()) {{ {type.Apply(TypescriptBinUnderingDeserializeVisitor.Ins, byteBufName, fieldName)} }} else {{ {fieldName} = null; }}"; } else { - return type.Apply(TypescriptUnderingDeserializeBinVisitor.Ins, byteBufName, fieldName); + return type.Apply(TypescriptBinUnderingDeserializeVisitor.Ins, byteBufName, fieldName); } } public override string Accept(TBean type, string bufName, string fieldName) { - return type.Apply(TypescriptUnderingDeserializeBinVisitor.Ins, bufName, fieldName); + return type.Apply(TypescriptBinUnderingDeserializeVisitor.Ins, bufName, fieldName); } } } diff --git a/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinSerializeVisitor.cs b/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinSerializeVisitor.cs new file mode 100644 index 0000000..ef1e3b7 --- /dev/null +++ b/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinSerializeVisitor.cs @@ -0,0 +1,31 @@ +锘縰sing Luban.Job.Common.Types; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Common.TypeVisitors +{ + class TypescriptBinSerializeVisitor : DecoratorFuncVisitor + { + public static TypescriptBinSerializeVisitor Ins { get; } = new TypescriptBinSerializeVisitor(); + + public override string DoAccept(TType type, string bytebufName, string fieldName) + { + if (type.IsNullable) + { + return $"if({bytebufName}.ReadBool()) {{{type.Apply(TypescriptBinUnderingSerializeVisitor.Ins, bytebufName, fieldName)} }} else {{ {fieldName} = null; }}"; + } + else + { + return type.Apply(TypescriptBinUnderingSerializeVisitor.Ins, bytebufName, fieldName); + } + } + + public override string Accept(TBean type, string bufName, string fieldName) + { + return type.Apply(TypescriptBinUnderingSerializeVisitor.Ins, bufName, fieldName); + } + } +} diff --git a/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingDeserializeVisitor.cs b/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingDeserializeVisitor.cs new file mode 100644 index 0000000..38c92c0 --- /dev/null +++ b/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingDeserializeVisitor.cs @@ -0,0 +1,22 @@ +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; + +namespace Luban.Job.Common.TypeVisitors +{ + public class TypescriptBinUnderingDeserializeVisitor : TypescriptBinUnderingDeserializeVisitorBase + { + public static TypescriptBinUnderingDeserializeVisitor Ins { get; } = new TypescriptBinUnderingDeserializeVisitor(); + + public override string Accept(TBean type, string bufVarName, string fieldName) + { + if (type.Bean.IsAbstractType) + { + return $"{fieldName} = {type.Bean.FullName}.deserializeFrom({bufVarName});"; + } + else + { + return $"{fieldName} = new {type.Bean.FullName}(); {fieldName}.deserialize({bufVarName});"; + } + } + } +} diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptUnderingDeserializeBinVisitor.cs b/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingDeserializeVisitorBase.cs similarity index 89% rename from src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptUnderingDeserializeBinVisitor.cs rename to src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingDeserializeVisitorBase.cs index 3a2de4b..bc37192 100644 --- a/src/Luban.Job.Cfg/Source/TypeVisitors/TypescriptUnderingDeserializeBinVisitor.cs +++ b/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingDeserializeVisitorBase.cs @@ -1,12 +1,10 @@ using Luban.Job.Common.Types; using Luban.Job.Common.TypeVisitors; -namespace Luban.Job.Cfg.TypeVisitors +namespace Luban.Job.Common.TypeVisitors { - class TypescriptUnderingDeserializeBinVisitor : ITypeFuncVisitor + public abstract class TypescriptBinUnderingDeserializeVisitorBase : ITypeFuncVisitor { - public static TypescriptUnderingDeserializeBinVisitor Ins { get; } = new TypescriptUnderingDeserializeBinVisitor(); - public string Accept(TBool type, string bufName, string fieldName) { return $"{fieldName} = {bufName}.ReadBool();"; @@ -69,7 +67,7 @@ namespace Luban.Job.Cfg.TypeVisitors public string Accept(TBytes type, string bufName, string fieldName) { - return $"{fieldName} = {bufName}.ReadArrayBuf();"; + return $"{fieldName} = new Uint8Array({bufName}.ReadArrayBuffer());"; } public string Accept(TText type, string bufName, string fieldName) @@ -77,17 +75,17 @@ namespace Luban.Job.Cfg.TypeVisitors return $"{fieldName} = {bufName}.ReadString();"; } - public string Accept(TBean type, string bufVarName, string fieldName) - { - if (type.Bean.IsAbstractType) - { - return $"{fieldName} = {type.Bean.FullName}.deserialize({bufVarName});"; - } - else - { - return $"{fieldName} = new {type.Bean.FullName}({bufVarName});"; - } - } + public abstract string Accept(TBean type, string bufVarName, string fieldName); + //{ + // if (type.Bean.IsAbstractType) + // { + // return $"{fieldName} = {type.Bean.FullName}.deserialize({bufVarName});"; + // } + // else + // { + // return $"{fieldName} = new {type.Bean.FullName}({bufVarName});"; + // } + //} private string GetNewArray(TArray arrayType, string size) { diff --git a/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingSerializeVisitor.cs b/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingSerializeVisitor.cs new file mode 100644 index 0000000..4281ffe --- /dev/null +++ b/src/Luban.Job.Common/Source/TypeVisitors/TypescriptBinUnderingSerializeVisitor.cs @@ -0,0 +1,171 @@ +锘縰sing Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Common.TypeVisitors +{ + class TypescriptBinUnderingSerializeVisitor : ITypeFuncVisitor + { + public static TypescriptBinUnderingSerializeVisitor Ins { get; } = new TypescriptBinUnderingSerializeVisitor(); + + public string Accept(TBool type, string bufName, string fieldName) + { + return $"{bufName}.WriteBool({fieldName});"; + } + + public string Accept(TByte type, string bufName, string fieldName) + { + return $"{bufName}.WriteByte({fieldName});"; + } + + public string Accept(TShort type, string bufName, string fieldName) + { + return $"{bufName}.WriteShort({fieldName});"; + } + + public string Accept(TFshort type, string bufName, string fieldName) + { + return $"{bufName}.WriteFshort({fieldName});"; + } + + public string Accept(TInt type, string bufName, string fieldName) + { + return $"{bufName}.WriteInt({fieldName});"; + } + + public string Accept(TFint type, string bufName, string fieldName) + { + return $"{bufName}.WriteFint({fieldName});"; + } + + public string Accept(TLong type, string bufName, string fieldName) + { + return $"{bufName}.WriteLong({fieldName});"; + } + + public string Accept(TFlong type, string bufName, string fieldName) + { + return $"{bufName}.WriteFlong({fieldName});"; + } + + public string Accept(TFloat type, string bufName, string fieldName) + { + return $"{bufName}.WriteFloat({fieldName});"; + } + + public string Accept(TDouble type, string bufName, string fieldName) + { + return $"{bufName}.WriteDouble({fieldName});"; + } + + public string Accept(TEnum type, string bufName, string fieldName) + { + return $"{bufName}.WriteInt({fieldName});"; + } + + public string Accept(TString type, string bufName, string fieldName) + { + return $"{bufName}.WriteString({fieldName});"; + } + + public string Accept(TBytes type, string bufName, string fieldName) + { + return $"{bufName}.WriteArrayBuffer({fieldName}.buffer);"; + } + + public string Accept(TText type, string bufName, string fieldName) + { + return $"{bufName}.WriteString({fieldName});"; + } + + public string Accept(TVector2 type, string bufVarName, string fieldName) + { + return $"{fieldName}.to({bufVarName})"; + } + + public string Accept(TVector3 type, string bufVarName, string fieldName) + { + return $"{fieldName}.to({bufVarName})"; + } + + public string Accept(TVector4 type, string bufVarName, string fieldName) + { + return $"{fieldName}.to({bufVarName})"; + } + + public string Accept(TDateTime type, string bufVarName, string fieldName) + { + return $"{bufVarName}.WriteInt({fieldName});"; + } + + public string Accept(TBean type, string bufVarName, string fieldName) + { + if (type.Bean.IsAbstractType) + { + return $"{type.Bean.FullName}.serializeTo({bufVarName}, {fieldName});"; + } + else + { + return $"{fieldName}.serialize({bufVarName});"; + } + } + + private static string GetNewArray(TArray arrayType, string size) + { + switch (arrayType.ElementType) + { + case TByte _: return $"new Uint8Array({size})"; + case TShort _: + case TFshort _: return $"new Int16Array({size})"; + case TInt _: + case TFint _: return $"new Int32Array({size})"; + case TLong _: + case TFlong _: return $"new Int64Array({size})"; + case TFloat _: return $"new Float32Array({size})"; + case TDouble _: return $"new Float64Array({size})"; + default: return "[]"; + } + } + + private static bool IsRawArrayElementType(TType elementType) + { + switch (elementType) + { + case TByte _: + case TShort _: + case TFshort _: + case TInt _: + case TFint _: + case TLong _: + case TFlong _: + case TFloat _: + case TDouble _: return true; + default: return false; + } + } + + public string Accept(TArray type, string bufVarName, string fieldName) + { + return $"{{ {bufVarName}.WriteSize({fieldName}.length); for(let _e of {fieldName}) {{ {type.ElementType.Apply(this, bufVarName, "_e")} }} }}"; + } + + public string Accept(TList type, string bufVarName, string fieldName) + { + return $"{{ {bufVarName}.WriteSize({fieldName}.length); for(let _e of {fieldName}) {{ {type.ElementType.Apply(this, bufVarName, "_e")} }} }}"; + } + + public string Accept(TSet type, string bufVarName, string fieldName) + { + return $"{{ {bufVarName}.WriteSize({fieldName}.size); for(let _e of {fieldName}) {{ {type.ElementType.Apply(this, bufVarName, "_e")} }} }}"; + } + + public string Accept(TMap type, string bufVarName, string fieldName) + { + return $"{{ {bufVarName}.WriteSize({fieldName}.size); for(let [_k, _v] of {fieldName}) {{ {type.KeyType.Apply(this, bufVarName, "_k")} {type.ValueType.Apply(this, bufVarName, "_v")} }} }}"; + } + } +} diff --git a/src/Luban.Job.Common/Source/Utils/RenderUtil.cs b/src/Luban.Job.Common/Source/Utils/RenderUtil.cs index fcb4c17..58efc2b 100644 --- a/src/Luban.Job.Common/Source/Utils/RenderUtil.cs +++ b/src/Luban.Job.Common/Source/Utils/RenderUtil.cs @@ -177,11 +177,9 @@ enum class {{name}} } - - [ThreadStatic] private static Template t_tsConstRender; - public static string RenderTsConstClass(DefConst c) + public static string RenderTypescriptConstClass(DefConst c) { var ctx = new TemplateContext(); var env = new TTypeTemplateCommonExtends @@ -192,15 +190,14 @@ enum class {{name}} var template = t_tsConstRender ??= Template.Parse(@" -namespace {{x.namespace_with_top_module}} -{ - export class {{x.name}} - { - {{~ for item in x.items ~}} - static {{item.name}} : {{ts_define_type item.ctype}} = {{ts_const_value item.ctype item.value}}; - {{~end~}} - } +{{typescript_namespace_begin}} + +export class {{x.name}} { + {{~ for item in x.items ~}} + static {{item.name}} = {{ts_const_value item.ctype item.value}}; + {{~end~}} } +{{typescript_namespace_end}} "); var result = template.Render(ctx); @@ -210,20 +207,17 @@ namespace {{x.namespace_with_top_module}} [ThreadStatic] private static Template t_tsEnumRender; - public static string RenderTsEnumClass(DefEnum e) + public static string RenderTypescriptEnumClass(DefEnum e) { var template = t_tsEnumRender ??= Template.Parse(@" -namespace {{namespace_with_top_module}} -{ - export enum {{name}} - { - {{- for item in items }} - {{item.name}} = {{item.value}}, - {{-end}} - } +{{typescript_namespace_begin}} + +export enum {{name}} { + {{- for item in items }} + {{item.name}} = {{item.value}}, + {{-end}} } - - +{{typescript_namespace_end}} "); var result = template.Render(e); diff --git a/src/Luban.Job.Proto/Source/Generate/TypescriptRender.cs b/src/Luban.Job.Proto/Source/Generate/TypescriptRender.cs new file mode 100644 index 0000000..1e6cec0 --- /dev/null +++ b/src/Luban.Job.Proto/Source/Generate/TypescriptRender.cs @@ -0,0 +1,231 @@ +锘縰sing Luban.Job.Common.Defs; +using Luban.Job.Common.Utils; +using Luban.Job.Proto.Defs; +using Scriban; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Proto.Generate +{ + class TypescriptRender + { + public string RenderAny(object o) + { + switch (o) + { + case DefConst c: return Render(c); + case DefEnum e: return Render(e); + case DefBean b: return Render(b); + case DefProto p: return Render(p); + case DefRpc r: return Render(r); + + default: throw new Exception($"unknown render type:{o}"); + } + } + + private string Render(DefConst c) + { + return RenderUtil.RenderTypescriptConstClass(c); + } + + private string Render(DefEnum e) + { + return RenderUtil.RenderTypescriptEnumClass(e); + } + + [ThreadStatic] + private static Template t_beanRender; + private string Render(DefBean b) + { + var template = t_beanRender ??= Template.Parse(@" +{{ + is_value_type = x.is_value_type + is_abstract_type = x.is_abstract_type + name = x.name + full_name = x.full_name + parent_def_type = x.parent_def_type + parent = x.parent + fields = x.fields + hierarchy_fields = x.hierarchy_fields +}} + + +{{x.typescript_namespace_begin}} + +export {{if x.is_abstract_type}} abstract {{end}} class {{name}} extends {{if parent_def_type}}{{x.parent}}{{else}}BeanBase{{end}} { +{{~if x.is_abstract_type~}} + static serializeTo(_buf_ : Bright.Serialization.ByteBuf, _bean_ : {{name}}) : void { + if (_bean_ == null) { + _buf_.WriteInt(0) + return + } + _buf_.WriteInt(_bean_.getTypeId()) + _bean_.serialize(_buf_) + } + + static deserializeFrom(_buf_ : Bright.Serialization.ByteBuf) : {{name}} { + let _bean_ :{{name}} + switch (_buf_.ReadInt()) { + case 0 : return null; + {{~ for child in x.hierarchy_not_abstract_children~}} + case {{child.id}}: _bean_ = new {{child.full_name}}(_buf_); break; + {{~end~}} + default: throw new Error(); + } + _bean_.deserialize(_buf_) + return _bean_ + } +{{else}} + static readonly ID = {{x.id}} + getTypeId() { return {{name}}.ID } +{{~end~}} + + + + {{~ for field in fields ~}} + {{field.ts_style_name}}{{if field.is_nullable}}?{{end}} : {{ts_define_type field.ctype}}; + {{~end~}} + + serialize(_buf_ : Bright.Serialization.ByteBuf) { + {{~if parent_def_type~}} + super.serialize(_buf_); + {{~end~}} + {{~ for field in fields ~}} + {{ts_bin_serialize ('this.' + field.ts_style_name) '_buf_' field.ctype}} + {{~end~}} + } + + deserialize(_buf_ : Bright.Serialization.ByteBuf) { + {{~if parent_def_type~}} + super.deserialize(_buf_); + {{~end~}} + {{~ for field in fields ~}} + {{ts_bin_deserialize ('this.' + field.ts_style_name) '_buf_' field.ctype}} + {{~end~}} + } + + toString(): string { + return ""{{full_name}}{ "" + {{~ for field in hierarchy_fields ~}} + + ""{{field.ts_style_name}}:"" + this.{{field.ts_style_name}} + "","" + {{~end~}} + + ""}""; + } +} +{{x.typescript_namespace_end}} +"); + var result = template.RenderCode(b); + + return result; + } + + [ThreadStatic] + private static Template t_protoRender; + private string Render(DefProto p) + { + var template = t_protoRender ??= Template.Parse(@" +{{ + name = x.name + full_name = x.full_name + parent = x.parent + fields = x.fields +}} +{{x.typescript_namespace_begin}} + +export class {{name}} extends Protocol { + static readonly ID = {{x.id}} + getTypeId() { return {{name}}.ID } + + + {{~ for field in fields ~}} + {{field.ts_style_name}}{{if field.is_nullable}}?{{end}} : {{ts_define_type field.ctype}}; + {{~end~}} + + serialize(_buf_ : Bright.Serialization.ByteBuf) { + {{~ for field in fields ~}} + {{ts_bin_serialize ('this.' + field.ts_style_name) '_buf_' field.ctype}} + {{~end~}} + } + + deserialize(_buf_ : Bright.Serialization.ByteBuf) { + {{~ for field in fields ~}} + {{ts_bin_deserialize ('this.' + field.ts_style_name) '_buf_' field.ctype}} + {{~end~}} + } + + toString(): string { + return ""{{full_name}}{ "" + {{~ for field in fields ~}} + + ""{{field.ts_style_name}}:"" + this.{{field.ts_style_name}} + "","" + {{~end~}} + + ""}""; + } +} +{{x.typescript_namespace_end}} +"); + var result = template.RenderCode(p); + + return result; + } + + [ThreadStatic] + private static Template t_rpcRender; + private string Render(DefRpc r) + { + var template = t_rpcRender ??= Template.Parse(@" +{{ + name = x.name + full_name = x.full_name + parent = x.parent + fields = x.fields + targ_type = x.targ_type + tres_type = x.tres_type +}} + +// TODO {{full_name}} + +"); + var result = template.RenderCode(r); + + return result; + } + + [ThreadStatic] + private static Template t_stubRender; + public string RenderStubs(string name, string module, List protos, List rpcs) + { + var template = t_stubRender ??= Template.Parse(@" + + type ProtocolFactory = () => Protocol + + export class {{name}} { + static readonly Factories = new Map([ + + {{~ for proto in protos ~}} + [{{proto.full_name}}.ID, () => new {{proto.full_name}}()], + {{~end~}} + + {{~ for rpc in rpcs ~}} + // TODO RPC .. [{{rpc.full_name}}.ID] = () => new {{rpc.full_name}}(), + {{~end~}} + ]) + } + + + +"); + var result = template.Render(new + { + Name = name, + Namespace = module, + Protos = protos, + Rpcs = rpcs, + }); + + return result; + } + } +} diff --git a/src/Luban.Job.Proto/Source/JobController.cs b/src/Luban.Job.Proto/Source/JobController.cs index 2e432c6..1b2b37b 100644 --- a/src/Luban.Job.Proto/Source/JobController.cs +++ b/src/Luban.Job.Proto/Source/JobController.cs @@ -1,6 +1,7 @@ using CommandLine; using Luban.Common.Protos; using Luban.Common.Utils; +using Luban.Job.Common; using Luban.Job.Common.Defs; using Luban.Job.Common.Utils; using Luban.Job.Proto.Defs; @@ -30,7 +31,7 @@ namespace Luban.Job.Proto [Option('c', "output_code_dir", Required = true, HelpText = "output code directory")] public string OutputCodeDir { get; set; } - [Option('g', "gen_type", Required = true, HelpText = "cs,lua,java,cpp")] + [Option('g', "gen_type", Required = true, HelpText = "cs,lua,java,cpp,ts")] public string GenType { get; set; } [Option('s', "service", Required = true, HelpText = "service")] @@ -145,6 +146,132 @@ namespace Luban.Job.Proto })); break; } + case "ts": + { + var render = new TypescriptRender(); + + tasks.Add(Task.Run(() => + { + var fileContent = new List + { + @$" +import {{Bright}} from 'csharp' + +export namespace {ass.TopModule} {{ +", + + @" +export interface ISerializable { + serialize(_buf_: Bright.Serialization.ByteBuf) : void + deserialize(_buf_: Bright.Serialization.ByteBuf) : void +} + +export abstract class BeanBase implements ISerializable { + abstract getTypeId() : number + abstract serialize(_buf_: Bright.Serialization.ByteBuf): void + abstract deserialize(_buf_: Bright.Serialization.ByteBuf): void +} + +export abstract class Protocol implements ISerializable { + abstract getTypeId() : number + abstract serialize(_buf_: Bright.Serialization.ByteBuf): void + abstract deserialize(_buf_: Bright.Serialization.ByteBuf): void +} + +export class Vector2 { + x: number; + y: number; + constructor(x: number, y: number) { + this.x = x; + this.y = y; + } + + to(_buf_: Bright.Serialization.ByteBuf) { + _buf_.WriteFloat(this.x) + _buf_.WriteFloat(this.y) + } + + static from(_buf_: Bright.Serialization.ByteBuf): Vector2 { + let x = _buf_.ReadFloat(); + let y = _buf_.ReadFloat(); + return new Vector2(x, y); + } + } + + + export class Vector3 { + x: number; + y: number; + z: number; + constructor(x: number, y: number, z: number) { + this.x = x; + this.y = y; + this.z = z; + } + + to(_buf_: Bright.Serialization.ByteBuf) { + _buf_.WriteFloat(this.x) + _buf_.WriteFloat(this.y) + _buf_.WriteFloat(this.z) + } + + static from(_buf_: Bright.Serialization.ByteBuf): Vector3 { + let x = _buf_.ReadFloat(); + let y = _buf_.ReadFloat(); + let z = _buf_.ReadFloat(); + return new Vector3(x, y, z); + } + } + + export class Vector4 { + x: number; + y: number; + z: number; + w: number; + constructor(x: number, y: number, z: number, w: number) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + to(_buf_: Bright.Serialization.ByteBuf) { + _buf_.WriteFloat(this.x) + _buf_.WriteFloat(this.y) + _buf_.WriteFloat(this.z) + _buf_.WriteFloat(this.w) + } + + static from(_buf_: Bright.Serialization.ByteBuf): Vector4 { + let x = _buf_.ReadFloat(); + let y = _buf_.ReadFloat(); + let z = _buf_.ReadFloat(); + let w = _buf_.ReadFloat(); + return new Vector4(x, y, z, w); + } + } + +" + }; + + foreach (var type in exportTypes) + { + fileContent.Add(render.RenderAny(type)); + } + + fileContent.Add(render.RenderStubs("ProtocolStub", ass.TopModule, ass.Types.Values.Where(t => t is DefProto).ToList(), + ass.Types.Values.Where(t => t is DefRpc).ToList())); + + fileContent.Add("}"); // end of topmodule + + var content = FileHeaderUtil.ConcatAutoGenerationHeader(string.Join('\n', fileContent), ELanguage.TYPESCRIPT); + var file = "Types.ts"; + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); + genCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + + break; + } default: { throw new NotSupportedException($"not support gen type:{genType}");