ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
AsyncNDRegisterAccessor.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 "../DeviceBackend.h"
6#include "../NDRegisterAccessor.h"
7#include "Domain.h"
8
9#include <ChimeraTK/cppext/finally.hpp>
10#include <ChimeraTK/cppext/future_queue.hpp>
11
12namespace ChimeraTK::async {
13
14 class AsyncAccessorManager;
15
22 template<typename UserType>
24 static constexpr size_t _queueSize{3};
25
26 public:
31 AsyncNDRegisterAccessor(boost::shared_ptr<DeviceBackend> backend, boost::shared_ptr<AsyncAccessorManager> manager,
32 boost::shared_ptr<Domain> asyncDomain, std::string const& name, size_t nChannels, size_t nElements,
33 AccessModeFlags accessModeFlags, std::string const& unit = std::string(TransferElement::unitNotSet),
34 std::string const& description = std::string());
35
36 ~AsyncNDRegisterAccessor() override;
37
41 void sendException(std::exception_ptr& e) { _dataTransportQueue.push_overwrite_exception(e); }
42
47
49 // implementation of inherited, virtual functions //
51
53 // This code should never be executed because the constructor checks that wait_for_new_data is set.
54 assert(false);
55 }
56
57 bool doWriteTransfer([[maybe_unused]] ChimeraTK::VersionNumber versionNumber) override {
58 assert(false);
59 return false;
60 }
61
62 bool doWriteTransferDestructively([[maybe_unused]] ChimeraTK::VersionNumber versionNumber) override {
63 assert(false);
64 return false;
65 }
66
67 void doPreWrite([[maybe_unused]] TransferType type, [[maybe_unused]] VersionNumber versionNumber) override {
68 throw ChimeraTK::logic_error("Writing is not supported for " + this->getName());
69 }
70
71 void doPreRead([[maybe_unused]] TransferType type) override {
72 if(!_backend->isOpen()) throw ChimeraTK::logic_error("Device not opened.");
73 // Pre-read conceptually does nothing in asynchronous reads
74 }
75
76 // Don't ask my why in template code the [[maybe_unused]] must be here, but gives a warning when put to the
77 // implementation.
78 void doPostRead([[maybe_unused]] TransferType type, bool updateDataBuffer) override;
79
80 [[nodiscard]] bool isReadOnly() const override {
81 return !isWriteable(); // as the accessor is always readable, isReadOnly() is equivalent to !isWriteable()
82 }
83 [[nodiscard]] bool isReadable() const override { return true; }
84 [[nodiscard]] bool isWriteable() const override { return false; }
85
86 void setExceptionBackend(boost::shared_ptr<DeviceBackend> exceptionBackend) override {
87 this->_exceptionBackend = exceptionBackend;
88 }
89
90 std::vector<boost::shared_ptr<TransferElement>> getHardwareAccessingElements() override {
91 return {boost::enable_shared_from_this<TransferElement>::shared_from_this()};
92 }
93 std::list<boost::shared_ptr<TransferElement>> getInternalElements() override { return {}; }
94
95 void replaceTransferElement(boost::shared_ptr<TransferElement> /*newElement*/) override {} // LCOV_EXCL_LINE
96
97 void interrupt() override { this->interrupt_impl(this->_dataTransportQueue); }
98
99 protected:
100 boost::shared_ptr<DeviceBackend> _backend;
101 boost::shared_ptr<AsyncAccessorManager> _accessorManager;
102 boost::shared_ptr<Domain> _asyncDomain;
104 using NDRegisterAccessor<UserType>::buffer_2D;
106
107 cppext::future_queue<Buffer, cppext::SWAP_DATA> _dataTransportQueue{_queueSize};
108 };
109
110 /********************************************************************************************************************/
111 /* Implementations are in the .cc file. We use the trick to declare for all known types here, */
112 /* and instantiate all of them in the .cc file. This is necessary because we cannot include */
113 /* AsyncAccessorManager.h to avoid a circular dependency, but need it for the implementation. */
114 /********************************************************************************************************************/
116
117} // namespace ChimeraTK::async
#define DECLARE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(TemplateClass)
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.
void interrupt_impl(QUEUE_TYPE &dataTransportQueue)
Implementation of interrupt()
static constexpr char unitNotSet[]
Constant string to be used as a unit when the unit is not provided or known.
const std::string & getName() const
Returns the name that identifies the process variable.
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.
The AsyncNDRegisterAccessor implements a data transport queue with typed data as continuation of the ...
boost::shared_ptr< AsyncAccessorManager > _accessorManager
void doPreRead(TransferType type) override
Backend specific implementation of preRead().
boost::shared_ptr< DeviceBackend > _backend
void doPostRead(TransferType type, bool updateDataBuffer) override
Backend specific implementation of postRead().
bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber) override
Implementation version of writeTransfer().
bool isReadOnly() const override
Check if transfer element is read only, i.e.
void setExceptionBackend(boost::shared_ptr< DeviceBackend > exceptionBackend) override
Set the backend to which the exception has to be reported.
void replaceTransferElement(boost::shared_ptr< TransferElement >) override
Search for all underlying TransferElements which are considered identical (see sameRegister()) with t...
void sendException(std::exception_ptr &e)
Pushes the exception to the queue.
bool doWriteTransferDestructively(ChimeraTK::VersionNumber versionNumber) override
Implementation version of writeTransferDestructively().
void doReadTransferSynchronously() override
Implementation version of readTransfer() for synchronous reads.
std::vector< boost::shared_ptr< TransferElement > > getHardwareAccessingElements() override
Obtain the underlying TransferElements with actual hardware access.
bool isReadable() const override
Check if transfer element is readable.
void doPreWrite(TransferType type, VersionNumber versionNumber) override
Backend specific implementation of preWrite().
void sendDestructively(typename NDRegisterAccessor< UserType >::Buffer &data)
You can only send destructively.
std::list< boost::shared_ptr< TransferElement > > getInternalElements() override
Obtain the full list of TransferElements internally used by this TransferElement.
bool isWriteable() const override
Check if transfer element is writeable.
void interrupt() override
Return from a blocking read immediately and throw boost::thread_interrupted.
cppext::future_queue< Buffer, cppext::SWAP_DATA > _dataTransportQueue
Exception thrown when a logic error has occured.
Definition Exception.h:51
TransferType
Used to indicate the applicable operation on a Transferelement.
Data type to create individual buffers.