Merge pull request #7968 from Techjar/fix-netplay-browser-search-hang
Qt/NetPlayBrowser: Refresh session list asynchronously
This commit is contained in:
commit
0f8e5ab207
|
@ -26,6 +26,7 @@
|
|||
#include "Core/ConfigManager.h"
|
||||
|
||||
#include "DolphinQt/QtUtils/ModalMessageBox.h"
|
||||
#include "DolphinQt/QtUtils/RunOnObject.h"
|
||||
|
||||
NetPlayBrowser::NetPlayBrowser(QWidget* parent) : QDialog(parent)
|
||||
{
|
||||
|
@ -40,9 +41,21 @@ NetPlayBrowser::NetPlayBrowser(QWidget* parent) : QDialog(parent)
|
|||
m_table_widget->verticalHeader()->setHidden(true);
|
||||
m_table_widget->setAlternatingRowColors(true);
|
||||
|
||||
m_refresh_run.Set(true);
|
||||
m_refresh_thread = std::thread([this] { RefreshLoop(); });
|
||||
|
||||
UpdateList();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
NetPlayBrowser::~NetPlayBrowser()
|
||||
{
|
||||
m_refresh_run.Set(false);
|
||||
m_refresh_event.Set();
|
||||
if (m_refresh_thread.joinable())
|
||||
m_refresh_thread.join();
|
||||
}
|
||||
|
||||
void NetPlayBrowser::CreateWidgets()
|
||||
{
|
||||
auto* layout = new QVBoxLayout;
|
||||
|
@ -109,6 +122,9 @@ void NetPlayBrowser::CreateWidgets()
|
|||
|
||||
void NetPlayBrowser::ConnectWidgets()
|
||||
{
|
||||
connect(m_region_combo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &NetPlayBrowser::Refresh);
|
||||
|
||||
connect(m_button_box, &QDialogButtonBox::accepted, this, &NetPlayBrowser::accept);
|
||||
connect(m_button_box, &QDialogButtonBox::rejected, this, &NetPlayBrowser::reject);
|
||||
connect(m_button_refresh, &QPushButton::pressed, this, &NetPlayBrowser::Refresh);
|
||||
|
@ -125,25 +141,6 @@ void NetPlayBrowser::ConnectWidgets()
|
|||
|
||||
void NetPlayBrowser::Refresh()
|
||||
{
|
||||
m_status_label->setText(tr("Refreshing..."));
|
||||
|
||||
m_table_widget->clear();
|
||||
m_table_widget->setColumnCount(7);
|
||||
m_table_widget->setHorizontalHeaderLabels({tr("Region"), tr("Name"), tr("Password?"),
|
||||
tr("In-Game?"), tr("Game"), tr("Players"),
|
||||
tr("Version")});
|
||||
|
||||
auto* hor_header = m_table_widget->horizontalHeader();
|
||||
|
||||
hor_header->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
hor_header->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
hor_header->setSectionResizeMode(2, QHeaderView::ResizeToContents);
|
||||
hor_header->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
||||
hor_header->setSectionResizeMode(4, QHeaderView::Stretch);
|
||||
hor_header->setHighlightSections(false);
|
||||
|
||||
NetPlayIndex client;
|
||||
|
||||
std::map<std::string, std::string> filters;
|
||||
|
||||
if (m_check_hide_incompatible->isChecked())
|
||||
|
@ -161,22 +158,78 @@ void NetPlayBrowser::Refresh()
|
|||
if (m_region_combo->currentIndex() != 0)
|
||||
filters["region"] = m_region_combo->currentData().toString().toStdString();
|
||||
|
||||
auto entries = client.List(filters);
|
||||
std::unique_lock<std::mutex> lock(m_refresh_filters_mutex);
|
||||
m_refresh_filters = std::move(filters);
|
||||
m_refresh_event.Set();
|
||||
}
|
||||
|
||||
if (!entries)
|
||||
void NetPlayBrowser::RefreshLoop()
|
||||
{
|
||||
while (m_refresh_run.IsSet())
|
||||
{
|
||||
m_status_label->setText(
|
||||
tr("Error obtaining session list: %1").arg(QString::fromStdString(client.GetLastError())));
|
||||
return;
|
||||
}
|
||||
m_refresh_event.Wait();
|
||||
|
||||
const int session_count = static_cast<int>(entries.value().size());
|
||||
std::unique_lock<std::mutex> lock(m_refresh_filters_mutex);
|
||||
if (m_refresh_filters)
|
||||
{
|
||||
auto filters = std::move(*m_refresh_filters);
|
||||
m_refresh_filters.reset();
|
||||
|
||||
lock.unlock();
|
||||
|
||||
RunOnObject(this, [this] {
|
||||
m_status_label->setText(tr("Refreshing..."));
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
NetPlayIndex client;
|
||||
|
||||
auto entries = client.List(filters);
|
||||
|
||||
if (entries)
|
||||
{
|
||||
RunOnObject(this, [this, &entries] {
|
||||
m_sessions = *entries;
|
||||
UpdateList();
|
||||
return nullptr;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
RunOnObject(this, [this, &client] {
|
||||
m_status_label->setText(tr("Error obtaining session list: %1")
|
||||
.arg(QString::fromStdString(client.GetLastError())));
|
||||
return nullptr;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetPlayBrowser::UpdateList()
|
||||
{
|
||||
const int session_count = static_cast<int>(m_sessions.size());
|
||||
|
||||
m_table_widget->clear();
|
||||
m_table_widget->setColumnCount(7);
|
||||
m_table_widget->setHorizontalHeaderLabels({tr("Region"), tr("Name"), tr("Password?"),
|
||||
tr("In-Game?"), tr("Game"), tr("Players"),
|
||||
tr("Version")});
|
||||
|
||||
auto* hor_header = m_table_widget->horizontalHeader();
|
||||
|
||||
hor_header->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
hor_header->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
hor_header->setSectionResizeMode(2, QHeaderView::ResizeToContents);
|
||||
hor_header->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
||||
hor_header->setSectionResizeMode(4, QHeaderView::Stretch);
|
||||
hor_header->setHighlightSections(false);
|
||||
|
||||
m_table_widget->setRowCount(session_count);
|
||||
|
||||
for (int i = 0; i < session_count; i++)
|
||||
{
|
||||
const auto& entry = entries.value()[i];
|
||||
const auto& entry = m_sessions[i];
|
||||
|
||||
auto* region = new QTableWidgetItem(QString::fromStdString(entry.region));
|
||||
auto* name = new QTableWidgetItem(QString::fromStdString(entry.name));
|
||||
|
@ -202,8 +255,6 @@ void NetPlayBrowser::Refresh()
|
|||
|
||||
m_status_label->setText(
|
||||
(session_count == 1 ? tr("%1 session found") : tr("%1 sessions found")).arg(session_count));
|
||||
|
||||
m_sessions = entries.value();
|
||||
}
|
||||
|
||||
void NetPlayBrowser::OnSelectionChanged()
|
||||
|
|
|
@ -4,10 +4,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "Common/Event.h"
|
||||
#include "Common/Flag.h"
|
||||
#include "UICommon/NetPlayIndex.h"
|
||||
|
||||
class QCheckBox;
|
||||
|
@ -24,6 +30,7 @@ class NetPlayBrowser : public QDialog
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit NetPlayBrowser(QWidget* parent = nullptr);
|
||||
~NetPlayBrowser();
|
||||
|
||||
void accept() override;
|
||||
signals:
|
||||
|
@ -34,6 +41,8 @@ private:
|
|||
void ConnectWidgets();
|
||||
|
||||
void Refresh();
|
||||
void RefreshLoop();
|
||||
void UpdateList();
|
||||
|
||||
void OnSelectionChanged();
|
||||
|
||||
|
@ -51,4 +60,10 @@ private:
|
|||
QRadioButton* m_radio_public;
|
||||
|
||||
std::vector<NetPlaySession> m_sessions;
|
||||
|
||||
std::thread m_refresh_thread;
|
||||
std::optional<std::map<std::string, std::string>> m_refresh_filters;
|
||||
std::mutex m_refresh_filters_mutex;
|
||||
Common::Flag m_refresh_run;
|
||||
Common::Event m_refresh_event;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue