tasks are shared ptrs that can be cancelled and undone

This commit is contained in:
itsmattkc
2019-07-06 13:22:47 -05:00
parent b62ec30015
commit 3038af3482
7 changed files with 106 additions and 20 deletions
+1 -1
View File
@@ -110,7 +110,7 @@ void Core::ImportFiles(const QStringList &urls, ProjectViewModel* model, Folder*
return;
}
olive::task_manager.AddTask(new ImportTask(model, parent, urls));
olive::task_manager.AddTask(std::make_shared<ImportTask>(model, parent, urls));
}
const olive::tool::Tool &Core::tool()
+11 -2
View File
@@ -50,6 +50,14 @@ bool ImportTask::Action()
Import(urls_, parent_, command);
// If this task was cancelled, we won't bother pushing an undo command (we don't end up with anything undoable since
// the undo command executes the final import anyway)
if (cancelled()) {
delete command;
return true;
}
olive::undo_stack.push(command);
return true;
@@ -122,14 +130,15 @@ void ImportTask::Import(const QStringList &files, Folder *folder, QUndoCommand *
parent_command);
// Create ProbeTask to analyze this media
ProbeTask* pt = new ProbeTask(f);
TaskPtr pt = std::make_shared<ProbeTask>(f);
// The task won't work unless it's in the main thread and we're definitely not
// FIXME: Should Tasks check what thread they're in and move themselves to the main thread?
pt->moveToThread(qApp->thread());
// Queue task in task manager
olive::task_manager.AddTask(pt);
new TaskManager::AddTaskCommand(pt, parent_command);
//olive::task_manager.AddTask(pt);
}
+26
View File
@@ -93,8 +93,34 @@ void Task::AddDependency(Task *dependency)
dependencies_.append(dependency);
}
void Task::EmitRemovedSignal()
{
emit Removed();
}
void Task::ResetState()
{
if (status_ == kWaiting) {
return;
}
if (status_ == kWorking) {
Cancel();
}
cancelled_ = false;
set_error(QString());
set_status(kWaiting);
}
void Task::Cancel()
{
if (status_ == kWaiting) {
set_status(kFinished);
}
if (status_ != kWorking) {
return;
}
+18
View File
@@ -21,6 +21,7 @@
#ifndef TASK_H
#define TASK_H
#include <memory>
#include <QObject>
#include "task/taskthread.h"
@@ -141,6 +142,16 @@ public:
*/
void AddDependency(Task* dependency);
/**
* @brief Emit the Removed() signal when this Task is about to get removed
*/
void EmitRemovedSignal();
/**
* @brief Reset this Task back to the waiting state
*/
void ResetState();
public slots:
/**
* @brief Cancel the Task
@@ -198,6 +209,11 @@ signals:
*/
void Finished();
/**
* @brief Signal emitted when this Task is removed from TaskManager
*/
void Removed();
private:
/**
* @brief Set the status of this Task (also emits StatusChanged())
@@ -223,4 +239,6 @@ private slots:
void ThreadComplete();
};
using TaskPtr = std::shared_ptr<Task>;
#endif // TASK_H
+33 -13
View File
@@ -35,16 +35,16 @@ TaskManager::~TaskManager()
Clear();
}
void TaskManager::AddTask(Task* t)
{
void TaskManager::AddTask(TaskPtr t)
{
// Connect Task's status signal to the Callback
connect(t, SIGNAL(StatusChanged(Task::Status)), this, SLOT(TaskCallback(Task::Status)));
connect(t.get(), SIGNAL(StatusChanged(Task::Status)), this, SLOT(TaskCallback(Task::Status)));
// Add the Task to the queue
tasks_.append(t);
// Emit signal that a Task was added
emit TaskAdded(t);
emit TaskAdded(t.get());
// Scan through queue and start any Tasks that can (including this one)
StartNextWaiting();
@@ -52,11 +52,9 @@ void TaskManager::AddTask(Task* t)
void TaskManager::Clear()
{
// TODO Cancelling tasks
// Delete Tasks from memory
for (int i=0;i<tasks_.size();i++) {
delete tasks_.at(i);
tasks_.at(i)->Cancel();
}
tasks_.clear();
}
@@ -67,7 +65,7 @@ void TaskManager::StartNextWaiting()
int working_count = 0;
for (int i=0;i<tasks_.size();i++) {
Task* t = tasks_.at(i);
TaskPtr t = tasks_.at(i);
if (t->status() == Task::kWorking) {
@@ -93,13 +91,17 @@ void TaskManager::StartNextWaiting()
void TaskManager::DeleteTask(Task *t)
{
// TODO Cancelling tasks?
// Cancel the task
t->Cancel();
// Remove instances of Task from queue
tasks_.removeAll(t);
// Destroy Task object
t->deleteLater();
for (int i=0;i<tasks_.size();i++) {
if (tasks_.at(i).get() == t) {
t->EmitRemovedSignal();
tasks_.removeAt(i);
break;
}
}
}
void TaskManager::TaskCallback(Task::Status status)
@@ -127,3 +129,21 @@ void TaskManager::TaskCallback(Task::Status status)
break;
}
}
TaskManager::AddTaskCommand::AddTaskCommand(TaskPtr t, QUndoCommand *parent) :
QUndoCommand(parent),
task_(t)
{
}
void TaskManager::AddTaskCommand::redo()
{
olive::task_manager.AddTask(task_);
}
void TaskManager::AddTaskCommand::undo()
{
olive::task_manager.DeleteTask(task_.get());
task_->ResetState();
}
+16 -3
View File
@@ -22,6 +22,7 @@
#define TASKMANAGER_H
#include <QVector>
#include <QUndoCommand>
#include "task/task.h"
@@ -84,13 +85,25 @@ public:
*
* The task to add and run. TaskManager takes ownership of this Task and will be responsible for freeing it.
*/
void AddTask(Task *t);
void AddTask(TaskPtr t);
/**
* @brief Forcibly
* @brief Forcibly cancel all commands and clear them
*/
void Clear();
class AddTaskCommand : public QUndoCommand {
public:
AddTaskCommand(TaskPtr t, QUndoCommand* parent = nullptr);
virtual void redo() override;
virtual void undo() override;
private:
TaskPtr task_;
};
signals:
/**
* @brief Signal emitted when a Task is added by AddTask()
@@ -129,7 +142,7 @@ private:
/**
* @brief Internal task array
*/
QVector<Task*> tasks_;
QVector<TaskPtr> tasks_;
/**
* @brief Constant set at run-time of how many Tasks can run concurrently
+1 -1
View File
@@ -75,7 +75,7 @@ void TaskViewItem::SetTask(Task *t)
// Connect to the task
connect(task_, SIGNAL(StatusChanged(Task::Status)), this, SLOT(TaskStatusChange(Task::Status)));
connect(task_, SIGNAL(ProgressChanged(int)), progress_bar_, SLOT(setValue(int)));
connect(task_, SIGNAL(destroyed()), this, SLOT(deleteLater()));
connect(task_, SIGNAL(Removed()), this, SLOT(deleteLater()));
connect(cancel_btn_, SIGNAL(clicked(bool)), task_, SLOT(Cancel()));
}