Extra2D/include/plugin/plugin_loader.h

157 lines
3.6 KiB
C++

#pragma once
#include <plugin\iplugin.h>
#include <vector>
#include <unordered_map>
#include <string>
#include <memory>
namespace extra2d {
/**
* @brief 插件加载器 - 非单例
*
* 管理所有插件的生命周期,支持动态加载/卸载
* 自动处理插件依赖关系
*/
class PluginLoader {
public:
PluginLoader();
~PluginLoader();
// 禁止拷贝
PluginLoader(const PluginLoader&) = delete;
PluginLoader& operator=(const PluginLoader&) = delete;
// 允许移动
PluginLoader(PluginLoader&&) noexcept;
PluginLoader& operator=(PluginLoader&&) noexcept;
/**
* @brief 从动态库加载插件
* @param path 插件动态库路径
* @return 是否加载成功
*/
bool loadFromLibrary(const char* path);
/**
* @brief 注册内置插件(静态链接)
* @param plugin 插件实例指针(不由加载器管理生命周期)
*/
void registerPlugin(IPlugin* plugin);
/**
* @brief 卸载插件
* @param name 插件名称
*/
void unloadPlugin(const char* name);
/**
* @brief 获取插件
* @param name 插件名称
* @return 插件指针,不存在返回 nullptr
*/
IPlugin* getPlugin(const char* name) const;
/**
* @brief 检查插件是否存在
* @param name 插件名称
* @return 是否存在
*/
bool hasPlugin(const char* name) const;
/**
* @brief 获取所有插件
* @return 插件列表
*/
std::vector<IPlugin*> getAllPlugins() const;
/**
* @brief 初始化所有插件(自动处理依赖)
* @return 是否全部初始化成功
*/
bool initAll();
/**
* @brief 关闭所有插件(按依赖逆序)
*/
void shutdownAll();
/**
* @brief 获取插件数量
* @return 插件数量
*/
size_t getPluginCount() const;
/**
* @brief 添加插件搜索路径
* @param path 搜索路径
*/
void addSearchPath(const char* path);
/**
* @brief 从目录加载所有插件
* @param directory 目录路径
* @return 加载成功的插件数量
*/
size_t loadPluginsFromDirectory(const char* directory);
private:
/**
* @brief 插件条目结构
*/
struct PluginEntry {
IPlugin* plugin = nullptr; // 插件实例
void* handle = nullptr; // 动态库句柄
bool isDynamic = false; // 是否为动态加载
bool owned = false; // 是否由加载器管理生命周期
};
/**
* @brief 解析插件依赖
* @param plugin 插件
* @return 依赖是否满足
*/
bool resolveDependencies(IPlugin* plugin);
/**
* @brief 检查依赖是否满足
* @param dependencies 依赖列表
* @return 是否满足
*/
bool checkDependencies(const std::vector<std::string>& dependencies);
/**
* @brief 按依赖顺序排序插件
*/
void sortPluginsByDependencies();
/**
* @brief 加载动态库
* @param path 库路径
* @return 库句柄
*/
void* loadDynamicLibrary(const char* path);
/**
* @brief 卸载动态库
* @param handle 库句柄
*/
void unloadDynamicLibrary(void* handle);
/**
* @brief 获取动态库符号
* @param handle 库句柄
* @param name 符号名称
* @return 符号地址
*/
void* getSymbol(void* handle, const char* name);
std::unordered_map<std::string, PluginEntry> plugins_;
std::vector<std::string> searchPaths_;
std::vector<IPlugin*> sortedPlugins_; // 按依赖排序的插件列表
bool inited_ = false;
};
} // namespace extra2d