1
0
mirror of synced 2025-02-20 04:01:01 +01:00

Improved events API

This commit is contained in:
WerWolv 2021-01-21 10:53:12 +01:00
parent f0ab13ebc3
commit a641f27b7e
18 changed files with 73 additions and 64 deletions

View File

@ -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;

View File

@ -2,8 +2,9 @@
#include <hex.hpp>
#include <vector>
#include <any>
#include <functional>
#include <vector>
namespace hex {
@ -33,13 +34,13 @@ namespace hex {
struct EventHandler {
void *owner;
Events eventType;
std::function<void(const void*)> callback;
std::function<std::any(const std::any&)> callback;
};
class EventManager {
public:
static void post(Events eventType, const void *userData);
static void subscribe(Events eventType, void *owner, std::function<void(const void*)> callback);
static std::vector<std::any> post(Events eventType, const std::any &userData);
static void subscribe(Events eventType, void *owner, std::function<std::any(const std::any&)> callback);
static void unsubscribe(Events eventType, void *sender);
};

View File

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

View File

@ -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<void()> &&function);
static std::vector<std::function<void()>>& getDeferedCalls();
static void postEvent(Events eventType, const void *userData = nullptr);
static std::vector<std::any> 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<void(const void*)> callback);
void subscribeEvent(Events eventType, const std::function<std::any(const std::any&)> &callback);
void subscribeEvent(Events eventType, const std::function<void(const std::any&)> &callback);
void unsubscribeEvent(Events eventType);
void doLater(std::function<void()> &&function);
protected:
void confirmButtons(const char *textLeft, const char *textRight, std::function<void()> leftButtonFn, std::function<void()> rightButtonFn);
void confirmButtons(const char *textLeft, const char *textRight, const std::function<void()> &leftButtonFn, const std::function<void()> &rightButtonFn);
private:
std::string m_viewName;

View File

@ -4,13 +4,16 @@
namespace hex {
void EventManager::post(Events eventType, const void *userData) {
std::vector<std::any> EventManager::post(Events eventType, const std::any &userData) {
std::vector<std::any> 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<void(const void*)> callback) {
void EventManager::subscribe(Events eventType, void *owner, std::function<std::any(const std::any&)> callback) {
for (auto &handler : SharedData::eventHandlers)
if (eventType == handler.eventType && owner == handler.owner)
return;

View File

@ -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) {

View File

@ -20,8 +20,8 @@ namespace hex {
return SharedData::deferredCalls;
}
void View::postEvent(Events eventType, const void *userData) {
EventManager::post(eventType, userData);
std::vector<std::any> 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<void(const void*)> callback) {
void View::subscribeEvent(Events eventType, const std::function<std::any(const std::any&)> &callback) {
EventManager::subscribe(eventType, this, callback);
}
void View::subscribeEvent(Events eventType, const std::function<void(const std::any&)> &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<void()> leftButtonFn, std::function<void()> rightButtonFn) {
void View::confirmButtons(const char *textLeft, const char *textRight, const std::function<void()> &leftButtonFn, const std::function<void()> &rightButtonFn) {
auto width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX(width / 9);
if (ImGui::Button(textLeft, ImVec2(width / 3, 0)))

View File

@ -8,8 +8,8 @@
namespace hex {
ViewBookmarks::ViewBookmarks() : View("Bookmarks") {
View::subscribeEvent(Events::AddBookmark, [this](const void *userData) {
auto bookmark = *reinterpret_cast<const ImHexApi::Bookmarks::Entry*>(userData);
View::subscribeEvent(Events::AddBookmark, [](auto userData) {
auto bookmark = std::any_cast<ImHexApi::Bookmarks::Entry>(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, &region);
View::postEvent(Events::SelectionChangeRequest, region);
ImGui::SameLine(0, 15);
if (ImGui::Button("Remove"))

View File

@ -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<const Region*>(userData);
View::subscribeEvent(Events::RegionSelected, [this](auto userData) {
auto region = std::any_cast<Region>(userData);
auto provider = SharedData::currentProvider;

View File

@ -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<const Region*>(userData);
View::subscribeEvent(Events::RegionSelected, [this](auto userData) {
auto region = std::any_cast<Region>(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);

View File

@ -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<const Region*>(userData);
View::subscribeEvent(Events::RegionSelected, [this](auto userData) {
auto region = std::any_cast<const Region>(userData);
if (this->m_shouldMatchSelection) {
this->m_hashRegion[0] = region.address;

View File

@ -93,15 +93,15 @@ namespace hex {
ImGui::EndTooltip();
};
View::subscribeEvent(Events::FileDropped, [this](const void *userData) {
auto filePath = static_cast<const char*>(userData);
View::subscribeEvent(Events::FileDropped, [this](auto userData) {
auto filePath = std::any_cast<const char*>(userData);
if (filePath != nullptr)
this->openFile(filePath);
});
View::subscribeEvent(Events::SelectionChangeRequest, [this](const void *userData) {
const Region &region = *reinterpret_cast<const Region*>(userData);
View::subscribeEvent(Events::SelectionChangeRequest, [this](auto userData) {
const Region &region = std::any_cast<Region>(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, &region);
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<GLFWwindow*>(static_cast<const GLFWwindow*>(userData));
View::subscribeEvent(Events::WindowClosing, [this](auto userData) {
auto window = std::any_cast<GLFWwindow*>(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();

View File

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

View File

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

View File

@ -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<const char*>(userData);
View::subscribeEvent(Events::AppendPatternLanguageCode, [this](auto userData) {
auto code = std::any_cast<const char*>(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) {

View File

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

View File

@ -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);

View File

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