Skip to content

Commit

Permalink
VideoCommon: watch texture pack folder for texture reloads (from dyna…
Browse files Browse the repository at this point in the history
…mic input textures)
  • Loading branch information
iwubcode committed Jul 12, 2024
1 parent f3bd9de commit 8904b56
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 7 deletions.
2 changes: 2 additions & 0 deletions Source/Core/DolphinLib.props
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@
<ClInclude Include="VideoCommon\Assets\MeshAsset.h" />
<ClInclude Include="VideoCommon\Assets\ShaderAsset.h" />
<ClInclude Include="VideoCommon\Assets\TextureAsset.h" />
<ClInclude Include="VideoCommon\Assets\WatchableFilesystemAssetLibrary.h" />
<ClInclude Include="VideoCommon\AsyncRequests.h" />
<ClInclude Include="VideoCommon\AsyncShaderCompiler.h" />
<ClInclude Include="VideoCommon\BoundingBox.h" />
Expand Down Expand Up @@ -1308,6 +1309,7 @@
<ClCompile Include="VideoCommon\Assets\MeshAsset.cpp" />
<ClCompile Include="VideoCommon\Assets\ShaderAsset.cpp" />
<ClCompile Include="VideoCommon\Assets\TextureAsset.cpp" />
<ClCompile Include="VideoCommon\Assets\WatchableFilesystemAssetLibrary.cpp" />
<ClCompile Include="VideoCommon\AsyncRequests.cpp" />
<ClCompile Include="VideoCommon\AsyncShaderCompiler.cpp" />
<ClCompile Include="VideoCommon\BoundingBox.cpp" />
Expand Down
42 changes: 38 additions & 4 deletions Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "Common/JsonUtil.h"
#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
#include "Core/System.h"
#include "VideoCommon/Assets/CustomAssetLoader.h"
#include "VideoCommon/Assets/MaterialAsset.h"
#include "VideoCommon/Assets/MeshAsset.h"
#include "VideoCommon/Assets/ShaderAsset.h"
Expand Down Expand Up @@ -53,7 +55,7 @@ std::size_t GetAssetSize(const CustomTextureData& data)
CustomAssetLibrary::TimeType
DirectFilesystemAssetLibrary::GetLastAssetWriteTime(const AssetID& asset_id) const
{
std::lock_guard lk(m_lock);
std::lock_guard lk(m_asset_map_lock);
if (auto iter = m_assetid_to_asset_map_path.find(asset_id);
iter != m_assetid_to_asset_map_path.end())
{
Expand Down Expand Up @@ -436,8 +438,40 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const Ass
void DirectFilesystemAssetLibrary::SetAssetIDMapData(const AssetID& asset_id,
AssetMap asset_path_map)
{
std::lock_guard lk(m_lock);
m_assetid_to_asset_map_path[asset_id] = std::move(asset_path_map);
AssetMap previous_asset_map;
{
std::lock_guard lk(m_asset_map_lock);
previous_asset_map = m_assetid_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_assetid_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& loader = system.GetCustomAssetLoader();
loader.ReloadAsset(iter->second);
}
}

bool DirectFilesystemAssetLibrary::LoadMips(const std::filesystem::path& asset_path,
Expand Down Expand Up @@ -495,7 +529,7 @@ bool DirectFilesystemAssetLibrary::LoadMips(const std::filesystem::path& asset_p
DirectFilesystemAssetLibrary::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_assetid_to_asset_map_path.find(asset_id);
iter != m_assetid_to_asset_map_path.end())
{
Expand Down
11 changes: 8 additions & 3 deletions Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
#include <mutex>
#include <string>

#include "VideoCommon/Assets/CustomAssetLibrary.h"
#include "VideoCommon/Assets/CustomTextureData.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:
using AssetMap = std::map<std::string, std::filesystem::path>;
Expand All @@ -34,13 +34,18 @@ class DirectFilesystemAssetLibrary final : public CustomAssetLibrary
void SetAssetIDMapData(const AssetID& asset_id, AssetMap asset_path_map);

private:
void PathModified(std::string_view path) override;

// Loads additional mip levels into the texture structure until _mip<N> texture is not found
bool LoadMips(const std::filesystem::path& asset_path, CustomTextureData::ArraySlice* data);

// Gets the asset map given an asset id
AssetMap GetAssetMapForID(const AssetID& asset_id) const;

mutable std::mutex m_lock;
mutable std::mutex m_asset_map_lock;
std::map<AssetID, std::map<std::string, std::filesystem::path>> m_assetid_to_asset_map_path;

mutable std::mutex m_path_map_lock;
std::map<std::string, AssetID, std::less<>> m_path_to_asset_id;
};
} // namespace VideoCommon
57 changes: 57 additions & 0 deletions Source/Core/VideoCommon/Assets/WatchableFilesystemAssetLibrary.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2024 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "VideoCommon/Assets/WatchableFilesystemAssetLibrary.h"

#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"

namespace VideoCommon
{
void WatchableFilesystemAssetLibrary::Watch(const std::string& path)
{
const auto [iter, inserted] = m_watched_paths.try_emplace(path, nullptr);
if (inserted)
{
iter->second = std::make_unique<wtr::watch>(path, [this](wtr::event e) {
if (e.path_type == wtr::event::path_type::watcher)
{
return;
}

if (e.effect_type == wtr::event::effect_type::create)
{
const auto path = WithUnifiedPathSeparators(PathToString(e.path_name));
PathAdded(path);
}
else if (e.effect_type == wtr::event::effect_type::modify)
{
const auto path = WithUnifiedPathSeparators(PathToString(e.path_name));
PathModified(path);
}
else if (e.effect_type == wtr::event::effect_type::rename)
{
if (!e.associated)
{
WARN_LOG_FMT(VIDEO, "Rename on path seen without association!");
return;
}

const auto old_path = WithUnifiedPathSeparators(PathToString(e.path_name));
const auto new_path = WithUnifiedPathSeparators(PathToString(e.associated->path_name));
PathRenamed(old_path, new_path);
}
else if (e.effect_type == wtr::event::effect_type::destroy)
{
const auto path = WithUnifiedPathSeparators(PathToString(e.path_name));
PathDeleted(path);
}
});
}
}

void WatchableFilesystemAssetLibrary::Unwatch(const std::string& path)
{
m_watched_paths.erase(path);
}
} // namespace VideoCommon
38 changes: 38 additions & 0 deletions Source/Core/VideoCommon/Assets/WatchableFilesystemAssetLibrary.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2024 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <map>
#include <memory>
#include <string>
#include <string_view>

#include <wtr/watcher.hpp>

#include "VideoCommon/Assets/CustomAssetLibrary.h"

namespace VideoCommon
{
class WatchableFilesystemAssetLibrary : public CustomAssetLibrary
{
public:
void Watch(const std::string& path);
void Unwatch(const std::string& path);

private:
// A new file or folder was added to one of the watched paths
virtual void PathAdded(std::string_view path) {}

// A file or folder was modified in one of the watched paths
virtual void PathModified(std::string_view path) {}

// A file or folder was renamed in one of the watched paths
virtual void PathRenamed(std::string_view old_path, std::string_view new_path) {}

// A file or folder was deleted in one of the watched paths
virtual void PathDeleted(std::string_view path) {}

std::map<std::string, std::unique_ptr<wtr::watch>> m_watched_paths;
};
} // namespace VideoCommon
2 changes: 2 additions & 0 deletions Source/Core/VideoCommon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ add_library(videocommon
Assets/ShaderAsset.h
Assets/TextureAsset.cpp
Assets/TextureAsset.h
Assets/WatchableFilesystemAssetLibrary.cpp
Assets/WatchableFilesystemAssetLibrary.h
AsyncRequests.cpp
AsyncRequests.h
AsyncShaderCompiler.cpp
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/VideoCommon/HiresTextures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,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);

Expand Down

0 comments on commit 8904b56

Please sign in to comment.