diff --git a/engine/3rdparty/zlib/include/refl/field.h b/engine/3rdparty/zlib/include/refl/field.h index 18f432a..521b1e6 100644 --- a/engine/3rdparty/zlib/include/refl/field.h +++ b/engine/3rdparty/zlib/include/refl/field.h @@ -6,8 +6,8 @@ using Ubpa::Name; using Ubpa::type_name; namespace refl { class UClass; - using Method = void(*)(...); using Offset = uint32_t; + using Method = void(*)(...); enum FieldFlag:uint32_t { FIELD_NONE_FLAG = 0, FIELD_MEMBER_FLAG = 1 << 0, @@ -16,8 +16,8 @@ namespace refl { }; struct FieldPtr { using Data = std::variant< - Offset, // offset - Method // method + Offset, // offset + Method // method >; Name name; const UClass* type; diff --git a/engine/3rdparty/zlib/include/refl/uclass.h b/engine/3rdparty/zlib/include/refl/uclass.h index 1ad8204..4a9a738 100644 --- a/engine/3rdparty/zlib/include/refl/uclass.h +++ b/engine/3rdparty/zlib/include/refl/uclass.h @@ -3,21 +3,16 @@ #include "field.h" #include "view.h" namespace refl { - enum ClassFlag :uint32_t { - CLASS_NONE_FLAG = 0, - CLASS_MEMBER_FLAG = 1 << 0, - CLASS_ATTRIBUTE_FLAG = 1 << 1, - CLASS_METHOD_FLAG = 1 << 2, - }; class UClass{ using enum FieldFlag; public: Name name; uint32_t size; - UClass* parent; + //uint32_t flag; + const UClass* parent; public: - constexpr UClass(Name name, uint32_t size, UClass* parent = nullptr) - :name(name),size(size), parent(parent){} + constexpr UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr) + :name(name), size(size), parent(parent){} ObjectView New(void* ptr = nullptr) const{ if (ptr == nullptr) { ptr = malloc(size); @@ -36,6 +31,16 @@ namespace refl { InitObject(ptr); return ptr; } + bool IsChildOf(const UClass* cls) const { + const UClass* _parent = parent; + while (_parent != nullptr) { + if (_parent == cls) { + return true; + } + _parent = _parent->parent; + } + return false; + } template bool IsChildOf(bool bthis = false) const { constexpr UClass* cls = &TypeInfo::StaticClass; @@ -56,53 +61,40 @@ namespace refl { virtual void InitObject(void* ptr)const { memset(ptr, 0, size); } - virtual const FieldPtr* GetField(const Name& name)const { + virtual const FieldPtr* GetField(const Name& name, bool isMethod)const { return nullptr; } - virtual std::vector GetParams() const { + virtual std::vector GetParams() const { return{}; } virtual void Call(const FieldPtr& field, std::vector& ArgsList)const{} - virtual bool ConvertToValue(ArgsView& args)const{ - return false; - } protected: - template - FieldPtr MakeMemberField(Name name) { + template + FieldPtr MakeMemberField(Name name, const UClass* cls) { FieldPtr::Data member = { offset }; constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; - return { name, &TypeInfo::StaticClass, {member}, flag }; + return { name, cls, {member}, flag }; } template FieldPtr MakeMethodField(R (* ptr)(Args...), Name name) { FieldPtr::Data member = { *(Method*)&ptr}; constexpr uint32_t flag = FIELD_METHOD_FLAG; - return { name, &TypeInfo::StaticClass, {member},flag }; + return { name, &TypeInfo::type...)>::StaticClass, {member},flag }; } template FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name) { FieldPtr::Data member = { *(Method*)&ptr }; constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; - return { name, &TypeInfo::StaticClass, {member},flag }; + return { name, &TypeInfo::type...)>::StaticClass, {member},flag }; } }; template<_ReflCheck_Ctor T> class UClass_Auto : public UClass{ public: using UClass::UClass; - bool ConvertToValue(ArgsView& args)const override { - if constexpr (std::is_same::value) { - using RawT = std::remove_pointer_t; - args.val = (void*)*(RawT*)args.val; - args.cls = &TypeInfo::StaticClass; - return true; - } - return false; - } protected: void InitObject(void* ptr)const override { - constexpr bool is_shallow_copyable = std::is_trivially_copyable::value; - if constexpr (!is_shallow_copyable){ + if constexpr (!std::is_trivially_copyable_v){ T obj{}; std::construct_at((T*)ptr, obj); } @@ -111,7 +103,7 @@ namespace refl { } } public: - static UClass_Auto BuildClass() { + constexpr static UClass_Auto BuildClass() { auto cls = UClass_Auto(type_name().View(), sizeof(T)); return cls; } @@ -120,41 +112,52 @@ namespace refl { template<_ReflCheck_Ctor_NoUClass T> struct TypeInfoImpl{ using UClass = UClass_Auto; - inline static UClass StaticClass = UClass::BuildClass(); + inline constexpr static UClass StaticClass = UClass::BuildClass(); }; + /* + * 模板优化 + * 成员参数转化为const void* + * 引用参数转化为指针 + */ template class UMethod_Auto : public UClass { using UClass::UClass; using MethodType = R(*)(Args...); public: - std::array UList; + std::array UList{}; - std::vector GetParams()const override { + std::vector GetParams()const override { return { UList.data(), UList.data() + UList.size()}; } void Call(const FieldPtr& field, std::vector& ArgsList)const override { - Call(field, ArgsList); - } - protected: - template - inline void Call(const FieldPtr& field, std::vector& ArgsList)const { - MethodType fptr = (MethodType)std::get(field.data); - int Indices = 0; - //fptr(ArgsList[1].val, Indices, Indices); - //fptr(std::forward((Args)Indices), ...); - int a = 1; - a = a + 1; + if constexpr (std::is_same_v) { + MethodType fptr = (MethodType)std::get(field.data); + auto param = ArgsList.rbegin(); + fptr(param++->cast_to()...); + } + else { + MethodType fptr = (MethodType)std::get(field.data); + auto param = ArgsList.rbegin(); + auto ret = ArgsList.begin(); + if (ret->cls == &TypeInfo::StaticClass) { + *(R*)ret->val = fptr(param++->cast_to()...); + } + else { + fptr(param++->cast_to()...); + } + } } public: + //为了简化判断,cls 对象 统统指向 T* static UMethod_Auto BuildClass() { - auto cls = UMethod_Auto(type_name().View(), sizeof(MethodType)); - if constexpr(!std::is_same::value) { + UMethod_Auto cls(type_name().View(), sizeof(MethodType)); + if constexpr(!std::is_same_v) { cls.UList[0] = &TypeInfo::StaticClass; } if (sizeof...(Args) > 0) { auto ptr = &cls.UList[1]; - (...,(*ptr = &TypeInfo::StaticClass, ptr++)); + (...,(*ptr = &TypeInfo*>::StaticClass, ptr++)); } return cls; } @@ -175,11 +178,14 @@ _cache_get: bool isChild = cache->type->IsChildOf(true); } return isChild; } - auto field = cls->GetField(name); + auto field = cls->GetField(name, false); if (field) { cache = field; goto _cache_get; } + if (cls->parent) { + return Parent().Get(name, t); + } return false; } template @@ -193,18 +199,24 @@ _cache_set: bool isChild = cache->type->IsChildOf(true); } return isChild; } - auto field = cls->GetField(name); + auto field = cls->GetField(name, false); if (field) { cache = field; goto _cache_set; } + if (cls->parent) { + return Parent().Set(name, t); + } return false; } template bool ObjectView::Invoke(const Name& name, Args&&... args) { - auto field = cls->GetField(name); + auto field = cls->GetField(name, true); if (!field) { + if (cls->parent) { + return Parent().Invoke(name, args...); + } return false; } constexpr int inputSize = sizeof...(Args); @@ -218,41 +230,66 @@ _cache_set: bool isChild = cache->type->IsChildOf(true); ArgsList.reserve(paramsSize); ArgsList.emplace_back(); if (member) { - ArgsList.emplace_back(ptr, cls ); + ArgsList.emplace_back(ptr, &TypeInfo::StaticClass); } - (..., (ArgsList.emplace_back((void*)&args, &TypeInfo::StaticClass))); + (..., (ArgsList.emplace_back(args))); for (int i = member + 1; i < paramsSize; i++) { if (ArgsList[i].cls != params[i]) { - ArgsList[i].ConvertTo(params[i]); + if (!ArgsList[i].ConvertTo(params[i])) { + return false; + } } } field->type->Call(*field, ArgsList); - return false; - } - template - inline bool ObjectView::InvokeRet(const Name& name, R& ret, Args&& ...args) - { - auto field = cls->GetField(name); - if (!field) { - return false; - } - if (field->flag & FIELD_MEMBER_FLAG) { - using MemberMethodType = R(*)(const void*, Args...); - MemberMethodType fptr = (MemberMethodType)std::get(field->data); - ret = fptr(ptr, std::forward(args)...); - } - else { - using MethodType = R(*)(Args...); - MethodType fptr = (MethodType)std::get(field->data); - ret = fptr(std::forward(args)...); - } return true; } - bool ArgsView::ConvertTo(UClass* toClass) { - ArgsView args{val}; - cls->ConvertToValue(args); - if (args.cls == toClass) { - *this = args; + template<_ReflCheck_Ctor R, typename ...Args> + R ObjectView::Invoke(const Name& name, Args&&... args) + { + auto field = cls->GetField(name, true); + if (!field) { + if (cls->parent) { + return Parent().Invoke(name, args...); + } + return {}; + } + R ret{}; + constexpr int inputSize = sizeof...(Args); + auto params = field->type->GetParams(); + int paramsSize = params.size(); + bool member = field->flag & FIELD_MEMBER_FLAG; + if (inputSize + member >= paramsSize) { + return false; + } + std::vector ArgsList; + ArgsList.reserve(paramsSize); + ArgsList.emplace_back(ret); + if (member) { + ArgsList.emplace_back(ptr, &TypeInfo::StaticClass); + } + (..., (ArgsList.emplace_back(args))); + for (int i = 0; i < paramsSize; i++) { + if (ArgsList[i].cls != params[i]) { + if (!ArgsList[i].ConvertTo(params[i])) { + return ret; + } + } + } + field->type->Call(*field, ArgsList); + return ret; + } + ObjectView ObjectView::Parent() { + return { ptr, cls ? cls->parent : nullptr }; + } + /*平凡对象的转化要支持吗 + * 比如同大小的安全转化 + * 对象从小到大 + * 对象从大到小 + */ + bool ArgsView::ConvertTo(const UClass* toClass) { + //子类转父类 + if (cls->IsChildOf(toClass)) { + cls = toClass; return true; } return false; diff --git a/engine/3rdparty/zlib/include/refl/view.h b/engine/3rdparty/zlib/include/refl/view.h index eb7487f..bc0b88e 100644 --- a/engine/3rdparty/zlib/include/refl/view.h +++ b/engine/3rdparty/zlib/include/refl/view.h @@ -1,4 +1,6 @@ +#pragma once #include +#include "type.h" namespace refl { class UClass; class FieldPtr; @@ -19,14 +21,31 @@ namespace refl { template bool Invoke(const Name& name, Args&&... args); - template - bool InvokeRet(const Name& name,R& ret, Args&&... args); + template<_ReflCheck_Ctor R, typename ...Args> + R Invoke(const Name& name, Args&&... args); + + ObjectView Parent(); }; class ArgsView { public: const void* val; const UClass* cls; ArgsView(const void* val = nullptr, const UClass* cls = nullptr) : val(val), cls(cls) {} - bool ConvertTo(UClass* toClass); + template + ArgsView(T&& v): val(&v), cls(&TypeInfo*>::StaticClass){} + + template + inline T cast_to() { + if constexpr (std::is_pointer_v) { + return (T)val; + } + else if constexpr (std::is_reference_v){ + using RT = std::remove_reference_t; + return *(RT*)val; + }else{ + return *(T*)val; + } + } + bool ConvertTo(const UClass* toClass); }; } \ 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 99c90fa..0c8fdc7 100644 --- a/engine/3rdparty/zlib/test/refl_01.cpp +++ b/engine/3rdparty/zlib/test/refl_01.cpp @@ -7,7 +7,10 @@ using namespace std; using namespace refl; struct vec3_parent { - + virtual void norm(int x1, int& x2) { + x2 = x1 * x2; + cout << x2 << "vec3_parent::norm" << endl; + } }; struct vec3 : public vec3_parent { using UClass = class vec3_UClass; @@ -15,10 +18,6 @@ struct vec3 : public vec3_parent { float y = 2; float z = 3; string name{ "hellohellohellohellohellohello" }; - void norm(int x1, int& x2) { - x2 = x1 * x * y * z * x2; - cout << x2 << "::norm" << endl; - } virtual float norm1(int x1 = 10) { cout << x1 << "::norm1" << endl; return x * y *z * x1; @@ -34,11 +33,18 @@ struct vec3 : public vec3_parent { struct vec3_UClass : public UClass { public: array FList; + int32_t AttrNum; using UClass::UClass; - const FieldPtr* GetField(const Name& name)const override { - for (auto& field : FList) { - if (field.name == name) { - return &field; + const FieldPtr* GetField(const Name& name, bool isMethod)const override { + // 指定开始位置的迭代器 + auto start = FList.begin(); + if (isMethod) { + start += AttrNum; + } + auto end = FList.end(); + for (auto it = start; it != end; ++it) { + if (it->name == name) { + return &*it; } } return nullptr; @@ -50,11 +56,12 @@ public: static vec3_UClass BuildClass() { vec3_UClass cls(type_name().View(), sizeof(vec3), &TypeInfo::StaticClass); //offsetof(vec3, x) 很坑,相当坑 - cls.FList[0] = cls.MakeMemberField("x"); - cls.FList[1] = cls.MakeMemberField("y"); - cls.FList[2] = cls.MakeMemberField("z"); + cls.AttrNum = 3; + cls.FList[0] = cls.MakeMemberField("x", &TypeInfo::StaticClass); + cls.FList[1] = cls.MakeMemberField("y", &TypeInfo::StaticClass); + cls.FList[2] = cls.MakeMemberField("z", &TypeInfo::StaticClass); cls.FList[3] = cls.MakeMethodField(&vec3::norm, "norm"); - //cls.FList[4] = cls.MakeMethodField(&vec3::norm1, "norm1"); + cls.FList[4] = cls.MakeMethodField(&vec3::norm1, "norm1"); //cls.FList[5] = cls.MakeMethodField(&vec3::norm2, "norm2"); return cls; } @@ -63,31 +70,48 @@ template void printt(void* ptr, std::vector& ArgsList) { using MethodType = void (*)(Args...); MethodType fptr = (MethodType)ptr; - auto param = ArgsList.begin(); - auto val1 = (++param)->val; - auto val2 = (++param)->val; - auto val3 = (++param)->val; - fptr(val1, (int)val2, (int*)(void *)val3); - //fptr(val1, (int)val2, std::forward((int&)val3)); + { + auto param = ArgsList.rbegin(); + fptr(param++->cast_to()...); + //fptr((Args)param++->val...); + } + /* { + auto param = ArgsList.begin(); + auto val1 = (++param); + auto val2 = (++param); + auto val3 = (++param); + fptr(val1->cast_to(), val1->cast_to(), val1->cast_to(); + } + */ //fptr((++param)->val, (int)(++param)->val, (int&)(++param)->val); - //fptr(std::forward(Args(param++->val))...); + //fptr(std::forward((Args)(++param)->val)...); int x = 1; x = x + 1; } int main() { auto cls = &TypeInfo::StaticClass; + auto cls2 = &TypeInfo::StaticClass; + auto cls3 = &TypeInfo::StaticClass; + auto cls4 = &TypeInfo::StaticClass; + auto cls5 = &TypeInfo::StaticClass; vec3 v; int x = 1, y = 2; std::vector ArgsList; ArgsList.emplace_back(); - ArgsList.emplace_back(&v); - ArgsList.emplace_back((void*)x); - ArgsList.emplace_back(&y); + ArgsList.emplace_back(v); + ArgsList.emplace_back(x); + ArgsList.emplace_back(y); auto ptr1 = &vec3::norm; - using MethodType = void (*)(void*, int, int*); + using MethodType = void (*)(void*, int, int&); MethodType ptr2 = *(MethodType*)&ptr1; - ptr2(&v, x , &y); - printt(*(void**)&ptr1, ArgsList); + using R = int; + using RetType = void*; + auto ttt = sizeof(void*); + RetType ret; + //ptr2(&v, x , y); + auto ov = cls->New((void*)& v); + ov.Invoke("norm", x, y); + printt(*(void**)&ptr1, ArgsList); //ptr2(x, y); - //cout << "hello world\n"; + cout << "hello world\n"; } \ No newline at end of file