Skip to content

Commit

Permalink
refactor MinecraftUpdate Task
Browse files Browse the repository at this point in the history
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
  • Loading branch information
Trial97 committed Jul 10, 2024
1 parent 5f345ce commit b989c5a
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 144 deletions.
125 changes: 9 additions & 116 deletions launcher/minecraft/MinecraftUpdate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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));
}

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;
addTask(makeShared<AssetUpdateTask>(m_inst));
}
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();
}
32 changes: 4 additions & 28 deletions launcher/minecraft/MinecraftUpdate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

0 comments on commit b989c5a

Please sign in to comment.