37template <
typename T>
class Group {
41 typename std::vector<T*>::iterator _it;
44 iterator(
typename std::vector<T*>::iterator it)
46 T& operator*()
const {
return **_it; }
47 T* operator->()
const {
return *_it; }
48 iterator& operator++() {
52 bool operator!=(
const iterator& other)
const {
return _it != other._it; }
53 bool operator==(
const iterator& other)
const {
return _it == other._it; }
60 class const_iterator {
61 typename std::vector<T*>::const_iterator _it;
64 const_iterator(
typename std::vector<T*>::const_iterator it)
66 const T& operator*()
const {
return **_it; }
67 const T* operator->()
const {
return *_it; }
68 const_iterator& operator++() {
72 bool operator!=(
const const_iterator& other)
const {
return _it != other._it; }
73 bool operator==(
const const_iterator& other)
const {
return _it == other._it; }
77 explicit Group(std::vector<T*> devices)
78 : _devices(std::move(devices)) {}
82 const T&
operator[](std::size_t i)
const {
return *_devices[i]; }
85 std::size_t
size()
const {
return _devices.size(); }
88 bool empty()
const {
return _devices.empty(); }
91 std::vector<T*>
get()
const {
return _devices; }
114 auto subs = std::make_shared<std::vector<subscription::Subscription> >();
115 for (
auto* dev : _devices) {
116 subs->push_back(dev->subscribe(callback));
120 for (
auto& s : *subs)
140 const std::size_t n = _devices.size();
143 std::vector<typename U::MeasurementType> buffer;
144 std::vector<bool> received;
145 std::size_t count = 0;
146 std::size_t expected = 0;
147 std::function<void(
const std::vector<typename U::MeasurementType>&)> callback;
150 auto state = std::make_shared<FrameState>();
151 state->buffer.resize(n);
152 state->received.resize(n,
false);
155 state->callback = std::move(callback);
157 auto subs = std::make_shared<std::vector<subscription::Subscription> >();
158 for (std::size_t i = 0; i < n; ++i) {
159 subs->push_back(_devices[i]->
subscribe([state, i](
const typename U::MeasurementType& m) {
160 state->buffer[i] = m;
161 if (!state->received[i]) {
162 state->received[i] =
true;
165 if (state->count == state->expected) {
166 state->callback(state->buffer);
168 std::fill(state->received.begin(), state->received.end(),
false);
176 for (
auto& s : *subs)
183 std::vector<T*> _devices;
Opaque token identifying a subscription.
RAII wrapper pairing a SubscriberToken with its cancel function.
Const dereferencing iterator so range-for over a const Group<T> yields const T&.
Definition Group.hpp:60
iterator end()
Past-the-end iterator (mutable).
Definition Group.hpp:96
std::vector< T * > get() const
Get the underlying vector of device pointers.
Definition Group.hpp:91
const_iterator begin() const
Begin iterator (const).
Definition Group.hpp:98
subscription::Subscription subscribe(std::function< void(const typename U::MeasurementType &)> callback)
Subscribe to all devices in the group.
Definition Group.hpp:113
T & operator[](std::size_t i)
Access device by index (returns reference).
Definition Group.hpp:81
iterator begin()
Begin iterator (mutable).
Definition Group.hpp:94
std::size_t size() const
Number of devices in this group.
Definition Group.hpp:85
const_iterator end() const
Past-the-end iterator (const).
Definition Group.hpp:100
bool empty() const
Whether the group is empty.
Definition Group.hpp:88
subscription::Subscription subscribeAll(std::function< void(const std::vector< typename U::MeasurementType > &)> callback)
Subscribe to all devices in the group with synchronized frame delivery.
Definition Group.hpp:139
Move-only RAII wrapper that pairs a SubscriberToken with an unsubscribe callable. Destroying a Subscr...
Definition Subscription.hpp:32
static SubscriberToken getNextToken() noexcept
Get the next token.
Definition SubscriberToken.hpp:43