diff --git a/engine/3rdparty/zlib/include/refl/field.h b/engine/3rdparty/zlib/include/refl/field.h index 0b39a4a..b58db86 100644 --- a/engine/3rdparty/zlib/include/refl/field.h +++ b/engine/3rdparty/zlib/include/refl/field.h @@ -5,23 +5,21 @@ using Ubpa::Name; using Ubpa::type_name; namespace refl { - struct MemberField { - uint32_t offset; - }; - struct MemberFuncField { - using Offsetor = std::function; - Offsetor func; - }; class UClass; + enum FieldFlag:uint32_t { + FIELD_NONE_FLAG = 0, + FIELD_MEMBER_FLAG = 1 << 0, + FIELD_ATTRIBUTE_FLAG = 1 << 1, + FIELD_METHOD_FLAG = 1 << 2, + }; struct FieldPtr { - using Offsetor = std::function; - // raw offsetor using Data = std::variant< - uint32_t, // forward_offset_value 0 BASIC - double // static_obj 2 STATIC + uint32_t, // offset + void* // method >; Name name; const UClass* type; Data data; + uint32_t flag; }; } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/object.h b/engine/3rdparty/zlib/include/refl/object.h index d677ded..7fe2dfb 100644 --- a/engine/3rdparty/zlib/include/refl/object.h +++ b/engine/3rdparty/zlib/include/refl/object.h @@ -18,5 +18,8 @@ namespace refl { 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 d980fc6..5b345c3 100644 --- a/engine/3rdparty/zlib/include/refl/type.h +++ b/engine/3rdparty/zlib/include/refl/type.h @@ -2,17 +2,18 @@ #include namespace refl { template - concept _CheckDefaultConstruct = requires { T(); }; + concept _ReflCheck_Ctor = requires { T(); }; template - concept _CheckBuildUClass = requires{{T::UClass::BuildClass()} -> std::same_as; }; + concept _ReflCheck_UClass = requires{{T::UClass::BuildClass()} -> std::same_as; }; + template + concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor && !_ReflCheck_UClass; - template - concept _ReflCheck = _CheckDefaultConstruct || _CheckBuildUClass; - template<_ReflCheck T, typename = void> + //主模板只有声明,没有定义,从而使得非特化非法 + template struct TypeInfo; - template<_ReflCheck T> - struct TypeInfo> { + template<_ReflCheck_UClass T> + struct TypeInfo { using UClass = typename T::UClass; inline static UClass StaticClass = UClass::BuildClass(); }; diff --git a/engine/3rdparty/zlib/include/refl/uclass.h b/engine/3rdparty/zlib/include/refl/uclass.h index d96d784..732be83 100644 --- a/engine/3rdparty/zlib/include/refl/uclass.h +++ b/engine/3rdparty/zlib/include/refl/uclass.h @@ -4,6 +4,7 @@ #include "object.h" namespace refl { class UClass{ + using enum FieldFlag; public: Name name; uint32_t size; @@ -52,19 +53,26 @@ namespace refl { return nullptr; } protected: - template + template FieldPtr MakeMemberField(T U::* ptr, Name name) { FieldPtr::Data member = { offset }; - return { name, &TypeInfo::StaticClass, {member} }; + constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; + return { name, &TypeInfo::StaticClass, {member}, flag }; } - template - FieldPtr MakeMethodField(T U::* ptr, Name name) { - FieldPtr::Data member = { offset }; - return { name, &TypeInfo::StaticClass, {member} }; + template + FieldPtr MakeMethodField(R (* ptr)(Args...), Name name) { + FieldPtr::Data member = { *(void**)&ptr }; + constexpr uint32_t flag = FIELD_METHOD_FLAG; + return { name, &TypeInfo::StaticClass, {member},flag }; + } + template + FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name) { + FieldPtr::Data member = { *(void**)&ptr }; + constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; + return { name, &TypeInfo::StaticClass, {member},flag }; } }; - template - requires std::is_default_constructible_v + template<_ReflCheck_Ctor T> class UClass_Auto : public UClass{ public: using UClass::UClass; @@ -72,7 +80,7 @@ namespace refl { void InitObject(void* ptr)const override { constexpr bool is_shallow_copyable = std::is_trivially_copyable::value; if constexpr (!is_shallow_copyable){ - constexpr T obj{}; + T obj{}; std::construct_at((T*)ptr, obj); } else { @@ -85,11 +93,36 @@ namespace refl { return cls; } }; - template<_ReflCheck T, typename> - struct TypeInfo { + template<_ReflCheck_Ctor_NoUClass T> + struct TypeInfo { 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; + public: + static UMethod_Auto BuildClass() { + auto cls = UMethod_Auto(type_name().View(), sizeof(MethodType)); + if constexpr(!std::is_same::value) { + cls.UList[0] = &TypeInfo::StaticClass; + } + if (sizeof...(Args) > 0) { + auto ptr = &cls.UList[1]; + (...,(*ptr = &TypeInfo::StaticClass, ptr++)); + } + return cls; + } + }; + // 函数指针类型的偏特化 + template + struct TypeInfo { + using UClass = UMethod_Auto; + inline static UClass StaticClass = UClass::BuildClass(); + }; template inline bool ObjectView::Get(const Name& name, T& t) { @@ -128,6 +161,39 @@ _cache_set: bool isChild = cache->type->IsChildOf(true); template bool ObjectView::Invoke(const Name& name, Args... args) { - return false; + 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...); + } + else { + using MethodType = void(*)(Args...); + MethodType fptr = (MethodType)std::get(field->data); + fptr(args...); + } + return true; + } + 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, args...); + } + else { + using MethodType = R(*)(Args...); + MethodType fptr = (MethodType)std::get(field->data); + ret = fptr(args...); + } + return true; } } \ No newline at end of file diff --git a/engine/3rdparty/zlib/test/refl/tstring.h b/engine/3rdparty/zlib/test/refl/tstring.h index 9b17b16..9562a19 100644 --- a/engine/3rdparty/zlib/test/refl/tstring.h +++ b/engine/3rdparty/zlib/test/refl/tstring.h @@ -5,13 +5,32 @@ using std::string; template void PrintHex(T& obj) { auto size = sizeof(T); - std::cout << type_name().View() << "<" << size <<"> " << " = 0x"; - char* ptr = (char*)& obj; + std::cout << std::hex << type_name().View() << "<" << size <<"> " << " = 0x"; + char* ptr = (char*)&obj; for (int i = 0; i < size; i++) { - std::cout << std::hex << std::setw(2) << std::setfill('0') <<(int)*(ptr + i); + std::cout << std::hex << std::setw(2) << std::setfill('0') <<(int)(uint8_t)*(ptr + i); } std::cout << "FF" << std::endl; } +template +void PrintHex8(T& obj) { + auto size = sizeof(T); + std::cout << std::hex << type_name().View() << "<" << size << "> " << "\n\t"; + { + int* ptr = (int*)&obj; + for (int i = 0; i < size / 4; i += 1) { + std::cout << std::dec << std::setw(8) << std::setfill('0') << *(ptr + i) << "-"; + } + std::cout << "=-0x"; + } + { + uintptr_t* ptr = (uintptr_t*)&obj; + for (int i = 0; i < size / 8; i += 1) { + std::cout << std::hex << std::setw(16) << std::setfill('0') << *(ptr + i) << "-"; + } + std::cout << ";-" << std::endl; + } +} void TestString1() { string hello = "abcdef"; int size = sizeof(string); diff --git a/engine/3rdparty/zlib/test/refl_01.cpp b/engine/3rdparty/zlib/test/refl_01.cpp index f91e1df..76fb8cd 100644 --- a/engine/3rdparty/zlib/test/refl_01.cpp +++ b/engine/3rdparty/zlib/test/refl_01.cpp @@ -3,6 +3,7 @@ #include "refl/uclass.h" #include "vertex.h" #include "tstring.h" +#include using namespace std; using namespace refl; struct vec3_parent { @@ -14,12 +15,25 @@ struct vec3 : public vec3_parent { float y = 2; float z = 3; string name{ "hellohellohellohellohellohello" }; - float norm() { - return x * y * z; + void norm(int x1) { + x1 = x * y * z; + cout << x1 << "::norm" << endl; + } + virtual float norm1(int x1) { + cout << x1 << "::norm1" << endl; + return x * y *z * x1; + } + static void norm2(int x1) { + cout << x1 << "::norm2" << endl; + } + void norm3(int x1) { + x1 = x * y * z; + cout << x1 << "::norm3" << endl; } }; struct vec3_UClass : public UClass { - array FList; +public: + array FList; using UClass::UClass; const FieldPtr* GetField(const Name& name)const override { for (auto& field : FList) { @@ -39,32 +53,38 @@ struct vec3_UClass : public UClass { 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.MakeMemberField(&vec3::name, "name"); + 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; } }; int main() { - using uclass = TypeInfo::UClass; - auto& res = TypeInfo::StaticClass; - auto& res2 = TypeInfo::StaticClass; - - auto& res3 = TypeInfo::StaticClass; - vec3 v1; - auto res4 = TypeInfo::StaticClass; - auto res5 = TypeInfo::StaticClass; - auto t1 = res3.FList[0]; - vec3_parent* v2 = res3.New(); - vec3* v22 = (vec3*)v2; - auto v3 = res3.New(); - int x1 = 110; - float x = *res.New(&x1); - v3.Get("x", x); - v3.Set("z", (float)33); - v2 = (vec3*)v3.ptr; - using T = int; - auto b1 = res3.IsChildOf(); - constexpr auto cls = UClass_Auto(type_name().View(), sizeof(T)); - cout << sizeof(Name) << "Type2: " << typeid(vec3).name() << endl; - delete v2; + auto& cls = TypeInfo::StaticClass; + 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"; } \ No newline at end of file