#pragma once #include #include #include #include #include struct ImGuiContext; namespace hex { struct SubCommand { std::string commandKey; std::string commandDesc; std::function&)> callback; }; struct PluginFunctions { using InitializePluginFunc = void (*)(); using InitializeLibraryFunc = void (*)(); using GetPluginNameFunc = const char *(*)(); using GetPluginAuthorFunc = const char *(*)(); using GetPluginDescriptionFunc = const char *(*)(); using GetCompatibleVersionFunc = const char *(*)(); using SetImGuiContextFunc = void (*)(ImGuiContext *); using IsBuiltinPluginFunc = bool (*)(); using GetSubCommandsFunc = void* (*)(); InitializePluginFunc initializePluginFunction = nullptr; InitializeLibraryFunc initializeLibraryFunction = nullptr; GetPluginNameFunc getPluginNameFunction = nullptr; GetPluginAuthorFunc getPluginAuthorFunction = nullptr; GetPluginDescriptionFunc getPluginDescriptionFunction = nullptr; GetCompatibleVersionFunc getCompatibleVersionFunction = nullptr; SetImGuiContextFunc setImGuiContextFunction = nullptr; IsBuiltinPluginFunc isBuiltinPluginFunction = nullptr; GetSubCommandsFunc getSubCommandsFunction = nullptr; }; class Plugin { public: explicit Plugin(const std::fs::path &path, bool libraryPlugin); explicit Plugin(PluginFunctions functions, bool libraryPlugin); Plugin(const Plugin &) = delete; Plugin(Plugin &&other) noexcept; ~Plugin(); Plugin& operator=(const Plugin &) = delete; Plugin& operator=(Plugin &&other) noexcept; [[nodiscard]] bool initializePlugin() const; [[nodiscard]] std::string getPluginName() const; [[nodiscard]] std::string getPluginAuthor() const; [[nodiscard]] std::string getPluginDescription() const; [[nodiscard]] std::string getCompatibleVersion() const; void setImGuiContext(ImGuiContext *ctx) const; [[nodiscard]] bool isBuiltinPlugin() const; [[nodiscard]] const std::fs::path &getPath() const; [[nodiscard]] bool isValid() const; [[nodiscard]] bool isLoaded() const; [[nodiscard]] std::span getSubCommands() const; [[nodiscard]] bool isLibraryPlugin() const { return m_libraryPlugin; } private: uintptr_t m_handle = 0; std::fs::path m_path; bool m_libraryPlugin; mutable bool m_initialized = false; PluginFunctions m_functions = {}; template [[nodiscard]] auto getPluginFunction(const std::string &symbol) { return reinterpret_cast(this->getPluginFunction(symbol)); } [[nodiscard]] void *getPluginFunction(const std::string &symbol) const; }; class PluginManager { public: PluginManager() = delete; static bool load(const std::fs::path &pluginFolder); static void unload(); static void reload(); static void addPlugin(PluginFunctions functions); static std::vector &getPlugins(); static std::vector &getPluginPaths(); }; }