126 lines
3.1 KiB
C++
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;
|
|
}
|
|
} |