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 Meta {
public:
UClass* cls;
uint32_t flag{ 0 };
template<typename T, typename Obj>
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>
concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor<T> && !_ReflCheck_UClass<T>;
//类型接口
template<typename T>
struct TypeInfoImpl;
template<typename T>
struct real_type {
using type = std::remove_cv_t<T>;
@ -47,6 +43,26 @@ namespace refl {
template<typename T>
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>
using TypeInfo = TypeInfoImpl<real_type_t<T>>;
}

View File

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

View File

@ -2,3 +2,15 @@
#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,__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 "uimeta_vertex_gen.inl"
const UClass* vec3::__GetMeta(const Name& name)
{
return fetch_meta_uclass<vec3>(name);
}
#include "vkmeta_vertex_gen.inl"
#include "dxmeta_vertex_gen.inl"

View File

@ -9,25 +9,17 @@ struct vec3_parent {
//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 {
using MyMeta = class vec3_Meta;
using MyUIMeta = class vec3_UIMeta;
__cppast(UIMeta = { 1.f})
UPROPERTY_vk({ 1.f})
float x = 1;
__cppast(Meta = { 2.f})
UPROPERTY_dx({ 2.f})
float y = 2;
__cppast(Meta = { 5.f})
UPROPERTY({ 5.f})
float z = 3;
__cppast(Meta = { "hello meta"})
UPROPERTY({ "hello meta"})
string name = "???";
__cppast(Meta = { {3,4} })
UFUNCTION({ {3,4} })
int norm(int x1, int& x2)override {
int tmp = x1 * 2 + 1;
x1 = x2;
@ -35,7 +27,7 @@ struct vec3 : public vec3_parent {
return x2;
//cout << x2 << "vec3::norm" << endl;
}
__cppast(Meta = {})
UFUNCTION({})
virtual float norm1(int& x1) {
x1 = x1 * x * y * z;
x = x1;
@ -44,15 +36,14 @@ struct vec3 : public vec3_parent {
//cout << x1 << "::norm1" << endl;
return x1;
}
__cppast(Meta = {})
UFUNCTION({})
static void norm2(int x1 = 10) {
cout << x1 << "::norm2" << endl;
}
__cppast(Meta = {})
UFUNCTION({})
static void norm3(int x1 = 10) {
x1 = x1 * 10;
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")
function cmd_compile(genfile, sourcefile, template)
print(os.programdir())
function cmd_compile(genfile, sourcefile, template, macro, define)
import("find_sdk")
local meta = find_sdk.find_my_program("refl")
template = template or path.join(meta.sdkdir, "template/refl.liquid")
argv = {"build", sourcefile, "-o", genfile, "-t", template}
template = template or path.join(meta.sdkdir, "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)
os.runv(meta.program, argv)
return argv
end
function _listen_gen_file(target, batch, template)
function _listen_gen_file(target, batch, template, macro, define)
genfile, sourcefile = batch[1], batch[2]
local dependfile = target:dependfile(genfile)
depend.on_changed(
function()
cmd_compile(batch[1], batch[2], template)
cmd_compile(batch[1], batch[2], template, macro, define)
end,
{dependfile = dependfile, files = sourcefile}
)
@ -26,9 +35,11 @@ function gen(target)
return
end
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
if batch[2] then
_listen_gen_file(target, batch, template)
_listen_gen_file(target, batch, template, macro, define)
end
end
end