1
0
mirror of synced 2024-11-12 10:10:53 +01:00

sys: Drastically improve highlighting performance

This commit is contained in:
WerWolv 2022-02-04 00:29:47 +01:00
parent ba68f463e5
commit 618eead341
6 changed files with 95 additions and 52 deletions

View File

@ -104,7 +104,7 @@ namespace hex {
EVENT_DEF(EventFileLoaded, fs::path); EVENT_DEF(EventFileLoaded, fs::path);
EVENT_DEF(EventFileUnloaded); EVENT_DEF(EventFileUnloaded);
EVENT_DEF(EventDataChanged); EVENT_DEF(EventDataChanged);
EVENT_DEF(EventPatternChanged, std::vector<pl::PatternData *> &); EVENT_DEF(EventHighlightingChanged);
EVENT_DEF(EventWindowClosing, GLFWwindow *); EVENT_DEF(EventWindowClosing, GLFWwindow *);
EVENT_DEF(EventRegionSelected, Region); EVENT_DEF(EventRegionSelected, Region);
EVENT_DEF(EventProjectFileStore); EVENT_DEF(EventProjectFileStore);

View File

@ -39,11 +39,15 @@ namespace hex {
id, Highlighting {region, color, tooltip} id, Highlighting {region, color, tooltip}
}); });
EventManager::post<EventHighlightingChanged>();
return id; return id;
} }
void removeHighlight(u32 id) { void removeHighlight(u32 id) {
s_highlights.erase(id); s_highlights.erase(id);
EventManager::post<EventHighlightingChanged>();
} }
std::map<u32, Highlighting> &getHighlights() { std::map<u32, Highlighting> &getHighlights() {

View File

@ -14,12 +14,22 @@ namespace hex::prv {
class Provider; class Provider;
} }
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
using SearchFunction = std::vector<std::pair<u64, u64>> (*)(prv::Provider *&provider, std::string string); using SearchFunction = std::vector<std::pair<u64, u64>> (*)(prv::Provider *&provider, std::string string);
struct HighlightBlock {
struct Highlight {
color_t color;
std::vector<std::string> tooltips;
};
constexpr static size_t Size = 0x2000;
u64 base;
std::array<Highlight, Size> highlight;
};
class ViewHexEditor : public View { class ViewHexEditor : public View {
public: public:
ViewHexEditor(); ViewHexEditor();
@ -54,6 +64,8 @@ namespace hex::plugin::builtin {
hex::EncodingFile m_currEncodingFile; hex::EncodingFile m_currEncodingFile;
u8 m_highlightAlpha = 0x80; u8 m_highlightAlpha = 0x80;
std::list<HighlightBlock> m_highlights;
bool m_processingImportExport = false; bool m_processingImportExport = false;
bool m_advancedDecodingEnabled = false; bool m_advancedDecodingEnabled = false;

View File

@ -59,45 +59,72 @@ namespace hex::plugin::builtin {
}; };
this->m_memoryEditor.HighlightFn = [](const ImU8 *data, size_t off, bool next) -> bool { this->m_memoryEditor.HighlightFn = [](const ImU8 *data, size_t off, bool next) -> bool {
bool firstByte = off == 0x00;
auto _this = (ViewHexEditor *)(data); auto _this = (ViewHexEditor *)(data);
std::optional<u32> currColor, prevColor;
auto provider = ImHexApi::Provider::get(); auto provider = ImHexApi::Provider::get();
off += provider->getBaseAddress() + provider->getCurrentPageAddress(); off += provider->getBaseAddress() + provider->getCurrentPageAddress();
u32 alpha = static_cast<u32>(_this->m_highlightAlpha) << 24; u32 alpha = static_cast<u32>(_this->m_highlightAlpha) << 24;
std::optional<color_t> currColor, prevColor;
for (auto &highlightBlock : _this->m_highlights) {
if (off >= highlightBlock.base && off < (highlightBlock.base + HighlightBlock::Size)) {
currColor = highlightBlock.highlight[off - highlightBlock.base].color;
}
if ((off - 1) >= highlightBlock.base && (off - 1) < (highlightBlock.base + HighlightBlock::Size)) {
prevColor = highlightBlock.highlight[(off - 1) - highlightBlock.base].color;
}
if (currColor && prevColor) break;
if (firstByte)
prevColor = 0x00;
}
if (!currColor || !prevColor) {
if (_this->m_highlights.size() > 0x10)
_this->m_highlights.pop_front();
auto blockStartOffset = off - (off % HighlightBlock::Size);
HighlightBlock newBlock = {
blockStartOffset,
{}
};
for (u32 i = 0; i < HighlightBlock::Size; i++) {
std::optional<color_t> highlightColor;
std::string highlightTooltip;
for (const auto &[id, highlight] : ImHexApi::HexEditor::getHighlights()) { for (const auto &[id, highlight] : ImHexApi::HexEditor::getHighlights()) {
auto &region = highlight.getRegion(); auto &region = highlight.getRegion();
auto &color = highlight.getColor(); auto &color = highlight.getColor();
auto &tooltip = highlight.getTooltip();
if (off >= region.address && off < (region.address + region.size)) if (blockStartOffset + i >= region.address && blockStartOffset + i < (region.address + region.size)) {
currColor = (color & 0x00FFFFFF) | alpha; highlightColor = (color & 0x00FFFFFF) | alpha;
if ((off - 1) >= region.address && (off - 1) < (region.address + region.size)) highlightTooltip = tooltip;
prevColor = (color & 0x00FFFFFF) | alpha; }
} }
{
auto patterns = provider->getPatternLanguageRuntime().getPatterns(); auto patterns = provider->getPatternLanguageRuntime().getPatterns();
for (const auto &pattern : patterns) { for (const auto &pattern : patterns) {
auto child = pattern->getPattern(off); auto child = pattern->getPattern(blockStartOffset + i);
if (child != nullptr) { if (child != nullptr) {
auto color = (child->getColor() & 0x00FFFFFF) | alpha; auto color = (child->getColor() & 0x00FFFFFF) | alpha;
currColor = currColor.has_value() ? ImAlphaBlendColors(color, currColor.value()) : color; highlightColor = highlightColor.has_value() ? ImAlphaBlendColors(color, highlightColor.value()) : color;
break; break;
} }
} }
for (const auto &pattern : patterns) { auto &currHighlight = newBlock.highlight[i];
auto child = pattern->getPattern(off - 1); currHighlight.color = highlightColor.value_or(0x00);
if (child != nullptr) { if (!highlightTooltip.empty())
auto color = (child->getColor() & 0x00FFFFFF) | alpha; currHighlight.tooltips.push_back(highlightTooltip);
prevColor = prevColor.has_value() ? ImAlphaBlendColors(color, currColor.value()) : color;
break;
}
} }
_this->m_highlights.push_back(std::move(newBlock));
} }
if (next && prevColor != currColor) { if (next && prevColor != currColor) {
@ -114,26 +141,28 @@ namespace hex::plugin::builtin {
}; };
this->m_memoryEditor.HoverFn = [](const ImU8 *data, size_t off) { this->m_memoryEditor.HoverFn = [](const ImU8 *data, size_t off) {
auto _this = (ViewHexEditor *)(data);
bool tooltipShown = false; bool tooltipShown = false;
auto provider = ImHexApi::Provider::get(); auto provider = ImHexApi::Provider::get();
off += provider->getBaseAddress() + provider->getCurrentPageAddress(); off += provider->getBaseAddress() + provider->getCurrentPageAddress();
for (const auto &[id, highlight] : ImHexApi::HexEditor::getHighlights()) { for (auto &highlightBlock : _this->m_highlights) {
auto &region = highlight.getRegion(); if (off >= highlightBlock.base && off < (highlightBlock.base + HighlightBlock::Size)) {
auto &color = highlight.getColor(); auto &highlight = highlightBlock.highlight[off - highlightBlock.base];
auto &tooltip = highlight.getTooltip(); if (!tooltipShown && !highlight.tooltips.empty()) {
if (off >= region.address && off < (region.address + region.size)) {
if (!tooltipShown && !tooltip.empty()) {
ImGui::BeginTooltip(); ImGui::BeginTooltip();
tooltipShown = true; tooltipShown = true;
} }
ImGui::ColorButton(tooltip.c_str(), ImColor(color).Value);
for (const auto &tooltip : highlight.tooltips) {
ImGui::ColorButton(tooltip.c_str(), ImColor(highlight.color).Value);
ImGui::SameLine(0, 10); ImGui::SameLine(0, 10);
ImGui::TextUnformatted(tooltip.c_str()); ImGui::TextUnformatted(tooltip.c_str());
} }
} }
}
if (tooltipShown) if (tooltipShown)
ImGui::EndTooltip(); ImGui::EndTooltip();
@ -175,6 +204,7 @@ namespace hex::plugin::builtin {
EventManager::unsubscribe<EventWindowClosing>(this); EventManager::unsubscribe<EventWindowClosing>(this);
EventManager::unsubscribe<RequestOpenWindow>(this); EventManager::unsubscribe<RequestOpenWindow>(this);
EventManager::unsubscribe<EventSettingsChanged>(this); EventManager::unsubscribe<EventSettingsChanged>(this);
EventManager::unsubscribe<EventHighlightingChanged>(this);
} }
void ViewHexEditor::drawContent() { void ViewHexEditor::drawContent() {
@ -384,11 +414,7 @@ namespace hex::plugin::builtin {
EventManager::post<EventFileLoaded>(path); EventManager::post<EventFileLoaded>(path);
EventManager::post<EventDataChanged>(); EventManager::post<EventDataChanged>();
EventManager::post<EventHighlightingChanged>();
{
std::vector<pl::PatternData *> patterns;
EventManager::post<EventPatternChanged>(patterns);
}
} }
void ViewHexEditor::copyBytes() const { void ViewHexEditor::copyBytes() const {
@ -908,6 +934,10 @@ namespace hex::plugin::builtin {
region = Region { address, size }; region = Region { address, size };
}); });
EventManager::subscribe<EventHighlightingChanged>(this, [this] {
this->m_highlights.clear();
});
} }
void ViewHexEditor::registerShortcuts() { void ViewHexEditor::registerShortcuts() {

View File

@ -7,7 +7,7 @@ namespace hex::plugin::builtin {
ViewPatternData::ViewPatternData() : View("hex.builtin.view.pattern_data.name") { ViewPatternData::ViewPatternData() : View("hex.builtin.view.pattern_data.name") {
EventManager::subscribe<EventPatternChanged>(this, [this](auto &) { EventManager::subscribe<EventHighlightingChanged>(this, [this]() {
if (!ImHexApi::Provider::isValid()) return; if (!ImHexApi::Provider::isValid()) return;
this->m_sortedPatterns[ImHexApi::Provider::get()].clear(); this->m_sortedPatterns[ImHexApi::Provider::get()].clear();
@ -15,7 +15,7 @@ namespace hex::plugin::builtin {
} }
ViewPatternData::~ViewPatternData() { ViewPatternData::~ViewPatternData() {
EventManager::unsubscribe<EventPatternChanged>(this); EventManager::unsubscribe<EventHighlightingChanged>(this);
} }
static bool beginPatternDataTable(prv::Provider *&provider, const std::vector<pl::PatternData *> &patterns, std::vector<pl::PatternData *> &sortedPatterns) { static bool beginPatternDataTable(prv::Provider *&provider, const std::vector<pl::PatternData *> &patterns, std::vector<pl::PatternData *> &sortedPatterns) {

View File

@ -624,10 +624,7 @@ namespace hex::plugin::builtin {
this->m_console.clear(); this->m_console.clear();
this->clearPatternData(); this->clearPatternData();
{ EventManager::post<EventHighlightingChanged>();
std::vector<pl::PatternData *> patterns;
EventManager::post<EventPatternChanged>(patterns);
}
std::thread([this, code] { std::thread([this, code] {
std::map<std::string, pl::Token::Literal> envVars; std::map<std::string, pl::Token::Literal> envVars;
@ -663,7 +660,7 @@ namespace hex::plugin::builtin {
} }
if (result) { if (result) {
EventManager::post<EventPatternChanged>(runtime.getPatterns()); EventManager::post<EventHighlightingChanged>();
} }
this->m_runningEvaluators--; this->m_runningEvaluators--;