Extra2D/Extra2D/include/extra2d/core/module_meta.h

142 lines
3.0 KiB
C++

#pragma once
#include <extra2d/core/export.h>
#include <extra2d/core/types.h>
#include <vector>
#include <string>
#include <unordered_map>
#include <memory>
#include <functional>
#include <algorithm>
namespace extra2d {
class Module;
/**
* @brief 模块元数据基类
*
* 提供模块的类型信息、依赖关系和创建工厂
*/
struct E2D_API ModuleMetaBase {
virtual ~ModuleMetaBase() = default;
/**
* @brief 获取模块名称
*/
virtual const char* getName() const = 0;
/**
* @brief 获取模块优先级
*/
virtual int getPriority() const { return 0; }
/**
* @brief 获取模块依赖
*/
virtual std::vector<const char*> getDependencies() const { return {}; }
/**
* @brief 创建模块实例
*/
virtual Module* create() = 0;
};
/**
* @brief 模块注册器(自动发现)
*
* 单例类,管理所有模块的注册、创建和生命周期
*/
class E2D_API ModuleRegistry {
public:
/**
* @brief 获取单例实例
*/
static ModuleRegistry& instance();
/**
* @brief 注册模块元数据
* @param meta 模块元数据指针
*/
void registerMeta(ModuleMetaBase* meta);
/**
* @brief 获取所有已注册模块元数据
*/
std::vector<ModuleMetaBase*> getAllMetas() const;
/**
* @brief 按名称获取模块元数据
*/
ModuleMetaBase* getMeta(const char* name) const;
/**
* @brief 创建并初始化所有模块
* @return 成功返回 true
*/
bool createAndInitAll();
/**
* @brief 销毁所有模块
*/
void destroyAll();
/**
* @brief 获取模块实例(按类型)
*/
template<typename T>
T* getModule() const {
for (const auto& [name, ptr] : instanceMap_) {
if (auto* derived = dynamic_cast<T*>(ptr)) {
return derived;
}
}
return nullptr;
}
/**
* @brief 获取模块实例(按名称)
*/
Module* getModule(const char* name) const;
/**
* @brief 检查模块是否存在
*/
bool hasModule(const char* name) const;
/**
* @brief 获取所有模块实例
*/
std::vector<Module*> getAllModules() const;
/**
* @brief 检查是否已初始化
*/
bool isInitialized() const { return initialized_; }
private:
ModuleRegistry() = default;
~ModuleRegistry() = default;
ModuleRegistry(const ModuleRegistry&) = delete;
ModuleRegistry& operator=(const ModuleRegistry&) = delete;
/**
* @brief 按依赖关系拓扑排序
*/
std::vector<ModuleMetaBase*> sortByDependency();
/**
* @brief 检测循环依赖
*/
bool hasCircularDependency() const;
std::vector<ModuleMetaBase*> metas_;
std::vector<std::unique_ptr<Module>> instances_;
std::unordered_map<std::string, Module*> instanceMap_;
bool initialized_ = false;
};
} // namespace extra2d