From a641f27b7e790d9b79278677df9a6eab77396e51 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Thu, 21 Jan 2021 10:53:12 +0100 Subject: [PATCH] Improved events API --- external/ImGui/include/imgui_memory_editor.h | 2 +- plugins/libimhex/include/hex/api/event.hpp | 9 ++++---- .../include/hex/lang/pattern_data.hpp | 4 ++-- plugins/libimhex/include/hex/views/view.hpp | 13 ++++++----- plugins/libimhex/source/api/event.cpp | 9 +++++--- plugins/libimhex/source/api/imhex_api.cpp | 2 +- plugins/libimhex/source/views/view.cpp | 14 +++++++----- source/views/view_bookmarks.cpp | 10 ++++----- source/views/view_data_inspector.cpp | 4 ++-- source/views/view_disassembler.cpp | 8 +++---- source/views/view_hashes.cpp | 6 ++--- source/views/view_hexeditor.cpp | 22 +++++++++---------- source/views/view_information.cpp | 2 +- source/views/view_patches.cpp | 6 ++--- source/views/view_pattern.cpp | 12 +++++----- source/views/view_settings.cpp | 2 +- source/views/view_strings.cpp | 4 ++-- source/window.cpp | 8 +++---- 18 files changed, 73 insertions(+), 64 deletions(-) diff --git a/external/ImGui/include/imgui_memory_editor.h b/external/ImGui/include/imgui_memory_editor.h index ea6634a26..47b762b5a 100644 --- a/external/ImGui/include/imgui_memory_editor.h +++ b/external/ImGui/include/imgui_memory_editor.h @@ -193,7 +193,7 @@ struct MemoryEditor { if (DataPreviewAddr != DataPreviewAddrOld || DataPreviewAddrEnd != DataPreviewAddrEndOld) { hex::Region selectionRegion = { std::min(DataPreviewAddr, DataPreviewAddrEnd), std::max(DataPreviewAddr, DataPreviewAddrEnd) - std::min(DataPreviewAddr, DataPreviewAddrEnd) }; - hex::View::postEvent(hex::Events::RegionSelected, &selectionRegion); + hex::View::postEvent(hex::Events::RegionSelected, selectionRegion); } DataPreviewAddrOld = DataPreviewAddr; diff --git a/plugins/libimhex/include/hex/api/event.hpp b/plugins/libimhex/include/hex/api/event.hpp index 0d6d92d9b..37991af00 100644 --- a/plugins/libimhex/include/hex/api/event.hpp +++ b/plugins/libimhex/include/hex/api/event.hpp @@ -2,8 +2,9 @@ #include -#include +#include #include +#include namespace hex { @@ -33,13 +34,13 @@ namespace hex { struct EventHandler { void *owner; Events eventType; - std::function callback; + std::function callback; }; class EventManager { public: - static void post(Events eventType, const void *userData); - static void subscribe(Events eventType, void *owner, std::function callback); + static std::vector post(Events eventType, const std::any &userData); + static void subscribe(Events eventType, void *owner, std::function callback); static void unsubscribe(Events eventType, void *sender); }; diff --git a/plugins/libimhex/include/hex/lang/pattern_data.hpp b/plugins/libimhex/include/hex/lang/pattern_data.hpp index d29d9f506..f9407b4d3 100644 --- a/plugins/libimhex/include/hex/lang/pattern_data.hpp +++ b/plugins/libimhex/include/hex/lang/pattern_data.hpp @@ -152,7 +152,7 @@ namespace hex::lang { ImGui::TableNextColumn(); if (ImGui::Selectable(("##PatternDataLine"s + std::to_string(this->getOffset())).c_str(), false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap)) { Region selectRegion = { this->getOffset(), this->getSize() }; - View::postEvent(Events::SelectionChangeRequest, &selectRegion); + View::postEvent(Events::SelectionChangeRequest, selectRegion); } ImGui::SameLine(); ImGui::Text("%s", this->getVariableName().c_str()); @@ -703,7 +703,7 @@ namespace hex::lang { ImGui::TableNextColumn(); if (ImGui::Selectable(("##PatternDataLine"s + std::to_string(this->getOffset())).c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) { Region selectRegion = { this->getOffset(), this->getSize() }; - View::postEvent(Events::SelectionChangeRequest, &selectRegion); + View::postEvent(Events::SelectionChangeRequest, selectRegion); } ImGui::SameLine(); ImGui::Text("%s", this->getVariableName().c_str()); diff --git a/plugins/libimhex/include/hex/views/view.hpp b/plugins/libimhex/include/hex/views/view.hpp index c6ab1f3aa..63ce2a0f5 100644 --- a/plugins/libimhex/include/hex/views/view.hpp +++ b/plugins/libimhex/include/hex/views/view.hpp @@ -15,16 +15,17 @@ namespace hex { class View { public: - View(std::string viewName); + explicit View(std::string viewName); virtual ~View() = default; virtual void drawContent() = 0; virtual void drawMenu(); virtual bool handleShortcut(int key, int mods); + static void doLater(std::function &&function); static std::vector>& getDeferedCalls(); - static void postEvent(Events eventType, const void *userData = nullptr); + static std::vector postEvent(Events eventType, const std::any &userData = { }); static void drawCommonInterfaces(); @@ -36,17 +37,17 @@ namespace hex { bool& getWindowOpenState(); - const std::string getName() const; + std::string_view getName() const; protected: - void subscribeEvent(Events eventType, std::function callback); + void subscribeEvent(Events eventType, const std::function &callback); + void subscribeEvent(Events eventType, const std::function &callback); void unsubscribeEvent(Events eventType); - void doLater(std::function &&function); protected: - void confirmButtons(const char *textLeft, const char *textRight, std::function leftButtonFn, std::function rightButtonFn); + void confirmButtons(const char *textLeft, const char *textRight, const std::function &leftButtonFn, const std::function &rightButtonFn); private: std::string m_viewName; diff --git a/plugins/libimhex/source/api/event.cpp b/plugins/libimhex/source/api/event.cpp index 33a5661ed..f27b74793 100644 --- a/plugins/libimhex/source/api/event.cpp +++ b/plugins/libimhex/source/api/event.cpp @@ -4,13 +4,16 @@ namespace hex { - void EventManager::post(Events eventType, const void *userData) { + std::vector EventManager::post(Events eventType, const std::any &userData) { + std::vector results; for (auto &handler : SharedData::eventHandlers) if (eventType == handler.eventType) - handler.callback(userData); + results.push_back(handler.callback(userData)); + + return results; } - void EventManager::subscribe(Events eventType, void *owner, std::function callback) { + void EventManager::subscribe(Events eventType, void *owner, std::function callback) { for (auto &handler : SharedData::eventHandlers) if (eventType == handler.eventType && owner == handler.owner) return; diff --git a/plugins/libimhex/source/api/imhex_api.cpp b/plugins/libimhex/source/api/imhex_api.cpp index 312afe989..0aa1ab103 100644 --- a/plugins/libimhex/source/api/imhex_api.cpp +++ b/plugins/libimhex/source/api/imhex_api.cpp @@ -17,7 +17,7 @@ namespace hex { entry.color = color; - EventManager::post(Events::AddBookmark, &entry); + EventManager::post(Events::AddBookmark, entry); } void ImHexApi::Bookmarks::add(u64 addr, size_t size, std::string_view name, std::string_view comment, u32 color) { diff --git a/plugins/libimhex/source/views/view.cpp b/plugins/libimhex/source/views/view.cpp index 40fb5138e..500ec45b8 100644 --- a/plugins/libimhex/source/views/view.cpp +++ b/plugins/libimhex/source/views/view.cpp @@ -20,8 +20,8 @@ namespace hex { return SharedData::deferredCalls; } - void View::postEvent(Events eventType, const void *userData) { - EventManager::post(eventType, userData); + std::vector View::postEvent(Events eventType, const std::any &userData) { + return EventManager::post(eventType, userData); } void View::drawCommonInterfaces() { @@ -63,14 +63,18 @@ namespace hex { return this->m_windowOpen; } - const std::string View::getName() const { + std::string_view View::getName() const { return this->m_viewName; } - void View::subscribeEvent(Events eventType, std::function callback) { + void View::subscribeEvent(Events eventType, const std::function &callback) { EventManager::subscribe(eventType, this, callback); } + void View::subscribeEvent(Events eventType, const std::function &callback) { + EventManager::subscribe(eventType, this, [callback](auto userData) -> std::any { callback(userData); return { }; }); + } + void View::unsubscribeEvent(Events eventType) { EventManager::unsubscribe(eventType, this); } @@ -79,7 +83,7 @@ namespace hex { SharedData::deferredCalls.push_back(function); } - void View::confirmButtons(const char *textLeft, const char *textRight, std::function leftButtonFn, std::function rightButtonFn) { + void View::confirmButtons(const char *textLeft, const char *textRight, const std::function &leftButtonFn, const std::function &rightButtonFn) { auto width = ImGui::GetWindowWidth(); ImGui::SetCursorPosX(width / 9); if (ImGui::Button(textLeft, ImVec2(width / 3, 0))) diff --git a/source/views/view_bookmarks.cpp b/source/views/view_bookmarks.cpp index 2c1bf78e3..7be09d9a3 100644 --- a/source/views/view_bookmarks.cpp +++ b/source/views/view_bookmarks.cpp @@ -8,8 +8,8 @@ namespace hex { ViewBookmarks::ViewBookmarks() : View("Bookmarks") { - View::subscribeEvent(Events::AddBookmark, [this](const void *userData) { - auto bookmark = *reinterpret_cast(userData); + View::subscribeEvent(Events::AddBookmark, [](auto userData) { + auto bookmark = std::any_cast(userData); bookmark.comment.resize(0xF'FFFF); if (bookmark.name.empty()) { @@ -29,10 +29,10 @@ namespace hex { ProjectFile::markDirty(); }); - View::subscribeEvent(Events::ProjectFileLoad, [](const void*) { + View::subscribeEvent(Events::ProjectFileLoad, [](auto) { SharedData::bookmarkEntries = ProjectFile::getBookmarks(); }); - View::subscribeEvent(Events::ProjectFileStore, [](const void*) { + View::subscribeEvent(Events::ProjectFileStore, [](auto) { ProjectFile::setBookmarks(SharedData::bookmarkEntries); }); } @@ -90,7 +90,7 @@ namespace hex { ImGui::TextColored(ImColor(0xFF9BC64D), bytesString.c_str()); } if (ImGui::Button("Jump to")) - View::postEvent(Events::SelectionChangeRequest, ®ion); + View::postEvent(Events::SelectionChangeRequest, region); ImGui::SameLine(0, 15); if (ImGui::Button("Remove")) diff --git a/source/views/view_data_inspector.cpp b/source/views/view_data_inspector.cpp index babb2fe6e..0552218bb 100644 --- a/source/views/view_data_inspector.cpp +++ b/source/views/view_data_inspector.cpp @@ -12,8 +12,8 @@ namespace hex { using NumberDisplayStyle = ContentRegistry::DataInspector::NumberDisplayStyle; ViewDataInspector::ViewDataInspector() : View("Data Inspector") { - View::subscribeEvent(Events::RegionSelected, [this](const void* userData) { - Region region = *static_cast(userData); + View::subscribeEvent(Events::RegionSelected, [this](auto userData) { + auto region = std::any_cast(userData); auto provider = SharedData::currentProvider; diff --git a/source/views/view_disassembler.cpp b/source/views/view_disassembler.cpp index 24dd12f2b..0262ccb25 100644 --- a/source/views/view_disassembler.cpp +++ b/source/views/view_disassembler.cpp @@ -10,12 +10,12 @@ using namespace std::literals::string_literals; namespace hex { ViewDisassembler::ViewDisassembler() : View("Disassembler") { - View::subscribeEvent(Events::DataChanged, [this](const void*){ + View::subscribeEvent(Events::DataChanged, [this](auto){ this->m_shouldInvalidate = true; }); - View::subscribeEvent(Events::RegionSelected, [this](const void *userData) { - Region region = *static_cast(userData); + View::subscribeEvent(Events::RegionSelected, [this](auto userData) { + auto region = std::any_cast(userData); if (this->m_shouldMatchSelection) { this->m_codeRegion[0] = region.address; @@ -260,7 +260,7 @@ namespace hex { ImGui::TableNextColumn(); if (ImGui::Selectable(("##DisassemblyLine"s + std::to_string(i)).c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) { Region selectRegion = { this->m_disassembly[i].offset, this->m_disassembly[i].size }; - View::postEvent(Events::SelectionChangeRequest, &selectRegion); + View::postEvent(Events::SelectionChangeRequest, selectRegion); } ImGui::SameLine(); ImGui::Text("0x%llx", this->m_disassembly[i].address); diff --git a/source/views/view_hashes.cpp b/source/views/view_hashes.cpp index 1700b8b2e..848cabde2 100644 --- a/source/views/view_hashes.cpp +++ b/source/views/view_hashes.cpp @@ -11,12 +11,12 @@ namespace hex { ViewHashes::ViewHashes() : View("Hashes") { - View::subscribeEvent(Events::DataChanged, [this](const void*){ + View::subscribeEvent(Events::DataChanged, [this](auto) { this->m_shouldInvalidate = true; }); - View::subscribeEvent(Events::RegionSelected, [this](const void *userData) { - Region region = *static_cast(userData); + View::subscribeEvent(Events::RegionSelected, [this](auto userData) { + auto region = std::any_cast(userData); if (this->m_shouldMatchSelection) { this->m_hashRegion[0] = region.address; diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index 4a1a79582..ba5d50104 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -93,15 +93,15 @@ namespace hex { ImGui::EndTooltip(); }; - View::subscribeEvent(Events::FileDropped, [this](const void *userData) { - auto filePath = static_cast(userData); + View::subscribeEvent(Events::FileDropped, [this](auto userData) { + auto filePath = std::any_cast(userData); if (filePath != nullptr) this->openFile(filePath); }); - View::subscribeEvent(Events::SelectionChangeRequest, [this](const void *userData) { - const Region ®ion = *reinterpret_cast(userData); + View::subscribeEvent(Events::SelectionChangeRequest, [this](auto userData) { + const Region ®ion = std::any_cast(userData); auto provider = SharedData::currentProvider; auto page = provider->getPageOfAddress(region.address); @@ -112,15 +112,15 @@ namespace hex { this->m_memoryEditor.GotoAddr = region.address; this->m_memoryEditor.DataPreviewAddr = region.address; this->m_memoryEditor.DataPreviewAddrEnd = region.address + region.size - 1; - View::postEvent(Events::RegionSelected, ®ion); + View::postEvent(Events::RegionSelected, region); }); - View::subscribeEvent(Events::ProjectFileLoad, [this](const void *userData) { + View::subscribeEvent(Events::ProjectFileLoad, [this](auto) { this->openFile(ProjectFile::getFilePath()); }); - View::subscribeEvent(Events::WindowClosing, [this](const void *userData) { - auto window = const_cast(static_cast(userData)); + View::subscribeEvent(Events::WindowClosing, [this](auto userData) { + auto window = std::any_cast(userData); if (ProjectFile::hasUnsavedChanges()) { glfwSetWindowShouldClose(window, GLFW_FALSE); @@ -129,7 +129,7 @@ namespace hex { } }); - View::subscribeEvent(Events::PatternChanged, [this](const void *userData) { + View::subscribeEvent(Events::PatternChanged, [this](auto) { this->m_highlightedBytes.clear(); for (const auto &pattern : this->m_patternData) @@ -169,7 +169,7 @@ namespace hex { provider->setCurrentPage(provider->getCurrentPage() - 1); Region dataPreview = { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 }; - View::postEvent(Events::RegionSelected, &dataPreview); + View::postEvent(Events::RegionSelected, dataPreview); } ImGui::SameLine(); @@ -178,7 +178,7 @@ namespace hex { provider->setCurrentPage(provider->getCurrentPage() + 1); Region dataPreview = { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 }; - View::postEvent(Events::RegionSelected, &dataPreview); + View::postEvent(Events::RegionSelected, dataPreview); } } ImGui::End(); diff --git a/source/views/view_information.cpp b/source/views/view_information.cpp index 7d34a9784..1daa81508 100644 --- a/source/views/view_information.cpp +++ b/source/views/view_information.cpp @@ -14,7 +14,7 @@ namespace hex { ViewInformation::ViewInformation() : View("Information") { - View::subscribeEvent(Events::DataChanged, [this](const void*) { + View::subscribeEvent(Events::DataChanged, [this](auto) { this->m_dataValid = false; this->m_highestBlockEntropy = 0; this->m_blockEntropy.clear(); diff --git a/source/views/view_patches.cpp b/source/views/view_patches.cpp index fec397472..03fcc6009 100644 --- a/source/views/view_patches.cpp +++ b/source/views/view_patches.cpp @@ -12,13 +12,13 @@ using namespace std::literals::string_literals; namespace hex { ViewPatches::ViewPatches() : View("Patches") { - View::subscribeEvent(Events::ProjectFileStore, [this](const void*) { + View::subscribeEvent(Events::ProjectFileStore, [](auto) { auto provider = SharedData::currentProvider; if (provider != nullptr) ProjectFile::setPatches(provider->getPatches()); }); - View::subscribeEvent(Events::ProjectFileLoad, [this](const void*) { + View::subscribeEvent(Events::ProjectFileLoad, [](auto) { auto provider = SharedData::currentProvider; if (provider != nullptr) provider->getPatches() = ProjectFile::getPatches(); @@ -53,7 +53,7 @@ namespace hex { ImGui::TableNextColumn(); if (ImGui::Selectable(("##patchLine" + std::to_string(index)).c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) { Region selectRegion = { address, 1 }; - View::postEvent(Events::SelectionChangeRequest, &selectRegion); + View::postEvent(Events::SelectionChangeRequest, selectRegion); } if (ImGui::IsMouseReleased(1) && ImGui::IsItemHovered()) { ImGui::OpenPopup("PatchContextMenu"); diff --git a/source/views/view_pattern.cpp b/source/views/view_pattern.cpp index ed96f0317..ec5e87afb 100644 --- a/source/views/view_pattern.cpp +++ b/source/views/view_pattern.cpp @@ -80,23 +80,23 @@ namespace hex { this->m_textEditor.SetLanguageDefinition(PatternLanguage()); this->m_textEditor.SetShowWhitespaces(false); - View::subscribeEvent(Events::ProjectFileStore, [this](const void*) { + View::subscribeEvent(Events::ProjectFileStore, [this](auto) { ProjectFile::setPattern(this->m_textEditor.GetText()); }); - View::subscribeEvent(Events::ProjectFileLoad, [this](const void*) { + View::subscribeEvent(Events::ProjectFileLoad, [this](auto) { this->m_textEditor.SetText(ProjectFile::getPattern()); this->parsePattern(this->m_textEditor.GetText().data()); }); - View::subscribeEvent(Events::AppendPatternLanguageCode, [this](const void *userData) { - const char *code = static_cast(userData); + View::subscribeEvent(Events::AppendPatternLanguageCode, [this](auto userData) { + auto code = std::any_cast(userData); this->m_textEditor.InsertText("\n"); this->m_textEditor.InsertText(code); }); - View::subscribeEvent(Events::FileLoaded, [this](const void* userData) { + View::subscribeEvent(Events::FileLoaded, [this](auto) { if (this->m_textEditor.GetText().find_first_not_of(" \f\n\r\t\v") != std::string::npos) return; @@ -185,7 +185,7 @@ namespace hex { return false; }); - View::subscribeEvent(Events::SettingsChanged, [this](const void*) { + View::subscribeEvent(Events::SettingsChanged, [this](auto) { int theme = ContentRegistry::Settings::getSettingsData()[SettingsCategoryInterface][SettingColorTheme]; switch (theme) { diff --git a/source/views/view_settings.cpp b/source/views/view_settings.cpp index 9d4cba7ea..dcb4caa9a 100644 --- a/source/views/view_settings.cpp +++ b/source/views/view_settings.cpp @@ -24,7 +24,7 @@ namespace hex { ImGui::TextUnformatted(name.c_str()); ImGui::SameLine(); if (callback(ContentRegistry::Settings::getSettingsData()[category][name])) - View::postEvent(Events::SettingsChanged, nullptr); + View::postEvent(Events::SettingsChanged); ImGui::NewLine(); } ImGui::NewLine(); diff --git a/source/views/view_strings.cpp b/source/views/view_strings.cpp index 30ec41c6e..616b70640 100644 --- a/source/views/view_strings.cpp +++ b/source/views/view_strings.cpp @@ -12,7 +12,7 @@ using namespace std::literals::string_literals; namespace hex { ViewStrings::ViewStrings() : View("Strings") { - View::subscribeEvent(Events::DataChanged, [this](const void*){ + View::subscribeEvent(Events::DataChanged, [this](auto){ this->m_foundStrings.clear(); }); @@ -149,7 +149,7 @@ namespace hex { ImGui::TableNextColumn(); if (ImGui::Selectable(("##StringLine"s + std::to_string(i)).c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) { Region selectRegion = { foundString.offset, foundString.size }; - View::postEvent(Events::SelectionChangeRequest, &selectRegion); + View::postEvent(Events::SelectionChangeRequest, selectRegion); } ImGui::PushID(i + 1); createStringContextMenu(foundString); diff --git a/source/window.cpp b/source/window.cpp index 22a52b716..3ab7d5858 100644 --- a/source/window.cpp +++ b/source/window.cpp @@ -27,7 +27,7 @@ namespace hex { void ImHexSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler *handler, void *, const char* line) { for (auto &view : ContentRegistry::Views::getEntries()) { - std::string format = view->getName() + "=%d"; + std::string format = std::string(view->getName()) + "=%d"; sscanf(line, format.c_str(), &view->getWindowOpenState()); } } @@ -38,7 +38,7 @@ namespace hex { buf->appendf("[%s][General]\n", handler->TypeName); for (auto &view : ContentRegistry::Views::getEntries()) { - buf->appendf("%s=%d\n", view->getName().c_str(), view->getWindowOpenState()); + buf->appendf("%s=%d\n", view->getName().data(), view->getWindowOpenState()); } buf->append("\n"); @@ -49,7 +49,7 @@ namespace hex { hex::SharedData::mainArgv = argv; ContentRegistry::Settings::load(); - View::postEvent(Events::SettingsChanged, nullptr); + View::postEvent(Events::SettingsChanged); this->initGLFW(); this->initImGui(); @@ -153,7 +153,7 @@ namespace hex { if (ImGui::BeginMenu("View")) { for (auto &view : ContentRegistry::Views::getEntries()) { if (view->hasViewMenuItemEntry()) - ImGui::MenuItem((view->getName() + " View").c_str(), "", &view->getWindowOpenState()); + ImGui::MenuItem((std::string(view->getName()) + " View").c_str(), "", &view->getWindowOpenState()); } ImGui::EndMenu(); }