ChimeraTK-DeviceAccess  03.18.00
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"
7 #include "NDRegisterAccessor.h"
8 #include "TwoDRegisterAccessor.h"
9 
10 #include <algorithm>
11 
12 namespace ChimeraTK {
13 
14  /********************************************************************************************************************/
15 
16  template<typename UserType>
17  class LNMBackendChannelAccessor : public NDRegisterAccessor<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
32  assert(_info.targetType == LNMBackendRegisterInfo::TargetType::CHANNEL);
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
60  TransferElement::_readQueue = _accessor->getReadQueue();
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) return false;
89  if(_registerPathName != rhsCasted->_registerPathName) return false;
90  if(_dev != rhsCasted->_dev) return false;
91  return true;
92  }
93 
94  [[nodiscard]] bool isReadOnly() const override { return true; }
95 
96  [[nodiscard]] bool isReadable() const override { return true; }
97 
98  [[nodiscard]] bool isWriteable() const override { return false; }
99 
100  void setExceptionBackend(boost::shared_ptr<DeviceBackend> exceptionBackend) override {
101  this->_exceptionBackend = exceptionBackend;
102  _accessor->setExceptionBackend(exceptionBackend);
103  }
104 
105  void interrupt() override { _accessor->interrupt(); }
106 
107  protected:
109  boost::shared_ptr<NDRegisterAccessor<UserType>> _accessor;
110 
113 
115  boost::shared_ptr<LogicalNameMappingBackend> _dev;
116 
119 
120  std::vector<boost::shared_ptr<TransferElement>> getHardwareAccessingElements() override {
121  return _accessor->getHardwareAccessingElements();
122  }
123 
124  std::list<boost::shared_ptr<TransferElement>> getInternalElements() override {
125  auto result = _accessor->getInternalElements();
126  result.push_front(_accessor);
127  return result;
128  }
129 
130  void replaceTransferElement(boost::shared_ptr<TransferElement> newElement) override {
131  auto casted = boost::dynamic_pointer_cast<NDRegisterAccessor<UserType>>(newElement);
132  if(casted && _accessor->mayReplaceOther(newElement)) {
133  _accessor = casted;
134  }
135  else {
136  _accessor->replaceTransferElement(newElement);
137  }
138  _accessor->setExceptionBackend(this->_exceptionBackend);
139  }
140  };
141 
142  DECLARE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(LNMBackendChannelAccessor);
143 
144 } // namespace ChimeraTK
ChimeraTK::LNMBackendChannelAccessor::doWriteTransfer
bool doWriteTransfer(ChimeraTK::VersionNumber) override
Definition: LNMBackendChannelAccessor.h:65
ChimeraTK::LNMBackendRegisterInfo::channel
unsigned int channel
The channel of the target 2D register (if TargetType::CHANNEL)
Definition: LNMBackendRegisterInfo.h:65
ChimeraTK::LNMBackendRegisterInfo::registerName
std::string registerName
The target register name.
Definition: LNMBackendRegisterInfo.h:56
ChimeraTK::LNMBackendChannelAccessor::mayReplaceOther
bool mayReplaceOther(const boost::shared_ptr< TransferElement const > &other) const override
Definition: LNMBackendChannelAccessor.h:86
TwoDRegisterAccessor.h
ChimeraTK::LNMBackendChannelAccessor::isReadable
bool isReadable() const override
Definition: LNMBackendChannelAccessor.h:96
ChimeraTK::LNMBackendChannelAccessor::_info
LNMBackendRegisterInfo _info
register information
Definition: LNMBackendChannelAccessor.h:118
LogicalNameMappingBackend.h
ChimeraTK::LNMBackendChannelAccessor::_registerPathName
RegisterPath _registerPathName
register and module name
Definition: LNMBackendChannelAccessor.h:112
ChimeraTK::LNMBackendChannelAccessor::doReadTransferSynchronously
void doReadTransferSynchronously() override
Definition: LNMBackendChannelAccessor.h:63
ChimeraTK::LNMBackendChannelAccessor::doPreWrite
void doPreWrite(TransferType type, VersionNumber) override
Definition: LNMBackendChannelAccessor.h:70
ChimeraTK::LNMBackendChannelAccessor::isReadOnly
bool isReadOnly() const override
Definition: LNMBackendChannelAccessor.h:94
ChimeraTK::LNMBackendChannelAccessor::setExceptionBackend
void setExceptionBackend(boost::shared_ptr< DeviceBackend > exceptionBackend) override
Definition: LNMBackendChannelAccessor.h:100
ChimeraTK::LNMBackendChannelAccessor::LNMBackendChannelAccessor
LNMBackendChannelAccessor(const boost::shared_ptr< DeviceBackend > &dev, const RegisterPath &registerPathName, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags)
Definition: LNMBackendChannelAccessor.h:19
NDRegisterAccessor.h
ChimeraTK::LNMBackendChannelAccessor::doPostRead
void doPostRead(TransferType type, bool hasNewData) override
Definition: LNMBackendChannelAccessor.h:78
ChimeraTK::AccessMode::wait_for_new_data
@ wait_for_new_data
Make any read blocking until new data has arrived since the last read.
ChimeraTK::LNMBackendRegisterInfo
RegisterInfo structure for the LogicalNameMappingBackend.
Definition: LNMBackendRegisterInfo.h:22
ChimeraTK::LNMBackendChannelAccessor
Definition: LNMBackendChannelAccessor.h:17
Device.h
ChimeraTK::LNMBackendChannelAccessor::getHardwareAccessingElements
std::vector< boost::shared_ptr< TransferElement > > getHardwareAccessingElements() override
Definition: LNMBackendChannelAccessor.h:120
ChimeraTK::LNMBackendRegisterInfo::deviceName
std::string deviceName
The target device alias.
Definition: LNMBackendRegisterInfo.h:53
ChimeraTK::TransferType
TransferType
Used to indicate the applicable operation on a Transferelement.
Definition: TransferElement.h:51
ChimeraTK::LNMBackendRegisterInfo::targetType
TargetType targetType
Type of the target.
Definition: LNMBackendRegisterInfo.h:50
ChimeraTK::AccessModeFlags::checkForUnknownFlags
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
ChimeraTK::LNMBackendChannelAccessor::doPreRead
void doPreRead(TransferType type) override
Definition: LNMBackendChannelAccessor.h:76
ChimeraTK::LNMBackendChannelAccessor::_accessor
boost::shared_ptr< NDRegisterAccessor< UserType > > _accessor
pointer to underlying accessor
Definition: LNMBackendChannelAccessor.h:109
ChimeraTK::LNMBackendChannelAccessor::_dev
boost::shared_ptr< LogicalNameMappingBackend > _dev
backend device
Definition: LNMBackendChannelAccessor.h:115
ChimeraTK::LNMBackendChannelAccessor::interrupt
void interrupt() override
Definition: LNMBackendChannelAccessor.h:105
ChimeraTK::LNMBackendChannelAccessor::getInternalElements
std::list< boost::shared_ptr< TransferElement > > getInternalElements() override
Definition: LNMBackendChannelAccessor.h:124
ChimeraTK::RegisterPath
Class to store a register path name.
Definition: RegisterPath.h:16
ChimeraTK::LNMBackendChannelAccessor::replaceTransferElement
void replaceTransferElement(boost::shared_ptr< TransferElement > newElement) override
Definition: LNMBackendChannelAccessor.h:130
ChimeraTK::VersionNumber
Class for generating and holding version numbers without exposing a numeric representation.
Definition: VersionNumber.h:23
ChimeraTK::TransferElement::_readQueue
cppext::future_queue< void > _readQueue
The queue for asynchronous read transfers.
Definition: TransferElement.h:847
ChimeraTK::AccessModeFlags
Set of AccessMode flags with additional functionality for an easier handling.
Definition: AccessMode.h:48
ChimeraTK::DECLARE_TEMPLATE_FOR_CHIMERATK_USER_TYPES
DECLARE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(DummyInterruptTriggerAccessor)
ChimeraTK
Definition: DummyBackend.h:16
ChimeraTK::LNMBackendChannelAccessor::isWriteable
bool isWriteable() const override
Definition: LNMBackendChannelAccessor.h:98
ChimeraTK::to_string
std::string to_string(Boolean &value)
Definition: SupportedUserTypes.h:59
ChimeraTK::NDRegisterAccessor
N-dimensional register accessor.
Definition: ForwardDeclarations.h:17
ChimeraTK::logic_error
Exception thrown when a logic error has occured.
Definition: Exception.h:51