support refl invoke return

This commit is contained in:
ouczbs 2024-04-09 22:26:33 +08:00
parent 1358747979
commit 361c6f917d
6 changed files with 114 additions and 30 deletions

View File

@ -12,13 +12,32 @@ namespace refl {
struct TypeInfoImpl; struct TypeInfoImpl;
template<typename T> template<typename T>
struct RealTypeImpl { struct real_type {
using type = std::remove_cv_t<std::remove_reference_t<T>>; using type = std::remove_cv_t<std::remove_reference_t<T>>;
}; };
template<typename T> template<typename T>
struct RealTypeImpl<T&> { struct real_type<T&> {
using type = std::remove_cv_t<T>*; using type = std::remove_cv_t<T>*;
}; };
template<typename T> template<typename T>
using TypeInfo = TypeInfoImpl<typename RealTypeImpl<T>::type>; using real_type_t = real_type<T>::type;
//转化为指针类型
template<typename T>
struct args_type {
using type = T;
};
template<typename T>
struct args_type<T&> {
using type = T;
};
template<typename T>
struct args_type<T*> {
using type = T;
};
template<typename T>
using args_type_t = args_type<std::remove_cv_t<T>>::type;
template<typename T>
using TypeInfo = TypeInfoImpl<real_type_t<T>>;
} }

View File

@ -21,6 +21,7 @@ namespace refl {
* 模板优化 * 模板优化
* 成员参数转化为const void* * 成员参数转化为const void*
* 引用参数转化为指针 * 引用参数转化为指针
* 返回引用转化为指针
*/ */
template<typename R, typename... Args> template<typename R, typename... Args>
class UMethod_Auto : public UClass { class UMethod_Auto : public UClass {
@ -44,7 +45,7 @@ namespace refl {
MethodType fptr = (MethodType)field.data.method; MethodType fptr = (MethodType)field.data.method;
auto param = ArgsList.rbegin(); auto param = ArgsList.rbegin();
auto ret = ArgsList.begin(); auto ret = ArgsList.begin();
if (ret->cls == &TypeInfo<R>::StaticClass) { if (ret->cls == &TypeInfo<R*>::StaticClass) {
*(R*)ret->val = fptr(param++->cast_to<Args>()...); *(R*)ret->val = fptr(param++->cast_to<Args>()...);
} }
else { else {
@ -55,11 +56,11 @@ namespace refl {
protected: protected:
constexpr void BuildUList() { constexpr void BuildUList() {
if constexpr (!std::is_same_v<R, void>) { if constexpr (!std::is_same_v<R, void>) {
UList[0] = &TypeInfo<R>::StaticClass; UList[0] = &TypeInfo<R*>::StaticClass;
} }
if constexpr (sizeof...(Args) > 0) { if constexpr (sizeof...(Args) > 0) {
auto ptr = &UList[1]; auto ptr = &UList[1];
(..., (*ptr = &TypeInfo<typename std::remove_pointer_t<Args>*>::StaticClass, ptr++)); (..., (*ptr = &TypeInfo<std::remove_pointer_t<Args>*>::StaticClass, ptr++));
} }
} }
public: public:

View File

@ -21,13 +21,13 @@ namespace refl {
template<typename ...Args> template<typename ...Args>
bool Invoke(const Name& name, Args&&... args); bool Invoke(const Name& name, Args&&... args);
template<_ReflCheck_Ctor R, typename ...Args> template<typename R, typename ...Args>
R Invoke(const Name& name, Args&&... args); R Invoke(const Name& name, Args&&... args);
ObjectView Parent(); ObjectView Parent();
}; };
//生命周期短,适用于传参,不建议保存数据 //生命周期短,适用于传参,不建议保存数据
//这里类型丢失了呀,存入的都是指针数据 //只能指向指针,引用=>指针,指针=>指针T => T*,T的类型丢失
struct ArgsView { struct ArgsView {
public: public:
const void* val; const void* val;
@ -36,13 +36,13 @@ namespace refl {
//右值=>右值压入栈caller入栈地址 //右值=>右值压入栈caller入栈地址
//左值=>caller变量地址 //左值=>caller变量地址
template<typename T> template<typename T>
ArgsView(T&& v): val(&v), cls(&TypeInfo<typename std::remove_reference_t<T>*>::StaticClass){ ArgsView(T&& v): val(&v), cls(&TypeInfo<args_type_t<T>*>::StaticClass){
if constexpr (std::is_same_v<std::remove_reference_t<T>, ArgsView>) { if constexpr (std::is_same_v<args_type_t<T>, ArgsView>) {
val = v.val; val = v.val;
cls = v.cls; cls = v.cls;
} }
} }
template<typename T> template<typename T>//参数 T* => T*
constexpr inline T cast_to() { constexpr inline T cast_to() {
if constexpr (std::is_pointer_v<T>) { if constexpr (std::is_pointer_v<T>) {
return (T)val; return (T)val;
@ -54,13 +54,26 @@ namespace refl {
return *(T*)val; return *(T*)val;
} }
} }
template<typename T>
T cast_ret() {
if constexpr (std::is_pointer_v<T>) {
return *(T*)val;
}
else if constexpr (std::is_reference_v<T>) {
using RT = std::remove_reference_t<T>;
return **(RT**)val;
}
else {
return *(T*)val;
}
}
bool ConvertTo(const UClass* toClass); bool ConvertTo(const UClass* toClass);
}; };
//存入的是真实的数据类型,type用于拷贝数据 //存入的是真实的数据类型,type用于拷贝数据
struct ArgsValue : public ArgsView { struct ArgsValue : public ArgsView {
const UClass* type; const UClass* type;
template<typename T> template<typename T>
ArgsValue(T&& t) : ArgsView(t), type(&TypeInfo<T>::StaticClass){} ArgsValue(T&& t) : ArgsView(t), type(&TypeInfo<args_type_t<T>>::StaticClass){}
}; };
struct ArgsValueList{ struct ArgsValueList{
void* data{ nullptr }; void* data{ nullptr };

View File

@ -89,38 +89,54 @@ namespace refl {
field->type->Call(*field, ArgsList); field->type->Call(*field, ArgsList);
return true; return true;
} }
template<_ReflCheck_Ctor R, typename ...Args> template<typename R, typename ...Args>
R ObjectView::Invoke(const Name& name, Args&&... args) R ObjectView::Invoke(const Name& name, Args&&... args)
{ {
//int x = 1; val = &x; *(int*)val = 2;//(x = 2) return *val; //val=>cast_to<int>
//int* x = nullptr; val = &x; *(int**)val = 0xff1234;//(x = 0xff1234) return *val;
real_type_t<R> data{};
ArgsView ret{ &data, &TypeInfo<real_type_t<R>*>::StaticClass };
auto field = cls->GetField(name, true); auto field = cls->GetField(name, true);
if (!field) { if (!field) {
if (cls->parent) { if (cls->parent) {
return Parent().Invoke<R>(name, args...); return Parent().Invoke<R>(name, args...);
} }
return {}; return ret.cast_ret<R>();
} }
R ret{};
constexpr int inputSize = sizeof...(Args); constexpr int inputSize = sizeof...(Args);
auto params = field->type->GetParams(); auto params = field->type->GetParams();
int paramsSize = params.size(); int paramsSize = params.size();
bool member = field->flag & FIELD_MEMBER_FLAG;
if (inputSize + member >= paramsSize) {
return false;
}
std::vector<ArgsView> ArgsList; std::vector<ArgsView> ArgsList;
ArgsList.reserve(paramsSize); ArgsList.reserve(paramsSize);
ArgsList.emplace_back(ret); ArgsList.emplace_back(ret);
if (member) {
if (field->flag & FIELD_MEMBER_FLAG) {
ArgsList.emplace_back(ptr, &TypeInfo<const void*>::StaticClass); ArgsList.emplace_back(ptr, &TypeInfo<const void*>::StaticClass);
} }
(..., (ArgsList.emplace_back(args))); (..., (ArgsList.emplace_back(args)));
int argsSize = ArgsList.size();
if (argsSize < paramsSize && field->flag & FIELD_METHOD_VALUE_FLAG) {
auto [argsPtr, valueSize] = field->value.method();
if (argsSize + valueSize >= paramsSize) {
for (int i = valueSize + argsSize - paramsSize; i < valueSize; i++) {
ArgsList.push_back(*(argsPtr + i));
}
argsSize = paramsSize;
}
}
if (argsSize < paramsSize) {
return ret.cast_ret<R>();
}
for (int i = 0; i < paramsSize; i++) { for (int i = 0; i < paramsSize; i++) {
if (ArgsList[i].cls != params[i] && !ArgsList[i].ConvertTo(params[i])) { if (ArgsList[i].cls != params[i] && !ArgsList[i].ConvertTo(params[i])) {
return ret; return ret.cast_ret<R>();
} }
} }
field->type->Call(*field, ArgsList); field->type->Call(*field, ArgsList);
return ret; return ret.cast_ret<R>();
} }
ObjectView ObjectView::Parent() { ObjectView ObjectView::Parent() {
return { ptr, cls ? cls->parent : nullptr }; return { ptr, cls ? cls->parent : nullptr };

View File

@ -22,7 +22,7 @@ namespace refl {
}; };
} }
FieldPtr::Data method = { *(Method*)&ptr }; FieldPtr::Data method = { *(Method*)&ptr };
return { name, &TypeInfo<R(*)(typename RealTypeImpl<Args>::type...)>::StaticClass, method, value, flag }; return { name, &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass, method, value, flag };
} }
template<typename T, typename R, typename ...Args> template<typename T, typename R, typename ...Args>
static FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name, const std::vector<ArgsValue>& args = {}) { static FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name, const std::vector<ArgsValue>& args = {}) {
@ -36,6 +36,6 @@ namespace refl {
}; };
} }
FieldPtr::Data method = { *(Method*)&ptr }; FieldPtr::Data method = { *(Method*)&ptr };
return { name, &TypeInfo<R(*)(const void*, typename RealTypeImpl<Args>::type...)>::StaticClass, method, value,flag }; return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass, method, value,flag };
} }
} }

View File

@ -21,9 +21,9 @@ struct vec3 : public vec3_parent {
x2 = x1 * x2; x2 = x1 * x2;
cout << x2 << "vec3::norm" << endl; cout << x2 << "vec3::norm" << endl;
} }
virtual float norm1(int x1 = 10) { virtual float norm1(float& x1) {
cout << x1 << "::norm1" << endl; cout << x1 << "::norm1" << endl;
return x * y *z * x1; return x1;
} }
static void norm2(int x1 = 10) { static void norm2(int x1 = 10) {
cout << x1 << "::norm2" << endl; cout << x1 << "::norm2" << endl;
@ -41,21 +41,56 @@ struct vec3 : public vec3_parent {
MakeMemberField(&vec3::y, "y"), MakeMemberField(&vec3::y, "y"),
MakeMemberField(&vec3::z, "z"), MakeMemberField(&vec3::z, "z"),
MakeMethodField(&vec3::norm, "norm", {8, 9}), MakeMethodField(&vec3::norm, "norm", {8, 9}),
MakeMethodField(&vec3::norm1, "norm1",{2}) MakeMethodField(&vec3::norm1, "norm1",{(float)2.0})
}; };
} }
}; };
int main() { int main() {
{
//T = > T*
int x = 1;
auto val = &x;
//T* = > T
//*val;
//x = 2;
*val = 2;
}
{
//T* = > T*
int x = 1, y = 2;
int* px = &x;
auto val = px;
//T* => T*
//val;
//px = &y;//做不到哈
val = &y;
}
{
//T* => T**
int x = 1, y = 2;
int* px = &x;
auto val = &px;
//T** = > T*;
//*val;
//px = &y;
*val = &y;
}
auto cls = &TypeInfo<vec3>::StaticClass; auto cls = &TypeInfo<vec3>::StaticClass;
int x = 2, y = 3; int x = 2, y = 3;
int* q1;
void* q2 = &q1;
*(int**)q2 = &x;
ArgsView a(&y);
ArgsView b(x);
ArgsView c(&q1);
auto ov = cls->New(); auto ov = cls->New();
ov.Invoke("norm", x); ov.Invoke("norm", x);
ov.Invoke("norm", x); ov.Invoke("norm", x);
ov.Invoke("norm", x, y); ov.Invoke("norm", x, y);
ov.Invoke("norm1", y); auto f = ov.Invoke<float>("norm1");
vec3* v = (vec3*)ov.ptr; vec3* v = (vec3*)ov.ptr;
v->norm1(y); ov.Invoke("norm1", (float)y);
ov.Invoke("norm1", y);
delete v; delete v;
cout << "hello world\n"; cout << "hello world\n";
} }