Merge pull request #2633 from Trial97/refactor_minecraft_update
refactor MinecraftUpdate Task
This commit is contained in:
commit
e9791d6bc1
@ -16,32 +16,22 @@
|
||||
#include "MinecraftUpdate.h"
|
||||
#include "MinecraftInstance.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QTextStream>
|
||||
|
||||
#include <FileSystem.h>
|
||||
#include "BaseInstance.h"
|
||||
#include "minecraft/Library.h"
|
||||
#include "minecraft/PackProfile.h"
|
||||
|
||||
#include "tasks/SequentialTask.h"
|
||||
#include "update/AssetUpdateTask.h"
|
||||
#include "update/FMLLibrariesTask.h"
|
||||
#include "update/FoldersTask.h"
|
||||
#include "update/LibrariesTask.h"
|
||||
|
||||
#include <meta/Index.h>
|
||||
#include <meta/Version.h>
|
||||
|
||||
MinecraftUpdate::MinecraftUpdate(MinecraftInstance* inst, QObject* parent) : Task(parent), m_inst(inst) {}
|
||||
MinecraftUpdate::MinecraftUpdate(MinecraftInstance* inst, QObject* parent) : SequentialTask(parent), m_inst(inst) {}
|
||||
|
||||
void MinecraftUpdate::executeTask()
|
||||
{
|
||||
m_tasks.clear();
|
||||
m_queue.clear();
|
||||
// create folders
|
||||
{
|
||||
m_tasks.append(makeShared<FoldersTask>(m_inst));
|
||||
addTask(makeShared<FoldersTask>(m_inst));
|
||||
}
|
||||
|
||||
// add metadata update task if necessary
|
||||
@ -50,121 +40,24 @@ void MinecraftUpdate::executeTask()
|
||||
components->reload(Net::Mode::Online);
|
||||
auto task = components->getCurrentTask();
|
||||
if (task) {
|
||||
m_tasks.append(task);
|
||||
addTask(task);
|
||||
}
|
||||
}
|
||||
|
||||
// libraries download
|
||||
{
|
||||
m_tasks.append(makeShared<LibrariesTask>(m_inst));
|
||||
addTask(makeShared<LibrariesTask>(m_inst));
|
||||
}
|
||||
|
||||
// FML libraries download and copy into the instance
|
||||
{
|
||||
m_tasks.append(makeShared<FMLLibrariesTask>(m_inst));
|
||||
addTask(makeShared<FMLLibrariesTask>(m_inst));
|
||||
}
|
||||
|
||||
// assets update
|
||||
{
|
||||
m_tasks.append(makeShared<AssetUpdateTask>(m_inst));
|
||||
addTask(makeShared<AssetUpdateTask>(m_inst));
|
||||
}
|
||||
|
||||
if (!m_preFailure.isEmpty()) {
|
||||
emitFailed(m_preFailure);
|
||||
return;
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
void MinecraftUpdate::next()
|
||||
{
|
||||
if (m_abort) {
|
||||
emitFailed(tr("Aborted by user."));
|
||||
return;
|
||||
}
|
||||
if (m_failed_out_of_order) {
|
||||
emitFailed(m_fail_reason);
|
||||
return;
|
||||
}
|
||||
m_currentTask++;
|
||||
if (m_currentTask > 0) {
|
||||
auto task = m_tasks[m_currentTask - 1];
|
||||
disconnect(task.get(), &Task::succeeded, this, &MinecraftUpdate::subtaskSucceeded);
|
||||
disconnect(task.get(), &Task::failed, this, &MinecraftUpdate::subtaskFailed);
|
||||
disconnect(task.get(), &Task::aborted, this, &Task::abort);
|
||||
disconnect(task.get(), &Task::progress, this, &MinecraftUpdate::progress);
|
||||
disconnect(task.get(), &Task::stepProgress, this, &MinecraftUpdate::propagateStepProgress);
|
||||
disconnect(task.get(), &Task::status, this, &MinecraftUpdate::setStatus);
|
||||
disconnect(task.get(), &Task::details, this, &MinecraftUpdate::setDetails);
|
||||
}
|
||||
if (m_currentTask == m_tasks.size()) {
|
||||
emitSucceeded();
|
||||
return;
|
||||
}
|
||||
auto task = m_tasks[m_currentTask];
|
||||
// if the task is already finished by the time we look at it, skip it
|
||||
if (task->isFinished()) {
|
||||
qCritical() << "MinecraftUpdate: Skipping finished subtask" << m_currentTask << ":" << task.get();
|
||||
next();
|
||||
}
|
||||
connect(task.get(), &Task::succeeded, this, &MinecraftUpdate::subtaskSucceeded);
|
||||
connect(task.get(), &Task::failed, this, &MinecraftUpdate::subtaskFailed);
|
||||
connect(task.get(), &Task::aborted, this, &Task::abort);
|
||||
connect(task.get(), &Task::progress, this, &MinecraftUpdate::progress);
|
||||
connect(task.get(), &Task::stepProgress, this, &MinecraftUpdate::propagateStepProgress);
|
||||
connect(task.get(), &Task::status, this, &MinecraftUpdate::setStatus);
|
||||
connect(task.get(), &Task::details, this, &MinecraftUpdate::setDetails);
|
||||
// if the task is already running, do not start it again
|
||||
if (!task->isRunning()) {
|
||||
task->start();
|
||||
}
|
||||
}
|
||||
|
||||
void MinecraftUpdate::subtaskSucceeded()
|
||||
{
|
||||
if (isFinished()) {
|
||||
qCritical() << "MinecraftUpdate: Subtask" << sender() << "succeeded, but work was already done!";
|
||||
return;
|
||||
}
|
||||
auto senderTask = QObject::sender();
|
||||
auto currentTask = m_tasks[m_currentTask].get();
|
||||
if (senderTask != currentTask) {
|
||||
qDebug() << "MinecraftUpdate: Subtask" << sender() << "succeeded out of order.";
|
||||
return;
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
void MinecraftUpdate::subtaskFailed(QString error)
|
||||
{
|
||||
if (isFinished()) {
|
||||
qCritical() << "MinecraftUpdate: Subtask" << sender() << "failed, but work was already done!";
|
||||
return;
|
||||
}
|
||||
auto senderTask = QObject::sender();
|
||||
auto currentTask = m_tasks[m_currentTask].get();
|
||||
if (senderTask != currentTask) {
|
||||
qDebug() << "MinecraftUpdate: Subtask" << sender() << "failed out of order.";
|
||||
m_failed_out_of_order = true;
|
||||
m_fail_reason = error;
|
||||
return;
|
||||
}
|
||||
emitFailed(error);
|
||||
}
|
||||
|
||||
bool MinecraftUpdate::abort()
|
||||
{
|
||||
if (!m_abort) {
|
||||
m_abort = true;
|
||||
auto task = m_tasks[m_currentTask];
|
||||
if (task->canAbort()) {
|
||||
return task->abort();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MinecraftUpdate::canAbort() const
|
||||
{
|
||||
return true;
|
||||
SequentialTask::executeTask();
|
||||
}
|
||||
|
@ -15,43 +15,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
#include "tasks/SequentialTask.h"
|
||||
|
||||
#include <quazip/quazip.h>
|
||||
#include "minecraft/VersionFilterData.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "tasks/Task.h"
|
||||
|
||||
class MinecraftVersion;
|
||||
class MinecraftInstance;
|
||||
|
||||
// FIXME: This looks very similar to a SequentialTask. Maybe we can reduce code duplications? :^)
|
||||
|
||||
class MinecraftUpdate : public Task {
|
||||
// this needs to be a task because components->reload does stuff that may block
|
||||
class MinecraftUpdate : public SequentialTask {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MinecraftUpdate(MinecraftInstance* inst, QObject* parent = 0);
|
||||
virtual ~MinecraftUpdate() {};
|
||||
virtual ~MinecraftUpdate() = default;
|
||||
|
||||
void executeTask() override;
|
||||
bool canAbort() const override;
|
||||
|
||||
private slots:
|
||||
bool abort() override;
|
||||
void subtaskSucceeded();
|
||||
void subtaskFailed(QString error);
|
||||
|
||||
private:
|
||||
void next();
|
||||
|
||||
private:
|
||||
MinecraftInstance* m_inst = nullptr;
|
||||
QList<Task::Ptr> m_tasks;
|
||||
QString m_preFailure;
|
||||
int m_currentTask = -1;
|
||||
bool m_abort = false;
|
||||
bool m_failed_out_of_order = false;
|
||||
QString m_fail_reason;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user