ChimeraTK-DeviceAccess 03.26.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(!_writeable) {
50 throw ChimeraTK::logic_error("Not writeable!");
51 }
52 }
53 catch(...) {
54 _thrownException = std::current_exception();
55 throw;
56 }
57 }
58
63 try {
65 }
66 catch(...) {
67 _thrownException = std::current_exception();
68 throw;
69 }
70 }
71
72 bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber) override {
76 _writeTransfer_version = versionNumber;
77 try {
79 }
80 catch(...) {
81 _thrownException = std::current_exception();
82 throw;
83 }
84 return _previousDataLost;
85 }
86
91 _writeTransfer_version = versionNumber;
92 try {
94 }
95 catch(...) {
96 _thrownException = std::current_exception();
97 throw;
98 }
99 return _previousDataLost;
100 }
101
102 void doPostRead(TransferType type, bool updateDataBuffer) override {
103 _transferType_post = type;
107 _updateDataBuffer = updateDataBuffer;
109
110 if(_setPostReadVersion == VersionNumber{nullptr}) {
112 }
113 else {
115 }
116
117 this->buffer_2D[0][0] = _setPostReadData;
118 }
119
120 void doPostWrite(TransferType type, VersionNumber versionNumber) override {
121 _transferType_post = type;
125 _postWrite_version = versionNumber;
127 }
128
129 bool mayReplaceOther(const boost::shared_ptr<TransferElement const>& other) const override {
130 if(this == other.get()) {
131 return false;
132 }
133
134 return _listMayReplaceElements.count(other->getId());
135 }
136 std::vector<boost::shared_ptr<TransferElement>> getHardwareAccessingElements() override {
137 if(_hardwareAccessingElements.size() == 0) {
138 // cannot call shared_from_this() in constructor, so we cannot put it by default into the list...
139 return {boost::enable_shared_from_this<TransferElement>::shared_from_this()};
140 }
142 }
143 std::list<boost::shared_ptr<TransferElement>> getInternalElements() override {
144 std::list<boost::shared_ptr<TransferElement>> r;
145 for(auto& e : _internalElements) r.push_back(e);
146 return r;
147 }
148 void replaceTransferElement(boost::shared_ptr<TransferElement> newElement) override {
149 _listReplacementElements.push_back(newElement->getId());
150 }
151
152 bool isReadOnly() const override { return !_writeable && _readable; }
153
154 bool isReadable() const override { return _readable; }
155
156 bool isWriteable() const override { return _writeable; }
157
158 void interrupt() override { this->interrupt_impl(this->_readQueue); }
159
160 bool _writeable{true};
161 bool _readable{true};
162
163 // counter flags to check which functions have been called how many times and in which order (via index)
171 size_t _preIndex{999999};
172 size_t _transferIndex{999999};
173 size_t _postIndex{999999};
174 static std::atomic<size_t> _currentIndex; // allows comparison across transfer elements
175
176 // recorded function arguments etc.
177 TransferType _transferType_pre, _transferType_post; // TransferType as seen in pre/postXxx()
178 bool _updateDataBuffer; // updateDataBuffer as seen in postRead() (set there)
182 std::exception_ptr _seenActiveException{nullptr}; // _activeException as seen in postXxx()
183 std::exception_ptr _thrownException{nullptr}; // the exception thrown by request (via command flags below)
184
185 // command flags to steer behaviour of this TE
186 bool _previousDataLost{false}; // flag to return by writeTransfer()/writeTransferDestructively()
187 bool _throwLogicErr{false}; // always in doPreXxx()
190 bool _throwNumericCast{false}; // in doPreWrite() or doPreRead() depending on operation
191 VersionNumber _setPostReadVersion{nullptr}; // if nullptr, a new version will be generated
192 UserType _setPostReadData{UserType()}; // data to be copied into the user buffer in postRead
193
194 // lists, counters etc. used for the TransferGroup tests
195 std::list<TransferElementID> _listReplacementElements; // list of all arguments of replaceTransferElement()
196 std::vector<boost::shared_ptr<TransferElementTestAccessor<UserType>>> _internalElements; // returned by
197 // getInternalElements()
198 std::vector<boost::shared_ptr<TransferElement>> _hardwareAccessingElements; // returned by
199 // getHardwareAccessingElements()
200 std::set<TransferElementID> _listMayReplaceElements; // mayReplaceOther() returns true if ID is found in this set
201
202 // reset all counters and revert command flags to defaults
232
233 // convenience function to put exceptions onto the readQueue (see also interrupt())
235 try {
236 throw ChimeraTK::runtime_error("Test");
237 }
238 catch(...) {
239 _thrownException = std::current_exception();
240 this->_readQueue.push_exception(std::current_exception());
241 }
242 }
244 try {
245 throw ChimeraTK::detail::DiscardValueException();
246 }
247 catch(...) {
248 _thrownException = std::current_exception();
249 this->_readQueue.push_exception(std::current_exception());
250 }
251 }
252 // simulate a reveiver thread by manually putting data into the queue
253 bool push() { return this->_readQueue.push(); }
254
258 };
259
260 template<typename T>
262
263} // 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.