From 1f1115f98330dd0089ce515ec0bc8feafddb123d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 30 Aug 2019 13:41:46 -0700 Subject: [PATCH] Add ApplicationState to qt launcher --- launchers/qt/src/LauncherState.cpp | 150 +++++++++++++++++++--------- launchers/qt/src/LauncherState.h | 40 +++++++- launchers/qt/src/LauncherWindow.cpp | 3 + launchers/qt/src/main.cpp | 3 +- 4 files changed, 144 insertions(+), 52 deletions(-) diff --git a/launchers/qt/src/LauncherState.cpp b/launchers/qt/src/LauncherState.cpp index 52e13bc3b7..9c5f66f9cf 100644 --- a/launchers/qt/src/LauncherState.cpp +++ b/launchers/qt/src/LauncherState.cpp @@ -17,52 +17,15 @@ static const std::array QML_FILE_ { { "qrc:/qml/SplashScreen.qml", "qrc:/qml/Login.qml", "qrc:/qml/DisplayName.qml", "qrc:/qml/Download.qml", "qrc:/qml/DownloadFinshed.qml", "qrc:/qml/Error.qml" } }; +void LauncherState::ASSERT_STATE(LauncherState::ApplicationState state) const { + if (_appState != state) { + __debugbreak(); + exit(0); + } +} + LauncherState::LauncherState() { - // TODO Show splash screen until this request is complete - auto request = new QNetworkRequest(QUrl("https://thunder.highfidelity.com/builds/api/tags/latest/?format=json")); - auto reply = _networkAccessManager.get(*request); - QObject::connect(reply, &QNetworkReply::finished, [reply, this]() { - if (reply->error()) { - qDebug() << "Error getting builds from thunder: " << reply->errorString(); - } else { - qDebug() << "Builds reply has been received"; - auto data = reply->readAll(); - QJsonParseError parseError; - auto doc = QJsonDocument::fromJson(data, &parseError); - if (parseError.error) { - qDebug() << "Error parsing response from thunder: " << data; - } else { - auto root = doc.object(); - if (!root.contains("default_tag")) { - return; - } - - _latestBuilds.defaultTag = root["default_tag"].toString(); - - auto results = root["results"]; - if (!results.isArray()) { - return; - } - - for (auto result : results.toArray()) { - auto entry = result.toObject(); - Build build; - build.tag = entry["name"].toString(); - build.latestVersion = entry["latest_version"].toInt(); - build.buildNumber = entry["build_number"].toInt(); -#ifdef Q_OS_WIN - build.installerZipURL = entry["installers"].toObject()["windows"].toObject()["zip_url"].toString(); -#elif defined(Q_OS_MACOS) - build.installerZipURL = entry["installers"].toObject()["mac"].toObject()["zip_url"].toString(); -#else - #error "Launcher is only supported on Windows and Mac OS" -#endif - _latestBuilds.builds.push_back(build); - } - } - } - setUIState(LauncherState::LOGIN_SCREEN); - }); + requestBuilds(); } QString LauncherState::getCurrentUISource() const { @@ -90,7 +53,74 @@ LauncherState::LastLoginError LauncherState::getLastLoginError() const { return _lastLoginError; } +void LauncherState::requestBuilds() { + ASSERT_STATE(ApplicationState::INIT); + _appState = ApplicationState::REQUESTING_BUILDS; + + // TODO Show splash screen until this request is complete + auto request = new QNetworkRequest(QUrl("https://thunder.highfidelity.com/builds/api/tags/latest/?format=json")); + auto reply = _networkAccessManager.get(*request); + + QObject::connect(reply, &QNetworkReply::finished, this, &LauncherState::receivedBuildsReply); +} + +void LauncherState::receivedBuildsReply() { + auto reply = static_cast(sender()); + + ASSERT_STATE(ApplicationState::REQUESTING_BUILDS); + + if (reply->error()) { + qDebug() << "Error getting builds from thunder: " << reply->errorString(); + } else { + qDebug() << "Builds reply has been received"; + auto data = reply->readAll(); + QJsonParseError parseError; + auto doc = QJsonDocument::fromJson(data, &parseError); + if (parseError.error) { + qDebug() << "Error parsing response from thunder: " << data; + } else { + auto root = doc.object(); + if (!root.contains("default_tag")) { + _appState = ApplicationState::REQUESTING_BUILDS_FAILED; + setUIState(LauncherState::ERROR_SCREEN); + return; + } + + _latestBuilds.defaultTag = root["default_tag"].toString(); + + auto results = root["results"]; + if (!results.isArray()) { + _appState = ApplicationState::REQUESTING_BUILDS_FAILED; + setUIState(LauncherState::ERROR_SCREEN); + return; + } + + for (auto result : results.toArray()) { + auto entry = result.toObject(); + Build build; + build.tag = entry["name"].toString(); + build.latestVersion = entry["latest_version"].toInt(); + build.buildNumber = entry["build_number"].toInt(); +#ifdef Q_OS_WIN + build.installerZipURL = entry["installers"].toObject()["windows"].toObject()["zip_url"].toString(); +#elif defined(Q_OS_MACOS) + build.installerZipURL = entry["installers"].toObject()["mac"].toObject()["zip_url"].toString(); +#else + #error "Launcher is only supported on Windows and Mac OS" +#endif + _latestBuilds.builds.push_back(build); + } + } + } + _appState = ApplicationState::WAITING_FOR_LOGIN; + setUIState(LauncherState::LOGIN_SCREEN); +} + void LauncherState::login(QString username, QString password) { + ASSERT_STATE(ApplicationState::WAITING_FOR_LOGIN); + + _appState = ApplicationState::REQUESTING_LOGIN; + qDebug() << "Got login: " << username << password; auto request = new QNetworkRequest(QUrl("https://metaverse.highfidelity.com/oauth/token")); @@ -104,7 +134,31 @@ void LauncherState::login(QString username, QString password) { auto reply = _networkAccessManager.post(*request, query.toString().toUtf8()); - QObject::connect(reply, &QNetworkReply::finished, [reply, this]() { - qDebug() << "Got response for login: " << reply->readAll(); - }); + QObject::connect(reply, &QNetworkReply::finished, this, &LauncherState::receivedLoginReply); +} + +Q_INVOKABLE void LauncherState::receivedLoginReply() { + auto reply = static_cast(sender()); + + ASSERT_STATE(ApplicationState::REQUESTING_LOGIN); + + qDebug() << "Got response for login: " << reply->readAll(); + + + download(); +} + +void LauncherState::download() { + _appState = ApplicationState::DOWNLOADING_CONTENT; + setUIState(LauncherState::DOWNLOAD_SCREEN); +} + +void LauncherState::contentDownloadComplete() { +} + +void LauncherState::clientDownloadComplete() { +} + +void LauncherState::launchClient() { + _appState = ApplicationState::LAUNCHING_HIGH_FIDELITY; } diff --git a/launchers/qt/src/LauncherState.h b/launchers/qt/src/LauncherState.h index 73e512be63..62a58c9778 100644 --- a/launchers/qt/src/LauncherState.h +++ b/launchers/qt/src/LauncherState.h @@ -32,6 +32,28 @@ public: }; Q_ENUMS(UIState); + enum class ApplicationState { + INIT, + + REQUESTING_BUILDS, + REQUESTING_BUILDS_FAILED, + + WAITING_FOR_LOGIN, + REQUESTING_LOGIN, + + WAITING_FOR_SIGNUP, + REQUESTING_SIGNUP, + + DOWNLOADING_CONTENT, + DOWNLOADING_HIGH_FIDELITY, + + EXTRACTING_DATA, + + LAUNCHING_HIGH_FIDELITY + }; + Q_ENUMS(ApplicationState); + + enum LastLoginError { NONE = 0, ORGINIZATION, @@ -41,6 +63,8 @@ public: Q_ENUMS(LastLoginError); Q_INVOKABLE QString getCurrentUISource() const; + void LauncherState::ASSERT_STATE(LauncherState::ApplicationState state) const; + static void declareQML(); void setUIState(UIState state); @@ -49,10 +73,21 @@ public: void setLastLoginError(LastLoginError lastLoginError); LastLoginError getLastLoginError() const; + // Request builds + void requestBuilds(); + Q_INVOKABLE void receivedBuildsReply(); - - // LOGIN + // Login Q_INVOKABLE void login(QString username, QString password); + Q_INVOKABLE void receivedLoginReply(); + + // Download + void download(); + Q_INVOKABLE void contentDownloadComplete(); + Q_INVOKABLE void clientDownloadComplete(); + + // Launching + void launchClient(); signals: void updateSourceUrl(QString sourceUrl); @@ -61,6 +96,7 @@ private: QNetworkAccessManager _networkAccessManager; LatestBuilds _latestBuilds; + ApplicationState _appState { ApplicationState::INIT }; UIState _uiState { SPLASH_SCREEN }; LastLoginError _lastLoginError { NONE }; }; diff --git a/launchers/qt/src/LauncherWindow.cpp b/launchers/qt/src/LauncherWindow.cpp index b86c2ca84c..a88df8efe7 100644 --- a/launchers/qt/src/LauncherWindow.cpp +++ b/launchers/qt/src/LauncherWindow.cpp @@ -7,6 +7,9 @@ void LauncherWindow::keyPressEvent(QKeyEvent* event) { QQuickView::keyPressEvent(event); if (!event->isAccepted()) { + if (event->key() == Qt::Key_Escape) { + exit(0); + } } } diff --git a/launchers/qt/src/main.cpp b/launchers/qt/src/main.cpp index 50bfb5f59d..9ed6f42390 100644 --- a/launchers/qt/src/main.cpp +++ b/launchers/qt/src/main.cpp @@ -9,8 +9,7 @@ Q_IMPORT_PLUGIN(QtQuick2Plugin); Q_IMPORT_PLUGIN(QtQuickControls2Plugin); Q_IMPORT_PLUGIN(QtQuickTemplates2Plugin); -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { QString name { "HQLauncher" }; QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setOrganizationName(name);