7 template<
typename UserType>
10 const boost::shared_ptr<DeviceBackend>& backend, std::shared_ptr<detail::CountedRecursiveMutex> mutex,
12 :
NDRegisterAccessor<UserType>(registerPathName, flags), _doubleBufferInfo(
std::move(doubleBufferConfig)),
14 _transferLock(*_mutex,
std::defer_lock) {
20 auto buf0Name = registerPathName +
".BUF0";
21 auto buf1Name = registerPathName +
".BUF1";
23 _buffer0 = backend->getRegisterAccessor<UserType>(buf0Name, numberOfWords, wordOffsetInRegister, flags);
24 _buffer1 = backend->getRegisterAccessor<UserType>(buf1Name, numberOfWords, wordOffsetInRegister, flags);
25 size_t nChannels =
_buffer0->getNumberOfChannels();
29 for(
size_t i = 0; i < nChannels; ++i) {
34 std::lock_guard<detail::CountedRecursiveMutex> lg(*
_mutex);
35 if(
_mutex->useCount() == 1) {
42 template<
typename UserType>
47 if(_mutex->useCount() == 1) {
48 _enableDoubleBufferReg->accessData(0) = 0;
49 _enableDoubleBufferReg->write();
52 _currentBufferNumberReg->read();
53 _currentBuffer = _currentBufferNumberReg->accessData(0);
56 if(_currentBuffer == 1) {
57 _buffer0->preRead(type);
60 _buffer1->preRead(type);
64 template<
typename UserType>
66 if(_currentBuffer == 1) {
67 _buffer0->readTransfer();
70 _buffer1->readTransfer();
74 template<
typename UserType>
76 auto unlocker = cppext::finally([&] { _transferLock.unlock(); });
77 if(_currentBuffer == 1) {
78 _buffer0->postRead(type, hasNewData);
81 _buffer1->postRead(type, hasNewData);
85 if(_mutex->useCount() == 1) {
86 _enableDoubleBufferReg->accessData(0) = 1;
87 _enableDoubleBufferReg->write();
90 this->_versionNumber = {};
91 if(_currentBuffer == 1) {
92 this->_dataValidity = _buffer0->dataValidity();
95 this->_dataValidity = _buffer1->dataValidity();
106 auto& reg = (_currentBuffer == 1) ? _buffer0 : _buffer1;
107 for(
size_t i = 0; i < reg->getNumberOfChannels(); ++i) {
108 buffer_2D[i].swap(reg->accessChannel(i));
113 template<
typename UserType>
117 return {TransferElement::shared_from_this()};
120 template<
typename UserType>
122 auto otherDoubleBuffer = boost::dynamic_pointer_cast<const DoubleBufferAccessor<UserType>>(other);
123 if(!otherDoubleBuffer || otherDoubleBuffer.get() ==
this) {
126 return (_buffer0->mayReplaceOther(otherDoubleBuffer->_buffer0));
#define INSTANTIATE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(TemplateClass)
Set of AccessMode flags with additional functionality for an easier handling.
void doPostRead(TransferType type, bool hasNewData) override
Backend specific implementation of postRead().
DoubleBufferAccessor(NumericAddressedRegisterInfo::DoubleBufferInfo doubleBufferConfig, const boost::shared_ptr< DeviceBackend > &backend, std::shared_ptr< detail::CountedRecursiveMutex > mutex, const RegisterPath ®isterPathName, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags)
boost::shared_ptr< NDRegisterAccessor< UserType > > _buffer1
boost::shared_ptr< ChimeraTK::NDRegisterAccessor< uint32_t > > _enableDoubleBufferReg
void doReadTransferSynchronously() override
Implementation version of readTransfer() for synchronous reads.
void doPreRead(TransferType type) override
Backend specific implementation of preRead().
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...
boost::shared_ptr< NDRegisterAccessor< UserType > > _buffer0
std::vector< boost::shared_ptr< TransferElement > > getHardwareAccessingElements() override
Obtain the underlying TransferElements with actual hardware access.
std::shared_ptr< detail::CountedRecursiveMutex > _mutex
NumericAddressedRegisterInfo::DoubleBufferInfo _doubleBufferInfo
boost::shared_ptr< ChimeraTK::NDRegisterAccessor< uint32_t > > _currentBufferNumberReg
N-dimensional register accessor.
std::vector< std::vector< UserType > > buffer_2D
Buffer of converted data elements.
Base class for address-based device backends (e.g.
Class to store a register path name.
TransferType
Used to indicate the applicable operation on a Transferelement.
uint32_t index
Index in enable register.
RegisterPath inactiveBufferRegisterPath
inactive register (BUF0/BUF1)
RegisterPath enableRegisterPath
double buffer enable