Browse Source

Add live reload for external content

Signed-off-by: crueter <crueter@eden-emu.dev>
pull/2862/head
crueter 3 days ago
parent
commit
b0ec579241
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 14
      src/qt_common/util/game.cpp
  2. 34
      src/yuzu/game_list.cpp
  3. 3
      src/yuzu/game_list.h
  4. 4
      src/yuzu/game_list_worker.cpp

14
src/qt_common/util/game.cpp

@ -373,27 +373,23 @@ void RemoveCacheStorage(u64 program_id)
}
// Metadata //
void ResetMetadata(bool show_message)
{
void ResetMetadata(bool show_message) {
const QString title = tr("Reset Metadata Cache");
if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir)
/ "game_list/")) {
if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) /
"game_list/")) {
if (show_message)
QtCommon::Frontend::Warning(rootObject,
title,
QtCommon::Frontend::Warning(rootObject, title,
tr("The metadata cache is already empty."));
} else if (Common::FS::RemoveDirRecursively(
Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) {
if (show_message)
QtCommon::Frontend::Information(rootObject,
title,
QtCommon::Frontend::Information(rootObject, title,
tr("The operation completed successfully."));
UISettings::values.is_game_list_reload_pending.exchange(true);
} else {
if (show_message)
QtCommon::Frontend::Warning(
title,
tr("The metadata cache couldn't be deleted. It might be in use or non-existent."));
}

34
src/yuzu/game_list.cpp

@ -16,11 +16,13 @@
#include <QToolButton>
#include <QVariantAnimation>
#include <fmt/ranges.h>
#include <qfilesystemwatcher.h>
#include <qnamespace.h>
#include <qscroller.h>
#include <qscrollerproperties.h>
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/core.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
@ -326,6 +328,10 @@ GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvid
watcher = new QFileSystemWatcher(this);
connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory);
external_watcher = new QFileSystemWatcher(this);
ResetExternalWatcher();
connect(external_watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshExternalContent);
this->main_window = parent;
layout = new QVBoxLayout;
tree_view = new QTreeView;
@ -920,18 +926,38 @@ const QStringList GameList::supported_file_extensions = {
void GameList::RefreshGameDirectory()
{
// Reset the externals watcher whenever the game list is reloaded,
// primarily ensures that new titles and external dirs are caught.
ResetExternalWatcher();
if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) {
LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
QtCommon::system->GetFileSystemController().CreateFactories(*QtCommon::vfs);
// TODO: If you force reset metadata here, live updates to the external directories DO get tracked.
// This is not correct however. Game list metadata in general is kind of a mess, but ideally this isn't the
// behavior as-is
PopulateAsync(UISettings::values.game_dirs);
}
}
// QtCommon::Game::ResetMetadata(false);
void GameList::RefreshExternalContent() {
// TODO: Explore the possibility of only resetting the metadata cache for that specific game.
if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) {
LOG_INFO(Frontend, "External content directory changed. Clearing metadata cache.");
QtCommon::Game::ResetMetadata(false);
QtCommon::system->GetFileSystemController().CreateFactories(*QtCommon::vfs);
PopulateAsync(UISettings::values.game_dirs);
}
}
void GameList::ResetExternalWatcher() {
auto watch_dirs = external_watcher->directories();
if (!watch_dirs.isEmpty()) {
external_watcher->removePaths(watch_dirs);
}
for (const std::string &dir : Settings::values.external_content_dirs) {
external_watcher->addPath(QString::fromStdString(dir));
}
}
void GameList::ToggleFavorite(u64 program_id) {
if (!UISettings::values.favorited_ids.contains(program_id)) {
tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(),

3
src/yuzu/game_list.h

@ -94,6 +94,8 @@ public:
public slots:
void RefreshGameDirectory();
void RefreshExternalContent();
void ResetExternalWatcher();
signals:
void BootGame(const QString& game_path, StartGameType type);
@ -160,6 +162,7 @@ private:
QStandardItemModel* item_model = nullptr;
std::unique_ptr<GameListWorker> current_worker;
QFileSystemWatcher* watcher = nullptr;
QFileSystemWatcher* external_watcher = nullptr;
ControllerNavigation* controller_navigation = nullptr;
CompatibilityList compatibility_list;

4
src/yuzu/game_list_worker.cpp

@ -510,10 +510,6 @@ void GameListWorker::run() {
}
}
for (const std::string &dir : Settings::values.external_content_dirs) {
watch_list << QString::fromStdString(dir);
}
RecordEvent([this](GameList* game_list) { game_list->DonePopulating(watch_list); });
processing_completed.Set();
}
Loading…
Cancel
Save