From 59b4f4efce23210186796a3df44939a93c7eb688 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Fri, 26 Dec 2025 18:42:10 +0100 Subject: [PATCH] impr: Add abstraction for common variable-saved-as-setting code pattern --- .../hex/api/content_registry/settings.hpp | 49 +++++++++++++++++++ .../content/views/view_achievements.hpp | 6 ++- .../content/views/view_pattern_editor.hpp | 7 +-- .../source/content/background_services.cpp | 14 ++---- plugins/builtin/source/content/ui_items.cpp | 5 +- .../content/views/view_achievements.cpp | 10 ++-- .../source/content/views/view_hex_editor.cpp | 5 +- .../content/views/view_pattern_editor.cpp | 12 ----- .../builtin/source/content/welcome_screen.cpp | 6 +-- .../source/content/window_decoration.cpp | 26 ++-------- plugins/windows/source/content/ui_items.cpp | 6 +-- 11 files changed, 74 insertions(+), 72 deletions(-) diff --git a/lib/libimhex/include/hex/api/content_registry/settings.hpp b/lib/libimhex/include/hex/api/content_registry/settings.hpp index b0fd0cfc7..334888e6e 100644 --- a/lib/libimhex/include/hex/api/content_registry/settings.hpp +++ b/lib/libimhex/include/hex/api/content_registry/settings.hpp @@ -344,10 +344,59 @@ EXPORT_MODULE namespace hex { using OnChangeCallback = std::function; u64 onChange(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, const OnChangeCallback &callback); + void removeOnChangeHandler(u64 id); using OnSaveCallback = std::function; u64 onSave(const OnSaveCallback &callback); + template + class SettingsVariable { + public: + explicit(false) SettingsVariable(const std::common_type_t &defaultValue) : m_defaultValue(defaultValue) { + m_onChangeId = onChange(UnlocalizedCategory.value.data(), UnlocalizedName.value.data(), [this](const SettingsValue &value) { + m_value = value.get(m_defaultValue); + }); + } + + ~SettingsVariable() { + removeOnChangeHandler(m_onChangeId); + } + + [[nodiscard]] T get() const { + if (!m_value.has_value()) { + m_value = read( + UnlocalizedCategory.value.data(), + UnlocalizedName.value.data(), + m_defaultValue + ); + } + + return m_value.value_or(m_defaultValue); + } + + void set(const std::common_type_t &value) { + write( + UnlocalizedCategory.value.data(), + UnlocalizedName.value.data(), + value + ); + } + + explicit(false) operator T() const { + return get(); + } + + SettingsVariable& operator=(const std::common_type_t &value) { + set(value); + return *this; + } + + private: + mutable std::optional m_value; + T m_defaultValue; + u64 m_onChangeId; + }; + } } \ No newline at end of file diff --git a/plugins/builtin/include/content/views/view_achievements.hpp b/plugins/builtin/include/content/views/view_achievements.hpp index 31befb568..d3cd0d58c 100644 --- a/plugins/builtin/include/content/views/view_achievements.hpp +++ b/plugins/builtin/include/content/views/view_achievements.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace hex::plugin::builtin { @@ -33,9 +34,10 @@ namespace hex::plugin::builtin { const Achievement *m_currAchievement = nullptr; const Achievement *m_achievementToGoto = nullptr; float m_achievementUnlockQueueTimer = -1; - bool m_showPopup = true; + ContentRegistry::Settings::SettingsVariable m_showPopup = true; + ImVec2 m_offset; }; -} \ No newline at end of file +} diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index 2172c8504..9e7058a64 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -137,8 +138,8 @@ namespace hex::plugin::builtin { std::atomic m_dangerousFunctionCalled = false; std::atomic m_dangerousFunctionsAllowed = DangerousFunctionPerms::Ask; - bool m_suggestSupportedPatterns = true; - bool m_autoApplyPatterns = false; + ContentRegistry::Settings::SettingsVariable m_suggestSupportedPatterns = true; + ContentRegistry::Settings::SettingsVariable m_autoApplyPatterns = false; PerProvider m_visualizerDrawer; bool m_tooltipJustOpened = false; @@ -177,7 +178,7 @@ namespace hex::plugin::builtin { std::array m_accessHistory = {}; u32 m_accessHistoryIndex = 0; - bool m_parentHighlightingEnabled = true; + ContentRegistry::Settings::SettingsVariable m_parentHighlightingEnabled = false; bool m_replaceMode = false; bool m_openFindReplacePopUp = false; bool m_openGotoLinePopUp = false; diff --git a/plugins/builtin/source/content/background_services.cpp b/plugins/builtin/source/content/background_services.cpp index 44c2d31c4..ea5108d51 100644 --- a/plugins/builtin/source/content/background_services.cpp +++ b/plugins/builtin/source/content/background_services.cpp @@ -22,8 +22,8 @@ namespace hex::plugin::builtin { - static bool s_networkInterfaceServiceEnabled = false; - static int s_autoBackupTime = 0; + static ContentRegistry::Settings::SettingsVariable s_networkInterfaceServiceEnabled = false; + static ContentRegistry::Settings::SettingsVariable s_autoBackupTime = 0; namespace { @@ -75,7 +75,7 @@ namespace hex::plugin::builtin { auto now = std::chrono::steady_clock::now(); static std::chrono::time_point lastBackupTime = now; - if (s_autoBackupTime > 0 && (now - lastBackupTime) > std::chrono::seconds(s_autoBackupTime)) { + if (s_autoBackupTime > 0 && (now - lastBackupTime) > std::chrono::seconds(s_autoBackupTime * 30)) { lastBackupTime = now; if (ImHexApi::Provider::isValid() && s_dataDirty) { @@ -118,18 +118,10 @@ namespace hex::plugin::builtin { } void registerBackgroundServices() { - ContentRegistry::Settings::onChange("hex.builtin.setting.general", "hex.builtin.setting.general.network_interface", [](const ContentRegistry::Settings::SettingsValue &value) { - s_networkInterfaceServiceEnabled = value.get(false); - }); - ContentRegistry::Settings::onChange("hex.builtin.setting.general", "hex.builtin.setting.general.mcp_server", [](const ContentRegistry::Settings::SettingsValue &value) { ContentRegistry::MCP::impl::setEnabled(value.get(false)); }); - ContentRegistry::Settings::onChange("hex.builtin.setting.general", "hex.builtin.setting.general.backups.auto_backup_time", [](const ContentRegistry::Settings::SettingsValue &value) { - s_autoBackupTime = value.get(0) * 30; - }); - ContentRegistry::BackgroundServices::registerService("hex.builtin.background_service.network_interface", handleNetworkInterfaceService); ContentRegistry::BackgroundServices::registerService("hex.builtin.background_service.auto_backup", handleAutoBackup); ContentRegistry::BackgroundServices::registerService("hex.builtin.background_service.mcp", handleMCPServer); diff --git a/plugins/builtin/source/content/ui_items.cpp b/plugins/builtin/source/content/ui_items.cpp index ba6eeaaff..a1f3182c0 100644 --- a/plugins/builtin/source/content/ui_items.cpp +++ b/plugins/builtin/source/content/ui_items.cpp @@ -473,10 +473,7 @@ namespace hex::plugin::builtin { rightClickedProvider = nullptr; }); - static bool alwaysShowProviderTabs = false; - ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.always_show_provider_tabs", [](const ContentRegistry::Settings::SettingsValue &value) { - alwaysShowProviderTabs = value.get(false); - }); + static ContentRegistry::Settings::SettingsVariable alwaysShowProviderTabs = false; // Toolbar items ContentRegistry::UserInterface::addToolbarItem([] { diff --git a/plugins/builtin/source/content/views/view_achievements.cpp b/plugins/builtin/source/content/views/view_achievements.cpp index b4a83c388..a7e60ed49 100644 --- a/plugins/builtin/source/content/views/view_achievements.cpp +++ b/plugins/builtin/source/content/views/view_achievements.cpp @@ -42,10 +42,6 @@ namespace hex::plugin::builtin { #else m_showPopup = true; #endif - - ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", [this](const ContentRegistry::Settings::SettingsValue &value) { - m_showPopup = value.get(true); - }); } } @@ -404,8 +400,10 @@ for (const auto &[categoryName, achievements] : startNodes) { ImGui::SetCursorScreenPos(innerWindowPos + ImVec2(0, innerWindowSize.y + windowPadding.y)); ImGui::BeginGroup(); { - if (ImGui::Checkbox("Show popup", &m_showPopup)) - ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", m_showPopup); + bool showPopup = m_showPopup; + if (ImGui::Checkbox("Show popup", &showPopup)) { + m_showPopup = showPopup; + } } ImGui::EndGroup(); diff --git a/plugins/builtin/source/content/views/view_hex_editor.cpp b/plugins/builtin/source/content/views/view_hex_editor.cpp index 45bf1e517..92a6928f6 100644 --- a/plugins/builtin/source/content/views/view_hex_editor.cpp +++ b/plugins/builtin/source/content/views/view_hex_editor.cpp @@ -78,10 +78,7 @@ namespace hex::plugin::builtin { return result; }); - static bool showHighlights = true; - ContentRegistry::Settings::onChange("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.show_highlights", [](const ContentRegistry::Settings::SettingsValue &value) { - showHighlights = value.get(true); - }); + static ContentRegistry::Settings::SettingsVariable showHighlights = true; ContentRegistry::Settings::onChange("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.gray_out_zeros", [this](const ContentRegistry::Settings::SettingsValue &value) { m_hexEditor.enableGrayOutZeros(value.get(true)); diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 3e811bb1d..dabed1f45 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -1840,14 +1840,6 @@ namespace hex::plugin::builtin { m_sourceCode.enableSync(value.get(false)); }); - ContentRegistry::Settings::onChange("hex.builtin.setting.general", "hex.builtin.setting.general.suggest_patterns", [this](const ContentRegistry::Settings::SettingsValue &value) { - m_suggestSupportedPatterns = value.get(true); - }); - - ContentRegistry::Settings::onChange("hex.builtin.setting.general", "hex.builtin.setting.general.auto_apply_patterns", [this](const ContentRegistry::Settings::SettingsValue &value) { - m_autoApplyPatterns = value.get(true); - }); - EventProviderOpened::subscribe(this, [this](prv::Provider *provider) { m_textEditor.get(provider).setLanguageDefinition(PatternLanguage()); m_textEditor.get(provider).setShowWhitespaces(false); @@ -2244,10 +2236,6 @@ namespace hex::plugin::builtin { } }); - ContentRegistry::Settings::onChange("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.pattern_parent_highlighting", [this](const ContentRegistry::Settings::SettingsValue &value) { - m_parentHighlightingEnabled = bool(value.get(false)); - }); - ImHexApi::HexEditor::addBackgroundHighlightingProvider([this](u64 address, const u8 *data, size_t size, bool) -> std::optional { std::ignore = data; std::ignore = size; diff --git a/plugins/builtin/source/content/welcome_screen.cpp b/plugins/builtin/source/content/welcome_screen.cpp index 4208f1baf..334722ef8 100644 --- a/plugins/builtin/source/content/welcome_screen.cpp +++ b/plugins/builtin/source/content/welcome_screen.cpp @@ -52,7 +52,7 @@ namespace hex::plugin::builtin { std::string s_tipOfTheDay; - bool s_simplifiedWelcomeScreen = false; + ContentRegistry::Settings::SettingsVariable s_simplifiedWelcomeScreen = false; class PopupRestoreBackup : public Popup { private: @@ -651,9 +651,7 @@ namespace hex::plugin::builtin { } } }); - ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.simplified_welcome_screen", [](const ContentRegistry::Settings::SettingsValue &value) { - s_simplifiedWelcomeScreen = value.get(false); - }); + ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.language", [](const ContentRegistry::Settings::SettingsValue &value) { auto language = value.get("en-US"); if (language != LocalizationManager::getSelectedLanguageId()) diff --git a/plugins/builtin/source/content/window_decoration.cpp b/plugins/builtin/source/content/window_decoration.cpp index ebebfe6dd..69125f18e 100644 --- a/plugins/builtin/source/content/window_decoration.cpp +++ b/plugins/builtin/source/content/window_decoration.cpp @@ -39,10 +39,11 @@ namespace hex::plugin::builtin { std::string s_windowTitle, s_windowTitleFull; u32 s_searchBarPosition = 0; AutoReset s_logoTexture; - bool s_showSearchBar = true; - bool s_displayShortcutHighlights = true; - bool s_useNativeMenuBar = false; - bool s_showTitlebarBackDrop = true; + + ContentRegistry::Settings::SettingsVariable s_showSearchBar = true; + ContentRegistry::Settings::SettingsVariable s_displayShortcutHighlights = true; + ContentRegistry::Settings::SettingsVariable s_useNativeMenuBar = true; + ContentRegistry::Settings::SettingsVariable s_showTitlebarBackDrop = true; void drawTitleBarBackDrop() { if (!s_showTitlebarBackDrop) @@ -753,23 +754,6 @@ namespace hex::plugin::builtin { RequestUpdateWindowTitle::post(); }); - - ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.show_header_command_palette", [](const ContentRegistry::Settings::SettingsValue &value) { - s_showSearchBar = value.get(true); - }); - - ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.display_shortcut_highlights", [](const ContentRegistry::Settings::SettingsValue &value) { - s_displayShortcutHighlights = value.get(true); - }); - - ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.use_native_menu_bar", [](const ContentRegistry::Settings::SettingsValue &value) { - s_useNativeMenuBar = value.get(true); - }); - - ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.show_titlebar_backdrop", [](const ContentRegistry::Settings::SettingsValue &value) { - s_showTitlebarBackDrop = value.get(true); - }); - ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.randomize_window_title", [](const ContentRegistry::Settings::SettingsValue &value) { const bool randomTitle = value.get(false); if (randomTitle) { diff --git a/plugins/windows/source/content/ui_items.cpp b/plugins/windows/source/content/ui_items.cpp index 597119b9c..d6d770f8c 100644 --- a/plugins/windows/source/content/ui_items.cpp +++ b/plugins/windows/source/content/ui_items.cpp @@ -15,11 +15,7 @@ namespace hex::plugin::windows { void addFooterItems() { - static bool showResourceUsage = true; - ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.show_resource_usage", [](const ContentRegistry::Settings::SettingsValue &value) { - showResourceUsage = value.get(false); - }); - + static ContentRegistry::Settings::SettingsVariable showResourceUsage = false; ContentRegistry::UserInterface::addFooterItem([] { if (!showResourceUsage) return;