73 lines
2.0 KiB
C++
73 lines
2.0 KiB
C++
#include "uclass.h"
|
|
#include "name.h"
|
|
#include "type.h"
|
|
namespace refl {
|
|
template <class T>
|
|
concept is_metas_v = requires(const Name & name) { Meta<T>::GetMeta(name); };
|
|
template<typename T>
|
|
class UClass_Auto : public UClass {
|
|
public:
|
|
UClass_Auto() : UClass(type_name<T>().View(), sizeof(T)) {
|
|
if constexpr (std::is_pointer_v<T>) {
|
|
using RT = std::remove_pointer_t<T>;
|
|
flag |= CLASS_POINTER_FLAG;
|
|
if constexpr (!std::is_same_v<RT, void>) {
|
|
parent = type_info<RT>();
|
|
}
|
|
}
|
|
else if constexpr (is_array_v<T>) {
|
|
using RT = is_array_t<T>;
|
|
flag = CLASS_ARRAY_FLAG;
|
|
if constexpr (std::is_pointer_v<RT>) {
|
|
flag |= CLASS_POINTER_FLAG;
|
|
}
|
|
parent = type_info<RT>();
|
|
}
|
|
else {
|
|
vtable.Add(string_hash("Construct"), (void*)&UClass::Construct<T>);
|
|
vtable.Add(string_hash("Destruct"), (void*)&UClass::Destruct<T>);
|
|
}
|
|
}
|
|
};
|
|
template<typename T, typename MetaImpl>
|
|
class UClass_Meta : public UClass {
|
|
using FieldsType = decltype(MetaImpl::MakeFields());
|
|
FieldsType Fields{ MetaImpl::MakeFields() };
|
|
UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)) {
|
|
if constexpr (has_parent_v<T>) {
|
|
parent = type_info<parent_t<T>>();
|
|
}
|
|
|
|
}
|
|
};
|
|
inline UniquePtr<table<Name, const UClass*>, string_hash("refl::ClassTable")> ClassTablePtr;
|
|
inline const UClass* find_info(Name name) {
|
|
auto& ClassTable = *ClassTablePtr.Ptr();
|
|
if (auto it = ClassTable.find(name); it != ClassTable.end()) {
|
|
return it->second;
|
|
}
|
|
return nullptr;
|
|
}
|
|
template<typename Type>
|
|
inline const UClass* type_info()
|
|
{
|
|
using T = real_type_t<Type>;
|
|
constexpr auto name = type_name<T>();
|
|
if (auto cls = find_info(name.View())) {
|
|
return cls;
|
|
}
|
|
UClass* cls;
|
|
if constexpr (is_meta_v<T>){
|
|
cls = new(GlobalPool()) UClass_Meta<T, meta_t<T>>{};
|
|
}
|
|
else if constexpr (std::is_same_v<T, void>) {
|
|
cls = new(GlobalPool()) UClass{ name.View(), 0 };
|
|
}
|
|
else {
|
|
cls = new(GlobalPool()) UClass_Auto<T>{};
|
|
}
|
|
auto& ClassTable = *ClassTablePtr.Ptr();
|
|
ClassTable[name.View()] = cls;
|
|
return cls;
|
|
}
|
|
} |