zengine-old/engine/3rdparty/zlib/include/refl/detail/view.inl
2024-04-08 21:01:50 +08:00

126 lines
3.1 KiB
C++

#pragma once
#include "uclass.h"
namespace refl {
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*)(ptr + std::get<uint32_t>(cache->data));
}
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*)(ptr + std::get<uint32_t>(cache->data)) = 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;
}
template<typename ...Args>
bool ObjectView::Invoke(const Name& name, Args&&... args)
{
auto field = cls->GetField(name, true);
if (!field) {
if (cls->parent) {
return Parent().Invoke(name, args...);
}
return false;
}
constexpr int inputSize = sizeof...(Args);
auto params = field->type->GetParams();
int paramsSize = params.size();
bool member = field->flag & FIELD_MEMBER_FLAG;
if (inputSize + member >= paramsSize) {
return false;
}
std::vector<ArgsView> ArgsList;
ArgsList.reserve(paramsSize);
ArgsList.emplace_back();
if (member) {
ArgsList.emplace_back(ptr, &TypeInfo<const void*>::StaticClass);
}
(..., (ArgsList.emplace_back(args)));
for (int i = member + 1; i < paramsSize; i++) {
if (ArgsList[i].cls != params[i] && !ArgsList[i].ConvertTo(params[i])) {
return false;
}
}
field->type->Call(*field, ArgsList);
return true;
}
template<_ReflCheck_Ctor R, typename ...Args>
R ObjectView::Invoke(const Name& name, Args&&... args)
{
auto field = cls->GetField(name, true);
if (!field) {
if (cls->parent) {
return Parent().Invoke<R>(name, args...);
}
return {};
}
R ret{};
constexpr int inputSize = sizeof...(Args);
auto params = field->type->GetParams();
int paramsSize = params.size();
bool member = field->flag & FIELD_MEMBER_FLAG;
if (inputSize + member >= paramsSize) {
return false;
}
std::vector<ArgsView> ArgsList;
ArgsList.reserve(paramsSize);
ArgsList.emplace_back(ret);
if (member) {
ArgsList.emplace_back(ptr, &TypeInfo<const void*>::StaticClass);
}
(..., (ArgsList.emplace_back(args)));
for (int i = 0; i < paramsSize; i++) {
if (ArgsList[i].cls != params[i] && !ArgsList[i].ConvertTo(params[i])) {
return ret;
}
}
field->type->Call(*field, ArgsList);
return ret;
}
ObjectView ObjectView::Parent() {
return { ptr, cls ? cls->parent : nullptr };
}
/*平凡对象的转化要支持吗
* 比如同大小的安全转化
* 对象从小到大
* 对象从大到小
*/
bool ArgsView::ConvertTo(const UClass* toClass) {
//子类转父类
if (cls->IsChildOf(toClass)) {
cls = toClass;
return true;
}
return false;
}
}