diff --git a/engine/assets/asset/mesh1.asset.meta b/engine/assets/asset/mesh1.asset.meta index 44d40d6..b910e10 100644 --- a/engine/assets/asset/mesh1.asset.meta +++ b/engine/assets/asset/mesh1.asset.meta @@ -6,9 +6,9 @@ metadatas: __class__: engineapi::Shader __data__: mVert: - guid: 9419e2a5-ddc4-414f-aa76-d08e9b162492 + guid: 020486aa-8987-4bd1-9de9-eeb7ab82c437 mFrag: - guid: eb1c9b43-a86b-40cb-9b3d-a3296d168c70 + guid: a4064a70-89d5-4d8f-b3c3-6486dcf786c0 - guid: 7a01231c-c35d-4b74-b20f-4ca6823995d9 name: "" t_hash: engineapi::Asset @@ -16,4 +16,8 @@ metadatas: __class__: engineapi::Material __data__: mShader: - guid: 0a2ef3e8-db70-4d3f-94b1-09f9f92519cd \ No newline at end of file + guid: 0a2ef3e8-db70-4d3f-94b1-09f9f92519cd +includes: + - /engine/assets/asset/mesh1.asset + - /engine/assets/shader/simple.frag + - /engine/assets/shader/simple.vert \ No newline at end of file diff --git a/engine/assets/file_resource.meta b/engine/assets/file_resource.meta index 0454be7..3712f59 100644 --- a/engine/assets/file_resource.meta +++ b/engine/assets/file_resource.meta @@ -1,10 +1,10 @@ /engine/assets/shader/simple.vert: - - 9419e2a5-ddc4-414f-aa76-d08e9b162492 + - 020486aa-8987-4bd1-9de9-eeb7ab82c437 /engine/assets/asset/mesh1.asset: - - 0a2ef3e8-db70-4d3f-94b1-09f9f92519cd - 7a01231c-c35d-4b74-b20f-4ca6823995d9 -/engine/assets/shader/simple.frag: - - eb1c9b43-a86b-40cb-9b3d-a3296d168c70 + - 0a2ef3e8-db70-4d3f-94b1-09f9f92519cd /engine/assets/models/cube.obj: - - 619d2750-cedc-40cc-8781-fbdd116ded89 - - 6c60e6b2-2ae6-4508-8117-8e797b9ac4bd \ No newline at end of file + - 3f6a5afc-2f21-47c4-86ba-9ddb9852d8f4 + - b91ca918-6b3c-4647-8773-d93d2807cb98 +/engine/assets/shader/simple.frag: + - a4064a70-89d5-4d8f-b3c3-6486dcf786c0 \ No newline at end of file diff --git a/engine/assets/models/cube.obj.meta b/engine/assets/models/cube.obj.meta index 5baa48f..0a0853f 100644 --- a/engine/assets/models/cube.obj.meta +++ b/engine/assets/models/cube.obj.meta @@ -1,13 +1,15 @@ metadatas: - - guid: 6c60e6b2-2ae6-4508-8117-8e797b9ac4bd + - guid: 3f6a5afc-2f21-47c4-86ba-9ddb9852d8f4 name: "" t_hash: engineapi::Model meta: ~ - - guid: 619d2750-cedc-40cc-8781-fbdd116ded89 + - guid: b91ca918-6b3c-4647-8773-d93d2807cb98 name: defaultobject t_hash: engineapi::Asset meta: __class__: engineapi::Mesh __data__: mMaterial: - guid: 7a01231c-c35d-4b74-b20f-4ca6823995d9 \ No newline at end of file + guid: 7a01231c-c35d-4b74-b20f-4ca6823995d9 +includes: + - /engine/assets/asset/mesh1.asset \ No newline at end of file diff --git a/engine/assets/shader/simple.frag.meta b/engine/assets/shader/simple.frag.meta index f024419..78a9e5f 100644 --- a/engine/assets/shader/simple.frag.meta +++ b/engine/assets/shader/simple.frag.meta @@ -1,5 +1,6 @@ metadatas: - - guid: eb1c9b43-a86b-40cb-9b3d-a3296d168c70 + - guid: a4064a70-89d5-4d8f-b3c3-6486dcf786c0 name: "" t_hash: engineapi::ShaderProgram - metadata: "" \ No newline at end of file + meta: ~ +includes: ~ \ No newline at end of file diff --git a/engine/assets/shader/simple.vert.meta b/engine/assets/shader/simple.vert.meta index 7a9d7c0..a9a2173 100644 --- a/engine/assets/shader/simple.vert.meta +++ b/engine/assets/shader/simple.vert.meta @@ -1,5 +1,6 @@ metadatas: - - guid: 9419e2a5-ddc4-414f-aa76-d08e9b162492 + - guid: 020486aa-8987-4bd1-9de9-eeb7ab82c437 name: "" t_hash: engineapi::ShaderProgram - metadata: "" \ No newline at end of file + meta: ~ +includes: ~ \ No newline at end of file diff --git a/engine/src/engine/asset/asset.cpp b/engine/src/engine/asset/asset.cpp index d036b98..c61eb26 100644 --- a/engine/src/engine/asset/asset.cpp +++ b/engine/src/engine/asset/asset.cpp @@ -6,11 +6,37 @@ #include "object/loader/assimp_loader.h" #include "yaml/yaml.h" namespace engineapi { + void FindIncludes(MetaBundle& bundle, Asset* asset) { + auto fieldList = asset->meta->GetFields(refl::FIND_ALL_MEMBER, FName("")); + refl::Any any(asset, asset->meta); + auto cls = &refl::TypeInfo::StaticClass; + for (auto field : fieldList) { + if (field.type == cls) { + RscHandleBase* base = any.Member(field).CastTo(); + FileBlock* file = ResourceManager::GetSingleton().GetResourceFile(base->guid); + if (file) { + bundle.includes.push_back(file->path); + } + } + } + } MetaBundle ResourceManager::GetVisitMeta(const ResourceBundle& bundle) { MetaBundle new_meta = MetaBundle{}; for (auto& elem : bundle.GetAll()) - std::visit([&](auto& handle) { new_meta.Add(handle); }, elem); + std::visit([&](auto& handle) { + using T = std::decay_t; + new_meta.Add(handle); + if constexpr (std::is_same_v) { + FindIncludes(new_meta, &*handle); + } + }, elem); + auto& v = new_meta.includes; + if (v.size() > 1) { + std::sort(v.begin(), v.end()); // 首先排序 + auto end_unique = std::unique(v.begin(), v.end()); // 去除重复元素 + v.erase(end_unique, v.end()); + } return new_meta; } void Asset::__Init__() diff --git a/engine/src/engine/asset/asset_loader.cpp b/engine/src/engine/asset/asset_loader.cpp index 81a3b0b..4d6acd0 100644 --- a/engine/src/engine/asset/asset_loader.cpp +++ b/engine/src/engine/asset/asset_loader.cpp @@ -3,8 +3,6 @@ #include "yaml/yaml.h" #include #include "file_handle.h" - -#include "render/asset/material.h" namespace engineapi { void AssetLoader::Init() { ResourceManager::GetSingleton().RegisterLoader(".asset"); @@ -16,22 +14,6 @@ namespace engineapi { if (!meta.meta) continue; auto rsc = ResourceManager::GetSingleton().LoadFromMeta(meta.guid, meta); - if (meta.meta.cls == &refl::TypeInfo::StaticClass) { - Shader* asset = (Shader*)& *rsc; - Guid g1 = asset->GetGuid(); - Guid g2 = meta.guid; - bool isame = g1 == g2; - g1 = meta.guid; - g2 = asset->GetGuid(); - } - else if (meta.meta.cls == &refl::TypeInfo::StaticClass) { - Material* asset = (Material*)&*rsc; - Guid g1 = asset->GetGuid(); - Guid g2 = meta.guid; - bool isame = g1 == g2; - g1 = meta.guid; - g2 = asset->GetGuid(); - } bundle.Add(rsc); } return bundle; diff --git a/engine/src/engine/asset/res/meta_bundle.cpp b/engine/src/engine/asset/res/meta_bundle.cpp index 733ad13..c318b21 100644 --- a/engine/src/engine/asset/res/meta_bundle.cpp +++ b/engine/src/engine/asset/res/meta_bundle.cpp @@ -3,9 +3,18 @@ namespace engineapi { + const SerializedMeta* MetaBundle::FetchMeta(const Guid& guid) const + { + for (auto& elem : metadatas) + { + if (elem.guid == guid) + return &elem; + } + return nullptr; + } bool MetaBundle::operator==(const MetaBundle& other)const { - return metadatas == other.metadatas; + return metadatas == other.metadatas && includes == other.includes; } bool MetaBundle::operator!=(const MetaBundle& other)const { diff --git a/engine/src/engine/asset/res/meta_bundle.h b/engine/src/engine/asset/res/meta_bundle.h index 5c26698..d4c356b 100644 --- a/engine/src/engine/asset/res/meta_bundle.h +++ b/engine/src/engine/asset/res/meta_bundle.h @@ -11,7 +11,7 @@ namespace engineapi UPROPERTY({}) string name; UPROPERTY({}) - string t_hash{}; + string t_hash; UPROPERTY({}) refl::Any meta; bool operator==(const SerializedMeta& other)const{ @@ -23,9 +23,11 @@ namespace engineapi { UPROPERTY({}) vector metadatas; - + UPROPERTY({}) + vector includes; MetaBundle() = default; + const SerializedMeta* FetchMeta(const Guid& guid) const; template const SerializedMeta* FetchMeta() const; template diff --git a/engine/src/engine/asset/res/package_path.h b/engine/src/engine/asset/res/package_path.h index 2325add..a49d386 100644 --- a/engine/src/engine/asset/res/package_path.h +++ b/engine/src/engine/asset/res/package_path.h @@ -21,7 +21,7 @@ namespace engineapi }; //占位符浪费了四个字节 struct FileBlock { - uint32_t flag; + uint32_t flag{0}; string path; string addr; operator bool() { diff --git a/engine/src/engine/asset/res/resource_config.h b/engine/src/engine/asset/res/resource_config.h index c1932c3..449855d 100644 --- a/engine/src/engine/asset/res/resource_config.h +++ b/engine/src/engine/asset/res/resource_config.h @@ -19,6 +19,7 @@ namespace engineapi { RscHandle mHandle; std::string mName; friend class RscHandle; + friend class ResourceManager; }; using Resources = std::tuple< class ShaderProgram diff --git a/engine/src/engine/asset/res/resource_handle.h b/engine/src/engine/asset/res/resource_handle.h index 469529e..d4dbd4e 100644 --- a/engine/src/engine/asset/res/resource_handle.h +++ b/engine/src/engine/asset/res/resource_handle.h @@ -8,7 +8,7 @@ namespace engineapi struct RscHandleBase { UPROPERTY({}) Guid guid; - void* res; + void* res{nullptr}; }; template struct RscHandle : public RscHandleBase @@ -17,7 +17,7 @@ namespace engineapi constexpr RscHandle() noexcept = default; template constexpr RscHandle(const RscHandle& other) noexcept : RscHandleBase(other.guid, other.res) {}; - constexpr RscHandle(const Guid& guid, Res* res) noexcept : RscHandleBase(guid, res) { ((Resource*)res)->mHandle = *this; } + constexpr RscHandle(const Guid& guid, Res* res) noexcept : RscHandleBase(guid, res) {} void Init(); void Clear() { res = nullptr; }; Res* operator->() { if (!res && guid) Init(); return (Res*)res; } diff --git a/engine/src/engine/asset/resource_manager.cpp b/engine/src/engine/asset/resource_manager.cpp index 8ca6ee5..44e36e5 100644 --- a/engine/src/engine/asset/resource_manager.cpp +++ b/engine/src/engine/asset/resource_manager.cpp @@ -31,16 +31,14 @@ namespace engineapi { return nullptr; return itr->second; } - ResourceBundle& ResourceManager::Load(const PackagePath& path, bool reload_resource) + ResourceBundle& ResourceManager::Load(const PackagePath& path, bool reload_resource, int deep) { NameID name = path(); auto it = mFileBlock.find(name); - if (it != mFileBlock.end()) { - if (!reload_resource) { - return it->second.bundle; - } - } auto& res = mFileBlock[name]; + if (deep > 5 || (!reload_resource && res && it != mFileBlock.end())) { + return res.bundle; + } Name ext = path.GetExtension(); IFileLoader* loader = GetLoader(ext); MetaBundle meta = GetMeta(path); @@ -54,13 +52,18 @@ namespace engineapi { mResourceFile[handle.guid] = FileManager::FindPathBlock(path); }, elem); } - if (is_dirty_meta || res.is_dirty) { + if (is_dirty_meta || res.IsDirty()) { mDirtyBlock.push_back(&res); } res.path = path.SafePath(); res.bundle = bundle; - res.is_meta_dirty = is_dirty_meta; + res.Loaded(true).MetaDirty(is_dirty_meta); res.bundle = bundle; + if (!new_meta.includes.empty()) { + for (auto include : new_meta.includes) { + Load(include, false, deep + 1); + } + } return res.bundle; } @@ -97,13 +100,13 @@ namespace engineapi { void ResourceManager::SaveDirtyFile() { for (auto block : mDirtyBlock) { - if (block->is_meta_dirty) { - block->is_meta_dirty = false; + if (block->IsMetaDirty()) { + block->MetaDirty(false); MetaBundle new_meta = GetVisitMeta(block->bundle); SaveMeta(block->path, new_meta); } - if (block->is_dirty) { - block->is_dirty = false; + if (block->IsDirty()) { + block->Dirty(false); auto loader = GetLoader(block->path.GetExtension()); loader->SaveFile(block->path, block->bundle); } diff --git a/engine/src/engine/asset/resource_manager.h b/engine/src/engine/asset/resource_manager.h index 5e27554..2bf73f2 100644 --- a/engine/src/engine/asset/resource_manager.h +++ b/engine/src/engine/asset/resource_manager.h @@ -17,6 +17,22 @@ namespace engineapi { FileDoesNotExist, FailedToLoadResource, }; + struct ResourceFileFlag{ + enum Value : uint32_t { + File_Default = 0, + File_Dirty = 1 << 0, + File_Meta_Dirty = 1 << 1, + File_Loaded = 1 << 2, + }; + Value val{ File_Default }; + // 构造函数和操作符重载,使类实例像整数一样使用 + ResourceFileFlag(Value v = File_Default) : val(v) {} + operator uint32_t() const { return val; } + ResourceFileFlag& operator=(Value v) { + val = v; + return *this; + } + }; template using LoadResult = result; class ResourceManager : public ISingleton @@ -69,7 +85,7 @@ namespace engineapi { template RscHandle Load(const PackagePath& path, bool reload_resource = true); - ResourceBundle& Load(const PackagePath& path, bool reload_resource = true); + ResourceBundle& Load(const PackagePath& path, bool reload_resource = true, int deep = 0); MetaBundle GetMeta(const PackagePath& path); MetaBundle GetVisitMeta(const ResourceBundle& bundle); void SaveMeta(const PackagePath& path, const MetaBundle& bundle); @@ -86,14 +102,29 @@ namespace engineapi { { ResourceBundle bundle; PackagePath path; - bool is_dirty{ false }; - bool is_meta_dirty{ false }; + uint32_t flag{0}; + ResourceFileBlock& SetFlag(bool is, ResourceFileFlag _flag) { + if (is) + flag |= _flag; + else + flag &= ~_flag; + return *this; + } + operator bool() { + return IsLoaded(); + } + ResourceFileBlock& Loaded(bool is) { return SetFlag(is, ResourceFileFlag::File_Loaded); } + ResourceFileBlock& Dirty(bool is) { return SetFlag(is, ResourceFileFlag::File_Dirty); } + ResourceFileBlock& MetaDirty(bool is) { return SetFlag(is, ResourceFileFlag::File_Meta_Dirty); } + bool IsLoaded() { return flag & ResourceFileFlag::File_Loaded; } + bool IsDirty() { return flag & ResourceFileFlag::File_Dirty; } + bool IsMetaDirty() { return flag & ResourceFileFlag::File_Meta_Dirty; } }; template struct ResourceManager::ResourceBlock { - R* resource; - ResourceFileBlock* file; + R* resource{nullptr}; + ResourceFileBlock* file{ nullptr }; bool valid() const { return resource; } }; } diff --git a/engine/src/engine/asset/resource_manager.inl b/engine/src/engine/asset/resource_manager.inl index 32a6890..ee01393 100644 --- a/engine/src/engine/asset/resource_manager.inl +++ b/engine/src/engine/asset/resource_manager.inl @@ -55,6 +55,7 @@ namespace engineapi { } else { control_block.resource = res; + res->mHandle.guid = guid; } res->Name(meta.name); return RscHandle{guid, res}; @@ -66,6 +67,7 @@ namespace engineapi { auto& control_block = table[guid]; // don't care just replace // attempt to put on other thread Res* res = new Res(std::forward(args)...); + res->mHandle.guid = guid; control_block.resource = res; return RscHandle{guid, res}; } diff --git a/engine/src/engine/object/loader/assimp_loader.cpp b/engine/src/engine/object/loader/assimp_loader.cpp index 6f5ec72..c47143c 100644 --- a/engine/src/engine/object/loader/assimp_loader.cpp +++ b/engine/src/engine/object/loader/assimp_loader.cpp @@ -131,7 +131,7 @@ namespace engineapi { RscHandle asset = m ? ResourceManager::GetSingleton().LoadEmplaceResource(m->guid, vertices, indices) : ResourceManager::GetSingleton().LoadEmplaceResource(vertices, indices); if (m && m->meta) { - void* ptr = &*asset; + Mesh* ptr = &*asset; m->meta.MoveTo(ptr); } asset->Name(mesh->mName.C_Str()); diff --git a/engine/src/engine/render/asset/material.h b/engine/src/engine/render/asset/material.h index 25787e4..9cd8a92 100644 --- a/engine/src/engine/render/asset/material.h +++ b/engine/src/engine/render/asset/material.h @@ -11,6 +11,9 @@ namespace engineapi { public: Material(); ~Material(); + void BeginLoad() { + mShader->BeginLoad(); + } RscHandle GetShader() { return mShader; } diff --git a/engine/src/engine/render/asset/mesh.cpp b/engine/src/engine/render/asset/mesh.cpp index b301fb4..f768676 100644 --- a/engine/src/engine/render/asset/mesh.cpp +++ b/engine/src/engine/render/asset/mesh.cpp @@ -6,6 +6,7 @@ namespace engineapi { } void Mesh::BeginLoad() { + mMaterial->BeginLoad(); RenderAPI::GetSingletonPtr()->SetStaticMesh(*this); } } diff --git a/engine/src/engine/render/asset/shader.cpp b/engine/src/engine/render/asset/shader.cpp index 1af8964..86bb24c 100644 --- a/engine/src/engine/render/asset/shader.cpp +++ b/engine/src/engine/render/asset/shader.cpp @@ -1,4 +1,5 @@ #include "shader.h" +#include "render/renderapi.h" namespace engineapi { Shader::Shader() : Asset(&refl::TypeInfo::StaticClass) { @@ -7,4 +8,8 @@ namespace engineapi { Shader::~Shader() { } + void Shader::BeginLoad() + { + RenderAPI::GetSingletonPtr()->LoadShader(*this); + } } diff --git a/engine/src/engine/render/asset/shader.h b/engine/src/engine/render/asset/shader.h index dd5da16..bcaa667 100644 --- a/engine/src/engine/render/asset/shader.h +++ b/engine/src/engine/render/asset/shader.h @@ -5,7 +5,7 @@ namespace engineapi { class Shader : public Asset { private: REFL_FRIEND(Shader) - uint32_t mId; + uint32_t mId{0}; ShaderInfo mInfo; UPROPERTY() RscHandle mVert; @@ -15,6 +15,7 @@ namespace engineapi { public: Shader(); ~Shader(); + void BeginLoad(); uint32_t& GetID() { return mId; }