From 126868c251c6a6b5b86d11331710a2c7f1a854c7 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sat, 11 Jan 2025 17:22:53 +0100 Subject: [PATCH] fix: Hang when filtering for a large number of items in the pattern data view --- .../include/content/views/view_pattern_data.hpp | 1 + plugins/builtin/romfs/lang/en_US.json | 1 + .../builtin/source/content/settings_entries.cpp | 2 ++ .../source/content/views/view_pattern_data.cpp | 6 ++++++ plugins/ui/include/ui/pattern_drawer.hpp | 4 ++++ plugins/ui/source/ui/pattern_drawer.cpp | 14 +++++++++++--- 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/plugins/builtin/include/content/views/view_pattern_data.hpp b/plugins/builtin/include/content/views/view_pattern_data.hpp index e35af8425..33dfae68c 100644 --- a/plugins/builtin/include/content/views/view_pattern_data.hpp +++ b/plugins/builtin/include/content/views/view_pattern_data.hpp @@ -15,6 +15,7 @@ namespace hex::plugin::builtin { private: bool m_rowColoring = false; + u32 m_maxFilterItems = 128; ui::PatternDrawer::TreeStyle m_treeStyle = ui::PatternDrawer::TreeStyle::Default; PerProvider> m_patternDrawer; diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 7ea024ed6..88adfae90 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -481,6 +481,7 @@ "hex.builtin.setting.general.max_mem_file_size": "Maximum size of file to load into memory", "hex.builtin.setting.general.max_mem_file_size.desc": "Small files are loaded into memory to prevent them from being modified directly on disk.\n\nIncreasing this size allows larger files to be loaded into memory before ImHex resorts to streaming in data from disk.", "hex.builtin.setting.general.network_interface": "Enable network interface", + "hex.builtin.setting.general.pattern_data_max_filter_items": "Max number of items shown when filtering pattern data", "hex.builtin.setting.general.save_recent_providers": "Save recently used providers", "hex.builtin.setting.general.show_tips": "Show tips on startup", "hex.builtin.setting.general.sync_pattern_source": "Sync pattern source code between providers", diff --git a/plugins/builtin/source/content/settings_entries.cpp b/plugins/builtin/source/content/settings_entries.cpp index 416a06711..e6e416b04 100644 --- a/plugins/builtin/source/content/settings_entries.cpp +++ b/plugins/builtin/source/content/settings_entries.cpp @@ -755,6 +755,8 @@ namespace hex::plugin::builtin { ContentRegistry::Settings::add("hex.builtin.setting.general", "", "hex.builtin.setting.general.auto_backup_time"); ContentRegistry::Settings::add("hex.builtin.setting.general", "", "hex.builtin.setting.general.max_mem_file_size", 512_MiB, 0_bytes, 32_GiB, 1_MiB) .setTooltip("hex.builtin.setting.general.max_mem_file_size.desc"); + ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.patterns", "hex.builtin.setting.general.pattern_data_max_filter_items", 128, 32, 1024); + ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.patterns", "hex.builtin.setting.general.auto_load_patterns", true); ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.patterns", "hex.builtin.setting.general.sync_pattern_source", false); ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.network", "hex.builtin.setting.general.network_interface", false); diff --git a/plugins/builtin/source/content/views/view_pattern_data.cpp b/plugins/builtin/source/content/views/view_pattern_data.cpp index a37574266..06a0f5ab0 100644 --- a/plugins/builtin/source/content/views/view_pattern_data.cpp +++ b/plugins/builtin/source/content/views/view_pattern_data.cpp @@ -25,6 +25,12 @@ namespace hex::plugin::builtin { drawer->enableRowColoring(m_rowColoring); }); + ContentRegistry::Settings::onChange("hex.builtin.setting.general", "hex.builtin.setting.general.pattern_data_max_filter_items", [this](const ContentRegistry::Settings::SettingsValue &value) { + m_maxFilterItems = value.get(128); + for (auto &drawer : m_patternDrawer.all()) + drawer->setMaxFilterDisplayItems(m_maxFilterItems); + }); + EventPatternEvaluating::subscribe(this, [this]{ (*m_patternDrawer)->reset(); }); diff --git a/plugins/ui/include/ui/pattern_drawer.hpp b/plugins/ui/include/ui/pattern_drawer.hpp index 63810e9cb..3f8561833 100644 --- a/plugins/ui/include/ui/pattern_drawer.hpp +++ b/plugins/ui/include/ui/pattern_drawer.hpp @@ -36,6 +36,8 @@ namespace hex::ui { void setHoverCallback(std::function callback) { m_hoverCallback = std::move(callback); } void enableRowColoring(bool enabled) { m_rowColoring = enabled; } void enablePatternEditing(bool enabled) { m_editingEnabled = enabled; } + void setMaxFilterDisplayItems(u32 count) { m_maxFilterDisplayItems = count; } + void reset(); void jumpToPattern(const pl::ptrn::Pattern *pattern) { m_jumpToPattern = pattern; } @@ -134,5 +136,7 @@ namespace hex::ui { pl::gen::fmt::FormatterArray m_formatters; u64 m_lastRunId = 0; + + u32 m_maxFilterDisplayItems = 128; }; } \ No newline at end of file diff --git a/plugins/ui/source/ui/pattern_drawer.cpp b/plugins/ui/source/ui/pattern_drawer.cpp index 8a055ffac..3c5c5268c 100644 --- a/plugins/ui/source/ui/pattern_drawer.cpp +++ b/plugins/ui/source/ui/pattern_drawer.cpp @@ -248,9 +248,17 @@ namespace hex::ui { std::vector treePath; for (auto &pattern : m_sortedPatterns) { - traversePatternTree(*pattern, treePath, [this, &treePath](auto &pattern){ - if (matchesFilter(m_filter.path, treePath, false)) - m_filteredPatterns.push_back(&pattern); + if (m_filteredPatterns.size() > m_maxFilterDisplayItems) + break; + + traversePatternTree(*pattern, treePath, [this, &treePath](auto &pattern) { + if (m_filteredPatterns.size() > m_maxFilterDisplayItems) + return; + + if (matchesFilter(m_filter.path, treePath, false)) { + if (pattern.getValue() == m_filter.value) + m_filteredPatterns.push_back(&pattern); + } }); } }