Merge f59c72ae9629584be631585f10fe02532423a29d into cc0ce62e7ff283919c95c12a1c8e3b0887271690

This commit is contained in:
Jordan Woyak 2026-01-08 14:40:02 -06:00 committed by GitHub
commit c349308a2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 62 additions and 50 deletions

View File

@ -13,51 +13,65 @@ namespace Common
FilesystemWatcher::FilesystemWatcher() = default;
FilesystemWatcher::~FilesystemWatcher() = default;
void FilesystemWatcher::Watch(const std::string& path)
void FilesystemWatcher::Watch(const std::string& path, StartedCallback started_callback)
{
const auto [iter, inserted] = m_watched_paths.try_emplace(path, nullptr);
if (inserted)
auto& watch_ptr = m_watched_paths[path];
// Are we already watching this path?
if (watch_ptr != nullptr)
{
iter->second = std::make_unique<wtr::watch>(path, [this](wtr::event e) {
const auto watched_path = PathToString(e.path_name);
if (e.path_type == wtr::event::path_type::watcher)
// The caller doesn't require notification on start so we're done.
if (!started_callback)
return;
// Remove and recreate the watch object so we can wait for a new "started" event.
watch_ptr.reset();
}
watch_ptr = std::make_unique<wtr::watch>(path, [this, started_callback](wtr::event e) {
const auto watched_path = PathToString(e.path_name);
if (e.path_type == wtr::event::path_type::watcher)
{
if (watched_path.starts_with('e'))
ERROR_LOG_FMT(COMMON, "Filesystem watcher: '{}'", watched_path);
else if (watched_path.starts_with('w'))
WARN_LOG_FMT(COMMON, "Filesystem watcher: '{}'", watched_path);
if (e.effect_type == wtr::event::effect_type::create && started_callback)
{
if (watched_path.starts_with('e'))
ERROR_LOG_FMT(COMMON, "Filesystem watcher: '{}'", watched_path);
else if (watched_path.starts_with('w'))
WARN_LOG_FMT(COMMON, "Filesystem watcher: '{}'", watched_path);
const auto unified_path = WithUnifiedPathSeparators(watched_path);
started_callback(unified_path);
}
return;
}
if (e.effect_type == wtr::event::effect_type::create)
{
const auto unified_path = WithUnifiedPathSeparators(watched_path);
PathAdded(unified_path);
}
else if (e.effect_type == wtr::event::effect_type::modify)
{
const auto unified_path = WithUnifiedPathSeparators(watched_path);
PathModified(unified_path);
}
else if (e.effect_type == wtr::event::effect_type::rename)
{
if (!e.associated)
{
WARN_LOG_FMT(COMMON, "Rename on path '{}' seen without association!", watched_path);
return;
}
if (e.effect_type == wtr::event::effect_type::create)
{
const auto unified_path = WithUnifiedPathSeparators(watched_path);
PathAdded(unified_path);
}
else if (e.effect_type == wtr::event::effect_type::modify)
{
const auto unified_path = WithUnifiedPathSeparators(watched_path);
PathModified(unified_path);
}
else if (e.effect_type == wtr::event::effect_type::rename)
{
if (!e.associated)
{
WARN_LOG_FMT(COMMON, "Rename on path '{}' seen without association!", watched_path);
return;
}
const auto old_path = WithUnifiedPathSeparators(watched_path);
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 unified_path = WithUnifiedPathSeparators(watched_path);
PathDeleted(unified_path);
}
});
}
const auto old_path = WithUnifiedPathSeparators(watched_path);
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 unified_path = WithUnifiedPathSeparators(watched_path);
PathDeleted(unified_path);
}
});
}
void FilesystemWatcher::Unwatch(const std::string& path)

View File

@ -3,18 +3,16 @@
#pragma once
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <string_view>
namespace wtr
{
inline namespace watcher
namespace wtr::inline watcher
{
class watch;
}
} // namespace wtr
namespace Common
{
@ -26,7 +24,9 @@ public:
FilesystemWatcher();
virtual ~FilesystemWatcher();
void Watch(const std::string& path);
using StartedCallback = std::function<void(std::string_view)>;
void Watch(const std::string& path, StartedCallback started_callback = {});
void Unwatch(const std::string& path);
private:

View File

@ -3,12 +3,9 @@
#include "VideoCommon/HiresTextures.h"
#include <algorithm>
#include <memory>
#include <mutex>
#include <string>
#include <string_view>
#include <thread>
#include <unordered_map>
#include <utility>
#include <vector>
@ -20,11 +17,10 @@
#include "Common/FileSearch.h"
#include "Common/FileUtil.h"
#include "Common/Logging/Log.h"
#include "Common/OneShotEvent.h"
#include "Common/StringUtil.h"
#include "Core/Config/GraphicsSettings.h"
#include "Core/ConfigManager.h"
#include "Core/System.h"
#include "VideoCommon/Assets/CustomAsset.h"
#include "VideoCommon/Assets/DirectFilesystemAssetLibrary.h"
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/Resources/CustomResourceManager.h"
@ -98,7 +94,9 @@ void HiresTexture::Update()
for (const auto& texture_directory : texture_directories)
{
// Watch this directory for any texture reloads
s_file_library->Watch(texture_directory);
Common::OneShotEvent started;
s_file_library->Watch(texture_directory, [&](std::string_view) { started.Set(); });
started.Wait();
const auto texture_paths =
Common::DoFileSearch({texture_directory}, extensions, /*recursive*/ true);