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

removed template specialisation for D_text in DoocsProcessScalar by introducing a helper class

parent 10912d04
No related branches found
No related tags found
No related merge requests found
#ifndef D_TEXTUNIFIER_H
#define D_TEXTUNIFIER_H
#include <d_fct.h>
/** A compatibility class that adds the constructor which would create a history,
* and the set_and_archive function to the D_text interface. As this does not
* have history it just calls the non-history equivalent.
* This class was introduces to avoid template specialisations in DoocsProcessScalar.
* (Local specialisations of functions don't work because one would have to
*/
struct D_textUnifier: public D_text {
using D_text::D_text;
D_textUnifier(EqFct* eqFct, std::string doocsPropertyName);
void set_and_archive(const std::string &str);
D_hist * get_histPointer ();
};
#endif // D_TEXTUNIFIER_H
......@@ -130,87 +130,6 @@ namespace ChimeraTK {
bool _publishZMQ{false};
};
/** Template specialisation for D_text, which has a different interface */
template<typename T>
class DoocsProcessScalar<T, D_text> : public D_text, public boost::noncopyable {
public:
void updateDoocsBuffer() {
// Note: we already own the location lock by specification of the
// DoocsUpdater
auto data = _processScalar->accessData(0);
this->set_value(data);
if(_publishZMQ) {
dmsg_info info;
memset(&info, 0, sizeof(info));
auto sinceEpoch = _processScalar->getVersionNumber().getTime().time_since_epoch();
auto time = std::chrono::duration_cast<std::chrono::microseconds>(sinceEpoch);
info.sec = time.count() / 1000000;
info.usec = time.count() % 1000000;
info.ident = _macroPulseNumberSource->accessData(0);
this->send(&info);
}
}
DoocsProcessScalar(EqFct* eqFct, std::string doocsPropertyName,
boost::shared_ptr<typename ChimeraTK::NDRegisterAccessor<T>> const& processScalar, DoocsUpdater& updater)
: D_text(doocsPropertyName.c_str(), eqFct), _processScalar(processScalar) {
if(processScalar->isReadable()) {
updater.addVariable(ChimeraTK::ScalarRegisterAccessor<T>(processScalar), eqFct,
std::bind(&DoocsProcessScalar<T, D_text>::updateDoocsBuffer, this));
}
}
DoocsProcessScalar(std::string doocsPropertyName, EqFct* eqFct,
boost::shared_ptr<typename ChimeraTK::NDRegisterAccessor<T>> const& processScalar, DoocsUpdater& updater)
: D_text(doocsPropertyName.c_str(), eqFct), _processScalar(processScalar) {
if(processScalar->isReadable()) {
updater.addVariable(ChimeraTK::ScalarRegisterAccessor<T>(processScalar), eqFct,
std::bind(&DoocsProcessScalar<T, D_text>::updateDoocsBuffer, this));
}
}
/**
* Override the Doocs set method which is triggered by the RPC calls.
*/
void set(EqAdr* adr, EqData* data1, EqData* data2, EqFct* eqfct) override {
// only assign the value if the variable is writeable
// Otherwise the content displayed by Doocs and the value in the application
// are inconsistent
if(_processScalar->isWriteable()) {
D_text::set(adr, data1, data2, eqfct);
// let the DOOCS_T set function do all the dirty work and use the
// get_value function afterwards to get the already assigned value
_processScalar->accessData(0) = this->value();
_processScalar->write();
}
}
/**
* Override the Doocs auto_init() method, which is called after initialising
* the value of the property from the config file.
*/
void auto_init(void) override {
D_text::auto_init();
// send the current value to the device
if(_processScalar->isWriteable()) {
_processScalar->accessData(0) = D_text::value();
_processScalar->write();
}
}
void publishZeroMQ() { _publishZMQ = true; }
void setMacroPulseNumberSource(boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int64_t>> macroPulseNumberSource) {
_macroPulseNumberSource = macroPulseNumberSource;
}
protected:
boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> _processScalar;
boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int64_t>> _macroPulseNumberSource;
DataConsistencyGroup _consistencyGroup;
bool _publishZMQ{false};
};
} // namespace ChimeraTK
#endif // __DOOCS_PROCESS_SCALAR_H__
#include "D_textUnifier.h"
// just call the constructor without history (the only one)
D_textUnifier::D_textUnifier(EqFct* eqFct, std::string doocsPropertyName)
: D_text(doocsPropertyName, eqFct){
}
void D_textUnifier::set_and_archive(const std::string &str){
set_value(str);
}
D_hist * D_textUnifier::get_histPointer(){
return nullptr;
}
......@@ -4,6 +4,7 @@
#include "DoocsProcessScalar.h"
#include "DoocsSpectrum.h"
#include "DoocsXY.h"
#include "D_textUnifier.h"
#include <d_fct.h>
#include "DoocsPVFactory.h"
......@@ -88,7 +89,7 @@ namespace ChimeraTK {
}
template<>
boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsScalar<std::string, D_text>(
boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsScalar<std::string, D_textUnifier>(
AutoPropertyDescription const& propertyDescription, DecoratorType /*decoratorType*/) {
auto processVariable = _controlSystemPVManager->getProcessVariable(propertyDescription.source);
......@@ -106,7 +107,7 @@ namespace ChimeraTK {
assert(processArray->getNumberOfChannels() == 1);
assert(processArray->getNumberOfSamples() == 1); // array of strings is not supported
boost::shared_ptr<D_fct> doocsPV(
new DoocsProcessScalar<std::string, D_text>(_eqFct, propertyDescription.name.c_str(), processArray, _updater));
new DoocsProcessScalar<std::string, D_textUnifier>(_eqFct, propertyDescription.name.c_str(), processArray, _updater));
// set read only mode if configures in the xml file or for output variables
if(!processArray->isWriteable() || !propertyDescription.isWriteable) {
......@@ -115,7 +116,7 @@ namespace ChimeraTK {
// publish via ZeroMQ if configured in the xml file
if(propertyDescription.publishZMQ) {
boost::dynamic_pointer_cast<DoocsProcessScalar<std::string, D_text>>(doocsPV)->publishZeroMQ();
boost::dynamic_pointer_cast<DoocsProcessScalar<std::string, D_textUnifier>>(doocsPV)->publishZeroMQ();
}
// set macro pulse number source, if configured
......@@ -132,7 +133,7 @@ namespace ChimeraTK {
throw ChimeraTK::logic_error("The property '" + mpnDecorated->getName() +
"' is used as a macro pulse number source, but it is not readable.");
}
boost::dynamic_pointer_cast<DoocsProcessScalar<std::string, D_text>>(doocsPV)->setMacroPulseNumberSource(
boost::dynamic_pointer_cast<DoocsProcessScalar<std::string, D_textUnifier>>(doocsPV)->setMacroPulseNumberSource(
mpnDecorated);
_updater.addVariable(ChimeraTK::ScalarRegisterAccessor<int64_t>(mpnDecorated), _eqFct, [] {});
}
......@@ -356,7 +357,7 @@ boost::shared_ptr<D_fct> DoocsPVFactory::autoCreate(std::shared_ptr<PropertyDesc
valueType, *processVariable, *autoPropertyDescription, DecoratorType::C_style_conversion);
case AutoPropertyDescription::DataType::Auto:
if(valueType == typeid(std::string)) {
return typedCreateScalarOrArray<D_text, std::string, std::nullptr_t, std::nullptr_t>(
return typedCreateScalarOrArray<D_textUnifier, std::string, std::nullptr_t, std::nullptr_t>(
valueType, *processVariable, *autoPropertyDescription, DecoratorType::range_checking);
}
throw std::logic_error("DoocsPVFactory does not implement a data type it should!");
......
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