#include "EventSystem.h"
#include <algorithm>
//////////////////////////////////////////////////////////////////////////
// EventReceiverID
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
EventReceiverID::LifetimeTracker::~LifetimeTracker()
{
for (auto& callback : m_RegisteredCallbacks)
{
std::get<0>(callback)(m_Receiver, std::get<1>(callback));
}
m_RegisteredCallbacks.clear();
}
//////////////////////////////////////////////////////////////////////////
EventReceiverID::EventReceiverID()
{
m_Lifetime.m_Receiver = this;
}
//////////////////////////////////////////////////////////////////////////
void EventReceiverID::AddUnregisterCallback(UnregisterCallback call, EventTypeSinkBase* sink)
{
std::lock_guard<std::recursive_mutex> lock(m_CallbackLock);
m_Lifetime.m_RegisteredCallbacks.emplace_back(call, sink);
}
//////////////////////////////////////////////////////////////////////////
void EventReceiverID::RemoveUnregisterCallback(UnregisterCallback call, EventTypeSinkBase* sink)
{
std::lock_guard<std::recursive_mutex> lock(m_CallbackLock);
auto pred = [&](const std::tuple<UnregisterCallback, EventTypeSinkBase*>& el)
{
return std::get<0>(el) == call && std::get<1>(el) == sink;
};
auto it = std::find_if(m_Lifetime.m_RegisteredCallbacks.begin(), m_Lifetime.m_RegisteredCallbacks.end(), pred);
if (it != m_Lifetime.m_RegisteredCallbacks.end())
{
m_Lifetime.m_RegisteredCallbacks.erase(it);
}
// There should only be one callback/sink combo matching the input
assert(std::find_if(m_Lifetime.m_RegisteredCallbacks.begin(), m_Lifetime.m_RegisteredCallbacks.end(), pred) ==
m_Lifetime.m_RegisteredCallbacks.end());
}
//////////////////////////////////////////////////////////////////////////
void EventReceiverID::RemoveUnregisterCallback(EventTypeSinkBase* sink)
{
std::lock_guard<std::recursive_mutex> lock(m_CallbackLock);
auto pred = [&](const std::tuple<UnregisterCallback, EventTypeSinkBase*>& el)
{
return std::get<1>(el) == sink;
};
// There can be multiple receivers using the same sink so we have to iterate
auto it = m_Lifetime.m_RegisteredCallbacks.begin();
while (it != m_Lifetime.m_RegisteredCallbacks.end())
{
auto found = std::find_if(it, m_Lifetime.m_RegisteredCallbacks.end(), pred);
if (found != m_Lifetime.m_RegisteredCallbacks.end())
{
it = m_Lifetime.m_RegisteredCallbacks.erase(found);
}
else
break;
}
}
//////////////////////////////////////////////////////////////////////////
bool EventReceiverID::HasRegisteredSinks()
{
std::lock_guard<std::recursive_mutex> lock(m_CallbackLock);
return !m_Lifetime.m_RegisteredCallbacks.empty();
}
//////////////////////////////////////////////////////////////////////////
// EventSink
//////////////////////////////////////////////////////////////////////////
std::shared_ptr<EventSink> EventSink::Global;