rebuild refl01

This commit is contained in:
ouczbs 2024-04-13 17:47:44 +08:00
parent a79b76c8f4
commit 7e6c362024
6 changed files with 175 additions and 97 deletions

View File

@ -9,7 +9,7 @@ namespace refl {
class ArgsView; class ArgsView;
using Offset = uint32_t; using Offset = uint32_t;
using Method = void(*)(...); using Method = void*;
using DefaultMember = const ArgsView (*)(); using DefaultMember = const ArgsView (*)();
using DefaultMethod = std::pair<ArgsView*, int>(*)(); using DefaultMethod = std::pair<ArgsView*, int>(*)();
@ -26,22 +26,23 @@ namespace refl {
{ {
Offset offset; Offset offset;
Method method; Method method;
Data() : method(nullptr) {} constexpr Data() : method(nullptr) {}
Data(Offset& offset) : offset(offset) {} constexpr Data(Offset& offset) : offset(offset) {}
Data(Method& method) : method(method) {} constexpr Data(Method& method) : method(method) {}
constexpr Data(const Method& method) : method(method) {}
}; };
union Default { union Default {
DefaultMember member; DefaultMember member;
DefaultMethod method; DefaultMethod method;
Default(): method(nullptr) {} constexpr Default(): method(nullptr) {}
Default(DefaultMember& member) : member(member) {} constexpr Default(DefaultMember& member) : member(member) {}
Default(DefaultMethod& method) : method(method) {} constexpr Default(DefaultMethod& method) : method(method) {}
}; };
Name name; Name name;
const UClass* type; const UClass* type{};
Data data; Data data{};
Default value; Default value{};
uint32_t flag; uint32_t flag{};
//safe //safe
bool Invoke(std::vector<ArgsView>& ArgsList)const; bool Invoke(std::vector<ArgsView>& ArgsList)const;
@ -50,5 +51,48 @@ namespace refl {
std::vector<const UClass*> GetParams() const; std::vector<const UClass*> GetParams() const;
}; };
/*
template<typename T, typename V>
consteval V* fetch_member_v(V T::*) {
return nullptr;
}
template<typename R, typename T, typename ...Args>
consteval auto fetch_method_v(R (T::* ptr)(Args...)) {
using MethodType = R(*)(T*, Args...);
return MethodType{nullptr};
}
template<typename R, typename ...Args>
consteval auto fetch_method_v(R(*ptr)(Args...)) {
return ptr;
}
template<typename... Args>
consteval auto FetchMembers(const std::tuple<Args...>&) {
return std::make_tuple(fetch_member_v(Args{nullptr})...);
}
template<typename... Args>
consteval auto FetchMethods(const std::tuple<Args...>&) {
return std::make_tuple(fetch_method_v(Args{ nullptr })...);
}
template<typename ...Args>
class FieldMembers{
public:
constexpr FieldMembers() {}
FieldMembers(const std::tuple<Args*...>&) {
}
constexpr static int GetSize() {
return sizeof...(Args);
}
};
template<typename ...Args>
class FieldMethods{
public:
constexpr FieldMethods() {}
FieldMethods(const std::tuple<Args*...>&) {
}
constexpr static int GetSize() {
return sizeof...(Args);
}
};*/
} }

View File

@ -1,10 +1,17 @@
#pragma once #pragma once
#include <type_traits> #include <type_traits>
#define REGISTER_CLASS_META(T, P) using MyUClass = UClass_Meta<T, P>;
#define REGISTER_MEMBER(Ptr, Name) MakeStaticField(Ptr, Name),
#define BUILD_FELDS() constexpr static auto __BuildFields() {\
return std::array{\
REGISTER_FIELDS(REGISTER_MEMBER, REGISTER_MEMBER)\
};\
};
namespace refl { namespace refl {
template <class T> template <class T>
concept _ReflCheck_Ctor = requires { T(); }; concept _ReflCheck_Ctor = requires { T(); };
template <class T> template <class T>
concept _ReflCheck_UClass = requires(typename T::MyUClass& cls) { T::BuildClass(cls); } ; concept _ReflCheck_UClass = requires { !std::is_void_v<decltype(T::__BuildFields())>; };
template <class T> template <class T>
concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor<T> && !_ReflCheck_UClass<T>; concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor<T> && !_ReflCheck_UClass<T>;
//类型接口 //类型接口

View File

@ -8,7 +8,7 @@ namespace refl {
using UClass::UClass; using UClass::UClass;
using MyUClass = UClass_Auto<T>; using MyUClass = UClass_Auto<T>;
public: public:
constexpr static MyUClass BuildClass() { consteval static MyUClass BuildClass() {
MyUClass cls(type_name<T>().View(), sizeof(T)); MyUClass cls(type_name<T>().View(), sizeof(T));
if constexpr (!std::is_trivially_copyable_v<T>) { if constexpr (!std::is_trivially_copyable_v<T>) {
cls.vtable.InitObject = &MyUClass::InitObject<T>; cls.vtable.InitObject = &MyUClass::InitObject<T>;
@ -16,6 +16,12 @@ namespace refl {
} }
return cls; return cls;
} }
void Set(void* ptr,const T& t) {
*(T*)ptr = t;
}
T& Get(void* ptr) {
return *(T*)ptr;
}
}; };
/* /*
@ -36,6 +42,15 @@ namespace refl {
auto& UList = static_cast<const MyUClass*>(cls)->UList; auto& UList = static_cast<const MyUClass*>(cls)->UList;
return { UList.data(), UList.data() + UList.size() }; return { UList.data(), UList.data() + UList.size() };
} }
static R Call(const FieldPtr* field, Args... args) {
MethodType fptr = (MethodType)field->data.method;
if constexpr (std::is_same_v<R, void>) {
fptr(args...);
}
else {
return fptr(args...);
}
}
static void Call(const FieldPtr* field, const std::vector<ArgsView>& ArgsList) { static void Call(const FieldPtr* field, const std::vector<ArgsView>& ArgsList) {
if constexpr (std::is_same_v<R, void>) { if constexpr (std::is_same_v<R, void>) {
MethodType fptr = (MethodType)field->data.method; MethodType fptr = (MethodType)field->data.method;
@ -55,7 +70,7 @@ namespace refl {
} }
} }
protected: protected:
constexpr void BuildUList() { consteval 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;
} }
@ -66,7 +81,7 @@ namespace refl {
} }
public: public:
//为了简化判断cls 对象 统统指向 T* //为了简化判断cls 对象 统统指向 T*
constexpr static MyUClass BuildClass() { consteval static MyUClass BuildClass() {
MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType)); MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType));
cls.vtable.GetParams = &MyUClass::GetParams; cls.vtable.GetParams = &MyUClass::GetParams;
cls.vtable.Call = &MyUClass::Call; cls.vtable.Call = &MyUClass::Call;
@ -74,6 +89,7 @@ namespace refl {
return cls; return cls;
} }
}; };
/*
class UClass_Custom : public UClass { class UClass_Custom : public UClass {
public: public:
using UClass::UClass; using UClass::UClass;
@ -96,13 +112,27 @@ namespace refl {
} }
return nullptr; return nullptr;
} }
/*
void BuildClass() { void BuildClass() {
FList.shrink_to_fit();//缩减容量FList大小不再改变了 FList.shrink_to_fit();//缩减容量FList大小不再改变了
vtable.GetField = &UClass_Custom::GetField; vtable.GetField = &UClass_Custom::GetField;
} }
*/ };*/
template<typename T, typename P = void>
class UClass_Meta : public UClass {
public:
using FieldsType = decltype(T::__BuildFields());
FieldsType Fields{ T::__BuildFields() };
consteval UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){
if constexpr (!std::is_same_v<P, void>) {
parent = &TypeInfo<P>::StaticClass;
}
}
}; };
//基础类型的偏特化 //基础类型的偏特化
template<_ReflCheck_Ctor_NoUClass T> template<_ReflCheck_Ctor_NoUClass T>
struct TypeInfoImpl<T> { struct TypeInfoImpl<T> {
@ -116,28 +146,10 @@ namespace refl {
using UClass = UMethod_Auto<R, Args...>; using UClass = UMethod_Auto<R, Args...>;
inline constexpr static UClass StaticClass = UClass::BuildClass(); inline constexpr static UClass StaticClass = UClass::BuildClass();
}; };
template<_ReflCheck_UClass T> template<_ReflCheck_UClass T>
struct TypeInfoImpl<T> { struct TypeInfoImpl<T> {
using MyUClass = typename T::MyUClass; using MyUClass = typename T::MyUClass;
inline static MyUClass StaticClass = []()->MyUClass { //这里如何改成 constexpr
MyUClass cls(type_name<T>().View(), sizeof(T)); inline constexpr static MyUClass StaticClass = MyUClass();
T::BuildClass(cls);
auto& vtable = cls.vtable;
if (!vtable.GetField) {
vtable.GetField = &MyUClass::GetField;
}
if constexpr (!std::is_trivially_copyable_v<T>) {
if (!vtable.InitObject) {
//这里一定会创建一个InitObject<T> 模板函数,如何优化
vtable.InitObject = &UClass::InitObject<T>;
}
if (!vtable.CopyObject) {
//这里一定会创建一个CopyObject<T> 模板函数,如何优化
vtable.CopyObject = &UClass::CopyObject<T>;
}
}
return cls;
}();
}; };
} }

View File

@ -4,39 +4,55 @@
namespace refl { namespace refl {
/* 成员变量需要定义默认值吗那为什么不在initObjec里初始化?*/ /* 成员变量需要定义默认值吗那为什么不在initObjec里初始化?*/
template<typename T, typename Obj> template<typename T, typename Obj>
static FieldPtr MakeMemberField(T Obj::* ptr, Name name) { consteval FieldPtr MakeStaticField(T Obj::* ptr, Name name) {
FieldPtr::Default value; FieldPtr::Default value;
Offset offset = reinterpret_cast<std::size_t>(&(reinterpret_cast<const Obj*>(0)->*ptr)); FieldPtr::Data member = { nullptr };
FieldPtr::Data member = { offset };
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
return { name, &TypeInfo<T>::StaticClass, member, value, flag }; return { name, &TypeInfo<T>::StaticClass, member, value, flag };
} }
template<typename R, typename ...Args> template<typename R, typename ...Args>
static FieldPtr MakeMethodField(R(*ptr)(Args...), Name name, const std::vector<ArgsValue>& args = {}) { consteval FieldPtr MakeStaticField(R(*ptr)(Args...), Name name/*, const std::vector<ArgsValue>& args = {}*/) {
uint32_t flag = FIELD_METHOD_FLAG; uint32_t flag = FIELD_METHOD_FLAG;
FieldPtr::Default value; FieldPtr::Default value;
if (args.size() > 0) { /*if (args.size() > 0) {
flag |= FIELD_METHOD_VALUE_FLAG; flag |= FIELD_METHOD_VALUE_FLAG;
static const ArgsValueList argsValue(args); static const ArgsValueList argsValue(args);
value.method = []() ->std::pair<ArgsView*, int> { value.method = []() ->std::pair<ArgsView*, int> {
return { argsValue.ptr , argsValue.num }; return { argsValue.ptr , argsValue.num };
}; };
} }*/
FieldPtr::Data method = { *(Method*)&ptr }; FieldPtr::Data method = { nullptr };
return { name, &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::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 = {}) { consteval FieldPtr MakeStaticField(R(T::* ptr)(Args...), Name name/*, const std::vector<ArgsValue>& args = {}*/) {
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
FieldPtr::Default value; FieldPtr::Default value;
if (args.size() > 0) { /*if (args.size() > 0) {
flag |= FIELD_METHOD_VALUE_FLAG; flag |= FIELD_METHOD_VALUE_FLAG;
static const ArgsValueList argsValue(args); static const ArgsValueList argsValue(args);
value.method = []() ->std::pair<ArgsView*, int> { value.method = []() ->std::pair<ArgsView*, int> {
return { argsValue.ptr , argsValue.num }; return { argsValue.ptr , argsValue.num };
}; };
} }*/
FieldPtr::Data method = { *(Method*)&ptr }; //Method fptr = nullptr;
FieldPtr::Data method = { nullptr };
return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass, method, value,flag }; return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass, method, value,flag };
} }
template<typename ...Args>
consteval auto MakeTuple(Args&&... args) {
return std::make_tuple(args...);
}
template<typename ...Args>
auto MakeStaticFields(const std::tuple<Args...>& args) {
constexpr std::size_t N = sizeof...(Args);
std::array<FieldPtr, N> fields{};
for (std::size_t i = 0; i < N; ++i) {
auto& arg = std::get<0>(args);
auto a1 = std::get<0>(arg);
auto a2 = std::get<1>(arg);
//fields[i] = MakeStaticField(std::get<0>(arg), std::get<1>(arg));
}
return fields;
}
} }

View File

@ -32,16 +32,27 @@ struct vec3 : public vec3_parent {
x1 = x1 * 10; x1 = x1 * 10;
//cout << x1 << "::norm3" << endl; //cout << x1 << "::norm3" << endl;
} }
using MyUClass = UClass_Custom; constexpr static auto __GetFields() {
static void BuildClass(MyUClass& cls) { return std::tuple{
cls.parent = &TypeInfo<vec3_parent>::StaticClass; MakeTuple(&vec3::x, "x"),
cls.AttrNum = 3; MakeTuple(&vec3::y, "y"),
cls.FList = { MakeTuple(&vec3::z, "z"),
MakeMemberField(&vec3::x, "x"), MakeTuple(&vec3::norm, "norm"),
MakeMemberField(&vec3::y, "y"), MakeTuple(&vec3::norm1, "norm1"),
MakeMemberField(&vec3::z, "z"), MakeTuple(&vec3::norm2, "norm2")
MakeMethodField(&vec3::norm, "norm", {8, 9}),
MakeMethodField(&vec3::norm1, "norm1",{(float)2.0})
}; };
} };
#define REGISTER_FIELDS(MemberFunc, MethodFunc)\
MemberFunc(&vec3::x, "x")\
MemberFunc(&vec3::y, "y")\
MemberFunc(&vec3::z, "z")\
MethodFunc(&vec3::norm,"norm",{})\
MethodFunc(&vec3::norm1,"norm1",{})\
MethodFunc(&vec3::norm2,"norm2",{})
REGISTER_CLASS_META(vec3, vec3_parent)
BUILD_FELDS()
#undef REGISTER_FIELDS
}; };

View File

@ -1,40 +1,28 @@
#include "refl/vertex.h" #include "refl/vertex.h"
#include <benchmark/benchmark.h> union MemberMethod {
void TestRefl1(benchmark::State& state) { using F1 = int(*)(int);
auto cls = &TypeInfo<vec3>::StaticClass; using F2 = void(*)();
vec3 v; F1 f1;
auto ptr = (void*)&v; F2 f2;
auto ov = cls->New(ptr); constexpr MemberMethod(F1 f):f1(f) {
int x = 1, y = 2;
for (auto _ : state) {
ov.Invoke("norm", { {},ptr, x, y});
}
}
BENCHMARK(TestRefl1);
void TestRefl2(benchmark::State& state) {
auto cls = &TypeInfo<vec3>::StaticClass;
vec3 v;
auto ptr = (void*)&v;
auto ov = cls->New(ptr);
int x = 1, y = 2;
std::vector<ArgsView> ArgsList;
ArgsList.emplace_back();
ArgsList.emplace_back(ptr);
ArgsList.emplace_back(x);
ArgsList.emplace_back(y);
auto field = cls->GetField(cls, "norm", true);
for (auto _ : state) {
field->Invoke(ArgsList);
}
}
BENCHMARK(TestRefl2);
void TestCPlusPlus(benchmark::State& state) {
vec3 v;
int x = 1, y = 2;
for (auto _ : state) {
v.norm(x, y);
}
}
BENCHMARK(TestCPlusPlus);
BENCHMARK_MAIN(); }
constexpr MemberMethod(F2 f) :f2(f) {
}
};
void test() {
}
template<typename T>
void print(T* t) {
}
int main() {
//auto& cls = TypeInfo<vec3>::StaticClass;
//int FList[3]{};
//auto norm = MakeMethodField(&vec3::norm,"norm");
MakeStaticFields(vec3::__GetFields());
std::cout << "hello world\n";
return 0;
}