mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-11-15 07:57:19 +00:00
176 lines
5 KiB
C++
176 lines
5 KiB
C++
#include "appmodel.h"
|
|
|
|
AppModel::AppModel(QObject *parent)
|
|
: QAbstractListModel(parent)
|
|
{
|
|
connect(&m_BoxArtManager, &BoxArtManager::boxArtLoadComplete,
|
|
this, &AppModel::handleBoxArtLoaded);
|
|
}
|
|
|
|
void AppModel::initialize(ComputerManager* computerManager, int computerIndex)
|
|
{
|
|
m_ComputerManager = computerManager;
|
|
connect(m_ComputerManager, &ComputerManager::computerStateChanged,
|
|
this, &AppModel::handleComputerStateChanged);
|
|
|
|
Q_ASSERT(computerIndex < m_ComputerManager->getComputers().count());
|
|
m_Computer = m_ComputerManager->getComputers().at(computerIndex);
|
|
m_Apps = m_Computer->appList;
|
|
m_CurrentGameId = m_Computer->currentGameId;
|
|
}
|
|
|
|
int AppModel::getRunningAppIndex()
|
|
{
|
|
if (m_CurrentGameId != 0) {
|
|
for (int i = 0; i < m_Apps.count(); i++) {
|
|
if (m_Apps[i].id == m_CurrentGameId) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
QString AppModel::getRunningAppName()
|
|
{
|
|
if (m_CurrentGameId != 0) {
|
|
for (int i = 0; i < m_Apps.count(); i++) {
|
|
if (m_Apps[i].id == m_CurrentGameId) {
|
|
return m_Apps[i].name;
|
|
}
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
Session* AppModel::createSessionForApp(int appIndex)
|
|
{
|
|
Q_ASSERT(appIndex < m_Apps.count());
|
|
NvApp app = m_Apps.at(appIndex);
|
|
|
|
return new Session(m_Computer, app);
|
|
}
|
|
|
|
int AppModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
// For list models only the root node (an invalid parent) should return the list's size. For all
|
|
// other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
|
|
if (parent.isValid())
|
|
return 0;
|
|
|
|
return m_Apps.count();
|
|
}
|
|
|
|
QVariant AppModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!index.isValid())
|
|
return QVariant();
|
|
|
|
Q_ASSERT(index.row() < m_Apps.count());
|
|
NvApp app = m_Apps.at(index.row());
|
|
|
|
switch (role)
|
|
{
|
|
case NameRole:
|
|
return app.name;
|
|
case RunningRole:
|
|
return m_Computer->currentGameId == app.id;
|
|
case BoxArtRole:
|
|
// FIXME: const-correctness
|
|
return const_cast<BoxArtManager&>(m_BoxArtManager).loadBoxArt(m_Computer, app);
|
|
default:
|
|
return QVariant();
|
|
}
|
|
}
|
|
|
|
QHash<int, QByteArray> AppModel::roleNames() const
|
|
{
|
|
QHash<int, QByteArray> names;
|
|
|
|
names[NameRole] = "name";
|
|
names[RunningRole] = "running";
|
|
names[BoxArtRole] = "boxart";
|
|
|
|
return names;
|
|
}
|
|
|
|
void AppModel::quitRunningApp()
|
|
{
|
|
m_ComputerManager->quitRunningApp(m_Computer);
|
|
}
|
|
|
|
void AppModel::handleComputerStateChanged(NvComputer* computer)
|
|
{
|
|
// Ignore updates for computers that aren't ours
|
|
if (computer != m_Computer) {
|
|
return;
|
|
}
|
|
|
|
// If the computer has gone offline or we've been unpaired,
|
|
// signal the UI so we can go back to the PC view.
|
|
if (m_Computer->state == NvComputer::CS_OFFLINE ||
|
|
m_Computer->pairState == NvComputer::PS_NOT_PAIRED) {
|
|
emit computerLost();
|
|
return;
|
|
}
|
|
|
|
// First, process additions/removals from the app list. This
|
|
// is required because the new game may now be running, so
|
|
// we can't check that first.
|
|
if (computer->appList != m_Apps) {
|
|
// Just reset the whole thing if the list changes
|
|
beginResetModel();
|
|
m_Apps = computer->appList;
|
|
m_CurrentGameId = computer->currentGameId;
|
|
endResetModel();
|
|
return;
|
|
}
|
|
|
|
// Finally, process changes to the active app
|
|
if (computer->currentGameId != m_CurrentGameId) {
|
|
// First, invalidate the running state of newly running game
|
|
for (int i = 0; i < m_Apps.count(); i++) {
|
|
if (m_Apps[i].id == computer->currentGameId) {
|
|
emit dataChanged(createIndex(i, 0),
|
|
createIndex(i, 0),
|
|
QVector<int>() << RunningRole);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Next, invalidate the running state of the old game (if it exists)
|
|
if (m_CurrentGameId != 0) {
|
|
for (int i = 0; i < m_Apps.count(); i++) {
|
|
if (m_Apps[i].id == m_CurrentGameId) {
|
|
emit dataChanged(createIndex(i, 0),
|
|
createIndex(i, 0),
|
|
QVector<int>() << RunningRole);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now update our internal state
|
|
m_CurrentGameId = m_Computer->currentGameId;
|
|
}
|
|
}
|
|
|
|
void AppModel::handleBoxArtLoaded(NvComputer* computer, NvApp app, QUrl /* image */)
|
|
{
|
|
Q_ASSERT(computer == m_Computer);
|
|
|
|
int index = m_Apps.indexOf(app);
|
|
|
|
// Make sure we're not delivering a callback to an app that's already been removed
|
|
if (index >= 0) {
|
|
// Let our view know the box art data has changed for this app
|
|
emit dataChanged(createIndex(index, 0),
|
|
createIndex(index, 0),
|
|
QVector<int>() << BoxArtRole);
|
|
}
|
|
else {
|
|
qWarning() << "App not found for box art callback:" << app.name;
|
|
}
|
|
}
|