10#include <boost/make_shared.hpp>
30 [[nodiscard]]
size_t useCount()
const;
33 thread_local static size_t targetUseCount;
34 std::unique_lock<std::recursive_mutex> _lock;
39 thread_local size_t ReferenceCountedUniqueLock::targetUseCount;
44 assert(_lock.owns_lock());
45 return targetUseCount;
51 assert(targetUseCount > 0);
69 if(numberOfBits == 0) {
73 return (
static_cast<uint64_t
>(-(numberOfBits != 0)) &
74 (
static_cast<uint64_t
>(-1) >> ((
sizeof(uint64_t) * CHAR_BIT) - numberOfBits)));
79 template<
typename UserType,
typename TargetType>
86 uint64_t shift, uint64_t numberOfBits, uint64_t dataInterpretationFractionalBits,
87 uint64_t dataInterpretationIsSigned)
91 if(_target->getNumberOfChannels() > 1 || _target->getNumberOfSamples() > 1) {
96 auto& map = boost::fusion::at_key<TargetType>(backend->sharedAccessorMap.table);
101 auto it = map.find(key);
102 if(it != map.end()) {
118 _target->preRead(type);
124 auto unlock = cppext::finally([
this] { this->
_lock.
unlock(); });
125 _target->postRead(type, hasNewData);
126 if(!hasNewData)
return;
128 if constexpr(std::is_same_v<uint64_t, TargetType>) {
129 auto validity = _target->dataValidity();
130 uint64_t v{_target->accessData(0)};
174 _target->accessData(0) &= ~_maskOnTarget;
175 _target->accessData(0) |= (value <<
_shift);
185 auto unlock = cppext::finally([
this] { this->
_lock.
unlock(); });
192 auto casted = boost::dynamic_pointer_cast<BitRangeAccessPluginDecorator<UserType, TargetType>>(newElement);
198 if(casted && casted.get() !=
this && casted->_target == _target) {
201 casted->_writeable =
false;
228 const LNMBackendRegisterInfo& info,
size_t pluginIndex,
const std::map<std::string, std::string>& parameters)
231 const auto& shift = parameters.at(
"shift");
235 auto [suffix, ec]{std::from_chars(shift.data(), shift.data() + shift.size(),
_shift)};
236 if(ec != std::errc()) {
238 R
"(: Unparseable parameter "shift".)");
241 catch(std::out_of_range&) {
243 R
"(: Missing parameter "shift".)");
247 const auto& numberOfBits = parameters.at(
"numberOfBits");
250 auto [suffix, ec]{std::from_chars(numberOfBits.data(), numberOfBits.data() + numberOfBits.size(),
_numberOfBits)};
251 if(ec != std::errc()) {
253 R
"(: Unparseable parameter "numberOfBits".)");
256 catch(std::out_of_range&) {
258 R
"(: Unparseable parameter "numberOfBits".)");
261 if(
const auto it = parameters.find(
"fractionalBits"); it != parameters.end()) {
266 if(ec != std::errc()) {
268 R
"(: Unparseable parameter "fractionalBits".)");
272 if(
const auto it = parameters.find(
"signed"); it != parameters.end()) {
273 std::stringstream ss(it->second);
292 template<
typename UserType,
typename TargetType>
296 if constexpr(std::is_integral<TargetType>::value) {
297 return boost::make_shared<BitRangeAccessPluginDecorator<UserType, TargetType>>(backend, target, params.
_name,
void remove(AccessMode flag)
Remove the given flag from the set.
Wrapper Class to avoid vector<bool> problems.
void setRawDataType(const DataType &d)
Set the raw data type.
@ none
The data type/concept does not exist, e.g. there is no raw transfer (do not confuse with Void)
The fixed point converter provides conversion functions between a user type and up to 32 bit fixed po...
UserType scalarToCooked(RawType const &raw) const
Inefficient convenience function for converting a single value to cooked.
RawType toRaw(UserType cookedValue) const
Conversion function from type T to fixed point.
LNMBackendRegisterInfo _info
RegisterInfo describing the the target register for which this plugin instance should work.
Base class for plugins that modify the behaviour of accessors in the logical name mapping backend.
BitRangeAccessPlugin(const LNMBackendRegisterInfo &info, size_t pluginIndex, const std::map< std::string, std::string > ¶meters)
bool dataInterpretationIsSigned
boost::shared_ptr< NDRegisterAccessor< UserType > > decorateAccessor(boost::shared_ptr< LogicalNameMappingBackend > &backend, boost::shared_ptr< NDRegisterAccessor< TargetType > > &target, const UndecoratedParams &accessorParams)
void doRegisterInfoUpdate() override
Implementation of the plugin specific register information update.
uint32_t dataInterpretationFractionalBits
Helper class that keeps track of how many locks were taken on the recursive mutex in the current thre...
ReferenceCountedUniqueLock()=default
ReferenceCountedUniqueLock(std::recursive_mutex &mutex)
RegisterInfo structure for the LogicalNameMappingBackend.
RegisterPath getRegisterName() const override
Return full path name of the register (including modules)
DataDescriptor _dataDescriptor
AccessModeFlags supportedFlags
Supported AccessMode flags.
std::pair< DeviceBackend *, RegisterPath > AccessorKey
Map of target accessors which are potentially shared across our accessors.
Base class for decorators of the NDRegisterAccessor.
void replaceTransferElement(boost::shared_ptr< ChimeraTK::TransferElement > newElement) override
bool isWriteable() const override
N-dimensional register accessor.
std::vector< std::vector< UserType > > buffer_2D
Buffer of converted data elements.
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.
bool _isInTransferGroup
Flag whether this TransferElement has been added to a TransferGroup or not.
const std::string & getName() const
Returns the name that identifies the process variable.
Class for generating and holding version numbers without exposing a numeric representation.
Exception thrown when a logic error has occured.
constexpr uint64_t getMaskForNBits(uint64_t numberOfBits)
@ faulty
The data is considered valid.
@ wait_for_new_data
Make any read blocking until new data has arrived since the last read.
@ 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.
void doPostWrite(TransferType type, VersionNumber) override
Backend specific implementation of postWrite().
BitRangeAccessPluginDecorator(boost::shared_ptr< LogicalNameMappingBackend > &backend, const boost::shared_ptr< ChimeraTK::NDRegisterAccessor< TargetType > > &target, const std::string &name, uint64_t shift, uint64_t numberOfBits, uint64_t dataInterpretationFractionalBits, uint64_t dataInterpretationIsSigned)
VersionNumber _temporaryVersion
void doPreRead(TransferType type) override
Backend specific implementation of preRead().
void doPostRead(TransferType type, bool hasNewData) override
Backend specific implementation of postRead().
ReferenceCountedUniqueLock _lock
void replaceTransferElement(boost::shared_ptr< ChimeraTK::TransferElement > newElement) override
void doPreWrite(TransferType type, VersionNumber versionNumber) override
Backend specific implementation of preWrite().
FixedPointConverter< DEPRECATED_FIXEDPOINT_DEFAULT > fixedPointConverter
Helper struct to hold extra parameters needed by some plugins, used in decorateAccessor()