Improved handling of late initialisation for component objects
This commit is contained in:
@@ -44,11 +44,13 @@ int Application::run(const std::vector<std::string>& arguments) {
|
||||
|
||||
this->startup();
|
||||
|
||||
if (this->insightConfig.insightEnabled) {
|
||||
this->insight = std::make_unique<Insight>(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<Insight>(
|
||||
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<TargetController>(
|
||||
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<Events::TargetControllerThreadStateChanged>();
|
||||
@@ -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<Events::ShutdownTargetController>());
|
||||
this->applicationEventListener->waitForEvent<Events::TargetControllerThreadStateChanged>(
|
||||
@@ -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(
|
||||
|
||||
@@ -49,7 +49,12 @@ namespace Bloom
|
||||
{
|
||||
"avr-gdb-rsp",
|
||||
[this] () -> std::unique_ptr<DebugServers::DebugServer> {
|
||||
return std::make_unique<DebugServers::Gdb::AvrGdbRsp>(this->eventManager);
|
||||
return std::make_unique<DebugServers::Gdb::AvrGdbRsp>(
|
||||
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> 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> projectConfig;
|
||||
std::optional<EnvironmentConfig> environmentConfig;
|
||||
std::optional<DebugServerConfig> debugServerConfig;
|
||||
std::optional<InsightConfig> insightConfig;
|
||||
|
||||
/**
|
||||
* The project environment selected by the user.
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user