zengine/engine/modules/engine/zlib/include/refl/detail/uclass.inl

290 lines
8.4 KiB
Plaintext
Raw Normal View History

2024-07-20 18:04:19 +08:00
#include "uclass.h"
#include "name.h"
2024-07-27 14:24:46 +08:00
#include "type.h"
2024-08-06 16:08:11 +08:00
namespace refl {
2024-07-20 18:04:19 +08:00
template <class T>
2024-07-27 14:24:46 +08:00
concept is_metas_v = requires(const Name & name) { Meta<T>::GetMeta(name); };
2024-07-20 18:04:19 +08:00
template<typename T>
class UClass_Auto : public UClass {
public:
2024-10-27 22:37:35 +08:00
UClass_Auto() : UClass(meta_name<T>().view(), sizeof(T)) {
2024-07-20 18:04:19 +08:00
if constexpr (std::is_pointer_v<T>) {
using RT = std::remove_pointer_t<T>;
2024-07-24 14:42:14 +08:00
flag |= CLASS_POINTER_FLAG;
2024-07-20 18:04:19 +08:00
if constexpr (!std::is_same_v<RT, void>) {
2024-10-25 09:45:49 +08:00
parent = meta_info<RT>();
2024-07-20 18:04:19 +08:00
}
}
else if constexpr (is_array_v<T>) {
using RT = is_array_t<T>;
2024-07-24 14:42:14 +08:00
flag = CLASS_ARRAY_FLAG;
2024-07-20 18:04:19 +08:00
if constexpr (std::is_pointer_v<RT>) {
2024-07-24 14:42:14 +08:00
flag |= CLASS_POINTER_FLAG;
2024-07-20 18:04:19 +08:00
}
2024-10-25 09:45:49 +08:00
parent = meta_info<RT>();
2024-07-20 18:04:19 +08:00
}
else {
2024-10-25 09:45:49 +08:00
vtable.AddConstruct(&UClass::Construct<T>);
vtable.AddDestruct(&UClass::Destruct<T>);
2024-10-25 22:57:25 +08:00
if constexpr (is_metas_v<T>) {
vtable.AddGetMeta(&Meta<T>::GetMeta);
}
2024-07-20 18:04:19 +08:00
}
}
};
2024-10-25 09:45:49 +08:00
/*
* 模板优化
* 成员参数转化为const void*
* 引用参数转化为指针
* 返回引用转化为指针
*/
template<typename R, typename... Args>
class UMethod_Auto : public UClass {
using MethodType = R(*)(Args...);
public:
std::array<const UClass*, sizeof...(Args) + 1> UList{};
2024-10-27 22:37:35 +08:00
UMethod_Auto() : UClass(meta_name<MethodType>().view(), sizeof(MethodType)) {
2024-10-25 09:45:49 +08:00
flag = CLASS_TRIVIAL_FLAG;
vtable.AddGetParams(&UMethod_Auto::GetParams);
vtable.AddCall(&UMethod_Auto::Call);
if constexpr (!std::is_same_v<R, void>) {
UList[0] = meta_info<R>();
}
if constexpr (sizeof...(Args) > 0) {
auto ptr = &UList[1];
(..., (*ptr = meta_info<Args>(), ptr++));
}
}
//这里顺序似乎是不确定的,但是我实际运用是对的
//如果使用make_index_sequence,会多一次函数调用
//为什么包裹一层迭代器,就不会出现警告了
static void Call(const FieldPtr* field, span<Any> ArgsList) {
assert(sizeof...(Args) < ArgsList.size());
auto param = ArgsList.end() - 1;
if constexpr (std::is_same_v<R, void>) {
MethodType fptr = (MethodType)field->data.method.fptr;
fptr((param--->CastTo<Args>())...);
}
else {
MethodType fptr = (MethodType)field->data.method.fptr;
auto ret = ArgsList.front();
if (ret.cls == meta_info<R>()) {
*(R*)ret.ptr = fptr((param--->CastTo<Args>())...);
}
else {
fptr((param--->CastTo<Args>())...);
}
}
}
static span<const UClass*> GetParams(const UClass* cls) {
auto& UList = ((UMethod_Auto*)cls)->UList;
return span<const UClass*>{UList};
}
};
class UClass_Container_Impl : public UClass {
public:
using UClass::UClass;
struct iterator {
void* ptr;
void* val;
};
//container
using size_impl = size_t(*)(const void*);
using to_iterator_impl = void(*)(iterator&, const void*);
using insert_impl = void (*)(const void*, const void*);
//iterator
using iterator_impl = void (*)(iterator*);
public:
size_impl vsize;
to_iterator_impl vbegin;
to_iterator_impl vend;
insert_impl vinsert;
iterator_impl viterator_add;
iterator_impl viterator_sub;
template<typename T>
static void insert(const void* ptr, const void* obj) {
using value_type = typename T::value_type;
if constexpr (is_sequence_v<T>) {
((T*)ptr)->push_back(*(value_type*)obj);
}
else if constexpr (is_map_v<T>) {
((T*)ptr)->insert(*(value_type*)obj);
}
}
};
template<is_container_v T, typename value_type>
class UClass_Container : public UClass_Container_Impl {
public:
static bool construct(void* ptr, const UClass* cls, span<Any> ArgsList) {
new(ptr)T();
return true;
}
static void destruct(void* ptr) {
((T*)ptr)->~T();
}
static void begin(iterator& pit, const void* ptr) {
auto it = ((T*)ptr)->begin();
memcpy(&pit, &it, sizeof(it));
pit.val = &*it;
}
static void end(iterator& pit, const void* ptr) {
auto it = ((T*)ptr)->end();
memcpy(&pit, &it, sizeof(it));
pit.val = &*it;
}
static void add(iterator* pit) {
auto it = ++(*(typename T::iterator*)pit);
memcpy(pit, &it, sizeof(it));
pit->val = &*it;
}
static void sub(iterator* pit) {
auto it = --(*(typename T::iterator*)pit);
memcpy(pit, &it, sizeof(it));
pit->val = &*it;
}
2024-10-27 22:37:35 +08:00
UClass_Container() : UClass_Container_Impl(meta_name<T>().view(), sizeof(T)) {
2024-10-25 09:45:49 +08:00
parent = meta_info<value_type>();
flag = CLASS_CONTAINER_FLAG;
vtable.AddConstruct(&UClass_Container::construct);
vtable.AddDestruct(&UClass_Container::destruct);
if constexpr (is_sequence_v<T>) {
flag |= CLASS_SEQUENCE_FLAG;
}
else if constexpr (is_map_v<T>)
{
flag |= CLASS_MAP_FLAG;
}
auto p_size = &T::size;
vsize = *(size_impl*)&p_size;
vbegin = &UClass_Container::begin;
vend = &UClass_Container::end;
vinsert = &UClass_Container::insert<T>;
viterator_add = &UClass_Container::add;
viterator_sub = &UClass_Container::sub;
};
};
2024-07-27 14:24:46 +08:00
template<typename T, typename MetaImpl>
class UClass_Meta : public UClass {
using FieldsType = decltype(MetaImpl::MakeFields());
2024-10-25 09:45:49 +08:00
public:
2024-07-27 14:24:46 +08:00
FieldsType Fields{ MetaImpl::MakeFields() };
2024-10-27 22:37:35 +08:00
UClass_Meta() : UClass(meta_name<T>().view(), sizeof(T)) {
2024-07-27 14:24:46 +08:00
if constexpr (has_parent_v<T>) {
2024-10-25 09:45:49 +08:00
parent = meta_info<parent_t<T>>();
2024-07-27 14:24:46 +08:00
}
2024-10-25 22:57:25 +08:00
if constexpr (is_metas_v<T>) {
vtable.AddGetMeta(&Meta<T>::GetMeta);
}
2024-10-25 09:45:49 +08:00
vtable.AddGetFields(&UClass_Meta::GetFields);
vtable.AddConstruct(&UClass::Construct<T>);
}
span<const FieldPtr> GetFields(EFieldFind find, const Name& name) const {
constexpr int length = std::tuple_size<FieldsType>::value;
constexpr int MemberCount = MetaImpl::MemberCount();
constexpr int CtorCount = MetaImpl::CtorCount();
switch (find) {
case EFieldFind::FIND_ALL_FIELD:
return span<const FieldPtr>(&Fields[0], length);
case EFieldFind::FIND_ALL_MEMBER:
return span<const FieldPtr>(&Fields[0], MemberCount);
case EFieldFind::FIND_ALL_METHOD:
return span<const FieldPtr>(&Fields[MemberCount + CtorCount], length - MemberCount - CtorCount);
case EFieldFind::FIND_CTOR:
return span<const FieldPtr>(&Fields[MemberCount], CtorCount);
case EFieldFind::FIND_FIELD:
for (int i = 0; i < length; i++) {
if (name == Fields[i].name) {
return span<const FieldPtr>(&Fields[i], 1);
}
}
return {};
case EFieldFind::FIND_MEMBER:
for (int i = 0; i < MemberCount; i++) {
if (name == Fields[i].name) {
return span<const FieldPtr>(&Fields[i], 1);
}
}
return {};
case EFieldFind::FIND_METHOD:
for (int i = MemberCount + CtorCount; i < length; i++) {
if (name == Fields[i].name) {
return span<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 span<const FieldPtr>(&Fields[first], count);
}
}
return {};
}
default:
return {};
}
}
static span<const FieldPtr> GetFields(const UClass* _cls, EFieldFind find, Name name) {
auto cls = static_cast<const UClass_Meta*>(_cls);
return cls->GetFields(find, name);
}
};
template<typename T>
struct meta_info_impl {
static UClass* create() {
return new(MetaGlobalPool()) UClass_Auto<T>{};
}
};
template<typename R, typename... Args>
struct meta_info_impl<R(*)(Args...)> {
static UClass* create() {
return new(MetaGlobalPool()) UMethod_Auto<R, Args...>{};
}
};
template<is_container_v T>
struct meta_info_impl<T> {
static UClass* create() {
return new(MetaGlobalPool()) UClass_Container<T, typename T::value_type>{};
2024-07-27 14:24:46 +08:00
}
2024-07-24 14:42:14 +08:00
};
2024-10-23 15:24:39 +08:00
using __tClassTable = table<Name, const UClass*>;
UNIQUER_INLINE(__tClassTable, ClassTable, "refl::ClassTable")
2024-08-06 16:08:11 +08:00
inline const UClass* find_info(Name name) {
2024-10-23 15:24:39 +08:00
auto& ClassTable = UNIQUER_VAL(ClassTable);
2024-08-06 16:08:11 +08:00
if (auto it = ClassTable.find(name); it != ClassTable.end()) {
return it->second;
}
return nullptr;
}
template<typename Type>
2024-10-25 09:45:49 +08:00
inline const UClass* meta_info()
2024-08-06 16:08:11 +08:00
{
using T = real_type_t<Type>;
2024-10-25 09:45:49 +08:00
constexpr auto name = meta_name<T>();
2024-10-27 22:37:35 +08:00
if (auto cls = find_info(name.view())) {
2024-08-06 16:08:11 +08:00
return cls;
}
UClass* cls;
if constexpr (is_meta_v<T>){
2024-10-25 09:45:49 +08:00
cls = new(MetaGlobalPool()) UClass_Meta<T, meta_t<T>>{};
2024-08-06 16:08:11 +08:00
}
else if constexpr (std::is_same_v<T, void>) {
2024-10-27 22:37:35 +08:00
cls = new(MetaGlobalPool()) UClass{ name.view(), 0 };
2024-08-06 16:08:11 +08:00
}
else {
2024-10-25 09:45:49 +08:00
cls = meta_info_impl<T>::create();
2024-08-06 16:08:11 +08:00
}
2024-10-23 15:24:39 +08:00
auto& ClassTable = UNIQUER_VAL(ClassTable);
2024-10-27 22:37:35 +08:00
ClassTable[name.view()] = cls;
2024-08-06 16:08:11 +08:00
return cls;
}
2024-07-20 18:04:19 +08:00
}