From 4ab1f13f937c0ee145284b391ef6d6b29cef38a9 Mon Sep 17 00:00:00 2001
From: Martin Hierholzer <martin.hierholzer@desy.de>
Date: Wed, 4 Jul 2018 13:44:17 +0200
Subject: [PATCH] - Use the ChimeraTK::ReadAnyGroup to determine when to update
 which DOOCS properties. - Replace the std::reference_wrapper<TransferElement>
 with a TransferElementAbstractor.

---
 include/DoocsProcessArray.h  |  5 +++--
 include/DoocsProcessScalar.h | 18 +++++++++---------
 include/DoocsUpdater.h       |  4 ++--
 src/DoocsSpectrum.cc         | 31 +++++++++++++++++--------------
 src/DoocsUpdater.cc          | 16 ++++++----------
 5 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/include/DoocsProcessArray.h b/include/DoocsProcessArray.h
index 1cd0025..f5a5d62 100644
--- a/include/DoocsProcessArray.h
+++ b/include/DoocsProcessArray.h
@@ -4,7 +4,7 @@
 #include <D_spectrum.h>
 #include <boost/noncopyable.hpp>
 
-#include <mtca4u/NDRegisterAccessor.h>
+#include <ChimeraTK/OneDRegisterAccessor.h>
 #include <ChimeraTK/ControlSystemAdapter/ProcessVariableListener.h>
 #include <ChimeraTK/ControlSystemAdapter/ControlSystemSynchronizationUtility.h>
 
@@ -25,7 +25,8 @@ namespace ChimeraTK {
           _processArray( processArray )
       {
         if (processArray->isReadable()){
-          updater.addVariable( *processArray , std::bind(&DoocsProcessArray<DOOCS_T, DOOCS_PRIMITIVE_T>::updateDoocsBuffer, this));
+          updater.addVariable( ChimeraTK::OneDRegisterAccessor<DOOCS_PRIMITIVE_T>(processArray),
+                               std::bind(&DoocsProcessArray<DOOCS_T, DOOCS_PRIMITIVE_T>::updateDoocsBuffer, this));
         }
       }
 
diff --git a/include/DoocsProcessScalar.h b/include/DoocsProcessScalar.h
index f0e654a..42b4928 100644
--- a/include/DoocsProcessScalar.h
+++ b/include/DoocsProcessScalar.h
@@ -2,7 +2,7 @@
 #define __DOOCS_PROCESS_SCALAR_H__
 
 #include <string>
-#include <mtca4u/NDRegisterAccessor.h>
+#include <ChimeraTK/ScalarRegisterAccessor.h>
 #include "DoocsUpdater.h"
 #include <boost/shared_ptr.hpp>
 #include <d_fct.h>
@@ -39,28 +39,28 @@ namespace ChimeraTK {
         this->get_eqfct()->unlock();
       }
     }
-    
-    
+
+
   DoocsProcessScalar( EqFct *eqFct, std::string doocsPropertyName,
                       boost::shared_ptr< typename mtca4u::NDRegisterAccessor<T> > const &processScalar,
                        DoocsUpdater & updater )
     : DOOCS_T(eqFct, doocsPropertyName.c_str()), _processScalar(processScalar)
     {
       if (processScalar->isReadable()){
-        updater.addVariable( *processScalar , std::bind(&DoocsProcessScalar<T, DOOCS_T>::updateDoocsBuffer, this));
+        updater.addVariable( ChimeraTK::ScalarRegisterAccessor<T>(processScalar) , std::bind(&DoocsProcessScalar<T, DOOCS_T>::updateDoocsBuffer, this));
       }
     }
-    
+
   DoocsProcessScalar( std::string doocsPropertyName, EqFct *eqFct,
                       boost::shared_ptr< typename mtca4u::NDRegisterAccessor<T> > const &processScalar,
                        DoocsUpdater & updater )
     : DOOCS_T(doocsPropertyName.c_str(), eqFct), _processScalar(processScalar)
     {
       if (processScalar->isReadable()){
-        updater.addVariable( *processScalar , std::bind(&DoocsProcessScalar<T, DOOCS_T>::updateDoocsBuffer, this));
+        updater.addVariable( ChimeraTK::ScalarRegisterAccessor<T>(processScalar) , std::bind(&DoocsProcessScalar<T, DOOCS_T>::updateDoocsBuffer, this));
       }
     }
-    
+
     /**
      * Override the Doocs set method which is triggered by the RPC calls.
      */
@@ -74,7 +74,7 @@ namespace ChimeraTK {
           _processScalar->write();
       }
     }
-    
+
     /**
      * Override the Doocs auto_init() method, which is called after initialising the value of
      * the property from the config file.
@@ -90,7 +90,7 @@ namespace ChimeraTK {
 
   protected:
     boost::shared_ptr<mtca4u::NDRegisterAccessor<T> > _processScalar;
-    
+
   };
 
 } // namespace ChimeraTK
diff --git a/include/DoocsUpdater.h b/include/DoocsUpdater.h
index 84225c5..50c4b9d 100644
--- a/include/DoocsUpdater.h
+++ b/include/DoocsUpdater.h
@@ -23,9 +23,9 @@ namespace ChimeraTK{
     void run();
     void stop();
 
-    void addVariable( mtca4u::TransferElement & variable, std::function<void ()> updaterFunction);
+    void addVariable( const ChimeraTK::TransferElementAbstractor &variable, std::function<void ()> updaterFunction);
   protected:
-    std::list< std::reference_wrapper< mtca4u::TransferElement > > _elementsToRead;
+    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< mtca4u::TransferElementID, std::vector< std::function<void ()> > > _toDoocsUpdateMap;
diff --git a/src/DoocsSpectrum.cc b/src/DoocsSpectrum.cc
index 5de0a22..19ebfa2 100644
--- a/src/DoocsSpectrum.cc
+++ b/src/DoocsSpectrum.cc
@@ -2,8 +2,11 @@
 
 #include <eq_fct.h>
 
+#include <ChimeraTK/OneDRegisterAccessor.h>
+#include <ChimeraTK/ScalarRegisterAccessor.h>
+
 namespace ChimeraTK {
-  
+
   DoocsSpectrum::DoocsSpectrum( EqFct *eqFct, std::string const & doocsPropertyName,
     boost::shared_ptr<  mtca4u::NDRegisterAccessor<float> > const &processArray,
     DoocsUpdater & updater,
@@ -14,21 +17,21 @@ namespace ChimeraTK {
       _processArray( processArray ), _startAccessor(startAccessor), _incrementAccessor(incrementAccessor)
   {
     if (processArray->isReadable()){
-      updater.addVariable( *processArray , std::bind(&DoocsSpectrum::updateDoocsBuffer, this));
+      updater.addVariable( ChimeraTK::OneDRegisterAccessor<float>(processArray) , std::bind(&DoocsSpectrum::updateDoocsBuffer, this));
     }
     if (startAccessor && startAccessor->isReadable()){
-      updater.addVariable( *startAccessor, std::bind(&DoocsSpectrum::updateParameters, this));
+      updater.addVariable( ChimeraTK::ScalarRegisterAccessor<float>(startAccessor), std::bind(&DoocsSpectrum::updateParameters, this));
     }
     if (incrementAccessor && incrementAccessor->isReadable()){
-      updater.addVariable( *incrementAccessor, std::bind(&DoocsSpectrum::updateParameters, this));
+      updater.addVariable( ChimeraTK::ScalarRegisterAccessor<float>(incrementAccessor), 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::auto_init();
     // send the current value to the device
@@ -39,16 +42,16 @@ namespace ChimeraTK {
 
   void DoocsSpectrum::updateDoocsBuffer(){
     // FIXME: find the efficient memcopying implementation for float
-    std::vector<float> & processVector = _processArray->accessChannel(0); 
-    
+    std::vector<float> & processVector = _processArray->accessChannel(0);
+
     if (this->get_eqfct()){
       this->get_eqfct()->lock();
     }
-    
+
     for(size_t i=0; i < processVector.size(); ++i) {
       fill_spectrum(i, processVector[i]);
     }
-        
+
     if (this->get_eqfct()){
       this->get_eqfct()->unlock();
     }
@@ -70,25 +73,25 @@ namespace ChimeraTK {
     }else{
       increment=this->spec_inc();
     }
-    
+
     spectrum_parameter( this->spec_time(), start, increment, this->spec_status() );
     if (this->get_eqfct()){
       this->get_eqfct()->unlock();
     }
   }
-  
+
   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); 
+    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();
   }
-  
+
 } // namespace ChimeraTK
 
 
diff --git a/src/DoocsUpdater.cc b/src/DoocsUpdater.cc
index 1421038..158ff82 100644
--- a/src/DoocsUpdater.cc
+++ b/src/DoocsUpdater.cc
@@ -4,13 +4,13 @@
 
 namespace ChimeraTK{
 
-  void DoocsUpdater::addVariable( mtca4u::TransferElement & variable, std::function<void ()> updaterFunction){
+  void DoocsUpdater::addVariable( const TransferElementAbstractor &variable, 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( std::reference_wrapper< mtca4u::TransferElement > (variable) );
+      _elementsToRead.push_back(variable);
     }
 
     _toDoocsUpdateMap[variable.getId()].push_back(updaterFunction);
@@ -18,8 +18,8 @@ namespace ChimeraTK{
 
   void DoocsUpdater::update(){
     for ( auto & transferElem : _elementsToRead ){
-      if (transferElem.get().readLatest()){
-        for (auto & updaterFunction : _toDoocsUpdateMap[transferElem.get().getId()]){
+      if (transferElem.readLatest()){
+        for (auto & updaterFunction : _toDoocsUpdateMap[transferElem.getId()]){
           updaterFunction();
         }
       }
@@ -27,16 +27,12 @@ namespace ChimeraTK{
   }
 
   void DoocsUpdater::updateLoop(){
+    ReadAnyGroup group(_elementsToRead.begin(), _elementsToRead.end());
     while(true){
-      /*
-      auto updatedElement = ChimeraTK::readAny(_elementsToRead);
+      auto updatedElement = group.waitAny();
       for (auto & updaterFunction : _toDoocsUpdateMap[updatedElement]){
         updaterFunction();
       }
-      */
-      /// @todo FIXME this is a temporary (?) work-around for the slow readAny()
-      update();
-      boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
     }
   }
 
-- 
GitLab