328 lines
8.3 KiB
C#
328 lines
8.3 KiB
C#
using Luban.Job.Common.Defs;
|
|
using Luban.Job.Common.Utils;
|
|
using Luban.Job.Proto.Defs;
|
|
using Scriban;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Luban.Job.Proto.Generate
|
|
{
|
|
class CsRender
|
|
{
|
|
public string RenderAny(object o)
|
|
{
|
|
switch (o)
|
|
{
|
|
case DefConst c: return Render(c);
|
|
case DefEnum e: return Render(e);
|
|
case DefBean b: return Render(b);
|
|
case DefProto p: return Render(p);
|
|
case DefRpc r: return Render(r);
|
|
|
|
default: throw new Exception($"unknown render type:{o}");
|
|
}
|
|
}
|
|
|
|
private string Render(DefConst c)
|
|
{
|
|
return RenderUtil.RenderCsConstClass(c);
|
|
}
|
|
|
|
private string Render(DefEnum e)
|
|
{
|
|
return RenderUtil.RenderCsEnumClass(e);
|
|
}
|
|
|
|
[ThreadStatic]
|
|
private static Template t_beanRender;
|
|
private string Render(DefBean b)
|
|
{
|
|
var template = t_beanRender ??= Template.Parse(@"
|
|
{{
|
|
is_value_type = x.is_value_type
|
|
is_abstract_type = x.is_abstract_type
|
|
name = x.name
|
|
full_name = x.full_name
|
|
parent_def_type = x.parent_def_type
|
|
parent = x.parent
|
|
fields = x.fields
|
|
hierarchy_fields = x.hierarchy_fields
|
|
}}
|
|
using Bright.Serialization;
|
|
|
|
namespace {{x.namespace_with_top_module}}
|
|
{
|
|
|
|
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~}}
|
|
public {{name}}()
|
|
{
|
|
}
|
|
{{~end~}}
|
|
|
|
public {{name}}(Bright.Common.NotNullInitialization _) {{if parent_def_type}} : base(_) {{end}}
|
|
{
|
|
{{~ for field in fields ~}}
|
|
{{~if cs_need_init field.ctype~}}
|
|
{{cs_init_field_ctor_value field.cs_style_name field.ctype}}
|
|
{{~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 (x != null)
|
|
{
|
|
_buf.WriteInt(x.GetTypeId());
|
|
x.Serialize(_buf);
|
|
}
|
|
else
|
|
{
|
|
_buf.WriteInt(0);
|
|
}
|
|
{{~else~}}
|
|
x.Serialize(_buf);
|
|
{{~end~}}
|
|
}
|
|
|
|
public static {{name}} Deserialize{{name}}(ByteBuf _buf)
|
|
{
|
|
{{~if is_abstract_type~}}
|
|
{{full_name}} x;
|
|
switch (_buf.ReadInt())
|
|
{
|
|
case 0 : return null;
|
|
{{~ 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~}}
|
|
var x = new {{full_name}}();
|
|
x.Deserialize(_buf);
|
|
{{~end~}}
|
|
return x;
|
|
}
|
|
{{~ for field in fields ~}}
|
|
public {{cs_define_type field.ctype}} {{field.cs_style_name}};
|
|
{{~end~}}
|
|
|
|
{{~if !is_abstract_type~}}
|
|
public const int ID = {{x.id}};
|
|
public override int GetTypeId() => ID;
|
|
|
|
public override void Serialize(ByteBuf _buf)
|
|
{
|
|
{{~ for field in hierarchy_fields ~}}
|
|
{{cs_serialize '_buf' field.cs_style_name field.ctype}}
|
|
{{~end~}}
|
|
}
|
|
|
|
public override void Deserialize(ByteBuf _buf)
|
|
{
|
|
{{~ 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.cs_style_name}}:"" + {{cs_to_string field.cs_style_name field.ctype}} + "",""
|
|
{{~end~}}
|
|
+ ""}"";
|
|
}
|
|
{{~end~}}
|
|
}
|
|
|
|
}
|
|
|
|
");
|
|
var result = template.RenderCode(b);
|
|
|
|
return result;
|
|
}
|
|
|
|
[ThreadStatic]
|
|
private static Template t_protoRender;
|
|
private string Render(DefProto p)
|
|
{
|
|
var template = t_protoRender ??= Template.Parse(@"
|
|
{{
|
|
name = x.name
|
|
full_name = x.full_name
|
|
parent = x.parent
|
|
fields = x.fields
|
|
}}
|
|
using Bright.Serialization;
|
|
|
|
namespace {{x.namespace_with_top_module}}
|
|
{
|
|
|
|
public sealed class {{name}} : Bright.Net.Codecs.Protocol
|
|
{
|
|
{{~ 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 cs_need_init field.ctype~}}
|
|
{{cs_init_field_ctor_value field.cs_style_name field.ctype}}
|
|
{{~end~}}
|
|
{{~end~}}
|
|
}
|
|
public const int ID = {{x.id}};
|
|
|
|
public override int GetTypeId()
|
|
{
|
|
return ID;
|
|
}
|
|
|
|
public override void Serialize(ByteBuf _buf)
|
|
{
|
|
{{~ for field in fields ~}}
|
|
{{cs_serialize '_buf' field.cs_style_name field.ctype}}
|
|
{{~end~}}
|
|
}
|
|
|
|
public override void Deserialize(ByteBuf _buf)
|
|
{
|
|
{{~ for field in fields ~}}
|
|
{{cs_deserialize '_buf' field.cs_style_name field.ctype}}
|
|
{{~end~}}
|
|
}
|
|
|
|
public override void Reset()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public override object Clone()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return ""{{full_name}}{ ""
|
|
{{~ for field in fields ~}}
|
|
+ ""{{field.cs_style_name}}:"" + {{cs_to_string field.cs_style_name field.ctype}} + "",""
|
|
{{~end~}}
|
|
+ ""}"";
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
");
|
|
var result = template.RenderCode(p);
|
|
|
|
return result;
|
|
}
|
|
|
|
[ThreadStatic]
|
|
private static Template t_rpcRender;
|
|
private string Render(DefRpc r)
|
|
{
|
|
var template = t_rpcRender ??= Template.Parse(@"
|
|
{{
|
|
name = x.name
|
|
full_name = x.full_name
|
|
parent = x.parent
|
|
fields = x.fields
|
|
targ_type = x.targ_type
|
|
tres_type = x.tres_type
|
|
}}
|
|
using Bright.Serialization;
|
|
|
|
namespace {{x.namespace_with_top_module}}
|
|
{
|
|
|
|
public sealed class {{name}} : Bright.Net.Codecs.Rpc<{{cs_define_type targ_type}}, {{cs_define_type tres_type}}>
|
|
{
|
|
public {{name}}()
|
|
{
|
|
}
|
|
|
|
public const int ID = {{x.id}};
|
|
|
|
public override int GetTypeId()
|
|
{
|
|
return ID;
|
|
}
|
|
|
|
public override void Reset()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public override object Clone()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return $""{{full_name}}{%{ {{arg:{Arg},res:{Res} }} }%}"";
|
|
}
|
|
}
|
|
}
|
|
|
|
");
|
|
var result = template.RenderCode(r);
|
|
|
|
return result;
|
|
}
|
|
|
|
[ThreadStatic]
|
|
private static Template t_stubRender;
|
|
public string RenderStubs(string name, string module, List<DefTypeBase> protos, List<DefTypeBase> rpcs)
|
|
{
|
|
var template = t_stubRender ??= Template.Parse(@"
|
|
using Bright.Serialization;
|
|
|
|
namespace {{namespace}}
|
|
{
|
|
|
|
public static class {{name}}
|
|
{
|
|
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 ~}}
|
|
[{{proto.full_name}}.ID] = () => new {{proto.full_name}}(),
|
|
{{~end~}}
|
|
|
|
{{~ for rpc in rpcs ~}}
|
|
[{{rpc.full_name}}.ID] = () => new {{rpc.full_name}}(),
|
|
{{~end~}}
|
|
};
|
|
}
|
|
|
|
}
|
|
|
|
");
|
|
var result = template.Render(new
|
|
{
|
|
Name = name,
|
|
Namespace = module,
|
|
Protos = protos,
|
|
Rpcs = rpcs,
|
|
});
|
|
|
|
return result;
|
|
}
|
|
}
|
|
}
|