feat: Propogated subtask progress
Oh boy this is big. > TaskStepProgress struct is now QMetaObject compatabile and can be sent through signals > Task now has a method to propogates sub task progress it must be signal bound by each task containing a task wishing to report progress of it's children. > Downloads report speed > Tasks now have UUIDS to track them - use when reporting - use when logging - use when storeing them or objects related to them Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include "tasks/Task.h"
|
||||
|
||||
ConcurrentTask::ConcurrentTask(QObject* parent, QString task_name, int max_concurrent)
|
||||
: Task(parent), m_name(task_name), m_total_max_size(max_concurrent)
|
||||
@@ -15,13 +16,9 @@ ConcurrentTask::~ConcurrentTask()
|
||||
}
|
||||
}
|
||||
|
||||
auto ConcurrentTask::getStepProgress() const -> QList<TaskStepProgress>
|
||||
auto ConcurrentTask::getStepProgress() const -> TaskStepProgressList
|
||||
{
|
||||
QList<TaskStepProgress> task_progress;
|
||||
for (auto progress : task_progress) {
|
||||
task_progress.append(task_progress);
|
||||
}
|
||||
return task_progress;
|
||||
return m_task_progress.values();
|
||||
}
|
||||
|
||||
void ConcurrentTask::addTask(Task::Ptr task)
|
||||
@@ -103,7 +100,7 @@ void ConcurrentTask::startNext()
|
||||
connect(next.get(), &Task::failed, this, [this, next](QString msg) { subTaskFailed(next, msg); });
|
||||
|
||||
connect(next.get(), &Task::status, this, [this, next](QString msg){ subTaskStatus(next, msg); });
|
||||
connect(next.get(), &Task::stepProgress, this, [this, next](QList<TaskStepProgress> tp){ subTaskStepProgress(next, tp); });
|
||||
connect(next.get(), &Task::stepProgress, this, [this, next](TaskStepProgressList tp){ subTaskStepProgress(next, tp); });
|
||||
|
||||
connect(next.get(), &Task::progress, this, [this, next](qint64 current, qint64 total){ subTaskProgress(next, current, total); });
|
||||
|
||||
@@ -112,6 +109,7 @@ void ConcurrentTask::startNext()
|
||||
|
||||
|
||||
updateState();
|
||||
updateStepProgress();
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
@@ -129,12 +127,12 @@ void ConcurrentTask::subTaskSucceeded(Task::Ptr task)
|
||||
m_succeeded.insert(task.get(), task);
|
||||
|
||||
m_doing.remove(task.get());
|
||||
m_task_progress.value(task->getUid())->state = TaskState::Succeeded;
|
||||
m_task_progress.value(task->getUid())->state = TaskStepState::Succeeded;
|
||||
|
||||
disconnect(task.get(), 0, this, 0);
|
||||
|
||||
updateState();
|
||||
|
||||
updateStepProgress();
|
||||
startNext();
|
||||
}
|
||||
|
||||
@@ -144,20 +142,22 @@ void ConcurrentTask::subTaskFailed(Task::Ptr task, const QString& msg)
|
||||
m_failed.insert(task.get(), task);
|
||||
|
||||
m_doing.remove(task.get());
|
||||
m_task_progress.value(task->getUid())->state = TaskState::Failed;
|
||||
m_task_progress.value(task->getUid())->state = TaskStepState::Failed;
|
||||
|
||||
disconnect(task.get(), 0, this, 0);
|
||||
|
||||
updateState();
|
||||
|
||||
updateStepProgress();
|
||||
startNext();
|
||||
}
|
||||
|
||||
void ConcurrentTask::subTaskStatus(Task::Ptr task, const QString& msg)
|
||||
{
|
||||
auto taskProgress = m_task_progress.value(task->getUid());
|
||||
taskProgress->status = msg;
|
||||
taskProgress->status = msg;
|
||||
taskProgress->state = TaskStepState::Running;
|
||||
updateState();
|
||||
updateStepProgress();
|
||||
}
|
||||
|
||||
void ConcurrentTask::subTaskProgress(Task::Ptr task, qint64 current, qint64 total)
|
||||
@@ -166,21 +166,28 @@ void ConcurrentTask::subTaskProgress(Task::Ptr task, qint64 current, qint64 tota
|
||||
|
||||
taskProgress->current = current;
|
||||
taskProgress->total = total;
|
||||
|
||||
taskProgress->state = TaskStepState::Running;
|
||||
taskProgress->details = task->getDetails();
|
||||
|
||||
updateStepProgress();
|
||||
updateState();
|
||||
}
|
||||
|
||||
void ConcurrentTask::subTaskStepProgress(Task::Ptr task, QList<TaskStepProgress> task_step_progress)
|
||||
void ConcurrentTask::subTaskStepProgress(Task::Ptr task, TaskStepProgressList task_step_progress)
|
||||
{
|
||||
for (auto progress : task_step_progress) {
|
||||
if (!m_task_progress.contains(progress.uid))
|
||||
m_task_progress.insert(progress.uid, std::make_shared<TaskStepProgress>(progress));
|
||||
|
||||
|
||||
if (!m_task_progress.contains(progress->uid)) {
|
||||
m_task_progress.insert(progress->uid, progress);
|
||||
} else {
|
||||
auto tp = m_task_progress.value(progress->uid);
|
||||
tp->current = progress->current;
|
||||
tp->total = progress->total;
|
||||
tp->status = progress->status;
|
||||
tp->details = progress->details;
|
||||
}
|
||||
}
|
||||
|
||||
updateStepProgress();
|
||||
|
||||
}
|
||||
|
||||
@@ -194,6 +201,7 @@ void ConcurrentTask::updateStepProgress()
|
||||
|
||||
m_stepProgress = current;
|
||||
m_stepTotalProgress = total;
|
||||
emit stepProgress(m_task_progress.values());
|
||||
}
|
||||
|
||||
void ConcurrentTask::updateState()
|
||||
|
||||
@@ -18,8 +18,8 @@ public:
|
||||
|
||||
bool canAbort() const override { return true; }
|
||||
|
||||
inline auto isMultiStep() const -> bool override { return m_queue.size() > 1; };
|
||||
auto getStepProgress() const -> QList<TaskStepProgress> override;
|
||||
inline auto isMultiStep() const -> bool override { return totalSize() > 1; };
|
||||
auto getStepProgress() const -> TaskStepProgressList override;
|
||||
|
||||
void addTask(Task::Ptr task);
|
||||
|
||||
@@ -41,7 +41,7 @@ slots:
|
||||
void subTaskFailed(Task::Ptr, const QString &msg);
|
||||
void subTaskStatus(Task::Ptr task, const QString &msg);
|
||||
void subTaskProgress(Task::Ptr task, qint64 current, qint64 total);
|
||||
void subTaskStepProgress(Task::Ptr task, QList<TaskStepProgress> task_step_progress);
|
||||
void subTaskStepProgress(Task::Ptr task, TaskStepProgressList task_step_progress);
|
||||
|
||||
protected:
|
||||
// NOTE: This is not thread-safe.
|
||||
|
||||
@@ -148,6 +148,11 @@ void Task::emitSucceeded()
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void Task::propogateStepProgress(TaskStepProgressList task_progress)
|
||||
{
|
||||
emit stepProgress(task_progress);
|
||||
}
|
||||
|
||||
QString Task::describe()
|
||||
{
|
||||
QString outStr;
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
#include "QObjectPtr.h"
|
||||
|
||||
enum class TaskState {
|
||||
enum class TaskStepState {
|
||||
Waiting,
|
||||
Running,
|
||||
Failed,
|
||||
@@ -50,16 +50,22 @@ enum class TaskState {
|
||||
Finished
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(TaskStepState)
|
||||
|
||||
struct TaskStepProgress {
|
||||
QUuid uid;
|
||||
qint64 current;
|
||||
qint64 total;
|
||||
QString status;
|
||||
QString details;
|
||||
TaskState state = TaskState::Waiting;
|
||||
bool isDone() { return (state == TaskState::Failed) || (state == TaskState::Succeeded) || (state == TaskState::Finished); }
|
||||
qint64 current = 0;
|
||||
qint64 total = -1;
|
||||
QString status = "";
|
||||
QString details = "";
|
||||
TaskStepState state = TaskStepState::Waiting;
|
||||
bool isDone() { return (state == TaskStepState::Failed) || (state == TaskStepState::Succeeded) || (state == TaskStepState::Finished); }
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(TaskStepProgress)
|
||||
|
||||
typedef QList<std::shared_ptr<TaskStepProgress>> TaskStepProgressList;
|
||||
|
||||
class Task : public QObject, public QRunnable {
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -97,7 +103,7 @@ class Task : public QObject, public QRunnable {
|
||||
|
||||
qint64 getProgress() { return m_progress; }
|
||||
qint64 getTotalProgress() { return m_progressTotal; }
|
||||
virtual auto getStepProgress() const -> QList<TaskStepProgress> { return {}; }
|
||||
virtual auto getStepProgress() const -> TaskStepProgressList { return {}; }
|
||||
|
||||
virtual auto getDetails() const -> QString { return ""; }
|
||||
|
||||
@@ -117,7 +123,7 @@ class Task : public QObject, public QRunnable {
|
||||
void aborted();
|
||||
void failed(QString reason);
|
||||
void status(QString status);
|
||||
void stepProgress(QList<TaskStepProgress> task_progress); //
|
||||
void stepProgress(TaskStepProgressList task_progress); //
|
||||
|
||||
/** Emitted when the canAbort() status has changed.
|
||||
*/
|
||||
@@ -140,6 +146,8 @@ class Task : public QObject, public QRunnable {
|
||||
virtual void emitAborted();
|
||||
virtual void emitFailed(QString reason = "");
|
||||
|
||||
virtual void propogateStepProgress(TaskStepProgressList task_progress);
|
||||
|
||||
public slots:
|
||||
void setStatus(const QString& status);
|
||||
void setProgress(qint64 current, qint64 total);
|
||||
|
||||
Reference in New Issue
Block a user