diff --git a/include/TestFacility.h b/include/TestFacility.h index 6d2be730f7c578768cbb2180cc28e1c61619bafb..401ab5bea2451cdb4f68fd42304147054d024668 100644 --- a/include/TestFacility.h +++ b/include/TestFacility.h @@ -41,7 +41,10 @@ namespace ChimeraTK { // send default values for all control system variables for(auto& pv : pvManager->getAllProcessVariables()) { callForType(pv->getValueType(), [&pv, this](auto arg) { + // Applies only to writeable variables. @todo FIXME It should also NOT apply for application-to-controlsystem + // variables with a return channel, despite being writeable here! if(!pv->isWriteable()) return; + // Safety check against incorrect usage if(pv->getVersionNumber() != VersionNumber(nullptr)) { throw ChimeraTK::logic_error("The variable '" + pv->getName() + "' has been written before TestFacility::runApplication() was called. Instead use " @@ -50,9 +53,25 @@ namespace ChimeraTK { typedef decltype(arg) T; auto pv_casted = boost::dynamic_pointer_cast<NDRegisterAccessor<T>>(pv); auto table = boost::fusion::at_key<T>(defaults.table); + // If default value has been stored, copy the default value to the PV. if(table.find(pv->getName()) != table.end()) { + /// Since pv_casted is the undecorated PV (lacking the TestableModeAccessorDecorator), we need to copy the + /// value also to the decorator. We still have to write through the undecorated PV, otherwise the tests are + /// stalled. @todo It is not understood why this happens! + /// Decorated accessors are stored in different maps for scalars are arrays... + if(pv_casted->getNumberOfSamples() == 1) { // scalar + auto accessor = this->getScalar<T>(pv->getName()); + accessor = table.at(pv->getName())[0]; + } + else { // array + auto accessor = this->getArray<T>(pv->getName()); + accessor = table.at(pv->getName()); + } + // copy value also to undecorated PV pv_casted->accessChannel(0) = table.at(pv->getName()); } + // Write the initial value. This must be done even if no default value has been stored, since it is expected + // by the application. pv_casted->write(); }); }