113 lines
3.2 KiB
Plaintext
113 lines
3.2 KiB
Plaintext
|
|
#pragma once
|
|||
|
|
#include "uclass.h"
|
|||
|
|
namespace refl {
|
|||
|
|
template<_ReflCheck_Ctor T>
|
|||
|
|
class UClass_Auto : public UClass {
|
|||
|
|
public:
|
|||
|
|
using UClass::UClass;
|
|||
|
|
using UClassType = UClass_Auto<T>;
|
|||
|
|
public:
|
|||
|
|
constexpr static UClassType BuildClass() {
|
|||
|
|
UClassType cls(type_name<T>().View(), sizeof(T));
|
|||
|
|
if constexpr (!std::is_trivially_copyable_v<T>) {
|
|||
|
|
cls.vtable.InitObject = &UClass::InitObject<T>;
|
|||
|
|
}
|
|||
|
|
return cls;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* 模板优化
|
|||
|
|
* 成员参数转化为const void*
|
|||
|
|
* 引用参数转化为指针
|
|||
|
|
*/
|
|||
|
|
template<typename R, typename... Args>
|
|||
|
|
class UMethod_Auto : public UClass {
|
|||
|
|
using UClass::UClass;
|
|||
|
|
using MethodType = R(*)(Args...);
|
|||
|
|
using UClassType = UMethod_Auto<R, Args...>;
|
|||
|
|
public:
|
|||
|
|
std::array<const UClass*, sizeof...(Args) + 1> UList{};
|
|||
|
|
|
|||
|
|
static std::vector<const UClass*> GetParams(const UClass* cls) {
|
|||
|
|
auto& UList = static_cast<const UClassType*>(cls)->UList;
|
|||
|
|
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>) {
|
|||
|
|
MethodType fptr = (MethodType)std::get<Method>(field.data);
|
|||
|
|
auto param = ArgsList.rbegin();
|
|||
|
|
fptr(param++->cast_to<Args>()...);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
MethodType fptr = (MethodType)std::get<Method>(field.data);
|
|||
|
|
auto param = ArgsList.rbegin();
|
|||
|
|
auto ret = ArgsList.begin();
|
|||
|
|
if (ret->cls == &TypeInfo<R>::StaticClass) {
|
|||
|
|
*(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>) {
|
|||
|
|
UList[0] = &TypeInfo<R>::StaticClass;
|
|||
|
|
}
|
|||
|
|
if constexpr (sizeof...(Args) > 0) {
|
|||
|
|
auto ptr = &UList[1];
|
|||
|
|
(..., (*ptr = &TypeInfo<typename std::remove_pointer_t<Args>*>::StaticClass, ptr++));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public:
|
|||
|
|
//为了简化判断,cls 对象 统统指向 T*
|
|||
|
|
constexpr static UClassType BuildClass() {
|
|||
|
|
UClassType cls(type_name<MethodType>().View(), sizeof(MethodType));
|
|||
|
|
cls.vtable.GetParams = &UClassType::GetParams;
|
|||
|
|
cls.vtable.Call = &UClassType::Call;
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
void BuildClass() {
|
|||
|
|
vtable.GetField = &UClass_Custom::GetField;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
//基础类型的偏特化
|
|||
|
|
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();
|
|||
|
|
};
|
|||
|
|
}
|