From a960cb0098e45157b45be4bbd64033a605d7e5d6 Mon Sep 17 00:00:00 2001 From: ouczbs Date: Sun, 14 Apr 2024 22:45:08 +0800 Subject: [PATCH] rebuild refl --- engine/3rdparty/xmake.lua | 1 - .../3rdparty/zlib/include/refl/detail/field.h | 7 ++ .../zlib/include/refl/detail/field.inl | 66 +++++++++++++++++++ .../3rdparty/zlib/include/refl/detail/type.h | 17 ++--- .../zlib/include/refl/detail/uclass.inl | 30 +++++++-- .../3rdparty/zlib/include/refl/detail/view.h | 19 +++--- .../zlib/include/refl/detail/view.inl | 28 +++++--- engine/3rdparty/zlib/include/refl/refl.h | 64 ++++++++---------- .../3rdparty/zlib/include/refl/std/sarray.h | 57 ++++++++++++++++ engine/3rdparty/zlib/test/refl/vertex.h | 40 ++++++----- engine/3rdparty/zlib/test/refl_01.cpp | 33 ++++------ 11 files changed, 255 insertions(+), 107 deletions(-) create mode 100644 engine/3rdparty/zlib/include/refl/std/sarray.h diff --git a/engine/3rdparty/xmake.lua b/engine/3rdparty/xmake.lua index ebc09d8..a96d18f 100644 --- a/engine/3rdparty/xmake.lua +++ b/engine/3rdparty/xmake.lua @@ -5,5 +5,4 @@ add_requires("tinyobjloader") add_requires("vulkansdk") add_requires("assimp") add_requires("nlohmann_json") -add_requires("ylt") add_requires("benchmark") \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/detail/field.h b/engine/3rdparty/zlib/include/refl/detail/field.h index 8790795..fabbd71 100644 --- a/engine/3rdparty/zlib/include/refl/detail/field.h +++ b/engine/3rdparty/zlib/include/refl/detail/field.h @@ -1,5 +1,6 @@ #pragma once #include "UTemplate/Type.hpp" +#include "../std/sarray.h" #include #include using Ubpa::Name; @@ -7,6 +8,7 @@ using Ubpa::type_name; namespace refl { class UClass; class ArgsView; + class ArgsValue; using Offset = uint32_t; using Method = void*; @@ -49,8 +51,13 @@ namespace refl { //unsafe bool Invoke(const std::vector& ArgsList)const; + template + R Call(Args&&... args)const; + std::vector GetParams() const; }; + template + class Field; /* template consteval V* fetch_member_v(V T::*) { diff --git a/engine/3rdparty/zlib/include/refl/detail/field.inl b/engine/3rdparty/zlib/include/refl/detail/field.inl index 42a3fe7..de3a0d4 100644 --- a/engine/3rdparty/zlib/include/refl/detail/field.inl +++ b/engine/3rdparty/zlib/include/refl/detail/field.inl @@ -1,5 +1,17 @@ #include "uclass.h" namespace refl { + template + inline R FieldPtr::Call(Args&& ...args)const + { + using MethodType = R(*)(Args...); + MethodType fptr = (MethodType)data.method; + if constexpr (std::is_same_v) { + fptr(std::forward(args)...); + } + else { + return fptr(std::forward(args)...); + } + } bool FieldPtr::Invoke(const std::vector& ArgsList)const{ auto Call = type->vtable.Call; if (Call) { @@ -42,4 +54,58 @@ namespace refl { } return{}; } + template + consteval int GetArgsSize() { + auto fields = T::__MakeStaticFields(); + int size = 0; + for (auto& field : fields) { + size += field.data.offset; + } + return size; + } + template + class Field { + public: + inline static char data[GetArgsSize()]{}; + inline static int index{0}; + template + static FieldPtr MakeField(V T::* ptr, Name name) + { + FieldPtr::Default value; + Offset offset = reinterpret_cast(&(reinterpret_cast(0)->*ptr)); + FieldPtr::Data member = { offset }; + constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; + return { name, &TypeInfo::StaticClass, member, value, flag }; + } + template + static FieldPtr MakeField(R(*ptr)(Args...), Name name, const sarray& args = {}) { + uint32_t flag = FIELD_METHOD_FLAG; + FieldPtr::Default value; + if (args.size() > 0) { + flag |= FIELD_METHOD_VALUE_FLAG; + static const ArgsValueList argsValue(args, &data[index]); + index += ArgsValueList::GetArgsSize(args); + value.method = []() ->std::pair { + return { argsValue.ptr , argsValue.num }; + }; + } + FieldPtr::Data method = { *(Method*)&ptr }; + return { name, &TypeInfo(*)(real_type_t...)>::StaticClass, method, value, flag }; + } + template + static FieldPtr MakeField(R(T::* ptr)(Args...), Name name, const sarray& args = {}) { + uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; + FieldPtr::Default value; + if (args.size() > 0) { + flag |= FIELD_METHOD_VALUE_FLAG; + static const ArgsValueList argsValue(args, &data[index]); + index += ArgsValueList::GetArgsSize(args); + value.method = []() ->std::pair { + return { argsValue.ptr , argsValue.num }; + }; + } + FieldPtr::Data method = { *(Method*)&ptr }; + return { name, &TypeInfo(*)(const void*,real_type_t...)>::StaticClass, method, value,flag }; + } + }; } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/detail/type.h b/engine/3rdparty/zlib/include/refl/detail/type.h index 311e63c..ec3822d 100644 --- a/engine/3rdparty/zlib/include/refl/detail/type.h +++ b/engine/3rdparty/zlib/include/refl/detail/type.h @@ -1,19 +1,20 @@ #pragma once #include -#define REGISTER_CLASS_META(T, P) using MyUClass = UClass_Meta; -#define REGISTER_MEMBER(Ptr, Name) MakeStaticField(Ptr, Name), -#define BUILD_FELDS() constexpr static auto __BuildFields() {\ - return std::array{\ - REGISTER_FIELDS(REGISTER_MEMBER, REGISTER_MEMBER)\ - };\ -}; namespace refl { template concept _ReflCheck_Ctor = requires { T(); }; template - concept _ReflCheck_UClass = requires { !std::is_void_v; }; + concept _ReflCheck_UClass = requires { !std::is_void_v; }; template concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor && !_ReflCheck_UClass; + + // 检查类型是否具有特定的静态成员函数 + template + struct has_init_object : std::false_type {}; + + template + struct has_init_object> : std::true_type {}; + //类型接口 template struct TypeInfoImpl; diff --git a/engine/3rdparty/zlib/include/refl/detail/uclass.inl b/engine/3rdparty/zlib/include/refl/detail/uclass.inl index 0b57ce8..ac5e192 100644 --- a/engine/3rdparty/zlib/include/refl/detail/uclass.inl +++ b/engine/3rdparty/zlib/include/refl/detail/uclass.inl @@ -119,18 +119,37 @@ namespace refl { } };*/ - + template class UClass_Meta : public UClass { public: - using FieldsType = decltype(T::__BuildFields()); - FieldsType Fields{ T::__BuildFields() }; - consteval UClass_Meta() : UClass(type_name().View(), sizeof(T)){ + using FieldsType = decltype(T::__MakeFields()); + FieldsType Fields{ T::__MakeFields() }; + UClass_Meta() : UClass(type_name().View(), sizeof(T)){ if constexpr (!std::is_same_v) { parent = &TypeInfo

::StaticClass; } + if constexpr (has_init_object::value) { + vtable.InitObject = &T::__InitObject; + } + else { + vtable.InitObject = &UClass::InitObject; + } } + const FieldPtr* GetField(int index) const { + return &Fields[index]; + } + const FieldPtr* GetField(const Name& name, int index = 0) const{ + constexpr int length = std::tuple_size::value; + auto ptr = index < length ? &Fields[index] : nullptr; + for (int i = index; i < length; i++, ptr++) { + if (name == ptr->name) { + return ptr; + } + } + return nullptr; + } }; //基础类型的偏特化 @@ -149,7 +168,6 @@ namespace refl { template<_ReflCheck_UClass T> struct TypeInfoImpl { using MyUClass = typename T::MyUClass; - //这里如何改成 constexpr - inline constexpr static MyUClass StaticClass = MyUClass(); + inline static MyUClass StaticClass = MyUClass(); }; } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/detail/view.h b/engine/3rdparty/zlib/include/refl/detail/view.h index a17bf78..4960b75 100644 --- a/engine/3rdparty/zlib/include/refl/detail/view.h +++ b/engine/3rdparty/zlib/include/refl/detail/view.h @@ -1,6 +1,7 @@ #pragma once #include #include "type.h" +#include "../std/sarray.h" namespace refl { class UClass; class FieldPtr; @@ -10,14 +11,14 @@ namespace refl { public: const void* val; const UClass* cls; - ArgsView() : val(nullptr), cls(nullptr) {} + constexpr ArgsView() : val(nullptr), cls(nullptr) {} //右值=>右值压入栈,caller入栈地址 //左值=>caller变量地址 template - ArgsView(T&& v): val(&v), cls(&TypeInfo*>::StaticClass){ + constexpr ArgsView(T&& v): val(&v), cls(&TypeInfo*>::StaticClass){ if constexpr (std::is_same_v, void*>) { val = v; - cls = &TypeInfo::StaticClass; + cls = &TypeInfo>::StaticClass; } else if constexpr (std::is_same_v, ArgsView>) { val = v.val; @@ -55,14 +56,16 @@ namespace refl { struct ArgsValue : public ArgsView { const UClass* type; template - ArgsValue(T&& t) : ArgsView(t), type(&TypeInfo>::StaticClass){} + constexpr ArgsValue(T&& t) : ArgsView(t), type(&TypeInfo>::StaticClass){} }; struct ArgsValueList{ - void* data{ nullptr }; - ArgsView* ptr{nullptr}; - int num{ 0 }; - ArgsValueList(const std::vector& args); + void* data; + ArgsView* ptr; + int num{0}; + bool isMemoryOwner{false}; + ArgsValueList(const sarray& args,void* memory = nullptr); ~ArgsValueList(); + constexpr static int GetArgsSize(const sarray& args); }; class ObjectView { public: diff --git a/engine/3rdparty/zlib/include/refl/detail/view.inl b/engine/3rdparty/zlib/include/refl/detail/view.inl index 1707fe2..40648be 100644 --- a/engine/3rdparty/zlib/include/refl/detail/view.inl +++ b/engine/3rdparty/zlib/include/refl/detail/view.inl @@ -15,20 +15,20 @@ namespace refl { } return false; } - ArgsValueList::ArgsValueList(const std::vector& args) { - num = args.size(); - int size = num * sizeof(ArgsView); - for (auto& arg : args) { - size += arg.cls->size; + ArgsValueList::ArgsValueList(const sarray& args, void* memory) + : ptr((ArgsView*)memory),data(memory), num(args.size()) + { + if (!memory) { + isMemoryOwner = true; + data = malloc(GetArgsSize(args)); + ptr = (ArgsView*)data; } - data = (void*)malloc(size); - ptr = (ArgsView*)data; char* pData = ((char*)data) + num * sizeof(ArgsView); for (auto& arg : args) { arg.type->InitObject(pData); arg.type->CopyObject(pData, arg.val); - ptr->cls = arg.cls; ptr->val = pData; + ptr->cls = arg.cls; ptr++; pData += arg.cls->size; } @@ -42,10 +42,20 @@ namespace refl { for (int i = 0; i < num; i++) { ptr->cls->DestObject((void*)ptr->val); } - free(data); + if (isMemoryOwner) { + free(data); + } num = 0; data = nullptr; } + inline constexpr int ArgsValueList::GetArgsSize(const sarray& args) + { + int size = args.size() * sizeof(ArgsView); + for (auto& arg : args) { + size += arg.type->size; + } + return size; + } template inline bool ObjectView::Get(const Name& name, T& t) { diff --git a/engine/3rdparty/zlib/include/refl/refl.h b/engine/3rdparty/zlib/include/refl/refl.h index 79f0317..bc8d343 100644 --- a/engine/3rdparty/zlib/include/refl/refl.h +++ b/engine/3rdparty/zlib/include/refl/refl.h @@ -1,58 +1,52 @@ #include "detail/uclass.inl" #include "detail/view.inl" #include "detail/field.inl" +#include "std/sarray.h" namespace refl { - /* 成员变量需要定义默认值吗?那为什么不在initObjec里初始化?*/ template consteval FieldPtr MakeStaticField(T Obj::* ptr, Name name) { FieldPtr::Default value; - FieldPtr::Data member = { nullptr }; + Offset offset = 0; + FieldPtr::Data member = { offset }; constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; return { name, &TypeInfo::StaticClass, member, value, flag }; } template - consteval FieldPtr MakeStaticField(R(*ptr)(Args...), Name name/*, const std::vector& args = {}*/) { + consteval FieldPtr MakeStaticField(R(*ptr)(Args...), Name name, const sarray& args = {}) { uint32_t flag = FIELD_METHOD_FLAG; FieldPtr::Default value; - /*if (args.size() > 0) { - flag |= FIELD_METHOD_VALUE_FLAG; - static const ArgsValueList argsValue(args); - value.method = []() ->std::pair { - return { argsValue.ptr , argsValue.num }; - }; - }*/ - FieldPtr::Data method = { nullptr }; + Offset offset = ArgsValueList::GetArgsSize(args); + FieldPtr::Data method = { offset }; return { name, &TypeInfo(*)(real_type_t...)>::StaticClass, method, value, flag }; } template - consteval FieldPtr MakeStaticField(R(T::* ptr)(Args...), Name name/*, const std::vector& args = {}*/) { + consteval FieldPtr MakeStaticField(R(T::* ptr)(Args...), Name name, const sarray& args = {}) { uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; FieldPtr::Default value; - /*if (args.size() > 0) { - flag |= FIELD_METHOD_VALUE_FLAG; - static const ArgsValueList argsValue(args); - value.method = []() ->std::pair { - return { argsValue.ptr , argsValue.num }; - }; - }*/ - //Method fptr = nullptr; - FieldPtr::Data method = { nullptr }; + Offset offset = ArgsValueList::GetArgsSize(args); + FieldPtr::Data method = { offset }; return { name, &TypeInfo(*)(const void*,real_type_t...)>::StaticClass, method, value,flag }; } - template - consteval auto MakeTuple(Args&&... args) { - return std::make_tuple(args...); - } - template - auto MakeStaticFields(const std::tuple& args) { - constexpr std::size_t N = sizeof...(Args); - std::array fields{}; - for (std::size_t i = 0; i < N; ++i) { - auto& arg = std::get<0>(args); - auto a1 = std::get<0>(arg); - auto a2 = std::get<1>(arg); - //fields[i] = MakeStaticField(std::get<0>(arg), std::get<1>(arg)); + template + consteval int GetStaticField(Name name) { + auto fields = T::__MakeStaticFields(); + auto first = fields.begin(); + for (auto& field : fields) { + if (field.name == name) { + return &field - &*first; + } } - return fields; + return 0; + } + template + consteval int GetStaticField(bool(* fptr)(FieldPtr)) { + auto fields = T::__MakeStaticFields(); + auto first = fields.begin(); + for (auto& field : fields) { + if (fptr(field)) { + return &field - &*first; + } + } + return 0; } } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/std/sarray.h b/engine/3rdparty/zlib/include/refl/std/sarray.h new file mode 100644 index 0000000..44346c4 --- /dev/null +++ b/engine/3rdparty/zlib/include/refl/std/sarray.h @@ -0,0 +1,57 @@ +#pragma once +#include +namespace refl { + template + class sarray { + protected: + const T* m_ptr; + int m_size; + public: + constexpr sarray() :m_ptr(nullptr), m_size(0) {} + constexpr sarray(std::initializer_list list) : m_ptr(list.begin()), m_size(list.size()) {} + template + constexpr sarray(const std::array& arr):m_ptr(&arr[0]), m_size(arr.size()){} + const T* get() const{ + return m_ptr; + } + const T* at(int i) const { + if (i < m_size) { + return m_ptr + i; + } + return nullptr; + } + constexpr int size() const { + return m_size; + } + constexpr const auto begin()const { + return iterator{ m_ptr }; + } + constexpr const auto end() const { + return iterator{ m_ptr + m_size}; + } + // Iterator class + class iterator { + private: + const T* ptr; + + public: + constexpr iterator(const T* p) : ptr(p) {} + + // Overload ++ to move to next element + constexpr iterator& operator++() { + ++ptr; + return *this; + } + + // Overload * to dereference iterator + constexpr const T& operator*() const { + return *ptr; + } + + // Overload != to compare iterators + constexpr bool operator!=(const iterator& other) const { + return ptr != other.ptr; + } + }; + }; +} \ No newline at end of file diff --git a/engine/3rdparty/zlib/test/refl/vertex.h b/engine/3rdparty/zlib/test/refl/vertex.h index df2b8a4..6ccb9fb 100644 --- a/engine/3rdparty/zlib/test/refl/vertex.h +++ b/engine/3rdparty/zlib/test/refl/vertex.h @@ -32,27 +32,25 @@ struct vec3 : public vec3_parent { x1 = x1 * 10; //cout << x1 << "::norm3" << endl; } - constexpr static auto __GetFields() { - return std::tuple{ - MakeTuple(&vec3::x, "x"), - MakeTuple(&vec3::y, "y"), - MakeTuple(&vec3::z, "z"), - MakeTuple(&vec3::norm, "norm"), - MakeTuple(&vec3::norm1, "norm1"), - MakeTuple(&vec3::norm2, "norm2") + using MyUClass = UClass_Meta; + consteval static auto __MakeStaticFields() { + return std::array{ + MakeStaticField(&vec3::x, "x"), + MakeStaticField(&vec3::y, "y"), + MakeStaticField(&vec3::z, "z"), + MakeStaticField(&vec3::norm, "norm", { 10,9 }), + MakeStaticField(&vec3::norm1, "norm1", { 10 }), + MakeStaticField(&vec3::norm2, "norm2", { 10 }), + }; + } + static auto __MakeFields() { + return std::array{ + Field::MakeField(&vec3::x, "x"), + Field::MakeField(&vec3::y, "y"), + Field::MakeField(&vec3::z, "z"), + Field::MakeField(&vec3::norm, "norm", {10,9}), + Field::MakeField(&vec3::norm1, "norm1", {10}), + Field::MakeField(&vec3::norm2, "norm2", {10}), }; }; - -#define REGISTER_FIELDS(MemberFunc, MethodFunc)\ - MemberFunc(&vec3::x, "x")\ - MemberFunc(&vec3::y, "y")\ - MemberFunc(&vec3::z, "z")\ - MethodFunc(&vec3::norm,"norm",{})\ - MethodFunc(&vec3::norm1,"norm1",{})\ - MethodFunc(&vec3::norm2,"norm2",{}) - REGISTER_CLASS_META(vec3, vec3_parent) - BUILD_FELDS() - - -#undef REGISTER_FIELDS }; \ No newline at end of file diff --git a/engine/3rdparty/zlib/test/refl_01.cpp b/engine/3rdparty/zlib/test/refl_01.cpp index 5132f62..a633939 100644 --- a/engine/3rdparty/zlib/test/refl_01.cpp +++ b/engine/3rdparty/zlib/test/refl_01.cpp @@ -1,28 +1,23 @@ #include "refl/vertex.h" -union MemberMethod { - using F1 = int(*)(int); - using F2 = void(*)(); - F1 f1; - F2 f2; - constexpr MemberMethod(F1 f):f1(f) { +#include "refl/std/sarray.h" +#include +struct object { - } - constexpr MemberMethod(F2 f) :f2(f) { - - } }; -void test() { - -} template -void print(T* t) { - +void testInitObject(){ + if constexpr (has_init_object::value){ + auto InitObject = &T::__InitObject; + } } int main() { - //auto& cls = TypeInfo::StaticClass; - //int FList[3]{}; - //auto norm = MakeMethodField(&vec3::norm,"norm"); - MakeStaticFields(vec3::__GetFields()); + testInitObject(); + auto& cls = TypeInfo::StaticClass; + auto field = cls.GetField(GetStaticField("norm")); + int x = 10; + auto ov = cls.New(); + ov->norm(x, x); + field->Call((void*)ov, 10, x); std::cout << "hello world\n"; return 0; } \ No newline at end of file