1
0
mirror of synced 2024-12-01 02:37:18 +01:00

feat: Allow extra plugin folders to be specified with the --plugins cli option

This commit is contained in:
WerWolv 2024-01-22 12:53:07 +01:00
parent f2bab005d0
commit 60e7362f4e
6 changed files with 45 additions and 23 deletions

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <functional> #include <functional>
#include <list>
#include <span> #include <span>
#include <string> #include <string>
@ -98,10 +99,11 @@ namespace hex {
static bool load(const std::fs::path &pluginFolder); static bool load(const std::fs::path &pluginFolder);
static void unload(); static void unload();
static void reload(); static void reload();
static void initializeNewPlugins();
static void addPlugin(const std::string &name, PluginFunctions functions); static void addPlugin(const std::string &name, PluginFunctions functions);
static std::vector<Plugin> &getPlugins(); static std::list<Plugin> &getPlugins();
static std::vector<std::fs::path> &getPluginPaths(); static std::vector<std::fs::path> &getPluginPaths();
static bool isPluginLoaded(const std::fs::path &path); static bool isPluginLoaded(const std::fs::path &path);

View File

@ -28,6 +28,7 @@ namespace hex::log {
}; };
std::vector<LogEntry>& getLogEntries(); std::vector<LogEntry>& 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); [[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); fmt::print(dest, "{}\n", message);
fflush(dest); 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) #if defined(DEBUG)
hex::log::impl::print(fg(fmt::color::light_green) | fmt::emphasis::bold, "[DEBUG]", fmt, args...); hex::log::impl::print(fg(fmt::color::light_green) | fmt::emphasis::bold, "[DEBUG]", fmt, args...);
#else #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 #endif
} }

View File

@ -51,7 +51,7 @@ void* PluginSubCommandsFunctionHelper<T>::getSubCommands() {
#define IMHEX_LIBRARY_SETUP(name) IMHEX_LIBRARY_SETUP_IMPL(name) #define IMHEX_LIBRARY_SETUP(name) IMHEX_LIBRARY_SETUP_IMPL(name)
#define 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 void initializeLibrary(); \
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getLibraryName() { return name; } \ IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getLibraryName() { return name; } \
IMHEX_PLUGIN_VISIBILITY_PREFIX void setImGuiContext(ImGuiContext *ctx) { \ IMHEX_PLUGIN_VISIBILITY_PREFIX void setImGuiContext(ImGuiContext *ctx) { \
@ -75,7 +75,7 @@ void* PluginSubCommandsFunctionHelper<T>::getSubCommands() {
IMHEX_PLUGIN_VISIBILITY_PREFIX void initializeLibrary() IMHEX_PLUGIN_VISIBILITY_PREFIX void initializeLibrary()
#define IMHEX_PLUGIN_SETUP_IMPL(name, author, description) \ #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 *getPluginName() { return name; } \
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginAuthor() { return author; } \ IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginAuthor() { return author; } \
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginDescription() { return description; } \ IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginDescription() { return description; } \

View File

@ -78,6 +78,10 @@ namespace hex {
} }
Plugin::~Plugin() { Plugin::~Plugin() {
if (isLoaded()) {
log::debug("Trying to unload plugin '{}'", getPluginName());
}
#if defined(OS_WINDOWS) #if defined(OS_WINDOWS)
if (m_handle != 0) if (m_handle != 0)
if (FreeLibrary(HMODULE(m_handle)) == FALSE) { if (FreeLibrary(HMODULE(m_handle)) == FALSE) {
@ -258,18 +262,19 @@ namespace hex {
return true; return true;
} }
void PluginManager::initializeNewPlugins() {
for (const auto &plugin : getPlugins()) {
if (!plugin.isLoaded())
hex::unused(plugin.initializePlugin());
}
}
void PluginManager::unload() { void PluginManager::unload() {
getPluginPaths().clear(); getPluginPaths().clear();
// Unload plugins in reverse order // Unload plugins in reverse order
auto &plugins = getPlugins(); auto &plugins = getPlugins();
const auto pluginCount = plugins.size(); while (!plugins.empty()) {
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());
}
plugins.pop_back(); plugins.pop_back();
} }
} }
@ -278,8 +283,8 @@ namespace hex {
getPlugins().emplace_back(name, functions); getPlugins().emplace_back(name, functions);
} }
std::vector<Plugin> &PluginManager::getPlugins() { std::list<Plugin> &PluginManager::getPlugins() {
static std::vector<Plugin> plugins; static std::list<Plugin> plugins;
return plugins; return plugins;
} }

View File

@ -63,6 +63,11 @@ namespace hex::log::impl {
return logEntries; 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) { 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())); const auto now = fmt::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));

View File

@ -12,6 +12,7 @@
#include <romfs/romfs.hpp> #include <romfs/romfs.hpp>
#include <hex/api/plugin_manager.hpp> #include <hex/api/plugin_manager.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/subcommands/subcommands.hpp> #include <hex/subcommands/subcommands.hpp>
@ -109,8 +110,8 @@ namespace hex::plugin::builtin {
} }
void handlePluginsCommand(const std::vector<std::string> &args) { void handlePluginsCommand(const std::vector<std::string> &args) {
hex::unused(args);
if (args.empty()) {
hex::log::println("Loaded plugins:"); hex::log::println("Loaded plugins:");
for (const auto &plugin : PluginManager::getPlugins()) { for (const auto &plugin : PluginManager::getPlugins()) {
@ -122,6 +123,14 @@ namespace hex::plugin::builtin {
} }
std::exit(EXIT_SUCCESS); std::exit(EXIT_SUCCESS);
} else {
TaskManager::doLater([args] {
for (const auto &arg : args) {
PluginManager::load(reinterpret_cast<const char8_t*>(arg.c_str()));
}
PluginManager::initializeNewPlugins();
});
}
} }
void handleHashCommand(const std::vector<std::string> &args) { void handleHashCommand(const std::vector<std::string> &args) {