6 #include <doocs/EqCall.h>
9 #include <ChimeraTK/SupportedUserTypes.h>
17 template<
typename UserType>
24 const std::string& registerPathName,
size_t numberOfWords,
size_t wordOffsetInRegister, AccessModeFlags flags);
26 void doPostRead(TransferType type,
bool hasNewData)
override;
28 void doPreWrite(TransferType type, VersionNumber)
override;
38 template<
typename CALLABLE>
46 template<
typename UserType>
48 boost::shared_ptr<DoocsBackend> backend,
const std::string& path,
const std::string& registerPathName,
49 size_t numberOfWords,
size_t wordOffsetInRegister, AccessModeFlags flags)
51 backend, path, registerPathName, numberOfWords, wordOffsetInRegister, flags) {
60 catch(ChimeraTK::runtime_error&) {
70 template<
typename UserType>
77 template<
typename UserType>
78 template<
typename CALLABLE>
104 callable(uint32_t());
114 callable(uint64_t());
130 throw ChimeraTK::runtime_error(
"DoocsBackend: Unexpected DOOCS type found in remote property " +
131 this->ea.show_adr() +
": " + data.type_string() +
" is not a numeric type.");
137 template<
typename UserType>
140 switch(this->dst.type()) {
142 return this->dst.get_bool();
147 return this->dst.get_short(index);
151 return this->dst.get_ushort(index);
156 return this->dst.get_int(index);
160 return this->dst.get_uint(index);
164 return this->dst.get_long(index);
168 return this->dst.get_ulong(index);
174 return this->dst.get_float(index);
179 return this->dst.get_double(index);
192 template<
typename UserType>
195 if(!hasNewData)
return;
198 if(this->dst.type() == DATA_NULL) {
202 std::fill(this->accessChannel(0).begin(), this->accessChannel(0).end(), UserType());
207 if(
size_t(this->dst.length()) < this->nElements + this->elementOffset) {
208 throw ChimeraTK::runtime_error(
"DoocsBackend: Unexpected array length found in remote property " +
209 this->ea.show_adr() +
": " + std::to_string(this->dst.length()) +
" is shorter than the expected " +
210 std::to_string(this->nElements + this->elementOffset));
214 auto copyFromSourcePointer = [&](
const auto* sourcePointer) {
215 using SourceType = std::remove_const_t<std::remove_reference_t<decltype(*sourcePointer)>>;
216 assert(sourcePointer);
218 sourcePointer += this->elementOffset;
219 if constexpr(std::is_same<UserType, SourceType>::value) {
221 memcpy(this->buffer_2D[0].data(), sourcePointer, this->nElements *
sizeof(SourceType));
224 std::transform(sourcePointer, sourcePointer + this->nElements, this->buffer_2D[0].begin(),
225 [](
const SourceType& v) {
return ChimeraTK::numericToUserType<UserType>(v); });
230 switch(this->dst.type()) {
233 copyFromSourcePointer(this->dst.get_float_array());
236 case DATA_A_DOUBLE: {
237 copyFromSourcePointer(this->dst.get_double_array());
241 copyFromSourcePointer(this->dst.get_int_array());
245 copyFromSourcePointer(this->dst.get_long_array());
250 copyFromSourcePointer(this->dst.get_short_array());
255 callForDoocsType(this->dst, [&](
auto t) {
256 using T = decltype(t);
257 for(
size_t i = 0; i < this->nElements; i++) {
258 this->buffer_2D[0][i] = ChimeraTK::numericToUserType<UserType>(dataGet<T>(i + this->elementOffset));
268 TransferType type, VersionNumber version) {
276 template<
typename UserType>
281 if(this->isPartial) {
282 this->doReadTransferSynchronously();
283 this->src = this->dst;
285 if(
size_t(this->src.length()) < this->nElements + this->elementOffset) {
286 this->src.length(this->nElements + this->elementOffset);
291 auto copyToTargetPointer = [&](
auto* targetPointer) {
292 using TargetType = std::remove_reference_t<decltype(*targetPointer)>;
293 assert(targetPointer);
295 targetPointer += this->elementOffset;
296 if constexpr(std::is_same<UserType, TargetType>::value) {
298 memcpy(targetPointer, this->buffer_2D[0].data(), this->nElements *
sizeof(TargetType));
301 std::transform(this->buffer_2D[0].begin(), this->buffer_2D[0].end(), targetPointer,
302 [](UserType v) {
return ChimeraTK::userTypeToNumeric<TargetType>(v); });
307 switch(this->src.type()) {
310 copyToTargetPointer(this->src.get_float_array());
313 case DATA_A_DOUBLE: {
314 copyToTargetPointer(this->src.get_double_array());
318 copyToTargetPointer(this->src.get_int_array());
322 copyToTargetPointer(this->src.get_long_array());
327 copyToTargetPointer(this->src.get_short_array());
332 callForDoocsType(this->src, [&](
auto t) {
333 using T = decltype(t);
334 if(this->src.array_length() == 0) {
336 this->src.set(ChimeraTK::userTypeToNumeric<T>(this->buffer_2D[0][0]));
339 for(
size_t i = 0; i < this->nElements; i++) {
340 this->src.set(ChimeraTK::userTypeToNumeric<T>(this->buffer_2D[0][i]),
int(i + this->elementOffset));