15 :
NDRegisterAccessor<UserType>(registerPathName, flags), _registerPathName(registerPathName),
16 _wordOffsetInRegister(wordOffsetInRegister), _flags(flags) {
18 _dev = boost::dynamic_pointer_cast<LogicalNameMappingBackend>(dev);
34 if(numberOfWords == 0) numberOfWords =
_info.
length;
37 if(wordOffsetInRegister + numberOfWords >
_info.
length) {
39 "Requested number of words and/or offset exceeds length of register '" + registerPathName +
"'.");
56 std::lock_guard<std::mutex> lock(lnmVariable.valueTable_mutex);
59 using T = decltype(arg);
60 auto& vtEntry = boost::fusion::at_key<T>(lnmVariable.valueTable.table);
62 cppext::future_queue<typename LNMVariable::ValueTable<T>::QueuedValue> queue(3);
64 vtEntry.subscriptions[this->getId()] = queue;
66 this->_readQueue = queue.template then<void>(
67 [this](const typename LNMVariable::ValueTable<T>::QueuedValue& queueValue) {
68 this->_queueValue.validity = queueValue.validity;
69 this->_queueValue.version = queueValue.version;
70 for(size_t i = 0; i < queueValue.value.size(); ++i) {
71 this->_queueValue.value[i] =
72 userTypeToUserType<UserType>(queueValue.value[i + this->_wordOffsetInRegister]);
75 std::launch::deferred);
77 if(
_dev->_asyncReadActive) {
78 queue.push({vtEntry.latestValue, vtEntry.latestValidity, vtEntry.latestVersion});
84 auto& lnmVariable = _dev->_variables[_info.name];
85 for(
auto* mp : lnmVariable.usingFormulas) {
86 if(mp->_hasPushParameter) {
88 if(!mp->_creatingFormulaHelper) {
89 auto h = mp->getFormulaHelper(_dev);
90 _formulaHelpers.push_back(h);
141 _dev->checkActiveException();
142 auto& lnmVariable = _dev->_variables[_info.name];
143 std::lock_guard<std::mutex> lock(lnmVariable.valueTable_mutex);
146 auto& vtEntry = boost::fusion::at_key<decltype(arg)>(lnmVariable.valueTable.table);
149 for(size_t i = 0; i < this->buffer_2D[0].size(); ++i) {
150 vtEntry.latestValue[i + _wordOffsetInRegister] = userTypeToUserType<decltype(arg)>(this->buffer_2D[0][i]);
152 vtEntry.latestValidity = this->dataValidity();
153 vtEntry.latestVersion = v;
156 if(_dev->_asyncReadActive) {
157 for(
auto& sub : vtEntry.subscriptions) {
158 sub.second.push_overwrite({vtEntry.latestValue, this->dataValidity(), v});
183 const boost::shared_ptr<TransferElement const>& other)
const {
184 auto rhsCasted = boost::dynamic_pointer_cast<const LNMBackendVariableAccessor<UserType>>(other);
185 if(rhsCasted.get() ==
this) {
191 if(_dev != rhsCasted->_dev) {
194 if(_info != rhsCasted->_info) {
197 if(_wordOffsetInRegister != rhsCasted->_wordOffsetInRegister) {
200 if(_flags != rhsCasted->_flags) {
243 if(!hasNewData)
return;
245 if(!_flags.has(AccessMode::wait_for_new_data)) {
247 auto& lnmVariable = _dev->_variables[_info.name];
248 std::lock_guard<std::mutex> lock(lnmVariable.valueTable_mutex);
251 auto& vtEntry = boost::fusion::at_key<decltype(arg)>(lnmVariable.valueTable.table);
252 for(size_t i = 0; i < this->buffer_2D[0].size(); ++i) {
253 this->buffer_2D[0][i] = userTypeToUserType<UserType>(vtEntry.latestValue[i + _wordOffsetInRegister]);
255 this->_dataValidity = vtEntry.latestValidity;
260 this->_versionNumber = vtEntry.latestVersion;
265 this->buffer_2D[0].swap(_queueValue.value);
266 this->_versionNumber = _queueValue.version;
267 this->_dataValidity = _queueValue.validity;
275 auto& lnmVariable = _dev->_variables[_info.name];
276 std::lock_guard<std::mutex> lock(lnmVariable.valueTable_mutex);
279 auto& vtEntry = boost::fusion::at_key<decltype(arg)>(lnmVariable.valueTable.table);
280 auto itsub = vtEntry.subscriptions.find(this->getId());
281 if(itsub != vtEntry.subscriptions.end()) {
282 this->interrupt_impl(itsub->second);