From 370bb4c3154813bf975a45599e59872089e1e405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 18 Jul 2023 15:52:14 +0200 Subject: [PATCH] More progressbar improvements --- Common/Net/HTTPClient.cpp | 50 ++++++++++++++++++-------------------- Common/Net/HTTPClient.h | 8 +++--- Common/Net/NetBuffer.cpp | 2 +- Common/Net/NetBuffer.h | 12 ++++++--- Common/System/OSD.cpp | 11 ++++++++- Core/RetroAchievements.cpp | 9 ++++--- assets/lang/en_US.ini | 1 + 7 files changed, 52 insertions(+), 41 deletions(-) diff --git a/Common/Net/HTTPClient.cpp b/Common/Net/HTTPClient.cpp index 98c70db433..83f4bf2083 100644 --- a/Common/Net/HTTPClient.cpp +++ b/Common/Net/HTTPClient.cpp @@ -303,7 +303,7 @@ int Client::SendRequest(const char *method, const RequestParams &req, const char } int Client::SendRequestWithData(const char *method, const RequestParams &req, const std::string &data, const char *otherHeaders, net::RequestProgress *progress) { - progress->Update(0.01f); + progress->Update(0, 0, false); net::Buffer buffer; const char *tpl = @@ -410,17 +410,11 @@ int Client::ReadResponseEntity(net::Buffer *readbuf, const std::vectorUpdate(0.02f); - } - if (!readbuf->ReadAllWithProgress(sock(), contentLength, progress)) return -1; @@ -428,7 +422,6 @@ int Client::ReadResponseEntity(net::Buffer *readbuf, const std::vectorIsVoid()) { if (chunked) { DeChunk(readbuf, output, contentLength); - progress->Update(1.0f); } else { output->Append(*readbuf); } @@ -440,42 +433,45 @@ int Client::ReadResponseEntity(net::Buffer *readbuf, const std::vectorUpdate(0.0f); // TJDO: is this right? + progress->Update(0, 0, true); return -1; } output->Append(decompressed); } } - progress->Update(1.0f); + progress->Update(contentLength, contentLength, true); return 0; } -Download::Download(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode) - : method_(method), progress_(&cancelled_), url_(url), postData_(postData), postMime_(postMime), outfile_(outfile), progressBarMode_(progressBarMode) { - - progress_.callback = [=](float progress) { +Download::Download(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode, const std::string &name) + : method_(method), progress_(&cancelled_), url_(url), postData_(postData), postMime_(postMime), outfile_(outfile), progressBarMode_(progressBarMode), name_(name) { + progress_.callback = [=](int64_t bytes, int64_t contentLength, bool done) { std::string message; if (!name_.empty()) { message = name_; } else { - std::size_t pos = url.rfind('/'); + std::size_t pos = url_.rfind('/'); if (pos != std::string::npos) { - message = url.substr(pos + 1); + message = url_.substr(pos + 1); } else { - message = url; + message = url_; } } if (progressBarMode_ != ProgressBarMode::NONE) { - g_OSD.SetProgressBar(url, std::move(message), 0.0f, 1.0f, progress, progressBarMode_ == ProgressBarMode::DELAYED ? 1.0f : 0.0f); // delay 0.5 seconds before showing. - if (progress == 1.0f) { - g_OSD.RemoveProgressBar(url, Failed() ? false : true, 0.5f); + INFO_LOG(IO, "Showing progress bar: %s", message.c_str()); + if (!done) { + g_OSD.SetProgressBar(url_, std::move(message), 0.0f, (float)contentLength, (float)bytes, progressBarMode_ == ProgressBarMode::DELAYED ? 3.0f : 0.0f); // delay 3 seconds before showing. + } else { + g_OSD.RemoveProgressBar(url_, Failed() ? false : true, 0.5f); } } }; } Download::~Download() { + g_OSD.RemoveProgressBar(url_, Failed() ? false : true, 0.5f); + _assert_msg_(joined_, "Download destructed without join"); } @@ -493,7 +489,7 @@ void Download::Join() { void Download::SetFailed(int code) { failed_ = true; - progress_.Update(1.0f); + progress_.Update(0, 0, true); completed_ = true; } @@ -588,8 +584,6 @@ void Download::Do() { resultCode_ = resultCode; } - progress_.Update(1.0f); - // Set this last to ensure no race conditions when checking Done. Users must always check // Done before looking at the result code. completed_ = true; @@ -612,8 +606,9 @@ std::shared_ptr Downloader::StartDownloadWithCallback( const Path &outfile, ProgressBarMode mode, std::function callback, + const std::string &name, const char *acceptMime) { - std::shared_ptr dl(new Download(RequestMethod::GET, url, "", "", outfile, mode)); + std::shared_ptr dl(new Download(RequestMethod::GET, url, "", "", outfile, mode, name)); if (!userAgent_.empty()) dl->SetUserAgent(userAgent_); if (acceptMime) @@ -629,8 +624,9 @@ std::shared_ptr Downloader::AsyncPostWithCallback( const std::string &postData, const std::string &postMime, ProgressBarMode mode, - std::function callback) { - std::shared_ptr dl(new Download(RequestMethod::POST, url, postData, postMime, Path(), mode)); + std::function callback, + const std::string &name) { + std::shared_ptr dl(new Download(RequestMethod::POST, url, postData, postMime, Path(), mode, name)); if (!userAgent_.empty()) dl->SetUserAgent(userAgent_); dl->SetCallback(callback); diff --git a/Common/Net/HTTPClient.h b/Common/Net/HTTPClient.h index 8987e3331e..88b76f116e 100644 --- a/Common/Net/HTTPClient.h +++ b/Common/Net/HTTPClient.h @@ -103,7 +103,7 @@ enum class ProgressBarMode { // Really an asynchronous request. class Download { public: - Download(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode = ProgressBarMode::DELAYED); + Download(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode = ProgressBarMode::DELAYED, const std::string &name = ""); ~Download(); void SetAccept(const char *mime) { @@ -153,8 +153,6 @@ public: callback_(*this); } } - // Visual name for the download, to be displayed in progress bars. - void SetName(const std::string &&name) { name_ = std::move(name); } private: void Do(); // Actually does the download. Runs on thread. @@ -198,6 +196,7 @@ public: const Path &outfile, ProgressBarMode mode, std::function callback, + const std::string &name = "", const char *acceptMime = nullptr); std::shared_ptr AsyncPostWithCallback( @@ -205,7 +204,8 @@ public: const std::string &postData, const std::string &postMime, // Use postMime = "application/x-www-form-urlencoded" for standard form-style posts, such as used by retroachievements. For encoding form data manually we have MultipartFormDataEncoder. ProgressBarMode mode, - std::function callback); + std::function callback, + const std::string &name = ""); // Drops finished downloads from the list. void Update(); diff --git a/Common/Net/NetBuffer.cpp b/Common/Net/NetBuffer.cpp index cf2f16706c..3cdbbcd189 100644 --- a/Common/Net/NetBuffer.cpp +++ b/Common/Net/NetBuffer.cpp @@ -89,7 +89,7 @@ bool Buffer::ReadAllWithProgress(int fd, int knownSize, RequestProgress *progres memcpy(p, &buf[0], retval); total += retval; if (progress) { - progress->Update((float)total / (float)knownSize); + progress->Update(total, knownSize, false); progress->kBps = (float)(total / (time_now_d() - st)) / 1024.0f; } } diff --git a/Common/Net/NetBuffer.h b/Common/Net/NetBuffer.h index bc49b97ab4..85b1421d28 100644 --- a/Common/Net/NetBuffer.h +++ b/Common/Net/NetBuffer.h @@ -12,17 +12,21 @@ public: RequestProgress() {} explicit RequestProgress(bool *c) : cancelled(c) {} - void Update(float newProgress) { - progress = newProgress; + void Update(int64_t downloaded, int64_t totalBytes, bool done) { + if (totalBytes) { + progress = (double)downloaded / (double)totalBytes; + } else { + progress = 0.01f; + } if (callback) { - callback(newProgress); + callback(downloaded, totalBytes, done); } } float progress = 0.0f; float kBps = 0.0f; bool *cancelled = nullptr; - std::function callback; + std::function callback; }; class Buffer : public ::Buffer { diff --git a/Common/System/OSD.cpp b/Common/System/OSD.cpp index f100737cc8..ab1b900e69 100644 --- a/Common/System/OSD.cpp +++ b/Common/System/OSD.cpp @@ -216,9 +216,14 @@ void OnScreenDisplay::ShowOnOff(const std::string &message, bool on, float durat } void OnScreenDisplay::SetProgressBar(std::string id, std::string &&message, float minValue, float maxValue, float progress, float delay) { - std::lock_guard guard(mutex_); + _dbg_assert_(!my_isnanorinf(progress)); + _dbg_assert_(!my_isnanorinf(minValue)); + _dbg_assert_(!my_isnanorinf(maxValue)); + double now = time_now_d(); bool found = false; + + std::lock_guard guard(mutex_); for (auto &bar : bars_) { if (bar.id == id) { bar.minValue = minValue; @@ -230,6 +235,10 @@ void OnScreenDisplay::SetProgressBar(std::string id, std::string &&message, floa } } + if (message == "dorequest.php") { + found = found; + } + ProgressBar bar; bar.id = id; bar.message = std::move(message); diff --git a/Core/RetroAchievements.cpp b/Core/RetroAchievements.cpp index 84710d136a..84302c8123 100644 --- a/Core/RetroAchievements.cpp +++ b/Core/RetroAchievements.cpp @@ -175,8 +175,9 @@ static void server_call_callback(const rc_api_request_t *request, rc_client_server_callback_t callback, void *callback_data, rc_client_t *client) { // If post data is provided, we need to make a POST request, otherwise, a GET request will suffice. + auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS); if (request->post_data) { - g_DownloadManager.AsyncPostWithCallback(std::string(request->url), std::string(request->post_data), "application/x-www-form-urlencoded", http::ProgressBarMode::DELAYED, [=](http::Download &download) { + std::shared_ptr download = g_DownloadManager.AsyncPostWithCallback(std::string(request->url), std::string(request->post_data), "application/x-www-form-urlencoded", http::ProgressBarMode::DELAYED, [=](http::Download &download) { std::string buffer; download.buffer().TakeAll(&buffer); rc_api_server_response_t response{}; @@ -184,9 +185,9 @@ static void server_call_callback(const rc_api_request_t *request, response.body_length = buffer.size(); response.http_status_code = download.ResultCode(); callback(&response, callback_data); - }); + }, ac->T("Contacting RetroAchievements server...")); } else { - g_DownloadManager.StartDownloadWithCallback(std::string(request->url), Path(), http::ProgressBarMode::DELAYED, [=](http::Download &download) { + std::shared_ptr download = g_DownloadManager.StartDownloadWithCallback(std::string(request->url), Path(), http::ProgressBarMode::DELAYED, [=](http::Download &download) { std::string buffer; download.buffer().TakeAll(&buffer); rc_api_server_response_t response{}; @@ -194,7 +195,7 @@ static void server_call_callback(const rc_api_request_t *request, response.body_length = buffer.size(); response.http_status_code = download.ResultCode(); callback(&response, callback_data); - }); + }, ac->T("Contacting RetroAchievements server...")); } } diff --git a/assets/lang/en_US.ini b/assets/lang/en_US.ini index ec4b256d5f..3462f24c2f 100644 --- a/assets/lang/en_US.ini +++ b/assets/lang/en_US.ini @@ -32,6 +32,7 @@ Achievements = Achievements Achievements are disabled = Achievements are disabled Challenge Mode = Challenge Mode Challenge Mode (no savestates) = Challenge Mode (no savestates) +Contacting RetroAchievements server... = Contacting RetroAchievements server... Customize = Customize Earned = You have earned %d of %d achievements, and %d of %d points Encore Mode = Encore Mode