impr: Speed up initial resource loading and event handling slightly

This commit is contained in:
WerWolv
2025-08-02 01:14:00 +02:00
parent 1e18abc598
commit f73866b86e
12 changed files with 44 additions and 27 deletions

View File

@@ -9,7 +9,6 @@
#include <map>
#include <string_view>
#include <hex/api/imhex_api.hpp>
#include <hex/helpers/logger.hpp>
#include <wolv/types/type_name.hpp>
@@ -90,9 +89,9 @@ EXPORT_MODULE namespace hex {
explicit Event(Callback func) noexcept : m_func(std::move(func)) { }
template<typename E>
void call(Params... params) const {
void call(auto&& ... params) const {
try {
m_func(params...);
m_func(std::forward<decltype(params)>(params)...);
} catch (const std::exception &e) {
log::error("An exception occurred while handling event {}: {}", wolv::type::getTypeName<E>(), e.what());
throw;
@@ -125,8 +124,8 @@ EXPORT_MODULE namespace hex {
* @return Token to unsubscribe from the event
*/
template<impl::EventType E>
static EventList::iterator subscribe(typename E::Callback function) {
std::scoped_lock lock(getEventMutex());
static EventList::iterator subscribe(E::Callback function) {
std::lock_guard lock(getEventMutex());
auto &events = getEvents();
return events.insert({ E::Id, std::make_unique<E>(function) });
@@ -139,15 +138,15 @@ EXPORT_MODULE namespace hex {
* @param function Function to call when the event is posted
*/
template<impl::EventType E>
static void subscribe(void *token, typename E::Callback function) {
std::scoped_lock lock(getEventMutex());
static void subscribe(void *token, E::Callback function) {
std::lock_guard lock(getEventMutex());
if (isAlreadyRegistered(token, E::Id)) {
log::fatal("The token '{}' has already registered the same event ('{}')", token, wolv::type::getTypeName<E>());
return;
}
getTokenStore().insert({ token, subscribe<E>(function) });
getTokenStore().insert({ token, subscribe<E>(std::move(function)) });
}
/**
@@ -155,7 +154,7 @@ EXPORT_MODULE namespace hex {
* @param token Token returned by subscribe
*/
static void unsubscribe(const EventList::iterator &token) noexcept {
std::scoped_lock lock(getEventMutex());
std::lock_guard lock(getEventMutex());
getEvents().erase(token);
}
@@ -167,7 +166,7 @@ EXPORT_MODULE namespace hex {
*/
template<impl::EventType E>
static void unsubscribe(void *token) noexcept {
std::scoped_lock lock(getEventMutex());
std::lock_guard lock(getEventMutex());
unsubscribe(token, E::Id);
}
@@ -179,9 +178,9 @@ EXPORT_MODULE namespace hex {
*/
template<impl::EventType E>
static void post(auto && ...args) {
std::scoped_lock lock(getEventMutex());
std::lock_guard lock(getEventMutex());
auto [begin, end] = getEvents().equal_range(E::Id);
const auto &[begin, end] = getEvents().equal_range(E::Id);
for (auto it = begin; it != end; ++it) {
const auto &[id, event] = *it;
(*static_cast<E *const>(event.get())).template call<E>(std::forward<decltype(args)>(args)...);
@@ -197,7 +196,7 @@ EXPORT_MODULE namespace hex {
* @brief Unsubscribe all subscribers from all events
*/
static void clear() noexcept {
std::scoped_lock lock(getEventMutex());
std::lock_guard lock(getEventMutex());
getEvents().clear();
getTokenStore().clear();

View File

@@ -4,6 +4,7 @@
/* Forward declarations */
struct GLFWwindow;
using ImGuiID = unsigned int;
namespace hex { class View; }
/* GUI events definitions */

View File

@@ -1,5 +1,6 @@
#pragma once
#include <hex/api/imhex_api.hpp>
#include <hex/api/event_manager.hpp>
#include <hex/helpers/patches.hpp>

View File

@@ -1,6 +1,7 @@
#pragma once
#include <hex/api/event_manager.hpp>
#include <hex/helpers/semantic_version.hpp>
struct ImGuiTestEngine;

View File

@@ -5,6 +5,11 @@
/* Provider events definitions */
namespace hex {
namespace prv {
class Provider;
}
/**
* @brief Called when the provider is created.
* This event is responsible for (optionally) initializing the provider and calling EventProviderOpened

View File

@@ -1,6 +1,7 @@
#pragma once
#include <hex.hpp>
#include <hex/api/imhex_api.hpp>
#include <hex/api/event_manager.hpp>
/* Forward declarations */

View File

@@ -873,16 +873,16 @@ namespace hex {
LocalizationManager::impl::setFallbackLanguage(code.get<std::string>());
}
impl::s_languages->insert({ code.get<std::string>(), hex::format("{} ({})", language.get<std::string>(), country.get<std::string>()) });
impl::s_languages->emplace(code.get<std::string>(), hex::format("{} ({})", language.get<std::string>(), country.get<std::string>()));
std::map<std::string, std::string> translationDefinitions;
for (auto &[key, value] : translations.items()) {
if (!value.is_string()) {
if (!value.is_string()) [[unlikely]] {
log::error("Localization data has invalid fields!");
continue;
}
translationDefinitions[key] = value.get<std::string>();
translationDefinitions.emplace(key, value.get<std::string>());
}
(*impl::s_definitions)[code.get<std::string>()].emplace_back(std::move(translationDefinitions));

View File

@@ -1086,21 +1086,21 @@ namespace hex {
return;
}
impl::s_fonts->emplace_back(MergeFont {
impl::s_fonts->emplace_back(
wolv::util::toUTF8String(path.filename()),
fontFile.readVector(),
offset,
fontSizeMultiplier
});
);
}
void registerMergeFont(const std::string &name, const std::span<const u8> &data, Offset offset, std::optional<float> fontSizeMultiplier) {
impl::s_fonts->emplace_back(MergeFont {
impl::s_fonts->emplace_back(
name,
{ data.begin(), data.end() },
std::vector<u8> { data.begin(), data.end() },
offset,
fontSizeMultiplier
});
);
}
void registerFont(const Font& font) {

View File

@@ -658,7 +658,7 @@ namespace hex {
static std::map<std::fs::path, std::string> s_fonts;
extern "C" void registerFont(const char *fontName, const char *fontPath) {
s_fonts[fontPath] = fontName;
s_fonts.emplace(fontPath, fontName);
}
const std::map<std::fs::path, std::string>& getFonts() {

View File

@@ -91,16 +91,23 @@
for (CFIndex i = 0; i < count; i++) {
CFStringRef fontName = (CFStringRef)CFArrayGetValueAtIndex(fontDescriptors, i);
// Get font path
CFDictionaryRef attributes = (__bridge CFDictionaryRef)@{ (__bridge NSString *)kCTFontNameAttribute : (__bridge NSString *)fontName };
// Get font path - skip fonts without valid URLs
CFDictionaryRef attributes = (__bridge CFDictionaryRef)@{ (__bridge NSString *)kCTFontFamilyNameAttribute : (__bridge NSString *)fontName };
CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes(attributes);
CFURLRef fontURL = CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute);
CFStringRef fontPath = CFURLCopyFileSystemPath(fontURL, kCFURLPOSIXPathStyle);
registerFont([(__bridge NSString *)fontName UTF8String], [(__bridge NSString *)fontPath UTF8String]);
if (fontURL != NULL) {
CFStringRef fontPath = CFURLCopyFileSystemPath(fontURL, kCFURLPOSIXPathStyle);
if (fontPath != NULL) {
registerFont([(__bridge NSString *)fontName UTF8String], [(__bridge NSString *)fontPath UTF8String]);
CFRelease(fontPath);
}
CFRelease(fontURL);
}
CFRelease(descriptor);
CFRelease(fontURL);
}
CFRelease(fontDescriptors);

View File

@@ -1,5 +1,6 @@
#pragma once
#include <hex/api/imhex_api.hpp>
#include <hex/providers/provider.hpp>
#include <hex/api/events/events_provider.hpp>

View File

@@ -1,3 +1,4 @@
#include <hex/api/imhex_api.hpp>
#include <hex/api/content_registry.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/api/events/events_provider.hpp>