Newer
Older
Import / projects / Gameloft / core / EventSystem / EventSystem.cpp
#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;