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;
|
2024-04-26 16:57:48 +08:00
|
|
|
|
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-04-25 21:45:41 +08:00
|
|
|
|
auto p1 = cls->parent;
|
|
|
|
|
|
auto p2 = toClass->parent;
|
|
|
|
|
|
assert(p1 && p2);
|
2024-04-11 10:13:15 +08:00
|
|
|
|
//子类转父类
|
2024-06-12 22:07:45 +08:00
|
|
|
|
return p1->IsChildOf(p2);
|
2024-04-25 21:45:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
inline constexpr int Any::Size()const
|
|
|
|
|
|
{
|
|
|
|
|
|
return cls->parent->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-04-26 16:57:48 +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-04-25 21:45:41 +08:00
|
|
|
|
pData += (*uptr)->parent->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++) {
|
|
|
|
|
|
any->cls->DestObject((void*)any->ptr);
|
|
|
|
|
|
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++) {
|
|
|
|
|
|
offset += (*uptr)->parent->size;//数据大小
|
|
|
|
|
|
}
|
|
|
|
|
|
return offset;
|
2024-04-14 22:45:08 +08:00
|
|
|
|
}
|
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;
|
|
|
|
|
|
}
|
2024-04-26 16:57:48 +08:00
|
|
|
|
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
|
|
|
|
}
|
2024-04-26 16:57:48 +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
|
|
|
|
}
|
2024-04-26 16:57:48 +08:00
|
|
|
|
inline AnyView AnyView::Parent() {
|
2024-04-08 21:01:50 +08:00
|
|
|
|
return { ptr, cls ? cls->parent : nullptr };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|