【重构】重构cfg JobController处理。通过注解方式,新增代码或者数据生成,不再需要修改JobController代码

main
walon 2021-08-27 15:00:14 +08:00
parent f31172c850
commit efd079939f
35 changed files with 669 additions and 546 deletions

View File

@ -0,0 +1,51 @@
using 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; }
}
}

View File

@ -0,0 +1,34 @@
using 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<Task> DataLoader { get; set; }
public List<DefTypeBase> ExportTypes { get; init; }
public List<DefTable> ExportTables { get; init; }
public ConcurrentBag<FileInfo> GenCodeFilesInOutputCodeDir { get; init; }
public ConcurrentBag<FileInfo> GenDataFilesInOutputDataDir { get; init; }
public ConcurrentBag<FileInfo> GenScatteredFiles { get; init; }
public List<Task> Tasks { get; init; }
}
}

View File

@ -1,12 +1,18 @@
using Luban.Common.Protos;
using Luban.Job.Cfg.Defs; using Luban.Job.Cfg.Defs;
using Luban.Job.Common.Defs; using Luban.Job.Common.Defs;
using Luban.Job.Common.Utils;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.Generate 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(DefConst c);
public abstract string Render(DefEnum c); public abstract string Render(DefEnum c);
public abstract string Render(DefBean b); public abstract string Render(DefBean b);
@ -24,5 +30,55 @@ namespace Luban.Job.Cfg.Generate
default: throw new Exception($"unknown render type:'{o}'"); 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<string> fileContent, Action<List<string>> preContent, Action<List<string>> 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 });
}));
}
} }
} }

View File

@ -1,14 +1,109 @@
using Luban.Common.Protos;
using Luban.Job.Cfg.Defs; using Luban.Job.Cfg.Defs;
using Luban.Job.Common;
using Luban.Job.Common.Defs; using Luban.Job.Common.Defs;
using Luban.Job.Common.Utils; using Luban.Job.Common.Utils;
using Scriban; using Scriban;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_cpp_bin")]
class CppCodeBinRender : CodeRenderBase class CppCodeBinRender : CodeRenderBase
{ {
public override void Render(GenContext ctx)
{
// 将所有 头文件定义 生成到一个文件
// 按照 const,enum,bean,table, service 的顺序生成
ctx.Tasks.Add(Task.Run(() =>
{
var headerFileContent = new List<string>
{
@$"
#pragma once
#include <functional>
#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) public override string Render(DefConst c)
{ {
return RenderUtil.RenderCppConstClass(c); return RenderUtil.RenderCppConstClass(c);

View File

@ -5,8 +5,15 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_cpp_editor")]
class CppEditorRender : CodeRenderBase class CppEditorRender : CodeRenderBase
{ {
public override void Render(GenContext ctx)
{
}
public override string Render(DefConst c) public override string Render(DefConst c)
{ {
return "// const"; return "// const";

View File

@ -1,13 +1,38 @@
using Luban.Common.Protos;
using Luban.Job.Cfg.Defs; using Luban.Job.Cfg.Defs;
using Luban.Job.Common;
using Luban.Job.Common.Defs; using Luban.Job.Common.Defs;
using Luban.Job.Common.Utils;
using Scriban; using Scriban;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_cpp_ue_bp")]
class CppUE4BpRender : CodeRenderBase 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] [ThreadStatic]
private static Template t_enumRender; private static Template t_enumRender;
public override string Render(DefEnum e) public override string Render(DefEnum e)

View File

@ -1,13 +1,55 @@
using Luban.Common.Protos;
using Luban.Job.Cfg.Defs; using Luban.Job.Cfg.Defs;
using Luban.Job.Common;
using Luban.Job.Common.Defs; using Luban.Job.Common.Defs;
using Luban.Job.Common.Utils;
using Scriban; using Scriban;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_cpp_ue_editor")]
class CppUE4EditorRender : CodeRenderBase 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] [ThreadStatic]
private static Template t_enumRender; private static Template t_enumRender;
public override string Render(DefEnum e) public override string Render(DefEnum e)

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_cs_bin")]
class CsCodeBinRender : CsCodeRenderBase class CsCodeBinRender : CsCodeRenderBase
{ {
public override string Render(DefBean b) public override string Render(DefBean b)

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_cs_json")]
class CsCodeJsonRender : CsCodeRenderBase class CsCodeJsonRender : CsCodeRenderBase
{ {
public override string Render(DefBean b) public override string Render(DefBean b)

View File

@ -3,8 +3,13 @@ using Luban.Job.Common.Utils;
namespace Luban.Job.Cfg.Generate 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) public override string Render(DefConst c)
{ {
return RenderUtil.RenderCsConstClass(c); return RenderUtil.RenderCsConstClass(c);

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_cs_unity_json")]
class CsCodeUnityJsonRender : CsCodeRenderBase class CsCodeUnityJsonRender : CsCodeRenderBase
{ {
public override string Render(DefBean b) public override string Render(DefBean b)

View File

@ -1,15 +1,34 @@
using Luban.Common.Protos;
using Luban.Job.Cfg.Defs; using Luban.Job.Cfg.Defs;
using Luban.Job.Common;
using Luban.Job.Common.Defs; using Luban.Job.Common.Defs;
using Luban.Job.Common.Utils; using Luban.Job.Common.Utils;
using Scriban; using Scriban;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_cs_unity_editor")]
class CsEditorRender : CsCodeRenderBase 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) public override string Render(DefBean b)
{ {
var template = StringTemplateUtil.GetTemplate("config/cs_editor_json/bean"); var template = StringTemplateUtil.GetTemplate("config/cs_editor_json/bean");

View File

@ -0,0 +1,13 @@
using 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);
}
}

View File

@ -0,0 +1,39 @@
using 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 });
}));
}
}
}
}

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_go_bin")]
class GoCodeBinRender : GoCodeRenderBase class GoCodeBinRender : GoCodeRenderBase
{ {
public override string Render(DefBean b) public override string Render(DefBean b)

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_go_json")]
class GoCodeJsonRender : GoCodeRenderBase class GoCodeJsonRender : GoCodeRenderBase
{ {
public override string Render(DefBean b) public override string Render(DefBean b)

View File

@ -12,6 +12,11 @@ namespace Luban.Job.Cfg.Generate
{ {
abstract class GoCodeRenderBase : CodeRenderBase abstract class GoCodeRenderBase : CodeRenderBase
{ {
public override void Render(GenContext ctx)
{
GenerateCodeScatter(ctx);
}
public override string Render(DefConst c) public override string Render(DefConst c)
{ {
string package = "cfg"; string package = "cfg";

View File

@ -5,7 +5,7 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
interface ICfgCodeRender : ICodeRender<DefTable> interface ICfgCodeRender : ICodeRender<DefTable>, IRender
{ {
string Render(DefBean b); string Render(DefBean b);

View File

@ -0,0 +1,13 @@
using 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);
}
}

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_java_bin")]
class JavaCodeBinRender : JavaCodeRenderBase class JavaCodeBinRender : JavaCodeRenderBase
{ {
public override string Render(DefBean b) public override string Render(DefBean b)

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_java_json")]
class JavaCodeJsonRender : JavaCodeRenderBase class JavaCodeJsonRender : JavaCodeRenderBase
{ {
public override string Render(DefBean b) public override string Render(DefBean b)

View File

@ -9,6 +9,11 @@ namespace Luban.Job.Cfg.Generate
{ {
abstract class JavaCodeRenderBase : CodeRenderBase abstract class JavaCodeRenderBase : CodeRenderBase
{ {
public override void Render(GenContext ctx)
{
GenerateCodeScatter(ctx);
}
public override string Render(DefConst c) public override string Render(DefConst c)
{ {
return RenderUtil.RenderJavaConstClass(c); return RenderUtil.RenderJavaConstClass(c);

View File

@ -0,0 +1,52 @@
using 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<Task<string>>();
foreach (var c in exportTables)
{
allJsonTask.Add(Task.Run(() =>
{
return (string)DataExporterUtil.ToOutputData(c, ctx.Assembly.GetTableExportDataList(c), "data_json2");
}));
}
var lines = new List<string>();
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 });
}
}
}

View File

@ -8,6 +8,7 @@ using System.Linq;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_lua_bin")]
class LuaCodeBinRender : LuaCodeRenderBase class LuaCodeBinRender : LuaCodeRenderBase
{ {
public override string RenderAll(List<DefTypeBase> types) public override string RenderAll(List<DefTypeBase> types)

View File

@ -8,6 +8,7 @@ using System.Linq;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_lua_lua")]
class LuaCodeLuaRender : LuaCodeRenderBase class LuaCodeLuaRender : LuaCodeRenderBase
{ {
[ThreadStatic] [ThreadStatic]

View File

@ -1,5 +1,7 @@
using Luban.Job.Cfg.Defs; using Luban.Common.Protos;
using Luban.Job.Cfg.Defs;
using Luban.Job.Common.Defs; using Luban.Job.Common.Defs;
using Luban.Job.Common.Utils;
using Scriban; using Scriban;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -11,6 +13,13 @@ namespace Luban.Job.Cfg.Generate
{ {
abstract class LuaCodeRenderBase : CodeRenderBase 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) public override string Render(DefConst c)
{ {

View File

@ -5,6 +5,8 @@ using System;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_python_json")]
[Render("code_python3_json")]
class Python3CodeJsonRender : PythonCodeRenderBase class Python3CodeJsonRender : PythonCodeRenderBase
{ {
public override string Render(DefBean b) public override string Render(DefBean b)

View File

@ -9,6 +9,21 @@ namespace Luban.Job.Cfg.Generate
{ {
abstract class PythonCodeRenderBase : CodeRenderBase abstract class PythonCodeRenderBase : CodeRenderBase
{ {
public override void Render(GenContext ctx)
{
ctx.Render = this;
ctx.Lan = Common.ELanguage.PYTHON;
var lines = new List<string>(10000);
static void PreContent(List<string> fileContent)
{
fileContent.Add(PythonStringTemplates.ImportTython3Enum);
fileContent.Add(PythonStringTemplates.PythonVectorTypes);
}
GenerateCodeMonolithic(ctx, "Types.py", lines, PreContent, null);
}
public override string Render(DefConst c) public override string Render(DefConst c)
{ {
return RenderUtil.RenderPythonConstClass(c); return RenderUtil.RenderPythonConstClass(c);

View File

@ -0,0 +1,19 @@
using 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;
}
}
}

View File

@ -0,0 +1,33 @@
using 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<string, IRender> renders = new();
foreach (var type in typeof(JobController).Assembly.DefinedTypes.Where(t => t.AsType().GetCustomAttributes(typeof(RenderAttribute)).Any()))
{
foreach (var attr in type.GetCustomAttributes<RenderAttribute>())
{
renders.Add(attr.Name, (IRender)System.Activator.CreateInstance(type));
}
}
s_renders = renders;
}
private static readonly Dictionary<string, IRender> s_renders;
public static IRender CreateRender(string genType)
{
return s_renders.TryGetValue(genType, out var render) ? render : null;
}
}
}

View File

@ -0,0 +1,49 @@
using 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<Task<List<ResourceInfo>>>();
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<string>(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 });
}));
}
}
}

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_typescript_bin")]
class TypescriptCodeBinRender : TypescriptCodeRenderBase class TypescriptCodeBinRender : TypescriptCodeRenderBase
{ {
public override string Render(DefBean b) public override string Render(DefBean b)

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate namespace Luban.Job.Cfg.Generate
{ {
[Render("code_typescript_json")]
class TypescriptCodeJsonRender : TypescriptCodeRenderBase class TypescriptCodeJsonRender : TypescriptCodeRenderBase
{ {
public override string Render(DefBean b) public override string Render(DefBean b)

View File

@ -9,6 +9,61 @@ namespace Luban.Job.Cfg.Generate
{ {
abstract class TypescriptCodeRenderBase : CodeRenderBase 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<string>(10000);
Action<List<string>> 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<List<string>> postContent = (fileContent) =>
{
fileContent.Add("}"); // end of topmodule
};
GenerateCodeMonolithic(ctx, "Types.ts", lines, preContent, postContent);
}
public override string Render(DefConst c) public override string Render(DefConst c)
{ {
return RenderUtil.RenderTypescriptConstClass(c); return RenderUtil.RenderTypescriptConstClass(c);

View File

@ -17,6 +17,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using FileInfo = Luban.Common.Protos.FileInfo; using FileInfo = Luban.Common.Protos.FileInfo;
@ -28,76 +29,6 @@ namespace Luban.Job.Cfg
{ {
private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger(); 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<string> args, out GenArgs options, out string errMsg) private static bool TryParseArg(List<string> args, out GenArgs options, out string errMsg)
{ {
var helpWriter = new StringWriter(); 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<DefTypeBase> ExportTypes { get; init; }
public List<DefTable> ExportTables { get; init; }
public ConcurrentBag<FileInfo> GenCodeFilesInOutputCodeDir { get; init; }
public ConcurrentBag<FileInfo> GenDataFilesInOutputDataDir { get; init; }
public ConcurrentBag<FileInfo> GenScatteredFiles { get; init; }
public List<Task> Tasks { get; init; }
}
public async Task GenAsync(RemoteAgent agent, GenJob rpc) public async Task GenAsync(RemoteAgent agent, GenJob rpc)
{ {
var res = new GenJobRes() var res = new GenJobRes()
@ -292,84 +202,19 @@ namespace Luban.Job.Cfg
GenDataFilesInOutputDataDir = genDataFilesInOutputDataDir, GenDataFilesInOutputDataDir = genDataFilesInOutputDataDir,
GenScatteredFiles = genScatteredFiles, GenScatteredFiles = genScatteredFiles,
Tasks = tasks, 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: var render = RenderFactory.CreateRender(genType);
{ if (render == null)
throw new Exception($"unknown gentype:{genType}"); {
} throw new Exception($"unknown gentype:{genType}");
} }
if (render is DataRenderBase)
{
await CheckLoadCfgDataAsync();
}
render.Render(ctx);
} }
await Task.WhenAll(tasks.ToArray()); await Task.WhenAll(tasks.ToArray());
@ -429,381 +274,5 @@ namespace Luban.Job.Cfg
agent.Session.ReplyRpc<GenJob, GenJobArg, GenJobRes>(rpc, res); agent.Session.ReplyRpc<GenJob, GenJobArg, GenJobRes>(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<string> fileContent, Action<List<string>> preContent, Action<List<string>> 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<string>(10000);
Action<List<string>> 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<List<string>> 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<string>(10000);
static void PreContent(List<string> 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<string>
{
@$"
#pragma once
#include <functional>
#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<Task<string>>();
foreach (var c in exportTables)
{
allJsonTask.Add(Task.Run(() =>
{
return (string)DataExporterUtil.ToOutputData(c, ctx.Assembly.GetTableExportDataList(c), "data_json2");
}));
}
var lines = new List<string>();
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<Task<List<ResourceInfo>>>();
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<string>(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 });
}));
}
} }
} }