diff --git a/src/Luban.Job.Cfg/Source/GenArgs.cs b/src/Luban.Job.Cfg/Source/GenArgs.cs new file mode 100644 index 0000000..a3a5632 --- /dev/null +++ b/src/Luban.Job.Cfg/Source/GenArgs.cs @@ -0,0 +1,51 @@ +锘縰sing CommandLine; +using Luban.Job.Common; + +namespace Luban.Job.Cfg +{ + public class GenArgs : GenArgsBase + { + + [Option("input_data_dir", Required = true, HelpText = "input data dir")] + public string InputDataDir { get; set; } + + [Option('v', "validate_root_dir", Required = false, HelpText = "validate root directory")] + public string ValidateRootDir { get; set; } + + [Option("output_data_dir", Required = true, HelpText = "output data directory")] + public string OutputDataDir { get; set; } + + [Option("output_data_resource_list_file", Required = false, HelpText = "output resource list file")] + public string OutputDataResourceListFile { get; set; } + + [Option("output_data_json_monolithic_file", Required = false, HelpText = "output monolithic json file")] + public string OutputDataJsonMonolithicFile { 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,data_bin,data_lua,data_json,data_json2,data_json_monolithic,data_resources . can be multi")] + public string GenType { get; set; } + + [Option('s', "service", Required = true, HelpText = "service")] + public string Service { get; set; } + + [Option("export_test_data", Required = false, HelpText = "export test data")] + public bool ExportTestData { get; set; } = false; + + [Option('t', "l10n_timezone", Required = false, HelpText = "timezone")] + public string TimeZone { get; set; } + + [Option("input_l10n_text_files", Required = false, HelpText = "input l10n text table files. can be multi, sep by ','")] + public string InputTextTableFiles { get; set; } + + [Option("l10n_text_field_name", Required = false, HelpText = "text value field name of text table files. default is text")] + public string TextValueFieldName { get; set; } + + [Option("output_l10n_not_translated_text_file", Required = false, HelpText = "the file save not translated l10n texts.")] + public string OutputNotConvertTextFile { get; set; } + + [Option("branch", Required = false, HelpText = "branch name")] + public string BranchName { get; set; } + + [Option("branch_input_data_dir", Required = false, HelpText = "branch input data root dir")] + public string BranchInputDataDir { get; set; } + } +} diff --git a/src/Luban.Job.Cfg/Source/GenContext.cs b/src/Luban.Job.Cfg/Source/GenContext.cs new file mode 100644 index 0000000..1e93525 --- /dev/null +++ b/src/Luban.Job.Cfg/Source/GenContext.cs @@ -0,0 +1,34 @@ +锘縰sing Luban.Job.Cfg.Defs; +using Luban.Job.Cfg.Generate; +using Luban.Job.Cfg.RawDefs; +using Luban.Job.Common; +using Luban.Job.Common.Defs; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Threading.Tasks; +using FileInfo = Luban.Common.Protos.FileInfo; + +namespace Luban.Job.Cfg +{ + class GenContext + { + public GenArgs GenArgs { get; init; } + public DefAssembly Assembly { get; init; } + public string GenType { get; set; } + public ICfgCodeRender Render { get; set; } + public ELanguage Lan { get; set; } + + public string TopModule => Assembly.TopModule; + public Service TargetService => Assembly.CfgTargetService; + + public Func DataLoader { get; set; } + + public List ExportTypes { get; init; } + public List ExportTables { get; init; } + public ConcurrentBag GenCodeFilesInOutputCodeDir { get; init; } + public ConcurrentBag GenDataFilesInOutputDataDir { get; init; } + public ConcurrentBag GenScatteredFiles { get; init; } + public List Tasks { get; init; } + } +} diff --git a/src/Luban.Job.Cfg/Source/Generate/CodeRenderBase.cs b/src/Luban.Job.Cfg/Source/Generate/CodeRenderBase.cs index 41ada48..13e9a46 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CodeRenderBase.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CodeRenderBase.cs @@ -1,12 +1,18 @@ +using Luban.Common.Protos; using Luban.Job.Cfg.Defs; using Luban.Job.Common.Defs; +using Luban.Job.Common.Utils; using System; using System.Collections.Generic; +using System.Threading.Tasks; namespace Luban.Job.Cfg.Generate { - public abstract class CodeRenderBase : ICfgCodeRender + abstract class CodeRenderBase : ICfgCodeRender { + public abstract void Render(GenContext ctx); + + public abstract string Render(DefConst c); public abstract string Render(DefEnum c); public abstract string Render(DefBean b); @@ -24,5 +30,55 @@ namespace Luban.Job.Cfg.Generate default: throw new Exception($"unknown render type:'{o}'"); } } + + protected void GenerateCodeScatter(GenContext ctx) + { + string genType = ctx.GenType; + ctx.Render = this; + ctx.Lan = RenderFileUtil.GetLanguage(genType); + foreach (var c in ctx.ExportTypes) + { + ctx.Tasks.Add(Task.Run(() => + { + var content = FileHeaderUtil.ConcatAutoGenerationHeader(ctx.Render.RenderAny(c), ctx.Lan); + var file = RenderFileUtil.GetDefTypePath(c.FullName, ctx.Lan); + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); + ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + } + + ctx.Tasks.Add(Task.Run(() => + { + var module = ctx.TopModule; + var name = ctx.TargetService.Manager; + var content = FileHeaderUtil.ConcatAutoGenerationHeader(ctx.Render.RenderService(name, module, ctx.ExportTables), ctx.Lan); + var file = RenderFileUtil.GetDefTypePath(name, ctx.Lan); + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); + ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + } + + protected void GenerateCodeMonolithic(GenContext ctx, string outputFile, List fileContent, Action> preContent, Action> postContent) + { + ctx.Tasks.Add(Task.Run(() => + { + fileContent.Add(FileHeaderUtil.GetAutoGenerationHeader(ctx.Lan)); + + preContent?.Invoke(fileContent); + + foreach (var type in ctx.ExportTypes) + { + fileContent.Add(ctx.Render.RenderAny(type)); + } + + fileContent.Add(ctx.Render.RenderService("Tables", ctx.TopModule, ctx.ExportTables)); + postContent?.Invoke(fileContent); + + var file = outputFile; + var md5 = CacheFileUtil.GenMd5AndAddCache(file, string.Join('\n', fileContent)); + ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + } + } } diff --git a/src/Luban.Job.Cfg/Source/Generate/CppCodeBinRender.cs b/src/Luban.Job.Cfg/Source/Generate/CppCodeBinRender.cs index d07b71c..c2208f0 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CppCodeBinRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CppCodeBinRender.cs @@ -1,14 +1,109 @@ +using Luban.Common.Protos; using Luban.Job.Cfg.Defs; +using Luban.Job.Common; using Luban.Job.Common.Defs; using Luban.Job.Common.Utils; using Scriban; using System; using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; namespace Luban.Job.Cfg.Generate { + [Render("code_cpp_bin")] class CppCodeBinRender : CodeRenderBase { + public override void Render(GenContext ctx) + { + // 将所有 头文件定义 生成到一个文件 + // 按照 const,enum,bean,table, service 的顺序生成 + + ctx.Tasks.Add(Task.Run(() => + { + var headerFileContent = new List + { + @$" +#pragma once +#include + +#include ""bright/serialization/ByteBuf.h"" +#include ""bright/CfgBean.hpp"" + +using ByteBuf = ::bright::serialization::ByteBuf; + +namespace {ctx.TopModule} +{{ +" + }; + + foreach (var type in ctx.ExportTypes) + { + if (type is DefEnum e) + { + headerFileContent.Add(Render(e)); + } + } + + foreach (var type in ctx.ExportTypes) + { + if (type is DefConst c) + { + headerFileContent.Add(Render(c)); + } + } + + foreach (var type in ctx.ExportTypes) + { + if (type is DefBean e) + { + headerFileContent.Add(RenderForwardDefine(e)); + } + } + + foreach (var type in ctx.ExportTypes) + { + if (type is DefBean e) + { + headerFileContent.Add(Render(e)); + } + } + + foreach (var type in ctx.ExportTables) + { + headerFileContent.Add(Render(type)); + } + + headerFileContent.Add(RenderService("Tables", ctx.TopModule, ctx.ExportTables)); + + headerFileContent.Add("}"); // end of topmodule + + var content = FileHeaderUtil.ConcatAutoGenerationHeader(string.Join('\n', headerFileContent), ELanguage.CPP); + var file = "gen_types.h"; + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content, true); + ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + + var beanTypes = ctx.ExportTypes.Where(c => c is DefBean).ToList(); + + int TYPE_PER_STUB_FILE = 100; + + for (int i = 0, n = (beanTypes.Count + TYPE_PER_STUB_FILE - 1) / TYPE_PER_STUB_FILE; i < n; i++) + { + int index = i; + ctx.Tasks.Add(Task.Run(() => + { + int startIndex = index * TYPE_PER_STUB_FILE; + var content = FileHeaderUtil.ConcatAutoGenerationHeader( + RenderStub(ctx.TopModule, beanTypes.GetRange(startIndex, Math.Min(TYPE_PER_STUB_FILE, beanTypes.Count - startIndex))), + ELanguage.CPP); + var file = $"gen_stub_{index}.cpp"; + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content, true); + ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + } + } + public override string Render(DefConst c) { return RenderUtil.RenderCppConstClass(c); diff --git a/src/Luban.Job.Cfg/Source/Generate/CppEditorRender.cs b/src/Luban.Job.Cfg/Source/Generate/CppEditorRender.cs index 21f907c..d87c202 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CppEditorRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CppEditorRender.cs @@ -5,8 +5,15 @@ using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { + [Render("code_cpp_editor")] class CppEditorRender : CodeRenderBase { + + public override void Render(GenContext ctx) + { + + } + public override string Render(DefConst c) { return "// const"; diff --git a/src/Luban.Job.Cfg/Source/Generate/CppUE4BpRender.cs b/src/Luban.Job.Cfg/Source/Generate/CppUE4BpRender.cs index 34f1b2b..dba8ba0 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CppUE4BpRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CppUE4BpRender.cs @@ -1,13 +1,38 @@ +using Luban.Common.Protos; using Luban.Job.Cfg.Defs; +using Luban.Job.Common; using Luban.Job.Common.Defs; +using Luban.Job.Common.Utils; using Scriban; using System; using System.Collections.Generic; +using System.Threading.Tasks; namespace Luban.Job.Cfg.Generate { + [Render("code_cpp_ue_bp")] class CppUE4BpRender : CodeRenderBase { + + public override void Render(GenContext ctx) + { + foreach (var c in ctx.ExportTypes) + { + if (!(c is DefEnum || c is DefBean)) + { + continue; + } + + ctx.Tasks.Add(Task.Run(() => + { + var content = FileHeaderUtil.ConcatAutoGenerationHeader(RenderAny(c), ELanguage.CPP); + var file = "bp_" + RenderFileUtil.GetUeCppDefTypeHeaderFilePath(c.FullName); + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content, true); + ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + } + } + [ThreadStatic] private static Template t_enumRender; public override string Render(DefEnum e) diff --git a/src/Luban.Job.Cfg/Source/Generate/CppUE4EditorRender.cs b/src/Luban.Job.Cfg/Source/Generate/CppUE4EditorRender.cs index 8cffa45..9d54284 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CppUE4EditorRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CppUE4EditorRender.cs @@ -1,13 +1,55 @@ +using Luban.Common.Protos; using Luban.Job.Cfg.Defs; +using Luban.Job.Common; using Luban.Job.Common.Defs; +using Luban.Job.Common.Utils; using Scriban; using System; using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; namespace Luban.Job.Cfg.Generate { + [Render("code_cpp_ue_editor")] class CppUE4EditorRender : CodeRenderBase { + public override void Render(GenContext ctx) + { + var render = new CppUE4EditorRender(); + + var renderTypes = ctx.Assembly.Types.Values.Where(c => c is DefEnum || c is DefBean).ToList(); + + foreach (var c in renderTypes) + { + ctx.Tasks.Add(Task.Run(() => + { + var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAny(c), ELanguage.CPP); + var file = "editor_" + RenderFileUtil.GetUeCppDefTypeHeaderFilePath(c.FullName); + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content, true); + ctx.GenCodeFilesInOutputCodeDir.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; + ctx.Tasks.Add(Task.Run(() => + { + int startIndex = index * TYPE_PER_STUB_FILE; + var content = FileHeaderUtil.ConcatAutoGenerationHeader( + render.RenderStub(renderTypes.GetRange(startIndex, Math.Min(TYPE_PER_STUB_FILE, renderTypes.Count - startIndex))), + ELanguage.CPP); + var file = $"stub_{index}.cpp"; + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content, true); + ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + } + } + + [ThreadStatic] private static Template t_enumRender; public override string Render(DefEnum e) diff --git a/src/Luban.Job.Cfg/Source/Generate/CsCodeBinRender.cs b/src/Luban.Job.Cfg/Source/Generate/CsCodeBinRender.cs index 707f194..5286d9a 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CsCodeBinRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CsCodeBinRender.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { + [Render("code_cs_bin")] class CsCodeBinRender : CsCodeRenderBase { public override string Render(DefBean b) diff --git a/src/Luban.Job.Cfg/Source/Generate/CsCodeJsonRender.cs b/src/Luban.Job.Cfg/Source/Generate/CsCodeJsonRender.cs index 01e519f..92d0dea 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CsCodeJsonRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CsCodeJsonRender.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { + [Render("code_cs_json")] class CsCodeJsonRender : CsCodeRenderBase { public override string Render(DefBean b) diff --git a/src/Luban.Job.Cfg/Source/Generate/CsCodeRenderBase.cs b/src/Luban.Job.Cfg/Source/Generate/CsCodeRenderBase.cs index 8283364..85599d1 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CsCodeRenderBase.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CsCodeRenderBase.cs @@ -3,8 +3,13 @@ using Luban.Job.Common.Utils; namespace Luban.Job.Cfg.Generate { - public abstract class CsCodeRenderBase : CodeRenderBase + abstract class CsCodeRenderBase : CodeRenderBase { + public override void Render(GenContext ctx) + { + GenerateCodeScatter(ctx); + } + public override string Render(DefConst c) { return RenderUtil.RenderCsConstClass(c); diff --git a/src/Luban.Job.Cfg/Source/Generate/CsCodeUnityJsonRender.cs b/src/Luban.Job.Cfg/Source/Generate/CsCodeUnityJsonRender.cs index 7a6b8ed..a1cd48a 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CsCodeUnityJsonRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CsCodeUnityJsonRender.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { + [Render("code_cs_unity_json")] class CsCodeUnityJsonRender : CsCodeRenderBase { public override string Render(DefBean b) diff --git a/src/Luban.Job.Cfg/Source/Generate/CsEditorRender.cs b/src/Luban.Job.Cfg/Source/Generate/CsEditorRender.cs index 1cc1872..0e682bf 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CsEditorRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CsEditorRender.cs @@ -1,15 +1,34 @@ +using Luban.Common.Protos; using Luban.Job.Cfg.Defs; +using Luban.Job.Common; using Luban.Job.Common.Defs; using Luban.Job.Common.Utils; using Scriban; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace Luban.Job.Cfg.Generate { + [Render("code_cs_unity_editor")] class CsEditorRender : CsCodeRenderBase { + public override void Render(GenContext ctx) + { + var render = new CsEditorRender(); + foreach (var c in ctx.Assembly.Types.Values) + { + ctx.Tasks.Add(Task.Run(() => + { + var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAny(c), ELanguage.CS); + var file = RenderFileUtil.GetDefTypePath(c.FullName, ELanguage.CS); + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); + ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + } + } + public override string Render(DefBean b) { var template = StringTemplateUtil.GetTemplate("config/cs_editor_json/bean"); diff --git a/src/Luban.Job.Cfg/Source/Generate/DataRenderBase.cs b/src/Luban.Job.Cfg/Source/Generate/DataRenderBase.cs new file mode 100644 index 0000000..25fef5d --- /dev/null +++ b/src/Luban.Job.Cfg/Source/Generate/DataRenderBase.cs @@ -0,0 +1,13 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Cfg.Generate +{ + abstract class DataRenderBase : IRender + { + public abstract void Render(GenContext ctx); + } +} diff --git a/src/Luban.Job.Cfg/Source/Generate/DataScatterRender.cs b/src/Luban.Job.Cfg/Source/Generate/DataScatterRender.cs new file mode 100644 index 0000000..8d0237f --- /dev/null +++ b/src/Luban.Job.Cfg/Source/Generate/DataScatterRender.cs @@ -0,0 +1,39 @@ +锘縰sing Luban.Common.Protos; +using Luban.Job.Cfg.Cache; +using Luban.Job.Cfg.Utils; +using Luban.Job.Common.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Cfg.Generate +{ + [Render("data_bin")] + [Render("data_json")] + [Render("data_json2")] + [Render("data_lua")] + class DataScatterRender : DataRenderBase + { + public override void Render(GenContext ctx) + { + string genType = ctx.GenType; + foreach (var table in ctx.ExportTables) + { + ctx.Tasks.Add(Task.Run(() => + { + var file = RenderFileUtil.GetOutputFileName(genType, table.OutputDataFile); + var records = ctx.Assembly.GetTableExportDataList(table); + if (!FileRecordCacheManager.Ins.TryGetRecordOutputData(table, records, genType, out string md5)) + { + var content = DataExporterUtil.ToOutputData(table, records, genType); + md5 = CacheFileUtil.GenStringOrBytesMd5AndAddCache(file, content); + FileRecordCacheManager.Ins.AddCachedRecordOutputData(table, records, genType, md5); + } + ctx.GenDataFilesInOutputDataDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + } + } + } +} diff --git a/src/Luban.Job.Cfg/Source/Generate/GoCodeBinRender.cs b/src/Luban.Job.Cfg/Source/Generate/GoCodeBinRender.cs index 5ca672f..1ba6d7c 100644 --- a/src/Luban.Job.Cfg/Source/Generate/GoCodeBinRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/GoCodeBinRender.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { + [Render("code_go_bin")] class GoCodeBinRender : GoCodeRenderBase { public override string Render(DefBean b) diff --git a/src/Luban.Job.Cfg/Source/Generate/GoCodeJsonRender.cs b/src/Luban.Job.Cfg/Source/Generate/GoCodeJsonRender.cs index 4e7eb5c..31d1f63 100644 --- a/src/Luban.Job.Cfg/Source/Generate/GoCodeJsonRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/GoCodeJsonRender.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { + [Render("code_go_json")] class GoCodeJsonRender : GoCodeRenderBase { public override string Render(DefBean b) diff --git a/src/Luban.Job.Cfg/Source/Generate/GoCodeRenderBase.cs b/src/Luban.Job.Cfg/Source/Generate/GoCodeRenderBase.cs index 5a28e76..422a211 100644 --- a/src/Luban.Job.Cfg/Source/Generate/GoCodeRenderBase.cs +++ b/src/Luban.Job.Cfg/Source/Generate/GoCodeRenderBase.cs @@ -12,6 +12,11 @@ namespace Luban.Job.Cfg.Generate { abstract class GoCodeRenderBase : CodeRenderBase { + public override void Render(GenContext ctx) + { + GenerateCodeScatter(ctx); + } + public override string Render(DefConst c) { string package = "cfg"; diff --git a/src/Luban.Job.Cfg/Source/Generate/ICfgCodeRender.cs b/src/Luban.Job.Cfg/Source/Generate/ICfgCodeRender.cs index 6857324..9f2cb86 100644 --- a/src/Luban.Job.Cfg/Source/Generate/ICfgCodeRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/ICfgCodeRender.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { - interface ICfgCodeRender : ICodeRender + interface ICfgCodeRender : ICodeRender, IRender { string Render(DefBean b); diff --git a/src/Luban.Job.Cfg/Source/Generate/IRender.cs b/src/Luban.Job.Cfg/Source/Generate/IRender.cs new file mode 100644 index 0000000..74905d3 --- /dev/null +++ b/src/Luban.Job.Cfg/Source/Generate/IRender.cs @@ -0,0 +1,13 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Cfg.Generate +{ + interface IRender + { + void Render(GenContext ctx); + } +} diff --git a/src/Luban.Job.Cfg/Source/Generate/JavaCodeBinRender.cs b/src/Luban.Job.Cfg/Source/Generate/JavaCodeBinRender.cs index e38159d..b8be5ed 100644 --- a/src/Luban.Job.Cfg/Source/Generate/JavaCodeBinRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/JavaCodeBinRender.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { + [Render("code_java_bin")] class JavaCodeBinRender : JavaCodeRenderBase { public override string Render(DefBean b) diff --git a/src/Luban.Job.Cfg/Source/Generate/JavaCodeJsonRender.cs b/src/Luban.Job.Cfg/Source/Generate/JavaCodeJsonRender.cs index d9bf60d..50a0056 100644 --- a/src/Luban.Job.Cfg/Source/Generate/JavaCodeJsonRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/JavaCodeJsonRender.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { + [Render("code_java_json")] class JavaCodeJsonRender : JavaCodeRenderBase { public override string Render(DefBean b) diff --git a/src/Luban.Job.Cfg/Source/Generate/JavaCodeRenderBase.cs b/src/Luban.Job.Cfg/Source/Generate/JavaCodeRenderBase.cs index 11c5ce5..08cb78b 100644 --- a/src/Luban.Job.Cfg/Source/Generate/JavaCodeRenderBase.cs +++ b/src/Luban.Job.Cfg/Source/Generate/JavaCodeRenderBase.cs @@ -9,6 +9,11 @@ namespace Luban.Job.Cfg.Generate { abstract class JavaCodeRenderBase : CodeRenderBase { + public override void Render(GenContext ctx) + { + GenerateCodeScatter(ctx); + } + public override string Render(DefConst c) { return RenderUtil.RenderJavaConstClass(c); diff --git a/src/Luban.Job.Cfg/Source/Generate/JsonDataMonolithicRender.cs b/src/Luban.Job.Cfg/Source/Generate/JsonDataMonolithicRender.cs new file mode 100644 index 0000000..89f41ca --- /dev/null +++ b/src/Luban.Job.Cfg/Source/Generate/JsonDataMonolithicRender.cs @@ -0,0 +1,52 @@ +锘縰sing Luban.Common.Protos; +using Luban.Job.Cfg.Utils; +using Luban.Job.Common.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Cfg.Generate +{ + [Render("data_json_monolithic")] + class JsonDataMonolithicRender : DataRenderBase + { + public override void Render(GenContext ctx) + { + ctx.Tasks.Add(this.GenJsonDataMonolithic(ctx)); + } + + private async Task GenJsonDataMonolithic(GenContext ctx) + { + var exportTables = ctx.ExportTables; + var allJsonTask = new List>(); + foreach (var c in exportTables) + { + allJsonTask.Add(Task.Run(() => + { + return (string)DataExporterUtil.ToOutputData(c, ctx.Assembly.GetTableExportDataList(c), "data_json2"); + })); + } + + var lines = new List(); + + lines.Add("{"); + for (int i = 0; i < exportTables.Count; i++) + { + if (i != 0) + { + lines.Add(","); + } + lines.Add($"\"{exportTables[i].FullName}\":"); + lines.Add(await allJsonTask[i]); + } + lines.Add("}"); + + var content = string.Join('\n', lines); + var outputFile = ctx.GenArgs.OutputDataJsonMonolithicFile; + var md5 = CacheFileUtil.GenMd5AndAddCache(outputFile, content); + ctx.GenScatteredFiles.Add(new FileInfo() { FilePath = outputFile, MD5 = md5 }); + } + } +} diff --git a/src/Luban.Job.Cfg/Source/Generate/LuaCodeBinRender.cs b/src/Luban.Job.Cfg/Source/Generate/LuaCodeBinRender.cs index 65d4af8..4c66459 100644 --- a/src/Luban.Job.Cfg/Source/Generate/LuaCodeBinRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/LuaCodeBinRender.cs @@ -8,6 +8,7 @@ using System.Linq; namespace Luban.Job.Cfg.Generate { + [Render("code_lua_bin")] class LuaCodeBinRender : LuaCodeRenderBase { public override string RenderAll(List types) diff --git a/src/Luban.Job.Cfg/Source/Generate/LuaCodeLuaRender.cs b/src/Luban.Job.Cfg/Source/Generate/LuaCodeLuaRender.cs index c5b4f5c..00a36ac 100644 --- a/src/Luban.Job.Cfg/Source/Generate/LuaCodeLuaRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/LuaCodeLuaRender.cs @@ -8,6 +8,7 @@ using System.Linq; namespace Luban.Job.Cfg.Generate { + [Render("code_lua_lua")] class LuaCodeLuaRender : LuaCodeRenderBase { [ThreadStatic] diff --git a/src/Luban.Job.Cfg/Source/Generate/LuaCodeRenderBase.cs b/src/Luban.Job.Cfg/Source/Generate/LuaCodeRenderBase.cs index 23a6a3d..a561550 100644 --- a/src/Luban.Job.Cfg/Source/Generate/LuaCodeRenderBase.cs +++ b/src/Luban.Job.Cfg/Source/Generate/LuaCodeRenderBase.cs @@ -1,5 +1,7 @@ -锘縰sing Luban.Job.Cfg.Defs; +锘縰sing Luban.Common.Protos; +using Luban.Job.Cfg.Defs; using Luban.Job.Common.Defs; +using Luban.Job.Common.Utils; using Scriban; using System; using System.Collections.Generic; @@ -11,6 +13,13 @@ namespace Luban.Job.Cfg.Generate { abstract class LuaCodeRenderBase : CodeRenderBase { + public override void Render(GenContext ctx) + { + var file = "Types.lua"; + var content = this.RenderAll(ctx.ExportTypes); + var md5 = CacheFileUtil.GenMd5AndAddCache(file, string.Join('\n', content)); + ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + } public override string Render(DefConst c) { diff --git a/src/Luban.Job.Cfg/Source/Generate/Python3CodeJsonRender.cs b/src/Luban.Job.Cfg/Source/Generate/Python3CodeJsonRender.cs index d4ca6bb..f43ab9f 100644 --- a/src/Luban.Job.Cfg/Source/Generate/Python3CodeJsonRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/Python3CodeJsonRender.cs @@ -5,6 +5,8 @@ using System; namespace Luban.Job.Cfg.Generate { + [Render("code_python_json")] + [Render("code_python3_json")] class Python3CodeJsonRender : PythonCodeRenderBase { public override string Render(DefBean b) diff --git a/src/Luban.Job.Cfg/Source/Generate/PythonCodeRenderBase.cs b/src/Luban.Job.Cfg/Source/Generate/PythonCodeRenderBase.cs index 32f2e87..cb7a772 100644 --- a/src/Luban.Job.Cfg/Source/Generate/PythonCodeRenderBase.cs +++ b/src/Luban.Job.Cfg/Source/Generate/PythonCodeRenderBase.cs @@ -9,6 +9,21 @@ namespace Luban.Job.Cfg.Generate { abstract class PythonCodeRenderBase : CodeRenderBase { + public override void Render(GenContext ctx) + { + ctx.Render = this; + ctx.Lan = Common.ELanguage.PYTHON; + + var lines = new List(10000); + static void PreContent(List fileContent) + { + fileContent.Add(PythonStringTemplates.ImportTython3Enum); + fileContent.Add(PythonStringTemplates.PythonVectorTypes); + } + + GenerateCodeMonolithic(ctx, "Types.py", lines, PreContent, null); + } + public override string Render(DefConst c) { return RenderUtil.RenderPythonConstClass(c); diff --git a/src/Luban.Job.Cfg/Source/Generate/RenderAttribute.cs b/src/Luban.Job.Cfg/Source/Generate/RenderAttribute.cs new file mode 100644 index 0000000..ff38022 --- /dev/null +++ b/src/Luban.Job.Cfg/Source/Generate/RenderAttribute.cs @@ -0,0 +1,19 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Cfg.Generate +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + class RenderAttribute : System.Attribute + { + public string Name { get; } + + public RenderAttribute(string name) + { + Name = name; + } + } +} diff --git a/src/Luban.Job.Cfg/Source/Generate/RenderFactory.cs b/src/Luban.Job.Cfg/Source/Generate/RenderFactory.cs new file mode 100644 index 0000000..10c24ea --- /dev/null +++ b/src/Luban.Job.Cfg/Source/Generate/RenderFactory.cs @@ -0,0 +1,33 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Cfg.Generate +{ + static class RenderFactory + { + static RenderFactory() + { + Dictionary renders = new(); + foreach (var type in typeof(JobController).Assembly.DefinedTypes.Where(t => t.AsType().GetCustomAttributes(typeof(RenderAttribute)).Any())) + { + foreach (var attr in type.GetCustomAttributes()) + { + renders.Add(attr.Name, (IRender)System.Activator.CreateInstance(type)); + } + } + + s_renders = renders; + } + + private static readonly Dictionary s_renders; + + public static IRender CreateRender(string genType) + { + return s_renders.TryGetValue(genType, out var render) ? render : null; + } + } +} diff --git a/src/Luban.Job.Cfg/Source/Generate/ResourceListRender.cs b/src/Luban.Job.Cfg/Source/Generate/ResourceListRender.cs new file mode 100644 index 0000000..1ad8d68 --- /dev/null +++ b/src/Luban.Job.Cfg/Source/Generate/ResourceListRender.cs @@ -0,0 +1,49 @@ +锘縰sing Luban.Common.Protos; +using Luban.Job.Cfg.RawDefs; +using Luban.Job.Cfg.Utils; +using Luban.Job.Common.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Cfg.Generate +{ + [Render("data_resources")] + class ResourceListRender : DataRenderBase + { + public override void Render(GenContext ctx) + { + var genDataTasks = new List>>(); + foreach (var c in ctx.ExportTables) + { + genDataTasks.Add(Task.Run(() => + { + return DataExporterUtil.ExportResourceList(ctx.Assembly.GetTableExportDataList(c)); + })); + } + + ctx.Tasks.Add(Task.Run(async () => + { + var ress = new HashSet<(string, string)>(10000); + var resourceLines = new List(10000); + foreach (var task in genDataTasks) + { + foreach (var ri in await task) + { + if (ress.Add((ri.Resource, ri.Tag))) + { + resourceLines.Add($"{ri.Resource},{ri.Tag}"); + } + } + } + var file = ctx.GenArgs.OutputDataResourceListFile; + var content = string.Join("\n", resourceLines); + var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); + + ctx.GenScatteredFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); + })); + } + } +} diff --git a/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeBinRender.cs b/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeBinRender.cs index 0f044fe..4b83dcf 100644 --- a/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeBinRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeBinRender.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { + [Render("code_typescript_bin")] class TypescriptCodeBinRender : TypescriptCodeRenderBase { public override string Render(DefBean b) diff --git a/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeJsonRender.cs b/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeJsonRender.cs index 1b552ef..4218b46 100644 --- a/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeJsonRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeJsonRender.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; namespace Luban.Job.Cfg.Generate { + [Render("code_typescript_json")] class TypescriptCodeJsonRender : TypescriptCodeRenderBase { public override string Render(DefBean b) diff --git a/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeRenderBase.cs b/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeRenderBase.cs index 31d86d9..0e0808e 100644 --- a/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeRenderBase.cs +++ b/src/Luban.Job.Cfg/Source/Generate/TypescriptCodeRenderBase.cs @@ -9,6 +9,61 @@ namespace Luban.Job.Cfg.Generate { abstract class TypescriptCodeRenderBase : CodeRenderBase { + public override void Render(GenContext ctx) + { + string genType = ctx.GenType; + var args = ctx.GenArgs; + ctx.Render = this; + ctx.Lan = RenderFileUtil.GetLanguage(genType); + + var lines = new List(10000); + Action> preContent = (fileContent) => + { + var brightRequirePath = args.TypescriptBrightRequirePath; + var brightPackageName = args.TypescriptBrightPackageName; + bool isGenBinary = genType.EndsWith("bin"); + if (isGenBinary) + { + if (args.UsePuertsByteBuf) + { + fileContent.Add(TypescriptStringTemplate.PuertsByteBufImports); + } + else + { + fileContent.Add(TypescriptStringTemplate.GetByteBufImports(brightRequirePath, brightPackageName)); + } + } + + if (args.EmbedBrightTypes) + { + fileContent.Add(isGenBinary ? + StringTemplateUtil.GetTemplateString("config/typescript_bin/vectors") + : StringTemplateUtil.GetTemplateString("config/typescript_json/vectors")); + if (isGenBinary) + { + fileContent.Add(TypescriptStringTemplate.SerializeTypes); + } + } + else + { + if (isGenBinary) + { + fileContent.Add(TypescriptStringTemplate.GetSerializeImports(brightRequirePath, brightPackageName)); + } + fileContent.Add(TypescriptStringTemplate.GetVectorImports(brightRequirePath, brightPackageName)); + } + + fileContent.Add(@$"export namespace {ctx.TopModule} {{"); + }; + + Action> postContent = (fileContent) => + { + fileContent.Add("}"); // end of topmodule + }; + + GenerateCodeMonolithic(ctx, "Types.ts", lines, preContent, postContent); + } + public override string Render(DefConst c) { return RenderUtil.RenderTypescriptConstClass(c); diff --git a/src/Luban.Job.Cfg/Source/JobController.cs b/src/Luban.Job.Cfg/Source/JobController.cs index 9ce508b..2257149 100644 --- a/src/Luban.Job.Cfg/Source/JobController.cs +++ b/src/Luban.Job.Cfg/Source/JobController.cs @@ -17,6 +17,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using System.Text.Json; using System.Threading.Tasks; using FileInfo = Luban.Common.Protos.FileInfo; @@ -28,76 +29,6 @@ namespace Luban.Job.Cfg { private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger(); - class GenArgs : GenArgsBase - { - - [Option("input_data_dir", Required = true, HelpText = "input data dir")] - public string InputDataDir { get; set; } - - [Option('v', "validate_root_dir", Required = false, HelpText = "validate root directory")] - public string ValidateRootDir { get; set; } - - [Option("output_data_dir", Required = true, HelpText = "output data directory")] - public string OutputDataDir { get; set; } - - [Option("output_data_resource_list_file", Required = false, HelpText = "output resource list file")] - public string OutputDataResourceListFile { get; set; } - - [Option("output_data_json_monolithic_file", Required = false, HelpText = "output monolithic json file")] - public string OutputDataJsonMonolithicFile { 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,data_bin,data_lua,data_json,data_json2,data_json_monolithic,data_resources . can be multi")] - public string GenType { get; set; } - - [Option('s', "service", Required = true, HelpText = "service")] - public string Service { get; set; } - - [Option("export_test_data", Required = false, HelpText = "export test data")] - public bool ExportTestData { get; set; } = false; - - [Option('t', "l10n_timezone", Required = false, HelpText = "timezone")] - public string TimeZone { get; set; } - - [Option("input_l10n_text_files", Required = false, HelpText = "input l10n text table files. can be multi, sep by ','")] - public string InputTextTableFiles { get; set; } - - [Option("l10n_text_field_name", Required = false, HelpText = "text value field name of text table files. default is text")] - public string TextValueFieldName { get; set; } - - [Option("output_l10n_not_translated_text_file", Required = false, HelpText = "the file save not translated l10n texts.")] - public string OutputNotConvertTextFile { get; set; } - - [Option("branch", Required = false, HelpText = "branch name")] - public string BranchName { get; set; } - - [Option("branch_input_data_dir", Required = false, HelpText = "branch input data root dir")] - public string BranchInputDataDir { get; set; } - } - - private ICfgCodeRender CreateCodeRender(string genType) - { - switch (genType) - { - case "code_cs_bin": return new CsCodeBinRender(); - case "code_cs_json": return new CsCodeJsonRender(); - case "code_cs_unity_json": return new CsCodeUnityJsonRender(); - case "code_java_bin": return new JavaCodeBinRender(); - case "code_java_json": return new JavaCodeJsonRender(); - case "code_go_bin": return new GoCodeBinRender(); - case "code_go_json": return new GoCodeJsonRender(); - case "code_cpp_bin": return new CppCodeBinRender(); - case "code_lua_bin": return new LuaCodeBinRender(); - case "code_lua_lua": return new LuaCodeLuaRender(); - case "code_python3_json": return new Python3CodeJsonRender(); - case "code_typescript_bin": return new TypescriptCodeBinRender(); - case "code_typescript_json": return new TypescriptCodeJsonRender(); - case "code_cpp_ue_editor": return new CppUE4EditorRender(); - case "code_cpp_ue_bp": return new CppUE4BpRender(); - case "code_cs_unity_editor": return new CsEditorRender(); - default: throw new ArgumentException($"not support gen type:{genType}"); - } - } - private static bool TryParseArg(List args, out GenArgs options, out string errMsg) { var helpWriter = new StringWriter(); @@ -173,27 +104,6 @@ namespace Luban.Job.Cfg } } - - class GenContext - { - public GenArgs GenArgs { get; init; } - public DefAssembly Assembly { get; init; } - public string GenType { get; set; } - public ICfgCodeRender Render { get; set; } - public ELanguage Lan { get; set; } - - public string TopModule => Assembly.TopModule; - public Service TargetService => Assembly.CfgTargetService; - - - public List ExportTypes { get; init; } - public List ExportTables { get; init; } - public ConcurrentBag GenCodeFilesInOutputCodeDir { get; init; } - public ConcurrentBag GenDataFilesInOutputDataDir { get; init; } - public ConcurrentBag GenScatteredFiles { get; init; } - public List Tasks { get; init; } - } - public async Task GenAsync(RemoteAgent agent, GenJob rpc) { var res = new GenJobRes() @@ -292,84 +202,19 @@ namespace Luban.Job.Cfg GenDataFilesInOutputDataDir = genDataFilesInOutputDataDir, GenScatteredFiles = genScatteredFiles, Tasks = tasks, + DataLoader = CheckLoadCfgDataAsync, }; - switch (genType) - { - case "code_cs_bin": - case "code_cs_json": - case "code_cs_unity_json": - case "code_java_bin": - case "code_java_json": - case "code_go_bin": - case "code_go_json": - { - GenerateCodeScatter(ctx); - break; - } - case "code_lua_bin": - case "code_lua_lua": - { - GenLuaCode(ctx); - break; - } - case "code_typescript_bin": - case "code_typescript_json": - { - GenTypescriptCode(ctx); - break; - } - case "code_python3_json": - { - GenPythonCodes(ctx); - break; - } - case "code_cpp_bin": - { - GenCppCode(ctx); - break; - } - case "code_cpp_ue_editor": - { - GenCppUeEditor(ctx); - break; - } - case "code_cs_unity_editor": - { - GenCsUnityEditor(ctx); - break; - } - case "code_cpp_ue_bp": - { - GenCppUeBp(ctx); - break; - } - case "data_bin": - case "data_json": - case "data_json2": - case "data_lua": - { - await CheckLoadCfgDataAsync(); - GenDataScatter(ctx); - break; - } - case "data_json_monolithic": - { - await CheckLoadCfgDataAsync(); - tasks.Add(GenJsonDataMonolithic(ctx)); - break; - } - case "data_resources": - { - await CheckLoadCfgDataAsync(); - GenResourceList(ctx); - break; - } - default: - { - throw new Exception($"unknown gentype:{genType}"); - } + var render = RenderFactory.CreateRender(genType); + if (render == null) + { + throw new Exception($"unknown gentype:{genType}"); } + if (render is DataRenderBase) + { + await CheckLoadCfgDataAsync(); + } + render.Render(ctx); } await Task.WhenAll(tasks.ToArray()); @@ -429,381 +274,5 @@ namespace Luban.Job.Cfg agent.Session.ReplyRpc(rpc, res); } - - private void GenerateCodeScatter(GenContext ctx) - { - string genType = ctx.GenType; - ctx.Render = CreateCodeRender(genType); - ctx.Lan = RenderFileUtil.GetLanguage(genType); - foreach (var c in ctx.ExportTypes) - { - ctx.Tasks.Add(Task.Run(() => - { - var content = FileHeaderUtil.ConcatAutoGenerationHeader(ctx.Render.RenderAny(c), ctx.Lan); - var file = RenderFileUtil.GetDefTypePath(c.FullName, ctx.Lan); - var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); - ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - })); - } - - ctx.Tasks.Add(Task.Run(() => - { - var module = ctx.TopModule; - var name = ctx.TargetService.Manager; - var content = FileHeaderUtil.ConcatAutoGenerationHeader(ctx.Render.RenderService(name, module, ctx.ExportTables), ctx.Lan); - var file = RenderFileUtil.GetDefTypePath(name, ctx.Lan); - var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); - ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - })); - } - - private void GenerateCodeMonolithic(GenContext ctx, string outputFile, List fileContent, Action> preContent, Action> postContent) - { - ctx.Tasks.Add(Task.Run(() => - { - fileContent.Add(FileHeaderUtil.GetAutoGenerationHeader(ctx.Lan)); - - preContent?.Invoke(fileContent); - - foreach (var type in ctx.ExportTypes) - { - fileContent.Add(ctx.Render.RenderAny(type)); - } - - fileContent.Add(ctx.Render.RenderService("Tables", ctx.TopModule, ctx.ExportTables)); - postContent?.Invoke(fileContent); - - var file = outputFile; - var md5 = CacheFileUtil.GenMd5AndAddCache(file, string.Join('\n', fileContent)); - ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - })); - } - - private void GenLuaCode(GenContext ctx) - { - string genType = ctx.GenType; - LuaCodeRenderBase render = CreateCodeRender(genType) as LuaCodeRenderBase; - var file = "Types.lua"; - var content = render.RenderAll(ctx.ExportTypes); - var md5 = CacheFileUtil.GenMd5AndAddCache(file, string.Join('\n', content)); - ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - } - - private void GenTypescriptCode(GenContext ctx) - { - string genType = ctx.GenType; - var args = ctx.GenArgs; - ctx.Render = CreateCodeRender(genType); - ctx.Lan = RenderFileUtil.GetLanguage(genType); - - var lines = new List(10000); - Action> preContent = (fileContent) => - { - var brightRequirePath = args.TypescriptBrightRequirePath; - var brightPackageName = args.TypescriptBrightPackageName; - bool isGenBinary = genType.EndsWith("bin"); - if (isGenBinary) - { - if (args.UsePuertsByteBuf) - { - fileContent.Add(TypescriptStringTemplate.PuertsByteBufImports); - } - else - { - fileContent.Add(TypescriptStringTemplate.GetByteBufImports(brightRequirePath, brightPackageName)); - } - } - - if (args.EmbedBrightTypes) - { - fileContent.Add(isGenBinary ? - StringTemplateUtil.GetTemplateString("config/typescript_bin/vectors") - : StringTemplateUtil.GetTemplateString("config/typescript_json/vectors")); - if (isGenBinary) - { - fileContent.Add(TypescriptStringTemplate.SerializeTypes); - } - } - else - { - if (isGenBinary) - { - fileContent.Add(TypescriptStringTemplate.GetSerializeImports(brightRequirePath, brightPackageName)); - } - fileContent.Add(TypescriptStringTemplate.GetVectorImports(brightRequirePath, brightPackageName)); - } - - fileContent.Add(@$"export namespace {ctx.TopModule} {{"); - }; - - Action> postContent = (fileContent) => - { - fileContent.Add("}"); // end of topmodule - }; - - GenerateCodeMonolithic(ctx, "Types.ts", lines, preContent, postContent); - } - - private void GenPythonCodes(GenContext ctx) - { - string genType = ctx.GenType; - ctx.Render = CreateCodeRender(genType); - ctx.Lan = RenderFileUtil.GetLanguage(genType); - - var lines = new List(10000); - static void PreContent(List fileContent) - { - fileContent.Add(PythonStringTemplates.ImportTython3Enum); - fileContent.Add(PythonStringTemplates.PythonVectorTypes); - } - - GenerateCodeMonolithic(ctx, "Types.py", lines, PreContent, null); - } - - private void GenCppCode(GenContext ctx) - { - var render = new CppCodeBinRender(); - // 灏嗘墍鏈 澶存枃浠跺畾涔 鐢熸垚鍒颁竴涓枃浠 - // 鎸夌収 const,enum,bean,table, service 鐨勯『搴忕敓鎴 - - ctx.Tasks.Add(Task.Run(() => - { - var headerFileContent = new List - { - @$" -#pragma once -#include - -#include ""bright/serialization/ByteBuf.h"" -#include ""bright/CfgBean.hpp"" - -using ByteBuf = ::bright::serialization::ByteBuf; - -namespace {ctx.TopModule} -{{ -" - }; - - foreach (var type in ctx.ExportTypes) - { - if (type is DefEnum e) - { - headerFileContent.Add(render.Render(e)); - } - } - - foreach (var type in ctx.ExportTypes) - { - if (type is DefConst c) - { - headerFileContent.Add(render.Render(c)); - } - } - - foreach (var type in ctx.ExportTypes) - { - if (type is DefBean e) - { - headerFileContent.Add(render.RenderForwardDefine(e)); - } - } - - foreach (var type in ctx.ExportTypes) - { - if (type is DefBean e) - { - headerFileContent.Add(render.Render(e)); - } - } - - foreach (var type in ctx.ExportTables) - { - headerFileContent.Add(render.Render(type)); - } - - headerFileContent.Add(render.RenderService("Tables", ctx.TopModule, ctx.ExportTables)); - - headerFileContent.Add("}"); // end of topmodule - - var content = FileHeaderUtil.ConcatAutoGenerationHeader(string.Join('\n', headerFileContent), ELanguage.CPP); - var file = "gen_types.h"; - var md5 = CacheFileUtil.GenMd5AndAddCache(file, content, true); - ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - })); - - var beanTypes = ctx.ExportTypes.Where(c => c is DefBean).ToList(); - - int TYPE_PER_STUB_FILE = 100; - - for (int i = 0, n = (beanTypes.Count + TYPE_PER_STUB_FILE - 1) / TYPE_PER_STUB_FILE; i < n; i++) - { - int index = i; - ctx.Tasks.Add(Task.Run(() => - { - int startIndex = index * TYPE_PER_STUB_FILE; - var content = FileHeaderUtil.ConcatAutoGenerationHeader( - render.RenderStub(ctx.TopModule, beanTypes.GetRange(startIndex, Math.Min(TYPE_PER_STUB_FILE, beanTypes.Count - startIndex))), - ELanguage.CPP); - var file = $"gen_stub_{index}.cpp"; - var md5 = CacheFileUtil.GenMd5AndAddCache(file, content, true); - ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - })); - } - } - - private void GenCppUeEditor(GenContext ctx) - { - var render = new CppUE4EditorRender(); - - var renderTypes = ctx.Assembly.Types.Values.Where(c => c is DefEnum || c is DefBean).ToList(); - - foreach (var c in renderTypes) - { - ctx.Tasks.Add(Task.Run(() => - { - var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAny(c), ELanguage.CPP); - var file = "editor_" + RenderFileUtil.GetUeCppDefTypeHeaderFilePath(c.FullName); - var md5 = CacheFileUtil.GenMd5AndAddCache(file, content, true); - ctx.GenCodeFilesInOutputCodeDir.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; - ctx.Tasks.Add(Task.Run(() => - { - int startIndex = index * TYPE_PER_STUB_FILE; - var content = FileHeaderUtil.ConcatAutoGenerationHeader( - render.RenderStub(renderTypes.GetRange(startIndex, Math.Min(TYPE_PER_STUB_FILE, renderTypes.Count - startIndex))), - ELanguage.CPP); - var file = $"stub_{index}.cpp"; - var md5 = CacheFileUtil.GenMd5AndAddCache(file, content, true); - ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - })); - } - } - - private void GenCsUnityEditor(GenContext ctx) - { - var render = new CsEditorRender(); - foreach (var c in ctx.Assembly.Types.Values) - { - ctx.Tasks.Add(Task.Run(() => - { - var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAny(c), ELanguage.CS); - var file = RenderFileUtil.GetDefTypePath(c.FullName, ELanguage.CS); - var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); - ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - })); - } - } - - private void GenCppUeBp(GenContext ctx) - { - var render = new CppUE4BpRender(); - foreach (var c in ctx.ExportTypes) - { - if (!(c is DefEnum || c is DefBean)) - { - continue; - } - - ctx.Tasks.Add(Task.Run(() => - { - var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAny(c), ELanguage.CPP); - var file = "bp_" + RenderFileUtil.GetUeCppDefTypeHeaderFilePath(c.FullName); - var md5 = CacheFileUtil.GenMd5AndAddCache(file, content, true); - ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - })); - } - } - - private void GenDataScatter(GenContext ctx) - { - string genType = ctx.GenType; - foreach (var table in ctx.ExportTables) - { - ctx.Tasks.Add(Task.Run(() => - { - var file = RenderFileUtil.GetOutputFileName(genType, table.OutputDataFile); - var records = ctx.Assembly.GetTableExportDataList(table); - if (!FileRecordCacheManager.Ins.TryGetRecordOutputData(table, records, genType, out string md5)) - { - var content = DataExporterUtil.ToOutputData(table, records, genType); - md5 = CacheFileUtil.GenStringOrBytesMd5AndAddCache(file, content); - FileRecordCacheManager.Ins.AddCachedRecordOutputData(table, records, genType, md5); - } - ctx.GenDataFilesInOutputDataDir.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - })); - } - } - - private async Task GenJsonDataMonolithic(GenContext ctx) - { - var exportTables = ctx.ExportTables; - var allJsonTask = new List>(); - foreach (var c in exportTables) - { - allJsonTask.Add(Task.Run(() => - { - return (string)DataExporterUtil.ToOutputData(c, ctx.Assembly.GetTableExportDataList(c), "data_json2"); - })); - } - - var lines = new List(); - - lines.Add("{"); - for (int i = 0; i < exportTables.Count; i++) - { - if (i != 0) - { - lines.Add(","); - } - lines.Add($"\"{exportTables[i].FullName}\":"); - lines.Add(await allJsonTask[i]); - } - lines.Add("}"); - - var content = string.Join('\n', lines); - var outputFile = ctx.GenArgs.OutputDataJsonMonolithicFile; - var md5 = CacheFileUtil.GenMd5AndAddCache(outputFile, content); - ctx.GenScatteredFiles.Add(new FileInfo() { FilePath = outputFile, MD5 = md5 }); - } - - private void GenResourceList(GenContext ctx) - { - var genDataTasks = new List>>(); - foreach (var c in ctx.ExportTables) - { - genDataTasks.Add(Task.Run(() => - { - return DataExporterUtil.ExportResourceList(ctx.Assembly.GetTableExportDataList(c)); - })); - } - - ctx.Tasks.Add(Task.Run(async () => - { - var ress = new HashSet<(string, string)>(10000); - var resourceLines = new List(10000); - foreach (var task in genDataTasks) - { - foreach (var ri in await task) - { - if (ress.Add((ri.Resource, ri.Tag))) - { - resourceLines.Add($"{ri.Resource},{ri.Tag}"); - } - } - } - var file = ctx.GenArgs.OutputDataResourceListFile; - var content = string.Join("\n", resourceLines); - var md5 = CacheFileUtil.GenMd5AndAddCache(file, content); - - ctx.GenScatteredFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 }); - })); - } } }