* support proto generation.

* fix DeepCompareTypeDefine bug
main
walon 2020-11-16 22:13:11 +08:00
parent 325d19e5ec
commit 3c34affab2
21 changed files with 716 additions and 802 deletions

View File

@ -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<string> args, out GenCfgArgs result, out string errMsg)
private bool TryParseArg(List<string> args, out GenArgs result, out string errMsg)
{
var helpWriter = new StringWriter();
var parser = new Parser(ps =>
{
ps.HelpWriter = helpWriter;
}); ;
var parseResult = parser.ParseArguments<GenCfgArgs>(args);
var parseResult = parser.ParseArguments<GenArgs>(args);
if (parseResult.Tag == ParserResultType.NotParsed)
{
errMsg = helpWriter.ToString();
@ -129,7 +129,7 @@ namespace Luban.Job.Cfg
}
else
{
result = (parseResult as Parsed<GenCfgArgs>).Value;
result = (parseResult as Parsed<GenArgs>).Value;
errMsg = null;
string inputDataDir = result.InputDataDir;
@ -170,7 +170,7 @@ namespace Luban.Job.Cfg
FileGroups = new List<FileGroup>(),
};
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;

View File

@ -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();
}

View File

@ -194,14 +194,15 @@ namespace Luban.Job.Common.Defs
_namespaceStack.Pop();
}
private static readonly List<string> _fieldRequireAttrs = new List<string> { "name", "id", "type", };
private static readonly List<string> _fieldRequireAttrs = new List<string> { "name", "type", };
private static readonly List<string> _fieldOptionalAttrs = new List<string> { "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"),
};

View File

@ -147,16 +147,16 @@ namespace Luban.Job.Common.Defs
var ids = new HashSet<int>();
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()

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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)

View File

@ -5,12 +5,6 @@
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Source\TypeVisitors\**" />
<EmbeddedResource Remove="Source\TypeVisitors\**" />
<None Remove="Source\TypeVisitors\**" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Luban.Job.Common\Luban.Job.Common.csproj" />
</ItemGroup>

View File

@ -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<DefTypeBase> GetExportTypes()
{
return Types.Values.ToList();
}
}
}

View File

@ -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<string> rpcAttrs = new List<string> { "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
}
}
}

View File

@ -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;";
}
}
}

View File

@ -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<ProtoDefTypeBase> protos, List<ProtoDefTypeBase> rpcs)
public string RenderStubs(string name, string module, List<DefTypeBase> protos, List<DefTypeBase> rpcs)
{
var template = t_stubRender ??= Template.Parse(@"
using Bright.Serialization;
@ -297,13 +300,13 @@ namespace {{namespace}}
{
public static System.Collections.Generic.Dictionary<int, Bright.Net.Codecs.ProtocolCreator> Factories { get; } = new System.Collections.Generic.Dictionary<int, Bright.Net.Codecs.ProtocolCreator>
{
{{- 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~}}
};
}

View File

@ -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;
// }
// }
// }
//}

View File

@ -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<string> args, out GenArgs result, out string errMsg)
{
var helpWriter = new StringWriter();
var parser = new Parser(ps =>
{
ps.HelpWriter = helpWriter;
}); ;
var parseResult = parser.ParseArguments<GenArgs>(args);
if (parseResult.Tag == ParserResultType.NotParsed)
{
errMsg = helpWriter.ToString();
result = null;
return false;
}
result = (parseResult as Parsed<GenArgs>).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<FileGroup>(),
};
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<GenJob, GenJobArg, GenJobRes>(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<DefTypeBase> exportTypes = ass.GetExportTypes();
var tasks = new List<Task>();
var genCodeFiles = new ConcurrentBag<FileInfo>();
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<GenJob, GenJobArg, GenJobRes>(rpc, res);
}
}
}

View File

@ -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<Service> ProtoServices { get; set; } = new List<Service>();

View File

@ -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<string, object> 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);
}
}
}

View File

@ -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<Task>();
// var outputFiles = new ConcurrentBag<FileInfo>();
// 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<Task>();
// 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<Task>();
// var outputCodeFiles = new ConcurrentBag<FileInfo>();
// ass.Load(EJobType.CONFIG, proto.Arg.Define, ctx);
// EGenTypes genTypes = proto.Arg.GenTypes;
// var targetService = ass.CfgTargetService;
// List<CTable> 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<string, IDefType>();
// 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<IDefType> 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<Task>();
// var outputDataFiles = new ConcurrentBag<FileInfo>();
// 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<Task>();
// var outputDataFiles = new ConcurrentBag<FileInfo>();
// 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<Task<List<CfgResourceInfo>>>();
// 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<Task>();
// var outputFiles = new ConcurrentBag<FileInfo>();
// ass.Load(EJobType.PROTO, proto.Arg.Define, ctx);
// var outputSyncFiles = new ConcurrentBag<FileInfo>();
// 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<Task>();
// var outputFiles = new ConcurrentBag<FileInfo>();
// ass.Load(EJobType.REP, proto.Arg.Define, ctx);
// var outputSyncFiles = new ConcurrentBag<FileInfo>();
// 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);
//}
}
}

View File

@ -0,0 +1,27 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
namespace Luban.Job.Proto.TypeVisitors
{
class CsDeserializeVisitor : DecoratorFuncVisitor<string, string, string>
{
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);
}
}
}

View File

@ -0,0 +1,27 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
namespace Luban.Job.Proto.TypeVisitors
{
class CsSerializeVisitor : DecoratorFuncVisitor<string, string, string>
{
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);
}
}
}

View File

@ -0,0 +1,126 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
namespace Luban.Job.Proto.TypeVisitors
{
class CsUnderingSerializeVisitor : ITypeFuncVisitor<string, string, string>
{
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();";
}
}
}

View File

@ -0,0 +1,125 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
namespace Luban.Job.Proto.TypeVisitors
{
class CsUnderingDeserializeVisitor : ITypeFuncVisitor<string, string, string>
{
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});";
}
}
}