diff --git a/app/backend/nvhttp.cpp b/app/backend/nvhttp.cpp index 8d08e158..bbbe8540 100644 --- a/app/backend/nvhttp.cpp +++ b/app/backend/nvhttp.cpp @@ -304,8 +304,7 @@ NvHTTP::getAppList() // We must have a valid app before advancing to the next one if (!apps.isEmpty() && !apps.last().isInitialized()) { qWarning() << "Invalid applist XML"; - Q_ASSERT(false); - return QVector(); + throw std::runtime_error("Invalid applist XML"); } apps.append(NvApp()); } diff --git a/app/cli/listapps.cpp b/app/cli/listapps.cpp index 29f966d3..c2d2bd1f 100644 --- a/app/cli/listapps.cpp +++ b/app/cli/listapps.cpp @@ -5,10 +5,8 @@ #include "backend/computerseeker.h" #include -#include #define COMPUTER_SEEK_TIMEOUT 30000 -#define APP_SEEK_TIMEOUT 10000 namespace CliListApps { @@ -16,9 +14,7 @@ namespace CliListApps enum State { StateInit, StateSeekComputer, - StateListApp, - StateSeekApp, - StateSeekEnded, + StateListApps, StateFailure, }; @@ -27,7 +23,6 @@ class Event public: enum Type { ComputerFound, - ComputerUpdated, ComputerSeekTimedout, Executed, }; @@ -67,9 +62,6 @@ public: q, &Launcher::onComputerSeekTimeout); m_ComputerSeeker->start(COMPUTER_SEEK_TIMEOUT); - q->connect(m_ComputerManager, &ComputerManager::computerStateChanged, - q, &Launcher::onComputerUpdated); - m_BoxArtManager = new BoxArtManager(q); if (m_Arguments.isVerbose()) { @@ -89,12 +81,28 @@ public: case Event::ComputerFound: if (m_State == StateSeekComputer) { if (event.computer->pairState == NvComputer::PS_PAIRED) { - m_State = StateSeekApp; + m_State = StateListApps; m_Computer = event.computer; - m_TimeoutTimer->start(APP_SEEK_TIMEOUT); + if (m_Arguments.isVerbose()) { fprintf(stdout, "Loading app list...\n"); } + + // To avoid race conditions where ComputerSeeker stops async polling, but + // ComputerManager is yet to update the app list, we will explicitly fetch the latest app list. + // Otherwise, it becomes complicated as we would have to guess whether ComputerManager + // would emit 1 signal (the list did not change) or 2 signals (indicating that the list has changed) + try { + NvHTTP http{m_Computer}; + + const auto appList = http.getAppList(); + m_Arguments.isPrintCSV() ? printAppsCSV(appList) : printApps(appList); + + QCoreApplication::exit(0); + } catch (std::exception& exception) { + fprintf(stderr, "%s\n", exception.what()); + QCoreApplication::exit(1); + } } else { m_State = StateFailure; fprintf(stderr, "%s\n", qPrintable(QObject::tr("Computer %1 has not been paired. " @@ -105,15 +113,6 @@ public: } } break; - // Occurs when a computer is updated - case Event::ComputerUpdated: - if (m_State == StateSeekApp) { - m_State = StateSeekEnded; - m_Arguments.isPrintCSV() ? printAppsCSV(m_Computer->appList) : printApps(m_Computer->appList); - - QCoreApplication::exit(0); - } - break; } } @@ -148,7 +147,6 @@ public: BoxArtManager *m_BoxArtManager; NvComputer *m_Computer; State m_State; - QTimer *m_TimeoutTimer; ListCommandLineParser m_Arguments; }; @@ -159,11 +157,7 @@ Launcher::Launcher(QString computer, ListCommandLineParser arguments, QObject *p Q_D(Launcher); d->m_ComputerName = computer; d->m_State = StateInit; - d->m_TimeoutTimer = new QTimer(this); - d->m_TimeoutTimer->setSingleShot(true); d->m_Arguments = arguments; - connect(d->m_TimeoutTimer, &QTimer::timeout, - this, &Launcher::onComputerSeekTimeout); } Launcher::~Launcher() @@ -199,12 +193,4 @@ void Launcher::onComputerSeekTimeout() d->handleEvent(event); } -void Launcher::onComputerUpdated(NvComputer *computer) -{ - Q_D(Launcher); - Event event(Event::ComputerUpdated); - event.computer = computer; - d->handleEvent(event); -} - } diff --git a/app/cli/listapps.h b/app/cli/listapps.h index a590d531..9b1d735f 100644 --- a/app/cli/listapps.h +++ b/app/cli/listapps.h @@ -27,7 +27,6 @@ public: private slots: void onComputerFound(NvComputer *computer); - void onComputerUpdated(NvComputer *computer); void onComputerSeekTimeout(); private: