diff --git a/launcher/launch/TaskStepWrapper.cpp b/launcher/launch/TaskStepWrapper.cpp index db9e8fad2..acf790a8f 100644 --- a/launcher/launch/TaskStepWrapper.cpp +++ b/launcher/launch/TaskStepWrapper.cpp @@ -23,10 +23,7 @@ void TaskStepWrapper::executeTask() return; } connect(m_task.get(), &Task::finished, this, &TaskStepWrapper::updateFinished); - connect(m_task.get(), &Task::progress, this, &TaskStepWrapper::setProgress); - connect(m_task.get(), &Task::stepProgress, this, &TaskStepWrapper::propagateStepProgress); - connect(m_task.get(), &Task::status, this, &TaskStepWrapper::setStatus); - connect(m_task.get(), &Task::details, this, &TaskStepWrapper::setDetails); + propagateFromOther(m_task.get()); emit progressReportingRequest(); } @@ -59,9 +56,7 @@ bool TaskStepWrapper::canAbort() const bool TaskStepWrapper::abort() { if (m_task && m_task->canAbort()) { - auto status = m_task->abort(); - emitFailed("Aborted."); - return status; + return m_task->abort(); } return Task::abort(); } diff --git a/launcher/minecraft/ComponentUpdateTask.cpp b/launcher/minecraft/ComponentUpdateTask.cpp index bdfdcfbcc..d392ddb7e 100644 --- a/launcher/minecraft/ComponentUpdateTask.cpp +++ b/launcher/minecraft/ComponentUpdateTask.cpp @@ -38,6 +38,9 @@ * If the component list changes, start over. */ +/* + * TODO: This task launches multiple other tasks. As such it should be converted to a ConcurrentTask + */ ComponentUpdateTask::ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile* list) : Task() { d.reset(new ComponentUpdateTaskData); @@ -48,9 +51,33 @@ ComponentUpdateTask::ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfi ComponentUpdateTask::~ComponentUpdateTask() {} +bool ComponentUpdateTask::canAbort() const +{ + for (const auto& status : d->remoteLoadStatusList) { + if (status.task && !status.task->canAbort()) { + return false; + } + } + + return true; +} + +bool ComponentUpdateTask::abort() +{ + bool aborted = true; + for (const auto& status : d->remoteLoadStatusList) { + if (status.task && !status.task->abort()) { + aborted = false; + } + } + + return aborted; +} + void ComponentUpdateTask::executeTask() { qCDebug(instanceProfileResolveC) << "Loading components"; + setStatus(tr("Loading components")); loadComponents(); } @@ -196,12 +223,13 @@ void ComponentUpdateTask::loadComponents() componentIndex++; } d->remoteTasksInProgress = taskIndex; + m_progressTotal = taskIndex; switch (result) { case LoadResult::LoadedLocal: { // Everything got loaded. Advance to dependency resolution. performUpdateActions(); resolveDependencies(d->mode == Mode::Launch || d->netmode == Net::Mode::Offline); - break; + return; } case LoadResult::RequiresRemote: { // we wait for signals. @@ -209,9 +237,11 @@ void ComponentUpdateTask::loadComponents() } case LoadResult::Failed: { emitFailed(tr("Some component metadata load tasks failed.")); - break; + return; } } + + setDetails(tr("Downloading metadata for %1 components").arg(taskIndex)); } namespace { @@ -754,6 +784,7 @@ void ComponentUpdateTask::remoteLoadFailed(size_t taskIndex, const QString& msg) void ComponentUpdateTask::checkIfAllFinished() { + setProgress(m_progress + 1, m_progressTotal); if (d->remoteTasksInProgress) { // not yet... return; diff --git a/launcher/minecraft/ComponentUpdateTask.h b/launcher/minecraft/ComponentUpdateTask.h index 64c55877b..c4c3fd3cc 100644 --- a/launcher/minecraft/ComponentUpdateTask.h +++ b/launcher/minecraft/ComponentUpdateTask.h @@ -17,6 +17,9 @@ class ComponentUpdateTask : public Task { explicit ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile* list); virtual ~ComponentUpdateTask(); + bool canAbort() const override; + bool abort() override; + protected: void executeTask(); diff --git a/launcher/minecraft/MinecraftLoadAndCheck.cpp b/launcher/minecraft/MinecraftLoadAndCheck.cpp index 149e7cf19..198076cc4 100644 --- a/launcher/minecraft/MinecraftLoadAndCheck.cpp +++ b/launcher/minecraft/MinecraftLoadAndCheck.cpp @@ -21,10 +21,7 @@ void MinecraftLoadAndCheck::executeTask() connect(m_task.get(), &Task::succeeded, this, &MinecraftLoadAndCheck::emitSucceeded); connect(m_task.get(), &Task::failed, this, &MinecraftLoadAndCheck::emitFailed); connect(m_task.get(), &Task::aborted, this, [this] { emitFailed(tr("Aborted")); }); - connect(m_task.get(), &Task::progress, this, &MinecraftLoadAndCheck::setProgress); - connect(m_task.get(), &Task::stepProgress, this, &MinecraftLoadAndCheck::propagateStepProgress); - connect(m_task.get(), &Task::status, this, &MinecraftLoadAndCheck::setStatus); - connect(m_task.get(), &Task::details, this, &MinecraftLoadAndCheck::setDetails); + propagateFromOther(m_task.get()); } bool MinecraftLoadAndCheck::canAbort() const @@ -38,9 +35,7 @@ bool MinecraftLoadAndCheck::canAbort() const bool MinecraftLoadAndCheck::abort() { if (m_task && m_task->canAbort()) { - auto status = m_task->abort(); - emitFailed("Aborted."); - return status; + return m_task->abort(); } return Task::abort(); } diff --git a/launcher/tasks/Task.cpp b/launcher/tasks/Task.cpp index fe5d84bb9..b01b2491c 100644 --- a/launcher/tasks/Task.cpp +++ b/launcher/tasks/Task.cpp @@ -194,6 +194,22 @@ QString Task::failReason() const return m_failReason; } +void Task::propagateFromOther(Task* other) +{ + Q_ASSERT(other); + connect(other, &Task::status, this, &Task::setStatus); + connect(other, &Task::details, this, &Task::setDetails); + connect(other, &Task::progress, this, &Task::setProgress); + connect(other, &Task::stepProgress, this, &Task::propagateStepProgress); + + setStatus(other->getStatus()); + setDetails(other->getDetails()); + setProgress(other->getProgress(), other->getTotalProgress()); + for (const auto& progress : other->getStepProgress()) { + propagateStepProgress(*progress); + } +} + void Task::logWarning(const QString& line) { qWarning() << line; diff --git a/launcher/tasks/Task.h b/launcher/tasks/Task.h index 43e71c8ab..6e7645338 100644 --- a/launcher/tasks/Task.h +++ b/launcher/tasks/Task.h @@ -127,6 +127,9 @@ class Task : public QObject, public QRunnable { QUuid getUid() { return m_uid; } + // Copies the other task's status, details, progress, and step progress to this task; and sets up connections for future propagation + void propagateFromOther(Task* other); + protected: void logWarning(const QString& line);