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 <unordered_map>
namespace refl {
using ConvertFunc = bool (*)(Any&, const Any&);
using ConvertMap = std::unordered_map<const UClass*, ConvertFunc>;
using UClassPair = std::pair<const UClass*, const UClass*>;
// 自定义哈希函数
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 {
protected:
static ConvertMap BuildClassMap();
template<typename From, typename To>
static bool ConvertTo(Any& to, const Any& from);
public:
static bool ToInt32(Any& dst, const Any& src);
static bool ToFloat(Any& dst, const Any& src);
static bool ToString(Any& dst,const Any& src);
static bool Construct(Any& dst, const Any& src);
static bool Construct(Any& to,const Any& from);
inline static ConvertMap ClassMap = BuildClassMap();
};
}

View File

@ -2,48 +2,48 @@
#include <string>
#include "convert.h"
namespace refl {
inline bool Convert::ToString(Any& dst, const Any& src)
{
if (src.cls == &TypeInfo<char>::StaticClass) {
std::construct_at(dst.CastTo<std::string*>(), src.CastTo<const char*>());
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()) {
template <typename To, typename From>
inline bool Convert::ConvertTo(Any& to, const Any& from) {
if constexpr (std::is_same_v<To, std::string>) {
if constexpr (std::is_same_v<From, char>) {
std::construct_at(to.CastTo<To*>(), from.CastTo<From*>());
return true;
}
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()
{
ConvertMap classMap;
classMap.emplace(&TypeInfo<std::string>::StaticClass, &ToString);
classMap.emplace(&TypeInfo<int>::StaticClass, &ToInt32);
classMap.emplace(&TypeInfo<uint32_t>::StaticClass, &ToInt32);
classMap.emplace(&TypeInfo<float>::StaticClass, &ToFloat);
#define RegisterToFrom(To, From) classMap.emplace(std::make_pair(&TypeInfo<To>::StaticClass, &TypeInfo<From>::StaticClass), &Convert::ConvertTo<To, From>);\
classMap.emplace(std::make_pair(&TypeInfo<From>::StaticClass, &TypeInfo<To>::StaticClass), &Convert::ConvertTo<From, To>)
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;
}
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...);
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>
consteval int fetch_meta_size() {
auto fields = T::__MakeStaticFields();
@ -32,7 +48,7 @@ namespace refl {
class MetaHelp {
public:
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>
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)...);
}
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;
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_CTOR_FLAG;

View File

@ -12,9 +12,6 @@ namespace refl_impl {
template<typename T, typename M>
struct _Meta;
template<typename T>
struct _ContainerMeta;
}
namespace refl {
// 定义一个模板结构体用于检测是否为 数组
@ -53,7 +50,12 @@ namespace refl {
concept is_tuple_v = is_tuple<T>::value;
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.end() } -> std::input_iterator;
};
@ -115,3 +117,9 @@ namespace refl {
template<typename 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) {
auto ptr = &UList[1];
(..., (*ptr = &TypeInfo<args_type_t<Args>>::StaticClass, ptr++));
(..., (*ptr = &TypeInfo<Args>::StaticClass, ptr++));
}
}
public:
@ -107,10 +107,6 @@ namespace refl {
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>
class UClass_Tuple : public UClass {
using UClass::UClass;
@ -255,12 +251,12 @@ namespace refl {
pit.val = &*it;
}
static void add(iterator* pit) {
auto it = ++(*(T::iterator*)pit);
auto it = ++(*(typename T::iterator*)pit);
memcpy(pit, &it, sizeof(it));
pit->val = &*it;
}
static void sub(iterator* pit) {
auto it = --(*(T::iterator*)pit);
auto it = --(*(typename T::iterator*)pit);
memcpy(pit, &it, sizeof(it));
pit->val = &*it;
}

View File

@ -12,6 +12,8 @@ namespace refl {
int Size();
const sarray<Any> ToSArray();
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{
public:

View File

@ -128,6 +128,18 @@ namespace refl {
}
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>
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_FUNC(R, ...) using USING_FUNC_NAME = R(*)(__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 {
struct Meta {};
struct vkMeta {};

View File

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

View File

@ -1 +1,3 @@
#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;
UPROPERTY({ "hello meta"})
string name = "???a";
UFUNCTION({})
USING_OVERLOAD_CTOR(vec3)
UFUNCTION({},ref = USING_CTOR_NAME)
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) {
x = x1;
y = y1;
z = z1;
}
UFUNCTION()
vec3 make() {
return vec3{};
}
};
#include "vertex_gen.inl"

View File

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

View File

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

View File

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

View File

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