Extra2D/Extra2D/include/extra2d/core/module_macros.h

157 lines
4.6 KiB
C++

#pragma once
#include <extra2d/core/export.h>
#include <extra2d/core/module_meta.h>
#include <extra2d/core/property.h>
#include <extra2d/core/types.h>
#include <initializer_list>
namespace extra2d {
/**
* @brief 模块元数据模板实现
*/
template<typename T>
class ModuleMeta : public ModuleMetaBase {
public:
using ModuleType = T;
const char* name_ = nullptr;
int priority_ = 0;
std::vector<const char*> dependencies_;
std::function<void(Module*, PropertyBinder&)> bindFunc_;
const char* getName() const override { return name_; }
int getPriority() const override { return priority_; }
std::vector<const char*> getDependencies() const override { return dependencies_; }
T* create() override {
return new T();
}
void bindProperties(Module* instance, PropertyBinder& binder) override {
if (bindFunc_) {
bindFunc_(instance, binder);
}
}
};
namespace detail {
/**
* @brief 模块注册辅助类(静态自动注册)
*/
template<typename T>
struct ModuleAutoRegister {
ModuleMeta<T> meta;
ModuleAutoRegister(const char* name, int priority, std::initializer_list<const char*> deps) {
meta.name_ = name;
meta.priority_ = priority;
meta.dependencies_ = std::vector<const char*>(deps);
ModuleRegistry::instance().registerMeta(&meta);
}
};
} // namespace detail
} // namespace extra2d
// ============================================================================
// 模块定义宏 - 静态自动注册
// ============================================================================
/**
* @brief 简化版模块定义(静态自动注册)
*
* 用于引擎内部模块,在动态库加载时自动注册
*/
#define E2D_MODULE(ModuleClassName, priorityValue, ...) \
__attribute__((used)) \
static ::extra2d::detail::ModuleAutoRegister< ::extra2d::ModuleClassName> \
E2D_CONCAT(_e2d_auto_reg_, ModuleClassName)( \
#ModuleClassName, priorityValue, { __VA_ARGS__ });
/**
* @brief 外部模块定义(自动生成 force_link 函数)
*
* 用于编译为单独 DLL 的自定义模块
*
* 使用示例(在模块 cpp 文件末尾):
* } // namespace extra2d
* E2D_MODULE_EXPORT(HelloModule, 1000)
*/
#define E2D_MODULE_EXPORT(ModuleClassName, priorityValue, ...) \
E2D_MODULE(ModuleClassName, priorityValue, __VA_ARGS__) \
extern "C" E2D_API void E2D_CONCAT(e2d_force_link_, ModuleClassName)() {}
/**
* @brief 声明外部模块的 force_link 函数
*/
#define E2D_DECLARE_FORCE_LINK(ModuleClassName) \
extern "C" void E2D_CONCAT(e2d_force_link_, ModuleClassName)()
/**
* @brief 调用 force_link 函数
*/
#define E2D_CALL_FORCE_LINK(ModuleClassName) \
E2D_CONCAT(e2d_force_link_, ModuleClassName)()
/**
* @brief 强制链接外部模块(声明 + 调用)
*
* 在 main.cpp 开头调用,触发 DLL 静态初始化
*/
#define E2D_FORCE_LINK(ModuleClassName) \
E2D_DECLARE_FORCE_LINK(ModuleClassName); \
E2D_CALL_FORCE_LINK(ModuleClassName)
/**
* @brief 带属性的模块定义开始
*/
#define E2D_MODULE_BEGIN(ModuleClassName) \
namespace { \
static ::extra2d::ModuleMeta< ::extra2d::ModuleClassName>& E2D_CONCAT(_e2d_get_meta_, ModuleClassName)() { \
static ::extra2d::ModuleMeta< ::extra2d::ModuleClassName> meta; \
return meta; \
} \
struct E2D_CONCAT(_E2D_ModuleCfg_, ModuleClassName) { \
E2D_CONCAT(_E2D_ModuleCfg_, ModuleClassName)()
/**
* @brief 定义模块优先级
*/
#define E2D_PRIORITY(value) \
{ auto& m = E2D_CONCAT(_e2d_get_meta_, ModuleClassName)(); m.priority_ = value; }
/**
* @brief 定义模块依赖
*/
#define E2D_DEPENDENCIES(...) \
{ \
auto& m = E2D_CONCAT(_e2d_get_meta_, ModuleClassName)(); \
m.dependencies_ = { __VA_ARGS__ }; \
}
/**
* @brief 定义属性
*/
#define E2D_PROPERTY(name, type) \
{ \
auto& m = E2D_CONCAT(_e2d_get_meta_, ModuleClassName)(); \
auto oldFunc = m.bindFunc_; \
m.bindFunc_ = [oldFunc](::extra2d::Module* inst, ::extra2d::PropertyBinder& binder) { \
if (oldFunc) oldFunc(inst, binder); \
auto* module = static_cast< ::extra2d::ModuleClassName*>(inst); \
binder.bind<type>(#name, module->name, #name, ""); \
}; \
}
/**
* @brief 结束模块定义
*/
#define E2D_MODULE_END() \
} E2D_CONCAT(_e2d_cfg_inst_, ModuleClassName); \
}