简介 (Introduction)

EnTT 提供了一种灵活的事件系统,基于信号 (signals) 和 事件 (events) 的机制,用于在实体-组件-系统 (ECS) 架构中实现高效的通信。信号和事件的核心区别在于:

EnTT 的事件系统旨在让开发者能以松耦合的方式处理实体之间的交互。信号适合需要持续监听的场景(例如,玩家受伤时更新 UI),而事件适合瞬时通知(例如,游戏关卡加载完成)。

信号 (Signals)

信号的实现,基于 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});
}

事件 (Events)

struct position {
    float x, y;
};

struct collision_event {
    entt::entity a, b;
};

void on_collision(const collision_event &event, entt::registry &registry) {
    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);
}