1
0
mirror of synced 2024-11-28 01:20:51 +01:00

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

@ -39,8 +39,12 @@ find_package(OpenGL REQUIRED)
find_package(Python COMPONENTS Development) find_package(Python COMPONENTS Development)
add_subdirectory(external/llvm) add_subdirectory(external/llvm)
# Plugins
add_subdirectory(plugins/libimhex) add_subdirectory(plugins/libimhex)
add_subdirectory(plugins/example)
if(Python_VERSION LESS 3) if(Python_VERSION LESS 3)
message(STATUS ${PYTHON_VERSION_MAJOR_MINOR}) message(STATUS ${PYTHON_VERSION_MAJOR_MINOR})

View File

@ -15,20 +15,13 @@ namespace hex {
~Plugin(); ~Plugin();
void initializePlugin(SharedData &sharedData) const; void initializePlugin(SharedData &sharedData) const;
View* createView() const;
void drawToolsEntry() const;
private: private:
using InitializePluginFunc = void(*)(SharedData &sharedData); using InitializePluginFunc = void(*)(SharedData &sharedData);
using CreateViewFunc = View*(*)();
using DrawToolsEntryFunc = void(*)();
void *m_handle = nullptr; void *m_handle = nullptr;
InitializePluginFunc m_initializePluginFunction = nullptr; InitializePluginFunc m_initializePluginFunction = nullptr;
CreateViewFunc m_createViewFunction = nullptr;
DrawToolsEntryFunc m_drawToolsEntryFunction = nullptr;
}; };
class PluginHandler { class PluginHandler {

View File

@ -14,18 +14,11 @@ namespace hex {
class Window { class Window {
public: public:
Window(); Window(int &argc, char **&argv);
~Window(); ~Window();
void loop(); void loop();
template<derived_from<View> T, typename ... Args>
T* addView(Args&& ... args) {
this->m_views.emplace_back(new T(std::forward<Args>(args)...));
return static_cast<T*>(this->m_views.back());
}
friend void *ImHexSettingsHandler_ReadOpenFn(ImGuiContext *ctx, ImGuiSettingsHandler *, const char *); friend void *ImHexSettingsHandler_ReadOpenFn(ImGuiContext *ctx, ImGuiSettingsHandler *, const char *);
friend void ImHexSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler *handler, void *, const char* line); friend void ImHexSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler *handler, void *, const char* line);
friend void ImHexSettingsHandler_ApplyAll(ImGuiContext *ctx, ImGuiSettingsHandler *handler); friend void ImHexSettingsHandler_ApplyAll(ImGuiContext *ctx, ImGuiSettingsHandler *handler);
@ -33,20 +26,18 @@ namespace hex {
bool setFont(const std::filesystem::path &font_path); bool setFont(const std::filesystem::path &font_path);
void initPlugins();
void deinitPlugins();
private: private:
void frameBegin(); void frameBegin();
void frameEnd(); void frameEnd();
void initGLFW(); void initGLFW();
void initImGui(); void initImGui();
void initPlugins();
void deinitGLFW(); void deinitGLFW();
void deinitImGui(); void deinitImGui();
void deinitPlugins();
GLFWwindow* m_window; GLFWwindow* m_window;
std::vector<View*> m_views;
std::vector<View*> m_pluginViews;
float m_globalScale = 1.0f, m_fontScale = 1.0f; float m_globalScale = 1.0f, m_fontScale = 1.0f;
bool m_fpsVisible = false; bool m_fpsVisible = false;

View File

@ -3,7 +3,9 @@ project(example)
set(CMAKE_CXX_STANDARD 20) 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") set(CMAKE_SHARED_LIBRARY_PREFIX "plugin")

View File

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

View File

@ -2,6 +2,7 @@
#include <hex.hpp> #include <hex.hpp>
#include <concepts>
#include <functional> #include <functional>
#include <map> #include <map>
#include <string> #include <string>
@ -12,12 +13,19 @@
namespace hex { namespace hex {
class View;
namespace lang { class ASTNode; } 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 { class ContentRegistry {
public: public:
ContentRegistry() = delete; ContentRegistry() = delete;
/* Settings Registry. Allows adding of new entries into the ImHex preferences window. */
struct Settings { struct Settings {
Settings() = delete; Settings() = delete;
@ -36,12 +44,14 @@ namespace hex {
static nlohmann::json& getSettingsData(); static nlohmann::json& getSettingsData();
}; };
/* Events Registry. Allows to define new events that can be used by other plugins later on subscribe to */
struct Events { struct Events {
Events() = delete; Events() = delete;
static auto get(std::string_view name); static auto get(std::string_view name);
}; };
/* Command Palette Command Registry. Allows adding of new commands to the command palette */
struct CommandPaletteCommands { struct CommandPaletteCommands {
CommandPaletteCommands() = delete; 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 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 { struct PatternLanguageFunctions {
PatternLanguageFunctions() = delete; 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 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 <vector>
#include <map> #include <map>
#include <helpers/event.hpp>
#include <helpers/content_registry.hpp> #include <helpers/content_registry.hpp>
#include <helpers/event.hpp>
#include <views/view.hpp>
#include <imgui.h> #include <imgui.h>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
@ -49,6 +50,9 @@ namespace hex {
private: private:
void initializeData() { void initializeData() {
static int mainArgcStorage;
static char **mainArgvStorage;
static ImGuiContext *imGuiContextStorage;
static std::vector<EventHandler> eventHandlersStorage; static std::vector<EventHandler> eventHandlersStorage;
static std::vector<std::function<void()>> deferredCallsStorage; static std::vector<std::function<void()>> deferredCallsStorage;
static prv::Provider *currentProviderStorage; static prv::Provider *currentProviderStorage;
@ -60,8 +64,10 @@ namespace hex {
static u32 customEventsLastIdStorage = u32(Events::Events_BuiltinEnd) + 1; static u32 customEventsLastIdStorage = u32(Events::Events_BuiltinEnd) + 1;
static std::vector<ContentRegistry::CommandPaletteCommands::Entry> commandPaletteCommandsStorage; static std::vector<ContentRegistry::CommandPaletteCommands::Entry> commandPaletteCommandsStorage;
static std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> patternLanguageFunctionsStorage; 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->eventHandlers = &eventHandlersStorage;
this->deferredCalls = &deferredCallsStorage; this->deferredCalls = &deferredCallsStorage;
this->currentProvider = &currentProviderStorage; this->currentProvider = &currentProviderStorage;
@ -74,6 +80,10 @@ namespace hex {
this->customEventsLastId = &customEventsLastIdStorage; this->customEventsLastId = &customEventsLastIdStorage;
this->commandPaletteCommands = &commandPaletteCommandsStorage; this->commandPaletteCommands = &commandPaletteCommandsStorage;
this->patternLanguageFunctions = &patternLanguageFunctionsStorage; this->patternLanguageFunctions = &patternLanguageFunctionsStorage;
this->views = &viewsStorage;
this->tools = &toolsStorage;
this->mainArgc = &mainArgcStorage;
this->mainArgv = &mainArgvStorage;
} }
void initializeData(const SharedData &other) { void initializeData(const SharedData &other) {
@ -90,10 +100,14 @@ namespace hex {
this->customEventsLastId = other.customEventsLastId; this->customEventsLastId = other.customEventsLastId;
this->commandPaletteCommands = other.commandPaletteCommands; this->commandPaletteCommands = other.commandPaletteCommands;
this->patternLanguageFunctions = other.patternLanguageFunctions; this->patternLanguageFunctions = other.patternLanguageFunctions;
this->views = other.views;
this->tools = other.tools;
this->mainArgc = other.mainArgc;
this->mainArgv = other.mainArgv;
} }
public: public:
ImGuiContext *imguiContext; ImGuiContext **imguiContext;
std::vector<EventHandler> *eventHandlers; std::vector<EventHandler> *eventHandlers;
std::vector<std::function<void()>> *deferredCalls; std::vector<std::function<void()>> *deferredCalls;
prv::Provider **currentProvider; prv::Provider **currentProvider;
@ -103,6 +117,11 @@ namespace hex {
u32 *customEventsLastId; u32 *customEventsLastId;
std::vector<ContentRegistry::CommandPaletteCommands::Entry> *commandPaletteCommands; std::vector<ContentRegistry::CommandPaletteCommands::Entry> *commandPaletteCommands;
std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> *patternLanguageFunctions; 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 *windowPos;
ImVec2 *windowSize; ImVec2 *windowSize;

View File

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

View File

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

View File

@ -10,21 +10,21 @@ namespace hex {
/* Settings */ /* Settings */
void ContentRegistry::Settings::load() { 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()) if (settingsFile.good())
settingsFile >> getSettingsData(); settingsFile >> getSettingsData();
} }
void ContentRegistry::Settings::store() { 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(); settingsFile << getSettingsData();
} }
void ContentRegistry::Settings::add(std::string_view category, std::string_view name, s64 defaultValue, const std::function<bool(nlohmann::json&)> &callback) { 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 }); ContentRegistry::Settings::getEntries()[category.data()].emplace_back(Entry{ name.data(), callback });
auto &json = (*SharedData::get().settingsJson); auto &json = getSettingsData();
if (!json.contains(category.data())) if (!json.contains(category.data()))
json[category.data()] = nlohmann::json::object(); 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) { 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 }); ContentRegistry::Settings::getEntries()[category.data()].emplace_back(Entry{ name.data(), callback });
(*SharedData::get().settingsJson)[category.data()] = nlohmann::json::object(); getSettingsData()[category.data()] = nlohmann::json::object();
(*SharedData::get().settingsJson)[category.data()][name.data()] = defaultValue; getSettingsData()[category.data()][name.data()] = defaultValue;
} }
std::map<std::string, std::vector<ContentRegistry::Settings::Entry>>& ContentRegistry::Settings::getEntries() { std::map<std::string, std::vector<ContentRegistry::Settings::Entry>>& ContentRegistry::Settings::getEntries() {
@ -66,10 +66,10 @@ namespace hex {
/* Command Palette Commands */ /* 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) { 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; return *SharedData::get().commandPaletteCommands;
} }
@ -77,11 +77,37 @@ namespace hex {
/* Pattern Language Functions */ /* 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) { 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; 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;
}
} }

View File

@ -179,10 +179,10 @@ namespace hex {
} }
bool LoaderScript::processFile(std::string_view scriptPath) { bool LoaderScript::processFile(std::string_view scriptPath) {
Py_SetProgramName(Py_DecodeLocale(mainArgv[0], nullptr)); Py_SetProgramName(Py_DecodeLocale((*SharedData::get().mainArgv)[0], nullptr));
if (std::filesystem::exists(std::filesystem::path(mainArgv[0]).parent_path().string() + "/lib/python" PYTHON_VERSION_MAJOR_MINOR)) if (std::filesystem::exists(std::filesystem::path((*SharedData::get().mainArgv)[0]).parent_path().string() + "/lib/python" PYTHON_VERSION_MAJOR_MINOR))
Py_SetPythonHome(Py_DecodeLocale(std::filesystem::path(mainArgv[0]).parent_path().string().c_str(), nullptr)); Py_SetPythonHome(Py_DecodeLocale(std::filesystem::path((*SharedData::get().mainArgv)[0]).parent_path().string().c_str(), nullptr));
PyImport_AppendInittab("_imhex", []() -> PyObject* { PyImport_AppendInittab("_imhex", []() -> PyObject* {

View File

@ -5,12 +5,8 @@
namespace hex { namespace hex {
// hex::plugin::createView(void)
constexpr auto CreateViewSymbol = "_ZN3hex6plugin10createViewEv";
// hex::plugin::drawToolsEntry(void)
constexpr auto DrawToolsEntrySymbol = "_ZN3hex6plugin14drawToolsEntryEv";
// hex::plugin::internal::initializePlugin(SharedData&) // hex::plugin::internal::initializePlugin(SharedData&)
constexpr auto InitializePluginSymbol = "_ZN3hex6plugin8internal16initializePluginER10SharedData"; constexpr auto InitializePluginSymbol = "_ZN3hex6plugin8internal16initializePluginERNS_10SharedDataE";
Plugin::Plugin(std::string_view path) { Plugin::Plugin(std::string_view path) {
this->m_handle = dlopen(path.data(), RTLD_LAZY); this->m_handle = dlopen(path.data(), RTLD_LAZY);
@ -18,8 +14,6 @@ namespace hex {
if (this->m_handle == nullptr) if (this->m_handle == nullptr)
return; return;
this->m_createViewFunction = reinterpret_cast<CreateViewFunc>(dlsym(this->m_handle, CreateViewSymbol));
this->m_drawToolsEntryFunction = reinterpret_cast<DrawToolsEntryFunc>(dlsym(this->m_handle, DrawToolsEntrySymbol));
this->m_initializePluginFunction = reinterpret_cast<InitializePluginFunc>(dlsym(this->m_handle, InitializePluginSymbol)); this->m_initializePluginFunction = reinterpret_cast<InitializePluginFunc>(dlsym(this->m_handle, InitializePluginSymbol));
} }
@ -33,19 +27,6 @@ namespace hex {
this->m_initializePluginFunction(sharedData); this->m_initializePluginFunction(sharedData);
} }
View* Plugin::createView() const {
if (this->m_createViewFunction != nullptr)
return this->m_createViewFunction();
return nullptr;
}
void Plugin::drawToolsEntry() const {
if (this->m_drawToolsEntryFunction != nullptr)
this->m_drawToolsEntryFunction();
}
void PluginHandler::load(std::string_view pluginFolder) { void PluginHandler::load(std::string_view pluginFolder) {
PluginHandler::unload(); PluginHandler::unload();
@ -54,8 +35,10 @@ namespace hex {
PluginHandler::s_pluginFolder = pluginFolder; PluginHandler::s_pluginFolder = pluginFolder;
for (auto& pluginPath : std::filesystem::directory_iterator(pluginFolder)) for (auto& pluginPath : std::filesystem::directory_iterator(pluginFolder)) {
PluginHandler::s_plugins.emplace_back(pluginPath.path().string()); if (pluginPath.is_regular_file())
PluginHandler::s_plugins.emplace_back(pluginPath.path().string());
}
} }
void PluginHandler::unload() { void PluginHandler::unload() {

View File

@ -1,6 +1,9 @@
#include "helpers/utils.hpp" #include "helpers/utils.hpp"
#include "window.hpp" #include "window.hpp"
#include <helpers/content_registry.hpp>
#include <providers/provider.hpp>
#include "lang/pattern_data.hpp" #include "lang/pattern_data.hpp"
#include "views/view_hexeditor.hpp" #include "views/view_hexeditor.hpp"
#include "views/view_pattern.hpp" #include "views/view_pattern.hpp"
@ -17,42 +20,39 @@
#include "views/view_command_palette.hpp" #include "views/view_command_palette.hpp"
#include "views/view_settings.hpp" #include "views/view_settings.hpp"
#include "providers/provider.hpp"
#include <vector> #include <vector>
int mainArgc;
char **mainArgv;
int main(int argc, char **argv) { int main(int argc, char **argv) {
mainArgc = argc; hex::Window window(argc, argv);
mainArgv = argv;
hex::Window window;
// Shared Data // Shared Data
std::vector<hex::lang::PatternData*> patternData; std::vector<hex::lang::PatternData*> patternData;
// Create views // Create views
window.addView<hex::ViewHexEditor>(patternData); hex::ContentRegistry::Views::add<hex::ViewHexEditor>(patternData);
window.addView<hex::ViewPattern>(patternData); hex::ContentRegistry::Views::add<hex::ViewPattern>(patternData);
window.addView<hex::ViewPatternData>(patternData); hex::ContentRegistry::Views::add<hex::ViewPatternData>(patternData);
window.addView<hex::ViewDataInspector>(); hex::ContentRegistry::Views::add<hex::ViewDataInspector>();
window.addView<hex::ViewHashes>(); hex::ContentRegistry::Views::add<hex::ViewHashes>();
window.addView<hex::ViewInformation>(); hex::ContentRegistry::Views::add<hex::ViewInformation>();
window.addView<hex::ViewStrings>(); hex::ContentRegistry::Views::add<hex::ViewStrings>();
window.addView<hex::ViewDisassembler>(); hex::ContentRegistry::Views::add<hex::ViewDisassembler>();
window.addView<hex::ViewBookmarks>(); hex::ContentRegistry::Views::add<hex::ViewBookmarks>();
window.addView<hex::ViewPatches>(); hex::ContentRegistry::Views::add<hex::ViewPatches>();
window.addView<hex::ViewTools>(); hex::ContentRegistry::Views::add<hex::ViewTools>();
window.addView<hex::ViewCommandPalette>(); hex::ContentRegistry::Views::add<hex::ViewCommandPalette>();
window.addView<hex::ViewHelp>(); hex::ContentRegistry::Views::add<hex::ViewHelp>();
window.addView<hex::ViewSettings>(); hex::ContentRegistry::Views::add<hex::ViewSettings>();
if (argc > 1) if (argc > 1)
hex::View::postEvent(hex::Events::FileDropped, argv[1]); hex::View::postEvent(hex::Events::FileDropped, argv[1]);
window.initPlugins();
window.loop(); window.loop();
return 0; window.deinitPlugins();
return EXIT_SUCCESS;
} }

View File

@ -313,8 +313,8 @@ namespace hex {
this->drawMathEvaluator(); this->drawMathEvaluator();
this->drawColorPicker(); this->drawColorPicker();
for (const auto& plugin : PluginHandler::getPlugins()) for (const auto& entries : ContentRegistry::Tools::getEntries())
plugin.drawToolsEntry(); entries();
} }
ImGui::End(); ImGui::End();

View File

@ -26,46 +26,45 @@ namespace hex {
} }
void ImHexSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler *handler, void *, const char* line) { void ImHexSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler *handler, void *, const char* line) {
auto *window = reinterpret_cast<Window *>(handler->UserData); for (auto &view : ContentRegistry::Views::getEntries()) {
for (auto &view : window->m_views) {
std::string format = view->getName() + "=%d"; std::string format = view->getName() + "=%d";
sscanf(line, format.c_str(), &view->getWindowOpenState()); sscanf(line, format.c_str(), &view->getWindowOpenState());
} }
} }
void ImHexSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler *handler, ImGuiTextBuffer *buf) { void ImHexSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler *handler, ImGuiTextBuffer *buf) {
auto *window = reinterpret_cast<Window *>(handler->UserData);
buf->reserve(buf->size() + 0x20); // Ballpark reserve buf->reserve(buf->size() + 0x20); // Ballpark reserve
buf->appendf("[%s][General]\n", handler->TypeName); buf->appendf("[%s][General]\n", handler->TypeName);
for (auto &view : window->m_views) { for (auto &view : ContentRegistry::Views::getEntries()) {
buf->appendf("%s=%d\n", view->getName().c_str(), view->getWindowOpenState()); buf->appendf("%s=%d\n", view->getName().c_str(), view->getWindowOpenState());
} }
buf->append("\n"); buf->append("\n");
} }
Window::Window() { Window::Window(int &argc, char **&argv) {
SharedData::get().initializeData(); SharedData::get().initializeData();
hex::SharedData::get().mainArgc = &argc;
hex::SharedData::get().mainArgv = &argv;
ContentRegistry::Settings::load(); ContentRegistry::Settings::load();
View::postEvent(Events::SettingsChanged, nullptr); View::postEvent(Events::SettingsChanged, nullptr);
this->initGLFW(); this->initGLFW();
this->initImGui(); this->initImGui();
this->initPlugins();
} }
Window::~Window() { Window::~Window() {
this->deinitImGui(); this->deinitImGui();
this->deinitGLFW(); this->deinitGLFW();
this->deinitPlugins();
ContentRegistry::Settings::store(); ContentRegistry::Settings::store();
for (auto &view : this->m_views) for (auto &view : ContentRegistry::Views::getEntries())
delete view; delete view;
ContentRegistry::Views::getEntries().clear();
} }
void Window::loop() { void Window::loop() {
@ -76,15 +75,7 @@ namespace hex {
call(); call();
View::getDeferedCalls().clear(); View::getDeferedCalls().clear();
for (auto &view : this->m_views) { for (auto &view : ContentRegistry::Views::getEntries()) {
if (!view->getWindowOpenState())
continue;
ImGui::SetNextWindowSizeConstraints(view->getMinSize(), view->getMaxSize());
view->drawContent();
}
for (auto &view : this->m_pluginViews) {
if (!view->getWindowOpenState()) if (!view->getWindowOpenState())
continue; continue;
@ -160,30 +151,14 @@ namespace hex {
if (ImGui::BeginMenu(menu)) ImGui::EndMenu(); if (ImGui::BeginMenu(menu)) ImGui::EndMenu();
if (ImGui::BeginMenu("View")) { if (ImGui::BeginMenu("View")) {
for (auto &view : this->m_views) { for (auto &view : ContentRegistry::Views::getEntries()) {
if (view->hasViewMenuItemEntry()) if (view->hasViewMenuItemEntry())
ImGui::MenuItem((view->getName() + " View").c_str(), "", &view->getWindowOpenState()); ImGui::MenuItem((view->getName() + " View").c_str(), "", &view->getWindowOpenState());
} }
if (!this->m_pluginViews.empty()) {
if (ImGui::BeginMenu("Plugin Views")) {
for (auto &view : this->m_pluginViews) {
if (view->hasViewMenuItemEntry())
ImGui::MenuItem((view->getName() + " View").c_str(), "", &view->getWindowOpenState());
}
ImGui::EndMenu();
}
}
ImGui::EndMenu(); ImGui::EndMenu();
} }
for (auto &view : this->m_views) { for (auto &view : ContentRegistry::Views::getEntries()) {
view->drawMenu();
}
for (auto &view : this->m_pluginViews) {
view->drawMenu(); view->drawMenu();
} }
@ -208,22 +183,10 @@ namespace hex {
} }
if (auto &[key, mods] = Window::s_currShortcut; key != -1) { if (auto &[key, mods] = Window::s_currShortcut; key != -1) {
bool shortcutHandled = false; for (auto &view : ContentRegistry::Views::getEntries()) {
for (auto &view : this->m_pluginViews) {
if (view->getWindowOpenState()) { if (view->getWindowOpenState()) {
if (view->handleShortcut(key, mods)) { if (view->handleShortcut(key, mods))
shortcutHandled = true;
break; break;
}
}
}
if (!shortcutHandled) {
for (auto &view : this->m_views) {
if (view->getWindowOpenState()) {
if (view->handleShortcut(key, mods))
break;
}
} }
} }
@ -232,7 +195,6 @@ namespace hex {
} }
ImGui::End(); ImGui::End();
} }
void Window::frameEnd() { void Window::frameEnd() {
@ -343,7 +305,7 @@ namespace hex {
style.ScaleAllSizes(this->m_globalScale); style.ScaleAllSizes(this->m_globalScale);
#ifdef __MINGW32__ #ifdef __MINGW32__
std::filesystem::path resourcePath = std::filesystem::path(mainArgv[0]).parent_path(); std::filesystem::path resourcePath = std::filesystem::path((*SharedData::get().mainArgv)[0]).parent_path();
#elif defined(__linux__) #elif defined(__linux__)
std::filesystem::path resourcePath = "/usr/share/ImHex"; std::filesystem::path resourcePath = "/usr/share/ImHex";
#else #else
@ -382,15 +344,15 @@ namespace hex {
} }
void Window::initPlugins() { void Window::initPlugins() {
(*SharedData::get().imguiContext) = ImGui::GetCurrentContext();
try { try {
auto pluginFolderPath = std::filesystem::path(mainArgv[0]).parent_path() / "plugins"; auto pluginFolderPath = std::filesystem::path((*SharedData::get().mainArgv)[0]).parent_path() / "plugins";
PluginHandler::load(pluginFolderPath.string()); PluginHandler::load(pluginFolderPath.string());
} catch (std::runtime_error &e) { return; } } catch (std::runtime_error &e) { return; }
for (const auto &plugin : PluginHandler::getPlugins()) { for (const auto &plugin : PluginHandler::getPlugins()) {
plugin.initializePlugin(SharedData::get()); plugin.initializePlugin(SharedData::get());
if (auto view = plugin.createView(); view != nullptr)
this->m_pluginViews.push_back(view);
} }
} }
@ -407,9 +369,6 @@ namespace hex {
void Window::deinitPlugins() { void Window::deinitPlugins() {
PluginHandler::unload(); PluginHandler::unload();
for (auto &view : this->m_pluginViews)
delete view;
} }
} }