117 lines
2.5 KiB
C++
117 lines
2.5 KiB
C++
#pragma once
|
|
#include "type.h"
|
|
#include "field.h"
|
|
#include "view.h"
|
|
namespace refl {
|
|
enum ClassFlag :uint32_t {
|
|
CLASS_NONE_FLAG = 0,
|
|
CLASS_TRIVIAL_FLAG = 1 << 0,
|
|
};
|
|
using enum ClassFlag;
|
|
struct vtable_uclass
|
|
{
|
|
//class
|
|
const FieldPtr* (*GetField)(const UClass*, const Name&, int);
|
|
//function
|
|
sarray<const UClass*>(*GetParams)(const UClass*);
|
|
//function
|
|
void (*Call)(const FieldPtr*, const sarray<ArgsView>& ArgsList);
|
|
|
|
//object
|
|
void (*InitObject)(void*);
|
|
void (*CopyObject)(void*, const void*);
|
|
void (*DestObject)(void*);
|
|
};
|
|
class UClass{
|
|
public:
|
|
Name name;
|
|
uint32_t size;
|
|
uint32_t flag{0};
|
|
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:
|
|
const FieldPtr* GetField(const Name& name, int index)const {
|
|
if (vtable.GetField) {
|
|
return vtable.GetField(this, name, index);
|
|
}
|
|
return nullptr;
|
|
}
|
|
void InitObject(void* ptr)const {
|
|
if (vtable.InitObject) {
|
|
vtable.InitObject(ptr);
|
|
}
|
|
else {
|
|
memset(ptr, 0, size);
|
|
}
|
|
}
|
|
void CopyObject(void* dst, const void* src)const {
|
|
if (vtable.CopyObject) {
|
|
vtable.CopyObject(dst, src);
|
|
}
|
|
else {
|
|
memcpy(dst, src, size);
|
|
}
|
|
}
|
|
void DestObject(void* ptr)const {
|
|
if (vtable.DestObject) {
|
|
vtable.DestObject(ptr);
|
|
}
|
|
}
|
|
public:
|
|
template<_ReflCheck_Ctor T>
|
|
static void InitObject(void* ptr) {
|
|
T obj{};
|
|
std::construct_at((T*)ptr, obj);
|
|
}
|
|
template<typename T>
|
|
static void CopyObject(void* dst, const void* src) {
|
|
*(T*)dst = *(T*)src;
|
|
}
|
|
};
|
|
} |