EnTT 提供了一种灵活的事件系统,基于信号 (signals) 和 事件 (events) 的机制,用于在实体-组件-系统 (ECS) 架构中实现高效的通信。信号和事件的核心区别在于:
EnTT 的事件系统旨在让开发者能以松耦合的方式处理实体之间的交互。信号适合需要持续监听的场景(例如,玩家受伤时更新 UI),而事件适合瞬时通知(例如,游戏关卡加载完成)。
信号的实现,基于 sigh(Signal Handler)类
发布者 (Publisher):触发信号。 订阅者 (Subscriber):注册回调函数以响应信号
#include <entt/entt.hpp>
struct my_event {
int value;
};
void callback(const my_event &event) {
std::cout << "Event received with value: " << event.value << std::endl;
}
int main() {
entt::sigh<void(const my_event &)> signal;
entt::sink sink{signal};
// 订阅回调
sink.connect<&callback>();
// 发布事件
signal.publish(my_event{42});
}
struct position {
float x, y;
};
struct collision_event {
entt::entity a, b;
};
void on_collision(const collision_event &event, entt::registry ®istry) {
auto &pos_a = registry.get<position>(event.a);
auto &pos_b = registry.get<position>(event.b);
std::cout << "Collision between entities at positions ("
<< pos_a.x << ", " << pos_a.y << ") and ("
<< pos_b.x << ", " << pos_b.y << ")" << std::endl;
}
int main() {
entt::registry registry;
entt::dispatcher dispatcher;
// 创建实体
auto entity_a = registry.create();
auto entity_b = registry.create();
registry.emplace<position>(entity_a, 1.0f, 2.0f);
registry.emplace<position>(entity_b, 3.0f, 4.0f);
// 连接事件处理
dispatcher.sink<collision_event>().connect<&on_collision>();
// 触发碰撞事件
dispatcher.trigger<collision_event>({entity_a, entity_b}, registry);
}