From f980d960b75d40cac79a15b52917eddcdbfad639 Mon Sep 17 00:00:00 2001 From: Nav Date: Wed, 24 May 2023 23:12:36 +0100 Subject: [PATCH] Refactored insight startup code to accommodate on-demand activation. Also created new event for activation request --- src/Application.cpp | 72 +++++++++++++------ src/Application.hpp | 25 ++++++- src/EventManager/Events/Event.hpp | 1 + src/EventManager/Events/Events.hpp | 4 ++ .../Events/InsightActivationRequested.hpp | 26 +++++++ src/Insight/Insight.cpp | 7 +- src/Insight/Insight.hpp | 5 ++ .../InsightWindow/InsightWindow.cpp | 4 ++ 8 files changed, 118 insertions(+), 26 deletions(-) create mode 100644 src/EventManager/Events/InsightActivationRequested.hpp diff --git a/src/Application.cpp b/src/Application.cpp index cfb2d665..77297aec 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -57,33 +57,19 @@ namespace Bloom this->startup(); #ifndef EXCLUDE_INSIGHT - if (this->insightConfig->insightEnabled) { - this->insight = std::make_unique( - *(this->applicationEventListener), - this->projectConfig.value(), - this->environmentConfig.value(), - this->insightConfig.value(), - this->projectSettings.value().insightSettings - ); - - /* - * Before letting Insight occupy the main thread, process any pending events that accumulated - * during startup. - */ - this->applicationEventListener->dispatchCurrentEvents(); - - if (Thread::getThreadState() == ThreadState::READY) { - this->insight->run(); - Logger::debug("Insight closed"); - } - - this->shutdown(); - return EXIT_SUCCESS; - } + this->insightActivationPending = this->insightConfig->insightEnabled; #endif // Main event loop while (Thread::getThreadState() == ThreadState::READY) { +#ifndef EXCLUDE_INSIGHT + if (this->insightActivationPending) { + this->insightActivationPending = false; + this->startInsight(); + continue; + } +#endif + this->applicationEventListener->waitAndDispatch(); } @@ -159,6 +145,11 @@ namespace Bloom std::bind(&Application::onDebugSessionFinished, this, std::placeholders::_1) ); +#ifndef EXCLUDE_INSIGHT + applicationEventListener->registerCallbackForEventType( + std::bind(&Application::onInsightActivationRequest, this, std::placeholders::_1) + ); +#endif this->startTargetController(); this->startDebugServer(); @@ -507,6 +498,41 @@ namespace Bloom } } +#ifndef EXCLUDE_INSIGHT + void Application::startInsight() { + assert(!this->insight); + + this->insight = std::make_unique( + *(this->applicationEventListener), + this->projectConfig.value(), + this->environmentConfig.value(), + this->insightConfig.value(), + this->projectSettings.value().insightSettings + ); + + /* + * Before letting Insight occupy the main thread, process any pending events that accumulated + * during startup. + */ + this->applicationEventListener->dispatchCurrentEvents(); + + if (Thread::getThreadState() == ThreadState::READY) { + this->insight->run(); + Logger::debug("Insight closed"); + } + } + + void Application::onInsightActivationRequest(const Events::InsightActivationRequested&) { + if (this->insight) { + // Insight has already been started + this->insight->showMainWindow(); + return; + } + + this->insightActivationPending = true; + } +#endif + void Application::onShutdownApplicationRequest(const Events::ShutdownApplication&) { Logger::debug("ShutdownApplication event received."); this->shutdown(); diff --git a/src/Application.hpp b/src/Application.hpp index e3d87aea..b4a726cf 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -86,8 +86,8 @@ namespace Bloom #ifndef EXCLUDE_INSIGHT /** - * Insight is, effectively, a small Qt application that serves a GUI to the user. It occupies the main thread, - * as well as a single worker thread, and possibly other threads created by Qt. + * Insight is a small Qt application that serves a GUI to the user. It occupies the main thread, as well as a + * single worker thread, and possibly other threads created by Qt. * * Insight is optional - users can disable it via their project configuration. * @@ -100,6 +100,13 @@ namespace Bloom * as we want to manage the lifetime of the object here. */ std::unique_ptr insight = nullptr; + + /** + * Activation of the Insight GUI can be requested by triggering an InsightActivationRequested event. + * + * This flag will be set upon that event being triggered. The Insight GUI will be started shortly after. + */ + bool insightActivationPending = false; #endif /** @@ -231,6 +238,20 @@ namespace Bloom */ void stopDebugServer(); +#ifndef EXCLUDE_INSIGHT + /** + * Starts the Insight GUI. + * + * This function should never be called more than once. + */ + void startInsight(); + + /** + * Handles requests to start the Insight GUI. + */ + void onInsightActivationRequest(const Events::InsightActivationRequested&); +#endif + /** * Triggers a shutdown of Bloom and all of its components. */ diff --git a/src/EventManager/Events/Event.hpp b/src/EventManager/Events/Event.hpp index bf4cce6c..90e02d66 100644 --- a/src/EventManager/Events/Event.hpp +++ b/src/EventManager/Events/Event.hpp @@ -32,6 +32,7 @@ namespace Bloom::Events TARGET_RESET, PROGRAMMING_MODE_ENABLED, PROGRAMMING_MODE_DISABLED, + INSIGHT_ACTIVATION_REQUESTED, }; class Event diff --git a/src/EventManager/Events/Events.hpp b/src/EventManager/Events/Events.hpp index 2998c181..f3c28f47 100644 --- a/src/EventManager/Events/Events.hpp +++ b/src/EventManager/Events/Events.hpp @@ -20,6 +20,10 @@ #include "ProgrammingModeEnabled.hpp" #include "ProgrammingModeDisabled.hpp" +#ifndef EXCLUDE_INSIGHT +#include "InsightActivationRequested.hpp" +#endif + namespace Bloom::Events { template diff --git a/src/EventManager/Events/InsightActivationRequested.hpp b/src/EventManager/Events/InsightActivationRequested.hpp new file mode 100644 index 00000000..77b73d6b --- /dev/null +++ b/src/EventManager/Events/InsightActivationRequested.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include "Event.hpp" + +namespace Bloom::Events +{ + class InsightActivationRequested: public Event + { + public: + static constexpr EventType type = EventType::INSIGHT_ACTIVATION_REQUESTED; + static const inline std::string name = "InsightActivationRequested"; + + InsightActivationRequested() = default; + + [[nodiscard]] EventType getType() const override { + return InsightActivationRequested::type; + } + + [[nodiscard]] std::string getName() const override { + return InsightActivationRequested::name; + } + }; +} diff --git a/src/Insight/Insight.cpp b/src/Insight/Insight.cpp index ceb3df5e..256bddc8 100644 --- a/src/Insight/Insight.cpp +++ b/src/Insight/Insight.cpp @@ -66,6 +66,11 @@ namespace Bloom this->shutdown(); } + void Insight::showMainWindow() { + this->mainWindow->show(); + this->mainWindow->activateWindow(); + } + void Insight::startup() { Logger::info("Starting Insight"); this->setThreadState(ThreadState::STARTING); @@ -102,7 +107,7 @@ namespace Bloom std::bind(&Insight::onProgrammingModeDisabledEvent, this, std::placeholders::_1) ); - QApplication::setQuitOnLastWindowClosed(true); + QApplication::setQuitOnLastWindowClosed(false); QApplication::setStyle(new BloomProxyStyle()); auto globalStylesheet = QFile( diff --git a/src/Insight/Insight.hpp b/src/Insight/Insight.hpp index 487de291..98b4d2a7 100644 --- a/src/Insight/Insight.hpp +++ b/src/Insight/Insight.hpp @@ -61,6 +61,11 @@ namespace Bloom */ void run(); + /** + * Opens main window and obtains focus. + */ + void showMainWindow(); + /** * Shuts down Insight. Called when the user closes the Insight window or a ShutdownApplication event is fired. */ diff --git a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp index fe9733c7..1e6e5940 100644 --- a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp @@ -318,6 +318,10 @@ namespace Bloom } void InsightWindow::showEvent(QShowEvent* event) { + if (!this->activated) { + this->activate(); + } + this->adjustPanels(); this->adjustMinimumSize(); }