diff --git a/.clang-tidy b/.clang-tidy index f0a51780a..b733f1b03 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -65,4 +65,5 @@ readability-*, -readability-redundant-access-specifiers, -readability-function-cognitive-complexity, -readability-identifier-naming, --readability-qualified-auto' \ No newline at end of file +*-include-cleaner, +-readability-qualified-auto' diff --git a/lib/libimhex/include/hex/api/content_registry.hpp b/lib/libimhex/include/hex/api/content_registry.hpp index 084233480..81c07bec5 100644 --- a/lib/libimhex/include/hex/api/content_registry.hpp +++ b/lib/libimhex/include/hex/api/content_registry.hpp @@ -11,9 +11,7 @@ #include #include #include -#include #include -#include #include #include @@ -184,7 +182,7 @@ namespace hex { [[nodiscard]] ImColor getColor() const; private: - std::array m_value; + std::array m_value{}; }; class DropDown : public Widget { public: @@ -316,8 +314,8 @@ namespace hex { DisplayCallback displayCallback; }; - std::vector &getEntries(); - std::vector &getHandlers(); + std::vector &getEntries(); + std::vector &getHandlers(); } @@ -340,7 +338,6 @@ namespace hex { * @brief Adds a new command handler to the command palette * @param type The type of the command * @param command The command to add - * @param unlocalizedDescription The description of the command * @param queryCallback The callback that will be called when the command palette wants to load the name and callback items * @param displayCallback The callback that will be called when the command is displayed in the command palette */ @@ -376,7 +373,7 @@ namespace hex { std::map &getVisualizers(); std::map &getInlineVisualizers(); std::map &getPragmas(); - std::vector &getFunctions(); + std::vector &getFunctions(); } @@ -429,19 +426,19 @@ namespace hex { * @brief Adds a new visualizer to the pattern language * @note Visualizers are extensions to the [[hex::visualize]] attribute, used to visualize data * @param name The name of the visualizer - * @param func The function callback + * @param function The function callback * @param parameterCount The amount of parameters the function takes */ - void addVisualizer(const std::string &name, const impl::VisualizerFunctionCallback &func, pl::api::FunctionParameterCount parameterCount); + void addVisualizer(const std::string &name, const impl::VisualizerFunctionCallback &function, pl::api::FunctionParameterCount parameterCount); /** * @brief Adds a new inline visualizer to the pattern language * @note Inline visualizers are extensions to the [[hex::inline_visualize]] attribute, used to visualize data * @param name The name of the visualizer - * @param func The function callback + * @param function The function callback * @param parameterCount The amount of parameters the function takes */ - void addInlineVisualizer(const std::string &name, const impl::VisualizerFunctionCallback &func, pl::api::FunctionParameterCount parameterCount); + void addInlineVisualizer(const std::string &name, const impl::VisualizerFunctionCallback &function, pl::api::FunctionParameterCount parameterCount); } @@ -487,7 +484,7 @@ namespace hex { bool detached; }; - std::vector &getEntries(); + std::vector &getEntries(); } @@ -519,11 +516,11 @@ namespace hex { std::string unlocalizedName; size_t requiredSize; size_t maxSize; - impl::GeneratorFunction generatorFunction; - std::optional editingFunction; + GeneratorFunction generatorFunction; + std::optional editingFunction; }; - std::vector &getEntries(); + std::vector &getEntries(); } @@ -562,7 +559,7 @@ namespace hex { void add(const Entry &entry); - std::vector &getEntries(); + std::vector &getEntries(); } @@ -647,14 +644,14 @@ namespace hex { constexpr static auto SeparatorValue = "$SEPARATOR$"; constexpr static auto SubMenuValue = "$SUBMENU$"; - std::multimap &getMainMenuItems(); - std::multimap &getMenuItems(); + std::multimap &getMainMenuItems(); + std::multimap &getMenuItems(); - std::vector &getWelcomeScreenEntries(); - std::vector &getFooterItems(); - std::vector &getToolbarItems(); - std::vector &getSidebarItems(); - std::vector &getTitleBarButtons(); + std::vector &getWelcomeScreenEntries(); + std::vector &getFooterItems(); + std::vector &getToolbarItems(); + std::vector &getSidebarItems(); + std::vector &getTitleBarButtons(); } @@ -682,7 +679,6 @@ namespace hex { * @param priority The priority of the entry. Lower values are displayed first * @param function The function to call when the entry is clicked * @param enabledCallback The function to call to determine if the entry is enabled - * @param view The view to use for the entry. If nullptr, the shortcut will work globally */ void addMenuItemSubMenu(std::vector unlocalizedMainMenuNames, u32 priority, const impl::MenuCallback &function, const impl::EnabledCallback& enabledCallback = []{ return true; }); @@ -745,16 +741,16 @@ namespace hex { * @tparam T The provider type that extends hex::prv::Provider * @param addToList Whether to display the provider in the Other Providers list in the welcome screen and File menu */ - template T> + template T> void add(bool addToList = true) { auto typeName = T().getTypeName(); - (void)EventManager::subscribe([expectedName = typeName](const std::string &name, bool skipLoadInterface, bool selectProvider, hex::prv::Provider **provider) { + (void)EventManager::subscribe([expectedName = typeName](const std::string &name, bool skipLoadInterface, bool selectProvider, prv::Provider **provider) { if (name != expectedName) return; prv::Provider *newProvider = new T(); - hex::ImHexApi::Provider::add(newProvider, skipLoadInterface, selectProvider); + ImHexApi::Provider::add(newProvider, skipLoadInterface, selectProvider); if (provider != nullptr) *provider = newProvider; @@ -777,7 +773,7 @@ namespace hex { Callback callback; }; - std::vector &getEntries(); + std::vector &getEntries(); } @@ -802,7 +798,7 @@ namespace hex { Callback callback; }; - std::vector &getEntries(); + std::vector &getEntries(); } @@ -858,7 +854,6 @@ namespace hex { /** * @brief Adds a new cell data visualizer * @tparam T The data visualizer type that extends hex::DataVisualizer - * @param unlocalizedName The unlocalized name of the data visualizer * @param args The arguments to pass to the constructor of the data visualizer */ template T, typename... Args> @@ -955,6 +950,7 @@ namespace hex { } + /* Background Service Registry. Allows adding new background services */ namespace BackgroundServices { namespace impl { @@ -972,6 +968,7 @@ namespace hex { void registerService(const std::string &unlocalizedName, const impl::Callback &callback); } + /* Network Communication Interface Registry. Allows adding new communication interface endpoints */ namespace CommunicationInterface { namespace impl { @@ -983,6 +980,25 @@ namespace hex { void registerNetworkEndpoint(const std::string &endpoint, const impl::NetworkCallback &callback); } + + /* Experiments Registry. Allows adding new experiments */ + namespace Experiments { + + namespace impl { + + struct Experiment { + std::string unlocalizedName, unlocalizedDescription; + bool enabled; + }; + + std::map &getExperiments(); + } + + void addExperiment(const std::string &experimentName, const std::string &unlocalizedName, const std::string &unlocalizedDescription = ""); + void enableExperiement(const std::string &experimentName, bool enabled); + + [[nodiscard]] bool isExperimentEnabled(const std::string &experimentName); + } } } diff --git a/lib/libimhex/source/api/content_registry.cpp b/lib/libimhex/source/api/content_registry.cpp index 0658c7d0a..fccf29504 100644 --- a/lib/libimhex/source/api/content_registry.cpp +++ b/lib/libimhex/source/api/content_registry.cpp @@ -132,18 +132,19 @@ namespace hex { } std::vector &getSettings() { - static std::vector categories; + static std::vector categories; return categories; } Widgets::Widget* add(const std::string &unlocalizedCategory, const std::string &unlocalizedSubCategory, const std::string &unlocalizedName, std::unique_ptr &&widget) { - auto category = impl::insertOrGetEntry(impl::getSettings(), unlocalizedCategory); - auto subCategory = impl::insertOrGetEntry(category->subCategories, unlocalizedSubCategory); - auto entry = impl::insertOrGetEntry(subCategory->entries, unlocalizedName); + const auto category = insertOrGetEntry(getSettings(), unlocalizedCategory); + const auto subCategory = insertOrGetEntry(category->subCategories, unlocalizedSubCategory); + const auto entry = insertOrGetEntry(subCategory->entries, unlocalizedName); entry->widget = std::move(widget); entry->widget->load(getSetting(unlocalizedCategory, unlocalizedName, entry->widget->store())); + entry->widget->onChanged(); return entry->widget.get(); } @@ -151,7 +152,7 @@ namespace hex { } void setCategoryDescription(const std::string &unlocalizedCategory, const std::string &unlocalizedDescription) { - auto category = impl::insertOrGetEntry(impl::getSettings(), unlocalizedCategory); + const auto category = insertOrGetEntry(impl::getSettings(), unlocalizedCategory); category->unlocalizedDescription = unlocalizedDescription; } @@ -247,9 +248,9 @@ namespace hex { } nlohmann::json ColorPicker::store() { - ImColor color(this->m_value[0], this->m_value[1], this->m_value[2], this->m_value[3]); + const ImColor color(this->m_value[0], this->m_value[1], this->m_value[2], this->m_value[3]); - return ImU32(color); + return static_cast(color); } ImColor ColorPicker::getColor() const { @@ -259,7 +260,7 @@ namespace hex { bool DropDown::draw(const std::string &name) { const char *preview = ""; - if (size_t(this->m_value) < this->m_items.size()) + if (static_cast(this->m_value) < this->m_items.size()) preview = this->m_items[this->m_value].c_str(); bool changed = false; @@ -267,7 +268,7 @@ namespace hex { int index = 0; for (const auto &item : this->m_items) { - bool selected = (index == this->m_value); + const bool selected = index == this->m_value; if (ImGui::Selectable(LangEntry(item), selected)) { this->m_value = index; @@ -310,7 +311,7 @@ namespace hex { nlohmann::json DropDown::store() { if (this->m_value == -1) return this->m_defaultItem; - if (size_t(this->m_value) >= this->m_items.size()) + if (static_cast(this->m_value) >= this->m_items.size()) return this->m_defaultItem; return this->m_settingsValues[this->m_value]; @@ -382,13 +383,13 @@ namespace hex { void add(Type type, const std::string &command, const std::string &unlocalizedDescription, const impl::DisplayCallback &displayCallback, const impl::ExecuteCallback &executeCallback) { log::debug("Registered new command palette command: {}", command); - impl::getEntries().push_back(ContentRegistry::CommandPaletteCommands::impl::Entry { type, command, unlocalizedDescription, displayCallback, executeCallback }); + impl::getEntries().push_back(impl::Entry { type, command, unlocalizedDescription, displayCallback, executeCallback }); } void addHandler(Type type, const std::string &command, const impl::QueryCallback &queryCallback, const impl::DisplayCallback &displayCallback) { log::debug("Registered new command palette command handler: {}", command); - impl::getHandlers().push_back(ContentRegistry::CommandPaletteCommands::impl::Handler { type, command, queryCallback, displayCallback }); + impl::getHandlers().push_back(impl::Handler { type, command, queryCallback, displayCallback }); } namespace impl { @@ -451,11 +452,11 @@ namespace hex { runtime.setIncludePaths(fs::getDefaultPaths(fs::ImHexPath::PatternsInclude) | fs::getDefaultPaths(fs::ImHexPath::Patterns)); - for (const auto &func : impl::getFunctions()) { - if (func.dangerous) - runtime.addDangerousFunction(func.ns, func.name, func.parameterCount, func.callback); + for (const auto &[ns, name, paramCount, callback, dangerous] : impl::getFunctions()) { + if (dangerous) + runtime.addDangerousFunction(ns, name, paramCount, callback); else - runtime.addFunction(func.ns, func.name, func.parameterCount, func.callback); + runtime.addFunction(ns, name, paramCount, callback); } for (const auto &[name, callback] : impl::getPragmas()) { @@ -506,14 +507,14 @@ namespace hex { namespace impl { - std::map &getVisualizers() { - static std::map visualizers; + std::map &getVisualizers() { + static std::map visualizers; return visualizers; } - std::map &getInlineVisualizers() { - static std::map visualizers; + std::map &getInlineVisualizers() { + static std::map visualizers; return visualizers; } @@ -524,8 +525,8 @@ namespace hex { return pragmas; } - std::vector &getFunctions() { - static std::vector functions; + std::vector &getFunctions() { + static std::vector functions; return functions; } @@ -551,7 +552,7 @@ namespace hex { void impl::add(std::unique_ptr &&view) { log::debug("Registered new view: {}", view->getUnlocalizedName()); - impl::getEntries().insert({ view->getUnlocalizedName(), std::move(view) }); + getEntries().insert({ view->getUnlocalizedName(), std::move(view) }); } View* getViewByName(const std::string &unlocalizedName) { @@ -601,8 +602,8 @@ namespace hex { namespace impl { - std::vector &getEntries() { - static std::vector entries; + std::vector &getEntries() { + static std::vector entries; return entries; } @@ -614,7 +615,7 @@ namespace hex { namespace ContentRegistry::DataProcessorNode { - void impl::add(const impl::Entry &entry) { + void impl::add(const Entry &entry) { log::debug("Registered new data processor node type: [{}]: {}", entry.category, entry.name); getEntries().push_back(entry); @@ -626,8 +627,8 @@ namespace hex { namespace impl { - std::vector &getEntries() { - static std::vector nodes; + std::vector &getEntries() { + static std::vector nodes; return nodes; } @@ -757,39 +758,39 @@ namespace hex { namespace impl { - std::multimap &getMainMenuItems() { - static std::multimap items; + std::multimap &getMainMenuItems() { + static std::multimap items; return items; } - std::multimap &getMenuItems() { - static std::multimap items; + std::multimap &getMenuItems() { + static std::multimap items; return items; } - std::vector &getWelcomeScreenEntries() { - static std::vector entries; + std::vector &getWelcomeScreenEntries() { + static std::vector entries; return entries; } - std::vector &getFooterItems() { - static std::vector items; + std::vector &getFooterItems() { + static std::vector items; return items; } - std::vector &getToolbarItems() { - static std::vector items; + std::vector &getToolbarItems() { + static std::vector items; return items; } - std::vector &getSidebarItems() { - static std::vector items; + std::vector &getSidebarItems() { + static std::vector items; return items; } - std::vector &getTitleBarButtons() { - static std::vector buttons; + std::vector &getTitleBarButtons() { + static std::vector buttons; return buttons; } @@ -830,8 +831,8 @@ namespace hex { namespace impl { - std::vector &getEntries() { - static std::vector entries; + std::vector &getEntries() { + static std::vector entries; return entries; } @@ -851,8 +852,8 @@ namespace hex { namespace impl { - std::vector &getEntries() { - static std::vector entries; + std::vector &getEntries() { + static std::vector entries; return entries; } @@ -882,7 +883,7 @@ namespace hex { ImGui::PushID(reinterpret_cast(address)); ImGui::InputScalarCallback("##editing_input", dataType, data, format, flags | TextInputFlags | ImGuiInputTextFlags_CallbackEdit, [](ImGuiInputTextCallbackData *data) -> int { - auto &userData = *reinterpret_cast(data->UserData); + auto &userData = *static_cast(data->UserData); if (data->BufTextLen >= userData.maxChars) userData.editingDone = true; @@ -911,7 +912,7 @@ namespace hex { ImGui::PushID(reinterpret_cast(address)); ImGui::InputText("##editing_input", data.data(), data.size() + 1, flags | TextInputFlags | ImGuiInputTextFlags_CallbackEdit, [](ImGuiInputTextCallbackData *data) -> int { - auto &userData = *reinterpret_cast(data->UserData); + auto &userData = *static_cast(data->UserData); userData.data->resize(data->BufSize); @@ -1029,4 +1030,55 @@ namespace hex { } + namespace ContentRegistry::Experiments { + + namespace impl { + + std::map &getExperiments() { + static std::map experiments; + + return experiments; + } + + } + + void addExperiment(const std::string &experimentName, const std::string &unlocalizedName, const std::string &unlocalizedDescription) { + auto &experiments = impl::getExperiments(); + + if (experiments.contains(experimentName)) { + log::error("Experiment with name '{}' already exists!", experimentName); + return; + } + + experiments[experimentName] = impl::Experiment { + .unlocalizedName = unlocalizedName, + .unlocalizedDescription = unlocalizedDescription, + .enabled = false + }; + } + + void enableExperiement(const std::string &experimentName, bool enabled) { + auto &experiments = impl::getExperiments(); + + if (!experiments.contains(experimentName)) { + log::error("Experiment with name '{}' does not exist!", experimentName); + return; + } + + experiments[experimentName].enabled = enabled; + } + + [[nodiscard]] bool isExperimentEnabled(const std::string &experimentName) { + auto &experiments = impl::getExperiments(); + + if (!experiments.contains(experimentName)) { + log::error("Experiment with name '{}' does not exist!", experimentName); + return false; + } + + return experiments[experimentName].enabled; + } + + } + } diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index bc2d2c71c..bd62ba42b 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -516,6 +516,8 @@ "hex.builtin.provider.motorola_srec": "Motorola SREC Provider", "hex.builtin.provider.motorola_srec.name": "Motorola SREC {0}", "hex.builtin.provider.view": "View", + "hex.builtin.setting.experiments": "Experiments", + "hex.builtin.setting.experiments.description": "Experiments are features that are still in development and may not work correctly yet.\n\nFeel free to try them out and report any issues you encounter!", "hex.builtin.setting.folders": "Folders", "hex.builtin.setting.folders.add_folder": "Add new folder", "hex.builtin.setting.folders.description": "Specify additional search paths for patterns, scripts, Yara rules and more",