impr: Add abstraction for common variable-saved-as-setting code pattern

This commit is contained in:
WerWolv
2025-12-26 18:42:10 +01:00
parent ed1f120b0b
commit 59b4f4efce
11 changed files with 74 additions and 72 deletions

View File

@@ -344,10 +344,59 @@ EXPORT_MODULE namespace hex {
using OnChangeCallback = std::function<void(const SettingsValue &)>;
u64 onChange(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, const OnChangeCallback &callback);
void removeOnChangeHandler(u64 id);
using OnSaveCallback = std::function<void()>;
u64 onSave(const OnSaveCallback &callback);
template<typename T, wolv::type::StaticString UnlocalizedCategory, wolv::type::StaticString UnlocalizedName>
class SettingsVariable {
public:
explicit(false) SettingsVariable(const std::common_type_t<T> &defaultValue) : m_defaultValue(defaultValue) {
m_onChangeId = onChange(UnlocalizedCategory.value.data(), UnlocalizedName.value.data(), [this](const SettingsValue &value) {
m_value = value.get<T>(m_defaultValue);
});
}
~SettingsVariable() {
removeOnChangeHandler(m_onChangeId);
}
[[nodiscard]] T get() const {
if (!m_value.has_value()) {
m_value = read<T>(
UnlocalizedCategory.value.data(),
UnlocalizedName.value.data(),
m_defaultValue
);
}
return m_value.value_or(m_defaultValue);
}
void set(const std::common_type_t<T> &value) {
write<T>(
UnlocalizedCategory.value.data(),
UnlocalizedName.value.data(),
value
);
}
explicit(false) operator T() const {
return get();
}
SettingsVariable& operator=(const std::common_type_t<T> &value) {
set(value);
return *this;
}
private:
mutable std::optional<T> m_value;
T m_defaultValue;
u64 m_onChangeId;
};
}
}

View File

@@ -2,6 +2,7 @@
#include <hex/ui/view.hpp>
#include <hex/api/achievement_manager.hpp>
#include <hex/api/content_registry/settings.hpp>
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<bool, "hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup"> m_showPopup = true;
ImVec2 m_offset;
};
}
}

View File

@@ -9,6 +9,7 @@
#include <ui/text_editor.hpp>
#include <content/text_highlighting/pattern_language.hpp>
#include <hex/api/content_registry/settings.hpp>
#include <hex/helpers/magic.hpp>
#include <ui/pattern_drawer.hpp>
@@ -137,8 +138,8 @@ namespace hex::plugin::builtin {
std::atomic<bool> m_dangerousFunctionCalled = false;
std::atomic<DangerousFunctionPerms> m_dangerousFunctionsAllowed = DangerousFunctionPerms::Ask;
bool m_suggestSupportedPatterns = true;
bool m_autoApplyPatterns = false;
ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.general", "hex.builtin.setting.general.suggest_patterns"> m_suggestSupportedPatterns = true;
ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.general", "hex.builtin.setting.general.auto_apply_patterns"> m_autoApplyPatterns = false;
PerProvider<ui::VisualizerDrawer> m_visualizerDrawer;
bool m_tooltipJustOpened = false;
@@ -177,7 +178,7 @@ namespace hex::plugin::builtin {
std::array<AccessData, 512> m_accessHistory = {};
u32 m_accessHistoryIndex = 0;
bool m_parentHighlightingEnabled = true;
ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.pattern_parent_highlighting"> m_parentHighlightingEnabled = false;
bool m_replaceMode = false;
bool m_openFindReplacePopUp = false;
bool m_openGotoLinePopUp = false;

View File

@@ -22,8 +22,8 @@
namespace hex::plugin::builtin {
static bool s_networkInterfaceServiceEnabled = false;
static int s_autoBackupTime = 0;
static ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.general", "hex.builtin.setting.general.network_interface"> s_networkInterfaceServiceEnabled = false;
static ContentRegistry::Settings::SettingsVariable<int, "hex.builtin.setting.general", "hex.builtin.setting.general.backups.auto_backup_time"> s_autoBackupTime = 0;
namespace {
@@ -75,7 +75,7 @@ namespace hex::plugin::builtin {
auto now = std::chrono::steady_clock::now();
static std::chrono::time_point<std::chrono::steady_clock> 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<bool>(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<bool>(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<int>(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);

View File

@@ -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<bool>(false);
});
static ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.interface", "hex.builtin.setting.interface.always_show_provider_tabs"> alwaysShowProviderTabs = false;
// Toolbar items
ContentRegistry::UserInterface::addToolbarItem([] {

View File

@@ -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<bool>(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<bool>("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();

View File

@@ -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<bool>(true);
});
static ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.show_highlights"> 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<bool>(true));

View File

@@ -1840,14 +1840,6 @@ namespace hex::plugin::builtin {
m_sourceCode.enableSync(value.get<bool>(false));
});
ContentRegistry::Settings::onChange("hex.builtin.setting.general", "hex.builtin.setting.general.suggest_patterns", [this](const ContentRegistry::Settings::SettingsValue &value) {
m_suggestSupportedPatterns = value.get<bool>(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<bool>(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<int>(false));
});
ImHexApi::HexEditor::addBackgroundHighlightingProvider([this](u64 address, const u8 *data, size_t size, bool) -> std::optional<color_t> {
std::ignore = data;
std::ignore = size;

View File

@@ -52,7 +52,7 @@ namespace hex::plugin::builtin {
std::string s_tipOfTheDay;
bool s_simplifiedWelcomeScreen = false;
ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.interface", "hex.builtin.setting.interface.simplified_welcome_screen"> s_simplifiedWelcomeScreen = false;
class PopupRestoreBackup : public Popup<PopupRestoreBackup> {
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<bool>(false);
});
ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.language", [](const ContentRegistry::Settings::SettingsValue &value) {
auto language = value.get<std::string>("en-US");
if (language != LocalizationManager::getSelectedLanguageId())

View File

@@ -39,10 +39,11 @@ namespace hex::plugin::builtin {
std::string s_windowTitle, s_windowTitleFull;
u32 s_searchBarPosition = 0;
AutoReset<ImGuiExt::Texture> s_logoTexture;
bool s_showSearchBar = true;
bool s_displayShortcutHighlights = true;
bool s_useNativeMenuBar = false;
bool s_showTitlebarBackDrop = true;
ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.interface", "hex.builtin.setting.interface.show_header_command_palette"> s_showSearchBar = true;
ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.interface", "hex.builtin.setting.interface.display_shortcut_highlights"> s_displayShortcutHighlights = true;
ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.interface", "hex.builtin.setting.interface.use_native_menu_bar"> s_useNativeMenuBar = true;
ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.interface", "hex.builtin.setting.interface.show_titlebar_backdrop"> 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<bool>(true);
});
ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.display_shortcut_highlights", [](const ContentRegistry::Settings::SettingsValue &value) {
s_displayShortcutHighlights = value.get<bool>(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<bool>(true);
});
ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.show_titlebar_backdrop", [](const ContentRegistry::Settings::SettingsValue &value) {
s_showTitlebarBackDrop = value.get<bool>(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<bool>(false);
if (randomTitle) {

View File

@@ -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<bool>(false);
});
static ContentRegistry::Settings::SettingsVariable<bool, "hex.builtin.setting.interface", "hex.builtin.setting.interface.show_resource_usage"> showResourceUsage = false;
ContentRegistry::UserInterface::addFooterItem([] {
if (!showResourceUsage)
return;