Skip to content
Permalink
Browse files

Merge pull request #7968 from Techjar/fix-netplay-browser-search-hang

Qt/NetPlayBrowser: Refresh session list asynchronously
  • Loading branch information...
spycrab committed Apr 14, 2019
2 parents 1cedbd5 + c7c4196 commit 0f8e5ab207b47331595af99df0b699de1081d9f1
Showing with 94 additions and 28 deletions.
  1. +79 −28 Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp
  2. +15 −0 Source/Core/DolphinQt/NetPlay/NetPlayBrowser.h
@@ -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();

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")});

const int session_count = static_cast<int>(entries.value().size());
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 @@ class NetPlayBrowser : public QDialog
void ConnectWidgets();

void Refresh();
void RefreshLoop();
void UpdateList();

void OnSelectionChanged();

@@ -51,4 +60,10 @@ class NetPlayBrowser : public QDialog
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;
};

0 comments on commit 0f8e5ab

Please sign in to comment.
You can’t perform that action at this time.