refl support overload

This commit is contained in:
ouczbs 2024-06-21 22:21:32 +08:00
parent 1c8b6c1b7c
commit d1311b829d
15 changed files with 155 additions and 166 deletions

View File

@ -29,7 +29,7 @@ namespace refl {
META_UI_FLAG = 1 << 0,
};
class UClass;
class Meta {
class MetaHelp {
public:
template<typename T, typename... Args>
static FieldPtr CtorField(char*& memory, const MethodData& data = {});

View File

@ -8,7 +8,7 @@ namespace refl {
new (mem) T(std::forward<Args>(args)...);
}
template<typename T, typename ...Args>
inline FieldPtr Meta::CtorField(char*& memory, const MethodData& data)
inline FieldPtr MetaHelp::CtorField(char*& memory, const MethodData& data)
{
MethodData method;
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_CTOR_FLAG;
@ -28,7 +28,7 @@ namespace refl {
return { FName("Ctor"), cls, method,flag};
}
template<typename T, typename Obj>
inline FieldPtr Meta::MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data)
inline FieldPtr MetaHelp::MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data)
{
MemberData member;
auto cls = &TypeInfo<T>::StaticClass;
@ -47,7 +47,7 @@ namespace refl {
return { name, cls, member,flag};
}
template<typename R, typename ...Args>
inline FieldPtr Meta::MethodField(R(*ptr)(Args...), const Name& name, char*& memory, const MethodData& data)
inline FieldPtr MetaHelp::MethodField(R(*ptr)(Args...), const Name& name, char*& memory, const MethodData& data)
{
MethodData method;
uint32_t flag = FIELD_METHOD_FLAG;
@ -67,7 +67,7 @@ namespace refl {
return { name, cls, method,flag };
}
template<typename T, typename R, typename ...Args>
inline FieldPtr Meta::MethodField(R(T::*ptr)(Args...),const Name& name, char*& memory, const MethodData& data)
inline FieldPtr MetaHelp::MethodField(R(T::*ptr)(Args...),const Name& name, char*& memory, const MethodData& data)
{
MethodData method;
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
@ -87,7 +87,7 @@ namespace refl {
return { name, cls, method,flag };
}
template<typename T, typename R, typename ...Args>
inline FieldPtr Meta::MethodField(R(T::* ptr)(Args...)const, const Name& name, char*& memory, const MethodData& data)
inline FieldPtr MetaHelp::MethodField(R(T::* ptr)(Args...)const, const Name& name, char*& memory, const MethodData& data)
{
MethodData method;
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;

View File

@ -1,13 +1,28 @@
#pragma once
#include <type_traits>
namespace refl_impl {
template<typename T>
struct MetaImpl;
template<typename T>
struct _Multy;
template<typename T, typename M>
struct _Static;
template<typename T, typename M>
struct _Meta;
}
namespace refl {
template <class T>
concept _ReflCheck_Meta = requires { typename T::MyStatic; typename T::MyUClass;};
using refl_impl::MetaImpl;
template <class MyMeta>
concept _ReflCheck_Parent = requires { typename MyMeta::Parent;} && std::is_same_v<typename MyMeta::Parent, void>;
template <class T>
concept _ReflCheck_Ctor = requires { T(); };
template <class T>
concept _ReflCheck_UClass = _ReflCheck_Meta<typename T::MyMeta>;
concept _ReflCheck_UClass = requires { typename MetaImpl<T>::MyMeta; };
template <class T>
concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor<T> && !_ReflCheck_UClass<T>;
@ -43,22 +58,6 @@ 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;

View File

@ -2,6 +2,9 @@
#include <array>
#include "uclass.h"
namespace refl {
template <class T>
concept _ReflCheck_Metas = requires(const Name & name) { MetaImpl<T>::MyMetas::GetMeta(name); };
template<_ReflCheck_Ctor T>
class UClass_Auto : public UClass {
public:
@ -20,8 +23,8 @@ namespace refl {
else {
cls.vtable.CtorObject = &MyUClass::CtorObject<T>;
}
if constexpr (requires {typename T::MyMetas; }) {
cls.vtable.GetMeta = &T::MyMetas::GetMeta;
if constexpr (_ReflCheck_Metas<T>) {
cls.vtable.GetMeta = &MetaImpl<T>::MyMetas::GetMeta;
}
return cls;
}
@ -112,21 +115,20 @@ namespace refl {
return cls;
}
};
template<typename T, typename P = void>
template<typename T, typename MyMeta>
class UClass_Meta : public UClass {
public:
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;
}
if constexpr (!std::is_same_v<P, void>) {
parent = &TypeInfo<P>::StaticClass;
if constexpr (_ReflCheck_Parent<MyMeta>) {
parent = &TypeInfo<typename MyMeta::Parent>::StaticClass;
}
if constexpr (requires(const Name & name) { T::MyMetas::GetMeta(name); }) {
vtable.GetMeta = &T::MyMetas::GetMeta;
if constexpr (_ReflCheck_Metas<T>) {
vtable.GetMeta = &MetaImpl<T>::MyMetas::GetMeta;
}
vtable.GetFields = &UClass_Meta::GetFields;
vtable.CtorObject = &UClass::CtorObject<T>;
@ -200,7 +202,7 @@ namespace refl {
};
template<_ReflCheck_UClass T>
struct TypeInfoImpl<T> {
using MyUClass = typename T::MyMeta::MyUClass;
using MyUClass = UClass_Meta<T, typename MetaImpl<T>::MyMeta>;
inline static MyUClass StaticClass = MyUClass();
};
// 函数指针类型的偏特化

View File

@ -1,19 +1,33 @@
#pragma once
#if !defined(__cppast)
#define __cppast(...)
#else
class string_view;
class string;
#endif
#define __Meta(...) __cppast(Meta,__VA_ARGS__)
#define __Meta(...) __cppast(Meta=__VA_ARGS__)
#define UPROPERTY(...) __Meta(__VA_ARGS__)
#define UFUNCTION(...) __Meta(__VA_ARGS__)
#define __vkMeta(...) __cppast(vkMeta,__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 __dxMeta(...) __cppast(dxMeta=__VA_ARGS__)
#define UPROPERTY_dx(...) __dxMeta(__VA_ARGS__)
#define UFUNCTION_dx(...) __dxMeta(__VA_ARGS__)
// 辅助宏,用于实际拼接
#define CONCATENATE(arg1, arg2) CONCATENATE_IMPL(arg1, arg2)
#define CONCATENATE_IMPL(arg1, arg2) arg1##arg2
#define MY_UNIQUE_NAME(base) CONCATENATE(base, __LINE__)
#define USING_CTOR_NAME MY_UNIQUE_NAME(__Ctor)
#define USING_FUNC_NAME MY_UNIQUE_NAME(__Func)
#define USING_OVERLOAD_CTOR(Class, ...) using USING_CTOR_NAME = Class(*)(__VA_ARGS__);
#define USING_OVERLOAD_FUNC(R, ...) using USING_FUNC_NAME = R(*)(__VA_ARGS__);
#define USING_OVERLOAD_CLASS_FUNC(R, Class, ...) using USING_FUNC_NAME = R(Class::*)(__VA_ARGS__);
namespace refl_impl {
struct Meta {};
struct vkMeta {};
struct dxMeta {};
}

View File

@ -60,42 +60,4 @@ namespace refl {
FieldPtr::Data method(offset);
return { name, cls,method,flag };
}
/*
//用处不大---------------begin
template<_ReflCheck_Meta T>
consteval int GetStaticFieldID(const Name& name) {
auto fields = T::MyStatic::__MakeStaticFields();
auto first = fields.begin();
for (auto& field : fields) {
if (field.name == name) {
return &field - &*first;
}
}
return 0;
}
template<_ReflCheck_Meta T>
consteval int GetStaticFieldID(bool(* fptr)(FieldPtr)) {
auto fields = T::MyStatic::__MakeStaticFields();
auto first = fields.begin();
for (auto& field : fields) {
if (fptr(field)) {
return &field - &*first;
}
}
return 0;
}
template<_ReflCheck_Meta T, auto name>
consteval auto GetStaticField() {
constexpr auto fields = T::MyMeta::__StaticFields();
using AutoType = decltype(name);
if constexpr (std::is_same_v<AutoType, int>) {
return std::get<name>(fields);
}
else {
constexpr auto id = GetStaticFieldID<T>(name.Data());
return std::get<id>(fields);
}
}
//用处不大---------------end
*/
}

View File

@ -10,7 +10,6 @@ struct vec3_parent {
}
};
struct vec3 : public vec3_parent {
using MyMeta = class vec3_Meta;
UPROPERTY_vk({ 1.f})
float x = 1;
UPROPERTY_dx({ 2.f})

View File

@ -4,9 +4,11 @@
#include <vector>
using std::string;
using std::vector;
using std::string_view;
namespace test {
struct Guid
{
using MyMeta = class Guid_Meta;
UPROPERTY({})
unsigned int Data1;
UPROPERTY({})
@ -18,6 +20,9 @@ struct Guid
constexpr Guid() noexcept
: Data1{ 0 }, Data2{ 0 }, Data3{ 0 }, Data4{ 0,0,0,0,0,0,0,0 }
{}
USING_OVERLOAD_CTOR(Guid, const string_view&)
UFUNCTION({}, ref = USING_CTOR_NAME)
Guid(const std::string_view& str) noexcept
: Guid{}
{
@ -48,6 +53,17 @@ struct Guid
{
return *reinterpret_cast<const GUID*>(this) != GUID_NULL;
}
USING_OVERLOAD_CLASS_FUNC(void, Guid, int)
UFUNCTION({}, ref = USING_FUNC_NAME)
void test(int x) {
}
USING_OVERLOAD_CLASS_FUNC(void, Guid, float)
UFUNCTION({}, ref = USING_FUNC_NAME)
void test(float x) {
}
operator std::string() const
{
char guid_cstr[39];
@ -64,20 +80,8 @@ struct Guid
const auto res = CoCreateGuid((GUID*)&guid);
return guid;
}
};
struct SerializedMeta
{
Guid guid;
string name;
string t_hash{};
string metadata;
};
struct ResourceBundle;
struct MetaBundle
{
vector<SerializedMeta> metadatas;
MetaBundle() = default;
};
}
#include "guid_gen.inl"

View File

@ -4,7 +4,10 @@
#include <cassert>
using namespace refl;
using namespace std;
using namespace test;
int main() {
using T = test::Guid;
auto cls = &TypeInfo<T>::StaticClass;
int x = 123;
Guid g1 = Guid::Make();
YAML::TextArchive::Register<Guid>();
@ -14,10 +17,10 @@ int main() {
auto res1 = YAML::Text_Unserialize<Guid>(rg1);
Guid g2 = res1.value();
assert(g1 == g2);
auto res2 = YAML::Text_Unserialize<MetaBundle>(rg1);
if (res2) {
MetaBundle aa = res2.value();
}
//auto res2 = YAML::Text_Unserialize<MetaBundle>(rg1);
//if (res2) {
//MetaBundle aa = res2.value();
//}
std::cout << rg1 << std::endl;
YAML::Node primes = YAML::Load("[2, 3, 5, 7, 11]");
for (std::size_t i = 0; i < primes.size(); i++) {

View File

@ -2,6 +2,7 @@ set_languages("cxx20")
add_requires("UTemplate")
target("zlib")
set_kind("static")
set_basename("myzlib")
add_packages("UTemplate", {public = true})
add_defines("YAML_CPP_STATIC_DEFINE", {public = true})
add_includedirs("include", {public = true})

View File

@ -14,7 +14,6 @@ namespace engineapi
}
struct Guid
{
using MyMeta = class Guid_Meta;
UPROPERTY({})
unsigned int Data1;
UPROPERTY({})
@ -23,10 +22,13 @@ namespace engineapi
unsigned short Data3;
UPROPERTY({})
unsigned char Data4[8];
Guid() noexcept
: Data1{ 0 }, Data2{ 0 }, Data3{ 0 }, Data4{ 0,0,0,0,0,0,0,0 }
{}
UFUNCTION({})
USING_OVERLOAD_CTOR(Guid, const string_view&)
UFUNCTION({}, ref = USING_CTOR_NAME)
Guid(const string_view& str) noexcept
: Guid{}
{

View File

@ -11,7 +11,6 @@ namespace engineapi
using zstd::hash_table;
using Ubpa::Name;
using Ubpa::NameID;
namespace fs = std::filesystem;
struct PackagePath {
string_view name;
string_view path;
@ -34,8 +33,10 @@ namespace engineapi
return false;
}
Name GetExtension() {
fs::path p(this->path);
return Name(p.extension().string());
size_t pos = path.rfind('.');
if (pos != std::string::npos)
return path.substr(pos);
return "";
}
string AbsolutePath();
static string AbsolutePath(string_view path) {

View File

@ -1,5 +1,6 @@
#include "resource_manager.inl"
#include "file_manager.h"
#include "yaml/yaml.h"
namespace engineapi {
void ResourceManager::Init()
{
@ -29,6 +30,11 @@ namespace engineapi {
MetaBundle ResourceManager::GetMeta(PackagePath path)
{
string text = FileManager::LoadTextFile(path.AbsolutePath() + ".meta");
auto res = YAML::Text_Unserialize<MetaBundle>(text);
if (res) {
return res.value();
}
return {};
}

View File

@ -8,12 +8,10 @@
namespace engineapi {
struct Vertex {};
struct PosVertex : public Vertex {
using MyMetas = class PosVertex_MultyMeta;
UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT })
Vector3 Position = {};
};
struct TexVertex : public Vertex {
using MyMetas = class TexVertex_MulytMeta;
UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT })
Vector3 Position = {};
UPROPERTY_vk()
@ -23,7 +21,6 @@ namespace engineapi {
};
struct BoneVertex : public Vertex
{
using MyMetas = class BoneVertex_MulytMeta;
UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT })
Vector3 Position = {};
UPROPERTY_vk()

View File

@ -3,8 +3,7 @@
#include "asset/file_manager.h"
#include "asset/resource_manager.h"
#include "vulkanapi/loader/vulkan_glsl_loader.h"
#include "zlog.h"
#include "yaml/yaml.h"
using namespace engineapi;
int main(int argc, char** argv)
{