diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-11-04 08:28:18 +0100 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-11-04 08:28:18 +0100 |
commit | 06f65659fc6ffde7cabd2135040cbfbf089e5a24 (patch) | |
tree | e3570bea52b87b6919550ee81d17927ccbc11cc5 /mwe/events/src/eventManager.cpp | |
parent | 128969619a22dfc17a9ea35335c0d21c6ad0c954 (diff) | |
parent | 6aa8fdd04728b6a499f526de727514ae3d0490b4 (diff) |
merge `origin/master` into `master`
Diffstat (limited to 'mwe/events/src/eventManager.cpp')
-rw-r--r-- | mwe/events/src/eventManager.cpp | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/mwe/events/src/eventManager.cpp b/mwe/events/src/eventManager.cpp new file mode 100644 index 0000000..34a093d --- /dev/null +++ b/mwe/events/src/eventManager.cpp @@ -0,0 +1,130 @@ +#include "eventManager.h" + +void EventManager::shutdown() { subscribers.clear(); } + +void EventManager::subscribe(int eventType, + std::unique_ptr<IEventHandlerWrapper> && handler, + int eventId) { + if (eventId) { + std::unordered_map< + int, std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>:: + iterator subscribers + = subscribersByEventId.find(eventType); + + if (subscribers != subscribersByEventId.end()) { + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>> & + handlersMap + = subscribers->second; + std::unordered_map< + int, + std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator + handlers + = handlersMap.find(eventId); + if (handlers != handlersMap.end()) { + handlers->second.emplace_back(std::move(handler)); + return; + } + } + subscribersByEventId[eventType][eventId].emplace_back( + std::move(handler)); + + } else { + auto & handlers = subscribers[eventType]; + handlers.emplace_back(std::move(handler)); + } +} + +void EventManager::unsubscribe(int eventType, const std::string & handlerName, + int eventId) { + if (eventId) { + std::unordered_map< + int, std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>:: + iterator subscriberList + = subscribersByEventId.find(eventType); + if (subscriberList != subscribersByEventId.end()) { + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>> & + handlersMap + = subscriberList->second; + std::unordered_map< + int, + std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator + handlers + = handlersMap.find(eventId); + if (handlers != handlersMap.end()) { + std::vector<std::unique_ptr<IEventHandlerWrapper>> & callbacks + = handlers->second; + for (std::vector< + std::unique_ptr<IEventHandlerWrapper>>::iterator it + = callbacks.begin(); + it != callbacks.end(); ++it) { + if (it->get()->getType() == handlerName) { + it = callbacks.erase(it); + return; + } + } + } + } + } else { + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator + handlersIt + = subscribers.find(eventType); + if (handlersIt != subscribers.end()) { + std::vector<std::unique_ptr<IEventHandlerWrapper>> & handlers + = handlersIt->second; + for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it + = handlers.begin(); + it != handlers.end(); ++it) { + if (it->get()->getType() == handlerName) { + it = handlers.erase(it); + return; + } + } + } + } +} + +void EventManager::triggerEvent(const Event & event_, int eventId) { + if (eventId > 0) { + auto handlersIt + = subscribersByEventId[event_.getEventType()].find(eventId); + if (handlersIt != subscribersByEventId[event_.getEventType()].end()) { + std::vector<std::unique_ptr<IEventHandlerWrapper>> & callbacks + = handlersIt->second; + for (auto it = callbacks.begin(); it != callbacks.end();) { + (*it)->exec(event_); + if ((*it)->isDestroyOnSuccess()) { + it = callbacks.erase(it); + } else { + ++it; + } + } + } + } else { + auto & handlers = subscribers[event_.getEventType()]; + for (std::unique_ptr<IEventHandlerWrapper> & handler : handlers) { + handler->exec(event_); + } + } +} + +void EventManager::queueEvent(std::unique_ptr<Event> && event_, int eventId) { + eventsQueue.emplace_back(std::move(event_), eventId); +} + +void EventManager::dispatchEvents() { + for (std::vector<std::pair<std::unique_ptr<Event>, int>>::iterator eventIt + = eventsQueue.begin(); + eventIt != eventsQueue.end();) { + if (!eventIt->first.get()->getHandled()) { + triggerEvent(*eventIt->first.get(), eventIt->second); + eventIt = eventsQueue.erase(eventIt); + } else { + ++eventIt; + } + } +} |