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

277 lines
6.7 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-25 21:45:41 +08:00
#include "convert.h"
2024-04-08 21:01:50 +08:00
namespace refl {
2024-04-15 19:53:39 +08:00
using enum ClassFlag;
inline bool Any::Check(const UClass* toClass) const{
2024-04-19 22:02:27 +08:00
if (cls == toClass) {
2024-04-25 21:45:41 +08:00
return true;
2024-04-19 22:02:27 +08:00
}
2024-06-14 22:24:52 +08:00
if (!cls) {
return false;
}
return cls->IsChildOf(toClass);
2024-04-25 21:45:41 +08:00
}
inline constexpr int Any::Size()const
{
2024-06-14 22:24:52 +08:00
return cls->size;
2024-04-11 10:13:15 +08:00
}
2024-04-25 21:45:41 +08:00
inline constexpr const UClass* Any::Parent()const
2024-04-14 22:45:08 +08:00
{
2024-04-25 21:45:41 +08:00
return cls->parent;
}
2024-06-14 22:24:52 +08:00
inline Any Any::Member(const FieldPtr& field)const
{
if (field.flag & FIELD_MEMBER_FLAG) {
return { (const char*)ptr + field.data.member.offset, field.type };
}
return {};
}
inline Any Any::Member(int i) const
{
if (cls->flag & CLASS_ARRAY_FLAG) {
int offset = i * cls->parent->size;
if(offset < cls->size)
return { (const char*)ptr + offset, cls->parent };
}
return Any();
}
inline int Any::ArraySize()const
{
if (cls->flag & CLASS_ARRAY_FLAG) {
return cls->size / cls->parent->size;
}
return 0;
}
inline bool Any::IsArray() const
{
return cls->flag & CLASS_ARRAY_FLAG;
}
inline bool Any::IsObject() const
{
return !(cls->flag & CLASS_ARRAY_FLAG) && !(cls->flag & CLASS_POINTER_FLAG);
}
2024-06-24 00:26:52 +08:00
inline bool Any::IsContainer() const
{
return cls->flag & CLASS_CONTAINER_FLAG;
}
inline bool Any::IsSequence() const
{
return cls->flag & CLASS_SEQUENCE_FLAG;
}
inline bool Any::IsMap() const
{
return cls->flag & CLASS_MAP_FLAG;
}
2024-06-14 22:24:52 +08:00
inline bool Any::Construct(const sarray<Any>& ArgsList) const
{
2024-06-24 00:26:52 +08:00
return cls->Construct((void*)ptr, ArgsList);
}
inline void Any::Destruct() const
{
cls->Destruct((void*)ptr);
2024-06-14 22:24:52 +08:00
}
inline AnyArgs::AnyArgs(const sarray<Any>& args, const sarray<const UClass*>& params, void* memory)
2024-04-25 21:45:41 +08:00
: data(memory), num(args.size()), size(GetArgsSize(args, params))
{
assert(size > 0);
2024-04-14 22:45:08 +08:00
if (!memory) {
isMemoryOwner = true;
2024-04-25 21:45:41 +08:00
data = malloc(size);
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-25 21:45:41 +08:00
auto uptr = params.at(params.size() - args.size());
2024-04-11 10:13:15 +08:00
for (auto& arg : args) {
2024-04-25 21:45:41 +08:00
any->cls = *uptr;
2024-04-19 22:02:27 +08:00
any->ptr = pData;
2024-04-25 21:45:41 +08:00
assert(Convert::Construct(*any, arg));
2024-04-19 22:02:27 +08:00
any++;
2024-06-14 22:24:52 +08:00
pData += (*uptr)->size;
2024-04-11 10:13:15 +08:00
}
}
2024-04-25 21:45:41 +08:00
inline AnyArgs::~AnyArgs()
2024-04-11 10:13:15 +08:00
{
if (num == 0 || !data) {
return;
}
2024-04-14 22:45:08 +08:00
if (isMemoryOwner) {
2024-04-25 21:45:41 +08:00
Any* any = (Any*)data;
for (int i = 0; i < num; i++) {
2024-06-24 00:26:52 +08:00
any->cls->Destruct((void*)any->ptr);
2024-04-25 21:45:41 +08:00
any++;
}
2024-04-14 22:45:08 +08:00
free(data);
}
2024-04-11 10:13:15 +08:00
num = 0;
data = nullptr;
}
2024-04-25 21:45:41 +08:00
inline int AnyArgs::Size()
2024-04-19 22:02:27 +08:00
{
2024-04-25 21:45:41 +08:00
return size;
2024-04-19 22:02:27 +08:00
}
2024-04-25 21:45:41 +08:00
inline const sarray<Any> AnyArgs::ToSArray()
2024-04-19 22:02:27 +08:00
{
return sarray<Any>((Any*)data, num);
}
2024-04-25 21:45:41 +08:00
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;
2024-04-14 22:45:08 +08:00
}
2024-04-25 21:45:41 +08:00
Offset offset = args.size() * sizeof(Any);
auto uptr = params.at(params.size() - args.size());
for (auto uend = params.back(); uptr < uend; uptr++) {
2024-06-14 22:24:52 +08:00
offset += (*uptr)->size;//数据大小
2024-04-25 21:45:41 +08:00
}
return offset;
2024-04-14 22:45:08 +08:00
}
2024-06-25 20:26:46 +08:00
template<typename ...Args>
inline consteval Offset AnyArgs::GetArgsSize(const sarray<Any>& args)
{
constexpr int N = sizeof...(Args);
if (args.size() == 0 || N < args.size() + 1) {
return 0;
}
int first = N - args.size();
Offset offset = args.size() * sizeof(Any);
offset += fetch_tuple_size<std::tuple<Args...>>(std::index_sequence_for<Args...>{}, first);
return 0;
}
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) {
2024-04-25 21:45:41 +08:00
_cache_get: bool isChild = cache->type->IsChildOf<T>();
2024-04-08 21:01:50 +08:00
if (isChild) {
2024-04-25 21:45:41 +08:00
t = *(T*)((const char*)ptr + cache->data.member.offset);
2024-04-08 21:01:50 +08:00
}
return isChild;
}
2024-06-12 22:07:45 +08:00
auto& fieldList = cls->GetFields(EFieldFind::FIND_MEMBER, name);
if (fieldList.valid()) {
cache = fieldList.front();
2024-04-08 21:01:50 +08:00
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) {
2024-04-25 21:45:41 +08:00
_cache_set: bool isChild = cache->type->IsChildOf<T>();
2024-04-08 21:01:50 +08:00
if (isChild) {
2024-04-25 21:45:41 +08:00
*(T*)((const char*)ptr + cache->data.member.offset) = t;
2024-04-08 21:01:50 +08:00
}
return isChild;
}
2024-06-12 22:07:45 +08:00
auto& fieldList = cls->GetFields(EFieldFind::FIND_MEMBER, name);
if (fieldList.valid()) {
cache = fieldList.front();
2024-04-08 21:01:50 +08:00
goto _cache_set;
}
if (cls->parent) {
return Parent().Set(name, t);
}
return false;
}
inline bool AnyView::Invoke(const Name& name,const sarray<Any>& ArgsList)
2024-04-08 21:01:50 +08:00
{
2024-06-12 22:07:45 +08:00
auto& fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name);
if (fieldList.empty()) {
2024-04-08 21:01:50 +08:00
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-06-12 22:07:45 +08:00
return fieldList[0]->Invoke(ArgsList);
2024-04-08 21:01:50 +08:00
}
inline bool AnyView::Invoke(const Name& name, svector<Any>& ArgsList)
2024-04-08 21:01:50 +08:00
{
2024-06-12 22:07:45 +08:00
auto fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name);
if (fieldList.empty()) {
2024-04-08 21:01:50 +08:00
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-06-12 22:07:45 +08:00
return fieldList[0]->Invoke(ArgsList);
}
inline bool AnyView::Invokes(const Name& name, const sarray<Any>& ArgsList)
{
auto fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name);
if (fieldList.empty()) {
if (cls->parent) {
return Parent().Invoke(name, ArgsList);
}
return false;
}
if(fieldList.size() == 1)
return fieldList[0]->Invoke(ArgsList);
for (auto& field : fieldList) {
if (field.Invokes(ArgsList)) {
return true;
}
}
return false;
}
inline bool AnyView::Invokes(const Name& name, svector<Any>& ArgsList)
{
auto fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name);
if (fieldList.empty()) {
if (cls->parent) {
return Parent().Invoke(name, ArgsList);
}
return false;
}
if (fieldList.size() == 1)
return fieldList[0]->Invoke(ArgsList);
for (auto& field : fieldList) {
if (field.Invokes(ArgsList)) {
return true;
}
}
return false;
2024-04-08 21:01:50 +08:00
}
inline AnyView AnyView::Parent() {
2024-04-08 21:01:50 +08:00
return { ptr, cls ? cls->parent : nullptr };
}
2024-06-24 00:26:52 +08:00
inline bool UClass::Construct(void* ptr, const sarray<Any>& ArgsList) const
2024-06-14 22:24:52 +08:00
{
2024-06-24 00:26:52 +08:00
if (vtable.Construct) {
if (vtable.Construct(ptr, this, ArgsList)) {
2024-06-14 22:24:52 +08:00
return true;
}
auto& fieldList = GetFields(EFieldFind::FIND_CTOR, FName("Ctor"));
if (fieldList.empty()) {
return false;
}
std::array<Any, 10> ArgsArray = { Any{} , Any{ptr} };
int i = 2;
for (auto& arg : ArgsList) {
ArgsArray[i++] = arg;
}
sarray<Any> FieldArgs(&ArgsArray[0], 2 + ArgsList.size());
if (fieldList.size() == 1) {
return fieldList[0]->Invoke(FieldArgs);
}
for (auto& field : fieldList) {
if (field.Invokes(FieldArgs)) {
return true;
}
}
return false;
}
if (ArgsList.valid() && ArgsList[0]->Check(this)) {
memcpy(ptr, ArgsList[0]->ptr, size);
return true;
}
memset(ptr, 0, size);
return true;
}
2024-04-08 21:01:50 +08:00
}