sys: Replace the terrible event manager with a much better one

This commit is contained in:
WerWolv
2021-03-27 11:36:36 +01:00
parent 688ca01b1b
commit d805d976a6
27 changed files with 206 additions and 227 deletions

View File

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

View File

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