From 9d09dee27fcc32a6bf1a529264edd2d6cf036b59 Mon Sep 17 00:00:00 2001 From: ouczbs Date: Tue, 2 Jul 2024 17:27:38 +0800 Subject: [PATCH] rebuild file_manager --- engine/assets/shader/gen/simple.frag.spv | Bin 460 -> 0 bytes engine/assets/shader/gen/simple.vert.spv | Bin 1388 -> 0 bytes engine/assets/shader/gen_glsl.bat | 20 ---- engine/assets/shader/simple.frag.spv | Bin 460 -> 0 bytes engine/assets/shader/simple.json | 0 engine/assets/shader/simple.ps.glsl | 8 -- engine/assets/shader/simple.vert | 3 - engine/assets/shader/simple.vert.spv | Bin 1388 -> 0 bytes engine/assets/shader/simple.vs.glsl | 27 ----- engine/src/engine/asset/asset.cpp | 12 +++ engine/src/engine/asset/file_manager.cpp | 52 ++++++--- engine/src/engine/asset/file_manager.h | 51 +++++++-- engine/src/engine/asset/res/meta_bundle.cpp | 9 +- engine/src/engine/asset/res/meta_bundle.h | 7 ++ engine/src/engine/asset/res/meta_bundle.inl | 8 ++ engine/src/engine/asset/res/package_path.cpp | 22 ++-- engine/src/engine/asset/res/package_path.h | 55 +++++----- engine/src/engine/asset/res/resource_bundle.h | 1 + .../src/engine/asset/res/resource_bundle.inl | 7 +- engine/src/engine/asset/res/resource_config.h | 4 + engine/src/engine/asset/res/resource_handle.h | 11 +- engine/src/engine/asset/resource_manager.cpp | 101 ++++++++++++++++-- engine/src/engine/asset/resource_manager.h | 39 +++++-- engine/src/engine/asset/resource_manager.inl | 40 +++++-- engine/src/engine/object/scene/scene.cpp | 2 +- engine/src/engine/render/asset/model.cpp | 2 +- .../vulkanapi/loader/vulkan_glsl_loader.cpp | 21 ++-- .../engine/vulkanapi/tool/glsl_to_spirv.cpp | 12 +-- .../src/engine/vulkanapi/tool/glsl_to_spirv.h | 2 +- 29 files changed, 352 insertions(+), 164 deletions(-) delete mode 100644 engine/assets/shader/gen/simple.frag.spv delete mode 100644 engine/assets/shader/gen/simple.vert.spv delete mode 100644 engine/assets/shader/gen_glsl.bat delete mode 100644 engine/assets/shader/simple.frag.spv delete mode 100644 engine/assets/shader/simple.json delete mode 100644 engine/assets/shader/simple.ps.glsl delete mode 100644 engine/assets/shader/simple.vert.spv delete mode 100644 engine/assets/shader/simple.vs.glsl create mode 100644 engine/src/engine/asset/asset.cpp diff --git a/engine/assets/shader/gen/simple.frag.spv b/engine/assets/shader/gen/simple.frag.spv deleted file mode 100644 index d3a34da739fba3451e4363825ef5dd2ceb1d6feb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 460 zcmYk3PfNo<5XHx)X>04Bil8^CcvOl9ErOt^$X)`4_5&<2S#TvLA-ffN>u2**c@cbX zRmg_P?7aQWat-WQY@`3@DI!M<<&r5nT#o=7yy diff --git a/engine/assets/shader/gen/simple.vert.spv b/engine/assets/shader/gen/simple.vert.spv deleted file mode 100644 index b3268c239576f9da290e5381651265414ccb169b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1388 zcmYk5-A~j&6vc<#c12JS5by)BhzbaGzvNkERo3{Az=6`15 zU*(I5=QnM2XLEDsoO|x{-kH1Y*7gNsX3V^~Y@V2EEt!@WBd+6p-22e$7Ui(}^w}Yb z1=IFIG>gh(1+ue#>e#Q#ZpwCL4`lnY16f!0Sk~6BCI3qY1ZK{}y(B(4iFt)2y7U?Gh~JXu+w|G=7HMzHk0auDwc}gVL#_Aa(Zdnnk>@OU&IdCy&G~!vp7V)= znIYnho*A0P%utj6u-@~1^k8O+IQ2Y|XC}Bi>N%7r29F-h%)vd^doo98S@iH*472!J zh`Hc>UP-}yZOFK*H&Sp<%q<#tH1u>^2LE0f?q#dyf(j$FSd(gj{pDw diff --git a/engine/assets/shader/gen_glsl.bat b/engine/assets/shader/gen_glsl.bat deleted file mode 100644 index 5b97178..0000000 --- a/engine/assets/shader/gen_glsl.bat +++ /dev/null @@ -1,20 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -set /p=exec.bat -set destPath=%2cpp/ -ECHO @echo on >>exec.bat -for %%i in (*.vs.glsl) do ( - set "s=%%i" - echo !s:vs.glsl=vert.spv! - set /p="glslc -fshader-stage=vertex %%i -o !s:vs.glsl=vert.spv!"> exec.bat - ECHO.>> exec.bat -) -for %%i in (*.ps.glsl) do ( - set "s=%%i" - echo !s:ps.glsl=frag.spv! - set /p="glslc -fshader-stage=fragment %%i -o !s:ps.glsl=frag.spv!"> exec.bat - ECHO.>> exec.bat -) -ECHO @echo off>> exec.bat -call exec.bat -del exec.bat \ No newline at end of file diff --git a/engine/assets/shader/simple.frag.spv b/engine/assets/shader/simple.frag.spv deleted file mode 100644 index d3a34da739fba3451e4363825ef5dd2ceb1d6feb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 460 zcmYk3PfNo<5XHx)X>04Bil8^CcvOl9ErOt^$X)`4_5&<2S#TvLA-ffN>u2**c@cbX zRmg_P?7aQWat-WQY@`3@DI!M<<&r5nT#o=7yy diff --git a/engine/assets/shader/simple.json b/engine/assets/shader/simple.json deleted file mode 100644 index e69de29..0000000 diff --git a/engine/assets/shader/simple.ps.glsl b/engine/assets/shader/simple.ps.glsl deleted file mode 100644 index 1a85ab6..0000000 --- a/engine/assets/shader/simple.ps.glsl +++ /dev/null @@ -1,8 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) out vec4 outColor; - -void main() { - outColor = vec4(1.0, 0.0, 0.0, 1.0); -} \ No newline at end of file diff --git a/engine/assets/shader/simple.vert b/engine/assets/shader/simple.vert index 06ed755..178188e 100644 --- a/engine/assets/shader/simple.vert +++ b/engine/assets/shader/simple.vert @@ -1,7 +1,6 @@ #version 450 #extension GL_GOOGLE_include_directive : enable -// 顶点位置输入变量 layout (location = 0) in vec3 position; layout (location = 1) in vec2 texture; layout (location = 2) in vec3 normal; @@ -9,8 +8,6 @@ layout (location = 3) in vec3 tangent; layout (location = 4) in vec4 weights; layout (location = 5) in uvec4 bones; - -// 顶点位置输出变量 //out vec4 outPosition; out gl_PerVertex { vec4 gl_Position; diff --git a/engine/assets/shader/simple.vert.spv b/engine/assets/shader/simple.vert.spv deleted file mode 100644 index b3268c239576f9da290e5381651265414ccb169b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1388 zcmYk5-A~j&6vc<#c12JS5by)BhzbaGzvNkERo3{Az=6`15 zU*(I5=QnM2XLEDsoO|x{-kH1Y*7gNsX3V^~Y@V2EEt!@WBd+6p-22e$7Ui(}^w}Yb z1=IFIG>gh(1+ue#>e#Q#ZpwCL4`lnY16f!0Sk~6BCI3qY1ZK{}y(B(4iFt)2y7U?Gh~JXu+w|G=7HMzHk0auDwc}gVL#_Aa(Zdnnk>@OU&IdCy&G~!vp7V)= znIYnho*A0P%utj6u-@~1^k8O+IQ2Y|XC}Bi>N%7r29F-h%)vd^doo98S@iH*472!J zh`Hc>UP-}yZOFK*H&Sp<%q<#tH1u>^2LE0f?q#dyf(j$FSd(gj{pDw diff --git a/engine/assets/shader/simple.vs.glsl b/engine/assets/shader/simple.vs.glsl deleted file mode 100644 index 06ed755..0000000 --- a/engine/assets/shader/simple.vs.glsl +++ /dev/null @@ -1,27 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable - -// 顶点位置输入变量 -layout (location = 0) in vec3 position; -layout (location = 1) in vec2 texture; -layout (location = 2) in vec3 normal; -layout (location = 3) in vec3 tangent; -layout (location = 4) in vec4 weights; -layout (location = 5) in uvec4 bones; - - -// 顶点位置输出变量 -//out vec4 outPosition; -out gl_PerVertex { - vec4 gl_Position; -}; - -vec2 positions[3] = vec2[]( - vec2(0.0, -0.5), - vec2(0.5, 0.5), - vec2(-0.5, 0.5) -); - -void main() { - gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); -} \ No newline at end of file diff --git a/engine/src/engine/asset/asset.cpp b/engine/src/engine/asset/asset.cpp new file mode 100644 index 0000000..b6bc00a --- /dev/null +++ b/engine/src/engine/asset/asset.cpp @@ -0,0 +1,12 @@ +#include "assert.h" +#include "render/asset/shader.h" +#include "resource_manager.h" +namespace engineapi { + MetaBundle ResourceManager::GetVisitMeta(const ResourceBundle& bundle) + { + MetaBundle new_meta = MetaBundle{}; + for (auto& elem : bundle.GetAll()) + std::visit([&](auto& handle) { new_meta.Add(handle); }, elem); + return new_meta; + } +} \ No newline at end of file diff --git a/engine/src/engine/asset/file_manager.cpp b/engine/src/engine/asset/file_manager.cpp index 24e4c39..17655cb 100644 --- a/engine/src/engine/asset/file_manager.cpp +++ b/engine/src/engine/asset/file_manager.cpp @@ -12,34 +12,53 @@ namespace engineapi { { } - string FileManager::LoadTextFile(const string& path) + string FileManager::real_path(const PackagePath& pack_path) + { + string_view name = pack_path.ParsePackage(); + string_view pre_path = FindMountPath(name); + if (name.empty() || pre_path.empty()) { + return string(pack_path.path); + } + string path; + path.reserve(pre_path.size() + pack_path.size() - name.size() - 1); + path.append(pre_path); + path.append(pack_path.path.substr(name.size() + 1)); + return path; + } + FileFlag FileManager::LoadErrorFlag(const PackagePath& pack_path) + { + uint32_t flag = FindPathFlag(pack_path); + if (flag & FileFlag::File_Http) { + return FileFlag::File_Http; + } + zlog::info("Failed to load file: {}", pack_path.path); + return FileFlag::File_Not_Exist; + } + result FileManager::LoadTextFile(const PackagePath& pack_path) { - string text = ""; ifstream file; file.exceptions(ifstream::failbit | ifstream::badbit); - try { + string path = real_path(pack_path); file.open(path); stringstream stream; stream << file.rdbuf(); file.close(); - text = stream.str(); + return stream.str(); } catch (ifstream::failure e) { - zlog::info("Failed to load text file: {}", path); + return LoadErrorFlag(pack_path); } - - return text; } - vector FileManager::LoadBinaryFile(const string& path) + result,FileFlag> FileManager::LoadBinaryFile(const PackagePath& pack_path) { + string path = real_path(pack_path); // ate:在文件末尾开始读取,从文件末尾开始读取的优点是我们可以使用读取位置来确定文件的大小并分配缓冲区 ifstream file(path, std::ios::ate | std::ios::binary); if (!file.is_open()) { - zlog::info("Failed to load binary file: {}", path); - return vector(); + return LoadErrorFlag(pack_path); } // 使用读取位置来确定文件的大小并分配缓冲区 @@ -53,13 +72,13 @@ namespace engineapi { return data; } - json FileManager::LoadJsonFile(const string& path) + result FileManager::LoadJsonFile(const PackagePath& pack_path) { + string path = real_path(pack_path); std::ifstream f(path); if (!f.is_open()) { - zlog::error("Load asset failed: {}", path); - return NULL; + return LoadErrorFlag(pack_path); } json data; try @@ -71,8 +90,15 @@ namespace engineapi { zlog::error("Asset format error: {}", path); string msg = e.what(); zlog::error("Error detail: {}", msg); + return FileFlag::File_Error; } return data; } + void FileManager::SaveTextFile(const PackagePath& pack_path,const string& value) + { + string path = real_path(pack_path); + std::ofstream of(path); + of.write(value.data(), value.size()); + } } diff --git a/engine/src/engine/asset/file_manager.h b/engine/src/engine/asset/file_manager.h index 98909e0..c9a080e 100644 --- a/engine/src/engine/asset/file_manager.h +++ b/engine/src/engine/asset/file_manager.h @@ -1,18 +1,27 @@ #pragma once #include "asset.h" #include "singleton.h" +#include "meta/result.h" #include namespace engineapi { using json = nlohmann::json; + using meta::result; class FileManager : public ISingleton { + public: + //占位符浪费了四个字节 + struct FileControlBlock { + uint32_t flag; + string path; + string addr; + }; public: void Init() override; void Shutdown() override; public: static void Mount(const string& name, const string& path) { - MountMap.emplace(NameID(name), std::make_pair(name,path)); + MountMap.emplace(NameID(name), std::make_pair(name, path)); } static std::pair FindMount(NameID id) { auto it = MountMap.find(id); @@ -21,18 +30,48 @@ namespace engineapi } return {}; } - static string FindMountName(NameID id) { + static string_view FindMountName(NameID id) { auto pair = FindMount(id); return pair.first; } - static string FindMountPath(NameID id) { + static string_view FindMountPath(NameID id) { auto pair = FindMount(id); return pair.second; } + static string_view FindPathView(const string_view& name) { + auto it = FileMap.find(name); + if (it != FileMap.end()) { + return it->second.path; + } + auto res = FileMap.emplace(name, FileControlBlock{ FileFlag::File_Default, string(name)}); + return res.first->second.path; + } + static uint32_t FindPathFlag(const PackagePath& pack_path) { + auto it = FileMap.find(pack_path.path); + if (it == FileMap.end()) { + return FileFlag::File_Not_Exist; + } + return it->second.flag; + } + static result FindPathBlock(const PackagePath& pack_path) { + auto it = FileMap.find(pack_path.path); + if (it == FileMap.end()) { + return FileFlag::File_Not_Exist; + } + return it->second; + } + private: inline static table> MountMap; + inline static table FileMap; + //外界不应该使用绝对路径 + static string real_path(const PackagePath& pack_path); public: - static string LoadTextFile(const string& path); - static vector LoadBinaryFile(const string& path); - static json LoadJsonFile(const string& path); + static FileFlag LoadErrorFlag(const PackagePath& pack_path); + + static result LoadTextFile(const PackagePath& pack_path); + static result, FileFlag> LoadBinaryFile(const PackagePath& pack_path); + static result LoadJsonFile(const PackagePath& pack_path); + + static void SaveTextFile(const PackagePath& pack_path, const string& value); }; } diff --git a/engine/src/engine/asset/res/meta_bundle.cpp b/engine/src/engine/asset/res/meta_bundle.cpp index 5cdb7e4..733ad13 100644 --- a/engine/src/engine/asset/res/meta_bundle.cpp +++ b/engine/src/engine/asset/res/meta_bundle.cpp @@ -3,5 +3,12 @@ namespace engineapi { - + bool MetaBundle::operator==(const MetaBundle& other)const + { + return metadatas == other.metadatas; + } + bool MetaBundle::operator!=(const MetaBundle& other)const + { + return !(*this == other); + } } \ No newline at end of file diff --git a/engine/src/engine/asset/res/meta_bundle.h b/engine/src/engine/asset/res/meta_bundle.h index 03b133b..bc30c85 100644 --- a/engine/src/engine/asset/res/meta_bundle.h +++ b/engine/src/engine/asset/res/meta_bundle.h @@ -14,6 +14,9 @@ namespace engineapi string t_hash{}; UPROPERTY({}) string metadata; + bool operator==(const SerializedMeta& other)const{ + return guid == other.guid && name == other.name && t_hash == other.t_hash && metadata == other.metadata; + } }; struct ResourceBundle; struct MetaBundle @@ -25,6 +28,10 @@ namespace engineapi template const SerializedMeta* FetchMeta() const; + template + void Add(RscHandle); + bool operator==(const MetaBundle& other)const; + bool operator!=(const MetaBundle& other)const; }; } #include "meta_bundle.inl" diff --git a/engine/src/engine/asset/res/meta_bundle.inl b/engine/src/engine/asset/res/meta_bundle.inl index 9ae8c5b..9eba3a7 100644 --- a/engine/src/engine/asset/res/meta_bundle.inl +++ b/engine/src/engine/asset/res/meta_bundle.inl @@ -12,4 +12,12 @@ namespace engineapi } return nullptr; } + template + void MetaBundle::Add(RscHandle h) + { + if (h) + { + metadatas.emplace_back(SerializedMeta{ h.guid, string{h->Name()}, string{type_name().View()}}); + } + } } \ No newline at end of file diff --git a/engine/src/engine/asset/res/package_path.cpp b/engine/src/engine/asset/res/package_path.cpp index 937bc55..d71217c 100644 --- a/engine/src/engine/asset/res/package_path.cpp +++ b/engine/src/engine/asset/res/package_path.cpp @@ -1,19 +1,21 @@ #include "package_path.h" #include "asset/file_manager.h" namespace engineapi { - PackagePath PackagePath::ToSuffixPath(const string_view& suffix) + PackagePath PackagePath::ToSuffixPath(const string_view& suffix)const { - if (CheckPackage()) { - return { FileManager::FindMountName(name) + string(suffix) , path}; - } - return *this; + string_view name = ParsePackage(); + if(name.empty() || suffix.empty()) + return *this; + string suffixPath; + suffixPath.reserve(path.size() + suffix.size()); + suffixPath.append(name); + suffixPath.append(suffix); + suffixPath.append(path.substr(name.size())); + return PackagePath{FileManager::FindPathView(suffixPath)}; } - string PackagePath::AbsolutePath() + PackagePath PackagePath::SafePath()const { - if (CheckPackage()) { - return FileManager::FindMountPath(name) + string(path); - } - return string(path); + return PackagePath{ FileManager::FindPathView(path) }; } } diff --git a/engine/src/engine/asset/res/package_path.h b/engine/src/engine/asset/res/package_path.h index cebf910..5c9a59c 100644 --- a/engine/src/engine/asset/res/package_path.h +++ b/engine/src/engine/asset/res/package_path.h @@ -10,48 +10,49 @@ namespace engineapi using zstd::hash_table; using Ubpa::Name; using Ubpa::NameID; + enum FileFlag : uint32_t { + File_Default = 0, + File_Binary = 1 << 0, + File_Compress = 1 << 1, + File_Http = 1 << 2, + File_Not_Exist = 1 << 3, + File_Error = 1 << 4, + }; struct PackagePath { - NameID name; string_view path; - PackagePath(const string& name,const string_view& path) : name(name), path(path) {} + PackagePath() {}; PackagePath(const char* path) : path(path) {} PackagePath(const string_view& path) : path(path) {} - PackagePath(const string& path) : path(StringView(path)) {}; PackagePath(const string&& path) : path(path) {} - bool CheckPackage() { - if (name.Valid()) { - return true; - } + size_t size() const{ + return path.size(); + } + string operator+(const char* suffix) const { + return string(path) + suffix; + } + string_view ParsePackage()const { + string_view name; if (path[0] == '/') { size_t pos = path.find('/', 1); if (pos != string::npos) { - name = path.substr(1, pos - 1); - path = path.substr(pos); - return true; + return path.substr(1, pos - 1); } } - return false; + return name; } - Name GetExtension() { + string_view GetFileName()const { + size_t pos = path.rfind('/'); + if (pos != std::string::npos) + return path.substr(pos + 1); + return ""; + } + Name GetExtension() const{ size_t pos = path.rfind('.'); if (pos != std::string::npos) return path.substr(pos); return ""; } - PackagePath ToSuffixPath(const string_view& suffix); - string AbsolutePath(); - static string AbsolutePath(string_view path) { - return PackagePath(path).AbsolutePath(); - }; - static string_view StringView(const string& str) { - NameID id = NameID(str); - auto it = StringTable.find(id); - if (it == StringTable.end()) { - it = StringTable.emplace_hint(it, id, str); - } - return it->second; - } - private: - inline static table StringTable; + PackagePath ToSuffixPath(const string_view& suffix)const; + PackagePath SafePath()const; }; } \ No newline at end of file diff --git a/engine/src/engine/asset/res/resource_bundle.h b/engine/src/engine/asset/res/resource_bundle.h index 960bd8f..1fde3ac 100644 --- a/engine/src/engine/asset/res/resource_bundle.h +++ b/engine/src/engine/asset/res/resource_bundle.h @@ -12,6 +12,7 @@ namespace engineapi // will reshuffle vector and invalidate span, but you shouldn't be accessing vector directly anyway so this is ok template void Add(RscHandle handle); template RscHandle Get() const; // get a resource from the bundle + span GetAll() const; // gets absolutely all resources private: struct sub_array { short index = 0, count = 0; }; diff --git a/engine/src/engine/asset/res/resource_bundle.inl b/engine/src/engine/asset/res/resource_bundle.inl index 93786d6..7132eec 100644 --- a/engine/src/engine/asset/res/resource_bundle.inl +++ b/engine/src/engine/asset/res/resource_bundle.inl @@ -1,5 +1,5 @@ -#include "resource_bundle.h" #pragma once +#include "resource_bundle.h" namespace engineapi { template @@ -25,6 +25,11 @@ namespace engineapi for (auto& elem : span{ &sub_arr + 1, subarrays.data() + subarrays.size() }) ++elem.index; } + inline span ResourceBundle::GetAll() const + { + return span(handles); + } + template inline RscHandle engineapi::ResourceBundle::Get() const { diff --git a/engine/src/engine/asset/res/resource_config.h b/engine/src/engine/asset/res/resource_config.h index 68e15eb..e89af7a 100644 --- a/engine/src/engine/asset/res/resource_config.h +++ b/engine/src/engine/asset/res/resource_config.h @@ -11,8 +11,12 @@ namespace engineapi { RscHandle GetHandle() const { return mHandle; } Resource() = default; + + std::string_view Name() const { return mName; } + void Name(std::string_view n) { mName = n; } private: RscHandle mHandle; + std::string mName; friend class RscHandle; }; using Resources = std::tuple< diff --git a/engine/src/engine/asset/res/resource_handle.h b/engine/src/engine/asset/res/resource_handle.h index 89f4ce8..f09c38e 100644 --- a/engine/src/engine/asset/res/resource_handle.h +++ b/engine/src/engine/asset/res/resource_handle.h @@ -14,9 +14,14 @@ namespace engineapi template constexpr RscHandle(const RscHandle& other) noexcept : guid{ other.guid }, res(other.res) {}; constexpr RscHandle(const Guid& guid, Res* res) noexcept : guid{ guid }, res(res) { ((Resource*)res)->mHandle = *this; } - void init(); - Res* operator->() { if (!res && guid) init(); return (Res*)res; } - Res& operator*() { if (!res && guid) init(); return *(Res*)res; } + void Init(); + void Clear(){ res = nullptr; }; + Res* operator->() { if (!res && guid) Init(); return (Res*)res; } + Res& operator*() { if (!res && guid) Init(); return *(Res*)res; } + operator bool() { if (!res && guid) Init(); return res; } + Res* operator->() const { return (Res*)res; } + Res& operator*()const { return *(Res*)res; } + operator bool() const { return res; } }; struct GenericResourceHandle diff --git a/engine/src/engine/asset/resource_manager.cpp b/engine/src/engine/asset/resource_manager.cpp index 48ebdff..3cd0512 100644 --- a/engine/src/engine/asset/resource_manager.cpp +++ b/engine/src/engine/asset/resource_manager.cpp @@ -5,12 +5,15 @@ namespace engineapi { void ResourceManager::Init() { mResourceTable = detail::ResourceHelper::GenResourceTables(); + LoadFileFlag(); } void ResourceManager::Shutdown() { constexpr static auto release_tables = detail::ResourceHelper::ReleaseTableResources(); for (auto& elem : release_tables) elem(this); + SaveFileFlag(); + SaveDirtyFiles(); } IFileLoader* ResourceManager::GetLoader(Name extension) { @@ -19,23 +22,99 @@ namespace engineapi { return nullptr; return itr->second; } - LoadResult ResourceManager::Load(PackagePath path, bool reload_resource) + ResourceBundle& ResourceManager::Load(PackagePath path, bool reload_resource) { - auto ext = path.GetExtension(); - auto* loader = GetLoader(ext); + auto it = mFileTable.find(path.path); + if (it != mFileTable.end()) { + if (!reload_resource) { + return it->second.bundle; + } + } + Name ext = path.GetExtension(); + IFileLoader* loader = GetLoader(ext); MetaBundle meta = GetMeta(path); - return loader->LoadFile(path, meta); + ResourceBundle bundle = loader->LoadFile(path, meta); + MetaBundle new_meta = GetVisitMeta(bundle); + bool is_dirty_meta = meta != new_meta; + mFileTable[path.path] = {bundle, path.SafePath(), false, is_dirty_meta}; + auto& res = mFileTable[path.path]; + for (auto& elem : bundle.GetAll()) { + std::visit([&](auto& handle) { + using T = std::decay_t; + GetControlBlock(handle)->file = &res; + }, elem); + } + if (is_dirty_meta) { + mDirtyBlocks.push_back(&res); + } + return res.bundle; } MetaBundle ResourceManager::GetMeta(PackagePath path) { - string text = FileManager::LoadTextFile(path.AbsolutePath() + ".meta"); - auto res = YAML::Text_Unserialize(text); - if (res) { - return res.value(); - } - return {}; - } + meta::result res; + if (mFileFlag & FileFlag::File_Binary) { + } + else { + auto res_text = FileManager::LoadTextFile(path + ".meta"); + if (res_text) { + res = YAML::Text_Unserialize(res_text.value()); + } + } + if (!res) { + return {}; + } + return res.value(); + } + void ResourceManager::SaveMeta(PackagePath path, const MetaBundle& bundle) + { + if (mFileFlag & FileFlag::File_Binary) { + + } + else { + string text = YAML::Text_Serialize(bundle); + FileManager::SaveTextFile(path, text); + } + } + void ResourceManager::SaveDirtyFiles() + { + for (auto block : mDirtyBlocks) { + if (block->is_meta_dirty) { + block->is_meta_dirty = false; + MetaBundle new_meta = GetVisitMeta(block->bundle); + SaveMeta(block->path, new_meta); + } + if (block->is_dirty) { + block->is_dirty = false; + auto loader = GetLoader(block->path.GetExtension()); + loader->SaveFile(block->path, block->bundle); + } + } + mDirtyBlocks.clear(); + } + constexpr const char* FileFlagName = "/engine/assets/file_flag.meta"; + void ResourceManager::LoadFileFlag() + { + auto res_text = FileManager::LoadTextFile(FileFlagName); + if (res_text) { + auto res = YAML::Text_Unserialize>(res_text.value()); + if (res) { + for (auto it : res.value()) { + mFileFlagTable.emplace(NameID(it.first), it); + } + mFileFlag = GetFileFlag(".meta"); + } + } + } + void ResourceManager::SaveFileFlag() + { + table res; + for (auto it : mFileFlagTable) { + res.emplace(it.second); + } + string text = YAML::Text_Serialize(res); + FileManager::SaveTextFile(FileFlagName, text); + } } diff --git a/engine/src/engine/asset/resource_manager.h b/engine/src/engine/asset/resource_manager.h index 111969c..8cf9ed0 100644 --- a/engine/src/engine/asset/resource_manager.h +++ b/engine/src/engine/asset/resource_manager.h @@ -22,14 +22,19 @@ namespace engineapi { class ResourceManager : public ISingleton { public: + struct FileControlBlock; template struct ResourceControlBlock; template using ResourceStorage = hash_table>; using GenericPtr = shared_ptr; private: - array mResourceTable; - hash_table mFileLoader; + uint32_t mFileFlag; + array mResourceTable; + hash_table mFileLoader; + hash_table> mFileFlagTable; + hash_table mFileTable; + vector mDirtyBlocks; public: void Init() override; void Shutdown() override; @@ -42,6 +47,9 @@ namespace engineapi { auto& GetTable() { return *reinterpret_cast*> (mResourceTable[ResourceID].get()); } + template + ResourceControlBlock* GetControlBlock(RscHandle handle); + template [[nodiscard]] RscHandle LoaderEmplaceResource(Args&& ... args) { return LoaderEmplaceResource(Guid::Make(), args...); @@ -55,21 +63,30 @@ namespace engineapi { template RscHandle Load(PackagePath path, bool reload_resource = true); - LoadResult Load(PackagePath path, bool reload_resource = true); + ResourceBundle& Load(PackagePath path, bool reload_resource = true); MetaBundle GetMeta(PackagePath path); + MetaBundle GetVisitMeta(const ResourceBundle& bundle); + void SaveMeta(PackagePath path, const MetaBundle& bundle); + void SaveDirtyFiles(); + + void LoadFileFlag(); + void SaveFileFlag(); + uint32_t GetFileFlag(const Name& name); + void SetFileFlag(const Name& name, uint32_t flag); + }; + struct ResourceManager::FileControlBlock + { + ResourceBundle bundle; + PackagePath path; + bool is_dirty{ false }; + bool is_meta_dirty{ false }; }; template struct ResourceManager::ResourceControlBlock { - bool dirty{ false }; - std::optional path{ std::nullopt }; R* resource; - - // meta data - shared_ptr userdata; - bool dirty_meta{ false }; - - bool valid() const { return s_cast(resource); } + FileControlBlock* file; + bool valid() const { return resource; } }; } #include "resource_manager.inl" \ No newline at end of file diff --git a/engine/src/engine/asset/resource_manager.inl b/engine/src/engine/asset/resource_manager.inl index f6bd4ec..4f67c82 100644 --- a/engine/src/engine/asset/resource_manager.inl +++ b/engine/src/engine/asset/resource_manager.inl @@ -3,8 +3,14 @@ namespace engineapi { class IFileLoader { + protected: + uint32_t mFileFlag = 0; public: + void SetFileFlag(uint32_t flag) { + mFileFlag = flag; + } virtual ResourceBundle LoadFile(PackagePath handle, const MetaBundle& meta) = 0; + virtual void SaveFile(PackagePath handle, const ResourceBundle& bundle) {}; virtual ~IFileLoader() = default; }; namespace detail { @@ -48,17 +54,15 @@ namespace engineapi { inline FLoader& ResourceManager::RegisterLoader(Name ext, Args&& ...args) { FLoader* ptr = new FLoader(std::forward(args)...); + ptr->SetFileFlag(GetFileFlag(ext)); mFileLoader[ext] = ptr; return *ptr; } template inline RscHandle ResourceManager::Load(PackagePath path, bool reload_resource) { - auto res = Load(path, reload_resource); - if (!res) - return {}; - - return res.value().Get(); + auto& res = Load(path, reload_resource); + return res.Get(); } template inline Res* ResourceManager::Get(const RscHandle& handle) @@ -69,8 +73,32 @@ namespace engineapi { return nullptr; return itr->second.resource; } + inline uint32_t ResourceManager::GetFileFlag(const Name& name) + { + auto it = mFileFlagTable.find(name.GetID()); + if (it == mFileFlagTable.end()) { + return 0; + } + return it->second.second; + } + inline void ResourceManager::SetFileFlag(const Name& name, uint32_t flag) + { + auto it = mFileFlagTable.find(name.GetID()); + if (it == mFileFlagTable.end()) { + mFileFlagTable.emplace(name.GetID(), std::make_pair(string(name.GetView()), flag)); + } + else { + it->second.second = flag; + } + } template - inline void RscHandle::init() + inline ResourceManager::ResourceControlBlock* ResourceManager::GetControlBlock(RscHandle handle) + { + auto& table = GetTable(); + return &table[handle.guid]; + } + template + inline void RscHandle::Init() { res = ResourceManager::GetSingleton().Get(*this); } diff --git a/engine/src/engine/object/scene/scene.cpp b/engine/src/engine/object/scene/scene.cpp index 95e959e..c69b0c9 100644 --- a/engine/src/engine/object/scene/scene.cpp +++ b/engine/src/engine/object/scene/scene.cpp @@ -13,7 +13,7 @@ namespace engineapi { int flags = 1; auto shader = ResourceManager::GetSingleton().LoaderEmplaceResource(); shader->mVertexName = type_name().View(); - //shader->mVert = ResourceManager::GetSingleton().Load("/engine/assets/shader/simple.vert"); + shader->mVert = ResourceManager::GetSingleton().Load("/engine/assets/shader/simple.vert"); shader->mFrag = ResourceManager::GetSingleton().Load("/engine/assets/shader/simple.frag"); RenderAPI::GetSingleton().LoadShader(&*shader); Material* material = new Material("/engine/assets/shader/simple.shader", flags); diff --git a/engine/src/engine/render/asset/model.cpp b/engine/src/engine/render/asset/model.cpp index 1049f59..b104756 100644 --- a/engine/src/engine/render/asset/model.cpp +++ b/engine/src/engine/render/asset/model.cpp @@ -9,7 +9,7 @@ namespace engineapi { string mName = ""; // 用ASSIMP加载模型文件 Assimp::Importer importer; - const aiScene* scene = importer.ReadFile(PackagePath::AbsolutePath(mName), aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_CalcTangentSpace + const aiScene* scene = importer.ReadFile(mName, aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_CalcTangentSpace | aiProcess_FixInfacingNormals | aiProcess_FlipWindingOrder | aiProcess_LimitBoneWeights); // 检查异常 diff --git a/engine/src/engine/vulkanapi/loader/vulkan_glsl_loader.cpp b/engine/src/engine/vulkanapi/loader/vulkan_glsl_loader.cpp index 1edf3a5..d8af684 100644 --- a/engine/src/engine/vulkanapi/loader/vulkan_glsl_loader.cpp +++ b/engine/src/engine/vulkanapi/loader/vulkan_glsl_loader.cpp @@ -32,18 +32,25 @@ namespace vulkanapi { int x = 1; int y = 2; } - //string PreprocessGlsl(string glsl); ResourceBundle VulkanGlslLoader::LoadFile(PackagePath handle, const MetaBundle& meta) { auto m = meta.FetchMeta(); auto program = m ? ResourceManager::GetSingleton().LoaderEmplaceResource(m->guid) : ResourceManager::GetSingleton().LoaderEmplaceResource(); - string glsl = FileManager::LoadTextFile(handle.AbsolutePath()); - auto shader_enum = GetShaderType(handle.GetExtension()); - glsl = GlslToSpirv::PreprocessGlsl(glsl); - auto spirv = GlslToSpirv::spirv(glsl, shader_enum); - if (spirv) { - program->Load(*spirv); + if (mFileFlag & FileFlag::File_Binary) { + + } + else { + auto res = FileManager::LoadTextFile(handle); + if (res) { + string glsl = res.value(); + auto shader_enum = GetShaderType(handle.GetExtension()); + //glsl = GlslToSpirv::PreprocessGlsl(glsl); + auto spirv = GlslToSpirv::spirv(glsl, shader_enum, handle.GetFileName()); + if (spirv) { + program->Load(*spirv); + } + } } return program; } diff --git a/engine/src/engine/vulkanapi/tool/glsl_to_spirv.cpp b/engine/src/engine/vulkanapi/tool/glsl_to_spirv.cpp index d74df9d..590a85f 100644 --- a/engine/src/engine/vulkanapi/tool/glsl_to_spirv.cpp +++ b/engine/src/engine/vulkanapi/tool/glsl_to_spirv.cpp @@ -1,6 +1,5 @@ #include "glsl_to_spirv.h" #include "zstd/table.h" -#include "meta/pad.h" #include "meta/hash.h" #include "yaml/yaml.h" #include @@ -45,19 +44,18 @@ namespace vulkanapi return shader_code.substr(0, version_end) + replacer + shader_code.substr(version_end, shader_code.size() - version_end); } - std::optional> GlslToSpirv::spirv(string_view glsl, vk::ShaderStageFlagBits v_stage, string_view code_id) + std::optional> GlslToSpirv::spirv(const string& glsl, vk::ShaderStageFlagBits v_stage, string_view code_id) { - string val = static_cast(glsl); std::optional> spirv_out; { shaderc::Compiler compiler; - shaderc::CompileOptions opt; - opt.SetTargetEnvironment(shaderc_target_env::shaderc_target_env_vulkan, 0); - auto result = compiler.CompileGlslToSpv(val, ConvertStageSC(v_stage), code_id.data(), opt); + shaderc::CompileOptions options; + options.SetOptimizationLevel(shaderc_optimization_level_performance); + options.SetTargetEnvironment(shaderc_target_env::shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_2); + auto result = compiler.CompileGlslToSpv(glsl, ConvertStageSC(v_stage), code_id.data(), options); if (result.GetCompilationStatus() != shaderc_compilation_status::shaderc_compilation_status_success) return spirv_out; spirv_out = vector{ result.begin(),result.end() }; - //meta::padding_vector(*spirv_out, (unsigned int)4, (unsigned int)0); } return spirv_out; } diff --git a/engine/src/engine/vulkanapi/tool/glsl_to_spirv.h b/engine/src/engine/vulkanapi/tool/glsl_to_spirv.h index 0dc7165..5a67114 100644 --- a/engine/src/engine/vulkanapi/tool/glsl_to_spirv.h +++ b/engine/src/engine/vulkanapi/tool/glsl_to_spirv.h @@ -11,6 +11,6 @@ namespace vulkanapi { public: static string PreprocessGlsl(string glsl); - static std::optional> spirv(string_view glsl, vk::ShaderStageFlagBits v_stage, string_view code_id = "unknown_shader"); + static std::optional> spirv(const string& glsl, vk::ShaderStageFlagBits v_stage, string_view code_id = "unknown_shader"); }; } \ No newline at end of file