tasks are shared ptrs that can be cancelled and undone
This commit is contained in:
+1
-1
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user