diff --git a/engine/3rdparty/zlib/include/refl/field.h b/engine/3rdparty/zlib/include/refl/field.h index b58db86..18f432a 100644 --- a/engine/3rdparty/zlib/include/refl/field.h +++ b/engine/3rdparty/zlib/include/refl/field.h @@ -6,16 +6,18 @@ using Ubpa::Name; using Ubpa::type_name; namespace refl { class UClass; + using Method = void(*)(...); + using Offset = uint32_t; enum FieldFlag:uint32_t { - FIELD_NONE_FLAG = 0, - FIELD_MEMBER_FLAG = 1 << 0, - FIELD_ATTRIBUTE_FLAG = 1 << 1, - FIELD_METHOD_FLAG = 1 << 2, + FIELD_NONE_FLAG = 0, + FIELD_MEMBER_FLAG = 1 << 0, + FIELD_ATTRIBUTE_FLAG = 1 << 1, + FIELD_METHOD_FLAG = 1 << 2, }; struct FieldPtr { using Data = std::variant< - uint32_t, // offset - void* // method + Offset, // offset + Method // method >; Name name; const UClass* type; diff --git a/engine/3rdparty/zlib/include/refl/object.h b/engine/3rdparty/zlib/include/refl/object.h deleted file mode 100644 index 7fe2dfb..0000000 --- a/engine/3rdparty/zlib/include/refl/object.h +++ /dev/null @@ -1,25 +0,0 @@ -#include -namespace refl { - class UClass; - class FieldPtr; - class ObjectView { - public: - const char* ptr; - const UClass* cls; - const FieldPtr* cache{nullptr}; - ObjectView(void* ptr, const UClass* cls) : ptr((const char*)ptr), cls(cls){} - public: - - template - bool Get(const Name& name, T& t); - - template - bool Set(const Name& name, const T& t); - - template - bool Invoke(const Name& name, Args... args); - - template - bool InvokeRet(const Name& name,R& ret, Args... args); - }; -} \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/type.h b/engine/3rdparty/zlib/include/refl/type.h index 5b345c3..bdfa4ef 100644 --- a/engine/3rdparty/zlib/include/refl/type.h +++ b/engine/3rdparty/zlib/include/refl/type.h @@ -8,13 +8,24 @@ namespace refl { template concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor && !_ReflCheck_UClass; - //主模板只有声明,没有定义,从而使得非特化非法 + //类型接口 template - struct TypeInfo; + struct TypeInfoImpl; template<_ReflCheck_UClass T> - struct TypeInfo { + struct TypeInfoImpl { using UClass = typename T::UClass; inline static UClass StaticClass = UClass::BuildClass(); }; + + template + struct RealTypeImpl { + using type = std::remove_cv_t>; + }; + template + struct RealTypeImpl { + using type = std::remove_cv_t*; + }; + template + using TypeInfo = TypeInfoImpl::type>; } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/uclass.h b/engine/3rdparty/zlib/include/refl/uclass.h index 732be83..1ad8204 100644 --- a/engine/3rdparty/zlib/include/refl/uclass.h +++ b/engine/3rdparty/zlib/include/refl/uclass.h @@ -1,8 +1,14 @@ #pragma once #include "type.h" #include "field.h" -#include "object.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: @@ -45,6 +51,7 @@ namespace refl { } return false; } + public: //unsafe if called by other, need check class && size virtual void InitObject(void* ptr)const { memset(ptr, 0, size); @@ -52,30 +59,46 @@ namespace refl { virtual const FieldPtr* GetField(const Name& name)const { return nullptr; } + 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(T U::* ptr, Name name) { + template + FieldPtr MakeMemberField(Name name) { FieldPtr::Data member = { offset }; constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; return { name, &TypeInfo::StaticClass, {member}, flag }; } template FieldPtr MakeMethodField(R (* ptr)(Args...), Name name) { - FieldPtr::Data member = { *(void**)&ptr }; + FieldPtr::Data member = { *(Method*)&ptr}; constexpr uint32_t flag = FIELD_METHOD_FLAG; - return { name, &TypeInfo::StaticClass, {member},flag }; + return { name, &TypeInfo::StaticClass, {member},flag }; } template FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name) { - FieldPtr::Data member = { *(void**)&ptr }; + FieldPtr::Data member = { *(Method*)&ptr }; constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; - return { name, &TypeInfo::StaticClass, {member},flag }; + return { name, &TypeInfo::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; @@ -93,17 +116,36 @@ namespace refl { return cls; } }; + template<_ReflCheck_Ctor_NoUClass T> - struct TypeInfo { + struct TypeInfoImpl{ using UClass = UClass_Auto; inline static UClass StaticClass = UClass::BuildClass(); }; + template class UMethod_Auto : public UClass { using UClass::UClass; using MethodType = R(*)(Args...); public: std::array UList; + + 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; + } public: static UMethod_Auto BuildClass() { auto cls = UMethod_Auto(type_name().View(), sizeof(MethodType)); @@ -119,7 +161,7 @@ namespace refl { }; // 函数指针类型的偏特化 template - struct TypeInfo { + struct TypeInfoImpl { using UClass = UMethod_Auto; inline static UClass StaticClass = UClass::BuildClass(); }; @@ -159,26 +201,36 @@ _cache_set: bool isChild = cache->type->IsChildOf(true); return false; } template - bool ObjectView::Invoke(const Name& name, Args... args) + bool ObjectView::Invoke(const Name& name, Args&&... args) { auto field = cls->GetField(name); if (!field) { return false; } - if (field->flag & FIELD_MEMBER_FLAG) { - using MemberMethodType = void(*)(const void*, Args...); - MemberMethodType fptr = (MemberMethodType)std::get(field->data); - fptr(ptr, args...); + 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; } - else { - using MethodType = void(*)(Args...); - MethodType fptr = (MethodType)std::get(field->data); - fptr(args...); + std::vector ArgsList; + ArgsList.reserve(paramsSize); + ArgsList.emplace_back(); + if (member) { + ArgsList.emplace_back(ptr, cls ); } - return true; + (..., (ArgsList.emplace_back((void*)&args, &TypeInfo::StaticClass))); + for (int i = member + 1; i < paramsSize; i++) { + if (ArgsList[i].cls != params[i]) { + ArgsList[i].ConvertTo(params[i]); + } + } + field->type->Call(*field, ArgsList); + return false; } template - inline bool ObjectView::InvokeRet(const Name& name, R& ret, Args ...args) + inline bool ObjectView::InvokeRet(const Name& name, R& ret, Args&& ...args) { auto field = cls->GetField(name); if (!field) { @@ -186,14 +238,23 @@ _cache_set: bool isChild = cache->type->IsChildOf(true); } if (field->flag & FIELD_MEMBER_FLAG) { using MemberMethodType = R(*)(const void*, Args...); - MemberMethodType fptr = (MemberMethodType)std::get(field->data); - ret = fptr(ptr, 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(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; + return true; + } + return false; + } } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/view.h b/engine/3rdparty/zlib/include/refl/view.h new file mode 100644 index 0000000..eb7487f --- /dev/null +++ b/engine/3rdparty/zlib/include/refl/view.h @@ -0,0 +1,32 @@ +#include +namespace refl { + class UClass; + class FieldPtr; + class ObjectView { + public: + const char* ptr; + const UClass* cls; + const FieldPtr* cache{nullptr}; + ObjectView(const void* ptr, const UClass* cls) : ptr((const char*)ptr), cls(cls){} + public: + + template + bool Get(const Name& name, T& t); + + template + bool Set(const Name& name, const T& t); + + template + bool Invoke(const Name& name, Args&&... args); + + template + bool InvokeRet(const Name& name,R& ret, Args&&... args); + }; + 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); + }; +} \ 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 76fb8cd..99c90fa 100644 --- a/engine/3rdparty/zlib/test/refl_01.cpp +++ b/engine/3rdparty/zlib/test/refl_01.cpp @@ -15,18 +15,18 @@ struct vec3 : public vec3_parent { float y = 2; float z = 3; string name{ "hellohellohellohellohellohello" }; - void norm(int x1) { - x1 = x * y * z; - cout << x1 << "::norm" << endl; + void norm(int x1, int& x2) { + x2 = x1 * x * y * z * x2; + cout << x2 << "::norm" << endl; } - virtual float norm1(int x1) { + virtual float norm1(int x1 = 10) { cout << x1 << "::norm1" << endl; return x * y *z * x1; } - static void norm2(int x1) { + static void norm2(int x1 = 10) { cout << x1 << "::norm2" << endl; } - void norm3(int x1) { + void norm3(int x1 = 10) { x1 = x * y * z; cout << x1 << "::norm3" << endl; } @@ -50,41 +50,44 @@ public: static vec3_UClass BuildClass() { vec3_UClass cls(type_name().View(), sizeof(vec3), &TypeInfo::StaticClass); //offsetof(vec3, x) 很坑,相当坑 - cls.FList[0] = cls.MakeMemberField(&vec3::x, "x"); - cls.FList[1] = cls.MakeMemberField(&vec3::y, "y"); - cls.FList[2] = cls.MakeMemberField(&vec3::z, "z"); - cls.FList[3] = cls.MakeMethodField(&vec3::norm, "norm"); - cls.FList[4] = cls.MakeMethodField(&vec3::norm1, "norm1"); - cls.FList[5] = cls.MakeMethodField(&vec3::norm2, "norm2"); + cls.FList[0] = cls.MakeMemberField("x"); + cls.FList[1] = cls.MakeMemberField("y"); + cls.FList[2] = cls.MakeMemberField("z"); + cls.FList[3] = cls.MakeMethodField(&vec3::norm, "norm"); + //cls.FList[4] = cls.MakeMethodField(&vec3::norm1, "norm1"); + //cls.FList[5] = cls.MakeMethodField(&vec3::norm2, "norm2"); return cls; } }; +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)); + //fptr((++param)->val, (int)(++param)->val, (int&)(++param)->val); + //fptr(std::forward(Args(param++->val))...); + int x = 1; + x = x + 1; +} int main() { - auto& cls = TypeInfo::StaticClass; + auto cls = &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); auto ptr1 = &vec3::norm; - auto ptr2 = &vec3::norm1; - auto ptr3 = &vec3::norm2; - auto ptr4 = &vec3::norm3; - vec3 v; - using Any = void*; - ObjectView pv(&v, &cls); - //using ClassMethod = void(Any::*)(int); - using MethodType = void(void*, int); - MethodType* ptr_wrap = (MethodType*)*(void**)&ptr1; - pv.Invoke("norm", 10); - ptr_wrap(&v, 10); - ptr_wrap = (MethodType*)*(void**)&ptr2; - float x; - pv.InvokeRet("norm1",x ,10); - ptr_wrap(&v, 10); - ptr_wrap = (MethodType*)*(void**)&ptr3; - pv.Invoke("norm2", 10); - ptr_wrap(&v, 10); - ptr_wrap = (MethodType*)*(void**)&ptr4; - ptr_wrap(&v, 10); - PrintHex8(ptr1); - PrintHex8(ptr2); - PrintHex8(ptr3); - PrintHex8(ptr4); - cout << "hello world\n"; + using MethodType = void (*)(void*, int, int*); + MethodType ptr2 = *(MethodType*)&ptr1; + ptr2(&v, x , &y); + printt(*(void**)&ptr1, ArgsList); + //ptr2(x, y); + //cout << "hello world\n"; } \ No newline at end of file