From c00fe1e7d6cd3e87501d0ef329d056d68f72929a Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 29 May 2024 22:13:03 +0200 Subject: [PATCH] Rework (preloader) scene completion functionality (#22122) * Remove the need for Scene::GetCompletionScene * Replace SetCompletionScene with SetOnComplete * Normalise return type for GetPreloaderScene * Rename 'onFinish' to 'onComplete' for consistency --- src/openrct2/Context.cpp | 106 +++++++++++++---------- src/openrct2/scenes/Scene.cpp | 14 +-- src/openrct2/scenes/Scene.h | 10 +-- src/openrct2/scenes/title/TitleScene.cpp | 5 ++ 4 files changed, 74 insertions(+), 61 deletions(-) diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 50ea85c61c..90d151db7d 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -310,9 +310,7 @@ namespace OpenRCT2 return EXIT_FAILURE; } - // NB: This takes some liberty in returning PreloaderScene* instead of IScene*. - // PreloaderScene adds some methods to Scene, which are used internally by Context. - PreloaderScene* GetPreloaderScene() override + IScene* GetPreloaderScene() override { if (auto* scene = _preloaderScene.get()) return scene; @@ -520,7 +518,7 @@ namespace OpenRCT2 if (!gOpenRCT2Headless) { - auto* preloaderScene = GetPreloaderScene(); + auto* preloaderScene = static_cast(GetPreloaderScene()); SetActiveScene(preloaderScene); // TODO: preload the title scene in another (parallel) job. @@ -573,10 +571,7 @@ namespace OpenRCT2 OpenProgress(STR_CHECKING_TITLE_SEQUENCES); TitleSequenceManager::Scan(); - if (GetPreloaderScene()->GetCompletionScene() == GetTitleScene()) - OpenProgress(STR_LOADING_TITLE_SEQUENCE); - else - OpenProgress(STR_LOADING_GENERIC); + OpenProgress(STR_LOADING_GENERIC); } public: @@ -975,7 +970,7 @@ namespace OpenRCT2 return true; } - IScene* DetermineStartUpScene() + void SwitchToStartUpScene() { if (gOpenRCT2Headless) { @@ -993,16 +988,19 @@ namespace OpenRCT2 } } + IScene* nextScene{}; switch (gOpenRCT2StartupAction) { case StartupAction::Intro: { - return GetIntroScene(); + nextScene = GetIntroScene(); + break; } case StartupAction::Title: { - return GetTitleScene(); + nextScene = GetTitleScene(); + break; } case StartupAction::Open: @@ -1016,14 +1014,16 @@ namespace OpenRCT2 auto data = DownloadPark(gOpenRCT2StartupActionPath); if (data.empty()) { - return GetTitleScene(); + nextScene = GetTitleScene(); + break; } auto ms = MemoryStream(data.data(), data.size(), MEMORY_ACCESS::READ); if (!LoadParkFromStream(&ms, gOpenRCT2StartupActionPath, true)) { Console::Error::WriteLine("Failed to load '%s'", gOpenRCT2StartupActionPath); - return GetTitleScene(); + nextScene = GetTitleScene(); + break; } #endif } @@ -1033,67 +1033,55 @@ namespace OpenRCT2 { if (!LoadParkFromFile(gOpenRCT2StartupActionPath, true)) { - return GetTitleScene(); + nextScene = GetTitleScene(); + break; } } catch (const std::exception& ex) { Console::Error::WriteLine("Failed to load '%s'", gOpenRCT2StartupActionPath); Console::Error::WriteLine("%s", ex.what()); - return GetTitleScene(); + nextScene = GetTitleScene(); + break; } } // Successfully loaded a file - return GetGameScene(); + nextScene = GetGameScene(); + break; } + case StartupAction::Edit: { if (String::SizeOf(gOpenRCT2StartupActionPath) == 0) { Editor::Load(); - return GetGameScene(); + nextScene = GetGameScene(); } else if (Editor::LoadLandscape(gOpenRCT2StartupActionPath)) { - return GetGameScene(); + nextScene = GetGameScene(); } - [[fallthrough]]; + else + { + nextScene = GetTitleScene(); + } + break; } + default: { - return GetTitleScene(); + nextScene = GetTitleScene(); } } + + SetActiveScene(nextScene); + InitNetworkGame(nextScene == GetGameScene()); } - /** - * Launches the game, after command line arguments have been parsed and processed. - */ - void Launch() + void InitNetworkGame(bool isGameScene) { - if (!_versionCheckFuture.valid()) - { - _versionCheckFuture = std::async(std::launch::async, [this] { - _newVersionInfo = GetLatestVersion(); - if (!String::StartsWith(gVersionInfoTag, _newVersionInfo.tag)) - { - _hasNewVersionInfo = true; - } - }); - } - - auto* scene = DetermineStartUpScene(); - if (!gOpenRCT2Headless) - { - _preloaderScene->SetCompletionScene(scene); - } - else - { - SetActiveScene(scene); - } - - if (scene == GetGameScene()) + if (isGameScene) { #ifndef DISABLE_NETWORK if (gNetworkStart == NETWORK_MODE_SERVER) @@ -1136,6 +1124,32 @@ namespace OpenRCT2 _network.BeginClient(gNetworkStartHost, gNetworkStartPort); } #endif // DISABLE_NETWORK + } + + /** + * Launches the game, after command line arguments have been parsed and processed. + */ + void Launch() + { + if (!_versionCheckFuture.valid()) + { + _versionCheckFuture = std::async(std::launch::async, [this] { + _newVersionInfo = GetLatestVersion(); + if (!String::StartsWith(gVersionInfoTag, _newVersionInfo.tag)) + { + _hasNewVersionInfo = true; + } + }); + } + + if (!gOpenRCT2Headless) + { + _preloaderScene->SetOnComplete([&]() { SwitchToStartUpScene(); }); + } + else + { + SwitchToStartUpScene(); + } _stdInOutConsole.Start(); RunGameLoop(); diff --git a/src/openrct2/scenes/Scene.cpp b/src/openrct2/scenes/Scene.cpp index f300c0d02c..af5d8fdc7f 100644 --- a/src/openrct2/scenes/Scene.cpp +++ b/src/openrct2/scenes/Scene.cpp @@ -31,19 +31,13 @@ GameState_t& Scene::GetGameState() void Scene::FinishScene() { - if (_nextScene != nullptr) + if (_onComplete != nullptr) { - _context.SetActiveScene(_nextScene); - _nextScene = nullptr; + _onComplete(); } } -IScene* Scene::GetCompletionScene() +void Scene::SetOnComplete(std::function onComplete) { - return _nextScene; -} - -void Scene::SetCompletionScene(IScene* scene) -{ - _nextScene = scene; + _onComplete = onComplete; } diff --git a/src/openrct2/scenes/Scene.h b/src/openrct2/scenes/Scene.h index a082717d26..fce0571ad9 100644 --- a/src/openrct2/scenes/Scene.h +++ b/src/openrct2/scenes/Scene.h @@ -11,6 +11,8 @@ #include "../common.h" +#include + namespace OpenRCT2 { struct GameState_t; @@ -28,8 +30,7 @@ namespace OpenRCT2 virtual void Tick() = 0; virtual void Stop() = 0; - virtual IScene* GetCompletionScene() = 0; - virtual void SetCompletionScene(IScene* scene) = 0; + virtual void SetOnComplete(std::function) = 0; }; class Scene : public IScene @@ -40,15 +41,14 @@ namespace OpenRCT2 GameState_t& GetGameState() override; IContext& GetContext() override; - IScene* GetCompletionScene() override; - void SetCompletionScene(IScene* scene) override; + void SetOnComplete(std::function) override; protected: void FinishScene(); protected: IContext& _context; - IScene* _nextScene = nullptr; + std::function _onComplete{}; }; } // namespace OpenRCT2 diff --git a/src/openrct2/scenes/title/TitleScene.cpp b/src/openrct2/scenes/title/TitleScene.cpp index 07e38464b4..6fff90c50b 100644 --- a/src/openrct2/scenes/title/TitleScene.cpp +++ b/src/openrct2/scenes/title/TitleScene.cpp @@ -121,6 +121,9 @@ void TitleScene::Load() ViewportInitAll(); ContextOpenWindow(WindowClass::MainWindow); CreateWindows(); + + GetContext().OpenProgress(STR_LOADING_TITLE_SEQUENCE); + TitleInitialise(); OpenRCT2::Audio::PlayTitleMusic(); @@ -139,6 +142,8 @@ void TitleScene::Load() _sequencePlayer->Update(); } + GetContext().CloseProgress(); + LOG_VERBOSE("TitleScene::Load() finished"); }