mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2025-01-09 09:48:43 +00:00
Make StreamingPreferences a proper singleton
This removes the need for several hacks in SettingsView to force updates and improves performance by not reloading preferences all over the place.
This commit is contained in:
parent
ebe270bec5
commit
d1ccd19fcc
9 changed files with 68 additions and 56 deletions
|
@ -1,7 +1,7 @@
|
||||||
#include "computermanager.h"
|
#include "computermanager.h"
|
||||||
#include "boxartmanager.h"
|
#include "boxartmanager.h"
|
||||||
#include "nvhttp.h"
|
#include "nvhttp.h"
|
||||||
#include "settings/streamingpreferences.h"
|
#include "nvpairingmanager.h"
|
||||||
|
|
||||||
#include <Limelight.h>
|
#include <Limelight.h>
|
||||||
#include <QtEndian>
|
#include <QtEndian>
|
||||||
|
@ -144,8 +144,8 @@ private:
|
||||||
NvComputer* m_Computer;
|
NvComputer* m_Computer;
|
||||||
};
|
};
|
||||||
|
|
||||||
ComputerManager::ComputerManager(QObject *parent)
|
ComputerManager::ComputerManager(StreamingPreferences* prefs)
|
||||||
: QObject(parent),
|
: m_Prefs(prefs),
|
||||||
m_PollingRef(0),
|
m_PollingRef(0),
|
||||||
m_MdnsBrowser(nullptr),
|
m_MdnsBrowser(nullptr),
|
||||||
m_CompatFetcher(nullptr),
|
m_CompatFetcher(nullptr),
|
||||||
|
@ -352,9 +352,7 @@ void ComputerManager::startPolling()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamingPreferences prefs;
|
if (m_Prefs->enableMdns) {
|
||||||
|
|
||||||
if (prefs.enableMdns) {
|
|
||||||
// Start an MDNS query for GameStream hosts
|
// Start an MDNS query for GameStream hosts
|
||||||
m_MdnsServer.reset(new QMdnsEngine::Server());
|
m_MdnsServer.reset(new QMdnsEngine::Server());
|
||||||
m_MdnsBrowser = new QMdnsEngine::Browser(m_MdnsServer.data(), "_nvstream._tcp.local.");
|
m_MdnsBrowser = new QMdnsEngine::Browser(m_MdnsServer.data(), "_nvstream._tcp.local.");
|
||||||
|
@ -784,10 +782,9 @@ private:
|
||||||
return serverInfo;
|
return serverInfo;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
if (!m_Mdns) {
|
if (!m_Mdns) {
|
||||||
StreamingPreferences prefs;
|
|
||||||
unsigned int portTestResult;
|
unsigned int portTestResult;
|
||||||
|
|
||||||
if (prefs.detectNetworkBlocking) {
|
if (m_ComputerManager->m_Prefs->detectNetworkBlocking) {
|
||||||
// We failed to connect to the specified PC. Let's test to make sure this network
|
// We failed to connect to the specified PC. Let's test to make sure this network
|
||||||
// isn't blocking Moonlight, so we can tell the user about it.
|
// isn't blocking Moonlight, so we can tell the user about it.
|
||||||
portTestResult = LiTestClientConnectivity("qt.conntest.moonlight-stream.org", 443,
|
portTestResult = LiTestClientConnectivity("qt.conntest.moonlight-stream.org", 443,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "nvcomputer.h"
|
#include "nvcomputer.h"
|
||||||
#include "nvpairingmanager.h"
|
#include "settings/streamingpreferences.h"
|
||||||
#include "settings/compatfetcher.h"
|
#include "settings/compatfetcher.h"
|
||||||
|
|
||||||
#include <qmdnsengine/server.h>
|
#include <qmdnsengine/server.h>
|
||||||
|
@ -218,7 +218,7 @@ class ComputerManager : public QObject
|
||||||
friend class DelayedFlushThread;
|
friend class DelayedFlushThread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ComputerManager(QObject *parent = nullptr);
|
explicit ComputerManager(StreamingPreferences* prefs);
|
||||||
|
|
||||||
virtual ~ComputerManager();
|
virtual ~ComputerManager();
|
||||||
|
|
||||||
|
@ -270,6 +270,7 @@ private:
|
||||||
|
|
||||||
void startPollingComputer(NvComputer* computer);
|
void startPollingComputer(NvComputer* computer);
|
||||||
|
|
||||||
|
StreamingPreferences* m_Prefs;
|
||||||
int m_PollingRef;
|
int m_PollingRef;
|
||||||
QReadWriteLock m_Lock;
|
QReadWriteLock m_Lock;
|
||||||
QMap<QString, NvComputer*> m_KnownHosts;
|
QMap<QString, NvComputer*> m_KnownHosts;
|
||||||
|
|
|
@ -1349,15 +1349,7 @@ Flickable {
|
||||||
font.pointSize: 12
|
font.pointSize: 12
|
||||||
checked: StreamingPreferences.swapFaceButtons
|
checked: StreamingPreferences.swapFaceButtons
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
// Check if the value changed (this is called on init too)
|
StreamingPreferences.swapFaceButtons = checked
|
||||||
if (StreamingPreferences.swapFaceButtons !== checked) {
|
|
||||||
StreamingPreferences.swapFaceButtons = checked
|
|
||||||
|
|
||||||
// Save and restart SdlGamepadKeyNavigation so it can pull the new value
|
|
||||||
StreamingPreferences.save()
|
|
||||||
SdlGamepadKeyNavigation.disable()
|
|
||||||
SdlGamepadKeyNavigation.enable()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolTip.delay: 1000
|
ToolTip.delay: 1000
|
||||||
|
@ -1621,10 +1613,6 @@ Flickable {
|
||||||
if (StreamingPreferences.enableMdns != checked) {
|
if (StreamingPreferences.enableMdns != checked) {
|
||||||
StreamingPreferences.enableMdns = checked
|
StreamingPreferences.enableMdns = checked
|
||||||
|
|
||||||
// We must save the updated preference to ensure
|
|
||||||
// ComputerManager can observe the change internally.
|
|
||||||
StreamingPreferences.save()
|
|
||||||
|
|
||||||
// Restart polling so the mDNS change takes effect
|
// Restart polling so the mDNS change takes effect
|
||||||
if (window.pollingActive) {
|
if (window.pollingActive) {
|
||||||
ComputerManager.stopPollingAsync()
|
ComputerManager.stopPollingAsync()
|
||||||
|
@ -1641,15 +1629,7 @@ Flickable {
|
||||||
font.pointSize: 12
|
font.pointSize: 12
|
||||||
checked: StreamingPreferences.detectNetworkBlocking
|
checked: StreamingPreferences.detectNetworkBlocking
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
// This is called on init, so only do the work if we've
|
StreamingPreferences.detectNetworkBlocking = checked
|
||||||
// actually changed the value.
|
|
||||||
if (StreamingPreferences.detectNetworkBlocking != checked) {
|
|
||||||
StreamingPreferences.detectNetworkBlocking = checked
|
|
||||||
|
|
||||||
// We must save the updated preference to ensure
|
|
||||||
// ComputerManager can observe the change internally.
|
|
||||||
StreamingPreferences.save()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
|
|
||||||
#define AXIS_NAVIGATION_REPEAT_DELAY 150
|
#define AXIS_NAVIGATION_REPEAT_DELAY 150
|
||||||
|
|
||||||
SdlGamepadKeyNavigation::SdlGamepadKeyNavigation()
|
SdlGamepadKeyNavigation::SdlGamepadKeyNavigation(StreamingPreferences* prefs)
|
||||||
: m_Enabled(false),
|
: m_Prefs(prefs),
|
||||||
|
m_Enabled(false),
|
||||||
m_UiNavMode(false),
|
m_UiNavMode(false),
|
||||||
m_FirstPoll(false),
|
m_FirstPoll(false),
|
||||||
m_LastAxisNavigationEventTime(0)
|
m_LastAxisNavigationEventTime(0)
|
||||||
|
@ -119,7 +120,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
|
||||||
QEvent::Type::KeyPress : QEvent::Type::KeyRelease;
|
QEvent::Type::KeyPress : QEvent::Type::KeyRelease;
|
||||||
|
|
||||||
// Swap face buttons if needed
|
// Swap face buttons if needed
|
||||||
if (m_Prefs.swapFaceButtons) {
|
if (m_Prefs->swapFaceButtons) {
|
||||||
switch (event.cbutton.button) {
|
switch (event.cbutton.button) {
|
||||||
case SDL_CONTROLLER_BUTTON_A:
|
case SDL_CONTROLLER_BUTTON_A:
|
||||||
event.cbutton.button = SDL_CONTROLLER_BUTTON_B;
|
event.cbutton.button = SDL_CONTROLLER_BUTTON_B;
|
||||||
|
|
|
@ -12,7 +12,7 @@ class SdlGamepadKeyNavigation : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SdlGamepadKeyNavigation();
|
SdlGamepadKeyNavigation(StreamingPreferences* prefs);
|
||||||
|
|
||||||
~SdlGamepadKeyNavigation();
|
~SdlGamepadKeyNavigation();
|
||||||
|
|
||||||
|
@ -31,11 +31,11 @@ private slots:
|
||||||
void onPollingTimerFired();
|
void onPollingTimerFired();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
StreamingPreferences* m_Prefs;
|
||||||
QTimer* m_PollingTimer;
|
QTimer* m_PollingTimer;
|
||||||
QList<SDL_GameController*> m_Gamepads;
|
QList<SDL_GameController*> m_Gamepads;
|
||||||
bool m_Enabled;
|
bool m_Enabled;
|
||||||
bool m_UiNavMode;
|
bool m_UiNavMode;
|
||||||
bool m_FirstPoll;
|
bool m_FirstPoll;
|
||||||
Uint32 m_LastAxisNavigationEventTime;
|
Uint32 m_LastAxisNavigationEventTime;
|
||||||
StreamingPreferences m_Prefs;
|
|
||||||
};
|
};
|
||||||
|
|
17
app/main.cpp
17
app/main.cpp
|
@ -570,8 +570,7 @@ int main(int argc, char *argv[])
|
||||||
runtimeVersion.major, runtimeVersion.minor, runtimeVersion.patch);
|
runtimeVersion.major, runtimeVersion.minor, runtimeVersion.patch);
|
||||||
|
|
||||||
// Apply the initial translation based on user preference
|
// Apply the initial translation based on user preference
|
||||||
StreamingPreferences prefs;
|
StreamingPreferences::get()->retranslate();
|
||||||
prefs.retranslate();
|
|
||||||
|
|
||||||
// Trickily declare the translation for dialog buttons
|
// Trickily declare the translation for dialog buttons
|
||||||
QCoreApplication::translate("QPlatformTheme", "&Yes");
|
QCoreApplication::translate("QPlatformTheme", "&Yes");
|
||||||
|
@ -636,8 +635,8 @@ int main(int argc, char *argv[])
|
||||||
qmlRegisterUncreatableType<Session>("Session", 1, 0, "Session", "Session cannot be created from QML");
|
qmlRegisterUncreatableType<Session>("Session", 1, 0, "Session", "Session cannot be created from QML");
|
||||||
qmlRegisterSingletonType<ComputerManager>("ComputerManager", 1, 0,
|
qmlRegisterSingletonType<ComputerManager>("ComputerManager", 1, 0,
|
||||||
"ComputerManager",
|
"ComputerManager",
|
||||||
[](QQmlEngine*, QJSEngine*) -> QObject* {
|
[](QQmlEngine* qmlEngine, QJSEngine*) -> QObject* {
|
||||||
return new ComputerManager();
|
return new ComputerManager(StreamingPreferences::get(qmlEngine));
|
||||||
});
|
});
|
||||||
qmlRegisterSingletonType<AutoUpdateChecker>("AutoUpdateChecker", 1, 0,
|
qmlRegisterSingletonType<AutoUpdateChecker>("AutoUpdateChecker", 1, 0,
|
||||||
"AutoUpdateChecker",
|
"AutoUpdateChecker",
|
||||||
|
@ -651,13 +650,13 @@ int main(int argc, char *argv[])
|
||||||
});
|
});
|
||||||
qmlRegisterSingletonType<SdlGamepadKeyNavigation>("SdlGamepadKeyNavigation", 1, 0,
|
qmlRegisterSingletonType<SdlGamepadKeyNavigation>("SdlGamepadKeyNavigation", 1, 0,
|
||||||
"SdlGamepadKeyNavigation",
|
"SdlGamepadKeyNavigation",
|
||||||
[](QQmlEngine*, QJSEngine*) -> QObject* {
|
[](QQmlEngine* qmlEngine, QJSEngine*) -> QObject* {
|
||||||
return new SdlGamepadKeyNavigation();
|
return new SdlGamepadKeyNavigation(StreamingPreferences::get(qmlEngine));
|
||||||
});
|
});
|
||||||
qmlRegisterSingletonType<StreamingPreferences>("StreamingPreferences", 1, 0,
|
qmlRegisterSingletonType<StreamingPreferences>("StreamingPreferences", 1, 0,
|
||||||
"StreamingPreferences",
|
"StreamingPreferences",
|
||||||
[](QQmlEngine* qmlEngine, QJSEngine*) -> QObject* {
|
[](QQmlEngine* qmlEngine, QJSEngine*) -> QObject* {
|
||||||
return new StreamingPreferences(qmlEngine);
|
return StreamingPreferences::get(qmlEngine);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create the identity manager on the main thread
|
// Create the identity manager on the main thread
|
||||||
|
@ -688,7 +687,7 @@ int main(int argc, char *argv[])
|
||||||
case GlobalCommandLineParser::StreamRequested:
|
case GlobalCommandLineParser::StreamRequested:
|
||||||
{
|
{
|
||||||
initialView = "qrc:/gui/CliStartStreamSegue.qml";
|
initialView = "qrc:/gui/CliStartStreamSegue.qml";
|
||||||
StreamingPreferences* preferences = new StreamingPreferences(&app);
|
StreamingPreferences* preferences = StreamingPreferences::get();
|
||||||
StreamCommandLineParser streamParser;
|
StreamCommandLineParser streamParser;
|
||||||
streamParser.parse(app.arguments(), preferences);
|
streamParser.parse(app.arguments(), preferences);
|
||||||
QString host = streamParser.getHost();
|
QString host = streamParser.getHost();
|
||||||
|
@ -720,7 +719,7 @@ int main(int argc, char *argv[])
|
||||||
ListCommandLineParser listParser;
|
ListCommandLineParser listParser;
|
||||||
listParser.parse(app.arguments());
|
listParser.parse(app.arguments());
|
||||||
auto launcher = new CliListApps::Launcher(listParser.getHost(), listParser, &app);
|
auto launcher = new CliListApps::Launcher(listParser.getHost(), listParser, &app);
|
||||||
launcher->execute(new ComputerManager(&app));
|
launcher->execute(new ComputerManager(StreamingPreferences::get()));
|
||||||
hasGUI = false;
|
hasGUI = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
|
#include <QReadWriteLock>
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
@ -48,18 +49,50 @@
|
||||||
|
|
||||||
#define CURRENT_DEFAULT_VER 2
|
#define CURRENT_DEFAULT_VER 2
|
||||||
|
|
||||||
StreamingPreferences::StreamingPreferences(QObject *parent)
|
static StreamingPreferences* s_GlobalPrefs;
|
||||||
: QObject(parent),
|
static QReadWriteLock s_GlobalPrefsLock;
|
||||||
m_QmlEngine(nullptr)
|
|
||||||
|
StreamingPreferences::StreamingPreferences(QQmlEngine *qmlEngine)
|
||||||
|
: m_QmlEngine(qmlEngine)
|
||||||
{
|
{
|
||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamingPreferences::StreamingPreferences(QQmlEngine *qmlEngine, QObject *parent)
|
StreamingPreferences* StreamingPreferences::get(QQmlEngine *qmlEngine)
|
||||||
: QObject(parent),
|
|
||||||
m_QmlEngine(qmlEngine)
|
|
||||||
{
|
{
|
||||||
reload();
|
{
|
||||||
|
QReadLocker readGuard(&s_GlobalPrefsLock);
|
||||||
|
|
||||||
|
// If we have a preference object and it's associated with a QML engine or
|
||||||
|
// if the caller didn't specify a QML engine, return the existing object.
|
||||||
|
if (s_GlobalPrefs && (s_GlobalPrefs->m_QmlEngine || !qmlEngine)) {
|
||||||
|
// The lifetime logic here relies on the QML engine also being a singleton.
|
||||||
|
Q_ASSERT(!qmlEngine || s_GlobalPrefs->m_QmlEngine == qmlEngine);
|
||||||
|
return s_GlobalPrefs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QWriteLocker writeGuard(&s_GlobalPrefsLock);
|
||||||
|
|
||||||
|
// If we already have an preference object but the QML engine is now available,
|
||||||
|
// associate the QML engine with the preferences.
|
||||||
|
if (s_GlobalPrefs) {
|
||||||
|
if (!s_GlobalPrefs->m_QmlEngine) {
|
||||||
|
s_GlobalPrefs->m_QmlEngine = qmlEngine;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We could reach this codepath if another thread raced with us
|
||||||
|
// and created the object while we were outside the pref lock.
|
||||||
|
Q_ASSERT(!qmlEngine || s_GlobalPrefs->m_QmlEngine == qmlEngine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s_GlobalPrefs = new StreamingPreferences(qmlEngine);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_GlobalPrefs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamingPreferences::reload()
|
void StreamingPreferences::reload()
|
||||||
|
|
|
@ -9,8 +9,7 @@ class StreamingPreferences : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StreamingPreferences(QObject *parent = nullptr);
|
static StreamingPreferences* get(QQmlEngine *qmlEngine = nullptr);
|
||||||
StreamingPreferences(QQmlEngine *qmlEngine, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
Q_INVOKABLE static int
|
Q_INVOKABLE static int
|
||||||
getDefaultBitrate(int width, int height, int fps);
|
getDefaultBitrate(int width, int height, int fps);
|
||||||
|
@ -206,6 +205,8 @@ signals:
|
||||||
void languageChanged();
|
void languageChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
explicit StreamingPreferences(QQmlEngine *qmlEngine);
|
||||||
|
|
||||||
QString getSuffixFromLanguage(Language lang);
|
QString getSuffixFromLanguage(Language lang);
|
||||||
|
|
||||||
QQmlEngine* m_QmlEngine;
|
QQmlEngine* m_QmlEngine;
|
||||||
|
|
|
@ -541,7 +541,7 @@ bool Session::populateDecoderProperties(SDL_Window* window)
|
||||||
}
|
}
|
||||||
|
|
||||||
Session::Session(NvComputer* computer, NvApp& app, StreamingPreferences *preferences)
|
Session::Session(NvComputer* computer, NvApp& app, StreamingPreferences *preferences)
|
||||||
: m_Preferences(preferences ? preferences : new StreamingPreferences(this)),
|
: m_Preferences(preferences ? preferences : StreamingPreferences::get()),
|
||||||
m_IsFullScreen(m_Preferences->windowMode != StreamingPreferences::WM_WINDOWED || !WMUtils::isRunningDesktopEnvironment()),
|
m_IsFullScreen(m_Preferences->windowMode != StreamingPreferences::WM_WINDOWED || !WMUtils::isRunningDesktopEnvironment()),
|
||||||
m_Computer(computer),
|
m_Computer(computer),
|
||||||
m_App(app),
|
m_App(app),
|
||||||
|
|
Loading…
Reference in a new issue