aboutsummaryrefslogtreecommitdiff
path: root/launcher/net/NetJob.cpp
diff options
context:
space:
mode:
authorflow <thiagodonato300@gmail.com>2022-04-21 22:12:14 -0300
committerflow <thiagodonato300@gmail.com>2022-05-12 18:11:49 -0300
commit8c8eabf7ac1920b47792b26790f3646cb6693ec0 (patch)
tree4cb5fca254ad911b52f7aaf4b5af6009ea6f6329 /launcher/net/NetJob.cpp
parent649b8ac7c6e12fcf91d204f908e027d3bfbb6a2a (diff)
downloadPrismLauncher-8c8eabf7ac1920b47792b26790f3646cb6693ec0.tar.gz
PrismLauncher-8c8eabf7ac1920b47792b26790f3646cb6693ec0.tar.bz2
PrismLauncher-8c8eabf7ac1920b47792b26790f3646cb6693ec0.zip
refactor: organize a little more the code in launcher/net/
This also reduces some code duplication by using some Task logic in NetAction.
Diffstat (limited to 'launcher/net/NetJob.cpp')
-rw-r--r--launcher/net/NetJob.cpp270
1 files changed, 140 insertions, 130 deletions
diff --git a/launcher/net/NetJob.cpp b/launcher/net/NetJob.cpp
index 9bad89ed..d08d6c4d 100644
--- a/launcher/net/NetJob.cpp
+++ b/launcher/net/NetJob.cpp
@@ -1,79 +1,170 @@
-/* Copyright 2013-2021 MultiMC Contributors
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * PolyMC - Minecraft Launcher
*
- * 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
+ * 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.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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.
*
- * 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.
+ * 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 "NetJob.h"
#include "Download.h"
-#include <QDebug>
+auto NetJob::addNetAction(NetAction::Ptr action) -> bool
+{
+ action->m_index_within_job = m_downloads.size();
+ m_downloads.append(action);
+ part_info pi;
+ m_parts_progress.append(pi);
+
+ partProgress(m_parts_progress.count() - 1, action->getProgress(), action->getTotalProgress());
+
+ if (action->isRunning()) {
+ connect(action.get(), &NetAction::succeeded, this, &NetJob::partSucceeded);
+ connect(action.get(), &NetAction::failed, this, &NetJob::partFailed);
+ connect(action.get(), &NetAction::netActionProgress, this, &NetJob::partProgress);
+ } else {
+ m_todo.append(m_parts_progress.size() - 1);
+ }
+
+ return true;
+}
+
+auto NetJob::canAbort() const -> bool
+{
+ bool canFullyAbort = true;
+
+ // can abort the downloads on the queue?
+ for (auto index : m_todo) {
+ auto part = m_downloads[index];
+ canFullyAbort &= part->canAbort();
+ }
+ // can abort the active downloads?
+ for (auto index : m_doing) {
+ auto part = m_downloads[index];
+ canFullyAbort &= part->canAbort();
+ }
+
+ return canFullyAbort;
+}
+
+void NetJob::executeTask()
+{
+ // hack that delays early failures so they can be caught easier
+ QMetaObject::invokeMethod(this, "startMoreParts", Qt::QueuedConnection);
+}
+
+auto NetJob::getFailedFiles() -> QStringList
+{
+ QStringList failed;
+ for (auto index : m_failed) {
+ failed.push_back(m_downloads[index]->url().toString());
+ }
+ failed.sort();
+ return failed;
+}
+
+auto NetJob::abort() -> bool
+{
+ bool fullyAborted = true;
+
+ // fail all downloads on the queue
+ m_failed.unite(m_todo.toSet());
+ m_todo.clear();
+
+ // abort active downloads
+ auto toKill = m_doing.toList();
+ for (auto index : toKill) {
+ auto part = m_downloads[index];
+ fullyAborted &= part->abort();
+ }
+
+ return fullyAborted;
+}
void NetJob::partSucceeded(int index)
{
// do progress. all slots are 1 in size at least
- auto &slot = parts_progress[index];
+ auto& slot = m_parts_progress[index];
partProgress(index, slot.total_progress, slot.total_progress);
m_doing.remove(index);
m_done.insert(index);
- downloads[index].get()->disconnect(this);
+ m_downloads[index].get()->disconnect(this);
+
startMoreParts();
}
void NetJob::partFailed(int index)
{
m_doing.remove(index);
- auto &slot = parts_progress[index];
- if (slot.failures == 3)
- {
+
+ auto& slot = m_parts_progress[index];
+ // Can try 3 times before failing by definitive
+ if (slot.failures == 3) {
m_failed.insert(index);
- }
- else
- {
+ } else {
slot.failures++;
m_todo.enqueue(index);
}
- downloads[index].get()->disconnect(this);
+
+ m_downloads[index].get()->disconnect(this);
+
startMoreParts();
}
void NetJob::partAborted(int index)
{
m_aborted = true;
+
m_doing.remove(index);
m_failed.insert(index);
- downloads[index].get()->disconnect(this);
+ m_downloads[index].get()->disconnect(this);
+
startMoreParts();
}
void NetJob::partProgress(int index, qint64 bytesReceived, qint64 bytesTotal)
{
- auto &slot = parts_progress[index];
+ auto& slot = m_parts_progress[index];
slot.current_progress = bytesReceived;
slot.total_progress = bytesTotal;
int done = m_done.size();
int doing = m_doing.size();
- int all = parts_progress.size();
+ int all = m_parts_progress.size();
qint64 bytesAll = 0;
qint64 bytesTotalAll = 0;
- for(auto & partIdx: m_doing)
- {
- auto part = parts_progress[partIdx];
+ for (auto& partIdx : m_doing) {
+ auto part = m_parts_progress[partIdx];
// do not count parts with unknown/nonsensical total size
- if(part.total_progress <= 0)
- {
+ if (part.total_progress <= 0) {
continue;
}
bytesAll += part.current_progress;
@@ -85,134 +176,53 @@ void NetJob::partProgress(int index, qint64 bytesReceived, qint64 bytesTotal)
auto current_total = all * 1000;
// HACK: make sure it never jumps backwards.
// FAIL: This breaks if the size is not known (or is it something else?) and jumps to 1000, so if it is 1000 reset it to inprogress
- if(m_current_progress == 1000) {
+ if (m_current_progress == 1000) {
m_current_progress = inprogress;
}
- if(m_current_progress > current)
- {
+ if (m_current_progress > current) {
current = m_current_progress;
}
m_current_progress = current;
setProgress(current, current_total);
}
-void NetJob::executeTask()
-{
- // hack that delays early failures so they can be caught easier
- QMetaObject::invokeMethod(this, "startMoreParts", Qt::QueuedConnection);
-}
-
void NetJob::startMoreParts()
{
- if(!isRunning())
- {
- // this actually makes sense. You can put running downloads into a NetJob and then not start it until much later.
+ if (!isRunning()) {
+ // this actually makes sense. You can put running m_downloads into a NetJob and then not start it until much later.
return;
}
+
// OK. We are actively processing tasks, proceed.
// Check for final conditions if there's nothing in the queue.
- if(!m_todo.size())
- {
- if(!m_doing.size())
- {
- if(!m_failed.size())
- {
+ if (!m_todo.size()) {
+ if (!m_doing.size()) {
+ if (!m_failed.size()) {
emitSucceeded();
- }
- else if(m_aborted)
- {
+ } else if (m_aborted) {
emitAborted();
- }
- else
- {
+ } else {
emitFailed(tr("Job '%1' failed to process:\n%2").arg(objectName()).arg(getFailedFiles().join("\n")));
}
}
return;
}
- // There's work to do, try to start more parts.
- while (m_doing.size() < 6)
- {
- if(!m_todo.size())
+
+ // There's work to do, try to start more parts, to a maximum of 6 concurrent ones.
+ while (m_doing.size() < 6) {
+ if (m_todo.size() == 0)
return;
int doThis = m_todo.dequeue();
m_doing.insert(doThis);
- auto part = downloads[doThis];
- // connect signals :D
- connect(part.get(), SIGNAL(succeeded(int)), SLOT(partSucceeded(int)));
- connect(part.get(), SIGNAL(failed(int)), SLOT(partFailed(int)));
- connect(part.get(), SIGNAL(aborted(int)), SLOT(partAborted(int)));
- connect(part.get(), SIGNAL(netActionProgress(int, qint64, qint64)),
- SLOT(partProgress(int, qint64, qint64)));
- part->start(m_network);
- }
-}
-
-
-QStringList NetJob::getFailedFiles()
-{
- QStringList failed;
- for (auto index: m_failed)
- {
- failed.push_back(downloads[index]->url().toString());
- }
- failed.sort();
- return failed;
-}
-bool NetJob::canAbort() const
-{
- bool canFullyAbort = true;
- // can abort the waiting?
- for(auto index: m_todo)
- {
- auto part = downloads[index];
- canFullyAbort &= part->canAbort();
- }
- // can abort the active?
- for(auto index: m_doing)
- {
- auto part = downloads[index];
- canFullyAbort &= part->canAbort();
- }
- return canFullyAbort;
-}
+ auto part = m_downloads[doThis];
-bool NetJob::abort()
-{
- bool fullyAborted = true;
- // fail all waiting
- m_failed.unite(m_todo.toSet());
- m_todo.clear();
- // abort active
- auto toKill = m_doing.toList();
- for(auto index: toKill)
- {
- auto part = downloads[index];
- fullyAborted &= part->abort();
- }
- return fullyAborted;
-}
+ // connect signals :D
+ connect(part.get(), &NetAction::succeeded, this, &NetJob::partSucceeded);
+ connect(part.get(), &NetAction::failed, this, &NetJob::partFailed);
+ connect(part.get(), &NetAction::aborted, this, &NetJob::partAborted);
+ connect(part.get(), &NetAction::netActionProgress, this, &NetJob::partProgress);
-bool NetJob::addNetAction(NetAction::Ptr action)
-{
- action->m_index_within_job = downloads.size();
- downloads.append(action);
- part_info pi;
- parts_progress.append(pi);
- partProgress(parts_progress.count() - 1, action->currentProgress(), action->totalProgress());
-
- if(action->isRunning())
- {
- connect(action.get(), SIGNAL(succeeded(int)), SLOT(partSucceeded(int)));
- connect(action.get(), SIGNAL(failed(int)), SLOT(partFailed(int)));
- connect(action.get(), SIGNAL(netActionProgress(int, qint64, qint64)), SLOT(partProgress(int, qint64, qint64)));
+ part->startAction(m_network);
}
- else
- {
- m_todo.append(parts_progress.size() - 1);
- }
- return true;
}
-
-NetJob::~NetJob() = default;