Files
oak-editor/app/dialog/task/task.cpp
T
itsmattkc 5a070f14de general: use IdlePriority rather than LowPriority
Fixes a number of playback stuttering and general UI lag issues by setting all
background tasks to IdlePriority rather than LowPriority. While it was assumed
LowPriority tasks would always get scheduled below NormalPriority (e.g. main
thread) tasks, it turns out this is not always the case. If the background tasks
start consuming a lot of CPU cycles, the scheduler may use "dynamic scheduling"
to schedule them above the main thread regardless leading to UI lag. This is
apparently the case for all thread priorities apart from IdlePriority, which
is allegedly a special case where threads are *only* scheduled when other
threads aren't busy ensuring the main thread stays responsive.
2020-02-20 17:48:50 +11:00

68 lines
1.9 KiB
C++

#include "task.h"
#include <QMessageBox>
#include <QThread>
TaskDialog::TaskDialog(Task* task, const QString& title, QWidget *parent) :
ProgressDialog(task->GetTitle(), title, parent),
task_(task),
task_failed_(false)
{
thread_ = new QThread();
// Connect the save manager progress signal to the progress bar update on the dialog
connect(task_, &Task::ProgressChanged, this, &TaskDialog::SetProgress, Qt::QueuedConnection);
// Connect cancel signal (must be a direct connection or it'll be queued after the save is already finished)
connect(this, &TaskDialog::Cancelled, this, &TaskDialog::reject, Qt::DirectConnection);
// Connect cleanup functions (ensure everything new'd in this function is deleteLater'd)
connect(task_, &Task::Finished, this, &TaskDialog::accept, Qt::QueuedConnection);
connect(task_, &Task::Finished, this, &TaskDialog::deleteLater, Qt::QueuedConnection);
connect(task_, &Task::Finished, task_, &Task::deleteLater, Qt::QueuedConnection);
connect(task_, &Task::Finished, thread_, &QThread::quit, Qt::QueuedConnection);
connect(task_, &Task::Finished, thread_, &QThread::deleteLater, Qt::QueuedConnection);
}
void TaskDialog::open()
{
ProgressDialog::open();
if (thread_->isRunning()) {
// Task has already started, no need to do anymore
return;
}
// Create a separate thread to run this task in
thread_->start();
// Move the task to this thread
task_->moveToThread(thread_);
// Start the task
QMetaObject::invokeMethod(task_, "Start", Qt::QueuedConnection);
}
void TaskDialog::accept()
{
if (task_failed_) {
QMessageBox::critical(this,
tr("Task Error"),
task_error_,
QMessageBox::Ok);
}
ProgressDialog::accept();
}
void TaskDialog::reject()
{
task_->Cancel();
}
void TaskDialog::TaskFailed(const QString &s)
{
task_failed_ = true;
task_error_ = s;
}