ChimeraTK-ApplicationCore 04.07.01
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 /* Implementations below this point */
156 /********************************************************************************************************************/
157 /********************************************************************************************************************/
158
159 template<typename UserType>
163
164 /********************************************************************************************************************/
165
166 template<typename UserType>
168 // Having a move-assignment operator is required to use the move-assignment
169 // operator of a module containing an accessor.
170 InversionOfControlAccessor<ArrayAccessor<UserType>>::replace(std::move(other));
171 return *this;
172 }
173
174 /********************************************************************************************************************/
175
176 template<typename UserType>
178 auto versionNumber = this->getOwner()->getCurrentVersionNumber();
179 bool dataLoss = ChimeraTK::OneDRegisterAccessor<UserType>::write(versionNumber);
180 if(dataLoss) {
181 Application::incrementDataLossCounter(this->_node.getQualifiedName());
182 }
183 return dataLoss;
184 }
185
186 /********************************************************************************************************************/
187
188 template<typename UserType>
190 auto versionNumber = this->getOwner()->getCurrentVersionNumber();
191 bool dataLoss = ChimeraTK::OneDRegisterAccessor<UserType>::writeDestructively(versionNumber);
192 if(dataLoss) {
193 Application::incrementDataLossCounter(this->_node.getQualifiedName());
194 }
195 return dataLoss;
196 }
197
198 /********************************************************************************************************************/
199
200 template<typename UserType>
201 void ArrayAccessor<UserType>::writeIfDifferent(const std::vector<UserType>& newValue) {
202 if(!std::equal(newValue.begin(), newValue.end(), this->get()->accessChannel(0).begin()) ||
203 this->template checkMetadataWriteDifference<UserType>()) {
204 setAndWrite(newValue);
205 }
206 }
207
208 /********************************************************************************************************************/
209
210 template<typename UserType>
211 void ArrayAccessor<UserType>::setAndWrite(const std::vector<UserType>& newValue) {
212 operator=(newValue);
213 this->write();
214 }
215
216 /********************************************************************************************************************/
217
218 template<typename UserType>
219 ArrayAccessor<UserType>::ArrayAccessor(Module* owner, const std::string& name, VariableDirection direction,
220 std::string unit, size_t nElements, UpdateMode mode, const std::string& description,
221 const std::unordered_set<std::string>& tags)
223 owner, name, direction, unit, nElements, mode, description, &typeid(UserType), tags) {
225 }
226
227 /********************************************************************************************************************/
228 /********************************************************************************************************************/
229
230 template<typename UserType>
231 ArrayPushInput<UserType>::ArrayPushInput(Module* owner, const std::string& name, std::string unit, size_t nElements,
232 const std::string& description, const std::unordered_set<std::string>& tags)
233 : ArrayAccessor<UserType>(
234 owner, name, {VariableDirection::consuming, false}, unit, nElements, UpdateMode::push, description, tags) {}
235
236 /********************************************************************************************************************/
237 /********************************************************************************************************************/
238
239 template<typename UserType>
240 ArrayPollInput<UserType>::ArrayPollInput(Module* owner, const std::string& name, std::string unit, size_t nElements,
241 const std::string& description, const std::unordered_set<std::string>& tags)
242 : ArrayAccessor<UserType>(
243 owner, name, {VariableDirection::consuming, false}, unit, nElements, UpdateMode::poll, description, tags) {}
244
245 /********************************************************************************************************************/
246 /********************************************************************************************************************/
247
248 template<typename UserType>
249 ArrayOutput<UserType>::ArrayOutput(Module* owner, const std::string& name, std::string unit, size_t nElements,
250 const std::string& description, const std::unordered_set<std::string>& tags)
251 : ArrayAccessor<UserType>(
252 owner, name, {VariableDirection::feeding, false}, unit, nElements, UpdateMode::push, description, tags) {}
253
254 /********************************************************************************************************************/
255 /********************************************************************************************************************/
256
257 template<typename UserType>
258 ArrayPushInputWB<UserType>::ArrayPushInputWB(Module* owner, const std::string& name, std::string unit,
259 size_t nElements, const std::string& description, const std::unordered_set<std::string>& tags)
260 : ArrayAccessor<UserType>(
261 owner, name, {VariableDirection::consuming, true}, unit, nElements, UpdateMode::push, description, tags) {}
262
263 /********************************************************************************************************************/
264 /********************************************************************************************************************/
265
266 template<typename UserType>
267 ArrayOutputPushRB<UserType>::ArrayOutputPushRB(Module* owner, const std::string& name, std::string unit,
268 size_t nElements, const std::string& description, const std::unordered_set<std::string>& tags)
269 : ArrayAccessor<UserType>(
270 owner, name, {VariableDirection::feeding, true}, unit, nElements, UpdateMode::push, description, tags) {}
271
272 /********************************************************************************************************************/
273 /********************************************************************************************************************/
274
275 template<typename UserType>
276 ArrayOutputRB<UserType>::ArrayOutputRB(Module* owner, const std::string& name, std::string unit, size_t nElements,
277 const std::string& description, const std::unordered_set<std::string>& tags)
278 : ArrayAccessor<UserType>(
279 owner, name, {VariableDirection::feeding, true}, unit, nElements, UpdateMode::push, description, tags) {}
280
281 /********************************************************************************************************************/
282 /********************************************************************************************************************/
283
284 template<typename UserType>
286 std::string unit, size_t nElements, const std::string& description, const std::unordered_set<std::string>& tags)
287 : ArrayAccessor<UserType>(
288 owner, name, {VariableDirection::feeding, true}, unit, nElements, UpdateMode::push, description, tags) {
289 this->addTag(ChimeraTK::SystemTags::reverseRecovery);
290 }
291
292 /********************************************************************************************************************/
293 /********************************************************************************************************************/
294
295} /* 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::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 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.
UpdateMode
Enum to define the update mode of variables.
Definition Flags.h:31
Struct to define the direction of variables.
Definition Flags.h:13