herald  2.0.0
sensor_delegate.h
1 // Copyright 2020-2021 Herald Project Contributors
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 
5 #ifndef HERALD_SENSOR_DELEGATE_H
6 #define HERALD_SENSOR_DELEGATE_H
7 
8 #include "datatype/sensor_type.h"
9 #include "datatype/proximity.h"
10 #include "datatype/payload_data.h"
11 #include "datatype/target_identifier.h"
12 #include "datatype/immediate_send_data.h"
13 #include "datatype/location.h"
14 #include "datatype/sensor_state.h"
15 
16 #include <variant>
17 #include <array>
18 
19 namespace herald {
20 
21 using namespace datatype;
22 
23 // /// \brief Base interface for classes wishing to implement callbacks for core low-level Herald proximity and presence events.
24 // class SensorDelegate {
25 // public:
26 // SensorDelegate() = default;
27 // virtual ~SensorDelegate() = default;
28 
29 
30 // /// Detection of a target with an ephemeral identifier, e.g. BLE central detecting a BLE peripheral.
31 // virtual void sensor(SensorType sensor, const TargetIdentifier& didDetect) = 0;
32 
33 // /// Read payload data from target, e.g. encrypted device identifier from BLE peripheral after successful connection.
34 // virtual void sensor(SensorType sensor, const PayloadData& didRead, const TargetIdentifier& fromTarget) = 0;
35 
36 // /// Receive written immediate send data from target, e.g. important timing signal.
37 // virtual void sensor(SensorType sensor, const ImmediateSendData& didReceive, const TargetIdentifier& fromTarget) = 0;
38 
39 // /// Read payload data of other targets recently acquired by a target, e.g. Android peripheral sharing payload data acquired from nearby iOS peripherals.
40 // virtual void sensor(SensorType sensor, const std::vector<PayloadData>& didShare, const TargetIdentifier& fromTarget) = 0;
41 
42 // /// Measure proximity to target, e.g. a sample of RSSI values from BLE peripheral.
43 // virtual void sensor(SensorType sensor, const Proximity& didMeasure, const TargetIdentifier& fromTarget) = 0;
44 
45 // /// Detection of time spent at location, e.g. at specific restaurant between 02/06/2020 19:00 and 02/06/2020 21:00
46 // template <typename LocationT>
47 // void sensor(SensorType sensor, const Location<LocationT>& didVisit) {}
48 
49 // /// Measure proximity to target with payload data. Combines didMeasure and didRead into a single convenient delegate method
50 // virtual void sensor(SensorType sensor, const Proximity& didMeasure, const TargetIdentifier& fromTarget, const PayloadData& withPayload) = 0;
51 
52 // /// Sensor state update
53 // virtual void sensor(SensorType sensor, const SensorState& didUpdateState) = 0;
54 // };
55 
56 // TODO move this into a general header
57 template<typename F, typename... Args, typename = decltype(std::declval<F>()(std::declval<Args&&>()...))>
58 std::true_type isValidImpl(void*);
59 
60 template<typename F, typename... Args>
61 std::false_type isValidImpl(...);
62 
63 inline constexpr auto isValid = [] (auto f) {
64  return [](auto&&... args) {
65  return decltype(isValidImpl<decltype(f),decltype(args)&&...>(nullptr)){};
66  };
67 };
68 
69 template<typename T>
70 struct TypeT {
71  using Type = T;
72 };
73 
74 template<typename T>
75 constexpr auto type = TypeT<T>{};
76 
77 template<typename T>
78 T valueT(TypeT<T>);
79 
80 
81 constexpr auto hasSensorFunction = isValid(
82  [](auto&& s,auto&& sensor,auto&& didRead,auto&& fromTarget) ->
83  decltype(((decltype(s))s).get().sensor(sensor,didRead,fromTarget)) {}
84 );
85 // template<typename T,typename SE, typename DR, typename FT>
86 // using HasSensorFunctionT = decltype(hasSensorFunction(std::declval<T>(),std::declval<SE>(),std::declval<DR>(),std::declval<FT>()));
87 template<typename T,typename... Args>
88 using HasSensorFunctionT = decltype(hasSensorFunction(std::declval<T>(),std::declval<Args>()...));
89 template<typename T,typename... Args>
90 constexpr auto HasSensorFunctionV = HasSensorFunctionT<T,Args...>::value;
91 
93 template <typename... SensorDelegateTs>
95 public:
96  static constexpr std::size_t Size = sizeof...(SensorDelegateTs);
97 
98  SensorDelegateSet(SensorDelegateTs&... dels) :
99  //delegates({std::variant<std::reference_wrapper<SensorDelegateTs&...>>(std::reference_wrapper<SensorDelegateTs&...>(dels...))}) {
100  // delegates(std::experimental::make_array({std::reference_wrapper<SensorDelegateTs&...>(dels...)})) {
101  delegates(std::array<
102  std::variant<std::reference_wrapper<SensorDelegateTs>...>
103  ,Size
104  >({std::variant<std::reference_wrapper<SensorDelegateTs>...>(dels)...})) {
105  // addDelegates(0,dels...);
106  }
107 
108  // auto begin() -> decltype(std::declval<std::array<
109  // std::variant<std::reference_wrapper<SensorDelegateTs>...>
110  // ,Size
111  // >>().begin()) {
112  // return delegates.begin();
113  // }
114 
115  // auto end() -> decltype(std::declval<std::array<
116  // std::variant<std::reference_wrapper<SensorDelegateTs>...>
117  // ,Size
118  // >>().end()) {
119  // return delegates.end();
120  // }
121 
123  void sensor(SensorType sensor, const TargetIdentifier& didDetect) {
124  for (auto& delegateV : delegates) {
125  std::visit([sensor,didDetect](auto&& arg) {
126  // ONLY INVOKE IF WE KNOW THIS FUNCTION EXISTS
127  if constexpr (HasSensorFunctionV<decltype(arg),decltype(sensor),decltype(didDetect)>) {
128  ((decltype(arg))arg).get().sensor(sensor,didDetect); // cast to call derived class function
129  }
130  }, delegateV);
131  }
132  }
133 
135  void sensor(SensorType sensor, const PayloadData& didRead, const TargetIdentifier& fromTarget) {
136  for (auto& delegateV : delegates) {
137  std::visit([sensor,didRead,fromTarget](auto&& arg) {
138  // ONLY INVOKE IF WE KNOW THIS FUNCTION EXISTS
139  if constexpr (HasSensorFunctionV<decltype(arg),decltype(sensor),decltype(didRead),decltype(fromTarget)>) {
140  ((decltype(arg))arg).get().sensor(sensor,didRead,fromTarget); // cast to call derived class function
141  }
142  }, delegateV);
143  }
144  }
145 
147  void sensor(SensorType sensor, const ImmediateSendData& didReceive, const TargetIdentifier& fromTarget) {
148  for (auto& delegateV : delegates) {
149  std::visit([sensor,didReceive,fromTarget](auto&& arg) {
150  // ONLY INVOKE IF WE KNOW THIS FUNCTION EXISTS
151  if constexpr (HasSensorFunctionV<decltype(arg),decltype(sensor),decltype(didReceive),decltype(fromTarget)>) {
152  ((decltype(arg))arg).get().sensor(sensor,didReceive,fromTarget); // cast to call derived class function
153  }
154  }, delegateV);
155  }
156  }
157 
159  void sensor(SensorType sensor, const DataSections<8>& didShare, const TargetIdentifier& fromTarget) {
160  for (auto& delegateV : delegates) {
161  std::visit([sensor,didShare,fromTarget](auto&& arg) {
162  // ONLY INVOKE IF WE KNOW THIS FUNCTION EXISTS
163  if constexpr (HasSensorFunctionV<decltype(arg),decltype(sensor),decltype(didShare),decltype(fromTarget)>) {
164  ((decltype(arg))arg).get().sensor(sensor,didShare,fromTarget); // cast to call derived class function
165  }
166  }, delegateV);
167  }
168  }
169 
171  void sensor(SensorType sensor, const Proximity& didMeasure, const TargetIdentifier& fromTarget) {
172  for (auto& delegateV : delegates) {
173  std::visit([sensor,didMeasure,fromTarget](auto&& arg) {
174  // ONLY INVOKE IF WE KNOW THIS FUNCTION EXISTS
175  if constexpr (HasSensorFunctionV<decltype(arg),decltype(sensor),decltype(didMeasure),decltype(fromTarget)>) {
176  ((decltype(arg))arg).get().sensor(sensor,didMeasure,fromTarget); // cast to call derived class function
177  }
178  }, delegateV);
179  }
180  }
181 
183  template <typename LocationT>
184  void sensor(SensorType sensor, const Location<LocationT>& didVisit) {
185  for (auto& delegateV : delegates) {
186  std::visit([sensor,didVisit](auto&& arg) {
187  // ONLY INVOKE IF WE KNOW THIS FUNCTION EXISTS
188  if constexpr (HasSensorFunctionV<decltype(arg),decltype(sensor),decltype(didVisit)>) {
189  ((decltype(arg))arg).get().sensor(sensor,didVisit); // cast to call derived class function
190  }
191  }, delegateV);
192  }
193  }
194 
196  void sensor(SensorType sensor, const Proximity& didMeasure, const TargetIdentifier& fromTarget, const PayloadData& withPayload) {
197  for (auto& delegateV : delegates) {
198  std::visit([sensor,didMeasure,fromTarget,withPayload](auto&& arg) {
199  // ONLY INVOKE IF WE KNOW THIS FUNCTION EXISTS
200  if constexpr (HasSensorFunctionV<decltype(arg),decltype(sensor),decltype(didMeasure),decltype(fromTarget),decltype(withPayload)>) {
201  ((decltype(arg))arg).get().sensor(sensor,didMeasure,fromTarget,withPayload); // cast to call derived class function
202  }
203  }, delegateV);
204  }
205  }
206 
208  void sensor(SensorType sensor, const SensorState& didUpdateState) {
209  for (auto& delegateV : delegates) {
210  std::visit([sensor,didUpdateState](auto&& arg) {
211  // ONLY INVOKE IF WE KNOW THIS FUNCTION EXISTS
212  if constexpr (HasSensorFunctionV<decltype(arg),decltype(sensor),decltype(didUpdateState)>) {
213  ((decltype(arg))arg).get().sensor(sensor,didUpdateState); // cast to call derived class function
214  }
215  }, delegateV);
216  }
217  }
218 
219 private:
220  std::array<
221  std::variant<std::reference_wrapper<SensorDelegateTs>...>
222  ,
223  Size
224  > delegates;
225 
226  // template <typename LastT>
227  // constexpr void addDelegates(int nextPos,LastT& last) {
228  // delegates[nextPos] = std::reference_wrapper<LastT>(last);
229  // }
230 
231  // template <typename FirstT, typename SecondT, typename... RestT>
232  // constexpr void addDelegates(int nextPos,FirstT& first, SecondT& second, RestT&... rest) {
233  // delegates[nextPos] = std::reference_wrapper<FirstT>(first);
234  // ++nextPos;
235  // addDelegates(nextPos,second,rest...);
236  // }
237 };
238 
239 
240 } // end namespace
241 
242 #endif
A set of variant typed Sensor Delegate instances. Delegate callbacks can be invoked on the whole set,...
Definition: sensor_delegate.h:94
void sensor(SensorType sensor, const SensorState &didUpdateState)
Sensor state update.
Definition: sensor_delegate.h:208
void sensor(SensorType sensor, const Location< LocationT > &didVisit)
Detection of time spent at location, e.g. at specific restaurant between 02/06/2020 19:00 and 02/06/2...
Definition: sensor_delegate.h:184
void sensor(SensorType sensor, const TargetIdentifier &didDetect)
Detection of a target with an ephemeral identifier, e.g. BLE central detecting a BLE peripheral.
Definition: sensor_delegate.h:123
void sensor(SensorType sensor, const PayloadData &didRead, const TargetIdentifier &fromTarget)
Read payload data from target, e.g. encrypted device identifier from BLE peripheral after successful ...
Definition: sensor_delegate.h:135
void sensor(SensorType sensor, const Proximity &didMeasure, const TargetIdentifier &fromTarget)
Measure proximity to target, e.g. a sample of RSSI values from BLE peripheral.
Definition: sensor_delegate.h:171
void sensor(SensorType sensor, const Proximity &didMeasure, const TargetIdentifier &fromTarget, const PayloadData &withPayload)
Measure proximity to target with payload data. Combines didMeasure and didRead into a single convenie...
Definition: sensor_delegate.h:196
void sensor(SensorType sensor, const ImmediateSendData &didReceive, const TargetIdentifier &fromTarget)
Receive written immediate send data from target, e.g. important timing signal.
Definition: sensor_delegate.h:147
void sensor(SensorType sensor, const DataSections< 8 > &didShare, const TargetIdentifier &fromTarget)
Read payload data of other targets recently acquired by a target, e.g. Android peripheral sharing pay...
Definition: sensor_delegate.h:159
Represents a fixed array of Data references using the default memory arena that tracks its own in-use...
Definition: data.h:513
Definition: immediate_send_data.h:13
Definition: location.h:18
Definition: payload_data.h:13
Definition: target_identifier.h:17
SensorType
Sensor type as qualifier for target identifier.
Definition: sensor_type.h:14
SensorState
Definition: sensor_state.h:11
Acts as a non-global memory arena for arbitrary classes.
Definition: aggregates.h:15
Definition: sensor_delegate.h:70
Definition: proximity.h:17