diff --git a/engine/3rdparty/zlib/include/refl/detail/field.h b/engine/3rdparty/zlib/include/refl/detail/field.h index 521b1e6..1a89a2c 100644 --- a/engine/3rdparty/zlib/include/refl/detail/field.h +++ b/engine/3rdparty/zlib/include/refl/detail/field.h @@ -6,22 +6,42 @@ using Ubpa::Name; using Ubpa::type_name; namespace refl { class UClass; + class ArgsView; + using Offset = uint32_t; using Method = void(*)(...); + + using DefaultMember = const ArgsView (*)(); + using DefaultMethod = std::pair(*)(); + 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, + FIELD_METHOD_VALUE_FLAG = 1 << 3 }; struct FieldPtr { - using Data = std::variant< - Offset, // offset - Method // method - >; + union Data + { + Offset offset; + Method method; + Data() : method(nullptr) {} + Data(Offset& offset) : offset(offset) {} + Data(Method& method) : method(method) {} + }; + union Default { + DefaultMember member; + DefaultMethod method; + Default(): method(nullptr) {} + Default(DefaultMember& member) : member(member) {} + Default(DefaultMethod& method) : method(method) {} + }; Name name; const UClass* type; Data data; + Default value; uint32_t 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 95fed11..a8b140c 100644 --- a/engine/3rdparty/zlib/include/refl/detail/type.h +++ b/engine/3rdparty/zlib/include/refl/detail/type.h @@ -4,20 +4,13 @@ namespace refl { template concept _ReflCheck_Ctor = requires { T(); }; template - concept _ReflCheck_UClass = requires{{T::BuildClass()} -> std::same_as; }; + concept _ReflCheck_UClass = requires(typename T::MyUClass& cls) { T::BuildClass(cls); } ; template concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor && !_ReflCheck_UClass; - //类型接口 template struct TypeInfoImpl; - template<_ReflCheck_UClass T> - struct TypeInfoImpl { - using MyUClass = typename T::MyUClass; - inline static MyUClass StaticClass = T::BuildClass(); - }; - template struct RealTypeImpl { using type = std::remove_cv_t>; diff --git a/engine/3rdparty/zlib/include/refl/detail/uclass.h b/engine/3rdparty/zlib/include/refl/detail/uclass.h index d8d37a3..dbaa097 100644 --- a/engine/3rdparty/zlib/include/refl/detail/uclass.h +++ b/engine/3rdparty/zlib/include/refl/detail/uclass.h @@ -5,8 +5,6 @@ namespace refl { struct vtable_uclass { - //object - void (*InitObject)(void*); //class const FieldPtr* (*GetField)(const UClass*, const Name&, bool); //function @@ -14,6 +12,10 @@ namespace refl { //function void (*Call)(const FieldPtr&, std::vector&); + //object + void (*InitObject)(void*); + void (*CopyObject)(void*, const void*); + void (*DestObject)(void*); }; class UClass{ using enum FieldFlag; @@ -70,20 +72,6 @@ namespace refl { return false; } public: - template<_ReflCheck_Ctor T> - static void InitObject(void* ptr) { - T obj{}; - std::construct_at((T*)ptr, obj); - } - //unsafe if called by other, need check class && size - void InitObject(void* ptr)const { - if (vtable.InitObject) { - vtable.InitObject(ptr); - } - else { - memset(ptr, 0, size); - } - } const FieldPtr* GetField(const Name& name, bool isMethod)const { if (vtable.GetField) { return vtable.GetField(this, name, isMethod); @@ -101,24 +89,36 @@ namespace refl { return vtable.Call(field, ArgsList); } } + void InitObject(void* ptr)const { + if (vtable.InitObject) { + vtable.InitObject(ptr); + } + else { + memset(ptr, 0, size); + } + } + void CopyObject(void* dst, const void* src)const { + if (vtable.CopyObject) { + vtable.CopyObject(dst, src); + } + else { + memcpy(dst, src, size); + } + } + void DestObject(void* ptr)const { + if (vtable.DestObject) { + vtable.DestObject(ptr); + } + } public: - template - constexpr static FieldPtr MakeMemberField(Name name, const UClass* cls) { - FieldPtr::Data member = { offset }; - constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; - return { name, cls, {member}, flag }; + template<_ReflCheck_Ctor T> + static void InitObject(void* ptr) { + T obj{}; + std::construct_at((T*)ptr, obj); } - template - static FieldPtr MakeMethodField(R (* ptr)(Args...), Name name) { - FieldPtr::Data member = { *(Method*)&ptr}; - constexpr uint32_t flag = FIELD_METHOD_FLAG; - return { name, &TypeInfo::type...)>::StaticClass, {member},flag }; - } - template - static 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::type...)>::StaticClass, {member},flag }; + template + static void CopyObject(void* dst, const void* src) { + *(T*)dst = *(T*)src; } }; } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/detail/uclass.inl b/engine/3rdparty/zlib/include/refl/detail/uclass.inl index 90df5da..d21a017 100644 --- a/engine/3rdparty/zlib/include/refl/detail/uclass.inl +++ b/engine/3rdparty/zlib/include/refl/detail/uclass.inl @@ -5,12 +5,13 @@ namespace refl { class UClass_Auto : public UClass { public: using UClass::UClass; - using UClassType = UClass_Auto; + using MyUClass = UClass_Auto; public: - constexpr static UClassType BuildClass() { - UClassType cls(type_name().View(), sizeof(T)); + constexpr static MyUClass BuildClass() { + MyUClass cls(type_name().View(), sizeof(T)); if constexpr (!std::is_trivially_copyable_v) { - cls.vtable.InitObject = &UClass::InitObject; + cls.vtable.InitObject = &MyUClass::InitObject; + cls.vtable.CopyObject = &MyUClass::CopyObject; } return cls; } @@ -25,22 +26,22 @@ namespace refl { class UMethod_Auto : public UClass { using UClass::UClass; using MethodType = R(*)(Args...); - using UClassType = UMethod_Auto; + using MyUClass = UMethod_Auto; public: std::array UList{}; static std::vector GetParams(const UClass* cls) { - auto& UList = static_cast(cls)->UList; + auto& UList = static_cast(cls)->UList; return { UList.data(), UList.data() + UList.size() }; } static void Call(const FieldPtr& field, std::vector& ArgsList) { if constexpr (std::is_same_v) { - MethodType fptr = (MethodType)std::get(field.data); + MethodType fptr = (MethodType)field.data.method; auto param = ArgsList.rbegin(); fptr(param++->cast_to()...); } else { - MethodType fptr = (MethodType)std::get(field.data); + MethodType fptr = (MethodType)field.data.method; auto param = ArgsList.rbegin(); auto ret = ArgsList.begin(); if (ret->cls == &TypeInfo::StaticClass) { @@ -63,10 +64,10 @@ namespace refl { } public: //为了简化判断,cls 对象 统统指向 T* - constexpr static UClassType BuildClass() { - UClassType cls(type_name().View(), sizeof(MethodType)); - cls.vtable.GetParams = &UClassType::GetParams; - cls.vtable.Call = &UClassType::Call; + constexpr static MyUClass BuildClass() { + MyUClass cls(type_name().View(), sizeof(MethodType)); + cls.vtable.GetParams = &MyUClass::GetParams; + cls.vtable.Call = &MyUClass::Call; cls.BuildUList(); return cls; } @@ -93,9 +94,12 @@ namespace refl { } return nullptr; } + /* void BuildClass() { + FList.shrink_to_fit();//缩减容量,FList大小不再改变了 vtable.GetField = &UClass_Custom::GetField; } + */ }; //基础类型的偏特化 template<_ReflCheck_Ctor_NoUClass T> @@ -110,4 +114,28 @@ namespace refl { using UClass = UMethod_Auto; inline constexpr static UClass StaticClass = UClass::BuildClass(); }; + + template<_ReflCheck_UClass T> + struct TypeInfoImpl { + using MyUClass = typename T::MyUClass; + inline static MyUClass StaticClass = []()->MyUClass { + MyUClass cls(type_name().View(), sizeof(T)); + T::BuildClass(cls); + auto& vtable = cls.vtable; + if (!vtable.GetField) { + vtable.GetField = &MyUClass::GetField; + } + if constexpr (!std::is_trivially_copyable_v) { + if (!vtable.InitObject) { + //这里一定会创建一个InitObject 模板函数,如何优化 + vtable.InitObject = &UClass::InitObject; + } + if (!vtable.CopyObject) { + //这里一定会创建一个CopyObject 模板函数,如何优化 + vtable.CopyObject = &UClass::CopyObject; + } + } + return cls; + }(); + }; } \ 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 2bd19fd..54e86e9 100644 --- a/engine/3rdparty/zlib/include/refl/detail/view.h +++ b/engine/3rdparty/zlib/include/refl/detail/view.h @@ -26,14 +26,22 @@ namespace refl { ObjectView Parent(); }; - class ArgsView { + //生命周期短,适用于传参,不建议保存数据 + //这里类型丢失了呀,存入的都是指针数据 + struct ArgsView { public: const void* val; const UClass* cls; ArgsView(const void* val = nullptr, const UClass* cls = nullptr) : val(val), cls(cls) {} + //右值=>右值压入栈,caller入栈地址 + //左值=>caller变量地址 template - ArgsView(T&& v): val(&v), cls(&TypeInfo*>::StaticClass){} - + ArgsView(T&& v): val(&v), cls(&TypeInfo*>::StaticClass){ + if constexpr (std::is_same_v, ArgsView>) { + val = v.val; + cls = v.cls; + } + } template constexpr inline T cast_to() { if constexpr (std::is_pointer_v) { @@ -48,4 +56,17 @@ namespace refl { } bool ConvertTo(const UClass* toClass); }; + //存入的是真实的数据类型,type用于拷贝数据 + struct ArgsValue : public ArgsView { + const UClass* type; + template + ArgsValue(T&& t) : ArgsView(t), type(&TypeInfo::StaticClass){} + }; + struct ArgsValueList{ + void* data{ nullptr }; + ArgsView* ptr{nullptr}; + int num{ 0 }; + ArgsValueList(const std::vector& args); + ~ArgsValueList(); + }; } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/detail/view.inl b/engine/3rdparty/zlib/include/refl/detail/view.inl index 6197250..3c05687 100644 --- a/engine/3rdparty/zlib/include/refl/detail/view.inl +++ b/engine/3rdparty/zlib/include/refl/detail/view.inl @@ -7,7 +7,7 @@ namespace refl { if (cache && cache->name == name) { _cache_get: bool isChild = cache->type->IsChildOf(true); if (isChild) { - t = *(T*)(ptr + std::get(cache->data)); + t = *(T*)(ptr + cache->data.offset); } return isChild; } @@ -25,10 +25,9 @@ namespace refl { inline bool ObjectView::Set(const Name& name, const T& t) { if (cache && cache->name == name) { - _cache_set: bool isChild = cache->type->IsChildOf(true); if (isChild) { - *(T*)(ptr + std::get(cache->data)) = t; + *(T*)(ptr + cache->data.offset) = t; } return isChild; } @@ -55,17 +54,33 @@ namespace refl { 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(); + + bool member = field->flag & FIELD_MEMBER_FLAG; if (member) { ArgsList.emplace_back(ptr, &TypeInfo::StaticClass); } (..., (ArgsList.emplace_back(args))); + + + int argsSize = ArgsList.size(); + if (argsSize < paramsSize && field->flag & FIELD_METHOD_VALUE_FLAG) { + auto [argsPtr, valueSize] = field->value.method(); + if (argsSize + valueSize >= paramsSize) { + for (int i = valueSize + argsSize - paramsSize; i < valueSize; i++) { + ArgsList.push_back(*(argsPtr + i)); + } + argsSize = paramsSize; + } + } + + if (argsSize < paramsSize) { + return false; + } + for (int i = member + 1; i < paramsSize; i++) { if (ArgsList[i].cls != params[i] && !ArgsList[i].ConvertTo(params[i])) { return false; @@ -123,4 +138,35 @@ 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; + } + 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++; + pData += arg.cls->size; + } + ptr = (ArgsView*)data; + } + inline ArgsValueList::~ArgsValueList() + { + if (num == 0 || !data) { + return; + } + for (int i = 0; i < num; i++) { + ptr->cls->DestObject((void*)ptr->val); + } + free(data); + num = 0; + data = nullptr; + } } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/refl.h b/engine/3rdparty/zlib/include/refl/refl.h index 57a0983..ee8d526 100644 --- a/engine/3rdparty/zlib/include/refl/refl.h +++ b/engine/3rdparty/zlib/include/refl/refl.h @@ -1,2 +1,41 @@ #include "detail/uclass.inl" #include "detail/view.inl" +namespace refl { + /* 成员变量需要定义默认值吗?那为什么不在initObjec里初始化?*/ + template + static FieldPtr MakeMemberField(T Obj::* 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 MakeMethodField(R(*ptr)(Args...), Name name, const std::vector& 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 = { *(Method*)&ptr }; + return { name, &TypeInfo::type...)>::StaticClass, method, value, flag }; + } + template + static FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name, const std::vector& 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 }; + }; + } + FieldPtr::Data method = { *(Method*)&ptr }; + return { name, &TypeInfo::type...)>::StaticClass, method, value,flag }; + } +} \ 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 0a3f721..6465696 100644 --- a/engine/3rdparty/zlib/test/refl_01.cpp +++ b/engine/3rdparty/zlib/test/refl_01.cpp @@ -33,27 +33,29 @@ struct vec3 : public vec3_parent { cout << x1 << "::norm3" << endl; } using MyUClass = UClass_Custom; - static MyUClass BuildClass() { - MyUClass cls(type_name().View(), sizeof(vec3), &TypeInfo::StaticClass); - auto& FList = cls.FList; - FList.reserve(6); - FList.push_back(cls.MakeMemberField("x", &TypeInfo::StaticClass)); - FList.push_back(cls.MakeMemberField("y", &TypeInfo::StaticClass)); - FList.push_back(cls.MakeMemberField("z", &TypeInfo::StaticClass)); - cls.AttrNum = FList.size(); - FList.push_back(cls.MakeMethodField(&vec3::norm, "norm")); - FList.push_back(cls.MakeMethodField(&vec3::norm, "norm1")); - cls.vtable.InitObject = &UClass::InitObject; - cls.BuildClass(); - return cls; + static void BuildClass(MyUClass& cls) { + cls.parent = &TypeInfo::StaticClass; + cls.AttrNum = 3; + cls.FList = { + MakeMemberField(&vec3::x, "x"), + MakeMemberField(&vec3::y, "y"), + MakeMemberField(&vec3::z, "z"), + MakeMethodField(&vec3::norm, "norm", {8, 9}), + MakeMethodField(&vec3::norm1, "norm1",{2}) + }; } }; int main() { auto cls = &TypeInfo::StaticClass; - int x = 100, y = 2; + int x = 2, y = 3; auto ov = cls->New(); + ov.Invoke("norm", x); + ov.Invoke("norm", x); ov.Invoke("norm", x, y); + ov.Invoke("norm1", y); vec3* v = (vec3*)ov.ptr; + v->norm1(y); + ov.Invoke("norm1", y); delete v; cout << "hello world\n"; } \ No newline at end of file