From 9cbdbddb08da2b5c78e068f543f1bf417860107b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 18 Jun 2024 17:27:17 +0300 Subject: [PATCH] made hasing task async Signed-off-by: Trial97 --- launcher/MMCZip.h | 2 +- launcher/modplatform/helpers/HashUtils.cpp | 37 ++++++++++++++-------- launcher/modplatform/helpers/HashUtils.h | 10 ++++-- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index a872411fa..eb0ea8f6a 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -213,7 +213,7 @@ class ExtractZipTask : public Task { {} virtual ~ExtractZipTask() = default; - typedef std::optional ZipResult; + using ZipResult = std::optional; protected: virtual void executeTask() override; diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp index b111ab1c1..13bac582e 100644 --- a/launcher/modplatform/helpers/HashUtils.cpp +++ b/launcher/modplatform/helpers/HashUtils.cpp @@ -1,16 +1,11 @@ #include "HashUtils.h" +#include #include #include - -#include "FileSystem.h" -#include "StringUtils.h" +#include #include -#include -#include -#include -#include namespace Hashing { @@ -143,12 +138,28 @@ QString hash(QByteArray data, Algorithm type) void Hasher::executeTask() { - m_result = hash(m_path, m_alg); - if (m_result.isEmpty()) { - emitFailed("Empty hash!"); - } else { - emitSucceeded(); - emit resultsReady(m_result); + m_zip_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return hash(m_path, m_alg); }); + connect(&m_zip_watcher, &QFutureWatcher::finished, this, [this] { + if (m_zip_future.isCanceled()) { + emitAborted(); + } else if (m_result = m_zip_future.result(); m_result.isEmpty()) { + emitFailed("Empty hash!"); + } else { + emitSucceeded(); + emit resultsReady(m_result); + } + }); + m_zip_watcher.setFuture(m_zip_future); +} + +bool Hasher::abort() +{ + if (m_zip_future.isRunning()) { + m_zip_future.cancel(); + // NOTE: Here we don't do `emitAborted()` because it will be done when `m_build_zip_future` actually cancels, which may not + // occur immediately. + return true; } + return false; } } // namespace Hashing diff --git a/launcher/modplatform/helpers/HashUtils.h b/launcher/modplatform/helpers/HashUtils.h index 2390312d2..3402c5c1f 100644 --- a/launcher/modplatform/helpers/HashUtils.h +++ b/launcher/modplatform/helpers/HashUtils.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include #include "modplatform/ModIndex.h" @@ -24,8 +26,7 @@ class Hasher : public Task { Hasher(QString file_path, Algorithm alg) : m_path(file_path), m_alg(alg) {} Hasher(QString file_path, QString alg) : Hasher(file_path, algorithmFromString(alg)) {} - /* We can't really abort this task, but we can say we aborted and finish our thing quickly :) */ - bool abort() override { return true; } + bool abort() override; void executeTask() override; @@ -35,10 +36,13 @@ class Hasher : public Task { signals: void resultsReady(QString hash); - protected: + private: QString m_result; QString m_path; Algorithm m_alg; + + QFuture m_zip_future; + QFutureWatcher m_zip_watcher; }; Hasher::Ptr createHasher(QString file_path, ModPlatform::ResourceProvider provider);