aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorConfuSomu2023-07-10 13:27:34 +0200
committerConfuSomu2023-07-10 13:42:16 +0200
commit5befd0666aef0b96e3e4bd41ed704ccaa3ace5d5 (patch)
tree76402efb62ecf9bc1817910179afc7f71b646e32 /src
parent9b70e3c5a208a881188bc6468fe27933cbdb02f8 (diff)
downloadActorViewer-5befd0666aef0b96e3e4bd41ed704ccaa3ace5d5.tar
ActorViewer-5befd0666aef0b96e3e4bd41ed704ccaa3ace5d5.tar.gz
ActorViewer-5befd0666aef0b96e3e4bd41ed704ccaa3ace5d5.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/archive_parser.cpp6
-rw-r--r--src/archive_parser.h6
-rw-r--r--src/list_item.cpp2
-rw-r--r--src/list_item.h2
-rw-r--r--src/mainwindow.cpp40
-rw-r--r--src/mainwindow.h9
6 files changed, 51 insertions, 14 deletions
diff --git a/src/archive_parser.cpp b/src/archive_parser.cpp
index 77d3ec0..96df1ec 100644
--- a/src/archive_parser.cpp
+++ b/src/archive_parser.cpp
@@ -19,7 +19,7 @@
Archive::Archive(QString outbox_filename, ArchiveType archive_type) :
outbox_filename(outbox_filename), archive_type(archive_type) {}
-Archive::InitError Archive::init() {
+std::variant<QString, Archive::InitError> Archive::init() {
QFile outbox_file(outbox_filename);
if (!outbox_file.open(QIODevice::ReadOnly | QIODevice::Text))
@@ -233,7 +233,7 @@ std::vector<APAttachmentFields> Archive::get_status_attachments_list(QJsonValueR
}
// status_index is assumed to be a valid index
-QString Archive::get_html_status_info(int status_index, int text_zone_width, StatusType status_type, QLocale* locale) {
+const QString Archive::get_html_status_info(int status_index, int text_zone_width, StatusType status_type, QLocale* locale) {
// the JSON AP Activity (TODO: fix misleading name)
QJsonObject obj = outbox_items->at(status_index).toObject();
@@ -303,7 +303,7 @@ QString Archive::get_html_status_info(int status_index, int text_zone_width, Sta
}
// TODO: make this use an APActivity object that will be present as an StatusListItem member.
-QString Archive::get_html_status_text(int status_index) {
+const QString Archive::get_html_status_text(int status_index) {
QString text("");
QJsonObject obj = outbox_items->at(status_index).toObject();
diff --git a/src/archive_parser.h b/src/archive_parser.h
index c206087..7377120 100644
--- a/src/archive_parser.h
+++ b/src/archive_parser.h
@@ -28,11 +28,11 @@ public:
Archive(QString outbox_filename, ArchiveType archive_type);
~Archive();
- InitError init();
+ std::variant<QString, InitError> init();
void update_status_list(ViewStatusTypes allowed_types, QListWidget *parent);
- QString get_html_status_info(int status_index, int text_zone_width, StatusType status_type, QLocale* locale);
- QString get_html_status_text(int status_index);
+ const QString get_html_status_info(int status_index, int text_zone_width, StatusType status_type, QLocale* locale);
+ const QString get_html_status_text(int status_index);
private:
QString outbox_filename;
QDir archive_root_dir;
diff --git a/src/list_item.cpp b/src/list_item.cpp
index c74fa39..020ccde 100644
--- a/src/list_item.cpp
+++ b/src/list_item.cpp
@@ -39,6 +39,6 @@ StatusType StatusListItem::get_status_type() {
return status_type;
}
-QString StatusListItem::get_info_html(int text_zone_width, QLocale* locale) {
+const QString StatusListItem::get_info_html(int text_zone_width, QLocale* locale) {
return data_archive->get_html_status_info(status_index, text_zone_width, status_type, locale);
}
diff --git a/src/list_item.h b/src/list_item.h
index 9ca0aac..4514903 100644
--- a/src/list_item.h
+++ b/src/list_item.h
@@ -13,7 +13,7 @@ public:
StatusListItem(const QString &text, StatusType status_type, bool has_attachement, Archive* data_archive, QListWidget *parent = nullptr, int index = 0);
int get_status_index();
StatusType get_status_type();
- QString get_info_html(int text_zone_width, QLocale* locale);
+ const QString get_info_html(int text_zone_width, QLocale* locale);
private:
int status_index;
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 <QRandomGenerator>
#include <QClipboard>
#include <QMimeData>
+#include <QtConcurrent/QtConcurrent>
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<std::variant<QString, Archive::InitError>>::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<QString, Archive::InitError> 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<StatusListItem*>(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<std::variant<QString, Archive::InitError>> 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<std::variant<QString, Archive::InitError>> 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<QString, Archive::InitError> result = archive_thread_watcher.result();
+
+ // For MainWindow::on_listWidget_itemActivated
+ if (const QString* status_info = std::get_if<QString>(&result)) {
+ finish_listWidget_itemActivated(*status_info);
+ } else
+ // For MainWindow::open_file
+ if (const Archive::InitError* parse_error = std::get_if<Archive::InitError>(&result)) {
+ finish_open_file(*parse_error);
+ } else
+ qDebug() << "What, the variant is weird";
+}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index f1de2d7..abf9acc 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -3,6 +3,8 @@
#include <QMainWindow>
#include <QListWidgetItem>
#include <QLocale>
+#include <QFutureWatcher>
+#include <variant>
#include "archive_parser.h"
#include "types.h"
@@ -47,6 +49,12 @@ private:
void reset_view_filters();
void relist_statuses();
void open_file(const QString &filename);
+ void archive_thread_watcher_done();
+
+ void finish_listWidget_itemActivated(const QString& status_info);
+ void finish_open_file(const Archive::InitError& parse_error);
+
+ QString open_file_filename;
Ui::MainWindow *ui;
@@ -54,6 +62,7 @@ private:
bool view_filters_changed = false;
Archive *data_archive = nullptr;
+ QFutureWatcher<std::variant<QString, Archive::InitError>> archive_thread_watcher;
QLocale locale_context;
};