ChimeraTK-ApplicationCore 04.07.00
Loading...
Searching...
No Matches
ScalarAccessor.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/ScalarRegisterAccessor.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
24 template<typename UserType>
25 class ScalarAccessor : public ChimeraTK::ScalarRegisterAccessor<UserType>,
26 public InversionOfControlAccessor<ScalarAccessor<UserType>> {
27 public:
29 void replace(const ChimeraTK::NDRegisterAccessorAbstractor<UserType>& newAccessor) = delete;
32 using ChimeraTK::ScalarRegisterAccessor<UserType>::operator=;
33
36
39
40 bool write(ChimeraTK::VersionNumber versionNumber) = delete;
41 bool writeDestructively(ChimeraTK::VersionNumber versionNumber) = delete;
42 void writeIfDifferent(UserType newValue, VersionNumber versionNumber, DataValidity validity) = delete;
43 void setAndWrite(UserType newValue, VersionNumber versionNumber) = delete;
44
45 bool write();
46
48
49 void writeIfDifferent(UserType newValue);
50
51 void setAndWrite(UserType newValue);
52
53 using value_type = UserType;
54
56
57 protected:
58 friend class InversionOfControlAccessor<ScalarAccessor<UserType>>;
59
60 ScalarAccessor(Module* owner, const std::string& name, VariableDirection direction, std::string unit,
61 UpdateMode mode, const std::string& description, const std::unordered_set<std::string>& tags = {});
62
65 ScalarAccessor() = default;
66 };
67
68 /********************************************************************************************************************/
69
71 template<typename UserType>
72 class ScalarPushInput : public ScalarAccessor<UserType> {
73 public:
74 ScalarPushInput(Module* owner, const std::string& name, std::string unit, const std::string& description,
75 const std::unordered_set<std::string>& tags = {});
77 using ScalarAccessor<UserType>::operator=;
78 };
79
80 /********************************************************************************************************************/
81
83 template<typename UserType>
84 class ScalarPollInput : public ScalarAccessor<UserType> {
85 public:
86 ScalarPollInput(Module* owner, const std::string& name, std::string unit, const std::string& description,
87 const std::unordered_set<std::string>& tags = {});
89 void read() { this->readLatest(); }
90 using ScalarAccessor<UserType>::operator=;
91 };
92
93 /********************************************************************************************************************/
94
96 template<typename UserType>
97 class ScalarOutput : public ScalarAccessor<UserType> {
98 public:
99 ScalarOutput(Module* owner, const std::string& name, std::string unit, const std::string& description,
100 const std::unordered_set<std::string>& tags = {});
101 ScalarOutput() : ScalarAccessor<UserType>() {}
102 using ScalarAccessor<UserType>::operator=;
103 };
104
105 /********************************************************************************************************************/
106
108 template<typename UserType>
109 class ScalarPushInputWB : public ScalarAccessor<UserType> {
110 public:
111 ScalarPushInputWB(Module* owner, const std::string& name, std::string unit, const std::string& description,
112 const std::unordered_set<std::string>& tags = {});
114 using ScalarAccessor<UserType>::operator=;
115 };
116
117 /********************************************************************************************************************/
118
120 template<typename UserType>
121 class ScalarOutputPushRB : public ScalarAccessor<UserType> {
122 public:
123 ScalarOutputPushRB(Module* owner, const std::string& name, std::string unit, const std::string& description,
124 const std::unordered_set<std::string>& tags = {});
126 using ScalarAccessor<UserType>::operator=;
127 };
128
129 /********************************************************************************************************************/
130
132 template<typename UserType>
134 public:
135 ScalarOutputReverseRecovery(Module* owner, const std::string& name, std::string unit,
136 const std::string& description, const std::unordered_set<std::string>& tags = {});
138 using ScalarAccessor<UserType>::operator=;
139 };
140 /********************************************************************************************************************/
141 /********************************************************************************************************************/
142 /* Implementations below this point */
143 /********************************************************************************************************************/
144 /********************************************************************************************************************/
145
146 template<typename UserType>
150
151 /********************************************************************************************************************/
152
153 template<typename UserType>
155 // Having a move-assignment operator is required to use the move-assignment
156 // operator of a module containing an accessor.
157 InversionOfControlAccessor<ScalarAccessor<UserType>>::replace(std::move(other));
158 return *this;
159 }
160
161 /********************************************************************************************************************/
162
163 template<typename UserType>
165 auto versionNumber = this->getOwner()->getCurrentVersionNumber();
166 bool dataLoss = ChimeraTK::ScalarRegisterAccessor<UserType>::write(versionNumber);
167 if(dataLoss) {
168 Application::incrementDataLossCounter(this->_node.getQualifiedName());
169 }
170 return dataLoss;
171 }
172
173 /********************************************************************************************************************/
174
175 template<typename UserType>
177 auto versionNumber = this->getOwner()->getCurrentVersionNumber();
178 bool dataLoss = ChimeraTK::ScalarRegisterAccessor<UserType>::writeDestructively(versionNumber);
179 if(dataLoss) {
180 Application::incrementDataLossCounter(this->_node.getQualifiedName());
181 }
182 return dataLoss;
183 }
184
185 /********************************************************************************************************************/
186
187 template<typename UserType>
189 if(this->get()->accessData(0, 0) != newValue || this->template checkMetadataWriteDifference<UserType>()) {
190 setAndWrite(newValue);
191 }
192 }
193
194 /********************************************************************************************************************/
195
196 template<typename UserType>
198 operator=(newValue);
199 this->write();
200 }
201
202 /********************************************************************************************************************/
203
204 template<typename UserType>
205 ScalarAccessor<UserType>::ScalarAccessor(Module* owner, const std::string& name, VariableDirection direction,
206 std::string unit, UpdateMode mode, const std::string& description, const std::unordered_set<std::string>& tags)
208 owner, name, direction, unit, 1, mode, description, &typeid(UserType), tags) {
210 }
211
212 /********************************************************************************************************************/
213 /********************************************************************************************************************/
214
215 template<typename UserType>
216 ScalarPushInput<UserType>::ScalarPushInput(Module* owner, const std::string& name, std::string unit,
217 const std::string& description, const std::unordered_set<std::string>& tags)
218 : ScalarAccessor<UserType>(
219 owner, name, {VariableDirection::consuming, false}, unit, UpdateMode::push, description, tags) {}
220
221 /********************************************************************************************************************/
222 /********************************************************************************************************************/
223
224 template<typename UserType>
225 ScalarPollInput<UserType>::ScalarPollInput(Module* owner, const std::string& name, std::string unit,
226 const std::string& description, const std::unordered_set<std::string>& tags)
227 : ScalarAccessor<UserType>(
228 owner, name, {VariableDirection::consuming, false}, unit, UpdateMode::poll, description, tags) {}
229
230 /********************************************************************************************************************/
231 /********************************************************************************************************************/
232
233 template<typename UserType>
234 ScalarOutput<UserType>::ScalarOutput(Module* owner, const std::string& name, std::string unit,
235 const std::string& description, const std::unordered_set<std::string>& tags)
236 : ScalarAccessor<UserType>(
237 owner, name, {VariableDirection::feeding, false}, unit, UpdateMode::push, description, tags) {}
238
239 /********************************************************************************************************************/
240 /********************************************************************************************************************/
241
242 template<typename UserType>
243 ScalarPushInputWB<UserType>::ScalarPushInputWB(Module* owner, const std::string& name, std::string unit,
244 const std::string& description, const std::unordered_set<std::string>& tags)
245 : ScalarAccessor<UserType>(
246 owner, name, {VariableDirection::consuming, true}, unit, UpdateMode::push, description, tags) {}
247
248 /********************************************************************************************************************/
249 /********************************************************************************************************************/
250
251 template<typename UserType>
252 ScalarOutputPushRB<UserType>::ScalarOutputPushRB(Module* owner, const std::string& name, std::string unit,
253 const std::string& description, const std::unordered_set<std::string>& tags)
254 : ScalarAccessor<UserType>(
255 owner, name, {VariableDirection::feeding, true}, unit, UpdateMode::push, description, tags) {}
256
257 /********************************************************************************************************************/
258 /********************************************************************************************************************/
259
260 template<typename UserType>
262 std::string unit, const std::string& description, const std::unordered_set<std::string>& tags)
263 : ScalarAccessor<UserType>(
264 owner, name, {VariableDirection::feeding, true}, unit, UpdateMode::push, description, tags) {
265 this->addTag(ChimeraTK::SystemTags::reverseRecovery);
266 }
267
268 /********************************************************************************************************************/
269
270} /* namespace ChimeraTK */
static void incrementDataLossCounter(const std::string &name)
Increment counter for how many write() operations have overwritten unread data.
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
Accessor for scalar variables (i.e.
bool write(ChimeraTK::VersionNumber versionNumber)=delete
bool writeDestructively(ChimeraTK::VersionNumber versionNumber)=delete
void setAndWrite(UserType newValue)
void writeIfDifferent(UserType newValue, VersionNumber versionNumber, DataValidity validity)=delete
ScalarAccessor(ScalarAccessor< UserType > &&other) noexcept
Move constructor.
ScalarAccessor< UserType > & operator=(ScalarAccessor< UserType > &&other) noexcept
Move assignment.
void writeIfDifferent(UserType newValue)
ScalarAccessor< UserType > & operator=(ScalarAccessor< UserType > &other)=delete
void setAndWrite(UserType newValue, VersionNumber versionNumber)=delete
ScalarAccessor()=default
Default constructor creates a dysfunctional accessor (to be assigned with a real accessor later)
ScalarAccessor(Module *owner, const std::string &name, VariableDirection direction, std::string unit, UpdateMode mode, const std::string &description, const std::unordered_set< std::string > &tags={})
void replace(const ChimeraTK::NDRegisterAccessorAbstractor< UserType > &newAccessor)=delete
Convenience class for output scalar accessors (always UpdateMode::push)
Convenience class for output scalar accessors with return channel ("read back") (always UpdateMode::p...
ScalarOutputPushRB(Module *owner, const std::string &name, std::string unit, const std::string &description, const std::unordered_set< std::string > &tags={})
Convenience class for output scalar accessors with return channel ("read back") (always UpdateMode::p...
Convenience class for input scalar accessors with UpdateMode::poll.
ScalarPollInput(Module *owner, const std::string &name, std::string unit, const std::string &description, const std::unordered_set< std::string > &tags={})
Convenience class for input scalar accessors with UpdateMode::push.
ScalarPushInput(Module *owner, const std::string &name, std::string unit, const std::string &description, const std::unordered_set< std::string > &tags={})
Convenience class for input scalar accessors with return channel ("write back") and UpdateMode::push.
ScalarPushInputWB(Module *owner, const std::string &name, std::string unit, const std::string &description, const std::unordered_set< std::string > &tags={})
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