diff --git a/Source/Core/DolphinQt2/QtUtils/QueueOnObject.h b/Source/Core/DolphinQt2/QtUtils/QueueOnObject.h new file mode 100644 index 0000000000..6110bccb79 --- /dev/null +++ b/Source/Core/DolphinQt2/QtUtils/QueueOnObject.h @@ -0,0 +1,20 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +// QWidget and subclasses are not thread-safe! However, Qt's signal-slot connection mechanism will +// invoke slots/functions on the correct thread for any object. We can (ab)use this to queue up +// arbitrary code from non-GUI threads. For more information, see: +// https://stackoverflow.com/questions/21646467/ + +template +static void QueueOnObject(QObject* obj, F&& func) +{ + QObject src; + QObject::connect(&src, &QObject::destroyed, obj, std::forward(func), Qt::QueuedConnection); +} diff --git a/Source/Core/DolphinQt2/WiiUpdate.cpp b/Source/Core/DolphinQt2/WiiUpdate.cpp index 8db46852e0..de91fc0e32 100644 --- a/Source/Core/DolphinQt2/WiiUpdate.cpp +++ b/Source/Core/DolphinQt2/WiiUpdate.cpp @@ -18,6 +18,7 @@ #include "Core/Core.h" #include "Core/WiiUtils.h" #include "DiscIO/NANDImporter.h" +#include "DolphinQt2/QtUtils/QueueOnObject.h" namespace WiiUpdate { @@ -62,21 +63,19 @@ void PerformOnlineUpdate(const std::string& region, QWidget* parent) std::future result = std::async(std::launch::async, [&] { const WiiUtils::UpdateResult res = WiiUtils::DoOnlineUpdate( [&](size_t processed, size_t total, u64 title_id) { - Core::QueueHostJob( - [&dialog, &was_cancelled, processed, total, title_id]() { - if (was_cancelled.IsSet()) - return; + QueueOnObject(&dialog, [&dialog, &was_cancelled, processed, total, title_id]() { + if (was_cancelled.IsSet()) + return; - dialog.setRange(0, static_cast(total)); - dialog.setValue(static_cast(processed)); - dialog.setLabelText(QObject::tr("Updating title %1...\nThis can take a while.") - .arg(title_id, 16, 16, QLatin1Char('0'))); - }, - true); + dialog.setRange(0, static_cast(total)); + dialog.setValue(static_cast(processed)); + dialog.setLabelText(QObject::tr("Updating title %1...\nThis can take a while.") + .arg(title_id, 16, 16, QLatin1Char('0'))); + }); return !was_cancelled.IsSet(); }, region); - Core::QueueHostJob([&dialog] { dialog.close(); }, true); + QueueOnObject(&dialog, [&dialog] { dialog.close(); }); return res; });