ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
TransferElementTestAccessor.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
6
7namespace ChimeraTK {
8
10 template<typename UserType>
12 public:
13 TransferElementTestAccessor(AccessModeFlags flags) : NDRegisterAccessor<UserType>("someName", flags) {
14 // this accessor uses a queue length of 3
15 this->_readQueue = {3};
16 this->buffer_2D.resize(1);
17 this->buffer_2D[0].resize(1);
18 }
19
21
22 void doPreRead(TransferType type) override {
23 _transferType_pre = type;
27 try {
28 if(_throwLogicErr) throw ChimeraTK::logic_error("Test");
30 if(!_readable) {
31 throw ChimeraTK::logic_error("Not readable!");
32 }
33 }
34 catch(...) {
35 _thrownException = std::current_exception();
36 throw;
37 }
38 }
39
40 void doPreWrite(TransferType type, VersionNumber versionNumber) override {
41 _transferType_pre = type;
45 _preWrite_version = versionNumber;
46 try {
47 if(_throwLogicErr) throw ChimeraTK::logic_error("Test");
49 if(_throwNumericCast) throw boost::numeric::bad_numeric_cast();
50 if(!_writeable) {
51 throw ChimeraTK::logic_error("Not writeable!");
52 }
53 }
54 catch(...) {
55 _thrownException = std::current_exception();
56 throw;
57 }
58 }
59
64 try {
66 }
67 catch(...) {
68 _thrownException = std::current_exception();
69 throw;
70 }
71 }
72
73 bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber) override {
77 _writeTransfer_version = versionNumber;
78 try {
80 }
81 catch(...) {
82 _thrownException = std::current_exception();
83 throw;
84 }
85 return _previousDataLost;
86 }
87
92 _writeTransfer_version = versionNumber;
93 try {
95 }
96 catch(...) {
97 _thrownException = std::current_exception();
98 throw;
99 }
100 return _previousDataLost;
101 }
102
103 void doPostRead(TransferType type, bool updateDataBuffer) override {
104 _transferType_post = type;
108 _updateDataBuffer = updateDataBuffer;
110
111 if(_setPostReadVersion == VersionNumber{nullptr}) {
113 }
114 else {
116 }
117
118 this->buffer_2D[0][0] = _setPostReadData;
119
120 try {
121 if(_throwNumericCast) throw boost::numeric::bad_numeric_cast();
122 }
123 catch(...) {
124 _thrownException = std::current_exception();
125 throw;
126 }
127 }
128
129 void doPostWrite(TransferType type, VersionNumber versionNumber) override {
130 _transferType_post = type;
134 _postWrite_version = versionNumber;
136 }
137
138 bool mayReplaceOther(const boost::shared_ptr<TransferElement const>& other) const override {
139 if(this == other.get()) {
140 return false;
141 }
142
143 return _listMayReplaceElements.count(other->getId());
144 }
145 std::vector<boost::shared_ptr<TransferElement>> getHardwareAccessingElements() override {
146 if(_hardwareAccessingElements.size() == 0) {
147 // cannot call shared_from_this() in constructor, so we cannot put it by default into the list...
148 return {boost::enable_shared_from_this<TransferElement>::shared_from_this()};
149 }
151 }
152 std::list<boost::shared_ptr<TransferElement>> getInternalElements() override {
153 std::list<boost::shared_ptr<TransferElement>> r;
154 for(auto& e : _internalElements) r.push_back(e);
155 return r;
156 }
157 void replaceTransferElement(boost::shared_ptr<TransferElement> newElement) override {
158 _listReplacementElements.push_back(newElement->getId());
159 }
160
161 bool isReadOnly() const override { return !_writeable && _readable; }
162
163 bool isReadable() const override { return _readable; }
164
165 bool isWriteable() const override { return _writeable; }
166
167 void interrupt() override { this->interrupt_impl(this->_readQueue); }
168
169 bool _writeable{true};
170 bool _readable{true};
171
172 // counter flags to check which functions have been called how many times and in which order (via index)
180 size_t _preIndex{999999};
181 size_t _transferIndex{999999};
182 size_t _postIndex{999999};
183 static std::atomic<size_t> _currentIndex; // allows comparison across transfer elements
184
185 // recorded function arguments etc.
186 TransferType _transferType_pre, _transferType_post; // TransferType as seen in pre/postXxx()
187 bool _updateDataBuffer; // updateDataBuffer as seen in postRead() (set there)
191 std::exception_ptr _seenActiveException{nullptr}; // _activeException as seen in postXxx()
192 std::exception_ptr _thrownException{nullptr}; // the exception thrown by request (via command flags below)
193
194 // command flags to steer behaviour of this TE
195 bool _previousDataLost{false}; // flag to return by writeTransfer()/writeTransferDestructively()
196 bool _throwLogicErr{false}; // always in doPreXxx()
199 bool _throwNumericCast{false}; // in doPreWrite() or doPreRead() depending on operation
200 VersionNumber _setPostReadVersion{nullptr}; // if nullptr, a new version will be generated
201 UserType _setPostReadData{UserType()}; // data to be copied into the user buffer in postRead
202
203 // lists, counters etc. used for the TransferGroup tests
204 std::list<TransferElementID> _listReplacementElements; // list of all arguments of replaceTransferElement()
205 std::vector<boost::shared_ptr<TransferElementTestAccessor<UserType>>> _internalElements; // returned by
206 // getInternalElements()
207 std::vector<boost::shared_ptr<TransferElement>> _hardwareAccessingElements; // returned by
208 // getHardwareAccessingElements()
209 std::set<TransferElementID> _listMayReplaceElements; // mayReplaceOther() returns true if ID is found in this set
210
211 // reset all counters and revert command flags to defaults
241
242 // convenience function to put exceptions onto the readQueue (see also interrupt())
244 try {
245 throw ChimeraTK::runtime_error("Test");
246 }
247 catch(...) {
248 _thrownException = std::current_exception();
249 this->_readQueue.push_exception(std::current_exception());
250 }
251 }
253 try {
254 throw ChimeraTK::detail::DiscardValueException();
255 }
256 catch(...) {
257 _thrownException = std::current_exception();
258 this->_readQueue.push_exception(std::current_exception());
259 }
260 }
261 // simulate a reveiver thread by manually putting data into the queue
262 bool push() { return this->_readQueue.push(); }
263
267 };
268
269 template<typename T>
271
272} // namespace ChimeraTK
Set of AccessMode flags with additional functionality for an easier handling.
Definition AccessMode.h:48
N-dimensional register accessor.
std::vector< std::vector< UserType > > buffer_2D
Buffer of converted data elements.
AccessModeFlags _accessModeFlags
The access mode flags for this transfer element.
std::exception_ptr _activeException
Exception to be rethrown in postXXX() in case hasSeenException == true Can be set via setActiveExcept...
void interrupt_impl(QUEUE_TYPE &dataTransportQueue)
Implementation of interrupt()
VersionNumber _versionNumber
The version number of the last successful transfer.
cppext::future_queue< void > _readQueue
The queue for asynchronous read transfers.
Special accessor used to test the behaviour of the TransferElement base class and the TransferGroup.
std::set< TransferElementID > _listMayReplaceElements
bool isReadOnly() const override
Check if transfer element is read only, i.e.
bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber) override
Implementation version of writeTransfer().
void doReadTransferSynchronously() override
Implementation version of readTransfer() for synchronous reads.
void doPostWrite(TransferType type, VersionNumber versionNumber) override
Backend specific implementation of postWrite().
std::vector< boost::shared_ptr< TransferElementTestAccessor< UserType > > > _internalElements
void replaceTransferElement(boost::shared_ptr< TransferElement > newElement) override
Search for all underlying TransferElements which are considered identical (see sameRegister()) with t...
std::exception_ptr _activeException
Exception to be rethrown in postXXX() in case hasSeenException == true Can be set via setActiveExcept...
bool doWriteTransferDestructively(ChimeraTK::VersionNumber versionNumber) override
Implementation version of writeTransferDestructively().
std::list< TransferElementID > _listReplacementElements
std::vector< boost::shared_ptr< TransferElement > > _hardwareAccessingElements
void interrupt() override
Return from a blocking read immediately and throw boost::thread_interrupted.
cppext::future_queue< void > _readQueue
The queue for asynchronous read transfers.
void doPreWrite(TransferType type, VersionNumber versionNumber) override
Backend specific implementation of preWrite().
std::vector< boost::shared_ptr< TransferElement > > getHardwareAccessingElements() override
Obtain the underlying TransferElements with actual hardware access.
std::list< boost::shared_ptr< TransferElement > > getInternalElements() override
Obtain the full list of TransferElements internally used by this TransferElement.
bool isReadable() const override
Check if transfer element is readable.
bool mayReplaceOther(const boost::shared_ptr< TransferElement const > &other) const override
Check whether the TransferElement can be used in places where the TransferElement "other" is currentl...
void doPreRead(TransferType type) override
Backend specific implementation of preRead().
bool isWriteable() const override
Check if transfer element is writeable.
void doPostRead(TransferType type, bool updateDataBuffer) override
Backend specific implementation of postRead().
Class for generating and holding version numbers without exposing a numeric representation.
Exception thrown when a logic error has occured.
Definition Exception.h:51
Exception thrown when a runtime error has occured.
Definition Exception.h:18
TransferType
Used to indicate the applicable operation on a Transferelement.