rebuild refl

This commit is contained in:
ouczbs 2024-04-14 22:45:08 +08:00
parent 7e6c362024
commit a960cb0098
11 changed files with 255 additions and 107 deletions

View File

@ -5,5 +5,4 @@ add_requires("tinyobjloader")
add_requires("vulkansdk") add_requires("vulkansdk")
add_requires("assimp") add_requires("assimp")
add_requires("nlohmann_json") add_requires("nlohmann_json")
add_requires("ylt")
add_requires("benchmark") add_requires("benchmark")

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "UTemplate/Type.hpp" #include "UTemplate/Type.hpp"
#include "../std/sarray.h"
#include <variant> #include <variant>
#include <functional> #include <functional>
using Ubpa::Name; using Ubpa::Name;
@ -7,6 +8,7 @@ using Ubpa::type_name;
namespace refl { namespace refl {
class UClass; class UClass;
class ArgsView; class ArgsView;
class ArgsValue;
using Offset = uint32_t; using Offset = uint32_t;
using Method = void*; using Method = void*;
@ -49,8 +51,13 @@ namespace refl {
//unsafe //unsafe
bool Invoke(const std::vector<ArgsView>& ArgsList)const; bool Invoke(const std::vector<ArgsView>& ArgsList)const;
template<typename R, typename... Args>
R Call(Args&&... args)const;
std::vector<const UClass*> GetParams() const; std::vector<const UClass*> GetParams() const;
}; };
template<typename T>
class Field;
/* /*
template<typename T, typename V> template<typename T, typename V>
consteval V* fetch_member_v(V T::*) { consteval V* fetch_member_v(V T::*) {

View File

@ -1,5 +1,17 @@
#include "uclass.h" #include "uclass.h"
namespace refl { namespace refl {
template<typename R, typename ...Args>
inline R FieldPtr::Call(Args&& ...args)const
{
using MethodType = R(*)(Args...);
MethodType fptr = (MethodType)data.method;
if constexpr (std::is_same_v<R, void>) {
fptr(std::forward<Args>(args)...);
}
else {
return fptr(std::forward<Args>(args)...);
}
}
bool FieldPtr::Invoke(const std::vector<ArgsView>& ArgsList)const{ bool FieldPtr::Invoke(const std::vector<ArgsView>& ArgsList)const{
auto Call = type->vtable.Call; auto Call = type->vtable.Call;
if (Call) { if (Call) {
@ -42,4 +54,58 @@ namespace refl {
} }
return{}; return{};
} }
template<typename T>
consteval int GetArgsSize() {
auto fields = T::__MakeStaticFields();
int size = 0;
for (auto& field : fields) {
size += field.data.offset;
}
return size;
}
template<typename T>
class Field {
public:
inline static char data[GetArgsSize<T>()]{};
inline static int index{0};
template<typename V>
static FieldPtr MakeField(V T::* ptr, Name name)
{
FieldPtr::Default value;
Offset offset = reinterpret_cast<std::size_t>(&(reinterpret_cast<const T*>(0)->*ptr));
FieldPtr::Data member = { offset };
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
return { name, &TypeInfo<V>::StaticClass, member, value, flag };
}
template<typename R, typename ...Args>
static FieldPtr MakeField(R(*ptr)(Args...), Name name, const sarray<ArgsValue>& args = {}) {
uint32_t flag = FIELD_METHOD_FLAG;
FieldPtr::Default value;
if (args.size() > 0) {
flag |= FIELD_METHOD_VALUE_FLAG;
static const ArgsValueList argsValue(args, &data[index]);
index += ArgsValueList::GetArgsSize(args);
value.method = []() ->std::pair<ArgsView*, int> {
return { argsValue.ptr , argsValue.num };
};
}
FieldPtr::Data method = { *(Method*)&ptr };
return { name, &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass, method, value, flag };
}
template<typename R, typename ...Args>
static FieldPtr MakeField(R(T::* ptr)(Args...), Name name, const sarray<ArgsValue>& args = {}) {
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
FieldPtr::Default value;
if (args.size() > 0) {
flag |= FIELD_METHOD_VALUE_FLAG;
static const ArgsValueList argsValue(args, &data[index]);
index += ArgsValueList::GetArgsSize(args);
value.method = []() ->std::pair<ArgsView*, int> {
return { argsValue.ptr , argsValue.num };
};
}
FieldPtr::Data method = { *(Method*)&ptr };
return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass, method, value,flag };
}
};
} }

View File

@ -1,19 +1,20 @@
#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 { !std::is_void_v<decltype(T::__BuildFields())>; }; concept _ReflCheck_UClass = requires { !std::is_void_v<decltype(T::__MakeFields())>; };
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>;
// 检查类型是否具有特定的静态成员函数
template<typename T, typename = void>
struct has_init_object : std::false_type {};
template<typename T>
struct has_init_object<T, std::void_t<decltype(&T::__InitObject)>> : std::true_type {};
//类型接口 //类型接口
template<typename T> template<typename T>
struct TypeInfoImpl; struct TypeInfoImpl;

View File

@ -119,18 +119,37 @@ namespace refl {
} }
};*/ };*/
template<typename T, typename P = void> template<typename T, typename P = void>
class UClass_Meta : public UClass { class UClass_Meta : public UClass {
public: public:
using FieldsType = decltype(T::__BuildFields()); using FieldsType = decltype(T::__MakeFields());
FieldsType Fields{ T::__BuildFields() }; FieldsType Fields{ T::__MakeFields() };
consteval UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){ UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){
if constexpr (!std::is_same_v<P, void>) { if constexpr (!std::is_same_v<P, void>) {
parent = &TypeInfo<P>::StaticClass; parent = &TypeInfo<P>::StaticClass;
} }
if constexpr (has_init_object<T>::value) {
vtable.InitObject = &T::__InitObject;
}
else {
vtable.InitObject = &UClass::InitObject<T>;
}
} }
const FieldPtr* GetField(int index) const {
return &Fields[index];
}
const FieldPtr* GetField(const Name& name, int index = 0) const{
constexpr int length = std::tuple_size<FieldsType>::value;
auto ptr = index < length ? &Fields[index] : nullptr;
for (int i = index; i < length; i++, ptr++) {
if (name == ptr->name) {
return ptr;
}
}
return nullptr;
}
}; };
//基础类型的偏特化 //基础类型的偏特化
@ -149,7 +168,6 @@ namespace refl {
template<_ReflCheck_UClass T> template<_ReflCheck_UClass T>
struct TypeInfoImpl<T> { struct TypeInfoImpl<T> {
using MyUClass = typename T::MyUClass; using MyUClass = typename T::MyUClass;
//这里如何改成 constexpr inline static MyUClass StaticClass = MyUClass();
inline constexpr static MyUClass StaticClass = MyUClass();
}; };
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include "type.h" #include "type.h"
#include "../std/sarray.h"
namespace refl { namespace refl {
class UClass; class UClass;
class FieldPtr; class FieldPtr;
@ -10,14 +11,14 @@ namespace refl {
public: public:
const void* val; const void* val;
const UClass* cls; const UClass* cls;
ArgsView() : val(nullptr), cls(nullptr) {} constexpr ArgsView() : val(nullptr), cls(nullptr) {}
//右值=>右值压入栈caller入栈地址 //右值=>右值压入栈caller入栈地址
//左值=>caller变量地址 //左值=>caller变量地址
template<typename T> template<typename T>
ArgsView(T&& v): val(&v), cls(&TypeInfo<args_type_t<T>*>::StaticClass){ constexpr ArgsView(T&& v): val(&v), cls(&TypeInfo<args_type_t<T>*>::StaticClass){
if constexpr (std::is_same_v<args_type_t<T>, void*>) { if constexpr (std::is_same_v<args_type_t<T>, void*>) {
val = v; val = v;
cls = &TypeInfo<const void*>::StaticClass; cls = &TypeInfo<args_type_t<T>>::StaticClass;
} }
else if constexpr (std::is_same_v<args_type_t<T>, ArgsView>) { else if constexpr (std::is_same_v<args_type_t<T>, ArgsView>) {
val = v.val; val = v.val;
@ -55,14 +56,16 @@ namespace refl {
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<args_type_t<T>>::StaticClass){} constexpr ArgsValue(T&& t) : ArgsView(t), type(&TypeInfo<args_type_t<T>>::StaticClass){}
}; };
struct ArgsValueList{ struct ArgsValueList{
void* data{ nullptr }; void* data;
ArgsView* ptr{nullptr}; ArgsView* ptr;
int num{ 0 }; int num{0};
ArgsValueList(const std::vector<ArgsValue>& args); bool isMemoryOwner{false};
ArgsValueList(const sarray<ArgsValue>& args,void* memory = nullptr);
~ArgsValueList(); ~ArgsValueList();
constexpr static int GetArgsSize(const sarray<ArgsValue>& args);
}; };
class ObjectView { class ObjectView {
public: public:

View File

@ -15,20 +15,20 @@ namespace refl {
} }
return false; return false;
} }
ArgsValueList::ArgsValueList(const std::vector<ArgsValue>& args) { ArgsValueList::ArgsValueList(const sarray<ArgsValue>& args, void* memory)
num = args.size(); : ptr((ArgsView*)memory),data(memory), num(args.size())
int size = num * sizeof(ArgsView); {
for (auto& arg : args) { if (!memory) {
size += arg.cls->size; isMemoryOwner = true;
data = malloc(GetArgsSize(args));
ptr = (ArgsView*)data;
} }
data = (void*)malloc(size);
ptr = (ArgsView*)data;
char* pData = ((char*)data) + num * sizeof(ArgsView); char* pData = ((char*)data) + num * sizeof(ArgsView);
for (auto& arg : args) { for (auto& arg : args) {
arg.type->InitObject(pData); arg.type->InitObject(pData);
arg.type->CopyObject(pData, arg.val); arg.type->CopyObject(pData, arg.val);
ptr->cls = arg.cls;
ptr->val = pData; ptr->val = pData;
ptr->cls = arg.cls;
ptr++; ptr++;
pData += arg.cls->size; pData += arg.cls->size;
} }
@ -42,10 +42,20 @@ namespace refl {
for (int i = 0; i < num; i++) { for (int i = 0; i < num; i++) {
ptr->cls->DestObject((void*)ptr->val); ptr->cls->DestObject((void*)ptr->val);
} }
free(data); if (isMemoryOwner) {
free(data);
}
num = 0; num = 0;
data = nullptr; data = nullptr;
} }
inline constexpr int ArgsValueList::GetArgsSize(const sarray<ArgsValue>& args)
{
int size = args.size() * sizeof(ArgsView);
for (auto& arg : args) {
size += arg.type->size;
}
return size;
}
template<typename T> template<typename T>
inline bool ObjectView::Get(const Name& name, T& t) inline bool ObjectView::Get(const Name& name, T& t)
{ {

View File

@ -1,58 +1,52 @@
#include "detail/uclass.inl" #include "detail/uclass.inl"
#include "detail/view.inl" #include "detail/view.inl"
#include "detail/field.inl" #include "detail/field.inl"
#include "std/sarray.h"
namespace refl { namespace refl {
/* 成员变量需要定义默认值吗那为什么不在initObjec里初始化?*/
template<typename T, typename Obj> template<typename T, typename Obj>
consteval FieldPtr MakeStaticField(T Obj::* ptr, Name name) { consteval FieldPtr MakeStaticField(T Obj::* ptr, Name name) {
FieldPtr::Default value; FieldPtr::Default value;
FieldPtr::Data member = { nullptr }; Offset offset = 0;
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>
consteval FieldPtr MakeStaticField(R(*ptr)(Args...), Name name/*, const std::vector<ArgsValue>& args = {}*/) { consteval FieldPtr MakeStaticField(R(*ptr)(Args...), Name name, const sarray<ArgsValue>& args = {}) {
uint32_t flag = FIELD_METHOD_FLAG; uint32_t flag = FIELD_METHOD_FLAG;
FieldPtr::Default value; FieldPtr::Default value;
/*if (args.size() > 0) { Offset offset = ArgsValueList::GetArgsSize(args);
flag |= FIELD_METHOD_VALUE_FLAG; FieldPtr::Data method = { offset };
static const ArgsValueList argsValue(args);
value.method = []() ->std::pair<ArgsView*, int> {
return { argsValue.ptr , argsValue.num };
};
}*/
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>
consteval FieldPtr MakeStaticField(R(T::* ptr)(Args...), Name name/*, const std::vector<ArgsValue>& args = {}*/) { consteval FieldPtr MakeStaticField(R(T::* ptr)(Args...), Name name, const sarray<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) { Offset offset = ArgsValueList::GetArgsSize(args);
flag |= FIELD_METHOD_VALUE_FLAG; FieldPtr::Data method = { offset };
static const ArgsValueList argsValue(args);
value.method = []() ->std::pair<ArgsView*, int> {
return { argsValue.ptr , argsValue.num };
};
}*/
//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> template<typename T>
consteval auto MakeTuple(Args&&... args) { consteval int GetStaticField(Name name) {
return std::make_tuple(args...); auto fields = T::__MakeStaticFields();
} auto first = fields.begin();
template<typename ...Args> for (auto& field : fields) {
auto MakeStaticFields(const std::tuple<Args...>& args) { if (field.name == name) {
constexpr std::size_t N = sizeof...(Args); return &field - &*first;
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; return 0;
}
template<typename T>
consteval int GetStaticField(bool(* fptr)(FieldPtr)) {
auto fields = T::__MakeStaticFields();
auto first = fields.begin();
for (auto& field : fields) {
if (fptr(field)) {
return &field - &*first;
}
}
return 0;
} }
} }

View File

@ -0,0 +1,57 @@
#pragma once
#include <concepts>
namespace refl {
template<typename T>
class sarray {
protected:
const T* m_ptr;
int m_size;
public:
constexpr sarray() :m_ptr(nullptr), m_size(0) {}
constexpr sarray(std::initializer_list<T> list) : m_ptr(list.begin()), m_size(list.size()) {}
template<int N>
constexpr sarray(const std::array<T, N>& arr):m_ptr(&arr[0]), m_size(arr.size()){}
const T* get() const{
return m_ptr;
}
const T* at(int i) const {
if (i < m_size) {
return m_ptr + i;
}
return nullptr;
}
constexpr int size() const {
return m_size;
}
constexpr const auto begin()const {
return iterator{ m_ptr };
}
constexpr const auto end() const {
return iterator{ m_ptr + m_size};
}
// Iterator class
class iterator {
private:
const T* ptr;
public:
constexpr iterator(const T* p) : ptr(p) {}
// Overload ++ to move to next element
constexpr iterator& operator++() {
++ptr;
return *this;
}
// Overload * to dereference iterator
constexpr const T& operator*() const {
return *ptr;
}
// Overload != to compare iterators
constexpr bool operator!=(const iterator& other) const {
return ptr != other.ptr;
}
};
};
}

View File

@ -32,27 +32,25 @@ struct vec3 : public vec3_parent {
x1 = x1 * 10; x1 = x1 * 10;
//cout << x1 << "::norm3" << endl; //cout << x1 << "::norm3" << endl;
} }
constexpr static auto __GetFields() { using MyUClass = UClass_Meta<vec3, vec3_parent>;
return std::tuple{ consteval static auto __MakeStaticFields() {
MakeTuple(&vec3::x, "x"), return std::array{
MakeTuple(&vec3::y, "y"), MakeStaticField(&vec3::x, "x"),
MakeTuple(&vec3::z, "z"), MakeStaticField(&vec3::y, "y"),
MakeTuple(&vec3::norm, "norm"), MakeStaticField(&vec3::z, "z"),
MakeTuple(&vec3::norm1, "norm1"), MakeStaticField(&vec3::norm, "norm", { 10,9 }),
MakeTuple(&vec3::norm2, "norm2") MakeStaticField(&vec3::norm1, "norm1", { 10 }),
MakeStaticField(&vec3::norm2, "norm2", { 10 }),
};
}
static auto __MakeFields() {
return std::array{
Field<vec3>::MakeField(&vec3::x, "x"),
Field<vec3>::MakeField(&vec3::y, "y"),
Field<vec3>::MakeField(&vec3::z, "z"),
Field<vec3>::MakeField(&vec3::norm, "norm", {10,9}),
Field<vec3>::MakeField(&vec3::norm1, "norm1", {10}),
Field<vec3>::MakeField(&vec3::norm2, "norm2", {10}),
}; };
}; };
#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,28 +1,23 @@
#include "refl/vertex.h" #include "refl/vertex.h"
union MemberMethod { #include "refl/std/sarray.h"
using F1 = int(*)(int); #include <array>
using F2 = void(*)(); struct object {
F1 f1;
F2 f2;
constexpr MemberMethod(F1 f):f1(f) {
}
constexpr MemberMethod(F2 f) :f2(f) {
}
}; };
void test() {
}
template<typename T> template<typename T>
void print(T* t) { void testInitObject(){
if constexpr (has_init_object<T>::value){
auto InitObject = &T::__InitObject;
}
} }
int main() { int main() {
//auto& cls = TypeInfo<vec3>::StaticClass; testInitObject<object>();
//int FList[3]{}; auto& cls = TypeInfo<vec3>::StaticClass;
//auto norm = MakeMethodField(&vec3::norm,"norm"); auto field = cls.GetField(GetStaticField<vec3>("norm"));
MakeStaticFields(vec3::__GetFields()); int x = 10;
auto ov = cls.New<vec3>();
ov->norm(x, x);
field->Call<void>((void*)ov, 10, x);
std::cout << "hello world\n"; std::cout << "hello world\n";
return 0; return 0;
} }