24 const std::string& registerPathName,
size_t numberOfWords,
size_t wordOffsetInRegister, AccessModeFlags flags);
30 void doPostRead(TransferType type,
bool hasNewData)
override;
31 void doPreWrite(TransferType, VersionNumber)
override;
34 return {boost::enable_shared_from_this<TransferElement>::shared_from_this()};
65 boost::shared_ptr<TangoBackend> backend_,
TangoRegisterInfo info,
const std::string& registerPathName,
66 size_t numberOfWords,
size_t wordOffsetInRegister, AccessModeFlags flags)
67 : NDRegisterAccessor<UserType>(registerPathName, flags), backend(std::move(backend_)), registerInfo(std::move(info)) {
70 auto nElements = numberOfWords;
73 nElements = actualLength;
76 if(flags.has(AccessMode::raw) || flags.has(AccessMode::wait_for_new_data)) {
77 throw ChimeraTK::logic_error(
"invalid access mode for this register");
81 throw ChimeraTK::logic_error(
82 "Requested number of words exceeds the length of the Tango attribute " + registerPathName);
87 NDRegisterAccessor<UserType>::buffer_2D.resize(1);
88 NDRegisterAccessor<UserType>::buffer_2D[0].resize(nElements);
131 NDRegisterAccessor<UserType>::doPreWrite(type, version);
132 if(!backend->isOpen()) {
133 throw ChimeraTK::logic_error(
"Write operation not allowed while device is closed.");
136 throw ChimeraTK::logic_error(
"Try to write read-only register \"" + registerInfo.getRegisterName() +
"\".");
139 std::vector<TangoType> value;
144 auto attr = backend->getDeviceProxy()->read_attribute(registerInfo.attributeInfo.name);
147 catch(CORBA::Exception& ex) {
148 throw ChimeraTK::runtime_error(
149 "Failure to read in read-modfiy-write of partial accessor " + registerInfo.getRegisterName());
154 value.resize(this->registerInfo.getNumberOfElements());
156 auto destinationStart = value.begin() + elementOffset;
158 if constexpr(std::is_same_v<TangoType, Tango::DevEnum>) {
159 std::transform(this->buffer_2D[0].begin(), this->buffer_2D[0].end(), destinationStart,
160 ChimeraTK::userTypeToNumeric<Tango::DevEnum, UserType>);
162 else if constexpr(std::is_same_v<TangoType, Tango::DevState>) {
165 std::transform(this->buffer_2D[0].begin(), this->buffer_2D[0].end(), destinationStart,
166 [](UserType& v) {
return static_cast<Tango::DevState
>(ChimeraTK::userTypeToNumeric<int, UserType>(v)); });
169 std::transform(this->buffer_2D[0].begin(), this->buffer_2D[0].end(), destinationStart,
170 ChimeraTK::userTypeToUserType<TangoType, UserType>);
172 this->writeAttribute = Tango::DeviceAttribute(this->registerInfo.attributeInfo.name, value);
191 NDRegisterAccessor<UserType>::doPostRead(type, hasNewData);
197 if(this->readAttribute.get_quality() != Tango::AttrQuality::ATTR_INVALID) {
198 std::vector<TangoType> value;
200 this->readAttribute >> value;
202 catch(Tango::DevFailed& ex) {
203 throw ChimeraTK::runtime_error(
"Failed to read from attribute " + registerInfo.attributeInfo.name);
206 auto length = std::min(this->buffer_2D[0].size(), value.size());
207 auto sourceStart = value.begin() + elementOffset;
208 auto sourceEnd = sourceStart + length;
209 if constexpr(std::is_same_v<TangoType, Tango::DevEnum>) {
211 sourceStart, sourceEnd, this->buffer_2D[0].begin(), ChimeraTK::numericToUserType<UserType, Tango::DevEnum>);
213 if constexpr(std::is_same_v<TangoType, Tango::DevState>) {
214 std::transform(sourceStart, sourceEnd, this->buffer_2D[0].begin(),
215 [](TangoType& v) {
return ChimeraTK::numericToUserType<UserType, int>(
static_cast<int>(v)); });
219 sourceStart, sourceEnd, this->buffer_2D[0].begin(), ChimeraTK::userTypeToUserType<UserType, TangoType>);
224 TransferElement::_versionNumber = {};
227 TransferElement::_dataValidity = (this->readAttribute.quality == Tango::AttrQuality::ATTR_VALID ||
228 this->readAttribute.quality == Tango::AttrQuality::ATTR_CHANGING) ?
230 DataValidity::faulty;