diff --git a/src/appmanager.cpp b/src/appmanager.cpp index 4072a69e4..1e16a2e12 100644 --- a/src/appmanager.cpp +++ b/src/appmanager.cpp @@ -28,6 +28,7 @@ #include "src/nexus.h" #include "src/net/toxuri.h" #include "src/widget/widget.h" +#include "src/video/camerasource.h" #if defined(Q_OS_UNIX) #include "src/platform/posixsignalnotifier.h" @@ -355,35 +356,31 @@ int AppManager::run() return -1; } - // TODO(sudden6): remove once we get rid of Nexus - Nexus& nexus = Nexus::getInstance(); // TODO(kriby): Consider moving application initializing variables into a globalSettings object // note: Because Settings is shouldering global settings as well as model specific ones it // cannot be integrated into a central model object yet - nexus.setSettings(settings.get()); - nexus.setMessageBoxManager(messageBoxManager.get()); - nexus.setIpc(ipc.get()); - auto& cameraSource = nexus.getCameraSource(); + cameraSource = std::unique_ptr(new CameraSource{*settings}); + nexus = std::unique_ptr(new Nexus{*settings, *messageBoxManager, *cameraSource, *ipc}); // Autologin // TODO (kriby): Shift responsibility of linking views to model objects from nexus // Further: generate view instances separately (loginScreen, mainGUI, audio) Profile* profile = nullptr; if (autoLogin && Profile::exists(profileName, settings->getPaths()) && !Profile::isEncrypted(profileName, settings->getPaths())) { - profile = Profile::loadProfile(profileName, QString(), *settings, &parser, cameraSource, *messageBoxManager); + profile = Profile::loadProfile(profileName, QString(), *settings, &parser, *cameraSource, *messageBoxManager); if (!profile) { QMessageBox::information(nullptr, tr("Error"), tr("Failed to load profile automatically.")); } } if (profile) { - nexus.bootstrapWithProfile(profile); + nexus->bootstrapWithProfile(profile); } else { - nexus.setParser(&parser); - int returnval = nexus.showLogin(profileName); + nexus->setParser(&parser); + int returnval = nexus->showLogin(profileName); if (returnval == QDialog::Rejected) { return -1; } - profile = nexus.getProfile(); + profile = nexus->getProfile(); } uriDialog = std::unique_ptr(new ToxURIDialog(nullptr, profile->getCore(), *messageBoxManager)); @@ -391,14 +388,14 @@ int AppManager::run() if (ipc->isAttached()) { // Start to accept Inter-process communication ipc->registerEventHandler("uri", &toxURIEventHandler, uriDialog.get()); - nexus.registerIpcHandlers(); + nexus->registerIpcHandlers(); } // Event was not handled by already running instance therefore we handle it ourselves if (eventType == "uri") { uriDialog->handleToxURI(firstParam); } else if (eventType == ToxSave::eventHandlerKey) { - nexus.handleToxSave(firstParam); + nexus->handleToxSave(firstParam); } connect(qapp.get(), &QApplication::aboutToQuit, this, &AppManager::cleanup); @@ -413,14 +410,14 @@ void AppManager::cleanup() // force save early even though destruction saves, because Windows OS will // close qTox before cleanup() is finished if logging out or shutting down, // once the top level window has exited, which occurs in ~Widget within - // ~Nexus. Re-ordering Nexus destruction is not trivial. + // ~nexus-> Re-ordering Nexus destruction is not trivial. if (settings) { settings->saveGlobal(); settings->savePersonal(); settings->sync(); } - Nexus::destroyInstance(); + nexus.reset(); settings.reset(); qDebug() << "Cleanup success"; diff --git a/src/appmanager.h b/src/appmanager.h index 885e2797f..5deed3011 100644 --- a/src/appmanager.h +++ b/src/appmanager.h @@ -28,6 +28,8 @@ class Settings; class IPC; class QApplication; class ToxURIDialog; +class Nexus; +class CameraSource; class AppManager : public QObject { @@ -47,4 +49,6 @@ private: std::unique_ptr settings; std::unique_ptr ipc; std::unique_ptr uriDialog; + std::unique_ptr cameraSource; + std::unique_ptr nexus; }; diff --git a/src/model/profile/profileinfo.cpp b/src/model/profile/profileinfo.cpp index f423b7124..2ac19c7c3 100644 --- a/src/model/profile/profileinfo.cpp +++ b/src/model/profile/profileinfo.cpp @@ -99,10 +99,11 @@ bool tryRemoveFile(const QString& filepath) * @param profile Pointer to Profile. * @note All pointers parameters shouldn't be null. */ -ProfileInfo::ProfileInfo(Core* core_, Profile* profile_, Settings& settings_) +ProfileInfo::ProfileInfo(Core* core_, Profile* profile_, Settings& settings_, Nexus& nexus_) : profile{profile_} , core{core_} , settings{settings_} + , nexus{nexus_} { connect(core_, &Core::idSet, this, &ProfileInfo::idChanged); connect(core_, &Core::usernameSet, this, &ProfileInfo::usernameChanged); @@ -235,7 +236,7 @@ IProfileInfo::SaveResult ProfileInfo::exportProfile(const QString& path) const QStringList ProfileInfo::removeProfile() { QStringList manualDeleteFiles = profile->remove(); - QMetaObject::invokeMethod(&Nexus::getInstance(), "showLogin"); + QMetaObject::invokeMethod(&nexus, "showLogin"); return manualDeleteFiles; } @@ -246,7 +247,7 @@ void ProfileInfo::logout() { // TODO(kriby): Refactor all of these invokeMethod calls with connect() properly when possible settings.saveGlobal(); - QMetaObject::invokeMethod(&Nexus::getInstance(), "showLogin", + QMetaObject::invokeMethod(&nexus, "showLogin", Q_ARG(QString, settings.getCurrentProfile())); } diff --git a/src/model/profile/profileinfo.h b/src/model/profile/profileinfo.h index 3c7782c88..3158068c4 100644 --- a/src/model/profile/profileinfo.h +++ b/src/model/profile/profileinfo.h @@ -29,12 +29,13 @@ class QFile; class QPoint; class Profile; class Settings; +class Nexus; class ProfileInfo : public QObject, public IProfileInfo { Q_OBJECT public: - ProfileInfo(Core* core_, Profile* profile_, Settings& settings); + ProfileInfo(Core* core_, Profile* profile_, Settings& settings, Nexus& nexus); bool setPassword(const QString& password) override; bool deletePassword() override; @@ -68,4 +69,5 @@ private: Profile* const profile; Core* const core; Settings& settings; + Nexus& nexus; }; diff --git a/src/nexus.cpp b/src/nexus.cpp index 3bc1a336c..825c0bdba 100644 --- a/src/nexus.cpp +++ b/src/nexus.cpp @@ -31,6 +31,7 @@ #include "widget/loginscreen.h" #include "src/widget/tool/messageboxmanager.h" #include "audio/audio.h" +#include "src/ipc.h" #include #include @@ -59,16 +60,18 @@ Q_DECLARE_OPAQUE_POINTER(ToxAV*) -namespace { -Nexus* nexus{nullptr}; -} // namespace - -Nexus::Nexus(QObject* parent) +Nexus::Nexus(Settings& settings_, IMessageBoxManager& messageBoxManager_, + CameraSource& cameraSource_, IPC& ipc_, QObject* parent) : QObject(parent) , profile{nullptr} + , settings{settings_} , widget{nullptr} + , cameraSource{cameraSource_} , style{new Style()} + , messageBoxManager{messageBoxManager_} + , ipc{ipc_} { + QObject::connect(this, &Nexus::saveGlobal, &settings, &Settings::saveGlobal); } Nexus::~Nexus() @@ -166,7 +169,7 @@ int Nexus::showLogin(const QString& profileName) delete profile; profile = nullptr; - LoginScreen loginScreen{*settings, *style, profileName}; + LoginScreen loginScreen{settings, *style, profileName}; connectLoginScreen(loginScreen); QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); @@ -192,25 +195,13 @@ void Nexus::bootstrapWithProfile(Profile* p) profile = p; if (profile) { - audioControl = std::unique_ptr(Audio::makeAudio(*settings)); + audioControl = std::unique_ptr(Audio::makeAudio(settings)); assert(audioControl != nullptr); profile->getCore().getAv()->setAudio(*audioControl); start(); } } -void Nexus::setSettings(Settings* settings_) -{ - cameraSource = std::unique_ptr(new CameraSource{*settings_}); - if (settings) { - QObject::disconnect(this, &Nexus::saveGlobal, settings, &Settings::saveGlobal); - } - settings = settings_; - if (settings) { - QObject::connect(this, &Nexus::saveGlobal, settings, &Settings::saveGlobal); - } -} - void Nexus::connectLoginScreen(const LoginScreen& loginScreen) { // TODO(kriby): Move connect sequences to a controller class object instead @@ -222,10 +213,10 @@ void Nexus::connectLoginScreen(const LoginScreen& loginScreen) QObject::connect(&loginScreen, &LoginScreen::createNewProfile, this, &Nexus::onCreateNewProfile); QObject::connect(&loginScreen, &LoginScreen::loadProfile, this, &Nexus::onLoadProfile); // LoginScreen -> Settings - QObject::connect(&loginScreen, &LoginScreen::autoLoginChanged, settings, &Settings::setAutoLogin); - QObject::connect(&loginScreen, &LoginScreen::autoLoginChanged, settings, &Settings::saveGlobal); + QObject::connect(&loginScreen, &LoginScreen::autoLoginChanged, &settings, &Settings::setAutoLogin); + QObject::connect(&loginScreen, &LoginScreen::autoLoginChanged, &settings, &Settings::saveGlobal); // Settings -> LoginScreen - QObject::connect(settings, &Settings::autoLoginChanged, &loginScreen, + QObject::connect(&settings, &Settings::autoLoginChanged, &loginScreen, &LoginScreen::onAutoLoginChanged); } @@ -235,8 +226,8 @@ void Nexus::showMainGUI() assert(profile); // Create GUI - widget = new Widget(*profile, *audioControl, *cameraSource, *settings, *style, - *ipc); + widget = new Widget(*profile, *audioControl, cameraSource, settings, *style, + ipc, *this); // Start GUI widget->init(); @@ -262,23 +253,6 @@ void Nexus::showMainGUI() widget->setEnabled(true); } -/** - * @brief Returns the singleton instance. - */ -Nexus& Nexus::getInstance() -{ - if (!nexus) - nexus = new Nexus; - - return *nexus; -} - -void Nexus::destroyInstance() -{ - delete nexus; - nexus = nullptr; -} - /** * @brief Get current user profile. * @return nullptr if not started, profile otherwise. @@ -295,8 +269,8 @@ Profile* Nexus::getProfile() */ void Nexus::onCreateNewProfile(const QString& name, const QString& pass) { - setProfile(Profile::createProfile(name, pass, *settings, parser, *cameraSource, - *messageBoxManager)); + setProfile(Profile::createProfile(name, pass, settings, parser, cameraSource, + messageBoxManager)); parser = nullptr; // only apply cmdline proxy settings once } @@ -305,8 +279,8 @@ void Nexus::onCreateNewProfile(const QString& name, const QString& pass) */ void Nexus::onLoadProfile(const QString& name, const QString& pass) { - setProfile(Profile::loadProfile(name, pass, *settings, parser, *cameraSource, - *messageBoxManager)); + setProfile(Profile::loadProfile(name, pass, settings, parser, cameraSource, + messageBoxManager)); parser = nullptr; // only apply cmdline proxy settings once } /** @@ -331,21 +305,6 @@ void Nexus::setParser(QCommandLineParser* parser_) parser = parser_; } -CameraSource& Nexus::getCameraSource() -{ - return *cameraSource; -} - -void Nexus::setMessageBoxManager(IMessageBoxManager* messageBoxManager_) -{ - messageBoxManager = messageBoxManager_; -} - -void Nexus::setIpc(IPC* ipc_) -{ - ipc = ipc_; -} - void Nexus::registerIpcHandlers() { widget->registerIpcHandlers(); diff --git a/src/nexus.h b/src/nexus.h index 2f358878f..30a71a49d 100644 --- a/src/nexus.h +++ b/src/nexus.h @@ -50,16 +50,13 @@ class Nexus : public QObject { Q_OBJECT public: + Nexus(Settings& settings, IMessageBoxManager& messageBoxManager, + CameraSource& cameraSource, IPC& ipc, QObject* parent = nullptr); + ~Nexus(); void start(); void showMainGUI(); - void setSettings(Settings* settings_); - void setMessageBoxManager(IMessageBoxManager* messageBoxManager); - void setIpc(IPC* ipc); void setParser(QCommandLineParser* parser_); - static Nexus& getInstance(); - static void destroyInstance(); Profile* getProfile(); - CameraSource& getCameraSource(); void registerIpcHandlers(); bool handleToxSave(const QString& path); @@ -101,19 +98,17 @@ public slots: void bootstrapWithProfile(Profile* p); private: - explicit Nexus(QObject* parent = nullptr); void connectLoginScreen(const LoginScreen& loginScreen); void setProfile(Profile* p); - ~Nexus(); private: Profile* profile; - Settings* settings; + Settings& settings; Widget* widget; std::unique_ptr audioControl; QCommandLineParser* parser = nullptr; - std::unique_ptr cameraSource; + CameraSource& cameraSource; std::unique_ptr