diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index b08aa2042b..02a4894609 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -679,6 +679,7 @@ + diff --git a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp index 5734da4961..7933212d3a 100644 --- a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp +++ b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp @@ -13,6 +13,8 @@ #include "Common/JsonUtil.h" #include "Common/Logging/Log.h" #include "Common/StringUtil.h" +#include "Core/System.h" +#include "VideoCommon/Assets/CustomResourceManager.h" #include "VideoCommon/Assets/MaterialAsset.h" #include "VideoCommon/Assets/MeshAsset.h" #include "VideoCommon/Assets/ShaderAsset.h" @@ -383,14 +385,46 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const Ass void DirectFilesystemAssetLibrary::SetAssetIDMapData(const AssetID& asset_id, VideoCommon::Assets::AssetMap asset_path_map) { - std::lock_guard lk(m_lock); - m_asset_id_to_asset_map_path[asset_id] = std::move(asset_path_map); + VideoCommon::Assets::AssetMap previous_asset_map; + { + std::lock_guard lk(m_asset_map_lock); + previous_asset_map = m_asset_id_to_asset_map_path[asset_id]; + } + + { + std::lock_guard lk(m_path_map_lock); + for (const auto& [name, path] : previous_asset_map) + { + m_path_to_asset_id.erase(PathToString(path)); + } + + for (const auto& [name, path] : asset_path_map) + { + m_path_to_asset_id[PathToString(path)] = asset_id; + } + } + + { + std::lock_guard lk(m_asset_map_lock); + m_asset_id_to_asset_map_path[asset_id] = std::move(asset_path_map); + } +} + +void DirectFilesystemAssetLibrary::PathModified(std::string_view path) +{ + std::lock_guard lk(m_path_map_lock); + if (const auto iter = m_path_to_asset_id.find(path); iter != m_path_to_asset_id.end()) + { + auto& system = Core::System::GetInstance(); + auto& resource_manager = system.GetCustomResourceManager(); + resource_manager.MarkAssetDirty(iter->second); + } } VideoCommon::Assets::AssetMap DirectFilesystemAssetLibrary::GetAssetMapForID(const AssetID& asset_id) const { - std::lock_guard lk(m_lock); + std::lock_guard lk(m_asset_map_lock); if (auto iter = m_asset_id_to_asset_map_path.find(asset_id); iter != m_asset_id_to_asset_map_path.end()) { diff --git a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h index a3dede8722..e3a8e81334 100644 --- a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h +++ b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h @@ -8,16 +8,16 @@ #include #include -#include "VideoCommon/Assets/CustomAssetLibrary.h" #include "VideoCommon/Assets/CustomTextureData.h" #include "VideoCommon/Assets/TextureAsset.h" #include "VideoCommon/Assets/Types.h" +#include "VideoCommon/Assets/WatchableFilesystemAssetLibrary.h" namespace VideoCommon { // This class implements 'CustomAssetLibrary' and loads any assets // directly from the filesystem -class DirectFilesystemAssetLibrary final : public CustomAssetLibrary +class DirectFilesystemAssetLibrary final : public WatchableFilesystemAssetLibrary { public: LoadInfo LoadTexture(const AssetID& asset_id, TextureAndSamplerData* data) override; @@ -32,10 +32,15 @@ public: void SetAssetIDMapData(const AssetID& asset_id, Assets::AssetMap asset_path_map); private: + void PathModified(std::string_view path) override; + // Gets the asset map given an asset id Assets::AssetMap GetAssetMapForID(const AssetID& asset_id) const; - mutable std::mutex m_lock; + mutable std::mutex m_asset_map_lock; std::map m_asset_id_to_asset_map_path; + + mutable std::mutex m_path_map_lock; + std::map> m_path_to_asset_id; }; } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Assets/WatchableFilesystemAssetLibrary.h b/Source/Core/VideoCommon/Assets/WatchableFilesystemAssetLibrary.h new file mode 100644 index 0000000000..196d311397 --- /dev/null +++ b/Source/Core/VideoCommon/Assets/WatchableFilesystemAssetLibrary.h @@ -0,0 +1,14 @@ +// Copyright 2024 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "Common/FilesystemWatcher.h" +#include "VideoCommon/Assets/CustomAssetLibrary.h" + +namespace VideoCommon +{ +class WatchableFilesystemAssetLibrary : public CustomAssetLibrary, public Common::FilesystemWatcher +{ +}; +} // namespace VideoCommon diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index 0ee9722c42..b4ba6ddf78 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -30,6 +30,7 @@ add_library(videocommon Assets/TextureAssetUtils.cpp Assets/TextureAssetUtils.h Assets/Types.h + Assets/WatchableFilesystemAssetLibrary.h AsyncRequests.cpp AsyncRequests.h AsyncShaderCompiler.cpp diff --git a/Source/Core/VideoCommon/HiresTextures.cpp b/Source/Core/VideoCommon/HiresTextures.cpp index 302670f0dc..8acc3aff03 100644 --- a/Source/Core/VideoCommon/HiresTextures.cpp +++ b/Source/Core/VideoCommon/HiresTextures.cpp @@ -96,6 +96,9 @@ void HiresTexture::Update() for (const auto& texture_directory : texture_directories) { + // Watch this directory for any texture reloads + s_file_library->Watch(texture_directory); + const auto texture_paths = Common::DoFileSearch({texture_directory}, extensions, /*recursive*/ true);