Skip to content
Snippets Groups Projects
Commit b7237dcd authored by Martin Christoph Hierholzer's avatar Martin Christoph Hierholzer
Browse files

TestFacility: fix not sending initial values for Void variables

parent fb5f36c8
No related branches found
No related tags found
No related merge requests found
......@@ -22,38 +22,48 @@ namespace ChimeraTK {
void TestFacility::runApplication() const {
app.testFacilityRunApplicationCalled = true;
// send default values for all control system variables
for(auto& pv : pvManager->getAllProcessVariables()) {
callForTypeNoVoid(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!
callForType(pv->getValueType(), [&pv, this](auto arg) {
using T = decltype(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 "
"TestFacility::setScalarDefault() resp. setArrayDefault() to set initial values.");
}
typedef decltype(arg) T;
// Get the PV accessor
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());
if constexpr(!std::is_same<T, ChimeraTK::Void>::value) {
auto table = boost::fusion::at_key<T>(defaults.table);
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());
}
// 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();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment