diff --git a/external/ImGui/include/imgui_memory_editor.h b/external/ImGui/include/imgui_memory_editor.h index 252c3aa55..d7d4978c4 100644 --- a/external/ImGui/include/imgui_memory_editor.h +++ b/external/ImGui/include/imgui_memory_editor.h @@ -48,7 +48,7 @@ #include // uint8_t, etc. #include -#include +#include #include @@ -223,7 +223,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::EventManager::post(selectionRegion); } DataPreviewAddrOld = DataPreviewAddr; diff --git a/plugins/libimhex/include/hex/api/content_registry.hpp b/plugins/libimhex/include/hex/api/content_registry.hpp index 68938b0e9..7bd3aff03 100644 --- a/plugins/libimhex/include/hex/api/content_registry.hpp +++ b/plugins/libimhex/include/hex/api/content_registry.hpp @@ -55,13 +55,6 @@ namespace hex { static nlohmann::json& getSettingsData(); }; - /* Events Registry. Allows to define new events that can be used by other plugins later on subscribe to */ - struct Events { - Events() = delete; - - static auto get(std::string_view name); - }; - /* Command Palette Command Registry. Allows adding of new commands to the command palette */ struct CommandPaletteCommands { CommandPaletteCommands() = delete; diff --git a/plugins/libimhex/include/hex/api/event.hpp b/plugins/libimhex/include/hex/api/event.hpp index ae78cdaac..d1a0ad190 100644 --- a/plugins/libimhex/include/hex/api/event.hpp +++ b/plugins/libimhex/include/hex/api/event.hpp @@ -2,48 +2,114 @@ #include -#include +#include +#include +#include #include -#include + +#include + +#define EVENT_DEF(event_name, ...) \ + struct event_name final : public hex::Event<__VA_ARGS__> { \ + constexpr static auto id = [] { return hex::EventId(); }(); \ + event_name(Callback func) noexcept : Event(func) { } \ + }; + +class GLFWwindow; namespace hex { - enum class Events : u32 { - FileLoaded, - DataChanged, - PatternChanged, - FileDropped, - WindowClosing, - RegionSelected, + class EventId { + public: + constexpr EventId(const char *func = __builtin_FUNCTION(), u32 line = __builtin_LINE()) { + this->m_hash = line ^ 123456789; + for (auto c : std::string_view(func)) { + this->m_hash = (this->m_hash >> 5) | (this->m_hash << 27); + this->m_hash ^= c; + } + } - SelectionChangeRequest, + constexpr bool operator ==(const EventId &rhs) const = default; - AddBookmark, - AppendPatternLanguageCode, - - ProjectFileStore, - ProjectFileLoad, - - SettingsChanged, - - OpenWindow, - CloseImHex, - - /* This is not a real event but a flag to show all events after this one are plugin ones */ - Events_BuiltinEnd + private: + u32 m_hash; }; - struct EventHandler { - void *owner; - Events eventType; - std::function callback; + struct EventBase { + EventBase() noexcept = default; + }; + + template + struct Event : public EventBase { + using Callback = std::function; + + explicit Event(Callback func) noexcept : m_func(func) {} + + void operator()(Params... params) const noexcept { + this->m_func(params...); + } + + private: + Callback m_func; }; class EventManager { public: - 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); + using EventList = std::list>; + + template + [[nodiscard]] static EventList::iterator subscribe(typename E::Callback function) { + return s_events.insert(s_events.end(), std::make_pair(E::id, new E(function))); + } + + template + static void subscribe(void *token, typename E::Callback function) { + s_tokenStore.insert(std::make_pair(token, subscribe(function))); + } + + static void unsubscribe(EventList::iterator iter) noexcept { + s_events.remove(*iter); + } + + template + static void unsubscribe(void *token) noexcept { + auto iter = std::find_if(s_tokenStore.begin(), s_tokenStore.end(), [&](auto &item){ + return item.first == token && item.second->first == E::id; + }); + + if (iter != s_tokenStore.end()) { + s_events.remove(*iter->second); + } + } + + template + static void post(auto ... args) noexcept { + for (const auto &[id, event] : s_events) { + if (id == E::id) + (*reinterpret_cast(event))(args...); + } + } + + private: + static std::map s_tokenStore; + static EventList s_events; }; + /* Default Events */ + EVENT_DEF(EventFileLoaded, std::string); + EVENT_DEF(EventDataChanged); + EVENT_DEF(EventPatternChanged); + EVENT_DEF(EventFileDropped, std::string); + EVENT_DEF(EventWindowClosing, GLFWwindow*); + EVENT_DEF(EventRegionSelected, Region); + EVENT_DEF(EventProjectFileStore); + EVENT_DEF(EventProjectFileLoad); + EVENT_DEF(EventSettingsChanged); + + EVENT_DEF(RequestOpenWindow, std::string); + EVENT_DEF(RequestSelectionChange, Region); + EVENT_DEF(RequestAddBookmark, ImHexApi::Bookmarks::Entry); + EVENT_DEF(RequestAppendPatternLanguageCode, std::string); + EVENT_DEF(RequestCloseImHex); + } \ No newline at end of file diff --git a/plugins/libimhex/include/hex/helpers/shared_data.hpp b/plugins/libimhex/include/hex/helpers/shared_data.hpp index 192f49ff4..4f4d4edd3 100644 --- a/plugins/libimhex/include/hex/helpers/shared_data.hpp +++ b/plugins/libimhex/include/hex/helpers/shared_data.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #include @@ -47,13 +46,10 @@ namespace hex { } public: - static std::vector eventHandlers; static std::vector> deferredCalls; static prv::Provider *currentProvider; static std::map> settingsEntries; static nlohmann::json settingsJson; - static std::map customEvents; - static u32 customEventsLastId; static std::vector commandPaletteCommands; static std::map patternLanguageFunctions; static std::vector views; diff --git a/plugins/libimhex/include/hex/lang/pattern_data.hpp b/plugins/libimhex/include/hex/lang/pattern_data.hpp index 8cf560e05..6a78538c7 100644 --- a/plugins/libimhex/include/hex/lang/pattern_data.hpp +++ b/plugins/libimhex/include/hex/lang/pattern_data.hpp @@ -154,8 +154,7 @@ namespace hex::lang { ImGui::TreeNodeEx(this->getVariableName().c_str(), ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_AllowItemOverlap); 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); + EventManager::post(Region { this->getOffset(), this->getSize() }); } this->drawCommentTooltip(); ImGui::SameLine(); @@ -743,8 +742,7 @@ namespace hex::lang { this->drawCommentTooltip(); 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); + EventManager::post(Region { this->getOffset(), this->getSize() }); } 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 b238d054f..5c282cff9 100644 --- a/plugins/libimhex/include/hex/views/view.hpp +++ b/plugins/libimhex/include/hex/views/view.hpp @@ -40,8 +40,6 @@ namespace hex { static void doLater(std::function &&function); static std::vector>& getDeferedCalls(); - static std::vector postEvent(Events eventType, const std::any &userData = { }); - static void drawCommonInterfaces(); static void showErrorPopup(std::string_view errorMessage); @@ -55,11 +53,6 @@ namespace hex { std::string_view getUnlocalizedName() const; protected: - void subscribeEvent(Events eventType, const std::function &callback); - void subscribeEvent(Events eventType, const std::function &callback); - - void unsubscribeEvent(Events eventType); - void discardNavigationRequests(); void confirmButtons(const char *textLeft, const char *textRight, const std::function &leftButtonFn, const std::function &rightButtonFn); diff --git a/plugins/libimhex/source/api/content_registry.cpp b/plugins/libimhex/source/api/content_registry.cpp index f1b604252..745b76fa4 100644 --- a/plugins/libimhex/source/api/content_registry.cpp +++ b/plugins/libimhex/source/api/content_registry.cpp @@ -133,21 +133,6 @@ namespace hex { } - /* Events */ - - auto ContentRegistry::Events::get(std::string_view name) { - auto &customEvents = SharedData::customEvents; - auto &lastId = SharedData::customEventsLastId; - - if (!customEvents.contains(name.data())) { - customEvents[name.data()] = static_cast(lastId); - lastId++; - } - - return customEvents[name.data()]; - } - - /* Command Palette Commands */ void ContentRegistry::CommandPaletteCommands::add(ContentRegistry::CommandPaletteCommands::Type type, std::string_view command, std::string_view unlocalizedDescription, const std::function &displayCallback, const std::function &executeCallback) { @@ -225,7 +210,7 @@ namespace hex { void ContentRegistry::Language::addLocalizations(std::string_view languageCode, const LanguageDefinition &definition) { getLanguageDefinitions()[languageCode.data()].push_back(definition); - EventManager::post(hex::Events::SettingsChanged, {}); + EventManager::post(); } std::map& ContentRegistry::Language::getLanguages() { diff --git a/plugins/libimhex/source/api/event.cpp b/plugins/libimhex/source/api/event.cpp index f27b74793..a88a26902 100644 --- a/plugins/libimhex/source/api/event.cpp +++ b/plugins/libimhex/source/api/event.cpp @@ -1,30 +1,8 @@ #include -#include - namespace hex { - std::vector EventManager::post(Events eventType, const std::any &userData) { - std::vector results; - for (auto &handler : SharedData::eventHandlers) - if (eventType == handler.eventType) - results.push_back(handler.callback(userData)); - - return results; - } - - void EventManager::subscribe(Events eventType, void *owner, std::function callback) { - for (auto &handler : SharedData::eventHandlers) - if (eventType == handler.eventType && owner == handler.owner) - return; - - SharedData::eventHandlers.push_back(EventHandler { owner, eventType, callback }); - } - - void EventManager::unsubscribe(Events eventType, void *sender) { - std::erase_if(SharedData::eventHandlers, [&eventType, &sender](EventHandler handler) { - return eventType == handler.eventType && sender == handler.owner; - }); - } + std::map EventManager::s_tokenStore; + EventManager::EventList EventManager::s_events; } \ No newline at end of file diff --git a/plugins/libimhex/source/api/imhex_api.cpp b/plugins/libimhex/source/api/imhex_api.cpp index 9462e9ea2..6d2c5dad5 100644 --- a/plugins/libimhex/source/api/imhex_api.cpp +++ b/plugins/libimhex/source/api/imhex_api.cpp @@ -18,7 +18,7 @@ namespace hex { entry.color = color; - EventManager::post(Events::AddBookmark, entry); + EventManager::post(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/helpers/shared_data.cpp b/plugins/libimhex/source/helpers/shared_data.cpp index 649ad5e8f..328f5a991 100644 --- a/plugins/libimhex/source/helpers/shared_data.cpp +++ b/plugins/libimhex/source/helpers/shared_data.cpp @@ -2,13 +2,10 @@ namespace hex { - std::vector SharedData::eventHandlers; std::vector> SharedData::deferredCalls; prv::Provider *SharedData::currentProvider; std::map> SharedData::settingsEntries; nlohmann::json SharedData::settingsJson; - std::map SharedData::customEvents; - u32 SharedData::customEventsLastId; std::vector SharedData::commandPaletteCommands; std::map SharedData::patternLanguageFunctions; std::vector SharedData::views; diff --git a/plugins/libimhex/source/views/view.cpp b/plugins/libimhex/source/views/view.cpp index abf23b5c8..7a961fa7d 100644 --- a/plugins/libimhex/source/views/view.cpp +++ b/plugins/libimhex/source/views/view.cpp @@ -24,10 +24,6 @@ namespace hex { return SharedData::deferredCalls; } - std::vector View::postEvent(Events eventType, const std::any &userData) { - return EventManager::post(eventType, userData); - } - void View::openFileBrowser(std::string_view title, DialogMode mode, const std::vector &validExtensions, const std::function &callback) { NFD::Init(); @@ -93,18 +89,6 @@ namespace hex { return this->m_unlocalizedViewName; } - 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); - } - void View::discardNavigationRequests() { if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard; diff --git a/source/helpers/loader_script_handler.cpp b/source/helpers/loader_script_handler.cpp index 24d58e1e7..b279087c3 100644 --- a/source/helpers/loader_script_handler.cpp +++ b/source/helpers/loader_script_handler.cpp @@ -163,7 +163,7 @@ namespace hex { code += "};\n"; - View::postEvent(Events::AppendPatternLanguageCode, code.c_str()); + EventManager::post(code); Py_RETURN_NONE; } diff --git a/source/main.cpp b/source/main.cpp index 8323a2b5f..3724bae42 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -53,7 +53,7 @@ int main(int argc, char **argv) { ContentRegistry::Views::add(); if (argc > 1) - View::postEvent(Events::FileDropped, const_cast(argv[1])); + EventManager::post(argv[1]); window.loop(); diff --git a/source/views/view_bookmarks.cpp b/source/views/view_bookmarks.cpp index 918b5e48f..f6790202b 100644 --- a/source/views/view_bookmarks.cpp +++ b/source/views/view_bookmarks.cpp @@ -8,8 +8,7 @@ namespace hex { ViewBookmarks::ViewBookmarks() : View("hex.view.bookmarks.name") { - View::subscribeEvent(Events::AddBookmark, [](auto userData) { - auto bookmark = std::any_cast(userData); + EventManager::subscribe(this, [](ImHexApi::Bookmarks::Entry bookmark) { bookmark.comment.resize(0xF'FFFF); if (bookmark.name.empty()) { @@ -29,18 +28,19 @@ namespace hex { ProjectFile::markDirty(); }); - View::subscribeEvent(Events::ProjectFileLoad, [](auto) { + EventManager::subscribe(this, []{ SharedData::bookmarkEntries = ProjectFile::getBookmarks(); }); - View::subscribeEvent(Events::ProjectFileStore, [](auto) { + + EventManager::subscribe(this, []{ ProjectFile::setBookmarks(SharedData::bookmarkEntries); }); } ViewBookmarks::~ViewBookmarks() { - View::unsubscribeEvent(Events::AddBookmark); - View::unsubscribeEvent(Events::ProjectFileLoad); - View::unsubscribeEvent(Events::ProjectFileStore); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); } void ViewBookmarks::drawContent() { @@ -90,7 +90,7 @@ namespace hex { ImGui::TextColored(ImColor(0xFF9BC64D), "%s", bytesString.c_str()); } if (ImGui::Button("hex.view.bookmarks.button.jump"_lang)) - View::postEvent(Events::SelectionChangeRequest, region); + EventManager::post(region); ImGui::SameLine(0, 15); if (ImGui::Button("hex.view.bookmarks.button.remove"_lang)) diff --git a/source/views/view_data_inspector.cpp b/source/views/view_data_inspector.cpp index 7746aba1b..c13301ba2 100644 --- a/source/views/view_data_inspector.cpp +++ b/source/views/view_data_inspector.cpp @@ -11,9 +11,7 @@ namespace hex { using NumberDisplayStyle = ContentRegistry::DataInspector::NumberDisplayStyle; ViewDataInspector::ViewDataInspector() : View("hex.view.data_inspector.name") { - View::subscribeEvent(Events::RegionSelected, [this](auto userData) { - auto region = std::any_cast(userData); - + EventManager::subscribe(this, [this](Region region) { auto provider = SharedData::currentProvider; if (provider == nullptr) { @@ -34,7 +32,7 @@ namespace hex { } ViewDataInspector::~ViewDataInspector() { - View::unsubscribeEvent(Events::RegionSelected); + EventManager::unsubscribe(this); } void ViewDataInspector::drawContent() { diff --git a/source/views/view_data_processor.cpp b/source/views/view_data_processor.cpp index 201fbb5c5..f8c2ce3d6 100644 --- a/source/views/view_data_processor.cpp +++ b/source/views/view_data_processor.cpp @@ -17,7 +17,7 @@ namespace hex { io.link_detach_with_modifier_click.modifier = &always; } - View::subscribeEvent(Events::SettingsChanged, [](auto) { + EventManager::subscribe(this, [] { auto theme = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color"); if (theme.is_number()) { @@ -38,7 +38,7 @@ namespace hex { } }); - View::subscribeEvent(Events::FileLoaded, [this](auto) { + EventManager::subscribe(this, [this](const std::string &path){ for (auto &node : this->m_nodes) { node->setCurrentOverlay(nullptr); } @@ -50,6 +50,9 @@ namespace hex { for (auto &node : this->m_nodes) delete node; + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + imnodes::PopAttributeFlag(); imnodes::PopAttributeFlag(); imnodes::Shutdown(); diff --git a/source/views/view_disassembler.cpp b/source/views/view_disassembler.cpp index 38a347a20..cec1d6498 100644 --- a/source/views/view_disassembler.cpp +++ b/source/views/view_disassembler.cpp @@ -13,13 +13,11 @@ using namespace std::literals::string_literals; namespace hex { ViewDisassembler::ViewDisassembler() : View("hex.view.disassembler.name") { - View::subscribeEvent(Events::DataChanged, [this](auto){ + EventManager::subscribe(this, [this]() { this->disassemble(); }); - View::subscribeEvent(Events::RegionSelected, [this](auto userData) { - auto region = std::any_cast(userData); - + EventManager::subscribe(this, [this](Region region) { if (this->m_shouldMatchSelection) { this->m_codeRegion[0] = region.address; this->m_codeRegion[1] = region.address + region.size - 1; @@ -28,8 +26,8 @@ namespace hex { } ViewDisassembler::~ViewDisassembler() { - View::unsubscribeEvent(Events::DataChanged); - View::unsubscribeEvent(Events::RegionSelected); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); } void ViewDisassembler::disassemble() { @@ -273,8 +271,7 @@ namespace hex { ImGui::TableNextRow(); 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); + EventManager::post(Region { this->m_disassembly[i].offset, this->m_disassembly[i].size }); } 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 8f3e395d3..4f40e287c 100644 --- a/source/views/view_hashes.cpp +++ b/source/views/view_hashes.cpp @@ -10,13 +10,11 @@ namespace hex { ViewHashes::ViewHashes() : View("hex.view.hashes.name") { - View::subscribeEvent(Events::DataChanged, [this](auto) { + EventManager::subscribe(this, [this]() { this->m_shouldInvalidate = true; }); - View::subscribeEvent(Events::RegionSelected, [this](auto userData) { - auto region = std::any_cast(userData); - + EventManager::subscribe(this, [this](Region region) { if (this->m_shouldMatchSelection) { this->m_hashRegion[0] = region.address; this->m_hashRegion[1] = region.address + region.size - 1; @@ -26,8 +24,8 @@ namespace hex { } ViewHashes::~ViewHashes() { - View::unsubscribeEvent(Events::DataChanged); - View::unsubscribeEvent(Events::RegionSelected); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); } diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index cb4e651f5..0351c0185 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -39,7 +39,7 @@ namespace hex { return; provider->write(off, &d, sizeof(ImU8)); - View::postEvent(Events::DataChanged); + EventManager::post(); ProjectFile::markDirty(); }; @@ -124,16 +124,11 @@ namespace hex { return { std::string(decoded), advance, color }; }; - View::subscribeEvent(Events::FileDropped, [this](auto userData) { - auto filePath = std::any_cast(userData); - - if (filePath != nullptr) - this->openFile(filePath); + EventManager::subscribe(this, [this](const std::string &filePath) { + this->openFile(filePath); }); - View::subscribeEvent(Events::SelectionChangeRequest, [this](auto userData) { - const Region ®ion = std::any_cast(userData); - + EventManager::subscribe(this, [this](Region region) { auto provider = SharedData::currentProvider; auto page = provider->getPageOfAddress(region.address); if (!page.has_value()) @@ -141,39 +136,37 @@ namespace hex { provider->setCurrentPage(page.value()); this->m_memoryEditor.GotoAddrAndHighlight(region.address, region.address + region.size - 1); - View::postEvent(Events::RegionSelected, region); + EventManager::post(region); }); - View::subscribeEvent(Events::ProjectFileLoad, [this](auto) { + EventManager::subscribe(this, [this]() { this->openFile(ProjectFile::getFilePath()); }); - View::subscribeEvent(Events::WindowClosing, [this](auto userData) { - auto window = std::any_cast(userData); - + EventManager::subscribe(this, [](GLFWwindow *window) { if (ProjectFile::hasUnsavedChanges()) { glfwSetWindowShouldClose(window, GLFW_FALSE); View::doLater([] { ImGui::OpenPopup("hex.view.hexeditor.save_changes.title"_lang); }); } }); - View::subscribeEvent(Events::PatternChanged, [this](auto) { + EventManager::subscribe(this, [this]() { this->m_highlightedBytes.clear(); for (const auto &pattern : this->m_patternData) this->m_highlightedBytes.merge(pattern->getHighlightedAddresses()); }); - View::subscribeEvent(Events::OpenWindow, [this](auto name) { - if (std::any_cast(name) == std::string("Open File")) { + EventManager::subscribe(this, [this](std::string name) { + if (name == "Open File") { View::openFileBrowser("hex.view.hexeditor.open_file"_lang, DialogMode::Open, { }, [this](auto path) { this->openFile(path); this->getWindowOpenState() = true; }); - } else if (std::any_cast(name) == std::string("Open Project")) { + } else if (name == "Open Project") { View::openFileBrowser("hex.view.hexeditor.open_project"_lang, DialogMode::Open, { { "Project File", "hexproj" } }, [this](auto path) { ProjectFile::load(path); - View::postEvent(Events::ProjectFileLoad); + EventManager::post(); this->getWindowOpenState() = true; }); } @@ -181,7 +174,12 @@ namespace hex { } ViewHexEditor::~ViewHexEditor() { - + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); } void ViewHexEditor::drawContent() { @@ -211,8 +209,7 @@ namespace hex { if (ImGui::ArrowButton("prevPage", ImGuiDir_Left)) { provider->setCurrentPage(provider->getCurrentPage() - 1); - Region dataPreview = { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 }; - View::postEvent(Events::RegionSelected, dataPreview); + EventManager::post(Region { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 }); } ImGui::SameLine(); @@ -220,8 +217,7 @@ namespace hex { if (ImGui::ArrowButton("nextPage", ImGuiDir_Right)) { provider->setCurrentPage(provider->getCurrentPage() + 1); - Region dataPreview = { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 }; - View::postEvent(Events::RegionSelected, dataPreview); + EventManager::post(Region { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 }); } } ImGui::End(); @@ -269,7 +265,12 @@ namespace hex { ImGui::TextUnformatted("hex.view.hexeditor.save_changes.desc"_lang); ImGui::NewLine(); - confirmButtons("hex.common.yes"_lang, "hex.common.no"_lang, [] { View::postEvent(Events::CloseImHex); }, [] { ImGui::CloseCurrentPopup(); }); + confirmButtons("hex.common.yes"_lang, "hex.common.no"_lang, [] { + EventManager::post(); + }, + [] { + ImGui::CloseCurrentPopup(); + }); if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape))) ImGui::CloseCurrentPopup(); @@ -364,13 +365,13 @@ namespace hex { if (ImGui::MenuItem("hex.view.hexeditor.menu.file.open_project"_lang, "")) { View::openFileBrowser("hex.view.hexeditor.menu.file.open_project"_lang, DialogMode::Open, { { "Project File", "hexproj" } }, [this](auto path) { ProjectFile::load(path); - View::postEvent(Events::ProjectFileLoad); + EventManager::post(); this->getWindowOpenState() = true; }); } if (ImGui::MenuItem("hex.view.hexeditor.menu.file.save_project"_lang, "", false, provider != nullptr && provider->isWritable())) { - View::postEvent(Events::ProjectFileStore); + EventManager::post(); if (ProjectFile::getProjectFilePath() == "") { View::openFileBrowser("hex.view.hexeditor.save_project"_lang, DialogMode::Save, { { "Project File", "hexproj" } }, [](auto path) { @@ -560,9 +561,9 @@ namespace hex { this->getWindowOpenState() = true; - View::postEvent(Events::FileLoaded, path); - View::postEvent(Events::DataChanged); - View::postEvent(Events::PatternChanged); + EventManager::post(path); + EventManager::post(); + EventManager::post(); } bool ViewHexEditor::saveToFile(std::string path, const std::vector& data) { diff --git a/source/views/view_information.cpp b/source/views/view_information.cpp index d5c996a3d..a7eb3d6c4 100644 --- a/source/views/view_information.cpp +++ b/source/views/view_information.cpp @@ -19,7 +19,7 @@ namespace hex { ViewInformation::ViewInformation() : View("hex.view.information.name") { - View::subscribeEvent(Events::DataChanged, [this](auto) { + EventManager::subscribe(this, [this]() { this->m_dataValid = false; this->m_highestBlockEntropy = 0; this->m_blockEntropy.clear(); @@ -33,7 +33,7 @@ namespace hex { } ViewInformation::~ViewInformation() { - View::unsubscribeEvent(Events::DataChanged); + EventManager::unsubscribe(this); } static float calculateEntropy(std::array &valueCounts, size_t numBytes) { @@ -209,7 +209,7 @@ namespace hex { ImPlot::PlotLine("##entropy_line", this->m_blockEntropy.data(), this->m_blockEntropy.size()); if (ImGui::IsItemClicked()) - View::postEvent(Events::SelectionChangeRequest, Region{ u64(ImPlot::GetPlotMousePos().x) * this->m_blockSize, 1 }); + EventManager::post( Region{ u64(ImPlot::GetPlotMousePos().x) * this->m_blockSize, 1 }); ImPlot::EndPlot(); } diff --git a/source/views/view_patches.cpp b/source/views/view_patches.cpp index 19a021820..e6535a0d8 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("hex.view.patches.name") { - View::subscribeEvent(Events::ProjectFileStore, [](auto) { + EventManager::subscribe(this, []{ auto provider = SharedData::currentProvider; if (provider != nullptr) ProjectFile::setPatches(provider->getPatches()); }); - View::subscribeEvent(Events::ProjectFileLoad, [](auto) { + EventManager::subscribe(this, []{ auto provider = SharedData::currentProvider; if (provider != nullptr) provider->getPatches() = ProjectFile::getPatches(); @@ -26,8 +26,8 @@ namespace hex { } ViewPatches::~ViewPatches() { - View::unsubscribeEvent(Events::ProjectFileStore); - View::unsubscribeEvent(Events::ProjectFileLoad); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); } void ViewPatches::drawContent() { @@ -52,8 +52,7 @@ namespace hex { ImGui::TableNextRow(); ImGui::TableNextColumn(); if (ImGui::Selectable(("##patchLine" + std::to_string(index)).c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) { - Region selectRegion = { address, 1 }; - View::postEvent(Events::SelectionChangeRequest, selectRegion); + EventManager::post(Region { address, 1 }); } if (ImGui::IsMouseReleased(1) && ImGui::IsItemHovered()) { ImGui::OpenPopup("PatchContextMenu"); diff --git a/source/views/view_pattern.cpp b/source/views/view_pattern.cpp index d7e654cfa..56fb7d1c8 100644 --- a/source/views/view_pattern.cpp +++ b/source/views/view_pattern.cpp @@ -82,23 +82,21 @@ namespace hex { this->m_textEditor.SetLanguageDefinition(PatternLanguage()); this->m_textEditor.SetShowWhitespaces(false); - View::subscribeEvent(Events::ProjectFileStore, [this](auto) { + EventManager::subscribe(this, [this]() { ProjectFile::setPattern(this->m_textEditor.GetText()); }); - View::subscribeEvent(Events::ProjectFileLoad, [this](auto) { + EventManager::subscribe(this, [this]() { this->m_textEditor.SetText(ProjectFile::getPattern()); this->parsePattern(this->m_textEditor.GetText().data()); }); - View::subscribeEvent(Events::AppendPatternLanguageCode, [this](auto userData) { - auto code = std::any_cast(userData); - + EventManager::subscribe(this, [this](std::string code) { this->m_textEditor.InsertText("\n"); this->m_textEditor.InsertText(code); }); - View::subscribeEvent(Events::FileLoaded, [this](auto) { + EventManager::subscribe(this, [this](const std::string &path) { if (this->m_textEditor.GetText().find_first_not_of(" \f\n\r\t\v") != std::string::npos) return; @@ -179,7 +177,7 @@ namespace hex { /* Settings */ { - View::subscribeEvent(Events::SettingsChanged, [this](auto) { + EventManager::subscribe(this, [this]() { auto theme = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color"); if (theme.is_number()) { @@ -204,8 +202,11 @@ namespace hex { ViewPattern::~ViewPattern() { delete this->m_patternLanguageRuntime; - View::unsubscribeEvent(Events::ProjectFileStore); - View::unsubscribeEvent(Events::ProjectFileLoad); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); } void ViewPattern::drawMenu() { @@ -354,7 +355,7 @@ namespace hex { this->clearPatternData(); this->m_textEditor.SetErrorMarkers({ }); this->m_console.clear(); - View::postEvent(Events::PatternChanged); + EventManager::post(); std::thread([this, buffer = std::string(buffer)] { auto result = this->m_patternLanguageRuntime->executeString(SharedData::currentProvider, buffer); @@ -368,7 +369,9 @@ namespace hex { if (result.has_value()) { this->m_patternData = std::move(result.value()); - View::doLater([]{ View::postEvent(Events::PatternChanged); }); + View::doLater([]{ + EventManager::post(); + }); } this->m_evaluatorRunning = false; diff --git a/source/views/view_pattern_data.cpp b/source/views/view_pattern_data.cpp index 1ac17660f..ccda1d767 100644 --- a/source/views/view_pattern_data.cpp +++ b/source/views/view_pattern_data.cpp @@ -8,13 +8,13 @@ namespace hex { ViewPatternData::ViewPatternData(std::vector &patternData) : View("hex.view.pattern_data.name"), m_patternData(patternData) { - this->subscribeEvent(Events::PatternChanged, [this](auto data) { + EventManager::subscribe(this, [this]() { this->m_sortedPatternData.clear(); }); } ViewPatternData::~ViewPatternData() { - this->unsubscribeEvent(Events::PatternChanged); + EventManager::unsubscribe(this); } static bool beginPatternDataTable(prv::Provider* &provider, const std::vector &patterns, std::vector &sortedPatterns) { diff --git a/source/views/view_settings.cpp b/source/views/view_settings.cpp index bb3ed8b90..3a2b9d2b9 100644 --- a/source/views/view_settings.cpp +++ b/source/views/view_settings.cpp @@ -5,8 +5,8 @@ namespace hex { ViewSettings::ViewSettings() : View("hex.view.settings.name") { - View::subscribeEvent(Events::OpenWindow, [this](auto name) { - if (std::any_cast(name) == std::string("hex.view.settings.name")) { + EventManager::subscribe(this, [this](const std::string &name) { + if (name == "hex.view.settings.name") { View::doLater([]{ ImGui::OpenPopup("hex.view.settings.name"_lang); }); this->getWindowOpenState() = true; } @@ -14,7 +14,7 @@ namespace hex { } ViewSettings::~ViewSettings() { - View::unsubscribeEvent(Events::OpenWindow); + EventManager::unsubscribe(this); } void ViewSettings::drawContent() { @@ -27,7 +27,7 @@ namespace hex { ImGui::Separator(); for (auto &[name, callback] : entries) { if (callback(LangEntry(name), ContentRegistry::Settings::getSettingsData()[category][name])) - View::postEvent(Events::SettingsChanged); + EventManager::post(); } ImGui::NewLine(); } diff --git a/source/views/view_strings.cpp b/source/views/view_strings.cpp index fcbaf029b..d059bec4a 100644 --- a/source/views/view_strings.cpp +++ b/source/views/view_strings.cpp @@ -14,7 +14,7 @@ using namespace std::literals::string_literals; namespace hex { ViewStrings::ViewStrings() : View("hex.view.strings.name") { - View::subscribeEvent(Events::DataChanged, [this](auto){ + EventManager::subscribe(this, [this]() { this->m_foundStrings.clear(); }); @@ -22,7 +22,7 @@ namespace hex { } ViewStrings::~ViewStrings() { - View::unsubscribeEvent(Events::DataChanged); + EventManager::unsubscribe(this); } @@ -161,8 +161,7 @@ namespace hex { ImGui::TableNextRow(); 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); + EventManager::post(Region { foundString.offset, foundString.size }); } ImGui::PushID(i + 1); createStringContextMenu(foundString); diff --git a/source/views/view_yara.cpp b/source/views/view_yara.cpp index 44700c8e0..bb78db510 100644 --- a/source/views/view_yara.cpp +++ b/source/views/view_yara.cpp @@ -81,8 +81,7 @@ namespace hex { ImGui::TableNextColumn(); ImGui::PushID(i); if (ImGui::Selectable("match", false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap)) { - Region selectRegion = { u64(address), size_t(size) }; - View::postEvent(Events::SelectionChangeRequest, selectRegion); + EventManager::post(Region { u64(address), size_t(size) }); } ImGui::PopID(); ImGui::SameLine(); diff --git a/source/window.cpp b/source/window.cpp index c1972197e..7ac485157 100644 --- a/source/window.cpp +++ b/source/window.cpp @@ -62,7 +62,7 @@ namespace hex { this->initGLFW(); this->initImGui(); - EventManager::subscribe(Events::SettingsChanged, this, [this](auto) -> std::any { + EventManager::subscribe(this, [this]() { { auto theme = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color"); @@ -102,13 +102,9 @@ namespace hex { if (targetFps.is_number()) this->m_targetFps = targetFps; } - - return { }; }); - EventManager::subscribe(Events::FileLoaded, this, [this](auto userData) -> std::any { - auto path = std::any_cast(userData); - + EventManager::subscribe(this, [this](const std::string &path){ this->m_recentFiles.push_front(path); { @@ -136,20 +132,16 @@ namespace hex { ContentRegistry::Settings::write("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files", recentFilesVector); } - - return { }; }); - EventManager::subscribe(Events::CloseImHex, this, [this](auto) -> std::any { + EventManager::subscribe(this, [this]() { glfwSetWindowShouldClose(this->m_window, true); - - return { }; }); this->initPlugins(); ContentRegistry::Settings::load(); - View::postEvent(Events::SettingsChanged); + EventManager::post(); for (const auto &path : ContentRegistry::Settings::read("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files")) this->m_recentFiles.push_back(path); @@ -168,9 +160,9 @@ namespace hex { this->deinitPlugins(); - EventManager::unsubscribe(Events::SettingsChanged, this); - EventManager::unsubscribe(Events::FileLoaded, this); - EventManager::unsubscribe(Events::CloseImHex, this); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); } void Window::loop() { @@ -417,9 +409,9 @@ namespace hex { ImGui::TextUnformatted("hex.welcome.header.start"_lang); { if (ImGui::BulletHyperlink("hex.welcome.start.open_file"_lang)) - EventManager::post(Events::OpenWindow, "Open File"); + EventManager::post("Open File"); if (ImGui::BulletHyperlink("hex.welcome.start.open_project"_lang)) - EventManager::post(Events::OpenWindow, "Open Project"); + EventManager::post("Open Project"); } ImGui::TableNextRow(ImGuiTableRowFlags_None, rowHeight); @@ -429,7 +421,7 @@ namespace hex { if (!this->m_recentFiles.empty()) { for (auto &path : this->m_recentFiles) { if (ImGui::BulletHyperlink(std::filesystem::path(path).filename().string().c_str())) { - EventManager::post(Events::FileDropped, path.c_str()); + EventManager::post(path); break; } } @@ -495,7 +487,7 @@ namespace hex { ImGui::TextUnformatted("hex.welcome.header.customize"_lang); { if (ImGui::DescriptionButton("hex.welcome.customize.settings.title"_lang, "hex.welcome.customize.settings.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0))) - EventManager::post(Events::OpenWindow, "hex.view.settings.title"); + EventManager::post("hex.view.settings.title"); } ImGui::TableNextRow(ImGuiTableRowFlags_None, rowHeight); ImGui::TableNextColumn(); @@ -638,11 +630,11 @@ namespace hex { if (count != 1) return; - View::postEvent(Events::FileDropped, paths[0]); + EventManager::post(paths[0]); }); glfwSetWindowCloseCallback(this->m_window, [](GLFWwindow *window) { - View::postEvent(Events::WindowClosing, window); + EventManager::post(window); });