mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-01 21:17:44 -05:00
sys: Replace the terrible event manager with a much better one
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -2,48 +2,114 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <any>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
#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<std::any(const std::any&)> callback;
|
||||
struct EventBase {
|
||||
EventBase() noexcept = default;
|
||||
};
|
||||
|
||||
template<typename ... Params>
|
||||
struct Event : public EventBase {
|
||||
using Callback = std::function<void(Params...)>;
|
||||
|
||||
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<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);
|
||||
using EventList = std::list<std::pair<EventId, EventBase*>>;
|
||||
|
||||
template<typename E>
|
||||
[[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<typename E>
|
||||
static void subscribe(void *token, typename E::Callback function) {
|
||||
s_tokenStore.insert(std::make_pair(token, subscribe<E>(function)));
|
||||
}
|
||||
|
||||
static void unsubscribe(EventList::iterator iter) noexcept {
|
||||
s_events.remove(*iter);
|
||||
}
|
||||
|
||||
template<typename E>
|
||||
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<typename E>
|
||||
static void post(auto ... args) noexcept {
|
||||
for (const auto &[id, event] : s_events) {
|
||||
if (id == E::id)
|
||||
(*reinterpret_cast<E *>(event))(args...);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static std::map<void*, EventList::iterator> 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);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user