All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
GenericEventProxy.h
1 #pragma once
2 
3 #include "ICallback.h"
4 #include "IEvent.h"
5 #include "IGenericEventProvider.h"
6 
7 #include <type_traits>
8 #include <unordered_map>
9 
10 namespace Eegeo
11 {
12  namespace Helpers
13  {
14  template <typename TEvent>
15  class GenericEventProxy : public TEvent::CallbackType, public IGenericEventProvider<TEvent, typename std::remove_const<typename TEvent::Param0>::type>
16  {
17  public:
19  using ParamType = typename TEvent::Param0;
20 
21  virtual TEvent& GetEvent(const typename GenericEventProxy::KeyType& key) override
22  {
23  auto itr = m_eventMap.find(key);
24  if (itr == m_eventMap.end())
25  {
26  itr = m_eventMap.emplace(std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(*this, key)).first;
27  }
28  return itr->second;
29  }
30 
31  virtual void operator()(ParamType& key) const override
32  {
33  auto itr = m_eventMap.find(key);
34  if (itr != m_eventMap.end())
35  {
36  itr->second.Raise(key);
37  }
38  }
39 
40  private:
41  // For now, there's no TEvent2, so we don't need to deal with picking the right class.
42  // Really, events should be variadic templates with perfect forwarding.
43  struct ConcreteEvent : public TEvent1<TEvent>
44  {
45  ConcreteEvent(GenericEventProxy<TEvent>& parent, const KeyType& key)
46  : parent(parent)
47  , key(key)
48  {}
49 
50  void Unregister(typename TEvent::CallbackType& callback) override
51  {
53  if (this->m_callbacks.empty())
54  {
55  parent.m_eventMap.erase(key);
56  }
57  }
58 
60  KeyType key;
61  };
62 
63  std::unordered_map<typename GenericEventProxy::KeyType, ConcreteEvent> m_eventMap;
64  };
65  }
66 }