#include #include #include void MscEventBus::publish(MscEvent &event) { std::vector listeners; { std::lock_guard lock(_listenersMutex); auto it = _listeners.find(event.getName()); if (it == _listeners.end()) return; for (const auto &entry : it->second) listeners.push_back(entry); } for (const auto &entry : listeners) { if (event.isCanceled()) break; entry.listener(event); if (entry.once) unsubscribe(entry.id); } } MscEventBus::SubscriptionId MscEventBus::_subscribe(const std::string &name, MscEventBus::Listener listener, bool once) { std::lock_guard lock(_listenersMutex); const SubscriptionId id = ++_lastId; auto listenerWithId = ListenerWithId{ .id = id, .listener = std::move(listener), .once = once}; _listeners[name].push_back(std::move(listenerWithId)); _listenersPaths[id] = name; return id; } MscEventBus::SubscriptionId MscEventBus::subscribe(const std::string &name, Listener listener) { return _subscribe(name, std::move(listener), false); } MscEventBus::SubscriptionId MscEventBus::subscribeOnce(const std::string &name, Listener listener) { return _subscribe(name, std::move(listener), true); } bool MscEventBus::unsubscribe(SubscriptionId id) { std::lock_guard lock(_listenersMutex); auto it = _listenersPaths.find(id); if (it == _listenersPaths.end()) return false; auto &listeners = _listeners.at(it->second); for (std::size_t i = 0; i < listeners.size(); i++) { if (listeners.at(i).id != id) continue; listeners.erase(listeners.begin() + i); _listenersPaths.erase(id); if (listeners.empty()) _listeners.erase(it->second); return true; } return false; }