zengine-old/engine/3rdparty/zlib/include/refl/detail/uclass.inl

142 lines
4.0 KiB
Plaintext
Raw Normal View History

2024-04-08 21:01:50 +08:00
#pragma once
#include "uclass.h"
namespace refl {
template<_ReflCheck_Ctor T>
class UClass_Auto : public UClass {
public:
using UClass::UClass;
2024-04-09 16:31:09 +08:00
using MyUClass = UClass_Auto<T>;
2024-04-08 21:01:50 +08:00
public:
2024-04-09 16:31:09 +08:00
constexpr static MyUClass BuildClass() {
MyUClass cls(type_name<T>().View(), sizeof(T));
2024-04-08 21:01:50 +08:00
if constexpr (!std::is_trivially_copyable_v<T>) {
2024-04-09 16:31:09 +08:00
cls.vtable.InitObject = &MyUClass::InitObject<T>;
cls.vtable.CopyObject = &MyUClass::CopyObject<T>;
2024-04-08 21:01:50 +08:00
}
return cls;
}
};
/*
* 模板优化
* 成员参数转化为const void*
* 引用参数转化为指针
2024-04-09 22:26:33 +08:00
* 返回引用转化为指针
2024-04-08 21:01:50 +08:00
*/
template<typename R, typename... Args>
class UMethod_Auto : public UClass {
using UClass::UClass;
using MethodType = R(*)(Args...);
2024-04-09 16:31:09 +08:00
using MyUClass = UMethod_Auto<R, Args...>;
2024-04-08 21:01:50 +08:00
public:
std::array<const UClass*, sizeof...(Args) + 1> UList{};
static std::vector<const UClass*> GetParams(const UClass* cls) {
2024-04-09 16:31:09 +08:00
auto& UList = static_cast<const MyUClass*>(cls)->UList;
2024-04-08 21:01:50 +08:00
return { UList.data(), UList.data() + UList.size() };
}
static void Call(const FieldPtr& field, std::vector<ArgsView>& ArgsList) {
if constexpr (std::is_same_v<R, void>) {
2024-04-09 16:31:09 +08:00
MethodType fptr = (MethodType)field.data.method;
2024-04-08 21:01:50 +08:00
auto param = ArgsList.rbegin();
fptr(param++->cast_to<Args>()...);
}
else {
2024-04-09 16:31:09 +08:00
MethodType fptr = (MethodType)field.data.method;
2024-04-08 21:01:50 +08:00
auto param = ArgsList.rbegin();
auto ret = ArgsList.begin();
2024-04-09 22:26:33 +08:00
if (ret->cls == &TypeInfo<R*>::StaticClass) {
2024-04-08 21:01:50 +08:00
*(R*)ret->val = fptr(param++->cast_to<Args>()...);
}
else {
fptr(param++->cast_to<Args>()...);
}
}
}
protected:
constexpr void BuildUList() {
if constexpr (!std::is_same_v<R, void>) {
2024-04-09 22:26:33 +08:00
UList[0] = &TypeInfo<R*>::StaticClass;
2024-04-08 21:01:50 +08:00
}
if constexpr (sizeof...(Args) > 0) {
auto ptr = &UList[1];
2024-04-09 22:26:33 +08:00
(..., (*ptr = &TypeInfo<std::remove_pointer_t<Args>*>::StaticClass, ptr++));
2024-04-08 21:01:50 +08:00
}
}
public:
//为了简化判断cls 对象 统统指向 T*
2024-04-09 16:31:09 +08:00
constexpr static MyUClass BuildClass() {
MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType));
cls.vtable.GetParams = &MyUClass::GetParams;
cls.vtable.Call = &MyUClass::Call;
2024-04-08 21:01:50 +08:00
cls.BuildUList();
return cls;
}
};
class UClass_Custom : public UClass {
public:
using UClass::UClass;
std::vector<FieldPtr> FList{};
int32_t AttrNum{ 0 };
static const FieldPtr* GetField(const UClass* _cls,const Name& name, bool isMethod){
auto cls = static_cast<const UClass_Custom*>(_cls);
auto& FList = cls->FList;
// 指定开始位置的迭代器
auto start = FList.begin();
if (isMethod) {
start += cls->AttrNum;
}
auto end = FList.end();
for (auto it = start; it != end; ++it) {
if (it->name == name) {
return &*it;
}
}
return nullptr;
}
2024-04-09 16:31:09 +08:00
/*
2024-04-08 21:01:50 +08:00
void BuildClass() {
2024-04-09 16:31:09 +08:00
FList.shrink_to_fit();//缩减容量FList大小不再改变了
2024-04-08 21:01:50 +08:00
vtable.GetField = &UClass_Custom::GetField;
}
2024-04-09 16:31:09 +08:00
*/
2024-04-08 21:01:50 +08:00
};
//基础类型的偏特化
template<_ReflCheck_Ctor_NoUClass T>
struct TypeInfoImpl<T> {
using UClass = UClass_Auto<T>;
inline constexpr static UClass StaticClass = UClass::BuildClass();
};
// 函数指针类型的偏特化
template<typename R, typename... Args>
struct TypeInfoImpl<R(*)(Args...)> {
using UClass = UMethod_Auto<R, Args...>;
inline constexpr static UClass StaticClass = UClass::BuildClass();
};
2024-04-09 16:31:09 +08:00
template<_ReflCheck_UClass T>
struct TypeInfoImpl<T> {
using MyUClass = typename T::MyUClass;
inline static MyUClass StaticClass = []()->MyUClass {
MyUClass cls(type_name<T>().View(), sizeof(T));
T::BuildClass(cls);
auto& vtable = cls.vtable;
if (!vtable.GetField) {
vtable.GetField = &MyUClass::GetField;
}
if constexpr (!std::is_trivially_copyable_v<T>) {
if (!vtable.InitObject) {
//这里一定会创建一个InitObject<T> 模板函数,如何优化
vtable.InitObject = &UClass::InitObject<T>;
}
if (!vtable.CopyObject) {
//这里一定会创建一个CopyObject<T> 模板函数,如何优化
vtable.CopyObject = &UClass::CopyObject<T>;
}
}
return cls;
}();
};
2024-04-08 21:01:50 +08:00
}