32 lines
1.2 KiB
C++
32 lines
1.2 KiB
C++
#include "game/entities/event_bus.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <utility>
|
|
|
|
auto EventBus::subscribe(const std::string& name, Handler handler) -> SubId {
|
|
const SubId ID = next_id_++;
|
|
subs_[name].push_back(Subscription{.id = ID, .handler = std::move(handler)});
|
|
return ID;
|
|
}
|
|
|
|
void EventBus::unsubscribe(SubId id) {
|
|
// Cerca lineal: els subscriptors per esdeveniment són pocs (un gestor
|
|
// de nivell, una HUD). Si algun dia creix, es pot passar a unordered_map
|
|
// per id, però ara la simplicitat és més valuosa.
|
|
for (auto& [name, vec] : subs_) {
|
|
auto removed = std::ranges::remove_if(vec, [id](const Subscription& s) { return s.id == id; });
|
|
vec.erase(removed.begin(), removed.end());
|
|
}
|
|
}
|
|
|
|
void EventBus::publish(const Event& event) {
|
|
auto it = subs_.find(event.name);
|
|
if (it == subs_.end()) { return; }
|
|
// Còpia del vector: un handler podria publicar un altre event i fer
|
|
// créixer el subs_ del mateix nom; iterar sobre la còpia evita
|
|
// invalidar iteradors. És barat: Subscription és petit i els handlers
|
|
// s'usen sovint una vegada.
|
|
const auto SUBS = it->second;
|
|
for (const auto& sub : SUBS) { sub.handler(event); }
|
|
}
|