ChimeraTK-DeviceAccess  03.18.00
TransferElement.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 "AccessMode.h"
6 #include "DeviceBackend.h"
7 #include "Exception.h"
8 #include "TransferElementID.h"
9 #include "VersionNumber.h"
10 
11 #include <ChimeraTK/cppext/future_queue.hpp>
12 
13 #include <boost/bind/bind.hpp>
14 #include <boost/enable_shared_from_this.hpp>
15 #include <boost/numeric/conversion/cast.hpp>
16 #include <boost/shared_ptr.hpp>
17 #include <boost/thread.hpp>
18 #include <boost/thread/future.hpp>
19 
20 #include <functional>
21 #include <iostream>
22 #include <list>
23 #include <string>
24 #include <typeinfo>
25 #include <utility>
26 #include <vector>
27 
28 namespace ChimeraTK {
29  class PersistentDataStorage;
30  class TransferGroup;
31 
41  enum class DataValidity {
42  ok,
43  faulty
44  };
45 
46  std::ostream& operator<<(std::ostream& os, const DataValidity& validity);
47 
52 
53  namespace detail {
60  class DiscardValueException {};
61 
62  } /* namespace detail */
63 
64  /********************************************************************************************************************/
65 
67  class TransferElement : public boost::enable_shared_from_this<TransferElement> {
68  public:
70  TransferElement(std::string name, AccessModeFlags accessModeFlags, std::string unit = std::string(unitNotSet),
71  std::string description = std::string())
72  : _name(std::move(name)), _unit(std::move(unit)), _description(std::move(description)),
73  _accessModeFlags(std::move(accessModeFlags)) {}
74 
76  TransferElement(const TransferElement& other) = delete;
77  TransferElement(TransferElement&& other) = delete;
78  TransferElement& operator=(const TransferElement& other) = delete;
79  TransferElement& operator=(TransferElement&& other) = delete;
80 
82  virtual ~TransferElement() = default;
83 
85  using SharedPtr = boost::shared_ptr<TransferElement>;
86 
88  const std::string& getName() const { return _name; }
89 
92  const std::string& getUnit() const { return _unit; }
93 
95  const std::string& getDescription() const { return _description; }
96 
100  virtual const std::type_info& getValueType() const = 0;
101 
104 
108 
112 
116  void read() {
118  throw ChimeraTK::logic_error("Calling read() or write() on the TransferElement '" + _name +
119  "' which is part of a TransferGroup is not allowed.");
120  }
122  throw ChimeraTK::logic_error("Directly calling read() on the TransferElement '" + _name +
123  "' which is part of a ReadAnyGroup is not allowed.");
124  }
125  this->readTransactionInProgress = false;
126 
127  preReadAndHandleExceptions(TransferType::read);
128  if(!_activeException) {
129  handleTransferException([&] { readTransfer(); });
130  }
131 
132  postReadAndHandleExceptions(TransferType::read, !_activeException);
133  }
134 
148  throw ChimeraTK::logic_error("Calling read() or write() on the TransferElement '" + _name +
149  "' which is part of a TransferGroup is not allowed.");
150  }
152  throw ChimeraTK::logic_error("Directly calling readNonBlocking() on the TransferElement '" + _name +
153  "' which is part of a ReadAnyGroup is not allowed.");
154  }
155  this->readTransactionInProgress = false;
156  preReadAndHandleExceptions(TransferType::readNonBlocking);
157  bool updateDataBuffer = false;
158  if(!_activeException) {
159  handleTransferException([&] { updateDataBuffer = readTransferNonBlocking(); });
160  }
161 
162  bool retVal = updateDataBuffer;
163  if(_activeException) {
164  auto previousVersionNumber = _versionNumber;
165  auto previousDataValidity = _dataValidity;
166  // always call postRead with updateDataBuffer = false in case of an exception
167  postReadAndHandleExceptions(TransferType::readNonBlocking, false);
168  // Usually we do not reach this point because postRead() is re-throwing the _activeException.
169  // If we reach this point the exception has been suppressed. We have to calculate a
170  // new return value because the dataBuffer has not changed, but the meta data
171  // could have, in which case we have to return true.
172  retVal = (previousVersionNumber != _versionNumber) || (previousDataValidity != _dataValidity);
173  }
174  else {
175  // call postRead with updateDataBuffer as returned by readTransferNonBlocking
176  postReadAndHandleExceptions(TransferType::readNonBlocking, updateDataBuffer);
177  }
178  return retVal;
179  }
180 
185  bool readLatest() {
187  bool updateDataBuffer = false;
188  // Call readNonBlocking until there is no new data to be read any more
189  while(readNonBlocking()) {
190  // remember whether we have new data
191  updateDataBuffer = true;
192  }
193  return updateDataBuffer;
194  }
195  // Without wait_for_new_data readNonBlocking always returns true, and the while loop above would never end.
196  // Hence we just call the (synchronous) read and return true;
197  read();
198  return true;
199  }
200 
204  bool write(ChimeraTK::VersionNumber versionNumber = {}) {
206  throw ChimeraTK::logic_error("Calling read() or write() on the TransferElement '" + _name +
207  "' which is part of a TransferGroup is not allowed.");
208  }
209  this->writeTransactionInProgress = false;
210  bool previousDataLost = true; // the value here does not matter. If there was an exception, it will be re-thrown
211  // in postWrite, so it is never returned
212 
213  preWriteAndHandleExceptions(TransferType::write, versionNumber);
214  if(!_activeException) {
215  handleTransferException([&] { previousDataLost = writeTransfer(versionNumber); });
216  }
217 
218  postWriteAndHandleExceptions(TransferType::write, versionNumber);
219  return previousDataLost;
220  }
221 
226  bool writeDestructively(ChimeraTK::VersionNumber versionNumber = {}) {
228  throw ChimeraTK::logic_error("Calling read() or write() on the TransferElement '" + _name +
229  "' which is part of a TransferGroup is not allowed.");
230  }
231  this->writeTransactionInProgress = false;
232 
233  preWriteAndHandleExceptions(TransferType::writeDestructively, versionNumber);
234  bool previousDataLost = true; // the value here does not matter. If there was an exception, it will be re-thrown
235  // in postWrite, so it is never returned
236  if(!_activeException) {
237  handleTransferException([&] { previousDataLost = writeTransferDestructively(versionNumber); });
238  }
239 
240  postWriteAndHandleExceptions(TransferType::writeDestructively, versionNumber);
241  return previousDataLost;
242  }
243 
260 
263  virtual bool isReadOnly() const = 0;
264 
267  virtual bool isReadable() const = 0;
268 
271  virtual bool isWriteable() const = 0;
272 
278  void setActiveException(std::exception_ptr& setThisException) {
279  if(setThisException) {
280  _activeException = setThisException;
281  setThisException = nullptr;
282  }
283  }
284 
295  virtual void setExceptionBackend(boost::shared_ptr<DeviceBackend> exceptionBackend) {
296  _exceptionBackend = std::move(exceptionBackend);
297  }
298 
301  boost::shared_ptr<DeviceBackend> getExceptionBackend() { return _exceptionBackend; }
302 
306  cppext::future_queue<void> getReadQueue() { return _readQueue; }
307 
308  protected:
313  boost::shared_ptr<DeviceBackend> _exceptionBackend;
314 
315  private:
319  template<typename Callable>
320  void handleTransferException(Callable function) {
321  try {
322  function();
323  }
324  catch(ChimeraTK::runtime_error&) {
325  _activeException = std::current_exception();
326  }
327  catch(boost::thread_interrupted&) {
328  _activeException = std::current_exception();
329  }
330  }
331 
332  // helper function that just gets rid of the DiscardValueException and otherwise does a pop_wait on the _readQueue.
333  // It does not deal with other exceptions. This is done in handleTransferException.
334  void readTransferAsyncWaitingImpl() {
335  retry:
336  try {
337  _readQueue.pop_wait();
338  }
339  catch(detail::DiscardValueException&) {
340  goto retry;
341  }
342  }
343 
344  public:
354  void readTransfer() {
356  readTransferAsyncWaitingImpl();
357  }
358  else {
360  }
361  }
362 
363  protected:
376  virtual void doReadTransferSynchronously() = 0;
377 
378  private:
379  // helper function that just gets rid of the DiscardValueException and otherwise does a pop on the _readQueue.
380  // It does not deal with other exceptions. This is done in handleTransferException.
381  bool readTransferAsyncNonWaitingImpl() {
382  retry:
383  try {
384  return _readQueue.pop();
385  }
386  catch(detail::DiscardValueException&) {
387  goto retry;
388  }
389  }
390 
391  public:
404  return readTransferAsyncNonWaitingImpl();
405  }
407  return true;
408  }
409 
410  private:
412  void preReadAndHandleExceptions(TransferType type) noexcept {
413  try {
414  preRead(type);
415  }
416  catch(ChimeraTK::logic_error&) {
417  _activeException = std::current_exception();
418  }
419  catch(ChimeraTK::runtime_error&) {
420  _activeException = std::current_exception();
421  }
422  catch(boost::thread_interrupted&) {
423  _activeException = std::current_exception();
424  }
425  }
426 
427  public:
432  void preRead(TransferType type) {
433  if(readTransactionInProgress) return;
434  _activeException = {nullptr};
435 
436  readTransactionInProgress = true; // remember that doPreRead has been called. It might throw, so we remember
437  // before we call it
438  doPreRead(type);
439  }
440 
447  protected:
448  virtual void doPreRead(TransferType) {}
449 
450  private:
453  void postReadAndHandleExceptions(TransferType type, bool updateDataBuffer) {
454  try {
455  postRead(type, updateDataBuffer);
456  }
457  catch(ChimeraTK::runtime_error& ex) {
458  if(_exceptionBackend) {
459  _exceptionBackend->setException(ex.what());
460  }
461  throw;
462  }
463  }
464 
465  public:
473  void postRead(TransferType type, bool updateDataBuffer) {
474  // only delegate to doPostRead() the first time postRead() is called in a row.
475  if(readTransactionInProgress) {
476  readTransactionInProgress = false;
477  doPostRead(type, updateDataBuffer);
478  }
479 
480  // Throw on each call of postRead(). All high-level elements for a shared low-level transfer element must see the
481  // exception. Note: doPostRead can throw an exception, but in that case _activeException must be false (we can
482  // only have one exception at a time). In case other code is added here later which needs to be executed after
483  // doPostRead() always, a try-catch block may be necessary.
484  if(_activeException) {
485  // don't clear the active connection. This is done in preRead().
486  std::rethrow_exception(_activeException);
487  }
488  }
489 
502  protected:
503  virtual void doPostRead(TransferType, bool /*updateDataBuffer*/) {}
504 
505  private:
507  void preWriteAndHandleExceptions(TransferType type, ChimeraTK::VersionNumber versionNumber) noexcept {
508  try {
509  preWrite(type, versionNumber);
510  }
511  catch(ChimeraTK::logic_error&) {
512  _activeException = std::current_exception();
513  }
514  catch(ChimeraTK::runtime_error&) {
515  _activeException = std::current_exception();
516  }
517  catch(boost::thread_interrupted&) {
518  _activeException = std::current_exception();
519  }
520  }
521 
522  public:
530  void preWrite(TransferType type, ChimeraTK::VersionNumber versionNumber) {
531  if(writeTransactionInProgress) return;
532 
533  _activeException = {};
534  if(versionNumber < getVersionNumber()) {
535  throw ChimeraTK::logic_error("The version number passed to write() of TransferElement '" + _name +
536  "' is less than the last version number used.");
537  }
538  writeTransactionInProgress = true; // must not be set, if the logic_error is thrown above due to the old version
539  doPreWrite(type, versionNumber);
540  }
541 
548  protected:
550 
551  private:
554  void postWriteAndHandleExceptions(TransferType type, VersionNumber versionNumber) {
555  try {
556  postWrite(type, versionNumber);
557  }
558  catch(ChimeraTK::runtime_error& ex) {
559  if(_exceptionBackend) {
560  _exceptionBackend->setException(ex.what());
561  }
562  throw;
563  }
564  }
565 
566  public:
573  void postWrite(TransferType type, VersionNumber versionNumber) {
574  if(writeTransactionInProgress) {
575  writeTransactionInProgress = false;
576  doPostWrite(type, versionNumber);
577  }
578 
579  // Note: doPostWrite can throw an exception, but in that case hasSeenException must be false (we can only have one
580  // exception at a time). In case other code is added here later which needs to be executed after doPostWrite()
581  // always, a try-catch block may be necessary.
582  // Another note: If writeTransactionInProgress == false, there can still be an exception, if the version number
583  // used in a write was too old (see preWrite).
584  if(_activeException) {
585  std::rethrow_exception(_activeException);
586  }
587 
588  // only after a successful write the version number is updated
589  _versionNumber = versionNumber;
590  }
591 
598  protected:
600 
601  public:
610  bool writeTransfer(ChimeraTK::VersionNumber versionNumber) { return doWriteTransfer(versionNumber); }
611 
612  protected:
620  virtual bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber) = 0;
621 
622  public:
635  return doWriteTransferDestructively(versionNumber);
636  }
637 
638  protected:
650  return doWriteTransfer(versionNumber);
651  }
652 
653  public:
677  virtual bool mayReplaceOther(const boost::shared_ptr<TransferElement const>& other) const {
678  (void)other; // prevent warning
679  return false;
680  }
681 
690  virtual std::vector<boost::shared_ptr<TransferElement>> getHardwareAccessingElements() = 0;
691 
711  virtual std::list<boost::shared_ptr<TransferElement>> getInternalElements() = 0;
712 
722  virtual boost::shared_ptr<TransferElement> getHighLevelImplElement() { return shared_from_this(); }
723 
730  // FIXME #11279 Implement API breaking changes from linter warnings
731  // NOLINTNEXTLINE(performance-unnecessary-value-param)
732  virtual void replaceTransferElement([[maybe_unused]] boost::shared_ptr<TransferElement> newElement) {}
733 
738  virtual boost::shared_ptr<TransferElement> makeCopyRegisterDecorator() = 0;
739 
742  static constexpr char unitNotSet[] = "n./a.";
743 
754  // FIXME #11279 Implement API breaking changes from linter warnings
755  // NOLINTNEXTLINE(performance-unnecessary-value-param)
756  virtual void setPersistentDataStorage(boost::shared_ptr<ChimeraTK::PersistentDataStorage>) {}
757 
762  TransferElementID getId() const { return _id; }
763 
783  virtual void interrupt() {}
784 
791  template<typename QUEUE_TYPE>
792  void interrupt_impl(QUEUE_TYPE& dataTransportQueue) {
793  dataTransportQueue.push_overwrite_exception(std::make_exception_ptr(boost::thread_interrupted()));
794  }
795 
797  bool isReadTransactionInProgress() const { return readTransactionInProgress; }
798 
800  bool isWriteTransactionInProgress() const { return writeTransactionInProgress; }
801 
802  protected:
804  std::string _name;
805 
807  std::string _unit;
808 
810  std::string _description;
811 
814 
817 
820  bool _isInTransferGroup{false};
821 
823  bool _isInReadAnyGroup{false};
824 
827 
828  friend class TransferGroup;
829  friend class ReadAnyGroup;
830 
831  private:
837  bool readTransactionInProgress{false};
838 
841  bool writeTransactionInProgress{false};
842 
843  protected:
847  cppext::future_queue<void> _readQueue;
848 
852 
856 
859  std::exception_ptr _activeException{nullptr};
860  }; // namespace ChimeraTK
861 
862 } /* namespace ChimeraTK */
863 namespace std {
864 
865  /********************************************************************************************************************/
866 
869  template<>
870  struct hash<ChimeraTK::TransferElementID> {
871  std::size_t operator()(const ChimeraTK::TransferElementID& f) const { return std::hash<size_t>{}(f._id); }
872  };
873 
874  /********************************************************************************************************************/
875 
877  template<>
878  struct less<ChimeraTK::TransferElementID> {
880  return a._id < b._id;
881  }
882  };
883 } // namespace std
ChimeraTK::runtime_error::what
const char * what() const noexcept override
Return the message describing what exactly went wrong.
Definition: Exception.cpp:14
ChimeraTK::TransferElement::readLatest
bool readLatest()
Read the latest value, discarding any other update since the last read if present.
Definition: TransferElement.h:185
ChimeraTK::TransferType::readLatest
@ readLatest
VersionNumber.h
DeviceBackend.h
ChimeraTK::TransferElement::doPostRead
virtual void doPostRead(TransferType, bool)
Backend specific implementation of postRead().
Definition: TransferElement.h:503
ChimeraTK::TransferElement::setPersistentDataStorage
virtual void setPersistentDataStorage(boost::shared_ptr< ChimeraTK::PersistentDataStorage >)
Associate a persistent data storage object to be updated on each write operation of this ProcessArray...
Definition: TransferElement.h:756
ChimeraTK::TransferType::writeDestructively
@ writeDestructively
ChimeraTK::DataValidity::faulty
@ faulty
The data is considered valid.
ChimeraTK::TransferElement::getName
const std::string & getName() const
Returns the name that identifies the process variable.
Definition: TransferElement.h:88
ChimeraTK::TransferElement::setActiveException
void setActiveException(std::exception_ptr &setThisException)
Set an active exception.
Definition: TransferElement.h:278
ChimeraTK::TransferElement::_id
TransferElementID _id
The ID of this TransferElement.
Definition: TransferElement.h:813
ChimeraTK::TransferElement::doWriteTransfer
virtual bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber)=0
Implementation version of writeTransfer().
ChimeraTK::TransferElement::replaceTransferElement
virtual void replaceTransferElement([[maybe_unused]] boost::shared_ptr< TransferElement > newElement)
Search for all underlying TransferElements which are considered identical (see sameRegister()) with t...
Definition: TransferElement.h:732
ChimeraTK::TransferElement::getDescription
const std::string & getDescription() const
Returns the description of this variable/register.
Definition: TransferElement.h:95
ChimeraTK::TransferElement::readNonBlocking
bool readNonBlocking()
Read the next value, if available in the input buffer.
Definition: TransferElement.h:146
ChimeraTK::TransferElement::getReadQueue
cppext::future_queue< void > getReadQueue()
Function to get a copy of the read queue.
Definition: TransferElement.h:306
ChimeraTK::TransferElement::getHighLevelImplElement
virtual boost::shared_ptr< TransferElement > getHighLevelImplElement()
Obtain the highest level implementation TransferElement.
Definition: TransferElement.h:722
ChimeraTK::TransferElement::readTransfer
void readTransfer()
Read the data from the device but do not fill it into the user buffer of this TransferElement.
Definition: TransferElement.h:354
ChimeraTK::TransferElement::makeCopyRegisterDecorator
virtual boost::shared_ptr< TransferElement > makeCopyRegisterDecorator()=0
Create a CopyRegisterDecorator of the right type decorating this TransferElement.
ChimeraTK::TransferElement::writeDestructively
bool writeDestructively(ChimeraTK::VersionNumber versionNumber={})
Just like write(), but allows the implementation to destroy the content of the user buffer in the pro...
Definition: TransferElement.h:226
ChimeraTK::TransferElement::interrupt_impl
void interrupt_impl(QUEUE_TYPE &dataTransportQueue)
Implementation of interrupt()
Definition: TransferElement.h:792
ChimeraTK::TransferElement::getExceptionBackend
boost::shared_ptr< DeviceBackend > getExceptionBackend()
Return the exception backend.
Definition: TransferElement.h:301
ChimeraTK::TransferElement::writeTransferDestructively
bool writeTransferDestructively(ChimeraTK::VersionNumber versionNumber)
Write the data to the device.
Definition: TransferElement.h:634
ChimeraTK::TransferElement::dataValidity
DataValidity dataValidity() const
Return current validity of the data.
Definition: TransferElement.h:111
ChimeraTK::TransferElement::_isInTransferGroup
bool _isInTransferGroup
Flag whether this TransferElement has been added to a TransferGroup or not.
Definition: TransferElement.h:820
ChimeraTK::TransferElement::setDataValidity
void setDataValidity(DataValidity validity=DataValidity::ok)
Set the current DataValidity for this TransferElement.
Definition: TransferElement.h:107
ChimeraTK::TransferElement::preWrite
void preWrite(TransferType type, ChimeraTK::VersionNumber versionNumber)
Transfer the data from the user buffer into the device send buffer, while converting the data from th...
Definition: TransferElement.h:530
TransferElementID.h
ChimeraTK::TransferElement::doReadTransferSynchronously
virtual void doReadTransferSynchronously()=0
Implementation version of readTransfer() for synchronous reads.
ChimeraTK::TransferElement::isReadOnly
virtual bool isReadOnly() const =0
Check if transfer element is read only, i.e.
ChimeraTK::TransferElement::_activeException
std::exception_ptr _activeException
Exception to be rethrown in postXXX() in case hasSeenException == true Can be set via setActiveExcept...
Definition: TransferElement.h:859
ChimeraTK::TransferElement::_unit
std::string _unit
Engineering unit.
Definition: TransferElement.h:807
ChimeraTK::TransferElementID::makeUnique
void makeUnique()
Assign an ID to this instance.
Definition: TransferElementID.cc:14
ChimeraTK::runtime_error
Exception thrown when a runtime error has occured.
Definition: Exception.h:18
ChimeraTK::TransferGroup
Group multiple data accessors to efficiently trigger data transfers on the whole group.
Definition: TransferGroup.h:26
ChimeraTK::TransferElement::~TransferElement
virtual ~TransferElement()=default
Abstract base classes need a virtual destructor.
ChimeraTK::TransferElement::postRead
void postRead(TransferType type, bool updateDataBuffer)
Transfer the data from the device receive buffer into the user buffer, while converting the data into...
Definition: TransferElement.h:473
ChimeraTK::TransferElement::getAccessModeFlags
AccessModeFlags getAccessModeFlags() const
Return the AccessModeFlags for this TransferElement.
Definition: TransferElement.h:103
ChimeraTK::TransferElement::SharedPtr
boost::shared_ptr< TransferElement > SharedPtr
A typedef for more compact syntax.
Definition: TransferElement.h:85
ChimeraTK::AccessModeFlags::has
bool has(AccessMode flag) const
Check if a certain flag is in the set.
Definition: AccessMode.cc:20
ChimeraTK::TransferElement::postWrite
void postWrite(TransferType type, VersionNumber versionNumber)
Perform any post-write clean-ups if necessary.
Definition: TransferElement.h:573
ChimeraTK::TransferElement::getHardwareAccessingElements
virtual std::vector< boost::shared_ptr< TransferElement > > getHardwareAccessingElements()=0
Obtain the underlying TransferElements with actual hardware access.
ChimeraTK::TransferElement::readTransferNonBlocking
bool readTransferNonBlocking()
Read the data from the device but do not fill it into the user buffer of this TransferElement.
Definition: TransferElement.h:402
ChimeraTK::TransferElement::unitNotSet
static constexpr char unitNotSet[]
Constant string to be used as a unit when the unit is not provided or known.
Definition: TransferElement.h:742
ChimeraTK::TransferElement::doPostWrite
virtual void doPostWrite(TransferType, VersionNumber)
Backend specific implementation of postWrite().
Definition: TransferElement.h:599
ChimeraTK::TransferElement::write
bool write(ChimeraTK::VersionNumber versionNumber={})
Write the data to device.
Definition: TransferElement.h:204
ChimeraTK::TransferElementID::_id
size_t _id
The actual ID value.
Definition: TransferElementID.h:48
ChimeraTK::DataValidity::ok
@ ok
ChimeraTK::DataValidity
DataValidity
The current state of the data.
Definition: TransferElement.h:41
ChimeraTK::TransferElement::doWriteTransferDestructively
virtual bool doWriteTransferDestructively(ChimeraTK::VersionNumber versionNumber)
Implementation version of writeTransferDestructively().
Definition: TransferElement.h:649
ChimeraTK::TransferElement::doPreWrite
virtual void doPreWrite(TransferType, VersionNumber)
Backend specific implementation of preWrite().
Definition: TransferElement.h:549
ChimeraTK::AccessMode::wait_for_new_data
@ wait_for_new_data
Make any read blocking until new data has arrived since the last read.
ChimeraTK::TransferElement::setExceptionBackend
virtual void setExceptionBackend(boost::shared_ptr< DeviceBackend > exceptionBackend)
Set the backend to which the exception has to be reported.
Definition: TransferElement.h:295
ChimeraTK::TransferElement::_dataValidity
DataValidity _dataValidity
The validity of the data in the application buffer.
Definition: TransferElement.h:855
ChimeraTK::TransferElement::_name
std::string _name
Identifier uniquely identifying the TransferElement.
Definition: TransferElement.h:804
ChimeraTK::TransferElement::_exceptionBackend
boost::shared_ptr< DeviceBackend > _exceptionBackend
The backend to which the runtime_errors are reported via DeviceBackend::setException().
Definition: TransferElement.h:313
ChimeraTK::TransferElement::TransferElement
TransferElement(std::string name, AccessModeFlags accessModeFlags, std::string unit=std::string(unitNotSet), std::string description=std::string())
Creates a transfer element with the specified name.
Definition: TransferElement.h:70
ChimeraTK::TransferType
TransferType
Used to indicate the applicable operation on a Transferelement.
Definition: TransferElement.h:51
ChimeraTK::TransferElement::doPreRead
virtual void doPreRead(TransferType)
Backend specific implementation of preRead().
Definition: TransferElement.h:448
ChimeraTK::TransferElement::isWriteable
virtual bool isWriteable() const =0
Check if transfer element is writeable.
ChimeraTK::TransferElement::makeUniqueId
void makeUniqueId()
Allow generating a unique ID from derived classes.
Definition: TransferElement.h:816
ChimeraTK::TransferElement::preRead
void preRead(TransferType type)
Perform any pre-read tasks if necessary.
Definition: TransferElement.h:432
std::hash< ChimeraTK::TransferElementID >::operator()
std::size_t operator()(const ChimeraTK::TransferElementID &f) const
Definition: TransferElement.h:871
std::less< ChimeraTK::TransferElementID >::operator()
bool operator()(const ChimeraTK::TransferElementID &a, const ChimeraTK::TransferElementID &b) const
Definition: TransferElement.h:879
ChimeraTK::TransferElement::_description
std::string _description
Description of this variable/register.
Definition: TransferElement.h:810
ChimeraTK::TransferType::write
@ write
ChimeraTK::TransferType::readNonBlocking
@ readNonBlocking
ChimeraTK::TransferElement::getVersionNumber
ChimeraTK::VersionNumber getVersionNumber() const
Returns the version number that is associated with the last transfer (i.e.
Definition: TransferElement.h:259
ChimeraTK::TransferElement
Base class for register accessors which can be part of a TransferGroup.
Definition: TransferElement.h:67
ChimeraTK::TransferElement::mayReplaceOther
virtual bool mayReplaceOther(const boost::shared_ptr< TransferElement const > &other) const
Check whether the TransferElement can be used in places where the TransferElement "other" is currentl...
Definition: TransferElement.h:677
ChimeraTK::TransferElement::isReadTransactionInProgress
bool isReadTransactionInProgress() const
Check whether a read transaction is in progress, i.e.
Definition: TransferElement.h:797
ChimeraTK::TransferElement::getUnit
const std::string & getUnit() const
Returns the engineering unit.
Definition: TransferElement.h:92
ChimeraTK::TransferElement::getId
TransferElementID getId() const
Obtain unique ID for this TransferElement, see TransferElementID for details.
Definition: TransferElement.h:762
ChimeraTK::ReadAnyGroup
Group several registers (= TransferElement) to allow waiting for an update of any of the registers.
Definition: ReadAnyGroup.h:21
ChimeraTK::operator<<
std::ostream & operator<<(std::ostream &stream, const DataDescriptor::FundamentalType &fundamentalType)
Definition: DataDescriptor.cpp:195
AccessMode.h
ChimeraTK::VersionNumber
Class for generating and holding version numbers without exposing a numeric representation.
Definition: VersionNumber.h:23
ChimeraTK::TransferElement::getInternalElements
virtual std::list< boost::shared_ptr< TransferElement > > getInternalElements()=0
Obtain the full list of TransferElements internally used by this TransferElement.
ChimeraTK::TransferElement::_readQueue
cppext::future_queue< void > _readQueue
The queue for asynchronous read transfers.
Definition: TransferElement.h:847
ChimeraTK::TransferElement::writeTransfer
bool writeTransfer(ChimeraTK::VersionNumber versionNumber)
Write the data to the device.
Definition: TransferElement.h:610
ChimeraTK::TransferElement::_isInReadAnyGroup
bool _isInReadAnyGroup
Flag whether this TransferElement has been added to a ReadAnyGroup or not.
Definition: TransferElement.h:823
ChimeraTK::TransferElement::operator=
TransferElement & operator=(const TransferElement &other)=delete
ChimeraTK::AccessModeFlags
Set of AccessMode flags with additional functionality for an easier handling.
Definition: AccessMode.h:48
Exception.h
ChimeraTK::TransferElementID
Simple class holding a unique ID for a TransferElement.
Definition: TransferElementID.h:17
ChimeraTK::TransferElement::read
void read()
Read the data from the device.
Definition: TransferElement.h:116
ChimeraTK::TransferElement::_accessModeFlags
AccessModeFlags _accessModeFlags
The access mode flags for this transfer element.
Definition: TransferElement.h:826
ChimeraTK::TransferElement::isWriteTransactionInProgress
bool isWriteTransactionInProgress() const
Check whether a write transaction is in progress, i.e.
Definition: TransferElement.h:800
ChimeraTK
Definition: DummyBackend.h:16
ChimeraTK::TransferType::read
@ read
ChimeraTK::TransferElement::isReadable
virtual bool isReadable() const =0
Check if transfer element is readable.
ChimeraTK::TransferElement::interrupt
virtual void interrupt()
Return from a blocking read immediately and throw boost::thread_interrupted.
Definition: TransferElement.h:783
ChimeraTK::TransferElement::getValueType
virtual const std::type_info & getValueType() const =0
Returns the std::type_info for the value type of this transfer element.
ChimeraTK::logic_error
Exception thrown when a logic error has occured.
Definition: Exception.h:51
ChimeraTK::TransferElement::_versionNumber
VersionNumber _versionNumber
The version number of the last successful transfer.
Definition: TransferElement.h:851