From 83ad84061e05fd7d07998757aa3fc9622066573f Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Sat, 20 Nov 2021 19:38:09 +0100 Subject: [PATCH] Core/Boot: Refactor storage of boot-to-savestate data into a separate class. --- Source/Android/jni/MainAndroid.cpp | 14 +++--- Source/Core/Core/Boot/Boot.cpp | 63 +++++++++++++++++++------- Source/Core/Core/Boot/Boot.h | 37 +++++++++++++-- Source/Core/Core/BootManager.cpp | 2 +- Source/Core/Core/Core.cpp | 6 ++- Source/Core/DolphinNoGUI/MainNoGUI.cpp | 6 ++- Source/Core/DolphinQt/Main.cpp | 6 ++- Source/Core/DolphinQt/MainWindow.cpp | 36 +++++++++------ Source/Core/DolphinQt/MainWindow.h | 9 ++-- 9 files changed, 126 insertions(+), 53 deletions(-) diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index c08106ee4f..4b94996796 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -549,8 +549,7 @@ static float GetRenderSurfaceScale(JNIEnv* env) } static void Run(JNIEnv* env, const std::vector& paths, bool riivolution, - const std::optional& savestate_path = {}, - bool delete_savestate = false) + BootSessionData boot_session_data = BootSessionData()) { ASSERT(!paths.empty()); __android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Running : %s", paths[0].c_str()); @@ -561,9 +560,8 @@ static void Run(JNIEnv* env, const std::vector& paths, bool riivolu s_have_wm_user_stop = false; - std::unique_ptr boot = BootParameters::GenerateFromFile(paths, savestate_path); - if (boot) - boot->delete_savestate = delete_savestate; + std::unique_ptr boot = + BootParameters::GenerateFromFile(paths, std::move(boot_session_data)); if (riivolution && std::holds_alternative(boot->parameters)) { @@ -638,8 +636,10 @@ Java_org_dolphinemu_dolphinemu_NativeLibrary_Run___3Ljava_lang_String_2ZLjava_la JNIEnv* env, jclass, jobjectArray jPaths, jboolean jRiivolution, jstring jSavestate, jboolean jDeleteSavestate) { - Run(env, JStringArrayToVector(env, jPaths), jRiivolution, GetJString(env, jSavestate), - jDeleteSavestate); + DeleteSavestateAfterBoot delete_state = + jDeleteSavestate ? DeleteSavestateAfterBoot::Yes : DeleteSavestateAfterBoot::No; + Run(env, JStringArrayToVector(env, jPaths), jRiivolution, + BootSessionData(GetJString(env, jSavestate), delete_state)); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ChangeDisc(JNIEnv* env, jclass, diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 3bb2c5e53d..39f5c1c69d 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -112,22 +112,53 @@ static std::vector ReadM3UFile(const std::string& m3u_path, return result; } -BootParameters::BootParameters(Parameters&& parameters_, - const std::optional& savestate_path_) - : parameters(std::move(parameters_)), savestate_path(savestate_path_) +BootSessionData::BootSessionData() { } -std::unique_ptr -BootParameters::GenerateFromFile(std::string boot_path, - const std::optional& savestate_path) +BootSessionData::BootSessionData(std::optional savestate_path, + DeleteSavestateAfterBoot delete_savestate) + : m_savestate_path(std::move(savestate_path)), m_delete_savestate(delete_savestate) { - return GenerateFromFile(std::vector{std::move(boot_path)}, savestate_path); } -std::unique_ptr -BootParameters::GenerateFromFile(std::vector paths, - const std::optional& savestate_path) +BootSessionData::BootSessionData(BootSessionData&& other) = default; + +BootSessionData& BootSessionData::operator=(BootSessionData&& other) = default; + +BootSessionData::~BootSessionData() = default; + +const std::optional& BootSessionData::GetSavestatePath() const +{ + return m_savestate_path; +} + +DeleteSavestateAfterBoot BootSessionData::GetDeleteSavestate() const +{ + return m_delete_savestate; +} + +void BootSessionData::SetSavestateData(std::optional savestate_path, + DeleteSavestateAfterBoot delete_savestate) +{ + m_savestate_path = std::move(savestate_path); + m_delete_savestate = delete_savestate; +} + +BootParameters::BootParameters(Parameters&& parameters_, BootSessionData boot_session_data_) + : parameters(std::move(parameters_)), boot_session_data(std::move(boot_session_data_)) +{ +} + +std::unique_ptr BootParameters::GenerateFromFile(std::string boot_path, + BootSessionData boot_session_data_) +{ + return GenerateFromFile(std::vector{std::move(boot_path)}, + std::move(boot_session_data_)); +} + +std::unique_ptr BootParameters::GenerateFromFile(std::vector paths, + BootSessionData boot_session_data_) { ASSERT(!paths.empty()); @@ -176,21 +207,21 @@ BootParameters::GenerateFromFile(std::vector paths, if (disc) { return std::make_unique(Disc{std::move(path), std::move(disc), paths}, - savestate_path); + std::move(boot_session_data_)); } if (extension == ".elf") { auto elf_reader = std::make_unique(path); return std::make_unique(Executable{std::move(path), std::move(elf_reader)}, - savestate_path); + std::move(boot_session_data_)); } if (extension == ".dol") { auto dol_reader = std::make_unique(path); return std::make_unique(Executable{std::move(path), std::move(dol_reader)}, - savestate_path); + std::move(boot_session_data_)); } if (is_drive) @@ -209,13 +240,13 @@ BootParameters::GenerateFromFile(std::vector paths, } if (extension == ".dff") - return std::make_unique(DFF{std::move(path)}, savestate_path); + return std::make_unique(DFF{std::move(path)}, std::move(boot_session_data_)); if (extension == ".wad") { std::unique_ptr wad = DiscIO::CreateWAD(std::move(path)); if (wad) - return std::make_unique(std::move(*wad), savestate_path); + return std::make_unique(std::move(*wad), std::move(boot_session_data_)); } if (extension == ".json") @@ -223,7 +254,7 @@ BootParameters::GenerateFromFile(std::vector paths, auto descriptor = DiscIO::ParseGameModDescriptorFile(path); if (descriptor) { - auto boot_params = GenerateFromFile(descriptor->base_file, savestate_path); + auto boot_params = GenerateFromFile(descriptor->base_file, std::move(boot_session_data_)); if (!boot_params) { PanicAlertFmtT("Could not recognize file {0}", descriptor->base_file); diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h index d9a891966b..b0564f751f 100644 --- a/Source/Core/Core/Boot/Boot.h +++ b/Source/Core/Core/Boot/Boot.h @@ -34,6 +34,34 @@ struct RegionSetting class BootExecutableReader; +enum class DeleteSavestateAfterBoot : u8 +{ + No, + Yes +}; + +class BootSessionData +{ +public: + BootSessionData(); + BootSessionData(std::optional savestate_path, + DeleteSavestateAfterBoot delete_savestate); + BootSessionData(const BootSessionData& other) = delete; + BootSessionData(BootSessionData&& other); + BootSessionData& operator=(const BootSessionData& other) = delete; + BootSessionData& operator=(BootSessionData&& other); + ~BootSessionData(); + + const std::optional& GetSavestatePath() const; + DeleteSavestateAfterBoot GetDeleteSavestate() const; + void SetSavestateData(std::optional savestate_path, + DeleteSavestateAfterBoot delete_savestate); + +private: + std::optional m_savestate_path; + DeleteSavestateAfterBoot m_delete_savestate = DeleteSavestateAfterBoot::No; +}; + struct BootParameters { struct Disc @@ -70,18 +98,17 @@ struct BootParameters }; static std::unique_ptr - GenerateFromFile(std::string boot_path, const std::optional& savestate_path = {}); + GenerateFromFile(std::string boot_path, BootSessionData boot_session_data_ = BootSessionData()); static std::unique_ptr GenerateFromFile(std::vector paths, - const std::optional& savestate_path = {}); + BootSessionData boot_session_data_ = BootSessionData()); using Parameters = std::variant; - BootParameters(Parameters&& parameters_, const std::optional& savestate_path_ = {}); + BootParameters(Parameters&& parameters_, BootSessionData boot_session_data_ = BootSessionData()); Parameters parameters; std::vector riivolution_patches; - std::optional savestate_path; - bool delete_savestate = false; + BootSessionData boot_session_data; }; class CBoot diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index fca36916b3..83361a1c1e 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -450,7 +450,7 @@ bool BootCore(std::unique_ptr boot, const WindowSystemInfo& wsi) std::make_unique( BootParameters::IPL{StartUp.m_region, std::move(std::get(boot->parameters))}, - boot->savestate_path), + std::move(boot->boot_session_data)), wsi); } return Core::Init(std::move(boot), wsi); diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 622d7f9d90..e4a7dc7e46 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -479,8 +479,10 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi Keyboard::LoadConfig(); } - const std::optional savestate_path = boot->savestate_path; - const bool delete_savestate = boot->delete_savestate; + BootSessionData boot_session_data = std::move(boot->boot_session_data); + const std::optional& savestate_path = boot_session_data.GetSavestatePath(); + const bool delete_savestate = + boot_session_data.GetDeleteSavestate() == DeleteSavestateAfterBoot::Yes; // Load and Init Wiimotes - only if we are booting in Wii mode bool init_wiimotes = false; diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp index 26b0e69a22..f439130441 100644 --- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp +++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp @@ -187,7 +187,8 @@ int main(int argc, char* argv[]) const std::list paths_list = options.all("exec"); const std::vector paths{std::make_move_iterator(std::begin(paths_list)), std::make_move_iterator(std::end(paths_list))}; - boot = BootParameters::GenerateFromFile(paths, save_state_path); + boot = BootParameters::GenerateFromFile( + paths, BootSessionData(save_state_path, DeleteSavestateAfterBoot::No)); game_specified = true; } else if (options.is_set("nand_title")) @@ -204,7 +205,8 @@ int main(int argc, char* argv[]) } else if (args.size()) { - boot = BootParameters::GenerateFromFile(args.front(), save_state_path); + boot = BootParameters::GenerateFromFile( + args.front(), BootSessionData(save_state_path, DeleteSavestateAfterBoot::No)); args.erase(args.begin()); game_specified = true; } diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index f7e8084dab..9c05198ca7 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -197,7 +197,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine const std::list paths_list = options.all("exec"); const std::vector paths{std::make_move_iterator(std::begin(paths_list)), std::make_move_iterator(std::end(paths_list))}; - boot = BootParameters::GenerateFromFile(paths, save_state_path); + boot = BootParameters::GenerateFromFile( + paths, BootSessionData(save_state_path, DeleteSavestateAfterBoot::No)); game_specified = true; } else if (options.is_set("nand_title")) @@ -216,7 +217,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine } else if (!args.empty()) { - boot = BootParameters::GenerateFromFile(args.front(), save_state_path); + boot = BootParameters::GenerateFromFile( + args.front(), BootSessionData(save_state_path, DeleteSavestateAfterBoot::No)); game_specified = true; } diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index 7e442398dd..c245a41557 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -244,8 +244,13 @@ MainWindow::MainWindow(std::unique_ptr boot_parameters, if (!movie_path.empty()) { - if (Movie::PlayInput(movie_path, &m_pending_boot->savestate_path)) + std::optional savestate_path; + if (Movie::PlayInput(movie_path, &savestate_path)) + { + m_pending_boot->boot_session_data.SetSavestateData(std::move(savestate_path), + DeleteSavestateAfterBoot::No); emit RecordingStatusChanged(true); + } } } @@ -768,14 +773,16 @@ void MainWindow::Play(const std::optional& savestate_path) std::shared_ptr selection = m_game_list->GetSelectedGame(); if (selection) { - StartGame(selection->GetFilePath(), ScanForSecondDisc::Yes, savestate_path); + StartGame(selection->GetFilePath(), ScanForSecondDisc::Yes, + std::make_unique(savestate_path, DeleteSavestateAfterBoot::No)); } else { const QString default_path = QString::fromStdString(Config::Get(Config::MAIN_DEFAULT_ISO)); if (!default_path.isEmpty() && QFile::exists(default_path)) { - StartGame(default_path, ScanForSecondDisc::Yes, savestate_path); + StartGame(default_path, ScanForSecondDisc::Yes, + std::make_unique(savestate_path, DeleteSavestateAfterBoot::No)); } else { @@ -978,7 +985,7 @@ void MainWindow::ScreenShot() } void MainWindow::ScanForSecondDiscAndStartGame(const UICommon::GameFile& game, - const std::optional& savestate_path) + std::unique_ptr boot_session_data) { auto second_game = m_game_list->FindSecondDisc(game); @@ -986,35 +993,37 @@ void MainWindow::ScanForSecondDiscAndStartGame(const UICommon::GameFile& game, if (second_game != nullptr) paths.push_back(second_game->GetFilePath()); - StartGame(paths, savestate_path); + StartGame(paths, std::move(boot_session_data)); } void MainWindow::StartGame(const QString& path, ScanForSecondDisc scan, - const std::optional& savestate_path) + std::unique_ptr boot_session_data) { - StartGame(path.toStdString(), scan, savestate_path); + StartGame(path.toStdString(), scan, std::move(boot_session_data)); } void MainWindow::StartGame(const std::string& path, ScanForSecondDisc scan, - const std::optional& savestate_path) + std::unique_ptr boot_session_data) { if (scan == ScanForSecondDisc::Yes) { std::shared_ptr game = m_game_list->FindGame(path); if (game != nullptr) { - ScanForSecondDiscAndStartGame(*game, savestate_path); + ScanForSecondDiscAndStartGame(*game, std::move(boot_session_data)); return; } } - StartGame(BootParameters::GenerateFromFile(path, savestate_path)); + StartGame(BootParameters::GenerateFromFile( + path, boot_session_data ? std::move(*boot_session_data) : BootSessionData())); } void MainWindow::StartGame(const std::vector& paths, - const std::optional& savestate_path) + std::unique_ptr boot_session_data) { - StartGame(BootParameters::GenerateFromFile(paths, savestate_path)); + StartGame(BootParameters::GenerateFromFile( + paths, boot_session_data ? std::move(*boot_session_data) : BootSessionData())); } void MainWindow::StartGame(std::unique_ptr&& parameters) @@ -1818,8 +1827,7 @@ void MainWindow::ShowRiivolutionBootWidget(const UICommon::GameFile& game) std::vector paths = {game.GetFilePath()}; if (second_game != nullptr) paths.push_back(second_game->GetFilePath()); - std::unique_ptr boot_params = - BootParameters::GenerateFromFile(paths, std::nullopt); + std::unique_ptr boot_params = BootParameters::GenerateFromFile(paths); if (!boot_params) return; if (!std::holds_alternative(boot_params->parameters)) diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h index c0e97af96d..6e53f2df10 100644 --- a/Source/Core/DolphinQt/MainWindow.h +++ b/Source/Core/DolphinQt/MainWindow.h @@ -15,6 +15,7 @@ class QStackedWidget; class QString; class BreakpointWidget; +class BootSessionData; struct BootParameters; class CheatsManager; class CodeWidget; @@ -132,13 +133,13 @@ private: }; void ScanForSecondDiscAndStartGame(const UICommon::GameFile& game, - const std::optional& savestate_path = {}); + std::unique_ptr boot_session_data = nullptr); void StartGame(const QString& path, ScanForSecondDisc scan, - const std::optional& savestate_path = {}); + std::unique_ptr boot_session_data = nullptr); void StartGame(const std::string& path, ScanForSecondDisc scan, - const std::optional& savestate_path = {}); + std::unique_ptr boot_session_data = nullptr); void StartGame(const std::vector& paths, - const std::optional& savestate_path = {}); + std::unique_ptr boot_session_data = nullptr); void StartGame(std::unique_ptr&& parameters); void ShowRenderWidget(); void HideRenderWidget(bool reinit = true, bool is_exit = false);