diff --git a/src/Luban.Job.Cfg/Source/JobController.cs b/src/Luban.Job.Cfg/Source/JobController.cs index 8fc9399..778d6f3 100644 --- a/src/Luban.Job.Cfg/Source/JobController.cs +++ b/src/Luban.Job.Cfg/Source/JobController.cs @@ -32,7 +32,7 @@ namespace Luban.Job.Cfg { private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger(); - class GenCfgArgs + class GenArgs { [Option('d', "define_file", Required = true, HelpText = "define file")] public string DefineFile { get; set; } @@ -49,7 +49,7 @@ namespace Luban.Job.Cfg [Option("output_data_dir", Required = true, HelpText = "output data directory")] public string OutputDataDir { get; set; } - [Option("gen_types", Required = true, HelpText = "cs_bin,cs_json,lua_bin,go_bin,cpp_ue_editor,cs_unity_editor can be multi")] + [Option("gen_types", Required = true, HelpText = "code_cs_bin,code_cs_json,code_lua_bin,data_bin,data_lua,data_json can be multi")] public string GenType { get; set; } [Option('s', "service", Required = true, HelpText = "service")] @@ -113,14 +113,14 @@ namespace Luban.Job.Cfg } - private bool TryParseArg(List args, out GenCfgArgs result, out string errMsg) + private bool TryParseArg(List args, out GenArgs result, out string errMsg) { var helpWriter = new StringWriter(); var parser = new Parser(ps => { ps.HelpWriter = helpWriter; }); ; - var parseResult = parser.ParseArguments(args); + var parseResult = parser.ParseArguments(args); if (parseResult.Tag == ParserResultType.NotParsed) { errMsg = helpWriter.ToString(); @@ -129,7 +129,7 @@ namespace Luban.Job.Cfg } else { - result = (parseResult as Parsed).Value; + result = (parseResult as Parsed).Value; errMsg = null; string inputDataDir = result.InputDataDir; @@ -170,7 +170,7 @@ namespace Luban.Job.Cfg FileGroups = new List(), }; - if (!TryParseArg(rpc.Arg.JobArguments, out GenCfgArgs args, out string errMsg)) + if (!TryParseArg(rpc.Arg.JobArguments, out GenArgs args, out string errMsg)) { res.ErrCode = Luban.Common.EErrorCode.JOB_ARGUMENT_ERROR; res.ErrMsg = errMsg; diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/DeepCompareTypeDefine.cs b/src/Luban.Job.Cfg/Source/TypeVisitors/DeepCompareTypeDefine.cs index adbcd90..0c49151 100644 --- a/src/Luban.Job.Cfg/Source/TypeVisitors/DeepCompareTypeDefine.cs +++ b/src/Luban.Job.Cfg/Source/TypeVisitors/DeepCompareTypeDefine.cs @@ -137,7 +137,7 @@ namespace Luban.Job.Cfg.TypeVisitors } else { - if (b.Children == null) + if (b.Children == null || a.Children.Count != b.Children.Count) { return setupNotEqual(); } diff --git a/src/Luban.Job.Common/Source/Defs/CommonDefLoader.cs b/src/Luban.Job.Common/Source/Defs/CommonDefLoader.cs index d3fd4a3..3aef447 100644 --- a/src/Luban.Job.Common/Source/Defs/CommonDefLoader.cs +++ b/src/Luban.Job.Common/Source/Defs/CommonDefLoader.cs @@ -194,14 +194,15 @@ namespace Luban.Job.Common.Defs _namespaceStack.Pop(); } - private static readonly List _fieldRequireAttrs = new List { "name", "id", "type", }; + private static readonly List _fieldRequireAttrs = new List { "name", "type", }; + private static readonly List _fieldOptionalAttrs = new List { "id", }; protected virtual Field CreateField(XElement e) { - ValidAttrKeys(e, null, _fieldRequireAttrs); + ValidAttrKeys(e, _fieldOptionalAttrs, _fieldRequireAttrs); var f = new Field() { - Id = XmlUtil.GetRequiredIntAttribute(e, "id"), + Id = XmlUtil.GetOptionIntAttribute(e, "id"), Name = XmlUtil.GetRequiredAttribute(e, "name"), Type = CreateType(e, "type"), }; diff --git a/src/Luban.Job.Common/Source/Defs/DefBeanBase.cs b/src/Luban.Job.Common/Source/Defs/DefBeanBase.cs index 7b13e5d..3501a7e 100644 --- a/src/Luban.Job.Common/Source/Defs/DefBeanBase.cs +++ b/src/Luban.Job.Common/Source/Defs/DefBeanBase.cs @@ -147,16 +147,16 @@ namespace Luban.Job.Common.Defs var ids = new HashSet(); foreach (var c in cs) { - if (c.Id == 0) + if (c.Id <= 0) { - throw new Exception($"bean:{FullName} is child of dynamic type. beanid:{Id} can't be 0!"); + throw new Exception($"bean:{FullName} is child of dynamic type. beanid:{Id} can't less then 0!"); } if (!ids.Add(c.Id)) { throw new Exception($"bean:{c.FullName} beanid:{c.Id} duplicate!"); } } - DefFieldBase.CompileFields(this, HierarchyFields, true); + DefFieldBase.CompileFields(this, HierarchyFields, IsSerializeCompatible); } public override void PostCompile() diff --git a/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs b/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs index a07d77c..eca978a 100644 --- a/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs +++ b/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs @@ -6,6 +6,11 @@ namespace Luban.Job.Common.Defs { public class TTypeTemplateCommonExtends : ScriptObject { + public static bool CsNeedInit(TType type) + { + return type.Apply(CsNeedInitVisitor.Ins); + } + public static string CsDefineType(TType type) { return type.Apply(CsDefineTypeName.Ins); diff --git a/src/Luban.Job.Common/Source/TypeVisitors/CsNeedInitVisitor.cs b/src/Luban.Job.Common/Source/TypeVisitors/CsNeedInitVisitor.cs new file mode 100644 index 0000000..e0a38fe --- /dev/null +++ b/src/Luban.Job.Common/Source/TypeVisitors/CsNeedInitVisitor.cs @@ -0,0 +1,54 @@ +using 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 +{ + public class CsNeedInitVisitor : AllFalseVisitor + { + public static CsNeedInitVisitor Ins { get; } = new CsNeedInitVisitor(); + + public override bool Accept(TString type) + { + return true; + } + + public override bool Accept(TText type) + { + return true; + } + + public override bool Accept(TBytes type) + { + return true; + } + + public override bool Accept(TArray type) + { + return true; + } + + public override bool Accept(TList type) + { + return true; + } + + public override bool Accept(TSet type) + { + return true; + } + + public override bool Accept(TMap type) + { + return true; + } + + public override bool Accept(TBean type) + { + return !type.IsDynamic; + } + } +} diff --git a/src/Luban.Job.Common/Source/TypeVisitors/CsUnderingDefineTypeName.cs b/src/Luban.Job.Common/Source/TypeVisitors/CsUnderingDefineTypeName.cs index e8c18ea..700d4b3 100644 --- a/src/Luban.Job.Common/Source/TypeVisitors/CsUnderingDefineTypeName.cs +++ b/src/Luban.Job.Common/Source/TypeVisitors/CsUnderingDefineTypeName.cs @@ -88,17 +88,17 @@ namespace Luban.Job.Common.TypeVisitors public string Accept(TList type) { - return $"List<{type.ElementType.Apply(this)}>"; + return $"System.Collections.Generic.List<{type.ElementType.Apply(this)}>"; } public string Accept(TSet type) { - return $"HashSet<{type.ElementType.Apply(this)}>"; + return $"System.Collections.Generic.HashSet<{type.ElementType.Apply(this)}>"; } public string Accept(TMap type) { - return $"Dictionary<{type.KeyType.Apply(this)}, {type.ValueType.Apply(this)}>"; + return $"System.Collections.Generic.Dictionary<{type.KeyType.Apply(this)}, {type.ValueType.Apply(this)}>"; } public string Accept(TVector2 type) diff --git a/src/Luban.Job.Proto/Luban.Job.Proto.csproj b/src/Luban.Job.Proto/Luban.Job.Proto.csproj index c23729e..e3fda32 100644 --- a/src/Luban.Job.Proto/Luban.Job.Proto.csproj +++ b/src/Luban.Job.Proto/Luban.Job.Proto.csproj @@ -5,12 +5,6 @@ net5.0 - - - - - - diff --git a/src/Luban.Job.Proto/Source/Defs/DefAssembly.cs b/src/Luban.Job.Proto/Source/Defs/DefAssembly.cs index 9c161f9..e208f4a 100644 --- a/src/Luban.Job.Proto/Source/Defs/DefAssembly.cs +++ b/src/Luban.Job.Proto/Source/Defs/DefAssembly.cs @@ -3,6 +3,7 @@ using Luban.Job.Proto.RawDefs; using Luban.Server.Common; using System; using System.Collections.Generic; +using System.Linq; namespace Luban.Job.Proto.Defs { @@ -107,5 +108,10 @@ namespace Luban.Job.Proto.Defs } } + + public List GetExportTypes() + { + return Types.Values.ToList(); + } } } diff --git a/src/Luban.Job.Proto/Source/Defs/ProtoDefLoader.cs b/src/Luban.Job.Proto/Source/Defs/ProtoDefLoader.cs index 150f628..b54f0b9 100644 --- a/src/Luban.Job.Proto/Source/Defs/ProtoDefLoader.cs +++ b/src/Luban.Job.Proto/Source/Defs/ProtoDefLoader.cs @@ -25,7 +25,15 @@ namespace Luban.Job.Proto.Defs public Defines BuildDefines() { - return new Defines(); + return new Defines() + { + TopModule = TopModule, + Consts = _consts, + Enums = _enums, + Beans = _beans, + Protos = _protos, + Rpcs = _rpcs, + }; } private readonly List rpcAttrs = new List { "id" }; @@ -90,11 +98,7 @@ namespace Luban.Job.Proto.Defs { s_logger.Trace("service {service_name} node: {name} {value}", name, ele.Name, ele.Attribute("value")?.Value); } - } - - protected override void AddBean(XElement e, string parent) - { - throw new NotImplementedException(); + //TODO service } } } diff --git a/src/Luban.Job.Proto/Source/Defs/TTypeTemplateExtends.cs b/src/Luban.Job.Proto/Source/Defs/TTypeTemplateExtends.cs new file mode 100644 index 0000000..0e1a850 --- /dev/null +++ b/src/Luban.Job.Proto/Source/Defs/TTypeTemplateExtends.cs @@ -0,0 +1,45 @@ +using Luban.Job.Common.Defs; +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; +using Luban.Job.Proto.TypeVisitors; + +namespace Luban.Job.Proto.Defs +{ + class TTypeTemplateExtends : TTypeTemplateCommonExtends + { + public static string CsSerialize(string bufName, string fieldName, TType type) + { + return type.Apply(CsSerializeVisitor.Ins, bufName, fieldName); + } + + public static string CsCompatibleSerialize(string bufName, string fieldName, TType type) + { + return type.Apply(CsSerializeVisitor.Ins, bufName, fieldName); + } + + public static string CsDeserialize(string bufName, string fieldName, TType type) + { + return type.Apply(CsDeserializeVisitor.Ins, bufName, fieldName); + } + + public static string CsCompatibleDeserialize(string bufName, string fieldName, TType type) + { + return type.Apply(CsDeserializeVisitor.Ins, bufName, fieldName); + } + + public static string LuaCommentType(TType type) + { + return type.Apply(LuaCommentTypeVisitor.Ins); + } + + public static string LuaUnderingDeserialize(string bufName, TType type) + { + return type.Apply(LuaUnderingDeserializeVisitor.Ins, bufName); + } + + public static string CsInitFieldCtorValue(DefField field) + { + return $"{field.CsStyleName} = default;"; + } + } +} diff --git a/src/Luban.Job.Proto/Source/Generate/CsRender.cs b/src/Luban.Job.Proto/Source/Generate/CsRender.cs index a3e972a..eafbffd 100644 --- a/src/Luban.Job.Proto/Source/Generate/CsRender.cs +++ b/src/Luban.Job.Proto/Source/Generate/CsRender.cs @@ -23,50 +23,58 @@ namespace Luban.Job.Proto.Generate } } - public string Render(DefConst c) + private string Render(DefConst c) { return RenderUtil.RenderCsConstClass(c); } - public string Render(DefEnum e) + private string Render(DefEnum e) { return RenderUtil.RenderCsEnumClass(e); } [ThreadStatic] private static Template t_beanRender; - public string Render(DefBean b) + 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 +}} using Bright.Serialization; -namespace {{namespace_with_top_module}} +namespace {{x.namespace_with_top_module}} { - public {{if is_value_type}}struct{{else}}{{cs_class_modifier}} class{{end}} {{name}} : {{if parent_def_type}} {{parent}} {{else}} BeanBase {{end}} + public {{if is_value_type}}struct{{else}}{{x.cs_class_modifier}} class{{end}} {{name}} : {{if parent_def_type}} {{parent}} {{else}} Bright.Serialization.BeanBase {{end}} { - {{if !is_value_type}} + {{~if !is_value_type~}} public {{name}}() { } - {{end}} + {{~end~}} public {{name}}(Bright.Common.NotNullInitialization _) {{if parent_def_type}} : base(_) {{end}} { - {{if is_value_type}} - {{- for field in fields }} - {{if field.ctype.need_init}}{{field.proto_cs_init_field}}{{else}}{{field.proto_cs_init_field_default_value}} {{end}} - {{-end}} - {{else}} - {{- for field in fields }} - {{if field.ctype.need_init}}{{field.proto_cs_init_field}}{{end}} - {{-end}} - {{end}} + {{~ for field in fields ~}} + {{~if cs_need_init field.ctype~}} + {{cs_init_field_ctor_value field}} + {{~else if is_value_type~}} + {field.cs_style_name} = default; + {{~end~}} + {{~end~}} } public static void Serialize{{name}}(ByteBuf _buf, {{name}} x) { - {{if is_abstract_type}} + {{~if is_abstract_type~}} if (x != null) { _buf.WriteInt(x.GetTypeId()); @@ -76,99 +84,106 @@ namespace {{namespace_with_top_module}} { _buf.WriteInt(0); } - {{else}} + {{~else~}} x.Serialize(_buf); - {{end}} + {{~end~}} } public static {{name}} Deserialize{{name}}(ByteBuf _buf) { - {{if is_abstract_type}} + {{~if is_abstract_type~}} {{full_name}} x; switch (_buf.ReadInt()) { case 0 : return null; - {{- for child in hierarchy_not_abstract_children}} + {{- for child in x.hierarchy_not_abstract_children}} case {{child.full_name}}.ID: x = new {{child.full_name}}(); break; {{-end}} default: throw new SerializationException(); } x.Deserialize(_buf); - {{else}} + {{~else~}} var x = new {{full_name}}(); x.Deserialize(_buf); - {{end}} + {{~end~}} return x; } - {{- for field in fields }} - public {{field.ctype.cs_define_type}} {{field.lan_style_name}}; - {{-end}} + {{~ for field in fields ~}} + public {{cs_define_type field.ctype}} {{field.cs_style_name}}; + {{~end~}} - {{if !is_abstract_type}} - public const int ID = {{id}}; - public override int GetTypeId() => ID; - {{end}} + {{~if !is_abstract_type~}} + public const int ID = {{x.id}}; + public override int GetTypeId() => ID; public override void Serialize(ByteBuf _buf) { - {{if parent_def_type}} base.Serialize(_buf); {{end}} - {{- for field in fields }} - {{field.cs_serialize}} - {{-end}} + {{~ for field in hierarchy_fields ~}} + {{cs_serialize '_buf' field.cs_style_name field.ctype}} + {{~end~}} } public override void Deserialize(ByteBuf _buf) { - {{if parent_def_type}} base.Deserialize(_buf); {{end}} - {{- for field in fields }} - {{field.cs_deserialize}} - {{-end}} + {{~ for field in hierarchy_fields ~}} + {{cs_deserialize '_buf' field.cs_style_name field.ctype}} + {{~end~}} } public override string ToString() { return ""{{full_name}}{ "" - {{- for field in hierarchy_fields }} - + ""{{field.lan_style_name}}:"" + {{field.proto_cs_to_string}} + "","" - {{-end}} + {{~ for field in hierarchy_fields ~}} + + ""{{field.cs_style_name}}:"" + {{cs_to_string field.cs_style_name field.ctype}} + "","" + {{~end~}} + ""}""; } + {{~end~}} } } "); - var result = template.Render(b); + var result = template.RenderCode(b); return result; } [ThreadStatic] private static Template t_protoRender; - public string Render(DefProto p) + 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 +}} using Bright.Serialization; -namespace {{namespace_with_top_module}} +namespace {{x.namespace_with_top_module}} { public sealed class {{name}} : Bright.Net.Codecs.Protocol { - {{- for field in fields }} - public {{field.ctype.cs_define_type}} {{field.lan_style_name}}; - {{-end}} + {{~ for field in fields ~}} + public {{cs_define_type field.ctype}} {{field.cs_style_name}}; + {{~end~}} + public {{name}}() { } public {{name}}(Bright.Common.NotNullInitialization _) { - {{- for field in fields }} - {{if field.ctype.need_init}}{{field.proto_cs_init_field}}{{end}} - {{-end}} + {{~ for field in fields ~}} + {{~if field.ctype.need_init~}} + {{cs_init_field_ctor_value field}} + {{~end~}} + {{~end~}} } - public const int ID = {{id}}; + public const int ID = {{x.id}}; public override int GetTypeId() { @@ -177,16 +192,16 @@ namespace {{namespace_with_top_module}} public override void Serialize(ByteBuf _buf) { - {{- for field in fields }} + {{~ for field in fields ~}} {{field.cs_serialize}} - {{-end}} + {{~end~}} } public override void Deserialize(ByteBuf _buf) { - {{- for field in fields }} + {{~ for field in fields ~}} {{field.cs_deserialize}} - {{-end}} + {{~end~}} } public override void Reset() @@ -202,9 +217,9 @@ namespace {{namespace_with_top_module}} public override string ToString() { return ""{{full_name}}{ "" - {{- for field in fields }} - + ""{{field.lan_style_name}}:"" + {{field.proto_cs_to_string}} + "","" - {{-end}} + {{~ for field in fields ~}} + + ""{{field.cs_style_name}}:"" + {{cs_to_string field.cs_style_name field.ctype}} + "","" + {{~end~}} + ""}""; } } @@ -212,54 +227,42 @@ namespace {{namespace_with_top_module}} } "); - var result = template.Render(p); + var result = template.RenderCode(p); return result; } [ThreadStatic] private static Template t_rpcRender; - public string Render(DefRpc r) + 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 +}} using Bright.Serialization; -namespace {{namespace_with_top_module}} +namespace {{x.namespace_with_top_module}} { - public sealed class {{name}} : Bright.Net.Codecs.Rpc<{{targ_type.cs_define_type}}, {{tres_type.cs_define_type}}> + public sealed class {{name}} : Bright.Net.Codecs.Rpc<{{cs_define_type targ_type}}, {{cs_define_type tres_type}}> { public {{name}}() { } - public const int ID = {{id}}; + public const int ID = {{x.id}}; public override int GetTypeId() { return ID; } - public override void SerializeArg(ByteBuf buf, {{targ_type.cs_define_type}} arg) - { - {{targ_type.cs_define_type}}.Serialize{{targ_type.bean.name}}(buf, arg); - } - - public override {{targ_type.cs_define_type}} DeserializeArg(ByteBuf buf) - { - return {{targ_type.cs_define_type}}.Deserialize{{targ_type.bean.name}}(buf); - } - - public override void SerializeRes(ByteBuf buf, {{tres_type.cs_define_type}} res) - { - {{tres_type.cs_define_type}}.Serialize{{tres_type.bean.name}}(buf, res); - } - - public override {{tres_type.cs_define_type}} DeserializeRes(ByteBuf buf) - { - return {{tres_type.cs_define_type}}.Deserialize{{tres_type.bean.name}}(buf); - } - public override void Reset() { throw new System.NotImplementedException(); @@ -278,14 +281,14 @@ namespace {{namespace_with_top_module}} } "); - var result = template.Render(r); + var result = template.RenderCode(r); return result; } [ThreadStatic] private static Template t_stubRender; - public string RenderStubs(string name, string module, List protos, List rpcs) + public string RenderStubs(string name, string module, List protos, List rpcs) { var template = t_stubRender ??= Template.Parse(@" using Bright.Serialization; @@ -297,13 +300,13 @@ namespace {{namespace}} { public static System.Collections.Generic.Dictionary Factories { get; } = new System.Collections.Generic.Dictionary { - {{- for proto in protos }} + {{~ for proto in protos ~}} [{{proto.full_name}}.ID] = () => new {{proto.full_name}}(), - {{-end}} + {{~end~}} - {{- for rpc in rpcs }} + {{~ for rpc in rpcs ~}} [{{rpc.full_name}}.ID] = () => new {{rpc.full_name}}(), - {{-end}} + {{~end~}} }; } diff --git a/src/Luban.Job.Proto/Source/GenerateProto.cs b/src/Luban.Job.Proto/Source/GenerateProto.cs deleted file mode 100644 index bdfc84d..0000000 --- a/src/Luban.Job.Proto/Source/GenerateProto.cs +++ /dev/null @@ -1,56 +0,0 @@ -//using Bright.Time; -//using Gen.Proto.Common.RawDefs; -//using Luban.Job.Common.Utils; - -//namespace Luban.Job.Proto.Client -//{ -// class GenerateProto -// { -// public bool Handle(CommandLineOptions options) -// { -// var timer = new ProfileTimer(); -// timer.StartPhase("所有阶段"); - -// timer.StartPhase("加载定义"); -// var protoLoader = new ProtoDefLoader(); -// protoLoader.Load(options.DefineFile); -// long defEndTime = TimeUtil.NowMillis; -// timer.EndPhaseAndLog(); - - -// timer.StartPhase("发起 GenProto"); -// string outputDir = options.OutputCodeDir; - -// var defines = protoLoader.BuildDefines(); - - -// defines.Target = options.Target; -// defines.Language = options.Languange; -// var rpc = new GenProto(); -// var res = rpc.Call(GenClient.Ins.Session, new GenProtoArg() -// { -// Define = defines, -// OutputCodeRelatePath = outputDir, -// }).Result; -// timer.EndPhaseAndLog(); - - -// if (res.OK) -// { -// timer.StartPhase("获取生成文件"); - -// DownloadFileUtil.DownloadGeneratedFiles(outputDir, res.NewCodeFiles).Wait(); - -// timer.EndPhaseAndLog(); - -// timer.EndPhaseAndLog(); -// return true; -// } -// else -// { -// timer.EndPhaseAndLog(); -// return false; -// } -// } -// } -//} diff --git a/src/Luban.Job.Proto/Source/JobController.cs b/src/Luban.Job.Proto/Source/JobController.cs index d53e3e7..0bda24c 100644 --- a/src/Luban.Job.Proto/Source/JobController.cs +++ b/src/Luban.Job.Proto/Source/JobController.cs @@ -1,16 +1,169 @@ +using CommandLine; using Luban.Common.Protos; +using Luban.Common.Utils; +using Luban.Job.Common.Defs; +using Luban.Job.Common.Utils; +using Luban.Job.Proto.Defs; +using Luban.Job.Proto.Generate; +using Luban.Job.Proto.RawDefs; using Luban.Server.Common; using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Threading.Tasks; +using FileInfo = Luban.Common.Protos.FileInfo; namespace Luban.Job.Proto { [Controller("proto")] public class JobController : IJobController { - public Task GenAsync(RemoteAgent agent, GenJob rpc) + private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger(); + + class GenArgs { - throw new NotImplementedException(); + [Option('d', "define_file", Required = true, HelpText = "define file")] + public string DefineFile { get; set; } + + [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")] + public string GenType { get; set; } + + [Option('s', "service", Required = true, HelpText = "service")] + public string Service { get; set; } + } + + + private bool TryParseArg(List args, out GenArgs result, out string errMsg) + { + var helpWriter = new StringWriter(); + var parser = new Parser(ps => + { + ps.HelpWriter = helpWriter; + }); ; + var parseResult = parser.ParseArguments(args); + if (parseResult.Tag == ParserResultType.NotParsed) + { + errMsg = helpWriter.ToString(); + result = null; + return false; + } + + result = (parseResult as Parsed).Value; + errMsg = null; + return true; + } + + public async Task GenAsync(RemoteAgent agent, GenJob rpc) + { + var res = new GenJobRes() + { + ErrCode = Luban.Common.EErrorCode.OK, + ErrMsg = "succ", + FileGroups = new List(), + }; + + if (!TryParseArg(rpc.Arg.JobArguments, out GenArgs args, out string errMsg)) + { + res.ErrCode = Luban.Common.EErrorCode.JOB_ARGUMENT_ERROR; + res.ErrMsg = errMsg; + agent.Session.ReplyRpc(rpc, res); + return; + } + + var timer = new ProfileTimer(); + timer.StartPhase("= gen_all ="); + try + { + string outputCodeDir = args.OutputCodeDir; + + + timer.StartPhase("build defines"); + var loader = new ProtoDefLoader(agent); + await loader.LoadAsync(args.DefineFile); + timer.EndPhaseAndLog(); + + var rawDefines = loader.BuildDefines(); + + var ass = new DefAssembly(); + + ass.Load(rawDefines, agent); + + var targetService = args.Service; + + + List exportTypes = ass.GetExportTypes(); + + var tasks = new List(); + var genCodeFiles = new ConcurrentBag(); + + + var genType = args.GenType; + switch (genType) + { + case "cs": + { + var render = new CsRender(); + foreach (var c in ass.Types.Values) + { + tasks.Add(Task.Run(() => + { + var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAny(c), Common.ELanguage.CS); + var file = RenderFileUtil.GetDefTypePath(c.FullName, Common.ELanguage.CS); + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); + genCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + } + tasks.Add(Task.Run(() => + { + var module = ass.TopModule; + var name = "ProtocolStub"; + var content = FileHeaderUtil.ConcatAutoGenerationHeader( + render.RenderStubs(name, module, + ass.Types.Values.Where(t => t is DefProto).ToList(), + ass.Types.Values.Where(t => t is DefRpc).ToList()), + Common.ELanguage.CS); + var file = RenderFileUtil.GetDefTypePath(name, Common.ELanguage.CS); + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); + genCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + break; + } + case "lua": + { + tasks.Add(Task.Run(() => + { + var render = new LuaRender(); + var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderTypes(ass.Types.Values.ToList()), Common.ELanguage.LUA); + var file = "ProtoTypes.lua"; + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); + genCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + break; + } + default: + { + throw new NotSupportedException($"not support gen type:{genType}"); + } + + } + + await Task.WhenAll(tasks.ToArray()); + + res.FileGroups.Add(new FileGroup() { Dir = outputCodeDir, Files = genCodeFiles.ToList() }); + } + catch (Exception e) + { + res.ErrCode = Luban.Common.EErrorCode.JOB_EXCEPTION; + res.ErrMsg = $"{e.Message} \n {e.StackTrace}"; + } + timer.EndPhaseAndLog(); + + agent.Session.ReplyRpc(rpc, res); } } } diff --git a/src/Luban.Job.Proto/Source/RawDefs/Defines.cs b/src/Luban.Job.Proto/Source/RawDefs/Defines.cs index 34bfe46..fe0dcc9 100644 --- a/src/Luban.Job.Proto/Source/RawDefs/Defines.cs +++ b/src/Luban.Job.Proto/Source/RawDefs/Defines.cs @@ -5,10 +5,6 @@ namespace Luban.Job.Proto.RawDefs { public class Defines { - public string Target { get; set; } = "*"; - - public string Language { get; set; } = "cs"; - public string TopModule { get; set; } = ""; public List ProtoServices { get; set; } = new List(); diff --git a/src/Luban.Job.Proto/Source/RenderExtension.cs b/src/Luban.Job.Proto/Source/RenderExtension.cs new file mode 100644 index 0000000..a167392 --- /dev/null +++ b/src/Luban.Job.Proto/Source/RenderExtension.cs @@ -0,0 +1,27 @@ +using Luban.Job.Proto.Defs; +using Scriban; +using System.Collections.Generic; + +namespace Luban.Job.Proto +{ + public static class RenderExtension + { + public static string RenderCode(this Template template, object model, Dictionary extraModels = null) + { + var ctx = new TemplateContext(); + var env = new TTypeTemplateExtends + { + ["x"] = model + }; + if (extraModels != null) + { + foreach ((var k, var v) in extraModels) + { + env[k] = v; + } + } + ctx.PushGlobal(env); + return template.Render(ctx); + } + } +} diff --git a/src/Luban.Job.Proto/Source/RpcController.cs b/src/Luban.Job.Proto/Source/RpcController.cs deleted file mode 100644 index c8acc9e..0000000 --- a/src/Luban.Job.Proto/Source/RpcController.cs +++ /dev/null @@ -1,623 +0,0 @@ -namespace Luban.Job.Proto.Server.Net -{ - class RpcController - { - - //private void LogException(IContext ctx, Exception e) - //{ - // if (e is AggregateException ae) - // { - // foreach (var ie in ae.InnerExceptions) - // { - // LogException(ctx, ie); - // } - // } - // else - // { - - // s_logger.Error(e, "发生异常"); - // ctx.Error(e, " {0} \n ", e.StackTrace); - // } - //} - - //private bool ValidateDataType(string outputDataType) - //{ - // switch (outputDataType) - // { - // case "bin": - // case "cbin": - // case "json": return true; - // default: return false; - // } - //} - - //private void OnGenDb(Session session, GenDb proto) - //{ - // var timer = new ProfileTimer(); - - // timer.StartPhase("生成代码"); - - // var res = new GenDbRes(); - - // string relatePath = proto.Arg.OutputCodeRelatePath; - - // var ass = new DefAssembly(); - // var ctx = new SessionContext(session, proto.Arg.Verbose); - // try - // { - // var genCodeTasks = new List(); - // var outputFiles = new ConcurrentBag(); - - // ass.Load(EJobType.DB, proto.Arg.Define, ctx); - // var render = new Generate.Db.CsRender(); - // foreach (var c in ass.Types.Values) - // { - // genCodeTasks.Add(Task.Run(() => - // { - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cs"); - // var file = FileUtil.GetCsDefTypePath(c.FullName); - // var md5 = GenMd5AndAddCache(file, content); - // outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // } - // genCodeTasks.Add(Task.Run(() => - // { - // var module = ass.TopModule; - // var name = "Tables"; - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderTables(name, module, ass.Types.Values.Where(t => t is BTable).ToList()), "cs"); - // var file = FileUtil.GetCsDefTypePath(name); - // var md5 = GenMd5AndAddCache(file, content); - // outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // Task.WhenAll(genCodeTasks).Wait(); - // ctx.Info(timer.EndPhaseAndLogToString()); - - // res.NewCodeFiles = outputFiles.ToList(); - // res.OK = true; - // } - // catch (Exception e) - // { - // res.OK = false; - // LogException(ctx, e); - // } - - // proto.ReturnResult(session, res); - //} - - //private ICsCodeRender CreateCsCodeRender(string outputDataType) - //{ - // switch (outputDataType) - // { - // case "bin": return new AppCsBinCodeRender(); - // case "cbin": return new AppCsCompatibleBinCodeRender(); - // case "json": return new AppCsJsonCodeRender(); - // default: throw new ArgumentException($"not support output data type:{outputDataType}"); - // } - //} - - //private void OnGenCfg(Session session, GenCfg proto) - //{ - // var res = new GenCfgRes(); - - // string lan = proto.Arg.Define.Language; - - // DefAssembly ass = new DefAssembly(); - - // var ctx = new SessionContext(session, proto.Arg.Verbose); - - - // var allJobs = new List(); - - - // try - // { - // string outputDataType = proto.Arg.OutputDataType; - // if (!ValidateDataType(outputDataType)) - // { - // throw new ArgumentException($"unknown outputdatatype:{outputDataType}"); - // } - - // bool exportTestData = proto.Arg.ExportTestData; - - // long genStartTime = TimeUtil.NowMillis; - // var genCodeTasks = new List(); - // var outputCodeFiles = new ConcurrentBag(); - - // ass.Load(EJobType.CONFIG, proto.Arg.Define, ctx); - // EGenTypes genTypes = proto.Arg.GenTypes; - // var targetService = ass.CfgTargetService; - - // List exportTables = ass.Types.Values.Where(t => t is CTable ct && ct.NeedExport).Select(t => (CTable)t).ToList(); - - // if (genTypes.HasFlag(EGenTypes.APP_CODE)) - // { - // var refTypes = new Dictionary(); - // long genCodeStartTime = TimeUtil.NowMillis; - - // foreach (var refType in targetService.Refs) - // { - // if (!ass.Types.ContainsKey(refType)) - // { - // throw new Exception($"service:{targetService.Name} ref:{refType} 类型不存在"); - // } - // if (!refTypes.TryAdd(refType, ass.Types[refType])) - // { - // throw new Exception($"service:{targetService.Name} ref:{refType} 重复引用"); - // } - // } - - // foreach (var table in exportTables) - // { - // refTypes[table.FullName] = table; - // table.ValueTType.Apply(RefTypeVisitor.Ins, refTypes); - // } - - // foreach (var type in ass.Types) - // { - // if (type.Value is DefConst || type.Value is DefEnum) - // { - // refTypes[type.Key] = type.Value; - // } - // } - - // List exportTypes = refTypes.Values.ToList(); - - // switch (lan) - // { - // case "cs": - // { - // ICsCodeRender render = CreateCsCodeRender(outputDataType); - // foreach (var c in exportTypes) - // { - // genCodeTasks.Add(Task.Run(() => - // { - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cs"); - // var file = FileUtil.GetCsDefTypePath(c.FullName); - // var md5 = GenMd5AndAddCache(file, content); - // outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // } - - - // genCodeTasks.Add(Task.Run(() => - // { - // var module = ass.TopModule; - // var name = targetService.Manager; - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderService(name, module, exportTables), "cs"); - // var file = FileUtil.GetCsDefTypePath(name); - // var md5 = GenMd5AndAddCache(file, content); - // outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - - // break; - // } - // case "go": - // { - // // - // // TODO? - // // 由于 go 语言不支持类型继承 - // // go 不支持 table.value_type 为多态的表 - // // - // // - // var render = new AppGoCodeRender(); - - - // foreach (var c in exportTypes) - // { - // genCodeTasks.Add(Task.Run(() => - // { - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "go"); - // var file = FileUtil.GetGoDefTypePath(c.FullName); - // var md5 = GenMd5AndAddCache(file, content); - // outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // } - - // genCodeTasks.Add(Task.Run(() => - // { - // var module = ass.TopModule; - // var name = targetService.Manager; - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderService(name, module, exportTables), "go"); - // var file = FileUtil.GetGoDefTypePath(name); - // var md5 = GenMd5AndAddCache(file, content); - // outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - - // break; - // } - // case "lua": - // { - // genCodeTasks.Add(Task.Run(() => - // { - // var render = new Generate.Cfg.LuaRender(); - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAll(exportTypes.ToList()), "lua"); - // var file = "CfgTypes.lua"; - // var md5 = GenMd5AndAddCache(file, content); - // outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // break; - // } - // case "editor_cs": - // { - // var render = new EditorCsRender(); - // foreach (var c in ass.Types.Values) - // { - // genCodeTasks.Add(Task.Run(() => - // { - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cpp"); - // var file = FileUtil.GetCsDefTypePath(c.FullName); - // var md5 = GenMd5AndAddCache(file, content); - // outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // } - // break; - // } - // case "editor_cpp": - // { - // var render = new EditorCppRender(); - // foreach (var c in ass.Types.Values) - // { - // genCodeTasks.Add(Task.Run(() => - // { - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cpp"); - // var file = FileUtil.GetCsDefTypePath(c.FullName); - // var md5 = GenMd5AndAddCache(file, content); - // outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // } - // break; - // } - // case "editor_ue_cpp": - // { - // var render = new UE4EditorCppRender(); - - // var renderTypes = ass.Types.Values.Where(c => c is DefEnum || c is DefBean).ToList(); - - // foreach (var c in renderTypes) - // { - // genCodeTasks.Add(Task.Run(() => - // { - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cpp"); - // var file = c.UeEditorHeaderFileName; - // var md5 = GenMd5AndAddCache(file, content); - // outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // } - - // int TYPE_PER_STUB_FILE = 200; - - // for (int i = 0, n = (renderTypes.Count + TYPE_PER_STUB_FILE - 1) / TYPE_PER_STUB_FILE; i < n; i++) - // { - // int index = i; - // genCodeTasks.Add(Task.Run(() => - // { - // int startIndex = index * TYPE_PER_STUB_FILE; - // var content = RenderUtils.ConcatAutoGenerationHeader( - // render.RenderStub(renderTypes.GetRange(startIndex, Math.Min(TYPE_PER_STUB_FILE, renderTypes.Count - startIndex))), - // "cpp"); - // var file = $"Stub_{index}.cpp"; - // var md5 = GenMd5AndAddCache(file, content); - // outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // } - // break; - // } - // case "ue_bp_cpp": - // { - // var render = new UE4BpCppRender(); - // foreach (var c in exportTypes) - // { - // if (c is DefConst || c is CTable) - // { - // continue; - // } - - // genCodeTasks.Add(Task.Run(() => - // { - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cpp"); - // var file = c.UeBpHeaderFileName; - // var md5 = GenMd5AndAddCache(file, content); - // outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // } - - // //{ - // // var module = ass.TopModule; - // // var name = targetService.Manager; - // // var content = render.RenderService(name, module, exportTables); - // // var file = FileUtil.GetCppDefTypeCppFilePath(name); - // // var md5 = GenMd5AndAddCache(file, content); - // // outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // //} - // break; - // } - // default: - // { - // throw new Exception($"unknown language:{lan}"); - // } - // } - - - // allJobs.Add(Task.Run(async () => - // { - // await Task.WhenAll(genCodeTasks); - // res.NewAppCodeFiles = outputCodeFiles.ToList(); - // long genCodeEndTime = TimeUtil.NowMillis; - // ctx.Info("====== 生成代码 总共耗时 {0} ms ======", (genCodeEndTime - genCodeStartTime)); - // })); - // } - - // if ((genTypes & (EGenTypes.APP_DATA | EGenTypes.APP_RESOURCE_LIST)) != 0) - // { - // var genDataTasks = new List(); - // var outputDataFiles = new ConcurrentBag(); - // var render = new AppBinaryDataRender(); - // long genDataStartTime = TimeUtil.NowMillis; - - // foreach (CTable c in exportTables) - // { - // genDataTasks.Add(Task.Run(async () => - // { - // long beginTime = TimeUtil.NowMillis; - // await c.Load(session, exportTestData); - // long endTime = TimeUtil.NowMillis; - // if (endTime - beginTime > 100) - // { - // ctx.Info("====== 配置表 {0} 加载耗时 {1} ms ======", c.FullName, (endTime - beginTime)); - // } - // })); - // } - // Task.WaitAll(genDataTasks.ToArray()); - // } - - - // if (genTypes.HasFlag(EGenTypes.APP_DATA)) - // { - // var genDataTasks = new List(); - // var outputDataFiles = new ConcurrentBag(); - // var render = new AppBinaryDataRender(); - // long genDataStartTime = TimeUtil.NowMillis; - - // foreach (CTable c in exportTables) - // { - // genDataTasks.Add(Task.Run(() => - // { - // var content = c.ToOutputData(outputDataType); - // var file = c.OutputDataFile; - // var md5 = GenMd5AndAddCache(file, content); - // outputDataFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // } - - // allJobs.Add(Task.Run(async () => - // { - // await Task.WhenAll(genDataTasks); - // long genDataEndTime = TimeUtil.NowMillis; - // ctx.Info("====== 生成配置数据 总共耗时 {0} ms ======", (genDataEndTime - genDataStartTime)); - // res.NewAppDataFiles = outputDataFiles.ToList(); - - // long verifyStartTime = TimeUtil.NowMillis; - // render.VerifyTables(exportTables); - // res.PathQueries = ass.GetPathQueries(); - - // long verifyEndTime = TimeUtil.NowMillis; - // ctx.Info("====== 校验配置 总共耗时 {0} ms ======", (verifyEndTime - verifyStartTime)); - // })); - // } - - // if (genTypes.HasFlag(EGenTypes.APP_RESOURCE_LIST)) - // { - // var genDataTasks = new List>>(); - // var render = new AppBinaryDataRender(); - // long genDataStartTime = TimeUtil.NowMillis; - - // foreach (CTable c in exportTables) - // { - // genDataTasks.Add(Task.Run(() => - // { - // return c.ExportResourceList(); - // })); - // } - - // allJobs.Add(Task.Run(async () => - // { - // var ress = new HashSet<(string, string)>(10000); - // foreach (var task in genDataTasks) - // { - // foreach (var ri in await task) - // { - // if (ress.Add((ri.Resource, ri.Tag))) - // { - // res.ResourceList.Add(ri); - // } - // } - // } - // long genDataEndTime = TimeUtil.NowMillis; - // ctx.Info("====== 生成导出资源列表 总共耗时 {0} ms ======", (genDataEndTime - genDataStartTime)); - // })); - // } - - // Task.WhenAll(allJobs).Wait(); - - // long genEndTime = TimeUtil.NowMillis; - // ctx.Info("======== 服务器端 总共耗时 {0} ms =======", (genEndTime - genStartTime)); - - // res.OK = true; - // } - // catch (Exception e) - // { - // res.OK = false; - // LogException(ctx, e); - // } - - // proto.ReturnResult(session, res); - //} - - //private void OnGenProto(Session session, GenProto proto) - //{ - // var timer = new ProfileTimer(); - - // timer.StartPhase("服务器生成代码"); - - // var res = new GenProtoRes(); - - // string relatePath = proto.Arg.OutputCodeRelatePath; - - // DefAssembly ass = new DefAssembly(); - // var ctx = new SessionContext(session, proto.Arg.Verbose); - // try - // { - // var genCodeTasks = new List(); - // var outputFiles = new ConcurrentBag(); - - // ass.Load(EJobType.PROTO, proto.Arg.Define, ctx); - // var outputSyncFiles = new ConcurrentBag(); - - // switch (proto.Arg.Define.Language) - // { - // case "cs": - // { - // var render = new CsRender(); - // foreach (var c in ass.Types.Values) - // { - // genCodeTasks.Add(Task.Run(() => - // { - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cs"); - // var file = FileUtil.GetCsDefTypePath(c.FullName); - // var md5 = GenMd5AndAddCache(file, content); - // outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // } - // genCodeTasks.Add(Task.Run(() => - // { - // var module = ass.TopModule; - // var name = "ProtocolStub"; - // var content = RenderUtils.ConcatAutoGenerationHeader( - // render.RenderStubs(name, module, - // ass.Types.Values.Where(t => t is PProto).ToList(), - // ass.Types.Values.Where(t => t is PRpc).ToList()), - // "cs"); - // var file = FileUtil.GetCsDefTypePath(name); - // var md5 = GenMd5AndAddCache(file, content); - // outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // break; - // } - // case "lua": - // { - // genCodeTasks.Add(Task.Run(() => - // { - // var render = new Generate.Proto.LuaRender(); - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderTypes(ass.Types.Values.ToList()), "lua"); - // var file = "ProtoTypes.lua"; - // var md5 = GenMd5AndAddCache(file, content); - // outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // break; - // } - // default: - // { - // throw new Exception($"unknown lan:{proto.Arg.Define.Language}"); - // } - // } - - // Task.WhenAll(genCodeTasks).Wait(); - // res.NewCodeFiles = outputFiles.ToList(); - - // ctx.Info(timer.EndPhaseAndLogToString()); - - // res.OK = true; - // } - // catch (Exception e) - // { - // res.OK = false; - // LogException(ctx, e); - // } - - // proto.ReturnResult(session, res); - //} - - //private void OnGenRep(Session session, GenRep proto) - //{ - // var timer = new ProfileTimer(); - - // timer.StartPhase("服务器生成代码"); - - // var res = new GenRepRes(); - - // string relatePath = proto.Arg.OutputCodeRelatePath; - - // DefAssembly ass = new DefAssembly(); - // var ctx = new SessionContext(session, proto.Arg.Verbose); - // try - // { - // var genCodeTasks = new List(); - // var outputFiles = new ConcurrentBag(); - - // ass.Load(EJobType.REP, proto.Arg.Define, ctx); - // var outputSyncFiles = new ConcurrentBag(); - - // switch (proto.Arg.Define.Language) - // { - // case "cs": - // { - // var render = new Generate.Rep.CsRender(); - // foreach (var c in ass.Types.Values) - // { - // genCodeTasks.Add(Task.Run(() => - // { - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cs"); - // var file = FileUtil.GetCsDefTypePath(c.FullName); - // var md5 = GenMd5AndAddCache(file, content); - - // outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // } - // genCodeTasks.Add(Task.Run(() => - // { - // var module = ass.TopModule; - // var name = "RepStub"; - // var content = RenderUtils.ConcatAutoGenerationHeader( - // render.RenderStubs(name, module, ass.Types.Values.Where(t => (t is DefActor) || (t is DefComponent)).ToList()), - // "cs"); - // var file = FileUtil.GetCsDefTypePath(name); - // var md5 = GenMd5AndAddCache(file, content); - // outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // break; - // } - // case "lua": - // { - // genCodeTasks.Add(Task.Run(() => - // { - // var render = new Generate.Rep.LuaRender(); - // var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderTypes(ass.Types.Values.ToList()), "lua"); - // var file = "RepTypes.lua"; - // var md5 = GenMd5AndAddCache(file, content); - // outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - // })); - // break; - // } - // default: - // { - // throw new Exception($"unknown lan:{proto.Arg.Define.Language}"); - // } - // } - - // Task.WhenAll(genCodeTasks).Wait(); - // res.NewCodeFiles = outputFiles.ToList(); - - // ctx.Info(timer.EndPhaseAndLogToString()); - - // res.OK = true; - // } - // catch (Exception e) - // { - // res.OK = false; - // LogException(ctx, e); - // } - - // proto.ReturnResult(session, res); - //} - } -} diff --git a/src/Luban.Job.Proto/Source/TypeVisitors/CsDeserializeVisitor.cs b/src/Luban.Job.Proto/Source/TypeVisitors/CsDeserializeVisitor.cs new file mode 100644 index 0000000..20ed8b4 --- /dev/null +++ b/src/Luban.Job.Proto/Source/TypeVisitors/CsDeserializeVisitor.cs @@ -0,0 +1,27 @@ +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; + +namespace Luban.Job.Proto.TypeVisitors +{ + class CsDeserializeVisitor : DecoratorFuncVisitor + { + public static CsDeserializeVisitor Ins { get; } = new CsDeserializeVisitor(); + + public override string DoAccept(TType type, string bufName, string fieldName) + { + if (type.IsNullable) + { + return $"if({bufName}.ReadBool()){{ {type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName)} }} else {{ {fieldName} = null; }}"; + } + else + { + return type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName); + } + } + + public override string Accept(TBean type, string bufName, string fieldName) + { + return type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName); + } + } +} diff --git a/src/Luban.Job.Proto/Source/TypeVisitors/CsSerializeVisitor.cs b/src/Luban.Job.Proto/Source/TypeVisitors/CsSerializeVisitor.cs new file mode 100644 index 0000000..8bc0a44 --- /dev/null +++ b/src/Luban.Job.Proto/Source/TypeVisitors/CsSerializeVisitor.cs @@ -0,0 +1,27 @@ +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; + +namespace Luban.Job.Proto.TypeVisitors +{ + class CsSerializeVisitor : DecoratorFuncVisitor + { + public static CsSerializeVisitor Ins { get; } = new CsSerializeVisitor(); + + public override string DoAccept(TType type, string bufName, string fieldName) + { + if (type.IsNullable) + { + return $"if({fieldName} != null){{ {bufName}.WriteBool(true); {type.Apply(CsUnderingSerializeVisitor.Ins, bufName, fieldName)} }} else {{ {bufName}.WriteBool(true); }}"; + } + else + { + return type.Apply(CsUnderingSerializeVisitor.Ins, bufName, fieldName); + } + } + + public override string Accept(TBean type, string bufName, string fieldName) + { + return type.Apply(CsUnderingSerializeVisitor.Ins, bufName, fieldName); + } + } +} diff --git a/src/Luban.Job.Proto/Source/TypeVisitors/CsUnderingDeserializeVisitor.cs b/src/Luban.Job.Proto/Source/TypeVisitors/CsUnderingDeserializeVisitor.cs new file mode 100644 index 0000000..e5428ef --- /dev/null +++ b/src/Luban.Job.Proto/Source/TypeVisitors/CsUnderingDeserializeVisitor.cs @@ -0,0 +1,126 @@ +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; + +namespace Luban.Job.Proto.TypeVisitors +{ + class CsUnderingSerializeVisitor : ITypeFuncVisitor + { + public static CsUnderingSerializeVisitor Ins { get; } = new CsUnderingSerializeVisitor(); + + public string Accept(TBool type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadBool();"; + } + + public string Accept(TByte type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadByte();"; + } + + public string Accept(TShort type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadShort();"; + } + + public string Accept(TFshort type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadFshort();"; + } + + public string Accept(TInt type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadInt();"; + } + + public string Accept(TFint type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadFint();"; + } + + public string Accept(TLong type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadLong();"; + } + + public string Accept(TFlong type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadFlong();"; + } + + public string Accept(TFloat type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadFloat();"; + } + + public string Accept(TDouble type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadDouble();"; + } + + public string Accept(TEnum type, string bufName, string fieldName) + { + return $"{fieldName} = ({type.DefineEnum.FullName}){bufName}.ReadInt();"; + } + + public string Accept(TString type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadString();"; + } + + public string Accept(TBytes type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadBytes();"; + } + + public string Accept(TText type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadString();"; + } + + public string Accept(TBean type, string bufName, string fieldName) + { + return $"{fieldName} = {type.Bean.FullName}.Deserialize{type.Bean.Name}({bufName});"; + } + + public string Accept(TArray type, string bufName, string fieldName) + { + return $"{{int n = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {type.ElementType.Apply(CsDefineTypeName.Ins)}[n];for(var i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(CsDefineTypeName.Ins)} _e;{type.ElementType.Apply(this, bufName, "_e")} {fieldName}[i] = _e;}}}}"; + } + + public string Accept(TList type, string bufName, string fieldName) + { + return $"{{int n = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {type.Apply(CsDefineTypeName.Ins)}(n);for(var i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(CsDefineTypeName.Ins)} _e; {type.ElementType.Apply(this, bufName, "_e")} {fieldName}.Add(_e);}}}}"; + } + + public string Accept(TSet type, string bufName, string fieldName) + { + return $"{{int n = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {type.Apply(CsDefineTypeName.Ins)}(/*n * 3 / 2*/);for(var i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(CsDefineTypeName.Ins)} _e; {type.ElementType.Apply(this, bufName, "_e")} {fieldName}.Add(_e);}}}}"; + } + + public string Accept(TMap type, string bufName, string fieldName) + { + return $"{{int n = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {type.Apply(CsDefineTypeName.Ins)}(n * 3 / 2);for(var i = 0 ; i < n ; i++) {{ {type.KeyType.Apply(CsDefineTypeName.Ins)} _k; {type.KeyType.Apply(this, bufName, "_k")} {type.ValueType.Apply(CsDefineTypeName.Ins)} _v; {type.ValueType.Apply(this, bufName, "_v")} {fieldName}.Add(_k, _v);}}}}"; + + } + + public string Accept(TVector2 type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadVector2();"; + } + + public string Accept(TVector3 type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadVector3();"; + } + + public string Accept(TVector4 type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadVector4();"; + } + + public string Accept(TDateTime type, string bufName, string fieldName) + { + return $"{fieldName} = {bufName}.ReadInt();"; + } + } +} diff --git a/src/Luban.Job.Proto/Source/TypeVisitors/CsUnderingSerializeVisitor.cs b/src/Luban.Job.Proto/Source/TypeVisitors/CsUnderingSerializeVisitor.cs new file mode 100644 index 0000000..bf37e92 --- /dev/null +++ b/src/Luban.Job.Proto/Source/TypeVisitors/CsUnderingSerializeVisitor.cs @@ -0,0 +1,125 @@ +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; + +namespace Luban.Job.Proto.TypeVisitors +{ + class CsUnderingDeserializeVisitor : ITypeFuncVisitor + { + public static CsUnderingDeserializeVisitor Ins { get; } = new CsUnderingDeserializeVisitor(); + + 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((int){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}.WriteBytes({fieldName});"; + } + + public string Accept(TText type, string bufName, string fieldName) + { + return $"{bufName}.WriteString({fieldName});"; + } + + public string Accept(TBean type, string bufName, string fieldName) + { + return $"{type.Bean.FullName}.Serialize{type.Bean.Name}({bufName}, {fieldName});"; + } + + public string Accept(TArray type, string bufName, string fieldName) + { + return $"{{ {bufName}.WriteSize({fieldName}.Length); foreach(var _e in {fieldName}) {{ {type.ElementType.Apply(this, bufName, "_e")} }} }}"; + } + + public string Accept(TList type, string bufName, string fieldName) + { + return $"{{ {bufName}.WriteSize({fieldName}.Count); foreach(var _e in {fieldName}) {{ {type.ElementType.Apply(this, bufName, "_e")} }} }}"; + } + + public string Accept(TSet type, string bufName, string fieldName) + { + return $"{{ {bufName}.WriteSize({fieldName}.Count); foreach(var _e in {fieldName}) {{ {type.ElementType.Apply(this, bufName, "_e")} }} }}"; + } + + public string Accept(TMap type, string bufName, string fieldName) + { + return $"{{ {bufName}.WriteSize({fieldName}.Count); foreach((var _k, var _v) in {fieldName}) {{ {type.KeyType.Apply(this, bufName, "_k")} {type.ValueType.Apply(this, bufName, "_v")} }} }}"; + } + + public string Accept(TVector2 type, string bufName, string fieldName) + { + return $"{bufName}.WriteVector2({fieldName});"; + } + + public string Accept(TVector3 type, string bufName, string fieldName) + { + return $"{bufName}.WriteVector3({fieldName});"; + } + + public string Accept(TVector4 type, string bufName, string fieldName) + { + return $"{bufName}.WriteVector4({fieldName});"; + } + + public string Accept(TDateTime type, string bufName, string fieldName) + { + return $"{bufName}.WriteInt({fieldName});"; + } + } +}