diff --git a/src/CSAdapterEqFct.cc b/src/CSAdapterEqFct.cc index 4914d6a2de95fd2873229d8cc999a0191eaede46..d968be4ed40e953fc6483fe2e1848466b3483c04 100644 --- a/src/CSAdapterEqFct.cc +++ b/src/CSAdapterEqFct.cc @@ -6,22 +6,22 @@ namespace ChimeraTK{ bool CSAdapterEqFct::emptyLocationVariablesHandled = false; - + CSAdapterEqFct::CSAdapterEqFct(int fctCode, boost::shared_ptr<ControlSystemPVManager> const & controlSystemPVManager, boost::shared_ptr<DoocsUpdater> const & updater, std::string fctName ) // The second argument in EqFct has to be a pointer to string, and NULL pointer is // used when the name is coming from the config file. This interface is so ugly that - // I changed it to std::string and need the ?: trick to get a NULL pointer in + // I changed it to std::string and need the ?: trick to get a NULL pointer in // if the string is empty : EqFct ("NAME = CSAdapterEqFct", fctName.empty()?NULL:&fctName), controlSystemPVManager_(controlSystemPVManager), fctCode_(fctCode), updater_(updater){ - + registerProcessVariablesInDoocs(); } - + CSAdapterEqFct::~CSAdapterEqFct(){ //stop the updater thread before any of the process variables go out of scope updater_->stop(); @@ -43,7 +43,13 @@ namespace ChimeraTK{ doocsProperties_.reserve( mappingForThisLocation.size() ); for (auto & propertyDescrition : mappingForThisLocation){ - doocsProperties_.push_back( factory.create( propertyDescrition ) ); + try { + doocsProperties_.push_back( factory.create( propertyDescrition ) ); + } + catch(std::invalid_argument &e) { + std::cerr << "**** WARNING: Could not create property for variable '" << propertyDescrition->location << "/" << + propertyDescrition->name << "': " << e.what() << ". Skipping this property." << std::endl; + } } } diff --git a/src/DoocsPVFactory.cc b/src/DoocsPVFactory.cc index a248fdf2fedde305774804b7436a5e0fa3f60740..da483b38826cd27184dc8ff4070df3a3907b6786 100644 --- a/src/DoocsPVFactory.cc +++ b/src/DoocsPVFactory.cc @@ -170,8 +170,9 @@ namespace ChimeraTK { } else if (valueType == typeid(double)) { return typedCreateScalarOrArray<double, D_double, double, D_doublearray, double>(*processVariable, *autoPropertyDescription, DecoratorType::range_checking, ArrayDescription::DataType::Double); } else if (valueType == typeid(std::string)) { - //@todo FIXME returning scalar also for arrays. This should result in an error - return createDoocsScalar<std::string, D_string>(*autoPropertyDescription, DecoratorType::range_checking); + return typedCreateScalarOrArray<std::string, D_string, std::string, + std::nullptr_t, std::nullptr_t>(*processVariable, *autoPropertyDescription, + DecoratorType::range_checking, ArrayDescription::DataType::Auto); } else { throw std::invalid_argument("unsupported value type"); } @@ -194,6 +195,12 @@ namespace ChimeraTK { return doocsPV; } + // template specialisation for cases with no matching DOOCS array type (e.g. string) + template<> + boost::shared_ptr<D_fct> DoocsPVFactory::typedCreateDoocsArray<std::nullptr_t,std::nullptr_t>(ArrayDescription const &){ + throw std::invalid_argument("Type not supported as an array"); + } + boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsArray( std::shared_ptr<ArrayDescription> const & arrayDescription){ if(arrayDescription->dataType == ArrayDescription::DataType::Auto){ // leave the desision which array to produce to the auto creation algorithm. We need it there anyway