From 60e7362f4ec3f3b6f11db8d5b512100a4ad39603 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Mon, 22 Jan 2024 12:53:07 +0100 Subject: [PATCH] feat: Allow extra plugin folders to be specified with the `--plugins` cli option --- .../include/hex/api/plugin_manager.hpp | 4 ++- lib/libimhex/include/hex/helpers/logger.hpp | 5 ++-- lib/libimhex/include/hex/plugin.hpp | 6 ++--- lib/libimhex/source/api/plugin_manager.cpp | 23 ++++++++++------- lib/libimhex/source/helpers/logger.cpp | 5 ++++ .../source/content/command_line_interface.cpp | 25 +++++++++++++------ 6 files changed, 45 insertions(+), 23 deletions(-) diff --git a/lib/libimhex/include/hex/api/plugin_manager.hpp b/lib/libimhex/include/hex/api/plugin_manager.hpp index d9776b97b..d0b70a83b 100644 --- a/lib/libimhex/include/hex/api/plugin_manager.hpp +++ b/lib/libimhex/include/hex/api/plugin_manager.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -98,10 +99,11 @@ namespace hex { static bool load(const std::fs::path &pluginFolder); static void unload(); static void reload(); + static void initializeNewPlugins(); static void addPlugin(const std::string &name, PluginFunctions functions); - static std::vector &getPlugins(); + static std::list &getPlugins(); static std::vector &getPluginPaths(); static bool isPluginLoaded(const std::fs::path &path); diff --git a/lib/libimhex/include/hex/helpers/logger.hpp b/lib/libimhex/include/hex/helpers/logger.hpp index 50b4e9531..541cac872 100644 --- a/lib/libimhex/include/hex/helpers/logger.hpp +++ b/lib/libimhex/include/hex/helpers/logger.hpp @@ -28,6 +28,7 @@ namespace hex::log { }; std::vector& getLogEntries(); + void addLogEntry(std::string_view project, std::string_view level, std::string_view message); [[maybe_unused]] void printPrefix(FILE *dest, const fmt::text_style &ts, const std::string &level, const char *projectName); @@ -41,7 +42,7 @@ namespace hex::log { fmt::print(dest, "{}\n", message); fflush(dest); - getLogEntries().push_back({ IMHEX_PROJECT_NAME, level, std::move(message) }); + addLogEntry(IMHEX_PROJECT_NAME, level, std::move(message)); } } @@ -50,7 +51,7 @@ namespace hex::log { #if defined(DEBUG) hex::log::impl::print(fg(fmt::color::light_green) | fmt::emphasis::bold, "[DEBUG]", fmt, args...); #else - impl::getLogEntries().push_back({ IMHEX_PROJECT_NAME, "[DEBUG]", fmt::format(fmt::runtime(fmt), args...) }); + impl::addLogEntry(IMHEX_PROJECT_NAME, "[DEBUG]", fmt::format(fmt::runtime(fmt), args...)); #endif } diff --git a/lib/libimhex/include/hex/plugin.hpp b/lib/libimhex/include/hex/plugin.hpp index d0bc2af57..da50d1236 100644 --- a/lib/libimhex/include/hex/plugin.hpp +++ b/lib/libimhex/include/hex/plugin.hpp @@ -51,7 +51,7 @@ void* PluginSubCommandsFunctionHelper::getSubCommands() { #define IMHEX_LIBRARY_SETUP(name) IMHEX_LIBRARY_SETUP_IMPL(name) #define IMHEX_LIBRARY_SETUP_IMPL(name) \ - namespace { static struct EXIT_HANDLER { ~EXIT_HANDLER() { hex::log::info("Unloaded library '{}'", name); } } HANDLER; } \ + namespace { static struct EXIT_HANDLER { ~EXIT_HANDLER() { hex::log::debug("Unloaded library '{}'", name); } } HANDLER; } \ IMHEX_PLUGIN_VISIBILITY_PREFIX void initializeLibrary(); \ IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getLibraryName() { return name; } \ IMHEX_PLUGIN_VISIBILITY_PREFIX void setImGuiContext(ImGuiContext *ctx) { \ @@ -59,7 +59,7 @@ void* PluginSubCommandsFunctionHelper::getSubCommands() { GImGui = ctx; \ } \ extern "C" [[gnu::visibility("default")]] void WOLV_TOKEN_CONCAT(forceLinkPlugin_, IMHEX_PLUGIN_NAME)() { \ - hex::PluginManager::addPlugin(name, hex::PluginFunctions { \ + hex::PluginManager::addPlugin(name, hex::PluginFunctions { \ nullptr, \ initializeLibrary, \ nullptr, \ @@ -75,7 +75,7 @@ void* PluginSubCommandsFunctionHelper::getSubCommands() { IMHEX_PLUGIN_VISIBILITY_PREFIX void initializeLibrary() #define IMHEX_PLUGIN_SETUP_IMPL(name, author, description) \ - namespace { static struct EXIT_HANDLER { ~EXIT_HANDLER() { hex::log::info("Unloaded plugin '{}'", name); } } HANDLER; } \ + namespace { static struct EXIT_HANDLER { ~EXIT_HANDLER() { hex::log::debug("Unloaded plugin '{}'", name); } } HANDLER; } \ IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginName() { return name; } \ IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginAuthor() { return author; } \ IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginDescription() { return description; } \ diff --git a/lib/libimhex/source/api/plugin_manager.cpp b/lib/libimhex/source/api/plugin_manager.cpp index d2b4e07cc..ea53b95b6 100644 --- a/lib/libimhex/source/api/plugin_manager.cpp +++ b/lib/libimhex/source/api/plugin_manager.cpp @@ -78,6 +78,10 @@ namespace hex { } Plugin::~Plugin() { + if (isLoaded()) { + log::debug("Trying to unload plugin '{}'", getPluginName()); + } + #if defined(OS_WINDOWS) if (m_handle != 0) if (FreeLibrary(HMODULE(m_handle)) == FALSE) { @@ -258,18 +262,19 @@ namespace hex { return true; } + void PluginManager::initializeNewPlugins() { + for (const auto &plugin : getPlugins()) { + if (!plugin.isLoaded()) + hex::unused(plugin.initializePlugin()); + } + } + void PluginManager::unload() { getPluginPaths().clear(); // Unload plugins in reverse order auto &plugins = getPlugins(); - const auto pluginCount = plugins.size(); - for (size_t i = 0; i < pluginCount; i++) { - auto &plugin = plugins[pluginCount - 1 - i]; - if (plugin.isLoaded()) { - log::info("Trying to unload plugin '{}'", plugin.getPluginName()); - } - + while (!plugins.empty()) { plugins.pop_back(); } } @@ -278,8 +283,8 @@ namespace hex { getPlugins().emplace_back(name, functions); } - std::vector &PluginManager::getPlugins() { - static std::vector plugins; + std::list &PluginManager::getPlugins() { + static std::list plugins; return plugins; } diff --git a/lib/libimhex/source/helpers/logger.cpp b/lib/libimhex/source/helpers/logger.cpp index 120c9b855..56a6713ca 100644 --- a/lib/libimhex/source/helpers/logger.cpp +++ b/lib/libimhex/source/helpers/logger.cpp @@ -63,6 +63,11 @@ namespace hex::log::impl { return logEntries; } + void addLogEntry(std::string_view project, std::string_view level, std::string_view message) { + getLogEntries().emplace_back(project.data(), level.data(), message.data()); + } + + void printPrefix(FILE *dest, const fmt::text_style &ts, const std::string &level, const char *projectName) { const auto now = fmt::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now())); diff --git a/plugins/builtin/source/content/command_line_interface.cpp b/plugins/builtin/source/content/command_line_interface.cpp index 199467880..a21daca9b 100644 --- a/plugins/builtin/source/content/command_line_interface.cpp +++ b/plugins/builtin/source/content/command_line_interface.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -109,19 +110,27 @@ namespace hex::plugin::builtin { } void handlePluginsCommand(const std::vector &args) { - hex::unused(args); - hex::log::println("Loaded plugins:"); + if (args.empty()) { + hex::log::println("Loaded plugins:"); - for (const auto &plugin : PluginManager::getPlugins()) { - hex::log::print("- \033[1m{}\033[0m", plugin.getPluginName()); + for (const auto &plugin : PluginManager::getPlugins()) { + hex::log::print("- \033[1m{}\033[0m", plugin.getPluginName()); - hex::log::println(" by {}", plugin.getPluginAuthor()); + hex::log::println(" by {}", plugin.getPluginAuthor()); - hex::log::println(" \033[2;3m{}\033[0m", plugin.getPluginDescription()); + hex::log::println(" \033[2;3m{}\033[0m", plugin.getPluginDescription()); + } + + std::exit(EXIT_SUCCESS); + } else { + TaskManager::doLater([args] { + for (const auto &arg : args) { + PluginManager::load(reinterpret_cast(arg.c_str())); + } + PluginManager::initializeNewPlugins(); + }); } - - std::exit(EXIT_SUCCESS); } void handleHashCommand(const std::vector &args) {