diff options
author | TheKodeToad <TheKodeToad@proton.me> | 2023-06-14 20:05:02 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-14 20:05:02 +0100 |
commit | 3526d00a2330aad7d01f345816505c4d1cd5b096 (patch) | |
tree | 31b34c829f21ef6f49bc3dda6bd1fc6b55ac7029 /launcher/tasks | |
parent | 79ce7eb1fc9351e689e7106e3dc3a641d9614c9a (diff) | |
parent | a4502f44c291fad2174e84bf883cdb754aa08e28 (diff) | |
download | PrismLauncher-3526d00a2330aad7d01f345816505c4d1cd5b096.tar.gz PrismLauncher-3526d00a2330aad7d01f345816505c4d1cd5b096.tar.bz2 PrismLauncher-3526d00a2330aad7d01f345816505c4d1cd5b096.zip |
Merge branch 'develop' into feat/dont-hide-settings
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
Diffstat (limited to 'launcher/tasks')
-rw-r--r-- | launcher/tasks/ConcurrentTask.cpp | 195 | ||||
-rw-r--r-- | launcher/tasks/ConcurrentTask.h | 70 | ||||
-rw-r--r-- | launcher/tasks/MultipleOptionsTask.cpp | 34 | ||||
-rw-r--r-- | launcher/tasks/MultipleOptionsTask.h | 34 | ||||
-rw-r--r-- | launcher/tasks/SequentialTask.cpp | 35 | ||||
-rw-r--r-- | launcher/tasks/SequentialTask.h | 35 | ||||
-rw-r--r-- | launcher/tasks/Task.cpp | 52 | ||||
-rw-r--r-- | launcher/tasks/Task.h | 66 |
8 files changed, 456 insertions, 65 deletions
diff --git a/launcher/tasks/ConcurrentTask.cpp b/launcher/tasks/ConcurrentTask.cpp index 3cc37b2a..9aada5e6 100644 --- a/launcher/tasks/ConcurrentTask.cpp +++ b/launcher/tasks/ConcurrentTask.cpp @@ -1,11 +1,49 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> + * Copyright (c) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "ConcurrentTask.h" -#include <QDebug> #include <QCoreApplication> +#include <QDebug> +#include "tasks/Task.h" ConcurrentTask::ConcurrentTask(QObject* parent, QString task_name, int max_concurrent) : Task(parent), m_name(task_name), m_total_max_size(max_concurrent) -{ setObjectName(task_name); } +{ + setObjectName(task_name); +} ConcurrentTask::~ConcurrentTask() { @@ -15,14 +53,9 @@ ConcurrentTask::~ConcurrentTask() } } -auto ConcurrentTask::getStepProgress() const -> qint64 +auto ConcurrentTask::getStepProgress() const -> TaskStepProgressList { - return m_stepProgress; -} - -auto ConcurrentTask::getStepTotalProgress() const -> qint64 -{ - return m_stepTotalProgress; + return m_task_progress.values(); } void ConcurrentTask::addTask(Task::Ptr task) @@ -32,11 +65,9 @@ void ConcurrentTask::addTask(Task::Ptr task) void ConcurrentTask::executeTask() { - // Start the least amount of tasks needed, but at least one - int num_starts = qMax(1, qMin(m_total_max_size, m_queue.size())); - for (int i = 0; i < num_starts; i++) { - QMetaObject::invokeMethod(this, &ConcurrentTask::startNext, Qt::QueuedConnection); - } + // Start one task, startNext handles starting the up to the m_total_max_size + // while tracking the number currently being done + QMetaObject::invokeMethod(this, &ConcurrentTask::startNext, Qt::QueuedConnection); } bool ConcurrentTask::abort() @@ -97,25 +128,28 @@ void ConcurrentTask::startNext() Task::Ptr next = m_queue.dequeue(); - connect(next.get(), &Task::succeeded, this, [this, next] { subTaskSucceeded(next); }); + connect(next.get(), &Task::succeeded, this, [this, next]() { subTaskSucceeded(next); }); connect(next.get(), &Task::failed, this, [this, next](QString msg) { subTaskFailed(next, msg); }); - connect(next.get(), &Task::status, this, &ConcurrentTask::subTaskStatus); - connect(next.get(), &Task::stepStatus, this, &ConcurrentTask::subTaskStatus); + connect(next.get(), &Task::status, this, [this, next](QString msg) { subTaskStatus(next, msg); }); + connect(next.get(), &Task::details, this, [this, next](QString msg) { subTaskDetails(next, msg); }); + connect(next.get(), &Task::stepProgress, this, [this, next](TaskStepProgress const& tp) { subTaskStepProgress(next, tp); }); - connect(next.get(), &Task::progress, this, &ConcurrentTask::subTaskProgress); + connect(next.get(), &Task::progress, this, [this, next](qint64 current, qint64 total) { subTaskProgress(next, current, total); }); m_doing.insert(next.get(), next); + qsizetype num_starts = qMin(m_queue.size(), m_total_max_size - m_doing.size()); + auto task_progress = std::make_shared<TaskStepProgress>(next->getUid()); + m_task_progress.insert(next->getUid(), task_progress); - setStepStatus(next->isMultiStep() ? next->getStepStatus() : next->getStatus()); updateState(); + updateStepProgress(*task_progress.get(), Operation::ADDED); QCoreApplication::processEvents(); QMetaObject::invokeMethod(next.get(), &Task::start, Qt::QueuedConnection); // Allow going up the number of concurrent tasks in case of tasks being added in the middle of a running task. - int num_starts = qMin(m_queue.size(), m_total_max_size - m_doing.size()); for (int i = 0; i < num_starts; i++) QMetaObject::invokeMethod(this, &ConcurrentTask::startNext, Qt::QueuedConnection); } @@ -123,12 +157,17 @@ void ConcurrentTask::startNext() void ConcurrentTask::subTaskSucceeded(Task::Ptr task) { m_done.insert(task.get(), task); + m_succeeded.insert(task.get(), task); + m_doing.remove(task.get()); + auto task_progress = m_task_progress.value(task->getUid()); + task_progress->state = TaskStepState::Succeeded; disconnect(task.get(), 0, this, 0); + emit stepProgress(*task_progress); updateState(); - + updateStepProgress(*task_progress, Operation::REMOVED); startNext(); } @@ -139,27 +178,123 @@ void ConcurrentTask::subTaskFailed(Task::Ptr task, const QString& msg) m_doing.remove(task.get()); + auto task_progress = m_task_progress.value(task->getUid()); + task_progress->state = TaskStepState::Failed; + disconnect(task.get(), 0, this, 0); + emit stepProgress(*task_progress); updateState(); - + updateStepProgress(*task_progress, Operation::REMOVED); startNext(); } -void ConcurrentTask::subTaskStatus(const QString& msg) +void ConcurrentTask::subTaskStatus(Task::Ptr task, const QString& msg) +{ + auto task_progress = m_task_progress.value(task->getUid()); + task_progress->status = msg; + task_progress->state = TaskStepState::Running; + + emit stepProgress(*task_progress); + + if (totalSize() == 1) { + setStatus(msg); + } +} + +void ConcurrentTask::subTaskDetails(Task::Ptr task, const QString& msg) { - setStepStatus(msg); + auto task_progress = m_task_progress.value(task->getUid()); + task_progress->details = msg; + task_progress->state = TaskStepState::Running; + + emit stepProgress(*task_progress); + + if (totalSize() == 1) { + setDetails(msg); + } } -void ConcurrentTask::subTaskProgress(qint64 current, qint64 total) +void ConcurrentTask::subTaskProgress(Task::Ptr task, qint64 current, qint64 total) { - m_stepProgress = current; - m_stepTotalProgress = total; + auto task_progress = m_task_progress.value(task->getUid()); + + task_progress->update(current, total); + + emit stepProgress(*task_progress); + updateStepProgress(*task_progress, Operation::CHANGED); + updateState(); + + if (totalSize() == 1) { + setProgress(task_progress->current, task_progress->total); + } +} + +void ConcurrentTask::subTaskStepProgress(Task::Ptr task, TaskStepProgress const& task_progress) +{ + Operation op = Operation::ADDED; + + if (!m_task_progress.contains(task_progress.uid)) { + m_task_progress.insert(task_progress.uid, std::make_shared<TaskStepProgress>(task_progress)); + op = Operation::ADDED; + emit stepProgress(task_progress); + updateStepProgress(task_progress, op); + } else { + auto tp = m_task_progress.value(task_progress.uid); + + tp->old_current = tp->current; + tp->old_total = tp->total; + + tp->current = task_progress.current; + tp->total = task_progress.total; + tp->status = task_progress.status; + tp->details = task_progress.details; + + op = Operation::CHANGED; + emit stepProgress(*tp.get()); + updateStepProgress(*tp.get(), op); + } + +} + +void ConcurrentTask::updateStepProgress(TaskStepProgress const& changed_progress, Operation op) +{ + + switch (op) { + case Operation::ADDED: + m_stepProgress += changed_progress.current; + m_stepTotalProgress += changed_progress.total; + break; + case Operation::REMOVED: + m_stepProgress -= changed_progress.current; + m_stepTotalProgress -= changed_progress.total; + break; + case Operation::CHANGED: + m_stepProgress -= changed_progress.old_current; + m_stepTotalProgress -= changed_progress.old_total; + m_stepProgress += changed_progress.current; + m_stepTotalProgress += changed_progress.total; + break; + } + } void ConcurrentTask::updateState() { - setProgress(m_done.count(), totalSize()); - setStatus(tr("Executing %1 task(s) (%2 out of %3 are done)") - .arg(QString::number(m_doing.count()), QString::number(m_done.count()), QString::number(totalSize()))); + if (totalSize() > 1) { + setProgress(m_done.count(), totalSize()); + setStatus(tr("Executing %1 task(s) (%2 out of %3 are done)") + .arg(QString::number(m_doing.count()), QString::number(m_done.count()), QString::number(totalSize()))); + } else { + setProgress(m_stepProgress, m_stepTotalProgress); + QString status = tr("Please wait..."); + if (m_queue.size() > 0) { + status = tr("Waiting for a task to start..."); + } else if (m_doing.size() > 0) { + status = tr("Executing 1 task:"); + } else if (m_done.size() > 0) { + status = tr("Task finished."); + } + setStatus(status); + } } diff --git a/launcher/tasks/ConcurrentTask.h b/launcher/tasks/ConcurrentTask.h index d074d2e2..6325fc9e 100644 --- a/launcher/tasks/ConcurrentTask.h +++ b/launcher/tasks/ConcurrentTask.h @@ -1,13 +1,51 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> + * Copyright (c) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #pragma once +#include <QHash> #include <QQueue> #include <QSet> +#include <QUuid> +#include <memory> #include "tasks/Task.h" class ConcurrentTask : public Task { Q_OBJECT -public: + public: using Ptr = shared_qobject_ptr<ConcurrentTask>; explicit ConcurrentTask(QObject* parent = nullptr, QString task_name = "", int max_concurrent = 6); @@ -15,15 +53,12 @@ public: bool canAbort() const override { return true; } - inline auto isMultiStep() const -> bool override { return m_queue.size() > 1; }; - auto getStepProgress() const -> qint64 override; - auto getStepTotalProgress() const -> qint64 override; - - inline auto getStepStatus() const -> QString override { return m_step_status; } + inline auto isMultiStep() const -> bool override { return totalSize() > 1; }; + auto getStepProgress() const -> TaskStepProgressList override; void addTask(Task::Ptr task); -public slots: + public slots: bool abort() override; /** Resets the internal state of the task. @@ -31,26 +66,28 @@ public slots: */ void clear(); -protected -slots: + protected slots: void executeTask() override; virtual void startNext(); void subTaskSucceeded(Task::Ptr); - void subTaskFailed(Task::Ptr, const QString &msg); - void subTaskStatus(const QString &msg); - void subTaskProgress(qint64 current, qint64 total); + void subTaskFailed(Task::Ptr, const QString& msg); + void subTaskStatus(Task::Ptr task, const QString& msg); + void subTaskDetails(Task::Ptr task, const QString& msg); + void subTaskProgress(Task::Ptr task, qint64 current, qint64 total); + void subTaskStepProgress(Task::Ptr task, TaskStepProgress const& task_step_progress); -protected: + protected: // NOTE: This is not thread-safe. [[nodiscard]] unsigned int totalSize() const { return m_queue.size() + m_doing.size() + m_done.size(); } - void setStepStatus(QString status) { m_step_status = status; emit stepStatus(status); }; + enum class Operation { ADDED, REMOVED, CHANGED }; + void updateStepProgress(TaskStepProgress const& changed_progress, Operation); virtual void updateState(); -protected: + protected: QString m_name; QString m_step_status; @@ -59,6 +96,9 @@ protected: QHash<Task*, Task::Ptr> m_doing; QHash<Task*, Task::Ptr> m_done; QHash<Task*, Task::Ptr> m_failed; + QHash<Task*, Task::Ptr> m_succeeded; + + QHash<QUuid, std::shared_ptr<TaskStepProgress>> m_task_progress; int m_total_max_size; diff --git a/launcher/tasks/MultipleOptionsTask.cpp b/launcher/tasks/MultipleOptionsTask.cpp index 034499df..89187a26 100644 --- a/launcher/tasks/MultipleOptionsTask.cpp +++ b/launcher/tasks/MultipleOptionsTask.cpp @@ -1,3 +1,37 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "MultipleOptionsTask.h" #include <QDebug> diff --git a/launcher/tasks/MultipleOptionsTask.h b/launcher/tasks/MultipleOptionsTask.h index db7d4d9a..a344343e 100644 --- a/launcher/tasks/MultipleOptionsTask.h +++ b/launcher/tasks/MultipleOptionsTask.h @@ -1,3 +1,37 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #pragma once #include "SequentialTask.h" diff --git a/launcher/tasks/SequentialTask.cpp b/launcher/tasks/SequentialTask.cpp index b2f86328..abf7536b 100644 --- a/launcher/tasks/SequentialTask.cpp +++ b/launcher/tasks/SequentialTask.cpp @@ -1,3 +1,38 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> + * Copyright (c) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "SequentialTask.h" #include <QDebug> diff --git a/launcher/tasks/SequentialTask.h b/launcher/tasks/SequentialTask.h index 5eace96e..cec3b2be 100644 --- a/launcher/tasks/SequentialTask.h +++ b/launcher/tasks/SequentialTask.h @@ -1,3 +1,38 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> + * Copyright (c) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #pragma once #include "ConcurrentTask.h" diff --git a/launcher/tasks/Task.cpp b/launcher/tasks/Task.cpp index 9ea1bb26..29c55cd4 100644 --- a/launcher/tasks/Task.cpp +++ b/launcher/tasks/Task.cpp @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> + * Copyright (c) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,8 +38,11 @@ #include <QDebug> +Q_LOGGING_CATEGORY(taskLogC, "launcher.task") + Task::Task(QObject *parent, bool show_debug) : QObject(parent), m_show_debug(show_debug) { + m_uid = QUuid::createUuid(); setAutoDelete(false); } @@ -51,11 +55,23 @@ void Task::setStatus(const QString &new_status) } } +void Task::setDetails(const QString& new_details) +{ + if (m_details != new_details) + { + m_details = new_details; + emit details(m_details); + } +} + void Task::setProgress(qint64 current, qint64 total) { - m_progress = current; - m_progressTotal = total; - emit progress(m_progress, m_progressTotal); + if ((m_progress != current) || (m_progressTotal != total)) { + m_progress = current; + m_progressTotal = total; + + emit progress(m_progress, m_progressTotal); + } } void Task::start() @@ -65,35 +81,35 @@ void Task::start() case State::Inactive: { if (m_show_debug) - qDebug() << "Task" << describe() << "starting for the first time"; + qCDebug(taskLogC) << "Task" << describe() << "starting for the first time"; break; } case State::AbortedByUser: { if (m_show_debug) - qDebug() << "Task" << describe() << "restarting for after being aborted by user"; + qCDebug(taskLogC) << "Task" << describe() << "restarting for after being aborted by user"; break; } case State::Failed: { if (m_show_debug) - qDebug() << "Task" << describe() << "restarting for after failing at first"; + qCDebug(taskLogC) << "Task" << describe() << "restarting for after failing at first"; break; } case State::Succeeded: { if (m_show_debug) - qDebug() << "Task" << describe() << "restarting for after succeeding at first"; + qCDebug(taskLogC) << "Task" << describe() << "restarting for after succeeding at first"; break; } case State::Running: { if (m_show_debug) - qWarning() << "The launcher tried to start task" << describe() << "while it was already running!"; + qCWarning(taskLogC) << "The launcher tried to start task" << describe() << "while it was already running!"; return; } } - // NOTE: only fall thorugh to here in end states + // NOTE: only fall through to here in end states m_state = State::Running; emit started(); executeTask(); @@ -104,12 +120,12 @@ void Task::emitFailed(QString reason) // Don't fail twice. if (!isRunning()) { - qCritical() << "Task" << describe() << "failed while not running!!!!: " << reason; + qCCritical(taskLogC) << "Task" << describe() << "failed while not running!!!!: " << reason; return; } m_state = State::Failed; m_failReason = reason; - qCritical() << "Task" << describe() << "failed: " << reason; + qCCritical(taskLogC) << "Task" << describe() << "failed: " << reason; emit failed(reason); emit finished(); } @@ -119,13 +135,13 @@ void Task::emitAborted() // Don't abort twice. if (!isRunning()) { - qCritical() << "Task" << describe() << "aborted while not running!!!!"; + qCCritical(taskLogC) << "Task" << describe() << "aborted while not running!!!!"; return; } m_state = State::AbortedByUser; m_failReason = "Aborted."; if (m_show_debug) - qDebug() << "Task" << describe() << "aborted."; + qCDebug(taskLogC) << "Task" << describe() << "aborted."; emit aborted(); emit finished(); } @@ -135,16 +151,21 @@ void Task::emitSucceeded() // Don't succeed twice. if (!isRunning()) { - qCritical() << "Task" << describe() << "succeeded while not running!!!!"; + qCCritical(taskLogC) << "Task" << describe() << "succeeded while not running!!!!"; return; } m_state = State::Succeeded; if (m_show_debug) - qDebug() << "Task" << describe() << "succeeded"; + qCDebug(taskLogC) << "Task" << describe() << "succeeded"; emit succeeded(); emit finished(); } +void Task::propogateStepProgress(TaskStepProgress const& task_progress) +{ + emit stepProgress(task_progress); +} + QString Task::describe() { QString outStr; @@ -159,6 +180,7 @@ QString Task::describe() { out << name; } + out << " ID: " << m_uid.toString(QUuid::WithoutBraces); out << QChar(')'); out.flush(); return outStr; diff --git a/launcher/tasks/Task.h b/launcher/tasks/Task.h index 3d607dca..6d8bbbb4 100644 --- a/launcher/tasks/Task.h +++ b/launcher/tasks/Task.h @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * PrismLauncher - Minecraft Launcher * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> + * Copyright (c) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,9 +37,54 @@ #pragma once #include <QRunnable> +#include <QUuid> +#include <QLoggingCategory> #include "QObjectPtr.h" +Q_DECLARE_LOGGING_CATEGORY(taskLogC) + +enum class TaskStepState { + Waiting, + Running, + Failed, + Succeeded +}; + +Q_DECLARE_METATYPE(TaskStepState) + +struct TaskStepProgress { + QUuid uid; + qint64 current = 0; + qint64 total = -1; + + qint64 old_current = 0; + qint64 old_total = -1; + + QString status = ""; + QString details = ""; + TaskStepState state = TaskStepState::Waiting; + TaskStepProgress() { + this->uid = QUuid::createUuid(); + } + TaskStepProgress(QUuid uid) { + this->uid = uid; + } + bool isDone() const { return (state == TaskStepState::Failed) || (state == TaskStepState::Succeeded); } + void update(qint64 current, qint64 total) { + this->old_current = this->current; + this->old_total = this->total; + + this->current = current; + this->total = total; + this->state = TaskStepState::Running; + } +}; + +Q_DECLARE_METATYPE(TaskStepProgress) + +typedef QList<std::shared_ptr<TaskStepProgress>> TaskStepProgressList; + class Task : public QObject, public QRunnable { Q_OBJECT public: @@ -73,12 +119,15 @@ class Task : public QObject, public QRunnable { auto getState() const -> State { return m_state; } QString getStatus() { return m_status; } - virtual auto getStepStatus() const -> QString { return m_status; } + QString getDetails() { return m_details; } qint64 getProgress() { return m_progress; } qint64 getTotalProgress() { return m_progressTotal; } - virtual auto getStepProgress() const -> qint64 { return 0; } - virtual auto getStepTotalProgress() const -> qint64 { return 100; } + virtual auto getStepProgress() const -> TaskStepProgressList { return {}; } + + + + QUuid getUid() { return m_uid; } protected: void logWarning(const QString& line); @@ -94,7 +143,8 @@ class Task : public QObject, public QRunnable { void aborted(); void failed(QString reason); void status(QString status); - void stepStatus(QString status); + void details(QString details); + void stepProgress(TaskStepProgress const& task_progress); /** Emitted when the canAbort() status has changed. */ @@ -117,8 +167,11 @@ class Task : public QObject, public QRunnable { virtual void emitAborted(); virtual void emitFailed(QString reason = ""); + virtual void propogateStepProgress(TaskStepProgress const& task_progress); + public slots: void setStatus(const QString& status); + void setDetails(const QString& details); void setProgress(qint64 current, qint64 total); protected: @@ -126,6 +179,7 @@ class Task : public QObject, public QRunnable { QStringList m_Warnings; QString m_failReason = ""; QString m_status; + QString m_details; int m_progress = 0; int m_progressTotal = 100; @@ -135,4 +189,6 @@ class Task : public QObject, public QRunnable { private: // Change using setAbortStatus bool m_can_abort = false; + QUuid m_uid; + }; |