diff --git a/engine/modules/engine/app/include/data/global.h b/engine/modules/engine/app/include/data/global.h index e69de29..dc2677f 100644 --- a/engine/modules/engine/app/include/data/global.h +++ b/engine/modules/engine/app/include/data/global.h @@ -0,0 +1,6 @@ +namespace api { + constexpr const char* CFileResourcePath = "/work/assets/file_resource.meta"; + constexpr const char* CFileFlagName = "/work/assets/file_flag.meta"; + constexpr const char* CFileMapName = "/work/assets/file_map.meta"; + constexpr const char* CFileMountName = "/work/assets/file_mount.meta"; +} \ No newline at end of file diff --git a/engine/modules/engine/app/xmake.lua b/engine/modules/engine/app/xmake.lua index c856d8e..81c3785 100644 --- a/engine/modules/engine/app/xmake.lua +++ b/engine/modules/engine/app/xmake.lua @@ -1,4 +1,4 @@ static_component("app","engine") - add_headerfiles("include/**.h", "include/**.inl","impl/*.inl") + add_headerfiles("include/**.h", "include/**.inl") add_files("src/**.cpp") add_deps("core", "asset", "zlib", "render") \ No newline at end of file diff --git a/engine/modules/engine/asset/impl/resource_system_impl.inl b/engine/modules/engine/asset/impl/resource_system_impl.inl index c3c6a3c..84b100f 100644 --- a/engine/modules/engine/asset/impl/resource_system_impl.inl +++ b/engine/modules/engine/asset/impl/resource_system_impl.inl @@ -3,6 +3,7 @@ #include "os/file_manager.h" #include "os/file_handle.h" #include "archive/json.h" +#include "data/global.h" namespace api { SINGLETON_DEFINE(ResourceSystem) using GenericPtr = ResourceSystem::GenericPtr; @@ -15,9 +16,9 @@ namespace api { array mResourceTable; table mResourceFile; table mFileLoader; - table> mFileFlags; - table mFileBlock; - vector mDirtyBlock; + table mFileFlags; + table mFileBlock; + vector mDirtyBlock; public: ResourceSystemImpl(ResourceSystem* owner); void Initialize(); @@ -159,11 +160,28 @@ namespace api { } void ResourceSystemImpl::LoadFileFlags() { - + FileHandle handle(CFileFlagName); + handle.Open(FILE_OP::READ); + if (handle) { + pmr::string text = handle.ReadAll(); + auto res = JsonDeserialize>(text); + if (res) { + mFileFlags = *res; + } + } + SetFileFlag(".hello", 1); + SaveFileFlags(); } void ResourceSystemImpl::SaveFileFlags() { + FileHandle handle(CFileFlagName); + handle.Open(FILE_OP::WRITE, mFileFlag & FileFlag::File_Binary); + if (mFileFlag & FileFlag::File_Binary) { + } + else { + handle.Write(JsonSerialize(mFileFlags)); + } } void ResourceSystemImpl::LoadResourceFile() { @@ -179,16 +197,16 @@ namespace api { if (it == mFileFlags.end()) { return 0; } - return it->second.second; + return it->second; } inline void ResourceSystemImpl::SetFileFlag(Name name, uint32_t flag) { auto it = mFileFlags.find(name); if (it == mFileFlags.end()) { - mFileFlags.emplace(name, std::make_pair(std::string(name.ToStringView()), flag)); + mFileFlags.emplace(name, flag); } else { - it->second.second = flag; + it->second = flag; } } inline ResourceSystem::ResourceFileBlock& ResourceSystemImpl::GetFileBlock(PackagePath path) { diff --git a/engine/modules/engine/asset/include/asset/asset.h b/engine/modules/engine/asset/include/asset/asset.h index eadb856..a0c0279 100644 --- a/engine/modules/engine/asset/include/asset/asset.h +++ b/engine/modules/engine/asset/include/asset/asset.h @@ -15,7 +15,7 @@ namespace api { { if (h) { - metadatas.emplace_back(SerializedMeta{ h.guid, h->Name(), type_name().View(), h->Meta()}); + metadatas.emplace_back(SerializedMeta{ h.guid, h->Name(), meta_name().View(), h->Meta()}); } } } \ No newline at end of file diff --git a/engine/modules/engine/asset/include/asset/res/guid.h b/engine/modules/engine/asset/include/asset/res/guid.h index 0b72c3e..0c1a31f 100644 --- a/engine/modules/engine/asset/include/asset/res/guid.h +++ b/engine/modules/engine/asset/include/asset/res/guid.h @@ -4,8 +4,8 @@ #include namespace api { - using refl::type_info; - using refl::type_name; + using refl::meta_info; + using refl::meta_name; using pmr::Name; using std::string_view; using std::span; diff --git a/engine/modules/engine/asset/include/asset/res/meta_bundle.inl b/engine/modules/engine/asset/include/asset/res/meta_bundle.inl index 7be590d..7f6059f 100644 --- a/engine/modules/engine/asset/include/asset/res/meta_bundle.inl +++ b/engine/modules/engine/asset/include/asset/res/meta_bundle.inl @@ -4,7 +4,7 @@ namespace api template inline const SerializedMeta* MetaBundle::FetchMeta() const { - string_view name = type_name().View(); + string_view name = meta_name().View(); for (auto& elem : metadatas) { if (elem.t_hash == name) @@ -15,7 +15,7 @@ namespace api template inline const SerializedMeta* MetaBundle::FetchMeta(string_view asset_name) const { - string_view name = type_name().View(); + string_view name = meta_name().View(); for (auto& elem : metadatas) { if (elem.t_hash == name && asset_name == elem.name) @@ -28,7 +28,7 @@ namespace api { if (h) { - metadatas.emplace_back(SerializedMeta{ h.guid, h->Name(), type_name().View() }); + metadatas.emplace_back(SerializedMeta{ h.guid, h->Name(), meta_name().View() }); } } } \ No newline at end of file diff --git a/engine/modules/engine/asset/include/asset/res/resource_handle.inl b/engine/modules/engine/asset/include/asset/res/resource_handle.inl index b775e86..e111163 100644 --- a/engine/modules/engine/asset/include/asset/res/resource_handle.inl +++ b/engine/modules/engine/asset/include/asset/res/resource_handle.inl @@ -15,7 +15,7 @@ namespace api{ using Base::operator=; template GenericResourceHandle(RscHandle handle) : Base(RscHandle{handle}) {} - GenericResourceHandle(string_view type_name, Guid guid); + GenericResourceHandle(string_view meta_name, Guid guid); template RscHandle AsHandle() const { return std::get>(*this); } diff --git a/engine/modules/engine/asset/src/res/resource_handle.cpp b/engine/modules/engine/asset/src/res/resource_handle.cpp index 7b07cb7..99d3d49 100644 --- a/engine/modules/engine/asset/src/res/resource_handle.cpp +++ b/engine/modules/engine/asset/src/res/resource_handle.cpp @@ -1,7 +1,7 @@ #include "asset/res/resource_handle.h" namespace api { - GenericResourceHandle::GenericResourceHandle(string_view type_name, Guid guid) + GenericResourceHandle::GenericResourceHandle(string_view meta_name, Guid guid) { } diff --git a/engine/modules/engine/asset/xmake.lua b/engine/modules/engine/asset/xmake.lua index e748496..666f83b 100644 --- a/engine/modules/engine/asset/xmake.lua +++ b/engine/modules/engine/asset/xmake.lua @@ -2,6 +2,6 @@ static_component("asset","engine") add_rules("c++.codegen",{ files = {"include/asset/res/*.h"} }) - add_headerfiles("include/**.h","include/**.inl", "impl/*.inl") + add_headerfiles("include/**.h","include/**.inl") add_files("src/**.cpp") add_deps("core", "zlib") \ No newline at end of file diff --git a/engine/modules/engine/core/include/archive/json/serde.inl b/engine/modules/engine/core/include/archive/json/serde.inl index fa254bc..f901fed 100644 --- a/engine/modules/engine/core/include/archive/json/serde.inl +++ b/engine/modules/engine/core/include/archive/json/serde.inl @@ -30,12 +30,46 @@ namespace gen { template struct JsonSerde>> { inline static bool Read(yyjson_val* val, const void* ptr) { + using value_type_t = typename T::value_type; + T& docker = *(T*)ptr; + size_t length = yyjson_arr_size(val); + char data[sizeof(value_type_t)]; + for (size_t i = 0; i < length; ++i) { + yyjson_val* obj_i = yyjson_arr_get(val, i); + if constexpr (refl::is_map_v) { + using key_type = refl::detail::is_pair::key_type; + using value_type = refl::detail::is_pair::value_type; + key_type& key = *(key_type*)data; + value_type& value = *(value_type*)(data + sizeof(key_type)); + JsonRead(yyjson_obj_get(obj_i, "#k"), key); + JsonRead(yyjson_obj_get(obj_i, "#v"), value); + docker[key] = value; + } + else { + value_type_t& obj = (value_type_t*)data; + JsonRead(obj_i, obj); + docker.push_back(obj); + } + } return true; } inline static yyjson_mut_val* Write(yyjson_mut_doc* doc, const void* ptr) { - T& v = *(T*)ptr; - yyjson_mut_val* obj = yyjson_mut_obj(doc); - return obj; + T& docker = *(T*)ptr; + if constexpr (refl::is_map_v) { + yyjson_mut_val* obj = yyjson_mut_obj(doc); + for (auto& it : docker) { + yyjson_mut_obj_add_val(doc, obj, "#k", JsonWrite(doc, it.first)); + yyjson_mut_obj_add_val(doc, obj, "#v", JsonWrite(doc, it.second)); + } + return obj; + } + else { + yyjson_mut_val* arr = yyjson_mut_arr(doc); + for (auto& it : docker) { + yyjson_mut_arr_add_val(doc, JsonWrite(doc, it)); + } + return arr; + } } }; } diff --git a/engine/modules/engine/core/include/archive/json/serialize.h b/engine/modules/engine/core/include/archive/json/serialize.h index 497374b..bc69111 100644 --- a/engine/modules/engine/core/include/archive/json/serialize.h +++ b/engine/modules/engine/core/include/archive/json/serialize.h @@ -4,7 +4,7 @@ namespace api { using refl::Any; using refl::UClass; - using refl::type_info; + using refl::meta_info; struct JsonVTable { using Read = bool(*)(yyjson_val*, const void*); using Write = yyjson_mut_val*(*)(yyjson_mut_doc*, const void*); diff --git a/engine/modules/engine/core/include/archive/json/serialize.inl b/engine/modules/engine/core/include/archive/json/serialize.inl index 5273aaa..234e540 100644 --- a/engine/modules/engine/core/include/archive/json/serialize.inl +++ b/engine/modules/engine/core/include/archive/json/serialize.inl @@ -43,7 +43,7 @@ namespace api { template inline void JsonArchive::Register() { - auto uclass = type_info(); + auto uclass = meta_info(); auto [bfind, it] = uclass->vtable.FindLast(VJsonSerdeRead()); if (!bfind && it) { it = it->Insert(VJsonSerdeRead(), (void*) &gen::JsonSerde::Read); @@ -70,6 +70,21 @@ namespace api { if (it) { return it(res, any.ptr); } + if (any.IsContainer()) { + bool isMap = any.IsMap(); + refl::Container docker = any; + auto fieldList = docker.GetFields(); + for (auto obj : docker) { + if (isMap) { + Any first = obj.Member(fieldList[0]); + Any second = obj.Member(fieldList[1]); + //result[Serialize(first)] = Serialize(second); + } + else { + //result.push_back(Serialize(obj)); + } + } + } return false; } } \ No newline at end of file diff --git a/engine/modules/engine/core/xmake.lua b/engine/modules/engine/core/xmake.lua index 97f0653..b727494 100644 --- a/engine/modules/engine/core/xmake.lua +++ b/engine/modules/engine/core/xmake.lua @@ -3,7 +3,7 @@ static_component("core","engine") files = {"include/module/module.h"} }) add_includedirs("3rdparty", {public = true}) - add_headerfiles("include/**.h","include/**.inl", "impl/*.inl","3rdparty/**.h") + add_headerfiles("include/**.h","include/**.inl","3rdparty/**.h") add_files("src/**.cpp") add_deps("zlib") add_packages("spdlog", {public = true}) \ No newline at end of file diff --git a/engine/modules/engine/render/include/render/asset/mesh.h b/engine/modules/engine/render/include/render/asset/mesh.h index e8a100f..3d401c3 100644 --- a/engine/modules/engine/render/include/render/asset/mesh.h +++ b/engine/modules/engine/render/include/render/asset/mesh.h @@ -34,7 +34,7 @@ namespace api { }; template inline Mesh::Mesh(vector& vertices, vector& indices) - : Asset(type_info()), mVertices(vertices), mIndices(indices) + : Asset(meta_info()), mVertices(vertices), mIndices(indices) { } }; \ No newline at end of file diff --git a/engine/modules/engine/render/src/asset/material.cpp b/engine/modules/engine/render/src/asset/material.cpp index e858852..7a6e8e5 100644 --- a/engine/modules/engine/render/src/asset/material.cpp +++ b/engine/modules/engine/render/src/asset/material.cpp @@ -1,6 +1,6 @@ #include "render/asset/material.h" namespace api { - Material::Material() : Asset(type_info()) + Material::Material() : Asset(meta_info()) { } Material::~Material() diff --git a/engine/modules/engine/render/src/asset/mesh.cpp b/engine/modules/engine/render/src/asset/mesh.cpp index cc5d5eb..25d31a0 100644 --- a/engine/modules/engine/render/src/asset/mesh.cpp +++ b/engine/modules/engine/render/src/asset/mesh.cpp @@ -1,6 +1,6 @@ #include "render/asset/mesh.h" namespace api { - Mesh::Mesh() : Asset(type_info()) + Mesh::Mesh() : Asset(meta_info()) { } diff --git a/engine/modules/engine/render/src/asset/shader.cpp b/engine/modules/engine/render/src/asset/shader.cpp index 1a86516..7e61e01 100644 --- a/engine/modules/engine/render/src/asset/shader.cpp +++ b/engine/modules/engine/render/src/asset/shader.cpp @@ -1,6 +1,6 @@ #include "render/asset/shader.h" namespace api { - Shader::Shader() : Asset(type_info()) + Shader::Shader() : Asset(meta_info()) { } Shader::~Shader() diff --git a/engine/modules/engine/render/xmake.lua b/engine/modules/engine/render/xmake.lua index 1e2d34b..6c9ffaa 100644 --- a/engine/modules/engine/render/xmake.lua +++ b/engine/modules/engine/render/xmake.lua @@ -1,6 +1,6 @@ static_component("render","engine") add_includedirs("3rdparty", {public = true}) - add_headerfiles("include/**.h", "include/**.inl", "impl/*.inl") + add_headerfiles("include/**.h", "include/**.inl") add_files("src/**.cpp") add_deps("asset", "zlib", "core","shaderc") add_syslinks("user32", {public = true}) diff --git a/engine/modules/engine/singleton/include/singleton.h b/engine/modules/engine/singleton/include/singleton.h index 863a276..2d3f61a 100644 --- a/engine/modules/engine/singleton/include/singleton.h +++ b/engine/modules/engine/singleton/include/singleton.h @@ -6,6 +6,8 @@ namespace singleapi { using std::pmr::unsynchronized_pool_resource; using std::pmr::unordered_map; }; + template + concept is_unique_wrap_t = requires(T* t) { typename T::UniqueType; { t->Ptr() } -> std::same_as; }; struct MemoryInfo { void* data; bool isAlive; @@ -84,6 +86,48 @@ public: return ms_Singleton; } }; +template +class UniquePtr { +protected: + using U = T::UniqueType; + inline static T* ms_Singleton = nullptr; +public: + template + UniquePtr(Args&&... args) { + using namespace singleapi; + MemoryInfo info{}; + if constexpr (hash == 0) { + size_t tHash = typeid(T).hash_code(); + info = GlobalManager::Ptr()->GetInstance(tHash, sizeof(T)); + } + else { + info = GlobalManager::Ptr()->GetInstance(hash, sizeof(T)); + } + if (info.isAlive) { + ms_Singleton = (T*)info.data; + } + else { + ms_Singleton = new(info.data)T(std::forward(args)...); + } + } + ~UniquePtr() { + using namespace singleapi; + bool isAlive = false; + if constexpr (hash == 0) { + size_t tHash = typeid(T).hash_code(); + isAlive = GlobalManager::Ptr()->KillInstance(tHash); + } + else { + isAlive = GlobalManager::Ptr()->KillInstance(hash); + } + if (ms_Singleton && isAlive) { + ms_Singleton->~T(); + } + } + static U* Ptr(void) { + return ms_Singleton->Ptr(); + } +}; constexpr inline size_t string_hash(std::string_view str) noexcept { constexpr size_t fnv_offset_basis = 0xcbf29ce484222325; @@ -110,6 +154,7 @@ public:\ #define SINGLETON_PTR() ms_Singleton = this; +#define UNIQUER_INLINE_STATIC(cls, name, hash) inline static UniquePtr name##Ptr; #define UNIQUER_INLINE(cls, name, hash) inline UniquePtr name##Ptr; #define UNIQUER_STATIC(cls, name, hash) static UniquePtr name##Ptr; #define UNIQUER_VAL(name) (*name##Ptr.Ptr()) diff --git a/engine/modules/engine/zlib/include/pmr/memory.inl b/engine/modules/engine/zlib/include/pmr/memory.inl index 7a1c2b5..c9cbfdb 100644 --- a/engine/modules/engine/zlib/include/pmr/memory.inl +++ b/engine/modules/engine/zlib/include/pmr/memory.inl @@ -2,6 +2,7 @@ #include "singleton.h" //全局生命周期,不回收内存 //局部生命周期,每帧回收内存 +ZLIB_API extern pmr::FrameAllocatorPool* MetaGlobalPool(); ZLIB_API extern pmr::FrameAllocatorPool* GlobalPool(); ZLIB_API extern pmr::FrameAllocatorPool* FramePool(); extern void* operator new(std::size_t size); @@ -9,6 +10,10 @@ extern void operator delete(void* ptr) noexcept; extern void operator delete[](void* ptr) noexcept; extern void* operator new(std::size_t size, std::align_val_t align); #ifdef ZLIB_API_VAL +ZLIB_API inline pmr::FrameAllocatorPool* MetaGlobalPool() { + static pmr::FrameAllocatorPool* globalPool = new pmr::FrameAllocatorPool(); + return globalPool; +} ZLIB_API inline pmr::FrameAllocatorPool* GlobalPool() { static pmr::FrameAllocatorPool* globalPool = new pmr::FrameAllocatorPool(); return globalPool; diff --git a/engine/modules/engine/zlib/include/pmr/name.h b/engine/modules/engine/zlib/include/pmr/name.h index 43c45c7..b666818 100644 --- a/engine/modules/engine/zlib/include/pmr/name.h +++ b/engine/modules/engine/zlib/include/pmr/name.h @@ -43,7 +43,7 @@ namespace pmr constexpr size_t Hash() const noexcept { return hash; } constexpr std::string_view Value() const noexcept { return value; } constexpr bool Valid() const noexcept { return hash != InvalidValue(); } - + operator Name() {return Name(value);} explicit constexpr operator bool() const noexcept { return Valid(); } constexpr auto operator<=>(const CName& rhs) const noexcept { return hash <=> rhs.hash; }; diff --git a/engine/modules/engine/zlib/include/refl/detail/any.h b/engine/modules/engine/zlib/include/refl/detail/any.h index 5aa49e3..0d9fd10 100644 --- a/engine/modules/engine/zlib/include/refl/detail/any.h +++ b/engine/modules/engine/zlib/include/refl/detail/any.h @@ -2,6 +2,8 @@ #include "type.h" namespace refl { class UClass; + class Container; + class FieldPtr; struct Any; template concept is_not_any_v = !std::is_same_v, Any>; @@ -13,9 +15,9 @@ namespace refl { constexpr Any() noexcept: ptr(nullptr), cls(nullptr) {} constexpr Any(const void* ptr, const UClass* cls) noexcept : ptr(ptr), cls(cls) {} template - constexpr Any(T&& v) noexcept : ptr(&v), cls(type_info()) {} + constexpr Any(T&& v) noexcept : ptr(&v), cls(meta_info()) {} template - constexpr Any(T* v) noexcept : ptr(v), cls(type_info()) {} + constexpr Any(T* v) noexcept : ptr(v), cls(meta_info()) {} template//参数 T* => T* constexpr inline T CastTo() const { if constexpr (std::is_pointer_v) { @@ -30,9 +32,24 @@ namespace refl { } } public: + operator span() const { + return span{(Any*)this, 1}; + } + operator Container()const; operator bool()const { return cls && ptr; } bool Check(const UClass* parent) const; template T FindVtable(size_t name)const; + bool Construct(span ArgsList) const; + Any New(pmr::memory_resource* pool)const; + + Any Member(const FieldPtr& field)const; + Any Member(int i)const; + + bool IsArray()const; + bool IsObject()const; + bool IsContainer()const; + bool IsSequence()const; + bool IsMap()const; }; } \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/any.inl b/engine/modules/engine/zlib/include/refl/detail/any.inl index efb9eea..3644a6e 100644 --- a/engine/modules/engine/zlib/include/refl/detail/any.inl +++ b/engine/modules/engine/zlib/include/refl/detail/any.inl @@ -1,6 +1,27 @@ #include "any.h" #include "uclass.h" +#include "convert.h" namespace refl{ + inline bool Any::IsArray() const + { + return cls->flag & CLASS_ARRAY_FLAG; + } + inline bool Any::IsObject() const + { + return !(cls->flag & CLASS_ARRAY_FLAG) && !(cls->flag & CLASS_POINTER_FLAG); + } + inline bool Any::IsContainer() const + { + return cls->flag & CLASS_CONTAINER_FLAG; + } + inline bool Any::IsSequence() const + { + return cls->flag & CLASS_SEQUENCE_FLAG; + } + inline bool Any::IsMap() const + { + return cls->flag & CLASS_MAP_FLAG; + } inline bool Any::Check(const UClass* parent)const { if (cls == parent) { @@ -11,9 +32,72 @@ namespace refl{ } return cls->IsChildOf(parent); } + inline bool Any::Construct(span ArgsList) const + { + return cls->Construct((void*)ptr, ArgsList); + } + inline Any Any::New(pmr::memory_resource* pool) const + { + void* data = pool->allocate(cls->size); + Any any{ data, cls }; + Convert::Construct(any, this); + return any; + } template inline T Any::FindVtable(size_t name) const { return (T)cls->vtable.Find(name); } + inline Any Any::Member(const FieldPtr& field)const + { + if (field.flag & FIELD_MEMBER_FLAG) { + return { (const char*)ptr + field.data.member.offset, field.type }; + } + return {}; + } + inline Any Any::Member(int i) const + { + if (cls->flag & CLASS_ARRAY_FLAG) { + int offset = i * cls->parent->size; + if (offset < cls->size) + return { (const char*)ptr + offset, cls->parent }; + } + return Any(); + } + + inline bool UClass::Construct(void* ptr, span ArgsList) const + { + auto construct = vtable.Construct(); + if (construct) { + if (construct(ptr, this, ArgsList)) { + return true; + } + auto fieldList = GetFields(EFieldFind::FIND_CTOR, Name("Ctor")); + if (fieldList.empty()) { + return false; + } + std::array ArgsArray = { Any{} , Any{ptr} }; + int i = 2; + for (auto& arg : ArgsList) { + ArgsArray[i++] = arg; + } + span FieldArgs(&ArgsArray[0], 2 + ArgsList.size()); + if (fieldList.size() == 1) { + return fieldList[0].Invoke(FieldArgs); + } + //todo: 函数重载需要更精确的处理吗? + for (auto& field : fieldList) { + if (field.Invoke(FieldArgs)) { + return true; + } + } + return false; + } + if (!ArgsList.empty() && ArgsList[0].Check(this)) { + memcpy(ptr, ArgsList[0].ptr, size); + return true; + } + memset(ptr, 0, size); + return true; + } } \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/container.inl b/engine/modules/engine/zlib/include/refl/detail/container.inl new file mode 100644 index 0000000..be3f7ea --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/container.inl @@ -0,0 +1,84 @@ +#pragma once +#include "any.h" +#include "uclass.inl" +#include +namespace refl { + class Container { + const void* ptr; + const UClass_Container_Impl* cls; + friend class Any; + Container(const void* ptr, const UClass_Container_Impl* cls) :ptr(ptr), cls(cls) {} + public: + operator Any()const{ + return Any{ ptr, cls }; + } + span GetFields() { + return cls->parent->GetFields(EFieldFind::FIND_ALL_MEMBER, Name("")); + } + void construct() { + cls->Construct((void*)ptr); + } + void destruct() { + cls->Destruct((void*)ptr); + } + void insert(const Any& any) { + if (any.cls == cls->parent) + cls->vinsert(ptr, any.ptr); + } + int size() { + return cls->vsize(ptr); + } + auto begin() { + Container::iterator it(cls); + cls->vbegin(it, ptr); + return it; + } + auto end() { + Container::iterator it(cls); + cls->vend(it, ptr); + return it; + } + // Iterator class + class iterator : public UClass_Container_Impl::iterator { + private: + const UClass_Container_Impl* cls; + public: + iterator(const UClass_Container_Impl* cls) + : cls(cls) {} + iterator& operator++() noexcept { + cls->viterator_add(this); + return *this; + } + iterator operator++(int) noexcept { + iterator tmp = *this; + cls->viterator_add(this); + return tmp; + } + iterator& operator--() noexcept { + cls->viterator_sub(this); + return *this; + } + iterator operator--(int) noexcept { + iterator tmp = *this; + cls->viterator_sub(this); + return tmp; + } + Any operator->() noexcept { + return { val , cls->parent }; + } + Any operator*() noexcept { + return { val , cls->parent }; + } + constexpr bool operator!=(const iterator& other) const noexcept { + return cls != other.cls || ptr != other.ptr; + } + constexpr bool operator==(const iterator& other) const noexcept { + return ptr == other.ptr && cls == other.cls; + } + }; + }; + inline Any::operator Container() const + { + return Container{ ptr, (const UClass_Container_Impl*)cls }; + } +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/convert.h b/engine/modules/engine/zlib/include/refl/detail/convert.h new file mode 100644 index 0000000..9e55015 --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/convert.h @@ -0,0 +1,38 @@ +#pragma once +#include "any.h" +#include "singleton.h" +namespace refl { + using UClassPair = std::pair; + // 自定义哈希函数 + struct UClassPairHash { + std::size_t operator()(const UClassPair& pair) const { + std::hash 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; + struct ConvertMapWrap { + using UniqueType = ConvertMap; + UniqueType table; + ConvertMapWrap(); + UniqueType* Ptr() { + return &table; + } + }; + class Convert { + protected: + friend class ConvertMapWrap; + static ConvertMap BuildConvertMap(); + template + static bool ConvertTo(Any& to, const Any& from); + static ConvertMap& GetConvertMap(); + public: + static bool Construct(Any& to, const Any& from); + }; +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/convert.inl b/engine/modules/engine/zlib/include/refl/detail/convert.inl new file mode 100644 index 0000000..ac7c8b9 --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/convert.inl @@ -0,0 +1,55 @@ +#include "convert.h" +namespace refl { + ConvertMapWrap::ConvertMapWrap() : table(Convert::BuildConvertMap()){} + template + inline bool refl::Convert::ConvertTo(Any& to, const Any& from) + { + if constexpr (std::is_same_v) { + if constexpr (std::is_same_v) { + std::construct_at(to.CastTo(), from.CastTo()); + return true; + } + return false; + } + else if constexpr (std::is_arithmetic_v) { + if constexpr (std::is_arithmetic_v) { + *to.CastTo() = (To)*from.CastTo(); + return true; + } + return false; + } + return false; + } + inline ConvertMap Convert::BuildConvertMap() + { + ConvertMap convertMap; +#define RegisterToFrom(To, From) convertMap.emplace(std::make_pair(meta_info(), meta_info()), &Convert::ConvertTo);\ + convertMap.emplace(std::make_pair(meta_info(), meta_info()), &Convert::ConvertTo) + + 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 convertMap; + } + inline ConvertMap& Convert::GetConvertMap() + { + UNIQUER_STATIC(ConvertMapWrap, ConvertMap, "refl::convert.ConvertMap") + return UNIQUER_VAL(ConvertMap); + } + inline bool Convert::Construct(Any& to, const Any& from) + { + if (to.Construct(from)) + return true; + auto& ConvertMap = GetConvertMap(); + auto it = ConvertMap.find(std::make_pair(to.cls, from.cls)); + if (it != ConvertMap.end()) { + return it->second(to, from); + } + return false; + } +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/field.h b/engine/modules/engine/zlib/include/refl/detail/field.h index cef30a9..01f57bd 100644 --- a/engine/modules/engine/zlib/include/refl/detail/field.h +++ b/engine/modules/engine/zlib/include/refl/detail/field.h @@ -1,13 +1,6 @@ #pragma once -#include "pmr/name.h" #include "any.h" -#include namespace refl { - using pmr::Name; - using pmr::CName; - using pmr::FName; - using pmr::table; - using std::span; using Offset = uint32_t; using Method = void*; struct MemberData { @@ -27,13 +20,13 @@ namespace refl { constexpr MethodData(Method fptr, span value, const Any& meta) : fptr(fptr), value(value), meta(meta) {} }; enum FieldFlag :uint32_t { - FIELD_NONE_FLAG = 0, - FIELD_MEMBER_FLAG = 1 << 0, - FIELD_METHOD_FLAG = 1 << 1, - FIELD_CTOR_FLAG = 1 << 2, - FIELD_VALUE_FLAG = 1 << 3, + FIELD_NONE_FLAG = 0, + FIELD_MEMBER_FLAG = 1 << 0, + FIELD_ATTRIBUTE_FLAG = 1 << 1, + FIELD_METHOD_FLAG = 1 << 2, + FIELD_METHOD_VALUE_FLAG = 1 << 3, + FIELD_CTOR_FLAG = 1 << 4, }; - using enum FieldFlag; struct FieldPtr { union Data { @@ -50,5 +43,10 @@ namespace refl { const UClass* type{}; Data data{}; uint32_t flag{}; + + template + auto Call(Func func, Args&&... args)const; + template + bool Invoke(span ArgsList)const; }; } \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/field.inl b/engine/modules/engine/zlib/include/refl/detail/field.inl index cf5586f..d95904c 100644 --- a/engine/modules/engine/zlib/include/refl/detail/field.inl +++ b/engine/modules/engine/zlib/include/refl/detail/field.inl @@ -1,4 +1,74 @@ #include "field.h" namespace refl{ - + template + consteval auto fetch_method_t(R(T::*)(Args...)) { + using MethodType = R(*)(const void*, Args...); + return MethodType{ nullptr }; + } + template + consteval auto fetch_method_t(R(*)(Args...)) { + using MethodType = R(*)(Args...); + return MethodType{ nullptr }; + } + template + inline auto FieldPtr::Call(Func func, Args && ...args) const + { + using MemberFunc = decltype(fetch_method_t(func)); + MemberFunc fptr = (MemberFunc)data.method.fptr; + return fptr(std::forward(args)...); + } + template + inline bool FieldPtr::Invoke(span ArgsList) const + { + auto Call = type->vtable.Call(); + if (Call) { + span params = type->GetParams(); + size_t paramsSize = params.size(); + size_t argsSize = ArgsList.size(); + if (argsSize > paramsSize) { + ArgsList = span{ ArgsList.data(), paramsSize }; + } + if constexpr (IsSafeMemory) { + if (argsSize < paramsSize && flag & FIELD_METHOD_VALUE_FLAG) { + auto value = data.method.value; + if (argsSize + value.size() >= paramsSize) { + ArgsList = span{ ArgsList.data(), paramsSize }; + std::copy(value.begin(), value.end(), &ArgsList[argsSize]); + argsSize = paramsSize; + } + } + if (argsSize < paramsSize) { + return false; + } + for (size_t i = 1; i < paramsSize; i++) { + if (ArgsList[i].cls != params[i] && ArgsList[i].Check(params[i])) { + return false; + } + } + Call(this, ArgsList); + } + else { + std::array ArgsArray{}; + if (argsSize < paramsSize && flag & FIELD_METHOD_VALUE_FLAG) { + auto value = data.method.value; + if (argsSize + value.size() >= paramsSize) { + std::copy(ArgsList.begin(), ArgsList.end(), ArgsArray.data()); + ArgsList = span{ ArgsArray.data(), paramsSize }; + std::copy(value.begin(), value.end(), &ArgsList[argsSize]); + argsSize = paramsSize; + } + } + if (argsSize < paramsSize) { + return false; + } + for (size_t i = 1; i < paramsSize; i++) { + if (ArgsList[i].cls != params[i] && ArgsList[i].Check(params[i])) { + return false; + } + } + Call(this, ArgsList); + } + } + return Call; + } } \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/meta.h b/engine/modules/engine/zlib/include/refl/detail/meta.h index 9da4da6..5fb6581 100644 --- a/engine/modules/engine/zlib/include/refl/detail/meta.h +++ b/engine/modules/engine/zlib/include/refl/detail/meta.h @@ -26,6 +26,11 @@ namespace gen { } namespace refl { struct MetaHelp{ + template + static constexpr auto remove_const(R(T::* ptr)(Args...) const) { + using MethodType = R(T::*)(Args...); + return (MethodType)ptr; + } template static FieldPtr CtorField(T(*ptr)(Args...), const MethodData& data = {}); @@ -39,6 +44,8 @@ namespace refl { static FieldPtr MethodField(R(T::* ptr)(Args...), CName name, const MethodData& data = {}); template - static FieldPtr MethodField(R(T::* ptr)(Args...)const, CName name, const MethodData& data = {}); + static FieldPtr MethodField(R(T::* ptr)(Args...)const, CName name, const MethodData& data = {}) { + return MethodField(remove_const(ptr), name, data); + } }; } \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/meta.inl b/engine/modules/engine/zlib/include/refl/detail/meta.inl index 7a188e0..b6adb46 100644 --- a/engine/modules/engine/zlib/include/refl/detail/meta.inl +++ b/engine/modules/engine/zlib/include/refl/detail/meta.inl @@ -1 +1,91 @@ -#include "meta.h" \ No newline at end of file +#include "meta.h" +#include "uclass.h" +namespace refl { + span MakeAnyArgs(span args, span params, pmr::memory_resource* alloc = MetaGlobalPool()) { + size_t clsIndex = params.size() - args.size(); + assert(clsIndex > 0); + span subParams = params.subspan(clsIndex); + clsIndex = subParams.size(); + int size = clsIndex * sizeof(Any); + for (auto cls : subParams) { + size += cls->size;//数据大小 + } + void* memory = (char*)alloc->allocate(size); + Any* any = (Any*)memory; + char* pData = (char*)memory + clsIndex * sizeof(Any); + for (size_t i = 0; i < clsIndex; i++) { + any->cls = subParams[i]; + any->ptr = pData; + assert(Convert::Construct(*any, args[i])); + any++; + pData += any->cls->size; + } + return span{(Any*)memory, clsIndex}; + } + template + static void NewCtor(void* mem, Args... args) { + new (mem) T(std::forward(args)...); + } + template + inline FieldPtr MetaHelp::CtorField(T(*ptr)(Args...), const MethodData& data) + { + const UClass* cls = meta_info...)>(); + uint32_t flag = FIELD_MEMBER_FLAG | FIELD_CTOR_FLAG; + MethodData method; + if (!data.value.empty()) { + flag |= FIELD_METHOD_VALUE_FLAG; + method.value = MakeAnyArgs(data.value, cls->GetParams()); + } + if (data.meta) { + method.meta = data.meta.New(MetaGlobalPool()); + } + method.fptr = (Method)&NewCtor; + return FieldPtr{Name("Ctor"), cls, method, flag}; + } + template + inline FieldPtr MetaHelp::MemberField(T Obj::* ptr, CName name, const MemberData& data) + { + const UClass* cls = meta_info(); + uint32_t flag = FIELD_MEMBER_FLAG | FIELD_CTOR_FLAG; + MemberData member; + member.offset = reinterpret_cast(&(reinterpret_cast(0)->*ptr)); + if (data.value) { + member.value = data.value.New(MetaGlobalPool()); + } + if (data.meta) { + member.meta = data.meta.New(MetaGlobalPool()); + } + return FieldPtr{ name, cls, member, flag }; + } + template + inline FieldPtr MetaHelp::MethodField(R(*ptr)(Args...), CName name, const MethodData& data) + { + MethodData method; + uint32_t flag = FIELD_METHOD_FLAG; + const UClass* cls = meta_info(*)(real_type_t...)>(); + if (!data.value.empty()) { + flag |= FIELD_METHOD_VALUE_FLAG; + method.value = MakeAnyArgs(data.value, cls->GetParams()); + } + if (data.meta) { + method.meta = data.meta.New(MetaGlobalPool()); + } + method.fptr = { *(Method*)&ptr }; + return { name, cls, method,flag }; + } + template + inline FieldPtr MetaHelp::MethodField(R(T::* ptr)(Args...), CName name, const MethodData& data) { + MethodData method; + uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; + const UClass* cls = meta_info(*)(const void*, real_type_t...)>(); + if (!data.value.empty()) { + flag |= FIELD_METHOD_VALUE_FLAG; + method.value = MakeAnyArgs(data.value, cls->GetParams()); + } + if (data.meta) { + method.meta = data.meta.New(MetaGlobalPool()); + } + method.fptr = { *(Method*)&ptr }; + return { name, cls, method,flag }; + } +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/name.h b/engine/modules/engine/zlib/include/refl/detail/name.h index 8e5fa4f..37c77d2 100644 --- a/engine/modules/engine/zlib/include/refl/detail/name.h +++ b/engine/modules/engine/zlib/include/refl/detail/name.h @@ -26,5 +26,5 @@ namespace refl { template constexpr auto value_name() noexcept; template - constexpr auto type_name() noexcept; + constexpr auto meta_name() noexcept; } \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/name.inl b/engine/modules/engine/zlib/include/refl/detail/name.inl index 3fce47e..76f53f4 100644 --- a/engine/modules/engine/zlib/include/refl/detail/name.inl +++ b/engine/modules/engine/zlib/include/refl/detail/name.inl @@ -15,7 +15,7 @@ namespace refl { # endif } template - constexpr auto raw_type_name() noexcept { + constexpr auto raw_meta_name() noexcept { constexpr std::string_view sign = func_signature(); constexpr size_t size = sign.size(); return TStr{ sign }; @@ -86,7 +86,7 @@ namespace refl { } } template - constexpr auto type_name() noexcept { + constexpr auto meta_name() noexcept { if constexpr (std::is_same_v) { return TStr{ "void" }; } @@ -96,7 +96,7 @@ namespace refl { return detail::concat(prefix, bit); } else { - return detail::raw_type_name(); + return detail::raw_meta_name(); } } } \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/type.h b/engine/modules/engine/zlib/include/refl/detail/type.h index b9dcb50..4ba74c0 100644 --- a/engine/modules/engine/zlib/include/refl/detail/type.h +++ b/engine/modules/engine/zlib/include/refl/detail/type.h @@ -1,7 +1,15 @@ #pragma once +#include "pmr/name.h" #include #include +#include +#include namespace refl { + using std::span; + using pmr::Name; + using pmr::CName; + using pmr::FName; + using pmr::table; namespace detail { // 定义一个模板结构体用于检测是否为 数组 template @@ -24,7 +32,10 @@ namespace refl { struct is_pair : std::false_type {}; template - struct is_pair> : std::true_type {}; + struct is_pair> : std::true_type { + using key_type = T1; + using value_type = T2; + }; // 定义一个模板结构体用于检测是否为 std::pair template @@ -112,5 +123,6 @@ namespace refl { //类型接口 struct UClass; template - const UClass* type_info(); + const UClass* meta_info(); + constexpr uint32_t MAX_ARGS_LENGTH = 10; } \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/uclass.h b/engine/modules/engine/zlib/include/refl/detail/uclass.h index 1abe079..6dabaa8 100644 --- a/engine/modules/engine/zlib/include/refl/detail/uclass.h +++ b/engine/modules/engine/zlib/include/refl/detail/uclass.h @@ -76,12 +76,30 @@ namespace refl { //class meta using GetMeta_t = const UClass* (*)(Name); //function - using GetParams_t = span(*)(const UClass*); + using GetParams_t = span(*)(const UClass*); //function args - using Call_t = void (*)(const FieldPtr*, span ArgsList); + using Call_t = void (*)(const FieldPtr*,span ArgsList); //object - using Construct_t = bool (*)(void* ptr, const UClass* cls, span ArgsList); + using Construct_t = bool (*)(void* ptr, const UClass* cls,span ArgsList); using Destruct_t = void (*)(void*); + void AddGetFields(GetFields_t func) { + Add(string_hash("GetFields"), (void*)func); + } + void AddGetMeta(GetMeta_t func) { + Add(string_hash("GetMeta"), (void*)func); + } + void AddGetParams(GetParams_t func) { + Add(string_hash("GetParams"), (void*)func); + } + void AddCall(Call_t func) { + Add(string_hash("Call"), (void*)func); + } + void AddConstruct(Construct_t func) { + Add(string_hash("Construct"), (void*)func); + } + void AddDestruct(Destruct_t func) { + Add(string_hash("Destruct"), (void*)func); + } GetFields_t GetFields() const { return (GetFields_t) Find(string_hash("GetFields")); } GetMeta_t GetMeta() const { return (GetMeta_t) Find(string_hash("GetMeta")); } GetParams_t GetParams() const { return (GetParams_t) Find(string_hash("GetParams")); } @@ -101,6 +119,32 @@ namespace refl { public: UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr) :name(name), size(size), parent(parent) {} + Any New(pmr::memory_resource* pool, span ArgsList = {}) const { + void* ptr = pool->allocate(size); + Construct(ptr, ArgsList); + return { ptr , this }; + } + bool Construct(void* ptr, span ArgsList = {})const; + void Destruct(void* ptr)const { + auto func = vtable.Destruct(); + if (func) { + func(ptr); + } + } + span GetFields(EFieldFind find, const Name& name)const { + auto func = vtable.GetFields(); + if (func) { + return func(this, find, name); + } + return {}; + } + span GetParams()const { + auto func = vtable.GetParams(); + if (func) { + return func(this); + } + return {}; + } bool IsChildOf(const UClass* cls, bool bthis = false) const { const UClass* _parent = bthis ? this : parent; while (_parent != nullptr) { @@ -113,7 +157,7 @@ namespace refl { } template bool IsChildOf(bool bthis = false) const { - return IsChildOf(type_info(), bthis); + return IsChildOf(meta_info(), bthis); } public: template diff --git a/engine/modules/engine/zlib/include/refl/detail/uclass.inl b/engine/modules/engine/zlib/include/refl/detail/uclass.inl index f79b598..b850650 100644 --- a/engine/modules/engine/zlib/include/refl/detail/uclass.inl +++ b/engine/modules/engine/zlib/include/refl/detail/uclass.inl @@ -7,12 +7,12 @@ namespace refl { template class UClass_Auto : public UClass { public: - UClass_Auto() : UClass(type_name().View(), sizeof(T)) { + UClass_Auto() : UClass(meta_name().View(), sizeof(T)) { if constexpr (std::is_pointer_v) { using RT = std::remove_pointer_t; flag |= CLASS_POINTER_FLAG; if constexpr (!std::is_same_v) { - parent = type_info(); + parent = meta_info(); } } else if constexpr (is_array_v) { @@ -21,23 +21,233 @@ namespace refl { if constexpr (std::is_pointer_v) { flag |= CLASS_POINTER_FLAG; } - parent = type_info(); + parent = meta_info(); } else { - vtable.Add(string_hash("Construct"), (void*)&UClass::Construct); - vtable.Add(string_hash("Destruct"), (void*)&UClass::Destruct); + vtable.AddConstruct(&UClass::Construct); + vtable.AddDestruct(&UClass::Destruct); } } }; + /* + * 模板优化 + * 成员参数转化为const void* + * 引用参数转化为指针 + * 返回引用转化为指针 + */ + template + class UMethod_Auto : public UClass { + using MethodType = R(*)(Args...); + public: + std::array UList{}; + UMethod_Auto() : UClass(meta_name().View(), sizeof(MethodType)) { + flag = CLASS_TRIVIAL_FLAG; + vtable.AddGetParams(&UMethod_Auto::GetParams); + vtable.AddCall(&UMethod_Auto::Call); + if constexpr (!std::is_same_v) { + UList[0] = meta_info(); + } + if constexpr (sizeof...(Args) > 0) { + auto ptr = &UList[1]; + (..., (*ptr = meta_info(), ptr++)); + } + } + //这里顺序似乎是不确定的,但是我实际运用是对的 + //如果使用make_index_sequence,会多一次函数调用 + //为什么包裹一层迭代器,就不会出现警告了 + static void Call(const FieldPtr* field, span ArgsList) { + assert(sizeof...(Args) < ArgsList.size()); + auto param = ArgsList.end() - 1; + if constexpr (std::is_same_v) { + MethodType fptr = (MethodType)field->data.method.fptr; + fptr((param--->CastTo())...); + } + else { + MethodType fptr = (MethodType)field->data.method.fptr; + auto ret = ArgsList.front(); + if (ret.cls == meta_info()) { + *(R*)ret.ptr = fptr((param--->CastTo())...); + } + else { + fptr((param--->CastTo())...); + } + } + } + static span GetParams(const UClass* cls) { + auto& UList = ((UMethod_Auto*)cls)->UList; + return span{UList}; + } + }; + class UClass_Container_Impl : public UClass { + public: + using UClass::UClass; + struct iterator { + void* ptr; + void* val; + }; + //container + using size_impl = size_t(*)(const void*); + using to_iterator_impl = void(*)(iterator&, const void*); + using insert_impl = void (*)(const void*, const void*); + //iterator + using iterator_impl = void (*)(iterator*); + public: + size_impl vsize; + to_iterator_impl vbegin; + to_iterator_impl vend; + insert_impl vinsert; + iterator_impl viterator_add; + iterator_impl viterator_sub; + template + static void insert(const void* ptr, const void* obj) { + using value_type = typename T::value_type; + if constexpr (is_sequence_v) { + ((T*)ptr)->push_back(*(value_type*)obj); + } + else if constexpr (is_map_v) { + ((T*)ptr)->insert(*(value_type*)obj); + } + } + }; + template + class UClass_Container : public UClass_Container_Impl { + public: + static bool construct(void* ptr, const UClass* cls, span ArgsList) { + new(ptr)T(); + return true; + } + static void destruct(void* ptr) { + ((T*)ptr)->~T(); + } + static void begin(iterator& pit, const void* ptr) { + auto it = ((T*)ptr)->begin(); + memcpy(&pit, &it, sizeof(it)); + pit.val = &*it; + } + static void end(iterator& pit, const void* ptr) { + auto it = ((T*)ptr)->end(); + memcpy(&pit, &it, sizeof(it)); + pit.val = &*it; + } + static void add(iterator* pit) { + auto it = ++(*(typename T::iterator*)pit); + memcpy(pit, &it, sizeof(it)); + pit->val = &*it; + } + static void sub(iterator* pit) { + auto it = --(*(typename T::iterator*)pit); + memcpy(pit, &it, sizeof(it)); + pit->val = &*it; + } + UClass_Container() : UClass_Container_Impl(meta_name().View(), sizeof(T)) { + parent = meta_info(); + flag = CLASS_CONTAINER_FLAG; + vtable.AddConstruct(&UClass_Container::construct); + vtable.AddDestruct(&UClass_Container::destruct); + if constexpr (is_sequence_v) { + flag |= CLASS_SEQUENCE_FLAG; + } + else if constexpr (is_map_v) + { + flag |= CLASS_MAP_FLAG; + } + auto p_size = &T::size; + vsize = *(size_impl*)&p_size; + vbegin = &UClass_Container::begin; + vend = &UClass_Container::end; + vinsert = &UClass_Container::insert; + + viterator_add = &UClass_Container::add; + viterator_sub = &UClass_Container::sub; + }; + }; template class UClass_Meta : public UClass { using FieldsType = decltype(MetaImpl::MakeFields()); + public: FieldsType Fields{ MetaImpl::MakeFields() }; - UClass_Meta() : UClass(type_name().View(), sizeof(T)) { + UClass_Meta() : UClass(meta_name().View(), sizeof(T)) { if constexpr (has_parent_v) { - parent = type_info>(); + parent = meta_info>(); } - + vtable.AddGetFields(&UClass_Meta::GetFields); + vtable.AddConstruct(&UClass::Construct); + } + span GetFields(EFieldFind find, const Name& name) const { + constexpr int length = std::tuple_size::value; + constexpr int MemberCount = MetaImpl::MemberCount(); + constexpr int CtorCount = MetaImpl::CtorCount(); + switch (find) { + case EFieldFind::FIND_ALL_FIELD: + return span(&Fields[0], length); + case EFieldFind::FIND_ALL_MEMBER: + return span(&Fields[0], MemberCount); + case EFieldFind::FIND_ALL_METHOD: + return span(&Fields[MemberCount + CtorCount], length - MemberCount - CtorCount); + case EFieldFind::FIND_CTOR: + return span(&Fields[MemberCount], CtorCount); + case EFieldFind::FIND_FIELD: + for (int i = 0; i < length; i++) { + if (name == Fields[i].name) { + return span(&Fields[i], 1); + } + } + return {}; + case EFieldFind::FIND_MEMBER: + for (int i = 0; i < MemberCount; i++) { + if (name == Fields[i].name) { + return span(&Fields[i], 1); + } + } + return {}; + case EFieldFind::FIND_METHOD: + for (int i = MemberCount + CtorCount; i < length; i++) { + if (name == Fields[i].name) { + return span(&Fields[i], 1); + } + } + return {}; + case EFieldFind::FIND_METHODS: + { + int first = 0, count = 0; + for (int i = MemberCount + CtorCount; i < length; i++) { + if (name == Fields[i].name) { + if (!count) { + first = i; + } + count++; + } + else if (count) { + return span(&Fields[first], count); + } + } + return {}; + } + default: + return {}; + } + } + static span GetFields(const UClass* _cls, EFieldFind find, Name name) { + auto cls = static_cast(_cls); + return cls->GetFields(find, name); + } + }; + template + struct meta_info_impl { + static UClass* create() { + return new(MetaGlobalPool()) UClass_Auto{}; + } + }; + template + struct meta_info_impl { + static UClass* create() { + return new(MetaGlobalPool()) UMethod_Auto{}; + } + }; + template + struct meta_info_impl { + static UClass* create() { + return new(MetaGlobalPool()) UClass_Container{}; } }; using __tClassTable = table; @@ -50,22 +260,22 @@ namespace refl { return nullptr; } template - inline const UClass* type_info() + inline const UClass* meta_info() { using T = real_type_t; - constexpr auto name = type_name(); + constexpr auto name = meta_name(); if (auto cls = find_info(name.View())) { return cls; } UClass* cls; if constexpr (is_meta_v){ - cls = new(GlobalPool()) UClass_Meta>{}; + cls = new(MetaGlobalPool()) UClass_Meta>{}; } else if constexpr (std::is_same_v) { - cls = new(GlobalPool()) UClass{ name.View(), 0 }; + cls = new(MetaGlobalPool()) UClass{ name.View(), 0 }; } else { - cls = new(GlobalPool()) UClass_Auto{}; + cls = meta_info_impl::create(); } auto& ClassTable = UNIQUER_VAL(ClassTable); ClassTable[name.View()] = cls; diff --git a/engine/modules/engine/zlib/include/refl/pch.h b/engine/modules/engine/zlib/include/refl/pch.h index b20f32b..46a6cdc 100644 --- a/engine/modules/engine/zlib/include/refl/pch.h +++ b/engine/modules/engine/zlib/include/refl/pch.h @@ -2,5 +2,7 @@ #include "detail/name.inl" #include "detail/any.inl" #include "detail/meta.inl" -#include "detail/uclass.inl" +#include "detail/field.inl" +#include "detail/convert.inl" +#include "detail/container.inl" #include "macro.h" \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/std/parray.h b/engine/modules/engine/zlib/include/refl/std/parray.h index 4122d23..6e50502 100644 --- a/engine/modules/engine/zlib/include/refl/std/parray.h +++ b/engine/modules/engine/zlib/include/refl/std/parray.h @@ -10,7 +10,7 @@ namespace refl { parray(): m_cls(nullptr), m_ptr(nullptr),m_count(0) {} template requires std::is_base_of_v - parray(std::vector& vec) : m_cls(type_info()), m_ptr(nullptr){ + parray(std::vector& vec) : m_cls(meta_info()), m_ptr(nullptr){ m_count = vec.size(); if (m_count > 0) { C* ptr = new C[m_count]; diff --git a/engine/modules/xmake.lua b/engine/modules/xmake.lua index a691cf2..734b6f3 100644 --- a/engine/modules/xmake.lua +++ b/engine/modules/xmake.lua @@ -12,13 +12,14 @@ end function static_component(name, owner, opt) target(owner) add_deps(name) + add_includedirs("impl") + add_headerfiles("impl/*.inl") target_end() target(name) set_kind("static") set_group("Engine/"..owner.."__comp") add_rules("engine.api") add_includedirs("include", {public = true}) - add_includedirs("impl") add_deps("singleton") end function shared_module(name, owner, opt) diff --git a/game/zworld/editor/test_refl.h b/game/zworld/editor/test_refl.h new file mode 100644 index 0000000..bf0aaff --- /dev/null +++ b/game/zworld/editor/test_refl.h @@ -0,0 +1,25 @@ +#include "refl/pch.h" +#include +using namespace refl; +using namespace std; +namespace api { + struct Guid { + UPROPERTY() + int a; + UPROPERTY() + float b; + UPROPERTY() + string view; + USING_OVERLOAD_CTOR(Guid, int , float) + UFUNCTION({}, ref = USING_CTOR_NAME) + Guid(int aa, float bb) :a(aa), b(bb), view("default") { + cout << view << endl; + } + UFUNCTION({}) + int Multy(int c)const { + int d = a * b; + return d * c; + } + }; +} +#include ".zworld-editor/test_refl_gen.inl" \ No newline at end of file diff --git a/game/zworld/editor/zworld_editor.cpp b/game/zworld/editor/zworld_editor.cpp index c4bfb67..66d8193 100644 --- a/game/zworld/editor/zworld_editor.cpp +++ b/game/zworld/editor/zworld_editor.cpp @@ -1,22 +1,26 @@ #define ZLIB_API #define ZLIB_API_VAL -#include "refl/pch.h" -#include -using namespace refl; -namespace api { - struct api_t { - - }; -} -struct test { - -}; -void (*testfn)(test); -using testfn_t = decltype(testfn); +#define CORE_API +#define CORE_API_VAL +#include "archive/json.h" +#include "test_refl.h" +#include +using namespace api; int main() { - auto r1 = type_name(); - auto r2 = type_name(); - auto t1 = r1.View(); - auto t2 = r2.View(); + table t1, t2; + t1[1] = "hello"; + t1[2] = "world"; + auto text = JsonSerialize(t1); + FileHandle handle("test.txt"); + handle.Open(FILE_OP::WRITE, false); + handle.Write(text); + auto res = JsonDeserialize>(text); + if (res) { + t2 = *res; + } + auto cls = meta_info(); + Any args[3] = { Any{ (int)2 }, Any{ (float)3 }, Any{false} }; + Any obj = cls->New(FramePool(), span{args}); + auto ptr = &api::Guid::Multy; std::cout << "hello world" << std::endl; } \ No newline at end of file diff --git a/game/zworld/logs/zengine.log b/game/zworld/logs/zengine.log new file mode 100644 index 0000000..e69de29 diff --git a/game/zworld/xmake.lua b/game/zworld/xmake.lua index 376752c..f9c8887 100644 --- a/game/zworld/xmake.lua +++ b/game/zworld/xmake.lua @@ -4,6 +4,9 @@ target("zworld") add_headerfiles("src/*.h") add_dependency("engine", "editor", "vulkan", {public = true}) target("zworld-editor") + add_rules("c++.codegen",{ + files = {"editor/test_refl.h"} + }) add_files("editor/*.cpp") add_headerfiles("editor/*.h") - add_deps("zlib") \ No newline at end of file + add_deps("zlib", "core") \ No newline at end of file