Refactored plugin system

This commit is contained in:
WerWolv
2021-01-12 16:50:15 +01:00
parent c09a8bca7f
commit 84a6fff034
15 changed files with 170 additions and 164 deletions

View File

@@ -3,7 +3,9 @@ project(example)
set(CMAKE_CXX_STANDARD 20)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libimhex ${CMAKE_CURRENT_BINARY_DIR}/plugins/libimhex)
if (NOT TARGET libimhex)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libimhex ${CMAKE_CURRENT_BINARY_DIR}/plugins/libimhex)
endif()
set(CMAKE_SHARED_LIBRARY_PREFIX "plugin")

View File

@@ -15,17 +15,9 @@ public:
}
};
IMHEX_PLUGIN {
IMHEX_PLUGIN_SETUP {
View* createView() {
return new ViewExample();
}
void drawToolsEntry() {
if (ImGui::CollapsingHeader("Example Tool")) {
ImGui::Text("Custom Plugin tool");
}
}
ContentRegistry::Views::add<ViewExample>();
}

View File

@@ -2,6 +2,7 @@
#include <hex.hpp>
#include <concepts>
#include <functional>
#include <map>
#include <string>
@@ -12,12 +13,19 @@
namespace hex {
class View;
namespace lang { class ASTNode; }
/*
The Content Registry is the heart of all features in ImHex that are in some way extendable by Plugins.
It allows you to add/register new content that will be picked up and used by the ImHex core or by other
plugins when needed.
*/
class ContentRegistry {
public:
ContentRegistry() = delete;
/* Settings Registry. Allows adding of new entries into the ImHex preferences window. */
struct Settings {
Settings() = delete;
@@ -36,12 +44,14 @@ namespace hex {
static nlohmann::json& getSettingsData();
};
/* Events Registry. Allows to define new events that can be used by other plugins later on subscribe to */
struct Events {
Events() = delete;
static auto get(std::string_view name);
};
/* Command Palette Command Registry. Allows adding of new commands to the command palette */
struct CommandPaletteCommands {
CommandPaletteCommands() = delete;
@@ -58,9 +68,10 @@ namespace hex {
};
static void add(Type type, std::string_view command, std::string_view description, const std::function<std::string(std::string)> &callback);
static std::vector<Entry> getEntries();
static std::vector<Entry>& getEntries();
};
/* Pattern Language Function Registry. Allows adding of new functions that may be used inside the pattern language */
struct PatternLanguageFunctions {
PatternLanguageFunctions() = delete;
@@ -75,7 +86,31 @@ namespace hex {
};
static void add(std::string_view name, u32 parameterCount, const std::function<hex::lang::ASTNode*(std::vector<hex::lang::ASTNode*>)> &func);
static std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> getEntries();
static std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function>& getEntries();
};
/* View Registry. Allows adding of new windows */
struct Views {
Views() = delete;
template<std::derived_from<View> T, typename ... Args>
static T* add(Args&& ... args) {
return static_cast<T*>(add(new T(std::forward<Args>(args)...)));
}
static std::vector<View*>& getEntries();
private:
static View* add(View *view);
};
/* Tools Registry. Allows adding new entries to the tools window */
struct Tools {
static void add(const std::function<void()> &function);
static std::vector<std::function<void()>>& getEntries();
};
};

View File

@@ -5,8 +5,9 @@
#include <vector>
#include <map>
#include <helpers/event.hpp>
#include <helpers/content_registry.hpp>
#include <helpers/event.hpp>
#include <views/view.hpp>
#include <imgui.h>
#include <nlohmann/json.hpp>
@@ -49,6 +50,9 @@ namespace hex {
private:
void initializeData() {
static int mainArgcStorage;
static char **mainArgvStorage;
static ImGuiContext *imGuiContextStorage;
static std::vector<EventHandler> eventHandlersStorage;
static std::vector<std::function<void()>> deferredCallsStorage;
static prv::Provider *currentProviderStorage;
@@ -60,8 +64,10 @@ namespace hex {
static u32 customEventsLastIdStorage = u32(Events::Events_BuiltinEnd) + 1;
static std::vector<ContentRegistry::CommandPaletteCommands::Entry> commandPaletteCommandsStorage;
static std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> patternLanguageFunctionsStorage;
static std::vector<View*> viewsStorage;
static std::vector<std::function<void()>> toolsStorage;
this->imguiContext = ImGui::GetCurrentContext();
this->imguiContext = &imGuiContextStorage;
this->eventHandlers = &eventHandlersStorage;
this->deferredCalls = &deferredCallsStorage;
this->currentProvider = &currentProviderStorage;
@@ -74,6 +80,10 @@ namespace hex {
this->customEventsLastId = &customEventsLastIdStorage;
this->commandPaletteCommands = &commandPaletteCommandsStorage;
this->patternLanguageFunctions = &patternLanguageFunctionsStorage;
this->views = &viewsStorage;
this->tools = &toolsStorage;
this->mainArgc = &mainArgcStorage;
this->mainArgv = &mainArgvStorage;
}
void initializeData(const SharedData &other) {
@@ -90,10 +100,14 @@ namespace hex {
this->customEventsLastId = other.customEventsLastId;
this->commandPaletteCommands = other.commandPaletteCommands;
this->patternLanguageFunctions = other.patternLanguageFunctions;
this->views = other.views;
this->tools = other.tools;
this->mainArgc = other.mainArgc;
this->mainArgv = other.mainArgv;
}
public:
ImGuiContext *imguiContext;
ImGuiContext **imguiContext;
std::vector<EventHandler> *eventHandlers;
std::vector<std::function<void()>> *deferredCalls;
prv::Provider **currentProvider;
@@ -103,6 +117,11 @@ namespace hex {
u32 *customEventsLastId;
std::vector<ContentRegistry::CommandPaletteCommands::Entry> *commandPaletteCommands;
std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> *patternLanguageFunctions;
std::vector<View*> *views;
std::vector<std::function<void()>> *tools;
int *mainArgc;
char ***mainArgv;
ImVec2 *windowPos;
ImVec2 *windowSize;

View File

@@ -15,9 +15,6 @@ using s32 = std::int32_t;
using s64 = std::int64_t;
using s128 = __int128_t;
extern int mainArgc;
extern char **mainArgv;
#ifdef OS_WINDOWS
#define MAGIC_PATH_SEPARATOR ";"
#else

View File

@@ -7,12 +7,17 @@
#include <views/view.hpp>
#include <providers/provider.hpp>
#include <helpers/shared_data.hpp>
#include <helpers/content_registry.hpp>
#define IMHEX_PLUGIN namespace hex::plugin::internal { \
void initializePlugin(SharedData &sharedData) { \
if (glGetString == NULL) \
gladLoadGL(); \
SharedData::get().initializeData(sharedData); \
} \
} \
namespace hex::plugin
#define IMHEX_PLUGIN_SETUP namespace hex::plugin { void setup(); } \
namespace hex::plugin::internal { \
void initializePlugin(SharedData &sharedData) { \
if (glGetString == NULL) \
gladLoadGL(); \
SharedData::get().initializeData(sharedData); \
ImGui::SetCurrentContext(*sharedData.imguiContext); \
hex::plugin::setup(); \
\
} \
} \
void hex::plugin::setup()

View File

@@ -10,21 +10,21 @@ namespace hex {
/* Settings */
void ContentRegistry::Settings::load() {
std::ifstream settingsFile(std::filesystem::path(mainArgv[0]).parent_path() / "settings.json");
std::ifstream settingsFile(std::filesystem::path((*SharedData::get().mainArgv)[0]).parent_path() / "settings.json");
if (settingsFile.good())
settingsFile >> getSettingsData();
}
void ContentRegistry::Settings::store() {
std::ofstream settingsFile(std::filesystem::path(mainArgv[0]).parent_path() / "settings.json", std::ios::trunc);
std::ofstream settingsFile(std::filesystem::path((*SharedData::get().mainArgv)[0]).parent_path() / "settings.json", std::ios::trunc);
settingsFile << getSettingsData();
}
void ContentRegistry::Settings::add(std::string_view category, std::string_view name, s64 defaultValue, const std::function<bool(nlohmann::json&)> &callback) {
ContentRegistry::Settings::getEntries()[category.data()].emplace_back(Entry{ name.data(), callback });
auto &json = (*SharedData::get().settingsJson);
auto &json = getSettingsData();
if (!json.contains(category.data()))
json[category.data()] = nlohmann::json::object();
@@ -35,8 +35,8 @@ namespace hex {
void ContentRegistry::Settings::add(std::string_view category, std::string_view name, std::string_view defaultValue, const std::function<bool(nlohmann::json&)> &callback) {
ContentRegistry::Settings::getEntries()[category.data()].emplace_back(Entry{ name.data(), callback });
(*SharedData::get().settingsJson)[category.data()] = nlohmann::json::object();
(*SharedData::get().settingsJson)[category.data()][name.data()] = defaultValue;
getSettingsData()[category.data()] = nlohmann::json::object();
getSettingsData()[category.data()][name.data()] = defaultValue;
}
std::map<std::string, std::vector<ContentRegistry::Settings::Entry>>& ContentRegistry::Settings::getEntries() {
@@ -66,10 +66,10 @@ namespace hex {
/* Command Palette Commands */
void ContentRegistry::CommandPaletteCommands::add(ContentRegistry::CommandPaletteCommands::Type type, std::string_view command, std::string_view description, const std::function<std::string(std::string)> &callback) {
SharedData::get().commandPaletteCommands->push_back(ContentRegistry::CommandPaletteCommands::Entry{ type, command.data(), description.data(), callback });
getEntries().push_back(ContentRegistry::CommandPaletteCommands::Entry{ type, command.data(), description.data(), callback });
}
std::vector<ContentRegistry::CommandPaletteCommands::Entry> ContentRegistry::CommandPaletteCommands::getEntries() {
std::vector<ContentRegistry::CommandPaletteCommands::Entry>& ContentRegistry::CommandPaletteCommands::getEntries() {
return *SharedData::get().commandPaletteCommands;
}
@@ -77,11 +77,37 @@ namespace hex {
/* Pattern Language Functions */
void ContentRegistry::PatternLanguageFunctions::add(std::string_view name, u32 parameterCount, const std::function<hex::lang::ASTNode*(std::vector<hex::lang::ASTNode*>)> &func) {
(*SharedData::get().patternLanguageFunctions)[name.data()] = Function{ parameterCount, func };
getEntries()[name.data()] = Function{ parameterCount, func };
}
std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> ContentRegistry::PatternLanguageFunctions::getEntries() {
std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function>& ContentRegistry::PatternLanguageFunctions::getEntries() {
return *SharedData::get().patternLanguageFunctions;
}
/* Views */
View* ContentRegistry::Views::add(View *view) {
auto &views = getEntries();
views.push_back(view);
return views.back();
}
std::vector<View*>& ContentRegistry::Views::getEntries() {
return *SharedData::get().views;
}
/* Tools */
void ContentRegistry::Tools::add(const std::function<void()> &function) {
getEntries().push_back(function);
}
std::vector<std::function<void()>>& ContentRegistry::Tools::getEntries() {
return *SharedData::get().tools;
}
}