diff --git a/include/CSAdapterEqFct.h b/include/CSAdapterEqFct.h index 8411dc619c3486801e8921b54e8b37ea999c1932..546d983e95c9004b48d758375b04fee144aae5ad 100644 --- a/include/CSAdapterEqFct.h +++ b/include/CSAdapterEqFct.h @@ -14,35 +14,31 @@ namespace ChimeraTK { -class CSAdapterEqFct : public EqFct, boost::noncopyable { -protected: - boost::shared_ptr<ControlSystemPVManager> controlSystemPVManager_; - int fctCode_; - std::map<std::shared_ptr<ChimeraTK::PropertyDescription>, - boost::shared_ptr<D_fct>> - doocsProperties_; - void registerProcessVariablesInDoocs(); - std::vector<ChimeraTK::ProcessVariable::SharedPtr> - getProcessVariablesInThisLocation(); - - static bool emptyLocationVariablesHandled; - boost::shared_ptr<DoocsUpdater> updater_; - -public: - // The fctName (location name ) is usually coming from the config file and - // should be left empty. Only for testing without actually running a DOOCS - // server you need it. - CSAdapterEqFct( - int fctCode, - boost::shared_ptr<ControlSystemPVManager> const &controlSystemPVManager, - boost::shared_ptr<DoocsUpdater> const &updater, - std::string fctName = std::string()); - ~CSAdapterEqFct(); - - void init() override; - void post_init() override; - int fct_code() override; -}; + class CSAdapterEqFct : public EqFct, boost::noncopyable { + protected: + boost::shared_ptr<ControlSystemPVManager> controlSystemPVManager_; + int fctCode_; + std::map<std::shared_ptr<ChimeraTK::PropertyDescription>, boost::shared_ptr<D_fct>> doocsProperties_; + void registerProcessVariablesInDoocs(); + std::vector<ChimeraTK::ProcessVariable::SharedPtr> getProcessVariablesInThisLocation(); + + static bool emptyLocationVariablesHandled; + boost::shared_ptr<DoocsUpdater> updater_; + + public: + // The fctName (location name ) is usually coming from the config file and + // should be left empty. Only for testing without actually running a DOOCS + // server you need it. + CSAdapterEqFct(int fctCode, + boost::shared_ptr<ControlSystemPVManager> const& controlSystemPVManager, + boost::shared_ptr<DoocsUpdater> const& updater, + std::string fctName = std::string()); + ~CSAdapterEqFct(); + + void init() override; + void post_init() override; + int fct_code() override; + }; } // namespace ChimeraTK diff --git a/include/DoocsAdapter.h b/include/DoocsAdapter.h index 5a054be72561d1cd0da23778c66da5271df1ae4d..cf4e913c3f189da9da6a50408db293652db06641 100644 --- a/include/DoocsAdapter.h +++ b/include/DoocsAdapter.h @@ -7,29 +7,28 @@ namespace ChimeraTK { -/** The main adapter class. With this tool the EqFct should shrink to about 4 - * lines of code (plus boiler plate). - */ -class DoocsAdapter { -public: - DoocsAdapter(); - boost::shared_ptr<DevicePVManager> const &getDevicePVManager() const; - boost::shared_ptr<ControlSystemPVManager> const & - getControlSystemPVManager() const; - - boost::shared_ptr<DoocsUpdater> updater; - - // An atomic bool which is set true in post_init_epilog to indicate that doocs - // is ready. Only used in testing. - static std::atomic<bool> isInitialised; - - // A convenience function to wait until the adapter is initialised. - static void waitUntilInitialised(); - -protected: - boost::shared_ptr<ControlSystemPVManager> _controlSystemPVManager; - boost::shared_ptr<DevicePVManager> _devicePVManager; -}; + /** The main adapter class. With this tool the EqFct should shrink to about 4 + * lines of code (plus boiler plate). + */ + class DoocsAdapter { + public: + DoocsAdapter(); + boost::shared_ptr<DevicePVManager> const& getDevicePVManager() const; + boost::shared_ptr<ControlSystemPVManager> const& getControlSystemPVManager() const; + + boost::shared_ptr<DoocsUpdater> updater; + + // An atomic bool which is set true in post_init_epilog to indicate that doocs + // is ready. Only used in testing. + static std::atomic<bool> isInitialised; + + // A convenience function to wait until the adapter is initialised. + static void waitUntilInitialised(); + + protected: + boost::shared_ptr<ControlSystemPVManager> _controlSystemPVManager; + boost::shared_ptr<DevicePVManager> _devicePVManager; + }; } // namespace ChimeraTK diff --git a/include/DoocsPVFactory.h b/include/DoocsPVFactory.h index fd305b08dac8072d35f9011849177202f86ca7fc..a0e6f3ba28c98d89ac8de0ad0ae11195eb29c3f3 100644 --- a/include/DoocsPVFactory.h +++ b/include/DoocsPVFactory.h @@ -13,65 +13,56 @@ namespace ChimeraTK { -/** - * The DoocsProcessVariableFactory creates Doocs variables (D_fct) from - * ChimeraTK::ProcessVariables. - */ -class DoocsPVFactory : boost::noncopyable { -public: /** - * The constructor needs a pointer to the EqFct. It is designed to be used - * inside the EqFct, so the 'this' pointer will be given. As it is not - * copyable this is ok. + * The DoocsProcessVariableFactory creates Doocs variables (D_fct) from + * ChimeraTK::ProcessVariables. */ - DoocsPVFactory(EqFct *const eqFct, DoocsUpdater &updater, - boost::shared_ptr<ControlSystemPVManager> const &csPVManager); + class DoocsPVFactory : boost::noncopyable { + public: + /** + * The constructor needs a pointer to the EqFct. It is designed to be used + * inside the EqFct, so the 'this' pointer will be given. As it is not + * copyable this is ok. + */ + DoocsPVFactory( + EqFct* const eqFct, DoocsUpdater& updater, boost::shared_ptr<ControlSystemPVManager> const& csPVManager); - boost::shared_ptr<D_fct> - create(std::shared_ptr<PropertyDescription> const &propertyDescription); + boost::shared_ptr<D_fct> create(std::shared_ptr<PropertyDescription> const& propertyDescription); -protected: - EqFct *_eqFct; //< The EqFct which is holding the factory. Needed in the - // constructor of the doocs properties. - DoocsUpdater &_updater; - boost::shared_ptr<ControlSystemPVManager> - _controlSystemPVManager; //< The pv manager, needed to get the instances + protected: + EqFct* _eqFct; //< The EqFct which is holding the factory. Needed in the + // constructor of the doocs properties. + DoocsUpdater& _updater; + 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> - createDoocsScalar(AutoPropertyDescription const &propertyDescription, - DecoratorType decoratorType); - /// @todo FIXME: use SpectrumDescription here - boost::shared_ptr<D_fct> - createDoocsSpectrum(SpectrumDescription const &spectrumDescription); + // 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> createDoocsScalar(AutoPropertyDescription const& propertyDescription, + DecoratorType decoratorType); + /// @todo FIXME: use SpectrumDescription here + boost::shared_ptr<D_fct> createDoocsSpectrum(SpectrumDescription const& spectrumDescription); - boost::shared_ptr<D_fct> createDoocsArray( - std::shared_ptr<ArrayDescription> const &spectrumDescription); + boost::shared_ptr<D_fct> createDoocsArray(std::shared_ptr<ArrayDescription> const& spectrumDescription); - template <class DOOCS_PRIMITIVE_T, class DOOCS_T> - boost::shared_ptr<D_fct> - typedCreateDoocsArray(ArrayDescription const &arrayDescription); + template<class DOOCS_PRIMITIVE_T, class DOOCS_T> + boost::shared_ptr<D_fct> typedCreateDoocsArray(ArrayDescription const& arrayDescription); - boost::shared_ptr<D_fct> - autoCreate(std::shared_ptr<PropertyDescription> const &propertyDescription); + boost::shared_ptr<D_fct> autoCreate(std::shared_ptr<PropertyDescription> const& propertyDescription); - template <class IMPL_T, class DOOCS_SCALAR_T, class DOOCS_PRIMARY_T, - class DOOCS_ARRAY_T, class DOOCS_ARRAY_PRIMITIVE_T> - boost::shared_ptr<D_fct> - typedCreateScalarOrArray(ProcessVariable &processVariable, - AutoPropertyDescription const &propertyDescription, - DecoratorType decoratorType, - ArrayDescription::DataType arrayDataType); -}; + template<class IMPL_T, class DOOCS_SCALAR_T, class DOOCS_PRIMARY_T, class DOOCS_ARRAY_T, + class DOOCS_ARRAY_PRIMITIVE_T> + boost::shared_ptr<D_fct> typedCreateScalarOrArray(ProcessVariable& processVariable, + AutoPropertyDescription const& propertyDescription, + DecoratorType decoratorType, + ArrayDescription::DataType arrayDataType); + }; -// specialisation for strings -template <> -typename boost::shared_ptr<D_fct> -DoocsPVFactory::createDoocsScalar<std::string, D_string>( - AutoPropertyDescription const &propertyDescription, - DecoratorType decoratorType); + // specialisation for strings + template<> + typename boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsScalar<std::string, D_string>( + AutoPropertyDescription const& propertyDescription, + DecoratorType decoratorType); } // namespace ChimeraTK diff --git a/include/DoocsProcessScalar.h b/include/DoocsProcessScalar.h index 8557c0932298a26c8a243e4f8ccd8c4e72612a0d..01b6ede664e08a537d87bafaf127398eee48e2da 100644 --- a/include/DoocsProcessScalar.h +++ b/include/DoocsProcessScalar.h @@ -11,110 +11,96 @@ namespace ChimeraTK { -/** The DoocsProcessScalar has three template parameters: - * \li \c T, The primitive value type of the ChimeraTK process variable - * \li \c DOOCS_T, The Doocs type which is used - */ -template <typename T, typename DOOCS_T> -class DoocsProcessScalar : public DOOCS_T, public boost::noncopyable { -public: - void updateDoocsBuffer() { - // Note: we already own the location lock by specification of the - // DoocsUpdater - auto data = _processScalar->accessData(0); - // we must not call set_and_archive if there is no history (otherwise it - // will be activated), but we have to if it is there. -> Abstraction, - // please! - if (this->get_histPointer()) { - this->set_and_archive(data); - } else { - 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); + /** The DoocsProcessScalar has three template parameters: + * \li \c T, The primitive value type of the ChimeraTK process variable + * \li \c DOOCS_T, The Doocs type which is used + */ + template<typename T, typename DOOCS_T> + class DoocsProcessScalar : public DOOCS_T, public boost::noncopyable { + public: + void updateDoocsBuffer() { + // Note: we already own the location lock by specification of the + // DoocsUpdater + auto data = _processScalar->accessData(0); + // we must not call set_and_archive if there is no history (otherwise it + // will be activated), but we have to if it is there. -> Abstraction, + // please! + if(this->get_histPointer()) { + this->set_and_archive(data); + } + else { + 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) - : DOOCS_T(eqFct, doocsPropertyName.c_str()), - _processScalar(processScalar) { - if (processScalar->isReadable()) { - updater.addVariable( - ChimeraTK::ScalarRegisterAccessor<T>(processScalar), eqFct, - std::bind(&DoocsProcessScalar<T, DOOCS_T>::updateDoocsBuffer, this)); + DoocsProcessScalar(EqFct* eqFct, std::string doocsPropertyName, + boost::shared_ptr<typename ChimeraTK::NDRegisterAccessor<T>> const& processScalar, DoocsUpdater& updater) + : DOOCS_T(eqFct, doocsPropertyName.c_str()), _processScalar(processScalar) { + if(processScalar->isReadable()) { + updater.addVariable(ChimeraTK::ScalarRegisterAccessor<T>(processScalar), eqFct, + std::bind(&DoocsProcessScalar<T, DOOCS_T>::updateDoocsBuffer, this)); + } } - } - DoocsProcessScalar( - std::string doocsPropertyName, EqFct *eqFct, - boost::shared_ptr<typename ChimeraTK::NDRegisterAccessor<T>> const - &processScalar, - DoocsUpdater &updater) - : DOOCS_T(doocsPropertyName.c_str(), eqFct), - _processScalar(processScalar) { - if (processScalar->isReadable()) { - updater.addVariable( - ChimeraTK::ScalarRegisterAccessor<T>(processScalar), eqFct, - std::bind(&DoocsProcessScalar<T, DOOCS_T>::updateDoocsBuffer, this)); + DoocsProcessScalar(std::string doocsPropertyName, EqFct* eqFct, + boost::shared_ptr<typename ChimeraTK::NDRegisterAccessor<T>> const& processScalar, DoocsUpdater& updater) + : DOOCS_T(doocsPropertyName.c_str(), eqFct), _processScalar(processScalar) { + if(processScalar->isReadable()) { + updater.addVariable(ChimeraTK::ScalarRegisterAccessor<T>(processScalar), eqFct, + std::bind(&DoocsProcessScalar<T, DOOCS_T>::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()) { - DOOCS_T::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 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()) { + DOOCS_T::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 { - DOOCS_T::auto_init(); - // send the current value to the device - if (_processScalar->isWriteable()) { - _processScalar->accessData(0) = DOOCS_T::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 { + DOOCS_T::auto_init(); + // send the current value to the device + if(_processScalar->isWriteable()) { + _processScalar->accessData(0) = DOOCS_T::value(); + _processScalar->write(); + } } - } - void publishZeroMQ() { publishZMQ = true; } + void publishZeroMQ() { publishZMQ = true; } - void setMacroPulseNumberSource( - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int64_t>> - macroPulseNumberSource) { - _macroPulseNumberSource = macroPulseNumberSource; - } + 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; - bool publishZMQ{false}; -}; + protected: + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> _processScalar; + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int64_t>> _macroPulseNumberSource; + bool publishZMQ{false}; + }; } // namespace ChimeraTK diff --git a/include/DoocsSpectrum.h b/include/DoocsSpectrum.h index fbe270bc25dcae08911c4dc3bb1211c21b15cd2d..27837a651ce01d9d1e2743c7173bf50a80c23e11 100644 --- a/include/DoocsSpectrum.h +++ b/include/DoocsSpectrum.h @@ -13,63 +13,56 @@ class EqFct; namespace ChimeraTK { -class DoocsSpectrum : public D_spectrum, public boost::noncopyable { -public: - /** The constructor expects an NDRegisterAccessor of float, which usually will - * be a decorator to the implementation type. The decorator cannot be - * generated in the constructor because the ProcessVariable aka - * TransferElement does not know about it's size, which is needed by the - * D_spectrum constructor. This is not a big drawback because the properties - * are greated by a factory function anyway. - */ - DoocsSpectrum(EqFct *eqFct, std::string const &doocsPropertyName, - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const - &processArray, - DoocsUpdater &updater, - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const - &startAccessor, - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const - &incrementAccessor); + class DoocsSpectrum : public D_spectrum, public boost::noncopyable { + public: + /** The constructor expects an NDRegisterAccessor of float, which usually will + * be a decorator to the implementation type. The decorator cannot be + * generated in the constructor because the ProcessVariable aka + * TransferElement does not know about it's size, which is needed by the + * D_spectrum constructor. This is not a big drawback because the properties + * are greated by a factory function anyway. + */ + DoocsSpectrum(EqFct* eqFct, std::string const& doocsPropertyName, + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const& processArray, DoocsUpdater& updater, + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const& startAccessor, + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const& incrementAccessor); - /** - * Overload the set function which is called by DOOCS to inject sending to the - * device. - */ - void set(EqAdr *eqAdr, EqData *data1, EqData *data2, EqFct *eqFct) override; + /** + * Overload the set function which is called by DOOCS to inject sending to the + * device. + */ + void set(EqAdr* eqAdr, EqData* data1, EqData* data2, EqFct* eqFct) override; - /** - * 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; + /** + * 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; - // call this function after a tranfer element has requested it. - void updateDoocsBuffer(); + // call this function after a tranfer element has requested it. + void updateDoocsBuffer(); - // callback function after the start or increment variables have changed - void updateParameters(); + // callback function after the start or increment variables have changed + void updateParameters(); - void publishZeroMQ() { publishZMQ = true; } + void publishZeroMQ() { publishZMQ = true; } - void setMacroPulseNumberSource( - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int64_t>> - macroPulseNumberSource) { - _macroPulseNumberSource = macroPulseNumberSource; - } + void setMacroPulseNumberSource(boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int64_t>> macroPulseNumberSource) { + _macroPulseNumberSource = macroPulseNumberSource; + } -protected: - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> _processArray; - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> _startAccessor; - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> _incrementAccessor; - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int64_t>> - _macroPulseNumberSource; - bool publishZMQ{false}; + protected: + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> _processArray; + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> _startAccessor; + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> _incrementAccessor; + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int64_t>> _macroPulseNumberSource; + bool publishZMQ{false}; - // Internal function which copies the content from the DOOCS container into - // the ChimeraTK ProcessArray and calls the send method. Factored out to allow - // unit testing. - void sendToDevice(); -}; + // Internal function which copies the content from the DOOCS container into + // the ChimeraTK ProcessArray and calls the send method. Factored out to allow + // unit testing. + void sendToDevice(); + }; } // namespace ChimeraTK diff --git a/include/DoocsTransferElement.h b/include/DoocsTransferElement.h index f1fd855734c853d32c9468eb15c13678c7d77f12..56ac6c5ad56333245c73123ab099d8d2220488d2 100644 --- a/include/DoocsTransferElement.h +++ b/include/DoocsTransferElement.h @@ -5,67 +5,49 @@ namespace ChimeraTK { -template <class UserType> -class DoocsTransferElement : public ChimeraTK::TransferElement { - -public: - /** The constructor expects an NDRegisterAccessor of UserType, which usually - * will be a decorator to the implementation type. The decorator cannot be - * generated in the constructor because the ProcessVariable aka - * TransferElement does not know about it's size, which is needed by the - * D_spectrum constructor. This is not a big drawback because the properties - * are greated by a factory function anyway. - */ - DoocsTransferElement( - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> const - &processArray) - : _processArray(processArray) {} - - // implement the stuff needed by TransferElement - virtual const std::type_info &getValueType() const override { - return typeid(UserType); - } - virtual TransferFuture &readAsync() override { - return _processArray->readAsync(); - } - - virtual void doReadTransfer() override { _processArray->doReadTransfer(); } - virtual bool doReadTransferNonBlocking() override { - return _processArray->doReadTransferNonBlocking(); - } - virtual bool doReadTransferLatest() override { - return _processArray->doReadTransferLatest(); - } - - virtual bool isSameRegister( - const boost::shared_ptr<TransferElement const> &other) const override { - return _processArray->isSameRegister(other); - } - virtual bool isReadOnly() const override { - // FIXME: We cannot access the doocs information here. - // because get_access is not const, - // only provides an implementation dependent int without constant - // definitions anyway. And d_access is private, not protected. - return _processArray->isReadOnly(); - } - virtual bool isWriteable() const override { - return _processArray->isWriteable(); - } - virtual bool isReadable() const override { - return _processArray->isReadable(); - } - virtual std::vector<boost::shared_ptr<TransferElement>> - getHardwareAccessingElements() override { - return _processArray->getHardwareAccessingElements(); - } - virtual void replaceTransferElement( - boost::shared_ptr<TransferElement> newElement) override { - return _processArray->replaceTransferElement(newElement); - } - -protected: - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> _processArray; -}; + template<class UserType> + class DoocsTransferElement : public ChimeraTK::TransferElement { + public: + /** The constructor expects an NDRegisterAccessor of UserType, which usually + * will be a decorator to the implementation type. The decorator cannot be + * generated in the constructor because the ProcessVariable aka + * TransferElement does not know about it's size, which is needed by the + * D_spectrum constructor. This is not a big drawback because the properties + * are greated by a factory function anyway. + */ + DoocsTransferElement(boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> const& processArray) + : _processArray(processArray) {} + + // implement the stuff needed by TransferElement + virtual const std::type_info& getValueType() const override { return typeid(UserType); } + virtual TransferFuture& readAsync() override { return _processArray->readAsync(); } + + virtual void doReadTransfer() override { _processArray->doReadTransfer(); } + virtual bool doReadTransferNonBlocking() override { return _processArray->doReadTransferNonBlocking(); } + virtual bool doReadTransferLatest() override { return _processArray->doReadTransferLatest(); } + + virtual bool isSameRegister(const boost::shared_ptr<TransferElement const>& other) const override { + return _processArray->isSameRegister(other); + } + virtual bool isReadOnly() const override { + // FIXME: We cannot access the doocs information here. + // because get_access is not const, + // only provides an implementation dependent int without constant + // definitions anyway. And d_access is private, not protected. + return _processArray->isReadOnly(); + } + virtual bool isWriteable() const override { return _processArray->isWriteable(); } + virtual bool isReadable() const override { return _processArray->isReadable(); } + virtual std::vector<boost::shared_ptr<TransferElement>> getHardwareAccessingElements() override { + return _processArray->getHardwareAccessingElements(); + } + virtual void replaceTransferElement(boost::shared_ptr<TransferElement> newElement) override { + return _processArray->replaceTransferElement(newElement); + } + + protected: + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> _processArray; + }; } // namespace ChimeraTK diff --git a/include/DoocsUpdater.h b/include/DoocsUpdater.h index f2e4a25c417e59ae92e1b1858b4d83f305dd8228..01c2739e6f2277c35dd2b162f05d7e5862e9f70a 100644 --- a/include/DoocsUpdater.h +++ b/include/DoocsUpdater.h @@ -9,43 +9,40 @@ namespace ChimeraTK { -/** A class to synchronise DeviceToControlSystem variable to Doocs. - * It contains a list of TransferElements and a thread which is monitoring them - * for updates. The thread has to be started with the run() functions, which - * returns immediately when the thread is started, and (FIXME can be stopped by - * the stop() function which returns after the thread has been joined). This - * happens latest in the destructor. - */ -class DoocsUpdater : public boost::noncopyable { - -public: - ~DoocsUpdater(); - void update(); // Update all variables once. This is a convenience function - // for testing. - - void updateLoop(); // Endless loop with interruption point around the update - // function. - - void run(); - void stop(); - - // Add a variable to be updated. Together with the TransferElementAbstractor - // pointing to the ChimeraTK::ProcessArray, the EqFct* to obtain the lock for - // and a function to be called which executes the actual update should be - // specified. The lock is held while the updaterFunction is called, so it must - // neither obtained nor freed within the updaterFunction. - void addVariable(const ChimeraTK::TransferElementAbstractor &variable, - EqFct *eq_fct, std::function<void()> updaterFunction); - -protected: - std::list<ChimeraTK::TransferElementAbstractor> _elementsToRead; - boost::thread - _syncThread; // we have to use boost thread to use interruption points - // FIXME: make this an unordered map - std::map<ChimeraTK::TransferElementID, std::vector<std::function<void()>>> - _toDoocsUpdateMap; - std::map<ChimeraTK::TransferElementID, std::vector<EqFct *>> _toDoocsEqFctMap; -}; + /** A class to synchronise DeviceToControlSystem variable to Doocs. + * It contains a list of TransferElements and a thread which is monitoring them + * for updates. The thread has to be started with the run() functions, which + * returns immediately when the thread is started, and (FIXME can be stopped by + * the stop() function which returns after the thread has been joined). This + * happens latest in the destructor. + */ + class DoocsUpdater : public boost::noncopyable { + public: + ~DoocsUpdater(); + void update(); // Update all variables once. This is a convenience function + // for testing. + + void updateLoop(); // Endless loop with interruption point around the update + // function. + + void run(); + void stop(); + + // Add a variable to be updated. Together with the TransferElementAbstractor + // pointing to the ChimeraTK::ProcessArray, the EqFct* to obtain the lock for + // and a function to be called which executes the actual update should be + // specified. The lock is held while the updaterFunction is called, so it must + // neither obtained nor freed within the updaterFunction. + void addVariable( + const ChimeraTK::TransferElementAbstractor& variable, EqFct* eq_fct, std::function<void()> updaterFunction); + + protected: + std::list<ChimeraTK::TransferElementAbstractor> _elementsToRead; + boost::thread _syncThread; // we have to use boost thread to use interruption points + // FIXME: make this an unordered map + std::map<ChimeraTK::TransferElementID, std::vector<std::function<void()>>> _toDoocsUpdateMap; + std::map<ChimeraTK::TransferElementID, std::vector<EqFct*>> _toDoocsEqFctMap; + }; } // namespace ChimeraTK #endif // __DOOCS_UPDATER_H__ diff --git a/include/VariableMapper.h b/include/VariableMapper.h index 2de5f01c463abb1a728cf22740b01b3015af4a27..2d8bfdf314c06b0e0ad9a788fe0e1ffcc85f0f9e 100644 --- a/include/VariableMapper.h +++ b/include/VariableMapper.h @@ -13,85 +13,77 @@ #include "PropertyDescription.h" namespace xmlpp { -class Node; -class Element; + class Node; + class Element; } // namespace xmlpp namespace ChimeraTK { -class VariableMapper { -public: - static VariableMapper &getInstance(); - void prepareOutput(std::string xmlFile, std::set<std::string> inputVariables); + class VariableMapper { + public: + static VariableMapper& getInstance(); + void prepareOutput(std::string xmlFile, std::set<std::string> inputVariables); - std::list<std::shared_ptr<PropertyDescription>> - getPropertiesInLocation(std::string location) const; - std::list<std::shared_ptr<PropertyDescription>> const & - getAllProperties() const; + std::list<std::shared_ptr<PropertyDescription>> getPropertiesInLocation(std::string location) const; + std::list<std::shared_ptr<PropertyDescription>> const& getAllProperties() const; - VariableMapper(VariableMapper &) = delete; - void operator=(VariableMapper const &) = delete; + VariableMapper(VariableMapper&) = delete; + void operator=(VariableMapper const&) = delete; - void directImport(std::set<std::string> inputVariables); + void directImport(std::set<std::string> inputVariables); - // empty the created mapping - void clear(); + // empty the created mapping + void clear(); - /// printing the map is useful for debugging - void print(std::ostream &os = std::cout) const; + /// printing the map is useful for debugging + void print(std::ostream& os = std::cout) const; - /// Function to get a bool out of the texts - /// true/True/TRUE/false/False/FALSE/1/0. Note on the input: we intentionally - /// make a copy because we modify it inside. - static bool evaluateBool(std::string txt); + /// Function to get a bool out of the texts + /// true/True/TRUE/false/False/FALSE/1/0. Note on the input: we intentionally + /// make a copy because we modify it inside. + static bool evaluateBool(std::string txt); - /// Loop through the sub nodes and take the string from the first non-empty - /// which can be casted to a string-node - static std::string getContentString(xmlpp::Node const *node); + /// Loop through the sub nodes and take the string from the first non-empty + /// which can be casted to a string-node + static std::string getContentString(xmlpp::Node const* node); -protected: - VariableMapper() = default; + protected: + VariableMapper() = default; - std::set<std::string> _inputVariables; - std::set<std::string> _usedInputVariables; // For tracing which variables are - // not to be imported. + std::set<std::string> _inputVariables; + std::set<std::string> _usedInputVariables; // For tracing which variables are + // not to be imported. - void processLocationNode(xmlpp::Node const *locationNode); - void processPropertyNode(xmlpp::Node const *propertyNode, - std::string locationName); - void processSpectrumNode(xmlpp::Node const *node, std::string locationName); - void processArrayNode(xmlpp::Node const *node, std::string locationName); - void processImportNode(xmlpp::Node const *importNode, - std::string importLocationName = std::string()); + void processLocationNode(xmlpp::Node const* locationNode); + void processPropertyNode(xmlpp::Node const* propertyNode, std::string locationName); + void processSpectrumNode(xmlpp::Node const* node, std::string locationName); + void processArrayNode(xmlpp::Node const* node, std::string locationName); + void processImportNode(xmlpp::Node const* importNode, std::string importLocationName = std::string()); - void import(std::string importSource, std::string importLocationName, - std::string directory = ""); - bool getHasHistoryDefault(std::string const &locationName); - bool getIsWriteableDefault(std::string const &locationName); - std::string getMacroPusleNumberSourceDefault(std::string const &locationName); + void import(std::string importSource, std::string importLocationName, std::string directory = ""); + bool getHasHistoryDefault(std::string const& locationName); + bool getIsWriteableDefault(std::string const& locationName); + std::string getMacroPusleNumberSourceDefault(std::string const& locationName); - std::map<std::string, LocationInfo> _locationDefaults; - PropertyAttributes _globalDefaults; + std::map<std::string, LocationInfo> _locationDefaults; + PropertyAttributes _globalDefaults; - // The created PropertyDescriptions - std::list<std::shared_ptr<PropertyDescription>> _descriptions; + // The created PropertyDescriptions + std::list<std::shared_ptr<PropertyDescription>> _descriptions; - /// An internal helper function to abbreviate the syntax - bool nodeIsWhitespace(const xmlpp::Node *node); + /// An internal helper function to abbreviate the syntax + bool nodeIsWhitespace(const xmlpp::Node* node); - // Check if the attribute exists (throw if not) and get it's content - std::string getAttributeValue(const xmlpp::Element *node, - std::string const &attributeName); + // Check if the attribute exists (throw if not) and get it's content + std::string getAttributeValue(const xmlpp::Element* node, std::string const& attributeName); - template <class PROPERTY_DESCRIPTION_TYPE> - void processHistoryAndWritableAttributes( - PROPERTY_DESCRIPTION_TYPE propertyDescription, - const xmlpp::Element *propertyXmlElement, std::string locationName); + template<class PROPERTY_DESCRIPTION_TYPE> + void processHistoryAndWritableAttributes(PROPERTY_DESCRIPTION_TYPE propertyDescription, + const xmlpp::Element* propertyXmlElement, std::string locationName); - void addDescription( - std::shared_ptr<PropertyDescription> const &propertyDescription, - std::list<std::string> const &absoluteSoures); -}; + void addDescription(std::shared_ptr<PropertyDescription> const& propertyDescription, + std::list<std::string> const& absoluteSoures); + }; } // namespace ChimeraTK diff --git a/include/basenameFromAddress.h b/include/basenameFromAddress.h index 4b6fb48b5ce502a19890197c13e2802cec2e535e..236846a9451bb435030b31fcb39dbb6cf228323b 100644 --- a/include/basenameFromAddress.h +++ b/include/basenameFromAddress.h @@ -3,17 +3,17 @@ namespace ChimeraTK { -/** Find the last slash and return the subsring behind it. - */ -inline std::string basenameFromAddress(std::string const &doocsAddress) { - // find first slash - auto slashPosition = doocsAddress.rfind("/"); - // no slash found: return the whole string - if (slashPosition == std::string::npos) { - return doocsAddress; + /** Find the last slash and return the subsring behind it. + */ + inline std::string basenameFromAddress(std::string const& doocsAddress) { + // find first slash + auto slashPosition = doocsAddress.rfind("/"); + // no slash found: return the whole string + if(slashPosition == std::string::npos) { + return doocsAddress; + } + return doocsAddress.substr(slashPosition + 1); } - return doocsAddress.substr(slashPosition + 1); -} } // namespace ChimeraTK diff --git a/include/getAllVariableNames.h b/include/getAllVariableNames.h index 8191c2ce5442130ff22948a30d3d3484f4a07483..6134423dc33c36c5c73f4589ec3f09291de9ca44 100644 --- a/include/getAllVariableNames.h +++ b/include/getAllVariableNames.h @@ -7,10 +7,9 @@ namespace ChimeraTK { -/// convenience function to get all variable names from the CS adapter as a -/// std::set (needed for instance for the variable mapper) -std::set<std::string> -getAllVariableNames(boost::shared_ptr<ControlSystemPVManager> csManager); + /// convenience function to get all variable names from the CS adapter as a + /// std::set (needed for instance for the variable mapper) + std::set<std::string> getAllVariableNames(boost::shared_ptr<ControlSystemPVManager> csManager); } // namespace ChimeraTK diff --git a/include/splitStringAtFirstSlash.h b/include/splitStringAtFirstSlash.h index 5a0c09beea9c65cf98e5bbdfddcd14fdb0abb19b..ab5671cb499b821b8841895a0552e3cd6c7e27de 100644 --- a/include/splitStringAtFirstSlash.h +++ b/include/splitStringAtFirstSlash.h @@ -3,30 +3,28 @@ namespace ChimeraTK { -/** Split the given process variable name into location and property name - * @todo TODO rename this function! */ -inline std::pair<std::string, std::string> -splitStringAtFirstSlash(std::string input) { - // find first slash - auto slashPosition = input.find_first_of("/"); - if (slashPosition == 0) { // ignore leading slash - input = input.substr(1); - slashPosition = input.find_first_of("/"); + /** Split the given process variable name into location and property name + * @todo TODO rename this function! */ + inline std::pair<std::string, std::string> splitStringAtFirstSlash(std::string input) { + // find first slash + auto slashPosition = input.find_first_of("/"); + if(slashPosition == 0) { // ignore leading slash + input = input.substr(1); + slashPosition = input.find_first_of("/"); + } + // no slash found: return empty location name + if(slashPosition == std::string::npos) { + return std::make_pair(std::string(), input); + } + // split at first slash into location name and property name + auto locationName = input.substr(0, slashPosition); + auto propertyName = input.substr(slashPosition + 1); + // replace any remaining slashes in property name with dots + while((slashPosition = propertyName.find_first_of("/")) != std::string::npos) { + propertyName[slashPosition] = '.'; + } + return std::make_pair(locationName, propertyName); } - // no slash found: return empty location name - if (slashPosition == std::string::npos) { - return std::make_pair(std::string(), input); - } - // split at first slash into location name and property name - auto locationName = input.substr(0, slashPosition); - auto propertyName = input.substr(slashPosition + 1); - // replace any remaining slashes in property name with dots - while ((slashPosition = propertyName.find_first_of("/")) != - std::string::npos) { - propertyName[slashPosition] = '.'; - } - return std::make_pair(locationName, propertyName); -} } // namespace ChimeraTK diff --git a/src/CSAdapterEqFct.cc b/src/CSAdapterEqFct.cc index 051061b7ba509365fd0055ee9db8fbb7f03fc7e2..7a07916e986793479e6e38d7852539b7006370e1 100644 --- a/src/CSAdapterEqFct.cc +++ b/src/CSAdapterEqFct.cc @@ -5,69 +5,62 @@ namespace ChimeraTK { -bool CSAdapterEqFct::emptyLocationVariablesHandled = false; + 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 if the string is empty - : EqFct("NAME = CSAdapterEqFct"), - controlSystemPVManager_(controlSystemPVManager), fctCode_(fctCode), - updater_(updater) { - // When testing the EqFct stand alone, the name is not set properly. Do this - // with the additional parameter of this constructor. - if (name().empty()) { - name_.assign(fctName); + 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 if the string is empty + : EqFct("NAME = CSAdapterEqFct"), controlSystemPVManager_(controlSystemPVManager), fctCode_(fctCode), + updater_(updater) { + // When testing the EqFct stand alone, the name is not set properly. Do this + // with the additional parameter of this constructor. + if(name().empty()) { + name_.assign(fctName); + } + registerProcessVariablesInDoocs(); } - registerProcessVariablesInDoocs(); -} -CSAdapterEqFct::~CSAdapterEqFct() { - // stop the updater thread before any of the process variables go out of scope - updater_->stop(); -} + CSAdapterEqFct::~CSAdapterEqFct() { + // stop the updater thread before any of the process variables go out of scope + updater_->stop(); + } -void CSAdapterEqFct::init() {} + void CSAdapterEqFct::init() {} -void CSAdapterEqFct::post_init() { - for (auto &pair : doocsProperties_) { - auto attrs = std::dynamic_pointer_cast<PropertyAttributes>(pair.first); - assert(attrs != nullptr); - if (attrs->publishZMQ) { - auto res = pair.second->set_mode(DMSG_EN); - if (res != 0) { - throw ChimeraTK::logic_error( - "Could not enable ZeroMQ messaging for prop_someZMQInt. Code: " + - std::to_string(res)); + void CSAdapterEqFct::post_init() { + for(auto& pair : doocsProperties_) { + auto attrs = std::dynamic_pointer_cast<PropertyAttributes>(pair.first); + assert(attrs != nullptr); + if(attrs->publishZMQ) { + auto res = pair.second->set_mode(DMSG_EN); + if(res != 0) { + throw ChimeraTK::logic_error( + "Could not enable ZeroMQ messaging for prop_someZMQInt. Code: " + std::to_string(res)); + } } } } -} -int CSAdapterEqFct::fct_code() { return fctCode_; } + int CSAdapterEqFct::fct_code() { return fctCode_; } -void CSAdapterEqFct::registerProcessVariablesInDoocs() { - // We only need the factory inside this function - DoocsPVFactory factory(this, *updater_, controlSystemPVManager_); + void CSAdapterEqFct::registerProcessVariablesInDoocs() { + // We only need the factory inside this function + DoocsPVFactory factory(this, *updater_, controlSystemPVManager_); - auto mappingForThisLocation = - VariableMapper::getInstance().getPropertiesInLocation(name()); + auto mappingForThisLocation = VariableMapper::getInstance().getPropertiesInLocation(name()); - for (auto &propertyDescription : mappingForThisLocation) { - try { - doocsProperties_[propertyDescription] = - factory.create(propertyDescription); - } catch (std::invalid_argument &e) { - std::cerr << "**** WARNING: Could not create property for variable '" - << propertyDescription->location << "/" - << propertyDescription->name << "': " << e.what() - << ". Skipping this property." << std::endl; + for(auto& propertyDescription : mappingForThisLocation) { + try { + doocsProperties_[propertyDescription] = factory.create(propertyDescription); + } + catch(std::invalid_argument& e) { + std::cerr << "**** WARNING: Could not create property for variable '" << propertyDescription->location << "/" + << propertyDescription->name << "': " << e.what() << ". Skipping this property." << std::endl; + } } } -} } // namespace ChimeraTK diff --git a/src/DoocsAdapter.cc b/src/DoocsAdapter.cc index 90eeee2fad29809618ff413b202ac471693abc4d..0fbba8fa7410673d08b7fd3cca4f68b735a79f35 100644 --- a/src/DoocsAdapter.cc +++ b/src/DoocsAdapter.cc @@ -2,41 +2,36 @@ namespace ChimeraTK { -std::atomic<bool> DoocsAdapter::isInitialised(false); - -DoocsAdapter::DoocsAdapter() { - // Create the managers. We need both - std::pair<boost::shared_ptr<ControlSystemPVManager>, - boost::shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); - - _controlSystemPVManager = pvManagers.first; - _devicePVManager = pvManagers.second; - - updater = boost::make_shared<DoocsUpdater>(); -} - -boost::shared_ptr<DevicePVManager> const & -DoocsAdapter::getDevicePVManager() const { - return _devicePVManager; -} - -boost::shared_ptr<ControlSystemPVManager> const & -DoocsAdapter::getControlSystemPVManager() const { - return _controlSystemPVManager; -} - -void DoocsAdapter::waitUntilInitialised() { - int i = 0; - while (true) { - if (isInitialised) { - return; + std::atomic<bool> DoocsAdapter::isInitialised(false); + + DoocsAdapter::DoocsAdapter() { + // Create the managers. We need both + std::pair<boost::shared_ptr<ControlSystemPVManager>, boost::shared_ptr<DevicePVManager>> pvManagers = + createPVManager(); + + _controlSystemPVManager = pvManagers.first; + _devicePVManager = pvManagers.second; + + updater = boost::make_shared<DoocsUpdater>(); + } + + boost::shared_ptr<DevicePVManager> const& DoocsAdapter::getDevicePVManager() const { return _devicePVManager; } + + boost::shared_ptr<ControlSystemPVManager> const& DoocsAdapter::getControlSystemPVManager() const { + return _controlSystemPVManager; + } + + void DoocsAdapter::waitUntilInitialised() { + int i = 0; + while(true) { + if(isInitialised) { + return; + } + // just sleep a bit. Use the "cheap" usleep, we don't care about precision + // here + ++i; + usleep(100); } - // just sleep a bit. Use the "cheap" usleep, we don't care about precision - // here - ++i; - usleep(100); } -} } // namespace ChimeraTK diff --git a/src/DoocsPVFactory.cc b/src/DoocsPVFactory.cc index f14d324301428eb478ac02069c875045089c36ff..78a284ee90642ed07961ddc15cd308201ec9b34a 100644 --- a/src/DoocsPVFactory.cc +++ b/src/DoocsPVFactory.cc @@ -11,449 +11,386 @@ namespace ChimeraTK { -DoocsPVFactory::DoocsPVFactory( - EqFct *const eqFct, DoocsUpdater &updater, - boost::shared_ptr<ControlSystemPVManager> const &csPVManager) - : _eqFct(eqFct), _updater(updater), _controlSystemPVManager(csPVManager) { - assert(eqFct != nullptr); -} - -// Fixme: is AutoPropertyDescription ok, or to we need IntDescripton, -// DoubleDescription etc. -template <class DOOCS_PRIMITIVE_T, class DOOCS_T> -typename boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsScalar( - AutoPropertyDescription const &propertyDescription, - DecoratorType decoratorType) { - auto processVariable = - _controlSystemPVManager->getProcessVariable(propertyDescription.source); - - // the DoocsProcessScalar needs the real ProcessScalar type, not just - // ProcessVariable - auto processArray = - getDecorator<DOOCS_PRIMITIVE_T>(processVariable, decoratorType); - - assert(processArray->getNumberOfChannels() == 1); - boost::shared_ptr<D_fct> doocsPV; - // 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. One has to subtract another 6 - // characters because Doocs automatically adds - // "._HIST", which also has to fit into the 64 characters - if (propertyDescription.name.length() > 64 - 6) { - std::cerr << "WARNING: Disabling history for " << processArray->getName() - << ". Name is too long." << std::endl; - doocsPV.reset(new DoocsProcessScalar<DOOCS_PRIMITIVE_T, DOOCS_T>( - propertyDescription.name.c_str(), _eqFct, processArray, _updater)); - } else { - if (propertyDescription.hasHistory) { - // version with history: EqFtc first - doocsPV.reset(new DoocsProcessScalar<DOOCS_PRIMITIVE_T, DOOCS_T>( - _eqFct, propertyDescription.name.c_str(), processArray, _updater)); - } else { - // version without history: name first + DoocsPVFactory::DoocsPVFactory( + EqFct* const eqFct, DoocsUpdater& updater, boost::shared_ptr<ControlSystemPVManager> const& csPVManager) + : _eqFct(eqFct), _updater(updater), _controlSystemPVManager(csPVManager) { + assert(eqFct != nullptr); + } + + // Fixme: is AutoPropertyDescription ok, or to we need IntDescripton, + // DoubleDescription etc. + template<class DOOCS_PRIMITIVE_T, class DOOCS_T> + typename boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsScalar( + AutoPropertyDescription const& propertyDescription, + DecoratorType decoratorType) { + auto processVariable = _controlSystemPVManager->getProcessVariable(propertyDescription.source); + + // the DoocsProcessScalar needs the real ProcessScalar type, not just + // ProcessVariable + auto processArray = getDecorator<DOOCS_PRIMITIVE_T>(processVariable, decoratorType); + + assert(processArray->getNumberOfChannels() == 1); + boost::shared_ptr<D_fct> doocsPV; + // 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. One has to subtract another 6 + // characters because Doocs automatically adds + // "._HIST", which also has to fit into the 64 characters + if(propertyDescription.name.length() > 64 - 6) { + std::cerr << "WARNING: Disabling history for " << processArray->getName() << ". Name is too long." << std::endl; doocsPV.reset(new DoocsProcessScalar<DOOCS_PRIMITIVE_T, DOOCS_T>( propertyDescription.name.c_str(), _eqFct, processArray, _updater)); } - } // if name too long + else { + if(propertyDescription.hasHistory) { + // version with history: EqFtc first + doocsPV.reset(new DoocsProcessScalar<DOOCS_PRIMITIVE_T, DOOCS_T>( + _eqFct, propertyDescription.name.c_str(), processArray, _updater)); + } + else { + // version without history: name first + doocsPV.reset(new DoocsProcessScalar<DOOCS_PRIMITIVE_T, DOOCS_T>( + propertyDescription.name.c_str(), _eqFct, processArray, _updater)); + } + } // if name too long + + // set read only mode if configured in the xml file or for output variables + if(!processArray->isWriteable() || !propertyDescription.isWriteable) { + doocsPV->set_ro_access(); + } - // set read only mode if configured in the xml file or for output variables - if (!processArray->isWriteable() || !propertyDescription.isWriteable) { - doocsPV->set_ro_access(); - } + // publish via ZeroMQ if configured in the xml file + if(propertyDescription.publishZMQ) { + boost::dynamic_pointer_cast<DoocsProcessScalar<DOOCS_PRIMITIVE_T, DOOCS_T>>(doocsPV)->publishZeroMQ(); + } - // publish via ZeroMQ if configured in the xml file - if (propertyDescription.publishZMQ) { - boost::dynamic_pointer_cast<DoocsProcessScalar<DOOCS_PRIMITIVE_T, DOOCS_T>>( - doocsPV) - ->publishZeroMQ(); - } + // set macro pulse number source, if configured + if(propertyDescription.macroPulseNumberSource.size() > 0) { + auto mpnSource = _controlSystemPVManager->getProcessVariable(propertyDescription.macroPulseNumberSource); + auto mpnDecorated = getDecorator<int64_t>(mpnSource, DecoratorType::C_style_conversion); + if(mpnDecorated->getNumberOfSamples() != 1) { + throw ChimeraTK::logic_error("The property '" + mpnDecorated->getName() + + "' is used as a macro pulse number source, but it has an array " + "length of " + + std::to_string(mpnDecorated->getNumberOfSamples()) + ". Length must be exactly 1"); + } + if(!mpnDecorated->isReadable()) { + 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<DOOCS_PRIMITIVE_T, DOOCS_T>>(doocsPV)->setMacroPulseNumberSource( + mpnDecorated); + _updater.addVariable(ChimeraTK::ScalarRegisterAccessor<int64_t>(mpnDecorated), _eqFct, [] {}); + } - // set macro pulse number source, if configured - if (propertyDescription.macroPulseNumberSource.size() > 0) { - auto mpnSource = _controlSystemPVManager->getProcessVariable( - propertyDescription.macroPulseNumberSource); - auto mpnDecorated = - getDecorator<int64_t>(mpnSource, DecoratorType::C_style_conversion); - if (mpnDecorated->getNumberOfSamples() != 1) { - throw ChimeraTK::logic_error( - "The property '" + mpnDecorated->getName() + - "' is used as a macro pulse number source, but it has an array " - "length of " + - std::to_string(mpnDecorated->getNumberOfSamples()) + - ". Length must be exactly 1"); - } - if (!mpnDecorated->isReadable()) { - 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<DOOCS_PRIMITIVE_T, DOOCS_T>>( - doocsPV) - ->setMacroPulseNumberSource(mpnDecorated); - _updater.addVariable( - ChimeraTK::ScalarRegisterAccessor<int64_t>(mpnDecorated), _eqFct, - [] {}); + return doocsPV; } - return doocsPV; -} - -template <> -boost::shared_ptr<D_fct> -DoocsPVFactory::createDoocsScalar<std::string, D_string>( - AutoPropertyDescription const &propertyDescription, - DecoratorType /*decoratorType*/) { - auto processVariable = - _controlSystemPVManager->getProcessVariable(propertyDescription.source); - - // FIXME: Use a decorator, but this has to be tested and implemented for - // strings first the DoocsProcessArray needs the real ProcessScalar type, not - // just ProcessVariable - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<std::string>> processArray = - boost::dynamic_pointer_cast<ChimeraTK::NDRegisterAccessor<std::string>>( - processVariable); - if (!processArray) { - throw std::invalid_argument( - std::string("DoocsPVFactory::createDoocsArray : processArray is of the " - "wrong type ") + - processVariable->getValueType().name()); - } + template<> + boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsScalar<std::string, D_string>( + AutoPropertyDescription const& propertyDescription, + DecoratorType /*decoratorType*/) { + auto processVariable = _controlSystemPVManager->getProcessVariable(propertyDescription.source); + + // FIXME: Use a decorator, but this has to be tested and implemented for + // strings first the DoocsProcessArray needs the real ProcessScalar type, not + // just ProcessVariable + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<std::string>> processArray = + boost::dynamic_pointer_cast<ChimeraTK::NDRegisterAccessor<std::string>>(processVariable); + if(!processArray) { + throw std::invalid_argument(std::string("DoocsPVFactory::createDoocsArray : processArray is of the " + "wrong type ") + + processVariable->getValueType().name()); + } - 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_string>( - _eqFct, propertyDescription.name.c_str(), processArray, _updater)); + 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_string>( + _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) { - 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(); + } - // publish via ZeroMQ if configured in the xml file - if (propertyDescription.publishZMQ) { - boost::dynamic_pointer_cast<DoocsProcessScalar<std::string, D_string>>( - doocsPV) - ->publishZeroMQ(); - } + // publish via ZeroMQ if configured in the xml file + if(propertyDescription.publishZMQ) { + boost::dynamic_pointer_cast<DoocsProcessScalar<std::string, D_string>>(doocsPV)->publishZeroMQ(); + } - // set macro pulse number source, if configured - if (propertyDescription.macroPulseNumberSource.size() > 0) { - auto mpnSource = _controlSystemPVManager->getProcessVariable( - propertyDescription.macroPulseNumberSource); - auto mpnDecorated = - getDecorator<int64_t>(mpnSource, DecoratorType::C_style_conversion); - if (mpnDecorated->getNumberOfSamples() != 1) { - throw ChimeraTK::logic_error( - "The property '" + mpnDecorated->getName() + - "' is used as a macro pulse number source, but it has an array " - "length of " + - std::to_string(mpnDecorated->getNumberOfSamples()) + - ". Length must be exactly 1"); - } - if (!mpnDecorated->isReadable()) { - 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_string>>( - doocsPV) - ->setMacroPulseNumberSource(mpnDecorated); - _updater.addVariable( - ChimeraTK::ScalarRegisterAccessor<int64_t>(mpnDecorated), _eqFct, - [] {}); - } + // set macro pulse number source, if configured + if(propertyDescription.macroPulseNumberSource.size() > 0) { + auto mpnSource = _controlSystemPVManager->getProcessVariable(propertyDescription.macroPulseNumberSource); + auto mpnDecorated = getDecorator<int64_t>(mpnSource, DecoratorType::C_style_conversion); + if(mpnDecorated->getNumberOfSamples() != 1) { + throw ChimeraTK::logic_error("The property '" + mpnDecorated->getName() + + "' is used as a macro pulse number source, but it has an array " + "length of " + + std::to_string(mpnDecorated->getNumberOfSamples()) + ". Length must be exactly 1"); + } + if(!mpnDecorated->isReadable()) { + 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_string>>(doocsPV)->setMacroPulseNumberSource( + mpnDecorated); + _updater.addVariable(ChimeraTK::ScalarRegisterAccessor<int64_t>(mpnDecorated), _eqFct, [] {}); + } - return doocsPV; -} - -boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsSpectrum( - SpectrumDescription const &spectrumDescription) { - auto processVariable = - _controlSystemPVManager->getProcessVariable(spectrumDescription.source); - float start = spectrumDescription.start; - float increment = spectrumDescription.increment; - - // in case dynamic changing of the axis is requested replace the static values - // from the config file with the data from the accessors. The spectrum will - // keep the data updated. - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> startAccessor; - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> incrementAccessor; - - if (spectrumDescription.startSource != "") { - startAccessor = - getDecorator<float>(_controlSystemPVManager->getProcessVariable( - spectrumDescription.startSource), - DecoratorType::C_style_conversion); - start = startAccessor->accessData(0); - } - if (spectrumDescription.incrementSource != "") { - incrementAccessor = - getDecorator<float>(_controlSystemPVManager->getProcessVariable( - spectrumDescription.incrementSource), - DecoratorType::C_style_conversion); - increment = incrementAccessor->accessData(0); + return doocsPV; } - // assert(processArray->getNumberOfChannels() == 1); - boost::shared_ptr<D_fct> doocsPV(new DoocsSpectrum( - _eqFct, spectrumDescription.name, - getDecorator<float>(processVariable, DecoratorType::C_style_conversion), - _updater, startAccessor, incrementAccessor)); + boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsSpectrum(SpectrumDescription const& spectrumDescription) { + auto processVariable = _controlSystemPVManager->getProcessVariable(spectrumDescription.source); + float start = spectrumDescription.start; + float increment = spectrumDescription.increment; + + // in case dynamic changing of the axis is requested replace the static values + // from the config file with the data from the accessors. The spectrum will + // keep the data updated. + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> startAccessor; + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> incrementAccessor; + + if(spectrumDescription.startSource != "") { + startAccessor = getDecorator<float>(_controlSystemPVManager->getProcessVariable(spectrumDescription.startSource), + DecoratorType::C_style_conversion); + start = startAccessor->accessData(0); + } + if(spectrumDescription.incrementSource != "") { + incrementAccessor = + getDecorator<float>(_controlSystemPVManager->getProcessVariable(spectrumDescription.incrementSource), + DecoratorType::C_style_conversion); + increment = incrementAccessor->accessData(0); + } - // set read only mode if configures in the xml file or for output variables - if (!processVariable->isWriteable() || !spectrumDescription.isWriteable) { - doocsPV->set_ro_access(); - } + // assert(processArray->getNumberOfChannels() == 1); + boost::shared_ptr<D_fct> doocsPV(new DoocsSpectrum(_eqFct, spectrumDescription.name, + getDecorator<float>(processVariable, DecoratorType::C_style_conversion), _updater, startAccessor, + incrementAccessor)); - // can use static cast, we know it's a D_spectrum, we just created it - auto spectrum = boost::static_pointer_cast<D_spectrum>(doocsPV); - spectrum->spectrum_parameter(spectrum->spec_time(), start, increment, - spectrum->spec_status()); + // set read only mode if configures in the xml file or for output variables + if(!processVariable->isWriteable() || !spectrumDescription.isWriteable) { + doocsPV->set_ro_access(); + } - // publish via ZeroMQ if configured in the xml file - if (spectrumDescription.publishZMQ) { - boost::dynamic_pointer_cast<DoocsSpectrum>(doocsPV)->publishZeroMQ(); - } + // can use static cast, we know it's a D_spectrum, we just created it + auto spectrum = boost::static_pointer_cast<D_spectrum>(doocsPV); + spectrum->spectrum_parameter(spectrum->spec_time(), start, increment, spectrum->spec_status()); - // set macro pulse number source, if configured - if (spectrumDescription.macroPulseNumberSource.size() > 0) { - auto mpnSource = _controlSystemPVManager->getProcessVariable( - spectrumDescription.macroPulseNumberSource); - auto mpnDecorated = - getDecorator<int64_t>(mpnSource, DecoratorType::C_style_conversion); - if (mpnDecorated->getNumberOfSamples() != 1) { - throw ChimeraTK::logic_error( - "The property '" + mpnDecorated->getName() + - "' is used as a macro pulse number source, but it has an array " - "length of " + - std::to_string(mpnDecorated->getNumberOfSamples()) + - ". Length must be exactly 1"); - } - if (!mpnDecorated->isReadable()) { - 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<DoocsSpectrum>(doocsPV) - ->setMacroPulseNumberSource(mpnDecorated); - } + // publish via ZeroMQ if configured in the xml file + if(spectrumDescription.publishZMQ) { + boost::dynamic_pointer_cast<DoocsSpectrum>(doocsPV)->publishZeroMQ(); + } - return doocsPV; -} - -// fixme: some of the variables needed here are redundant and can be sovled with -// mpl and/or fusion maps -template <class IMPL_T, class DOOCS_SCALAR_T, class DOOCS_PRIMITIVE_T, - class DOOCS_ARRAY_T, class DOOCS_ARRAY_PRIMITIVE_T> -boost::shared_ptr<D_fct> DoocsPVFactory::typedCreateScalarOrArray( - ProcessVariable &processVariable, - AutoPropertyDescription const &autoPropertyDescription, - DecoratorType decoratorType, ArrayDescription::DataType arrayDataType) { - // We have to convert to the original NDRegisterAccessor to determine the - // number of samples. We cannot use a decorator because scalar and array - // DOOCS_PRIMITIVE_T can be different, and once a decorator is created you - // cannot get the other type any more. - - auto &ndAccessor = - dynamic_cast<ChimeraTK::NDRegisterAccessor<IMPL_T> &>(processVariable); - auto nSamples = ndAccessor.getNumberOfSamples(); - - if (nSamples == 1) { - return createDoocsScalar<DOOCS_PRIMITIVE_T, DOOCS_SCALAR_T>( - autoPropertyDescription, decoratorType); - } else { - return typedCreateDoocsArray<DOOCS_ARRAY_PRIMITIVE_T, DOOCS_ARRAY_T>( - ArrayDescription(autoPropertyDescription, arrayDataType)); + // set macro pulse number source, if configured + if(spectrumDescription.macroPulseNumberSource.size() > 0) { + auto mpnSource = _controlSystemPVManager->getProcessVariable(spectrumDescription.macroPulseNumberSource); + auto mpnDecorated = getDecorator<int64_t>(mpnSource, DecoratorType::C_style_conversion); + if(mpnDecorated->getNumberOfSamples() != 1) { + throw ChimeraTK::logic_error("The property '" + mpnDecorated->getName() + + "' is used as a macro pulse number source, but it has an array " + "length of " + + std::to_string(mpnDecorated->getNumberOfSamples()) + ". Length must be exactly 1"); + } + if(!mpnDecorated->isReadable()) { + 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<DoocsSpectrum>(doocsPV)->setMacroPulseNumberSource(mpnDecorated); + } + + return doocsPV; } -} - -boost::shared_ptr<D_fct> DoocsPVFactory::autoCreate( - std::shared_ptr<PropertyDescription> const &propertyDescription) { - // do auto creation - auto autoPropertyDescription = - std::static_pointer_cast<AutoPropertyDescription>(propertyDescription); - - auto pvName = autoPropertyDescription->source; - auto processVariable = _controlSystemPVManager->getProcessVariable(pvName); - - std::type_info const &valueType = processVariable->getValueType(); - /* 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) - */ - - // fixme: make this a boost::foreach in the data types provided by - // DeviceAccess. This will detect uncovered new data types at compile time, - // not only at run time - if (valueType == typeid(int8_t)) { - return typedCreateScalarOrArray<int8_t, D_int, int32_t, D_bytearray, - uint8_t>( - *processVariable, *autoPropertyDescription, - DecoratorType::C_style_conversion, ArrayDescription::DataType::Byte); - } else if (valueType == typeid(uint8_t)) { - return typedCreateScalarOrArray<uint8_t, D_int, int32_t, D_bytearray, - uint8_t>( - *processVariable, *autoPropertyDescription, - DecoratorType::C_style_conversion, ArrayDescription::DataType::Byte); - } else if (valueType == typeid(int16_t)) { - return typedCreateScalarOrArray<int16_t, D_int, int32_t, D_shortarray, - int16_t>( - *processVariable, *autoPropertyDescription, - DecoratorType::C_style_conversion, ArrayDescription::DataType::Short); - } else if (valueType == typeid(uint16_t)) { - return typedCreateScalarOrArray<uint16_t, D_int, int32_t, D_shortarray, - int16_t>( - *processVariable, *autoPropertyDescription, - DecoratorType::C_style_conversion, ArrayDescription::DataType::Short); - } else if (valueType == typeid(int32_t)) { - return typedCreateScalarOrArray<int32_t, D_int, int32_t, D_intarray, - int32_t>( - *processVariable, *autoPropertyDescription, - DecoratorType::C_style_conversion, ArrayDescription::DataType::Int); - } else if (valueType == typeid(uint32_t)) { - return typedCreateScalarOrArray<uint32_t, D_int, int32_t, D_intarray, - int32_t>( - *processVariable, *autoPropertyDescription, - DecoratorType::C_style_conversion, ArrayDescription::DataType::Int); - } else if (valueType == typeid(int64_t)) { - // there is no scalar int64 representation in doocs, so we always create an - // array, also for length = 1 - return typedCreateDoocsArray<int64_t, D_longarray>(ArrayDescription( - *autoPropertyDescription, ArrayDescription::DataType::Long)); - } else if (valueType == typeid(uint64_t)) { - return typedCreateDoocsArray<int64_t, D_longarray>(ArrayDescription( - *autoPropertyDescription, ArrayDescription::DataType::Long)); - } else if (valueType == typeid(float)) { - return typedCreateScalarOrArray<float, D_float, float, D_floatarray, float>( - *processVariable, *autoPropertyDescription, - DecoratorType::C_style_conversion, ArrayDescription::DataType::Float); - } else if (valueType == typeid(double)) { - return typedCreateScalarOrArray<double, D_double, double, D_doublearray, - double>( - *processVariable, *autoPropertyDescription, - DecoratorType::C_style_conversion, ArrayDescription::DataType::Double); - } else if (valueType == typeid(std::string)) { - 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"); + + // fixme: some of the variables needed here are redundant and can be sovled with + // mpl and/or fusion maps + template<class IMPL_T, class DOOCS_SCALAR_T, class DOOCS_PRIMITIVE_T, class DOOCS_ARRAY_T, + class DOOCS_ARRAY_PRIMITIVE_T> + boost::shared_ptr<D_fct> DoocsPVFactory::typedCreateScalarOrArray(ProcessVariable& processVariable, + AutoPropertyDescription const& autoPropertyDescription, DecoratorType decoratorType, + ArrayDescription::DataType arrayDataType) { + // We have to convert to the original NDRegisterAccessor to determine the + // number of samples. We cannot use a decorator because scalar and array + // DOOCS_PRIMITIVE_T can be different, and once a decorator is created you + // cannot get the other type any more. + + auto& ndAccessor = dynamic_cast<ChimeraTK::NDRegisterAccessor<IMPL_T>&>(processVariable); + auto nSamples = ndAccessor.getNumberOfSamples(); + + if(nSamples == 1) { + return createDoocsScalar<DOOCS_PRIMITIVE_T, DOOCS_SCALAR_T>(autoPropertyDescription, decoratorType); + } + else { + return typedCreateDoocsArray<DOOCS_ARRAY_PRIMITIVE_T, DOOCS_ARRAY_T>( + ArrayDescription(autoPropertyDescription, arrayDataType)); + } } -} - -template <class DOOCS_PRIMITIVE_T, class DOOCS_T> -boost::shared_ptr<D_fct> DoocsPVFactory::typedCreateDoocsArray( - ArrayDescription const &arrayDescription) { - auto processVariable = - _controlSystemPVManager->getProcessVariable(arrayDescription.source); - - ///@todo FIXME Add the decorator type as option to the array description, and - /// only use C_style_conversion as default - boost::shared_ptr<D_fct> doocsPV( - new DoocsProcessArray<DOOCS_T, DOOCS_PRIMITIVE_T>( - _eqFct, arrayDescription.name, - getDecorator<DOOCS_PRIMITIVE_T>(processVariable, - DecoratorType::C_style_conversion), - _updater)); - - // set read only mode if configures in the xml file or for output variables - if (!processVariable->isWriteable() || !arrayDescription.isWriteable) { - doocsPV->set_ro_access(); + + boost::shared_ptr<D_fct> DoocsPVFactory::autoCreate(std::shared_ptr<PropertyDescription> const& propertyDescription) { + // do auto creation + auto autoPropertyDescription = std::static_pointer_cast<AutoPropertyDescription>(propertyDescription); + + auto pvName = autoPropertyDescription->source; + auto processVariable = _controlSystemPVManager->getProcessVariable(pvName); + + std::type_info const& valueType = processVariable->getValueType(); + /* 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) + */ + + // fixme: make this a boost::foreach in the data types provided by + // DeviceAccess. This will detect uncovered new data types at compile time, + // not only at run time + if(valueType == typeid(int8_t)) { + return typedCreateScalarOrArray<int8_t, D_int, int32_t, D_bytearray, uint8_t>(*processVariable, + *autoPropertyDescription, DecoratorType::C_style_conversion, ArrayDescription::DataType::Byte); + } + else if(valueType == typeid(uint8_t)) { + return typedCreateScalarOrArray<uint8_t, D_int, int32_t, D_bytearray, uint8_t>(*processVariable, + *autoPropertyDescription, DecoratorType::C_style_conversion, ArrayDescription::DataType::Byte); + } + else if(valueType == typeid(int16_t)) { + return typedCreateScalarOrArray<int16_t, D_int, int32_t, D_shortarray, int16_t>(*processVariable, + *autoPropertyDescription, DecoratorType::C_style_conversion, ArrayDescription::DataType::Short); + } + else if(valueType == typeid(uint16_t)) { + return typedCreateScalarOrArray<uint16_t, D_int, int32_t, D_shortarray, int16_t>(*processVariable, + *autoPropertyDescription, DecoratorType::C_style_conversion, ArrayDescription::DataType::Short); + } + else if(valueType == typeid(int32_t)) { + return typedCreateScalarOrArray<int32_t, D_int, int32_t, D_intarray, int32_t>(*processVariable, + *autoPropertyDescription, DecoratorType::C_style_conversion, ArrayDescription::DataType::Int); + } + else if(valueType == typeid(uint32_t)) { + return typedCreateScalarOrArray<uint32_t, D_int, int32_t, D_intarray, int32_t>(*processVariable, + *autoPropertyDescription, DecoratorType::C_style_conversion, ArrayDescription::DataType::Int); + } + else if(valueType == typeid(int64_t)) { + // there is no scalar int64 representation in doocs, so we always create an + // array, also for length = 1 + return typedCreateDoocsArray<int64_t, D_longarray>( + ArrayDescription(*autoPropertyDescription, ArrayDescription::DataType::Long)); + } + else if(valueType == typeid(uint64_t)) { + return typedCreateDoocsArray<int64_t, D_longarray>( + ArrayDescription(*autoPropertyDescription, ArrayDescription::DataType::Long)); + } + else if(valueType == typeid(float)) { + return typedCreateScalarOrArray<float, D_float, float, D_floatarray, float>(*processVariable, + *autoPropertyDescription, DecoratorType::C_style_conversion, ArrayDescription::DataType::Float); + } + else if(valueType == typeid(double)) { + return typedCreateScalarOrArray<double, D_double, double, D_doublearray, double>(*processVariable, + *autoPropertyDescription, DecoratorType::C_style_conversion, ArrayDescription::DataType::Double); + } + else if(valueType == typeid(std::string)) { + 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"); + } } - // publish via ZeroMQ if configured in the xml file - if (arrayDescription.publishZMQ) { - boost::dynamic_pointer_cast<DoocsProcessArray<DOOCS_T, DOOCS_PRIMITIVE_T>>( - doocsPV) - ->publishZeroMQ(); + template<class DOOCS_PRIMITIVE_T, class DOOCS_T> + boost::shared_ptr<D_fct> DoocsPVFactory::typedCreateDoocsArray(ArrayDescription const& arrayDescription) { + auto processVariable = _controlSystemPVManager->getProcessVariable(arrayDescription.source); + + ///@todo FIXME Add the decorator type as option to the array description, and + /// only use C_style_conversion as default + boost::shared_ptr<D_fct> doocsPV(new DoocsProcessArray<DOOCS_T, DOOCS_PRIMITIVE_T>(_eqFct, arrayDescription.name, + getDecorator<DOOCS_PRIMITIVE_T>(processVariable, DecoratorType::C_style_conversion), _updater)); + + // set read only mode if configures in the xml file or for output variables + if(!processVariable->isWriteable() || !arrayDescription.isWriteable) { + doocsPV->set_ro_access(); + } + + // publish via ZeroMQ if configured in the xml file + if(arrayDescription.publishZMQ) { + boost::dynamic_pointer_cast<DoocsProcessArray<DOOCS_T, DOOCS_PRIMITIVE_T>>(doocsPV)->publishZeroMQ(); + } + + // set macro pulse number source, if configured + if(arrayDescription.macroPulseNumberSource.size() > 0) { + auto mpnSource = _controlSystemPVManager->getProcessVariable(arrayDescription.macroPulseNumberSource); + auto mpnDecorated = getDecorator<int64_t>(mpnSource, DecoratorType::C_style_conversion); + if(mpnDecorated->getNumberOfSamples() != 1) { + throw ChimeraTK::logic_error("The property '" + mpnDecorated->getName() + + "' is used as a macro pulse number source, but it has an array " + "length of " + + std::to_string(mpnDecorated->getNumberOfSamples()) + ". Length must be exactly 1"); + } + if(!mpnDecorated->isReadable()) { + 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<DoocsProcessArray<DOOCS_T, DOOCS_PRIMITIVE_T>>(doocsPV)->setMacroPulseNumberSource( + mpnDecorated); + _updater.addVariable(ChimeraTK::ScalarRegisterAccessor<int64_t>(mpnDecorated), _eqFct, [] {}); + } + + return doocsPV; } - // set macro pulse number source, if configured - if (arrayDescription.macroPulseNumberSource.size() > 0) { - auto mpnSource = _controlSystemPVManager->getProcessVariable( - arrayDescription.macroPulseNumberSource); - auto mpnDecorated = - getDecorator<int64_t>(mpnSource, DecoratorType::C_style_conversion); - if (mpnDecorated->getNumberOfSamples() != 1) { - throw ChimeraTK::logic_error( - "The property '" + mpnDecorated->getName() + - "' is used as a macro pulse number source, but it has an array " - "length of " + - std::to_string(mpnDecorated->getNumberOfSamples()) + - ". Length must be exactly 1"); - } - if (!mpnDecorated->isReadable()) { - 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<DoocsProcessArray<DOOCS_T, DOOCS_PRIMITIVE_T>>( - doocsPV) - ->setMacroPulseNumberSource(mpnDecorated); - _updater.addVariable( - ChimeraTK::ScalarRegisterAccessor<int64_t>(mpnDecorated), _eqFct, - [] {}); + // 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"); } - 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 - // FIXME: This does not produce arrays of length 1 because it will produce a - // scalar - return autoCreate(arrayDescription); - } else if (arrayDescription->dataType == ArrayDescription::DataType::Byte) { - return typedCreateDoocsArray<uint8_t, D_bytearray>(*arrayDescription); - } else if (arrayDescription->dataType == ArrayDescription::DataType::Short) { - return typedCreateDoocsArray<int16_t, D_shortarray>(*arrayDescription); - } else if (arrayDescription->dataType == ArrayDescription::DataType::Int) { - return typedCreateDoocsArray<int32_t, D_intarray>(*arrayDescription); - } else if (arrayDescription->dataType == ArrayDescription::DataType::Long) { - return typedCreateDoocsArray<int64_t, D_longarray>(*arrayDescription); - } else if (arrayDescription->dataType == ArrayDescription::DataType::Float) { - return typedCreateDoocsArray<float, D_floatarray>(*arrayDescription); - } else if (arrayDescription->dataType == ArrayDescription::DataType::Double) { - return typedCreateDoocsArray<double, D_doublearray>(*arrayDescription); - } else { - throw std::logic_error( - "DoocsPVFactory does not implement a data type it should!"); + 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 + // FIXME: This does not produce arrays of length 1 because it will produce a + // scalar + return autoCreate(arrayDescription); + } + else if(arrayDescription->dataType == ArrayDescription::DataType::Byte) { + return typedCreateDoocsArray<uint8_t, D_bytearray>(*arrayDescription); + } + else if(arrayDescription->dataType == ArrayDescription::DataType::Short) { + return typedCreateDoocsArray<int16_t, D_shortarray>(*arrayDescription); + } + else if(arrayDescription->dataType == ArrayDescription::DataType::Int) { + return typedCreateDoocsArray<int32_t, D_intarray>(*arrayDescription); + } + else if(arrayDescription->dataType == ArrayDescription::DataType::Long) { + return typedCreateDoocsArray<int64_t, D_longarray>(*arrayDescription); + } + else if(arrayDescription->dataType == ArrayDescription::DataType::Float) { + return typedCreateDoocsArray<float, D_floatarray>(*arrayDescription); + } + else if(arrayDescription->dataType == ArrayDescription::DataType::Double) { + return typedCreateDoocsArray<double, D_doublearray>(*arrayDescription); + } + else { + throw std::logic_error("DoocsPVFactory does not implement a data type it should!"); + } } -} - -boost::shared_ptr<D_fct> DoocsPVFactory::create( - std::shared_ptr<PropertyDescription> const &propertyDescription) { - auto &requestedType = propertyDescription->type(); - if (requestedType == typeid(AutoPropertyDescription)) { - return autoCreate(propertyDescription); - } else if (requestedType == typeid(SpectrumDescription)) { - return createDoocsSpectrum( - *std::static_pointer_cast<SpectrumDescription>(propertyDescription)); - } else if (requestedType == typeid(ArrayDescription)) { - return createDoocsArray( - std::static_pointer_cast<ArrayDescription>(propertyDescription)); - } else { - throw std::invalid_argument("Sorry, your type is not supported yet."); + + boost::shared_ptr<D_fct> DoocsPVFactory::create(std::shared_ptr<PropertyDescription> const& propertyDescription) { + auto& requestedType = propertyDescription->type(); + if(requestedType == typeid(AutoPropertyDescription)) { + return autoCreate(propertyDescription); + } + else if(requestedType == typeid(SpectrumDescription)) { + return createDoocsSpectrum(*std::static_pointer_cast<SpectrumDescription>(propertyDescription)); + } + else if(requestedType == typeid(ArrayDescription)) { + return createDoocsArray(std::static_pointer_cast<ArrayDescription>(propertyDescription)); + } + else { + throw std::invalid_argument("Sorry, your type is not supported yet."); + } } -} } // namespace ChimeraTK diff --git a/src/DoocsSpectrum.cc b/src/DoocsSpectrum.cc index e11784f2bc678a9dbfe7df1e2b19affed3217070..17c052395fe6002f8a7e8436c3530187b9875cb1 100644 --- a/src/DoocsSpectrum.cc +++ b/src/DoocsSpectrum.cc @@ -7,100 +7,92 @@ namespace ChimeraTK { -DoocsSpectrum::DoocsSpectrum( - EqFct *eqFct, std::string const &doocsPropertyName, - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const &processArray, - DoocsUpdater &updater, - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const - &startAccessor, - boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const - &incrementAccessor) + DoocsSpectrum::DoocsSpectrum(EqFct* eqFct, std::string const& doocsPropertyName, + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const& processArray, DoocsUpdater& updater, + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const& startAccessor, + boost::shared_ptr<ChimeraTK::NDRegisterAccessor<float>> const& incrementAccessor) - : D_spectrum(doocsPropertyName.c_str(), processArray->getNumberOfSamples(), - eqFct, true), - _processArray(processArray), _startAccessor(startAccessor), - _incrementAccessor(incrementAccessor) { - if (processArray->isReadable()) { - updater.addVariable(ChimeraTK::OneDRegisterAccessor<float>(processArray), - eqFct, - std::bind(&DoocsSpectrum::updateDoocsBuffer, this)); + : D_spectrum(doocsPropertyName.c_str(), processArray->getNumberOfSamples(), eqFct, true), _processArray(processArray), + _startAccessor(startAccessor), _incrementAccessor(incrementAccessor) { + if(processArray->isReadable()) { + updater.addVariable(ChimeraTK::OneDRegisterAccessor<float>(processArray), + eqFct, + std::bind(&DoocsSpectrum::updateDoocsBuffer, this)); + } + if(startAccessor && startAccessor->isReadable()) { + updater.addVariable(ChimeraTK::ScalarRegisterAccessor<float>(startAccessor), + eqFct, + std::bind(&DoocsSpectrum::updateParameters, this)); + } + if(incrementAccessor && incrementAccessor->isReadable()) { + updater.addVariable(ChimeraTK::ScalarRegisterAccessor<float>(incrementAccessor), eqFct, + std::bind(&DoocsSpectrum::updateParameters, this)); + } } - if (startAccessor && startAccessor->isReadable()) { - updater.addVariable(ChimeraTK::ScalarRegisterAccessor<float>(startAccessor), - eqFct, - std::bind(&DoocsSpectrum::updateParameters, this)); - } - if (incrementAccessor && incrementAccessor->isReadable()) { - updater.addVariable( - ChimeraTK::ScalarRegisterAccessor<float>(incrementAccessor), eqFct, - std::bind(&DoocsSpectrum::updateParameters, this)); - } -} - -void DoocsSpectrum::set(EqAdr *eqAdr, EqData *data1, EqData *data2, - EqFct *eqFct) { - D_spectrum::set(eqAdr, data1, data2, eqFct); - sendToDevice(); -} -void DoocsSpectrum::auto_init(void) { - D_spectrum::read(); - // send the current value to the device - if (_processArray->isWriteable()) { + void DoocsSpectrum::set(EqAdr* eqAdr, EqData* data1, EqData* data2, EqFct* eqFct) { + D_spectrum::set(eqAdr, data1, data2, eqFct); sendToDevice(); } -} -void DoocsSpectrum::updateDoocsBuffer() { - // Note: we already own the location lock by specification of the DoocsUpdater + void DoocsSpectrum::auto_init(void) { + D_spectrum::read(); + // send the current value to the device + if(_processArray->isWriteable()) { + sendToDevice(); + } + } - // FIXME: find the efficient memcopying implementation for float - std::vector<float> &processVector = _processArray->accessChannel(0); + void DoocsSpectrum::updateDoocsBuffer() { + // Note: we already own the location lock by specification of the DoocsUpdater - for (size_t i = 0; i < processVector.size(); ++i) { - fill_spectrum(i, processVector[i]); - } - if (publishZMQ) { - dmsg_info info; - memset(&info, 0, sizeof(info)); - auto sinceEpoch = - _processArray->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); - } -} + // FIXME: find the efficient memcopying implementation for float + std::vector<float>& processVector = _processArray->accessChannel(0); -void DoocsSpectrum::updateParameters() { - // Note: we already own the location lock by specification of the DoocsUpdater - float start, increment; - if (_startAccessor) { - start = _startAccessor->accessData(0); - } else { - start = this->spec_start(); - } - if (_incrementAccessor) { - increment = _incrementAccessor->accessData(0); - } else { - increment = this->spec_inc(); + for(size_t i = 0; i < processVector.size(); ++i) { + fill_spectrum(i, processVector[i]); + } + if(publishZMQ) { + dmsg_info info; + memset(&info, 0, sizeof(info)); + auto sinceEpoch = _processArray->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); + } } - spectrum_parameter(this->spec_time(), start, increment, this->spec_status()); -} + void DoocsSpectrum::updateParameters() { + // Note: we already own the location lock by specification of the DoocsUpdater + float start, increment; + if(_startAccessor) { + start = _startAccessor->accessData(0); + } + else { + start = this->spec_start(); + } + if(_incrementAccessor) { + increment = _incrementAccessor->accessData(0); + } + else { + increment = this->spec_inc(); + } + + spectrum_parameter(this->spec_time(), start, increment, this->spec_status()); + } -void DoocsSpectrum::sendToDevice() { - // Brute force implementation with a loop. Works for all data types. - // FIXME: find the efficient, memcopying function for float - // always get a fresh reference - std::vector<float> &processVector = _processArray->accessChannel(0); - size_t arraySize = processVector.size(); - for (size_t i = 0; i < arraySize; ++i) { - processVector[i] = read_spectrum(i); + void DoocsSpectrum::sendToDevice() { + // Brute force implementation with a loop. Works for all data types. + // FIXME: find the efficient, memcopying function for float + // always get a fresh reference + std::vector<float>& processVector = _processArray->accessChannel(0); + size_t arraySize = processVector.size(); + for(size_t i = 0; i < arraySize; ++i) { + processVector[i] = read_spectrum(i); + } + _processArray->write(); } - _processArray->write(); -} } // namespace ChimeraTK diff --git a/src/DoocsUpdater.cc b/src/DoocsUpdater.cc index 6a2861861fb2dda9d958d4cf82a04a6c5319f1a5..ddcd99c025ba55d57756a7054e6f500bc68ab950 100644 --- a/src/DoocsUpdater.cc +++ b/src/DoocsUpdater.cc @@ -5,73 +5,68 @@ namespace ChimeraTK { -void DoocsUpdater::addVariable(const TransferElementAbstractor &variable, - EqFct *eq_fct, - std::function<void()> updaterFunction) { - // Don't add the transfer element twice into the list of elements to read. - // To check if there is such an element we use the map with the lookup table - // which has a search function, instead of manually looking at the elements in - // the list and compare the ID. - if (_toDoocsUpdateMap.find(variable.getId()) == _toDoocsUpdateMap.end()) { - _elementsToRead.push_back(variable); - } + void DoocsUpdater::addVariable(const TransferElementAbstractor& variable, + EqFct* eq_fct, + std::function<void()> + updaterFunction) { + // Don't add the transfer element twice into the list of elements to read. + // To check if there is such an element we use the map with the lookup table + // which has a search function, instead of manually looking at the elements in + // the list and compare the ID. + if(_toDoocsUpdateMap.find(variable.getId()) == _toDoocsUpdateMap.end()) { + _elementsToRead.push_back(variable); + } - _toDoocsUpdateMap[variable.getId()].push_back(updaterFunction); - _toDoocsEqFctMap[variable.getId()].push_back(eq_fct); -} + _toDoocsUpdateMap[variable.getId()].push_back(updaterFunction); + _toDoocsEqFctMap[variable.getId()].push_back(eq_fct); + } -void DoocsUpdater::update() { - for (auto &transferElem : _elementsToRead) { - if (transferElem.readLatest()) { - for (auto &updaterFunction : _toDoocsUpdateMap[transferElem.getId()]) { - updaterFunction(); + void DoocsUpdater::update() { + for(auto& transferElem : _elementsToRead) { + if(transferElem.readLatest()) { + for(auto& updaterFunction : _toDoocsUpdateMap[transferElem.getId()]) { + updaterFunction(); + } } } } -} -void DoocsUpdater::updateLoop() { - if (_elementsToRead.empty()) { - return; - } + void DoocsUpdater::updateLoop() { + if(_elementsToRead.empty()) { + return; + } - ReadAnyGroup group(_elementsToRead.begin(), _elementsToRead.end()); - while (true) { - // Wait until any variable got an update - auto notification = group.waitAny(); - auto updatedElement = notification.getId(); - // Gather all involved locations in a unique set - std::unordered_set<EqFct *> locationsToLock; - for (auto &location : _toDoocsEqFctMap[updatedElement]) - locationsToLock.insert(location); - // Lock all involved locations - for (auto &location : locationsToLock) - location->lock(); - // Complete the read transfer of the process variable - notification.accept(); - // Call all updater functions - for (auto &updaterFunction : _toDoocsUpdateMap[updatedElement]) - updaterFunction(); - // Unlock all involved locations - for (auto &location : locationsToLock) - location->unlock(); - // Allow shutting down this thread... - boost::this_thread::interruption_point(); + ReadAnyGroup group(_elementsToRead.begin(), _elementsToRead.end()); + while(true) { + // Wait until any variable got an update + auto notification = group.waitAny(); + auto updatedElement = notification.getId(); + // Gather all involved locations in a unique set + std::unordered_set<EqFct*> locationsToLock; + for(auto& location : _toDoocsEqFctMap[updatedElement]) locationsToLock.insert(location); + // Lock all involved locations + for(auto& location : locationsToLock) location->lock(); + // Complete the read transfer of the process variable + notification.accept(); + // Call all updater functions + for(auto& updaterFunction : _toDoocsUpdateMap[updatedElement]) updaterFunction(); + // Unlock all involved locations + for(auto& location : locationsToLock) location->unlock(); + // Allow shutting down this thread... + boost::this_thread::interruption_point(); + } } -} -void DoocsUpdater::run() { - _syncThread = boost::thread(boost::bind(&DoocsUpdater::updateLoop, this)); -} + void DoocsUpdater::run() { _syncThread = boost::thread(boost::bind(&DoocsUpdater::updateLoop, this)); } -void DoocsUpdater::stop() { - _syncThread.interrupt(); - for (auto &var : _elementsToRead) { - var.getHighLevelImplElement()->interrupt(); + void DoocsUpdater::stop() { + _syncThread.interrupt(); + for(auto& var : _elementsToRead) { + var.getHighLevelImplElement()->interrupt(); + } + _syncThread.join(); } - _syncThread.join(); -} -DoocsUpdater::~DoocsUpdater() { stop(); } + DoocsUpdater::~DoocsUpdater() { stop(); } } // namespace ChimeraTK diff --git a/src/VariableMapper.cc b/src/VariableMapper.cc index 13bef4d4719ea129226a6209dfd8ac77911ac1fa..7c6cb3398f4137292f7cb0ccdfa7855a408b175d 100644 --- a/src/VariableMapper.cc +++ b/src/VariableMapper.cc @@ -10,548 +10,515 @@ namespace ChimeraTK { -/********************************************************************************************************************/ + /********************************************************************************************************************/ -VariableMapper &VariableMapper::getInstance() { - static VariableMapper instance; - return instance; -} + VariableMapper& VariableMapper::getInstance() { + static VariableMapper instance; + return instance; + } -/********************************************************************************************************************/ + /********************************************************************************************************************/ -bool VariableMapper::nodeIsWhitespace(const xmlpp::Node *node) { - const xmlpp::TextNode *nodeAsText = - dynamic_cast<const xmlpp::TextNode *>(node); - if (nodeAsText) { - return nodeAsText->is_white_space(); + bool VariableMapper::nodeIsWhitespace(const xmlpp::Node* node) { + const xmlpp::TextNode* nodeAsText = dynamic_cast<const xmlpp::TextNode*>(node); + if(nodeAsText) { + return nodeAsText->is_white_space(); + } + return false; } - return false; -} -/********************************************************************************************************************/ + /********************************************************************************************************************/ -void VariableMapper::processLocationNode(xmlpp::Node const *locationNode) { - const xmlpp::Element *location = - dynamic_cast<const xmlpp::Element *>(locationNode); - if (!location) { - throw std::invalid_argument("Error parsing xml file in location node."); - } - std::string locationName = getAttributeValue(location, "name"); - - for (auto const &node : location->get_children()) { - if (nodeIsWhitespace(node)) - continue; - if (dynamic_cast<xmlpp::CommentNode const *>(node)) - continue; - - if (node->get_name() == "property") { - processPropertyNode(node, locationName); - } else if (node->get_name() == "import") { - processImportNode(node, locationName); - } else if (node->get_name() == "has_history") { - auto &locationInfo = _locationDefaults[locationName]; - locationInfo.useHasHistoryDefault = true; - locationInfo.hasHistory = evaluateBool(getContentString(node)); - } else if (node->get_name() == "is_writeable") { - auto &locationInfo = _locationDefaults[locationName]; - locationInfo.useIsWriteableDefault = true; - locationInfo.isWriteable = evaluateBool(getContentString(node)); - } else if (node->get_name() == "macro_pulse_number_source") { - auto &locationInfo = _locationDefaults[locationName]; - locationInfo.useMacroPulseNumberSourceDefault = true; - locationInfo.macroPulseNumberSource = getContentString(node); - } else if (node->get_name() == "D_spectrum") { - processSpectrumNode(node, locationName); - } else if (node->get_name() == "D_array") { - processArrayNode(node, locationName); - } else { - throw std::invalid_argument( - std::string("Error parsing xml file in location ") + locationName + - ": Unknown node '" + node->get_name() + "'"); + void VariableMapper::processLocationNode(xmlpp::Node const* locationNode) { + const xmlpp::Element* location = dynamic_cast<const xmlpp::Element*>(locationNode); + if(!location) { + throw std::invalid_argument("Error parsing xml file in location node."); } - } -} - -/********************************************************************************************************************/ - -std::string determineName(const xmlpp::Element *property, std::string source) { - const xmlpp::Attribute *nameAttribute = property->get_attribute("name"); - // if a name is given in xml take it - if (nameAttribute) { - return nameAttribute->get_value(); - } else { // auto-determine the name from the source - ///@todo FIXME: use register path to do the slash and replace fiddeling - std::string name; - if (source[0] == '/') { - name = source.substr(1); - } else { - name = source; - } - // replace / with . in name - return std::regex_replace(name, std::regex("/"), "."); - } -} + std::string locationName = getAttributeValue(location, "name"); -/********************************************************************************************************************/ + for(auto const& node : location->get_children()) { + if(nodeIsWhitespace(node)) continue; + if(dynamic_cast<xmlpp::CommentNode const*>(node)) continue; -std::string getAbsoluteSource(std::string source, std::string locationName) { - if (source[0] == '/') { - return source; - } else { - return std::string("/") + locationName + "/" + source; - } -} - -/********************************************************************************************************************/ - -template <class PROPERTY_DESCRIPTION_TYPE> -void VariableMapper::processHistoryAndWritableAttributes( - PROPERTY_DESCRIPTION_TYPE propertyDescription, - const xmlpp::Element *propertyXmlElement, std::string locationName) { - auto hasHistoryNodes = propertyXmlElement->get_children("has_history"); - if (!hasHistoryNodes.empty()) { - propertyDescription->hasHistory = - evaluateBool(getContentString(hasHistoryNodes.front())); - } else { - propertyDescription->hasHistory = getHasHistoryDefault(locationName); + if(node->get_name() == "property") { + processPropertyNode(node, locationName); + } + else if(node->get_name() == "import") { + processImportNode(node, locationName); + } + else if(node->get_name() == "has_history") { + auto& locationInfo = _locationDefaults[locationName]; + locationInfo.useHasHistoryDefault = true; + locationInfo.hasHistory = evaluateBool(getContentString(node)); + } + else if(node->get_name() == "is_writeable") { + auto& locationInfo = _locationDefaults[locationName]; + locationInfo.useIsWriteableDefault = true; + locationInfo.isWriteable = evaluateBool(getContentString(node)); + } + else if(node->get_name() == "macro_pulse_number_source") { + auto& locationInfo = _locationDefaults[locationName]; + locationInfo.useMacroPulseNumberSourceDefault = true; + locationInfo.macroPulseNumberSource = getContentString(node); + } + else if(node->get_name() == "D_spectrum") { + processSpectrumNode(node, locationName); + } + else if(node->get_name() == "D_array") { + processArrayNode(node, locationName); + } + else { + throw std::invalid_argument(std::string("Error parsing xml file in location ") + locationName + + ": Unknown node '" + node->get_name() + "'"); + } + } } - auto isWriteableNodes = propertyXmlElement->get_children("is_writeable"); - if (!isWriteableNodes.empty()) { - propertyDescription->isWriteable = - evaluateBool(getContentString(isWriteableNodes.front())); - } else { - propertyDescription->isWriteable = getIsWriteableDefault(locationName); + /********************************************************************************************************************/ + + std::string determineName(const xmlpp::Element* property, std::string source) { + const xmlpp::Attribute* nameAttribute = property->get_attribute("name"); + // if a name is given in xml take it + if(nameAttribute) { + return nameAttribute->get_value(); + } + else { // auto-determine the name from the source + ///@todo FIXME: use register path to do the slash and replace fiddeling + std::string name; + if(source[0] == '/') { + name = source.substr(1); + } + else { + name = source; + } + // replace / with . in name + return std::regex_replace(name, std::regex("/"), "."); + } } - auto publishZeroMQ = propertyXmlElement->get_children("publish_ZMQ"); - if (!publishZeroMQ.empty()) { - propertyDescription->publishZMQ = - evaluateBool(getContentString(publishZeroMQ.front())); - } else { - propertyDescription->publishZMQ = false; + /********************************************************************************************************************/ + + std::string getAbsoluteSource(std::string source, std::string locationName) { + if(source[0] == '/') { + return source; + } + else { + return std::string("/") + locationName + "/" + source; + } } - auto macroPulseNumberSource = - propertyXmlElement->get_children("macro_pulse_number_source"); - if (!macroPulseNumberSource.empty()) { - propertyDescription->macroPulseNumberSource = - getContentString(macroPulseNumberSource.front()); - } else { - propertyDescription->macroPulseNumberSource = - getMacroPusleNumberSourceDefault(locationName); + /********************************************************************************************************************/ + + template<class PROPERTY_DESCRIPTION_TYPE> + void VariableMapper::processHistoryAndWritableAttributes(PROPERTY_DESCRIPTION_TYPE propertyDescription, + const xmlpp::Element* propertyXmlElement, std::string locationName) { + auto hasHistoryNodes = propertyXmlElement->get_children("has_history"); + if(!hasHistoryNodes.empty()) { + propertyDescription->hasHistory = evaluateBool(getContentString(hasHistoryNodes.front())); + } + else { + propertyDescription->hasHistory = getHasHistoryDefault(locationName); + } + + auto isWriteableNodes = propertyXmlElement->get_children("is_writeable"); + if(!isWriteableNodes.empty()) { + propertyDescription->isWriteable = evaluateBool(getContentString(isWriteableNodes.front())); + } + else { + propertyDescription->isWriteable = getIsWriteableDefault(locationName); + } + + auto publishZeroMQ = propertyXmlElement->get_children("publish_ZMQ"); + if(!publishZeroMQ.empty()) { + propertyDescription->publishZMQ = evaluateBool(getContentString(publishZeroMQ.front())); + } + else { + propertyDescription->publishZMQ = false; + } + + auto macroPulseNumberSource = propertyXmlElement->get_children("macro_pulse_number_source"); + if(!macroPulseNumberSource.empty()) { + propertyDescription->macroPulseNumberSource = getContentString(macroPulseNumberSource.front()); + } + else { + propertyDescription->macroPulseNumberSource = getMacroPusleNumberSourceDefault(locationName); + } } -} -/********************************************************************************************************************/ + /********************************************************************************************************************/ -void VariableMapper::addDescription( - std::shared_ptr<PropertyDescription> const &propertyDescription, - std::list<std::string> const &absoluteSources) { - _descriptions.push_back(propertyDescription); - for (auto &source : absoluteSources) { - _usedInputVariables.insert(source); + void VariableMapper::addDescription(std::shared_ptr<PropertyDescription> const& propertyDescription, + std::list<std::string> const& absoluteSources) { + _descriptions.push_back(propertyDescription); + for(auto& source : absoluteSources) { + _usedInputVariables.insert(source); + } } -} -/********************************************************************************************************************/ + /********************************************************************************************************************/ -xmlpp::Element const *asXmlElement(xmlpp::Node const *node) { - const xmlpp::Element *element = dynamic_cast<const xmlpp::Element *>(node); - if (!element) { - throw std::invalid_argument( - "Error parsing xml file: Node is not an element node: " + - node->get_name()); + xmlpp::Element const* asXmlElement(xmlpp::Node const* node) { + const xmlpp::Element* element = dynamic_cast<const xmlpp::Element*>(node); + if(!element) { + throw std::invalid_argument("Error parsing xml file: Node is not an element node: " + node->get_name()); + } + return element; } - return element; -} -/********************************************************************************************************************/ + /********************************************************************************************************************/ -void VariableMapper::processPropertyNode(xmlpp::Node const *propertyNode, - std::string locationName) { - auto property = asXmlElement(propertyNode); + void VariableMapper::processPropertyNode(xmlpp::Node const* propertyNode, std::string locationName) { + auto property = asXmlElement(propertyNode); - std::string source = getAttributeValue(property, "source"); - std::string name = determineName(property, source); - std::string absoluteSource = getAbsoluteSource(source, locationName); + std::string source = getAttributeValue(property, "source"); + std::string name = determineName(property, source); + std::string absoluteSource = getAbsoluteSource(source, locationName); - // prepare the property description - auto autoPropertyDescription = std::make_shared<AutoPropertyDescription>( - absoluteSource, locationName, name); + // prepare the property description + auto autoPropertyDescription = std::make_shared<AutoPropertyDescription>(absoluteSource, locationName, name); - processHistoryAndWritableAttributes(autoPropertyDescription, property, - locationName); + processHistoryAndWritableAttributes(autoPropertyDescription, property, locationName); - addDescription(autoPropertyDescription, {absoluteSource}); -} + addDescription(autoPropertyDescription, {absoluteSource}); + } -/********************************************************************************************************************/ + /********************************************************************************************************************/ -void VariableMapper::processSpectrumNode(xmlpp::Node const *node, - std::string locationName) { - auto spectrumXml = asXmlElement(node); + void VariableMapper::processSpectrumNode(xmlpp::Node const* node, std::string locationName) { + auto spectrumXml = asXmlElement(node); - // the "main source" of a spectum - std::string source = getAttributeValue(spectrumXml, "source"); - std::string name = determineName(spectrumXml, source); - std::string absoluteSource = getAbsoluteSource(source, locationName); + // the "main source" of a spectum + std::string source = getAttributeValue(spectrumXml, "source"); + std::string name = determineName(spectrumXml, source); + std::string absoluteSource = getAbsoluteSource(source, locationName); - // prepare the property description - auto spectrumDescription = - std::make_shared<SpectrumDescription>(absoluteSource, locationName, name); + // prepare the property description + auto spectrumDescription = std::make_shared<SpectrumDescription>(absoluteSource, locationName, name); - processHistoryAndWritableAttributes(spectrumDescription, spectrumXml, - locationName); + processHistoryAndWritableAttributes(spectrumDescription, spectrumXml, locationName); - auto startNodes = spectrumXml->get_children("start"); - if (!startNodes.empty()) { - spectrumDescription->start = - std::stof(getContentString(startNodes.front())); - } - std::list<std::string> usedVariables({absoluteSource}); - auto incrementNodes = spectrumXml->get_children("increment"); - if (!incrementNodes.empty()) { - spectrumDescription->increment = - std::stof(getContentString(incrementNodes.front())); - } - auto startSourceNodes = spectrumXml->get_children("startSource"); - if (!startSourceNodes.empty()) { - auto startSource = getContentString(startSourceNodes.front()); - spectrumDescription->startSource = startSource; - usedVariables.push_back(startSource); - } - auto incrementSourceNodes = spectrumXml->get_children("incrementSource"); - if (!incrementSourceNodes.empty()) { - auto incrementSource = getContentString(incrementSourceNodes.front()); - spectrumDescription->incrementSource = incrementSource; - usedVariables.push_back(incrementSource); - } + auto startNodes = spectrumXml->get_children("start"); + if(!startNodes.empty()) { + spectrumDescription->start = std::stof(getContentString(startNodes.front())); + } + std::list<std::string> usedVariables({absoluteSource}); + auto incrementNodes = spectrumXml->get_children("increment"); + if(!incrementNodes.empty()) { + spectrumDescription->increment = std::stof(getContentString(incrementNodes.front())); + } + auto startSourceNodes = spectrumXml->get_children("startSource"); + if(!startSourceNodes.empty()) { + auto startSource = getContentString(startSourceNodes.front()); + spectrumDescription->startSource = startSource; + usedVariables.push_back(startSource); + } + auto incrementSourceNodes = spectrumXml->get_children("incrementSource"); + if(!incrementSourceNodes.empty()) { + auto incrementSource = getContentString(incrementSourceNodes.front()); + spectrumDescription->incrementSource = incrementSource; + usedVariables.push_back(incrementSource); + } - addDescription(spectrumDescription, usedVariables); -} - -/********************************************************************************************************************/ - -void VariableMapper::processArrayNode(xmlpp::Node const *node, - std::string locationName) { - auto arrayXml = asXmlElement(node); - - // the "main source" of a spectum - std::string source = getAttributeValue(arrayXml, "source"); - std::string name = determineName(arrayXml, source); - - const xmlpp::Attribute *typeAttribute = arrayXml->get_attribute("type"); - std::map<std::string, ArrayDescription::DataType> dataTypeMap( - {{"auto", ArrayDescription::DataType::Auto}, - {"byte", ArrayDescription::DataType::Byte}, - {"short", ArrayDescription::DataType::Short}, - {"int", ArrayDescription::DataType::Int}, - {"long", ArrayDescription::DataType::Long}, - {"float", ArrayDescription::DataType::Float}, - {"double", ArrayDescription::DataType::Double}}); - - ArrayDescription::DataType type; - if (typeAttribute) { - type = dataTypeMap[typeAttribute->get_value()]; - } else { - type = ArrayDescription::DataType::Auto; + addDescription(spectrumDescription, usedVariables); } - std::string absoluteSource = getAbsoluteSource(source, locationName); + /********************************************************************************************************************/ - // prepare the property description - auto arrayDescription = std::make_shared<ArrayDescription>( - absoluteSource, locationName, name, type); + void VariableMapper::processArrayNode(xmlpp::Node const* node, std::string locationName) { + auto arrayXml = asXmlElement(node); - processHistoryAndWritableAttributes(arrayDescription, arrayXml, locationName); + // the "main source" of a spectum + std::string source = getAttributeValue(arrayXml, "source"); + std::string name = determineName(arrayXml, source); - addDescription(arrayDescription, {absoluteSource}); -} + const xmlpp::Attribute* typeAttribute = arrayXml->get_attribute("type"); + std::map<std::string, ArrayDescription::DataType> dataTypeMap({{"auto", ArrayDescription::DataType::Auto}, + {"byte", ArrayDescription::DataType::Byte}, {"short", ArrayDescription::DataType::Short}, + {"int", ArrayDescription::DataType::Int}, {"long", ArrayDescription::DataType::Long}, + {"float", ArrayDescription::DataType::Float}, {"double", ArrayDescription::DataType::Double}}); -/********************************************************************************************************************/ - -void VariableMapper::processImportNode(xmlpp::Node const *importNode, - std::string importLocationName) { - const xmlpp::Element *importElement = - dynamic_cast<const xmlpp::Element *>(importNode); - std::string directory; - if (importElement) { - // look for a directory attribute - const xmlpp::Attribute *directoryAttribute = - importElement->get_attribute("directory"); - if (directoryAttribute) { - directory = directoryAttribute->get_value(); + ArrayDescription::DataType type; + if(typeAttribute) { + type = dataTypeMap[typeAttribute->get_value()]; } - } + else { + type = ArrayDescription::DataType::Auto; + } + + std::string absoluteSource = getAbsoluteSource(source, locationName); - for (auto const &node : importNode->get_children()) { - const xmlpp::TextNode *nodeAsText = - dynamic_cast<const xmlpp::TextNode *>(node); - std::string importSource = nodeAsText->get_content(); - import(importSource, importLocationName, directory); + // prepare the property description + auto arrayDescription = std::make_shared<ArrayDescription>(absoluteSource, locationName, name, type); + + processHistoryAndWritableAttributes(arrayDescription, arrayXml, locationName); + + addDescription(arrayDescription, {absoluteSource}); } -} -/********************************************************************************************************************/ + /********************************************************************************************************************/ -void VariableMapper::import(std::string importSource, - std::string importLocationName, - std::string directory) { - // a slash will be added after the source, so we make the source empty for an - // import of everything - if (importSource == "/") { - importSource = ""; + void VariableMapper::processImportNode(xmlpp::Node const* importNode, std::string importLocationName) { + const xmlpp::Element* importElement = dynamic_cast<const xmlpp::Element*>(importNode); + std::string directory; + if(importElement) { + // look for a directory attribute + const xmlpp::Attribute* directoryAttribute = importElement->get_attribute("directory"); + if(directoryAttribute) { + directory = directoryAttribute->get_value(); + } + } + + for(auto const& node : importNode->get_children()) { + const xmlpp::TextNode* nodeAsText = dynamic_cast<const xmlpp::TextNode*>(node); + std::string importSource = nodeAsText->get_content(); + import(importSource, importLocationName, directory); + } } - // loop source tree, cut beginning, replace / with _ and add a property - for (auto const &processVariable : _inputVariables) { - if (_usedInputVariables.find(processVariable) != - _usedInputVariables.end()) { - continue; - } - - if (processVariable.find(importSource + "/") == 0) { - // processVariable starts with wanted source - auto nameSource = processVariable.substr( - importSource.size() + 1); // add the slash to be removed - // we use the register path because it removes duplicate separators and - // allows to use . as separater to replace all / with . - ChimeraTK::RegisterPath propertyName; - std::string locationName; - if (importLocationName.empty()) { - // a global import, try to get the location name from the source - auto locationAndPropertyName = splitStringAtFirstSlash(nameSource); - locationName = locationAndPropertyName.first; - propertyName = locationAndPropertyName.second; - if (locationName.empty()) { - throw std::logic_error( - std::string("Invalid XML content in global import of ") + - (importSource.empty() ? "/" : importSource) + - ": Cannot create location name from '" + nameSource + - "', one hirarchy level is missing."); + /********************************************************************************************************************/ + + void VariableMapper::import(std::string importSource, std::string importLocationName, std::string directory) { + // a slash will be added after the source, so we make the source empty for an + // import of everything + if(importSource == "/") { + importSource = ""; + } + + // loop source tree, cut beginning, replace / with _ and add a property + for(auto const& processVariable : _inputVariables) { + if(_usedInputVariables.find(processVariable) != _usedInputVariables.end()) { + continue; + } + + if(processVariable.find(importSource + "/") == 0) { + // processVariable starts with wanted source + auto nameSource = processVariable.substr(importSource.size() + 1); // add the slash to be removed + // we use the register path because it removes duplicate separators and + // allows to use . as separater to replace all / with . + ChimeraTK::RegisterPath propertyName; + std::string locationName; + if(importLocationName.empty()) { + // a global import, try to get the location name from the source + auto locationAndPropertyName = splitStringAtFirstSlash(nameSource); + locationName = locationAndPropertyName.first; + propertyName = locationAndPropertyName.second; + if(locationName.empty()) { + throw std::logic_error(std::string("Invalid XML content in global import of ") + + (importSource.empty() ? "/" : importSource) + ": Cannot create location name from '" + nameSource + + "', one hirarchy level is missing."); + } + // convenience for the user: You get an error message is you try a + // global import with directory (in case you did not validate your xml + // against the schema). + if(!directory.empty()) { + throw std::logic_error(std::string("Invalid XML content in global import of ") + + (importSource.empty() ? "/" : importSource) + ": You cannot have a directory in a global import."); + } } - // convenience for the user: You get an error message is you try a - // global import with directory (in case you did not validate your xml - // against the schema). - if (!directory.empty()) { - throw std::logic_error( - std::string("Invalid XML content in global import of ") + - (importSource.empty() ? "/" : importSource) + - ": You cannot have a directory in a global import."); + else { + // import into a location, we know the location name. + // add the directory first, then add the name source property + propertyName /= directory; + propertyName /= nameSource; + locationName = importLocationName; } - } else { - // import into a location, we know the location name. - // add the directory first, then add the name source property - propertyName /= directory; - propertyName /= nameSource; - locationName = importLocationName; - } - // get the property name with . instead of / - propertyName.setAltSeparator("."); - auto autoPropertyDescription = std::make_shared<AutoPropertyDescription>( - processVariable, locationName, propertyName.getWithAltSeparator()); + // get the property name with . instead of / + propertyName.setAltSeparator("."); + auto autoPropertyDescription = std::make_shared<AutoPropertyDescription>( + processVariable, locationName, propertyName.getWithAltSeparator()); - // we are importing, so all properties get the intended defaults (not - // individual settings) - autoPropertyDescription->hasHistory = getHasHistoryDefault(locationName); - autoPropertyDescription->isWriteable = - getIsWriteableDefault(locationName); - autoPropertyDescription->macroPulseNumberSource = - getMacroPusleNumberSourceDefault(locationName); + // we are importing, so all properties get the intended defaults (not + // individual settings) + autoPropertyDescription->hasHistory = getHasHistoryDefault(locationName); + autoPropertyDescription->isWriteable = getIsWriteableDefault(locationName); + autoPropertyDescription->macroPulseNumberSource = getMacroPusleNumberSourceDefault(locationName); - addDescription(autoPropertyDescription, {processVariable}); + addDescription(autoPropertyDescription, {processVariable}); + } } } -} -/********************************************************************************************************************/ + /********************************************************************************************************************/ -void VariableMapper::prepareOutput(std::string xmlFile, - std::set<std::string> inputVariables) { - clear(); - _inputVariables = inputVariables; + void VariableMapper::prepareOutput(std::string xmlFile, std::set<std::string> inputVariables) { + clear(); + _inputVariables = inputVariables; - xmlpp::DomParser parser; - // parser.set_validate(); - parser.set_substitute_entities(); // We just want the text to be - // resolved/unescaped automatically. - parser.parse_file(xmlFile); + xmlpp::DomParser parser; + // parser.set_validate(); + parser.set_substitute_entities(); // We just want the text to be + // resolved/unescaped automatically. + parser.parse_file(xmlFile); - if (parser) { - // Walk the tree: - const xmlpp::Node *rootNode = - parser.get_document()->get_root_node(); // deleted by DomParser. + if(parser) { + // Walk the tree: + const xmlpp::Node* rootNode = parser.get_document()->get_root_node(); // deleted by DomParser. - for (auto const &mainNode : rootNode->get_children()) { - if (nodeIsWhitespace(mainNode)) - continue; - if (dynamic_cast<xmlpp::CommentNode const *>(mainNode)) - continue; + for(auto const& mainNode : rootNode->get_children()) { + if(nodeIsWhitespace(mainNode)) continue; + if(dynamic_cast<xmlpp::CommentNode const*>(mainNode)) continue; - if (mainNode->get_name() == "location") { - processLocationNode(mainNode); - } else if (mainNode->get_name() == "import") { - processImportNode(mainNode); - } else if (mainNode->get_name() == "has_history") { - _globalDefaults.hasHistory = evaluateBool(getContentString(mainNode)); - } else if (mainNode->get_name() == "is_writeable") { - _globalDefaults.isWriteable = evaluateBool(getContentString(mainNode)); - } else if (mainNode->get_name() == "macro_pulse_number_source") { - _globalDefaults.macroPulseNumberSource = getContentString(mainNode); - } else { - throw std::invalid_argument(std::string("Error parsing xml file ") + - xmlFile + ": Unknown node '" + - mainNode->get_name() + "'"); + if(mainNode->get_name() == "location") { + processLocationNode(mainNode); + } + else if(mainNode->get_name() == "import") { + processImportNode(mainNode); + } + else if(mainNode->get_name() == "has_history") { + _globalDefaults.hasHistory = evaluateBool(getContentString(mainNode)); + } + else if(mainNode->get_name() == "is_writeable") { + _globalDefaults.isWriteable = evaluateBool(getContentString(mainNode)); + } + else if(mainNode->get_name() == "macro_pulse_number_source") { + _globalDefaults.macroPulseNumberSource = getContentString(mainNode); + } + else { + throw std::invalid_argument( + std::string("Error parsing xml file ") + xmlFile + ": Unknown node '" + mainNode->get_name() + "'"); + } } } - } else { - throw std::invalid_argument(std::string("Error parsing xml file ") + - xmlFile + ". No document produced."); + else { + throw std::invalid_argument(std::string("Error parsing xml file ") + xmlFile + ". No document produced."); + } } -} -/********************************************************************************************************************/ + /********************************************************************************************************************/ -std::list<std::shared_ptr<PropertyDescription>> const & -VariableMapper::getAllProperties() const { - return _descriptions; -} + std::list<std::shared_ptr<PropertyDescription>> const& VariableMapper::getAllProperties() const { + return _descriptions; + } -/********************************************************************************************************************/ + /********************************************************************************************************************/ -std::list<std::shared_ptr<PropertyDescription>> -VariableMapper::getPropertiesInLocation(std::string location) const { - std::list<std::shared_ptr<PropertyDescription>> output; + std::list<std::shared_ptr<PropertyDescription>> VariableMapper::getPropertiesInLocation(std::string location) const { + std::list<std::shared_ptr<PropertyDescription>> output; - for (auto const &variable : _descriptions) { - if (variable->location == location) { - (void)output.push_back(variable); + for(auto const& variable : _descriptions) { + if(variable->location == location) { + (void)output.push_back(variable); + } } + return output; } - return output; -} - -/********************************************************************************************************************/ - -void VariableMapper::directImport(std::set<std::string> inputVariables) { - clear(); - _inputVariables = inputVariables; - import( - "/", - ""); // import from /, create location names from first level of the tree -} - -/********************************************************************************************************************/ - -void VariableMapper::clear() { - _inputVariables.clear(); - _usedInputVariables.clear(); - _locationDefaults.clear(); - _globalDefaults = PropertyAttributes(); - _descriptions.clear(); -} - -/********************************************************************************************************************/ - -/// printing the map is useful for debugging -void VariableMapper::print(std::ostream &os) const { - os << "====== VariableMapper =====" << std::endl; - for (auto &description : _descriptions) { - description->print(os); + + /********************************************************************************************************************/ + + void VariableMapper::directImport(std::set<std::string> inputVariables) { + clear(); + _inputVariables = inputVariables; + import("/", + ""); // import from /, create location names from first level of the tree } - os << "======= Mapping End =======" << std::endl; -} -/********************************************************************************************************************/ + /********************************************************************************************************************/ -bool VariableMapper::evaluateBool(std::string txt) { - transform(txt.begin(), txt.end(), txt.begin(), ::tolower); - if (txt == "false" or txt == "0") { - return false; - } else if (txt == "true" or txt == "1") { - return true; - } else { - throw std::invalid_argument( - std::string("Error parsing xml file: could not convert to bool: ") + - txt); + void VariableMapper::clear() { + _inputVariables.clear(); + _usedInputVariables.clear(); + _locationDefaults.clear(); + _globalDefaults = PropertyAttributes(); + _descriptions.clear(); } -} -/********************************************************************************************************************/ + /********************************************************************************************************************/ -std::string VariableMapper::getContentString(xmlpp::Node const *node) { - for (auto const &subNode : node->get_children()) { - const xmlpp::TextNode *nodeAsText = - dynamic_cast<const xmlpp::TextNode *>(subNode); - if (nodeAsText) { - if (nodeAsText->is_white_space()) { - continue; + /// printing the map is useful for debugging + void VariableMapper::print(std::ostream& os) const { + os << "====== VariableMapper =====" << std::endl; + for(auto& description : _descriptions) { + description->print(os); + } + os << "======= Mapping End =======" << std::endl; + } + + /********************************************************************************************************************/ + + bool VariableMapper::evaluateBool(std::string txt) { + transform(txt.begin(), txt.end(), txt.begin(), ::tolower); + if(txt == "false" or txt == "0") { + return false; + } + else if(txt == "true" or txt == "1") { + return true; + } + else { + throw std::invalid_argument(std::string("Error parsing xml file: could not convert to bool: ") + txt); + } + } + + /********************************************************************************************************************/ + + std::string VariableMapper::getContentString(xmlpp::Node const* node) { + for(auto const& subNode : node->get_children()) { + const xmlpp::TextNode* nodeAsText = dynamic_cast<const xmlpp::TextNode*>(subNode); + if(nodeAsText) { + if(nodeAsText->is_white_space()) { + continue; + } + return nodeAsText->get_content(); } - return nodeAsText->get_content(); } + throw std::invalid_argument( + std::string("Error parsing xml file: node ") + node->get_name() + " does not have text nodes as children."); } - throw std::invalid_argument(std::string("Error parsing xml file: node ") + - node->get_name() + - " does not have text nodes as children."); -} - -/********************************************************************************************************************/ - -bool VariableMapper::getHasHistoryDefault(std::string const &locationName) { - // if there is no default setting for the location, we will get the "default - // default" which has useHasHistoryDefault disabled which is auto-generated by - // the [] operator - auto locationInfo = _locationDefaults[locationName]; - if (locationInfo.useHasHistoryDefault) { - return locationInfo.hasHistory; - } else { - return _globalDefaults.hasHistory; + + /********************************************************************************************************************/ + + bool VariableMapper::getHasHistoryDefault(std::string const& locationName) { + // if there is no default setting for the location, we will get the "default + // default" which has useHasHistoryDefault disabled which is auto-generated by + // the [] operator + auto locationInfo = _locationDefaults[locationName]; + if(locationInfo.useHasHistoryDefault) { + return locationInfo.hasHistory; + } + else { + return _globalDefaults.hasHistory; + } } -} - -/********************************************************************************************************************/ - -bool VariableMapper::getIsWriteableDefault(std::string const &locationName) { - // if there is no default setting for the location, we will get the "default - // default" which has useIsWriteableDefault disabled which is auto-generated - // by the [] operator - auto locationInfo = _locationDefaults[locationName]; - if (locationInfo.useIsWriteableDefault) { - return locationInfo.isWriteable; - } else { - return _globalDefaults.isWriteable; + + /********************************************************************************************************************/ + + bool VariableMapper::getIsWriteableDefault(std::string const& locationName) { + // if there is no default setting for the location, we will get the "default + // default" which has useIsWriteableDefault disabled which is auto-generated + // by the [] operator + auto locationInfo = _locationDefaults[locationName]; + if(locationInfo.useIsWriteableDefault) { + return locationInfo.isWriteable; + } + else { + return _globalDefaults.isWriteable; + } } -} - -/********************************************************************************************************************/ - -std::string VariableMapper::getMacroPusleNumberSourceDefault( - std::string const &locationName) { - // if there is no default setting for the location, we will get the "default - // default" which has useMacroPulseNumberSourceDefault disabled which is - // auto-generated by the [] operator - auto locationInfo = _locationDefaults[locationName]; - if (locationInfo.useMacroPulseNumberSourceDefault) { - return locationInfo.macroPulseNumberSource; - } else { - return _globalDefaults.macroPulseNumberSource; + + /********************************************************************************************************************/ + + std::string VariableMapper::getMacroPusleNumberSourceDefault(std::string const& locationName) { + // if there is no default setting for the location, we will get the "default + // default" which has useMacroPulseNumberSourceDefault disabled which is + // auto-generated by the [] operator + auto locationInfo = _locationDefaults[locationName]; + if(locationInfo.useMacroPulseNumberSourceDefault) { + return locationInfo.macroPulseNumberSource; + } + else { + return _globalDefaults.macroPulseNumberSource; + } } -} - -/********************************************************************************************************************/ - -std::string -VariableMapper::getAttributeValue(const xmlpp::Element *node, - std::string const &attributeName) { - auto attribute = node->get_attribute(attributeName); - if (!attribute) { - throw std::invalid_argument("Error parsing xml file. Attribute '" + - attributeName + "' not found in node '" + - node->get_name() + "'."); + + /********************************************************************************************************************/ + + std::string VariableMapper::getAttributeValue(const xmlpp::Element* node, std::string const& attributeName) { + auto attribute = node->get_attribute(attributeName); + if(!attribute) { + throw std::invalid_argument( + "Error parsing xml file. Attribute '" + attributeName + "' not found in node '" + node->get_name() + "'."); + } + return attribute->get_value(); } - return attribute->get_value(); -} } // namespace ChimeraTK diff --git a/src/eq_create.cc b/src/eq_create.cc index 49534cdb8ead456079a2ecfe4187744a62aead3a..862506795c1d3307ef40ee2f379805029d0245e1 100644 --- a/src/eq_create.cc +++ b/src/eq_create.cc @@ -5,8 +5,8 @@ #include "getAllVariableNames.h" #include <sys/stat.h> -char const *object_name; -static char const *XML_CONFIG_SUFFIX = "-DoocsVariableConfig.xml"; +char const* object_name; +static char const* XML_CONFIG_SUFFIX = "-DoocsVariableConfig.xml"; static ChimeraTK::DoocsAdapter doocsAdapter; @@ -18,22 +18,19 @@ void eq_init_prolog() { object_name = ChimeraTK::ApplicationBase::getInstance().getName().c_str(); // Create static instances for all applications cores. They must not have // overlapping process variable names ("location/protery" must be unique). - ChimeraTK::ApplicationBase::getInstance().setPVManager( - doocsAdapter.getDevicePVManager()); + ChimeraTK::ApplicationBase::getInstance().setPVManager(doocsAdapter.getDevicePVManager()); ChimeraTK::ApplicationBase::getInstance().initialise(); // the variable manager can only be filled after we have the CS manager - auto pvNames = - ChimeraTK::getAllVariableNames(doocsAdapter.getControlSystemPVManager()); + auto pvNames = ChimeraTK::getAllVariableNames(doocsAdapter.getControlSystemPVManager()); - auto xmlFileName = - ChimeraTK::ApplicationBase::getInstance().getName() + XML_CONFIG_SUFFIX; + auto xmlFileName = ChimeraTK::ApplicationBase::getInstance().getName() + XML_CONFIG_SUFFIX; struct stat buffer; - if (stat(xmlFileName.c_str(), &buffer) == 0) { - ChimeraTK::VariableMapper::getInstance().prepareOutput(xmlFileName, - pvNames); - } else { + if(stat(xmlFileName.c_str(), &buffer) == 0) { + ChimeraTK::VariableMapper::getInstance().prepareOutput(xmlFileName, pvNames); + } + else { std::cerr << "WARNING: No XML file for the Doocs variable config found. " "Trying direct import." << std::endl; @@ -46,9 +43,8 @@ void eq_init_prolog() { /* eq_create returns a ControlSystemAdapter-based location for any location type */ -EqFct *eq_create(int eq_code, void *) { - return new ChimeraTK::CSAdapterEqFct( - eq_code, doocsAdapter.getControlSystemPVManager(), doocsAdapter.updater); +EqFct* eq_create(int eq_code, void*) { + return new ChimeraTK::CSAdapterEqFct(eq_code, doocsAdapter.getControlSystemPVManager(), doocsAdapter.updater); } /* post_init_epilog is called after all DOOCS properties are fully intialised, diff --git a/src/getAllVariableNames.cc b/src/getAllVariableNames.cc index d8ba1dad426d55da8f341f996aa6399e11b2074f..43d8bb491dd52e91caea7a6390b991ad8dee445d 100644 --- a/src/getAllVariableNames.cc +++ b/src/getAllVariableNames.cc @@ -2,14 +2,13 @@ namespace ChimeraTK { -std::set<std::string> -getAllVariableNames(boost::shared_ptr<ControlSystemPVManager> csManager) { - std::set<std::string> output; - for (auto &pv : csManager->getAllProcessVariables()) { - output.insert(pv->getName()); - } + std::set<std::string> getAllVariableNames(boost::shared_ptr<ControlSystemPVManager> csManager) { + std::set<std::string> output; + for(auto& pv : csManager->getAllProcessVariables()) { + output.insert(pv->getName()); + } - return output; -} + return output; + } } // namespace ChimeraTK diff --git a/tests/include/DOOCSProcessVariableAdapter_testCases_numericals.hpp b/tests/include/DOOCSProcessVariableAdapter_testCases_numericals.hpp index 025d98ec74a447d18c48cdd5398a981ef67f6ac8..ef33572160c8bccafcfd79fde67f07703014e123 100644 --- a/tests/include/DOOCSProcessVariableAdapter_testCases_numericals.hpp +++ b/tests/include/DOOCSProcessVariableAdapter_testCases_numericals.hpp @@ -6,8 +6,7 @@ using namespace boost::unit_test; // for int, double, float -BOOST_FIXTURE_TEST_SUITE( - test_operation, +BOOST_FIXTURE_TEST_SUITE(test_operation, CallbacksTestFixture) // operation check: return values matter BOOST_AUTO_TEST_CASE(test_getset_nocb) { @@ -36,13 +35,11 @@ BOOST_AUTO_TEST_CASE(test_getset_cb) { doocs_adapter->set(1); BOOST_CHECK(doocs_adapter->get() == 1); - doocs_adapter->setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + doocs_adapter->setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); doocs_adapter->set(2); BOOST_CHECK(doocs_adapter->get() == 2); - doocs_adapter->setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + doocs_adapter->setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); doocs_adapter->set(3); BOOST_CHECK(doocs_adapter->get() == 0); // <--- @@ -56,13 +53,11 @@ BOOST_AUTO_TEST_CASE(test_getwcsetwc_cb) { doocs_adapter->setWithoutCallback(1); BOOST_CHECK(doocs_adapter->getWithoutCallback() == 1); - doocs_adapter->setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + doocs_adapter->setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); doocs_adapter->setWithoutCallback(2); BOOST_CHECK(doocs_adapter->getWithoutCallback() == 2); - doocs_adapter->setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + doocs_adapter->setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); doocs_adapter->setWithoutCallback(3); BOOST_CHECK(doocs_adapter->getWithoutCallback() == 3); // <--- @@ -74,8 +69,7 @@ BOOST_AUTO_TEST_SUITE_END() // ============================================================================ -BOOST_FIXTURE_TEST_SUITE( - test_callbacks, +BOOST_FIXTURE_TEST_SUITE(test_callbacks, CallbacksTestFixture) // callback arbitrarily present: callback counters // matter, return values don't @@ -85,8 +79,7 @@ BOOST_AUTO_TEST_CASE(test_get_cb_count) { doocs_adapter->get(); BOOST_CHECK(_get_cb_counter == 0); - doocs_adapter->setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + doocs_adapter->setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); doocs_adapter->get(); BOOST_CHECK(_get_cb_counter == 1); @@ -100,8 +93,7 @@ BOOST_AUTO_TEST_CASE(test_get_cb_count) { doocs_adapter->get(); BOOST_CHECK(_get_cb_counter == 2); - doocs_adapter->setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + doocs_adapter->setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); doocs_adapter->get(); BOOST_CHECK(_get_cb_counter == 3); @@ -128,8 +120,7 @@ BOOST_AUTO_TEST_CASE(test_set_cb_count) { BOOST_CHECK(_set_cb_counter == 0); BOOST_CHECK(_set_cb_counter_equals == 0); - doocs_adapter->setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + doocs_adapter->setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); doocs_adapter->set(1); BOOST_CHECK(_set_cb_counter == 1); @@ -149,8 +140,7 @@ BOOST_AUTO_TEST_CASE(test_set_cb_count) { BOOST_CHECK(_set_cb_counter == 2); BOOST_CHECK(_set_cb_counter_equals == 2); - doocs_adapter->setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + doocs_adapter->setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); doocs_adapter->set(2); BOOST_CHECK(_set_cb_counter == 3); @@ -175,8 +165,7 @@ BOOST_AUTO_TEST_SUITE_END() // ============================================================================ -BOOST_FIXTURE_TEST_SUITE( - test_no_callbacks, +BOOST_FIXTURE_TEST_SUITE(test_no_callbacks, CallbacksTestFixture) // callback arbitrarily present: callback counters // matter, return values don't @@ -186,8 +175,7 @@ BOOST_AUTO_TEST_CASE(test_get_nocb_count) { doocs_adapter->getWithoutCallback(); BOOST_CHECK(_get_cb_counter == 0); - doocs_adapter->setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + doocs_adapter->setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); doocs_adapter->getWithoutCallback(); BOOST_CHECK(_get_cb_counter == 0); @@ -197,8 +185,7 @@ BOOST_AUTO_TEST_CASE(test_get_nocb_count) { doocs_adapter->getWithoutCallback(); BOOST_CHECK(_get_cb_counter == 0); - doocs_adapter->setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + doocs_adapter->setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); doocs_adapter->getWithoutCallback(); BOOST_CHECK(_get_cb_counter == 0); @@ -221,8 +208,7 @@ BOOST_AUTO_TEST_CASE(test_set_nocb_count) { BOOST_CHECK(_set_cb_counter == 0); BOOST_CHECK(_set_cb_counter_equals == 0); - doocs_adapter->setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + doocs_adapter->setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); doocs_adapter->setWithoutCallback(1); BOOST_CHECK(_set_cb_counter == 0); @@ -242,8 +228,7 @@ BOOST_AUTO_TEST_CASE(test_set_nocb_count) { BOOST_CHECK(_set_cb_counter == 0); BOOST_CHECK(_set_cb_counter_equals == 0); - doocs_adapter->setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + doocs_adapter->setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); doocs_adapter->setWithoutCallback(1); BOOST_CHECK(_set_cb_counter == 0); @@ -303,14 +288,11 @@ BOOST_AUTO_TEST_CASE(set_from_other_pv__callbacks_operation) { BOOST_CHECK(_get_cb_counter2 == 0); BOOST_CHECK(_set_cb_counter2 == 0); - doocs_adapter1->setOnSetCallbackFunction(boost::bind( - &InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks - doocs_adapter1->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback1, this)); - doocs_adapter2->setOnSetCallbackFunction( - boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); - doocs_adapter2->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback2, this)); + doocs_adapter1->setOnSetCallbackFunction( + boost::bind(&InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks + doocs_adapter1->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback1, this)); + doocs_adapter2->setOnSetCallbackFunction(boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); + doocs_adapter2->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback2, this)); // -- when -- doocs_adapter2->set(*doocs_adapter1); @@ -325,8 +307,7 @@ BOOST_AUTO_TEST_CASE(set_from_other_pv__callbacks_operation) { BOOST_CHECK(_set_cb_counter2 == 2); } -BOOST_AUTO_TEST_CASE( - set_from_other_pv__callbacks_assignment) // or rather for no assignment +BOOST_AUTO_TEST_CASE(set_from_other_pv__callbacks_assignment) // or rather for no assignment { // -- given -- doocs_adapter1->clearOnGetCallbackFunction(); // make sure no callbacks @@ -342,14 +323,11 @@ BOOST_AUTO_TEST_CASE( BOOST_CHECK(_get_cb_counter2 == 0); BOOST_CHECK(_set_cb_counter2 == 0); - doocs_adapter1->setOnSetCallbackFunction(boost::bind( - &InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks - doocs_adapter1->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback1, this)); - doocs_adapter2->setOnSetCallbackFunction( - boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); - doocs_adapter2->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback2, this)); + doocs_adapter1->setOnSetCallbackFunction( + boost::bind(&InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks + doocs_adapter1->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback1, this)); + doocs_adapter2->setOnSetCallbackFunction(boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); + doocs_adapter2->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback2, this)); doocs_adapter1->set(1); // do some random get/set() ... doocs_adapter1->setWithoutCallback(1); @@ -360,8 +338,7 @@ BOOST_AUTO_TEST_CASE( doocs_adapter2->get(); doocs_adapter2->getWithoutCallback(); - BOOST_CHECK(_get_cb_counter1 == - 1); // ... and check the callback operation so far + BOOST_CHECK(_get_cb_counter1 == 1); // ... and check the callback operation so far BOOST_CHECK(_set_cb_counter1 == 1); BOOST_CHECK(_get_cb_counter2 == 2); BOOST_CHECK(_set_cb_counter2 == 2); @@ -385,8 +362,7 @@ BOOST_AUTO_TEST_CASE( doocs_adapter2->get(); doocs_adapter2->getWithoutCallback(); - BOOST_CHECK(_get_cb_counter1 == - 2); // ... and make sure the callback assignment remains unaltered + BOOST_CHECK(_get_cb_counter1 == 2); // ... and make sure the callback assignment remains unaltered BOOST_CHECK(_set_cb_counter1 == 2); BOOST_CHECK(_get_cb_counter2 == 4); BOOST_CHECK(_set_cb_counter2 == 6); @@ -429,14 +405,11 @@ BOOST_AUTO_TEST_CASE(setWithoutCallback_from_other_pv__callbacks_operation) { BOOST_CHECK(_get_cb_counter2 == 0); BOOST_CHECK(_set_cb_counter2 == 0); - doocs_adapter1->setOnSetCallbackFunction(boost::bind( - &InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks - doocs_adapter1->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback1, this)); - doocs_adapter2->setOnSetCallbackFunction( - boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); - doocs_adapter2->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback2, this)); + doocs_adapter1->setOnSetCallbackFunction( + boost::bind(&InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks + doocs_adapter1->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback1, this)); + doocs_adapter2->setOnSetCallbackFunction(boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); + doocs_adapter2->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback2, this)); // -- when -- doocs_adapter2->setWithoutCallback(*doocs_adapter1); @@ -451,9 +424,8 @@ BOOST_AUTO_TEST_CASE(setWithoutCallback_from_other_pv__callbacks_operation) { BOOST_CHECK(_set_cb_counter2 == 0); } -BOOST_AUTO_TEST_CASE( - setWithoutCallback_from_other_pv__callbacks_assignment) // or rather for no - // assignment +BOOST_AUTO_TEST_CASE(setWithoutCallback_from_other_pv__callbacks_assignment) // or rather for no + // assignment { // -- given -- doocs_adapter1->clearOnGetCallbackFunction(); // make sure no callbacks @@ -469,14 +441,11 @@ BOOST_AUTO_TEST_CASE( BOOST_CHECK(_get_cb_counter2 == 0); BOOST_CHECK(_set_cb_counter2 == 0); - doocs_adapter1->setOnSetCallbackFunction(boost::bind( - &InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks - doocs_adapter1->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback1, this)); - doocs_adapter2->setOnSetCallbackFunction( - boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); - doocs_adapter2->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback2, this)); + doocs_adapter1->setOnSetCallbackFunction( + boost::bind(&InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks + doocs_adapter1->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback1, this)); + doocs_adapter2->setOnSetCallbackFunction(boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); + doocs_adapter2->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback2, this)); doocs_adapter1->set(1); // do some random get/set() ... doocs_adapter1->setWithoutCallback(1); @@ -487,8 +456,7 @@ BOOST_AUTO_TEST_CASE( doocs_adapter2->get(); doocs_adapter2->getWithoutCallback(); - BOOST_CHECK(_get_cb_counter1 == - 1); // ... and check the callback operation so far + BOOST_CHECK(_get_cb_counter1 == 1); // ... and check the callback operation so far BOOST_CHECK(_set_cb_counter1 == 1); BOOST_CHECK(_get_cb_counter2 == 2); BOOST_CHECK(_set_cb_counter2 == 2); @@ -511,8 +479,7 @@ BOOST_AUTO_TEST_CASE( doocs_adapter2->get(); doocs_adapter2->getWithoutCallback(); - BOOST_CHECK(_get_cb_counter1 == - 2); // ... and make sure the callback assignment remains unaltered + BOOST_CHECK(_get_cb_counter1 == 2); // ... and make sure the callback assignment remains unaltered BOOST_CHECK(_set_cb_counter1 == 2); BOOST_CHECK(_get_cb_counter2 == 4); BOOST_CHECK(_set_cb_counter2 == 4); @@ -555,14 +522,11 @@ BOOST_AUTO_TEST_CASE(assign_from_other_pv__callbacks_operation) { BOOST_CHECK(_get_cb_counter2 == 0); BOOST_CHECK(_set_cb_counter2 == 0); - doocs_adapter1->setOnSetCallbackFunction(boost::bind( - &InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks - doocs_adapter1->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback1, this)); - doocs_adapter2->setOnSetCallbackFunction( - boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); - doocs_adapter2->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback2, this)); + doocs_adapter1->setOnSetCallbackFunction( + boost::bind(&InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks + doocs_adapter1->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback1, this)); + doocs_adapter2->setOnSetCallbackFunction(boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); + doocs_adapter2->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback2, this)); // -- when -- *doocs_adapter2 = *doocs_adapter1; @@ -577,8 +541,7 @@ BOOST_AUTO_TEST_CASE(assign_from_other_pv__callbacks_operation) { BOOST_CHECK(_set_cb_counter2 == 0); } -BOOST_AUTO_TEST_CASE( - assign_from_other_pv__callbacks_assignment) // or rather for no assignment +BOOST_AUTO_TEST_CASE(assign_from_other_pv__callbacks_assignment) // or rather for no assignment { // -- given -- doocs_adapter1->clearOnGetCallbackFunction(); // make sure no callbacks @@ -594,14 +557,11 @@ BOOST_AUTO_TEST_CASE( BOOST_CHECK(_get_cb_counter2 == 0); BOOST_CHECK(_set_cb_counter2 == 0); - doocs_adapter1->setOnSetCallbackFunction(boost::bind( - &InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks - doocs_adapter1->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback1, this)); - doocs_adapter2->setOnSetCallbackFunction( - boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); - doocs_adapter2->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback2, this)); + doocs_adapter1->setOnSetCallbackFunction( + boost::bind(&InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks + doocs_adapter1->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback1, this)); + doocs_adapter2->setOnSetCallbackFunction(boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); + doocs_adapter2->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback2, this)); doocs_adapter1->set(1); // do some random get/set() ... doocs_adapter1->setWithoutCallback(1); @@ -612,8 +572,7 @@ BOOST_AUTO_TEST_CASE( doocs_adapter2->get(); doocs_adapter2->getWithoutCallback(); - BOOST_CHECK(_get_cb_counter1 == - 1); // ... and check the callback operation so far + BOOST_CHECK(_get_cb_counter1 == 1); // ... and check the callback operation so far BOOST_CHECK(_set_cb_counter1 == 1); BOOST_CHECK(_get_cb_counter2 == 2); BOOST_CHECK(_set_cb_counter2 == 2); @@ -636,8 +595,7 @@ BOOST_AUTO_TEST_CASE( doocs_adapter2->get(); doocs_adapter2->getWithoutCallback(); - BOOST_CHECK(_get_cb_counter1 == - 2); // ... and make sure the callback assignment remains unaltered + BOOST_CHECK(_get_cb_counter1 == 2); // ... and make sure the callback assignment remains unaltered BOOST_CHECK(_set_cb_counter1 == 2); BOOST_CHECK(_get_cb_counter2 == 4); BOOST_CHECK(_set_cb_counter2 == 4); @@ -672,10 +630,9 @@ BOOST_AUTO_TEST_CASE(assign_from_primtype__callbacks_operation) { BOOST_CHECK(_get_cb_counter2 == 0); BOOST_CHECK(_set_cb_counter2 == 0); - doocs_adapter2->setOnSetCallbackFunction(boost::bind( - &InterPVTestFixture::on_set_callback2, this, _1, _2)); // prime callbacks - doocs_adapter2->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback2, this)); + doocs_adapter2->setOnSetCallbackFunction( + boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); // prime callbacks + doocs_adapter2->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback2, this)); // -- when -- *doocs_adapter2 = 5; @@ -687,8 +644,7 @@ BOOST_AUTO_TEST_CASE(assign_from_primtype__callbacks_operation) { BOOST_CHECK(_set_cb_counter2 == 0); } -BOOST_AUTO_TEST_CASE( - assign_from_primtype__callbacks_assignment) // or rather for no assignment +BOOST_AUTO_TEST_CASE(assign_from_primtype__callbacks_assignment) // or rather for no assignment { // -- given -- doocs_adapter2->clearOnGetCallbackFunction(); // make sure no callbacks @@ -699,18 +655,16 @@ BOOST_AUTO_TEST_CASE( BOOST_CHECK(_get_cb_counter2 == 0); BOOST_CHECK(_set_cb_counter2 == 0); - doocs_adapter2->setOnSetCallbackFunction(boost::bind( - &InterPVTestFixture::on_set_callback2, this, _1, _2)); // prime callbacks - doocs_adapter2->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback2, this)); + doocs_adapter2->setOnSetCallbackFunction( + boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); // prime callbacks + doocs_adapter2->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback2, this)); doocs_adapter2->set(1); // do some random get/set() ... doocs_adapter2->setWithoutCallback(1); doocs_adapter2->get(); doocs_adapter2->getWithoutCallback(); - BOOST_CHECK(_get_cb_counter2 == - 2); // ... and check the callback operation so far + BOOST_CHECK(_get_cb_counter2 == 2); // ... and check the callback operation so far BOOST_CHECK(_set_cb_counter2 == 2); // -- when -- @@ -725,8 +679,7 @@ BOOST_AUTO_TEST_CASE( doocs_adapter2->get(); doocs_adapter2->getWithoutCallback(); - BOOST_CHECK(_get_cb_counter2 == - 4); // ... and make sure the callback assignment remains unaltered + BOOST_CHECK(_get_cb_counter2 == 4); // ... and make sure the callback assignment remains unaltered BOOST_CHECK(_set_cb_counter2 == 4); } @@ -779,14 +732,11 @@ BOOST_AUTO_TEST_CASE(conversion__callbacks_operation) { BOOST_CHECK(_get_cb_counter2 == 0); BOOST_CHECK(_set_cb_counter2 == 0); - doocs_adapter1->setOnSetCallbackFunction(boost::bind( - &InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks - doocs_adapter1->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback1, this)); - doocs_adapter2->setOnSetCallbackFunction( - boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); - doocs_adapter2->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback2, this)); + doocs_adapter1->setOnSetCallbackFunction( + boost::bind(&InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks + doocs_adapter1->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback1, this)); + doocs_adapter2->setOnSetCallbackFunction(boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); + doocs_adapter2->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback2, this)); // -- when -- double val = *doocs_adapter1; @@ -807,8 +757,7 @@ BOOST_AUTO_TEST_CASE(conversion__callbacks_operation) { BOOST_CHECK(_set_cb_counter2 == 0); } -BOOST_AUTO_TEST_CASE( - conversion__callbacks_assignment) // or rather for no assignment +BOOST_AUTO_TEST_CASE(conversion__callbacks_assignment) // or rather for no assignment { // -- given -- doocs_adapter1->clearOnGetCallbackFunction(); // make sure no callbacks @@ -824,14 +773,11 @@ BOOST_AUTO_TEST_CASE( BOOST_CHECK(_get_cb_counter2 == 0); BOOST_CHECK(_set_cb_counter2 == 0); - doocs_adapter1->setOnSetCallbackFunction(boost::bind( - &InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks - doocs_adapter1->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback1, this)); - doocs_adapter2->setOnSetCallbackFunction( - boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); - doocs_adapter2->setOnGetCallbackFunction( - boost::bind(&InterPVTestFixture::on_get_callback2, this)); + doocs_adapter1->setOnSetCallbackFunction( + boost::bind(&InterPVTestFixture::on_set_callback1, this, _1, _2)); // prime callbacks + doocs_adapter1->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback1, this)); + doocs_adapter2->setOnSetCallbackFunction(boost::bind(&InterPVTestFixture::on_set_callback2, this, _1, _2)); + doocs_adapter2->setOnGetCallbackFunction(boost::bind(&InterPVTestFixture::on_get_callback2, this)); doocs_adapter1->set(1); // do some random get/set() ... doocs_adapter1->setWithoutCallback(1); @@ -842,8 +788,7 @@ BOOST_AUTO_TEST_CASE( doocs_adapter2->get(); doocs_adapter2->getWithoutCallback(); - BOOST_CHECK(_get_cb_counter1 == - 1); // ... and check the callback operation so far + BOOST_CHECK(_get_cb_counter1 == 1); // ... and check the callback operation so far BOOST_CHECK(_set_cb_counter1 == 1); BOOST_CHECK(_get_cb_counter2 == 2); BOOST_CHECK(_set_cb_counter2 == 2); @@ -872,8 +817,7 @@ BOOST_AUTO_TEST_CASE( doocs_adapter2->get(); doocs_adapter2->getWithoutCallback(); - BOOST_CHECK(_get_cb_counter1 == - 2); // ... and make sure the callback assignment remains unaltered + BOOST_CHECK(_get_cb_counter1 == 2); // ... and make sure the callback assignment remains unaltered BOOST_CHECK(_set_cb_counter1 == 2); BOOST_CHECK(_get_cb_counter2 == 4); BOOST_CHECK(_set_cb_counter2 == 4); diff --git a/tests/include/emptyServerFunctions.h b/tests/include/emptyServerFunctions.h index a22c9fdd050df608805ed3bec0beeda4f5313bf1..93b6932e111a571903fa9f54bc341c56d5067fb6 100644 --- a/tests/include/emptyServerFunctions.h +++ b/tests/include/emptyServerFunctions.h @@ -13,8 +13,10 @@ // LCOV_EXCL_START -const char *object_name = "empty"; -EqFct *eq_create(int /*eq_code*/, void *) { return NULL; } +const char* object_name = "empty"; +EqFct* eq_create(int /*eq_code*/, void*) { + return NULL; +} void eq_init_epilog() {} void eq_init_prolog() {} void refresh_epilog() {} diff --git a/tests/include/m4uD_array_testCases_numericals.hpp b/tests/include/m4uD_array_testCases_numericals.hpp index b570a4dde65088a65ea073e94534f93bb4508e67..0a166c6d54075641f7af36bf1eb2848125dde95c 100644 --- a/tests/include/m4uD_array_testCases_numericals.hpp +++ b/tests/include/m4uD_array_testCases_numericals.hpp @@ -6,44 +6,41 @@ using namespace boost::unit_test; // for: int, double, float -BOOST_FIXTURE_TEST_SUITE( - test_operation, +BOOST_FIXTURE_TEST_SUITE(test_operation, CallbacksTestFixture) // operation check: return values matter -BOOST_AUTO_TEST_CASE(test_length) { BOOST_CHECK_EQUAL(mydarray.length(), 4); } +BOOST_AUTO_TEST_CASE(test_length) { + BOOST_CHECK_EQUAL(mydarray.length(), 4); +} BOOST_AUTO_TEST_CASE(test_getset_nocb) { // vec_test = [0,0,0,0] vec_test.assign(4, 0.0); - const TypedVector &vec_mydarray = mydarray.getspectrum(*pa); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray.begin(), vec_mydarray.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray = mydarray.getspectrum(*pa); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray.begin(), vec_mydarray.end(), vec_test.begin(), vec_test.end()); // vec_test = [1,1,1,1] vec_test.assign(4, 1.0); mydarray.setspectrum(vec_test, *pa); - const TypedVector &vec_mydarray1 = mydarray.getspectrum(*pa); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray1.begin(), vec_mydarray1.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray1 = mydarray.getspectrum(*pa); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray1.begin(), vec_mydarray1.end(), vec_test.begin(), vec_test.end()); } BOOST_AUTO_TEST_CASE(test_getwcsetwc_nocb) { // vec_test = [0,0,0,0] vec_test.assign(4, 0.0); - const TypedVector &vec_mydarray = mydarray.getspectrum_without_callback(); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray.begin(), vec_mydarray.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray = mydarray.getspectrum_without_callback(); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray.begin(), vec_mydarray.end(), vec_test.begin(), vec_test.end()); // vec_test = [1,1,1,1] vec_test.assign(4, 1.0); mydarray.setspectrum_without_callback(vec_test); - const TypedVector &vec_mydarray1 = mydarray.getspectrum_without_callback(); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray1.begin(), vec_mydarray1.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray1 = mydarray.getspectrum_without_callback(); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray1.begin(), vec_mydarray1.end(), vec_test.begin(), vec_test.end()); } BOOST_AUTO_TEST_CASE(test_randomaccess) // a "random access" @@ -63,79 +60,67 @@ BOOST_AUTO_TEST_CASE(test_getset_cb) { // vec_test = [0,0,0,0] vec_test.assign(4, 0.0); - const TypedVector &vec_mydarray = mydarray.getspectrum(*pa); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray.begin(), vec_mydarray.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray = mydarray.getspectrum(*pa); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray.begin(), vec_mydarray.end(), vec_test.begin(), vec_test.end()); // vec_test = [1,1,1,1] vec_test.assign(4, 1.0); mydarray.setspectrum(vec_test, *pa); - const TypedVector &vec_mydarray1 = mydarray.getspectrum(*pa); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray1.begin(), vec_mydarray1.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray1 = mydarray.getspectrum(*pa); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray1.begin(), vec_mydarray1.end(), vec_test.begin(), vec_test.end()); - mydarray.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); + mydarray.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); // vec_test = [2,2,2,2], then [5,2,2,2] vec_test.assign(4, 2.0); mydarray.setspectrum(vec_test, *pa); vec_test[0] = 5; // vec_test[3] = 6; - const TypedVector &vec_mydarray2 = mydarray.getspectrum(*pa); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray2.begin(), vec_mydarray2.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray2 = mydarray.getspectrum(*pa); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray2.begin(), vec_mydarray2.end(), vec_test.begin(), vec_test.end()); - mydarray.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); + mydarray.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); // vec_test = [3,3,3,3], then [5,3,3,6] vec_test.assign(4, 3.0); mydarray.setspectrum(vec_test, *pa); vec_test[0] = 5; vec_test[3] = 6; - const TypedVector &vec_mydarray3 = mydarray.getspectrum(*pa); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray3.begin(), vec_mydarray3.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray3 = mydarray.getspectrum(*pa); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray3.begin(), vec_mydarray3.end(), vec_test.begin(), vec_test.end()); } BOOST_AUTO_TEST_CASE(test_getwcsetwc_cb) { // vec_test = [0,0,0,0] vec_test.assign(4, 0.0); - const TypedVector &vec_mydarray = mydarray.getspectrum_without_callback(); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray.begin(), vec_mydarray.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray = mydarray.getspectrum_without_callback(); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray.begin(), vec_mydarray.end(), vec_test.begin(), vec_test.end()); // vec_test = [1,1,1,1] vec_test.assign(4, 1.0); mydarray.setspectrum_without_callback(vec_test); - const TypedVector &vec_mydarray1 = mydarray.getspectrum_without_callback(); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray1.begin(), vec_mydarray1.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray1 = mydarray.getspectrum_without_callback(); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray1.begin(), vec_mydarray1.end(), vec_test.begin(), vec_test.end()); - mydarray.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); + mydarray.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); // vec_test = [2,2,2,2] vec_test.assign(4, 2.0); mydarray.setspectrum_without_callback(vec_test); // vec_test[0] = 5;// vec_test[3] = 6; - const TypedVector &vec_mydarray2 = mydarray.getspectrum_without_callback(); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray2.begin(), vec_mydarray2.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray2 = mydarray.getspectrum_without_callback(); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray2.begin(), vec_mydarray2.end(), vec_test.begin(), vec_test.end()); - mydarray.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); + mydarray.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); // vec_test = [3,3,3,3] vec_test.assign(4, 3.0); mydarray.setspectrum_without_callback(vec_test); // vec_test[0] = 5; vec_test[3] = 6; - const TypedVector &vec_mydarray3 = mydarray.getspectrum_without_callback(); - BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray3.begin(), vec_mydarray3.end(), - vec_test.begin(), vec_test.end()); + const TypedVector& vec_mydarray3 = mydarray.getspectrum_without_callback(); + BOOST_CHECK_EQUAL_COLLECTIONS(vec_mydarray3.begin(), vec_mydarray3.end(), vec_test.begin(), vec_test.end()); } BOOST_AUTO_TEST_CASE(test_cachesync) { @@ -144,7 +129,7 @@ BOOST_AUTO_TEST_CASE(test_cachesync) { mydarray.getspectrum(*pa); BOOST_CHECK_EQUAL(mydarray.__is_cache_synced_flag(), true); BOOST_CHECK_EQUAL(mydarray.__is_cache_synced_vect(), - true); // D_spectrum has 0's after creation + true); // D_spectrum has 0's after creation // vec_test = [0,0,0,0] vec_test.assign(4, 0.0); @@ -302,8 +287,7 @@ BOOST_CHECK_EQUAL(mydarray.__is_cache_synced_vect(), true); BOOST_AUTO_TEST_CASE(test_fill) { mydarray.fill(30); - for (int i = 0; i < mydarray.length(); ++i) - BOOST_CHECK_EQUAL(mydarray.read_spectrum(i), 30); + for(int i = 0; i < mydarray.length(); ++i) BOOST_CHECK_EQUAL(mydarray.read_spectrum(i), 30); } BOOST_AUTO_TEST_CASE(test_fillvector) { @@ -314,16 +298,14 @@ BOOST_AUTO_TEST_CASE(test_fillvector) { TypedVector v(4); mydarray.fillVector(v); - BOOST_CHECK_EQUAL_COLLECTIONS(v.begin(), v.end(), vec_test.begin(), - vec_test.end()); + BOOST_CHECK_EQUAL_COLLECTIONS(v.begin(), v.end(), vec_test.begin(), vec_test.end()); } BOOST_AUTO_TEST_SUITE_END() // ============================================================================ -BOOST_FIXTURE_TEST_SUITE( - test_callbacks, +BOOST_FIXTURE_TEST_SUITE(test_callbacks, CallbacksTestFixture) // callback arbitrarily present: callback counters // matter, return values don't @@ -333,8 +315,7 @@ BOOST_AUTO_TEST_CASE(test_get_cb_count) { mydarray.getspectrum(*pa); BOOST_CHECK(_get_cb_counter == 0); - mydarray.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); + mydarray.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); mydarray.getspectrum(*pa); BOOST_CHECK(_get_cb_counter == 1); @@ -348,8 +329,7 @@ BOOST_AUTO_TEST_CASE(test_get_cb_count) { mydarray.getspectrum(*pa); BOOST_CHECK(_get_cb_counter == 2); - mydarray.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); + mydarray.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); mydarray.getspectrum(*pa); BOOST_CHECK(_get_cb_counter == 3); @@ -376,8 +356,7 @@ BOOST_AUTO_TEST_CASE(test_set_cb_count) { mydarray.setspectrum(vec_test, *pa); BOOST_CHECK(_set_cb_counter == 0); - mydarray.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); + mydarray.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); mydarray.setspectrum(vec_test, *pa); BOOST_CHECK(_set_cb_counter == 1); @@ -393,8 +372,7 @@ BOOST_AUTO_TEST_CASE(test_set_cb_count) { mydarray.setspectrum(vec_test, *pa); BOOST_CHECK(_set_cb_counter == 2); - mydarray.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); + mydarray.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); mydarray.setspectrum(vec_test, *pa); BOOST_CHECK(_set_cb_counter == 3); @@ -412,8 +390,7 @@ BOOST_AUTO_TEST_SUITE_END() // ============================================================================ -BOOST_FIXTURE_TEST_SUITE( - test_no_callbacks, +BOOST_FIXTURE_TEST_SUITE(test_no_callbacks, CallbacksTestFixture) // callback absent: callback counters matter, return // values don't @@ -423,8 +400,7 @@ BOOST_AUTO_TEST_CASE(test_get_nocb_count) { mydarray.getspectrum_without_callback(); BOOST_CHECK(_get_cb_counter == 0); - mydarray.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); + mydarray.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); mydarray.getspectrum_without_callback(); BOOST_CHECK(_get_cb_counter == 0); @@ -438,8 +414,7 @@ BOOST_AUTO_TEST_CASE(test_get_nocb_count) { mydarray.getspectrum_without_callback(); BOOST_CHECK(_get_cb_counter == 0); - mydarray.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); + mydarray.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this, _1)); mydarray.getspectrum_without_callback(); BOOST_CHECK(_get_cb_counter == 0); @@ -466,8 +441,7 @@ BOOST_AUTO_TEST_CASE(test_set_nocb_count) { mydarray.setspectrum_without_callback(vec_test); BOOST_CHECK(_set_cb_counter == 0); - mydarray.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); + mydarray.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); mydarray.setspectrum_without_callback(vec_test); BOOST_CHECK(_set_cb_counter == 0); @@ -483,8 +457,7 @@ BOOST_AUTO_TEST_CASE(test_set_nocb_count) { mydarray.setspectrum_without_callback(vec_test); BOOST_CHECK(_set_cb_counter == 0); - mydarray.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); + mydarray.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1)); mydarray.setspectrum_without_callback(vec_test); BOOST_CHECK(_set_cb_counter == 0); diff --git a/tests/include/m4uD_type_testCases_numericals.hpp b/tests/include/m4uD_type_testCases_numericals.hpp index 307bd72d25a508fb7a2821729cc9067c6c5373cd..7c8f7ad193f80a921e950d98644f179a108090d7 100644 --- a/tests/include/m4uD_type_testCases_numericals.hpp +++ b/tests/include/m4uD_type_testCases_numericals.hpp @@ -6,8 +6,7 @@ using namespace boost::unit_test; // for: int, double, float -BOOST_FIXTURE_TEST_SUITE( - test_operation, +BOOST_FIXTURE_TEST_SUITE(test_operation, CallbacksTestFixture) // operation check: return values matter BOOST_AUTO_TEST_CASE(test_getset_nocb) { @@ -48,13 +47,11 @@ BOOST_AUTO_TEST_CASE(test_getset_cb) { mydtype.setval(1); BOOST_CHECK(mydtype.getval() == 1); // <--- - mydtype.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + mydtype.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); mydtype.setval(2); BOOST_CHECK(mydtype.getval() == 2); // <--- - mydtype.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + mydtype.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); mydtype.setval(3); BOOST_CHECK(mydtype.getval() == 0); // <--- @@ -68,13 +65,11 @@ BOOST_AUTO_TEST_CASE(test_getwcsetwc_cb) { mydtype.setval_without_callback(1); BOOST_CHECK(mydtype.getval_without_callback() == 1); // <--- - mydtype.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + mydtype.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); mydtype.setval_without_callback(2); BOOST_CHECK(mydtype.getval_without_callback() == 2); // <--- - mydtype.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + mydtype.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); mydtype.setval_without_callback(3); BOOST_CHECK(mydtype.getval_without_callback() == 3); // <--- @@ -86,8 +81,7 @@ BOOST_AUTO_TEST_SUITE_END() // ============================================================================ -BOOST_FIXTURE_TEST_SUITE( - test_callbacks, +BOOST_FIXTURE_TEST_SUITE(test_callbacks, CallbacksTestFixture) // callback arbitrarily present: callback counters // matter, return values don't @@ -97,8 +91,7 @@ BOOST_AUTO_TEST_CASE(test_get_cb_count) { mydtype.getval(); BOOST_CHECK(_get_cb_counter == 0); - mydtype.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + mydtype.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); mydtype.getval(); BOOST_CHECK(_get_cb_counter == 1); @@ -112,8 +105,7 @@ BOOST_AUTO_TEST_CASE(test_get_cb_count) { mydtype.getval(); BOOST_CHECK(_get_cb_counter == 2); - mydtype.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + mydtype.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); mydtype.getval(); BOOST_CHECK(_get_cb_counter == 3); @@ -140,8 +132,7 @@ BOOST_AUTO_TEST_CASE(test_set_cb_count) { BOOST_CHECK(_set_cb_counter == 0); BOOST_CHECK(_set_cb_counter_equals == 0); - mydtype.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + mydtype.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); mydtype.setval(1); BOOST_CHECK(_set_cb_counter == 1); @@ -161,8 +152,7 @@ BOOST_AUTO_TEST_CASE(test_set_cb_count) { BOOST_CHECK(_set_cb_counter == 2); BOOST_CHECK(_set_cb_counter_equals == 2); - mydtype.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + mydtype.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); mydtype.setval(1); BOOST_CHECK(_set_cb_counter == 3); @@ -183,8 +173,7 @@ BOOST_AUTO_TEST_CASE(test_set_cb_equals_count) { BOOST_CHECK(_set_cb_counter == 0); BOOST_CHECK(_set_cb_counter_equals == 0); - mydtype.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + mydtype.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); mydtype.setval(1); BOOST_CHECK(_set_cb_counter == 1); @@ -202,8 +191,7 @@ BOOST_AUTO_TEST_SUITE_END() // ============================================================================ -BOOST_FIXTURE_TEST_SUITE( - test_no_callbacks, +BOOST_FIXTURE_TEST_SUITE(test_no_callbacks, CallbacksTestFixture) // callback absent: callback counters matter, return // values don't @@ -213,8 +201,7 @@ BOOST_AUTO_TEST_CASE(test_get_nocb_count) { mydtype.getval_without_callback(); BOOST_CHECK(_get_cb_counter == 0); - mydtype.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + mydtype.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); mydtype.getval_without_callback(); BOOST_CHECK(_get_cb_counter == 0); @@ -224,8 +211,7 @@ BOOST_AUTO_TEST_CASE(test_get_nocb_count) { mydtype.getval_without_callback(); BOOST_CHECK(_get_cb_counter == 0); - mydtype.setOnGetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_get_callback, this)); + mydtype.setOnGetCallbackFunction(boost::bind(&CallbacksTestFixture::on_get_callback, this)); mydtype.getval_without_callback(); BOOST_CHECK(_get_cb_counter == 0); @@ -248,8 +234,7 @@ BOOST_AUTO_TEST_CASE(test_set_nocb_count) { BOOST_CHECK(_set_cb_counter == 0); BOOST_CHECK(_set_cb_counter_equals == 0); - mydtype.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + mydtype.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); mydtype.setval_without_callback(1); BOOST_CHECK(_set_cb_counter == 0); @@ -269,8 +254,7 @@ BOOST_AUTO_TEST_CASE(test_set_nocb_count) { BOOST_CHECK(_set_cb_counter == 0); BOOST_CHECK(_set_cb_counter_equals == 0); - mydtype.setOnSetCallbackFunction( - boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); + mydtype.setOnSetCallbackFunction(boost::bind(&CallbacksTestFixture::on_set_callback, this, _1, _2)); mydtype.setval_without_callback(1); BOOST_CHECK(_set_cb_counter == 0); diff --git a/tests/include/serverBasedTestTools.h b/tests/include/serverBasedTestTools.h index 1565317c07f540e4f1389b1215fe96a769971845..0cd4c2401d26de6e57dc4cccad6ce3232de63388 100644 --- a/tests/include/serverBasedTestTools.h +++ b/tests/include/serverBasedTestTools.h @@ -9,33 +9,37 @@ static const int ACCESS_RO = 0; // read only static const int ACCESS_RW = 1; // read/write -template <class DOOCS_T> -void checkHistory(DOOCS_T *property, bool expected_has_history) { +template<class DOOCS_T> +void checkHistory(DOOCS_T* property, bool expected_has_history) { bool has_history = property->get_histPointer(); BOOST_CHECK_MESSAGE(has_history == expected_has_history, - "History on/off wrong for " + property->basename() + - ". Should be " + - (expected_has_history ? "true" : "false")); + "History on/off wrong for " + property->basename() + ". Should be " + (expected_has_history ? "true" : "false")); } -template <> void checkHistory(D_spectrum * /*property*/, bool) { +template<> +void checkHistory(D_spectrum* /*property*/, bool) { /// @todo FIXME implement check on D_spectrum history/ ring buffer } // there are no histories for arrays. Do nothing -template <> void checkHistory(D_bytearray * /*property*/, bool) {} -template <> void checkHistory(D_shortarray * /*property*/, bool) {} -template <> void checkHistory(D_intarray * /*property*/, bool) {} -template <> void checkHistory(D_longarray * /*property*/, bool) {} -template <> void checkHistory(D_floatarray * /*property*/, bool) {} -template <> void checkHistory(D_doublearray * /*property*/, bool) {} - -EqFct *getLocationFromPropertyAddress(std::string const &propertyAddress) { +template<> +void checkHistory(D_bytearray* /*property*/, bool) {} +template<> +void checkHistory(D_shortarray* /*property*/, bool) {} +template<> +void checkHistory(D_intarray* /*property*/, bool) {} +template<> +void checkHistory(D_longarray* /*property*/, bool) {} +template<> +void checkHistory(D_floatarray* /*property*/, bool) {} +template<> +void checkHistory(D_doublearray* /*property*/, bool) {} + +EqFct* getLocationFromPropertyAddress(std::string const& propertyAddress) { EqAdr ad; // obtain location pointer ad.adr(propertyAddress.c_str()); - EqFct *eqFct = eq_get(&ad); - BOOST_REQUIRE_MESSAGE(eqFct, "Could not get location for property " + - propertyAddress); + EqFct* eqFct = eq_get(&ad); + BOOST_REQUIRE_MESSAGE(eqFct, "Could not get location for property " + propertyAddress); return eqFct; } @@ -43,22 +47,21 @@ EqFct *getLocationFromPropertyAddress(std::string const &propertyAddress) { /// Used internally. /// ATTENTION: DOES NOT LOCK THE LOCATION. DO THIS MANUALLY BEFORE GETTING THE /// PROPERTY! -template <class DOOCS_T> -DOOCS_T *getDoocsProperty(std::string const &propertyAddress) { +template<class DOOCS_T> +DOOCS_T* getDoocsProperty(std::string const& propertyAddress) { auto eqFct = getLocationFromPropertyAddress(propertyAddress); auto propertyName = ChimeraTK::basenameFromAddress(propertyAddress); - auto property = dynamic_cast<DOOCS_T *>(eqFct->find_property(propertyName)); - BOOST_REQUIRE_MESSAGE(property, "Could not find property address " - << propertyAddress - << "), or property has unexpected type."); + auto property = dynamic_cast<DOOCS_T*>(eqFct->find_property(propertyName)); + BOOST_REQUIRE_MESSAGE( + property, "Could not find property address " << propertyAddress << "), or property has unexpected type."); return property; } -template <class DOOCS_T> -void checkDoocsProperty(std::string const &propertyAddress, - bool expected_has_history = true, - bool expected_is_writeable = true) { +template<class DOOCS_T> +void checkDoocsProperty(std::string const& propertyAddress, + bool expected_has_history = true, + bool expected_is_writeable = true) { auto location = getLocationFromPropertyAddress(propertyAddress); location->lock(); @@ -67,14 +70,12 @@ void checkDoocsProperty(std::string const &propertyAddress, checkHistory(property, expected_has_history); std::stringstream errorMessage; - errorMessage << "Access rights not correct for '" << propertyAddress - << "': access word is " << property->get_access() - << ", expected " - << (expected_is_writeable ? ACCESS_RW : ACCESS_RO); - if (expected_is_writeable) { - BOOST_CHECK_MESSAGE(property->get_access() == ACCESS_RW, - errorMessage.str()); - } else { + errorMessage << "Access rights not correct for '" << propertyAddress << "': access word is " << property->get_access() + << ", expected " << (expected_is_writeable ? ACCESS_RW : ACCESS_RO); + if(expected_is_writeable) { + BOOST_CHECK_MESSAGE(property->get_access() == ACCESS_RW, errorMessage.str()); + } + else { BOOST_CHECK(property->get_access() == ACCESS_RO); } @@ -83,7 +84,7 @@ void checkDoocsProperty(std::string const &propertyAddress, // this function does the locking so it can be used in a loop and frees the lock // in between. -float readSpectrumStart(std::string const &propertyAddress) { +float readSpectrumStart(std::string const& propertyAddress) { auto location = getLocationFromPropertyAddress(propertyAddress); location->lock(); @@ -97,7 +98,7 @@ float readSpectrumStart(std::string const &propertyAddress) { // sorry for copying the code. It really sucks to wrap 10 lines of bloat around // 1 line of content. -float readSpectrumIncrement(std::string const &propertyAddress) { +float readSpectrumIncrement(std::string const& propertyAddress) { auto location = getLocationFromPropertyAddress(propertyAddress); location->lock(); @@ -123,41 +124,37 @@ float readSpectrumIncrement(std::string const &propertyAddress) { // // -void checkDataType(std::string const &propertyAddress, int dataType) { +void checkDataType(std::string const& propertyAddress, int dataType) { auto location = getLocationFromPropertyAddress(propertyAddress); - BOOST_REQUIRE_MESSAGE(location, - "could not find location for " + propertyAddress); + BOOST_REQUIRE_MESSAGE(location, "could not find location for " + propertyAddress); location->lock(); auto property = getDoocsProperty<D_fct>(propertyAddress); - BOOST_REQUIRE_MESSAGE(property, - "could not find property for " + propertyAddress); + BOOST_REQUIRE_MESSAGE(property, "could not find property for " + propertyAddress); BOOST_CHECK(property->data_type() == dataType); location->unlock(); } -#define CHECK_WITH_TIMEOUT(...) \ - { \ - static const size_t nIterations = 10000; \ - size_t local_index_i = 0; \ - for (; local_index_i < nIterations; ++local_index_i) { \ - if (__VA_ARGS__) { \ - std::cout << "ok after " << local_index_i << std::endl; \ - break; \ - } \ - usleep(100); \ - } \ - if (local_index_i == nIterations) \ - BOOST_CHECK(__VA_ARGS__); \ +#define CHECK_WITH_TIMEOUT(...) \ + { \ + static const size_t nIterations = 10000; \ + size_t local_index_i = 0; \ + for(; local_index_i < nIterations; ++local_index_i) { \ + if(__VA_ARGS__) { \ + std::cout << "ok after " << local_index_i << std::endl; \ + break; \ + } \ + usleep(100); \ + } \ + if(local_index_i == nIterations) BOOST_CHECK(__VA_ARGS__); \ } -template <class T> -void checkWithTimeout(std::function<T()> accessorFunction, T referenceValue, - size_t nIterations = 10000, - size_t microSecondsPerIteration = 100) { - for (size_t i = 0; i < nIterations; ++i) { - if (accessorFunction() == referenceValue) { +template<class T> +void checkWithTimeout(std::function<T()> accessorFunction, T referenceValue, size_t nIterations = 10000, + size_t microSecondsPerIteration = 100) { + for(size_t i = 0; i < nIterations; ++i) { + if(accessorFunction() == referenceValue) { std::cout << "test OK after " << i << " iterations" << std::endl; return; } @@ -165,23 +162,17 @@ void checkWithTimeout(std::function<T()> accessorFunction, T referenceValue, } std::stringstream errorMessage; - errorMessage << "accessor function failed after " << nIterations - << ", expected value is " << referenceValue + errorMessage << "accessor function failed after " << nIterations << ", expected value is " << referenceValue << ", current value is " << accessorFunction(); BOOST_ERROR(errorMessage.str()); } -void checkSpectrum(std::string const &propertyAddress, - bool expected_has_history = true, - bool expected_is_writeable = true, - float expected_start = 0.0, float expected_increment = 1.0) { - checkDoocsProperty<D_spectrum>(propertyAddress, expected_has_history, - expected_is_writeable); - - CHECK_WITH_TIMEOUT( - std::fabs(readSpectrumStart(propertyAddress) - expected_start) < 0.001); - CHECK_WITH_TIMEOUT(std::fabs(readSpectrumIncrement(propertyAddress) - - expected_increment) < 0.001); +void checkSpectrum(std::string const& propertyAddress, bool expected_has_history = true, + bool expected_is_writeable = true, float expected_start = 0.0, float expected_increment = 1.0) { + checkDoocsProperty<D_spectrum>(propertyAddress, expected_has_history, expected_is_writeable); + + CHECK_WITH_TIMEOUT(std::fabs(readSpectrumStart(propertyAddress) - expected_start) < 0.001); + CHECK_WITH_TIMEOUT(std::fabs(readSpectrumIncrement(propertyAddress) - expected_increment) < 0.001); } #endif // SERVER_BASED_TEST_TOOLS_H diff --git a/tests/include/set_doocs_value.h b/tests/include/set_doocs_value.h index 168c6c910bca0d14f6d4f82e78db39347c3ee86d..892d8bd4e13f5e1da82a1d689e5b7f6a9d48ef1b 100644 --- a/tests/include/set_doocs_value.h +++ b/tests/include/set_doocs_value.h @@ -5,8 +5,8 @@ // a convenience function to call set() on a D_fct, which is doing the real call // overloaded/ not overloaded set_value, fill history, call set_and_arcive etc. -template <class DOOCS_T, class T> -int set_doocs_value(DOOCS_T &property, T value) { +template<class DOOCS_T, class T> +int set_doocs_value(DOOCS_T& property, T value) { EqAdr adr; EqData src, dest; src.set(value); diff --git a/tests/src/serverTestGlobalTurnOnOffHistory.cpp b/tests/src/serverTestGlobalTurnOnOffHistory.cpp index eccbde96f06ae4a3932e812ddcaaf2974c874792..614521dfe70cfccc5f467bf1de6aec545a0be5e7 100644 --- a/tests/src/serverTestGlobalTurnOnOffHistory.cpp +++ b/tests/src/serverTestGlobalTurnOnOffHistory.cpp @@ -9,12 +9,11 @@ #include <doocs-server-test-helper/doocsServerTestHelper.h> #include <thread> -ReferenceTestApplication - referenceTestApplication("serverTestGlobalTurnOnOffHistory"); +ReferenceTestApplication referenceTestApplication("serverTestGlobalTurnOnOffHistory"); // declare that we have some thing like a doocs server. is is linked from the // doocs lib, but there is no header. -extern int eq_server(int, char **); +extern int eq_server(int, char**); //#include <limits> //#include <sstream> @@ -29,34 +28,20 @@ void testVariableExistence() { // the stuff with default. We are lazy and put the integer types as we have to // list D_double and D_float separately anyway if we don't want to do // meta-programming - for (auto &location : {"SHORT", "USHORT", "CHAR", "UCHAR", "INT", "UINT"}) { + for(auto& location : {"SHORT", "USHORT", "CHAR", "UCHAR", "INT", "UINT"}) { std::cout << "testing " << location << std::endl; - checkDoocsProperty<D_int>( - std::string("//") + location + "/DATA_TYPE_CONSTANT", false, false); - checkDoocsProperty<D_int>( - std::string("//") + location + "/FROM_DEVICE_SCALAR", false, false); - checkDoocsProperty<D_int>( - std::string("//") + location + "/TO_DEVICE_SCALAR", false, true); + checkDoocsProperty<D_int>(std::string("//") + location + "/DATA_TYPE_CONSTANT", false, false); + checkDoocsProperty<D_int>(std::string("//") + location + "/FROM_DEVICE_SCALAR", false, false); + checkDoocsProperty<D_int>(std::string("//") + location + "/TO_DEVICE_SCALAR", false, true); } - for (auto &nameWriteable : {std::make_pair("CONSTANT_ARRAY", false), - {"FROM_DEVICE_ARRAY", false}, - {"TO_DEVICE_ARRAY", true}}) { - checkDoocsProperty<D_intarray>(std::string("//INT/") + nameWriteable.first, - false, nameWriteable.second); - checkDoocsProperty<D_intarray>(std::string("//UINT/") + nameWriteable.first, - false, nameWriteable.second); - checkDoocsProperty<D_bytearray>(std::string("//CHAR/") + - nameWriteable.first, - false, nameWriteable.second); - checkDoocsProperty<D_bytearray>(std::string("//UCHAR/") + - nameWriteable.first, - false, nameWriteable.second); - checkDoocsProperty<D_shortarray>(std::string("//SHORT/") + - nameWriteable.first, - false, nameWriteable.second); - checkDoocsProperty<D_shortarray>(std::string("//USHORT/") + - nameWriteable.first, - false, nameWriteable.second); + for(auto& nameWriteable : + {std::make_pair("CONSTANT_ARRAY", false), {"FROM_DEVICE_ARRAY", false}, {"TO_DEVICE_ARRAY", true}}) { + checkDoocsProperty<D_intarray>(std::string("//INT/") + nameWriteable.first, false, nameWriteable.second); + checkDoocsProperty<D_intarray>(std::string("//UINT/") + nameWriteable.first, false, nameWriteable.second); + checkDoocsProperty<D_bytearray>(std::string("//CHAR/") + nameWriteable.first, false, nameWriteable.second); + checkDoocsProperty<D_bytearray>(std::string("//UCHAR/") + nameWriteable.first, false, nameWriteable.second); + checkDoocsProperty<D_shortarray>(std::string("//SHORT/") + nameWriteable.first, false, nameWriteable.second); + checkDoocsProperty<D_shortarray>(std::string("//USHORT/") + nameWriteable.first, false, nameWriteable.second); } std::cout << "testing DOUBLE" << std::endl; @@ -78,24 +63,21 @@ void testVariableExistence() { // due to the doocs server thread you can only have one test suite class GlobalTurnOnOffHistoryServerTestSuite : public test_suite { -public: - GlobalTurnOnOffHistoryServerTestSuite(int argc, char *argv[]) - : test_suite("GlobalTurnOnOffHistory server test suite"), - doocsServerThread(eq_server, argc, argv) { + public: + GlobalTurnOnOffHistoryServerTestSuite(int argc, char* argv[]) + : test_suite("GlobalTurnOnOffHistory server test suite"), doocsServerThread(eq_server, argc, argv) { // wait for doocs to start up before detaching the thread and continuing ChimeraTK::DoocsAdapter::waitUntilInitialised(); doocsServerThread.detach(); add(BOOST_TEST_CASE(&testVariableExistence)); } -protected: + protected: std::thread doocsServerThread; }; -test_suite *init_unit_test_suite(int argc, char *argv[]) { - std::cout << static_cast<void *>(&ApplicationBase::getInstance()) - << std::endl; - framework::master_test_suite().p_name.value = - "GlobalTurnOnOffHistory server test suite"; +test_suite* init_unit_test_suite(int argc, char* argv[]) { + std::cout << static_cast<void*>(&ApplicationBase::getInstance()) << std::endl; + framework::master_test_suite().p_name.value = "GlobalTurnOnOffHistory server test suite"; return new GlobalTurnOnOffHistoryServerTestSuite(argc, argv); } diff --git a/tests/src/serverTestGlobalTurnOnOffWriteable.cpp b/tests/src/serverTestGlobalTurnOnOffWriteable.cpp index 1a912ca349ec4c05779000425af36efc286e304c..87e1efe11472988efa85bbe6439bf204761c73d5 100644 --- a/tests/src/serverTestGlobalTurnOnOffWriteable.cpp +++ b/tests/src/serverTestGlobalTurnOnOffWriteable.cpp @@ -9,12 +9,11 @@ #include <doocs-server-test-helper/doocsServerTestHelper.h> #include <thread> -ReferenceTestApplication - referenceTestApplication("serverTestGlobalTurnOnOffWriteable"); +ReferenceTestApplication referenceTestApplication("serverTestGlobalTurnOnOffWriteable"); // declare that we have some thing like a doocs server. is is linked from the // doocs lib, but there is no header. -extern int eq_server(int, char **); +extern int eq_server(int, char**); //#include <limits> //#include <sstream> @@ -27,30 +26,21 @@ void testVariableExistence() { // the stuff with default. We are lazy and put the integer types as we have to // list D_double and D_float separately anyway if we don't want to do // meta-programming - for (auto &location : {"SHORT", "USHORT", "CHAR", "UCHAR", "INT", "UINT"}) { + for(auto& location : {"SHORT", "USHORT", "CHAR", "UCHAR", "INT", "UINT"}) { std::cout << "testing " << location << std::endl; - checkDoocsProperty<D_int>( - std::string("//") + location + "/DATA_TYPE_CONSTANT", true, false); - checkDoocsProperty<D_int>( - std::string("//") + location + "/FROM_DEVICE_SCALAR", true, false); - checkDoocsProperty<D_int>( - std::string("//") + location + "/TO_DEVICE_SCALAR", true, false); + checkDoocsProperty<D_int>(std::string("//") + location + "/DATA_TYPE_CONSTANT", true, false); + checkDoocsProperty<D_int>(std::string("//") + location + "/FROM_DEVICE_SCALAR", true, false); + checkDoocsProperty<D_int>(std::string("//") + location + "/TO_DEVICE_SCALAR", true, false); } - for (auto &name : - {"CONSTANT_ARRAY", "FROM_DEVICE_ARRAY", "TO_DEVICE_ARRAY"}) { + for(auto& name : {"CONSTANT_ARRAY", "FROM_DEVICE_ARRAY", "TO_DEVICE_ARRAY"}) { checkDoocsProperty<D_intarray>(std::string("//INT/") + name, true, false); checkDoocsProperty<D_intarray>(std::string("//UINT/") + name, true, false); checkDoocsProperty<D_bytearray>(std::string("//CHAR/") + name, true, false); - checkDoocsProperty<D_bytearray>(std::string("//UCHAR/") + name, true, - false); - checkDoocsProperty<D_shortarray>(std::string("//SHORT/") + name, true, - false); - checkDoocsProperty<D_shortarray>(std::string("//USHORT/") + name, true, - false); - checkDoocsProperty<D_shortarray>(std::string("//SHORT/") + name, true, - false); - checkDoocsProperty<D_shortarray>(std::string("//USHORT/") + name, true, - false); + checkDoocsProperty<D_bytearray>(std::string("//UCHAR/") + name, true, false); + checkDoocsProperty<D_shortarray>(std::string("//SHORT/") + name, true, false); + checkDoocsProperty<D_shortarray>(std::string("//USHORT/") + name, true, false); + checkDoocsProperty<D_shortarray>(std::string("//SHORT/") + name, true, false); + checkDoocsProperty<D_shortarray>(std::string("//USHORT/") + name, true, false); } std::cout << "testing DOUBLE" << std::endl; @@ -72,22 +62,20 @@ void testVariableExistence() { // due to the doocs server thread you can only have one test suite class GlobalTurnOnOffWriteableServerTestSuite : public test_suite { -public: - GlobalTurnOnOffWriteableServerTestSuite(int argc, char *argv[]) - : test_suite("GlobalTurnOnOffWriteable server test suite"), - doocsServerThread(eq_server, argc, argv) { + public: + GlobalTurnOnOffWriteableServerTestSuite(int argc, char* argv[]) + : test_suite("GlobalTurnOnOffWriteable server test suite"), doocsServerThread(eq_server, argc, argv) { // wait for doocs to start up before detaching the thread and continuing ChimeraTK::DoocsAdapter::waitUntilInitialised(); doocsServerThread.detach(); add(BOOST_TEST_CASE(&testVariableExistence)); } -protected: + protected: std::thread doocsServerThread; }; -test_suite *init_unit_test_suite(int argc, char *argv[]) { - framework::master_test_suite().p_name.value = - "GlobalTurnOnOffWriteable server test suite"; +test_suite* init_unit_test_suite(int argc, char* argv[]) { + framework::master_test_suite().p_name.value = "GlobalTurnOnOffWriteable server test suite"; return new GlobalTurnOnOffWriteableServerTestSuite(argc, argv); } diff --git a/tests/src/serverTestImportAllIntoLocation.cpp b/tests/src/serverTestImportAllIntoLocation.cpp index f773834e0f5e936cd707861b4b1d5fd12f6f174c..baeae9cd4674eaa7ff36920811d8deae233be3f1 100644 --- a/tests/src/serverTestImportAllIntoLocation.cpp +++ b/tests/src/serverTestImportAllIntoLocation.cpp @@ -8,12 +8,11 @@ #include <doocs-server-test-helper/doocsServerTestHelper.h> #include <thread> -ReferenceTestApplication - referenceTestApplication("serverTestImportAllIntoLocation"); +ReferenceTestApplication referenceTestApplication("serverTestImportAllIntoLocation"); // declare that we have some thing like a doocs server. is is linked from the // doocs lib, but there is no header. -extern int eq_server(int, char **); +extern int eq_server(int, char**); //#include <limits> //#include <sstream> @@ -32,27 +31,20 @@ using namespace ChimeraTK; void testVariableExistence() { // for (auto const directory : { "CHAR", "DOUBLE", "FLOAT", "INT", "SHORT", // "UCHAR", "UINT", "USHORT"} ){ - for (auto const directory : - {"DOUBLE", "FLOAT", "INT", "SHORT", "UCHAR", "UINT", "USHORT", "CHAR"}) { - for (auto const variable : - {"CONSTANT_ARRAY", "FROM_DEVICE_ARRAY", "TO_DEVICE_ARRAY "}) { + for(auto const directory : {"DOUBLE", "FLOAT", "INT", "SHORT", "UCHAR", "UINT", "USHORT", "CHAR"}) { + for(auto const variable : {"CONSTANT_ARRAY", "FROM_DEVICE_ARRAY", "TO_DEVICE_ARRAY "}) { // if this throws the property does not exist. we should always be able to // read" - std::cout << "testing existence of " - << std::string("//MASTER/") + directory + "." + variable - << std::endl; - BOOST_CHECK_NO_THROW(DoocsServerTestHelper::doocsGetArray<int>( - (std::string("//MASTER/") + directory + "." + variable).c_str())); + std::cout << "testing existence of " << std::string("//MASTER/") + directory + "." + variable << std::endl; + BOOST_CHECK_NO_THROW( + DoocsServerTestHelper::doocsGetArray<int>((std::string("//MASTER/") + directory + "." + variable).c_str())); } - for (auto const variable : - {"DATA_TYPE_CONSTANT", "FROM_DEVICE_SCALAR", "TO_DEVICE_SCALAR"}) { - std::cout << "testing existence of " - << std::string("//MASTER/") + directory + "." + variable - << std::endl; + for(auto const variable : {"DATA_TYPE_CONSTANT", "FROM_DEVICE_SCALAR", "TO_DEVICE_SCALAR"}) { + std::cout << "testing existence of " << std::string("//MASTER/") + directory + "." + variable << std::endl; // if this throws the property does not exist. we should always be able to // read" - BOOST_CHECK_NO_THROW(DoocsServerTestHelper::doocsGet<int>( - (std::string("//MASTER/") + directory + "." + variable).c_str())); + BOOST_CHECK_NO_THROW( + DoocsServerTestHelper::doocsGet<int>((std::string("//MASTER/") + directory + "." + variable).c_str())); std::cout << "test done " << std::endl; } } @@ -60,22 +52,20 @@ void testVariableExistence() { // due to the doocs server thread you can only have one test suite class MyTestSuite : public test_suite { -public: - MyTestSuite(int argc, char *argv[]) - : test_suite("ImportAllIntoLocation server test suite"), - doocsServerThread(eq_server, argc, argv) { + public: + MyTestSuite(int argc, char* argv[]) + : test_suite("ImportAllIntoLocation server test suite"), doocsServerThread(eq_server, argc, argv) { // wait for doocs to start up before detaching the thread and continuing ChimeraTK::DoocsAdapter::waitUntilInitialised(); doocsServerThread.detach(); add(BOOST_TEST_CASE(&testVariableExistence)); } -protected: + protected: std::thread doocsServerThread; }; -test_suite *init_unit_test_suite(int argc, char *argv[]) { - framework::master_test_suite().p_name.value = - "ImportAllIntoLocation server test suite"; +test_suite* init_unit_test_suite(int argc, char* argv[]) { + framework::master_test_suite().p_name.value = "ImportAllIntoLocation server test suite"; return new MyTestSuite(argc, argv); } diff --git a/tests/src/serverTestPlainVariableCreation.cpp b/tests/src/serverTestPlainVariableCreation.cpp index 8b9ce1a76c35a20dc9887d02d2e6f379e9e2ad3f..0244eb7d73884190ad7b97b61ac32b396e32c4bc 100644 --- a/tests/src/serverTestPlainVariableCreation.cpp +++ b/tests/src/serverTestPlainVariableCreation.cpp @@ -8,12 +8,11 @@ #include <doocs-server-test-helper/doocsServerTestHelper.h> #include <thread> -ReferenceTestApplication - referenceTestApplication("serverTestPlainVariableCreation"); +ReferenceTestApplication referenceTestApplication("serverTestPlainVariableCreation"); // declare that we have some thing like a doocs server. is is linked from the // doocs lib, but there is no header. -extern int eq_server(int, char **); +extern int eq_server(int, char**); //#include <limits> //#include <sstream> @@ -30,43 +29,38 @@ using namespace ChimeraTK; /// Check that all expected variables are there. void testVariableExistence() { - for (auto const location : - {"CHAR", "DOUBLE", "FLOAT", "INT", "SHORT", "UCHAR", "UINT", "USHORT"}) { - for (auto const property : - {"CONSTANT_ARRAY", "FROM_DEVICE_ARRAY", "TO_DEVICE_ARRAY "}) { + for(auto const location : {"CHAR", "DOUBLE", "FLOAT", "INT", "SHORT", "UCHAR", "UINT", "USHORT"}) { + for(auto const property : {"CONSTANT_ARRAY", "FROM_DEVICE_ARRAY", "TO_DEVICE_ARRAY "}) { // if this throws the property does not exist. we should always be able to // read" - BOOST_CHECK_NO_THROW(DoocsServerTestHelper::doocsGetArray<int>( - (std::string("//") + location + "/" + property).c_str())); + BOOST_CHECK_NO_THROW( + DoocsServerTestHelper::doocsGetArray<int>((std::string("//") + location + "/" + property).c_str())); } - for (auto const property : - {"DATA_TYPE_CONSTANT", "FROM_DEVICE_SCALAR", "TO_DEVICE_SCALAR"}) { + for(auto const property : {"DATA_TYPE_CONSTANT", "FROM_DEVICE_SCALAR", "TO_DEVICE_SCALAR"}) { // if this throws the property does not exist. we should always be able to // read" - BOOST_CHECK_NO_THROW(DoocsServerTestHelper::doocsGet<int>( - (std::string("//") + location + "/" + property).c_str())); + BOOST_CHECK_NO_THROW( + DoocsServerTestHelper::doocsGet<int>((std::string("//") + location + "/" + property).c_str())); } } } // due to the doocs server thread you can only have one test suite class PlainVariableCreationTestSuite : public test_suite { -public: - PlainVariableCreationTestSuite(int argc, char *argv[]) - : test_suite("PlainVariableCreation test suite"), - doocsServerThread(eq_server, argc, argv) { + public: + PlainVariableCreationTestSuite(int argc, char* argv[]) + : test_suite("PlainVariableCreation test suite"), doocsServerThread(eq_server, argc, argv) { // wait for doocs to start up before detaching the thread and continuing ChimeraTK::DoocsAdapter::waitUntilInitialised(); doocsServerThread.detach(); add(BOOST_TEST_CASE(&testVariableExistence)); } -protected: + protected: std::thread doocsServerThread; }; -test_suite *init_unit_test_suite(int argc, char *argv[]) { - framework::master_test_suite().p_name.value = - "PlainVariableCreation server test suite"; +test_suite* init_unit_test_suite(int argc, char* argv[]) { + framework::master_test_suite().p_name.value = "PlainVariableCreation server test suite"; return new PlainVariableCreationTestSuite(argc, argv); } diff --git a/tests/src/serverTestReadWrite.cpp b/tests/src/serverTestReadWrite.cpp index b0d530a0e2996a34e13e0f616024ff998f3783f9..4aa77f05ddc03ebb6ebc1dc86a8082ee1110035b 100644 --- a/tests/src/serverTestReadWrite.cpp +++ b/tests/src/serverTestReadWrite.cpp @@ -13,7 +13,7 @@ ReferenceTestApplication referenceTestApplication("serverTestReadWrite"); // declare that we have some thing like a doocs server. is is linked from the // doocs lib, but there is no header. -extern int eq_server(int, char **); +extern int eq_server(int, char**); //#include <limits> //#include <sstream> @@ -35,98 +35,76 @@ void testReadWrite() { std::cout << "got the application main lock" << std::endl; // just a few tests before we start - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//INT/DATA_TYPE_CONSTANT") == -4); - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//CHAR/DATA_TYPE_CONSTANT") == -1); - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//INT/FROM_DEVICE_SCALAR") == 0); - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//CHAR/FROM_DEVICE_SCALAR") == 0); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//INT/DATA_TYPE_CONSTANT") == -4); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//CHAR/DATA_TYPE_CONSTANT") == -1); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//INT/FROM_DEVICE_SCALAR") == 0); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//CHAR/FROM_DEVICE_SCALAR") == 0); DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", 42); DoocsServerTestHelper::doocsSet<int>("//CHAR/TO_DEVICE_SCALAR", 44); - DoocsServerTestHelper::doocsSet<int>( - "//INT/TO_DEVICE_ARRAY", - {140, 141, 142, 143, 144, 145, 146, 147, 148, 149}); + DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_ARRAY", {140, 141, 142, 143, 144, 145, 146, 147, 148, 149}); - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//INT/FROM_DEVICE_SCALAR") == 0); - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//CHAR/FROM_DEVICE_SCALAR") == 0); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//INT/FROM_DEVICE_SCALAR") == 0); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//CHAR/FROM_DEVICE_SCALAR") == 0); // run the application loop. Still no changes until we run the doocs server // update referenceTestApplication.runMainLoopOnce(); // now finally after the next update we should see the new data in doocs - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//INT/FROM_DEVICE_SCALAR") == 42); - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//CHAR/FROM_DEVICE_SCALAR") == 44); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//INT/FROM_DEVICE_SCALAR") == 42); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//CHAR/FROM_DEVICE_SCALAR") == 44); // we have to get stuff as float in order to work with spectra - auto intArray = - DoocsServerTestHelper::doocsGetArray<float>("//INT/FROM_DEVICE_ARRAY"); + auto intArray = DoocsServerTestHelper::doocsGetArray<float>("//INT/FROM_DEVICE_ARRAY"); int testVal = 140; - for (size_t i = 0; i < intArray.size(); ++i) { - CHECK_WITH_TIMEOUT(std::fabs(DoocsServerTestHelper::doocsGetArray<float>( - "//INT/FROM_DEVICE_ARRAY")[i] - - testVal) < 0.001); + for(size_t i = 0; i < intArray.size(); ++i) { + CHECK_WITH_TIMEOUT( + std::fabs(DoocsServerTestHelper::doocsGetArray<float>("//INT/FROM_DEVICE_ARRAY")[i] - testVal) < 0.001); // can't increment in check with timeout because it evaluated the equation // multiple times, so it increments multiple times ++testVal; } - auto constArray = - DoocsServerTestHelper::doocsGetArray<float>("//INT/CONSTANT_ARRAY"); - for (int i = 0; i < int(constArray.size()); ++i) { - CHECK_WITH_TIMEOUT( - std::fabs(DoocsServerTestHelper::doocsGetArray<float>( - "//INT/CONSTANT_ARRAY")[i] - - (-4 * i * i)) < - 0.001); // float check to compensate binary roundings errors + auto constArray = DoocsServerTestHelper::doocsGetArray<float>("//INT/CONSTANT_ARRAY"); + for(int i = 0; i < int(constArray.size()); ++i) { + CHECK_WITH_TIMEOUT(std::fabs(DoocsServerTestHelper::doocsGetArray<float>("//INT/CONSTANT_ARRAY")[i] - + (-4 * i * i)) < 0.001); // float check to compensate binary roundings errors } - for (auto const location : - {"CHAR", "DOUBLE", "FLOAT", "INT", "SHORT", "UCHAR", "UINT", "USHORT"}) { - for (auto const property : - {"CONSTANT_ARRAY", "FROM_DEVICE_ARRAY", "TO_DEVICE_ARRAY "}) { + for(auto const location : {"CHAR", "DOUBLE", "FLOAT", "INT", "SHORT", "UCHAR", "UINT", "USHORT"}) { + for(auto const property : {"CONSTANT_ARRAY", "FROM_DEVICE_ARRAY", "TO_DEVICE_ARRAY "}) { // if this throws the property does not exist. we should always be able to // read" - BOOST_CHECK_NO_THROW(DoocsServerTestHelper::doocsGetArray<int>( - (std::string("//") + location + "/" + property).c_str())); + BOOST_CHECK_NO_THROW( + DoocsServerTestHelper::doocsGetArray<int>((std::string("//") + location + "/" + property).c_str())); } - for (auto const property : - {"DATA_TYPE_CONSTANT", "FROM_DEVICE_SCALAR", "TO_DEVICE_SCALAR"}) { + for(auto const property : {"DATA_TYPE_CONSTANT", "FROM_DEVICE_SCALAR", "TO_DEVICE_SCALAR"}) { // if this throws the property does not exist. we should always be able to // read" - BOOST_CHECK_NO_THROW(DoocsServerTestHelper::doocsGet<int>( - (std::string("//") + location + "/" + property).c_str())); + BOOST_CHECK_NO_THROW( + DoocsServerTestHelper::doocsGet<int>((std::string("//") + location + "/" + property).c_str())); } } } // due to the doocs server thread you can only have one test suite class DoocsServerTestSuite : public test_suite { -public: - DoocsServerTestSuite(int argc, char *argv[]) - : test_suite("Read write test suite"), - doocsServerThread(eq_server, argc, argv) { + public: + DoocsServerTestSuite(int argc, char* argv[]) + : test_suite("Read write test suite"), doocsServerThread(eq_server, argc, argv) { // wait for doocs to start up before detaching the thread and continuing ChimeraTK::DoocsAdapter::waitUntilInitialised(); doocsServerThread.detach(); add(BOOST_TEST_CASE(&testReadWrite)); } - virtual ~DoocsServerTestSuite() { - referenceTestApplication.releaseManualLoopControl(); - } + virtual ~DoocsServerTestSuite() { referenceTestApplication.releaseManualLoopControl(); } -protected: + protected: std::thread doocsServerThread; }; -test_suite *init_unit_test_suite(int argc, char *argv[]) { +test_suite* init_unit_test_suite(int argc, char* argv[]) { framework::master_test_suite().p_name.value = "Read write server test suite"; return new DoocsServerTestSuite(argc, argv); } diff --git a/tests/src/serverTestRenameImport.cpp b/tests/src/serverTestRenameImport.cpp index 4d076b5b8ff1d390e72ccf4fc557226a83ac5ef0..eb530469a3d0cdbd53840244ab5acf6ddbdd7478 100644 --- a/tests/src/serverTestRenameImport.cpp +++ b/tests/src/serverTestRenameImport.cpp @@ -13,7 +13,7 @@ ReferenceTestApplication referenceTestApplication("serverTestRenameImport"); // declare that we have some thing like a doocs server. is is linked from the // doocs lib, but there is no header. -extern int eq_server(int, char **); +extern int eq_server(int, char**); //#include <limits> //#include <sstream> @@ -30,30 +30,19 @@ using namespace ChimeraTK; /// Check that all expected variables are there. void testVariableExistence() { - checkDoocsProperty<D_intarray>( - "//MY_RENAMED_INTEGER_LOCATION/RENAMED.CONST_ARRAY", true, false); - checkDoocsProperty<D_intarray>( - "//MY_RENAMED_INTEGER_LOCATION/FROM_DEVICE_ARRAY", true, false); - checkDoocsProperty<D_intarray>( - "//MY_RENAMED_INTEGER_LOCATION/TO_DEVICE_ARRAY", true, true); - checkDoocsProperty<D_int>("//MY_RENAMED_INTEGER_LOCATION/DATA_TYPE_CONSTANT", - true, false); - CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>( - "//MY_RENAMED_INTEGER_LOCATION/DATA_TYPE_CONSTANT") == - -4); - checkDoocsProperty<D_int>("//MY_RENAMED_INTEGER_LOCATION/FROM_DEVICE_SCALAR", - true, false); - checkDoocsProperty<D_int>("//MY_RENAMED_INTEGER_LOCATION/TO_DEVICE_SCALAR", - true, true); - - checkDoocsProperty<D_shortarray>("//SHORT/myStuff.CONSTANT_ARRAY", true, - false); - checkDoocsProperty<D_shortarray>("//SHORT/myStuff.FROM_DEVICE_ARRAY", true, - false); + checkDoocsProperty<D_intarray>("//MY_RENAMED_INTEGER_LOCATION/RENAMED.CONST_ARRAY", true, false); + checkDoocsProperty<D_intarray>("//MY_RENAMED_INTEGER_LOCATION/FROM_DEVICE_ARRAY", true, false); + checkDoocsProperty<D_intarray>("//MY_RENAMED_INTEGER_LOCATION/TO_DEVICE_ARRAY", true, true); + checkDoocsProperty<D_int>("//MY_RENAMED_INTEGER_LOCATION/DATA_TYPE_CONSTANT", true, false); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//MY_RENAMED_INTEGER_LOCATION/DATA_TYPE_CONSTANT") == -4); + checkDoocsProperty<D_int>("//MY_RENAMED_INTEGER_LOCATION/FROM_DEVICE_SCALAR", true, false); + checkDoocsProperty<D_int>("//MY_RENAMED_INTEGER_LOCATION/TO_DEVICE_SCALAR", true, true); + + checkDoocsProperty<D_shortarray>("//SHORT/myStuff.CONSTANT_ARRAY", true, false); + checkDoocsProperty<D_shortarray>("//SHORT/myStuff.FROM_DEVICE_ARRAY", true, false); checkDoocsProperty<D_shortarray>("//SHORT/myStuff.TO_DEVICE_ARRAY"); checkDoocsProperty<D_int>("//SHORT/myStuff.DATA_TYPE_CONSTANT", true, false); - CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>( - "//SHORT/myStuff.DATA_TYPE_CONSTANT") == -2); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//SHORT/myStuff.DATA_TYPE_CONSTANT") == -2); checkDoocsProperty<D_int>("//SHORT/myStuff.FROM_DEVICE_SCALAR", true, false); checkDoocsProperty<D_int>("//CHERRY_PICKED/TO_DEVICE_SHORT"); @@ -62,8 +51,7 @@ void testVariableExistence() { checkDoocsProperty<D_doublearray>("//DOUBLE/FROM_DEVICE_ARRAY", true, false); checkDoocsProperty<D_doublearray>("//DOUBLE/TO_DEVICE_ARRAY"); checkDoocsProperty<D_double>("//DOUBLE/RENAMED_CONSTANT", false, false); - CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<double>( - "//DOUBLE/RENAMED_CONSTANT") == 1. / 8.); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<double>("//DOUBLE/RENAMED_CONSTANT") == 1. / 8.); checkDoocsProperty<D_double>("//DOUBLE/FROM_DEVICE_SCALAR", true, false); checkDoocsProperty<D_double>("//DOUBLE/DOUBLE.TO_DEVICE_SCALAR", true, false); checkDoocsProperty<D_float>("//DOUBLE/I_AM_A_FLOAT_SCALAR"); @@ -74,16 +62,14 @@ void testVariableExistence() { checkDoocsProperty<D_floatarray>("//FLOAT/FROM_DEVICE_ARRAY", true, false); checkDoocsProperty<D_floatarray>("//FLOAT/TO_DEVICE_ARRAY"); checkDoocsProperty<D_float>("//FLOAT/DATA_TYPE_CONSTANT", true, false); - CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<float>( - "//FLOAT/DATA_TYPE_CONSTANT") == 1. / 4.); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<float>("//FLOAT/DATA_TYPE_CONSTANT") == 1. / 4.); checkDoocsProperty<D_float>("//FLOAT/FROM_DEVICE_SCALAR", true, false); checkDoocsProperty<D_intarray>("//UINT/CONSTANT_ARRAY", true, false); checkDoocsProperty<D_intarray>("//UINT/FROM_DEVICE_ARRAY", true, false); checkDoocsProperty<D_intarray>("//UINT/TO_DEVICE_ARRAY"); checkDoocsProperty<D_int>("//UINT/DATA_TYPE_CONSTANT", true, false); - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//UINT/DATA_TYPE_CONSTANT") == 4); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//UINT/DATA_TYPE_CONSTANT") == 4); checkDoocsProperty<D_int>("//UINT/FROM_DEVICE_SCALAR", true, false); checkDoocsProperty<D_int>("//UINT/TO_DEVICE_SCALAR"); @@ -91,8 +77,7 @@ void testVariableExistence() { checkDoocsProperty<D_shortarray>("//USHORT/FROM_DEVICE_ARRAY", true, false); checkDoocsProperty<D_shortarray>("//USHORT/TO_DEVICE_ARRAY"); checkDoocsProperty<D_int>("//USHORT/DATA_TYPE_CONSTANT", false, false); - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//USHORT/DATA_TYPE_CONSTANT") == 2); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//USHORT/DATA_TYPE_CONSTANT") == 2); checkDoocsProperty<D_int>("//USHORT/FROM_DEVICE_SCALAR", false, false); checkDoocsProperty<D_int>("//USHORT/TO_DEVICE_SCALAR", true, true); @@ -100,8 +85,7 @@ void testVariableExistence() { checkDoocsProperty<D_bytearray>("//UCHAR/FROM_DEVICE_ARRAY", true, false); checkDoocsProperty<D_bytearray>("//UCHAR/TO_DEVICE_ARRAY", true, false); checkDoocsProperty<D_int>("//UCHAR/DATA_TYPE_CONSTANT", true, false); - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//UCHAR/DATA_TYPE_CONSTANT") == 1); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//UCHAR/DATA_TYPE_CONSTANT") == 1); checkDoocsProperty<D_int>("//UCHAR/FROM_DEVICE_SCALAR", true, false); checkDoocsProperty<D_int>("//UCHAR/TO_DEVICE_SCALAR"); @@ -109,30 +93,27 @@ void testVariableExistence() { checkDoocsProperty<D_bytearray>("//CHAR/FROM_DEVICE_ARRAY", true, false); checkDoocsProperty<D_bytearray>("//CHAR/TO_DEVICE_ARRAY"); checkDoocsProperty<D_int>("//CHAR/DATA_TYPE_CONSTANT", true, false); - CHECK_WITH_TIMEOUT( - DoocsServerTestHelper::doocsGet<int>("//CHAR/DATA_TYPE_CONSTANT") == -1); + CHECK_WITH_TIMEOUT(DoocsServerTestHelper::doocsGet<int>("//CHAR/DATA_TYPE_CONSTANT") == -1); checkDoocsProperty<D_int>("//CHAR/FROM_DEVICE_SCALAR", true, false); checkDoocsProperty<D_int>("//CHAR/TO_DEVICE_SCALAR"); } // due to the doocs server thread you can only have one test suite class RenameImportServerTestSuite : public test_suite { -public: - RenameImportServerTestSuite(int argc, char *argv[]) - : test_suite("RenameImport server test suite"), - doocsServerThread(eq_server, argc, argv) { + public: + RenameImportServerTestSuite(int argc, char* argv[]) + : test_suite("RenameImport server test suite"), doocsServerThread(eq_server, argc, argv) { // wait for doocs to start up before detaching the thread and continuing ChimeraTK::DoocsAdapter::waitUntilInitialised(); doocsServerThread.detach(); add(BOOST_TEST_CASE(&testVariableExistence)); } -protected: + protected: std::thread doocsServerThread; }; -test_suite *init_unit_test_suite(int argc, char *argv[]) { - framework::master_test_suite().p_name.value = - "RenameImport server test suite"; +test_suite* init_unit_test_suite(int argc, char* argv[]) { + framework::master_test_suite().p_name.value = "RenameImport server test suite"; return new RenameImportServerTestSuite(argc, argv); } diff --git a/tests/src/serverTestSpectrumArray.cpp b/tests/src/serverTestSpectrumArray.cpp index 24b007985e629ffcbea18fe3dcef304bac060141..746b43c84e2a25883799e6014e8424ed345c00f0 100644 --- a/tests/src/serverTestSpectrumArray.cpp +++ b/tests/src/serverTestSpectrumArray.cpp @@ -13,7 +13,7 @@ ReferenceTestApplication referenceTestApplication("serverTestSpectrumArray"); // declare that we have some thing like a doocs server. is is linked from the // doocs lib, but there is no header. -extern int eq_server(int, char **); +extern int eq_server(int, char**); //#include <limits> //#include <sstream> @@ -29,14 +29,13 @@ using namespace ChimeraTK; // float, double> simple_test_types; // the array must have testStartValue+i at index i. -template <class T> -bool testArrayContent(std::string const &propertyName, T testStartValue, - T delta) { +template<class T> +bool testArrayContent(std::string const& propertyName, T testStartValue, T delta) { auto array = DoocsServerTestHelper::doocsGetArray<T>(propertyName); bool isOK = true; T currentTestValue = testStartValue; - for (auto val : array) { - if (std::fabs(val - currentTestValue) > 0.001) { + for(auto val : array) { + if(std::fabs(val - currentTestValue) > 0.001) { isOK = false; } currentTestValue += delta; @@ -67,28 +66,21 @@ void testReadWrite() { // check that the "short array" is of type long checkDataType("//SHORT/MY_RETYPED_SHORT_ARRAY", DATA_A_LONG); + DoocsServerTestHelper::doocsSetSpectrum("//INT/TO_DEVICE_ARRAY", {140, 141, 142, 143, 144, 145, 146, 147, 148, 149}); DoocsServerTestHelper::doocsSetSpectrum( - "//INT/TO_DEVICE_ARRAY", - {140, 141, 142, 143, 144, 145, 146, 147, 148, 149}); - DoocsServerTestHelper::doocsSetSpectrum( - "//DOUBLE/TO_DEVICE_ARRAY", - {240.3, 241.3, 242.3, 243.3, 244.3, 245.3, 246.3, 247.3, 248.3, 249.3}); + "//DOUBLE/TO_DEVICE_ARRAY", {240.3, 241.3, 242.3, 243.3, 244.3, 245.3, 246.3, 247.3, 248.3, 249.3}); // check the the control system side still sees 0 in all arrays. The // application has not reacted yet - CHECK_WITH_TIMEOUT( - testArrayContent<float>("//INT/MY_RENAMED_INTARRAY", 0, 0) == true); - CHECK_WITH_TIMEOUT( - testArrayContent<float>("//DOUBLE/FROM_DEVICE_ARRAY", 0, 0) == true); + CHECK_WITH_TIMEOUT(testArrayContent<float>("//INT/MY_RENAMED_INTARRAY", 0, 0) == true); + CHECK_WITH_TIMEOUT(testArrayContent<float>("//DOUBLE/FROM_DEVICE_ARRAY", 0, 0) == true); // run the application loop. referenceTestApplication.runMainLoopOnce(); - CHECK_WITH_TIMEOUT( - testArrayContent<float>("//INT/MY_RENAMED_INTARRAY", 140, 1) == true); - CHECK_WITH_TIMEOUT( - testArrayContent<float>("//DOUBLE/FROM_DEVICE_ARRAY", 240.3, 1) == true); + CHECK_WITH_TIMEOUT(testArrayContent<float>("//INT/MY_RENAMED_INTARRAY", 140, 1) == true); + CHECK_WITH_TIMEOUT(testArrayContent<float>("//DOUBLE/FROM_DEVICE_ARRAY", 240.3, 1) == true); // notIntArray = // DoocsServerTestHelper::doocsGetArray<double>("//INT/MY_RENAMED_INTARRAY") @@ -111,7 +103,7 @@ void testPropertyDoesNotExist(std::string addressString) { EqData ed, res; // obtain location pointer ad.adr(addressString.c_str()); - EqFct *eqFct = eq_get(&ad); + EqFct* eqFct = eq_get(&ad); BOOST_REQUIRE_MESSAGE(eqFct != NULL, "Could not get location for property."); // obtain value eqFct->lock(); @@ -119,9 +111,8 @@ void testPropertyDoesNotExist(std::string addressString) { eqFct->unlock(); // check for errors /// todo FIXME: check for the correct error code - BOOST_CHECK_MESSAGE(res.error() != 0, std::string("Could read from ") + - addressString + - ", but it should not be there"); + BOOST_CHECK_MESSAGE( + res.error() != 0, std::string("Could read from ") + addressString + ", but it should not be there"); } void testPropertiesDontExist() { @@ -131,26 +122,22 @@ void testPropertiesDontExist() { // due to the doocs server thread you can only have one test suite class DoocsServerTestSuite : public test_suite { -public: - DoocsServerTestSuite(int argc, char *argv[]) - : test_suite("Spectrum and array server test suite"), - doocsServerThread(eq_server, argc, argv) { + public: + DoocsServerTestSuite(int argc, char* argv[]) + : test_suite("Spectrum and array server test suite"), doocsServerThread(eq_server, argc, argv) { // wait for doocs to start up before detaching the thread and continuing ChimeraTK::DoocsAdapter::waitUntilInitialised(); doocsServerThread.detach(); add(BOOST_TEST_CASE(&testReadWrite)); add(BOOST_TEST_CASE(&testPropertiesDontExist)); } - virtual ~DoocsServerTestSuite() { - referenceTestApplication.releaseManualLoopControl(); - } + virtual ~DoocsServerTestSuite() { referenceTestApplication.releaseManualLoopControl(); } -protected: + protected: std::thread doocsServerThread; }; -test_suite *init_unit_test_suite(int argc, char *argv[]) { - framework::master_test_suite().p_name.value = - "Spectrum and array server test suite"; +test_suite* init_unit_test_suite(int argc, char* argv[]) { + framework::master_test_suite().p_name.value = "Spectrum and array server test suite"; return new DoocsServerTestSuite(argc, argv); } diff --git a/tests/src/serverTestZeroMQ.cpp b/tests/src/serverTestZeroMQ.cpp index 6316f870d5f4ddcd78185a3008a7d8d45225e6ff..8aaf650d54df0857e7bd482fdebeb72cf55c0109 100644 --- a/tests/src/serverTestZeroMQ.cpp +++ b/tests/src/serverTestZeroMQ.cpp @@ -17,7 +17,7 @@ static ReferenceTestApplication referenceTestApplication("serverTestZeroMQ"); /**********************************************************************************************************************/ -extern int eq_server(int, char **); +extern int eq_server(int, char**); struct DoocsLauncher { DoocsLauncher() { @@ -28,14 +28,14 @@ struct DoocsLauncher { // update config file with the RPC number std::string command = "sed -i serverTestZeroMQ.conf -e " "'s/^SVR.RPC_NUMBER:.*$/SVR.RPC_NUMBER: " + - rpc_no + "/'"; + rpc_no + "/'"; auto rc = std::system(command.c_str()); (void)rc; // start the server std::thread(eq_server, - boost::unit_test::framework::master_test_suite().argc, - boost::unit_test::framework::master_test_suite().argv) + boost::unit_test::framework::master_test_suite().argc, + boost::unit_test::framework::master_test_suite().argv) .detach(); // wait until server has started (both the update thread and the rpc thread) DoocsServerTestHelper::runUpdate(); @@ -43,8 +43,7 @@ struct DoocsLauncher { EqAdr ea; EqData src, dst; ea.adr("doocs://localhost:" + rpc_no + "/F/D/UINT/FROM_DEVICE_SCALAR"); - while (eq.get(&ea, &src, &dst)) - usleep(100000); + while(eq.get(&ea, &src, &dst)) usleep(100000); dmsg_start(); referenceTestApplication.initialiseManualLoopControl(); } @@ -77,37 +76,33 @@ BOOST_AUTO_TEST_CASE(testScalar) { /// written and then our values. int macroPulseNumber = 12345; - DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", - macroPulseNumber); + DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", macroPulseNumber); uint32_t expectedValue = 42; - DoocsServerTestHelper::doocsSet<uint32_t>("//UINT/TO_DEVICE_SCALAR", - expectedValue); + DoocsServerTestHelper::doocsSet<uint32_t>("//UINT/TO_DEVICE_SCALAR", expectedValue); EqData dst; EqAdr ea; - ea.adr("doocs://localhost:" + DoocsLauncher::rpc_no + - "/F/D/UINT/FROM_DEVICE_SCALAR"); + ea.adr("doocs://localhost:" + DoocsLauncher::rpc_no + "/F/D/UINT/FROM_DEVICE_SCALAR"); dmsg_t tag; int err = dmsg_attach(&ea, &dst, nullptr, - [](void *, EqData *data, dmsg_info_t *info) { - std::lock_guard<std::mutex> lock(mutex); - received.copy_from(data); - receivedInfo = *info; - dataReceived = true; - }, - &tag); + [](void*, EqData* data, dmsg_info_t* info) { + std::lock_guard<std::mutex> lock(mutex); + received.copy_from(data); + receivedInfo = *info; + dataReceived = true; + }, + &tag); BOOST_CHECK(!err); // The ZeroMQ system in DOOCS is setup in the background, hence we have to try // in a loop until we receive the data. size_t counter = 0; dataReceived = false; - while (!dataReceived) { + while(!dataReceived) { usleep(1000); referenceTestApplication.runMainLoopOnce(); - if (++counter > 10000) - break; + if(++counter > 10000) break; } BOOST_CHECK(dataReceived == true); { @@ -120,7 +115,7 @@ BOOST_AUTO_TEST_CASE(testScalar) { // update // From now on, each update should be received. - for (size_t i = 0; i < 10; ++i) { + for(size_t i = 0; i < 10; ++i) { dataReceived = false; usleep(10000); BOOST_CHECK(dataReceived == false); @@ -130,26 +125,16 @@ BOOST_AUTO_TEST_CASE(testScalar) { std::lock_guard<std::mutex> lock(mutex); BOOST_CHECK_EQUAL(received.error(), 0); BOOST_CHECK_EQUAL(received.get_int(), expectedValue); - auto time = - appPVmanager->getProcessArray<uint32_t>("UINT/FROM_DEVICE_SCALAR") - ->getVersionNumber() - .getTime(); - auto secs = std::chrono::duration_cast<std::chrono::seconds>( - time.time_since_epoch()) - .count(); - auto usecs = std::chrono::duration_cast<std::chrono::microseconds>( - time.time_since_epoch()) - .count() - - secs * 1e6; + auto time = appPVmanager->getProcessArray<uint32_t>("UINT/FROM_DEVICE_SCALAR")->getVersionNumber().getTime(); + auto secs = std::chrono::duration_cast<std::chrono::seconds>(time.time_since_epoch()).count(); + auto usecs = std::chrono::duration_cast<std::chrono::microseconds>(time.time_since_epoch()).count() - secs * 1e6; BOOST_CHECK_EQUAL(receivedInfo.sec, secs); BOOST_CHECK_EQUAL(receivedInfo.usec, usecs); BOOST_CHECK_EQUAL(receivedInfo.ident, macroPulseNumber); ++macroPulseNumber; - DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", - macroPulseNumber); + DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", macroPulseNumber); expectedValue = 100 + i; - DoocsServerTestHelper::doocsSet<uint32_t>("//UINT/TO_DEVICE_SCALAR", - expectedValue); + DoocsServerTestHelper::doocsSet<uint32_t>("//UINT/TO_DEVICE_SCALAR", expectedValue); } } @@ -165,53 +150,47 @@ BOOST_AUTO_TEST_CASE(testArray) { auto appPVmanager = referenceTestApplication.getPVManager(); int macroPulseNumber = 99999; - DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", - macroPulseNumber); + DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", macroPulseNumber); - std::vector<int32_t> expectedArrayValue = {42, 43, 44, 45, 46, - 47, 48, 49, 50, 51}; - DoocsServerTestHelper::doocsSet<int32_t>("//UINT/TO_DEVICE_ARRAY", - expectedArrayValue); + std::vector<int32_t> expectedArrayValue = {42, 43, 44, 45, 46, 47, 48, 49, 50, 51}; + DoocsServerTestHelper::doocsSet<int32_t>("//UINT/TO_DEVICE_ARRAY", expectedArrayValue); EqData dst; EqAdr ea; - ea.adr("doocs://localhost:" + DoocsLauncher::rpc_no + - "/F/D/UINT/FROM_DEVICE_ARRAY"); + ea.adr("doocs://localhost:" + DoocsLauncher::rpc_no + "/F/D/UINT/FROM_DEVICE_ARRAY"); dmsg_t tag; int err = dmsg_attach(&ea, &dst, nullptr, - [](void *, EqData *data, dmsg_info_t *info) { - std::lock_guard<std::mutex> lock(mutex); - received.copy_from(data); - receivedInfo = *info; - dataReceived = true; - }, - &tag); + [](void*, EqData* data, dmsg_info_t* info) { + std::lock_guard<std::mutex> lock(mutex); + received.copy_from(data); + receivedInfo = *info; + dataReceived = true; + }, + &tag); BOOST_CHECK(!err); // The ZeroMQ system in DOOCS is setup in the background, hence we have to try // in a loop until we receive the data. size_t counter = 0; dataReceived = false; - while (!dataReceived) { + while(!dataReceived) { usleep(1000); referenceTestApplication.runMainLoopOnce(); - if (++counter > 10000) - break; + if(++counter > 10000) break; } BOOST_CHECK(dataReceived == true); { std::lock_guard<std::mutex> lock(mutex); BOOST_CHECK_EQUAL(received.error(), 0); BOOST_CHECK_EQUAL(received.length(), 10); - for (size_t k = 0; k < 10; ++k) - BOOST_CHECK_EQUAL(received.get_int(k), expectedArrayValue[k]); + for(size_t k = 0; k < 10; ++k) BOOST_CHECK_EQUAL(received.get_int(k), expectedArrayValue[k]); } usleep(100000); // this sleep is bad, but there seems not to be any better // solution - we need to be sure there is no further pending // update // From now on, each update should be received. - for (size_t i = 0; i < 10; ++i) { + for(size_t i = 0; i < 10; ++i) { dataReceived = false; usleep(10000); BOOST_CHECK(dataReceived == false); @@ -221,28 +200,17 @@ BOOST_AUTO_TEST_CASE(testArray) { std::lock_guard<std::mutex> lock(mutex); BOOST_CHECK_EQUAL(received.error(), 0); BOOST_CHECK_EQUAL(received.length(), 10); - for (size_t k = 0; k < 10; ++k) - BOOST_CHECK_EQUAL(received.get_int(k), expectedArrayValue[k]); - auto time = - appPVmanager->getProcessArray<uint32_t>("UINT/FROM_DEVICE_ARRAY") - ->getVersionNumber() - .getTime(); - auto secs = std::chrono::duration_cast<std::chrono::seconds>( - time.time_since_epoch()) - .count(); - auto usecs = std::chrono::duration_cast<std::chrono::microseconds>( - time.time_since_epoch()) - .count() - - secs * 1e6; + for(size_t k = 0; k < 10; ++k) BOOST_CHECK_EQUAL(received.get_int(k), expectedArrayValue[k]); + auto time = appPVmanager->getProcessArray<uint32_t>("UINT/FROM_DEVICE_ARRAY")->getVersionNumber().getTime(); + auto secs = std::chrono::duration_cast<std::chrono::seconds>(time.time_since_epoch()).count(); + auto usecs = std::chrono::duration_cast<std::chrono::microseconds>(time.time_since_epoch()).count() - secs * 1e6; BOOST_CHECK_EQUAL(receivedInfo.sec, secs); BOOST_CHECK_EQUAL(receivedInfo.usec, usecs); BOOST_CHECK_EQUAL(receivedInfo.ident, macroPulseNumber); --macroPulseNumber; - DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", - macroPulseNumber); + DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", macroPulseNumber); expectedArrayValue[1] = 100 + i; - DoocsServerTestHelper::doocsSet<int32_t>("//UINT/TO_DEVICE_ARRAY", - expectedArrayValue); + DoocsServerTestHelper::doocsSet<int32_t>("//UINT/TO_DEVICE_ARRAY", expectedArrayValue); } } @@ -258,53 +226,46 @@ BOOST_AUTO_TEST_CASE(testSpectrum) { auto appPVmanager = referenceTestApplication.getPVManager(); int macroPulseNumber = -100; - DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", - macroPulseNumber); + DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", macroPulseNumber); - std::vector<float> expectedFloatArrayValue = {42, 43, 44, 45, 46, - 47, 48, 49, 50, 51}; - DoocsServerTestHelper::doocsSet<float>("//FLOAT/TO_DEVICE_ARRAY", - expectedFloatArrayValue); + std::vector<float> expectedFloatArrayValue = {42, 43, 44, 45, 46, 47, 48, 49, 50, 51}; + DoocsServerTestHelper::doocsSet<float>("//FLOAT/TO_DEVICE_ARRAY", expectedFloatArrayValue); EqData dst; EqAdr ea; - ea.adr("doocs://localhost:" + DoocsLauncher::rpc_no + - "/F/D/FLOAT/FROM_DEVICE_ARRAY"); + ea.adr("doocs://localhost:" + DoocsLauncher::rpc_no + "/F/D/FLOAT/FROM_DEVICE_ARRAY"); dmsg_t tag; int err = dmsg_attach(&ea, &dst, nullptr, - [](void *, EqData *data, dmsg_info_t *info) { - std::lock_guard<std::mutex> lock(mutex); - received.copy_from(data); - receivedInfo = *info; - dataReceived = true; - }, - &tag); + [](void*, EqData* data, dmsg_info_t* info) { + std::lock_guard<std::mutex> lock(mutex); + received.copy_from(data); + receivedInfo = *info; + dataReceived = true; + }, + &tag); BOOST_CHECK(!err); // The ZeroMQ system in DOOCS is setup in the background, hence we have to try // in a loop until we receive the data. size_t counter = 0; dataReceived = false; - while (!dataReceived) { + while(!dataReceived) { usleep(1000); referenceTestApplication.runMainLoopOnce(); - if (++counter > 10000) - break; + if(++counter > 10000) break; } BOOST_CHECK(dataReceived == true); BOOST_CHECK_EQUAL(received.error(), 0); BOOST_CHECK_EQUAL(received.length(), 10); BOOST_CHECK_CLOSE(received.get_spectrum()->s_start, 123., 0.001); BOOST_CHECK_CLOSE(received.get_spectrum()->s_inc, 0.56, 0.001); - for (size_t k = 0; k < 10; ++k) - BOOST_CHECK_CLOSE(received.get_float(k), expectedFloatArrayValue[k], - 0.0001); + for(size_t k = 0; k < 10; ++k) BOOST_CHECK_CLOSE(received.get_float(k), expectedFloatArrayValue[k], 0.0001); usleep(100000); // this sleep is bad, but there seems not to be any better // solution - we need to be sure there is no further pending // update // From now on, each update should be received. - for (size_t i = 0; i < 10; ++i) { + for(size_t i = 0; i < 10; ++i) { dataReceived = false; usleep(10000); BOOST_CHECK(dataReceived == false); @@ -316,29 +277,17 @@ BOOST_AUTO_TEST_CASE(testSpectrum) { BOOST_CHECK_EQUAL(received.length(), 10); BOOST_CHECK_CLOSE(received.get_spectrum()->s_start, 123., 0.001); BOOST_CHECK_CLOSE(received.get_spectrum()->s_inc, 0.56, 0.001); - for (size_t k = 0; k < 10; ++k) - BOOST_CHECK_CLOSE(received.get_float(k), expectedFloatArrayValue[k], - 0.0001); - auto time = - appPVmanager->getProcessArray<float>("FLOAT/FROM_DEVICE_ARRAY") - ->getVersionNumber() - .getTime(); - auto secs = std::chrono::duration_cast<std::chrono::seconds>( - time.time_since_epoch()) - .count(); - auto usecs = std::chrono::duration_cast<std::chrono::microseconds>( - time.time_since_epoch()) - .count() - - secs * 1e6; + for(size_t k = 0; k < 10; ++k) BOOST_CHECK_CLOSE(received.get_float(k), expectedFloatArrayValue[k], 0.0001); + auto time = appPVmanager->getProcessArray<float>("FLOAT/FROM_DEVICE_ARRAY")->getVersionNumber().getTime(); + auto secs = std::chrono::duration_cast<std::chrono::seconds>(time.time_since_epoch()).count(); + auto usecs = std::chrono::duration_cast<std::chrono::microseconds>(time.time_since_epoch()).count() - secs * 1e6; BOOST_CHECK_EQUAL(receivedInfo.sec, secs); BOOST_CHECK_EQUAL(receivedInfo.usec, usecs); BOOST_CHECK_EQUAL(receivedInfo.ident, macroPulseNumber); macroPulseNumber *= -2; - DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", - macroPulseNumber); + DoocsServerTestHelper::doocsSet<int>("//INT/TO_DEVICE_SCALAR", macroPulseNumber); expectedFloatArrayValue[1] = 100 + i; - DoocsServerTestHelper::doocsSet<float>("//FLOAT/TO_DEVICE_ARRAY", - expectedFloatArrayValue); + DoocsServerTestHelper::doocsSet<float>("//FLOAT/TO_DEVICE_ARRAY", expectedFloatArrayValue); } } diff --git a/tests/src/testBasenameFromAddress.cpp b/tests/src/testBasenameFromAddress.cpp index 3e2471fa5715daa5806bf3b125a674e5ed0ee1cf..6518cedd6ba313ac7203b89c0a76d1dcc5b26a7d 100644 --- a/tests/src/testBasenameFromAddress.cpp +++ b/tests/src/testBasenameFromAddress.cpp @@ -11,8 +11,7 @@ using namespace ChimeraTK; BOOST_AUTO_TEST_SUITE(BasenameFromAddressTestSuite) BOOST_AUTO_TEST_CASE(testSpitting) { - BOOST_CHECK(basenameFromAddress("//LOCATION/PROPERTY.NAME") == - "PROPERTY.NAME"); + BOOST_CHECK(basenameFromAddress("//LOCATION/PROPERTY.NAME") == "PROPERTY.NAME"); BOOST_CHECK(basenameFromAddress("PROPERTY.NAME") == "PROPERTY.NAME"); BOOST_CHECK(basenameFromAddress("/PROPERTY.NAME") == "PROPERTY.NAME"); BOOST_CHECK(basenameFromAddress("//PROPERTY.NAME/") == ""); diff --git a/tests/src/testCSAdapterEqFct.cpp b/tests/src/testCSAdapterEqFct.cpp index d7907175dd19ec5c70b8310f0c738a4957bc9ffa..952dfc06df54c1caa5570ea807d3d0fa734f2c33 100644 --- a/tests/src/testCSAdapterEqFct.cpp +++ b/tests/src/testCSAdapterEqFct.cpp @@ -21,18 +21,15 @@ using namespace ChimeraTK; /// @todo FIXME: This should never be done in a test. FOR TESTING, USE THE /// PUBLIC API ONLY! class TestableCSAdapterEqFct : public CSAdapterEqFct { -public: - TestableCSAdapterEqFct( - int fctCode, - boost::shared_ptr<ControlSystemPVManager> controlSystemPVManager, - boost::shared_ptr<DoocsUpdater> const &updater, std::string fctName) - : CSAdapterEqFct(fctCode, controlSystemPVManager, updater, fctName) {} + public: + TestableCSAdapterEqFct(int fctCode, boost::shared_ptr<ControlSystemPVManager> controlSystemPVManager, + boost::shared_ptr<DoocsUpdater> const& updater, std::string fctName) + : CSAdapterEqFct(fctCode, controlSystemPVManager, updater, fctName) {} std::vector<boost::shared_ptr<D_fct>> getDoocsProperties() { // ugly work around required after refactoring - this should not be // required, but it happens if one tests against private API... std::vector<boost::shared_ptr<D_fct>> v; - for (auto &p : doocsProperties_) - v.push_back(p.second); + for(auto& p : doocsProperties_) v.push_back(p.second); return v; } }; @@ -41,11 +38,9 @@ struct BusinessLogic { boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int>> toDeviceInt; boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int>> fromDeviceInt; - BusinessLogic(boost::shared_ptr<ChimeraTK::DevicePVManager> const &pvManager) - : toDeviceInt(pvManager->createProcessArray<int>( - controlSystemToDevice, "test/TO_DEVICE/INT", 1)), - fromDeviceInt(pvManager->createProcessArray<int>( - deviceToControlSystem, "test/FROM_DEVICE/INT", 1)) {} + BusinessLogic(boost::shared_ptr<ChimeraTK::DevicePVManager> const& pvManager) + : toDeviceInt(pvManager->createProcessArray<int>(controlSystemToDevice, "test/TO_DEVICE/INT", 1)), + fromDeviceInt(pvManager->createProcessArray<int>(deviceToControlSystem, "test/FROM_DEVICE/INT", 1)) {} }; BOOST_AUTO_TEST_SUITE(CSAdapterEqFctTestSuite) @@ -72,20 +67,17 @@ BOOST_AUTO_TEST_CASE(testCSAdapterEqFct) { // We do extraction by name and put them into a map. For convenience we use // raw pointers. This would not be possible in a real application because // the vector with the properties is not exposed. - std::map<std::string, D_int *> doocsProperties; + std::map<std::string, D_int*> doocsProperties; - for (size_t i = 0; i < eqFct.getDoocsProperties().size(); ++i) { - D_int *doocsInt = - dynamic_cast<D_int *>(eqFct.getDoocsProperties()[i].get()); + for(size_t i = 0; i < eqFct.getDoocsProperties().size(); ++i) { + D_int* doocsInt = dynamic_cast<D_int*>(eqFct.getDoocsProperties()[i].get()); BOOST_REQUIRE(doocsInt); doocsProperties[doocsInt->property_name()] = doocsInt; } // note: doocs property names always have a space (and a comment which can // be empty, but the space is always there)" - BOOST_REQUIRE(doocsProperties.find("TO_DEVICE.INT ") != - doocsProperties.end()); - BOOST_REQUIRE(doocsProperties.find("FROM_DEVICE.INT ") != - doocsProperties.end()); + BOOST_REQUIRE(doocsProperties.find("TO_DEVICE.INT ") != doocsProperties.end()); + BOOST_REQUIRE(doocsProperties.find("FROM_DEVICE.INT ") != doocsProperties.end()); // write once and check set_doocs_value(*(doocsProperties["TO_DEVICE.INT "]), 13); @@ -121,28 +113,23 @@ BOOST_AUTO_TEST_CASE(testWithMapping) { // Initialse the mapping with an xml file. auto csManager = doocsAdapter.getControlSystemPVManager(); - VariableMapper::getInstance().prepareOutput("EqFctTest.xml", - getAllVariableNames(csManager)); + VariableMapper::getInstance().prepareOutput("EqFctTest.xml", getAllVariableNames(csManager)); // in the mapping two locations are created auto updater = boost::make_shared<DoocsUpdater>(); - TestableCSAdapterEqFct toDeviceEqFct(42, csManager, updater, - "test.TO_DEVICE"); - TestableCSAdapterEqFct fromDeviceEqFct(42, csManager, updater, - "test.FROM_DEVICE"); + TestableCSAdapterEqFct toDeviceEqFct(42, csManager, updater, "test.TO_DEVICE"); + TestableCSAdapterEqFct fromDeviceEqFct(42, csManager, updater, "test.FROM_DEVICE"); BOOST_REQUIRE(toDeviceEqFct.getDoocsProperties().size() == 1); BOOST_REQUIRE(fromDeviceEqFct.getDoocsProperties().size() == 1); // extract the two properties and check the name - std::map<std::string, D_int *> doocsProperties; + std::map<std::string, D_int*> doocsProperties; // both properties are called int, but are in different locations - D_int *doocsInt = - dynamic_cast<D_int *>(toDeviceEqFct.getDoocsProperties()[0].get()); + D_int* doocsInt = dynamic_cast<D_int*>(toDeviceEqFct.getDoocsProperties()[0].get()); BOOST_REQUIRE(std::string(doocsInt->property_name()) == "INT "); - doocsInt = - dynamic_cast<D_int *>(fromDeviceEqFct.getDoocsProperties()[0].get()); + doocsInt = dynamic_cast<D_int*>(fromDeviceEqFct.getDoocsProperties()[0].get()); BOOST_REQUIRE(std::string(doocsInt->property_name()) == "INT "); } diff --git a/tests/src/testDoocsPVFactory.cpp b/tests/src/testDoocsPVFactory.cpp index 63185dd550e7510a6cb40c671538174570bf609a..50292c1db2af8cfc142b317d4b3493db28c03f4e 100644 --- a/tests/src/testDoocsPVFactory.cpp +++ b/tests/src/testDoocsPVFactory.cpp @@ -25,57 +25,42 @@ using boost::shared_ptr; // use boost meta-programming to use test case templates // The list of types is an mpl type -typedef boost::mpl::list<int64_t, uint64_t, int32_t, uint32_t, int16_t, - uint16_t, int8_t, uint8_t, float, double> +typedef boost::mpl::list<int64_t, uint64_t, int32_t, uint32_t, int16_t, uint16_t, int8_t, uint8_t, float, double> simple_test_types; EqFct myEqFct("MY_EQ_FCT"); -template <class DOOCS_PRIMITIVE_T, class DOOCS_T> -static void testCreateProcessScalar( - std::shared_ptr<PropertyDescription> const &propertyDescription, - DoocsPVFactory &factory, std::string const &expectedPropertyName) { - +template<class DOOCS_PRIMITIVE_T, class DOOCS_T> +static void testCreateProcessScalar(std::shared_ptr<PropertyDescription> const& propertyDescription, + DoocsPVFactory& factory, std::string const& expectedPropertyName) { // have the variable created and check that it is the right type - boost::shared_ptr<D_fct> doocsVariableAsDFct = - factory.create(propertyDescription); + boost::shared_ptr<D_fct> doocsVariableAsDFct = factory.create(propertyDescription); // get the raw pointer and dynamic cast it to the expected type - DoocsProcessScalar<DOOCS_PRIMITIVE_T, DOOCS_T> *doocsScalarType = - dynamic_cast<DoocsProcessScalar<DOOCS_PRIMITIVE_T, DOOCS_T> *>( - doocsVariableAsDFct.get()); + DoocsProcessScalar<DOOCS_PRIMITIVE_T, DOOCS_T>* doocsScalarType = + dynamic_cast<DoocsProcessScalar<DOOCS_PRIMITIVE_T, DOOCS_T>*>(doocsVariableAsDFct.get()); // if the cast succeeds the factory works as expected we are done - std::string errorMessage = - std::string("testCreateProcessScalar failed for type ") + - typeid(DOOCS_PRIMITIVE_T).name(); + std::string errorMessage = std::string("testCreateProcessScalar failed for type ") + typeid(DOOCS_PRIMITIVE_T).name(); BOOST_CHECK_MESSAGE(doocsScalarType, errorMessage); - errorMessage = - std::string("Error checking property name: expectedPropertyName '") + - expectedPropertyName + "', property_name() '" + - doocsVariableAsDFct->property_name() + "'"; - BOOST_CHECK_MESSAGE(expectedPropertyName == - doocsVariableAsDFct->property_name(), - errorMessage); + errorMessage = std::string("Error checking property name: expectedPropertyName '") + expectedPropertyName + + "', property_name() '" + doocsVariableAsDFct->property_name() + "'"; + BOOST_CHECK_MESSAGE(expectedPropertyName == doocsVariableAsDFct->property_name(), errorMessage); } BOOST_AUTO_TEST_SUITE(PVManagerTestSuite) BOOST_AUTO_TEST_CASE(testAutoCreateScalars) { - std::pair<shared_ptr<ControlSystemPVManager>, shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<shared_ptr<ControlSystemPVManager>, shared_ptr<DevicePVManager>> pvManagers = createPVManager(); shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; shared_ptr<DevicePVManager> devManager = pvManagers.second; devManager->createProcessArray<int32_t>(controlSystemToDevice, "/I/int32", 1); - devManager->createProcessArray<uint32_t>(controlSystemToDevice, "/U/uint32", - 1); + devManager->createProcessArray<uint32_t>(controlSystemToDevice, "/U/uint32", 1); devManager->createProcessArray<int16_t>(controlSystemToDevice, "/I/int16", 1); - devManager->createProcessArray<uint16_t>(controlSystemToDevice, "/U/uint16", - 1); + devManager->createProcessArray<uint16_t>(controlSystemToDevice, "/U/uint16", 1); devManager->createProcessArray<int8_t>(controlSystemToDevice, "/I/int8", 1); devManager->createProcessArray<uint8_t>(controlSystemToDevice, "/U/uint8", 1); devManager->createProcessArray<float>(controlSystemToDevice, "/FP/float", 1); - devManager->createProcessArray<double>(controlSystemToDevice, "/FP/double", - 1); + devManager->createProcessArray<double>(controlSystemToDevice, "/FP/double", 1); DoocsUpdater updater; @@ -83,42 +68,34 @@ BOOST_AUTO_TEST_CASE(testAutoCreateScalars) { // We insert check points with integers so we know where the algorithm kicks // out in case of an error. These checkpoints are always true. - testCreateProcessScalar<int32_t, D_int>( - std::make_shared<AutoPropertyDescription>("I/int32", "I", "int32"), - factory, "int32 "); // DOOCS property names always have a space (and - // potentially some description)" + testCreateProcessScalar<int32_t, D_int>(std::make_shared<AutoPropertyDescription>("I/int32", "I", "int32"), factory, + "int32 "); // DOOCS property names always have a space (and + // potentially some description)" BOOST_CHECK(-32); testCreateProcessScalar<int32_t, D_int>( - std::make_shared<AutoPropertyDescription>("U/uint32", "I", "uint32"), - factory, "uint32 "); + std::make_shared<AutoPropertyDescription>("U/uint32", "I", "uint32"), factory, "uint32 "); BOOST_CHECK(32); - testCreateProcessScalar<int32_t, D_int>( - std::make_shared<AutoPropertyDescription>("I/int16", "I", "int16"), - factory, "int16 "); // DOOCS property names always have a space (and - // potentially some description)" + testCreateProcessScalar<int32_t, D_int>(std::make_shared<AutoPropertyDescription>("I/int16", "I", "int16"), factory, + "int16 "); // DOOCS property names always have a space (and + // potentially some description)" BOOST_CHECK(-16); - testCreateProcessScalar<int32_t, D_int>( - std::make_shared<AutoPropertyDescription>("U/uint16", "I", "uint16"), - factory, "uint16 "); // DOOCS property names always have a space (and - // potentially some description)" + testCreateProcessScalar<int32_t, D_int>(std::make_shared<AutoPropertyDescription>("U/uint16", "I", "uint16"), factory, + "uint16 "); // DOOCS property names always have a space (and + // potentially some description)" BOOST_CHECK(16); - testCreateProcessScalar<int32_t, D_int>( - std::make_shared<AutoPropertyDescription>("I/int8", "I", "int8"), factory, + testCreateProcessScalar<int32_t, D_int>(std::make_shared<AutoPropertyDescription>("I/int8", "I", "int8"), factory, "int8 "); // DOOCS property names always have a space (and potentially // some description)" BOOST_CHECK(-8); - testCreateProcessScalar<int32_t, D_int>( - std::make_shared<AutoPropertyDescription>("U/uint8", "I", "uint8"), - factory, "uint8 "); // DOOCS property names always have a space (and - // potentially some description)" + testCreateProcessScalar<int32_t, D_int>(std::make_shared<AutoPropertyDescription>("U/uint8", "I", "uint8"), factory, + "uint8 "); // DOOCS property names always have a space (and + // potentially some description)" BOOST_CHECK(8); - testCreateProcessScalar<float, D_float>( - std::make_shared<AutoPropertyDescription>("FP/float", "FP", "float"), - factory, "float "); // DOOCS property names always have a space (and - // potentially some description)" + testCreateProcessScalar<float, D_float>(std::make_shared<AutoPropertyDescription>("FP/float", "FP", "float"), factory, + "float "); // DOOCS property names always have a space (and + // potentially some description)" BOOST_CHECK(0.5); - testCreateProcessScalar<double, D_double>( - std::make_shared<AutoPropertyDescription>("FP/double", "FP", "double"), + testCreateProcessScalar<double, D_double>(std::make_shared<AutoPropertyDescription>("FP/double", "FP", "double"), factory, "double "); // DOOCS property names always have a space (and // potentially some description)" BOOST_CHECK(32); @@ -151,17 +128,14 @@ BOOST_AUTO_TEST_CASE(testAutoCreateScalars) { //} BOOST_AUTO_TEST_CASE_TEMPLATE(testCreateSpectrum, T, simple_test_types) { - std::pair<shared_ptr<ControlSystemPVManager>, shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<shared_ptr<ControlSystemPVManager>, shared_ptr<DevicePVManager>> pvManagers = createPVManager(); shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; shared_ptr<DevicePVManager> devManager = pvManagers.second; static const size_t arraySize = 10; // array 1 will have default settings, array 2 custom start and increment - devManager->createProcessArray<T>(controlSystemToDevice, "A/fromDeviceArray1", - arraySize); - devManager->createProcessArray<T>(controlSystemToDevice, "A/fromDeviceArray2", - arraySize); + devManager->createProcessArray<T>(controlSystemToDevice, "A/fromDeviceArray1", arraySize); + devManager->createProcessArray<T>(controlSystemToDevice, "A/fromDeviceArray2", arraySize); // we need this later anyway, do we make a temporary variable auto pvNames = ChimeraTK::getAllVariableNames(csManager); @@ -170,19 +144,15 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(testCreateSpectrum, T, simple_test_types) { DoocsPVFactory factory(&myEqFct, updater, csManager); - auto propertyDescriptions = { - std::make_shared<SpectrumDescription>("A/fromDeviceArray1", "A", - "fromDeviceArray1"), - std::make_shared<SpectrumDescription>("A/fromDeviceArray2", "A", - "fromDeviceArray2")}; + auto propertyDescriptions = {std::make_shared<SpectrumDescription>("A/fromDeviceArray1", "A", "fromDeviceArray1"), + std::make_shared<SpectrumDescription>("A/fromDeviceArray2", "A", "fromDeviceArray2")}; // have the variable created and check that it is the right type - for (auto const &description : propertyDescriptions) { + for(auto const& description : propertyDescriptions) { boost::shared_ptr<D_fct> doocsVariableAsDFct = factory.create(description); // get the raw pointer and dynamic cast it to the expected type - DoocsSpectrum *doocsSpectrum = - dynamic_cast<DoocsSpectrum *>(doocsVariableAsDFct.get()); + DoocsSpectrum* doocsSpectrum = dynamic_cast<DoocsSpectrum*>(doocsVariableAsDFct.get()); // if the cast succeeds the factory works as expected we are done BOOST_REQUIRE(doocsSpectrum); @@ -191,16 +161,15 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(testCreateSpectrum, T, simple_test_types) { // FIXME: add tests for x-axis config } -template <class DOOCS_T> -void testArrayIsCorrectType(DoocsPVFactory &factory, - ArrayDescription::DataType dataType, - std::string name = "fromDeviceArray1") { - auto description = - std::make_shared<ArrayDescription>("A/" + name, "A", name, dataType); +template<class DOOCS_T> +void testArrayIsCorrectType(DoocsPVFactory& factory, + ArrayDescription::DataType dataType, + std::string name = "fromDeviceArray1") { + auto description = std::make_shared<ArrayDescription>("A/" + name, "A", name, dataType); boost::shared_ptr<D_fct> doocsVariableAsDFct = factory.create(description); // get the raw pointer and dynamic cast it to the expected type - DOOCS_T *doocsArray = dynamic_cast<DOOCS_T *>(doocsVariableAsDFct.get()); + DOOCS_T* doocsArray = dynamic_cast<DOOCS_T*>(doocsVariableAsDFct.get()); // if the cast succeeds the factory works as expected we are done BOOST_REQUIRE(doocsArray); @@ -208,26 +177,19 @@ void testArrayIsCorrectType(DoocsPVFactory &factory, } BOOST_AUTO_TEST_CASE_TEMPLATE(testCreateArray, T, simple_test_types) { - std::pair<shared_ptr<ControlSystemPVManager>, shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<shared_ptr<ControlSystemPVManager>, shared_ptr<DevicePVManager>> pvManagers = createPVManager(); shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; shared_ptr<DevicePVManager> devManager = pvManagers.second; static const size_t arraySize = 10; // PVs can only get one decorator, so we have to put one array for each // decorator/doocs type we want to test - devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray1", - arraySize); - devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray2", - arraySize); - devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray3", - arraySize); - devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray4", - arraySize); - devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray5", - arraySize); - devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray6", - arraySize); + devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray1", arraySize); + devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray2", arraySize); + devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray3", arraySize); + devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray4", arraySize); + devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray5", arraySize); + devManager->createProcessArray<T>(deviceToControlSystem, "A/fromDeviceArray6", arraySize); // we need this later anyway, do we make a temporary variable auto pvNames = ChimeraTK::getAllVariableNames(csManager); @@ -236,47 +198,30 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(testCreateArray, T, simple_test_types) { DoocsPVFactory factory(&myEqFct, updater, csManager); - testArrayIsCorrectType<D_bytearray>(factory, ArrayDescription::DataType::Byte, - "fromDeviceArray1"); - testArrayIsCorrectType<D_shortarray>( - factory, ArrayDescription::DataType::Short, "fromDeviceArray2"); - testArrayIsCorrectType<D_intarray>(factory, ArrayDescription::DataType::Int, - "fromDeviceArray3"); - testArrayIsCorrectType<D_longarray>(factory, ArrayDescription::DataType::Long, - "fromDeviceArray4"); - testArrayIsCorrectType<D_floatarray>( - factory, ArrayDescription::DataType::Float, "fromDeviceArray5"); - testArrayIsCorrectType<D_doublearray>( - factory, ArrayDescription::DataType::Double, "fromDeviceArray6"); + testArrayIsCorrectType<D_bytearray>(factory, ArrayDescription::DataType::Byte, "fromDeviceArray1"); + testArrayIsCorrectType<D_shortarray>(factory, ArrayDescription::DataType::Short, "fromDeviceArray2"); + testArrayIsCorrectType<D_intarray>(factory, ArrayDescription::DataType::Int, "fromDeviceArray3"); + testArrayIsCorrectType<D_longarray>(factory, ArrayDescription::DataType::Long, "fromDeviceArray4"); + testArrayIsCorrectType<D_floatarray>(factory, ArrayDescription::DataType::Float, "fromDeviceArray5"); + testArrayIsCorrectType<D_doublearray>(factory, ArrayDescription::DataType::Double, "fromDeviceArray6"); } BOOST_AUTO_TEST_CASE(testAutoCreateArray) { - std::pair<shared_ptr<ControlSystemPVManager>, shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<shared_ptr<ControlSystemPVManager>, shared_ptr<DevicePVManager>> pvManagers = createPVManager(); shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; shared_ptr<DevicePVManager> devManager = pvManagers.second; static const size_t arraySize = 10; - devManager->createProcessArray<int8_t>(controlSystemToDevice, - "A/toDeviceCharArray", arraySize); - devManager->createProcessArray<uint8_t>(controlSystemToDevice, - "A/toDeviceUCharArray", arraySize); - devManager->createProcessArray<int16_t>(controlSystemToDevice, - "A/toDeviceShortArray", arraySize); - devManager->createProcessArray<uint16_t>(controlSystemToDevice, - "A/toDeviceUShortArray", arraySize); - devManager->createProcessArray<int32_t>(controlSystemToDevice, - "A/toDeviceIntArray", arraySize); - devManager->createProcessArray<uint32_t>(controlSystemToDevice, - "A/toDeviceUIntArray", arraySize); - devManager->createProcessArray<int64_t>(controlSystemToDevice, - "A/toDeviceLongArray", arraySize); - devManager->createProcessArray<uint64_t>(controlSystemToDevice, - "A/toDeviceULongArray", arraySize); - devManager->createProcessArray<float>(controlSystemToDevice, - "A/toDeviceFloatArray", arraySize); - devManager->createProcessArray<double>(controlSystemToDevice, - "A/toDeviceDoubleArray", arraySize); + devManager->createProcessArray<int8_t>(controlSystemToDevice, "A/toDeviceCharArray", arraySize); + devManager->createProcessArray<uint8_t>(controlSystemToDevice, "A/toDeviceUCharArray", arraySize); + devManager->createProcessArray<int16_t>(controlSystemToDevice, "A/toDeviceShortArray", arraySize); + devManager->createProcessArray<uint16_t>(controlSystemToDevice, "A/toDeviceUShortArray", arraySize); + devManager->createProcessArray<int32_t>(controlSystemToDevice, "A/toDeviceIntArray", arraySize); + devManager->createProcessArray<uint32_t>(controlSystemToDevice, "A/toDeviceUIntArray", arraySize); + devManager->createProcessArray<int64_t>(controlSystemToDevice, "A/toDeviceLongArray", arraySize); + devManager->createProcessArray<uint64_t>(controlSystemToDevice, "A/toDeviceULongArray", arraySize); + devManager->createProcessArray<float>(controlSystemToDevice, "A/toDeviceFloatArray", arraySize); + devManager->createProcessArray<double>(controlSystemToDevice, "A/toDeviceDoubleArray", arraySize); // we need this later anyway, do we make a temporary variable auto pvNames = ChimeraTK::getAllVariableNames(csManager); @@ -285,46 +230,32 @@ BOOST_AUTO_TEST_CASE(testAutoCreateArray) { DoocsPVFactory factory(&myEqFct, updater, csManager); - testArrayIsCorrectType<D_bytearray>(factory, ArrayDescription::DataType::Auto, - "toDeviceCharArray"); - testArrayIsCorrectType<D_bytearray>(factory, ArrayDescription::DataType::Auto, - "toDeviceUCharArray"); - testArrayIsCorrectType<D_shortarray>( - factory, ArrayDescription::DataType::Auto, "toDeviceShortArray"); - testArrayIsCorrectType<D_shortarray>( - factory, ArrayDescription::DataType::Auto, "toDeviceUShortArray"); - testArrayIsCorrectType<D_intarray>(factory, ArrayDescription::DataType::Auto, - "toDeviceIntArray"); - testArrayIsCorrectType<D_intarray>(factory, ArrayDescription::DataType::Auto, - "toDeviceUIntArray"); - testArrayIsCorrectType<D_longarray>(factory, ArrayDescription::DataType::Auto, - "toDeviceLongArray"); - testArrayIsCorrectType<D_longarray>(factory, ArrayDescription::DataType::Auto, - "toDeviceULongArray"); - testArrayIsCorrectType<D_floatarray>( - factory, ArrayDescription::DataType::Auto, "toDeviceFloatArray"); - testArrayIsCorrectType<D_doublearray>( - factory, ArrayDescription::DataType::Auto, "toDeviceDoubleArray"); + testArrayIsCorrectType<D_bytearray>(factory, ArrayDescription::DataType::Auto, "toDeviceCharArray"); + testArrayIsCorrectType<D_bytearray>(factory, ArrayDescription::DataType::Auto, "toDeviceUCharArray"); + testArrayIsCorrectType<D_shortarray>(factory, ArrayDescription::DataType::Auto, "toDeviceShortArray"); + testArrayIsCorrectType<D_shortarray>(factory, ArrayDescription::DataType::Auto, "toDeviceUShortArray"); + testArrayIsCorrectType<D_intarray>(factory, ArrayDescription::DataType::Auto, "toDeviceIntArray"); + testArrayIsCorrectType<D_intarray>(factory, ArrayDescription::DataType::Auto, "toDeviceUIntArray"); + testArrayIsCorrectType<D_longarray>(factory, ArrayDescription::DataType::Auto, "toDeviceLongArray"); + testArrayIsCorrectType<D_longarray>(factory, ArrayDescription::DataType::Auto, "toDeviceULongArray"); + testArrayIsCorrectType<D_floatarray>(factory, ArrayDescription::DataType::Auto, "toDeviceFloatArray"); + testArrayIsCorrectType<D_doublearray>(factory, ArrayDescription::DataType::Auto, "toDeviceDoubleArray"); } BOOST_AUTO_TEST_CASE(testInt64Scalar) { - std::pair<shared_ptr<ControlSystemPVManager>, shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<shared_ptr<ControlSystemPVManager>, shared_ptr<DevicePVManager>> pvManagers = createPVManager(); shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; shared_ptr<DevicePVManager> devManager = pvManagers.second; - devManager->createProcessArray<int64_t>(controlSystemToDevice, - "I/toDeviceInt", 1); + devManager->createProcessArray<int64_t>(controlSystemToDevice, "I/toDeviceInt", 1); DoocsUpdater updater; DoocsPVFactory factory(&myEqFct, updater, csManager); - ProcessVariable::SharedPtr processScalar = - csManager->getProcessArray<int64_t>("I/toDeviceInt"); + ProcessVariable::SharedPtr processScalar = csManager->getProcessArray<int64_t>("I/toDeviceInt"); - auto description = std::make_shared<AutoPropertyDescription>( - "I/toDeviceInt", "I", "toDeviceInt"); + auto description = std::make_shared<AutoPropertyDescription>("I/toDeviceInt", "I", "toDeviceInt"); auto variable64 = factory.create(description); // 64 bit integer scalars become D_longarrays because there is no 64 bit // scalar representation in Doocs diff --git a/tests/src/testDoocsProcessScalar.cpp b/tests/src/testDoocsProcessScalar.cpp index 42b54cdbc76416b36ebf2ace138fd211dd37eb65..1cb0fcc17595cccaa83c2c667d2fdf5c421a722e 100644 --- a/tests/src/testDoocsProcessScalar.cpp +++ b/tests/src/testDoocsProcessScalar.cpp @@ -18,23 +18,20 @@ using namespace ChimeraTK; // use boost meta-programming to use test case templates // The list of types is an mpl type -typedef boost::mpl::list<int32_t, uint32_t, int16_t, uint16_t, int8_t, uint8_t> - integer_test_types; +typedef boost::mpl::list<int32_t, uint32_t, int16_t, uint16_t, int8_t, uint8_t> integer_test_types; BOOST_AUTO_TEST_SUITE(DoocsProcessScalarTestSuite) BOOST_AUTO_TEST_CASE_TEMPLATE(toDeviceIntegerTypeTest, T, integer_test_types) { - std::pair<boost::shared_ptr<ControlSystemPVManager>, - boost::shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<boost::shared_ptr<ControlSystemPVManager>, boost::shared_ptr<DevicePVManager>> pvManagers = + createPVManager(); boost::shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; boost::shared_ptr<DevicePVManager> devManager = pvManagers.second; DoocsUpdater updater; boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> deviceVariable = - devManager->createProcessArray<T>(controlSystemToDevice, - "toDeviceVariable", 1); + devManager->createProcessArray<T>(controlSystemToDevice, "toDeviceVariable", 1); boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> controlSystemVariable = csManager->getProcessArray<T>("toDeviceVariable"); // set the variables to 0 @@ -42,8 +39,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(toDeviceIntegerTypeTest, T, integer_test_types) { controlSystemVariable->accessData(0) = 0; // just write to the doocs scalar, it is automatically sending - DoocsProcessScalar<T, D_int> doocsScalar(NULL, "TO_DEVICE_VARIABLE", - controlSystemVariable, updater); + DoocsProcessScalar<T, D_int> doocsScalar(NULL, "TO_DEVICE_VARIABLE", controlSystemVariable, updater); BOOST_CHECK(set_doocs_value(doocsScalar, 42) == 0); BOOST_CHECK(controlSystemVariable->accessData(0) == 42); @@ -57,7 +53,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(toDeviceIntegerTypeTest, T, integer_test_types) { // check that the set() overloading is working by calling the function of the // base class (note: cast to a reference, otherwise inheritance/ virtual // functions calls do not work) - BOOST_CHECK(set_doocs_value(static_cast<D_int &>(doocsScalar), -13.) == 0); + BOOST_CHECK(set_doocs_value(static_cast<D_int&>(doocsScalar), -13.) == 0); BOOST_CHECK(controlSystemVariable->accessData(0) == static_cast<T>(-13)); // receive on the device side and check that the value has arrived @@ -69,26 +65,22 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(toDeviceIntegerTypeTest, T, integer_test_types) { // duplication to do DoocsProcessScalar<float, D_float, float> and // DoocsProcessScalar<double, D_double, double> BOOST_AUTO_TEST_CASE(toDeviceFloatTest) { - std::pair<boost::shared_ptr<ControlSystemPVManager>, - boost::shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<boost::shared_ptr<ControlSystemPVManager>, boost::shared_ptr<DevicePVManager>> pvManagers = + createPVManager(); boost::shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; boost::shared_ptr<DevicePVManager> devManager = pvManagers.second; DoocsUpdater updater; boost::shared_ptr<ProcessArray<float>> deviceFloat = - devManager->createProcessArray<float>(controlSystemToDevice, - "toDeviceFloat", 1); - boost::shared_ptr<ProcessArray<float>> controlSystemFloat = - csManager->getProcessArray<float>("toDeviceFloat"); + devManager->createProcessArray<float>(controlSystemToDevice, "toDeviceFloat", 1); + boost::shared_ptr<ProcessArray<float>> controlSystemFloat = csManager->getProcessArray<float>("toDeviceFloat"); // set the variables to 0 deviceFloat->accessData(0) = 0; controlSystemFloat->accessData(0) = 0; // just write to the doocs scalar, it is automatically sending - DoocsProcessScalar<float, D_float> doocsScalar(NULL, "TO_DEVICE_FLOAT", - controlSystemFloat, updater); + DoocsProcessScalar<float, D_float> doocsScalar(NULL, "TO_DEVICE_FLOAT", controlSystemFloat, updater); BOOST_CHECK(set_doocs_value(doocsScalar, 12.125) == 0); BOOST_CHECK(controlSystemFloat->accessData(0) == 12.125); @@ -100,7 +92,7 @@ BOOST_AUTO_TEST_CASE(toDeviceFloatTest) { // check that the value() overloading is working by calling the function of // the base class (note: cast to a reference, otherwise inheritance/ virtual // functions calls do not work) - BOOST_CHECK(set_doocs_value(static_cast<D_float &>(doocsScalar), -13.) == 0); + BOOST_CHECK(set_doocs_value(static_cast<D_float&>(doocsScalar), -13.) == 0); BOOST_CHECK(controlSystemFloat->accessData(0) == -13.); // receive on the device side and check that the value has arrived @@ -109,26 +101,22 @@ BOOST_AUTO_TEST_CASE(toDeviceFloatTest) { } BOOST_AUTO_TEST_CASE(toDeviceDoubleTest) { - std::pair<boost::shared_ptr<ControlSystemPVManager>, - boost::shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<boost::shared_ptr<ControlSystemPVManager>, boost::shared_ptr<DevicePVManager>> pvManagers = + createPVManager(); boost::shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; boost::shared_ptr<DevicePVManager> devManager = pvManagers.second; DoocsUpdater updater; boost::shared_ptr<ProcessArray<double>> deviceDouble = - devManager->createProcessArray<double>(controlSystemToDevice, - "toDeviceDouble", 1); - boost::shared_ptr<ProcessArray<double>> controlSystemDouble = - csManager->getProcessArray<double>("toDeviceDouble"); + devManager->createProcessArray<double>(controlSystemToDevice, "toDeviceDouble", 1); + boost::shared_ptr<ProcessArray<double>> controlSystemDouble = csManager->getProcessArray<double>("toDeviceDouble"); // set the variables to 0 deviceDouble->accessData(0) = 0; controlSystemDouble->accessData(0) = 0; // just write to the doocs scalar, it is automatically sending - DoocsProcessScalar<double, D_double> doocsScalar( - NULL, "TO_DEVICE_DOUBLE", controlSystemDouble, updater); + DoocsProcessScalar<double, D_double> doocsScalar(NULL, "TO_DEVICE_DOUBLE", controlSystemDouble, updater); BOOST_CHECK(set_doocs_value(doocsScalar, 12.125) == 0); BOOST_CHECK(controlSystemDouble->accessData(0) == 12.125); @@ -140,7 +128,7 @@ BOOST_AUTO_TEST_CASE(toDeviceDoubleTest) { // check that the value() overloading is working by calling the function of // the base class (note: cast to a reference, otherwise inheritance/ virtual // functions calls do not work) - BOOST_CHECK(set_doocs_value(static_cast<D_double &>(doocsScalar), -13.) == 0); + BOOST_CHECK(set_doocs_value(static_cast<D_double&>(doocsScalar), -13.) == 0); BOOST_CHECK(controlSystemDouble->accessData(0) == -13.); // receive on the device side and check that the value has arrived @@ -148,29 +136,24 @@ BOOST_AUTO_TEST_CASE(toDeviceDoubleTest) { BOOST_CHECK(deviceDouble->accessData(0) == -13.); } -BOOST_AUTO_TEST_CASE_TEMPLATE(fromDeviceIntegerTypeTest, T, - integer_test_types) { - std::pair<boost::shared_ptr<ControlSystemPVManager>, - boost::shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); +BOOST_AUTO_TEST_CASE_TEMPLATE(fromDeviceIntegerTypeTest, T, integer_test_types) { + std::pair<boost::shared_ptr<ControlSystemPVManager>, boost::shared_ptr<DevicePVManager>> pvManagers = + createPVManager(); boost::shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; boost::shared_ptr<DevicePVManager> devManager = pvManagers.second; DoocsUpdater updater; typename boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> deviceVariable = - devManager->createProcessArray<T>(deviceToControlSystem, - "fromDeviceVariable", 1); - typename boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> - controlSystemVariable = - csManager->getProcessArray<T>("fromDeviceVariable"); + devManager->createProcessArray<T>(deviceToControlSystem, "fromDeviceVariable", 1); + typename boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> controlSystemVariable = + csManager->getProcessArray<T>("fromDeviceVariable"); // set the variables to 0 deviceVariable->accessData(0) = 0; controlSystemVariable->accessData(0) = 0; // initialise the doocs scalar - DoocsProcessScalar<T, D_int> doocsScalar(NULL, "FROM_DEVICE_VARIABLE", - controlSystemVariable, updater); + DoocsProcessScalar<T, D_int> doocsScalar(NULL, "FROM_DEVICE_VARIABLE", controlSystemVariable, updater); BOOST_CHECK(set_doocs_value(doocsScalar, 0) == 0); deviceVariable->accessData(0) = 42; @@ -191,26 +174,22 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(fromDeviceIntegerTypeTest, T, } BOOST_AUTO_TEST_CASE(fromDeviceFloatTest) { - std::pair<boost::shared_ptr<ControlSystemPVManager>, - boost::shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<boost::shared_ptr<ControlSystemPVManager>, boost::shared_ptr<DevicePVManager>> pvManagers = + createPVManager(); boost::shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; boost::shared_ptr<DevicePVManager> devManager = pvManagers.second; DoocsUpdater updater; ProcessArray<float>::SharedPtr deviceVariable = - devManager->createProcessArray<float>(deviceToControlSystem, - "fromDeviceVariable", 1); - ProcessArray<float>::SharedPtr controlSystemVariable = - csManager->getProcessArray<float>("fromDeviceVariable"); + devManager->createProcessArray<float>(deviceToControlSystem, "fromDeviceVariable", 1); + ProcessArray<float>::SharedPtr controlSystemVariable = csManager->getProcessArray<float>("fromDeviceVariable"); // set the variables to 0 deviceVariable->accessData(0) = 0; controlSystemVariable->accessData(0) = 0; // initialise the doocs scalar - DoocsProcessScalar<float, D_float> doocsScalar( - NULL, "FROM_DEVICE_VARIABLE", controlSystemVariable, updater); + DoocsProcessScalar<float, D_float> doocsScalar(NULL, "FROM_DEVICE_VARIABLE", controlSystemVariable, updater); BOOST_CHECK(set_doocs_value(doocsScalar, 0) == 0); deviceVariable->accessData(0) = 12.125; @@ -225,26 +204,22 @@ BOOST_AUTO_TEST_CASE(fromDeviceFloatTest) { } BOOST_AUTO_TEST_CASE(fromDeviceDoubleTest) { - std::pair<boost::shared_ptr<ControlSystemPVManager>, - boost::shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<boost::shared_ptr<ControlSystemPVManager>, boost::shared_ptr<DevicePVManager>> pvManagers = + createPVManager(); boost::shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; boost::shared_ptr<DevicePVManager> devManager = pvManagers.second; DoocsUpdater updater; ProcessArray<double>::SharedPtr deviceVariable = - devManager->createProcessArray<double>(deviceToControlSystem, - "fromDeviceVariable", 1); - ProcessArray<double>::SharedPtr controlSystemVariable = - csManager->getProcessArray<double>("fromDeviceVariable"); + devManager->createProcessArray<double>(deviceToControlSystem, "fromDeviceVariable", 1); + ProcessArray<double>::SharedPtr controlSystemVariable = csManager->getProcessArray<double>("fromDeviceVariable"); // set the variables to 0 deviceVariable->accessData(0) = 0; controlSystemVariable->accessData(0) = 0; // initialise the doocs scalar - DoocsProcessScalar<double, D_double> doocsScalar( - NULL, "FROM_DEVICE_VARIABLE", controlSystemVariable, updater); + DoocsProcessScalar<double, D_double> doocsScalar(NULL, "FROM_DEVICE_VARIABLE", controlSystemVariable, updater); BOOST_CHECK(set_doocs_value(doocsScalar, 0) == 0); deviceVariable->accessData(0) = 12.125; diff --git a/tests/src/testDoocsSpectrum.cpp b/tests/src/testDoocsSpectrum.cpp index dd9ac5bfcc1e69c9d01a9f3a23ea1732669b9c8e..58e371fdfaff0db3a07de10953530a3310bbc955 100644 --- a/tests/src/testDoocsSpectrum.cpp +++ b/tests/src/testDoocsSpectrum.cpp @@ -18,37 +18,29 @@ using namespace boost::unit_test_framework; using namespace ChimeraTK; class TestableDoocsSpectrum : public DoocsSpectrum { -public: - TestableDoocsSpectrum( - EqFct *const eqFct, std::string const &doocsPropertyName, - boost::shared_ptr<typename ChimeraTK::NDRegisterAccessor<float>> const - &processArray, - DoocsUpdater &updater) - : DoocsSpectrum(eqFct, doocsPropertyName, processArray, updater, nullptr, - nullptr) {} + public: + TestableDoocsSpectrum(EqFct* const eqFct, std::string const& doocsPropertyName, + boost::shared_ptr<typename ChimeraTK::NDRegisterAccessor<float>> const& processArray, DoocsUpdater& updater) + : DoocsSpectrum(eqFct, doocsPropertyName, processArray, updater, nullptr, nullptr) {} void sendToDevice() { DoocsSpectrum::sendToDevice(); } }; // use boost meta-programming to use test case templates // The list of types is an mpl type -typedef boost::mpl::list<int32_t, uint32_t, int16_t, uint16_t, int8_t, uint8_t, - float, double> - simple_test_types; +typedef boost::mpl::list<int32_t, uint32_t, int16_t, uint16_t, int8_t, uint8_t, float, double> simple_test_types; BOOST_AUTO_TEST_SUITE(DoocsSpectrumTestSuite) BOOST_AUTO_TEST_CASE_TEMPLATE(toDeviceTest, T, simple_test_types) { - std::pair<boost::shared_ptr<ControlSystemPVManager>, - boost::shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<boost::shared_ptr<ControlSystemPVManager>, boost::shared_ptr<DevicePVManager>> pvManagers = + createPVManager(); boost::shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; boost::shared_ptr<DevicePVManager> devManager = pvManagers.second; static const size_t arraySize = 8; boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> deviceVariable = - devManager->createProcessArray<T>(controlSystemToDevice, - "toDeviceVariable", arraySize); + devManager->createProcessArray<T>(controlSystemToDevice, "toDeviceVariable", arraySize); boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> controlSystemVariable = csManager->getProcessArray<T>("toDeviceVariable"); @@ -57,8 +49,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(toDeviceTest, T, simple_test_types) { // Write to the doocs spectrum and send it. // We use the 'testable' version which exposes sendToDevice, which otherwise // is protected. - TestableDoocsSpectrum doocsSpectrum( - NULL, "someName", getDecorator<float>(controlSystemVariable), updater); + TestableDoocsSpectrum doocsSpectrum(NULL, "someName", getDecorator<float>(controlSystemVariable), updater); // create unique signature for each template parameter // negative factor for signed values @@ -66,7 +57,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(toDeviceTest, T, simple_test_types) { // integer size offset for integer, fractional offset for floating type T offset = (std::numeric_limits<T>::is_integer ? sizeof(T) : 1. / sizeof(T)); - for (size_t i = 0; i < arraySize; ++i) { + for(size_t i = 0; i < arraySize; ++i) { doocsSpectrum.fill_spectrum(i, sign * static_cast<T>(i * i) + offset); } doocsSpectrum.sendToDevice(); @@ -74,39 +65,32 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(toDeviceTest, T, simple_test_types) { // receive on the device side and check that the value has arrived deviceVariable->readNonBlocking(); - std::vector<T> &deviceVector = deviceVariable->accessChannel(0); - for (size_t i = 0; i < arraySize; ++i) { + std::vector<T>& deviceVector = deviceVariable->accessChannel(0); + for(size_t i = 0; i < arraySize; ++i) { std::stringstream errorMessage; - errorMessage << "i = " << i << ", deviceVector[i] = " << deviceVector[i] - << " expected " << sign * static_cast<T>(i * i) + offset; - BOOST_CHECK_MESSAGE(deviceVector[i] == - sign * static_cast<T>(i * i) + offset, - errorMessage.str()); + errorMessage << "i = " << i << ", deviceVector[i] = " << deviceVector[i] << " expected " + << sign * static_cast<T>(i * i) + offset; + BOOST_CHECK_MESSAGE(deviceVector[i] == sign * static_cast<T>(i * i) + offset, errorMessage.str()); } } BOOST_AUTO_TEST_CASE_TEMPLATE(fromDeviceTest, T, simple_test_types) { - std::pair<boost::shared_ptr<ControlSystemPVManager>, - boost::shared_ptr<DevicePVManager>> - pvManagers = createPVManager(); + std::pair<boost::shared_ptr<ControlSystemPVManager>, boost::shared_ptr<DevicePVManager>> pvManagers = + createPVManager(); boost::shared_ptr<ControlSystemPVManager> csManager = pvManagers.first; boost::shared_ptr<DevicePVManager> devManager = pvManagers.second; static const size_t arraySize = 8; typename boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> deviceVariable = - devManager->createProcessArray<T>(deviceToControlSystem, - "fromDeviceVariable", arraySize); - typename boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> - controlSystemVariable = - csManager->getProcessArray<T>("fromDeviceVariable"); + devManager->createProcessArray<T>(deviceToControlSystem, "fromDeviceVariable", arraySize); + typename boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>> controlSystemVariable = + csManager->getProcessArray<T>("fromDeviceVariable"); DoocsUpdater updater; // initialise the doocs spectrum - DoocsSpectrum doocsSpectrum(NULL, "someName", - getDecorator<float>(controlSystemVariable), - updater, nullptr, nullptr); - for (size_t i = 0; i < arraySize; ++i) { + DoocsSpectrum doocsSpectrum(NULL, "someName", getDecorator<float>(controlSystemVariable), updater, nullptr, nullptr); + for(size_t i = 0; i < arraySize; ++i) { doocsSpectrum.fill_spectrum(i, 0); } @@ -114,15 +98,15 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(fromDeviceTest, T, simple_test_types) { T sign = (std::numeric_limits<T>::is_signed ? -1 : 1); T offset = (std::numeric_limits<T>::is_integer ? sizeof(T) : 1. / sizeof(T)); - std::vector<T> &deviceVector = deviceVariable->accessChannel(0); - for (size_t i = 0; i < arraySize; ++i) { + std::vector<T>& deviceVector = deviceVariable->accessChannel(0); + for(size_t i = 0; i < arraySize; ++i) { deviceVector[i] = (sign * static_cast<T>(i * i) + offset); } deviceVariable->write(); // everything should still be 0 on the CS side - std::vector<T> &csVector = controlSystemVariable->accessChannel(0); - for (size_t i = 0; i < arraySize; ++i) { + std::vector<T>& csVector = controlSystemVariable->accessChannel(0); + for(size_t i = 0; i < arraySize; ++i) { BOOST_CHECK(csVector[i] == 0); BOOST_CHECK(doocsSpectrum.read_spectrum(i) == 0); } @@ -131,10 +115,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(fromDeviceTest, T, simple_test_types) { // The actual vector buffer has changed. We have to get the new reference. csVector = controlSystemVariable->accessChannel(0); - for (size_t i = 0; i < arraySize; ++i) { + for(size_t i = 0; i < arraySize; ++i) { BOOST_CHECK(csVector[i] == sign * static_cast<T>(i * i) + offset); - BOOST_CHECK(doocsSpectrum.read_spectrum(i) == - sign * static_cast<T>(i * i) + offset); + BOOST_CHECK(doocsSpectrum.read_spectrum(i) == sign * static_cast<T>(i * i) + offset); } } diff --git a/tests/src/testSplitStringAtFirstSlash.cpp b/tests/src/testSplitStringAtFirstSlash.cpp index f1f5e40c6537b08fbbbca3f7850717d457a5418d..deee9118f4f10c00cd3b0cd9a027ad928d92b522 100644 --- a/tests/src/testSplitStringAtFirstSlash.cpp +++ b/tests/src/testSplitStringAtFirstSlash.cpp @@ -30,8 +30,7 @@ BOOST_AUTO_TEST_CASE(testSpitting) { splitResult = splitStringAtFirstSlash("string/With/twoSlashes"); BOOST_CHECK(splitResult.first == "string"); - BOOST_CHECK(splitResult.second == - "With.twoSlashes"); // second slash gets replaced with dot + BOOST_CHECK(splitResult.second == "With.twoSlashes"); // second slash gets replaced with dot } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/src/testVariableMapper.cpp b/tests/src/testVariableMapper.cpp index 2929af8be851d8b2b272318b96dfd47e5494bc2a..b3ee918bd8320783ded983b94521bb912a6a6c47 100644 --- a/tests/src/testVariableMapper.cpp +++ b/tests/src/testVariableMapper.cpp @@ -7,8 +7,8 @@ using namespace ChimeraTK; BOOST_AUTO_TEST_CASE(testCreation) { - VariableMapper &vm = VariableMapper::getInstance(); - VariableMapper &vm2 = VariableMapper::getInstance(); + VariableMapper& vm = VariableMapper::getInstance(); + VariableMapper& vm2 = VariableMapper::getInstance(); BOOST_CHECK(&vm == &vm2); } @@ -62,7 +62,7 @@ std::set<std::string> generateInputVariables() { } void testXmlParsing(std::string xmlFile) { - VariableMapper &vm = VariableMapper::getInstance(); + VariableMapper& vm = VariableMapper::getInstance(); vm.prepareOutput(xmlFile, generateInputVariables()); // vm.print(); // only used for error handling. nothing tested here @@ -73,7 +73,8 @@ BOOST_AUTO_TEST_CASE(testEvaluateBool) { try { VariableMapper::evaluateBool("fale"); BOOST_ERROR("testEvaluateBool did not throw as expected"); // LCOV_EXCL_LINE - } catch (std::logic_error &e) { + } + catch(std::logic_error& e) { std::cout << " -- For manually checking the exception message for invalid " "bool syntax:\n " << e.what() << std::endl; @@ -93,9 +94,9 @@ BOOST_AUTO_TEST_CASE(testWrongGlobalDirectory) { // location try { testXmlParsing("variableTreeXml/wrongGlobalDirectory.xml"); - BOOST_ERROR( - "testWrongGlobalDirectory did not throw as expected."); // LCOV_EXCL_LINE - } catch (std::logic_error &e) { + BOOST_ERROR("testWrongGlobalDirectory did not throw as expected."); // LCOV_EXCL_LINE + } + catch(std::logic_error& e) { std::cout << " -- For manually checking the exception message for " "directory in global import:\n " << e.what() << std::endl; @@ -105,9 +106,9 @@ BOOST_AUTO_TEST_CASE(testWrongGlobalDirectory) { BOOST_AUTO_TEST_CASE(testImportTooShort) { try { testXmlParsing("variableTreeXml/globalImportPartTooShort.xml"); - BOOST_ERROR( - "testImportTooShort did not throw as expected."); // LCOV_EXCL_LINE - } catch (std::logic_error &e) { + BOOST_ERROR("testImportTooShort did not throw as expected."); // LCOV_EXCL_LINE + } + catch(std::logic_error& e) { std::cout << " -- For manually checking the exception message for too " "short tree depth:\n " << e.what() << std::endl; @@ -117,9 +118,9 @@ BOOST_AUTO_TEST_CASE(testImportTooShort) { BOOST_AUTO_TEST_CASE(testUnknownMainNode) { try { testXmlParsing("variableTreeXml/unknownMainNode.xml"); - BOOST_ERROR( - "testUnknownMainNode did not throw as expected"); // LCOV_EXCL_LINE - } catch (std::logic_error &e) { + BOOST_ERROR("testUnknownMainNode did not throw as expected"); // LCOV_EXCL_LINE + } + catch(std::logic_error& e) { std::cout << " -- For manually checking the exception message for unknown " "main node:\n " << e.what() << std::endl; @@ -129,9 +130,9 @@ BOOST_AUTO_TEST_CASE(testUnknownMainNode) { BOOST_AUTO_TEST_CASE(testUnkownLocationNode) { try { testXmlParsing("variableTreeXml/unknownLocationNode.xml"); - BOOST_ERROR( - "testUnknownLocationNode did not throw as expected"); // LCOV_EXCL_LINE - } catch (std::logic_error &e) { + BOOST_ERROR("testUnknownLocationNode did not throw as expected"); // LCOV_EXCL_LINE + } + catch(std::logic_error& e) { std::cout << " -- For manually checking the exception message for unknown " "location node:\n " << e.what() << std::endl;