Off-loaded ByteItemGraphicsScene construction to Insight worker task

This commit is contained in:
Nav
2022-09-10 22:50:52 +01:00
parent a88b77df8a
commit 241d94da54
13 changed files with 231 additions and 43 deletions

View File

@@ -31,6 +31,7 @@ target_sources(
${CMAKE_CURRENT_SOURCE_DIR}/InsightWorker/Tasks/ReadProgramCounter.cpp ${CMAKE_CURRENT_SOURCE_DIR}/InsightWorker/Tasks/ReadProgramCounter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/InsightWorker/Tasks/GetTargetState.cpp ${CMAKE_CURRENT_SOURCE_DIR}/InsightWorker/Tasks/GetTargetState.cpp
${CMAKE_CURRENT_SOURCE_DIR}/InsightWorker/Tasks/GetTargetDescriptor.cpp ${CMAKE_CURRENT_SOURCE_DIR}/InsightWorker/Tasks/GetTargetDescriptor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/InsightWorker/Tasks/ConstructHexViewerByteItemScene.cpp
# Error dialogue window # Error dialogue window
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/ErrorDialogue.cpp ${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/ErrorDialogue.cpp

View File

@@ -166,7 +166,7 @@ namespace Bloom
*/ */
auto* eventDispatchTimer = new QTimer(&(this->application)); auto* eventDispatchTimer = new QTimer(&(this->application));
QObject::connect(eventDispatchTimer, &QTimer::timeout, this, &Insight::dispatchEvents); QObject::connect(eventDispatchTimer, &QTimer::timeout, this, &Insight::dispatchEvents);
eventDispatchTimer->start(50); eventDispatchTimer->start(100);
QObject::connect( QObject::connect(
this->mainWindow, this->mainWindow,

View File

@@ -0,0 +1,32 @@
#include "ConstructHexViewerByteItemScene.hpp"
namespace Bloom
{
ConstructHexViewerByteItemScene::ConstructHexViewerByteItemScene(
const Targets::TargetMemoryDescriptor& memoryDescriptor,
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
const Widgets::HexViewerWidgetSettings& settings,
Widgets::Label* hoveredAddressLabel
)
: memoryDescriptor(memoryDescriptor)
, focusedMemoryRegions(focusedMemoryRegions)
, excludedMemoryRegions(excludedMemoryRegions)
, settings(settings)
, hoveredAddressLabel(hoveredAddressLabel)
{}
void ConstructHexViewerByteItemScene::run(TargetController::TargetControllerConsole&) {
auto* scene = new Widgets::ByteItemGraphicsScene(
this->memoryDescriptor,
this->focusedMemoryRegions,
this->excludedMemoryRegions,
this->settings,
this->hoveredAddressLabel,
nullptr
);
scene->moveToThread(nullptr);
emit this->sceneCreated(scene);
}
}

View File

@@ -0,0 +1,44 @@
#pragma once
#include "InsightWorkerTask.hpp"
#include "src/Targets/TargetMemory.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidgetSettings.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/FocusedMemoryRegion.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/ExcludedMemoryRegion.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteItemGraphicsScene.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/Label.hpp"
namespace Bloom
{
class ConstructHexViewerByteItemScene: public InsightWorkerTask
{
Q_OBJECT
public:
ConstructHexViewerByteItemScene(
const Targets::TargetMemoryDescriptor& memoryDescriptor,
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
const Widgets::HexViewerWidgetSettings& settings,
Widgets::Label* hoveredAddressLabel
);
TaskGroups getTaskGroups() const override {
return TaskGroups();
};
signals:
void sceneCreated(Widgets::ByteItemGraphicsScene* scene);
protected:
void run(TargetController::TargetControllerConsole& targetControllerConsole) override;
private:
const Targets::TargetMemoryDescriptor& memoryDescriptor;
std::vector<FocusedMemoryRegion>& focusedMemoryRegions;
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions;
const Widgets::HexViewerWidgetSettings& settings;
Widgets::Label* hoveredAddressLabel;
};
}

View File

@@ -444,6 +444,11 @@ QScrollBar::sub-line:vertical {
color: rgba(175, 177, 179, 0.3); color: rgba(175, 177, 179, 0.3);
} }
#hex-viewer-container #loading-hex-viewer-label {
color: #838386;
font-size: 14px;
}
#hex-viewer-container QScrollBar:vertical { #hex-viewer-container QScrollBar:vertical {
background-color: transparent; background-color: transparent;
width: 12px; width: 12px;

View File

@@ -1,17 +1,13 @@
#include "ByteItemContainerGraphicsView.hpp" #include "ByteItemContainerGraphicsView.hpp"
#include "src/Insight/InsightWorker/InsightWorker.hpp"
#include "src/Insight/InsightWorker/Tasks/ConstructHexViewerByteItemScene.hpp"
namespace Bloom::Widgets namespace Bloom::Widgets
{ {
using Bloom::Targets::TargetMemoryDescriptor; using Bloom::Targets::TargetMemoryDescriptor;
ByteItemContainerGraphicsView::ByteItemContainerGraphicsView( ByteItemContainerGraphicsView::ByteItemContainerGraphicsView(QWidget* parent)
const TargetMemoryDescriptor& targetMemoryDescriptor,
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
const HexViewerWidgetSettings& settings,
Label* hoveredAddressLabel,
QWidget* parent
)
: QGraphicsView(parent) : QGraphicsView(parent)
{ {
this->setObjectName("graphics-view"); this->setObjectName("graphics-view");
@@ -20,27 +16,52 @@ namespace Bloom::Widgets
this->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff); this->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
this->setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate); this->setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
}
this->scene = new ByteItemGraphicsScene( void ByteItemContainerGraphicsView::initScene(
const TargetMemoryDescriptor& targetMemoryDescriptor,
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
const HexViewerWidgetSettings& settings,
Label* hoveredAddressLabel
) {
auto* constructSceneTask = new ConstructHexViewerByteItemScene(
targetMemoryDescriptor, targetMemoryDescriptor,
focusedMemoryRegions, focusedMemoryRegions,
excludedMemoryRegions, excludedMemoryRegions,
settings, settings,
hoveredAddressLabel, hoveredAddressLabel
this
); );
this->setScene(this->scene); QObject::connect(
constructSceneTask,
&ConstructHexViewerByteItemScene::sceneCreated,
this,
[this] (ByteItemGraphicsScene* scene) {
scene->moveToThread(this->thread());
scene->setParent(this);
this->scene = scene;
this->scene->refreshRegions();
this->scene->setEnabled(this->isEnabled());
this->setScene(this->scene);
emit this->ready();
}
);
InsightWorker::queueTask(constructSceneTask);
} }
void ByteItemContainerGraphicsView::scrollToByteItemAtAddress(Targets::TargetMemoryAddress address) { void ByteItemContainerGraphicsView::scrollToByteItemAtAddress(Targets::TargetMemoryAddress address) {
this->centerOn(this->scene->getByteItemPositionByAddress(address)); if (this->scene != nullptr) {
this->centerOn(this->scene->getByteItemPositionByAddress(address));
}
} }
bool ByteItemContainerGraphicsView::event(QEvent* event) { bool ByteItemContainerGraphicsView::event(QEvent* event) {
const auto eventType = event->type(); const auto eventType = event->type();
if (eventType == QEvent::Type::EnabledChange) { if (eventType == QEvent::Type::EnabledChange && this->scene != nullptr) {
this->scene->setEnabled(this->isEnabled()); this->scene->setEnabled(this->isEnabled());
} }
@@ -49,6 +70,9 @@ namespace Bloom::Widgets
void ByteItemContainerGraphicsView::resizeEvent(QResizeEvent* event) { void ByteItemContainerGraphicsView::resizeEvent(QResizeEvent* event) {
QGraphicsView::resizeEvent(event); QGraphicsView::resizeEvent(event);
this->scene->adjustSize();
if (this->scene != nullptr) {
this->scene->adjustSize();
}
} }
} }

View File

@@ -18,13 +18,14 @@ namespace Bloom::Widgets
Q_OBJECT Q_OBJECT
public: public:
ByteItemContainerGraphicsView( ByteItemContainerGraphicsView(QWidget* parent);
void initScene(
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor, const Targets::TargetMemoryDescriptor& targetMemoryDescriptor,
std::vector<FocusedMemoryRegion>& focusedMemoryRegions, std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions, std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
const HexViewerWidgetSettings& settings, const HexViewerWidgetSettings& settings,
Label* hoveredAddressLabel, Label* hoveredAddressLabel
QWidget* parent
); );
[[nodiscard]] ByteItemGraphicsScene* getScene() const { [[nodiscard]] ByteItemGraphicsScene* getScene() const {
@@ -33,6 +34,9 @@ namespace Bloom::Widgets
void scrollToByteItemAtAddress(Targets::TargetMemoryAddress address); void scrollToByteItemAtAddress(Targets::TargetMemoryAddress address);
signals:
void ready();
protected: protected:
bool event(QEvent* event) override; bool event(QEvent* event) override;
void resizeEvent(QResizeEvent* event) override; void resizeEvent(QResizeEvent* event) override;

View File

@@ -22,7 +22,6 @@ namespace Bloom::Widgets
, excludedMemoryRegions(excludedMemoryRegions) , excludedMemoryRegions(excludedMemoryRegions)
, settings(settings) , settings(settings)
, hoveredAddressLabel(hoveredAddressLabel) , hoveredAddressLabel(hoveredAddressLabel)
, parent(parent)
{ {
this->setObjectName("byte-widget-container"); this->setObjectName("byte-widget-container");
@@ -60,8 +59,6 @@ namespace Bloom::Widgets
&ByteItemGraphicsScene::onTargetStateChanged &ByteItemGraphicsScene::onTargetStateChanged
); );
this->refreshRegions();
this->adjustSize();
} }
void ByteItemGraphicsScene::updateValues(const Targets::TargetMemoryBuffer& buffer) { void ByteItemGraphicsScene::updateValues(const Targets::TargetMemoryBuffer& buffer) {
@@ -153,6 +150,7 @@ namespace Bloom::Widgets
} }
void ByteItemGraphicsScene::adjustSize(bool forced) { void ByteItemGraphicsScene::adjustSize(bool forced) {
const auto* parent = this->getParent();
const auto width = this->getSceneWidth(); const auto width = this->getSceneWidth();
const auto columnCount = static_cast<std::size_t>( const auto columnCount = static_cast<std::size_t>(
@@ -177,7 +175,7 @@ namespace Bloom::Widgets
0, 0,
0, 0,
width, width,
std::max(static_cast<int>(this->sceneRect().height()), this->parent->viewport()->height()) std::max(static_cast<int>(this->sceneRect().height()), parent->viewport()->height())
); );
return; return;
@@ -199,7 +197,7 @@ namespace Bloom::Widgets
0, 0,
0, 0,
width, width,
std::max(sceneHeight, this->parent->height()) std::max(sceneHeight, parent->height())
); );
} }
} }

View File

@@ -93,7 +93,6 @@ namespace Bloom::Widgets
const QMargins margins = QMargins(10, 10, 10, 10); const QMargins margins = QMargins(10, 10, 10, 10);
const HexViewerWidgetSettings& settings; const HexViewerWidgetSettings& settings;
QGraphicsView* parent = nullptr;
Label* hoveredAddressLabel = nullptr; Label* hoveredAddressLabel = nullptr;
ByteAddressContainer* byteAddressContainer = nullptr; ByteAddressContainer* byteAddressContainer = nullptr;
@@ -104,6 +103,11 @@ namespace Bloom::Widgets
QGraphicsRectItem* rubberBandRectItem = nullptr; QGraphicsRectItem* rubberBandRectItem = nullptr;
std::optional<QPointF> rubberBandInitPoint = std::nullopt; std::optional<QPointF> rubberBandInitPoint = std::nullopt;
QGraphicsView* getParent() const {
return dynamic_cast<QGraphicsView*>(this->parent());
}
int getSceneWidth() { int getSceneWidth() {
/* /*
* Minus 2 for the QSS margin on the vertical scrollbar (which isn't accounted for during viewport * Minus 2 for the QSS margin on the vertical scrollbar (which isn't accounted for during viewport
@@ -111,7 +115,8 @@ namespace Bloom::Widgets
* *
* See https://bugreports.qt.io/browse/QTBUG-99189 for more on this. * See https://bugreports.qt.io/browse/QTBUG-99189 for more on this.
*/ */
return std::max(this->parent->viewport()->width(), 400) - 2; auto* parent = this->getParent();
return std::max(parent != nullptr ? parent->viewport()->width() : 400, 400) - 2;
} }
void updateAnnotationValues(const Targets::TargetMemoryBuffer& buffer); void updateAnnotationValues(const Targets::TargetMemoryBuffer& buffer);

View File

@@ -71,16 +71,8 @@ namespace Bloom::Widgets
this->hoveredAddressLabel = this->bottomBar->findChild<Label*>("byte-address-label"); this->hoveredAddressLabel = this->bottomBar->findChild<Label*>("byte-address-label");
this->loadingHexViewerLabel = this->container->findChild<Label*>("loading-hex-viewer-label");
this->byteItemGraphicsViewContainer = this->container->findChild<QWidget*>("graphics-view-container"); this->byteItemGraphicsViewContainer = this->container->findChild<QWidget*>("graphics-view-container");
this->byteItemGraphicsView = new ByteItemContainerGraphicsView(
this->targetMemoryDescriptor,
this->focusedMemoryRegions,
this->excludedMemoryRegions,
this->settings,
this->hoveredAddressLabel,
this->byteItemGraphicsViewContainer
);
this->byteItemGraphicsScene = this->byteItemGraphicsView->getScene();
this->setHoveredRowAndColumnHighlightingEnabled(this->settings.highlightHoveredRowAndCol); this->setHoveredRowAndColumnHighlightingEnabled(this->settings.highlightHoveredRowAndCol);
this->setFocusedMemoryHighlightingEnabled(this->settings.highlightFocusedMemory); this->setFocusedMemoryHighlightingEnabled(this->settings.highlightFocusedMemory);
@@ -165,16 +157,48 @@ namespace Bloom::Widgets
this->show(); this->show();
} }
void HexViewerWidget::init() {
this->byteItemGraphicsView = new ByteItemContainerGraphicsView(this->byteItemGraphicsViewContainer);
QObject::connect(
this->byteItemGraphicsView,
&ByteItemContainerGraphicsView::ready,
this,
[this] {
this->byteItemGraphicsScene = this->byteItemGraphicsView->getScene();
this->loadingHexViewerLabel->hide();
this->byteItemGraphicsViewContainer->show();
this->byteItemGraphicsView->setFixedSize(this->byteItemGraphicsViewContainer->size());
emit this->ready();
}
);
this->byteItemGraphicsView->initScene(
this->targetMemoryDescriptor,
this->focusedMemoryRegions,
this->excludedMemoryRegions,
this->settings,
this->hoveredAddressLabel
);
}
void HexViewerWidget::updateValues(const Targets::TargetMemoryBuffer& buffer) { void HexViewerWidget::updateValues(const Targets::TargetMemoryBuffer& buffer) {
this->byteItemGraphicsScene->updateValues(buffer); if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->updateValues(buffer);
}
} }
void HexViewerWidget::refreshRegions() { void HexViewerWidget::refreshRegions() {
this->byteItemGraphicsScene->refreshRegions(); if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->refreshRegions();
}
} }
void HexViewerWidget::setStackPointer(Targets::TargetStackPointer stackPointer) { void HexViewerWidget::setStackPointer(Targets::TargetStackPointer stackPointer) {
this->byteItemGraphicsScene->updateStackPointer(stackPointer); if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->updateStackPointer(stackPointer);
}
} }
void HexViewerWidget::resizeEvent(QResizeEvent* event) { void HexViewerWidget::resizeEvent(QResizeEvent* event) {
@@ -199,38 +223,52 @@ namespace Bloom::Widgets
this->highlightStackMemoryButton->setChecked(enabled); this->highlightStackMemoryButton->setChecked(enabled);
this->settings.highlightStackMemory = enabled; this->settings.highlightStackMemory = enabled;
this->byteItemGraphicsScene->invalidateChildItemCaches(); if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->invalidateChildItemCaches();
}
} }
void HexViewerWidget::setHoveredRowAndColumnHighlightingEnabled(bool enabled) { void HexViewerWidget::setHoveredRowAndColumnHighlightingEnabled(bool enabled) {
this->highlightHoveredRowAndColumnButton->setChecked(enabled); this->highlightHoveredRowAndColumnButton->setChecked(enabled);
this->settings.highlightHoveredRowAndCol = enabled; this->settings.highlightHoveredRowAndCol = enabled;
this->byteItemGraphicsScene->invalidateChildItemCaches(); if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->invalidateChildItemCaches();
}
} }
void HexViewerWidget::setFocusedMemoryHighlightingEnabled(bool enabled) { void HexViewerWidget::setFocusedMemoryHighlightingEnabled(bool enabled) {
this->highlightFocusedMemoryButton->setChecked(enabled); this->highlightFocusedMemoryButton->setChecked(enabled);
this->settings.highlightFocusedMemory = enabled; this->settings.highlightFocusedMemory = enabled;
this->byteItemGraphicsScene->invalidateChildItemCaches(); if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->invalidateChildItemCaches();
}
} }
void HexViewerWidget::setAnnotationsEnabled(bool enabled) { void HexViewerWidget::setAnnotationsEnabled(bool enabled) {
this->displayAnnotationsButton->setChecked(enabled); this->displayAnnotationsButton->setChecked(enabled);
this->settings.displayAnnotations = enabled; this->settings.displayAnnotations = enabled;
this->byteItemGraphicsScene->adjustSize(true); if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->adjustSize(true);
}
} }
void HexViewerWidget::setDisplayAsciiEnabled(bool enabled) { void HexViewerWidget::setDisplayAsciiEnabled(bool enabled) {
this->displayAsciiButton->setChecked(enabled); this->displayAsciiButton->setChecked(enabled);
this->settings.displayAsciiValues = enabled; this->settings.displayAsciiValues = enabled;
this->byteItemGraphicsScene->invalidateChildItemCaches(); if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->invalidateChildItemCaches();
}
} }
void HexViewerWidget::onGoToAddressInputChanged() { void HexViewerWidget::onGoToAddressInputChanged() {
if (this->byteItemGraphicsScene == nullptr) {
return;
}
auto addressConversionOk = false; auto addressConversionOk = false;
const auto address = this->goToAddressInput->text().toUInt(&addressConversionOk, 16); const auto address = this->goToAddressInput->text().toUInt(&addressConversionOk, 16);

View File

@@ -34,10 +34,14 @@ namespace Bloom::Widgets
QWidget* parent QWidget* parent
); );
void init();
void updateValues(const Targets::TargetMemoryBuffer& buffer); void updateValues(const Targets::TargetMemoryBuffer& buffer);
void refreshRegions(); void refreshRegions();
void setStackPointer(Targets::TargetStackPointer stackPointer); void setStackPointer(Targets::TargetStackPointer stackPointer);
signals:
void ready();
protected: protected:
void resizeEvent(QResizeEvent* event) override; void resizeEvent(QResizeEvent* event) override;
void showEvent(QShowEvent* event) override; void showEvent(QShowEvent* event) override;
@@ -53,6 +57,7 @@ namespace Bloom::Widgets
QWidget* toolBar = nullptr; QWidget* toolBar = nullptr;
QWidget* bottomBar = nullptr; QWidget* bottomBar = nullptr;
Label* loadingHexViewerLabel = nullptr;
QWidget* byteItemGraphicsViewContainer = nullptr; QWidget* byteItemGraphicsViewContainer = nullptr;
ByteItemContainerGraphicsView* byteItemGraphicsView = nullptr; ByteItemContainerGraphicsView* byteItemGraphicsView = nullptr;
ByteItemGraphicsScene* byteItemGraphicsScene = nullptr; ByteItemGraphicsScene* byteItemGraphicsScene = nullptr;

View File

@@ -178,11 +178,30 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item alignment="Qt::AlignHCenter">
<widget class="Label" name="loading-hex-viewer-label">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"/>
</property>
<property name="visible">
<bool>true</bool>
</property>
<property name="alignment">
<enum>Qt::AlignCenter</enum>
</property>
<property name="text">
<string>Loading...</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QWidget" name="graphics-view-container"> <widget class="QWidget" name="graphics-view-container">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"/> <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"/>
</property> </property>
<property name="visible">
<bool>false</bool>
</property>
</widget> </widget>
</item> </item>
<item> <item>

View File

@@ -89,6 +89,19 @@ namespace Bloom::Widgets
containerLayout->insertWidget(1, this->hexViewerWidget); containerLayout->insertWidget(1, this->hexViewerWidget);
QObject::connect(
this->hexViewerWidget,
&HexViewerWidget::ready,
this,
[this] {
if (this->data.has_value()) {
this->hexViewerWidget->updateValues(this->data.value());
}
}
);
this->hexViewerWidget->init();
this->setRefreshOnTargetStopEnabled(this->settings.refreshOnTargetStop); this->setRefreshOnTargetStopEnabled(this->settings.refreshOnTargetStop);
this->setRefreshOnActivationEnabled(this->settings.refreshOnActivation); this->setRefreshOnActivationEnabled(this->settings.refreshOnActivation);