Skip to content
Snippets Groups Projects
Commit 77619b23 authored by Martin Killenberg's avatar Martin Killenberg
Browse files

split createDoocsProperty into createDoocsScalar and createDoocsSpectrum for further refactoring

parent 510a8453
No related branches found
No related tags found
No related merge requests found
......@@ -29,18 +29,22 @@ namespace ChimeraTK {
protected:
EqFct * _eqFct; //< The EqFct which is holding the factory. Needed in the constructor of the doocs properties.
boost::shared_ptr<ControlSystemSynchronizationUtility> _syncUtility; //< The syncUtility is needed to register listeners
boost::shared_ptr<ControlSystemPVManager> _controlSystemPVManager; //< The pv manager, needed to get the instances @todo Do we need it in a proper design?
boost::shared_ptr<ControlSystemPVManager> _controlSystemPVManager; //< The pv manager, needed to get the instances
// create the DOOCS property. Note: DOOCS_T is only used for scalar properties, not for arrays!
template<class T, class DOOCS_T>
typename boost::shared_ptr<D_fct> createDoocsProperty(typename ProcessVariable::SharedPtr & processVariable);
typename boost::shared_ptr<D_fct> createDoocsScalar(typename ProcessVariable::SharedPtr & processVariable);
template<class T>
typename boost::shared_ptr<D_fct> createDoocsSpectrum(typename ProcessVariable::SharedPtr & processVariable);
boost::shared_ptr<D_fct> autoCreate( std::shared_ptr<PropertyDescription> const & propertyDescription);
};
// specialisation for strings
template<>
typename boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsProperty<std::string, D_string>(typename ProcessVariable::SharedPtr & processVariable);
typename boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsScalar<std::string, D_string>(typename ProcessVariable::SharedPtr & processVariable);
}//namespace ChimeraTK
......
......@@ -8,6 +8,7 @@
#include "DoocsPVFactory.h"
#include "splitStringAtFirstSlash.h"
#include "VariableMapper.h"
#include <ChimeraTK/ControlSystemAdapter/TypeChangingDecorator.h>
namespace ChimeraTK {
......@@ -18,7 +19,7 @@ namespace ChimeraTK {
}
template<class T, class DOOCS_T>
typename boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsProperty(typename ProcessVariable::SharedPtr & processVariable) {
typename boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsScalar(typename ProcessVariable::SharedPtr & processVariable) {
// the DoocsProcessArray needs the real ProcessScalar type, not just ProcessVariable
typename boost::shared_ptr< mtca4u::NDRegisterAccessor<T> > processArray
= boost::dynamic_pointer_cast< mtca4u::NDRegisterAccessor<T> >(processVariable);
......@@ -33,42 +34,37 @@ namespace ChimeraTK {
assert(processArray->getNumberOfChannels() == 1);
boost::shared_ptr<D_fct> doocsPV;
if(processArray->getNumberOfSamples() > 1 ) {
doocsPV.reset( new DoocsSpectrum<T>(_eqFct, propertyDescription->name, processArray, *_syncUtility) );
// Histories seem to be supported by DOOCS only for property names shorter than 64 characters, so disable history for longer names.
// The DOOCS property name is the variable name without the location name and the separating slash between location and property name.
if(propertyDescription->name.length() > 64) {
std::cerr << "WARNING: Disabling history for " << processArray->getName() << ". Name is too long." << std::endl;
doocsPV.reset( new DoocsProcessScalar<T, DOOCS_T>(propertyDescription->name.c_str(), _eqFct, processArray, *_syncUtility) );
}
else { // scalar
// Histories seem to be supported by DOOCS only for property names shorter than 64 characters, so disable history for longer names.
// The DOOCS property name is the variable name without the location name and the separating slash between location and property name.
if(propertyDescription->name.length() > 64) {
std::cerr << "WARNING: Disabling history for " << processArray->getName() << ". Name is too long." << std::endl;
else{
if (autoPropertyDescription && autoPropertyDescription->hasHistory){
// version with history: EqFtc first
doocsPV.reset( new DoocsProcessScalar<T, DOOCS_T>(_eqFct, propertyDescription->name.c_str(), processArray, *_syncUtility) );
}else{
// version without history: name first
doocsPV.reset( new DoocsProcessScalar<T, DOOCS_T>(propertyDescription->name.c_str(), _eqFct, processArray, *_syncUtility) );
}
else{
if (autoPropertyDescription && autoPropertyDescription->hasHistory){
// version with history: EqFtc first
doocsPV.reset( new DoocsProcessScalar<T, DOOCS_T>(_eqFct, propertyDescription->name.c_str(), processArray, *_syncUtility) );
}else{
// version without history: name first
doocsPV.reset( new DoocsProcessScalar<T, DOOCS_T>(propertyDescription->name.c_str(), _eqFct, processArray, *_syncUtility) );
}
}// if name too long
}// if scalar
}// if name too long
// FIXME: Make it scalar and put it into one if query
if (autoPropertyDescription && !(autoPropertyDescription->isWriteable)){
doocsPV->set_ro_access();
}
// set read only mode if configures in the xml file or for output variables
if (!processArray->isWriteable()){// || !propertyDescription.isWriteable){
doocsPV->set_ro_access();
}
return doocsPV;
}
template<>
boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsProperty<std::string, D_string>(
boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsScalar<std::string, D_string>(
boost::shared_ptr<ProcessVariable> & processVariable) {
// the DoocsProcessArray needs the real ProcessScalar type, not just ProcessVariable
boost::shared_ptr< mtca4u::NDRegisterAccessor<std::string> > processArray
......@@ -85,32 +81,104 @@ namespace ChimeraTK {
return boost::shared_ptr<D_fct>( new DoocsProcessScalar<std::string, D_string>(_eqFct, propertyDescription->name.c_str(), processArray, *_syncUtility) );
}
boost::shared_ptr<D_fct> DoocsPVFactory::create( ProcessVariable::SharedPtr & processVariable ){
template<class T>
typename boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsSpectrum(typename ProcessVariable::SharedPtr & processVariable) {
// the DoocsProcessArray needs the real type, not just ProcessVariable
typename boost::shared_ptr< mtca4u::NDRegisterAccessor<T> > processArray
= boost::dynamic_pointer_cast< mtca4u::NDRegisterAccessor<T> >(processVariable);
if (!processArray){
throw std::invalid_argument(std::string("DoocsPVFactory::createDoocsArray : processArray is of the wrong type ")
+ processVariable->getValueType().name());
}
auto propertyDescription = VariableMapper::getInstance().getAllProperties().at(processVariable->getName());
// FIXME: This has to go for scalars
auto autoPropertyDescription = std::dynamic_pointer_cast<AutoPropertyDescription>(propertyDescription);
assert(processArray->getNumberOfChannels() == 1);
boost::shared_ptr<D_fct> doocsPV( new DoocsSpectrum<T>(_eqFct, propertyDescription->name, processArray, *_syncUtility) );
// FIXME: Make it scalar and put it into one if query
if (autoPropertyDescription && !(autoPropertyDescription->isWriteable)){
doocsPV->set_ro_access();
}
// set read only mode if configures in the xml file or for output variables
if (!processArray->isWriteable()){// || !propertyDescription.isWriteable){
doocsPV->set_ro_access();
}
return doocsPV;
}
boost::shared_ptr<D_fct> DoocsPVFactory::autoCreate( std::shared_ptr<PropertyDescription> const & propertyDescription ){
// do auto creation
auto pvName = std::static_pointer_cast<AutoPropertyDescription>(propertyDescription)->source;
auto pv = _controlSystemPVManager->getProcessVariable(pvName);
// fixme: merge the create stuff in here and remove the create function.
return create( pv );
}
boost::shared_ptr<D_fct> DoocsPVFactory::create( ProcessVariable::SharedPtr & processVariable ){
std::type_info const & valueType = processVariable->getValueType();
// We use an int accessor decorator just to have some type.
// All we need to do here is to determine the number of samples. No need to write an if/then/else
// on the type, or a boot::fustion::for_each, which is in the decorator factory.
// Unfortynately we need different impl_type -> doocs_type decision for scalars and arrays,
// so we have to know this here.
auto intDecoratedPV = ChimeraTK::getDecorator<int>( *processVariable );
auto nSamples = intDecoratedPV->getNumberOfSamples();
/* TODO:
- create functions "createDoocsArray" and "createDoocsSpectrum"
- first use spectrum here for 1D, then switch to array (tests need to be adapted)
- create spectrum, array and d_int/float/double upon request from 1d (scalar for D_array and 1D)
*/
// Unfortunately we need a big if/else block to hard-code the template
// parameter. The value type in only known at run time,
// but the template parameter has to be known at compile time.
if (valueType == typeid(int8_t)) {
return createDoocsProperty<int8_t, D_int>(processVariable);
} else if (valueType == typeid(uint8_t)) {
return createDoocsProperty<uint8_t, D_int>(processVariable);
} else if (valueType == typeid(int16_t)) {
return createDoocsProperty<int16_t, D_int>(processVariable);
} else if (valueType == typeid(uint16_t)) {
return createDoocsProperty<uint16_t, D_int>(processVariable);
} else if (valueType == typeid(int32_t)) {
return createDoocsProperty<int32_t, D_int>(processVariable);
} else if (valueType == typeid(uint32_t)) {
return createDoocsProperty<uint32_t, D_int>(processVariable);
} else if (valueType == typeid(float)) {
return createDoocsProperty<float, D_float>(processVariable);
} else if (valueType == typeid(double)) {
return createDoocsProperty<double, D_double>(processVariable);
} else if (valueType == typeid(std::string)) {
return createDoocsProperty<std::string, D_string>(processVariable);
} else {
throw std::invalid_argument("unsupported value type");
if (nSamples == 1){
if (valueType == typeid(int8_t)) {
return createDoocsScalar<int8_t, D_int>(processVariable);
} else if (valueType == typeid(uint8_t)) {
return createDoocsScalar<uint8_t, D_int>(processVariable);
} else if (valueType == typeid(int16_t)) {
return createDoocsScalar<int16_t, D_int>(processVariable);
} else if (valueType == typeid(uint16_t)) {
return createDoocsScalar<uint16_t, D_int>(processVariable);
} else if (valueType == typeid(int32_t)) {
return createDoocsScalar<int32_t, D_int>(processVariable);
} else if (valueType == typeid(uint32_t)) {
return createDoocsScalar<uint32_t, D_int>(processVariable);
} else if (valueType == typeid(float)) {
return createDoocsScalar<float, D_float>(processVariable);
} else if (valueType == typeid(double)) {
return createDoocsScalar<double, D_double>(processVariable);
} else if (valueType == typeid(std::string)) {
return createDoocsScalar<std::string, D_string>(processVariable);
} else {
throw std::invalid_argument("unsupported value type");
}
}else{ //nSamples > 1
if (valueType == typeid(int8_t)) {
return createDoocsSpectrum<int8_t>(processVariable);
} else if (valueType == typeid(uint8_t)) {
return createDoocsSpectrum<uint8_t>(processVariable);
} else if (valueType == typeid(int16_t)) {
return createDoocsSpectrum<int16_t>(processVariable);
} else if (valueType == typeid(uint16_t)) {
return createDoocsSpectrum<uint16_t>(processVariable);
} else if (valueType == typeid(int32_t)) {
return createDoocsSpectrum<int32_t>(processVariable);
} else if (valueType == typeid(uint32_t)) {
return createDoocsSpectrum<uint32_t>(processVariable);
} else if (valueType == typeid(float)) {
return createDoocsSpectrum<float>(processVariable);
} else if (valueType == typeid(double)) {
return createDoocsSpectrum<double>(processVariable);
} else {
throw std::invalid_argument("unsupported value type");
}
}
}
......
......@@ -42,8 +42,8 @@ public:
}
template<class T, class DOOCS_T>
typename boost::shared_ptr<D_fct> createDoocsProperty(typename ProcessVariable::SharedPtr & processVariable){
return DoocsPVFactory::createDoocsProperty<T, DOOCS_T>(processVariable);
typename boost::shared_ptr<D_fct> createDoocsScalar(typename ProcessVariable::SharedPtr & processVariable){
return DoocsPVFactory::createDoocsScalar<T, DOOCS_T>(processVariable);
}
};
......@@ -218,7 +218,7 @@ BOOST_AUTO_TEST_CASE( testErrorHandling ){
// Unfortunately BOOST_CHECK cannot deal with multiple template parameters,
// so we have to trick it
try{
testableFactory.createDoocsProperty<int32_t, D_int>( processScalar );
testableFactory.createDoocsScalar<int32_t, D_int>( processScalar );
// In a working unit test this line should not be hit, so er exclude it
// from the coverage report.
BOOST_FAIL( "createDoocsScalar did not throw as expected");//LCOV_EXCL_LINE
......@@ -227,7 +227,7 @@ BOOST_AUTO_TEST_CASE( testErrorHandling ){
// now the same with arrays
ProcessVariable::SharedPtr processArray = csManager->getProcessArray<int64_t>("A/toDeviceArray");
BOOST_CHECK_THROW( ( testableFactory.createDoocsProperty<int32_t, D_int>(processArray) ),
BOOST_CHECK_THROW( ( testableFactory.createDoocsScalar<int32_t, D_int>(processArray) ),
std::invalid_argument );
// finally we check that the create method catches the not-supported type.
......
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