update refl invoke
This commit is contained in:
parent
326f9b10be
commit
c6ca4f12ec
6
engine/3rdparty/zlib/include/refl/field.h
vendored
6
engine/3rdparty/zlib/include/refl/field.h
vendored
@ -6,8 +6,8 @@ using Ubpa::Name;
|
||||
using Ubpa::type_name;
|
||||
namespace refl {
|
||||
class UClass;
|
||||
using Method = void(*)(...);
|
||||
using Offset = uint32_t;
|
||||
using Method = void(*)(...);
|
||||
enum FieldFlag:uint32_t {
|
||||
FIELD_NONE_FLAG = 0,
|
||||
FIELD_MEMBER_FLAG = 1 << 0,
|
||||
@ -16,8 +16,8 @@ namespace refl {
|
||||
};
|
||||
struct FieldPtr {
|
||||
using Data = std::variant<
|
||||
Offset, // offset
|
||||
Method // method
|
||||
Offset, // offset
|
||||
Method // method
|
||||
>;
|
||||
Name name;
|
||||
const UClass* type;
|
||||
|
||||
193
engine/3rdparty/zlib/include/refl/uclass.h
vendored
193
engine/3rdparty/zlib/include/refl/uclass.h
vendored
@ -3,21 +3,16 @@
|
||||
#include "field.h"
|
||||
#include "view.h"
|
||||
namespace refl {
|
||||
enum ClassFlag :uint32_t {
|
||||
CLASS_NONE_FLAG = 0,
|
||||
CLASS_MEMBER_FLAG = 1 << 0,
|
||||
CLASS_ATTRIBUTE_FLAG = 1 << 1,
|
||||
CLASS_METHOD_FLAG = 1 << 2,
|
||||
};
|
||||
class UClass{
|
||||
using enum FieldFlag;
|
||||
public:
|
||||
Name name;
|
||||
uint32_t size;
|
||||
UClass* parent;
|
||||
//uint32_t flag;
|
||||
const UClass* parent;
|
||||
public:
|
||||
constexpr UClass(Name name, uint32_t size, UClass* parent = nullptr)
|
||||
:name(name),size(size), parent(parent){}
|
||||
constexpr UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr)
|
||||
:name(name), size(size), parent(parent){}
|
||||
ObjectView New(void* ptr = nullptr) const{
|
||||
if (ptr == nullptr) {
|
||||
ptr = malloc(size);
|
||||
@ -36,6 +31,16 @@ namespace refl {
|
||||
InitObject(ptr);
|
||||
return ptr;
|
||||
}
|
||||
bool IsChildOf(const UClass* cls) const {
|
||||
const UClass* _parent = parent;
|
||||
while (_parent != nullptr) {
|
||||
if (_parent == cls) {
|
||||
return true;
|
||||
}
|
||||
_parent = _parent->parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
template<typename T>
|
||||
bool IsChildOf(bool bthis = false) const {
|
||||
constexpr UClass* cls = &TypeInfo<T>::StaticClass;
|
||||
@ -56,53 +61,40 @@ namespace refl {
|
||||
virtual void InitObject(void* ptr)const {
|
||||
memset(ptr, 0, size);
|
||||
}
|
||||
virtual const FieldPtr* GetField(const Name& name)const {
|
||||
virtual const FieldPtr* GetField(const Name& name, bool isMethod)const {
|
||||
return nullptr;
|
||||
}
|
||||
virtual std::vector<UClass*> GetParams() const {
|
||||
virtual std::vector<const UClass*> GetParams() const {
|
||||
return{};
|
||||
}
|
||||
virtual void Call(const FieldPtr& field, std::vector<ArgsView>& ArgsList)const{}
|
||||
virtual bool ConvertToValue(ArgsView& args)const{
|
||||
return false;
|
||||
}
|
||||
protected:
|
||||
template<typename T,Offset offset>
|
||||
FieldPtr MakeMemberField(Name name) {
|
||||
template<Offset offset>
|
||||
FieldPtr MakeMemberField(Name name, const UClass* cls) {
|
||||
FieldPtr::Data member = { offset };
|
||||
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
|
||||
return { name, &TypeInfo<T>::StaticClass, {member}, flag };
|
||||
return { name, cls, {member}, flag };
|
||||
}
|
||||
template<typename R, typename ...Args>
|
||||
FieldPtr MakeMethodField(R (* ptr)(Args...), Name name) {
|
||||
FieldPtr::Data member = { *(Method*)&ptr};
|
||||
constexpr uint32_t flag = FIELD_METHOD_FLAG;
|
||||
return { name, &TypeInfo<R(*)(Args...)>::StaticClass, {member},flag };
|
||||
return { name, &TypeInfo<R(*)(typename RealTypeImpl<Args>::type...)>::StaticClass, {member},flag };
|
||||
}
|
||||
template<typename T, typename R, typename ...Args>
|
||||
FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name) {
|
||||
FieldPtr::Data member = { *(Method*)&ptr };
|
||||
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
|
||||
return { name, &TypeInfo<R(*)(const void*, Args...)>::StaticClass, {member},flag };
|
||||
return { name, &TypeInfo<R(*)(const void*, typename RealTypeImpl<Args>::type...)>::StaticClass, {member},flag };
|
||||
}
|
||||
};
|
||||
template<_ReflCheck_Ctor T>
|
||||
class UClass_Auto : public UClass{
|
||||
public:
|
||||
using UClass::UClass;
|
||||
bool ConvertToValue(ArgsView& args)const override {
|
||||
if constexpr (std::is_same<T, int*>::value) {
|
||||
using RawT = std::remove_pointer_t<T>;
|
||||
args.val = (void*)*(RawT*)args.val;
|
||||
args.cls = &TypeInfo<RawT>::StaticClass;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected:
|
||||
void InitObject(void* ptr)const override {
|
||||
constexpr bool is_shallow_copyable = std::is_trivially_copyable<T>::value;
|
||||
if constexpr (!is_shallow_copyable){
|
||||
if constexpr (!std::is_trivially_copyable_v<T>){
|
||||
T obj{};
|
||||
std::construct_at((T*)ptr, obj);
|
||||
}
|
||||
@ -111,7 +103,7 @@ namespace refl {
|
||||
}
|
||||
}
|
||||
public:
|
||||
static UClass_Auto<T> BuildClass() {
|
||||
constexpr static UClass_Auto<T> BuildClass() {
|
||||
auto cls = UClass_Auto<T>(type_name<T>().View(), sizeof(T));
|
||||
return cls;
|
||||
}
|
||||
@ -120,41 +112,52 @@ namespace refl {
|
||||
template<_ReflCheck_Ctor_NoUClass T>
|
||||
struct TypeInfoImpl<T>{
|
||||
using UClass = UClass_Auto<T>;
|
||||
inline static UClass StaticClass = UClass::BuildClass();
|
||||
inline constexpr static UClass StaticClass = UClass::BuildClass();
|
||||
};
|
||||
|
||||
/*
|
||||
* 模板优化
|
||||
* 成员参数转化为const void*
|
||||
* 引用参数转化为指针
|
||||
*/
|
||||
template<typename R, typename... Args>
|
||||
class UMethod_Auto : public UClass {
|
||||
using UClass::UClass;
|
||||
using MethodType = R(*)(Args...);
|
||||
public:
|
||||
std::array<UClass*, sizeof...(Args) + 1> UList;
|
||||
std::array<const UClass*, sizeof...(Args) + 1> UList{};
|
||||
|
||||
std::vector<UClass*> GetParams()const override {
|
||||
std::vector<const UClass*> GetParams()const override {
|
||||
return { UList.data(), UList.data() + UList.size()};
|
||||
}
|
||||
void Call(const FieldPtr& field, std::vector<ArgsView>& ArgsList)const override {
|
||||
Call<Args...>(field, ArgsList);
|
||||
}
|
||||
protected:
|
||||
template<typename... Args>
|
||||
inline void Call(const FieldPtr& field, std::vector<ArgsView>& ArgsList)const {
|
||||
MethodType fptr = (MethodType)std::get<Method>(field.data);
|
||||
int Indices = 0;
|
||||
//fptr(ArgsList[1].val, Indices, Indices);
|
||||
//fptr(std::forward<Args>((Args)Indices), ...);
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
if constexpr (std::is_same_v<R, void>) {
|
||||
MethodType fptr = (MethodType)std::get<Method>(field.data);
|
||||
auto param = ArgsList.rbegin();
|
||||
fptr(param++->cast_to<Args>()...);
|
||||
}
|
||||
else {
|
||||
MethodType fptr = (MethodType)std::get<Method>(field.data);
|
||||
auto param = ArgsList.rbegin();
|
||||
auto ret = ArgsList.begin();
|
||||
if (ret->cls == &TypeInfo<R>::StaticClass) {
|
||||
*(R*)ret->val = fptr(param++->cast_to<Args>()...);
|
||||
}
|
||||
else {
|
||||
fptr(param++->cast_to<Args>()...);
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
//为了简化判断,cls 对象 统统指向 T*
|
||||
static UMethod_Auto<R,Args...> BuildClass() {
|
||||
auto cls = UMethod_Auto<R, Args...>(type_name<MethodType>().View(), sizeof(MethodType));
|
||||
if constexpr(!std::is_same<R, void>::value) {
|
||||
UMethod_Auto<R,Args...> cls(type_name<MethodType>().View(), sizeof(MethodType));
|
||||
if constexpr(!std::is_same_v<R, void>) {
|
||||
cls.UList[0] = &TypeInfo<R>::StaticClass;
|
||||
}
|
||||
if (sizeof...(Args) > 0) {
|
||||
auto ptr = &cls.UList[1];
|
||||
(...,(*ptr = &TypeInfo<Args>::StaticClass, ptr++));
|
||||
(...,(*ptr = &TypeInfo<typename std::remove_pointer_t<Args>*>::StaticClass, ptr++));
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
@ -175,11 +178,14 @@ _cache_get: bool isChild = cache->type->IsChildOf<T>(true);
|
||||
}
|
||||
return isChild;
|
||||
}
|
||||
auto field = cls->GetField(name);
|
||||
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>
|
||||
@ -193,18 +199,24 @@ _cache_set: bool isChild = cache->type->IsChildOf<T>(true);
|
||||
}
|
||||
return isChild;
|
||||
}
|
||||
auto field = cls->GetField(name);
|
||||
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);
|
||||
auto field = cls->GetField(name, true);
|
||||
if (!field) {
|
||||
if (cls->parent) {
|
||||
return Parent().Invoke(name, args...);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
constexpr int inputSize = sizeof...(Args);
|
||||
@ -218,41 +230,66 @@ _cache_set: bool isChild = cache->type->IsChildOf<T>(true);
|
||||
ArgsList.reserve(paramsSize);
|
||||
ArgsList.emplace_back();
|
||||
if (member) {
|
||||
ArgsList.emplace_back(ptr, cls );
|
||||
ArgsList.emplace_back(ptr, &TypeInfo<const void*>::StaticClass);
|
||||
}
|
||||
(..., (ArgsList.emplace_back((void*)&args, &TypeInfo<Args>::StaticClass)));
|
||||
(..., (ArgsList.emplace_back(args)));
|
||||
for (int i = member + 1; i < paramsSize; i++) {
|
||||
if (ArgsList[i].cls != params[i]) {
|
||||
ArgsList[i].ConvertTo(params[i]);
|
||||
if (!ArgsList[i].ConvertTo(params[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
field->type->Call(*field, ArgsList);
|
||||
return false;
|
||||
}
|
||||
template<typename R, typename ...Args>
|
||||
inline bool ObjectView::InvokeRet(const Name& name, R& ret, Args&& ...args)
|
||||
{
|
||||
auto field = cls->GetField(name);
|
||||
if (!field) {
|
||||
return false;
|
||||
}
|
||||
if (field->flag & FIELD_MEMBER_FLAG) {
|
||||
using MemberMethodType = R(*)(const void*, Args...);
|
||||
MemberMethodType fptr = (MemberMethodType)std::get<Method>(field->data);
|
||||
ret = fptr(ptr, std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
using MethodType = R(*)(Args...);
|
||||
MethodType fptr = (MethodType)std::get<Method>(field->data);
|
||||
ret = fptr(std::forward<Args>(args)...);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool ArgsView::ConvertTo(UClass* toClass) {
|
||||
ArgsView args{val};
|
||||
cls->ConvertToValue(args);
|
||||
if (args.cls == toClass) {
|
||||
*this = args;
|
||||
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]) {
|
||||
if (!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;
|
||||
|
||||
25
engine/3rdparty/zlib/include/refl/view.h
vendored
25
engine/3rdparty/zlib/include/refl/view.h
vendored
@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "type.h"
|
||||
namespace refl {
|
||||
class UClass;
|
||||
class FieldPtr;
|
||||
@ -19,14 +21,31 @@ namespace refl {
|
||||
template<typename ...Args>
|
||||
bool Invoke(const Name& name, Args&&... args);
|
||||
|
||||
template<typename R, typename ...Args>
|
||||
bool InvokeRet(const Name& name,R& ret, Args&&... args);
|
||||
template<_ReflCheck_Ctor R, typename ...Args>
|
||||
R Invoke(const Name& name, Args&&... args);
|
||||
|
||||
ObjectView Parent();
|
||||
};
|
||||
class ArgsView {
|
||||
public:
|
||||
const void* val;
|
||||
const UClass* cls;
|
||||
ArgsView(const void* val = nullptr, const UClass* cls = nullptr) : val(val), cls(cls) {}
|
||||
bool ConvertTo(UClass* toClass);
|
||||
template<typename T>
|
||||
ArgsView(T&& v): val(&v), cls(&TypeInfo<typename std::remove_reference_t<T>*>::StaticClass){}
|
||||
|
||||
template<typename T>
|
||||
inline T cast_to() {
|
||||
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);
|
||||
};
|
||||
}
|
||||
78
engine/3rdparty/zlib/test/refl_01.cpp
vendored
78
engine/3rdparty/zlib/test/refl_01.cpp
vendored
@ -7,7 +7,10 @@
|
||||
using namespace std;
|
||||
using namespace refl;
|
||||
struct vec3_parent {
|
||||
|
||||
virtual void norm(int x1, int& x2) {
|
||||
x2 = x1 * x2;
|
||||
cout << x2 << "vec3_parent::norm" << endl;
|
||||
}
|
||||
};
|
||||
struct vec3 : public vec3_parent {
|
||||
using UClass = class vec3_UClass;
|
||||
@ -15,10 +18,6 @@ struct vec3 : public vec3_parent {
|
||||
float y = 2;
|
||||
float z = 3;
|
||||
string name{ "hellohellohellohellohellohello" };
|
||||
void norm(int x1, int& x2) {
|
||||
x2 = x1 * x * y * z * x2;
|
||||
cout << x2 << "::norm" << endl;
|
||||
}
|
||||
virtual float norm1(int x1 = 10) {
|
||||
cout << x1 << "::norm1" << endl;
|
||||
return x * y *z * x1;
|
||||
@ -34,11 +33,18 @@ struct vec3 : public vec3_parent {
|
||||
struct vec3_UClass : public UClass {
|
||||
public:
|
||||
array<FieldPtr,6> FList;
|
||||
int32_t AttrNum;
|
||||
using UClass::UClass;
|
||||
const FieldPtr* GetField(const Name& name)const override {
|
||||
for (auto& field : FList) {
|
||||
if (field.name == name) {
|
||||
return &field;
|
||||
const FieldPtr* GetField(const Name& name, bool isMethod)const override {
|
||||
// 指定开始位置的迭代器
|
||||
auto start = FList.begin();
|
||||
if (isMethod) {
|
||||
start += AttrNum;
|
||||
}
|
||||
auto end = FList.end();
|
||||
for (auto it = start; it != end; ++it) {
|
||||
if (it->name == name) {
|
||||
return &*it;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@ -50,11 +56,12 @@ public:
|
||||
static vec3_UClass BuildClass() {
|
||||
vec3_UClass cls(type_name<vec3>().View(), sizeof(vec3), &TypeInfo<vec3_parent>::StaticClass);
|
||||
//offsetof(vec3, x) 很坑,相当坑
|
||||
cls.FList[0] = cls.MakeMemberField<float, offsetof(vec3, x)>("x");
|
||||
cls.FList[1] = cls.MakeMemberField<float, offsetof(vec3, y)>("y");
|
||||
cls.FList[2] = cls.MakeMemberField<float, offsetof(vec3, z)>("z");
|
||||
cls.AttrNum = 3;
|
||||
cls.FList[0] = cls.MakeMemberField<offsetof(vec3, x)>("x", &TypeInfo<float>::StaticClass);
|
||||
cls.FList[1] = cls.MakeMemberField<offsetof(vec3, y)>("y", &TypeInfo<float>::StaticClass);
|
||||
cls.FList[2] = cls.MakeMemberField<offsetof(vec3, z)>("z", &TypeInfo<float>::StaticClass);
|
||||
cls.FList[3] = cls.MakeMethodField(&vec3::norm, "norm");
|
||||
//cls.FList[4] = cls.MakeMethodField(&vec3::norm1, "norm1");
|
||||
cls.FList[4] = cls.MakeMethodField(&vec3::norm1, "norm1");
|
||||
//cls.FList[5] = cls.MakeMethodField(&vec3::norm2, "norm2");
|
||||
return cls;
|
||||
}
|
||||
@ -63,31 +70,48 @@ template<typename ...Args>
|
||||
void printt(void* ptr, std::vector<ArgsView>& ArgsList) {
|
||||
using MethodType = void (*)(Args...);
|
||||
MethodType fptr = (MethodType)ptr;
|
||||
auto param = ArgsList.begin();
|
||||
auto val1 = (++param)->val;
|
||||
auto val2 = (++param)->val;
|
||||
auto val3 = (++param)->val;
|
||||
fptr(val1, (int)val2, (int*)(void *)val3);
|
||||
//fptr(val1, (int)val2, std::forward<int&>((int&)val3));
|
||||
{
|
||||
auto param = ArgsList.rbegin();
|
||||
fptr(param++->cast_to<Args>()...);
|
||||
//fptr((Args)param++->val...);
|
||||
}
|
||||
/* {
|
||||
auto param = ArgsList.begin();
|
||||
auto val1 = (++param);
|
||||
auto val2 = (++param);
|
||||
auto val3 = (++param);
|
||||
fptr(val1->cast_to<void *>(), val1->cast_to<void*>(), val1->cast_to<void*>();
|
||||
}
|
||||
*/
|
||||
//fptr((++param)->val, (int)(++param)->val, (int&)(++param)->val);
|
||||
//fptr(std::forward<Args>(Args(param++->val))...);
|
||||
//fptr(std::forward<Args>((Args)(++param)->val)...);
|
||||
int x = 1;
|
||||
x = x + 1;
|
||||
}
|
||||
int main() {
|
||||
auto cls = &TypeInfo<vec3>::StaticClass;
|
||||
auto cls2 = &TypeInfo<int>::StaticClass;
|
||||
auto cls3 = &TypeInfo<int*>::StaticClass;
|
||||
auto cls4 = &TypeInfo<void*>::StaticClass;
|
||||
auto cls5 = &TypeInfo<decltype(&vec3::norm)>::StaticClass;
|
||||
vec3 v;
|
||||
int x = 1, y = 2;
|
||||
std::vector<ArgsView> ArgsList;
|
||||
ArgsList.emplace_back();
|
||||
ArgsList.emplace_back(&v);
|
||||
ArgsList.emplace_back((void*)x);
|
||||
ArgsList.emplace_back(&y);
|
||||
ArgsList.emplace_back(v);
|
||||
ArgsList.emplace_back(x);
|
||||
ArgsList.emplace_back(y);
|
||||
auto ptr1 = &vec3::norm;
|
||||
using MethodType = void (*)(void*, int, int*);
|
||||
using MethodType = void (*)(void*, int, int&);
|
||||
MethodType ptr2 = *(MethodType*)&ptr1;
|
||||
ptr2(&v, x , &y);
|
||||
printt<const void*, int , int*>(*(void**)&ptr1, ArgsList);
|
||||
using R = int;
|
||||
using RetType = void*;
|
||||
auto ttt = sizeof(void*);
|
||||
RetType ret;
|
||||
//ptr2(&v, x , y);
|
||||
auto ov = cls->New((void*)& v);
|
||||
ov.Invoke("norm", x, y);
|
||||
printt<const void*, int , int&>(*(void**)&ptr1, ArgsList);
|
||||
//ptr2(x, y);
|
||||
//cout << "hello world\n";
|
||||
cout << "hello world\n";
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user