From c063b694907a66cdeca48a96a131cc4f752eb1c0 Mon Sep 17 00:00:00 2001 From: Nav Date: Sat, 22 Jan 2022 16:10:55 +0000 Subject: [PATCH] Constructing Insight settings from project settings json --- .../MemoryRegion.hpp | 12 - .../MemoryRegionManagerWindow.cpp | 2 +- src/ProjectSettings.cpp | 255 +++++++++++++++++- src/ProjectSettings.hpp | 30 ++- 4 files changed, 284 insertions(+), 15 deletions(-) diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegion.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegion.hpp index 2b4a8a49..9136f3f7 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegion.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegion.hpp @@ -25,7 +25,6 @@ namespace Bloom class MemoryRegion { public: - std::size_t id = MemoryRegion::lastId++; QString name; QDateTime createdDate = DateTime::currentDateTime(); MemoryRegionType type; @@ -63,19 +62,8 @@ namespace Bloom MemoryRegion& operator = (const MemoryRegion& other) = default; MemoryRegion& operator = (MemoryRegion&& other) = default; - bool operator == (const MemoryRegion& other) const { - return this->id == other.id; - } - - bool operator != (const MemoryRegion& other) const { - return !(*this == other); - } - [[nodiscard]] bool intersectsWith(const MemoryRegion& other) const { return this->addressRange.intersectsWith(other.addressRange); } - - private: - static inline std::atomic lastId = 0; }; } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp index 9531239c..70bd1c2e 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp @@ -175,7 +175,7 @@ void MemoryRegionManagerWindow::sortRegionItems() { * layout, and then re-inserting them in the correct order. */ auto regionItemCompare = [] (RegionItem* itemA, RegionItem* itemB) { - return itemA->getMemoryRegion().id < itemB->getMemoryRegion().id; + return itemA->getMemoryRegion().createdDate < itemB->getMemoryRegion().createdDate; }; auto sortedRegionItems = std::set(regionItemCompare); diff --git a/src/ProjectSettings.cpp b/src/ProjectSettings.cpp index be8b766f..da7f89c4 100644 --- a/src/ProjectSettings.cpp +++ b/src/ProjectSettings.cpp @@ -1,9 +1,262 @@ #include "ProjectSettings.hpp" +#include + #include "src/Logger/Logger.hpp" using namespace Bloom; ProjectSettings::ProjectSettings(const QJsonObject& jsonObject) { - + if (jsonObject.contains("insight")) { + this->insightSettings = InsightProjectSettings(jsonObject.find("insight")->toObject()); + } +} + +QJsonObject ProjectSettings::toJson() const { + auto projectSettingsObj = QJsonObject(); + + projectSettingsObj.insert("insight", this->insightSettings.toJson()); + + return projectSettingsObj; +} + +InsightProjectSettings::InsightProjectSettings(const QJsonObject& jsonObject) { + if (jsonObject.contains("mainWindowSize")) { + const auto mainWindowSizeObj = jsonObject.find("mainWindowSize")->toObject(); + + if (mainWindowSizeObj.contains("width") && mainWindowSizeObj.contains("height")) { + this->mainWindowSize = QSize( + mainWindowSizeObj.find("width")->toInt(), + mainWindowSizeObj.find("height")->toInt() + ); + } + } + + if (jsonObject.contains("memoryInspectionPaneSettings")) { + const auto settingsMappingObj = jsonObject.find("memoryInspectionPaneSettings")->toObject(); + + for (auto settingsIt = settingsMappingObj.begin(); settingsIt != settingsMappingObj.end(); settingsIt++) { + const auto settingsObj = settingsIt.value().toObject(); + const auto memoryTypeName = settingsIt.key(); + + if (!InsightProjectSettings::memoryTypesByName.contains(memoryTypeName)) { + continue; + } + + const auto memoryType = InsightProjectSettings::memoryTypesByName.at(memoryTypeName); + auto inspectionPaneSettings = Widgets::TargetMemoryInspectionPaneSettings(); + + if (settingsObj.contains("hexViewerSettings")) { + auto& hexViewerSettings = inspectionPaneSettings.hexViewerWidgetSettings; + const auto hexViewerSettingsObj = settingsObj.find("hexViewerSettings")->toObject(); + + if (hexViewerSettingsObj.contains("highlightStackMemory")) { + hexViewerSettings.highlightStackMemory = + hexViewerSettingsObj.value("highlightStackMemory").toBool(); + } + + if (hexViewerSettingsObj.contains("highlightFocusedMemory")) { + hexViewerSettings.highlightFocusedMemory = + hexViewerSettingsObj.value("highlightFocusedMemory").toBool(); + } + + if (hexViewerSettingsObj.contains("highlightHoveredRowAndCol")) { + hexViewerSettings.highlightHoveredRowAndCol = + hexViewerSettingsObj.value("highlightHoveredRowAndCol").toBool(); + } + + if (hexViewerSettingsObj.contains("displayAsciiValues")) { + hexViewerSettings.displayAsciiValues = + hexViewerSettingsObj.value("displayAsciiValues").toBool(); + } + + if (hexViewerSettingsObj.contains("displayAnnotations")) { + hexViewerSettings.displayAnnotations = + hexViewerSettingsObj.value("displayAnnotations").toBool(); + } + } + + if (settingsObj.contains("focusedRegions")) { + const auto focusedRegions = settingsObj.find("focusedRegions")->toArray(); + + for (const auto& regionValue : focusedRegions) { + const auto regionObj = regionValue.toObject(); + + if (!regionObj.contains("name") + || !regionObj.contains("addressRange") + || !regionObj.contains("addressInputType") + || !regionObj.contains("createdTimestamp") + || !regionObj.contains("dataType") + ) { + continue; + } + + const auto addressRangeObj = regionObj.find("addressRange")->toObject(); + if (!addressRangeObj.contains("startAddress") || !addressRangeObj.contains("endAddress")) { + continue; + } + + auto region = FocusedMemoryRegion( + regionObj.find("name")->toString(), + { + static_cast(addressRangeObj.find("startAddress")->toInteger()), + static_cast(addressRangeObj.find("endAddress")->toInteger()), + } + ); + + region.createdDate.setSecsSinceEpoch(regionObj.find("createdTimestamp")->toInteger()); + + const auto addressInputType = InsightProjectSettings::addressRangeInputTypesByName.valueAt( + regionObj.find("addressInputType")->toString() + ); + + if (addressInputType.has_value()) { + region.addressRangeInputType = addressInputType.value(); + } + + const auto dataType = InsightProjectSettings::regionDataTypesByName.valueAt( + regionObj.find("dataType")->toString() + ); + + if (dataType.has_value()) { + region.dataType = dataType.value(); + } + + inspectionPaneSettings.focusedMemoryRegions.emplace_back(region); + } + } + + if (settingsObj.contains("excludedRegions")) { + const auto excludedRegions = settingsObj.find("excludedRegions")->toArray(); + + for (const auto& regionValue : excludedRegions) { + const auto regionObj = regionValue.toObject(); + + if (!regionObj.contains("name") + || !regionObj.contains("addressRange") + || !regionObj.contains("addressInputType") + || !regionObj.contains("createdTimestamp") + ) { + continue; + } + + const auto addressRangeObj = regionObj.find("addressRange")->toObject(); + if (!addressRangeObj.contains("startAddress") || !addressRangeObj.contains("endAddress")) { + continue; + } + + auto region = ExcludedMemoryRegion( + regionObj.find("name")->toString(), + { + static_cast(addressRangeObj.find("startAddress")->toInteger()), + static_cast(addressRangeObj.find("endAddress")->toInteger()), + } + ); + + region.createdDate.setSecsSinceEpoch(regionObj.find("createdTimestamp")->toInteger()); + + const auto addressInputType = InsightProjectSettings::addressRangeInputTypesByName.valueAt( + regionObj.find("addressInputType")->toString() + ); + + if (addressInputType.has_value()) { + region.addressRangeInputType = addressInputType.value(); + } + + inspectionPaneSettings.excludedMemoryRegions.emplace_back(region); + } + } + + this->memoryInspectionPaneSettingsByMemoryType.insert(std::pair(memoryType, inspectionPaneSettings)); + } + } +} + +QJsonObject InsightProjectSettings::toJson() const { + auto insightObj = QJsonObject(); + + if (this->mainWindowSize.has_value()) { + insightObj.insert("mainWindowSize", QJsonObject({ + {"width", this->mainWindowSize->width()}, + {"height", this->mainWindowSize->height()}, + })); + } + + auto memoryInspectionPaneSettingsObj = QJsonObject(); + + for (const auto& [memoryType, inspectionPaneSettings] : this->memoryInspectionPaneSettingsByMemoryType) { + if (!InsightProjectSettings::memoryTypesByName.contains(memoryType)) { + // This is just a precaution - all known memory types should be in the mapping. + continue; + } + + auto settingsObj = QJsonObject(); + + const auto& hexViewerSettings = inspectionPaneSettings.hexViewerWidgetSettings; + settingsObj.insert("hexViewerSettings", QJsonObject({ + {"highlightStackMemory", hexViewerSettings.highlightStackMemory}, + {"highlightFocusedMemory", hexViewerSettings.highlightFocusedMemory}, + {"highlightHoveredRowAndCol", hexViewerSettings.highlightHoveredRowAndCol}, + {"displayAsciiValues", hexViewerSettings.displayAsciiValues}, + {"displayAnnotations", hexViewerSettings.displayAnnotations}, + })); + + const auto& regionDataTypesByName = InsightProjectSettings::regionDataTypesByName; + const auto& addressRangeInputTypesByName = InsightProjectSettings::addressRangeInputTypesByName; + + auto focusedRegions = QJsonArray(); + for (const auto& focusedRegion : inspectionPaneSettings.focusedMemoryRegions) { + if (!regionDataTypesByName.contains(focusedRegion.dataType) + || !addressRangeInputTypesByName.contains(focusedRegion.addressRangeInputType) + ) { + continue; + } + + const auto addressRangeObj = QJsonObject({ + {"startAddress", static_cast(focusedRegion.addressRange.startAddress)}, + {"endAddress", static_cast(focusedRegion.addressRange.endAddress)}, + }); + + auto regionObj = QJsonObject({ + {"name", focusedRegion.name}, + {"addressRange", addressRangeObj}, + {"createdTimestamp", focusedRegion.createdDate.toSecsSinceEpoch()}, + {"addressInputType", addressRangeInputTypesByName.at(focusedRegion.addressRangeInputType)}, + {"dataType", regionDataTypesByName.at(focusedRegion.dataType)}, + }); + + focusedRegions.push_back(regionObj); + } + + auto excludedRegions = QJsonArray(); + for (const auto& excludedRegion : inspectionPaneSettings.excludedMemoryRegions) { + if (!addressRangeInputTypesByName.contains(excludedRegion.addressRangeInputType)) { + continue; + } + + const auto addressRangeObj = QJsonObject({ + {"startAddress", static_cast(excludedRegion.addressRange.startAddress)}, + {"endAddress", static_cast(excludedRegion.addressRange.endAddress)}, + }); + + auto regionObj = QJsonObject({ + {"name", excludedRegion.name}, + {"addressRange", addressRangeObj}, + {"createdTimestamp", excludedRegion.createdDate.toSecsSinceEpoch()}, + {"addressInputType", addressRangeInputTypesByName.at(excludedRegion.addressRangeInputType)}, + }); + + excludedRegions.push_back(regionObj); + } + + settingsObj.insert("focusedRegions", focusedRegions); + settingsObj.insert("excludedRegions", excludedRegions); + memoryInspectionPaneSettingsObj.insert( + InsightProjectSettings::memoryTypesByName.at(memoryType), + settingsObj + ); + } + + insightObj.insert("memoryInspectionPaneSettings", memoryInspectionPaneSettingsObj); + return insightObj; } diff --git a/src/ProjectSettings.hpp b/src/ProjectSettings.hpp index 8c399e14..ab8c2d28 100644 --- a/src/ProjectSettings.hpp +++ b/src/ProjectSettings.hpp @@ -3,22 +3,48 @@ #include #include #include +#include +#include #include #include "src/Targets/TargetMemory.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPaneSettings.hpp" +#include "src/Helpers/BiMap.hpp" + namespace Bloom { struct InsightProjectSettings { + public: + std::optional mainWindowSize; + std::map< Targets::TargetMemoryType, Widgets::TargetMemoryInspectionPaneSettings > memoryInspectionPaneSettingsByMemoryType; InsightProjectSettings() = default; - InsightProjectSettings(const QJsonObject& jsonObject); + explicit InsightProjectSettings(const QJsonObject& jsonObject); + + [[nodiscard]] QJsonObject toJson() const; + + private: + static const inline BiMap memoryTypesByName = { + {Targets::TargetMemoryType::RAM, "ram"}, + {Targets::TargetMemoryType::EEPROM, "eeprom"}, + }; + + static const inline BiMap regionDataTypesByName = { + {MemoryRegionDataType::UNKNOWN, "other"}, + {MemoryRegionDataType::UNSIGNED_INTEGER, "unsigned_int"}, + {MemoryRegionDataType::ASCII_STRING, "ascii_string"}, + }; + + static const inline BiMap addressRangeInputTypesByName = { + {MemoryRegionAddressInputType::ABSOLUTE, "absolute"}, + {MemoryRegionAddressInputType::RELATIVE, "relative"}, + }; }; struct ProjectSettings @@ -27,5 +53,7 @@ namespace Bloom ProjectSettings() = default; explicit ProjectSettings(const QJsonObject& jsonObject); + + [[nodiscard]] QJsonObject toJson() const; }; }