feat: Allow extra plugin folders to be specified with the --plugins
cli option
This commit is contained in:
parent
f2bab005d0
commit
60e7362f4e
@ -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);
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) { \
|
||||||
@ -59,7 +59,7 @@ void* PluginSubCommandsFunctionHelper<T>::getSubCommands() {
|
|||||||
GImGui = ctx; \
|
GImGui = ctx; \
|
||||||
} \
|
} \
|
||||||
extern "C" [[gnu::visibility("default")]] void WOLV_TOKEN_CONCAT(forceLinkPlugin_, IMHEX_PLUGIN_NAME)() { \
|
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, \
|
nullptr, \
|
||||||
initializeLibrary, \
|
initializeLibrary, \
|
||||||
nullptr, \
|
nullptr, \
|
||||||
@ -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; } \
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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()));
|
||||||
|
|
||||||
|
@ -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,19 +110,27 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handlePluginsCommand(const std::vector<std::string> &args) {
|
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()) {
|
for (const auto &plugin : PluginManager::getPlugins()) {
|
||||||
hex::log::print("- \033[1m{}\033[0m", plugin.getPluginName());
|
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) {
|
void handleHashCommand(const std::vector<std::string> &args) {
|
||||||
|
Loading…
Reference in New Issue
Block a user