Implement manually adding PCs

This commit is contained in:
Cameron Gutman 2018-07-06 00:34:16 -07:00
parent 6687936e2f
commit ecebf75b88
6 changed files with 135 additions and 58 deletions

View File

@ -421,58 +421,12 @@ void ComputerManager::stopPollingAsync()
}
}
bool ComputerManager::addNewHost(QString address, bool mdns)
void ComputerManager::addNewHost(QString address, bool mdns)
{
NvHTTP http(address);
QString serverInfo;
try {
serverInfo = http.getServerInfo();
} catch (...) {
return false;
}
NvComputer* newComputer = new NvComputer(address, serverInfo);
// Update addresses depending on the context
if (mdns) {
newComputer->localAddress = address;
}
else {
newComputer->manualAddress = address;
}
// Check if this PC already exists
QWriteLocker lock(&m_Lock);
NvComputer* existingComputer = m_KnownHosts[newComputer->uuid];
if (existingComputer != nullptr) {
// Fold it into the existing PC
bool changed = existingComputer->update(*newComputer);
delete newComputer;
// Drop the lock before notifying
lock.unlock();
// Tell our client if something changed
if (changed) {
handleComputerStateChanged(existingComputer);
}
}
else {
// Store this in our active sets
m_KnownHosts[newComputer->uuid] = newComputer;
// Start polling if enabled (write lock required)
startPollingComputer(newComputer);
// Drop the lock before notifying
lock.unlock();
// Tell our client about this new PC
handleComputerStateChanged(newComputer);
}
return true;
// Punt to a worker thread to avoid stalling the
// UI while waiting for serverinfo query to complete
PendingAddTask* addTask = new PendingAddTask(this, address, mdns);
QThreadPool::globalInstance()->start(addTask);
}
void

View File

@ -242,6 +242,7 @@ class ComputerManager : public QObject
Q_OBJECT
friend class DeferredHostDeletionTask;
friend class PendingAddTask;
public:
explicit ComputerManager(QObject *parent = nullptr);
@ -250,7 +251,7 @@ public:
Q_INVOKABLE void stopPollingAsync();
Q_INVOKABLE bool addNewHost(QString address, bool mdns);
Q_INVOKABLE void addNewHost(QString address, bool mdns);
void pairHost(NvComputer* computer, QString pin);
@ -264,6 +265,8 @@ signals:
void pairingCompleted(NvComputer* computer, QString error);
void computerAddCompleted(QVariant success);
private slots:
void handleComputerStateChanged(NvComputer* computer);
@ -334,3 +337,93 @@ private:
NvComputer* m_Computer;
QString m_Pin;
};
class PendingAddTask : public QObject, public QRunnable
{
Q_OBJECT
public:
PendingAddTask(ComputerManager* computerManager, QString address, bool mdns)
: m_ComputerManager(computerManager),
m_Address(address),
m_Mdns(mdns)
{
connect(this, &PendingAddTask::computerAddCompleted,
computerManager, &ComputerManager::computerAddCompleted);
connect(this, &PendingAddTask::computerStateChanged,
computerManager, &ComputerManager::handleComputerStateChanged);
}
signals:
void computerAddCompleted(QVariant success);
void computerStateChanged(NvComputer* computer);
private:
void run()
{
NvHTTP http(m_Address);
QString serverInfo;
try {
serverInfo = http.getServerInfo();
} catch (...) {
emit computerAddCompleted(false);
return;
}
NvComputer* newComputer = new NvComputer(m_Address, serverInfo);
// Update addresses depending on the context
if (m_Mdns) {
newComputer->localAddress = m_Address;
}
else {
newComputer->manualAddress = m_Address;
}
// Check if this PC already exists
QWriteLocker lock(&m_ComputerManager->m_Lock);
NvComputer* existingComputer = m_ComputerManager->m_KnownHosts[newComputer->uuid];
if (existingComputer != nullptr) {
// Fold it into the existing PC
bool changed = existingComputer->update(*newComputer);
delete newComputer;
// Drop the lock before notifying
lock.unlock();
// For non-mDNS clients, let them know it succeeded
if (!m_Mdns) {
emit computerAddCompleted(true);
}
// Tell our client if something changed
if (changed) {
emit computerStateChanged(existingComputer);
}
}
else {
// Store this in our active sets
m_ComputerManager->m_KnownHosts[newComputer->uuid] = newComputer;
// Start polling if enabled (write lock required)
m_ComputerManager->startPollingComputer(newComputer);
// Drop the lock before notifying
lock.unlock();
// For non-mDNS clients, let them know it succeeded
if (!m_Mdns) {
emit computerAddCompleted(true);
}
// Tell our client about this new PC
emit computerStateChanged(newComputer);
}
}
ComputerManager* m_ComputerManager;
QString m_Address;
bool m_Mdns;
};

View File

@ -16,6 +16,16 @@ GridView {
cellWidth: 225; cellHeight: 350;
focus: true
Component.onCompleted: {
// Start polling when this view is shown
ComputerManager.startPolling()
}
Component.onDestruction: {
// Stop polling when this view is destroyed
ComputerManager.stopPollingAsync()
}
function createModel()
{
var model = Qt.createQmlObject('import AppModel 1.0; AppModel {}', parent, '')

View File

@ -21,6 +21,9 @@ GridView {
Component.onCompleted: {
// Start polling when this view is shown
ComputerManager.startPolling()
// Setup signals on CM
ComputerManager.computerAddCompleted.connect(addComplete)
}
Component.onDestruction: {
@ -38,8 +41,16 @@ GridView {
// Display a failed dialog if we got an error
if (error !== null) {
pairingFailedDialog.text = error
pairingFailedDialog.open()
errorDialog.text = error
errorDialog.open()
}
}
function addComplete(success)
{
if (!success) {
errorDialog.text = "Unable to connect to the specified PC. Ensure GameStream is enabled in GeForce Experience."
errorDialog.open()
}
}
@ -145,8 +156,8 @@ GridView {
}
else {
// cannot pair while something is streaming or attempting to pair
pairingFailedDialog.text = "This PC is currently busy. Make sure to quit any running games and try again."
pairingFailedDialog.open()
errorDialog.text = "This PC is currently busy. Make sure to quit any running games and try again."
errorDialog.open()
}
}
}
@ -158,7 +169,7 @@ GridView {
}
MessageDialog {
id: pairingFailedDialog
id: errorDialog
// don't allow edits to the rest of the window while open
modality:Qt.WindowModal
icon: StandardIcon.Critical
@ -189,7 +200,7 @@ GridView {
editTextItem.selectAll()
}
onAccepted: {
console.log("accepted, with value: " + editText.text)
ComputerManager.addNewHost(editText.text, false)
}
ColumnLayout {

View File

@ -93,6 +93,13 @@ void ComputerModel::deleteComputer(int computerIndex)
endRemoveRows();
}
bool ComputerModel::wakeComputer(int computerIndex)
{
Q_ASSERT(computerIndex < m_Computers.count());
return m_Computers[computerIndex]->wake();
}
void ComputerModel::pairComputer(int computerIndex, QString pin)
{
Q_ASSERT(computerIndex < m_Computers.count());

View File

@ -31,6 +31,8 @@ public:
Q_INVOKABLE void pairComputer(int computerIndex, QString pin);
Q_INVOKABLE bool wakeComputer(int computerIndex);
signals:
void pairingCompleted(QVariant error);