【重构】重构 cpp_bin 生成,全部可以在模板中定制

【重构】重构 cpp_ue_editor_json、cpp_ue_bp、cs_unity_editor_json 生成
main
walon 2022-02-12 12:33:08 +08:00
parent caa476272b
commit e76b20b24f
20 changed files with 363 additions and 414 deletions

View File

@ -24,94 +24,76 @@ namespace Luban.Job.Cfg.Generate
DefAssembly.LocalAssebmly.CurrentLanguage = ELanguage.CPP;
ctx.Tasks.Add(Task.Run(() =>
{
var headerFileContent = new List<string>
{
@$"
#pragma once
#include <functional>
var enums = new List<DefEnum>();
var enumCodes = new List<string>();
#include ""bright/serialization/ByteBuf.h""
#include ""bright/CfgBean.hpp""
var beans = new List<DefBean>();
var beanCodes = new List<string>();
using ByteBuf = ::bright::serialization::ByteBuf;
namespace {ctx.TopModule}
{{
"
};
var tables = ctx.ExportTables;
var tableCodes = new List<string>();
foreach (var type in ctx.ExportTypes)
{
if (type is DefEnum e)
switch(type)
{
headerFileContent.Add(Render(e));
}
}
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));
case DefEnum e:
{
enums.Add(e);
enumCodes.Add(Render(e));
break;
}
case DefBean b:
{
beans.Add(b);
beanCodes.Add(Render(b));
break;
}
}
}
foreach (var type in ctx.ExportTables)
{
headerFileContent.Add(Render(type));
tableCodes.Add(Render(type));
}
headerFileContent.Add(RenderService(ctx.Assembly.TableManagerName, ctx.TopModule, ctx.ExportTables));
string tablesCode = RenderService(ctx.Assembly.TableManagerName, 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 rawContent = GetConfigTemplate("all_types").RenderCode(new
{
Enums = enums,
Beans = beans,
EnumCodes = enumCodes,
BeanCodes = beanCodes,
TableCodes = tableCodes,
TablesCode = tablesCode,
});
var content = FileHeaderUtil.ConcatAutoGenerationHeader(rawContent, ELanguage.CPP);
var file = ctx.Assembly.GetOptionOr($"{RenderTemplateDir}.output_all_types_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;
int TYPE_PER_STUB_FILE = int.Parse(ctx.Assembly.GetOptionOr($"{RenderTemplateDir}.type_per_stub_file", "100"));
string stubFileFormat = ctx.Assembly.GetOptionOr($"{RenderTemplateDir}.stub_file_name_format", "gen_stub_{0}.cpp");
var template = GetConfigTemplate("stub");
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 rawContent = template.RenderCode(new { Types = beanTypes.GetRange(startIndex, Math.Min(TYPE_PER_STUB_FILE, beanTypes.Count - startIndex)), });
var content = FileHeaderUtil.ConcatAutoGenerationHeader(rawContent, ELanguage.CPP);
var file = string.Format(stubFileFormat, index);
var md5 = CacheFileUtil.GenMd5AndAddCache(file, content, true);
ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 });
}));
}
}
private string RenderStub(string topModule, List<DefTypeBase> types)
{
var template = StringTemplateManager.Ins.GetTemplate("config/cpp_bin/stub");
return template.RenderCode(new {
TopModule = topModule,
Types = types,
});
}
private string RenderForwardDefine(DefBean b)
{
return $"{b.CppNamespaceBegin} class {b.Name}; {b.CppNamespaceEnd} ";
}
}
}

View File

@ -1,13 +0,0 @@
using Luban.Job.Cfg.Defs;
using Luban.Job.Common.Defs;
using Luban.Job.Common.Generate;
using System.Collections.Generic;
namespace Luban.Job.Cfg.Generate
{
[Render("code_cpp_editor")]
class CppEditorRender : TemplateCodeRenderBase
{
protected override string RenderTemplateDir => "cpp_editor_json";
}
}

View File

@ -12,8 +12,9 @@ using System.Threading.Tasks;
namespace Luban.Job.Cfg.Generate
{
[Render("code_cpp_ue_bp")]
class CppUE4BpRender : CodeRenderBase
class CppUE4BpRender : TemplateCodeRenderBase
{
protected override string RenderTemplateDir => "cpp_ue_bp";
public override void Render(GenContext ctx)
{
@ -34,82 +35,11 @@ namespace Luban.Job.Cfg.Generate
}
}
[ThreadStatic]
private static Template t_enumRender;
public override string Render(DefEnum e)
{
// ue 不允许 UEnum 为这
// ue 强制枚举underling type 为 uint8, 意味着不能超过255
var template = t_enumRender ??= Template.Parse(@"
#pragma once
#include ""CoreMinimal.h""
#include ""{{ue_bp_header_file_name_without_suffix}}.generated.h""
UENUM(BlueprintType)
enum class {{ue_bp_full_name}} : uint8
{
{{~if !contains_value_equal0_item~}}
__DEFAULT__ = 0,
{{~end~}}
{{~if contains_any_ue_enum_compatible_item~}}
{{~for item in items ~}}
{{if item.int_value >= 256}}//{{end}}{{item.name}} = {{item.value}} UMETA(DisplayName = ""{{item.alias_or_name}}""),
{{~end~}}
{{~else~}}
DUMMY UMETA(DisplayName = ""DUMMY""),
{{~end~}}
};
");
var template = GetConfigTemplate("enum");
var result = template.Render(e);
return result;
}
[ThreadStatic]
private static Template t_beanRender;
public override string Render(DefBean b)
{
var template = t_beanRender ??= Template.Parse(@"
#pragma once
#include ""CoreMinimal.h""
#include ""UCfgObj.h""
{{ue_bp_includes}}
#include ""{{ue_bp_header_file_name_without_suffix}}.generated.h""
UCLASS(BlueprintType)
class X6PROTO_API {{ue_bp_full_name}} : public {{if parent_def_type}} {{parent_def_type.ue_bp_full_name}} {{else}} UCfgObj {{end}}
{
GENERATED_BODY()
public:
{{~for field in export_fields ~}}
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (DisplayName = ""{{field.name}}""))
{{field.ctype.ue_bp_cpp_define_type}} {{field.name}};
{{~end~}}
};
");
var result = template.Render(b);
return result;
}
public override string Render(DefTable c)
{
throw new NotImplementedException();
}
public override string RenderService(string name, string module, List<DefTable> tables)
{
throw new NotImplementedException();
}
}
}

View File

@ -3,6 +3,7 @@ using Luban.Job.Cfg.Defs;
using Luban.Job.Common;
using Luban.Job.Common.Defs;
using Luban.Job.Common.Generate;
using Luban.Job.Common.Tpl;
using Luban.Job.Common.Utils;
using Scriban;
using System;
@ -13,8 +14,10 @@ using System.Threading.Tasks;
namespace Luban.Job.Cfg.Generate
{
[Render("code_cpp_ue_editor_json")]
class CppUE4EditorJsonRender : CodeRenderBase
class CppUE4EditorJsonRender : TemplateEditorJsonCodeRenderBase
{
protected override string RenderTemplateDir => "cpp_ue_editor_json";
public override void Render(GenContext ctx)
{
var render = new CppUE4EditorJsonRender();
@ -26,250 +29,28 @@ namespace Luban.Job.Cfg.Generate
ctx.Tasks.Add(Task.Run(() =>
{
var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAny(c), ELanguage.CPP);
var file = "editor_" + RenderFileUtil.GetUeCppDefTypeHeaderFilePath(c.FullName);
var file = 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;
int TYPE_PER_STUB_FILE = int.Parse(ctx.Assembly.GetOptionOr($"{RenderTemplateDir}.type_per_stub_file", "200"));
string stubFileFormat = ctx.Assembly.GetOptionOr($"{RenderTemplateDir}.stub_file_name_format", "gen_stub_{0}.cpp");
var template = GetConfigTemplate("stub");
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 rawContent = template.RenderCode(new { Types = renderTypes.GetRange(startIndex, Math.Min(TYPE_PER_STUB_FILE, renderTypes.Count - startIndex)), });
var content = FileHeaderUtil.ConcatAutoGenerationHeader(rawContent, ELanguage.CPP);
var file = string.Format(stubFileFormat, index);
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)
{
var template = t_enumRender ??= Template.Parse(@"
#pragma once
#include ""CoreMinimal.h""
namespace editor
{
{{cpp_namespace_begin}}
enum class {{ue_fname}}
{
{{~for item in items ~}}
{{item.name}} = {{item.value}},
{{~end~}}
};
bool X6PROTOEDITOR_API {{ue_fname}}ToString({{ue_fname}} value, FString& s);
bool X6PROTOEDITOR_API {{ue_fname}}FromString(const FString& s, {{ue_fname}}& x);
{{cpp_namespace_end}}
}
");
var result = template.Render(e);
return result;
}
[ThreadStatic]
private static Template t_beanRender;
public override string Render(DefBean b)
{
var template = t_beanRender ??= Template.Parse(@"
#pragma once
#include ""CoreMinimal.h""
#include ""FCfgObj.h""
{{editor_cpp_includes}}
namespace editor
{
{{cpp_namespace_begin}}
struct X6PROTOEDITOR_API {{ue_fname}} : public {{if parent_def_type}} {{parent_def_type.ue_fname}}{{else}}FCfgObj{{end}}
{
{{~for field in fields ~}}
{{field.ctype.editor_ue_cpp_define_type}} {{field.name}};
{{~end~}}
{{~if !is_abstract_type~}}
bool Load(FJsonObject* _json) override;
bool Save(FJsonObject*& result) override;
{{~end~}}
static bool Create(FJsonObject* _json, {{ue_fname}}*& result);
};
{{cpp_namespace_end}}
}
");
var result = template.Render(b);
return result;
}
private class Stub
{
public List<DefTypeBase> Types { get; set; }
public string Includes
{
get
{
var includeTypes = new HashSet<DefTypeBase>(Types);
foreach (var type in Types)
{
if (type is DefBean bean)
{
foreach (DefBean c in bean.HierarchyNotAbstractChildren)
{
includeTypes.Add(c);
}
}
}
//return string.Join('\n', includeTypes.Select(im => $"#include \"{ im.UeEditorHeaderFileName}\""));
throw new NotImplementedException();
}
}
}
[ThreadStatic]
private static Template t_stubRender;
public string RenderStub(List<DefTypeBase> types)
{
var template = t_stubRender ??= Template.Parse(@"
#include ""JsonUtil.h""
{{includes}}
namespace editor
{
{{~for type in types~}}
{{type.cpp_namespace_begin}}
{{~if type.is_bean~}}
{{~if type.is_abstract_type~}}
bool {{type.ue_fname}}::Create(FJsonObject* _json, {{type.ue_fname}}*& result)
{
FString type;
if (_json->TryGetStringField(FString(""{{type.json_type_name_key}}""), type))
{
{{~for child in type.hierarchy_not_abstract_children~}}
if (type == ""{{cs_impl_data_type child x}}"")
{
result = new {{child.ue_fname}}();
} else
{{~end~}}
{
result = nullptr;
return false;
}
if (!result->Load(_json))
{
delete result;
return false;
}
return true;
}
else
{
result = nullptr;
return false;
}
}
{{~else~}}
bool {{type.ue_fname}}::Create(FJsonObject* _json, {{type.ue_fname}}*& result)
{
result = new {{type.ue_fname}}();
if (!result->Load(_json))
{
delete result;
return false;
}
return true;
}
bool {{type.ue_fname}}::Save(FJsonObject*& result)
{
auto _json = new FJsonObject();
_json->SetStringField(""{{type.json_type_name_key}}"", ""{{type.name}}"");
{{~for field in type.hierarchy_fields~}}
{{field.editor_ue_cpp_save}}
{{~end~}}
result = _json;
return true;
}
bool {{type.ue_fname}}::Load(FJsonObject* _json)
{
{{~for field in type.hierarchy_fields~}}
{{field.editor_ue_cpp_load}}
{{~end~}}
return true;
}
{{~end~}}
{{~else~}}
bool {{type.ue_fname}}ToString({{type.ue_fname}} value, FString& s)
{
{{~for item in type.items ~}}
if (value == {{type.ue_fname}}::{{item.name}}) { s = ""{{item.name}}""; return true; }
{{~end~}}
return false;
}
bool {{type.ue_fname}}FromString(const FString& s, {{type.ue_fname}}& value)
{
{{~for item in type.items ~}}
if (s == ""{{item.name}}"")
{
value = {{type.ue_fname}}::{{item.name}};
return true;
}
{{~end~}}
return false;
}
{{~end~}}
{{type.cpp_namespace_end}}
{{~end~}}
}
");
var result = template.Render(new Stub
{
Types = types,
});
return result;
}
public override string Render(DefTable c)
{
throw new NotImplementedException();
}
public override string RenderService(string name, string module, List<DefTable> tables)
{
throw new NotImplementedException();
}
}
}

View File

@ -11,37 +11,8 @@ using System.Threading.Tasks;
namespace Luban.Job.Cfg.Generate
{
[Render("code_cs_unity_editor_json")]
class CsUnityEditorRender : TemplateCodeRenderBase
class CsUnityEditorRender : TemplateEditorJsonCodeRenderBase
{
override protected string RenderTemplateDir => "cs_unity_editor_json";
public override string Render(DefEnum e)
{
var template = StringTemplateManager.Ins.GetTemplate($"config/{RenderTemplateDir}/enum");
var result = template.RenderCode(e);
return result;
}
public override void Render(GenContext ctx)
{
ctx.Assembly.CurrentLanguage = ELanguage.CS;
foreach (var c in ctx.Assembly.Types.Values)
{
if (!(c is DefBean) && !(c is DefEnum))
{
continue;
}
ctx.Tasks.Add(Task.Run(() =>
{
var content = FileHeaderUtil.ConcatAutoGenerationHeader(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 });
}));
}
}
}
}

View File

@ -46,7 +46,7 @@ namespace Luban.Job.Cfg.Generate
private string RenderConvertJson2BinaryBat(string name, string module, List<DefTable> tables)
{
var template = StringTemplateManager.Ins.GetTemplate($"config/{RenderTemplateDir}/convert_json_to_binary_bat");
var template = GetConfigTemplate("convert_json_to_binary_bat");
var result = template.RenderCode(new {
Name = name,
Namespace = module,
@ -57,7 +57,7 @@ namespace Luban.Job.Cfg.Generate
private string RenderConvertJson2BinarySh(string name, string module, List<DefTable> tables)
{
var template = StringTemplateManager.Ins.GetTemplate($"config/{RenderTemplateDir}/convert_json_to_binary_sh");
var template = GetConfigTemplate("convert_json_to_binary_sh");
var result = template.RenderCode(new {
Name = name,
Namespace = module,
@ -92,7 +92,7 @@ namespace Luban.Job.Cfg.Generate
// 所以排到前面生成
beans.Sort((a, b) => (a.IsAbstractType ? 0 : 1) - (b.IsAbstractType ? 0 : 1));
var template = StringTemplateManager.Ins.GetTemplate($"config/{RenderTemplateDir}/all");
var template = GetConfigTemplate("all");
var result = template.RenderCode(new {
Namespace = ass.TopModule,
Enums = enums.Select(e => Render((DefEnum)e)).ToList(),

View File

@ -30,7 +30,7 @@ namespace Luban.Job.Cfg.Generate
lines,
ls =>
{
var template = StringTemplateManager.Ins.GetTemplate("config/rust_json/include");
var template = GetConfigTemplate("include");
var result = template.RenderCode(ctx.ExportTypes);
ls.Add(result);
}, null);

View File

@ -16,6 +16,16 @@ namespace Luban.Job.Cfg.Generate
protected abstract string RenderTemplateDir { get; }
protected Scriban.Template GetConfigTemplate(string name)
{
return StringTemplateManager.Ins.GetTemplate($"config/{RenderTemplateDir}/{name}");
}
protected Scriban.Template GetCommonTemplate(string name)
{
return StringTemplateManager.Ins.GetTemplate($"common/{CommonRenderTemplateDir}/{name}");
}
public override void Render(GenContext ctx)
{
GenerateCodeScatter(ctx);
@ -23,7 +33,7 @@ namespace Luban.Job.Cfg.Generate
public override string Render(DefEnum e)
{
var template = StringTemplateManager.Ins.GetTemplate($"common/{CommonRenderTemplateDir}/enum");
var template = GetCommonTemplate("enum");
var result = template.RenderCode(e);
return result;
@ -31,21 +41,21 @@ namespace Luban.Job.Cfg.Generate
public override string Render(DefBean b)
{
var template = StringTemplateManager.Ins.GetTemplate($"config/{RenderTemplateDir}/bean");
var template = GetConfigTemplate("bean");
var result = template.RenderCode(b);
return result;
}
public override string Render(DefTable p)
{
var template = StringTemplateManager.Ins.GetTemplate($"config/{RenderTemplateDir}/table");
var template = GetConfigTemplate("table");
var result = template.RenderCode(p);
return result;
}
public override string RenderService(string name, string module, List<DefTable> tables)
{
var template = StringTemplateManager.Ins.GetTemplate($"config/{RenderTemplateDir}/tables");
var template = GetConfigTemplate("tables");
var result = template.RenderCode(new {
Name = name,
Namespace = module,
@ -60,7 +70,7 @@ namespace Luban.Job.Cfg.Generate
var beans = types.Where(t => t is DefBean).ToList();
var tables = types.Where(t => t is DefTable).ToList();
var template = StringTemplateManager.Ins.GetTemplate($"config/{RenderTemplateDir}/all");
var template = GetConfigTemplate("all");
var result = template.RenderCode(new {
Namespace = DefAssembly.LocalAssebmly.TopModule,
Enums = enums.Select(e => Render((DefEnum)e)).ToList(),

View File

@ -17,11 +17,16 @@ namespace Luban.Job.Cfg.Generate
[Render("convert_template")]
class TemplateConvertRender : DataRenderBase
{
protected Template GetConvertTemplate(string name)
{
return StringTemplateManager.Ins.GetTemplate($"config/convert/{name}");
}
public override void Render(GenContext ctx)
{
string genType = ctx.GenType;
Template template = StringTemplateManager.Ins.GetTemplate($"config/convert/{ctx.GenArgs.TemplateConvertFile}");
Template template = GetConvertTemplate(ctx.GenArgs.TemplateConvertFile);
foreach (var table in ctx.ExportTables)
{

View File

@ -0,0 +1,44 @@
using Luban.Common.Protos;
using Luban.Job.Cfg.Defs;
using Luban.Job.Common;
using Luban.Job.Common.Defs;
using Luban.Job.Common.Tpl;
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
{
abstract class TemplateEditorJsonCodeRenderBase :TemplateCodeRenderBase
{
public override string Render(DefEnum e)
{
var template = GetConfigTemplate("enum");
var result = template.RenderCode(e);
return result;
}
public override void Render(GenContext ctx)
{
ELanguage lan = GetLanguage(ctx);
ctx.Assembly.CurrentLanguage = lan;
foreach (var c in ctx.Assembly.Types.Values)
{
if (c is not DefBean && c is not DefEnum)
{
continue;
}
ctx.Tasks.Add(Task.Run(() =>
{
var content = FileHeaderUtil.ConcatAutoGenerationHeader(RenderAny(c), lan);
var file = RenderFileUtil.GetDefTypePath(c.FullName, lan);
var md5 = CacheFileUtil.GenMd5AndAddCache(file, content);
ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 });
}));
}
}
}
}

View File

@ -80,6 +80,11 @@ namespace Luban.Job.Common.Defs
return Options.TryGetValue(optionName, out var value) ? value : null;
}
public string GetOptionOr(string optionName, string defaultValue)
{
return Options.TryGetValue(optionName, out var value) ? value : defaultValue;
}
private void SetCurrentExternalSelectors(string selectors)
{
if (string.IsNullOrEmpty(selectors))

View File

@ -79,6 +79,9 @@
<None Update="Templates\common\typescript\enum.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\cpp_bin\all_types.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\cpp_bin\bean.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@ -91,6 +94,21 @@
<None Update="Templates\config\cpp_bin\tables.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\cpp_ue_bp\bean.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\cpp_ue_bp\enum.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\cpp_ue_editor_json\bean.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\cpp_ue_editor_json\enum.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\cpp_ue_editor_json\stub.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\config\cs_bin\bean.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

View File

@ -0,0 +1,30 @@
#pragma once
#include <functional>
#include "bright/serialization/ByteBuf.h"
#include "bright/CfgBean.hpp"
using ByteBuf = ::bright::serialization::ByteBuf;
namespace {{assembly.top_module}}
{
{{~for e in x.enum_codes~}}
{{e}}
{{~end~}}
{{~for b in x.beans~}}
{{b.cpp_namespace_begin}} class {{b.name}}; {{b.cpp_namespace_end}}
{{~end~}}
{{~for b in x.bean_codes~}}
{{b}}
{{~end~}}
{{~for t in x.table_codes~}}
{{t}}
{{~end~}}
{{x.tables_code}}
}

View File

@ -3,7 +3,7 @@
using ByteBuf = bright::serialization::ByteBuf;
namespace {{x.top_module}}
namespace {{assembly.top_module}}
{
{{~for type in x.types~}}

View File

@ -0,0 +1,22 @@
#pragma once
#include ""CoreMinimal.h""
#include ""UCfgObj.h""
{{ue_bp_includes}}
#include ""{{ue_bp_header_file_name_without_suffix}}.generated.h""
UCLASS(BlueprintType)
class X6PROTO_API {{ue_bp_full_name}} : public {{if parent_def_type}} {{parent_def_type.ue_bp_full_name}} {{else}} UCfgObj {{end}}
{
GENERATED_BODY()
public:
{{~for field in export_fields ~}}
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (DisplayName = ""{{field.name}}""))
{{field.ctype.ue_bp_cpp_define_type}} {{field.name}};
{{~end~}}
};

View File

@ -0,0 +1,19 @@
#pragma once
#include ""CoreMinimal.h""
#include ""{{ue_bp_header_file_name_without_suffix}}.generated.h""
UENUM(BlueprintType)
enum class {{ue_bp_full_name}} : uint8
{
{{~if !contains_value_equal0_item~}}
__DEFAULT__ = 0,
{{~end~}}
{{~if contains_any_ue_enum_compatible_item~}}
{{~for item in items ~}}
{{if item.int_value >= 256}}//{{end}}{{item.name}} = {{item.value}} UMETA(DisplayName = ""{{item.alias_or_name}}""),
{{~end~}}
{{~else~}}
DUMMY UMETA(DisplayName = ""DUMMY""),
{{~end~}}
};

View File

@ -0,0 +1,27 @@
#pragma once
#include ""CoreMinimal.h""
#include ""FCfgObj.h""
{{editor_cpp_includes}}
namespace editor
{
{{cpp_namespace_begin}}
struct X6PROTOEDITOR_API {{ue_fname}} : public {{if parent_def_type}} {{parent_def_type.ue_fname}}{{else}}FCfgObj{{end}}
{
{{~for field in fields ~}}
{{field.ctype.editor_ue_cpp_define_type}} {{field.name}};
{{~end~}}
{{~if !is_abstract_type~}}
bool Load(FJsonObject* _json) override;
bool Save(FJsonObject*& result) override;
{{~end~}}
static bool Create(FJsonObject* _json, {{ue_fname}}*& result);
};
{{cpp_namespace_end}}

View File

@ -0,0 +1,21 @@
#pragma once
#include ""CoreMinimal.h""
namespace editor
{
{{cpp_namespace_begin}}
enum class {{ue_fname}}
{
{{~for item in items ~}}
{{item.name}} = {{item.value}},
{{~end~}}
};
bool X6PROTOEDITOR_API {{ue_fname}}ToString({{ue_fname}} value, FString& s);
bool X6PROTOEDITOR_API {{ue_fname}}FromString(const FString& s, {{ue_fname}}& x);
{{cpp_namespace_end}}
}

View File

@ -0,0 +1,97 @@
#include ""JsonUtil.h""
{{includes}}
namespace editor
{
{{~for type in types~}}
{{type.cpp_namespace_begin}}
{{~if type.is_bean~}}
{{~if type.is_abstract_type~}}
bool {{type.ue_fname}}::Create(FJsonObject* _json, {{type.ue_fname}}*& result)
{
FString type;
if (_json->TryGetStringField(FString(""{{type.json_type_name_key}}""), type))
{
{{~for child in type.hierarchy_not_abstract_children~}}
if (type == ""{{cs_impl_data_type child x}}"")
{
result = new {{child.ue_fname}}();
} else
{{~end~}}
{
result = nullptr;
return false;
}
if (!result->Load(_json))
{
delete result;
return false;
}
return true;
}
else
{
result = nullptr;
return false;
}
}
{{~else~}}
bool {{type.ue_fname}}::Create(FJsonObject* _json, {{type.ue_fname}}*& result)
{
result = new {{type.ue_fname}}();
if (!result->Load(_json))
{
delete result;
return false;
}
return true;
}
bool {{type.ue_fname}}::Save(FJsonObject*& result)
{
auto _json = new FJsonObject();
_json->SetStringField(""{{type.json_type_name_key}}"", ""{{type.name}}"");
{{~for field in type.hierarchy_fields~}}
{{field.editor_ue_cpp_save}}
{{~end~}}
result = _json;
return true;
}
bool {{type.ue_fname}}::Load(FJsonObject* _json)
{
{{~for field in type.hierarchy_fields~}}
{{field.editor_ue_cpp_load}}
{{~end~}}
return true;
}
{{~end~}}
{{~else~}}
bool {{type.ue_fname}}ToString({{type.ue_fname}} value, FString& s)
{
{{~for item in type.items ~}}
if (value == {{type.ue_fname}}::{{item.name}}) { s = ""{{item.name}}""; return true; }
{{~end~}}
return false;
}
bool {{type.ue_fname}}FromString(const FString& s, {{type.ue_fname}}& value)
{
{{~for item in type.items ~}}
if (s == ""{{item.name}}"")
{
value = {{type.ue_fname}}::{{item.name}};
return true;
}
{{~end~}}
return false;
}
{{~end~}}
{{type.cpp_namespace_end}}
{{~end~}}
}