2024-04-08 21:01:50 +08:00
|
|
|
|
#pragma once
|
2024-04-11 10:13:15 +08:00
|
|
|
|
#include <array>
|
2024-04-08 21:01:50 +08:00
|
|
|
|
#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-13 17:47:44 +08:00
|
|
|
|
consteval static MyUClass BuildClass() {
|
2024-04-09 16:31:09 +08:00
|
|
|
|
MyUClass cls(type_name<T>().View(), sizeof(T));
|
2024-06-12 22:07:45 +08:00
|
|
|
|
if constexpr (std::is_pointer_v<T>){
|
2024-04-25 21:45:41 +08:00
|
|
|
|
using RawT = std::remove_pointer_t<T>;
|
|
|
|
|
|
cls.flag = CLASS_POINTER_FLAG;
|
|
|
|
|
|
if constexpr (!std::is_same_v<RawT, void>) {
|
|
|
|
|
|
cls.parent = &TypeInfo<RawT>::StaticClass;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-06-14 22:24:52 +08:00
|
|
|
|
else {
|
|
|
|
|
|
cls.vtable.CtorObject = &MyUClass::CtorObject<T>;
|
|
|
|
|
|
}
|
2024-04-29 15:00:09 +08:00
|
|
|
|
if constexpr (requires {typename T::MyMetas; }) {
|
|
|
|
|
|
cls.vtable.GetMeta = &T::MyMetas::GetMeta;
|
|
|
|
|
|
}
|
2024-04-08 21:01:50 +08:00
|
|
|
|
return cls;
|
|
|
|
|
|
}
|
2024-04-13 17:47:44 +08:00
|
|
|
|
void Set(void* ptr,const T& t) {
|
|
|
|
|
|
*(T*)ptr = t;
|
|
|
|
|
|
}
|
|
|
|
|
|
T& Get(void* ptr) {
|
|
|
|
|
|
return *(T*)ptr;
|
|
|
|
|
|
}
|
2024-04-08 21:01:50 +08:00
|
|
|
|
};
|
2024-04-25 21:45:41 +08:00
|
|
|
|
template<_ReflCheck_Ctor T, int N>
|
|
|
|
|
|
class UClass_Array : public UClass {
|
|
|
|
|
|
public:
|
|
|
|
|
|
using UClass::UClass;
|
|
|
|
|
|
using MyUClass = UClass_Array<T, N>;
|
|
|
|
|
|
public:
|
|
|
|
|
|
consteval static MyUClass BuildClass() {
|
|
|
|
|
|
MyUClass cls(type_name<T[N]>().View(), sizeof(T) * N, &TypeInfo<T>::StaticClass);
|
2024-06-12 22:07:45 +08:00
|
|
|
|
if constexpr (std::is_pointer_v<T>) {
|
2024-04-25 21:45:41 +08:00
|
|
|
|
cls.flag = CLASS_POINTER_FLAG | CLASS_ARRAY_FLAG;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
2024-06-12 22:07:45 +08:00
|
|
|
|
cls.flag = CLASS_ARRAY_FLAG;
|
2024-04-25 21:45:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
return cls;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2024-04-08 21:01:50 +08:00
|
|
|
|
/*
|
|
|
|
|
|
* 模板优化
|
|
|
|
|
|
* 成员参数转化为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{};
|
2024-04-25 21:45:41 +08:00
|
|
|
|
consteval sarray<const UClass*> GetParams()const {
|
|
|
|
|
|
return sarray<const UClass*>(&UList.front(), UList.size());
|
|
|
|
|
|
}
|
2024-04-16 16:17:13 +08:00
|
|
|
|
static sarray<const UClass*> GetParams(const UClass* cls) {
|
2024-04-09 16:31:09 +08:00
|
|
|
|
auto& UList = static_cast<const MyUClass*>(cls)->UList;
|
2024-04-16 16:17:13 +08:00
|
|
|
|
return sarray<const UClass*>(&UList.front(),UList.size());
|
2024-04-08 21:01:50 +08:00
|
|
|
|
}
|
2024-04-15 19:53:39 +08:00
|
|
|
|
//这里顺序似乎是不确定的,但是我实际运用是对的
|
|
|
|
|
|
//如果使用make_index_sequence,会多一次函数调用
|
|
|
|
|
|
//为什么包裹一层迭代器,就不会出现警告了
|
2024-04-19 22:02:27 +08:00
|
|
|
|
static void Call(const FieldPtr* field, const sarray<Any>& ArgsList) {
|
2024-04-15 19:53:39 +08:00
|
|
|
|
assert(sizeof...(Args) <= ArgsList.size());
|
2024-04-08 21:01:50 +08:00
|
|
|
|
if constexpr (std::is_same_v<R, void>) {
|
2024-04-19 22:02:27 +08:00
|
|
|
|
MethodType fptr = (MethodType)field->data.method.fptr;
|
2024-04-15 19:53:39 +08:00
|
|
|
|
auto param = ArgsList.end();
|
2024-04-25 21:45:41 +08:00
|
|
|
|
fptr((param--->CastTo<Args>())...);
|
2024-04-08 21:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
else {
|
2024-04-19 22:02:27 +08:00
|
|
|
|
MethodType fptr = (MethodType)field->data.method.fptr;
|
2024-04-15 19:53:39 +08:00
|
|
|
|
auto param = ArgsList.end();
|
2024-04-16 16:17:13 +08:00
|
|
|
|
auto ret = ArgsList.front();
|
2024-06-14 22:24:52 +08:00
|
|
|
|
if (ret->cls == &TypeInfo<R>::StaticClass) {
|
2024-04-25 21:45:41 +08:00
|
|
|
|
*(R*)ret->ptr = fptr((param--->CastTo<Args>())...);
|
2024-04-08 21:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
else {
|
2024-04-25 21:45:41 +08:00
|
|
|
|
fptr((param--->CastTo<Args>())...);
|
2024-04-08 21:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
protected:
|
2024-04-13 17:47:44 +08:00
|
|
|
|
consteval void BuildUList() {
|
2024-04-08 21:01:50 +08:00
|
|
|
|
if constexpr (!std::is_same_v<R, void>) {
|
2024-06-14 22:24:52 +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-06-14 22:24:52 +08:00
|
|
|
|
(..., (*ptr = &TypeInfo<args_type_t<Args>>::StaticClass, ptr++));
|
2024-04-08 21:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public:
|
|
|
|
|
|
//为了简化判断,cls 对象 统统指向 T*
|
2024-04-13 17:47:44 +08:00
|
|
|
|
consteval static MyUClass BuildClass() {
|
2024-04-09 16:31:09 +08:00
|
|
|
|
MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType));
|
|
|
|
|
|
cls.vtable.GetParams = &MyUClass::GetParams;
|
|
|
|
|
|
cls.vtable.Call = &MyUClass::Call;
|
2024-04-15 19:53:39 +08:00
|
|
|
|
cls.flag = CLASS_TRIVIAL_FLAG;
|
2024-04-08 21:01:50 +08:00
|
|
|
|
cls.BuildUList();
|
|
|
|
|
|
return cls;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2024-04-13 17:47:44 +08:00
|
|
|
|
template<typename T, typename P = void>
|
|
|
|
|
|
class UClass_Meta : public UClass {
|
|
|
|
|
|
public:
|
2024-04-29 15:00:09 +08:00
|
|
|
|
using MyMeta = meta_type_t<T>;
|
|
|
|
|
|
using FieldsType = decltype(MyMeta::__MakeFields());
|
|
|
|
|
|
FieldsType Fields{ MyMeta::__MakeFields() };
|
2024-04-14 22:45:08 +08:00
|
|
|
|
UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){
|
2024-04-15 19:53:39 +08:00
|
|
|
|
if constexpr (std::is_trivially_copyable_v<T>) {
|
|
|
|
|
|
flag = CLASS_TRIVIAL_FLAG;
|
|
|
|
|
|
}
|
2024-04-13 17:47:44 +08:00
|
|
|
|
if constexpr (!std::is_same_v<P, void>) {
|
|
|
|
|
|
parent = &TypeInfo<P>::StaticClass;
|
|
|
|
|
|
}
|
2024-04-29 15:00:09 +08:00
|
|
|
|
if constexpr (requires(const Name & name) { T::MyMetas::GetMeta(name); }) {
|
|
|
|
|
|
vtable.GetMeta = &T::MyMetas::GetMeta;
|
2024-04-28 00:23:35 +08:00
|
|
|
|
}
|
2024-06-12 22:07:45 +08:00
|
|
|
|
vtable.GetFields = &UClass_Meta::GetFields;
|
2024-06-14 22:24:52 +08:00
|
|
|
|
vtable.CtorObject = &UClass::CtorObject<T>;
|
2024-04-13 17:47:44 +08:00
|
|
|
|
}
|
2024-04-14 22:45:08 +08:00
|
|
|
|
const FieldPtr* GetField(int index) const {
|
|
|
|
|
|
return &Fields[index];
|
|
|
|
|
|
}
|
2024-06-12 22:07:45 +08:00
|
|
|
|
const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name) const {
|
2024-04-14 22:45:08 +08:00
|
|
|
|
constexpr int length = std::tuple_size<FieldsType>::value;
|
2024-06-12 22:07:45 +08:00
|
|
|
|
constexpr int MemberCount = MyMeta::MyStatic::MemberCount();
|
|
|
|
|
|
constexpr int CtorCount = MyMeta::MyStatic::CtorCount();
|
|
|
|
|
|
switch (find) {
|
|
|
|
|
|
case EFieldFind::FIND_ALL_FIELD:
|
|
|
|
|
|
return sarray<const FieldPtr>(&Fields[0], length);
|
|
|
|
|
|
case EFieldFind::FIND_ALL_MEMBER:
|
|
|
|
|
|
return sarray<const FieldPtr>(&Fields[0], MemberCount);
|
|
|
|
|
|
case EFieldFind::FIND_ALL_METHOD:
|
|
|
|
|
|
return sarray<const FieldPtr>(&Fields[MemberCount + CtorCount], length - MemberCount - CtorCount);
|
|
|
|
|
|
case EFieldFind::FIND_CTOR:
|
|
|
|
|
|
return sarray<const FieldPtr>(&Fields[MemberCount], CtorCount);
|
|
|
|
|
|
case EFieldFind::FIND_FIELD:
|
|
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
|
|
if (name == Fields[i].name) {
|
|
|
|
|
|
return sarray<const FieldPtr>(&Fields[i], 1);
|
|
|
|
|
|
}
|
2024-04-14 22:45:08 +08:00
|
|
|
|
}
|
2024-06-12 22:07:45 +08:00
|
|
|
|
return {};
|
|
|
|
|
|
case EFieldFind::FIND_MEMBER:
|
|
|
|
|
|
for (int i = 0; i < MemberCount; i++) {
|
|
|
|
|
|
if (name == Fields[i].name) {
|
|
|
|
|
|
return sarray<const FieldPtr>(&Fields[i], 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return {};
|
|
|
|
|
|
case EFieldFind::FIND_METHOD:
|
|
|
|
|
|
for (int i = MemberCount + CtorCount; i < length; i++) {
|
|
|
|
|
|
if (name == Fields[i].name) {
|
|
|
|
|
|
return sarray<const FieldPtr>(&Fields[i], 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return {};
|
|
|
|
|
|
case EFieldFind::FIND_METHODS:
|
|
|
|
|
|
{
|
|
|
|
|
|
int first = 0,count = 0;
|
|
|
|
|
|
for (int i = MemberCount + CtorCount; i < length; i++) {
|
|
|
|
|
|
if (name == Fields[i].name) {
|
|
|
|
|
|
if (!count) {
|
|
|
|
|
|
first = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
count++;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (count) {
|
|
|
|
|
|
return sarray<const FieldPtr>(&Fields[first], count);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return {};
|
|
|
|
|
|
}
|
|
|
|
|
|
default:
|
|
|
|
|
|
return {};
|
2024-04-14 22:45:08 +08:00
|
|
|
|
}
|
2024-06-12 22:07:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
static const sarray<const FieldPtr> GetFields(const UClass* _cls, EFieldFind find, const Name& name) {
|
|
|
|
|
|
auto cls = static_cast<const UClass_Meta*>(_cls);
|
|
|
|
|
|
return cls->GetFields(find, name);
|
|
|
|
|
|
}
|
2024-04-08 21:01:50 +08:00
|
|
|
|
};
|
2024-04-13 17:47:44 +08:00
|
|
|
|
|
2024-06-14 22:24:52 +08:00
|
|
|
|
template<>
|
|
|
|
|
|
struct TypeInfoImpl<void> {
|
|
|
|
|
|
inline constexpr static UClass StaticClass = { type_name<void>().View(), 0 };
|
|
|
|
|
|
};
|
|
|
|
|
|
template<_ReflCheck_UClass T>
|
2024-04-08 21:01:50 +08:00
|
|
|
|
struct TypeInfoImpl<T> {
|
2024-06-14 22:24:52 +08:00
|
|
|
|
using MyUClass = typename T::MyMeta::MyUClass;
|
|
|
|
|
|
inline static MyUClass StaticClass = MyUClass();
|
2024-04-08 21:01:50 +08:00
|
|
|
|
};
|
|
|
|
|
|
// 函数指针类型的偏特化
|
|
|
|
|
|
template<typename R, typename... Args>
|
|
|
|
|
|
struct TypeInfoImpl<R(*)(Args...)> {
|
|
|
|
|
|
using UClass = UMethod_Auto<R, Args...>;
|
|
|
|
|
|
inline constexpr static UClass StaticClass = UClass::BuildClass();
|
|
|
|
|
|
};
|
2024-04-25 21:45:41 +08:00
|
|
|
|
template<typename T, int N>
|
|
|
|
|
|
struct TypeInfoImpl<T[N]> {
|
|
|
|
|
|
using UClass = UClass_Array<T,N>;
|
|
|
|
|
|
inline constexpr static UClass StaticClass = UClass::BuildClass();
|
|
|
|
|
|
};
|
2024-06-14 22:24:52 +08:00
|
|
|
|
//基础类型的偏特化
|
|
|
|
|
|
template<_ReflCheck_Ctor_NoUClass T>
|
|
|
|
|
|
struct TypeInfoImpl<T> {
|
|
|
|
|
|
using UClass = UClass_Auto<T>;
|
|
|
|
|
|
inline constexpr static UClass StaticClass = UClass::BuildClass();
|
|
|
|
|
|
};
|
2024-04-08 21:01:50 +08:00
|
|
|
|
}
|