diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 9a1ed440e5..11b80a0063 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -48,6 +48,7 @@ #include "net/PasteUpload.h" #include "pathmatcher/MultiMatcher.h" #include "pathmatcher/SimplePrefixMatcher.h" +#include "tasks/Task.h" #include "tools/GenericProfiler.h" #include "ui/InstanceWindow.h" #include "ui/MainWindow.h" @@ -1397,6 +1398,7 @@ bool Application::launch(InstancePtr instance, if (m_updateRunning) { qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed."; } else if (instance->canLaunch()) { + QMutexLocker locker(&m_instanceExtrasMutex); auto& extras = m_instanceExtras[instance->id()]; auto window = extras.window; if (window) { @@ -1422,7 +1424,7 @@ bool Application::launch(InstancePtr instance, connect(controller.get(), &LaunchController::failed, this, &Application::controllerFailed); connect(controller.get(), &LaunchController::aborted, this, [this] { controllerFailed(tr("Aborted")); }); addRunningInstance(); - controller->start(); + QMetaObject::invokeMethod(controller.get(), &Task::start, Qt::QueuedConnection); return true; } else if (instance->isRunning()) { showInstanceWindow(instance, "console"); @@ -1440,9 +1442,11 @@ bool Application::kill(InstancePtr instance) qWarning() << "Attempted to kill instance" << instance->id() << ", which isn't running."; return false; } + QMutexLocker locker(&m_instanceExtrasMutex); auto& extras = m_instanceExtras[instance->id()]; // NOTE: copy of the shared pointer keeps it alive auto controller = extras.controller; + locker.unlock(); if (controller) { return controller->abort(); } @@ -1496,6 +1500,8 @@ void Application::controllerSucceeded() if (!controller) return; auto id = controller->id(); + + QMutexLocker locker(&m_instanceExtrasMutex); auto& extras = m_instanceExtras[id]; // on success, do... @@ -1521,6 +1527,7 @@ void Application::controllerFailed(const QString& error) if (!controller) return; auto id = controller->id(); + QMutexLocker locker(&m_instanceExtrasMutex); auto& extras = m_instanceExtras[id]; // on failure, do... nothing @@ -1578,6 +1585,7 @@ InstanceWindow* Application::showInstanceWindow(InstancePtr instance, QString pa if (!instance) return nullptr; auto id = instance->id(); + QMutexLocker locker(&m_instanceExtrasMutex); auto& extras = m_instanceExtras[id]; auto& window = extras.window; @@ -1615,6 +1623,7 @@ void Application::on_windowClose() m_openWindows--; auto instWindow = qobject_cast(QObject::sender()); if (instWindow) { + QMutexLocker locker(&m_instanceExtrasMutex); auto& extras = m_instanceExtras[instWindow->instanceId()]; extras.window = nullptr; if (extras.controller) { diff --git a/launcher/Application.h b/launcher/Application.h index 6b218f9f89..dad76d7026 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -280,6 +280,7 @@ class Application : public QApplication { shared_qobject_ptr controller; }; std::map m_instanceExtras; + mutable QMutex m_instanceExtrasMutex; // main state variables size_t m_openWindows = 0; diff --git a/launcher/SysInfo.cpp b/launcher/SysInfo.cpp index 0dfa74de7f..cfcf638055 100644 --- a/launcher/SysInfo.cpp +++ b/launcher/SysInfo.cpp @@ -81,9 +81,9 @@ QString getSupportedJavaArchitecture() if (arch == "arm64") return "mac-os-arm64"; if (arch.contains("64")) - return "mac-os-64"; + return "mac-os-x64"; if (arch.contains("86")) - return "mac-os-86"; + return "mac-os-x86"; // Unknown, maybe something new, appending arch return "mac-os-" + arch; } else if (sys == "linux") { diff --git a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h deleted file mode 100644 index fb2e22de68..0000000000 --- a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include - -#include "Application.h" -#include "FileSystem.h" -#include "minecraft/mod/Resource.h" - -#include "tasks/Task.h" - -/** Very simple task that just loads a folder's contents directly. - */ -class BasicFolderLoadTask : public Task { - Q_OBJECT - public: - struct Result { - QMap resources; - }; - using ResultPtr = std::shared_ptr; - - [[nodiscard]] ResultPtr result() const { return m_result; } - - public: - BasicFolderLoadTask(QDir dir) : Task(nullptr, false), m_dir(dir), m_result(new Result), m_thread_to_spawn_into(thread()) - { - m_create_func = [](QFileInfo const& entry) -> Resource::Ptr { return makeShared(entry); }; - } - BasicFolderLoadTask(QDir dir, std::function create_function) - : Task(nullptr, false) - , m_dir(dir) - , m_result(new Result) - , m_create_func(std::move(create_function)) - , m_thread_to_spawn_into(thread()) - {} - - [[nodiscard]] bool canAbort() const override { return true; } - bool abort() override - { - m_aborted.store(true); - return true; - } - - void executeTask() override - { - if (thread() != m_thread_to_spawn_into) - connect(this, &Task::finished, this->thread(), &QThread::quit); - - m_dir.refresh(); - for (auto entry : m_dir.entryInfoList()) { - auto filePath = entry.absoluteFilePath(); - if (auto app = APPLICATION_DYN; app && app->checkQSavePath(filePath)) { - continue; - } - auto newFilePath = FS::getUniqueResourceName(filePath); - if (newFilePath != filePath) { - FS::move(filePath, newFilePath); - entry = QFileInfo(newFilePath); - } - auto resource = m_create_func(entry); - resource->moveToThread(m_thread_to_spawn_into); - m_result->resources.insert(resource->internal_id(), resource); - } - - if (m_aborted) - emit finished(); - else - emitSucceeded(); - } - - private: - QDir m_dir; - ResultPtr m_result; - - std::atomic m_aborted = false; - - std::function m_create_func; - - /** This is the thread in which we should put new mod objects */ - QThread* m_thread_to_spawn_into; -};