From 5befd0666aef0b96e3e4bd41ed704ccaa3ace5d5 Mon Sep 17 00:00:00 2001 From: ConfuSomu Date: Mon, 10 Jul 2023 13:27:34 +0200 Subject: Implement basic multithreading support A few CPU heavy operations, which are opening an archive and displaying a selected Activity, have been moved to another thread to avoid having long-running operations on the main thread. --- src/mainwindow.cpp | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ede24f8..363f2b1 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -9,6 +9,7 @@ #include #include #include +#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) @@ -17,6 +18,7 @@ MainWindow::MainWindow(QWidget *parent) ui->setupUi(this); connect(ui->buttonCopy, &QPushButton::clicked, ui->actionCopy_status, &QAction::trigger); connect(ui->buttonRandom, &QPushButton::clicked, ui->actionRandom_status, &QAction::trigger); + connect(&archive_thread_watcher, &QFutureWatcher>::finished, this, &MainWindow::archive_thread_watcher_done); } MainWindow::~MainWindow() @@ -60,15 +62,22 @@ void MainWindow::on_actionAbout_triggered(bool checked) { QMessageBox::information(this, "title", "text"); } +std::variant start_listWidget_itemActivated(StatusListItem* status, int text_zone_width, QLocale* locale) { + return (QString)status->get_info_html(text_zone_width, locale); +} + void MainWindow::on_listWidget_itemActivated(QListWidgetItem *item) { StatusListItem* status = dynamic_cast(item); if (status != nullptr) { - // TODO: do this in another thread - QString status_info = status->get_info_html(ui->statusInfoText->width(), &locale_context); - ui->statusInfoText->setHtml(status_info); + const QFuture> status_info = QtConcurrent::run(start_listWidget_itemActivated, status, ui->statusInfoText->width(), &locale_context); + archive_thread_watcher.setFuture(status_info); } } +void MainWindow::finish_listWidget_itemActivated(const QString& status_info) { + ui->statusInfoText->setHtml(status_info); +} + void MainWindow::on_actionRandom_status_triggered(bool checked) { if (data_archive == nullptr) return; // No archive open, avoids crashing @@ -201,14 +210,19 @@ void MainWindow::open_file(const QString &filename) { data_archive = nullptr; } - // TODO: Do this in another thread + open_file_filename = filename; + QApplication::setOverrideCursor(Qt::WaitCursor); data_archive = new Archive(filename, ArchiveType::MASTODON); - auto parse_error = data_archive->init(); + QFuture> parse_error = QtConcurrent::run(data_archive, &Archive::init); + archive_thread_watcher.setFuture(parse_error); +} + +void MainWindow::finish_open_file(const Archive::InitError& parse_error) { switch (parse_error) { case Archive::FailedOpeningFile: - QMessageBox::warning(this, tr("Archive Parser"), tr("Failed opening file %1").arg(filename)); break; + QMessageBox::warning(this, tr("Archive Parser"), tr("Failed opening file %1").arg(open_file_filename)); break; case Archive::JsonParseError: QMessageBox::warning(this, tr("Archive Parser"), tr("Failed parsing outbox JSON.")); break; case Archive::JsonEmpty: @@ -228,3 +242,17 @@ void MainWindow::open_file(const QString &filename) { QApplication::restoreOverrideCursor(); } + +void MainWindow::archive_thread_watcher_done() { + std::variant result = archive_thread_watcher.result(); + + // For MainWindow::on_listWidget_itemActivated + if (const QString* status_info = std::get_if(&result)) { + finish_listWidget_itemActivated(*status_info); + } else + // For MainWindow::open_file + if (const Archive::InitError* parse_error = std::get_if(&result)) { + finish_open_file(*parse_error); + } else + qDebug() << "What, the variant is weird"; +} -- cgit v1.2.3-54-g00ecf