refl support multymeta

This commit is contained in:
ouczbs 2024-04-29 15:00:09 +08:00
parent 9aa69217e1
commit 9b5b3d61a7
8 changed files with 84 additions and 42 deletions

View File

@ -31,9 +31,6 @@ namespace refl {
class UClass; class UClass;
class Meta { class Meta {
public: public:
UClass* cls;
uint32_t flag{ 0 };
template<typename T, typename Obj> template<typename T, typename Obj>
static FieldPtr MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data = {}); static FieldPtr MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data = {});

View File

@ -11,10 +11,6 @@ namespace refl {
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>
struct TypeInfoImpl;
template<typename T> template<typename T>
struct real_type { struct real_type {
using type = std::remove_cv_t<T>; using type = std::remove_cv_t<T>;
@ -47,6 +43,26 @@ namespace refl {
template<typename T> template<typename T>
using args_type_t = args_type<std::remove_cv_t<T>>::type; using args_type_t = args_type<std::remove_cv_t<T>>::type;
// meta_type 的主模板定义
template<typename T>
struct meta_type {
using type = typename T::MyMeta;
};
// 对满足 _ReflCheck_Meta 概念的类型进行重载
template<_ReflCheck_Meta T>
struct meta_type<T> {
using type = T;
};
// 类型别名模板
template<typename T>
using meta_type_t = typename meta_type<T>::type;
//类型接口
template<typename T>
struct TypeInfoImpl;
template<typename T> template<typename T>
using TypeInfo = TypeInfoImpl<real_type_t<T>>; using TypeInfo = TypeInfoImpl<real_type_t<T>>;
} }

View File

@ -24,6 +24,9 @@ namespace refl {
else { else {
cls.flag = CLASS_TRIVIAL_FLAG; cls.flag = CLASS_TRIVIAL_FLAG;
} }
if constexpr (requires {typename T::MyMetas; }) {
cls.vtable.GetMeta = &T::MyMetas::GetMeta;
}
return cls; return cls;
} }
void Set(void* ptr,const T& t) { void Set(void* ptr,const T& t) {
@ -120,8 +123,9 @@ 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::MyMeta::__MakeFields()); using MyMeta = meta_type_t<T>;
FieldsType Fields{ T::MyMeta::__MakeFields() }; using FieldsType = decltype(MyMeta::__MakeFields());
FieldsType Fields{ MyMeta::__MakeFields() };
UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){ UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){
if constexpr (std::is_trivially_copyable_v<T>) { if constexpr (std::is_trivially_copyable_v<T>) {
flag = CLASS_TRIVIAL_FLAG; flag = CLASS_TRIVIAL_FLAG;
@ -135,8 +139,8 @@ namespace refl {
else { else {
vtable.InitObject = &UClass::InitObject<T>; vtable.InitObject = &UClass::InitObject<T>;
} }
if constexpr (requires(const Name & name) { T::__GetMeta(name); }) { if constexpr (requires(const Name & name) { T::MyMetas::GetMeta(name); }) {
vtable.GetMeta = &T::__GetMeta; vtable.GetMeta = &T::MyMetas::GetMeta;
} }
vtable.GetField = &UClass_Meta::GetField; vtable.GetField = &UClass_Meta::GetField;
} }

View File

@ -1,4 +1,16 @@
#pragma once #pragma once
#if !defined(__cppast) #if !defined(__cppast)
#define __cppast(...) #define __cppast(...)
#endif #endif
#define __Meta(...) __cppast(Meta,__VA_ARGS__)
#define UPROPERTY(...) __Meta(__VA_ARGS__)
#define UFUNCTION(...) __Meta(__VA_ARGS__)
#define __vkMeta(...) __cppast(vkMeta,__VA_ARGS__)
#define UPROPERTY_vk(...) __vkMeta(__VA_ARGS__)
#define UFUNCTION_vk(...) __vkMeta(__VA_ARGS__)
#define __dxMeta(...) __cppast(dxMeta,__VA_ARGS__)
#define UPROPERTY_dx(...) __dxMeta(__VA_ARGS__)
#define UFUNCTION_dx(...) __dxMeta(__VA_ARGS__)

View File

@ -1,6 +1,3 @@
#include "vertex.h" #include "vertex.h"
#include "uimeta_vertex_gen.inl" #include "vkmeta_vertex_gen.inl"
const UClass* vec3::__GetMeta(const Name& name) #include "dxmeta_vertex_gen.inl"
{
return fetch_meta_uclass<vec3>(name);
}

View File

@ -9,25 +9,17 @@ struct vec3_parent {
//cout << x2 << "vec3_parent::norm" << endl; //cout << x2 << "vec3_parent::norm" << endl;
} }
}; };
struct vec4 {
string name{ "hello" };
};
template<typename T>
const UClass* fetch_meta_uclass(const Name& name) {
return &TypeInfo<typename T::MyUIMeta>::StaticClass;
};
struct vec3 : public vec3_parent { struct vec3 : public vec3_parent {
using MyMeta = class vec3_Meta; using MyMeta = class vec3_Meta;
using MyUIMeta = class vec3_UIMeta; UPROPERTY_vk({ 1.f})
__cppast(UIMeta = { 1.f})
float x = 1; float x = 1;
__cppast(Meta = { 2.f}) UPROPERTY_dx({ 2.f})
float y = 2; float y = 2;
__cppast(Meta = { 5.f}) UPROPERTY({ 5.f})
float z = 3; float z = 3;
__cppast(Meta = { "hello meta"}) UPROPERTY({ "hello meta"})
string name = "???"; string name = "???";
__cppast(Meta = { {3,4} }) UFUNCTION({ {3,4} })
int norm(int x1, int& x2)override { int norm(int x1, int& x2)override {
int tmp = x1 * 2 + 1; int tmp = x1 * 2 + 1;
x1 = x2; x1 = x2;
@ -35,7 +27,7 @@ struct vec3 : public vec3_parent {
return x2; return x2;
//cout << x2 << "vec3::norm" << endl; //cout << x2 << "vec3::norm" << endl;
} }
__cppast(Meta = {}) UFUNCTION({})
virtual float norm1(int& x1) { virtual float norm1(int& x1) {
x1 = x1 * x * y * z; x1 = x1 * x * y * z;
x = x1; x = x1;
@ -44,15 +36,14 @@ struct vec3 : public vec3_parent {
//cout << x1 << "::norm1" << endl; //cout << x1 << "::norm1" << endl;
return x1; return x1;
} }
__cppast(Meta = {}) UFUNCTION({})
static void norm2(int x1 = 10) { static void norm2(int x1 = 10) {
cout << x1 << "::norm2" << endl; cout << x1 << "::norm2" << endl;
} }
__cppast(Meta = {}) UFUNCTION({})
static void norm3(int x1 = 10) { static void norm3(int x1 = 10) {
x1 = x1 * 10; x1 = x1 * 10;
cout << x1 << "::norm3" << endl; cout << x1 << "::norm3" << endl;
} }
static const UClass* __GetMeta(const Name& name);
}; };
#include "meta_vertex_gen.inl" #include "vertex_gen.inl"

14
engine/xmake/gen/macro.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#if !defined(__cppast)
#define __cppast(...)
#endif
#define __Meta(...) __cppast(Meta,__VA_ARGS__)
#define UPROPERTY(...) __Meta(__VA_ARGS__)
#define UFUNCTION(...) __Meta(__VA_ARGS__)
/*
#define __vkMeta(...) __cppast(vkMeta,...)
#define UPROPERTY_vk(...) __vkMeta(...)
#define UFUNCTION_vk(...) __vkMeta(...)
*/

View File

@ -1,21 +1,30 @@
import("core.project.depend") import("core.project.depend")
function cmd_compile(genfile, sourcefile, template) function cmd_compile(genfile, sourcefile, template, macro, define)
print(os.programdir())
import("find_sdk") import("find_sdk")
local meta = find_sdk.find_my_program("refl") local meta = find_sdk.find_my_program("refl")
template = template or path.join(meta.sdkdir, "template/refl.liquid") template = template or path.join(meta.sdkdir, "template")
argv = {"build", sourcefile, "-o", genfile, "-t", template} if not macro then --优先使用库定义
macro = path.join(os.projectdir(), "engine/3rdparty/zlib/include/refl/macro.h")
if not os.exists(macro) then
macro = path.join(os.curdir(), "macro.h")
end
end
argv = {"build", sourcefile, "-o", genfile, "-t", template, "-m", macro}
if define then
table.insert(argv, "-d")
table.insert(argv, define)
end
print("cmd_meta_compile", genfile) print("cmd_meta_compile", genfile)
os.runv(meta.program, argv) os.runv(meta.program, argv)
return argv return argv
end end
function _listen_gen_file(target, batch, template) function _listen_gen_file(target, batch, template, macro, define)
genfile, sourcefile = batch[1], batch[2] genfile, sourcefile = batch[1], batch[2]
local dependfile = target:dependfile(genfile) local dependfile = target:dependfile(genfile)
depend.on_changed( depend.on_changed(
function() function()
cmd_compile(batch[1], batch[2], template) cmd_compile(batch[1], batch[2], template, macro, define)
end, end,
{dependfile = dependfile, files = sourcefile} {dependfile = dependfile, files = sourcefile}
) )
@ -26,9 +35,11 @@ function gen(target)
return return
end end
local template = target:extraconf("rules", "c++.codegen", "template") local template = target:extraconf("rules", "c++.codegen", "template")
local macro = target:extraconf("rules", "c++.codegen", "macro")
local define = target:extraconf("rules", "c++.codegen", "define")
for _, batch in ipairs(gen_batch) do for _, batch in ipairs(gen_batch) do
if batch[2] then if batch[2] then
_listen_gen_file(target, batch, template) _listen_gen_file(target, batch, template, macro, define)
end end
end end
end end