1
0
mirror of synced 2024-11-12 02:00:52 +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
#include <functional>
#include <list>
#include <span>
#include <string>
@ -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<Plugin> &getPlugins();
static std::list<Plugin> &getPlugins();
static std::vector<std::fs::path> &getPluginPaths();
static bool isPluginLoaded(const std::fs::path &path);

View File

@ -28,6 +28,7 @@ namespace hex::log {
};
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);
@ -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
}

View File

@ -51,7 +51,7 @@ void* PluginSubCommandsFunctionHelper<T>::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<T>::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<T>::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; } \

View File

@ -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<Plugin> &PluginManager::getPlugins() {
static std::vector<Plugin> plugins;
std::list<Plugin> &PluginManager::getPlugins() {
static std::list<Plugin> plugins;
return plugins;
}

View File

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

View File

@ -12,6 +12,7 @@
#include <romfs/romfs.hpp>
#include <hex/api/plugin_manager.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/helpers/utils.hpp>
#include <hex/subcommands/subcommands.hpp>
@ -109,19 +110,27 @@ namespace hex::plugin::builtin {
}
void handlePluginsCommand(const std::vector<std::string> &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<const char8_t*>(arg.c_str()));
}
PluginManager::initializeNewPlugins();
});
}
std::exit(EXIT_SUCCESS);
}
void handleHashCommand(const std::vector<std::string> &args) {