All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
DispatchQueue.h
1 // Copyright eeGeo Ltd (2012-2015), All Rights Reserved
2 
3 #pragma once
4 
5 #include "Types.h"
6 #include "CatalogBinding.h"
7 #include "MessageQueue.h"
8 
9 namespace Eegeo
10 {
11  namespace Messaging
12  {
14  {
15  public:
16  virtual ~MessageInfo() {};
17  virtual void Dispatch() = 0;
18  };
19 
20  template <typename TMessageCatalog>
22  {
23  private:
24  template <typename TMessage>
25  class TypedMessageInfo : public MessageInfo
26  {
27  private:
28  TMessage m_message;
29  TMessageCatalog& m_catalog;
30  public:
31  TypedMessageInfo(const TMessage& message, TMessageCatalog& catalog)
32  : m_message(message)
33  , m_catalog(catalog)
34  {
35  }
36 
37  void Dispatch()
38  {
40  binding.Dispatch(m_message);
41  }
42  };
43 
44  template<typename TMessage>
45  struct HandlesMessage
46  {
47  typedef char (&NotHandled)[1];
48  typedef char (&Handled)[2];
49  static Handled CheckImplements(Eegeo::Messaging::CatalogBinding<TMessage>*);
50  static NotHandled CheckImplements(...);
51  static const bool IsHandled = sizeof(CheckImplements(static_cast<TMessageCatalog*>(0))) == sizeof(Handled);
52  };
53 
54  template<bool Condition, typename ReturnType = void>
55  struct Conditional
56  {
57  typedef ReturnType rt;
58  };
59 
60  template<typename ReturnType>
61  struct Conditional<false, ReturnType> { };
62 
63  template<typename TMessage>
64  typename Conditional<HandlesMessage<TMessage>::IsHandled>::rt EnqueueIfHandled(const TMessage& message)
65  {
66  // message is handled by this catalog...
67  m_messages.Enqueue(new TypedMessageInfo<TMessage>(message, m_catalog));
68  }
69 
70  template<typename TMessage>
71  typename Conditional<!HandlesMessage<TMessage>::IsHandled>::rt EnqueueIfHandled(const TMessage& message)
72  {
73  // message is not handled by this catalog...
74  }
75 
76  TMessageCatalog m_catalog;
78 
79  public:
80 
81  template <typename TMessage>
82  void TryEnqueue(const TMessage& message)
83  {
84  EnqueueIfHandled(message);
85  }
86 
87  template <typename TMessage>
88  void Subscribe(Eegeo::Helpers::ICallback1<const TMessage&>& handler)
89  {
91  binding.Subscribe(handler);
92  }
93 
94  template <typename TMessage>
95  void Unsubscribe(Eegeo::Helpers::ICallback1<const TMessage&>& handler)
96  {
98  binding.Unsubscribe(handler);
99  }
100 
101  void Flush()
102  {
103  MessageInfo* info;
104  while (m_messages.TryDequeue(info))
105  {
106  info->Dispatch();
107  delete info;
108  }
109  }
110  };
111  }
112 }