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

152 lines
3.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "uclass.h"
#include "view.h"
#include "convert.h"
namespace refl {
using enum ClassFlag;
inline bool Any::Check(const UClass* toClass) const{
if (cls == toClass) {
return true;
}
auto p1 = cls->parent;
auto p2 = toClass->parent;
assert(p1 && p2);
//子类转父类
if (p1->IsChildOf(p2)) {
return true;
}
if (p1->flag & CLASS_TRIVIAL_FLAG && p2->flag & CLASS_TRIVIAL_FLAG && p1->size >= p2->size) {
return true;
}
return false;
}
inline constexpr int Any::Size()const
{
return cls->parent->size;
}
inline constexpr const UClass* Any::Parent()const
{
return cls->parent;
}
inline AnyArgs::AnyArgs(const sarray<Any>& args, const sarray<const UClass*>& params, void* memory)
: data(memory), num(args.size()), size(GetArgsSize(args, params))
{
assert(size > 0);
if (!memory) {
isMemoryOwner = true;
data = malloc(size);
}
Any* any = (Any*)data;
assert(any != nullptr);
char* pData = ((char*)data) + num * sizeof(Any);
auto uptr = params.at(params.size() - args.size());
for (auto& arg : args) {
any->cls = *uptr;
any->ptr = pData;
assert(Convert::Construct(*any, arg));
any++;
pData += (*uptr)->parent->size;
}
}
inline AnyArgs::~AnyArgs()
{
if (num == 0 || !data) {
return;
}
if (isMemoryOwner) {
Any* any = (Any*)data;
for (int i = 0; i < num; i++) {
any->cls->DestObject((void*)any->ptr);
any++;
}
free(data);
}
num = 0;
data = nullptr;
}
inline int AnyArgs::Size()
{
return size;
}
inline const sarray<Any> AnyArgs::ToSArray()
{
return sarray<Any>((Any*)data, num);
}
inline constexpr Offset AnyArgs::GetArgsSize(const sarray<Any>& args,const sarray<const UClass*>& params)
{ //这里空间换时间Any多占用了一个数据指针
if (args.size() == 0 || params.size() < args.size() + 1) {
return 0;
}
Offset offset = args.size() * sizeof(Any);
auto uptr = params.at(params.size() - args.size());
for (auto uend = params.back(); uptr < uend; uptr++) {
offset += (*uptr)->parent->size;//数据大小
}
return offset;
}
template<typename T>
inline bool AnyView::Get(const Name& name, T& t)
{
if (cache && cache->name == name) {
_cache_get: bool isChild = cache->type->IsChildOf<T>();
if (isChild) {
t = *(T*)((const char*)ptr + cache->data.member.offset);
}
return isChild;
}
auto field = cls->GetField(name, 0);
if (field) {
cache = field;
goto _cache_get;
}
if (cls->parent) {
return Parent().Get(name, t);
}
return false;
}
template<typename T>
inline bool AnyView::Set(const Name& name, const T& t)
{
if (cache && cache->name == name) {
_cache_set: bool isChild = cache->type->IsChildOf<T>();
if (isChild) {
*(T*)((const char*)ptr + cache->data.member.offset) = t;
}
return isChild;
}
auto field = cls->GetField(name, 0);
if (field) {
cache = field;
goto _cache_set;
}
if (cls->parent) {
return Parent().Set(name, t);
}
return false;
}
inline bool AnyView::Invoke(const Name& name,const sarray<Any>& ArgsList)
{
auto field = cls->GetField(name, 0);
if (!field) {
if (cls->parent) {
return Parent().Invoke(name, ArgsList);
}
return false;
}
return field->Invoke(ArgsList);
}
inline bool AnyView::Invoke(const Name& name, svector<Any>& ArgsList)
{
auto field = cls->GetField(name, 0);
if (!field) {
if (cls->parent) {
return Parent().Invoke(name, ArgsList);
}
return false;
}
return field->Invoke(ArgsList);
}
inline AnyView AnyView::Parent() {
return { ptr, cls ? cls->parent : nullptr };
}
}