From 0828271799229b6b10dfc6cf37c13397f3031efb Mon Sep 17 00:00:00 2001 From: ouczbs Date: Thu, 25 Apr 2024 21:45:41 +0800 Subject: [PATCH] refl rebuild --- .../3rdparty/zlib/include/refl/detail/any.h | 26 ++--- .../zlib/include/refl/detail/convert.h | 15 +++ .../zlib/include/refl/detail/convert.inl | 32 +++++++ .../3rdparty/zlib/include/refl/detail/field.h | 10 +- .../zlib/include/refl/detail/field.inl | 2 +- .../3rdparty/zlib/include/refl/detail/meta.h | 8 +- .../zlib/include/refl/detail/meta.inl | 68 +++++++------- .../zlib/include/refl/detail/uclass.h | 31 +++--- .../zlib/include/refl/detail/uclass.inl | 46 +++++++-- .../3rdparty/zlib/include/refl/detail/view.h | 32 ++----- .../zlib/include/refl/detail/view.inl | 94 ++++++++++--------- engine/3rdparty/zlib/include/refl/refl.h | 25 ++--- .../3rdparty/zlib/include/refl/std/sarray.h | 9 +- .../3rdparty/zlib/include/refl/std/svector.h | 9 +- engine/3rdparty/zlib/test/refl/vertex.h | 44 ++------- engine/3rdparty/zlib/test/refl_01.cpp | 8 +- engine/xmake/gen/meta_refl.lua | 21 +++-- engine/xmake/gen/xmake.lua | 1 - 18 files changed, 267 insertions(+), 214 deletions(-) create mode 100644 engine/3rdparty/zlib/include/refl/detail/convert.h create mode 100644 engine/3rdparty/zlib/include/refl/detail/convert.inl diff --git a/engine/3rdparty/zlib/include/refl/detail/any.h b/engine/3rdparty/zlib/include/refl/detail/any.h index 71e4e4c..78cf891 100644 --- a/engine/3rdparty/zlib/include/refl/detail/any.h +++ b/engine/3rdparty/zlib/include/refl/detail/any.h @@ -8,7 +8,9 @@ namespace refl { public: const void* ptr; const UClass* cls; - constexpr Any(const void* ptr,const UClass* cls) : ptr(ptr), cls(cls) {} + constexpr Any(const void* ptr, const UClass* cls) : ptr(ptr), cls(cls) { + //assert(cls->flag & CLASS_POINTER_FLAG); + } constexpr Any() : ptr(nullptr), cls(nullptr) {} //右值=>右值压入栈,caller入栈地址 //左值=>caller变量地址 @@ -27,7 +29,7 @@ namespace refl { } } template//参数 T* => T* - constexpr inline T cast_to() const { + constexpr inline T CastTo() const { if constexpr (std::is_pointer_v) { return (T)ptr; } @@ -39,22 +41,14 @@ namespace refl { return *(T*)ptr; } } - template - T cast_ret() const { - if constexpr (std::is_pointer_v) { - return *(T*)ptr; - } - else if constexpr (std::is_reference_v) { - using RT = std::remove_reference_t; - return **(RT**)ptr; - } - else { - return *(T*)ptr; - } - } - Any* ConvertTo(const UClass* toClass); + bool Check(const UClass* toClass)const; constexpr bool IsValid() const{ return cls != nullptr && ptr != nullptr; } + constexpr int Size()const; + constexpr const UClass* Parent()const; + constexpr Any Change(const void* ptr)const { + return {ptr, cls}; + } }; } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/detail/convert.h b/engine/3rdparty/zlib/include/refl/detail/convert.h new file mode 100644 index 0000000..632f329 --- /dev/null +++ b/engine/3rdparty/zlib/include/refl/detail/convert.h @@ -0,0 +1,15 @@ +#pragma once +#include "any.h" +#include +namespace refl { + using ConvertFunc = bool (*)(Any&, const Any&); + using ConvertMap = std::map; + class Convert { + protected: + static ConvertMap BuildClassMap(); + public: + static bool ToString(Any& dst,const Any& src); + static bool Construct(Any& dst, const Any& src); + inline static ConvertMap ClassMap = BuildClassMap(); + }; +} \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/detail/convert.inl b/engine/3rdparty/zlib/include/refl/detail/convert.inl new file mode 100644 index 0000000..d2269df --- /dev/null +++ b/engine/3rdparty/zlib/include/refl/detail/convert.inl @@ -0,0 +1,32 @@ +#pragma once +#include +#include "convert.h" +namespace refl { + bool Convert::ToString(Any& dst, const Any& src) + { + if (src.Parent() == &TypeInfo::StaticClass) { + std::construct_at(dst.CastTo(), src.CastTo()); + return true; + } + return false; + } + inline bool Convert::Construct(Any& dst, const Any& src) + { + if (dst.Check(src.cls)) { + dst.cls->InitObject((void*)dst.ptr); + dst.cls->CopyObject((void*)dst.ptr, src.ptr); + return true; + } + auto it = ClassMap.find(dst.cls); + if (it == ClassMap.end()) { + return false; + } + return it->second(dst, src); + } + ConvertMap Convert::BuildClassMap() + { + ConvertMap classMap; + classMap.emplace(&TypeInfo::StaticClass, &ToString); + return classMap; + } +} \ 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 0503cf1..faa2652 100644 --- a/engine/3rdparty/zlib/include/refl/detail/field.h +++ b/engine/3rdparty/zlib/include/refl/detail/field.h @@ -13,17 +13,19 @@ namespace refl { using Offset = uint32_t; using Method = void*; struct MemberData { - Offset offset; + Offset offset{0}; Any value; Any meta; - constexpr MemberData() :offset(0), value(), meta() {} + constexpr MemberData() :value(), meta() {} + constexpr MemberData(const Any& value, const Any& meta = {}) : value(value), meta(meta) {} constexpr MemberData(Offset offset,const Any& value,const Any& meta) : offset(offset), value(value), meta(meta) {} }; struct MethodData { - Method fptr; + Method fptr{nullptr}; sarray value; Any meta; - constexpr MethodData() :fptr(nullptr), value(), meta() {} + constexpr MethodData() :value(), meta() {} + constexpr MethodData(const sarray& value, const Any& meta = {}) : value(value), meta(meta) {} constexpr MethodData(Method fptr,const sarray& value, const Any& meta) : fptr(fptr), value(value), meta(meta) {} }; enum FieldFlag:uint32_t { diff --git a/engine/3rdparty/zlib/include/refl/detail/field.inl b/engine/3rdparty/zlib/include/refl/detail/field.inl index d634bf1..5941854 100644 --- a/engine/3rdparty/zlib/include/refl/detail/field.inl +++ b/engine/3rdparty/zlib/include/refl/detail/field.inl @@ -36,7 +36,7 @@ namespace refl { Any* a = ArgsList.front(); auto p = params.front(); for (auto e = params.back(); p < e; ++p, ++a) { - if (a->cls != *p && !a->ConvertTo(*p)) { + if (a->cls != *p && !a->Check(*p)) { return false; } } diff --git a/engine/3rdparty/zlib/include/refl/detail/meta.h b/engine/3rdparty/zlib/include/refl/detail/meta.h index 234407c..3e19ee7 100644 --- a/engine/3rdparty/zlib/include/refl/detail/meta.h +++ b/engine/3rdparty/zlib/include/refl/detail/meta.h @@ -26,20 +26,18 @@ namespace refl { META_UI_FLAG = 1 << 0, }; class UClass; - class MemberDataValue; - class MethodDataValue; class Meta { public: UClass* cls; uint32_t flag{ 0 }; template - static FieldPtr MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberDataValue& data = {}); + static FieldPtr MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data = {}); template - static FieldPtr MethodField(R(*ptr)(Args...), const Name& name,char*& memory, const MethodDataValue& data = {}); + static FieldPtr MethodField(R(*ptr)(Args...), const Name& name,char*& memory, const MethodData& data = {}); template - static FieldPtr MethodField(R(T::*ptr)(Args...), const Name& name,char*& memory, const MethodDataValue& data = {}); + static FieldPtr MethodField(R(T::*ptr)(Args...), const Name& name,char*& memory, const MethodData& data = {}); }; } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/detail/meta.inl b/engine/3rdparty/zlib/include/refl/detail/meta.inl index d951d3c..b846844 100644 --- a/engine/3rdparty/zlib/include/refl/detail/meta.inl +++ b/engine/3rdparty/zlib/include/refl/detail/meta.inl @@ -1,68 +1,64 @@ #pragma once #include "meta.h" #include "uclass.h" +#include "convert.h" namespace refl { template - inline FieldPtr Meta::MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberDataValue& data) + inline FieldPtr Meta::MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data) { MemberData member; + auto cls = &TypeInfo::StaticClass; member.offset = reinterpret_cast(&(reinterpret_cast(0)->*ptr)); - if (AnyValue arg = data.value; arg.IsValid()) { - arg.type->InitObject(memory); - arg.type->CopyObject(memory, arg.ptr); - member.value = Any(memory, arg.cls).ConvertTo(&TypeInfo*>::StaticClass); - memory += arg.type->size; + if (data.value.IsValid()) { + member.value = Any(memory, cls); + assert(Convert::Construct(member.value, data.value)); + memory += member.value.Size(); } - if (AnyValue arg = data.meta; arg.IsValid()) { - arg.type->InitObject(memory); - arg.type->CopyObject(memory, arg.ptr); - member.meta = Any(memory, arg.cls); - memory += arg.type->size; + if (data.meta.IsValid()) { + member.meta = data.meta.Change(memory); + Convert::Construct(member.meta, data.meta); + memory += data.meta.Size(); } constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; - return { name, &TypeInfo::StaticClass, member,flag}; + return { name, cls, member,flag}; } template - inline FieldPtr Meta::MethodField(R(*ptr)(Args...), const Name& name, char*& memory, const MethodDataValue& data) + inline FieldPtr Meta::MethodField(R(*ptr)(Args...), const Name& name, char*& memory, const MethodData& data) { MethodData method; uint32_t flag = FIELD_METHOD_FLAG; - auto cls = &TypeInfo(*)(real_type_t...)>::StaticClass; - if (auto& args = data.value; !args.empty()) { + constexpr auto cls = &TypeInfo(*)(real_type_t...)>::StaticClass; + if (data.value.IsValid()) { flag |= FIELD_METHOD_VALUE_FLAG; - AnyValueList argsValue(args, memory); - argsValue.ConvertArgs(cls->vtable.GetParams(cls)); - method.value = argsValue.ToSArray(); - memory += AnyValueList::GetArgsSize(args); + AnyArgs args(data.value, cls->GetParams(), memory); + method.value = args.ToSArray(); + memory += args.Size(); } - if (AnyValue arg = data.meta; arg.IsValid()) { - arg.type->InitObject(memory); - arg.type->CopyObject(memory, arg.ptr); - method.meta = Any(memory, arg.cls); - memory += arg.type->size; + if (data.meta.IsValid()) { + method.meta = data.meta.Change(memory); + Convert::Construct(method.meta, data.meta); + memory += data.meta.Size(); } method.fptr = { *(Method*)&ptr }; return { name, cls, method,flag }; } template - inline FieldPtr Meta::MethodField(R(T::*ptr)(Args...),const Name& name, char*& memory, const MethodDataValue& data) + inline FieldPtr Meta::MethodField(R(T::*ptr)(Args...),const Name& name, char*& memory, const MethodData& data) { MethodData method; uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; - auto cls = &TypeInfo(*)(const void*, real_type_t...)>::StaticClass; - if (auto& args = data.value; !args.empty()) { + constexpr auto cls = &TypeInfo(*)(const void*, real_type_t...)>::StaticClass; + if (data.value.IsValid()) { flag |= FIELD_METHOD_VALUE_FLAG; - AnyValueList argsValue(args, memory); - argsValue.ConvertArgs(cls->vtable.GetParams(cls)); - method.value = argsValue.ToSArray(); - memory += AnyValueList::GetArgsSize(args); + AnyArgs args(data.value, cls->GetParams(), memory); + method.value = args.ToSArray(); + memory += args.Size(); } - if (AnyValue arg = data.meta; arg.IsValid()) { - arg.type->InitObject(memory); - arg.type->CopyObject(memory, arg.ptr); - method.meta = Any(memory, arg.cls); - memory += arg.type->size; + if (data.meta.IsValid()) { + method.meta = data.meta.Change(memory); + Convert::Construct(method.meta, data.meta); + memory += data.meta.Size(); } method.fptr = { *(Method*)&ptr }; return { name, cls, method,flag }; diff --git a/engine/3rdparty/zlib/include/refl/detail/uclass.h b/engine/3rdparty/zlib/include/refl/detail/uclass.h index 9200b16..1d4cd7b 100644 --- a/engine/3rdparty/zlib/include/refl/detail/uclass.h +++ b/engine/3rdparty/zlib/include/refl/detail/uclass.h @@ -6,6 +6,8 @@ namespace refl { enum ClassFlag :uint32_t { CLASS_NONE_FLAG = 0, CLASS_TRIVIAL_FLAG = 1 << 0, + CLASS_POINTER_FLAG = 1 << 1, + CLASS_ARRAY_FLAG = 1 << 2, }; using enum ClassFlag; struct vtable_uclass @@ -63,18 +65,7 @@ namespace refl { } template bool IsChildOf(bool bthis = false) const { - constexpr UClass* cls = &TypeInfo::StaticClass; - if (bthis) { - return cls == this; - } - const UClass* _parent = this; - while (_parent != nullptr) { - if (_parent == cls) { - return true; - } - _parent = _parent->parent; - } - return false; + return IsChildOf(&TypeInfo::StaticClass); } public: const FieldPtr* GetField(const Name& name, int index)const { @@ -114,5 +105,21 @@ namespace refl { static void CopyObject(void* dst, const void* src) { *(T*)dst = *(T*)src; } + template<_ReflCheck_Ctor T, int N> + static void InitObject(void* ptr) { + T* tptr = (T*)ptr; + T obj{}; + for (int i = 0; i < N; i++) { + std::construct_at(tptr++, obj); + } + } + template + static void CopyObject(void* dst, const void* src) { + T* tdst = (T*)dst; + const T* tsrc = (const T*)src; + for (int i = 0; i < N; i++) { + *tdst++ = *tsrc++; + } + } }; } \ 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 52c0c83..47e56c3 100644 --- a/engine/3rdparty/zlib/include/refl/detail/uclass.inl +++ b/engine/3rdparty/zlib/include/refl/detail/uclass.inl @@ -14,6 +14,13 @@ namespace refl { cls.vtable.InitObject = &MyUClass::InitObject; cls.vtable.CopyObject = &MyUClass::CopyObject; } + else if constexpr (std::is_pointer_v){ + using RawT = std::remove_pointer_t; + cls.flag = CLASS_POINTER_FLAG; + if constexpr (!std::is_same_v) { + cls.parent = &TypeInfo::StaticClass; + } + } else { cls.flag = CLASS_TRIVIAL_FLAG; } @@ -26,7 +33,27 @@ namespace refl { return *(T*)ptr; } }; - + template<_ReflCheck_Ctor T, int N> + class UClass_Array : public UClass { + public: + using UClass::UClass; + using MyUClass = UClass_Array; + public: + consteval static MyUClass BuildClass() { + MyUClass cls(type_name().View(), sizeof(T) * N, &TypeInfo::StaticClass); + if constexpr (!std::is_trivially_copyable_v) { + cls.vtable.InitObject = &MyUClass::InitObject; + cls.vtable.CopyObject = &MyUClass::CopyObject; + } + else if constexpr (std::is_pointer_v) { + cls.flag = CLASS_POINTER_FLAG | CLASS_ARRAY_FLAG; + } + else { + cls.flag = CLASS_TRIVIAL_FLAG | CLASS_ARRAY_FLAG; + } + return cls; + } + }; /* * 模板优化 * 成员参数转化为const void* @@ -40,7 +67,9 @@ namespace refl { using MyUClass = UMethod_Auto; public: std::array UList{}; - + consteval sarray GetParams()const { + return sarray(&UList.front(), UList.size()); + } static sarray GetParams(const UClass* cls) { auto& UList = static_cast(cls)->UList; return sarray(&UList.front(),UList.size()); @@ -53,17 +82,17 @@ namespace refl { if constexpr (std::is_same_v) { MethodType fptr = (MethodType)field->data.method.fptr; auto param = ArgsList.end(); - fptr((param--->cast_to())...); + fptr((param--->CastTo())...); } else { MethodType fptr = (MethodType)field->data.method.fptr; auto param = ArgsList.end(); auto ret = ArgsList.front(); if (ret->cls == &TypeInfo::StaticClass) { - *(R*)ret->ptr = fptr((param--->cast_to())...); + *(R*)ret->ptr = fptr((param--->CastTo())...); } else { - fptr((param--->cast_to())...); + fptr((param--->CastTo())...); } } } @@ -74,7 +103,7 @@ namespace refl { } if constexpr (sizeof...(Args) > 0) { auto ptr = &UList[1]; - (..., (*ptr = &TypeInfo>*>::StaticClass, ptr++)); + (..., (*ptr = &TypeInfo*>::StaticClass, ptr++)); } } public: @@ -143,4 +172,9 @@ namespace refl { using MyUClass = typename T::MyMeta::MyUClass; inline static MyUClass StaticClass = MyUClass(); }; + template + struct TypeInfoImpl { + using UClass = UClass_Array; + inline constexpr static UClass StaticClass = UClass::BuildClass(); + }; } \ 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 61f4c75..ca1b01b 100644 --- a/engine/3rdparty/zlib/include/refl/detail/view.h +++ b/engine/3rdparty/zlib/include/refl/detail/view.h @@ -2,36 +2,16 @@ #include #include "field.h" namespace refl { - //存入的是真实的数据类型,type用于拷贝数据 - struct AnyValue : public Any { - const UClass* type; - constexpr AnyValue() :Any(), type(nullptr) {} - template - constexpr AnyValue(T&& t) : Any(t), type(&TypeInfo>::StaticClass){} - }; - struct MemberDataValue { - Offset offset{0}; - AnyValue value; - AnyValue meta; - constexpr MemberDataValue() :value(), meta() {} - constexpr MemberDataValue(const AnyValue& value, const AnyValue& meta = {}) : value(value), meta(meta) {} - }; - struct MethodDataValue { - Method fptr{nullptr}; - sarray value; - AnyValue meta; - constexpr MethodDataValue() :value(), meta() {} - constexpr MethodDataValue(const sarray& value, const AnyValue& meta = {}) : value(value), meta(meta) {} - }; - struct AnyValueList{ + struct AnyArgs { void* data; int num; + int size; bool isMemoryOwner{false}; - AnyValueList(const sarray& args,void* memory = nullptr); - ~AnyValueList(); - void ConvertArgs(sarray params); + AnyArgs(const sarray& args,const sarray& params,void* memory = nullptr); + ~AnyArgs(); + int Size(); const sarray ToSArray(); - constexpr static int GetArgsSize(const sarray& args); + constexpr static Offset GetArgsSize(const sarray& args, const sarray& params); }; class AnyView : public Any{ public: diff --git a/engine/3rdparty/zlib/include/refl/detail/view.inl b/engine/3rdparty/zlib/include/refl/detail/view.inl index 0912b16..b2b68eb 100644 --- a/engine/3rdparty/zlib/include/refl/detail/view.inl +++ b/engine/3rdparty/zlib/include/refl/detail/view.inl @@ -1,90 +1,96 @@ #pragma once #include "uclass.h" #include "view.h" +#include "convert.h" namespace refl { - /*平凡对象的转化要支持吗 - * 比如同大小的安全转化 - * 对象从小到大 - * 对象从大到小 - */ using enum ClassFlag; - Any* Any::ConvertTo(const UClass* toClass) { + bool Any::Check(const UClass* toClass) const{ if (cls == toClass) { - return this; + return true; } + auto p1 = cls->parent; + auto p2 = toClass->parent; + assert(p1 && p2); //子类转父类 - if (cls->IsChildOf(toClass)) { - cls = toClass; - return this; + if (p1->IsChildOf(p2)) { + return true; } - if (cls->flag & CLASS_TRIVIAL_FLAG && toClass->flag & CLASS_TRIVIAL_FLAG) { - cls = toClass; - return this; + if (p1->flag & CLASS_TRIVIAL_FLAG && p2->flag & CLASS_TRIVIAL_FLAG && p1->size >= p2->size) { + return true; } - return nullptr; + return false; } - AnyValueList::AnyValueList(const sarray& args, void* memory) - : data(memory), num(args.size()) + inline constexpr int Any::Size()const { + return cls->parent->size; + } + inline constexpr const UClass* Any::Parent()const + { + return cls->parent; + } + AnyArgs::AnyArgs(const sarray& args, const sarray& params, void* memory) + : data(memory), num(args.size()), size(GetArgsSize(args, params)) + { + assert(size > 0); if (!memory) { isMemoryOwner = true; - data = malloc(GetArgsSize(args)); + data = malloc(size); } Any* any = (Any*)data; assert(any != nullptr); char* pData = ((char*)data) + num * sizeof(Any); + auto uptr = params.at(params.size() - args.size()); for (auto& arg : args) { - arg.type->InitObject(pData); - arg.type->CopyObject(pData, arg.ptr); + any->cls = *uptr; any->ptr = pData; - any->cls = arg.cls; + assert(Convert::Construct(*any, arg)); any++; - pData += arg.type->size; + pData += (*uptr)->parent->size; } } - inline AnyValueList::~AnyValueList() + inline AnyArgs::~AnyArgs() { if (num == 0 || !data) { return; } - Any* ptr = (Any*)data; - for (int i = 0; i < num; i++) { - ptr->cls->DestObject((void*)ptr->ptr); - ptr++; - } if (isMemoryOwner) { + Any* any = (Any*)data; + for (int i = 0; i < num; i++) { + any->cls->DestObject((void*)any->ptr); + any++; + } free(data); } num = 0; data = nullptr; } - inline void AnyValueList::ConvertArgs(sarray params) + inline int AnyArgs::Size() { - Any* ptr = (Any*)data; - int first = params.size() - num; - for (int i = 0; i < num; i++, ptr++) { - ptr->ConvertTo(*params.at(first + i)); - } + return size; } - inline const sarray AnyValueList::ToSArray() + inline const sarray AnyArgs::ToSArray() { return sarray((Any*)data, num); } - inline constexpr int AnyValueList::GetArgsSize(const sarray& args) - { - int size = args.size() * sizeof(Any); - for (auto& arg : args) { - size += arg.type->size; + inline constexpr Offset AnyArgs::GetArgsSize(const sarray& args,const sarray& params) + { //这里空间换时间,Any多占用了一个数据指针 + if (args.size() == 0 || params.size() < args.size() + 1) { + return 0; } - return size; + Offset offset = args.size() * sizeof(Any); + auto uptr = params.at(params.size() - args.size()); + for (auto uend = params.back(); uptr < uend; uptr++) { + offset += (*uptr)->parent->size;//数据大小 + } + return offset; } template inline bool AnyView::Get(const Name& name, T& t) { if (cache && cache->name == name) { - _cache_get: bool isChild = cache->type->IsChildOf(true); + _cache_get: bool isChild = cache->type->IsChildOf(); if (isChild) { - t = *(T*)((const char*)ptr + cache->data.offset); + t = *(T*)((const char*)ptr + cache->data.member.offset); } return isChild; } @@ -102,9 +108,9 @@ namespace refl { inline bool AnyView::Set(const Name& name, const T& t) { if (cache && cache->name == name) { - _cache_set: bool isChild = cache->type->IsChildOf(true); + _cache_set: bool isChild = cache->type->IsChildOf(); if (isChild) { - *(T*)((const char*)ptr + cache->data.offset) = t; + *(T*)((const char*)ptr + cache->data.member.offset) = t; } return isChild; } diff --git a/engine/3rdparty/zlib/include/refl/refl.h b/engine/3rdparty/zlib/include/refl/refl.h index 78518f1..b3925e0 100644 --- a/engine/3rdparty/zlib/include/refl/refl.h +++ b/engine/3rdparty/zlib/include/refl/refl.h @@ -2,39 +2,42 @@ #include "detail/uclass.inl" #include "detail/view.inl" #include "detail/field.inl" +#include "detail/convert.inl" #include "detail/meta.inl" #include "std/sarray.h" #include "macro.h" namespace refl { template - consteval FieldPtr StaticMemberField(T Obj::* ptr, const Name& name, const MemberDataValue& data = {}) { + consteval FieldPtr StaticMemberField(T Obj::* ptr, const Name& name, const MemberData& data = {}) { Offset offset = data.value.IsValid() ? sizeof(T) : 0; if (data.meta.IsValid()) { - offset += data.meta.type->size; + offset += data.meta.Size(); } FieldPtr::Data member(offset); - constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; + uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; return { name,&TypeInfo::StaticClass, member,flag}; } template - consteval FieldPtr StaticMethodField(R(*ptr)(Args...), const Name& name, const MethodDataValue& data = {}) { + consteval FieldPtr StaticMethodField(R(*ptr)(Args...), const Name& name, const MethodData& data = {}) { uint32_t flag = FIELD_METHOD_FLAG; - Offset offset = AnyValueList::GetArgsSize(data.value); + auto cls = &TypeInfo(*)(real_type_t...)>::StaticClass; + Offset offset = AnyArgs::GetArgsSize(data.value, cls->GetParams()); if (data.meta.IsValid()) { - offset += data.meta.type->size; + offset += data.meta.Size(); } FieldPtr::Data method(offset); - return { name,&TypeInfo(*)(real_type_t...)>::StaticClass,method, flag }; + return { name,cls,method, flag }; } template - consteval FieldPtr StaticMethodField(R(T::* ptr)(Args...), const Name& name, const MethodDataValue& data = {}) { + consteval FieldPtr StaticMethodField(R(T::* ptr)(Args...), const Name& name, const MethodData& data = {}) { uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; - Offset offset = AnyValueList::GetArgsSize(data.value); + auto cls = &TypeInfo(*)(const void*, real_type_t...)>::StaticClass; + Offset offset = AnyArgs::GetArgsSize(data.value, cls->GetParams()); if (data.meta.IsValid()) { - offset += data.meta.type->size; + offset += data.meta.Size(); } FieldPtr::Data method(offset); - return { name, &TypeInfo(*)(const void*,real_type_t...)>::StaticClass,method,flag }; + return { name, cls,method,flag }; } //用处不大---------------begin template<_ReflCheck_Meta T> diff --git a/engine/3rdparty/zlib/include/refl/std/sarray.h b/engine/3rdparty/zlib/include/refl/std/sarray.h index 1932eac..22100ab 100644 --- a/engine/3rdparty/zlib/include/refl/std/sarray.h +++ b/engine/3rdparty/zlib/include/refl/std/sarray.h @@ -12,18 +12,21 @@ namespace refl { constexpr sarray(const svector& vec) : m_ptr(vec.front()), m_count(vec.size()) {} constexpr sarray() :m_ptr(nullptr), m_count(0) {} constexpr sarray(std::initializer_list list) : m_ptr(list.begin()), m_count(list.size()) {} - const T* front() const noexcept { + constexpr const T* front() const noexcept { return m_ptr; } - const T* back()const noexcept { + constexpr const T* back()const noexcept { return m_ptr + m_count; } - const T* at(int i) const noexcept { + constexpr const T* at(int i) const noexcept { if (i < m_count) { return m_ptr + i; } return nullptr; } + constexpr bool IsValid() const noexcept { + return m_count > 0; + } constexpr bool empty() const noexcept { return m_count == 0; } diff --git a/engine/3rdparty/zlib/include/refl/std/svector.h b/engine/3rdparty/zlib/include/refl/std/svector.h index ae262dc..11f8189 100644 --- a/engine/3rdparty/zlib/include/refl/std/svector.h +++ b/engine/3rdparty/zlib/include/refl/std/svector.h @@ -11,18 +11,21 @@ namespace refl { public: constexpr svector() :m_ptr(nullptr), m_count(0), m_capicty(0){} constexpr svector(T* ptr, int size, int count) : m_ptr(ptr), m_capicty(size), m_count(count){} - T* front()const noexcept { + constexpr T* front()const noexcept { return m_ptr; } - T* back()const noexcept { + constexpr T* back()const noexcept { return m_ptr + m_count; } - void push_back(const T& t) { + constexpr void push_back(const T& t) { if (m_count < m_capicty) { *(m_ptr + m_count) = t; m_count++; } } + constexpr bool IsValid() const noexcept { + return m_count > 0; + } constexpr bool empty() const noexcept { return m_count == 0; } diff --git a/engine/3rdparty/zlib/test/refl/vertex.h b/engine/3rdparty/zlib/test/refl/vertex.h index e6149f0..e2dacf5 100644 --- a/engine/3rdparty/zlib/test/refl/vertex.h +++ b/engine/3rdparty/zlib/test/refl/vertex.h @@ -21,7 +21,8 @@ struct vec3 : public vec3_parent { float y = 2; __cppast(Meta = { 0.f}) float z = 3; - string name{ "hello" }; + __cppast(Meta = { "hello meta"}) + string name = "???"; __cppast(Meta = { {3,4} }) int norm(int x1, int& x2)override { int tmp = x1 * 2 + 1; @@ -30,6 +31,7 @@ struct vec3 : public vec3_parent { return x2; //cout << x2 << "vec3::norm" << endl; } + __cppast(Meta = {}) virtual float norm1(int& x1) { x1 = x1 * x * y * z; x = x1; @@ -38,47 +40,15 @@ struct vec3 : public vec3_parent { //cout << x1 << "::norm1" << endl; return x1; } + __cppast(Meta = {}) static void norm2(int x1 = 10) { cout << x1 << "::norm2" << endl; } + __cppast(Meta = {}) static void norm3(int x1 = 10) { x1 = x1 * 10; cout << x1 << "::norm3" << endl; } }; -struct vec3_Static_Meta { - //这里好像不需要 - consteval static auto __StaticFields() { - return std::make_tuple(&vec3::x, &vec3::y, &vec3::z, &vec3::norm, &vec3::norm1, &vec3::norm2); - }; - consteval static auto __MakeStaticFields() { - return std::array{ - StaticMemberField(&vec3::x, FName("x"), {0.f,vec4{}}), - StaticMemberField(&vec3::y, FName("y"), {0.f,{}}), - StaticMemberField(&vec3::z, FName("z"), {0.f,{}}), - StaticMethodField(&vec3::norm, FName("norm"), {{10,9},{}}), - StaticMethodField(&vec3::norm1, FName("norm1"), {{10},{}}), - StaticMethodField(&vec3::norm2, FName("norm2"), {{10},{}}), - }; - } - consteval static int Size() { - return fetch_meta_size(); - } -}; -struct vec3_Meta : public Meta{ - using MyStatic = vec3_Static_Meta; - using MyUClass = UClass_Meta; - inline static char s_data[MyStatic::Size()]{}; - static auto __MakeFields() { - char* memory = &s_data[0]; - return std::array{ - MemberField(&vec3::x, FName("x"),memory, {0.f,vec4{}}), - MemberField(&vec3::y, FName("y"),memory, {0.f,{}}), - MemberField(&vec3::z, FName("z"),memory, {0.f,{}}), - MethodField(&vec3::norm, FName("norm"), memory, {{10,9},{}}), - MethodField(&vec3::norm1, FName("norm1"),memory, {{10},{}}), - MethodField(&vec3::norm2, FName("norm2"),memory, {{10},{}}), - }; - }; -}; -#include "meta_vertex.inl" \ No newline at end of file + +#include "meta_vertex_gen.inl" \ 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 eb6cf0b..e458218 100644 --- a/engine/3rdparty/zlib/test/refl_01.cpp +++ b/engine/3rdparty/zlib/test/refl_01.cpp @@ -5,9 +5,15 @@ vec3 v; constexpr int smeta = sizeof(vec3_Meta); constexpr int scls = sizeof(decltype(*cls)); auto ov = cls->New((void*)&v); -constexpr Name func = FName("norm"); void TestRefl1(benchmark::State& state) { int x = 1, y = 2; + auto rx = &vec3_Meta::s_data[0]; + auto f = cls->GetField(GetStaticFieldID(FName("name"))); + string hello; + ov.Get(FName("name"), hello); + hello = *f->data.member.value.CastTo(); + ov.Set(FName("name"), hello); + constexpr auto r = StaticMemberField(&vec3::name, FName("name"), { ("hello meta")}); for (auto _ : state) { std::array arr{&x, ov.ptr}; svector svec(&arr.front(), arr.size(), 2); diff --git a/engine/xmake/gen/meta_refl.lua b/engine/xmake/gen/meta_refl.lua index afd6be0..f0c21e8 100644 --- a/engine/xmake/gen/meta_refl.lua +++ b/engine/xmake/gen/meta_refl.lua @@ -1,20 +1,21 @@ import("core.project.depend") -function cmd_compile(genfile, sourcefile) +function cmd_compile(genfile, sourcefile, template) print(os.programdir()) import("find_sdk") local meta = find_sdk.find_my_program("refl") - argv = {"build", sourcefile, "--output=" .. genfile} - print("cmd_compile", genfile) - os.execv(meta.program, argv, {envs = {PATH = meta.sdkdir}}) + template = template or path.join(meta.sdkdir, "template/refl.liquid") + argv = {"build", sourcefile, "-o", genfile, "-t", template} + print("cmd_meta_compile", genfile) + os.runv(meta.program, argv) return argv end -function _listen_gen_file(target, batch) +function _listen_gen_file(target, batch, template) genfile, sourcefile = batch[1], batch[2] local dependfile = target:dependfile(genfile) depend.on_changed( function() - cmd_compile(genfile, sourcefile) + cmd_compile(batch[1], batch[2], template) end, {dependfile = dependfile, files = sourcefile} ) @@ -24,20 +25,24 @@ function gen(target) if not gen_batch then return end + local template = target:extraconf("rules", "c++.codegen", "template") for _, batch in ipairs(gen_batch) do if batch[2] then - _listen_gen_file(target, batch) + _listen_gen_file(target, batch, template) end end end function main(target, headerfiles) local sourcedir = path.join(target:autogendir({root = true}), target:plat(), "inl") + if not os.isdir(sourcedir) then + os.mkdir(sourcedir) + end target:add("includedirs", sourcedir, {public = true}) local gen_batch = {} for idx, headerfile in pairs(headerfiles) do -- batch - sourcefile = path.join(sourcedir, "meta_" .. path.basename(headerfile) .. ".inl") + sourcefile = path.join(sourcedir, path.basename(headerfile) .. "_gen.inl") table.insert(gen_batch, {sourcefile, headerfile}) end -- save unit batch diff --git a/engine/xmake/gen/xmake.lua b/engine/xmake/gen/xmake.lua index 1d25039..4125ecb 100644 --- a/engine/xmake/gen/xmake.lua +++ b/engine/xmake/gen/xmake.lua @@ -13,6 +13,5 @@ rule("c++.codegen") meta_refl(target, headerfiles) end) on_config(function (target) - print("c++.codegen on_config") import("meta_refl").gen(target) end) \ No newline at end of file