From 9df2624221e0546ee3da4ddf0914b49dba3cddca Mon Sep 17 00:00:00 2001 From: ouczbs Date: Thu, 13 Jun 2024 21:34:13 +0800 Subject: [PATCH] refl support ctor --- .gitignore | 1 + src/refl/ClassMeta.cs | 25 +++++- src/refl/GenMeta.cs | 18 ++-- src/refl/cpp/gen/vertex_gen.inl | 30 ------- src/refl/cpp/gen/vkmeta_vertex_gen.inl | 118 ------------------------ src/refl/cpp/vertex.h | 120 +++++++++++++++---------- src/refl/template/meta.liquid | 16 +++- 7 files changed, 124 insertions(+), 204 deletions(-) delete mode 100644 src/refl/cpp/gen/vertex_gen.inl delete mode 100644 src/refl/cpp/gen/vkmeta_vertex_gen.inl diff --git a/.gitignore b/.gitignore index d0dcd5a..018bead 100644 --- a/.gitignore +++ b/.gitignore @@ -369,3 +369,4 @@ tmp/ # Remove artifacts produced by dotnet-releaser artifacts-dotnet-releaser/ +src/refl/cpp/gen/ diff --git a/src/refl/ClassMeta.cs b/src/refl/ClassMeta.cs index 73ae745..470f381 100644 --- a/src/refl/ClassMeta.cs +++ b/src/refl/ClassMeta.cs @@ -1,4 +1,5 @@ using CppAst; +using Irony; namespace refl { @@ -18,11 +19,12 @@ namespace refl { public List MemberList { get; set; } public List MethodList { get; set; } - + public List CtorList { get; set; } public FieldMeta() { MemberList = new List(); MethodList = new List(); + CtorList = new List(); } } internal class ClassMeta @@ -32,7 +34,6 @@ namespace refl public string Path { get; set; } public Dictionary Fields { get; set; } - public ClassMeta(string name, string parentName) { Name = name; @@ -85,6 +86,26 @@ namespace refl cls_meta.Fields[key].MemberList.Add(new FieldData(field.Name, value)); } } + foreach (var func in cppClass.Constructors) + { + if (func.Attributes.Count == 0) + continue; + foreach (var attribute in func.Attributes) + { + string key, value; + MetaToken.ParseMeta(attribute.Arguments, out key, out value); + if (!cls_meta.Fields.ContainsKey(key)) + { + cls_meta.Fields.Add(key, new FieldMeta()); + } + List nameList = new List{ cppClass.Name }; + foreach (var parm in func.Parameters) + { + nameList.Add(parm.Type.FullName); + } + cls_meta.Fields[key].CtorList.Add(new FieldData(string.Join(",", nameList), value)); + } + } foreach (var func in cppClass.Functions) { if (func.Attributes.Count == 0) diff --git a/src/refl/GenMeta.cs b/src/refl/GenMeta.cs index 6481214..a78beab 100644 --- a/src/refl/GenMeta.cs +++ b/src/refl/GenMeta.cs @@ -8,13 +8,13 @@ namespace refl { public string Name { get; set; } public string Meta { get; set; } - public bool IsMethod { get; set; } + public int Type { get; set; } - public FieldMetaData(string name, string meta, bool isMethod) + public FieldMetaData(string name, string meta, int type) { Name = name; Meta = meta; - IsMethod = isMethod; + Type = type; } } internal class ClassMetaData @@ -26,6 +26,8 @@ namespace refl public string Indent2 { get; set; } = ""; public string MetaName { get; set; } = ""; public bool IsMultyMeta { get; set; } = false; + public int MemberCount { get; set; } = 0; + public int CtorCount { get; set; } = 0; public List FieldList = new List(); @@ -70,12 +72,18 @@ namespace refl data.FieldList.Clear(); foreach (var field in pair.Value.MemberList) { - data.FieldList.Add(new FieldMetaData(field.Name, field.Meta, false)); + data.FieldList.Add(new FieldMetaData(field.Name, field.Meta, 1)); + } + foreach (var field in pair.Value.CtorList) + { + data.FieldList.Add(new FieldMetaData(field.Name, field.Meta, 2)); } foreach (var field in pair.Value.MethodList) { - data.FieldList.Add(new FieldMetaData(field.Name, field.Meta, true)); + data.FieldList.Add(new FieldMetaData(field.Name, field.Meta, 3)); } + data.MemberCount = pair.Value.MemberList.Count; + data.CtorCount = pair.Value.CtorList.Count; data.IsMultyMeta = !pair.Key.Equals("Meta"); data.MetaName = pair.Key; isMulty = isMulty || data.IsMultyMeta; diff --git a/src/refl/cpp/gen/vertex_gen.inl b/src/refl/cpp/gen/vertex_gen.inl deleted file mode 100644 index 42a9cbe..0000000 --- a/src/refl/cpp/gen/vertex_gen.inl +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -namespace engineapi { - struct PosVertex_MulytMeta { - static const refl::UClass* vkMeta(); - static const refl::UClass* GetMeta(const Name& name) { - if (name == FName("vkMeta")) { - return vkMeta(); - } - return nullptr; - } - }; - 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; - } - }; -} diff --git a/src/refl/cpp/gen/vkmeta_vertex_gen.inl b/src/refl/cpp/gen/vkmeta_vertex_gen.inl deleted file mode 100644 index 06e6879..0000000 --- a/src/refl/cpp/gen/vkmeta_vertex_gen.inl +++ /dev/null @@ -1,118 +0,0 @@ -#pragma once -namespace engineapi { - struct PosVertex_Static_vkMeta { - consteval static auto __StaticFields() { - return std::make_tuple(&PosVertex::Position); - }; - - consteval static auto __MakeStaticFields() { - return std::array{ - refl::StaticMemberField(&PosVertex::Position, FName("Position"), {{}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT }}), - }; - }; - - consteval static int Size() { - return refl::fetch_meta_size(); - }; - }; - - struct PosVertex_vkMeta : public refl::Meta { - using MyUClass = refl::UClass_Meta; - using MyStatic = PosVertex_Static_vkMeta; - using MyMetas = class PosVertex_MulytMeta; - inline static char s_data[MyStatic::Size()]{}; - static auto __MakeFields() { - char* memory = &s_data[0]; - return std::array{ - MemberField(&PosVertex::Position, FName("Position"), memory, {{}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT }}), - }; - }; - }; - 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(); - }; - }; - - struct TexVertex_vkMeta : public refl::Meta { - using MyUClass = refl::UClass_Meta; - 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(); - }; - }; - - struct BoneVertex_vkMeta : public refl::Meta { - using MyUClass = refl::UClass_Meta; - 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; - }; -} diff --git a/src/refl/cpp/vertex.h b/src/refl/cpp/vertex.h index d01dee8..69a394a 100644 --- a/src/refl/cpp/vertex.h +++ b/src/refl/cpp/vertex.h @@ -1,47 +1,75 @@ -#pragma once -#include "math/vector3.h" -#include "math/vector2.h" -#include "meta.h" -// 顶点最多关联4个骨骼 -#define MAX_NUM_BONES_PER_VERTEX 4 - -namespace engineapi { - struct Vertex { - - }; - struct PosVertex { - using MyMetas = class PosVertex_MultyMeta; - UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT }) - Vector3 Position = {}; - }; - struct TexVertex : public Vertex { - using MyMetas = class TexVertex_MulytMeta; - UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT }) - Vector3 Position = {}; - UPROPERTY_vk() - Vector3 Normal = {}; - UPROPERTY_vk() - Vector2 TexCoords = {}; - }; - struct BoneVertex : public Vertex - { - using MyMetas = class BoneVertex_MulytMeta; - UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT }) - Vector3 Position = {}; - UPROPERTY_vk() - Vector2 TexCoords = {}; - UPROPERTY_vk() - Vector3 Normal = {}; - UPROPERTY_vk() - Vector3 Tangent = {}; - // 骨骼蒙皮数据 - UPROPERTY_vk() - float Weights[MAX_NUM_BONES_PER_VERTEX] = {}; - UPROPERTY_vk() - uint32_t BoneIDs[MAX_NUM_BONES_PER_VERTEX] = {}; - UFUNCTION_vk({1,2},"hello") - void AddBoneData(uint32_t boneID, float weight); - }; +#include +#include "refl/refl.h" +using namespace std; +using namespace refl; +struct vec3_parent { + virtual int norm(int x1, int& x2) { + x2 = x1 * x2; + return x2; + //cout << x2 << "vec3_parent::norm" << endl; + } }; - -#include "vertex_gen.inl" \ No newline at end of file +struct vec3 : public vec3_parent { + using MyMeta = class vec3_Meta; + UPROPERTY_vk({ 1.f }) + float x = 1; + UPROPERTY_dx({ 2.f }) + float y = 2; + UPROPERTY({ 5.f }) + float z = 3; + UPROPERTY({ "hello meta" }) + string name = "???"; + UPROPERTY_vk({ 1.f }) + UFUNCTION({}) + vec3() { + } + UPROPERTY_vk({ 1.f }) + UFUNCTION({}) + vec3(float x1) { + x = x1; + } + UPROPERTY_dx({ 2.f }) + UFUNCTION({}) + vec3(float x1, float y1) { + x = x1; + y = y1; + } + UFUNCTION({}) + vec3(float x1, float y1, float z1) { + x = x1; + y = y1; + z = z1; + } + UFUNCTION({}) + vec3(float x1, float y1, float z1, float w1) { + x = x1; + y = y1; + z = z1; + } + UFUNCTION({ {3,4} }) + int norm(int x1, int& x2)override { + int tmp = x1 * 2 + 1; + x1 = x2; + x2 = tmp; + return x2; + //cout << x2 << "vec3::norm" << endl; + } + UFUNCTION({}) + virtual float norm1(int& x1) { + x1 = x1 * x * y * z; + x = x1; + y = x1 - 1; + //z = x1 - 10; + //cout << x1 << "::norm1" << endl; + return x1; + } + UFUNCTION({}) + static void norm2(int x1 = 10) { + cout << x1 << "::norm2" << endl; + } + UFUNCTION({}) + static void norm3(int x1 = 10) { + x1 = x1 * 10; + cout << x1 << "::norm3" << endl; + } +}; \ No newline at end of file diff --git a/src/refl/template/meta.liquid b/src/refl/template/meta.liquid index 681915a..f7854a4 100644 --- a/src/refl/template/meta.liquid +++ b/src/refl/template/meta.liquid @@ -1,14 +1,16 @@ {%- assign NewLine = newline_to_br -%} {{ Indent2 }}struct {{ Name }}_Static_{{MetaName}} { {{ Indent2 }} consteval static auto __StaticFields() { -{{ Indent2 }} return std::make_tuple({% for field in FieldList %}&{{Name}}::{{field.Name}}{% unless forloop.last %}, {% endunless %}{% endfor %}); +{{ Indent2 }} return std::make_tuple({% for field in FieldList %}{% if field.Type != 2 %}{% unless forloop.first %}, {% endunless %}&{{Name}}::{{field.Name}}{% endif %}{% endfor %}); {{ Indent2 }} }; {{ NewLine }} {{ Indent2 }} consteval static auto __MakeStaticFields() { {{ Indent2 }} return std::array{ {{ NewLine }} {%- for field in FieldList -%} -{{ NewLine }} {%- if field.IsMethod -%} +{{ NewLine }} {%- if field.Type == 1 -%} {{ Indent2 }} refl::StaticMethodField(&{{Name}}::{{field.Name}}, FName("{{field.Name}}"), {{field.Meta}}), +{{ NewLine }} {%- elsif field.Type == 2 -%} +{{ Indent2 }} refl::StaticCtorField<{{field.Name}}>({{field.Meta}}), {{ NewLine }} {%- else -%} {{ Indent2 }} refl::StaticMemberField(&{{Name}}::{{field.Name}}, FName("{{field.Name}}"), {{field.Meta}}), {{ NewLine }} {%- endif -%} @@ -19,6 +21,12 @@ {{ Indent2 }} consteval static int Size() { {{ Indent2 }} return refl::fetch_meta_size<{{ Name }}_Static_{{MetaName}}>(); {{ Indent2 }} }; +{{ Indent2 }} consteval static int MemberCount() { +{{ Indent2 }} return {{MemberCount}}; +{{ Indent2 }} }; +{{ Indent2 }} consteval static int CtorCount() { +{{ Indent2 }} return {{CtorCount}}; +{{ Indent2 }} }; {{ Indent2 }}}; {{ NewLine }} {{ Indent2 }}struct {{ Name }}_{{MetaName}} : public refl::Meta { @@ -32,8 +40,10 @@ {{ Indent2 }} char* memory = &s_data[0]; {{ Indent2 }} return std::array{ {{ NewLine }} {%- for field in FieldList -%} -{{ NewLine }} {%- if field.IsMethod -%} +{{ NewLine }} {%- if field.Type == 1 -%} {{ Indent2 }} MethodField(&{{Name}}::{{field.Name}}, FName("{{field.Name}}"), memory, {{field.Meta}}), +{{ NewLine }} {%- elsif field.Type == 2 -%} +{{ Indent2 }} CtorField<{{field.Name}}>({{field.Meta}}), {{ NewLine }} {%- else -%} {{ Indent2 }} MemberField(&{{Name}}::{{field.Name}}, FName("{{field.Name}}"), memory, {{field.Meta}}), {{ NewLine }} {%- endif -%}