【特性】新增code_protobuf3及data_protobuf3_json支持

【修复】修复FlatBuffers json导出格式中map数据的格式错误。本应该是{"K":v}却序列化成[[k1,v1]]
main
walon 2021-12-08 20:39:58 +08:00
parent aa0d0a9a36
commit e650ff6fe6
16 changed files with 253 additions and 9 deletions

View File

@ -78,5 +78,20 @@ namespace Luban.Job.Cfg.DataExporters
} }
x.WriteEndObject(); x.WriteEndObject();
} }
public override void Accept(DMap type, Utf8JsonWriter x)
{
x.WriteStartArray();
foreach (var d in type.Datas)
{
x.WriteStartObject();
x.WritePropertyName("key");
d.Key.Apply(this, x);
x.WritePropertyName("value");
d.Value.Apply(this, x);
x.WriteEndObject();
}
x.WriteEndArray();
}
} }
} }

View File

@ -15,9 +15,9 @@ using System.Threading.Tasks;
namespace Luban.Job.Cfg.DataExporters namespace Luban.Job.Cfg.DataExporters
{ {
class ProtobufExportor : IDataActionVisitor<CodedOutputStream> class ProtobufBinExportor : IDataActionVisitor<CodedOutputStream>
{ {
public static ProtobufExportor Ins { get; } = new(); public static ProtobufBinExportor Ins { get; } = new();
public void WriteList(DefTable table, List<Record> datas, MemoryStream x) public void WriteList(DefTable table, List<Record> datas, MemoryStream x)
{ {

View File

@ -0,0 +1,88 @@
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources;
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Defs;
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
using System;
using System.Collections.Generic;
using System.Text.Json;
namespace Luban.Job.Cfg.DataExporters
{
class ProtobufJsonExportor : JsonExportor
{
public static new FlatBuffersJsonExportor Ins { get; } = new();
public void WriteAsTable(List<Record> datas, Utf8JsonWriter x)
{
x.WriteStartObject();
// 如果修改了这个名字请同时修改table.tpl
x.WritePropertyName("data_list");
x.WriteStartArray();
foreach (var d in datas)
{
d.Data.Apply(this, x);
}
x.WriteEndArray();
x.WriteEndObject();
}
public override void Accept(DText type, Utf8JsonWriter x)
{
// 不支持本地化。只能简单起见这么做了
//x.WriteStartObject();
//x.WritePropertyName(DText.KEY_NAME);
//x.WriteStringValue(type.Key);
//x.WritePropertyName(DText.TEXT_NAME);
x.WriteStringValue(type.TextOfCurrentAssembly);
//x.WriteEndObject();
}
public override void Accept(DBean type, Utf8JsonWriter x)
{
x.WriteStartObject();
if (type.Type.IsAbstractType)
{
// protobuf oneof 用 @type来识别类型
x.WritePropertyName("@type");
x.WriteStringValue(TBean.Create(false, type.ImplType, null).Apply(ProtobufTypeNameVisitor.Ins));
}
var defFields = type.ImplType.HierarchyFields;
int index = 0;
foreach (var d in type.Fields)
{
var defField = (DefField)defFields[index++];
// 特殊处理 bean 多态类型
// 另外,不生成 xxx:null 这样
if (d == null || !defField.NeedExport)
{
//x.WriteNullValue();
}
else
{
x.WritePropertyName(defField.Name);
d.Apply(this, x);
}
}
x.WriteEndObject();
}
public override void Accept(DMap type, Utf8JsonWriter x)
{
x.WriteStartArray();
foreach (var d in type.Datas)
{
x.WriteStartArray();
x.WriteStringValue(d.Key.Apply(ToJsonLiteralVisitor.Ins));
d.Value.Apply(this, x);
x.WriteEndArray();
}
x.WriteEndArray();
}
}
}

View File

@ -8,7 +8,7 @@ namespace Luban.Job.Cfg
[Option('s', "service", Required = true, HelpText = "service")] [Option('s', "service", Required = true, HelpText = "service")]
public string Service { get; set; } public string Service { get; set; }
[Option("gen_types", Required = true, HelpText = "code_cs_bin,code_cs_json,code_cs_unity_json,code_lua_bin,code_java_bin,code_java_json,code_go_bin,code_go_json,code_cpp_bin,code_python3_json,code_typescript_bin,code_typescript_json,code_rust_json,code_protobuf,code_template,code_flatbuffers,data_bin,data_lua,data_json,data_json2,data_json_monolithic,data_resources,data_template,data_protobuf,data_flatbuffers_json,convert_json,convert_lua,convert_xlsx . can be multi")] [Option("gen_types", Required = true, HelpText = "code_cs_bin,code_cs_json,code_cs_unity_json,code_lua_bin,code_java_bin,code_java_json,code_go_bin,code_go_json,code_cpp_bin,code_python3_json,code_typescript_bin,code_typescript_json,code_rust_json,code_protobuf,code_template,code_flatbuffers,data_bin,data_lua,data_json,data_json2,data_json_monolithic,data_resources,data_template,data_protobuf_bin,data_protobuf_json,data_flatbuffers_json,convert_json,convert_lua,convert_xlsx . can be multi")]
public string GenType { get; set; } public string GenType { get; set; }
[Option("input_data_dir", Required = true, HelpText = "input data dir")] [Option("input_data_dir", Required = true, HelpText = "input data dir")]

View File

@ -13,7 +13,8 @@ namespace Luban.Job.Cfg.Generate
[Render("data_lua")] [Render("data_lua")]
[Render("data_xml")] [Render("data_xml")]
[Render("data_yaml")] [Render("data_yaml")]
[Render("data_protobuf")] [Render("data_protobuf_bin")]
[Render("data_protobuf_json")]
[Render("data_msgpack")] [Render("data_msgpack")]
[Render("data_flatbuffers_json")] [Render("data_flatbuffers_json")]
class DataScatterRender : DataRenderBase class DataScatterRender : DataRenderBase

View File

@ -15,6 +15,8 @@ namespace Luban.Job.Cfg.Generate
[Render("code_protobuf2")] [Render("code_protobuf2")]
class Protobuf2SchemaRender : ProtobufSchemaRenderBase class Protobuf2SchemaRender : ProtobufSchemaRenderBase
{ {
protected override string CommonRenderTemplateDir => "protobuf2";
protected override string RenderTemplateDir => "protobuf2"; protected override string RenderTemplateDir => "protobuf2";
} }
} }

View File

@ -10,6 +10,8 @@ namespace Luban.Job.Cfg.Generate
[Render("code_protobuf3")] [Render("code_protobuf3")]
class Protobuf3SchemaRender : ProtobufSchemaRenderBase class Protobuf3SchemaRender : ProtobufSchemaRenderBase
{ {
protected override string RenderTemplateDir => "protobuf"; protected override string CommonRenderTemplateDir => "protobuf3";
protected override string RenderTemplateDir => "protobuf3";
} }
} }

View File

@ -93,12 +93,25 @@ namespace Luban.Job.Cfg.Utils
} }
return string.Join('\n', content); return string.Join('\n', content);
} }
case "data_protobuf": case "data_protobuf_bin":
{ {
var ms = new MemoryStream(); var ms = new MemoryStream();
ProtobufExportor.Ins.WriteList(table, records, ms); ProtobufBinExportor.Ins.WriteList(table, records, ms);
return DataUtil.StreamToBytes(ms); return DataUtil.StreamToBytes(ms);
} }
case "data_protobuf_json":
{
var ss = new MemoryStream();
var jsonWriter = new Utf8JsonWriter(ss, new JsonWriterOptions()
{
Indented = !table.Assembly.OutputCompactJson,
SkipValidation = false,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(System.Text.Unicode.UnicodeRanges.All),
});
ProtobufJsonExportor.Ins.WriteAsTable(records, jsonWriter);
jsonWriter.Flush();
return DataUtil.StreamToBytes(ss);
}
case "data_msgpack": case "data_msgpack":
{ {
var ms = new System.Buffers.ArrayBufferWriter<byte>(); var ms = new System.Buffers.ArrayBufferWriter<byte>();

View File

@ -245,6 +245,29 @@ namespace Luban.Job.Common.Defs
} }
} }
public static string Protobuf3PreDecorator(TType type)
{
if (type.IsNullable)
{
return "optional";
}
else if (type.IsCollection)
{
if (type is TMap)
{
return "";
}
else
{
return "repeated";
}
}
else
{
return "";
}
}
public static string FlatBuffersDefineType(TType type) public static string FlatBuffersDefineType(TType type)
{ {
return type.Apply(FlatBuffersTypeNameVisitor.Ins); return type.Apply(FlatBuffersTypeNameVisitor.Ins);

View File

@ -64,7 +64,10 @@
<None Update="Templates\common\lua\base.tpl"> <None Update="Templates\common\lua\base.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="Templates\common\protobuf\enum.tpl"> <None Update="Templates\common\protobuf3\enum.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\common\protobuf2\enum.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="Templates\common\python\enum.tpl"> <None Update="Templates\common\python\enum.tpl">
@ -187,6 +190,18 @@
<None Update="Templates\config\lua_lua\all.tpl"> <None Update="Templates\config\lua_lua\all.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="Templates\config\protobuf3\all.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\protobuf3\bean.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\protobuf3\table.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\protobuf3\tables.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\protobuf2\bean.tpl"> <None Update="Templates\config\protobuf2\bean.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>

View File

@ -9,7 +9,7 @@ enum {{x.pb_full_name}} {
{{~for item in items ~}} {{~for item in items ~}}
{{x.pb_full_name}}_{{item.name}} = {{item.int_value}}; {{x.pb_full_name}}_{{item.name}} = {{item.int_value}};
{{~end~}} {{~end~}}
{{~if items.empty?~}} {{~if items.empty?}}
{{x.pb_full_name}}_EMPTY_PLACEHOLDER = 0; {{x.pb_full_name}}_EMPTY_PLACEHOLDER = 0;
{{~end~}} {{~end~}}
} }

View File

@ -0,0 +1,15 @@
{{~
name = x.name
namespace_with_top_module = x.namespace_with_top_module
comment = x.comment
items = x.items
~}}
enum {{x.pb_full_name}} {
{{~if items.empty? || items[0].int_value != 0~}}
{{x.pb_full_name}}_EMPTY_PLACEHOLDER = 0;
{{~end~}}
{{~for item in items ~}}
{{x.pb_full_name}}_{{item.name}} = {{item.int_value}};
{{~end~}}
}

View File

@ -0,0 +1,36 @@
syntax = "proto3";
package {{x.namespace}};
// luban internal types begin
message Vector2 {
float x = 1;
float y = 2;
}
message Vector3 {
float x = 1;
float y = 2;
float z = 3;
}
message Vector4 {
float x = 1;
float y = 2;
float z = 3;
float w = 4;
}
// luban internal types end
{{~for enum in x.enums ~}}
{{enum}}
{{~end~}}
{{~for bean in x.beans~}}
{{bean}}
{{~end~}}
{{~for table in x.tables~}}
{{table}}
{{~end~}}

View File

@ -0,0 +1,20 @@
{{~
name = x.name
parent_def_type = x.parent_def_type
export_fields = x.export_fields
hierarchy_export_fields = x.hierarchy_export_fields
~}}
message {{x.pb_full_name}} {
{{~if x.is_abstract_type ~}}
oneof value {
{{~for c in x.hierarchy_not_abstract_children~}}
{{c.pb_full_name}} {{c.name}} = {{c.auto_id}};
{{~end~}}
}
{{~else~}}
{{~for f in hierarchy_export_fields ~}}
{{protobuf3_pre_decorator f.ctype}} {{protobuf_define_type f.ctype}} {{f.name}} = {{f.auto_id}} {{protobuf_suffix_options f.ctype}};
{{~end~}}
{{~end~}}
}

View File

@ -0,0 +1,9 @@
{{~
name = x.name
key_type = x.key_ttype
value_type = x.value_ttype
~}}
message {{x.pb_full_name}} {
repeated {{protobuf_define_type value_type}} data_list = 1 [packed = false];
}

View File

@ -0,0 +1,5 @@
{{~
name = x.name
namespace = x.namespace
tables = x.tables
~}}