This commit is contained in:
ouczbs 2024-06-25 20:26:46 +08:00
parent dd880d4972
commit 87f2eb7708
16 changed files with 135 additions and 83 deletions

View File

@ -2,17 +2,28 @@
#include "any.h" #include "any.h"
#include <unordered_map> #include <unordered_map>
namespace refl { namespace refl {
using UClassPair = std::pair<const UClass*, const UClass*>;
using ConvertFunc = bool (*)(Any&, const Any&); // 自定义哈希函数
using ConvertMap = std::unordered_map<const UClass*, ConvertFunc>; struct UClassPairHash {
std::size_t operator()(const UClassPair& pair) const {
std::hash<const UClass*> ptr_hash;
return ptr_hash(pair.first) ^ (ptr_hash(pair.second) << 1);
}
};
struct UClassPairEqual {
bool operator()(const UClassPair& lhs, const UClassPair& rhs) const {
return lhs.first == rhs.first && lhs.second == rhs.second;
}
};
using ConvertFunc = bool (*)(Any& to, const Any& from);
using ConvertMap = std::unordered_map<UClassPair, ConvertFunc, UClassPairHash, UClassPairEqual>;
class Convert { class Convert {
protected: protected:
static ConvertMap BuildClassMap(); static ConvertMap BuildClassMap();
template<typename From, typename To>
static bool ConvertTo(Any& to, const Any& from);
public: public:
static bool ToInt32(Any& dst, const Any& src); static bool Construct(Any& to,const Any& from);
static bool ToFloat(Any& dst, const Any& src);
static bool ToString(Any& dst,const Any& src);
static bool Construct(Any& dst, const Any& src);
inline static ConvertMap ClassMap = BuildClassMap(); inline static ConvertMap ClassMap = BuildClassMap();
}; };
} }

View File

@ -2,48 +2,48 @@
#include <string> #include <string>
#include "convert.h" #include "convert.h"
namespace refl { namespace refl {
inline bool Convert::ToString(Any& dst, const Any& src) template <typename To, typename From>
{ inline bool Convert::ConvertTo(Any& to, const Any& from) {
if (src.cls == &TypeInfo<char>::StaticClass) { if constexpr (std::is_same_v<To, std::string>) {
std::construct_at(dst.CastTo<std::string*>(), src.CastTo<const char*>()); if constexpr (std::is_same_v<From, char>) {
return true; std::construct_at(to.CastTo<To*>(), from.CastTo<From*>());
} return true;
return false; }
}
inline bool Convert::ToInt32(Any& dst, const Any& src)
{
if (src.cls == &TypeInfo<float>::StaticClass) {
*dst.CastTo<int*>() = *src.CastTo<float*>();
return true;
}
return false;
}
inline bool Convert::ToFloat(Any& dst, const Any& src)
{
if (src.cls == &TypeInfo<int>::StaticClass) {
*dst.CastTo<float*>() = *src.CastTo<int*>();
return true;
}
return false;
}
inline bool Convert::Construct(Any& dst, const Any& src)
{
if (dst.cls->Construct((void*)dst.ptr, src)) {
return true;
}
auto it = ClassMap.find(dst.cls);
if (it == ClassMap.end()) {
return false; return false;
} }
return it->second(dst, src); else if constexpr (std::is_arithmetic_v<To>) {
if constexpr (std::is_arithmetic_v<From>) {
*to.CastTo<To*>() = (To)*from.CastTo<From*>();
return true;
}
return false;
}
return false;
} }
inline ConvertMap Convert::BuildClassMap() inline ConvertMap Convert::BuildClassMap()
{ {
ConvertMap classMap; ConvertMap classMap;
classMap.emplace(&TypeInfo<std::string>::StaticClass, &ToString); #define RegisterToFrom(To, From) classMap.emplace(std::make_pair(&TypeInfo<To>::StaticClass, &TypeInfo<From>::StaticClass), &Convert::ConvertTo<To, From>);\
classMap.emplace(&TypeInfo<int>::StaticClass, &ToInt32); classMap.emplace(std::make_pair(&TypeInfo<From>::StaticClass, &TypeInfo<To>::StaticClass), &Convert::ConvertTo<From, To>)
classMap.emplace(&TypeInfo<uint32_t>::StaticClass, &ToInt32);
classMap.emplace(&TypeInfo<float>::StaticClass, &ToFloat); RegisterToFrom(int, uint32_t);
RegisterToFrom(int, uint16_t);
RegisterToFrom(int, float);
RegisterToFrom(int, double);
RegisterToFrom(float, uint32_t);
RegisterToFrom(float, double);
RegisterToFrom(std::string, char);
#undef RegisterToFrom
return classMap; return classMap;
} }
inline bool Convert::Construct(Any& to,const Any& from)
{
if (to.Construct(from))
return true;
auto it = ClassMap.find(std::make_pair(to.cls, from.cls));
if (it != ClassMap.end()) {
return it->second(to, from);
}
return false;
}
} }

View File

@ -11,6 +11,22 @@ namespace refl {
using MethodType = R(*)(Args...); using MethodType = R(*)(Args...);
return MethodType{ nullptr }; return MethodType{ nullptr };
} }
template<typename Tuple, int Index>
consteval int fetch_tuple_elm_size(int first = 0) {
using T = std::tuple_element<Index, Tuple>::type;
if constexpr (std::is_same_v<T, void>) {
return 0;
}
else {
return Index >= first ? sizeof(T) : 0;
}
}
template<typename Tuple, std::size_t... Is>
consteval int fetch_tuple_size(std::index_sequence<Is...>, int first = 0) {
int size = 0;
(..., (size += fetch_tuple_elm_size<Tuple, Is>(first)));
return size;
}
template<typename T> template<typename T>
consteval int fetch_meta_size() { consteval int fetch_meta_size() {
auto fields = T::__MakeStaticFields(); auto fields = T::__MakeStaticFields();
@ -32,7 +48,7 @@ namespace refl {
class MetaHelp { class MetaHelp {
public: public:
template<typename T, typename... Args> template<typename T, typename... Args>
static FieldPtr CtorField(char*& memory, const MethodData& data = {}); static FieldPtr CtorField(T(*ptr)(Args...), char*& memory, const MethodData& data = {});
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

@ -8,7 +8,7 @@ namespace refl {
new (mem) T(std::forward<Args>(args)...); new (mem) T(std::forward<Args>(args)...);
} }
template<typename T, typename ...Args> template<typename T, typename ...Args>
inline FieldPtr MetaHelp::CtorField(char*& memory, const MethodData& data) inline FieldPtr MetaHelp::CtorField(T(*ptr)(Args...), char*& memory, const MethodData& data)
{ {
MethodData method; MethodData method;
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_CTOR_FLAG; uint32_t flag = FIELD_MEMBER_FLAG | FIELD_CTOR_FLAG;

View File

@ -12,9 +12,6 @@ namespace refl_impl {
template<typename T, typename M> template<typename T, typename M>
struct _Meta; struct _Meta;
template<typename T>
struct _ContainerMeta;
} }
namespace refl { namespace refl {
// 定义一个模板结构体用于检测是否为 数组 // 定义一个模板结构体用于检测是否为 数组
@ -53,7 +50,12 @@ namespace refl {
concept is_tuple_v = is_tuple<T>::value; concept is_tuple_v = is_tuple<T>::value;
template<typename T> template<typename T>
concept is_container_v = !is_array<T>::value && !std::is_same_v<T, std::string> && requires(T a) { concept is_string_v = requires(T t) {
{ static_cast<std::string>(t) } -> std::convertible_to<std::string>;
};
template<typename T>
concept is_container_v = !is_array<T>::value && !is_string_v<T> && requires(T a) {
{ a.begin() } -> std::input_iterator; { a.begin() } -> std::input_iterator;
{ a.end() } -> std::input_iterator; { a.end() } -> std::input_iterator;
}; };
@ -114,4 +116,10 @@ namespace refl {
template<typename T> template<typename T>
using TypeInfo = TypeInfoImpl<real_type_t<T>>; using TypeInfo = TypeInfoImpl<real_type_t<T>>;
}
namespace refl {
constexpr static std::array<std::string_view, 16> IndexNames = {
"1", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "11", "12", "13", "14", "15", "16"
};
} }

View File

@ -93,7 +93,7 @@ namespace refl {
} }
if constexpr (sizeof...(Args) > 0) { if constexpr (sizeof...(Args) > 0) {
auto ptr = &UList[1]; auto ptr = &UList[1];
(..., (*ptr = &TypeInfo<args_type_t<Args>>::StaticClass, ptr++)); (..., (*ptr = &TypeInfo<Args>::StaticClass, ptr++));
} }
} }
public: public:
@ -107,10 +107,6 @@ namespace refl {
return cls; return cls;
} }
}; };
constexpr static std::array<std::string_view, 16> IndexNames = {
"1", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "11", "12", "13", "14", "15", "16"
};
template<typename... Types> template<typename... Types>
class UClass_Tuple : public UClass { class UClass_Tuple : public UClass {
using UClass::UClass; using UClass::UClass;
@ -255,12 +251,12 @@ namespace refl {
pit.val = &*it; pit.val = &*it;
} }
static void add(iterator* pit) { static void add(iterator* pit) {
auto it = ++(*(T::iterator*)pit); auto it = ++(*(typename T::iterator*)pit);
memcpy(pit, &it, sizeof(it)); memcpy(pit, &it, sizeof(it));
pit->val = &*it; pit->val = &*it;
} }
static void sub(iterator* pit) { static void sub(iterator* pit) {
auto it = --(*(T::iterator*)pit); auto it = --(*(typename T::iterator*)pit);
memcpy(pit, &it, sizeof(it)); memcpy(pit, &it, sizeof(it));
pit->val = &*it; pit->val = &*it;
} }

View File

@ -12,6 +12,8 @@ namespace refl {
int Size(); int Size();
const sarray<Any> ToSArray(); const sarray<Any> ToSArray();
constexpr static Offset GetArgsSize(const sarray<Any>& args, const sarray<const UClass*>& params); constexpr static Offset GetArgsSize(const sarray<Any>& args, const sarray<const UClass*>& params);
template<typename...Args>
consteval static Offset GetArgsSize(const sarray<Any>& args);
}; };
class AnyView : public Any{ class AnyView : public Any{
public: public:

View File

@ -128,6 +128,18 @@ namespace refl {
} }
return offset; return offset;
} }
template<typename ...Args>
inline consteval Offset AnyArgs::GetArgsSize(const sarray<Any>& args)
{
constexpr int N = sizeof...(Args);
if (args.size() == 0 || N < args.size() + 1) {
return 0;
}
int first = N - args.size();
Offset offset = args.size() * sizeof(Any);
offset += fetch_tuple_size<std::tuple<Args...>>(std::index_sequence_for<Args...>{}, first);
return 0;
}
template<typename T> template<typename T>
inline bool AnyView::Get(const Name& name, T& t) inline bool AnyView::Get(const Name& name, T& t)
{ {

View File

@ -26,6 +26,14 @@
#define USING_OVERLOAD_CTOR(Class, ...) using USING_CTOR_NAME = Class(*)(__VA_ARGS__); #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_FUNC(R, ...) using USING_FUNC_NAME = R(*)(__VA_ARGS__);
#define USING_OVERLOAD_CLASS_FUNC(R, Class, ...) using USING_FUNC_NAME = R(Class::*)(__VA_ARGS__); #define USING_OVERLOAD_CLASS_FUNC(R, Class, ...) using USING_FUNC_NAME = R(Class::*)(__VA_ARGS__);
/*
struct vec3{
USING_OVERLOAD_CTOR(vec3)
UFUNCTION({},ref = USING_CTOR_NAME)
vec3(){}
}
*/
namespace refl_impl { namespace refl_impl {
struct Meta {}; struct Meta {};
struct vkMeta {}; struct vkMeta {};

View File

@ -8,15 +8,14 @@
#include "macro.h" #include "macro.h"
namespace refl { namespace refl {
template<typename T, typename... Args> template<typename T, typename... Args>
consteval FieldPtr StaticCtorField(const MethodData& data = {}) { consteval FieldPtr StaticCtorField(T(*ptr)(Args...), const MethodData& data = {}) {
uint32_t flag = FIELD_CTOR_FLAG; uint32_t flag = FIELD_CTOR_FLAG;
auto cls = &TypeInfo<void(*)(void*, real_type_t<Args>...)>::StaticClass; Offset offset = AnyArgs::GetArgsSize<void,void*, Args...>(data.value);
Offset offset = AnyArgs::GetArgsSize(data.value, cls->GetParams());
if (data.meta.IsValid()) { if (data.meta.IsValid()) {
offset += data.meta.Size(); offset += data.meta.Size();
} }
FieldPtr::Data method(offset); FieldPtr::Data method(offset);
return {FName("Ctor"),cls,method, flag}; return {FName("Ctor"), nullptr, method, flag};
} }
template<typename T, typename Obj> template<typename T, typename Obj>
consteval FieldPtr StaticMemberField(T Obj::* ptr, const Name& name, const MemberData& data = {}) { consteval FieldPtr StaticMemberField(T Obj::* ptr, const Name& name, const MemberData& data = {}) {
@ -26,39 +25,36 @@ namespace refl {
} }
FieldPtr::Data member(offset); FieldPtr::Data member(offset);
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
return { name,&TypeInfo<T>::StaticClass, member,flag}; return { name, nullptr , member , flag};
} }
template<typename R, typename ...Args> template<typename R, typename ...Args>
consteval FieldPtr StaticMethodField(R(*ptr)(Args...), const Name& name, const MethodData& data = {}) { consteval FieldPtr StaticMethodField(R(*ptr)(Args...), const Name& name, const MethodData& data = {}) {
uint32_t flag = FIELD_METHOD_FLAG; uint32_t flag = FIELD_METHOD_FLAG;
auto cls = &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass; Offset offset = AnyArgs::GetArgsSize<R, Args...>(data.value);
Offset offset = AnyArgs::GetArgsSize(data.value, cls->GetParams());
if (data.meta.IsValid()) { if (data.meta.IsValid()) {
offset += data.meta.Size(); offset += data.meta.Size();
} }
FieldPtr::Data method(offset); FieldPtr::Data method(offset);
return { name,cls,method, flag }; return { name,nullptr,method, flag };
} }
template<typename T, typename R, typename ...Args> template<typename T, typename R, typename ...Args>
consteval FieldPtr StaticMethodField(R(T::* ptr)(Args...), const Name& name, const MethodData& data = {}) { consteval FieldPtr StaticMethodField(R(T::* ptr)(Args...), const Name& name, const MethodData& data = {}) {
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
auto cls = &TypeInfo<real_type_t<R>(*)(const void*, real_type_t<Args>...)>::StaticClass; Offset offset = AnyArgs::GetArgsSize<R,void*, Args...>(data.value);
Offset offset = AnyArgs::GetArgsSize(data.value, cls->GetParams());
if (data.meta.IsValid()) { if (data.meta.IsValid()) {
offset += data.meta.Size(); offset += data.meta.Size();
} }
FieldPtr::Data method(offset); FieldPtr::Data method(offset);
return { name, cls,method,flag }; return { name, nullptr,method,flag };
} }
template<typename T, typename R, typename ...Args> template<typename T, typename R, typename ...Args>
consteval FieldPtr StaticMethodField(R(T::* ptr)(Args...)const, const Name& name, const MethodData& data = {}) { consteval FieldPtr StaticMethodField(R(T::* ptr)(Args...)const, const Name& name, const MethodData& data = {}) {
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
auto cls = &TypeInfo<real_type_t<R>(*)(const void*, real_type_t<Args>...)>::StaticClass; Offset offset = AnyArgs::GetArgsSize<R, void*, Args...>(data.value);
Offset offset = AnyArgs::GetArgsSize(data.value, cls->GetParams());
if (data.meta.IsValid()) { if (data.meta.IsValid()) {
offset += data.meta.Size(); offset += data.meta.Size();
} }
FieldPtr::Data method(offset); FieldPtr::Data method(offset);
return { name, cls,method,flag }; return { name, nullptr, method,flag };
} }
} }

View File

@ -1 +1,3 @@
#include "vertex.h" #include "vertex.h"
#include "vkmeta_vertex_gen.inl"
#include "dxmeta_vertex_gen.inl"

View File

@ -18,14 +18,20 @@ struct vec3 : public vec3_parent {
uint32_t z = 3; uint32_t z = 3;
UPROPERTY({ "hello meta"}) UPROPERTY({ "hello meta"})
string name = "???a"; string name = "???a";
UFUNCTION({}) USING_OVERLOAD_CTOR(vec3)
UFUNCTION({},ref = USING_CTOR_NAME)
vec3() { vec3() {
} }
UFUNCTION({1, 2.f, 3.f}) USING_OVERLOAD_CTOR(vec3,float, int , uint32_t)
UFUNCTION({1, 2.f, 3.f}, ref = USING_CTOR_NAME)
vec3(float x1, int y1, uint32_t z1) { vec3(float x1, int y1, uint32_t z1) {
x = x1; x = x1;
y = y1; y = y1;
z = z1; z = z1;
} }
UFUNCTION()
vec3 make() {
return vec3{};
}
}; };
#include "vertex_gen.inl" #include "vertex_gen.inl"

View File

@ -7,7 +7,7 @@ using std::vector;
struct Guid struct Guid
{ {
using MyMeta = class Guid_Meta; using MyMeta = class Guid_Meta;
UPROPERTY({}) UPROPERTY({1})
unsigned int Data1; unsigned int Data1;
UPROPERTY({}) UPROPERTY({})
unsigned short Data2; unsigned short Data2;
@ -59,9 +59,6 @@ struct Guid
return std::string{ guid_cstr }; return std::string{ guid_cstr };
} }
UFUNCTION({}) UFUNCTION({})
bool test(int a, float* b, char** c){
return false;
}
static Guid Make() static Guid Make()
{ {
Guid guid; Guid guid;

View File

@ -38,5 +38,4 @@ namespace engineapi {
void AddBoneData(uint32_t boneID, float weight); void AddBoneData(uint32_t boneID, float weight);
}; };
}; };
#include "vertex_gen.inl" #include "vertex_gen.inl"

View File

@ -12,7 +12,6 @@
#include "wrapper/descriptorpool.h" #include "wrapper/descriptorpool.h"
#include "window.h" #include "window.h"
#include "zlog.h" #include "zlog.h"
Vector3 vec3;
#include "vkmeta_vertex_gen.inl" #include "vkmeta_vertex_gen.inl"
namespace vulkanapi { namespace vulkanapi {
RenderVulkanAPI::RenderVulkanAPI() RenderVulkanAPI::RenderVulkanAPI()

View File

@ -1,12 +1,12 @@
rule("glsl.env") rule("glsl.env")
after_load(function (target) after_load(function (target)
import("glsl_compiler")(target) --import("glsl_compiler")(target)
end) end)
on_config(function (target) on_config(function (target)
import("glsl_compiler").compile(target) --import("glsl_compiler").compile(target)
end) end)
-- before load -- before load
before_build(function (target) before_build(function (target)
os.cd("$(projectdir)/engine/assets/shader") --os.cd("$(projectdir)/engine/assets/shader")
os.execv("gen_glsl.bat") --os.execv("gen_glsl.bat")
end ) end )