12#include <ChimeraTK/cppext/finally.hpp>
20 template<
typename UserType>
24 size_t numberOfWords,
size_t wordOffsetInRegister,
AccessModeFlags flags)
33 _dev = boost::dynamic_pointer_cast<LogicalNameMappingBackend>(dev);
42 if(wordOffsetInRegister != 0) {
45 if(numberOfWords > 1) {
46 throw ChimeraTK::logic_error(
"LNMBackendBitAccessors must have size 1, but " + registerPathName +
" has size " +
53 std::string devName = info.deviceName;
54 boost::shared_ptr<DeviceBackend> targetDevice;
55 if(devName !=
"this") {
56 targetDevice =
_dev->_devices[devName];
62 std::unique_lock<std::mutex> l{
_dev->sharedAccessorMap_mutex};
63 auto& map = boost::fusion::at_key<uint64_t>(
_dev->sharedAccessorMap.table);
69 auto it = map.find(key);
73 if(it == map.end() || (
_accessor = map[key].accessor.lock()) ==
nullptr) {
74 _accessor = targetDevice->getRegisterAccessor<uint64_t>(key.second, numberOfWords, wordOffsetInRegister, {});
75 if(
_accessor->getNumberOfSamples() != 1) {
77 "LNMBackendBitAccessors only work with target registers of size 1: " + registerPathName);
81 lock = std::unique_lock<std::recursive_mutex>(map[key].mutex, std::defer_lock);
92 assert(
lock.owns_lock());
97 assert(
lock.owns_lock());
107 auto unlock = cppext::finally([
this] { this->
lock.unlock(); });
109 if(!hasNewData)
return;
136 auto unlock = cppext::finally([
this] { this->
lock.unlock(); });
140 [[nodiscard]]
bool mayReplaceOther(
const boost::shared_ptr<TransferElement const>& other)
const override {
141 auto rhsCasted = boost::dynamic_pointer_cast<const LNMBackendBitAccessor<UserType>>(other);
142 if(rhsCasted.get() ==
this) {
145 if(!rhsCasted)
return false;
147 if(
_dev != rhsCasted->_dev)
return false;
152 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
157 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
162 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
167 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
169 _accessor->setExceptionBackend(exceptionBackend);
174 boost::shared_ptr<NDRegisterAccessor<uint64_t>>
_accessor;
178 std::unique_lock<std::recursive_mutex>
lock;
189 boost::shared_ptr<LogicalNameMappingBackend>
_dev;
200 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
201 return _accessor->getHardwareAccessingElements();
205 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
206 auto result =
_accessor->getInternalElements();
212 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
213 auto casted = boost::dynamic_pointer_cast<NDRegisterAccessor<uint64_t>>(newElement);
214 if(casted &&
_accessor->mayReplaceOther(newElement)) {
215 _accessor = detail::createCopyDecorator<uint64_t>(casted);
218 _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.
The fixed point converter provides conversion functions between a user type and up to 32 bit fixed po...
RawType toRaw(UserType cookedValue) const
Conversion function from type T to fixed point.
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.
FixedPointConverter< DEPRECATED_FIXEDPOINT_DEFAULT > _fixedPointConverter
fixed point converter to handle type conversions from our "raw" type int to the requested user type.
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)