zengine-old/engine/3rdparty/zlib/include/refl/detail/uclass.h
2024-04-08 21:01:50 +08:00

124 lines
3.2 KiB
C++

#pragma once
#include "type.h"
#include "field.h"
#include "view.h"
namespace refl {
struct vtable_uclass
{
//object
void (*InitObject)(void*);
//class
const FieldPtr* (*GetField)(const UClass*, const Name&, bool);
//function
std::vector<const UClass*>(*GetParams)(const UClass*);
//function
void (*Call)(const FieldPtr&, std::vector<ArgsView>&);
};
class UClass{
using enum FieldFlag;
public:
Name name;
uint32_t size;
//uint32_t flag;
const UClass* parent;
vtable_uclass vtable{};
public:
constexpr UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr)
:name(name), size(size), parent(parent){}
ObjectView New(void* ptr = nullptr) const{
if (ptr == nullptr) {
ptr = malloc(size);
InitObject(ptr);
}
return { ptr , this };
}
template<typename T>
T* New(T* ptr = nullptr) const{
if (!IsChildOf<T>()) {
return nullptr;
}
if (ptr == nullptr) {
ptr = (T*)malloc(size);
}
InitObject(ptr);
return ptr;
}
bool IsChildOf(const UClass* cls) const {
const UClass* _parent = parent;
while (_parent != nullptr) {
if (_parent == cls) {
return true;
}
_parent = _parent->parent;
}
return false;
}
template<typename T>
bool IsChildOf(bool bthis = false) const {
constexpr UClass* cls = &TypeInfo<T>::StaticClass;
if (bthis) {
return cls == this;
}
const UClass* _parent = this;
while (_parent != nullptr) {
if (_parent == cls) {
return true;
}
_parent = _parent->parent;
}
return false;
}
public:
template<_ReflCheck_Ctor T>
static void InitObject(void* ptr) {
T obj{};
std::construct_at((T*)ptr, obj);
}
//unsafe if called by other, need check class && size
void InitObject(void* ptr)const {
if (vtable.InitObject) {
vtable.InitObject(ptr);
}
else {
memset(ptr, 0, size);
}
}
const FieldPtr* GetField(const Name& name, bool isMethod)const {
if (vtable.GetField) {
return vtable.GetField(this, name, isMethod);
}
return nullptr;
}
std::vector<const UClass*> GetParams() const {
if (vtable.GetParams) {
return vtable.GetParams(this);
}
return{};
}
void Call(const FieldPtr& field, std::vector<ArgsView>& ArgsList)const{
if (vtable.Call) {
return vtable.Call(field, ArgsList);
}
}
public:
template<Offset offset>
constexpr static FieldPtr MakeMemberField(Name name, const UClass* cls) {
FieldPtr::Data member = { offset };
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
return { name, cls, {member}, flag };
}
template<typename R, typename ...Args>
static FieldPtr MakeMethodField(R (* ptr)(Args...), Name name) {
FieldPtr::Data member = { *(Method*)&ptr};
constexpr uint32_t flag = FIELD_METHOD_FLAG;
return { name, &TypeInfo<R(*)(typename RealTypeImpl<Args>::type...)>::StaticClass, {member},flag };
}
template<typename T, typename R, typename ...Args>
static FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name) {
FieldPtr::Data member = { *(Method*)&ptr };
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
return { name, &TypeInfo<R(*)(const void*, typename RealTypeImpl<Args>::type...)>::StaticClass, {member},flag };
}
};
}