Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qt/NetPlayBrowser: Refresh session list asynchronously #7968

Merged
merged 1 commit into from Apr 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
107 changes: 79 additions & 28 deletions Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp
Expand Up @@ -26,6 +26,7 @@
#include "Core/ConfigManager.h"

#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/RunOnObject.h"

NetPlayBrowser::NetPlayBrowser(QWidget* parent) : QDialog(parent)
{
Expand All @@ -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;
Expand Down Expand Up @@ -107,6 +120,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);
Expand All @@ -123,25 +139,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())
Expand All @@ -159,22 +156,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));
Expand All @@ -200,8 +253,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()
Expand Down
15 changes: 15 additions & 0 deletions Source/Core/DolphinQt/NetPlay/NetPlayBrowser.h
Expand Up @@ -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;
Expand All @@ -24,6 +30,7 @@ class NetPlayBrowser : public QDialog
Q_OBJECT
public:
explicit NetPlayBrowser(QWidget* parent = nullptr);
~NetPlayBrowser();

void accept() override;
signals:
Expand All @@ -34,6 +41,8 @@ class NetPlayBrowser : public QDialog
void ConnectWidgets();

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

void OnSelectionChanged();

Expand All @@ -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;
};