134 lines
3.2 KiB
C++
134 lines
3.2 KiB
C++
#pragma once
|
|
#include "field.h"
|
|
#include "view.h"
|
|
#include "meta.h"
|
|
#include "convert.h"
|
|
namespace refl {
|
|
enum ClassFlag :uint32_t {
|
|
CLASS_NONE_FLAG = 0,
|
|
CLASS_TRIVIAL_FLAG = 1 << 0,
|
|
CLASS_POINTER_FLAG = 1 << 1,
|
|
CLASS_ARRAY_FLAG = 1 << 2,
|
|
};
|
|
using enum ClassFlag;
|
|
enum EFieldFind :uint32_t {
|
|
FIND_ALL_FIELD = 0,
|
|
FIND_ALL_MEMBER,
|
|
FIND_ALL_METHOD,
|
|
FIND_FIELD,
|
|
FIND_CTOR,
|
|
FIND_MEMBER,
|
|
FIND_METHOD,
|
|
FIND_METHODS,//函数重载 特别是构造函数
|
|
};
|
|
struct vtable_uclass
|
|
{
|
|
//class
|
|
const sarray<const FieldPtr> (*GetFields)(const UClass*, EFieldFind find, const Name& name);
|
|
//function
|
|
sarray<const UClass*>(*GetParams)(const UClass*);
|
|
//function
|
|
void (*Call)(const FieldPtr*, const sarray<Any>& ArgsList);
|
|
//meta
|
|
const UClass* (*GetMeta)(const Name&);
|
|
//object
|
|
bool (*CtorObject)(void* ptr,const UClass* cls, const sarray<Any>& ArgsList);
|
|
bool (*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){}
|
|
AnyView New(void* ptr = nullptr, const sarray<Any>& ArgsList = {}) const {
|
|
if (ptr == nullptr) {
|
|
ptr = malloc(size);
|
|
CtorObject(ptr, ArgsList);
|
|
}
|
|
return { ptr , this };
|
|
}
|
|
template<typename T>
|
|
T* New(T* ptr = nullptr, const sarray<Any>& ArgsList = {}) const{
|
|
if (!IsChildOf<T>()) {
|
|
return nullptr;
|
|
}
|
|
if (ptr == nullptr) {
|
|
ptr = (T*)malloc(size);
|
|
}
|
|
CtorObject(ptr, ArgsList);
|
|
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 {
|
|
return IsChildOf(&TypeInfo<T>::StaticClass);
|
|
}
|
|
public:
|
|
const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name)const {
|
|
if (vtable.GetFields) {
|
|
return vtable.GetFields(this, find, name);
|
|
}
|
|
return {};
|
|
}
|
|
bool CtorObject(void* ptr, const sarray<Any>& ArgsList = {})const {
|
|
if (vtable.CtorObject) {
|
|
if (vtable.CtorObject(ptr, this, ArgsList)) {
|
|
return true;
|
|
}
|
|
auto& fieldList = GetFields(EFieldFind::FIND_CTOR, FName("Ctor"));
|
|
if (fieldList.empty()) {
|
|
return false;
|
|
}
|
|
if (fieldList.size() == 1) {
|
|
return fieldList[0]->Invoke(ArgsList);
|
|
}
|
|
for (auto& field : fieldList) {
|
|
if (field.Invokes(ArgsList)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
memset(ptr, 0, size);
|
|
return true;
|
|
}
|
|
void DestObject(void* ptr)const {
|
|
if (vtable.DestObject) {
|
|
vtable.DestObject(ptr);
|
|
}
|
|
}
|
|
public:
|
|
template<typename T>
|
|
static bool CtorObject(void* ptr, const UClass* cls, const sarray<Any>& ArgsList = {}) {
|
|
int size = ArgsList.size();
|
|
if (size == 0) {
|
|
if constexpr (std::is_trivially_constructible_v<T>) {
|
|
std::construct_at((T*)ptr);
|
|
return true;
|
|
}
|
|
else {
|
|
throw "refl::error:: no default construct function!!!";
|
|
}
|
|
}
|
|
if (size == 1 && ArgsList[0]->Check(cls)) {
|
|
*(T*)ptr = *(const T*)ArgsList[0]->ptr;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
} |