This commit is contained in:
Nav
2022-04-28 21:08:55 +01:00
parent 178df2d9e0
commit 80405057f6
8 changed files with 275 additions and 265 deletions

View File

@@ -160,7 +160,7 @@ namespace Bloom
&InsightWindow::openAboutWindow
);
// Tool bar button connections
// Toolbar button connections
QObject::connect(
this->refreshIoInspectionButton,
&QToolButton::clicked,

View File

@@ -53,8 +53,7 @@ namespace Bloom::Widgets
size.setWidth(static_cast<int>(
std::cos(angleRadians) * textSize.width()
+ std::ceil(std::sin(angleRadians) * textSize.height())
))
;
));
size.setHeight(static_cast<int>(
std::sin(angleRadians) * textSize.width()
+ std::ceil(std::cos(angleRadians) * textSize.height())

View File

@@ -12,7 +12,9 @@ namespace Bloom::Widgets
public:
RotatableLabel(const QString& text, QWidget* parent): QLabel(text, parent) {};
RotatableLabel(int angleDegrees, const QString& text, QWidget* parent)
: QLabel(text, parent), angle(angleDegrees) {};
: QLabel(text, parent),
angle(angleDegrees)
{};
void setAngle(int angleDegrees) {
this->angle = angleDegrees;
@@ -23,11 +25,11 @@ namespace Bloom::Widgets
[[nodiscard]] QSize sizeHint() const override {
return this->getContainerSize();
};
}
[[nodiscard]] QSize minimumSizeHint() const override {
return this->getContainerSize();
};
}
private:
int angle = 90;

View File

@@ -12,285 +12,287 @@
#include "src/Helpers/Paths.hpp"
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::Widgets;
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetMemoryDescriptor;
using Bloom::Targets::TargetMemoryType;
TargetMemoryInspectionPane::TargetMemoryInspectionPane(
const TargetMemoryDescriptor& targetMemoryDescriptor,
TargetMemoryInspectionPaneSettings& settings,
InsightWorker& insightWorker,
PanelWidget* parent
)
: PaneWidget(parent)
, targetMemoryDescriptor(targetMemoryDescriptor)
, settings(settings)
, insightWorker(insightWorker)
namespace Bloom::Widgets
{
this->setObjectName("target-memory-inspection-pane");
using namespace Bloom::Exceptions;
auto memoryInspectionPaneUiFile = QFile(
QString::fromStdString(Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/UiFiles/TargetMemoryInspectionPane.ui"
)
);
using Bloom::Targets::TargetMemoryDescriptor;
using Bloom::Targets::TargetMemoryType;
if (!memoryInspectionPaneUiFile.open(QFile::ReadOnly)) {
throw Exception("Failed to open MemoryInspectionPane UI file");
}
TargetMemoryInspectionPane::TargetMemoryInspectionPane(
const TargetMemoryDescriptor& targetMemoryDescriptor,
TargetMemoryInspectionPaneSettings& settings,
InsightWorker& insightWorker,
PanelWidget* parent
)
: PaneWidget(parent)
, targetMemoryDescriptor(targetMemoryDescriptor)
, settings(settings)
, insightWorker(insightWorker)
{
this->setObjectName("target-memory-inspection-pane");
auto uiLoader = UiLoader(this);
this->container = uiLoader.load(&memoryInspectionPaneUiFile, this);
this->container->setFixedSize(parent->width(), parent->maximumHeight());
this->titleBar = this->container->findChild<QWidget*>("title-bar");
this->titleBar->layout()->setContentsMargins(7, 0, 7, 0);
auto* titleLabel = this->titleBar->findChild<QLabel*>("title");
titleLabel->setText(
this->targetMemoryDescriptor.type == TargetMemoryType::EEPROM ? "Internal EEPROM" : "Internal RAM"
);
// Quick sanity check to ensure the validity of persisted settings.
this->sanitiseSettings();
auto* subContainerLayout = this->container->findChild<QHBoxLayout*>("sub-container-layout");
this->manageMemoryRegionsButton = this->container->findChild<SvgToolButton*>("manage-memory-regions-btn");
this->hexViewerWidget = new HexViewerWidget(
this->targetMemoryDescriptor,
this->settings.hexViewerWidgetSettings,
this->settings.focusedMemoryRegions,
this->settings.excludedMemoryRegions,
this->insightWorker,
this
);
this->hexViewerWidget->setDisabled(true);
subContainerLayout->addWidget(this->hexViewerWidget);
QObject::connect(
this->manageMemoryRegionsButton,
&QToolButton::clicked,
this,
&TargetMemoryInspectionPane::openMemoryRegionManagerWindow
);
QObject::connect(
&insightWorker,
&InsightWorker::targetStateUpdated,
this,
&TargetMemoryInspectionPane::onTargetStateChanged
);
QObject::connect(
this->hexViewerWidget->refreshButton,
&QToolButton::clicked,
this,
[this] {
this->refreshMemoryValues();
}
);
}
void TargetMemoryInspectionPane::refreshMemoryValues(std::optional<std::function<void(void)>> callback) {
this->hexViewerWidget->refreshButton->setDisabled(true);
this->hexViewerWidget->refreshButton->startSpin();
auto excludedAddressRanges = std::set<Targets::TargetMemoryAddressRange>();
std::transform(
this->settings.excludedMemoryRegions.begin(),
this->settings.excludedMemoryRegions.end(),
std::inserter(excludedAddressRanges, excludedAddressRanges.begin()),
[this] (const ExcludedMemoryRegion& excludedRegion) {
return excludedRegion.addressRange;
}
);
auto* readMemoryTask = new ReadTargetMemory(
this->targetMemoryDescriptor.type,
this->targetMemoryDescriptor.addressRange.startAddress,
this->targetMemoryDescriptor.size(),
excludedAddressRanges
);
QObject::connect(
readMemoryTask,
&ReadTargetMemory::targetMemoryRead,
this,
[this] (const Targets::TargetMemoryBuffer& buffer) {
this->onMemoryRead(buffer);
// Refresh the stack pointer if this is RAM.
if (this->targetMemoryDescriptor.type == Targets::TargetMemoryType::RAM) {
auto* readStackPointerTask = new ReadStackPointer();
QObject::connect(
readStackPointerTask,
&ReadStackPointer::stackPointerRead,
this,
[this] (std::uint32_t stackPointer) {
this->hexViewerWidget->setStackPointer(stackPointer);
}
);
this->insightWorker.queueTask(readStackPointerTask);
}
}
);
QObject::connect(
readMemoryTask,
&InsightWorkerTask::finished,
this,
[this] {
this->hexViewerWidget->refreshButton->stopSpin();
if (this->targetState == Targets::TargetState::STOPPED) {
this->hexViewerWidget->refreshButton->setDisabled(false);
}
}
);
if (callback.has_value()) {
QObject::connect(
readMemoryTask,
&InsightWorkerTask::completed,
this,
callback.value()
auto memoryInspectionPaneUiFile = QFile(
QString::fromStdString(Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/UiFiles/TargetMemoryInspectionPane.ui"
)
);
}
this->insightWorker.queueTask(readMemoryTask);
}
void TargetMemoryInspectionPane::activate() {
this->show();
this->activated = true;
this->postActivate();
}
void TargetMemoryInspectionPane::deactivate() {
this->hide();
this->activated = false;
this->postDeactivate();
}
void TargetMemoryInspectionPane::resizeEvent(QResizeEvent* event) {
const auto parentSize = this->parentPanel->size();
const auto width = parentSize.width() - 1;
this->container->setFixedSize(width, parentSize.height());
}
void TargetMemoryInspectionPane::postActivate() {
if (this->targetState == Targets::TargetState::STOPPED) {
this->refreshMemoryValues([this] {
this->hexViewerWidget->setDisabled(false);
});
}
}
void TargetMemoryInspectionPane::postDeactivate() {
}
void TargetMemoryInspectionPane::sanitiseSettings() {
// Remove any invalid memory regions. It's very unlikely that there will be any, but not impossible.
auto processedFocusedMemoryRegions = std::vector<FocusedMemoryRegion>();
auto processedExcludedMemoryRegions = std::vector<ExcludedMemoryRegion>();
const auto regionIntersects = [
&processedFocusedMemoryRegions,
&processedExcludedMemoryRegions
] (const MemoryRegion& region) {
for (const auto& processedFocusedRegion : processedFocusedMemoryRegions) {
if (processedFocusedRegion.intersectsWith(region)) {
return true;
}
if (!memoryInspectionPaneUiFile.open(QFile::ReadOnly)) {
throw Exception("Failed to open MemoryInspectionPane UI file");
}
for (const auto& processedExcludedRegion : processedExcludedMemoryRegions) {
if (processedExcludedRegion.intersectsWith(region)) {
return true;
}
}
auto uiLoader = UiLoader(this);
this->container = uiLoader.load(&memoryInspectionPaneUiFile, this);
this->container->setFixedSize(parent->width(), parent->maximumHeight());
return false;
};
this->titleBar = this->container->findChild<QWidget*>("title-bar");
for (const auto& focusedRegion : this->settings.focusedMemoryRegions) {
if (!this->targetMemoryDescriptor.addressRange.contains(focusedRegion.addressRange)
|| regionIntersects(focusedRegion)
) {
continue;
}
this->titleBar->layout()->setContentsMargins(7, 0, 7, 0);
auto* titleLabel = this->titleBar->findChild<QLabel*>("title");
titleLabel->setText(
this->targetMemoryDescriptor.type == TargetMemoryType::EEPROM ? "Internal EEPROM" : "Internal RAM"
);
processedFocusedMemoryRegions.emplace_back(focusedRegion);
}
// Quick sanity check to ensure the validity of persisted settings.
this->sanitiseSettings();
for (const auto& excludedRegion : this->settings.excludedMemoryRegions) {
if (!this->targetMemoryDescriptor.addressRange.contains(excludedRegion.addressRange)
|| regionIntersects(excludedRegion)
) {
continue;
}
processedExcludedMemoryRegions.emplace_back(excludedRegion);
}
this->settings.focusedMemoryRegions = std::move(processedFocusedMemoryRegions);
this->settings.excludedMemoryRegions = std::move(processedExcludedMemoryRegions);
}
void TargetMemoryInspectionPane::onTargetStateChanged(Targets::TargetState newState) {
if (this->targetState == newState) {
return;
}
using Targets::TargetState;
this->targetState = newState;
if (newState == TargetState::STOPPED && this->activated) {
this->refreshMemoryValues([this] {
this->hexViewerWidget->setDisabled(false);
});
} else if (newState == TargetState::RUNNING) {
this->hexViewerWidget->setDisabled(true);
}
}
void TargetMemoryInspectionPane::onMemoryRead(const Targets::TargetMemoryBuffer& buffer) {
this->hexViewerWidget->updateValues(buffer);
}
void TargetMemoryInspectionPane::openMemoryRegionManagerWindow() {
if (this->memoryRegionManagerWindow == nullptr) {
this->memoryRegionManagerWindow = new MemoryRegionManagerWindow(
auto* subContainerLayout = this->container->findChild<QHBoxLayout*>("sub-container-layout");
this->manageMemoryRegionsButton = this->container->findChild<SvgToolButton*>("manage-memory-regions-btn");
this->hexViewerWidget = new HexViewerWidget(
this->targetMemoryDescriptor,
this->settings.hexViewerWidgetSettings,
this->settings.focusedMemoryRegions,
this->settings.excludedMemoryRegions,
this->insightWorker,
this
);
this->hexViewerWidget->setDisabled(true);
subContainerLayout->addWidget(this->hexViewerWidget);
QObject::connect(
this->manageMemoryRegionsButton,
&QToolButton::clicked,
this,
&TargetMemoryInspectionPane::openMemoryRegionManagerWindow
);
QObject::connect(
this->memoryRegionManagerWindow,
&MemoryRegionManagerWindow::changesApplied,
&insightWorker,
&InsightWorker::targetStateUpdated,
this,
&TargetMemoryInspectionPane::onMemoryRegionsChange
&TargetMemoryInspectionPane::onTargetStateChanged
);
QObject::connect(
this->hexViewerWidget->refreshButton,
&QToolButton::clicked,
this,
[this] {
this->refreshMemoryValues();
}
);
}
if (!this->memoryRegionManagerWindow->isVisible()) {
this->memoryRegionManagerWindow->refreshRegions();
this->memoryRegionManagerWindow->show();
void TargetMemoryInspectionPane::refreshMemoryValues(std::optional<std::function<void(void)>> callback) {
this->hexViewerWidget->refreshButton->setDisabled(true);
this->hexViewerWidget->refreshButton->startSpin();
} else {
this->memoryRegionManagerWindow->activateWindow();
auto excludedAddressRanges = std::set<Targets::TargetMemoryAddressRange>();
std::transform(
this->settings.excludedMemoryRegions.begin(),
this->settings.excludedMemoryRegions.end(),
std::inserter(excludedAddressRanges, excludedAddressRanges.begin()),
[this] (const ExcludedMemoryRegion& excludedRegion) {
return excludedRegion.addressRange;
}
);
auto* readMemoryTask = new ReadTargetMemory(
this->targetMemoryDescriptor.type,
this->targetMemoryDescriptor.addressRange.startAddress,
this->targetMemoryDescriptor.size(),
excludedAddressRanges
);
QObject::connect(
readMemoryTask,
&ReadTargetMemory::targetMemoryRead,
this,
[this] (const Targets::TargetMemoryBuffer& buffer) {
this->onMemoryRead(buffer);
// Refresh the stack pointer if this is RAM.
if (this->targetMemoryDescriptor.type == Targets::TargetMemoryType::RAM) {
auto* readStackPointerTask = new ReadStackPointer();
QObject::connect(
readStackPointerTask,
&ReadStackPointer::stackPointerRead,
this,
[this] (std::uint32_t stackPointer) {
this->hexViewerWidget->setStackPointer(stackPointer);
}
);
this->insightWorker.queueTask(readStackPointerTask);
}
}
);
QObject::connect(
readMemoryTask,
&InsightWorkerTask::finished,
this,
[this] {
this->hexViewerWidget->refreshButton->stopSpin();
if (this->targetState == Targets::TargetState::STOPPED) {
this->hexViewerWidget->refreshButton->setDisabled(false);
}
}
);
if (callback.has_value()) {
QObject::connect(
readMemoryTask,
&InsightWorkerTask::completed,
this,
callback.value()
);
}
this->insightWorker.queueTask(readMemoryTask);
}
void TargetMemoryInspectionPane::activate() {
this->show();
this->activated = true;
this->postActivate();
}
void TargetMemoryInspectionPane::deactivate() {
this->hide();
this->activated = false;
this->postDeactivate();
}
void TargetMemoryInspectionPane::resizeEvent(QResizeEvent* event) {
const auto parentSize = this->parentPanel->size();
const auto width = parentSize.width() - 1;
this->container->setFixedSize(width, parentSize.height());
}
void TargetMemoryInspectionPane::postActivate() {
if (this->targetState == Targets::TargetState::STOPPED) {
this->refreshMemoryValues([this] {
this->hexViewerWidget->setDisabled(false);
});
}
}
void TargetMemoryInspectionPane::postDeactivate() {
}
void TargetMemoryInspectionPane::sanitiseSettings() {
// Remove any invalid memory regions. It's very unlikely that there will be any, but not impossible.
auto processedFocusedMemoryRegions = std::vector<FocusedMemoryRegion>();
auto processedExcludedMemoryRegions = std::vector<ExcludedMemoryRegion>();
const auto regionIntersects = [
&processedFocusedMemoryRegions,
&processedExcludedMemoryRegions
] (const MemoryRegion& region) {
for (const auto& processedFocusedRegion : processedFocusedMemoryRegions) {
if (processedFocusedRegion.intersectsWith(region)) {
return true;
}
}
for (const auto& processedExcludedRegion : processedExcludedMemoryRegions) {
if (processedExcludedRegion.intersectsWith(region)) {
return true;
}
}
return false;
};
for (const auto& focusedRegion : this->settings.focusedMemoryRegions) {
if (!this->targetMemoryDescriptor.addressRange.contains(focusedRegion.addressRange)
|| regionIntersects(focusedRegion)
) {
continue;
}
processedFocusedMemoryRegions.emplace_back(focusedRegion);
}
for (const auto& excludedRegion : this->settings.excludedMemoryRegions) {
if (!this->targetMemoryDescriptor.addressRange.contains(excludedRegion.addressRange)
|| regionIntersects(excludedRegion)
) {
continue;
}
processedExcludedMemoryRegions.emplace_back(excludedRegion);
}
this->settings.focusedMemoryRegions = std::move(processedFocusedMemoryRegions);
this->settings.excludedMemoryRegions = std::move(processedExcludedMemoryRegions);
}
void TargetMemoryInspectionPane::onTargetStateChanged(Targets::TargetState newState) {
if (this->targetState == newState) {
return;
}
using Targets::TargetState;
this->targetState = newState;
if (newState == TargetState::STOPPED && this->activated) {
this->refreshMemoryValues([this] {
this->hexViewerWidget->setDisabled(false);
});
} else if (newState == TargetState::RUNNING) {
this->hexViewerWidget->setDisabled(true);
}
}
void TargetMemoryInspectionPane::onMemoryRead(const Targets::TargetMemoryBuffer& buffer) {
this->hexViewerWidget->updateValues(buffer);
}
void TargetMemoryInspectionPane::openMemoryRegionManagerWindow() {
if (this->memoryRegionManagerWindow == nullptr) {
this->memoryRegionManagerWindow = new MemoryRegionManagerWindow(
this->targetMemoryDescriptor,
this->settings.focusedMemoryRegions,
this->settings.excludedMemoryRegions,
this
);
QObject::connect(
this->memoryRegionManagerWindow,
&MemoryRegionManagerWindow::changesApplied,
this,
&TargetMemoryInspectionPane::onMemoryRegionsChange
);
}
if (!this->memoryRegionManagerWindow->isVisible()) {
this->memoryRegionManagerWindow->refreshRegions();
this->memoryRegionManagerWindow->show();
} else {
this->memoryRegionManagerWindow->activateWindow();
}
}
void TargetMemoryInspectionPane::onMemoryRegionsChange() {
this->hexViewerWidget->refreshRegions();
}
}
void TargetMemoryInspectionPane::onMemoryRegionsChange() {
this->hexViewerWidget->refreshRegions();
}

View File

@@ -9,7 +9,6 @@
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/ErrorDialogue.hpp"
#include "src/Helpers/Paths.hpp"
#include "src/Helpers/DateTime.hpp"
#include "src/Exceptions/Exception.hpp"
#include "src/Insight/InsightWorker/Tasks/ReadTargetRegisters.hpp"

View File

@@ -25,7 +25,11 @@ namespace Bloom::Widgets
const TargetDescriptor& targetDescriptor,
InsightWorker& insightWorker,
PanelWidget* parent
): PaneWidget(parent), targetDescriptor(targetDescriptor), insightWorker(insightWorker) {
)
: PaneWidget(parent)
, targetDescriptor(targetDescriptor)
, insightWorker(insightWorker)
{
this->setObjectName("target-registers-side-pane");
auto targetRegistersPaneUiFile = QFile(

View File

@@ -12,7 +12,11 @@ namespace Bloom::Widgets::InsightTargetWidgets
Targets::TargetVariant targetVariant,
InsightWorker& insightWorker,
QWidget* parent
): QWidget(parent), targetVariant(std::move(targetVariant)), insightWorker(insightWorker) {
)
: QWidget(parent)
, targetVariant(std::move(targetVariant))
, insightWorker(insightWorker)
{
QObject::connect(
&(this->insightWorker),
&InsightWorker::targetStateUpdated,

View File

@@ -3,7 +3,7 @@
#include "Command.hpp"
#include "src/TargetController/Responses/TargetMemoryRead.hpp"
#include "src/Targets/TargetRegister.hpp"
#include "src/Targets/TargetMemory.hpp"
namespace Bloom::TargetController::Commands
{