Merge branch 'PrismLauncher:develop' into develop

This commit is contained in:
Awqre 2024-11-17 08:19:35 +00:00 committed by GitHub
commit 3c88eccf17
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
69 changed files with 658 additions and 650 deletions

12
flake.lock generated
View File

@ -34,11 +34,11 @@
}, },
"nix-filter": { "nix-filter": {
"locked": { "locked": {
"lastModified": 1710156097, "lastModified": 1730207686,
"narHash": "sha256-1Wvk8UP7PXdf8bCCaEoMnOT1qe5/Duqgj+rL8sRQsSM=", "narHash": "sha256-SCHiL+1f7q9TAnxpasriP6fMarWE5H43t25F5/9e28I=",
"owner": "numtide", "owner": "numtide",
"repo": "nix-filter", "repo": "nix-filter",
"rev": "3342559a24e85fc164b295c3444e8a139924675b", "rev": "776e68c1d014c3adde193a18db9d738458cd2ba4",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -49,11 +49,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1729256560, "lastModified": 1730785428,
"narHash": "sha256-/uilDXvCIEs3C9l73JTACm4quuHUsIHcns1c+cHUJwA=", "narHash": "sha256-Zwl8YgTVJTEum+L+0zVAWvXAGbWAuXHax3KzuejaDyo=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "4c2fcb090b1f3e5b47eaa7bd33913b574a11e0a0", "rev": "4aa36568d413aca0ea84a1684d2d46f55dbabad7",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@ -1871,7 +1871,7 @@ bool Application::handleDataMigration(const QString& currentData,
matcher->add(std::make_shared<SimplePrefixMatcher>("themes/")); matcher->add(std::make_shared<SimplePrefixMatcher>("themes/"));
ProgressDialog diag; ProgressDialog diag;
DataMigrationTask task(nullptr, oldData, currentData, matcher); DataMigrationTask task(oldData, currentData, matcher);
if (diag.execWithTask(&task)) { if (diag.execWithTask(&task)) {
qDebug() << "<> Migration succeeded"; qDebug() << "<> Migration succeeded";
setDoNotMigrate(); setDoNotMigrate();

View File

@ -12,11 +12,8 @@
#include <QtConcurrent> #include <QtConcurrent>
DataMigrationTask::DataMigrationTask(QObject* parent, DataMigrationTask::DataMigrationTask(const QString& sourcePath, const QString& targetPath, const IPathMatcher::Ptr pathMatcher)
const QString& sourcePath, : Task(), m_sourcePath(sourcePath), m_targetPath(targetPath), m_pathMatcher(pathMatcher), m_copy(sourcePath, targetPath)
const QString& targetPath,
const IPathMatcher::Ptr pathMatcher)
: Task(parent), m_sourcePath(sourcePath), m_targetPath(targetPath), m_pathMatcher(pathMatcher), m_copy(sourcePath, targetPath)
{ {
m_copy.matcher(m_pathMatcher.get()).whitelist(true); m_copy.matcher(m_pathMatcher.get()).whitelist(true);
} }

View File

@ -18,7 +18,7 @@
class DataMigrationTask : public Task { class DataMigrationTask : public Task {
Q_OBJECT Q_OBJECT
public: public:
explicit DataMigrationTask(QObject* parent, const QString& sourcePath, const QString& targetPath, IPathMatcher::Ptr pathmatcher); explicit DataMigrationTask(const QString& sourcePath, const QString& targetPath, IPathMatcher::Ptr pathmatcher);
~DataMigrationTask() override = default; ~DataMigrationTask() override = default;
protected: protected:

View File

@ -61,6 +61,6 @@ void InstanceCreationTask::executeTask()
return; return;
} }
} }
if (!m_abort)
emitSucceeded(); emitSucceeded();
} }

View File

@ -69,9 +69,11 @@ bool InstanceImportTask::abort()
if (!canAbort()) if (!canAbort())
return false; return false;
if (task) bool wasAborted = false;
task->abort(); if (m_task)
return Task::abort(); wasAborted = m_task->abort();
Task::abort();
return wasAborted;
} }
void InstanceImportTask::executeTask() void InstanceImportTask::executeTask()
@ -104,7 +106,7 @@ void InstanceImportTask::downloadFromUrl()
connect(filesNetJob.get(), &NetJob::stepProgress, this, &InstanceImportTask::propagateStepProgress); connect(filesNetJob.get(), &NetJob::stepProgress, this, &InstanceImportTask::propagateStepProgress);
connect(filesNetJob.get(), &NetJob::failed, this, &InstanceImportTask::emitFailed); connect(filesNetJob.get(), &NetJob::failed, this, &InstanceImportTask::emitFailed);
connect(filesNetJob.get(), &NetJob::aborted, this, &InstanceImportTask::emitAborted); connect(filesNetJob.get(), &NetJob::aborted, this, &InstanceImportTask::emitAborted);
task.reset(filesNetJob); m_task.reset(filesNetJob);
filesNetJob->start(); filesNetJob->start();
} }
@ -193,7 +195,7 @@ void InstanceImportTask::processZipPack()
stepProgress(*progressStep); stepProgress(*progressStep);
}); });
connect(zipTask.get(), &Task::succeeded, this, &InstanceImportTask::extractFinished); connect(zipTask.get(), &Task::succeeded, this, &InstanceImportTask::extractFinished, Qt::QueuedConnection);
connect(zipTask.get(), &Task::aborted, this, &InstanceImportTask::emitAborted); connect(zipTask.get(), &Task::aborted, this, &InstanceImportTask::emitAborted);
connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) {
progressStep->state = TaskStepState::Failed; progressStep->state = TaskStepState::Failed;
@ -210,12 +212,13 @@ void InstanceImportTask::processZipPack()
progressStep->status = status; progressStep->status = status;
stepProgress(*progressStep); stepProgress(*progressStep);
}); });
task.reset(zipTask); m_task.reset(zipTask);
zipTask->start(); zipTask->start();
} }
void InstanceImportTask::extractFinished() void InstanceImportTask::extractFinished()
{ {
setAbortable(false);
QDir extractDir(m_stagingPath); QDir extractDir(m_stagingPath);
qDebug() << "Fixing permissions for extracted pack files..."; qDebug() << "Fixing permissions for extracted pack files...";
@ -289,8 +292,11 @@ void InstanceImportTask::processFlame()
inst_creation_task->setGroup(m_instGroup); inst_creation_task->setGroup(m_instGroup);
inst_creation_task->setConfirmUpdate(shouldConfirmUpdate()); inst_creation_task->setConfirmUpdate(shouldConfirmUpdate());
connect(inst_creation_task.get(), &Task::succeeded, this, [this, inst_creation_task] { auto weak = inst_creation_task.toWeakRef();
setOverride(inst_creation_task->shouldOverride(), inst_creation_task->originalInstanceID()); connect(inst_creation_task.get(), &Task::succeeded, this, [this, weak] {
if (auto sp = weak.lock()) {
setOverride(sp->shouldOverride(), sp->originalInstanceID());
}
emitSucceeded(); emitSucceeded();
}); });
connect(inst_creation_task.get(), &Task::failed, this, &InstanceImportTask::emitFailed); connect(inst_creation_task.get(), &Task::failed, this, &InstanceImportTask::emitFailed);
@ -299,11 +305,12 @@ void InstanceImportTask::processFlame()
connect(inst_creation_task.get(), &Task::status, this, &InstanceImportTask::setStatus); connect(inst_creation_task.get(), &Task::status, this, &InstanceImportTask::setStatus);
connect(inst_creation_task.get(), &Task::details, this, &InstanceImportTask::setDetails); connect(inst_creation_task.get(), &Task::details, this, &InstanceImportTask::setDetails);
connect(this, &Task::aborted, inst_creation_task.get(), &InstanceCreationTask::abort);
connect(inst_creation_task.get(), &Task::aborted, this, &Task::abort); connect(inst_creation_task.get(), &Task::aborted, this, &Task::abort);
connect(inst_creation_task.get(), &Task::abortStatusChanged, this, &Task::setAbortable); connect(inst_creation_task.get(), &Task::abortStatusChanged, this, &Task::setAbortable);
inst_creation_task->start(); m_task.reset(inst_creation_task);
setAbortable(true);
m_task->start();
} }
void InstanceImportTask::processTechnic() void InstanceImportTask::processTechnic()
@ -350,7 +357,7 @@ void InstanceImportTask::processMultiMC()
void InstanceImportTask::processModrinth() void InstanceImportTask::processModrinth()
{ {
ModrinthCreationTask* inst_creation_task = nullptr; shared_qobject_ptr<ModrinthCreationTask> inst_creation_task = nullptr;
if (!m_extra_info.isEmpty()) { if (!m_extra_info.isEmpty()) {
auto pack_id_it = m_extra_info.constFind("pack_id"); auto pack_id_it = m_extra_info.constFind("pack_id");
Q_ASSERT(pack_id_it != m_extra_info.constEnd()); Q_ASSERT(pack_id_it != m_extra_info.constEnd());
@ -367,7 +374,7 @@ void InstanceImportTask::processModrinth()
original_instance_id = original_instance_id_it.value(); original_instance_id = original_instance_id_it.value();
inst_creation_task = inst_creation_task =
new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id); makeShared<ModrinthCreationTask>(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id);
} else { } else {
QString pack_id; QString pack_id;
if (!m_sourceUrl.isEmpty()) { if (!m_sourceUrl.isEmpty()) {
@ -376,7 +383,7 @@ void InstanceImportTask::processModrinth()
} }
// FIXME: Find a way to get the ID in directly imported ZIPs // FIXME: Find a way to get the ID in directly imported ZIPs
inst_creation_task = new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id); inst_creation_task = makeShared<ModrinthCreationTask>(m_stagingPath, m_globalSettings, m_parent, pack_id);
} }
inst_creation_task->setName(*this); inst_creation_task->setName(*this);
@ -384,20 +391,23 @@ void InstanceImportTask::processModrinth()
inst_creation_task->setGroup(m_instGroup); inst_creation_task->setGroup(m_instGroup);
inst_creation_task->setConfirmUpdate(shouldConfirmUpdate()); inst_creation_task->setConfirmUpdate(shouldConfirmUpdate());
connect(inst_creation_task, &Task::succeeded, this, [this, inst_creation_task] { auto weak = inst_creation_task.toWeakRef();
setOverride(inst_creation_task->shouldOverride(), inst_creation_task->originalInstanceID()); connect(inst_creation_task.get(), &Task::succeeded, this, [this, weak] {
if (auto sp = weak.lock()) {
setOverride(sp->shouldOverride(), sp->originalInstanceID());
}
emitSucceeded(); emitSucceeded();
}); });
connect(inst_creation_task, &Task::failed, this, &InstanceImportTask::emitFailed); connect(inst_creation_task.get(), &Task::failed, this, &InstanceImportTask::emitFailed);
connect(inst_creation_task, &Task::progress, this, &InstanceImportTask::setProgress); connect(inst_creation_task.get(), &Task::progress, this, &InstanceImportTask::setProgress);
connect(inst_creation_task, &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress); connect(inst_creation_task.get(), &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress);
connect(inst_creation_task, &Task::status, this, &InstanceImportTask::setStatus); connect(inst_creation_task.get(), &Task::status, this, &InstanceImportTask::setStatus);
connect(inst_creation_task, &Task::details, this, &InstanceImportTask::setDetails); connect(inst_creation_task.get(), &Task::details, this, &InstanceImportTask::setDetails);
connect(inst_creation_task, &Task::finished, inst_creation_task, &InstanceCreationTask::deleteLater);
connect(this, &Task::aborted, inst_creation_task, &InstanceCreationTask::abort); connect(inst_creation_task.get(), &Task::aborted, this, &Task::abort);
connect(inst_creation_task, &Task::aborted, this, &Task::abort); connect(inst_creation_task.get(), &Task::abortStatusChanged, this, &Task::setAbortable);
connect(inst_creation_task, &Task::abortStatusChanged, this, &Task::setAbortable);
inst_creation_task->start(); m_task.reset(inst_creation_task);
setAbortable(true);
m_task->start();
} }

View File

@ -40,16 +40,13 @@
#include <QUrl> #include <QUrl>
#include "InstanceTask.h" #include "InstanceTask.h"
#include <memory>
#include <optional>
class QuaZip; class QuaZip;
class InstanceImportTask : public InstanceTask { class InstanceImportTask : public InstanceTask {
Q_OBJECT Q_OBJECT
public: public:
explicit InstanceImportTask(const QUrl& sourceUrl, QWidget* parent = nullptr, QMap<QString, QString>&& extra_info = {}); explicit InstanceImportTask(const QUrl& sourceUrl, QWidget* parent = nullptr, QMap<QString, QString>&& extra_info = {});
virtual ~InstanceImportTask() = default;
bool abort() override; bool abort() override;
protected: protected:
@ -70,7 +67,7 @@ class InstanceImportTask : public InstanceTask {
private: /* data */ private: /* data */
QUrl m_sourceUrl; QUrl m_sourceUrl;
QString m_archivePath; QString m_archivePath;
Task::Ptr task; Task::Ptr m_task;
enum class ModpackType { enum class ModpackType {
Unknown, Unknown,
MultiMC, MultiMC,

View File

@ -116,7 +116,7 @@ void JavaCommon::TestCheck::run()
emit finished(); emit finished();
return; return;
} }
checker.reset(new JavaChecker(m_path, "", 0, 0, 0, 0, this)); checker.reset(new JavaChecker(m_path, "", 0, 0, 0, 0));
connect(checker.get(), &JavaChecker::checkFinished, this, &JavaCommon::TestCheck::checkFinished); connect(checker.get(), &JavaChecker::checkFinished, this, &JavaCommon::TestCheck::checkFinished);
checker->start(); checker->start();
} }
@ -128,7 +128,7 @@ void JavaCommon::TestCheck::checkFinished(const JavaChecker::Result& result)
emit finished(); emit finished();
return; return;
} }
checker.reset(new JavaChecker(m_path, m_args, m_maxMem, m_maxMem, result.javaVersion.requiresPermGen() ? m_permGen : 0, 0, this)); checker.reset(new JavaChecker(m_path, m_args, m_maxMem, m_maxMem, result.javaVersion.requiresPermGen() ? m_permGen : 0, 0));
connect(checker.get(), &JavaChecker::checkFinished, this, &JavaCommon::TestCheck::checkFinishedWithArgs); connect(checker.get(), &JavaChecker::checkFinished, this, &JavaCommon::TestCheck::checkFinishedWithArgs);
checker->start(); checker->start();
} }

View File

@ -62,7 +62,7 @@
#include "launch/steps/TextPrint.h" #include "launch/steps/TextPrint.h"
#include "tasks/Task.h" #include "tasks/Task.h"
LaunchController::LaunchController(QObject* parent) : Task(parent) {} LaunchController::LaunchController() : Task() {}
void LaunchController::executeTask() void LaunchController::executeTask()
{ {

View File

@ -47,7 +47,7 @@ class LaunchController : public Task {
public: public:
void executeTask() override; void executeTask() override;
LaunchController(QObject* parent = nullptr); LaunchController();
virtual ~LaunchController() = default; virtual ~LaunchController() = default;
void setInstance(InstancePtr instance) { m_instance = instance; } void setInstance(InstancePtr instance) { m_instance = instance; }

View File

@ -44,8 +44,8 @@
#include "FileSystem.h" #include "FileSystem.h"
#include "java/JavaUtils.h" #include "java/JavaUtils.h"
JavaChecker::JavaChecker(QString path, QString args, int minMem, int maxMem, int permGen, int id, QObject* parent) JavaChecker::JavaChecker(QString path, QString args, int minMem, int maxMem, int permGen, int id)
: Task(parent), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen), m_id(id) : Task(), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen), m_id(id)
{} {}
void JavaChecker::executeTask() void JavaChecker::executeTask()

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <QProcess> #include <QProcess>
#include <QTimer> #include <QTimer>
#include <memory>
#include "JavaVersion.h" #include "JavaVersion.h"
#include "QObjectPtr.h" #include "QObjectPtr.h"
@ -26,7 +25,7 @@ class JavaChecker : public Task {
enum class Validity { Errored, ReturnedInvalidData, Valid } validity = Validity::Errored; enum class Validity { Errored, ReturnedInvalidData, Valid } validity = Validity::Errored;
}; };
explicit JavaChecker(QString path, QString args, int minMem = 0, int maxMem = 0, int permGen = 0, int id = 0, QObject* parent = 0); explicit JavaChecker(QString path, QString args, int minMem = 0, int maxMem = 0, int permGen = 0, int id = 0);
signals: signals:
void checkFinished(const Result& result); void checkFinished(const Result& result);

View File

@ -163,7 +163,7 @@ void JavaListLoadTask::executeTask()
JavaUtils ju; JavaUtils ju;
QList<QString> candidate_paths = m_only_managed_versions ? getPrismJavaBundle() : ju.FindJavaPaths(); QList<QString> candidate_paths = m_only_managed_versions ? getPrismJavaBundle() : ju.FindJavaPaths();
ConcurrentTask::Ptr job(new ConcurrentTask(this, "Java detection", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt())); ConcurrentTask::Ptr job(new ConcurrentTask("Java detection", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));
m_job.reset(job); m_job.reset(job);
connect(m_job.get(), &Task::finished, this, &JavaListLoadTask::javaCheckerFinished); connect(m_job.get(), &Task::finished, this, &JavaListLoadTask::javaCheckerFinished);
connect(m_job.get(), &Task::progress, this, &Task::setProgress); connect(m_job.get(), &Task::progress, this, &Task::setProgress);
@ -171,7 +171,7 @@ void JavaListLoadTask::executeTask()
qDebug() << "Probing the following Java paths: "; qDebug() << "Probing the following Java paths: ";
int id = 0; int id = 0;
for (QString candidate : candidate_paths) { for (QString candidate : candidate_paths) {
auto checker = new JavaChecker(candidate, "", 0, 0, 0, id, this); auto checker = new JavaChecker(candidate, "", 0, 0, 0, id);
connect(checker, &JavaChecker::checkFinished, [this](const JavaChecker::Result& result) { m_results << result; }); connect(checker, &JavaChecker::checkFinished, [this](const JavaChecker::Result& result) { m_results << result; });
job->addTask(Task::Ptr(checker)); job->addTask(Task::Ptr(checker));
id++; id++;

View File

@ -16,7 +16,7 @@
#include "LaunchStep.h" #include "LaunchStep.h"
#include "LaunchTask.h" #include "LaunchTask.h"
LaunchStep::LaunchStep(LaunchTask* parent) : Task(parent), m_parent(parent) LaunchStep::LaunchStep(LaunchTask* parent) : Task(), m_parent(parent)
{ {
connect(this, &LaunchStep::readyForLaunch, parent, &LaunchTask::onReadyForLaunch); connect(this, &LaunchStep::readyForLaunch, parent, &LaunchTask::onReadyForLaunch);
connect(this, &LaunchStep::logLine, parent, &LaunchTask::onLogLine); connect(this, &LaunchStep::logLine, parent, &LaunchTask::onLogLine);

View File

@ -94,7 +94,7 @@ void CheckJava::executeTask()
// if timestamps are not the same, or something is missing, check! // if timestamps are not the same, or something is missing, check!
if (m_javaSignature != storedSignature || storedVersion.size() == 0 || storedArchitecture.size() == 0 || if (m_javaSignature != storedSignature || storedVersion.size() == 0 || storedArchitecture.size() == 0 ||
storedRealArchitecture.size() == 0 || storedVendor.size() == 0) { storedRealArchitecture.size() == 0 || storedVendor.size() == 0) {
m_JavaChecker.reset(new JavaChecker(realJavaPath, "", 0, 0, 0, 0, this)); m_JavaChecker.reset(new JavaChecker(realJavaPath, "", 0, 0, 0, 0));
emit logLine(QString("Checking Java version..."), MessageLevel::Launcher); emit logLine(QString("Checking Java version..."), MessageLevel::Launcher);
connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished); connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished);
m_JavaChecker->start(); m_JavaChecker->start();

View File

@ -140,8 +140,8 @@ Task::Ptr Index::loadVersion(const QString& uid, const QString& version, Net::Mo
} }
auto versionList = get(uid); auto versionList = get(uid);
auto loadTask = makeShared<SequentialTask>( auto loadTask =
this, tr("Load meta for %1:%2", "This is for the task name that loads the meta index.").arg(uid, version)); makeShared<SequentialTask>(tr("Load meta for %1:%2", "This is for the task name that loads the meta index.").arg(uid, version));
if (status() != BaseEntity::LoadStatus::Remote || force) { if (status() != BaseEntity::LoadStatus::Remote || force) {
loadTask->addTask(this->loadTask(mode)); loadTask->addTask(this->loadTask(mode));
} }

View File

@ -34,8 +34,7 @@ VersionList::VersionList(const QString& uid, QObject* parent) : BaseVersionList(
Task::Ptr VersionList::getLoadTask() Task::Ptr VersionList::getLoadTask()
{ {
auto loadTask = auto loadTask = makeShared<SequentialTask>(tr("Load meta for %1", "This is for the task name that loads the meta index.").arg(m_uid));
makeShared<SequentialTask>(this, tr("Load meta for %1", "This is for the task name that loads the meta index.").arg(m_uid));
loadTask->addTask(APPLICATION->metadataIndex()->loadTask(Net::Mode::Online)); loadTask->addTask(APPLICATION->metadataIndex()->loadTask(Net::Mode::Online));
loadTask->addTask(this->loadTask(Net::Mode::Online)); loadTask->addTask(this->loadTask(Net::Mode::Online));
return loadTask; return loadTask;

View File

@ -38,7 +38,7 @@
* If the component list changes, start over. * If the component list changes, start over.
*/ */
ComponentUpdateTask::ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile* list, QObject* parent) : Task(parent) ComponentUpdateTask::ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile* list) : Task()
{ {
d.reset(new ComponentUpdateTaskData); d.reset(new ComponentUpdateTaskData);
d->m_profile = list; d->m_profile = list;

View File

@ -14,7 +14,7 @@ class ComponentUpdateTask : public Task {
enum class Mode { Launch, Resolution }; enum class Mode { Launch, Resolution };
public: public:
explicit ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile* list, QObject* parent = 0); explicit ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile* list);
virtual ~ComponentUpdateTask(); virtual ~ComponentUpdateTask();
protected: protected:

View File

@ -1119,7 +1119,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
// load meta // load meta
{ {
auto mode = session->status != AuthSession::PlayableOffline ? Net::Mode::Online : Net::Mode::Offline; auto mode = session->status != AuthSession::PlayableOffline ? Net::Mode::Online : Net::Mode::Offline;
process->appendStep(makeShared<TaskStepWrapper>(pptr, makeShared<MinecraftLoadAndCheck>(this, mode, pptr))); process->appendStep(makeShared<TaskStepWrapper>(pptr, makeShared<MinecraftLoadAndCheck>(this, mode)));
} }
// check java // check java

View File

@ -2,9 +2,7 @@
#include "MinecraftInstance.h" #include "MinecraftInstance.h"
#include "PackProfile.h" #include "PackProfile.h"
MinecraftLoadAndCheck::MinecraftLoadAndCheck(MinecraftInstance* inst, Net::Mode netmode, QObject* parent) MinecraftLoadAndCheck::MinecraftLoadAndCheck(MinecraftInstance* inst, Net::Mode netmode) : m_inst(inst), m_netmode(netmode) {}
: Task(parent), m_inst(inst), m_netmode(netmode)
{}
void MinecraftLoadAndCheck::executeTask() void MinecraftLoadAndCheck::executeTask()
{ {

View File

@ -23,7 +23,7 @@ class MinecraftInstance;
class MinecraftLoadAndCheck : public Task { class MinecraftLoadAndCheck : public Task {
Q_OBJECT Q_OBJECT
public: public:
explicit MinecraftLoadAndCheck(MinecraftInstance* inst, Net::Mode netmode, QObject* parent = nullptr); explicit MinecraftLoadAndCheck(MinecraftInstance* inst, Net::Mode netmode);
virtual ~MinecraftLoadAndCheck() = default; virtual ~MinecraftLoadAndCheck() = default;
void executeTask() override; void executeTask() override;

View File

@ -19,7 +19,7 @@
#include <Application.h> #include <Application.h>
AuthFlow::AuthFlow(AccountData* data, Action action, QObject* parent) : Task(parent), m_data(data) AuthFlow::AuthFlow(AccountData* data, Action action) : Task(), m_data(data)
{ {
if (data->type == AccountType::MSA) { if (data->type == AccountType::MSA) {
if (action == Action::DeviceCode) { if (action == Action::DeviceCode) {

View File

@ -17,7 +17,7 @@ class AuthFlow : public Task {
public: public:
enum class Action { Refresh, Login, DeviceCode }; enum class Action { Refresh, Login, DeviceCode };
explicit AuthFlow(AccountData* data, Action action = Action::Refresh, QObject* parent = 0); explicit AuthFlow(AccountData* data, Action action = Action::Refresh);
virtual ~AuthFlow() = default; virtual ~AuthFlow() = default;
void executeTask() override; void executeTask() override;

View File

@ -121,7 +121,7 @@ shared_qobject_ptr<AuthFlow> MinecraftAccount::login(bool useDeviceCode)
{ {
Q_ASSERT(m_currentTask.get() == nullptr); Q_ASSERT(m_currentTask.get() == nullptr);
m_currentTask.reset(new AuthFlow(&data, useDeviceCode ? AuthFlow::Action::DeviceCode : AuthFlow::Action::Login, this)); m_currentTask.reset(new AuthFlow(&data, useDeviceCode ? AuthFlow::Action::DeviceCode : AuthFlow::Action::Login));
connect(m_currentTask.get(), &Task::succeeded, this, &MinecraftAccount::authSucceeded); connect(m_currentTask.get(), &Task::succeeded, this, &MinecraftAccount::authSucceeded);
connect(m_currentTask.get(), &Task::failed, this, &MinecraftAccount::authFailed); connect(m_currentTask.get(), &Task::failed, this, &MinecraftAccount::authFailed);
connect(m_currentTask.get(), &Task::aborted, this, [this] { authFailed(tr("Aborted")); }); connect(m_currentTask.get(), &Task::aborted, this, [this] { authFailed(tr("Aborted")); });
@ -135,7 +135,7 @@ shared_qobject_ptr<AuthFlow> MinecraftAccount::refresh()
return m_currentTask; return m_currentTask;
} }
m_currentTask.reset(new AuthFlow(&data, AuthFlow::Action::Refresh, this)); m_currentTask.reset(new AuthFlow(&data, AuthFlow::Action::Refresh));
connect(m_currentTask.get(), &Task::succeeded, this, &MinecraftAccount::authSucceeded); connect(m_currentTask.get(), &Task::succeeded, this, &MinecraftAccount::authSucceeded);
connect(m_currentTask.get(), &Task::failed, this, &MinecraftAccount::authFailed); connect(m_currentTask.get(), &Task::failed, this, &MinecraftAccount::authFailed);

View File

@ -57,9 +57,7 @@
#include "tasks/SequentialTask.h" #include "tasks/SequentialTask.h"
AutoInstallJava::AutoInstallJava(LaunchTask* parent) AutoInstallJava::AutoInstallJava(LaunchTask* parent)
: LaunchStep(parent) : LaunchStep(parent), m_instance(m_parent->instance()), m_supported_arch(SysInfo::getSupportedJavaArchitecture()) {};
, m_instance(m_parent->instance())
, m_supported_arch(SysInfo::getSupportedJavaArchitecture()) {};
void AutoInstallJava::executeTask() void AutoInstallJava::executeTask()
{ {
@ -179,7 +177,7 @@ void AutoInstallJava::downloadJava(Meta::Version::Ptr version, QString javaName)
return; return;
} }
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
auto seq = makeShared<SequentialTask>(this, tr("Install Java")); auto seq = makeShared<SequentialTask>(tr("Install Java"));
seq->addTask(m_current_task); seq->addTask(m_current_task);
seq->addTask(makeShared<Java::SymlinkTask>(final_path)); seq->addTask(makeShared<Java::SymlinkTask>(final_path));
m_current_task = seq; m_current_task = seq;

View File

@ -48,16 +48,10 @@
#include <QThreadPool> #include <QThreadPool>
#include <QUrl> #include <QUrl>
#include <QUuid> #include <QUuid>
#include <algorithm>
#include "Application.h" #include "Application.h"
#include "Json.h"
#include "minecraft/mod/tasks/LocalModParseTask.h" #include "minecraft/mod/tasks/LocalModParseTask.h"
#include "minecraft/mod/tasks/LocalResourceUpdateTask.h"
#include "modplatform/ModIndex.h"
#include "modplatform/flame/FlameAPI.h"
#include "modplatform/flame/FlameModIndex.h"
ModFolderModel::ModFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent) ModFolderModel::ModFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent)
: ResourceFolderModel(QDir(dir), instance, is_indexed, create_dir, parent) : ResourceFolderModel(QDir(dir), instance, is_indexed, create_dir, parent)
@ -246,7 +240,7 @@ void ModFolderModel::onParseSucceeded(int ticket, QString mod_id)
auto result = cast_task->result(); auto result = cast_task->result();
if (result && resource) if (result && resource)
resource->finishResolvingWithDetails(std::move(result->details)); static_cast<Mod*>(resource.get())->finishResolvingWithDetails(std::move(result->details));
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1)); emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
} }

View File

@ -47,10 +47,6 @@
#include "Mod.h" #include "Mod.h"
#include "ResourceFolderModel.h" #include "ResourceFolderModel.h"
#include "minecraft/mod/tasks/LocalModParseTask.h"
#include "minecraft/mod/tasks/ResourceFolderLoadTask.h"
#include "modplatform/ModIndex.h"
class BaseInstance; class BaseInstance;
class QFileSystemWatcher; class QFileSystemWatcher;

View File

@ -41,7 +41,6 @@
#include <QPointer> #include <QPointer>
#include "MetadataHandler.h" #include "MetadataHandler.h"
#include "ModDetails.h"
#include "QObjectPtr.h" #include "QObjectPtr.h"
enum class ResourceType { enum class ResourceType {

View File

@ -16,8 +16,6 @@
#include "Application.h" #include "Application.h"
#include "FileSystem.h" #include "FileSystem.h"
#include "QVariantUtils.h"
#include "StringUtils.h"
#include "minecraft/mod/tasks/ResourceFolderLoadTask.h" #include "minecraft/mod/tasks/ResourceFolderLoadTask.h"
#include "Json.h" #include "Json.h"
@ -327,7 +325,7 @@ bool ResourceFolderModel::update()
return true; return true;
} }
void ResourceFolderModel::resolveResource(Resource* res) void ResourceFolderModel::resolveResource(Resource::Ptr res)
{ {
if (!res->shouldResolve()) { if (!res->shouldResolve()) {
return; return;
@ -386,7 +384,7 @@ void ResourceFolderModel::onUpdateSucceeded()
void ResourceFolderModel::onParseSucceeded(int ticket, QString resource_id) void ResourceFolderModel::onParseSucceeded(int ticket, QString resource_id)
{ {
auto iter = m_active_parse_tasks.constFind(ticket); auto iter = m_active_parse_tasks.constFind(ticket);
if (iter == m_active_parse_tasks.constEnd()) if (iter == m_active_parse_tasks.constEnd() || !m_resources_index.contains(resource_id))
return; return;
int row = m_resources_index[resource_id]; int row = m_resources_index[resource_id];
@ -705,7 +703,7 @@ QString ResourceFolderModel::instDirPath() const
void ResourceFolderModel::onParseFailed(int ticket, QString resource_id) void ResourceFolderModel::onParseFailed(int ticket, QString resource_id)
{ {
auto iter = m_active_parse_tasks.constFind(ticket); auto iter = m_active_parse_tasks.constFind(ticket);
if (iter == m_active_parse_tasks.constEnd()) if (iter == m_active_parse_tasks.constEnd() || !m_resources_index.contains(resource_id))
return; return;
auto removed_index = m_resources_index[resource_id]; auto removed_index = m_resources_index[resource_id];
@ -724,3 +722,126 @@ void ResourceFolderModel::onParseFailed(int ticket, QString resource_id)
} }
endRemoveRows(); endRemoveRows();
} }
void ResourceFolderModel::applyUpdates(QSet<QString>& current_set, QSet<QString>& new_set, QMap<QString, Resource::Ptr>& new_resources)
{
// see if the kept resources changed in some way
{
QSet<QString> kept_set = current_set;
kept_set.intersect(new_set);
for (auto const& kept : kept_set) {
auto row_it = m_resources_index.constFind(kept);
Q_ASSERT(row_it != m_resources_index.constEnd());
auto row = row_it.value();
auto& new_resource = new_resources[kept];
auto const& current_resource = m_resources.at(row);
if (new_resource->dateTimeChanged() == current_resource->dateTimeChanged()) {
// no significant change, ignore...
continue;
}
// If the resource is resolving, but something about it changed, we don't want to
// continue the resolving.
if (current_resource->isResolving()) {
auto ticket = current_resource->resolutionTicket();
if (m_active_parse_tasks.contains(ticket)) {
auto task = (*m_active_parse_tasks.find(ticket)).get();
task->abort();
}
}
m_resources[row].reset(new_resource);
resolveResource(m_resources.at(row));
emit dataChanged(index(row, 0), index(row, columnCount(QModelIndex()) - 1));
}
}
// remove resources no longer present
{
QSet<QString> removed_set = current_set;
removed_set.subtract(new_set);
QList<int> removed_rows;
for (auto& removed : removed_set)
removed_rows.append(m_resources_index[removed]);
std::sort(removed_rows.begin(), removed_rows.end(), std::greater<int>());
for (auto& removed_index : removed_rows) {
auto removed_it = m_resources.begin() + removed_index;
Q_ASSERT(removed_it != m_resources.end());
if ((*removed_it)->isResolving()) {
auto ticket = (*removed_it)->resolutionTicket();
if (m_active_parse_tasks.contains(ticket)) {
auto task = (*m_active_parse_tasks.find(ticket)).get();
task->abort();
}
}
beginRemoveRows(QModelIndex(), removed_index, removed_index);
m_resources.erase(removed_it);
endRemoveRows();
}
}
// add new resources to the end
{
QSet<QString> added_set = new_set;
added_set.subtract(current_set);
// When you have a Qt build with assertions turned on, proceeding here will abort the application
if (added_set.size() > 0) {
beginInsertRows(QModelIndex(), static_cast<int>(m_resources.size()),
static_cast<int>(m_resources.size() + added_set.size() - 1));
for (auto& added : added_set) {
auto res = new_resources[added];
m_resources.append(res);
resolveResource(m_resources.last());
}
endInsertRows();
}
}
// update index
{
m_resources_index.clear();
int idx = 0;
for (auto const& mod : qAsConst(m_resources)) {
m_resources_index[mod->internal_id()] = idx;
idx++;
}
}
}
Resource::Ptr ResourceFolderModel::find(QString id)
{
auto iter =
std::find_if(m_resources.constBegin(), m_resources.constEnd(), [&](Resource::Ptr const& r) { return r->internal_id() == id; });
if (iter == m_resources.constEnd())
return nullptr;
return *iter;
}
QList<Resource*> ResourceFolderModel::allResources()
{
QList<Resource*> result;
result.reserve(m_resources.size());
for (const Resource ::Ptr& resource : m_resources)
result.append((resource.get()));
return result;
}
QList<Resource*> ResourceFolderModel::selectedResources(const QModelIndexList& indexes)
{
QList<Resource*> result;
for (const QModelIndex& index : indexes) {
if (index.column() != 0)
continue;
result.append(&at(index.row()));
}
return result;
}

View File

@ -21,10 +21,6 @@ class QSortFilterProxyModel;
/* A macro to define useful functions to handle Resource* -> T* more easily on derived classes */ /* A macro to define useful functions to handle Resource* -> T* more easily on derived classes */
#define RESOURCE_HELPERS(T) \ #define RESOURCE_HELPERS(T) \
[[nodiscard]] T& operator[](int index) \
{ \
return *static_cast<T*>(m_resources[index].get()); \
} \
[[nodiscard]] T& at(int index) \ [[nodiscard]] T& at(int index) \
{ \ { \
return *static_cast<T*>(m_resources[index].get()); \ return *static_cast<T*>(m_resources[index].get()); \
@ -33,22 +29,6 @@ class QSortFilterProxyModel;
{ \ { \
return *static_cast<const T*>(m_resources.at(index).get()); \ return *static_cast<const T*>(m_resources.at(index).get()); \
} \ } \
[[nodiscard]] T& first() \
{ \
return *static_cast<T*>(m_resources.first().get()); \
} \
[[nodiscard]] T& last() \
{ \
return *static_cast<T*>(m_resources.last().get()); \
} \
[[nodiscard]] T* find(QString id) \
{ \
auto iter = std::find_if(m_resources.constBegin(), m_resources.constEnd(), \
[id](Resource::Ptr const& r) { return r->internal_id() == id; }); \
if (iter == m_resources.constEnd()) \
return nullptr; \
return static_cast<T*>((*iter).get()); \
} \
QList<T*> selected##T##s(const QModelIndexList& indexes) \ QList<T*> selected##T##s(const QModelIndexList& indexes) \
{ \ { \
QList<T*> result; \ QList<T*> result; \
@ -133,11 +113,17 @@ class ResourceFolderModel : public QAbstractListModel {
virtual bool update(); virtual bool update();
/** Creates a new parse task, if needed, for 'res' and start it.*/ /** Creates a new parse task, if needed, for 'res' and start it.*/
virtual void resolveResource(Resource* res); virtual void resolveResource(Resource::Ptr res);
[[nodiscard]] qsizetype size() const { return m_resources.size(); } [[nodiscard]] qsizetype size() const { return m_resources.size(); }
[[nodiscard]] bool empty() const { return size() == 0; } [[nodiscard]] bool empty() const { return size() == 0; }
RESOURCE_HELPERS(Resource)
[[nodiscard]] Resource& at(int index) { return *m_resources[index].get(); }
[[nodiscard]] const Resource& at(int index) const { return *m_resources.at(index).get(); }
QList<Resource*> selectedResources(const QModelIndexList& indexes);
QList<Resource*> allResources();
[[nodiscard]] Resource::Ptr find(QString id);
[[nodiscard]] QDir const& dir() const { return m_dir; } [[nodiscard]] QDir const& dir() const { return m_dir; }
@ -225,10 +211,8 @@ class ResourceFolderModel : public QAbstractListModel {
* It uses set operations to find differences between the current state and the updated state, * It uses set operations to find differences between the current state and the updated state,
* to act only on those disparities. * to act only on those disparities.
* *
* The implementation is at the end of this header.
*/ */
template <typename T> void applyUpdates(QSet<QString>& current_set, QSet<QString>& new_set, QMap<QString, Resource::Ptr>& new_resources);
void applyUpdates(QSet<QString>& current_set, QSet<QString>& new_set, QMap<QString, T>& new_resources);
protected slots: protected slots:
void directoryChanged(QString); void directoryChanged(QString);
@ -281,102 +265,3 @@ class ResourceFolderModel : public QAbstractListModel {
QMap<int, Task::Ptr> m_active_parse_tasks; QMap<int, Task::Ptr> m_active_parse_tasks;
std::atomic<int> m_next_resolution_ticket = 0; std::atomic<int> m_next_resolution_ticket = 0;
}; };
/* Template definition to avoid some code duplication */
template <typename T>
void ResourceFolderModel::applyUpdates(QSet<QString>& current_set, QSet<QString>& new_set, QMap<QString, T>& new_resources)
{
// see if the kept resources changed in some way
{
QSet<QString> kept_set = current_set;
kept_set.intersect(new_set);
for (auto const& kept : kept_set) {
auto row_it = m_resources_index.constFind(kept);
Q_ASSERT(row_it != m_resources_index.constEnd());
auto row = row_it.value();
auto& new_resource = new_resources[kept];
auto const& current_resource = m_resources.at(row);
if (new_resource->dateTimeChanged() == current_resource->dateTimeChanged()) {
// no significant change, ignore...
continue;
}
// If the resource is resolving, but something about it changed, we don't want to
// continue the resolving.
if (current_resource->isResolving()) {
auto ticket = current_resource->resolutionTicket();
if (m_active_parse_tasks.contains(ticket)) {
auto task = (*m_active_parse_tasks.find(ticket)).get();
task->abort();
}
}
m_resources[row].reset(new_resource);
resolveResource(m_resources.at(row).get());
emit dataChanged(index(row, 0), index(row, columnCount(QModelIndex()) - 1));
}
}
// remove resources no longer present
{
QSet<QString> removed_set = current_set;
removed_set.subtract(new_set);
QList<int> removed_rows;
for (auto& removed : removed_set)
removed_rows.append(m_resources_index[removed]);
std::sort(removed_rows.begin(), removed_rows.end(), std::greater<int>());
for (auto& removed_index : removed_rows) {
auto removed_it = m_resources.begin() + removed_index;
Q_ASSERT(removed_it != m_resources.end());
if ((*removed_it)->isResolving()) {
auto ticket = (*removed_it)->resolutionTicket();
if (m_active_parse_tasks.contains(ticket)) {
auto task = (*m_active_parse_tasks.find(ticket)).get();
task->abort();
}
}
beginRemoveRows(QModelIndex(), removed_index, removed_index);
m_resources.erase(removed_it);
endRemoveRows();
}
}
// add new resources to the end
{
QSet<QString> added_set = new_set;
added_set.subtract(current_set);
// When you have a Qt build with assertions turned on, proceeding here will abort the application
if (added_set.size() > 0) {
beginInsertRows(QModelIndex(), static_cast<int>(m_resources.size()),
static_cast<int>(m_resources.size() + added_set.size() - 1));
for (auto& added : added_set) {
auto res = new_resources[added];
m_resources.append(res);
resolveResource(m_resources.last().get());
}
endInsertRows();
}
}
// update index
{
m_resources_index.clear();
int idx = 0;
for (auto const& mod : qAsConst(m_resources)) {
m_resources_index[mod->internal_id()] = idx;
idx++;
}
}
}

View File

@ -45,7 +45,6 @@
#include "Version.h" #include "Version.h"
#include "minecraft/mod/tasks/LocalResourcePackParseTask.h" #include "minecraft/mod/tasks/LocalResourcePackParseTask.h"
#include "minecraft/mod/tasks/ResourceFolderLoadTask.h"
ResourcePackFolderModel::ResourcePackFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent) ResourcePackFolderModel::ResourcePackFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent)
: ResourceFolderModel(dir, instance, is_indexed, create_dir, parent) : ResourceFolderModel(dir, instance, is_indexed, create_dir, parent)

View File

@ -52,11 +52,10 @@ static bool checkDependencies(std::shared_ptr<GetModDependenciesTask::PackDepend
(!loaders || !sel->version.loaders || sel->version.loaders & loaders); (!loaders || !sel->version.loaders || sel->version.loaders & loaders);
} }
GetModDependenciesTask::GetModDependenciesTask(QObject* parent, GetModDependenciesTask::GetModDependenciesTask(BaseInstance* instance,
BaseInstance* instance,
ModFolderModel* folder, ModFolderModel* folder,
QList<std::shared_ptr<PackDependency>> selected) QList<std::shared_ptr<PackDependency>> selected)
: SequentialTask(parent, tr("Get dependencies")) : SequentialTask(tr("Get dependencies"))
, m_selected(selected) , m_selected(selected)
, m_flame_provider{ ModPlatform::ResourceProvider::FLAME, std::make_shared<ResourceDownload::FlameModModel>(*instance), , m_flame_provider{ ModPlatform::ResourceProvider::FLAME, std::make_shared<ResourceDownload::FlameModModel>(*instance),
std::make_shared<FlameAPI>() } std::make_shared<FlameAPI>() }
@ -185,7 +184,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen
auto provider = providerName == m_flame_provider.name ? m_flame_provider : m_modrinth_provider; auto provider = providerName == m_flame_provider.name ? m_flame_provider : m_modrinth_provider;
auto tasks = makeShared<SequentialTask>( auto tasks = makeShared<SequentialTask>(
this, QString("DependencyInfo: %1").arg(dep.addonId.toString().isEmpty() ? dep.version : dep.addonId.toString())); QString("DependencyInfo: %1").arg(dep.addonId.toString().isEmpty() ? dep.version : dep.addonId.toString()));
if (!dep.addonId.toString().isEmpty()) { if (!dep.addonId.toString().isEmpty()) {
tasks->addTask(getProjectInfoTask(pDep)); tasks->addTask(getProjectInfoTask(pDep));

View File

@ -61,10 +61,7 @@ class GetModDependenciesTask : public SequentialTask {
std::shared_ptr<ResourceAPI> api; std::shared_ptr<ResourceAPI> api;
}; };
explicit GetModDependenciesTask(QObject* parent, explicit GetModDependenciesTask(BaseInstance* instance, ModFolderModel* folder, QList<std::shared_ptr<PackDependency>> selected);
BaseInstance* instance,
ModFolderModel* folder,
QList<std::shared_ptr<PackDependency>> selected);
auto getDependecies() const -> QList<std::shared_ptr<PackDependency>> { return m_pack_dependencies; } auto getDependecies() const -> QList<std::shared_ptr<PackDependency>> { return m_pack_dependencies; }
QHash<QString, PackDependencyExtraInfo> getExtraInfo(); QHash<QString, PackDependencyExtraInfo> getExtraInfo();

View File

@ -157,7 +157,7 @@ bool validate(QFileInfo file)
} // namespace DataPackUtils } // namespace DataPackUtils
LocalDataPackParseTask::LocalDataPackParseTask(int token, DataPack& dp) : Task(nullptr, false), m_token(token), m_data_pack(dp) {} LocalDataPackParseTask::LocalDataPackParseTask(int token, DataPack& dp) : Task(false), m_token(token), m_data_pack(dp) {}
bool LocalDataPackParseTask::abort() bool LocalDataPackParseTask::abort()
{ {

View File

@ -730,7 +730,7 @@ bool loadIconFile(const Mod& mod, QPixmap* pixmap)
} // namespace ModUtils } // namespace ModUtils
LocalModParseTask::LocalModParseTask(int token, ResourceType type, const QFileInfo& modFile) LocalModParseTask::LocalModParseTask(int token, ResourceType type, const QFileInfo& modFile)
: Task(nullptr, false), m_token(token), m_type(type), m_modFile(modFile), m_result(new Result()) : Task(false), m_token(token), m_type(type), m_modFile(modFile), m_result(new Result())
{} {}
bool LocalModParseTask::abort() bool LocalModParseTask::abort()

View File

@ -358,9 +358,7 @@ bool validate(QFileInfo file)
} // namespace ResourcePackUtils } // namespace ResourcePackUtils
LocalResourcePackParseTask::LocalResourcePackParseTask(int token, ResourcePack& rp) LocalResourcePackParseTask::LocalResourcePackParseTask(int token, ResourcePack& rp) : Task(false), m_token(token), m_resource_pack(rp) {}
: Task(nullptr, false), m_token(token), m_resource_pack(rp)
{}
bool LocalResourcePackParseTask::abort() bool LocalResourcePackParseTask::abort()
{ {

View File

@ -93,7 +93,7 @@ bool validate(QFileInfo file)
} // namespace ShaderPackUtils } // namespace ShaderPackUtils
LocalShaderPackParseTask::LocalShaderPackParseTask(int token, ShaderPack& sp) : Task(nullptr, false), m_token(token), m_shader_pack(sp) {} LocalShaderPackParseTask::LocalShaderPackParseTask(int token, ShaderPack& sp) : Task(false), m_token(token), m_shader_pack(sp) {}
bool LocalShaderPackParseTask::abort() bool LocalShaderPackParseTask::abort()
{ {

View File

@ -230,8 +230,7 @@ bool validate(QFileInfo file)
} // namespace TexturePackUtils } // namespace TexturePackUtils
LocalTexturePackParseTask::LocalTexturePackParseTask(int token, TexturePack& rp) : Task(nullptr, false), m_token(token), m_texture_pack(rp) LocalTexturePackParseTask::LocalTexturePackParseTask(int token, TexturePack& rp) : Task(false), m_token(token), m_texture_pack(rp) {}
{}
bool LocalTexturePackParseTask::abort() bool LocalTexturePackParseTask::abort()
{ {

View File

@ -170,7 +170,7 @@ bool validate(QFileInfo file)
} // namespace WorldSaveUtils } // namespace WorldSaveUtils
LocalWorldSaveParseTask::LocalWorldSaveParseTask(int token, WorldSave& save) : Task(nullptr, false), m_token(token), m_save(save) {} LocalWorldSaveParseTask::LocalWorldSaveParseTask(int token, WorldSave& save) : Task(false), m_token(token), m_save(save) {}
bool LocalWorldSaveParseTask::abort() bool LocalWorldSaveParseTask::abort()
{ {

View File

@ -47,7 +47,7 @@ ResourceFolderLoadTask::ResourceFolderLoadTask(const QDir& resource_dir,
bool is_indexed, bool is_indexed,
bool clean_orphan, bool clean_orphan,
std::function<Resource*(const QFileInfo&)> create_function) std::function<Resource*(const QFileInfo&)> create_function)
: Task(nullptr, false) : Task(false)
, m_resource_dir(resource_dir) , m_resource_dir(resource_dir)
, m_index_dir(index_dir) , m_index_dir(index_dir)
, m_is_indexed(is_indexed) , m_is_indexed(is_indexed)

View File

@ -19,7 +19,7 @@ static ModrinthAPI modrinth_api;
static FlameAPI flame_api; static FlameAPI flame_api;
EnsureMetadataTask::EnsureMetadataTask(Resource* resource, QDir dir, ModPlatform::ResourceProvider prov) EnsureMetadataTask::EnsureMetadataTask(Resource* resource, QDir dir, ModPlatform::ResourceProvider prov)
: Task(nullptr), m_index_dir(dir), m_provider(prov), m_hashing_task(nullptr), m_current_task(nullptr) : Task(), m_index_dir(dir), m_provider(prov), m_hashing_task(nullptr), m_current_task(nullptr)
{ {
auto hash_task = createNewHash(resource); auto hash_task = createNewHash(resource);
if (!hash_task) if (!hash_task)
@ -30,9 +30,9 @@ EnsureMetadataTask::EnsureMetadataTask(Resource* resource, QDir dir, ModPlatform
} }
EnsureMetadataTask::EnsureMetadataTask(QList<Resource*>& resources, QDir dir, ModPlatform::ResourceProvider prov) EnsureMetadataTask::EnsureMetadataTask(QList<Resource*>& resources, QDir dir, ModPlatform::ResourceProvider prov)
: Task(nullptr), m_index_dir(dir), m_provider(prov), m_current_task(nullptr) : Task(), m_index_dir(dir), m_provider(prov), m_current_task(nullptr)
{ {
m_hashing_task.reset(new ConcurrentTask(this, "MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt())); m_hashing_task.reset(new ConcurrentTask("MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));
for (auto* resource : resources) { for (auto* resource : resources) {
auto hash_task = createNewHash(resource); auto hash_task = createNewHash(resource);
if (!hash_task) if (!hash_task)
@ -44,7 +44,7 @@ EnsureMetadataTask::EnsureMetadataTask(QList<Resource*>& resources, QDir dir, Mo
} }
EnsureMetadataTask::EnsureMetadataTask(QHash<QString, Resource*>& resources, QDir dir, ModPlatform::ResourceProvider prov) EnsureMetadataTask::EnsureMetadataTask(QHash<QString, Resource*>& resources, QDir dir, ModPlatform::ResourceProvider prov)
: Task(nullptr), m_resources(resources), m_index_dir(dir), m_provider(prov), m_current_task(nullptr) : Task(), m_resources(resources), m_index_dir(dir), m_provider(prov), m_current_task(nullptr)
{} {}
Hashing::Hasher::Ptr EnsureMetadataTask::createNewHash(Resource* resource) Hashing::Hasher::Ptr EnsureMetadataTask::createNewHash(Resource* resource)

View File

@ -444,6 +444,7 @@ bool FlameCreationTask::createInstance()
setError(tr("Unable to resolve mod IDs:\n") + reason); setError(tr("Unable to resolve mod IDs:\n") + reason);
loop.quit(); loop.quit();
}); });
connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::aborted, &loop, &QEventLoop::quit);
connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::progress, this, &FlameCreationTask::setProgress); connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::progress, this, &FlameCreationTask::setProgress);
connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::status, this, &FlameCreationTask::setStatus); connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::status, this, &FlameCreationTask::setStatus);
connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::stepProgress, this, &FlameCreationTask::propagateStepProgress); connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::stepProgress, this, &FlameCreationTask::propagateStepProgress);
@ -677,7 +678,7 @@ void FlameCreationTask::validateZIPResources(QEventLoop& loop)
} }
} }
// TODO make this work with other sorts of resource // TODO make this work with other sorts of resource
auto task = makeShared<ConcurrentTask>(this, "CreateModMetadata", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()); auto task = makeShared<ConcurrentTask>("CreateModMetadata", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt());
auto results = m_mod_id_resolver->getResults().files; auto results = m_mod_id_resolver->getResults().files;
auto folder = FS::PathCombine(m_stagingPath, "minecraft", "mods", ".index"); auto folder = FS::PathCombine(m_stagingPath, "minecraft", "mods", ".index");
for (auto file : results) { for (auto file : results) {

View File

@ -103,8 +103,7 @@ void FlamePackExportTask::collectHashes()
setStatus(tr("Finding file hashes...")); setStatus(tr("Finding file hashes..."));
setProgress(1, 5); setProgress(1, 5);
auto allMods = mcInstance->loaderModList()->allMods(); auto allMods = mcInstance->loaderModList()->allMods();
ConcurrentTask::Ptr hashingTask( ConcurrentTask::Ptr hashingTask(new ConcurrentTask("MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));
new ConcurrentTask(this, "MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));
task.reset(hashingTask); task.reset(hashingTask);
for (const QFileInfo& file : files) { for (const QFileInfo& file : files) {
const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath());

View File

@ -43,11 +43,16 @@ Task::Ptr NetworkResourceAPI::searchProjects(SearchArgs&& args, SearchCallbacks&
callbacks.on_succeed(doc); callbacks.on_succeed(doc);
}); });
QObject::connect(netJob.get(), &NetJob::failed, [netJob, callbacks](const QString& reason) { // Capture a weak_ptr instead of a shared_ptr to avoid circular dependency issues.
// This prevents the lambda from extending the lifetime of the shared resource,
// as it only temporarily locks the resource when needed.
auto weak = netJob.toWeakRef();
QObject::connect(netJob.get(), &NetJob::failed, [weak, callbacks](const QString& reason) {
int network_error_code = -1; int network_error_code = -1;
if (auto netJob = weak.lock()) {
if (auto* failed_action = netJob->getFailedActions().at(0); failed_action) if (auto* failed_action = netJob->getFailedActions().at(0); failed_action)
network_error_code = failed_action->replyStatusCode(); network_error_code = failed_action->replyStatusCode();
}
callbacks.on_fail(reason, network_error_code); callbacks.on_fail(reason, network_error_code);
}); });
QObject::connect(netJob.get(), &NetJob::aborted, [callbacks] { callbacks.on_abort(); }); QObject::connect(netJob.get(), &NetJob::aborted, [callbacks] { callbacks.on_abort(); });
@ -102,11 +107,17 @@ Task::Ptr NetworkResourceAPI::getProjectVersions(VersionSearchArgs&& args, Versi
callbacks.on_succeed(doc, args.pack); callbacks.on_succeed(doc, args.pack);
}); });
QObject::connect(netJob.get(), &NetJob::failed, [netJob, callbacks](const QString& reason) {
// Capture a weak_ptr instead of a shared_ptr to avoid circular dependency issues.
// This prevents the lambda from extending the lifetime of the shared resource,
// as it only temporarily locks the resource when needed.
auto weak = netJob.toWeakRef();
QObject::connect(netJob.get(), &NetJob::failed, [weak, callbacks](const QString& reason) {
int network_error_code = -1; int network_error_code = -1;
if (auto netJob = weak.lock()) {
if (auto* failed_action = netJob->getFailedActions().at(0); failed_action) if (auto* failed_action = netJob->getFailedActions().at(0); failed_action)
network_error_code = failed_action->replyStatusCode(); network_error_code = failed_action->replyStatusCode();
}
callbacks.on_fail(reason, network_error_code); callbacks.on_fail(reason, network_error_code);
}); });
@ -153,11 +164,17 @@ Task::Ptr NetworkResourceAPI::getDependencyVersion(DependencySearchArgs&& args,
callbacks.on_succeed(doc, args.dependency); callbacks.on_succeed(doc, args.dependency);
}); });
QObject::connect(netJob.get(), &NetJob::failed, [netJob, callbacks](const QString& reason) {
// Capture a weak_ptr instead of a shared_ptr to avoid circular dependency issues.
// This prevents the lambda from extending the lifetime of the shared resource,
// as it only temporarily locks the resource when needed.
auto weak = netJob.toWeakRef();
QObject::connect(netJob.get(), &NetJob::failed, [weak, callbacks](const QString& reason) {
int network_error_code = -1; int network_error_code = -1;
if (auto netJob = weak.lock()) {
if (auto* failed_action = netJob->getFailedActions().at(0); failed_action) if (auto* failed_action = netJob->getFailedActions().at(0); failed_action)
network_error_code = failed_action->replyStatusCode(); network_error_code = failed_action->replyStatusCode();
}
callbacks.on_fail(reason, network_error_code); callbacks.on_fail(reason, network_error_code);
}); });
return netJob; return netJob;

View File

@ -32,7 +32,7 @@ void ModrinthCheckUpdate::executeTask()
setProgress(0, (m_loaders_list.isEmpty() ? 1 : m_loaders_list.length()) * 2 + 1); setProgress(0, (m_loaders_list.isEmpty() ? 1 : m_loaders_list.length()) * 2 + 1);
auto hashing_task = auto hashing_task =
makeShared<ConcurrentTask>(this, "MakeModrinthHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()); makeShared<ConcurrentTask>("MakeModrinthHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt());
for (auto* resource : m_resources) { for (auto* resource : m_resources) {
auto hash = resource->metadata()->hash; auto hash = resource->metadata()->hash;
@ -99,8 +99,7 @@ void ModrinthCheckUpdate::checkVersionsResponse(std::shared_ptr<QByteArray> resp
// If the returned project is empty, but we have Modrinth metadata, // If the returned project is empty, but we have Modrinth metadata,
// it means this specific version is not available // it means this specific version is not available
if (project_obj.isEmpty()) { if (project_obj.isEmpty()) {
qDebug() << "Mod " << m_mappings.find(hash).value()->name() << " got an empty response." qDebug() << "Mod " << m_mappings.find(hash).value()->name() << " got an empty response." << "Hash: " << hash;
<< "Hash: " << hash;
++iter; ++iter;
continue; continue;
} }

View File

@ -45,7 +45,7 @@
#endif #endif
NetJob::NetJob(QString job_name, shared_qobject_ptr<QNetworkAccessManager> network, int max_concurrent) NetJob::NetJob(QString job_name, shared_qobject_ptr<QNetworkAccessManager> network, int max_concurrent)
: ConcurrentTask(nullptr, job_name), m_network(network) : ConcurrentTask(job_name), m_network(network)
{ {
#if defined(LAUNCHER_APPLICATION) #if defined(LAUNCHER_APPLICATION)
if (APPLICATION_DYN && max_concurrent < 0) if (APPLICATION_DYN && max_concurrent < 0)

View File

@ -38,7 +38,7 @@
#include <QDebug> #include <QDebug>
#include "tasks/Task.h" #include "tasks/Task.h"
ConcurrentTask::ConcurrentTask(QObject* parent, QString task_name, int max_concurrent) : Task(parent), m_total_max_size(max_concurrent) ConcurrentTask::ConcurrentTask(QString task_name, int max_concurrent) : Task(), m_total_max_size(max_concurrent)
{ {
setObjectName(task_name); setObjectName(task_name);
} }

View File

@ -48,7 +48,7 @@ class ConcurrentTask : public Task {
public: public:
using Ptr = shared_qobject_ptr<ConcurrentTask>; using Ptr = shared_qobject_ptr<ConcurrentTask>;
explicit ConcurrentTask(QObject* parent = nullptr, QString task_name = "", int max_concurrent = 6); explicit ConcurrentTask(QString task_name = "", int max_concurrent = 6);
~ConcurrentTask() override; ~ConcurrentTask() override;
// safe to call before starting the task // safe to call before starting the task

View File

@ -36,7 +36,7 @@
#include <QDebug> #include <QDebug>
MultipleOptionsTask::MultipleOptionsTask(QObject* parent, const QString& task_name) : ConcurrentTask(parent, task_name, 1) {} MultipleOptionsTask::MultipleOptionsTask(const QString& task_name) : ConcurrentTask(task_name, 1) {}
void MultipleOptionsTask::executeNextSubTask() void MultipleOptionsTask::executeNextSubTask()
{ {

View File

@ -42,7 +42,7 @@
class MultipleOptionsTask : public ConcurrentTask { class MultipleOptionsTask : public ConcurrentTask {
Q_OBJECT Q_OBJECT
public: public:
explicit MultipleOptionsTask(QObject* parent = nullptr, const QString& task_name = ""); explicit MultipleOptionsTask(const QString& task_name = "");
~MultipleOptionsTask() override = default; ~MultipleOptionsTask() override = default;
private slots: private slots:

View File

@ -38,7 +38,7 @@
#include <QDebug> #include <QDebug>
#include "tasks/ConcurrentTask.h" #include "tasks/ConcurrentTask.h"
SequentialTask::SequentialTask(QObject* parent, QString task_name) : ConcurrentTask(parent, task_name, 1) {} SequentialTask::SequentialTask(QString task_name) : ConcurrentTask(task_name, 1) {}
void SequentialTask::subTaskFailed(Task::Ptr task, const QString& msg) void SequentialTask::subTaskFailed(Task::Ptr task, const QString& msg)
{ {

View File

@ -47,7 +47,7 @@
class SequentialTask : public ConcurrentTask { class SequentialTask : public ConcurrentTask {
Q_OBJECT Q_OBJECT
public: public:
explicit SequentialTask(QObject* parent = nullptr, QString task_name = ""); explicit SequentialTask(QString task_name = "");
~SequentialTask() override = default; ~SequentialTask() override = default;
protected slots: protected slots:

View File

@ -40,7 +40,7 @@
Q_LOGGING_CATEGORY(taskLogC, "launcher.task") Q_LOGGING_CATEGORY(taskLogC, "launcher.task")
Task::Task(QObject* parent, bool show_debug) : QObject(parent), m_show_debug(show_debug) Task::Task(bool show_debug) : m_show_debug(show_debug)
{ {
m_uid = QUuid::createUuid(); m_uid = QUuid::createUuid();
setAutoDelete(false); setAutoDelete(false);

View File

@ -87,7 +87,7 @@ class Task : public QObject, public QRunnable {
enum class State { Inactive, Running, Succeeded, Failed, AbortedByUser }; enum class State { Inactive, Running, Succeeded, Failed, AbortedByUser };
public: public:
explicit Task(QObject* parent = 0, bool show_debug_log = true); explicit Task(bool show_debug_log = true);
virtual ~Task() = default; virtual ~Task() = default;
bool isRunning() const; bool isRunning() const;

View File

@ -46,7 +46,7 @@ BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, cons
: QDialog(parent), ui(new Ui::BlockedModsDialog), m_mods(mods), m_hash_type(hash_type) : QDialog(parent), ui(new Ui::BlockedModsDialog), m_mods(mods), m_hash_type(hash_type)
{ {
m_hashing_task = shared_qobject_ptr<ConcurrentTask>( m_hashing_task = shared_qobject_ptr<ConcurrentTask>(
new ConcurrentTask(this, "MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt())); new ConcurrentTask("MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));
connect(m_hashing_task.get(), &Task::finished, this, &BlockedModsDialog::hashTaskFinished); connect(m_hashing_task.get(), &Task::finished, this, &BlockedModsDialog::hashTaskFinished);
ui->setupUi(this); ui->setupUi(this);

View File

@ -85,7 +85,7 @@ int MSALoginDialog::exec()
connect(m_authflow_task.get(), &AuthFlow::authorizeWithBrowserWithExtra, this, &MSALoginDialog::authorizeWithBrowserWithExtra); connect(m_authflow_task.get(), &AuthFlow::authorizeWithBrowserWithExtra, this, &MSALoginDialog::authorizeWithBrowserWithExtra);
connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_authflow_task.get(), &Task::abort); connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_authflow_task.get(), &Task::abort);
m_devicecode_task.reset(new AuthFlow(m_account->accountData(), AuthFlow::Action::DeviceCode, this)); m_devicecode_task.reset(new AuthFlow(m_account->accountData(), AuthFlow::Action::DeviceCode));
connect(m_devicecode_task.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed); connect(m_devicecode_task.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed);
connect(m_devicecode_task.get(), &Task::succeeded, this, &QDialog::accept); connect(m_devicecode_task.get(), &Task::succeeded, this, &QDialog::accept);
connect(m_devicecode_task.get(), &Task::aborted, this, &MSALoginDialog::reject); connect(m_devicecode_task.get(), &Task::aborted, this, &MSALoginDialog::reject);

View File

@ -302,7 +302,7 @@ GetModDependenciesTask::Ptr ModDownloadDialog::getModDependenciesTask()
selectedVers.append(std::make_shared<GetModDependenciesTask::PackDependency>(selected->getPack(), selected->getVersion())); selectedVers.append(std::make_shared<GetModDependenciesTask::PackDependency>(selected->getPack(), selected->getVersion()));
} }
return makeShared<GetModDependenciesTask>(this, m_instance, model, selectedVers); return makeShared<GetModDependenciesTask>(m_instance, model, selectedVers);
} }
} }
return nullptr; return nullptr;

View File

@ -45,8 +45,7 @@ ResourceUpdateDialog::ResourceUpdateDialog(QWidget* parent,
, m_parent(parent) , m_parent(parent)
, m_resource_model(resource_model) , m_resource_model(resource_model)
, m_candidates(search_for) , m_candidates(search_for)
, m_second_try_metadata( , m_second_try_metadata(new ConcurrentTask("Second Metadata Search", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()))
new ConcurrentTask(nullptr, "Second Metadata Search", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()))
, m_instance(instance) , m_instance(instance)
, m_include_deps(include_deps) , m_include_deps(include_deps)
, m_filter_loaders(filter_loaders) , m_filter_loaders(filter_loaders)
@ -90,7 +89,7 @@ void ResourceUpdateDialog::checkCandidates()
auto versions = mcVersions(m_instance); auto versions = mcVersions(m_instance);
auto loadersList = m_filter_loaders ? mcLoadersList(m_instance) : QList<ModPlatform::ModLoaderType>(); auto loadersList = m_filter_loaders ? mcLoadersList(m_instance) : QList<ModPlatform::ModLoaderType>();
SequentialTask check_task(m_parent, tr("Checking for updates")); SequentialTask check_task(tr("Checking for updates"));
if (!m_modrinth_to_update.empty()) { if (!m_modrinth_to_update.empty()) {
m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loadersList, m_resource_model)); m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loadersList, m_resource_model));
@ -195,7 +194,7 @@ void ResourceUpdateDialog::checkCandidates()
auto* mod_model = dynamic_cast<ModFolderModel*>(m_resource_model.get()); auto* mod_model = dynamic_cast<ModFolderModel*>(m_resource_model.get());
if (mod_model != nullptr) { if (mod_model != nullptr) {
auto depTask = makeShared<GetModDependenciesTask>(this, m_instance, mod_model, selectedVers); auto depTask = makeShared<GetModDependenciesTask>(m_instance, mod_model, selectedVers);
connect(depTask.get(), &Task::failed, this, [this](const QString& reason) { connect(depTask.get(), &Task::failed, this, [this](const QString& reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec();
@ -269,7 +268,7 @@ auto ResourceUpdateDialog::ensureMetadata() -> bool
{ {
auto index_dir = indexDir(); auto index_dir = indexDir();
SequentialTask seq(m_parent, tr("Looking for metadata")); SequentialTask seq(tr("Looking for metadata"));
// A better use of data structures here could remove the need for this QHash // A better use of data structures here could remove the need for this QHash
QHash<QString, bool> should_try_others; QHash<QString, bool> should_try_others;

View File

@ -317,7 +317,7 @@ void InstallDialog::done(int result)
deletePath(); deletePath();
} }
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
auto seq = makeShared<SequentialTask>(this, tr("Install Java")); auto seq = makeShared<SequentialTask>(tr("Install Java"));
seq->addTask(task); seq->addTask(task);
seq->addTask(makeShared<Java::SymlinkTask>(final_path)); seq->addTask(makeShared<Java::SymlinkTask>(final_path));
task = seq; task = seq;

View File

@ -45,6 +45,24 @@
<string>Features</string> <string>Features</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_9"> <layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>473</width>
<height>770</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item> <item>
<widget class="QGroupBox" name="updateSettingsBox"> <widget class="QGroupBox" name="updateSettingsBox">
<property name="title"> <property name="title">
@ -359,6 +377,10 @@
</item> </item>
</layout> </layout>
</widget> </widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="userInterfaceTab"> <widget class="QWidget" name="userInterfaceTab">
<attribute name="title"> <attribute name="title">
<string>User Interface</string> <string>User Interface</string>

View File

@ -112,6 +112,7 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared
m_model->loadColumns(ui->treeView); m_model->loadColumns(ui->treeView);
connect(ui->treeView->header(), &QHeaderView::sectionResized, this, [this] { m_model->saveColumns(ui->treeView); }); connect(ui->treeView->header(), &QHeaderView::sectionResized, this, [this] { m_model->saveColumns(ui->treeView); });
connect(ui->filterEdit, &QLineEdit::textChanged, this, &ExternalResourcesPage::filterTextChanged);
} }
ExternalResourcesPage::~ExternalResourcesPage() ExternalResourcesPage::~ExternalResourcesPage()

View File

@ -51,22 +51,15 @@
#include "Application.h" #include "Application.h"
#include "ui/GuiUtil.h"
#include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/CustomMessageBox.h"
#include "ui/dialogs/ResourceDownloadDialog.h" #include "ui/dialogs/ResourceDownloadDialog.h"
#include "ui/dialogs/ResourceUpdateDialog.h" #include "ui/dialogs/ResourceUpdateDialog.h"
#include "DesktopServices.h"
#include "minecraft/PackProfile.h" #include "minecraft/PackProfile.h"
#include "minecraft/VersionFilterData.h" #include "minecraft/VersionFilterData.h"
#include "minecraft/mod/Mod.h" #include "minecraft/mod/Mod.h"
#include "minecraft/mod/ModFolderModel.h" #include "minecraft/mod/ModFolderModel.h"
#include "modplatform/ModIndex.h"
#include "modplatform/ResourceAPI.h"
#include "Version.h"
#include "tasks/ConcurrentTask.h" #include "tasks/ConcurrentTask.h"
#include "tasks/Task.h" #include "tasks/Task.h"
#include "ui/dialogs/ProgressDialog.h" #include "ui/dialogs/ProgressDialog.h"
@ -155,7 +148,7 @@ void ModFolderPage::downloadMods()
ResourceDownload::ModDownloadDialog mdownload(this, m_model, m_instance); ResourceDownload::ModDownloadDialog mdownload(this, m_model, m_instance);
if (mdownload.exec()) { if (mdownload.exec()) {
auto tasks = new ConcurrentTask(this, tr("Download Mods"), APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt()); auto tasks = new ConcurrentTask(tr("Download Mods"), APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();
@ -238,7 +231,7 @@ void ModFolderPage::updateMods(bool includeDeps)
} }
if (update_dialog.exec()) { if (update_dialog.exec()) {
auto tasks = new ConcurrentTask(this, "Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt()); auto tasks = new ConcurrentTask("Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();
@ -310,7 +303,7 @@ void ModFolderPage::changeModVersion()
ResourceDownload::ModDownloadDialog mdownload(this, m_model, m_instance); ResourceDownload::ModDownloadDialog mdownload(this, m_model, m_instance);
mdownload.setResourceMetadata((*mods_list.begin())->metadata()); mdownload.setResourceMetadata((*mods_list.begin())->metadata());
if (mdownload.exec()) { if (mdownload.exec()) {
auto tasks = new ConcurrentTask(this, "Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt()); auto tasks = new ConcurrentTask("Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();

View File

@ -37,8 +37,6 @@
#include "ResourcePackPage.h" #include "ResourcePackPage.h"
#include "ResourceDownloadTask.h"
#include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/CustomMessageBox.h"
#include "ui/dialogs/ProgressDialog.h" #include "ui/dialogs/ProgressDialog.h"
#include "ui/dialogs/ResourceDownloadDialog.h" #include "ui/dialogs/ResourceDownloadDialog.h"
@ -88,8 +86,7 @@ void ResourcePackPage::downloadResourcePacks()
ResourceDownload::ResourcePackDownloadDialog mdownload(this, m_model, m_instance); ResourceDownload::ResourcePackDownloadDialog mdownload(this, m_model, m_instance);
if (mdownload.exec()) { if (mdownload.exec()) {
auto tasks = auto tasks = new ConcurrentTask("Download Resource Pack", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
new ConcurrentTask(this, "Download Resource Pack", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();
@ -168,8 +165,7 @@ void ResourcePackPage::updateResourcePacks()
} }
if (update_dialog.exec()) { if (update_dialog.exec()) {
auto tasks = auto tasks = new ConcurrentTask("Download Resource Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
new ConcurrentTask(this, "Download Resource Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();
@ -242,8 +238,7 @@ void ResourcePackPage::changeResourcePackVersion()
ResourceDownload::ResourcePackDownloadDialog mdownload(this, m_model, m_instance); ResourceDownload::ResourcePackDownloadDialog mdownload(this, m_model, m_instance);
mdownload.setResourceMetadata(resource.metadata()); mdownload.setResourceMetadata(resource.metadata());
if (mdownload.exec()) { if (mdownload.exec()) {
auto tasks = auto tasks = new ConcurrentTask("Download Resource Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
new ConcurrentTask(this, "Download Resource Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();

View File

@ -83,7 +83,7 @@ void ShaderPackPage::downloadShaderPack()
ResourceDownload::ShaderPackDownloadDialog mdownload(this, m_model, m_instance); ResourceDownload::ShaderPackDownloadDialog mdownload(this, m_model, m_instance);
if (mdownload.exec()) { if (mdownload.exec()) {
auto tasks = new ConcurrentTask(this, "Download Shader Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt()); auto tasks = new ConcurrentTask("Download Shader Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();
@ -162,7 +162,7 @@ void ShaderPackPage::updateShaderPacks()
} }
if (update_dialog.exec()) { if (update_dialog.exec()) {
auto tasks = new ConcurrentTask(this, "Download Shader Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt()); auto tasks = new ConcurrentTask("Download Shader Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();
@ -235,8 +235,7 @@ void ShaderPackPage::changeShaderPackVersion()
ResourceDownload::ShaderPackDownloadDialog mdownload(this, m_model, m_instance); ResourceDownload::ShaderPackDownloadDialog mdownload(this, m_model, m_instance);
mdownload.setResourceMetadata(resource.metadata()); mdownload.setResourceMetadata(resource.metadata());
if (mdownload.exec()) { if (mdownload.exec()) {
auto tasks = auto tasks = new ConcurrentTask("Download Shader Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
new ConcurrentTask(this, "Download Shader Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();

View File

@ -92,8 +92,7 @@ void TexturePackPage::downloadTexturePacks()
ResourceDownload::TexturePackDownloadDialog mdownload(this, m_model, m_instance); ResourceDownload::TexturePackDownloadDialog mdownload(this, m_model, m_instance);
if (mdownload.exec()) { if (mdownload.exec()) {
auto tasks = auto tasks = new ConcurrentTask("Download Texture Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
new ConcurrentTask(this, "Download Texture Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();
@ -172,8 +171,7 @@ void TexturePackPage::updateTexturePacks()
} }
if (update_dialog.exec()) { if (update_dialog.exec()) {
auto tasks = auto tasks = new ConcurrentTask("Download Texture Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
new ConcurrentTask(this, "Download Texture Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();
@ -223,7 +221,8 @@ void TexturePackPage::deleteTexturePackMetadata()
m_model->deleteMetadata(selection); m_model->deleteMetadata(selection);
} }
void TexturePackPage::changeTexturePackVersion() { void TexturePackPage::changeTexturePackVersion()
{
if (m_instance->typeName() != "Minecraft") if (m_instance->typeName() != "Minecraft")
return; // this is a null instance or a legacy instance return; // this is a null instance or a legacy instance
@ -245,8 +244,7 @@ void TexturePackPage::changeTexturePackVersion() {
ResourceDownload::TexturePackDownloadDialog mdownload(this, m_model, m_instance); ResourceDownload::TexturePackDownloadDialog mdownload(this, m_model, m_instance);
mdownload.setResourceMetadata(resource.metadata()); mdownload.setResourceMetadata(resource.metadata());
if (mdownload.exec()) { if (mdownload.exec()) {
auto tasks = auto tasks = new ConcurrentTask("Download Texture Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
new ConcurrentTask(this, "Download Texture Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
connect(tasks, &Task::failed, [this, tasks](QString reason) { connect(tasks, &Task::failed, [this, tasks](QString reason) {
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
tasks->deleteLater(); tasks->deleteLater();

View File

@ -435,7 +435,7 @@ void VersionPage::on_actionDownload_All_triggered()
if (updateTasks.isEmpty()) { if (updateTasks.isEmpty()) {
return; return;
} }
auto task = makeShared<SequentialTask>(this); auto task = makeShared<SequentialTask>();
for (auto t : updateTasks) { for (auto t : updateTasks) {
task->addTask(t); task->addTask(t);
} }

View File

@ -460,7 +460,7 @@ void JavaSettingsWidget::checkJavaPath(const QString& path)
} }
setJavaStatus(JavaStatus::Pending); setJavaStatus(JavaStatus::Pending);
m_checker.reset( m_checker.reset(
new JavaChecker(path, "", minHeapSize(), maxHeapSize(), m_permGenSpinBox->isVisible() ? m_permGenSpinBox->value() : 0, 0, this)); new JavaChecker(path, "", minHeapSize(), maxHeapSize(), m_permGenSpinBox->isVisible() ? m_permGenSpinBox->value() : 0, 0));
connect(m_checker.get(), &JavaChecker::checkFinished, this, &JavaSettingsWidget::checkFinished); connect(m_checker.get(), &JavaChecker::checkFinished, this, &JavaSettingsWidget::checkFinished);
m_checker->start(); m_checker->start();
} }

View File

@ -16,7 +16,7 @@ class BasicTask : public Task {
friend class TaskTest; friend class TaskTest;
public: public:
BasicTask(bool show_debug_log = true) : Task(nullptr, show_debug_log) {} BasicTask(bool show_debug_log = true) : Task(show_debug_log) {}
private: private:
void executeTask() override { emitSucceeded(); } void executeTask() override { emitSucceeded(); }