9#include <ChimeraTK/cppext/finally.hpp>
15 template<
typename UserType>
19 size_t numberOfWords,
size_t wordOffsetInRegister,
AccessModeFlags flags)
27 _dev = boost::dynamic_pointer_cast<LogicalNameMappingBackend>(dev);
36 if(wordOffsetInRegister != 0) {
39 if(numberOfWords > 1) {
40 throw ChimeraTK::logic_error(
"LNMBackendBitAccessors must have size 1, but " + registerPathName +
" has size " +
47 std::string devName = info.deviceName;
48 boost::shared_ptr<DeviceBackend> targetDevice;
49 if(devName !=
"this") {
50 targetDevice =
_dev->_devices[devName];
56 std::unique_lock<std::mutex> l{
_dev->sharedAccessorMap_mutex};
57 auto& map = boost::fusion::at_key<uint64_t>(
_dev->sharedAccessorMap.table);
63 auto it = map.find(key);
67 if(it == map.end() || (
_accessor = map[key].accessor.lock()) ==
nullptr) {
68 _accessor = targetDevice->getRegisterAccessor<uint64_t>(key.second, numberOfWords, wordOffsetInRegister, {});
69 if(
_accessor->getNumberOfSamples() != 1) {
71 "LNMBackendBitAccessors only work with target registers of size 1: " + registerPathName);
75 lock = std::unique_lock<std::recursive_mutex>(map[key].mutex, std::defer_lock);
86 assert(
lock.owns_lock());
91 assert(
lock.owns_lock());
101 auto unlock = cppext::finally([
this] { this->
lock.unlock(); });
103 if(!hasNewData)
return;
130 auto unlock = cppext::finally([
this] { this->
lock.unlock(); });
134 [[nodiscard]]
bool mayReplaceOther(
const boost::shared_ptr<TransferElement const>& other)
const override {
135 auto rhsCasted = boost::dynamic_pointer_cast<const LNMBackendBitAccessor<UserType>>(other);
136 if(rhsCasted.get() ==
this) {
139 if(!rhsCasted)
return false;
141 if(
_dev != rhsCasted->_dev)
return false;
146 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
151 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
156 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
161 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
163 _accessor->setExceptionBackend(exceptionBackend);
168 boost::shared_ptr<NDRegisterAccessor<uint64_t>>
_accessor;
172 std::unique_lock<std::recursive_mutex>
lock;
183 boost::shared_ptr<LogicalNameMappingBackend>
_dev;
189 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
190 return _accessor->getHardwareAccessingElements();
194 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
195 auto result =
_accessor->getInternalElements();
201 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
202 auto casted = boost::dynamic_pointer_cast<NDRegisterAccessor<uint64_t>>(newElement);
203 if(casted &&
_accessor->mayReplaceOther(newElement)) {
204 _accessor = detail::createCopyDecorator<uint64_t>(casted);
207 _accessor->replaceTransferElement(newElement);
#define DECLARE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(TemplateClass)
Set of AccessMode flags with additional functionality for an easier handling.
bool has(AccessMode flag) const
Check if a certain flag is in the set.
void checkForUnknownFlags(const std::set< AccessMode > &knownFlags) const
Check of any flag which is not in the given set "knownFlags" is set.
VersionNumber _versionNumberTemp
temporary version number passed to the target accessor in write transfers The VersionNumber needs to ...
std::vector< boost::shared_ptr< TransferElement > > getHardwareAccessingElements() override
Obtain the underlying TransferElements with actual hardware access.
void doPostRead(TransferType type, bool hasNewData) override
Backend specific implementation of postRead().
std::list< boost::shared_ptr< TransferElement > > getInternalElements() override
Obtain the full list of TransferElements internally used by this TransferElement.
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...
void doPreWrite(TransferType type, VersionNumber) override
Backend specific implementation of preWrite().
void doReadTransferSynchronously() override
Implementation version of readTransfer() for synchronous reads.
void replaceTransferElement(boost::shared_ptr< TransferElement > newElement) override
Search for all underlying TransferElements which are considered identical (see sameRegister()) with t...
void doPostWrite(TransferType type, VersionNumber) override
Backend specific implementation of postWrite().
bool isWriteable() const override
Check if transfer element is writeable.
void setExceptionBackend(boost::shared_ptr< DeviceBackend > exceptionBackend) override
Set the backend to which the exception has to be reported.
bool isReadOnly() const override
Check if transfer element is read only, i.e.
bool isReadable() const override
Check if transfer element is readable.
size_t _bitMask
bit mask for the bit we want to access
boost::shared_ptr< LogicalNameMappingBackend > _dev
backend device
LNMBackendBitAccessor(const boost::shared_ptr< DeviceBackend > &dev, const RegisterPath ®isterPathName, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags)
RegisterPath _registerPathName
register and module name
void doPreRead(TransferType type) override
Backend specific implementation of preRead().
boost::shared_ptr< NDRegisterAccessor< uint64_t > > _accessor
pointer to underlying accessor
std::unique_lock< std::recursive_mutex > lock
Lock to be held during a transfer.
bool doWriteTransfer(ChimeraTK::VersionNumber) override
Implementation version of writeTransfer().
std::pair< DeviceBackend *, RegisterPath > AccessorKey
Map of target accessors which are potentially shared across our accessors.
N-dimensional register accessor.
Class to store a register path name.
void setAltSeparator(const std::string &altSeparator)
set alternative separator.
DataValidity _dataValidity
The validity of the data in the application buffer.
VersionNumber _versionNumber
The version number of the last successful transfer.
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.
@ raw
Raw access: disable any possible conversion from the original hardware data type into the given UserT...
TransferType
Used to indicate the applicable operation on a Transferelement.
std::string to_string(const std::string &v)