From ae3960fefa25e436b5a9822d056aa6907aa61f6e Mon Sep 17 00:00:00 2001 From: swurl Date: Sun, 11 May 2025 00:27:11 -0400 Subject: [PATCH] more fixes - replaced some user-facing references to legacy with eden - added progress bar & threading to migration - disable Citron migration for now Signed-off-by: swurl --- src/yuzu/CMakeLists.txt | 2 + .../configuration/configure_input_advanced.ui | 6 +- src/yuzu/main.cpp | 4 +- src/yuzu/migration_worker.cpp | 123 ++++++++++++++ src/yuzu/migration_worker.h | 41 +++++ src/yuzu/user_data_migration.cpp | 158 +++++------------- src/yuzu/user_data_migration.h | 20 +-- src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 12 +- .../emu_window/emu_window_sdl2_gl.cpp | 2 +- .../emu_window/emu_window_sdl2_null.cpp | 2 +- .../emu_window/emu_window_sdl2_vk.cpp | 6 +- src/yuzu_cmd/yuzu.cpp | 2 +- 12 files changed, 233 insertions(+), 145 deletions(-) create mode 100644 src/yuzu/migration_worker.cpp create mode 100644 src/yuzu/migration_worker.h diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 15b898279b..9425ee73f6 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -238,6 +238,8 @@ add_executable(yuzu yuzu.qrc yuzu.rc migration_dialog.h migration_dialog.cpp + migration_worker.h + migration_worker.cpp ) set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden") diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui index 2994d0ab48..2bdd137b08 100644 --- a/src/yuzu/configuration/configure_input_advanced.ui +++ b/src/yuzu/configuration/configure_input_advanced.ui @@ -2656,7 +2656,7 @@ - Requires restarting yuzu + Requires restarting eden @@ -2698,7 +2698,7 @@ - Requires restarting yuzu + Requires restarting eden @@ -2714,7 +2714,7 @@ - Requires restarting yuzu + Requires restarting eden diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 503891dc22..54d64f33c9 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -3040,8 +3040,8 @@ bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_vi } // Create icon file path - out_icon_path /= (program_id == 0 ? fmt::format("yuzu-{}.{}", game_file_name, ico_extension) - : fmt::format("yuzu-{:016X}.{}", program_id, ico_extension)); + out_icon_path /= (program_id == 0 ? fmt::format("eden-{}.{}", game_file_name, ico_extension) + : fmt::format("eden-{:016X}.{}", program_id, ico_extension)); return true; } diff --git a/src/yuzu/migration_worker.cpp b/src/yuzu/migration_worker.cpp new file mode 100644 index 0000000000..2bb6eee944 --- /dev/null +++ b/src/yuzu/migration_worker.cpp @@ -0,0 +1,123 @@ +#include "migration_worker.h" + +#include + +#include "common/fs/path_util.h" + +MigrationWorker::MigrationWorker(const LegacyEmu selected_legacy_emu_, + const bool clear_shader_cache_, + const MigrationStrategy strategy_) + : QObject() + , selected_legacy_emu(selected_legacy_emu_) + , clear_shader_cache(clear_shader_cache_) + , strategy(strategy_) +{} + +void MigrationWorker::process() +{ + namespace fs = std::filesystem; + const auto copy_options = fs::copy_options::update_existing | fs::copy_options::recursive; + + std::string legacy_user_dir; + std::string legacy_config_dir; + std::string legacy_cache_dir; + +#define LEGACY_EMU(emu) \ + case LegacyEmu::emu: \ + legacy_user_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##Dir).string(); \ + legacy_config_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##ConfigDir) \ + .string(); \ + legacy_cache_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##CacheDir) \ + .string(); \ + break; + + switch (selected_legacy_emu) { + LEGACY_EMU(Citron) + LEGACY_EMU(Sudachi) + LEGACY_EMU(Yuzu) + LEGACY_EMU(Suyu) + } + +#undef LEGACY_EMU + + fs::path eden_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir); + fs::path config_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir); + fs::path cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir); + fs::path shader_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir); + + try { + fs::remove_all(eden_dir); + } catch (fs::filesystem_error &_) { + // ignore because linux does stupid crap sometimes. + } + + switch (strategy) { + case MigrationStrategy::Link: + // Create symlinks/directory junctions if requested + + // Windows 11 has random permission nonsense to deal with. + try { + fs::create_directory_symlink(legacy_user_dir, eden_dir); + } catch (const fs::filesystem_error &e) { + emit error(tr("Linking the old directory failed. You may need to re-run with " + "administrative privileges on Windows.\nOS gave error: %1") + .arg(tr(e.what()))); + return; + } + +// Windows doesn't need any more links, because cache and config +// are already children of the root directory +#ifndef WIN32 + if (fs::is_directory(legacy_config_dir)) { + fs::create_directory_symlink(legacy_config_dir, config_dir); + } + + if (fs::is_directory(legacy_cache_dir)) { + fs::create_directory_symlink(legacy_cache_dir, cache_dir); + } +#endif + break; + case MigrationStrategy::Move: + // Rename directories if deletion is requested (achieves the same result) + fs::rename(legacy_user_dir, eden_dir); + +// Windows doesn't need any more renames, because cache and config +// are already children of the root directory +#ifndef WIN32 + if (fs::is_directory(legacy_config_dir)) { + fs::rename(legacy_config_dir, config_dir); + } + + if (fs::is_directory(legacy_cache_dir)) { + fs::rename(legacy_cache_dir, cache_dir); + } +#endif + break; + case MigrationStrategy::Copy: + default: + // Default behavior: copy + fs::copy(legacy_user_dir, eden_dir, copy_options); + + if (fs::is_directory(legacy_config_dir)) { + fs::copy(legacy_config_dir, config_dir, copy_options); + } + + if (fs::is_directory(legacy_cache_dir)) { + fs::copy(legacy_cache_dir, cache_dir, copy_options); + } + + success_text.append(tr("\n\nIf you wish to clean up the files which were left in the old " + "data location, you can do so by deleting the following directory:\n" + "%1") + .arg(QString::fromStdString(legacy_user_dir))); + break; + } + + // Delete and re-create shader dir + if (clear_shader_cache) { + fs::remove_all(shader_dir); + fs::create_directory(shader_dir); + } + + emit finished(success_text); +} diff --git a/src/yuzu/migration_worker.h b/src/yuzu/migration_worker.h new file mode 100644 index 0000000000..49bb695b32 --- /dev/null +++ b/src/yuzu/migration_worker.h @@ -0,0 +1,41 @@ +#ifndef MIGRATION_WORKER_H +#define MIGRATION_WORKER_H + +#include + +class MigrationWorker : public QObject +{ + Q_OBJECT +public: + enum class LegacyEmu { + Citron, + Sudachi, + Yuzu, + Suyu, + }; + + enum class MigrationStrategy { + Copy, + Move, + Link, + }; + + MigrationWorker(const LegacyEmu selected_legacy_emu, + const bool clear_shader_cache, + const MigrationStrategy strategy); + +public slots: + void process(); + +signals: + void finished(const QString &success_text); + void error(const QString &error_message); + +private: + LegacyEmu selected_legacy_emu; + bool clear_shader_cache; + MigrationStrategy strategy; + QString success_text = tr("Data was migrated successfully."); +}; + +#endif // MIGRATION_WORKER_H diff --git a/src/yuzu/user_data_migration.cpp b/src/yuzu/user_data_migration.cpp index 12d780e226..1585695ff0 100644 --- a/src/yuzu/user_data_migration.cpp +++ b/src/yuzu/user_data_migration.cpp @@ -14,9 +14,12 @@ #include "migration_dialog.h" // Needs to be included at the end due to https://bugreports.qt.io/browse/QTBUG-73263 +#include #include #include +#include #include +#include #include namespace fs = std::filesystem; @@ -88,13 +91,13 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) // Reflection would make this code 10x better // but for now... MACRO MADNESS!!!! QMap found; - QMap legacyMap; + QMap legacyMap; QMap buttonMap; #define EMU_MAP(name) \ const bool name##_found = fs::is_directory( \ Common::FS::GetLegacyPath(Common::FS::LegacyPath::name##Dir)); \ - legacyMap[main_window->tr(#name)] = LegacyEmu::name; \ + legacyMap[main_window->tr(#name)] = MigrationWorker::LegacyEmu::name; \ found[main_window->tr(#name)] = name##_found; \ if (name##_found) \ any_found = true; @@ -116,7 +119,15 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) if (!iter.value()) continue; - buttonMap[iter.key()] = migration_prompt.addButton(iter.key()); + QAbstractButton *button = migration_prompt.addButton(iter.key()); + // TMP: disable citron + if (iter.key() == main_window->tr("Citron")) { + button->setEnabled(false); + button->setToolTip( + main_window->tr("Citron migration is known to cause issues. It's recommended " + "to manually set up your data again.")); + } + buttonMap[iter.key()] = button; promptText.append(main_window->tr("\n- %1").arg(iter.key())); } @@ -127,13 +138,13 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) migration_prompt.exec(); - MigrationStrategy strategy; + MigrationWorker::MigrationStrategy strategy; if (link->isChecked()) { - strategy = MigrationStrategy::Link; + strategy = MigrationWorker::MigrationStrategy::Link; } else if (clear_old->isChecked()) { - strategy = MigrationStrategy::Move; + strategy = MigrationWorker::MigrationStrategy::Move; } else { - strategy = MigrationStrategy::Copy; + strategy = MigrationWorker::MigrationStrategy::Copy; } QMapIterator buttonIter(buttonMap); @@ -171,120 +182,37 @@ void UserDataMigrator::ShowMigrationCancelledMessage(QMainWindow *main_window) } void UserDataMigrator::MigrateUserData(QMainWindow *main_window, - const LegacyEmu selected_legacy_emu, + const MigrationWorker::LegacyEmu selected_legacy_emu, const bool clear_shader_cache, - const MigrationStrategy strategy) + const MigrationWorker::MigrationStrategy strategy) { - namespace fs = std::filesystem; - const auto copy_options = fs::copy_options::update_existing | fs::copy_options::recursive; + // Create a dialog to let the user know it's migrating, some users noted confusion. + QProgressDialog *progress = new QProgressDialog(main_window); + progress->setWindowTitle(main_window->tr("Migrating")); + progress->setLabelText(main_window->tr("Migrating, this may take a while...")); + progress->setRange(0, 0); + progress->setCancelButton(nullptr); + progress->setWindowModality(Qt::WindowModality::ApplicationModal); - QString success_text = main_window->tr("Data was migrated successfully."); + QThread *thread = new QThread(main_window); + MigrationWorker *worker = new MigrationWorker(selected_legacy_emu, clear_shader_cache, strategy); + worker->moveToThread(thread); - std::string legacy_user_dir; - std::string legacy_config_dir; - std::string legacy_cache_dir; + thread->connect(thread, &QThread::started, worker, &MigrationWorker::process); -#define LEGACY_EMU(emu) \ - case LegacyEmu::emu: \ - legacy_user_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##Dir).string(); \ - legacy_config_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##ConfigDir) \ - .string(); \ - legacy_cache_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##CacheDir) \ - .string(); \ - break; + thread->connect(worker, &MigrationWorker::finished, progress, [=](const QString &success_text) { + progress->close(); + QMessageBox::information(main_window, + main_window->tr("Migration"), + success_text, + QMessageBox::Ok); - switch (selected_legacy_emu) { - LEGACY_EMU(Citron) - LEGACY_EMU(Sudachi) - LEGACY_EMU(Yuzu) - LEGACY_EMU(Suyu) - } + thread->quit(); + }); -#undef LEGACY_EMU + thread->connect(worker, &MigrationWorker::finished, worker, &QObject::deleteLater); + thread->connect(thread, &QThread::finished, thread, &QObject::deleteLater); - fs::path eden_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir); - fs::path config_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir); - fs::path cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir); - fs::path shader_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir); - - fs::remove_all(eden_dir); - - switch (strategy) { - case MigrationStrategy::Link: - // Create symlinks/directory junctions if requested - - // Windows 11 has random permission nonsense to deal with. - try { - fs::create_directory_symlink(legacy_user_dir, eden_dir); - } catch (const fs::filesystem_error &e) { - QMessageBox::critical( - main_window, - main_window->tr("Link Failed"), - main_window - ->tr("Linking the old directory failed. You may need to re-run with " - "administrative privileges on Windows.\nOS gave error: %1") - .arg(main_window->tr(e.what()))); - std::exit(127); - } - -// Windows doesn't need any more links, because cache and config -// are already children of the root directory -#ifndef WIN32 - if (fs::is_directory(legacy_config_dir)) { - fs::create_directory_symlink(legacy_config_dir, config_dir); - } - - if (fs::is_directory(legacy_cache_dir)) { - fs::create_directory_symlink(legacy_cache_dir, cache_dir); - } -#endif - break; - case MigrationStrategy::Move: - // Rename directories if deletion is requested (achieves the same result) - fs::rename(legacy_user_dir, eden_dir); - -// Windows doesn't need any more renames, because cache and config -// are already children of the root directory -#ifndef WIN32 - if (fs::is_directory(legacy_config_dir)) { - fs::rename(legacy_config_dir, config_dir); - } - - if (fs::is_directory(legacy_cache_dir)) { - fs::rename(legacy_cache_dir, cache_dir); - } -#endif - break; - case MigrationStrategy::Copy: - default: - // Default behavior: copy - fs::copy(legacy_user_dir, eden_dir, copy_options); - - if (fs::is_directory(legacy_config_dir)) { - fs::copy(legacy_config_dir, config_dir, copy_options); - } - - if (fs::is_directory(legacy_cache_dir)) { - fs::copy(legacy_cache_dir, cache_dir, copy_options); - } - - success_text.append( - main_window - ->tr("\n\nIf you wish to clean up the files which were left in the old " - "data location, you can do so by deleting the following directory:\n" - "%1") - .arg(QString::fromStdString(legacy_user_dir))); - break; - } - - // Delete and re-create shader dir - if (clear_shader_cache) { - fs::remove_all(shader_dir); - fs::create_directory(shader_dir); - } - - QMessageBox::information(main_window, - main_window->tr("Migration"), - success_text, - QMessageBox::Ok); + thread->start(); + progress->exec(); } diff --git a/src/yuzu/user_data_migration.h b/src/yuzu/user_data_migration.h index 3c4f745b87..fbf76eb334 100644 --- a/src/yuzu/user_data_migration.h +++ b/src/yuzu/user_data_migration.h @@ -8,27 +8,17 @@ #pragma once #include +#include "migration_worker.h" class UserDataMigrator { public: UserDataMigrator(QMainWindow* main_window); private: - enum class LegacyEmu { - Citron, - Sudachi, - Yuzu, - Suyu, - }; - - enum class MigrationStrategy { - Copy, - Move, - Link, - }; - void ShowMigrationPrompt(QMainWindow* main_window); void ShowMigrationCancelledMessage(QMainWindow* main_window); - void MigrateUserData(QMainWindow* main_window, const LegacyEmu selected_legacy_emu, - const bool clear_shader_cache, const MigrationStrategy strategy); + void MigrateUserData(QMainWindow* main_window, + const MigrationWorker::LegacyEmu selected_legacy_emu, + const bool clear_shader_cache, + const MigrationWorker::MigrationStrategy strategy); }; diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index eae614f9d0..3974e4b357 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -223,10 +223,12 @@ void EmuWindow_SDL2::WaitEvent() { const u32 current_time = SDL_GetTicks(); if (current_time > last_time + 2000) { const auto results = system.GetAndResetPerfStats(); - const auto title = - fmt::format("yuzu {} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname, - Common::g_scm_branch, Common::g_scm_desc, results.average_game_fps, - results.emulation_speed * 100.0); + const auto title = fmt::format("eden {} | {}-{} | FPS: {:.0f} ({:.0f}%)", + Common::g_build_fullname, + Common::g_scm_branch, + Common::g_scm_desc, + results.average_game_fps, + results.emulation_speed * 100.0); SDL_SetWindowTitle(render_window, title.c_str()); last_time = current_time; } @@ -236,7 +238,7 @@ void EmuWindow_SDL2::WaitEvent() { void EmuWindow_SDL2::SetWindowIcon() { SDL_RWops* const yuzu_icon_stream = SDL_RWFromConstMem((void*)yuzu_icon, yuzu_icon_size); if (yuzu_icon_stream == nullptr) { - LOG_WARNING(Frontend, "Failed to create yuzu icon stream."); + LOG_WARNING(Frontend, "Failed to create eden icon stream."); return; } SDL_Surface* const window_icon = SDL_LoadBMP_RW(yuzu_icon_stream, 1); diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 35e8aeda79..2e90be35ae 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -90,7 +90,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste } SDL_GL_SetSwapInterval(0); - std::string window_title = fmt::format("yuzu {} | {}-{}", Common::g_build_fullname, + std::string window_title = fmt::format("eden {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc); render_window = SDL_CreateWindow(window_title.c_str(), diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp index a969c1c291..043cdbf68d 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp @@ -23,7 +23,7 @@ EmuWindow_SDL2_Null::EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) : EmuWindow_SDL2{input_subsystem_, system_} { - const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name, + const std::string window_title = fmt::format("eden {} | {}-{} (Vulkan)", Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc); render_window = SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index c8378a5179..f4980932ed 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp @@ -18,8 +18,10 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) : EmuWindow_SDL2{input_subsystem_, system_} { - const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name, - Common::g_scm_branch, Common::g_scm_desc); + const std::string window_title = fmt::format("eden {} | {}-{} (Vulkan)", + Common::g_build_name, + Common::g_scm_branch, + Common::g_scm_desc); render_window = SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 790d630aad..55c0915814 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -81,7 +81,7 @@ static void PrintHelp(const char* argv0) { } static void PrintVersion() { - std::cout << "yuzu " << Common::g_scm_branch << " " << Common::g_scm_desc << std::endl; + std::cout << "eden " << Common::g_scm_branch << " " << Common::g_scm_desc << std::endl; } static void OnStateChanged(const Network::RoomMember::State& state) {