129 lines
2.9 KiB
C++
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 };
|
|
}
|
|
} |