zengine-old/engine/3rdparty/zlib/include/refl/detail/view.inl
2024-04-15 19:53:39 +08:00

129 lines
2.9 KiB
C++

#pragma once
#include "uclass.h"
#include "view.h"
namespace refl {
/*平凡对象的转化要支持吗
* 比如同大小的安全转化
* 对象从小到大
* 对象从大到小
*/
using enum ClassFlag;
bool ArgsView::ConvertTo(const UClass* toClass) {
//子类转父类
if (cls->IsChildOf(toClass)) {
cls = toClass;
return true;
}
if (cls->flag & CLASS_TRIVIAL_FLAG && toClass->flag & CLASS_TRIVIAL_FLAG) {
cls = toClass;
return true;
}
return false;
}
ArgsValueList::ArgsValueList(const sarray<ArgsValue>& args, void* memory)
: ptr((ArgsView*)memory),data(memory), num(args.size())
{
if (!memory) {
isMemoryOwner = true;
data = malloc(GetArgsSize(args));
ptr = (ArgsView*)data;
}
char* pData = ((char*)data) + num * sizeof(ArgsView);
for (auto& arg : args) {
arg.type->InitObject(pData);
arg.type->CopyObject(pData, arg.val);
ptr->val = pData;
ptr->cls = arg.cls;
ptr++;
pData += arg.cls->size;
}
ptr = (ArgsView*)data;
}
inline ArgsValueList::~ArgsValueList()
{
if (num == 0 || !data) {
return;
}
for (int i = 0; i < num; i++) {
ptr->cls->DestObject((void*)ptr->val);
}
if (isMemoryOwner) {
free(data);
}
num = 0;
data = nullptr;
}
inline constexpr int ArgsValueList::GetArgsSize(const sarray<ArgsValue>& args)
{
int size = args.size() * sizeof(ArgsView);
for (auto& arg : args) {
size += arg.type->size;
}
return size;
}
template<typename T>
inline bool ObjectView::Get(const Name& name, T& t)
{
if (cache && cache->name == name) {
_cache_get: bool isChild = cache->type->IsChildOf<T>(true);
if (isChild) {
t = *(T*)((const char*)ptr + cache->data.offset);
}
return isChild;
}
auto field = cls->GetField(name, false);
if (field) {
cache = field;
goto _cache_get;
}
if (cls->parent) {
return Parent().Get(name, t);
}
return false;
}
template<typename T>
inline bool ObjectView::Set(const Name& name, const T& t)
{
if (cache && cache->name == name) {
_cache_set: bool isChild = cache->type->IsChildOf<T>(true);
if (isChild) {
*(T*)((const char*)ptr + cache->data.offset) = t;
}
return isChild;
}
auto field = cls->GetField(name, false);
if (field) {
cache = field;
goto _cache_set;
}
if (cls->parent) {
return Parent().Set(name, t);
}
return false;
}
bool ObjectView::Invoke(const Name& name,const sarray<ArgsView>& ArgsList)
{
auto field = cls->GetField(name, true);
if (!field) {
if (cls->parent) {
return Parent().Invoke(name, ArgsList);
}
return false;
}
return field->Invoke(ArgsList);
}
bool ObjectView::Invoke(const Name& name, std::vector<ArgsView>& ArgsList)
{
auto field = cls->GetField(name, true);
if (!field) {
if (cls->parent) {
return Parent().Invoke(name, ArgsList);
}
return false;
}
return field->Invoke(ArgsList);
}
ObjectView ObjectView::Parent() {
return { ptr, cls ? cls->parent : nullptr };
}
}