Files
dota_factory/src/lib/eventsystem/EventManager.cpp

130 lines
2.7 KiB
C++

#include "EventManager.h"
#include <set>
#include "EventHandlerBase.h"
std::shared_ptr<EventManager> EventManager::getInstance()
{
if (!s_instance)
{
s_instance = std::shared_ptr<EventManager>(new EventManager());
}
return s_instance;
}
void EventManager::destroyInstance()
{
if (s_instance)
{
s_instance.reset();
}
}
std::shared_ptr<EventManager> EventManager::s_instance = std::shared_ptr<EventManager>();
void EventManager::registerEventHandler(EventHandlerBase *eventHandler)
{
std::scoped_lock<std::mutex> lock(m_eventHandlersMutex);
m_eventHandlers[eventHandler->m_id] = eventHandler;
}
void EventManager::unregisterEventHandler(EventHandlerBase *eventHandler)
{
std::scoped_lock<std::mutex> lock(m_eventHandlersMutex);
m_eventHandlers.erase(eventHandler->m_id);
}
void EventManager::sendEventImmediately(std::shared_ptr<Event> event)
{
if (event)
{
std::set<unsigned int> eventHandlerIds;
{
std::scoped_lock<std::mutex> lock(m_eventHandlersMutex);
for (auto it : m_eventHandlers)
{
eventHandlerIds.insert(it.first);
}
}
for (unsigned int id : eventHandlerIds)
{
// this is necessary to allow HandleBaseEvent() to remove event handlers without causing a crash
EventHandlerBase *eventHandler = nullptr;
{
std::scoped_lock<std::mutex> lock(m_eventHandlersMutex);
auto it = m_eventHandlers.find(id);
if (it != m_eventHandlers.end())
{
eventHandler = it->second;
}
}
if (eventHandler)
{
eventHandler->handleBaseEvent(event);
}
}
}
}
void EventManager::addEvent(std::shared_ptr<Event> event)
{
if (event)
{
std::scoped_lock<std::mutex> lock(m_eventsMutex);
m_events.push_back(event);
}
}
void EventManager::processEvents()
{
std::vector<std::shared_ptr<Event>> events;
{
std::scoped_lock<std::mutex> lock(m_eventsMutex);
events = m_events;
m_events.clear();
}
std::set<unsigned int> eventHandlerIds;
{
std::scoped_lock<std::mutex> lock(m_eventHandlersMutex);
for (auto it : m_eventHandlers)
{
eventHandlerIds.insert(it.first);
}
}
for (std::shared_ptr<Event> event : events)
{
for (unsigned int id : eventHandlerIds)
{
// this is necessary to allow HandleBaseEvent() to remove event handlers without causing a crash
EventHandlerBase *eventHandler = nullptr;
{
std::scoped_lock<std::mutex> lock(m_eventHandlersMutex);
auto it = m_eventHandlers.find(id);
if (it != m_eventHandlers.end())
{
eventHandler = it->second;
}
}
if (eventHandler)
{
eventHandler->handleBaseEvent(event);
}
}
}
}
void EventManager::clearEvents()
{
std::scoped_lock<std::mutex> lock(m_eventsMutex);
m_events.clear();
}
bool EventManager::hasEvents() const
{
return !m_events.empty();
}