#pragma once #include "uclass.h" namespace refl { template inline bool ObjectView::Get(const Name& name, T& t) { if (cache && cache->name == name) { _cache_get: bool isChild = cache->type->IsChildOf(true); if (isChild) { t = *(T*)(ptr + std::get(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 inline bool ObjectView::Set(const Name& name, const T& t) { if (cache && cache->name == name) { _cache_set: bool isChild = cache->type->IsChildOf(true); if (isChild) { *(T*)(ptr + std::get(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 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 ArgsList; ArgsList.reserve(paramsSize); ArgsList.emplace_back(); if (member) { ArgsList.emplace_back(ptr, &TypeInfo::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(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 ArgsList; ArgsList.reserve(paramsSize); ArgsList.emplace_back(ret); if (member) { ArgsList.emplace_back(ptr, &TypeInfo::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; } }