ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
LNMBackendChannelAccessor.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 "Device.h"
9
10#include <algorithm>
11
12namespace ChimeraTK {
13
14 /********************************************************************************************************************/
15
16 template<typename UserType>
18 public:
19 LNMBackendChannelAccessor(const boost::shared_ptr<DeviceBackend>& dev, const RegisterPath& registerPathName,
20 size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags)
21 : NDRegisterAccessor<UserType>(registerPathName, flags), _registerPathName(registerPathName) {
22 // check for unknown flags
24
25 // FIXME: use right type in constructor argument...
26 _dev = boost::dynamic_pointer_cast<LogicalNameMappingBackend>(dev);
27
28 // copy the register info and create the internal accessors, if needed
29 _info = _dev->_catalogue_mutable.getBackendRegister(_registerPathName);
30
31 // check for incorrect usage of this accessor
33
34 // get target device and accessor
35 std::string devName = _info.deviceName;
36 boost::shared_ptr<DeviceBackend> targetDevice;
37 if(devName != "this") {
38 targetDevice = _dev->_devices[devName];
39 }
40 else {
41 targetDevice = dev;
42 }
43 _accessor = targetDevice->getRegisterAccessor<UserType>(
44 RegisterPath(_info.registerName), numberOfWords, wordOffsetInRegister, flags);
45
46 // verify channel number
47 if(_info.channel >= _accessor->getNumberOfChannels()) {
48 throw ChimeraTK::logic_error("LNMBackendChannelAccessor: Requested channel number " +
50 " exceeds number of channels of target register,"
51 " in accesor for register '" +
52 registerPathName + "'.");
53 }
54
55 // allocate the buffer
57 NDRegisterAccessor<UserType>::buffer_2D[0].resize(_accessor->getNumberOfSamples());
58
59 // set readQueue
61 }
62
63 void doReadTransferSynchronously() override { _accessor->readTransfer(); }
64
65 bool doWriteTransfer(ChimeraTK::VersionNumber /*versionNumber*/) override {
66 assert(false); // writing not allowed
67 return true;
68 }
69
70 void doPreWrite(TransferType type, VersionNumber) override {
71 std::ignore = type;
72 throw ChimeraTK::logic_error("Writing to channel-type registers of logical "
73 "name mapping devices is not supported.");
74 }
75
76 void doPreRead(TransferType type) override { _accessor->preRead(type); }
77
78 void doPostRead(TransferType type, bool hasNewData) override {
79 _accessor->postRead(type, hasNewData);
80 if(!hasNewData) return;
82 this->_versionNumber = _accessor->getVersionNumber();
83 this->_dataValidity = _accessor->dataValidity();
84 }
85
86 [[nodiscard]] bool mayReplaceOther(const boost::shared_ptr<TransferElement const>& other) const override {
87 auto rhsCasted = boost::dynamic_pointer_cast<const LNMBackendChannelAccessor<UserType>>(other);
88 if(rhsCasted.get() == this) {
89 return false;
90 }
91 if(!rhsCasted) return false;
92 if(_registerPathName != rhsCasted->_registerPathName) return false;
93 if(_dev != rhsCasted->_dev) return false;
94 return true;
95 }
96
97 [[nodiscard]] bool isReadOnly() const override { return true; }
98
99 [[nodiscard]] bool isReadable() const override { return true; }
100
101 [[nodiscard]] bool isWriteable() const override { return false; }
102
103 void setExceptionBackend(boost::shared_ptr<DeviceBackend> exceptionBackend) override {
104 this->_exceptionBackend = exceptionBackend;
105 _accessor->setExceptionBackend(exceptionBackend);
106 }
107
108 void interrupt() override { _accessor->interrupt(); }
109
110 protected:
112 boost::shared_ptr<NDRegisterAccessor<UserType>> _accessor;
113
116
118 boost::shared_ptr<LogicalNameMappingBackend> _dev;
119
122
123 std::vector<boost::shared_ptr<TransferElement>> getHardwareAccessingElements() override {
124 return _accessor->getHardwareAccessingElements();
125 }
126
127 std::list<boost::shared_ptr<TransferElement>> getInternalElements() override {
128 auto result = _accessor->getInternalElements();
129 result.push_front(_accessor);
130 return result;
131 }
132
133 void replaceTransferElement(boost::shared_ptr<TransferElement> newElement) override {
134 auto casted = boost::dynamic_pointer_cast<NDRegisterAccessor<UserType>>(newElement);
135 if(casted && _accessor->mayReplaceOther(newElement)) {
136 _accessor = casted;
137 }
138 else {
139 _accessor->replaceTransferElement(newElement);
140 }
141 _accessor->setExceptionBackend(this->_exceptionBackend);
142 }
143 };
144
146
147} // namespace ChimeraTK
#define DECLARE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(TemplateClass)
Set of AccessMode flags with additional functionality for an easier handling.
Definition AccessMode.h:48
void checkForUnknownFlags(const std::set< AccessMode > &knownFlags) const
Check of any flag which is not in the given set "knownFlags" is set.
Definition AccessMode.cc:32
bool isReadable() const override
Check if transfer element is readable.
void doPostRead(TransferType type, bool hasNewData) override
Backend specific implementation of postRead().
void replaceTransferElement(boost::shared_ptr< TransferElement > newElement) override
Search for all underlying TransferElements which are considered identical (see sameRegister()) with t...
void doPreWrite(TransferType type, VersionNumber) override
Backend specific implementation of preWrite().
void setExceptionBackend(boost::shared_ptr< DeviceBackend > exceptionBackend) override
Set the backend to which the exception has to be reported.
void interrupt() override
Return from a blocking read immediately and throw boost::thread_interrupted.
bool isWriteable() const override
Check if transfer element is writeable.
void doPreRead(TransferType type) override
Backend specific implementation of preRead().
boost::shared_ptr< LogicalNameMappingBackend > _dev
backend device
void doReadTransferSynchronously() override
Implementation version of readTransfer() for synchronous reads.
RegisterPath _registerPathName
register and module name
boost::shared_ptr< NDRegisterAccessor< UserType > > _accessor
pointer to underlying accessor
bool doWriteTransfer(ChimeraTK::VersionNumber) override
Implementation version of writeTransfer().
std::vector< boost::shared_ptr< TransferElement > > getHardwareAccessingElements() override
Obtain the underlying TransferElements with actual hardware access.
bool isReadOnly() const override
Check if transfer element is read only, i.e.
LNMBackendChannelAccessor(const boost::shared_ptr< DeviceBackend > &dev, const RegisterPath &registerPathName, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags)
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...
std::list< boost::shared_ptr< TransferElement > > getInternalElements() override
Obtain the full list of TransferElements internally used by this TransferElement.
LNMBackendRegisterInfo _info
register information
RegisterInfo structure for the LogicalNameMappingBackend.
std::string registerName
The target register name.
std::string deviceName
The target device alias.
TargetType targetType
Type of the target.
unsigned int channel
The channel of the target 2D register (if TargetType::CHANNEL)
N-dimensional register accessor.
Class to store a register path name.
cppext::future_queue< void > getReadQueue()
Function to get a copy of the read queue.
DataValidity _dataValidity
The validity of the data in the application buffer.
VersionNumber _versionNumber
The version number of the last successful transfer.
cppext::future_queue< void > _readQueue
The queue for asynchronous read transfers.
boost::shared_ptr< DeviceBackend > _exceptionBackend
The backend to which the runtime_errors are reported via DeviceBackend::setException().
Class for generating and holding version numbers without exposing a numeric representation.
Exception thrown when a logic error has occured.
Definition Exception.h:51
@ wait_for_new_data
Make any read blocking until new data has arrived since the last read.
TransferType
Used to indicate the applicable operation on a Transferelement.
std::string to_string(const std::string &v)