hmbdc
simplify-high-performance-messaging-programming
 All Classes Namespaces Functions Variables Friends Pages
MessageDispacher.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 
4 #include "hmbdc/app/Message.hpp"
5 #include "hmbdc/app/Logger.hpp"
6 #include "hmbdc/MetaUtils.hpp"
7 
8 namespace hmbdc { namespace app {
9 
10 namespace messagehandler_detail {
11 template <typename CcClient, typename Message>
12 struct dispatcher {
13  bool operator()(CcClient& c, MessageHead& m) {
14  if (m.typeTag == Message::typeTag) {
15  HMBDC_LOG_r(c.hmbdcName(), this, " received ", m.get<Message>());
16  c.handleMessageCb(m.get<Message>());
17  using Wrap = MessageWrap<Message>;
18  auto& wrap = static_cast<Wrap&>(m);
19  wrap.~Wrap();
20  return true;
21  }
22  return false;
23  }
24 };
25 
26 template <typename CcClient>
27 struct dispatcher<CcClient, JustBytes> {
28  bool operator()(CcClient& c, MessageHead& m) {
29  if (m.typeTag > 1000) { //only deliver user messages
30  auto j = &m.get<uint8_t>();
31  HMBDC_LOG_r(c, this, " received bytes typeTag=", m.typeTag);
32  c.handleJustBytesCb(m.typeTag, j);
33  }
34  return true;
35  }
36 };
37 
38 template<class T, class U>
39 struct ascending_by_tag
40 : std::integral_constant<bool, T::typeTag < U::typeTag>
41 {};
42 
43 
44 template <typename CcClient, typename ... Messages>
45 struct SeqMessageDispacher {
46  bool operator()(CcClient&, MessageHead&) const{return false;}
47 };
48 
49 template <typename CcClient, typename M, typename ... Messages>
50 struct SeqMessageDispacher<CcClient, std::tuple<M, Messages...>> {
51  bool operator()(CcClient& c, MessageHead& e) const {
52  if (!dispatcher<CcClient, M>()(c, e))
53  return SeqMessageDispacher<CcClient, std::tuple<Messages ...>>()(c, e);
54  else
55  return true;
56  }
57 };
58 
59 }
60 
61 #if __GNUC_PREREQ(9,0)
62 template <typename CcClient, typename ... Messages>
63 struct MessageDispacher {
64  bool operator()(CcClient&, MessageHead&) const;
65 };
66 
67 template <typename CcClient, typename ... Messages>
68 struct MessageDispacher<CcClient, std::tuple<Messages...>> {
69  static_assert(
70  index_in_tuple<JustBytes, std::tuple<Messages...>>::value == sizeof...(Messages)
71  || sizeof...(Messages) <= 16
72  , "JustBytes cannot be combined with too many other types");
73 
74  bool operator()(CcClient& c, MessageHead& e) const {
75  if constexpr (sizeof...(Messages) > 16) {
76  using SortedTupleMessages
77  = typename sort_tuple<messagehandler_detail::ascending_by_tag
78  , std::tuple<Messages...>>::type;
79 
80  return bsearch_tuple<SortedTupleMessages>()(
81  [&c, &e](auto* t) {
82  using M = typename std::remove_reference<decltype(*t)>::type;
83  if (messagehandler_detail::dispatcher<CcClient, M>()(c, e)) {
84  return 0;
85  }
86  if (e.typeTag < M::typeTag) return -1;
87  return 1;
88  }
89  );
90  } else {
91  return messagehandler_detail::SeqMessageDispacher<
92  CcClient, std::tuple<Messages ...>>()(c, e);
93  }
94  }
95 };
96 
97 #else
98 
99 template <typename CcClient, typename ... Messages>
100 using MessageDispacher = messagehandler_detail::SeqMessageDispacher<
101  CcClient, Messages ...>;
102 #endif
103 
104 }}
Definition: MessageDispacher.hpp:12
Definition: Message.hpp:78
A special type of message only used on the receiving side.
Definition: Message.hpp:182
Definition: Message.hpp:112