support refl invoke return
This commit is contained in:
parent
1358747979
commit
361c6f917d
25
engine/3rdparty/zlib/include/refl/detail/type.h
vendored
25
engine/3rdparty/zlib/include/refl/detail/type.h
vendored
@ -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>>;
|
||||||
}
|
}
|
||||||
@ -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:
|
||||||
|
|||||||
25
engine/3rdparty/zlib/include/refl/detail/view.h
vendored
25
engine/3rdparty/zlib/include/refl/detail/view.h
vendored
@ -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 };
|
||||||
|
|||||||
@ -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 };
|
||||||
|
|||||||
4
engine/3rdparty/zlib/include/refl/refl.h
vendored
4
engine/3rdparty/zlib/include/refl/refl.h
vendored
@ -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 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
47
engine/3rdparty/zlib/test/refl_01.cpp
vendored
47
engine/3rdparty/zlib/test/refl_01.cpp
vendored
@ -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";
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user