upload refl invoke
This commit is contained in:
parent
a8113a70b1
commit
2c39b681a3
20
engine/3rdparty/zlib/include/refl/field.h
vendored
20
engine/3rdparty/zlib/include/refl/field.h
vendored
@ -5,23 +5,21 @@
|
|||||||
using Ubpa::Name;
|
using Ubpa::Name;
|
||||||
using Ubpa::type_name;
|
using Ubpa::type_name;
|
||||||
namespace refl {
|
namespace refl {
|
||||||
struct MemberField {
|
|
||||||
uint32_t offset;
|
|
||||||
};
|
|
||||||
struct MemberFuncField {
|
|
||||||
using Offsetor = std::function<void* (void*)>;
|
|
||||||
Offsetor func;
|
|
||||||
};
|
|
||||||
class UClass;
|
class UClass;
|
||||||
|
enum FieldFlag:uint32_t {
|
||||||
|
FIELD_NONE_FLAG = 0,
|
||||||
|
FIELD_MEMBER_FLAG = 1 << 0,
|
||||||
|
FIELD_ATTRIBUTE_FLAG = 1 << 1,
|
||||||
|
FIELD_METHOD_FLAG = 1 << 2,
|
||||||
|
};
|
||||||
struct FieldPtr {
|
struct FieldPtr {
|
||||||
using Offsetor = std::function<void* (void*)>;
|
|
||||||
// raw offsetor
|
|
||||||
using Data = std::variant<
|
using Data = std::variant<
|
||||||
uint32_t, // forward_offset_value 0 BASIC
|
uint32_t, // offset
|
||||||
double // static_obj 2 STATIC
|
void* // method
|
||||||
>;
|
>;
|
||||||
Name name;
|
Name name;
|
||||||
const UClass* type;
|
const UClass* type;
|
||||||
Data data;
|
Data data;
|
||||||
|
uint32_t flag;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
3
engine/3rdparty/zlib/include/refl/object.h
vendored
3
engine/3rdparty/zlib/include/refl/object.h
vendored
@ -18,5 +18,8 @@ namespace refl {
|
|||||||
|
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
bool Invoke(const Name& name, Args... args);
|
bool Invoke(const Name& name, Args... args);
|
||||||
|
|
||||||
|
template<typename R, typename ...Args>
|
||||||
|
bool InvokeRet(const Name& name,R& ret, Args... args);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
15
engine/3rdparty/zlib/include/refl/type.h
vendored
15
engine/3rdparty/zlib/include/refl/type.h
vendored
@ -2,17 +2,18 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
namespace refl {
|
namespace refl {
|
||||||
template <class T>
|
template <class T>
|
||||||
concept _CheckDefaultConstruct = requires { T(); };
|
concept _ReflCheck_Ctor = requires { T(); };
|
||||||
template <class T>
|
template <class T>
|
||||||
concept _CheckBuildUClass = requires{{T::UClass::BuildClass()} -> std::same_as<typename T::UClass>; };
|
concept _ReflCheck_UClass = requires{{T::UClass::BuildClass()} -> std::same_as<typename T::UClass>; };
|
||||||
|
template <class T>
|
||||||
|
concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor<T> && !_ReflCheck_UClass<T>;
|
||||||
|
|
||||||
template <class T>
|
//主模板只有声明,没有定义,从而使得非特化非法
|
||||||
concept _ReflCheck = _CheckDefaultConstruct<T> || _CheckBuildUClass<T>;
|
template<typename T>
|
||||||
template<_ReflCheck T, typename = void>
|
|
||||||
struct TypeInfo;
|
struct TypeInfo;
|
||||||
|
|
||||||
template<_ReflCheck T>
|
template<_ReflCheck_UClass T>
|
||||||
struct TypeInfo<T, std::void_t<typename T::UClass, decltype(T::UClass::BuildClass())>> {
|
struct TypeInfo<T> {
|
||||||
using UClass = typename T::UClass;
|
using UClass = typename T::UClass;
|
||||||
inline static UClass StaticClass = UClass::BuildClass();
|
inline static UClass StaticClass = UClass::BuildClass();
|
||||||
};
|
};
|
||||||
|
|||||||
90
engine/3rdparty/zlib/include/refl/uclass.h
vendored
90
engine/3rdparty/zlib/include/refl/uclass.h
vendored
@ -4,6 +4,7 @@
|
|||||||
#include "object.h"
|
#include "object.h"
|
||||||
namespace refl {
|
namespace refl {
|
||||||
class UClass{
|
class UClass{
|
||||||
|
using enum FieldFlag;
|
||||||
public:
|
public:
|
||||||
Name name;
|
Name name;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
@ -52,19 +53,26 @@ namespace refl {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
template<uint32_t offset, typename T,typename U>
|
template<uint32_t offset, typename T,typename U>
|
||||||
FieldPtr MakeMemberField(T U::* ptr, Name name) {
|
FieldPtr MakeMemberField(T U::* ptr, Name name) {
|
||||||
FieldPtr::Data member = { offset };
|
FieldPtr::Data member = { offset };
|
||||||
return { name, &TypeInfo<T>::StaticClass, {member} };
|
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
|
||||||
|
return { name, &TypeInfo<T>::StaticClass, {member}, flag };
|
||||||
}
|
}
|
||||||
template<uint32_t offset, typename T, typename U>
|
template<typename R, typename ...Args>
|
||||||
FieldPtr MakeMethodField(T U::* ptr, Name name) {
|
FieldPtr MakeMethodField(R (* ptr)(Args...), Name name) {
|
||||||
FieldPtr::Data member = { offset };
|
FieldPtr::Data member = { *(void**)&ptr };
|
||||||
return { name, &TypeInfo<T>::StaticClass, {member} };
|
constexpr uint32_t flag = FIELD_METHOD_FLAG;
|
||||||
|
return { name, &TypeInfo<decltype(ptr)>::StaticClass, {member},flag };
|
||||||
|
}
|
||||||
|
template<typename T, typename R, typename ...Args>
|
||||||
|
FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name) {
|
||||||
|
FieldPtr::Data member = { *(void**)&ptr };
|
||||||
|
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
|
||||||
|
return { name, &TypeInfo<R(*)(Args...)>::StaticClass, {member},flag };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T>
|
template<_ReflCheck_Ctor T>
|
||||||
requires std::is_default_constructible_v<T>
|
|
||||||
class UClass_Auto : public UClass{
|
class UClass_Auto : public UClass{
|
||||||
public:
|
public:
|
||||||
using UClass::UClass;
|
using UClass::UClass;
|
||||||
@ -72,7 +80,7 @@ namespace refl {
|
|||||||
void InitObject(void* ptr)const override {
|
void InitObject(void* ptr)const override {
|
||||||
constexpr bool is_shallow_copyable = std::is_trivially_copyable<T>::value;
|
constexpr bool is_shallow_copyable = std::is_trivially_copyable<T>::value;
|
||||||
if constexpr (!is_shallow_copyable){
|
if constexpr (!is_shallow_copyable){
|
||||||
constexpr T obj{};
|
T obj{};
|
||||||
std::construct_at((T*)ptr, obj);
|
std::construct_at((T*)ptr, obj);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -85,11 +93,36 @@ namespace refl {
|
|||||||
return cls;
|
return cls;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<_ReflCheck T, typename>
|
template<_ReflCheck_Ctor_NoUClass T>
|
||||||
struct TypeInfo {
|
struct TypeInfo<T> {
|
||||||
using UClass = UClass_Auto<T>;
|
using UClass = UClass_Auto<T>;
|
||||||
inline static UClass StaticClass = UClass::BuildClass();
|
inline static UClass StaticClass = UClass::BuildClass();
|
||||||
};
|
};
|
||||||
|
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;
|
||||||
|
public:
|
||||||
|
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) {
|
||||||
|
cls.UList[0] = &TypeInfo<R>::StaticClass;
|
||||||
|
}
|
||||||
|
if (sizeof...(Args) > 0) {
|
||||||
|
auto ptr = &cls.UList[1];
|
||||||
|
(...,(*ptr = &TypeInfo<Args>::StaticClass, ptr++));
|
||||||
|
}
|
||||||
|
return cls;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 函数指针类型的偏特化
|
||||||
|
template<typename R, typename... Args>
|
||||||
|
struct TypeInfo<R(*)(Args...)> {
|
||||||
|
using UClass = UMethod_Auto<R,Args...>;
|
||||||
|
inline static UClass StaticClass = UClass::BuildClass();
|
||||||
|
};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool ObjectView::Get(const Name& name, T& t)
|
inline bool ObjectView::Get(const Name& name, T& t)
|
||||||
{
|
{
|
||||||
@ -128,6 +161,39 @@ _cache_set: bool isChild = cache->type->IsChildOf<T>(true);
|
|||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
bool ObjectView::Invoke(const Name& name, Args... args)
|
bool ObjectView::Invoke(const Name& name, Args... args)
|
||||||
{
|
{
|
||||||
return false;
|
auto field = cls->GetField(name);
|
||||||
|
if (!field) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (field->flag & FIELD_MEMBER_FLAG) {
|
||||||
|
using MemberMethodType = void(*)(const void*, Args...);
|
||||||
|
MemberMethodType fptr = (MemberMethodType)std::get<void*>(field->data);
|
||||||
|
fptr(ptr, args...);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
using MethodType = void(*)(Args...);
|
||||||
|
MethodType fptr = (MethodType)std::get<void*>(field->data);
|
||||||
|
fptr(args...);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
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<void*>(field->data);
|
||||||
|
ret = fptr(ptr, args...);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
using MethodType = R(*)(Args...);
|
||||||
|
MethodType fptr = (MethodType)std::get<void*>(field->data);
|
||||||
|
ret = fptr(args...);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
25
engine/3rdparty/zlib/test/refl/tstring.h
vendored
25
engine/3rdparty/zlib/test/refl/tstring.h
vendored
@ -5,13 +5,32 @@ using std::string;
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void PrintHex(T& obj) {
|
void PrintHex(T& obj) {
|
||||||
auto size = sizeof(T);
|
auto size = sizeof(T);
|
||||||
std::cout << type_name<T>().View() << "<" << size <<"> " << " = 0x";
|
std::cout << std::hex << type_name<T>().View() << "<" << size <<"> " << " = 0x";
|
||||||
char* ptr = (char*)& obj;
|
char* ptr = (char*)&obj;
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
std::cout << std::hex << std::setw(2) << std::setfill('0') <<(int)*(ptr + i);
|
std::cout << std::hex << std::setw(2) << std::setfill('0') <<(int)(uint8_t)*(ptr + i);
|
||||||
}
|
}
|
||||||
std::cout << "FF" << std::endl;
|
std::cout << "FF" << std::endl;
|
||||||
}
|
}
|
||||||
|
template<typename T>
|
||||||
|
void PrintHex8(T& obj) {
|
||||||
|
auto size = sizeof(T);
|
||||||
|
std::cout << std::hex << type_name<T>().View() << "<" << size << "> " << "\n\t";
|
||||||
|
{
|
||||||
|
int* ptr = (int*)&obj;
|
||||||
|
for (int i = 0; i < size / 4; i += 1) {
|
||||||
|
std::cout << std::dec << std::setw(8) << std::setfill('0') << *(ptr + i) << "-";
|
||||||
|
}
|
||||||
|
std::cout << "=-0x";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
uintptr_t* ptr = (uintptr_t*)&obj;
|
||||||
|
for (int i = 0; i < size / 8; i += 1) {
|
||||||
|
std::cout << std::hex << std::setw(16) << std::setfill('0') << *(ptr + i) << "-";
|
||||||
|
}
|
||||||
|
std::cout << ";-" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
void TestString1() {
|
void TestString1() {
|
||||||
string hello = "abcdef";
|
string hello = "abcdef";
|
||||||
int size = sizeof(string);
|
int size = sizeof(string);
|
||||||
|
|||||||
72
engine/3rdparty/zlib/test/refl_01.cpp
vendored
72
engine/3rdparty/zlib/test/refl_01.cpp
vendored
@ -3,6 +3,7 @@
|
|||||||
#include "refl/uclass.h"
|
#include "refl/uclass.h"
|
||||||
#include "vertex.h"
|
#include "vertex.h"
|
||||||
#include "tstring.h"
|
#include "tstring.h"
|
||||||
|
#include <functional>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace refl;
|
using namespace refl;
|
||||||
struct vec3_parent {
|
struct vec3_parent {
|
||||||
@ -14,12 +15,25 @@ struct vec3 : public vec3_parent {
|
|||||||
float y = 2;
|
float y = 2;
|
||||||
float z = 3;
|
float z = 3;
|
||||||
string name{ "hellohellohellohellohellohello" };
|
string name{ "hellohellohellohellohellohello" };
|
||||||
float norm() {
|
void norm(int x1) {
|
||||||
return x * y * z;
|
x1 = x * y * z;
|
||||||
|
cout << x1 << "::norm" << endl;
|
||||||
|
}
|
||||||
|
virtual float norm1(int x1) {
|
||||||
|
cout << x1 << "::norm1" << endl;
|
||||||
|
return x * y *z * x1;
|
||||||
|
}
|
||||||
|
static void norm2(int x1) {
|
||||||
|
cout << x1 << "::norm2" << endl;
|
||||||
|
}
|
||||||
|
void norm3(int x1) {
|
||||||
|
x1 = x * y * z;
|
||||||
|
cout << x1 << "::norm3" << endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct vec3_UClass : public UClass {
|
struct vec3_UClass : public UClass {
|
||||||
array<FieldPtr,4> FList;
|
public:
|
||||||
|
array<FieldPtr,6> FList;
|
||||||
using UClass::UClass;
|
using UClass::UClass;
|
||||||
const FieldPtr* GetField(const Name& name)const override {
|
const FieldPtr* GetField(const Name& name)const override {
|
||||||
for (auto& field : FList) {
|
for (auto& field : FList) {
|
||||||
@ -39,32 +53,38 @@ struct vec3_UClass : public UClass {
|
|||||||
cls.FList[0] = cls.MakeMemberField<offsetof(vec3, x)>(&vec3::x, "x");
|
cls.FList[0] = cls.MakeMemberField<offsetof(vec3, x)>(&vec3::x, "x");
|
||||||
cls.FList[1] = cls.MakeMemberField<offsetof(vec3, y)>(&vec3::y, "y");
|
cls.FList[1] = cls.MakeMemberField<offsetof(vec3, y)>(&vec3::y, "y");
|
||||||
cls.FList[2] = cls.MakeMemberField<offsetof(vec3, z)>(&vec3::z, "z");
|
cls.FList[2] = cls.MakeMemberField<offsetof(vec3, z)>(&vec3::z, "z");
|
||||||
cls.FList[3] = cls.MakeMemberField<offsetof(vec3, name)>(&vec3::name, "name");
|
cls.FList[3] = cls.MakeMethodField(&vec3::norm, "norm");
|
||||||
|
cls.FList[4] = cls.MakeMethodField(&vec3::norm1, "norm1");
|
||||||
|
cls.FList[5] = cls.MakeMethodField(&vec3::norm2, "norm2");
|
||||||
return cls;
|
return cls;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
int main() {
|
int main() {
|
||||||
using uclass = TypeInfo<vec3>::UClass;
|
auto& cls = TypeInfo<vec3>::StaticClass;
|
||||||
auto& res = TypeInfo<int>::StaticClass;
|
auto ptr1 = &vec3::norm;
|
||||||
auto& res2 = TypeInfo<Name>::StaticClass;
|
auto ptr2 = &vec3::norm1;
|
||||||
|
auto ptr3 = &vec3::norm2;
|
||||||
auto& res3 = TypeInfo<vec3>::StaticClass;
|
auto ptr4 = &vec3::norm3;
|
||||||
vec3 v1;
|
vec3 v;
|
||||||
auto res4 = TypeInfo<size_t>::StaticClass;
|
using Any = void*;
|
||||||
auto res5 = TypeInfo<string_view>::StaticClass;
|
ObjectView pv(&v, &cls);
|
||||||
auto t1 = res3.FList[0];
|
//using ClassMethod = void(Any::*)(int);
|
||||||
vec3_parent* v2 = res3.New<vec3_parent>();
|
using MethodType = void(void*, int);
|
||||||
vec3* v22 = (vec3*)v2;
|
MethodType* ptr_wrap = (MethodType*)*(void**)&ptr1;
|
||||||
auto v3 = res3.New();
|
pv.Invoke("norm", 10);
|
||||||
int x1 = 110;
|
ptr_wrap(&v, 10);
|
||||||
float x = *res.New(&x1);
|
ptr_wrap = (MethodType*)*(void**)&ptr2;
|
||||||
v3.Get("x", x);
|
float x;
|
||||||
v3.Set("z", (float)33);
|
pv.InvokeRet("norm1",x ,10);
|
||||||
v2 = (vec3*)v3.ptr;
|
ptr_wrap(&v, 10);
|
||||||
using T = int;
|
ptr_wrap = (MethodType*)*(void**)&ptr3;
|
||||||
auto b1 = res3.IsChildOf<vec3_parent>();
|
pv.Invoke("norm2", 10);
|
||||||
constexpr auto cls = UClass_Auto<int>(type_name<T>().View(), sizeof(T));
|
ptr_wrap(&v, 10);
|
||||||
cout << sizeof(Name) << "Type2: " << typeid(vec3).name() << endl;
|
ptr_wrap = (MethodType*)*(void**)&ptr4;
|
||||||
delete v2;
|
ptr_wrap(&v, 10);
|
||||||
|
PrintHex8(ptr1);
|
||||||
|
PrintHex8(ptr2);
|
||||||
|
PrintHex8(ptr3);
|
||||||
|
PrintHex8(ptr4);
|
||||||
cout << "hello world\n";
|
cout << "hello world\n";
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user