roo_transceivers
API Documentation for roo_transceivers
Loading...
Searching...
No Matches
transceiver_collection.h
Go to the documentation of this file.
1#pragma once
2
4
5namespace roo_transceivers {
6
7/// Abstract transceiver interface used by `TransceiverCollection`.
9 public:
10 Transceiver() = default;
11 virtual ~Transceiver() = default;
12
13 virtual void getDescriptor(roo_transceivers_Descriptor& descriptor) const = 0;
14
15 virtual Measurement read(const SensorId& sensor) const = 0;
16 virtual bool write(const ActuatorId& actuator, float value) = 0;
17
18 virtual void requestUpdate() {}
19 virtual void addEventListener(EventListener* listener) = 0;
20 virtual void removeEventListener(EventListener* listener) = 0;
21};
22
24 public:
25 /// Entry pairing a device locator with a transceiver instance.
30
31 /// Creates an empty collection.
33
34 /// Creates a collection and registers the provided transceivers.
35 TransceiverCollection(std::vector<Entry> transceivers) {
36 for (auto& transceiver : transceivers) {
37 add(transceiver.locator, transceiver.instance);
38 }
39 }
40
41 /// Registers a transceiver under `locator`.
42 ///
43 /// Fails hard on duplicate locator.
44 void add(const DeviceLocator& locator, Transceiver* device) {
45 CHECK(transceivers_.insert(std::make_pair(locator, device)).second)
46 << "Duplicate device locator: " << locator;
47 device->addEventListener(this);
48 }
49
50 /// Removes transceiver identified by `locator`.
51 ///
52 /// Returns `true` if an entry was removed.
53 bool remove(const DeviceLocator& locator) {
54 auto itr = transceivers_.find(locator);
55 if (itr == transceivers_.end()) {
56 return false;
57 }
58 itr->second->removeEventListener(this);
59 transceivers_.erase(locator);
60 return true;
61 }
62
63 size_t deviceCount() const override { return transceivers_.size(); }
64
65 /// Iterates over device locators.
66 ///
67 /// Callback returning `false` interrupts iteration and this method returns
68 /// `false`. Returning `true` continues iteration.
70 std::function<bool(const DeviceLocator&)> callback) const override {
71 for (const auto& transceiver : transceivers_) {
72 if (!callback(transceiver.first)) return false;
73 }
74 return true;
75 }
76
77 /// Retrieves descriptor for a registered transceiver.
78 ///
79 /// Returns `false` when `locator` is unknown.
81 const DeviceLocator& locator,
82 roo_transceivers_Descriptor& descriptor) const override {
83 const auto& itr = transceivers_.find(locator);
84 if (itr == transceivers_.end()) return false;
85 itr->second->getDescriptor(descriptor);
86 return true;
87 }
88
89 /// Returns latest known measurement for `locator`.
90 ///
91 /// Unknown device or sensor returns initial/unspecified measurement.
92 Measurement read(const SensorLocator& locator) const override {
93 const auto& itr = transceivers_.find(locator.device_locator());
94 return (itr != transceivers_.end()) ? itr->second->read(locator.sensor_id())
95 : Measurement();
96 }
97
98 /// Writes to the addressed actuator.
99 ///
100 /// Returns `false` when target device/actuator is unknown or write fails.
101 bool write(const ActuatorLocator& locator, float value) override {
102 auto itr = transceivers_.find(locator.device_locator());
103 return (itr != transceivers_.end())
104 ? itr->second->write(locator.actuator_id(), value)
105 : false;
106 }
107
108 void requestUpdate() override {
109 for (const auto& transceiver : transceivers_) {
110 transceiver.second->requestUpdate();
111 }
112 }
113
114 virtual void addEventListener(EventListener* listener) {
115 listeners_.insert(listener);
116 }
117
118 virtual void removeEventListener(EventListener* listener) {
119 listeners_.erase(listener);
120 }
121
122 void devicesChanged() override {
123 for (auto listener : listeners_) {
124 listener->devicesChanged();
125 }
126 }
127
128 void newReadingsAvailable() override {
129 for (auto listener : listeners_) {
130 listener->newReadingsAvailable();
131 }
132 }
133
134 private:
135 roo_collections::FlatSmallHashMap<DeviceLocator, Transceiver*> transceivers_;
136 roo_collections::FlatSmallHashSet<EventListener*> listeners_;
137};
138
140 public:
141 /// Builds index maps for a static descriptor.
143 : descriptor_(std::move(descriptor)) {
144 for (size_t i = 0; i < descriptor.sensors_count; i++) {
145 sensors_[descriptor.sensors[i].id] = i;
146 }
147 for (size_t i = 0; i < descriptor.actuators_count; i++) {
148 actuators_[descriptor.actuators[i].id] = i;
149 }
150 }
151
153 return descriptor_;
154 }
155
156 /// Returns sensor index or `-1` if not found.
157 int resolveSensorIndex(const SensorId& id) const {
158 auto itr = sensors_.find(id);
159 return (itr == sensors_.end()) ? -1 : itr->second;
160 }
161
162 /// Returns actuator index or `-1` if not found.
163 int resolveActuatorIndex(const ActuatorId& id) const {
164 auto itr = actuators_.find(id);
165 return (itr == actuators_.end()) ? -1 : itr->second;
166 }
167
168 private:
169 roo_transceivers_Descriptor descriptor_;
170 roo_collections::FlatSmallHashMap<SensorId, int> sensors_;
171 roo_collections::FlatSmallHashMap<ActuatorId, int> actuators_;
172};
173
174/// Transceiver with statically defined descriptor.
175///
176/// Provides default implementations with input validation and listener
177/// management.
179 public:
180 /// `type` must outlive this transceiver.
182
183 void getDescriptor(roo_transceivers_Descriptor& descriptor) const override {
184 descriptor = type_->getDescriptor();
185 }
186
187 Measurement read(const SensorId& sensor) const override {
188 int idx = type_->resolveSensorIndex(sensor);
189 if (idx < 0) return Measurement();
190 return readFromSensor(idx);
191 }
192
193 bool write(const ActuatorId& actuator, float value) override {
194 int idx = type_->resolveActuatorIndex(actuator);
195 if (idx < 0) return false;
196 return writeToActuator(idx, value);
197 }
198
199 void addEventListener(EventListener* listener) override {
200 event_listeners_.insert(listener);
201 }
202
203 void removeEventListener(EventListener* listener) override {
204 event_listeners_.erase(listener);
205 }
206
207 protected:
208 /// Reads sensor by validated descriptor index.
209 virtual Measurement readFromSensor(int idx) const = 0;
210
211 /// Writes actuator by validated descriptor index.
212 virtual bool writeToActuator(int idx, float value) = 0;
213
215 for (auto* listener : event_listeners_) {
216 listener->newReadingsAvailable();
217 }
218 }
219
221 roo_collections::FlatSmallHashSet<EventListener*> event_listeners_;
222};
223
224/// Transceiver exposing one statically defined sensor and no actuators.
225///
226/// Provides validated defaults and listener management.
227class SimpleSensor : public Transceiver {
228 public:
229 /// Constructs single-sensor transceiver metadata.
231 : quantity_(quantity), id_(id) {}
232
233 void getDescriptor(roo_transceivers_Descriptor& descriptor) const override {
234 descriptor.sensors_count = 1;
235 strncpy(descriptor.sensors[0].id, id_.c_str(), SensorId::kCapacity);
236 descriptor.sensors[0].quantity = quantity_;
237 descriptor.actuators_count = 0;
238 }
239
240 Measurement read(const SensorId& sensor) const override {
241 if (sensor != id_) return Measurement();
242 return Measurement(quantity_, roo_time::Uptime::Now(), readFromSensor());
243 }
244
245 bool write(const ActuatorId& actuator, float value) override { return false; }
246
247 void addEventListener(EventListener* listener) override {
248 event_listeners_.insert(listener);
249 }
250
251 void removeEventListener(EventListener* listener) override {
252 event_listeners_.erase(listener);
253 }
254
255 protected:
256 virtual float readFromSensor() const = 0;
257
259 for (auto* listener : event_listeners_) {
260 listener->newReadingsAvailable();
261 }
262 }
263
266 roo_collections::FlatSmallHashSet<EventListener*> event_listeners_;
267};
268
269} // namespace roo_transceivers
Identifies actuator within a transceiver device.
Definition id.h:104
const DeviceLocator & device_locator() const
Returns the device locator.
Definition id.h:115
const ActuatorId & actuator_id() const
Returns the actuator id.
Definition id.h:124
Identifies a transceiver device by schema and device id.
Definition id.h:21
Listener for universe-level change notifications.
Definition notification.h:9
Measurement of a quantity at a specific time.
Definition measurement.h:11
Identifies sensor within a transceiver device.
Definition id.h:57
const SensorId & sensor_id() const
Returns the sensor id.
Definition id.h:76
const DeviceLocator & device_locator() const
Returns the device locator.
Definition id.h:67
Transceiver exposing one statically defined sensor and no actuators.
void addEventListener(EventListener *listener) override
virtual float readFromSensor() const =0
bool write(const ActuatorId &actuator, float value) override
Measurement read(const SensorId &sensor) const override
SimpleSensor(roo_transceivers_Quantity quantity, SensorId id="")
Constructs single-sensor transceiver metadata.
roo_transceivers_Quantity quantity_
void getDescriptor(roo_transceivers_Descriptor &descriptor) const override
void removeEventListener(EventListener *listener) override
roo_collections::FlatSmallHashSet< EventListener * > event_listeners_
Transceiver with statically defined descriptor.
Measurement read(const SensorId &sensor) const override
virtual bool writeToActuator(int idx, float value)=0
Writes actuator by validated descriptor index.
void getDescriptor(roo_transceivers_Descriptor &descriptor) const override
bool write(const ActuatorId &actuator, float value) override
roo_collections::FlatSmallHashSet< EventListener * > event_listeners_
SimpleTransceiver(const TransceiverType *type)
type must outlive this transceiver.
void removeEventListener(EventListener *listener) override
void addEventListener(EventListener *listener) override
virtual Measurement readFromSensor(int idx) const =0
Reads sensor by validated descriptor index.
void requestUpdate() override
Requests sensor reading update from underlying devices.
virtual void addEventListener(EventListener *listener)
Registers a listener for device-set and reading update events.
bool write(const ActuatorLocator &locator, float value) override
Writes to the addressed actuator.
size_t deviceCount() const override
Returns the total number of transceiver devices in this universe.
TransceiverCollection()=default
Creates an empty collection.
bool getDeviceDescriptor(const DeviceLocator &locator, roo_transceivers_Descriptor &descriptor) const override
Retrieves descriptor for a registered transceiver.
void devicesChanged() override
Called when the set of devices changes.
void newReadingsAvailable() override
Called when new readings are available.
virtual void removeEventListener(EventListener *listener)
Removes a previously registered event listener.
Measurement read(const SensorLocator &locator) const override
Returns latest known measurement for locator.
void add(const DeviceLocator &locator, Transceiver *device)
Registers a transceiver under locator.
bool remove(const DeviceLocator &locator)
Removes transceiver identified by locator.
bool forEachDevice(std::function< bool(const DeviceLocator &)> callback) const override
Iterates over device locators.
TransceiverCollection(std::vector< Entry > transceivers)
Creates a collection and registers the provided transceivers.
TransceiverType(roo_transceivers_Descriptor descriptor)
Builds index maps for a static descriptor.
int resolveSensorIndex(const SensorId &id) const
Returns sensor index or -1 if not found.
const roo_transceivers_Descriptor & getDescriptor() const
int resolveActuatorIndex(const ActuatorId &id) const
Returns actuator index or -1 if not found.
Abstract transceiver interface used by TransceiverCollection.
virtual void removeEventListener(EventListener *listener)=0
virtual void addEventListener(EventListener *listener)=0
virtual void getDescriptor(roo_transceivers_Descriptor &descriptor) const =0
virtual bool write(const ActuatorId &actuator, float value)=0
virtual Measurement read(const SensorId &sensor) const =0
virtual ~Transceiver()=default
An abstract collection of transceiver devices.
Definition universe.h:19
roo_collections::SmallString< 24 > SensorId
Sensor identifier (short string).
Definition id.h:16
roo_collections::SmallString< 24 > ActuatorId
Actuator identifier (short string).
Definition id.h:18
Definition id.h:151
enum _roo_transceivers_Quantity roo_transceivers_Quantity
roo_transceivers_Descriptor_Sensor sensors[16]
roo_transceivers_Descriptor_Actuator actuators[16]
Entry pairing a device locator with a transceiver instance.