2020-12-22 18:10:01 +01:00
|
|
|
#pragma once
|
|
|
|
|
2021-01-11 21:11:03 +01:00
|
|
|
#include <hex.hpp>
|
|
|
|
|
2024-03-26 19:46:25 +01:00
|
|
|
#include <algorithm>
|
|
|
|
#include <functional>
|
2021-03-27 11:36:36 +01:00
|
|
|
#include <list>
|
2024-02-26 20:51:08 +01:00
|
|
|
#include <mutex>
|
2021-03-27 11:36:36 +01:00
|
|
|
#include <map>
|
|
|
|
#include <string_view>
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2021-03-27 11:36:36 +01:00
|
|
|
#include <hex/api/imhex_api.hpp>
|
2023-05-02 20:35:30 +02:00
|
|
|
#include <hex/helpers/logger.hpp>
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2023-05-02 20:35:30 +02:00
|
|
|
#include <wolv/types/type_name.hpp>
|
|
|
|
|
2023-12-08 10:29:44 +01:00
|
|
|
#define EVENT_DEF_IMPL(event_name, event_name_string, should_log, ...) \
|
|
|
|
struct event_name final : public hex::impl::Event<__VA_ARGS__> { \
|
|
|
|
constexpr static auto Id = [] { return hex::impl::EventId(event_name_string); }(); \
|
|
|
|
constexpr static auto ShouldLog = (should_log); \
|
|
|
|
explicit event_name(Callback func) noexcept : Event(std::move(func)) { } \
|
|
|
|
\
|
|
|
|
static EventManager::EventList::iterator subscribe(Event::Callback function) { return EventManager::subscribe<event_name>(function); } \
|
|
|
|
static void subscribe(void *token, Event::Callback function) { EventManager::subscribe<event_name>(token, function); } \
|
|
|
|
static void unsubscribe(const EventManager::EventList::iterator &token) noexcept { EventManager::unsubscribe(token); } \
|
|
|
|
static void unsubscribe(void *token) noexcept { EventManager::unsubscribe<event_name>(token); } \
|
2024-03-01 18:21:15 +01:00
|
|
|
static void post(auto &&...args) { EventManager::post<event_name>(std::forward<decltype(args)>(args)...); } \
|
2023-12-08 10:29:44 +01:00
|
|
|
};
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2023-06-10 15:08:56 +02:00
|
|
|
#define EVENT_DEF(event_name, ...) EVENT_DEF_IMPL(event_name, #event_name, true, __VA_ARGS__)
|
|
|
|
#define EVENT_DEF_NO_LOG(event_name, ...) EVENT_DEF_IMPL(event_name, #event_name, false, __VA_ARGS__)
|
2023-05-02 20:35:30 +02:00
|
|
|
|
2023-08-06 21:33:15 +02:00
|
|
|
|
|
|
|
/* Forward declarations */
|
2022-03-27 00:01:28 +01:00
|
|
|
struct GLFWwindow;
|
2023-12-13 23:03:39 +01:00
|
|
|
namespace hex {
|
|
|
|
class Achievement;
|
|
|
|
class View;
|
|
|
|
}
|
2023-08-06 21:33:15 +02:00
|
|
|
|
2024-01-31 11:26:22 +01:00
|
|
|
namespace pl::ptrn { class Pattern; }
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2021-03-27 11:36:36 +01:00
|
|
|
namespace hex {
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
namespace impl {
|
|
|
|
|
|
|
|
class EventId {
|
|
|
|
public:
|
2023-06-10 15:08:56 +02:00
|
|
|
explicit constexpr EventId(const char *eventName) {
|
2023-12-19 13:10:25 +01:00
|
|
|
m_hash = 0x811C'9DC5;
|
2024-01-30 22:00:42 +01:00
|
|
|
for (const char c : std::string_view(eventName)) {
|
2023-12-19 13:10:25 +01:00
|
|
|
m_hash = (m_hash >> 5) | (m_hash << 27);
|
|
|
|
m_hash ^= c;
|
2023-03-21 15:33:43 +01:00
|
|
|
}
|
2021-03-27 11:36:36 +01:00
|
|
|
}
|
2021-01-11 20:31:40 +01:00
|
|
|
|
2023-08-26 12:54:52 +02:00
|
|
|
constexpr bool operator==(const EventId &other) const {
|
2023-12-19 13:10:25 +01:00
|
|
|
return m_hash == other.m_hash;
|
2023-08-26 12:54:52 +02:00
|
|
|
}
|
2021-01-11 21:11:03 +01:00
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
private:
|
|
|
|
u32 m_hash;
|
|
|
|
};
|
2021-01-11 21:11:03 +01:00
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
struct EventBase {
|
|
|
|
EventBase() noexcept = default;
|
2024-01-30 22:00:42 +01:00
|
|
|
virtual ~EventBase() = default;
|
2023-03-21 15:33:43 +01:00
|
|
|
};
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
template<typename... Params>
|
2023-11-10 20:47:08 +01:00
|
|
|
struct Event : EventBase {
|
2023-03-21 15:33:43 +01:00
|
|
|
using Callback = std::function<void(Params...)>;
|
2021-03-27 11:36:36 +01:00
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
explicit Event(Callback func) noexcept : m_func(std::move(func)) { }
|
2021-03-27 11:36:36 +01:00
|
|
|
|
2024-03-01 18:21:15 +01:00
|
|
|
void operator()(std::string_view eventName, Params... params) const {
|
2024-02-18 02:12:57 +01:00
|
|
|
try {
|
|
|
|
m_func(params...);
|
|
|
|
} catch (const std::exception &e) {
|
2024-03-01 18:21:15 +01:00
|
|
|
log::error("An exception occurred while handling event {}: {}", eventName, e.what());
|
|
|
|
throw;
|
2024-02-18 02:12:57 +01:00
|
|
|
}
|
2023-03-21 15:33:43 +01:00
|
|
|
}
|
2021-03-27 11:36:36 +01:00
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
private:
|
|
|
|
Callback m_func;
|
|
|
|
};
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2023-08-26 12:54:52 +02:00
|
|
|
template<typename T>
|
|
|
|
concept EventType = std::derived_from<T, EventBase>;
|
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The EventManager allows subscribing to and posting events to different parts of the program.
|
|
|
|
* To create a new event, use the EVENT_DEF macro. This will create a new event type with the given name and parameters
|
|
|
|
*/
|
2020-12-22 18:10:01 +01:00
|
|
|
class EventManager {
|
|
|
|
public:
|
2023-06-11 10:47:17 +02:00
|
|
|
using EventList = std::list<std::pair<impl::EventId, std::unique_ptr<impl::EventBase>>>;
|
2023-03-21 15:33:43 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Subscribes to an event
|
|
|
|
* @tparam E Event
|
|
|
|
* @param function Function to call when the event is posted
|
|
|
|
* @return Token to unsubscribe from the event
|
|
|
|
*/
|
2023-08-26 12:54:52 +02:00
|
|
|
template<impl::EventType E>
|
2022-02-08 18:38:54 +01:00
|
|
|
static EventList::iterator subscribe(typename E::Callback function) {
|
2023-11-04 23:16:38 +01:00
|
|
|
std::scoped_lock lock(getEventMutex());
|
|
|
|
|
2023-07-26 13:50:51 +02:00
|
|
|
auto &events = getEvents();
|
|
|
|
return events.insert(events.end(), std::make_pair(E::Id, std::make_unique<E>(function)));
|
2021-03-27 11:36:36 +01:00
|
|
|
}
|
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
/**
|
|
|
|
* @brief Subscribes to an event
|
|
|
|
* @tparam E Event
|
|
|
|
* @param token Unique token to register the event to. Later required to unsubscribe again
|
|
|
|
* @param function Function to call when the event is posted
|
|
|
|
*/
|
2023-08-26 12:54:52 +02:00
|
|
|
template<impl::EventType E>
|
2021-03-27 11:36:36 +01:00
|
|
|
static void subscribe(void *token, typename E::Callback function) {
|
2023-11-04 23:16:38 +01:00
|
|
|
std::scoped_lock lock(getEventMutex());
|
|
|
|
|
fix: Event unsubscribe not working correcetly when using same key for multiple events (#1309)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->
### Problem description
<!-- Describe the bug that you fixed/feature request that you
implemented, or link to an existing issue describing it -->
Fixed possible bug of `EventManager::unsubscribe`
`std::map` only allows unique key, but the same token can subscribe to
multiple events.
https://github.com/WerWolv/ImHex/blob/1a2a926b772f32d4f5e4c723c48e0e6e65a16b0a/lib/libimhex/include/hex/api/event.hpp#L104-L107
If the previous token has already subscribed to an event, then when
subscribing again, `getTokenStore().insert` will not do anything
(Because its type is `std::map`)
https://github.com/WerWolv/ImHex/blob/1a2a926b772f32d4f5e4c723c48e0e6e65a16b0a/lib/libimhex/include/hex/api/event.hpp#L122-L134
At this point in `unsubscribe`, the `iter` may not be able to find the
correct event and erase it
### Implementation description
<!-- Explain what you did to correct the problem -->
Change `tokenStore` to `std::multimap` instead of `std::map`, which
cannot unsubscribe multiple events correctly
### Screenshots
<!-- If your change is visual, take a screenshot showing it. Ideally,
make before/after sceenshots -->
### Additional things
<!-- Anything else you would like to say -->
2023-10-07 23:35:35 +02:00
|
|
|
if (getTokenStore().contains(token)) {
|
|
|
|
auto&& [begin, end] = getTokenStore().equal_range(token);
|
2024-01-30 22:00:42 +01:00
|
|
|
const auto eventRegistered = std::any_of(begin, end, [&](auto &item) {
|
fix: Event unsubscribe not working correcetly when using same key for multiple events (#1309)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->
### Problem description
<!-- Describe the bug that you fixed/feature request that you
implemented, or link to an existing issue describing it -->
Fixed possible bug of `EventManager::unsubscribe`
`std::map` only allows unique key, but the same token can subscribe to
multiple events.
https://github.com/WerWolv/ImHex/blob/1a2a926b772f32d4f5e4c723c48e0e6e65a16b0a/lib/libimhex/include/hex/api/event.hpp#L104-L107
If the previous token has already subscribed to an event, then when
subscribing again, `getTokenStore().insert` will not do anything
(Because its type is `std::map`)
https://github.com/WerWolv/ImHex/blob/1a2a926b772f32d4f5e4c723c48e0e6e65a16b0a/lib/libimhex/include/hex/api/event.hpp#L122-L134
At this point in `unsubscribe`, the `iter` may not be able to find the
correct event and erase it
### Implementation description
<!-- Explain what you did to correct the problem -->
Change `tokenStore` to `std::multimap` instead of `std::map`, which
cannot unsubscribe multiple events correctly
### Screenshots
<!-- If your change is visual, take a screenshot showing it. Ideally,
make before/after sceenshots -->
### Additional things
<!-- Anything else you would like to say -->
2023-10-07 23:35:35 +02:00
|
|
|
return item.second->first == E::Id;
|
|
|
|
});
|
|
|
|
if (eventRegistered) {
|
|
|
|
log::fatal("The token '{}' has already registered the same event ('{}')", token, wolv::type::getTypeName<E>());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-04 23:16:38 +01:00
|
|
|
getTokenStore().insert({ token, subscribe<E>(function) });
|
2021-03-27 11:36:36 +01:00
|
|
|
}
|
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
/**
|
|
|
|
* @brief Unsubscribes from an event
|
|
|
|
* @param token Token returned by subscribe
|
|
|
|
*/
|
|
|
|
static void unsubscribe(const EventList::iterator &token) noexcept {
|
2023-11-04 23:16:38 +01:00
|
|
|
std::scoped_lock lock(getEventMutex());
|
|
|
|
|
2023-07-26 13:50:51 +02:00
|
|
|
getEvents().erase(token);
|
2021-03-27 11:36:36 +01:00
|
|
|
}
|
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
/**
|
|
|
|
* @brief Unsubscribes from an event
|
|
|
|
* @tparam E Event
|
|
|
|
* @param token Token passed to subscribe
|
|
|
|
*/
|
2023-08-26 12:54:52 +02:00
|
|
|
template<impl::EventType E>
|
2021-03-27 11:36:36 +01:00
|
|
|
static void unsubscribe(void *token) noexcept {
|
2023-11-04 23:16:38 +01:00
|
|
|
std::scoped_lock lock(getEventMutex());
|
|
|
|
|
2023-07-26 13:50:51 +02:00
|
|
|
auto &tokenStore = getTokenStore();
|
|
|
|
auto iter = std::find_if(tokenStore.begin(), tokenStore.end(), [&](auto &item) {
|
2023-05-02 20:35:30 +02:00
|
|
|
return item.first == token && item.second->first == E::Id;
|
2021-03-27 11:36:36 +01:00
|
|
|
});
|
|
|
|
|
2023-07-26 13:50:51 +02:00
|
|
|
if (iter != tokenStore.end()) {
|
|
|
|
getEvents().remove(*iter->second);
|
|
|
|
tokenStore.erase(iter);
|
2021-03-27 11:36:36 +01:00
|
|
|
}
|
2023-01-01 01:01:24 +01:00
|
|
|
|
2021-03-27 11:36:36 +01:00
|
|
|
}
|
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
/**
|
|
|
|
* @brief Posts an event to all subscribers of it
|
|
|
|
* @tparam E Event
|
|
|
|
* @param args Arguments to pass to the event
|
|
|
|
*/
|
2023-08-26 12:54:52 +02:00
|
|
|
template<impl::EventType E>
|
2024-03-01 18:21:15 +01:00
|
|
|
static void post(auto && ...args) {
|
2023-11-04 23:16:38 +01:00
|
|
|
std::scoped_lock lock(getEventMutex());
|
|
|
|
|
2023-07-26 13:50:51 +02:00
|
|
|
for (const auto &[id, event] : getEvents()) {
|
2023-05-02 20:35:30 +02:00
|
|
|
if (id == E::Id) {
|
2024-03-01 18:21:15 +01:00
|
|
|
(*static_cast<E *const>(event.get()))(wolv::type::getTypeName<E>(), std::forward<decltype(args)>(args)...);
|
2023-05-02 20:35:30 +02:00
|
|
|
}
|
2021-03-27 11:36:36 +01:00
|
|
|
}
|
2023-05-02 20:35:30 +02:00
|
|
|
|
|
|
|
#if defined (DEBUG)
|
|
|
|
if (E::ShouldLog)
|
|
|
|
log::debug("Event posted: '{}'", wolv::type::getTypeName<E>());
|
|
|
|
#endif
|
2021-03-27 11:36:36 +01:00
|
|
|
}
|
2022-01-24 20:53:17 +01:00
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
/**
|
|
|
|
* @brief Unsubscribe all subscribers from all events
|
|
|
|
*/
|
2022-08-03 10:45:50 +02:00
|
|
|
static void clear() noexcept {
|
2023-11-04 23:16:38 +01:00
|
|
|
std::scoped_lock lock(getEventMutex());
|
|
|
|
|
2023-07-26 13:50:51 +02:00
|
|
|
getEvents().clear();
|
|
|
|
getTokenStore().clear();
|
2022-08-03 10:45:50 +02:00
|
|
|
}
|
|
|
|
|
2021-03-27 11:36:36 +01:00
|
|
|
private:
|
fix: Event unsubscribe not working correcetly when using same key for multiple events (#1309)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->
### Problem description
<!-- Describe the bug that you fixed/feature request that you
implemented, or link to an existing issue describing it -->
Fixed possible bug of `EventManager::unsubscribe`
`std::map` only allows unique key, but the same token can subscribe to
multiple events.
https://github.com/WerWolv/ImHex/blob/1a2a926b772f32d4f5e4c723c48e0e6e65a16b0a/lib/libimhex/include/hex/api/event.hpp#L104-L107
If the previous token has already subscribed to an event, then when
subscribing again, `getTokenStore().insert` will not do anything
(Because its type is `std::map`)
https://github.com/WerWolv/ImHex/blob/1a2a926b772f32d4f5e4c723c48e0e6e65a16b0a/lib/libimhex/include/hex/api/event.hpp#L122-L134
At this point in `unsubscribe`, the `iter` may not be able to find the
correct event and erase it
### Implementation description
<!-- Explain what you did to correct the problem -->
Change `tokenStore` to `std::multimap` instead of `std::map`, which
cannot unsubscribe multiple events correctly
### Screenshots
<!-- If your change is visual, take a screenshot showing it. Ideally,
make before/after sceenshots -->
### Additional things
<!-- Anything else you would like to say -->
2023-10-07 23:35:35 +02:00
|
|
|
static std::multimap<void *, EventList::iterator>& getTokenStore();
|
2023-07-26 13:50:51 +02:00
|
|
|
static EventList& getEvents();
|
2023-11-04 23:16:38 +01:00
|
|
|
static std::recursive_mutex& getEventMutex();
|
2020-12-22 18:10:01 +01:00
|
|
|
};
|
|
|
|
|
2021-03-27 11:36:36 +01:00
|
|
|
/* Default Events */
|
2023-06-01 18:35:41 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called when Imhex finished startup, and will enter the main window rendering loop
|
|
|
|
*/
|
|
|
|
EVENT_DEF(EventImHexStartupFinished);
|
|
|
|
|
2022-03-04 11:36:37 +01:00
|
|
|
EVENT_DEF(EventFileLoaded, std::fs::path);
|
2024-01-25 22:49:56 +01:00
|
|
|
EVENT_DEF(EventDataChanged, prv::Provider *);
|
2022-02-04 00:29:47 +01:00
|
|
|
EVENT_DEF(EventHighlightingChanged);
|
2022-01-24 20:53:17 +01:00
|
|
|
EVENT_DEF(EventWindowClosing, GLFWwindow *);
|
2022-11-08 21:43:22 +01:00
|
|
|
EVENT_DEF(EventRegionSelected, ImHexApi::HexEditor::ProviderRegion);
|
2021-08-17 13:41:44 +02:00
|
|
|
EVENT_DEF(EventAbnormalTermination, int);
|
2023-05-22 12:00:35 +02:00
|
|
|
EVENT_DEF(EventThemeChanged);
|
2021-09-16 22:23:51 +02:00
|
|
|
EVENT_DEF(EventOSThemeChanged);
|
2024-02-03 23:56:08 +01:00
|
|
|
EVENT_DEF(EventWindowFocused, bool);
|
2023-05-05 22:02:18 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called when the provider is created.
|
|
|
|
* This event is responsible for (optionally) initializing the provider and calling EventProviderOpened
|
|
|
|
* (although the event can also be called manually without problem)
|
|
|
|
*/
|
2022-01-24 20:53:17 +01:00
|
|
|
EVENT_DEF(EventProviderCreated, prv::Provider *);
|
2022-02-01 18:09:40 +01:00
|
|
|
EVENT_DEF(EventProviderChanged, prv::Provider *, prv::Provider *);
|
2023-05-05 22:02:18 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called as a continuation of EventProviderCreated
|
|
|
|
* this event is normally called immediately after EventProviderCreated successfully initialized the provider.
|
|
|
|
* If no initialization (Provider::skipLoadInterface() has been set), this event should be called manually
|
|
|
|
* If skipLoadInterface failed, this event is not called
|
|
|
|
*
|
|
|
|
* @note this is not related to Provider::open()
|
|
|
|
*/
|
2022-08-08 21:23:52 +02:00
|
|
|
EVENT_DEF(EventProviderOpened, prv::Provider *);
|
|
|
|
EVENT_DEF(EventProviderClosing, prv::Provider *, bool *);
|
|
|
|
EVENT_DEF(EventProviderClosed, prv::Provider *);
|
2022-07-30 22:01:49 +02:00
|
|
|
EVENT_DEF(EventProviderDeleted, prv::Provider *);
|
2023-04-06 17:36:28 +02:00
|
|
|
EVENT_DEF(EventProviderSaved, prv::Provider *);
|
2022-02-15 22:50:04 +01:00
|
|
|
EVENT_DEF(EventWindowInitialized);
|
2024-01-28 22:14:59 +01:00
|
|
|
EVENT_DEF(EventWindowDeinitializing, GLFWwindow *);
|
2023-04-06 17:36:28 +02:00
|
|
|
EVENT_DEF(EventBookmarkCreated, ImHexApi::Bookmarks::Entry&);
|
|
|
|
EVENT_DEF(EventPatchCreated, u64, u8, u8);
|
feat: Added hex::group attribute and various fixes (#1302)
As discussed (many times) on Discord, does the same as the new favorite
tag, but instead allows you to add multiple groups.
Initially, this would cause some insane issues with draw/reset
(apparantly) fighting eachother in the pattern drawer. After a lot of
trial and error, I decided to rewrite the flow that is responsible for
calling reset. Now evaluating patterns is the one to decide when the
reset happens, not the core "game"-loop.
To make sure that draw and reset can never happen at the same time, the
mutex originally used for the favorites has been repurposed. Due to the
restructuring, the mutex in the favorite-task is no longer needed, as
that will only ever kick-off after reset is called and if there are
actually patterns, which can never line up to be accessed on different
threads at the same time.
Last but not least, I noticed that hard crashes could result in your
config file getting overridden. I added a check to prevent that.
Last I issue I can see is that if you use an excessive amount of
favorites/groups, a crash can still happen, but it only happens when you
close the program (occasionally, but unpredictable). Before, this would
happen if you ran the evaluation a second time. I boiled the cause of
the crash down to these lines of code in evaluator.cpp >
patternDestroyed:
```cpp
if (pattern->isPatternLocal()) {
if (auto it = this->m_patternLocalStorage.find(pattern->getHeapAddress()); it != this->m_patternLocalStorage.end()) {
auto &[key, data] = *it;
data.referenceCount--;
if (data.referenceCount == 0)
this->m_patternLocalStorage.erase(it);
} else if (!this->m_evaluated) {
err::E0001.throwError(fmt::format("Double free of variable named '{}'.", pattern->getVariableName()));
}
}
```
Specifically, trying to access the `*it` is the reason for the crash
(this was also the cause of the crashes before my fixes, but then during
evaluation).
I'm suspecting the root cause is somewhere in the `.clone` methods of
the patterns. I'd say that for now a crash when closing the program is
more acceptable than during evaluation (which can even happen if you use
favorites).
2023-09-16 13:09:59 +02:00
|
|
|
EVENT_DEF(EventPatternEvaluating);
|
2023-04-06 17:36:28 +02:00
|
|
|
EVENT_DEF(EventPatternExecuted, const std::string&);
|
|
|
|
EVENT_DEF(EventPatternEditorChanged, const std::string&);
|
|
|
|
EVENT_DEF(EventStoreContentDownloaded, const std::fs::path&);
|
|
|
|
EVENT_DEF(EventStoreContentRemoved, const std::fs::path&);
|
2023-04-17 16:18:48 +02:00
|
|
|
EVENT_DEF(EventImHexClosing);
|
2023-08-06 21:33:15 +02:00
|
|
|
EVENT_DEF(EventAchievementUnlocked, const Achievement&);
|
2023-12-14 13:50:26 +01:00
|
|
|
EVENT_DEF(EventSearchBoxClicked, u32);
|
2023-12-13 23:03:39 +01:00
|
|
|
EVENT_DEF(EventViewOpened, View*);
|
2024-01-21 18:39:51 +01:00
|
|
|
EVENT_DEF(EventFirstLaunch);
|
2021-03-27 11:36:36 +01:00
|
|
|
|
2024-01-10 23:46:50 +01:00
|
|
|
EVENT_DEF(EventFileDragged, bool);
|
|
|
|
EVENT_DEF(EventFileDropped, std::fs::path);
|
|
|
|
|
2023-11-25 12:43:48 +01:00
|
|
|
EVENT_DEF(EventProviderDataModified, prv::Provider *, u64, u64, const u8*);
|
|
|
|
EVENT_DEF(EventProviderDataInserted, prv::Provider *, u64, u64);
|
|
|
|
EVENT_DEF(EventProviderDataRemoved, prv::Provider *, u64, u64);
|
2024-06-12 19:51:12 +02:00
|
|
|
EVENT_DEF(EventProviderDirtied, prv::Provider *);
|
2023-11-25 12:43:48 +01:00
|
|
|
|
2023-05-27 16:59:30 +02:00
|
|
|
/**
|
|
|
|
* @brief Called when a project has been loaded
|
|
|
|
*/
|
|
|
|
EVENT_DEF(EventProjectOpened);
|
|
|
|
|
2023-05-02 20:35:30 +02:00
|
|
|
EVENT_DEF_NO_LOG(EventFrameBegin);
|
|
|
|
EVENT_DEF_NO_LOG(EventFrameEnd);
|
|
|
|
EVENT_DEF_NO_LOG(EventSetTaskBarIconState, u32, u32, u32);
|
2024-06-24 22:53:25 +02:00
|
|
|
EVENT_DEF_NO_LOG(EventImGuiElementRendered, ImGuiID, const std::array<float, 4>&)
|
2023-05-02 20:35:30 +02:00
|
|
|
|
2023-11-28 00:19:42 +01:00
|
|
|
EVENT_DEF(RequestAddInitTask, std::string, bool, std::function<bool()>);
|
|
|
|
EVENT_DEF(RequestAddExitTask, std::string, std::function<bool()>);
|
2021-03-27 11:36:36 +01:00
|
|
|
EVENT_DEF(RequestOpenWindow, std::string);
|
2024-01-31 11:26:22 +01:00
|
|
|
EVENT_DEF(RequestHexEditorSelectionChange, Region);
|
|
|
|
EVENT_DEF(RequestPatternEditorSelectionChange, u32, u32);
|
|
|
|
EVENT_DEF(RequestJumpToPattern, const pl::ptrn::Pattern*);
|
2023-11-25 12:43:48 +01:00
|
|
|
EVENT_DEF(RequestAddBookmark, Region, std::string, std::string, color_t, u64*);
|
|
|
|
EVENT_DEF(RequestRemoveBookmark, u64);
|
2021-09-26 21:18:25 +02:00
|
|
|
EVENT_DEF(RequestSetPatternLanguageCode, std::string);
|
2023-12-13 23:03:39 +01:00
|
|
|
EVENT_DEF(RequestRunPatternCode);
|
2023-04-01 11:18:52 +02:00
|
|
|
EVENT_DEF(RequestLoadPatternLanguageFile, std::fs::path);
|
|
|
|
EVENT_DEF(RequestSavePatternLanguageFile, std::fs::path);
|
2023-01-07 17:31:22 +01:00
|
|
|
EVENT_DEF(RequestUpdateWindowTitle);
|
2021-08-21 13:53:50 +02:00
|
|
|
EVENT_DEF(RequestCloseImHex, bool);
|
2022-08-16 11:48:37 +02:00
|
|
|
EVENT_DEF(RequestRestartImHex);
|
2022-03-04 11:36:37 +01:00
|
|
|
EVENT_DEF(RequestOpenFile, std::fs::path);
|
2022-12-29 19:26:00 +01:00
|
|
|
EVENT_DEF(RequestChangeTheme, std::string);
|
2021-09-26 21:18:25 +02:00
|
|
|
EVENT_DEF(RequestOpenPopup, std::string);
|
2024-01-11 20:11:22 +01:00
|
|
|
EVENT_DEF(RequestAddVirtualFile, std::fs::path, std::vector<u8>, Region);
|
2023-05-05 22:02:18 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Creates a provider from it's unlocalized name, and add it to the provider list
|
|
|
|
*/
|
2023-06-08 17:02:16 +02:00
|
|
|
EVENT_DEF(RequestCreateProvider, std::string, bool, bool, hex::prv::Provider **);
|
2023-02-16 18:06:40 +01:00
|
|
|
EVENT_DEF(RequestInitThemeHandlers);
|
2021-08-21 13:53:50 +02:00
|
|
|
|
2023-07-13 14:08:23 +02:00
|
|
|
/**
|
|
|
|
* @brief Send an event to the main Imhex instance
|
|
|
|
*/
|
|
|
|
EVENT_DEF(SendMessageToMainInstance, const std::string, const std::vector<u8>&);
|
2023-08-26 01:47:44 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Move the data from all PerProvider instances from one provider to another.
|
|
|
|
* The 'from' provider should not have any per provider data after this, and should be immediately deleted
|
|
|
|
*/
|
|
|
|
EVENT_DEF(MovePerProviderData, prv::Provider *, prv::Provider *);
|
2024-02-26 20:51:08 +01:00
|
|
|
|
2024-03-01 18:21:15 +01:00
|
|
|
/**
|
|
|
|
* Called when ImHex managed to catch an error in a general try/catch to prevent/recover from a crash
|
|
|
|
*/
|
|
|
|
EVENT_DEF(EventCrashRecovered, const std::exception &);
|
2020-12-22 18:10:01 +01:00
|
|
|
}
|