ChimeraTK-ApplicationCore 04.08.00
Loading...
Searching...
No Matches
ArrayAccessor.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#pragma once
4
5#include "Application.h"
7
8#include <ChimeraTK/OneDRegisterAccessor.h>
9#include <ChimeraTK/SystemTags.h>
10
11#include <boost/smart_ptr/shared_ptr.hpp>
12#include <boost/thread.hpp>
13
14#include <string>
15
16namespace ChimeraTK {
17
18 /********************************************************************************************************************/
19
23 template<typename UserType>
24 class ArrayAccessor : public ChimeraTK::OneDRegisterAccessor<UserType>,
25 public InversionOfControlAccessor<ArrayAccessor<UserType>> {
26 public:
28 void replace(const ChimeraTK::NDRegisterAccessorAbstractor<UserType>& newAccessor) = delete;
31 using ChimeraTK::OneDRegisterAccessor<UserType>::operator=;
32
35
38
39 bool write(ChimeraTK::VersionNumber versionNumber) = delete;
40 bool writeDestructively(ChimeraTK::VersionNumber versionNumber) = delete;
42 const std::vector<UserType>& newValue, VersionNumber versionNumber, DataValidity validity) = delete;
43 void setAndWrite(const std::vector<UserType>& newValue, VersionNumber versionNumber) = delete;
44
45 bool write();
46
48
49 void writeIfDifferent(const std::vector<UserType>& newValue);
50
51 void setAndWrite(const std::vector<UserType>& newValue);
52
53 using value_type = UserType;
54
56
57 protected:
58 friend class InversionOfControlAccessor<ArrayAccessor<UserType>>;
59
60 ArrayAccessor(Module* owner, const std::string& name, VariableDirection direction, std::string unit,
61 size_t nElements, UpdateMode mode, const std::string& description,
62 const std::unordered_set<std::string>& tags = {});
63
65 ArrayAccessor() = default;
66 };
67
68 /********************************************************************************************************************/
69
71 template<typename UserType>
72 class ArrayPushInput : public ArrayAccessor<UserType> {
73 public:
74 ArrayPushInput(Module* owner, const std::string& name, std::string unit, size_t nElements,
75 const std::string& description, const std::unordered_set<std::string>& tags = {});
76 ArrayPushInput() = default;
77 using ArrayAccessor<UserType>::operator=;
78 };
79
80 /********************************************************************************************************************/
81
83 template<typename UserType>
84 class ArrayPollInput : public ArrayAccessor<UserType> {
85 public:
86 ArrayPollInput(Module* owner, const std::string& name, std::string unit, size_t nElements,
87 const std::string& description, const std::unordered_set<std::string>& tags = {});
88 ArrayPollInput() = default;
89 void read() { this->readLatest(); }
90 using ArrayAccessor<UserType>::operator=;
91 };
92
93 /********************************************************************************************************************/
94
96 template<typename UserType>
97 class ArrayOutput : public ArrayAccessor<UserType> {
98 public:
99 ArrayOutput(Module* owner, const std::string& name, std::string unit, size_t nElements,
100 const std::string& description, const std::unordered_set<std::string>& tags = {});
101 ArrayOutput() = default;
102 using ArrayAccessor<UserType>::operator=;
103 };
104
105 /********************************************************************************************************************/
106
109 template<typename UserType>
110 class ArrayPushInputWB : public ArrayAccessor<UserType> {
111 public:
112 ArrayPushInputWB(Module* owner, const std::string& name, std::string unit, size_t nElements,
113 const std::string& description, const std::unordered_set<std::string>& tags = {});
114 ArrayPushInputWB() = default;
115 using ArrayAccessor<UserType>::operator=;
116 };
117
118 /********************************************************************************************************************/
119
122 template<typename UserType>
123 class ArrayOutputPushRB : public ArrayAccessor<UserType> {
124 public:
125 ArrayOutputPushRB(Module* owner, const std::string& name, std::string unit, size_t nElements,
126 const std::string& description, const std::unordered_set<std::string>& tags = {});
127 ArrayOutputPushRB() = default;
128 using ArrayAccessor<UserType>::operator=;
129 };
130
131 /********************************************************************************************************************/
132
134 template<typename UserType>
135 class ArrayOutputRB : public ArrayAccessor<UserType> {
136 public:
137 [[deprecated]] ArrayOutputRB(Module* owner, const std::string& name, std::string unit, size_t nElements,
138 const std::string& description, const std::unordered_set<std::string>& tags = {});
139 ArrayOutputRB() = default;
140 using ArrayAccessor<UserType>::operator=;
141 };
142
143 /********************************************************************************************************************/
144
145 template<typename UserType>
146 class ArrayOutputReverseRecovery : public ArrayAccessor<UserType> {
147 public:
148 ArrayOutputReverseRecovery(Module* owner, const std::string& name, std::string unit, size_t nElements,
149 const std::string& description, const std::unordered_set<std::string>& tags = {});
151 using ArrayAccessor<UserType>::operator=;
152 };
153
154 /********************************************************************************************************************/
155
157 template<typename UserType>
159 public:
160 ArrayPushInputNoInitialValue(Module* owner, const std::string& name, std::string unit, size_t nElements,
161 const std::string& description, const std::unordered_set<std::string>& tags = {});
163 using ArrayAccessor<UserType>::operator=;
164 };
165
166 /********************************************************************************************************************/
167
169 template<typename UserType>
171 public:
172 ArrayPollInputNoInitialValue(Module* owner, const std::string& name, std::string unit, size_t nElements,
173 const std::string& description, const std::unordered_set<std::string>& tags = {});
175 void read() { this->readLatest(); }
176 using ArrayAccessor<UserType>::operator=;
177 };
178
179 /********************************************************************************************************************/
180 /********************************************************************************************************************/
181 /* Implementations below this point */
182 /********************************************************************************************************************/
183 /********************************************************************************************************************/
184
185 template<typename UserType>
189
190 /********************************************************************************************************************/
191
192 template<typename UserType>
194 // Having a move-assignment operator is required to use the move-assignment
195 // operator of a module containing an accessor.
196 InversionOfControlAccessor<ArrayAccessor<UserType>>::replace(std::move(other));
197 return *this;
198 }
199
200 /********************************************************************************************************************/
201
202 template<typename UserType>
204 auto versionNumber = this->getOwner()->getCurrentVersionNumber();
205 bool dataLoss = ChimeraTK::OneDRegisterAccessor<UserType>::write(versionNumber);
206 if(dataLoss) {
207 Application::incrementDataLossCounter(this->_node.getQualifiedName());
208 }
209 return dataLoss;
210 }
211
212 /********************************************************************************************************************/
213
214 template<typename UserType>
216 auto versionNumber = this->getOwner()->getCurrentVersionNumber();
217 bool dataLoss = ChimeraTK::OneDRegisterAccessor<UserType>::writeDestructively(versionNumber);
218 if(dataLoss) {
219 Application::incrementDataLossCounter(this->_node.getQualifiedName());
220 }
221 return dataLoss;
222 }
223
224 /********************************************************************************************************************/
225
226 template<typename UserType>
227 void ArrayAccessor<UserType>::writeIfDifferent(const std::vector<UserType>& newValue) {
228 if(!std::equal(newValue.begin(), newValue.end(), this->get()->accessChannel(0).begin()) ||
229 this->template checkMetadataWriteDifference<UserType>()) {
230 setAndWrite(newValue);
231 }
232 }
233
234 /********************************************************************************************************************/
235
236 template<typename UserType>
237 void ArrayAccessor<UserType>::setAndWrite(const std::vector<UserType>& newValue) {
238 operator=(newValue);
239 this->write();
240 }
241
242 /********************************************************************************************************************/
243
244 template<typename UserType>
245 ArrayAccessor<UserType>::ArrayAccessor(Module* owner, const std::string& name, VariableDirection direction,
246 std::string unit, size_t nElements, UpdateMode mode, const std::string& description,
247 const std::unordered_set<std::string>& tags)
249 owner, name, direction, unit, nElements, mode, description, &typeid(UserType), tags) {
251 }
252
253 /********************************************************************************************************************/
254 /********************************************************************************************************************/
255
256 template<typename UserType>
257 ArrayPushInput<UserType>::ArrayPushInput(Module* owner, const std::string& name, std::string unit, size_t nElements,
258 const std::string& description, const std::unordered_set<std::string>& tags)
259 : ArrayAccessor<UserType>(
260 owner, name, {VariableDirection::consuming, false}, unit, nElements, UpdateMode::push, description, tags) {}
261
262 /********************************************************************************************************************/
263 /********************************************************************************************************************/
264
265 template<typename UserType>
266 ArrayPollInput<UserType>::ArrayPollInput(Module* owner, const std::string& name, std::string unit, size_t nElements,
267 const std::string& description, const std::unordered_set<std::string>& tags)
268 : ArrayAccessor<UserType>(
269 owner, name, {VariableDirection::consuming, false}, unit, nElements, UpdateMode::poll, description, tags) {}
270
271 /********************************************************************************************************************/
272 /********************************************************************************************************************/
273
274 template<typename UserType>
275 ArrayOutput<UserType>::ArrayOutput(Module* owner, const std::string& name, std::string unit, size_t nElements,
276 const std::string& description, const std::unordered_set<std::string>& tags)
277 : ArrayAccessor<UserType>(
278 owner, name, {VariableDirection::feeding, false}, unit, nElements, UpdateMode::push, description, tags) {}
279
280 /********************************************************************************************************************/
281 /********************************************************************************************************************/
282
283 template<typename UserType>
284 ArrayPushInputWB<UserType>::ArrayPushInputWB(Module* owner, const std::string& name, std::string unit,
285 size_t nElements, const std::string& description, const std::unordered_set<std::string>& tags)
286 : ArrayAccessor<UserType>(
287 owner, name, {VariableDirection::consuming, true}, unit, nElements, UpdateMode::push, description, tags) {}
288
289 /********************************************************************************************************************/
290 /********************************************************************************************************************/
291
292 template<typename UserType>
293 ArrayOutputPushRB<UserType>::ArrayOutputPushRB(Module* owner, const std::string& name, std::string unit,
294 size_t nElements, const std::string& description, const std::unordered_set<std::string>& tags)
295 : ArrayAccessor<UserType>(
296 owner, name, {VariableDirection::feeding, true}, unit, nElements, UpdateMode::push, description, tags) {}
297
298 /********************************************************************************************************************/
299 /********************************************************************************************************************/
300
301 template<typename UserType>
302 ArrayOutputRB<UserType>::ArrayOutputRB(Module* owner, const std::string& name, std::string unit, size_t nElements,
303 const std::string& description, const std::unordered_set<std::string>& tags)
304 : ArrayAccessor<UserType>(
305 owner, name, {VariableDirection::feeding, true}, unit, nElements, UpdateMode::push, description, tags) {}
306
307 /********************************************************************************************************************/
308 /********************************************************************************************************************/
309
310 template<typename UserType>
312 std::string unit, size_t nElements, const std::string& description, const std::unordered_set<std::string>& tags)
313 : ArrayAccessor<UserType>(
314 owner, name, {VariableDirection::feeding, true}, unit, nElements, UpdateMode::push, description, tags) {
315 this->addTag(ChimeraTK::SystemTags::reverseRecovery);
316 }
317
318 /********************************************************************************************************************/
319
320 template<typename UserType>
322 std::string unit, size_t nElements, const std::string& description, const std::unordered_set<std::string>& tags)
323 : ArrayAccessor<UserType>(
324 owner, name, {VariableDirection::consuming, false}, unit, nElements, UpdateMode::push, description, tags) {
326 }
327
328 /********************************************************************************************************************/
329
330 template<typename UserType>
332 std::string unit, size_t nElements, const std::string& description, const std::unordered_set<std::string>& tags)
333 : ArrayAccessor<UserType>(
334 owner, name, {VariableDirection::consuming, false}, unit, nElements, UpdateMode::poll, description, tags) {
336 }
337
338 /********************************************************************************************************************/
339 /********************************************************************************************************************/
340
341} /* namespace ChimeraTK */
static void incrementDataLossCounter(const std::string &name)
Increment counter for how many write() operations have overwritten unread data.
Accessor for array variables (i.e.
void setAndWrite(const std::vector< UserType > &newValue)
void writeIfDifferent(const std::vector< UserType > &newValue, VersionNumber versionNumber, DataValidity validity)=delete
ArrayAccessor(Module *owner, const std::string &name, VariableDirection direction, std::string unit, size_t nElements, UpdateMode mode, const std::string &description, const std::unordered_set< std::string > &tags={})
ArrayAccessor()=default
Default constructor creates a dysfunctional accessor (to be assigned with a real accessor later)
ArrayAccessor(ArrayAccessor< UserType > &&other) noexcept
Move constructor.
void replace(const ChimeraTK::NDRegisterAccessorAbstractor< UserType > &newAccessor)=delete
ArrayAccessor< UserType > & operator=(ArrayAccessor< UserType > &&other) noexcept
Move assignment.
ArrayAccessor< UserType > & operator=(ArrayAccessor< UserType > &other)=delete
bool write(ChimeraTK::VersionNumber versionNumber)=delete
void writeIfDifferent(const std::vector< UserType > &newValue)
void setAndWrite(const std::vector< UserType > &newValue, VersionNumber versionNumber)=delete
bool writeDestructively(ChimeraTK::VersionNumber versionNumber)=delete
Convenience class for output array accessors (always UpdateMode::push)
ArrayOutput(Module *owner, const std::string &name, std::string unit, size_t nElements, const std::string &description, const std::unordered_set< std::string > &tags={})
Convenience class for output array accessors with return channel ("read back") (always UpdateMode::pu...
Deprecated, do not use.
Convenience class for input array accessors with UpdateMode::poll.
ArrayPollInput(Module *owner, const std::string &name, std::string unit, size_t nElements, const std::string &description, const std::unordered_set< std::string > &tags={})
Convenience class for input array accessors with UpdateMode::poll that skip initial value reading.
Convenience class for input array accessors with UpdateMode::push.
ArrayPushInput(Module *owner, const std::string &name, std::string unit, size_t nElements, const std::string &description, const std::unordered_set< std::string > &tags={})
Convenience class for input array accessors with UpdateMode::push that skip initial value reading.
Convenience class for input array accessors with return channel ("write back") and UpdateMode::push.
Adds features required for inversion of control to an accessor.
void deinit()
Early deinitialisation of stuff we cannot do in our destructor.
void init()
Late initialisation of stuff we cannot do in our constructor.
Base class for ApplicationModule and DeviceModule, to have a common interface for these module types.
Definition Module.h:21
Class describing a node of a variable network.
InvalidityTracer application module.
constexpr char noInitialValueReadTag[]
System tag to mark an accessor which should be excluded from the initial value read during applicatio...
UpdateMode
Enum to define the update mode of variables.
Definition Flags.h:31
Struct to define the direction of variables.
Definition Flags.h:13