ChimeraTK-DeviceAccess 03.29.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 // propagate the (plugin-updated) engineering unit and description from the register info into the accessor
34
35 // check for incorrect usage of this accessor
37
38 // get target device and accessor
39 std::string devName = _info.deviceName;
40 boost::shared_ptr<DeviceBackend> targetDevice;
41 if(devName != "this") {
42 targetDevice = _dev->_devices[devName];
43 }
44 else {
45 targetDevice = dev;
46 }
47 _accessor = targetDevice->getRegisterAccessor<UserType>(
48 RegisterPath(_info.registerName), numberOfWords, wordOffsetInRegister, flags);
49
50 // verify channel number
51 if(_info.channel >= _accessor->getNumberOfChannels()) {
52 throw ChimeraTK::logic_error("LNMBackendChannelAccessor: Requested channel number " +
54 " exceeds number of channels of target register,"
55 " in accesor for register '" +
56 registerPathName + "'.");
57 }
58
59 // allocate the buffer
61 NDRegisterAccessor<UserType>::buffer_2D[0].resize(_accessor->getNumberOfSamples());
62
63 // set readQueue
65 }
66
67 void doReadTransferSynchronously() override { _accessor->readTransfer(); }
68
69 bool doWriteTransfer(ChimeraTK::VersionNumber /*versionNumber*/) override {
70 assert(false); // writing not allowed
71 return true;
72 }
73
74 void doPreWrite(TransferType type, VersionNumber) override {
75 std::ignore = type;
76 throw ChimeraTK::logic_error("Writing to channel-type registers of logical "
77 "name mapping devices is not supported.");
78 }
79
80 void doPreRead(TransferType type) override { _accessor->preRead(type); }
81
82 void doPostRead(TransferType type, bool hasNewData) override {
83 _accessor->postRead(type, hasNewData);
84 if(!hasNewData) return;
86 this->_versionNumber = _accessor->getVersionNumber();
87 this->_dataValidity = _accessor->dataValidity();
88 }
89
90 [[nodiscard]] bool mayReplaceOther(const boost::shared_ptr<TransferElement const>& other) const override {
91 auto rhsCasted = boost::dynamic_pointer_cast<const LNMBackendChannelAccessor<UserType>>(other);
92 if(rhsCasted.get() == this) {
93 return false;
94 }
95 if(!rhsCasted) return false;
96 if(_registerPathName != rhsCasted->_registerPathName) return false;
97 if(_dev != rhsCasted->_dev) return false;
98 return true;
99 }
100
101 [[nodiscard]] bool isReadOnly() const override { return true; }
102
103 [[nodiscard]] bool isReadable() const override { return true; }
104
105 [[nodiscard]] bool isWriteable() const override { return false; }
106
107 void setExceptionBackend(boost::shared_ptr<DeviceBackend> exceptionBackend) override {
108 this->_exceptionBackend = exceptionBackend;
109 _accessor->setExceptionBackend(exceptionBackend);
110 }
111
112 void interrupt() override { _accessor->interrupt(); }
113
114 protected:
116 boost::shared_ptr<NDRegisterAccessor<UserType>> _accessor;
117
120
122 boost::shared_ptr<LogicalNameMappingBackend> _dev;
123
126
127 std::vector<boost::shared_ptr<TransferElement>> getHardwareAccessingElements() override {
128 return _accessor->getHardwareAccessingElements();
129 }
130
131 std::list<boost::shared_ptr<TransferElement>> getInternalElements() override {
132 auto result = _accessor->getInternalElements();
133 result.push_front(_accessor);
134 return result;
135 }
136
137 void replaceTransferElement(boost::shared_ptr<TransferElement> newElement) override {
138 auto casted = boost::dynamic_pointer_cast<NDRegisterAccessor<UserType>>(newElement);
139 if(casted && _accessor->mayReplaceOther(newElement)) {
140 _accessor = casted;
141 }
142 else {
143 _accessor->replaceTransferElement(newElement);
144 }
145 _accessor->setExceptionBackend(this->_exceptionBackend);
146 }
147 };
148
150
151} // 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 description
Custom description overwritten by plugins (e.g.
std::string engineeringUnit
Custom engineering unit overwritten by plugins (e.g.
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.
std::string _description
Description of this variable/register.
std::string _unit
Engineering unit.
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)