157 lines
3.6 KiB
C
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
|