support multy meta

This commit is contained in:
ouczbs 2024-04-29 14:58:45 +08:00
parent 9815ea28bb
commit 26086ef353
12 changed files with 313 additions and 261 deletions

View File

@ -76,15 +76,13 @@ namespace refl
continue; continue;
foreach (var attribute in field.Attributes) foreach (var attribute in field.Attributes)
{ {
var attr_metas = MetaToken.ParseMeta(attribute.Arguments); string key, value;
foreach (var pair in attr_metas) MetaToken.ParseMeta(attribute.Arguments, out key, out value);
if (!cls_meta.Fields.ContainsKey(key))
{ {
if (!cls_meta.Fields.ContainsKey(pair.Key)) cls_meta.Fields.Add(key, new FieldMeta());
{
cls_meta.Fields.Add(pair.Key, new FieldMeta());
}
cls_meta.Fields[pair.Key].MemberList.Add(new FieldData(field.Name, pair.Value));
} }
cls_meta.Fields[key].MemberList.Add(new FieldData(field.Name, value));
} }
} }
foreach (var func in cppClass.Functions) foreach (var func in cppClass.Functions)
@ -93,15 +91,13 @@ namespace refl
continue; continue;
foreach (var attribute in func.Attributes) foreach (var attribute in func.Attributes)
{ {
var attr_metas = MetaToken.ParseMeta(attribute.Arguments); string key, value;
foreach (var pair in attr_metas) MetaToken.ParseMeta(attribute.Arguments, out key, out value);
if (!cls_meta.Fields.ContainsKey(key))
{ {
if (!cls_meta.Fields.ContainsKey(pair.Key)) cls_meta.Fields.Add(key, new FieldMeta());
{
cls_meta.Fields.Add(pair.Key, new FieldMeta());
}
cls_meta.Fields[pair.Key].MethodList.Add(new FieldData(func.Name, pair.Value));
} }
cls_meta.Fields[key].MethodList.Add(new FieldData(func.Name, value));
} }
} }
return cls_meta; return cls_meta;

View File

@ -1,5 +1,6 @@
using Fluid; using Fluid;
using System.Text; using System.Text;
using System.Xml.Linq;
namespace refl namespace refl
{ {
@ -15,7 +16,7 @@ namespace refl
public static bool InitTemplate(string dir) public static bool InitTemplate(string dir)
{ {
string meta_file = Path.Combine(dir, "meta.liquid"); string meta_file = Path.Combine(dir, "meta.liquid");
string multy_meta_file = Path.Combine(dir, "meta.liquid"); string multy_meta_file = Path.Combine(dir, "multy_meta.liquid");
var parser = new FluidParser(); var parser = new FluidParser();
return GenMeta.InitTemplate(meta_file, parser) && GenMultyMeta.InitTemplate(multy_meta_file, parser); return GenMeta.InitTemplate(meta_file, parser) && GenMultyMeta.InitTemplate(multy_meta_file, parser);
} }
@ -90,26 +91,29 @@ namespace refl
} }
public void GenClassMeta(ClassMeta cls, ClassMetaData data) public void GenClassMeta(ClassMeta cls, ClassMetaData data)
{ {
meta.GenClassMeta(cls, data); if (meta.GenClassMeta(cls, data))
if (cls.Fields.Count > 0)
{ {
multyMeta.GenClassMeta(cls, data); var res = multyMeta.GenClassMeta(cls, data.Indent2);
Output.Append(res);
} }
} }
public static void GenNamespaceBegin(string indent, string name_space) public static void GenNamespaceBegin(string indent, string name_space)
{ {
string line = $"{indent}namespace {name_space} {{";
foreach (var name in ModuleMeta.NameSet) foreach (var name in ModuleMeta.NameSet)
{ {
string line = $"{indent}namespace {name_space} {{";
FileList[name].AppendLine(line); FileList[name].AppendLine(line);
} }
Output.AppendLine(line);
} }
public static void GenNamespaceEnd(string indent) public static void GenNamespaceEnd(string indent)
{ {
string line = $"{indent}}}";
foreach (var name in ModuleMeta.NameSet) foreach (var name in ModuleMeta.NameSet)
{ {
FileList[name].AppendLine($"{indent}}}"); FileList[name].AppendLine(line);
} }
Output.AppendLine(line);
} }
public static void Append(string name, string res) public static void Append(string name, string res)
{ {

View File

@ -60,10 +60,11 @@ namespace refl
} }
return true; return true;
} }
public void GenClassMeta(ClassMeta cls, ClassMetaData data) public bool GenClassMeta(ClassMeta cls, ClassMetaData data)
{ {
data.Name = cls.Name; data.Name = cls.Name;
data.ParentName = cls.ParentName; data.ParentName = cls.ParentName;
bool isMulty = false;
foreach (var pair in cls.Fields) foreach (var pair in cls.Fields)
{ {
data.FieldList.Clear(); data.FieldList.Clear();
@ -77,10 +78,12 @@ namespace refl
} }
data.IsMultyMeta = !pair.Key.Equals("Meta"); data.IsMultyMeta = !pair.Key.Equals("Meta");
data.MetaName = pair.Key; data.MetaName = pair.Key;
isMulty = isMulty || data.IsMultyMeta;
var context = new TemplateContext(data, options); var context = new TemplateContext(data, options);
var res = template.Render(context); var res = template.Render(context);
Gen.Append(pair.Key, res); Gen.Append(pair.Key, res);
} }
return isMulty;
} }
} }
} }

View File

@ -7,6 +7,14 @@ using System.Threading.Tasks;
namespace refl namespace refl
{ {
internal class MultyMetaClassData
{
public string Name { get; set; } = "";
public string Indent2 { get; set; } = "";
public bool HasMeta { get; set; } = false;
public List<string> MetaList = new List<string>();
}
internal class GenMultyMeta internal class GenMultyMeta
{ {
private static IFluidTemplate? template; private static IFluidTemplate? template;
@ -22,9 +30,24 @@ namespace refl
} }
return true; return true;
} }
public void GenClassMeta(ClassMeta cls, ClassMetaData data) public string GenClassMeta(ClassMeta cls, string indent)
{ {
MultyMetaClassData data = new MultyMetaClassData();
data.Name = cls.Name;
data.Indent2 = indent;
foreach (var pair in cls.Fields)
{
if (pair.Key.Equals("Meta"))
{
data.HasMeta = true;
}
else
{
data.MetaList.Add(pair.Key);
}
}
var context = new TemplateContext(data, options);
return template.Render(context);
} }
} }
} }

View File

@ -3,83 +3,62 @@ namespace refl
{ {
internal class MetaToken internal class MetaToken
{ {
enum State /*
{
Start,
Key,
Value
}
// 判断左右括号是否匹配的辅助方法
static bool IsMatching(char left, char right) static bool IsMatching(char left, char right)
{ {
return (left == '(' && right == ')') || return (left == '(' && right == ')') ||
(left == '[' && right == ']') || (left == '[' && right == ']') ||
(left == '{' && right == '}'); (left == '{' && right == '}') ||
(left == '"' && right == '"') ||
(left == '\'' && right == '\'');
} }
public static Dictionary<string,string> ParseMeta(string line) public static int FindTokenIndex(string line)
{ {
State state = State.Start;
StringBuilder key = new StringBuilder();
StringBuilder value = new StringBuilder();
Stack<char> stack = new Stack<char>(); Stack<char> stack = new Stack<char>();
Dictionary<string,string> metas = new Dictionary<string, string>(); for(int i = 0, l = line.Length;i < l; i++)
foreach (char c in line)
{ {
switch (state) var c = line[i];
if (c == ',' && stack.Count == 0)
{ {
case State.Start: return i;
if (!char.IsWhiteSpace(c)) }
{ if(stack.Count > 0 && IsMatching(stack.Peek(), c))
key.Append(c); {
state = State.Key; stack.Pop();
} }else if(c == '(' || c == '{' || c == '[' || c =='"' || c == '\'')
break; {
case State.Key: stack.Push(c);
if(c == ',')
{
state = State.Value;
}
else
{
key.Append(c);
}
break;
case State.Value:
if (stack.Count == 0 && (c == ',' || c == '\n'))
{
metas.Add(key.ToString().Trim(), value.ToString().Trim());
key.Clear();
value.Clear();
state = State.Start;
break;
}
value.Append(c);
if(c == '(' || c == '{' || c == '[')
{
stack.Push(c);
}else if(stack.Count > 0 && IsMatching(stack.Peek(), c))
{
stack.Pop();
}
if(c == '"')
{
if(stack.Count > 0 && stack.Peek() == c)
{
stack.Pop();
}
else
{
stack.Push(c);
}
}
break;
} }
} }
if(key.Length > 0 && value.Length > 0) return -1;
}
public static void ParseMeta(string line, out string key, out string value)
{
int index = FindTokenIndex(line);
if (index == -1)
{ {
metas.Add(key.ToString().Trim(), "{" + value.ToString().Trim()+"}"); key = line;
value = "{}";
}
else
{
key = line.Substring(0, index);
value = '{' + line.Substring(index + 1) + '}';
}
}*/
public static void ParseMeta(string line, out string key, out string value)
{
if (line.Contains(','))
{
var res = line.Split(',', 2);
key = res[0];
value = '{' + res[1] + '}';
}
else
{
key = line;
value = "{}";
} }
return metas;
} }
} }
} }

View File

@ -1,35 +0,0 @@
#pragma once
struct vec3_Static_Meta {
consteval static auto __StaticFields() {
return std::make_tuple(&vec3::z, &vec3::name, &vec3::norm, &vec3::norm1);
};
consteval static auto __MakeStaticFields() {
return std::array{
refl::StaticMemberField(&vec3::z, FName("z"), {5.f}),
refl::StaticMemberField(&vec3::name, FName("name"), {"hello meta"}),
refl::StaticMethodField(&vec3::norm, FName("norm"), {{3,4}}),
refl::StaticMethodField(&vec3::norm1, FName("norm1"), {{1}}),
};
};
consteval static int Size() {
return refl::fetch_meta_size<vec3_Static_Meta>();
};
};
struct vec3_Meta : public refl::Meta {
using MyStatic = vec3_Static_Meta;
using MyUClass = refl::UClass_Meta<vec3, vec3_parent>;;
inline static char s_data[MyStatic::Size()]{};
static auto __MakeFields() {
char* memory = &s_data[0];
return std::array{
MemberField(&vec3::z, FName("z"), memory, {5.f}),
MemberField(&vec3::name, FName("name"), memory, {"hello meta"}),
MethodField(&vec3::norm, FName("norm"), memory, {{3,4}}),
MethodField(&vec3::norm1, FName("norm1"), memory, {{1}}),
};
};
};

View File

@ -1,11 +1,30 @@
#pragma once #pragma once
#include "meta_vertex_gen.inl" namespace engineapi {
struct PosVertex_MulytMeta {
template<> static const refl::UClass* vkMeta();
struct MultyMeta<vec3> { static const refl::UClass* GetMeta(const Name& name) {
const refl::UClass* Meta() { if (name == FName("vkMeta")) {
return &TypeInfo<vec3>::StaticClass; return vkMeta();
} }
const refl::UClass* vkMeta(); return nullptr;
const refl::UClass* GetMeta(const Name& name); }
}; };
struct TexVertex_MulytMeta {
static const refl::UClass* vkMeta();
static const refl::UClass* GetMeta(const Name& name) {
if (name == FName("vkMeta")) {
return vkMeta();
}
return nullptr;
}
};
struct BoneVertex_MulytMeta {
static const refl::UClass* vkMeta();
static const refl::UClass* GetMeta(const Name& name) {
if (name == FName("vkMeta")) {
return vkMeta();
}
return nullptr;
}
};
}

View File

@ -1,31 +1,118 @@
#pragma once #pragma once
struct vec3_Static_vkMeta { namespace engineapi {
consteval static auto __StaticFields() { struct PosVertex_Static_vkMeta {
return std::make_tuple(&vec3::x, &vec3::y); consteval static auto __StaticFields() {
}; return std::make_tuple(&PosVertex::Position);
};
consteval static auto __MakeStaticFields() { consteval static auto __MakeStaticFields() {
return std::array{ return std::array{
refl::StaticMemberField(&vec3::x, FName("x"), {1.f}), refl::StaticMemberField(&PosVertex::Position, FName("Position"), {{}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT }}),
refl::StaticMemberField(&vec3::y, FName("y"), {2.f}), };
}; };
};
consteval static int Size() { consteval static int Size() {
return refl::fetch_meta_size<vec3_Static_vkMeta>(); return refl::fetch_meta_size<PosVertex_Static_vkMeta>();
}; };
}; };
struct vec3_vkMeta : public refl::Meta { struct PosVertex_vkMeta : public refl::Meta {
using MyStatic = vec3_Static_vkMeta; using MyUClass = refl::UClass_Meta<PosVertex_vkMeta, void>;
using MyUClass = refl::UClass_Meta<vec3, vec3_parent>;; using MyStatic = PosVertex_Static_vkMeta;
inline static char s_data[MyStatic::Size()]{}; using MyMetas = class PosVertex_MulytMeta;
inline static MyUClass s_cls = MyUClass(); inline static char s_data[MyStatic::Size()]{};
static auto __MakeFields() { static auto __MakeFields() {
char* memory = &s_data[0]; char* memory = &s_data[0];
return std::array{ return std::array{
MemberField(&vec3::x, FName("x"), memory, {1.f}), MemberField(&PosVertex::Position, FName("Position"), memory, {{}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT }}),
MemberField(&vec3::y, FName("y"), memory, {2.f}), };
}; };
}; };
}; const refl::UClass* PosVertex_MulytMeta::vkMeta()
{
static const auto s_cls = PosVertex_vkMeta::MyUClass();
return &s_cls;
};
struct TexVertex_Static_vkMeta {
consteval static auto __StaticFields() {
return std::make_tuple(&TexVertex::Position, &TexVertex::Normal, &TexVertex::TexCoords);
};
consteval static auto __MakeStaticFields() {
return std::array{
refl::StaticMemberField(&TexVertex::Position, FName("Position"), {{}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT }}),
refl::StaticMemberField(&TexVertex::Normal, FName("Normal"), {}),
refl::StaticMemberField(&TexVertex::TexCoords, FName("TexCoords"), {}),
};
};
consteval static int Size() {
return refl::fetch_meta_size<TexVertex_Static_vkMeta>();
};
};
struct TexVertex_vkMeta : public refl::Meta {
using MyUClass = refl::UClass_Meta<TexVertex_vkMeta, Vertex>;
using MyStatic = TexVertex_Static_vkMeta;
using MyMetas = class TexVertex_MulytMeta;
inline static char s_data[MyStatic::Size()]{};
static auto __MakeFields() {
char* memory = &s_data[0];
return std::array{
MemberField(&TexVertex::Position, FName("Position"), memory, {{}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT }}),
MemberField(&TexVertex::Normal, FName("Normal"), memory, {}),
MemberField(&TexVertex::TexCoords, FName("TexCoords"), memory, {}),
};
};
};
const refl::UClass* TexVertex_MulytMeta::vkMeta()
{
static const auto s_cls = TexVertex_vkMeta::MyUClass();
return &s_cls;
};
struct BoneVertex_Static_vkMeta {
consteval static auto __StaticFields() {
return std::make_tuple(&BoneVertex::Position, &BoneVertex::TexCoords, &BoneVertex::Normal, &BoneVertex::Tangent, &BoneVertex::Weights, &BoneVertex::BoneIDs, &BoneVertex::AddBoneData);
};
consteval static auto __MakeStaticFields() {
return std::array{
refl::StaticMemberField(&BoneVertex::Position, FName("Position"), {{}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT }}),
refl::StaticMemberField(&BoneVertex::TexCoords, FName("TexCoords"), {}),
refl::StaticMemberField(&BoneVertex::Normal, FName("Normal"), {}),
refl::StaticMemberField(&BoneVertex::Tangent, FName("Tangent"), {}),
refl::StaticMemberField(&BoneVertex::Weights, FName("Weights"), {}),
refl::StaticMemberField(&BoneVertex::BoneIDs, FName("BoneIDs"), {}),
refl::StaticMethodField(&BoneVertex::AddBoneData, FName("AddBoneData"), {{1,2},"hello"}),
};
};
consteval static int Size() {
return refl::fetch_meta_size<BoneVertex_Static_vkMeta>();
};
};
struct BoneVertex_vkMeta : public refl::Meta {
using MyUClass = refl::UClass_Meta<BoneVertex_vkMeta, Vertex>;
using MyStatic = BoneVertex_Static_vkMeta;
using MyMetas = class BoneVertex_MulytMeta;
inline static char s_data[MyStatic::Size()]{};
static auto __MakeFields() {
char* memory = &s_data[0];
return std::array{
MemberField(&BoneVertex::Position, FName("Position"), memory, {{}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT }}),
MemberField(&BoneVertex::TexCoords, FName("TexCoords"), memory, {}),
MemberField(&BoneVertex::Normal, FName("Normal"), memory, {}),
MemberField(&BoneVertex::Tangent, FName("Tangent"), memory, {}),
MemberField(&BoneVertex::Weights, FName("Weights"), memory, {}),
MemberField(&BoneVertex::BoneIDs, FName("BoneIDs"), memory, {}),
MethodField(&BoneVertex::AddBoneData, FName("AddBoneData"), memory, {{1,2},"hello"}),
};
};
};
const refl::UClass* BoneVertex_MulytMeta::vkMeta()
{
static const auto s_cls = BoneVertex_vkMeta::MyUClass();
return &s_cls;
};
}

View File

@ -8,3 +8,7 @@
#define __vkMeta(...) __cppast(vkMeta,__VA_ARGS__) #define __vkMeta(...) __cppast(vkMeta,__VA_ARGS__)
#define UPROPERTY_vk(...) __vkMeta(__VA_ARGS__) #define UPROPERTY_vk(...) __vkMeta(__VA_ARGS__)
#define UFUNCTION_vk(...) __vkMeta(__VA_ARGS__) #define UFUNCTION_vk(...) __vkMeta(__VA_ARGS__)
#define __dxMeta(...) __cppast(dxMeta,__VA_ARGS__)
#define UPROPERTY_dx(...) __dxMeta(__VA_ARGS__)
#define UFUNCTION_dx(...) __dxMeta(__VA_ARGS__)

View File

@ -1,62 +1,47 @@
#include <iostream> #pragma once
#include "refl/refl.h" #include "math/vector3.h"
using namespace std; #include "math/vector2.h"
using namespace refl; #include "meta.h"
struct vec3_parent { // 顶点最多关联4个骨骼
virtual int norm(int x1, int& x2) { #define MAX_NUM_BONES_PER_VERTEX 4
x2 = x1 * x2;
return x2; namespace engineapi {
//cout << x2 << "vec3_parent::norm" << endl; struct Vertex {
}
}; };
struct vec3 : public vec3_parent { struct PosVertex {
using MyMeta = class vec3_Meta; using MyMetas = class PosVertex_MultyMeta;
using MyMetas = MulytMeta<vec3>; UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT })
UPROPERTY_vk(1.f) Vector3 Position = {};
float x = 1; };
UPROPERTY_vk(2.f ) struct TexVertex : public Vertex {
float y = 2; using MyMetas = class TexVertex_MulytMeta;
UPROPERTY(5.f) UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT })
float z = 3; Vector3 Position = {};
UPROPERTY("hello meta") UPROPERTY_vk()
string name = "???"; Vector3 Normal = {};
UFUNCTION({3,4}) UPROPERTY_vk()
int norm(int x1, int& x2)override { Vector2 TexCoords = {};
int tmp = x1 * 2 + 1; };
x1 = x2; struct BoneVertex : public Vertex
x2 = tmp; {
return x2; using MyMetas = class BoneVertex_MulytMeta;
//cout << x2 << "vec3::norm" << endl; UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT })
} Vector3 Position = {};
UFUNCTION({1}) UPROPERTY_vk()
virtual float norm1(int& x1) { Vector2 TexCoords = {};
x1 = x1 * x * y * z; UPROPERTY_vk()
x = x1; Vector3 Normal = {};
y = x1 - 1; UPROPERTY_vk()
//z = x1 - 10; Vector3 Tangent = {};
//cout << x1 << "::norm1" << endl; // 骨骼蒙皮数据
return x1; UPROPERTY_vk()
} float Weights[MAX_NUM_BONES_PER_VERTEX] = {};
UFUNCTION() UPROPERTY_vk()
static void norm2(int x1 = 10) { uint32_t BoneIDs[MAX_NUM_BONES_PER_VERTEX] = {};
cout << x1 << "::norm2" << endl; UFUNCTION_vk({1,2},"hello")
} void AddBoneData(uint32_t boneID, float weight);
UFUNCTION() };
static void norm3(int x1 = 10) {
x1 = x1 * 10;
cout << x1 << "::norm3" << endl;
}
}; };
template<> #include "vertex_gen.inl"
struct MulytMeta<vec3> {
static const UClass* UIMeta();
static const UClass* GetMeta(const Name& name) {
if (name == FName("UIMeta")) {
return UIMeta();
}
return nullptr;
}
};
//template const UClass* MetaClass<vec3::UIMeta>();
#include "meta_vertex_gen.inl"

View File

@ -22,10 +22,12 @@
{{ Indent2 }}}; {{ Indent2 }}};
{{ NewLine }} {{ NewLine }}
{{ Indent2 }}struct {{ Name }}_{{MetaName}} : public refl::Meta { {{ Indent2 }}struct {{ Name }}_{{MetaName}} : public refl::Meta {
{{ Indent2 }} using MyUClass = refl::UClass_Meta<{{ Name }}_{{MetaName}}, {{ ParentName }}>;
{{ Indent2 }} using MyStatic = {{ Name }}_Static_{{MetaName}}; {{ Indent2 }} using MyStatic = {{ Name }}_Static_{{MetaName}};
{{ Indent2 }} using MyUClass = refl::UClass_Meta<{{ Name }}, {{ ParentName }}>;; {{ NewLine }} {%-if IsMultyMeta -%}
{{ Indent2 }} using MyMetas = class {{Name}}_MulytMeta;
{{ NewLine }} {%- endif -%}
{{ Indent2 }} inline static char s_data[MyStatic::Size()]{}; {{ Indent2 }} inline static char s_data[MyStatic::Size()]{};
{{ NewLine }} {%if IsMultyMeta %}inline static MyUClass s_cls = MyUClass();{% endif %}
{{ Indent2 }} static auto __MakeFields() { {{ Indent2 }} static auto __MakeFields() {
{{ Indent2 }} char* memory = &s_data[0]; {{ Indent2 }} char* memory = &s_data[0];
{{ Indent2 }} return std::array{ {{ Indent2 }} return std::array{
@ -39,4 +41,10 @@
{{ Indent2 }} }; {{ Indent2 }} };
{{ Indent2 }} }; {{ Indent2 }} };
{{ Indent2 }}}; {{ Indent2 }}};
{{ NewLine }} {{ NewLine }}{%- if IsMultyMeta -%}
{{ Indent2 }}const refl::UClass* {{Name}}_MulytMeta::{{ MetaName }}()
{{ Indent2 }}{
{{ Indent2 }} static const auto s_cls = {{ Name }}_{{MetaName}}::MyUClass();
{{ Indent2 }} return &s_cls;
{{ Indent2 }}};
{{ NewLine }}{%- endif -%}

View File

@ -1,41 +1,20 @@
{%- assign NewLine = newline_to_br -%} {%- assign NewLine = newline_to_br -%}
{{ Indent2 }}struct {{ Name }}_Static_{{MetaName}} { {{ Indent2 }}struct {{Name}}_MulytMeta {
{{ Indent2 }} consteval static auto __StaticFields() { {{ NewLine }}{%- for Meta in MetaList -%}
{{ Indent2 }} return std::make_tuple({% for field in FieldList %}&{{Name}}::{{field.Name}}{% unless forloop.last %}, {% endunless %}{% endfor %}); {{ Indent2 }} static const refl::UClass* {{Meta}}();
{{ Indent2 }} }; {{ NewLine }}{%- endfor -%}
{{ NewLine }} {{ Indent2 }} static const refl::UClass* GetMeta(const Name& name) {
{{ Indent2 }} consteval static auto __MakeStaticFields() { {{ NewLine }}{%- for Meta in MetaList -%}
{{ Indent2 }} return std::array{ {{ Indent2 }} if (name == FName("{{Meta}}")) {
{{ NewLine }} {%- for field in FieldList -%} {{ Indent2 }} return {{Meta}}();
{{ NewLine }} {%- if field.IsMethod -%} {{ Indent2 }} }
{{ Indent2 }} refl::StaticMethodField(&{{Name}}::{{field.Name}}, FName("{{field.Name}}"), {{field.Meta}}), {{ NewLine }}{%- endfor -%}
{{ NewLine }} {%- else -%} {{ NewLine }}{%- if HasMeta -%}
{{ Indent2 }} refl::StaticMemberField(&{{Name}}::{{field.Name}}, FName("{{field.Name}}"), {{field.Meta}}), {{ Indent2 }} if (name == FName("Meta")) {
{{ NewLine }} {%- endif -%} {{ Indent2 }} return &refl::TypeInfo<{{Name}}>::StaticClass;
{{ NewLine }} {%- endfor -%} {{ Indent2 }} }
{{ Indent2 }} }; {{ NewLine }}{%- endif -%}
{{ Indent2 }} }; {{ Indent2 }} return nullptr;
{{ NewLine }} {{ Indent2 }} }
{{ Indent2 }} consteval static int Size() {
{{ Indent2 }} return refl::fetch_meta_size<{{ Name }}_Static_{{MetaName}}>();
{{ Indent2 }} };
{{ Indent2 }}};
{{ NewLine }}
{{ Indent2 }}struct {{ Name }}_{{MetaName}} : public refl::Meta {
{{ Indent2 }} using MyStatic = {{ Name }}_Static_{{MetaName}};
{{ Indent2 }} using MyUClass = refl::UClass_Meta<{{ Name }}, {{ ParentName }}>;;
{{ Indent2 }} inline static char s_data[MyStatic::Size()]{};
{{ Indent2 }} static auto __MakeFields() {
{{ Indent2 }} char* memory = &s_data[0];
{{ Indent2 }} return std::array{
{{ NewLine }} {%- for field in FieldList -%}
{{ NewLine }} {%- if field.IsMethod -%}
{{ Indent2 }} MethodField(&{{Name}}::{{field.Name}}, FName("{{field.Name}}"), memory, {{field.Meta}}),
{{ NewLine }} {%- else -%}
{{ Indent2 }} MemberField(&{{Name}}::{{field.Name}}, FName("{{field.Name}}"), memory, {{field.Meta}}),
{{ NewLine }} {%- endif -%}
{{ NewLine }} {%- endfor -%}
{{ Indent2 }} };
{{ Indent2 }} };
{{ Indent2 }}}; {{ Indent2 }}};
{{ NewLine }} {{ NewLine }}