/* * Author: Patrick-Christopher Mattulat * Company: Lynar Studios * E-Mail: webmaster@lynarstudios.com * Created: 2024-05-16 * Changed: 2024-05-30 * * */ #include #include #include using ls::std::core::Class; using ls::std::core::EventNotHandledException; using ls::std::event::Event; using ls::std::event::EventListener; using ls::std::event::EventManager; using ls::std::event::EventParameter; using ls::std::event::type::event_action; using ls::std::event::type::event_listeners; using ls::std::event::type::listener_id; using ::std::make_pair; using ::std::move; using ::std::shared_ptr; EventManager::EventManager() : Class("EventManager") {} EventManager::~EventManager() noexcept = default; listener_id EventManager::getNextProvisionId() const { return this->provisionId; } bool EventManager::holdsListenerForEvent(listener_id _id, const Event &_event) { bool holdsListener{}; if (this->_observesEvent(_event)) { for (const auto &[listener, eventAction] : this->inventory[_event.getClassName()]) { holdsListener = listener->getId() == _id; if (holdsListener) { break; } } } return holdsListener; } void EventManager::invoke(const Event &_event) { if (!this->_observesEvent(_event)) { throw EventNotHandledException("event " + _event.getClassName() + " is not known by event manager"); } const auto &listeners = this->inventory[_event.getClassName()]; EventManager::_notifyListeners(listeners); } void EventManager::invoke(const Event &_event, const EventParameter &_parameter) { if (!this->_observesEvent(_event)) { throw EventNotHandledException("event " + _event.getClassName() + " is not known by event manager"); } const auto &listeners = this->inventory[_event.getClassName()]; EventManager::_giveListenersParameter(listeners, _parameter); EventManager::_notifyListeners(listeners); } listener_id EventManager::requestListenerId() { listener_id providedId = this->provisionId; ++this->provisionId; return providedId; } void EventManager::subscribeListenerForEvent(shared_ptr _listener, const Event &_event, event_action _action) { if (!this->_observesEvent(_event)) { this->inventory[_event.getClassName()] = {}; } auto inventoryEntry = make_pair, event_action>(::move(_listener), ::move(_action)); this->inventory[_event.getClassName()].push_back(inventoryEntry); } void EventManager::unsubscribeListenerForEvent(const shared_ptr &_listener, const Event &_event) { if (this->_observesEvent(_event)) { for (auto iterator = this->inventory[_event.getClassName()].begin(); iterator != this->inventory[_event.getClassName()].end(); iterator++) { if (iterator->first->getId() == _listener->getId()) { this->inventory[_event.getClassName()].erase(iterator); break; } } } } void EventManager::_giveListenersParameter(const event_listeners &_listeners, const EventParameter &_parameter) { for (const auto &[listener, action] : _listeners) { listener->setParameter(_parameter); } } void EventManager::_notifyListeners(const event_listeners &_listeners) { for (const auto &[listener, eventAction] : _listeners) { eventAction(); } } bool EventManager::_observesEvent(const Event &_event) const { return this->inventory.find(_event.getClassName()) != this->inventory.end(); }