zengine-old/engine/3rdparty/zlib/include/refl/detail/view.inl

146 lines
3.2 KiB
Plaintext
Raw Normal View History

2024-04-08 21:01:50 +08:00
#pragma once
#include "uclass.h"
2024-04-11 10:13:15 +08:00
#include "view.h"
2024-04-08 21:01:50 +08:00
namespace refl {
2024-04-11 10:13:15 +08:00
/*平凡对象的转化要支持吗
* 比如同大小的安全转化
* 对象从小到大
* 对象从大到小
*/
2024-04-15 19:53:39 +08:00
using enum ClassFlag;
2024-04-19 22:02:27 +08:00
Any* Any::ConvertTo(const UClass* toClass) {
if (cls == toClass) {
return this;
}
2024-04-11 10:13:15 +08:00
//子类转父类
if (cls->IsChildOf(toClass)) {
cls = toClass;
2024-04-19 22:02:27 +08:00
return this;
2024-04-11 10:13:15 +08:00
}
2024-04-15 19:53:39 +08:00
if (cls->flag & CLASS_TRIVIAL_FLAG && toClass->flag & CLASS_TRIVIAL_FLAG) {
cls = toClass;
2024-04-19 22:02:27 +08:00
return this;
2024-04-15 19:53:39 +08:00
}
2024-04-19 22:02:27 +08:00
return nullptr;
2024-04-11 10:13:15 +08:00
}
2024-04-19 22:02:27 +08:00
AnyValueList::AnyValueList(const sarray<AnyValue>& args, void* memory)
: data(memory), num(args.size())
2024-04-14 22:45:08 +08:00
{
if (!memory) {
isMemoryOwner = true;
data = malloc(GetArgsSize(args));
2024-04-11 10:13:15 +08:00
}
2024-04-19 22:02:27 +08:00
Any* any = (Any*)data;
assert(any != nullptr);
char* pData = ((char*)data) + num * sizeof(Any);
2024-04-11 10:13:15 +08:00
for (auto& arg : args) {
arg.type->InitObject(pData);
2024-04-19 22:02:27 +08:00
arg.type->CopyObject(pData, arg.ptr);
any->ptr = pData;
any->cls = arg.cls;
any++;
2024-04-16 16:17:13 +08:00
pData += arg.type->size;
2024-04-11 10:13:15 +08:00
}
}
2024-04-19 22:02:27 +08:00
inline AnyValueList::~AnyValueList()
2024-04-11 10:13:15 +08:00
{
if (num == 0 || !data) {
return;
}
2024-04-19 22:02:27 +08:00
Any* ptr = (Any*)data;
2024-04-11 10:13:15 +08:00
for (int i = 0; i < num; i++) {
2024-04-19 22:02:27 +08:00
ptr->cls->DestObject((void*)ptr->ptr);
ptr++;
2024-04-11 10:13:15 +08:00
}
2024-04-14 22:45:08 +08:00
if (isMemoryOwner) {
free(data);
}
2024-04-11 10:13:15 +08:00
num = 0;
data = nullptr;
}
2024-04-19 22:02:27 +08:00
inline void AnyValueList::ConvertArgs(sarray<const UClass*> params)
{
Any* ptr = (Any*)data;
int first = params.size() - num;
for (int i = 0; i < num; i++, ptr++) {
ptr->ConvertTo(*params.at(first + i));
}
}
inline const sarray<Any> AnyValueList::ToSArray()
{
return sarray<Any>((Any*)data, num);
}
inline constexpr int AnyValueList::GetArgsSize(const sarray<AnyValue>& args)
2024-04-14 22:45:08 +08:00
{
2024-04-19 22:02:27 +08:00
int size = args.size() * sizeof(Any);
2024-04-14 22:45:08 +08:00
for (auto& arg : args) {
size += arg.type->size;
}
return size;
}
2024-04-08 21:01:50 +08:00
template<typename T>
2024-04-19 22:02:27 +08:00
inline bool AnyView::Get(const Name& name, T& t)
2024-04-08 21:01:50 +08:00
{
if (cache && cache->name == name) {
_cache_get: bool isChild = cache->type->IsChildOf<T>(true);
if (isChild) {
2024-04-15 19:53:39 +08:00
t = *(T*)((const char*)ptr + cache->data.offset);
2024-04-08 21:01:50 +08:00
}
return isChild;
}
2024-04-16 16:17:13 +08:00
auto field = cls->GetField(name, 0);
2024-04-08 21:01:50 +08:00
if (field) {
cache = field;
goto _cache_get;
}
if (cls->parent) {
return Parent().Get(name, t);
}
return false;
}
template<typename T>
2024-04-19 22:02:27 +08:00
inline bool AnyView::Set(const Name& name, const T& t)
2024-04-08 21:01:50 +08:00
{
if (cache && cache->name == name) {
_cache_set: bool isChild = cache->type->IsChildOf<T>(true);
if (isChild) {
2024-04-15 19:53:39 +08:00
*(T*)((const char*)ptr + cache->data.offset) = t;
2024-04-08 21:01:50 +08:00
}
return isChild;
}
2024-04-16 16:17:13 +08:00
auto field = cls->GetField(name, 0);
2024-04-08 21:01:50 +08:00
if (field) {
cache = field;
goto _cache_set;
}
if (cls->parent) {
return Parent().Set(name, t);
}
return false;
}
2024-04-19 22:02:27 +08:00
bool AnyView::Invoke(const Name& name,const sarray<Any>& ArgsList)
2024-04-08 21:01:50 +08:00
{
2024-04-16 16:17:13 +08:00
auto field = cls->GetField(name, 0);
2024-04-08 21:01:50 +08:00
if (!field) {
if (cls->parent) {
2024-04-11 10:13:15 +08:00
return Parent().Invoke(name, ArgsList);
2024-04-09 16:31:09 +08:00
}
return false;
}
2024-04-11 10:13:15 +08:00
return field->Invoke(ArgsList);
2024-04-08 21:01:50 +08:00
}
2024-04-19 22:02:27 +08:00
bool AnyView::Invoke(const Name& name, svector<Any>& ArgsList)
2024-04-08 21:01:50 +08:00
{
2024-04-16 16:17:13 +08:00
auto field = cls->GetField(name, 0);
2024-04-08 21:01:50 +08:00
if (!field) {
if (cls->parent) {
2024-04-11 10:13:15 +08:00
return Parent().Invoke(name, ArgsList);
2024-04-08 21:01:50 +08:00
}
2024-04-11 10:13:15 +08:00
return false;
2024-04-08 21:01:50 +08:00
}
2024-04-11 10:13:15 +08:00
return field->Invoke(ArgsList);
2024-04-08 21:01:50 +08:00
}
2024-04-19 22:02:27 +08:00
AnyView AnyView::Parent() {
2024-04-08 21:01:50 +08:00
return { ptr, cls ? cls->parent : nullptr };
}
}