From 5fb3c10c3ab53b0b42a3904ee03ce0f53fc46ad6 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 3 Feb 2019 22:42:25 +0000 Subject: [PATCH] Make download objects async with progress --- data/language/en-GB.txt | 1 + src/openrct2-ui/windows/ObjectLoadError.cpp | 97 +++++++++++++++------ src/openrct2/localisation/StringIds.h | 1 + 3 files changed, 70 insertions(+), 29 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index c28b17aad7..aa934d9242 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3747,6 +3747,7 @@ STR_6296 :GiB STR_6297 :TiB STR_6298 :{STRING}/sec STR_6299 :Download all +STR_6300 :Downloading object ({COMMA16} / {COMMA16}): [{STRING}] ############# # Scenarios # diff --git a/src/openrct2-ui/windows/ObjectLoadError.cpp b/src/openrct2-ui/windows/ObjectLoadError.cpp index b5275dc941..281e39e803 100644 --- a/src/openrct2-ui/windows/ObjectLoadError.cpp +++ b/src/openrct2-ui/windows/ObjectLoadError.cpp @@ -18,9 +18,12 @@ #include #include #include +#include #include #include +static constexpr auto OPENRCT2_API_LEGACY_OBJECT_URL = "https://api.openrct2.io/objects/legacy/"; + // clang-format off enum WINDOW_OBJECT_LOAD_ERROR_WIDGET_IDX { WIDX_BACKGROUND, @@ -67,6 +70,7 @@ static void window_object_load_error_scrollmousedown(rct_window *w, int32_t scro static void window_object_load_error_paint(rct_window *w, rct_drawpixelinfo *dpi); static void window_object_load_error_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int32_t scrollIndex); static void window_object_load_error_download_all(rct_window* w); +static void next_download(); static rct_window_event_list window_object_load_error_events = { window_object_load_error_close, @@ -103,6 +107,8 @@ static rct_window_event_list window_object_load_error_events = { static std::vector _invalid_entries; static int32_t highlighted_index = -1; static std::string file_path; +static int32_t _currentDownloadIndex; +static bool _downloadingObjects; /** * Returns an rct_string_id that represents an rct_object_entry's type. @@ -348,7 +354,22 @@ static void window_object_load_error_scrollpaint(rct_window* w, rct_drawpixelinf } } -static void DownloadObject(IObjectRepository& objRepo, const std::string name, const std::string_view url) +static void show_progress(const std::string& name, int32_t count, int32_t total) +{ + char str_downloading_objects[256]; + set_format_arg(0, int16_t, count); + set_format_arg(2, int16_t, total); + set_format_arg(4, char*, name.c_str()); + + format_string(str_downloading_objects, sizeof(str_downloading_objects), STR_DOWNLOADING_OBJECTS, gCommonFormatArgs); + + auto intent = Intent(WC_NETWORK_STATUS); + intent.putExtra(INTENT_EXTRA_MESSAGE, std::string(str_downloading_objects)); + intent.putExtra(INTENT_EXTRA_CALLBACK, []() -> void { _downloadingObjects = false; }); + context_open_intent(&intent); +} + +static void DownloadObject(const std::string name, const std::string_view url) { using namespace OpenRCT2::Network; try @@ -356,40 +377,50 @@ static void DownloadObject(IObjectRepository& objRepo, const std::string name, c Http::Request req; req.method = Http::Method::GET; req.url = url; - auto response = Http::Do(req); - if (response.status == Http::Status::OK) - { - auto data = (uint8_t*)response.body.data(); - auto dataLen = response.body.size(); - objRepo.AddObjectFromFile(name, data, dataLen); - } - else - { - throw std::runtime_error("Non 200 status"); - } + Http::DoAsync(req, [name](Http::Response response) { + if (response.status == Http::Status::OK) + { + auto data = (uint8_t*)response.body.data(); + auto dataLen = response.body.size(); + + auto& objRepo = OpenRCT2::GetContext()->GetObjectRepository(); + objRepo.AddObjectFromFile(name, data, dataLen); + } + else + { + throw std::runtime_error("Non 200 status"); + } + next_download(); + }); } catch (const std::exception&) { std::printf(" Failed to download %s\n", name.c_str()); + next_download(); } } -static void window_object_load_error_download_all(rct_window* w) +static void next_download() { using namespace OpenRCT2::Network; - auto& objRepo = OpenRCT2::GetContext()->GetObjectRepository(); - for (const auto& entry : _invalid_entries) + if (!_downloadingObjects || _currentDownloadIndex >= _invalid_entries.size()) { - auto name = String::Trim(std::string(entry.name, sizeof(entry.name))); + // Finished... + return; + } - std::printf("Downloading %s...\n", name.c_str()); - try - { - Http::Request req; - req.method = Http::Method::GET; - req.url = "http://localhost:5000/objects/legacy/" + name; - auto response = Http::Do(req); + auto& entry = _invalid_entries[_currentDownloadIndex]; + auto name = String::Trim(std::string(entry.name, sizeof(entry.name))); + show_progress(name, _currentDownloadIndex + 1, (int32_t)_invalid_entries.size()); + std::printf("Downloading %s...\n", name.c_str()); + _currentDownloadIndex++; + try + { + Http::Request req; + req.method = Http::Method::GET; + req.url = OPENRCT2_API_LEGACY_OBJECT_URL + name; + Http::DoAsync(req, [name](Http::Response response) { if (response.status == Http::Status::OK) { auto jresponse = Json::FromString(response.body); @@ -399,7 +430,7 @@ static void window_object_load_error_download_all(rct_window* w) auto downloadLink = json_string_value(json_object_get(jresponse, "download")); if (downloadLink != nullptr) { - DownloadObject(objRepo, objName, downloadLink); + DownloadObject(objName, downloadLink); } json_decref(jresponse); } @@ -407,11 +438,19 @@ static void window_object_load_error_download_all(rct_window* w) else { std::printf(" %s not found\n", name.c_str()); + next_download(); } - } - catch (const std::exception&) - { - std::printf(" Failed to query %s\n", name.c_str()); - } + }); + } + catch (const std::exception&) + { + std::printf(" Failed to query %s\n", name.c_str()); } } + +static void window_object_load_error_download_all(rct_window* w) +{ + _currentDownloadIndex = 0; + _downloadingObjects = true; + next_download(); +} diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 8154ceb540..7fa4d6fc6d 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3928,6 +3928,7 @@ enum STR_NETWORK_SPEED_SEC = 6298, STR_DOWNLOAD_ALL = 6299, + STR_DOWNLOADING_OBJECTS = 6300, // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768