From 49383eb448bc613d7522c8f738918ec1fb300655 Mon Sep 17 00:00:00 2001 From: Nav Date: Fri, 31 Dec 2021 19:45:15 +0000 Subject: [PATCH] Improved handling of late initialisation for component objects --- src/Application.cpp | 62 +++++++++++-------- src/Application.hpp | 21 +++++-- src/DebugServers/DebugServer.hpp | 24 ++++--- .../GdbRsp/AvrGdbRsp/AvrGdbRsp.hpp | 7 ++- src/DebugServers/GdbRsp/GdbRspDebugServer.hpp | 7 ++- src/Insight/Insight.hpp | 28 ++++----- .../InsightWindow/InsightWindow.cpp | 12 +++- .../InsightWindow/InsightWindow.hpp | 6 +- src/TargetController/TargetController.hpp | 14 ++--- 9 files changed, 109 insertions(+), 72 deletions(-) diff --git a/src/Application.cpp b/src/Application.cpp index 92879f63..3419e361 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -44,11 +44,13 @@ int Application::run(const std::vector& arguments) { this->startup(); - if (this->insightConfig.insightEnabled) { - this->insight = std::make_unique(this->eventManager); - this->insight->setProjectConfig(this->projectConfig); - this->insight->setEnvironmentConfig(this->environmentConfig); - this->insight->setInsightConfig(this->insightConfig); + if (this->insightConfig->insightEnabled) { + this->insight = std::make_unique( + this->eventManager, + this->projectConfig.value(), + this->environmentConfig.value(), + this->insightConfig.value() + ); /* * Before letting Insight occupy the main thread, process any pending events that accumulated @@ -92,8 +94,8 @@ void Application::startup() { std::bind(&Application::onShutdownApplicationRequest, this, std::placeholders::_1) ); - this->projectConfig = this->extractConfig(); - Logger::configure(this->projectConfig); + this->projectConfig = Application::extractConfig(); + Logger::configure(this->projectConfig.value()); // Start signal handler this->blockAllSignalsOnCurrentThread(); @@ -101,21 +103,30 @@ void Application::startup() { Logger::info("Selected environment: \"" + this->selectedEnvironmentName + "\""); Logger::debug("Number of environments extracted from config: " - + std::to_string(this->projectConfig.environments.size())); + + std::to_string(this->projectConfig->environments.size())); // Validate the selected environment - if (!projectConfig.environments.contains(this->selectedEnvironmentName)) { + if (!this->projectConfig->environments.contains(this->selectedEnvironmentName)) { throw InvalidConfig("Environment (\"" + this->selectedEnvironmentName + "\") not found in configuration."); } - this->environmentConfig = projectConfig.environments.at(this->selectedEnvironmentName); - this->insightConfig = this->environmentConfig.insightConfig.value_or(this->projectConfig.insightConfig); + this->environmentConfig = this->projectConfig->environments.at(this->selectedEnvironmentName); - if (this->environmentConfig.debugServerConfig.has_value()) { - this->debugServerConfig = this->environmentConfig.debugServerConfig.value(); + if (this->environmentConfig->insightConfig.has_value()) { + this->insightConfig = this->environmentConfig->insightConfig.value(); - } else if (this->projectConfig.debugServerConfig.has_value()) { - this->debugServerConfig = this->projectConfig.debugServerConfig.value(); + } else if (this->projectConfig->insightConfig.has_value()) { + this->insightConfig = this->projectConfig->insightConfig.value(); + + } else { + throw InvalidConfig("Insight configuration missing."); + } + + if (this->environmentConfig->debugServerConfig.has_value()) { + this->debugServerConfig = this->environmentConfig->debugServerConfig.value(); + + } else if (this->projectConfig->debugServerConfig.has_value()) { + this->debugServerConfig = this->projectConfig->debugServerConfig.value(); } else { throw InvalidConfig("Debug server configuration missing."); @@ -269,12 +280,15 @@ int Application::initProject() { } void Application::startTargetController() { - this->targetController.setProjectConfig(this->projectConfig); - this->targetController.setEnvironmentConfig(this->environmentConfig); + this->targetController = std::make_unique( + this->eventManager, + this->projectConfig.value(), + this->environmentConfig.value() + ); this->targetControllerThread = std::thread( &TargetController::run, - std::ref(this->targetController) + this->targetController.get() ); auto tcStateChangeEvent = this->applicationEventListener->waitForEvent(); @@ -285,7 +299,7 @@ void Application::startTargetController() { } void Application::stopTargetController() { - auto targetControllerState = this->targetController.getThreadState(); + auto targetControllerState = this->targetController->getThreadState(); if (targetControllerState == ThreadState::STARTING || targetControllerState == ThreadState::READY) { this->eventManager.triggerEvent(std::make_shared()); this->applicationEventListener->waitForEvent( @@ -302,15 +316,11 @@ void Application::stopTargetController() { void Application::startDebugServer() { auto supportedDebugServers = this->getSupportedDebugServers(); - if (!supportedDebugServers.contains(this->debugServerConfig.name)) { - throw Exceptions::InvalidConfig("DebugServer \"" + this->debugServerConfig.name + "\" not found."); + if (!supportedDebugServers.contains(this->debugServerConfig->name)) { + throw Exceptions::InvalidConfig("DebugServer \"" + this->debugServerConfig->name + "\" not found."); } - this->debugServer = supportedDebugServers.at(this->debugServerConfig.name)(); - this->debugServer->setProjectConfig(this->projectConfig); - this->debugServer->setEnvironmentConfig(this->environmentConfig); - this->debugServer->setDebugServerConfig(this->debugServerConfig); - + this->debugServer = supportedDebugServers.at(this->debugServerConfig->name)(); Logger::info("Selected DebugServer: " + this->debugServer->getName()); this->debugServerThread = std::thread( diff --git a/src/Application.hpp b/src/Application.hpp index 5c05a980..91fa2f01 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -49,7 +49,12 @@ namespace Bloom { "avr-gdb-rsp", [this] () -> std::unique_ptr { - return std::make_unique(this->eventManager); + return std::make_unique( + this->eventManager, + this->projectConfig.value(), + this->environmentConfig.value(), + this->debugServerConfig.value() + ); } }, }; @@ -97,8 +102,12 @@ namespace Bloom * dedicated thread. * * See the TargetController class for more on this. + * + * I could have used std::optional here, for the late initialisation, but given that we're using + * std::unique_ptr for the debug server (for polymorphism), I thought I'd keep it consistent and just use + * std::unique_ptr for lazy loading. */ - TargetController targetController = TargetController(this->eventManager); + std::unique_ptr targetController = nullptr; std::thread targetControllerThread; /** @@ -133,10 +142,10 @@ namespace Bloom * * See ProjectConfig.hpp for more on this. */ - ProjectConfig projectConfig; - EnvironmentConfig environmentConfig; - DebugServerConfig debugServerConfig; - InsightConfig insightConfig; + std::optional projectConfig; + std::optional environmentConfig; + std::optional debugServerConfig; + std::optional insightConfig; /** * The project environment selected by the user. diff --git a/src/DebugServers/DebugServer.hpp b/src/DebugServers/DebugServer.hpp index 7e47687f..908f70d4 100644 --- a/src/DebugServers/DebugServer.hpp +++ b/src/DebugServers/DebugServer.hpp @@ -28,21 +28,19 @@ namespace Bloom::DebugServers class DebugServer: public Thread { public: - explicit DebugServer(EventManager& eventManager): eventManager(eventManager) {}; + explicit DebugServer( + EventManager& eventManager, + const ProjectConfig& projectConfig, + const EnvironmentConfig& environmentConfig, + const DebugServerConfig& debugServerConfig + ): + eventManager(eventManager), + projectConfig(projectConfig), + environmentConfig(environmentConfig), + debugServerConfig(debugServerConfig) {}; + virtual ~DebugServer() = default; - void setProjectConfig(const ProjectConfig& projectConfig) { - this->projectConfig = projectConfig; - } - - void setEnvironmentConfig(const EnvironmentConfig& environmentConfig) { - this->environmentConfig = environmentConfig; - } - - void setDebugServerConfig(const DebugServerConfig& debugServerConfig) { - this->debugServerConfig = debugServerConfig; - } - /** * Entry point for the DebugServer. This must called from a dedicated thread. */ diff --git a/src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.hpp b/src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.hpp index 9de6942c..77b7a54e 100644 --- a/src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.hpp +++ b/src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.hpp @@ -26,7 +26,12 @@ namespace Bloom::DebugServers::Gdb class AvrGdbRsp: public GdbRspDebugServer { public: - explicit AvrGdbRsp(EventManager& eventManager): GdbRspDebugServer(eventManager) {}; + explicit AvrGdbRsp( + EventManager& eventManager, + const ProjectConfig& projectConfig, + const EnvironmentConfig& environmentConfig, + const DebugServerConfig& debugServerConfig + ): GdbRspDebugServer(eventManager, projectConfig, environmentConfig, debugServerConfig) {}; std::string getName() const override { return "AVR GDB Remote Serial Protocol Debug Server"; diff --git a/src/DebugServers/GdbRsp/GdbRspDebugServer.hpp b/src/DebugServers/GdbRsp/GdbRspDebugServer.hpp index 46a3f451..1fd11264 100644 --- a/src/DebugServers/GdbRsp/GdbRspDebugServer.hpp +++ b/src/DebugServers/GdbRsp/GdbRspDebugServer.hpp @@ -36,7 +36,12 @@ namespace Bloom::DebugServers::Gdb class GdbRspDebugServer: public DebugServer { public: - explicit GdbRspDebugServer(EventManager& eventManager): DebugServer(eventManager) {}; + explicit GdbRspDebugServer( + EventManager& eventManager, + const ProjectConfig& projectConfig, + const EnvironmentConfig& environmentConfig, + const DebugServerConfig& debugServerConfig + ): DebugServer(eventManager, projectConfig, environmentConfig, debugServerConfig) {}; std::string getName() const override { return "GDB Remote Serial Protocol DebugServer"; diff --git a/src/Insight/Insight.hpp b/src/Insight/Insight.hpp index e7ced041..1ded24e7 100644 --- a/src/Insight/Insight.hpp +++ b/src/Insight/Insight.hpp @@ -37,8 +37,16 @@ namespace Bloom * * @param eventManager */ - explicit Insight(EventManager& eventManager): + explicit Insight( + EventManager& eventManager, + const ProjectConfig& projectConfig, + const EnvironmentConfig& environmentConfig, + const InsightConfig& insightConfig + ): eventManager(eventManager), + projectConfig(projectConfig), + environmentConfig(environmentConfig), + insightConfig(insightConfig), application( ( QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, false), @@ -49,18 +57,6 @@ namespace Bloom ) ) {}; - void setProjectConfig(const ProjectConfig& projectConfig) { - this->projectConfig = projectConfig; - } - - void setEnvironmentConfig(const EnvironmentConfig& environmentConfig) { - this->environmentConfig = environmentConfig; - } - - void setInsightConfig(const InsightConfig& insightConfig) { - this->insightConfig = insightConfig; - } - /** * Entry point for Insight. */ @@ -80,7 +76,11 @@ namespace Bloom QApplication application; InsightWorker* insightWorker = new InsightWorker(this->eventManager); - InsightWindow* mainWindow = new InsightWindow(*(this->insightWorker)); + InsightWindow* mainWindow = new InsightWindow( + *(this->insightWorker), + this->environmentConfig, + this->insightConfig + ); TargetControllerConsole targetControllerConsole = TargetControllerConsole( this->eventManager, diff --git a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp index 78015abe..ed7a531f 100644 --- a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp @@ -27,7 +27,17 @@ using Bloom::Targets::TargetPackage; using Bloom::Targets::TargetPinDescriptor; using Bloom::Targets::TargetMemoryType; -InsightWindow::InsightWindow(InsightWorker& insightWorker): QMainWindow(nullptr), insightWorker(insightWorker) { +InsightWindow::InsightWindow( + InsightWorker& insightWorker, + const EnvironmentConfig& environmentConfig, + const InsightConfig& insightConfig +): + QMainWindow(nullptr), + insightWorker(insightWorker), + environmentConfig(environmentConfig), + targetConfig(environmentConfig.targetConfig), + insightConfig(insightConfig) +{ this->setObjectName("main-window"); this->setWindowTitle("Bloom Insight"); this->setMinimumSize(1000, 500); diff --git a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp index 2cba3fd6..80430ca4 100644 --- a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp @@ -30,7 +30,11 @@ namespace Bloom Q_OBJECT public: - InsightWindow(InsightWorker& insightWorker); + InsightWindow( + InsightWorker& insightWorker, + const EnvironmentConfig& environmentConfig, + const InsightConfig& insightConfig + ); void setEnvironmentConfig(const EnvironmentConfig& environmentConfig) { this->environmentConfig = environmentConfig; diff --git a/src/TargetController/TargetController.hpp b/src/TargetController/TargetController.hpp index c87f9d98..9b634c75 100644 --- a/src/TargetController/TargetController.hpp +++ b/src/TargetController/TargetController.hpp @@ -34,15 +34,11 @@ namespace Bloom class TargetController: public Thread { public: - explicit TargetController(EventManager& eventManager): eventManager(eventManager) {}; - - void setProjectConfig(const ProjectConfig& projectConfig) { - this->projectConfig = projectConfig; - } - - void setEnvironmentConfig(const EnvironmentConfig& environmentConfig) { - this->environmentConfig = environmentConfig; - } + explicit TargetController( + EventManager& eventManager, + const ProjectConfig& projectConfig, + const EnvironmentConfig& environmentConfig + ): eventManager(eventManager), projectConfig(projectConfig), environmentConfig(environmentConfig) {}; /** * Entry point for the TargetController.