sys: Drastically improve highlighting performance
This commit is contained in:
parent
ba68f463e5
commit
618eead341
@ -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);
|
||||||
|
@ -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() {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 ®ion = highlight.getRegion();
|
auto ®ion = 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 ®ion = 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() {
|
||||||
|
@ -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) {
|
||||||
|
@ -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--;
|
||||||
|
Loading…
Reference in New Issue
Block a user