From f7a76139a668a33ee0a168aa7e0d2fa7c8e82d68 Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Tue, 14 Jun 2022 10:46:43 +0200
Subject: [PATCH] Add and use typedef for entity info retrieval function

---
 .../libraries/armem_gui/MemoryViewer.cpp      | 77 ++++++++++---------
 .../armem_gui/instance/InstanceView.cpp       | 13 ++--
 .../libraries/armem_gui/memory/GroupBox.cpp   |  4 +-
 .../libraries/armem_gui/memory/GroupBox.h     |  3 +-
 .../prediction_widget/PredictionWidget.cpp    | 14 ++--
 .../prediction_widget/PredictionWidget.h      | 22 +++---
 6 files changed, 65 insertions(+), 68 deletions(-)

diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
index 1a715ee38..bfe6a2b3c 100644
--- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
+++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
@@ -76,46 +76,49 @@ namespace armarx::armem::gui
         processQueryResultTimer->start();
 
         // Memory View
-        memoryGroup = new armem::gui::MemoryGroupBox(
-            [this](const MemoryID& entityID)
-                -> std::pair<aron::type::ObjectPtr, std::vector<PredictionEngine>>
+        auto retrieveEntityInfo = [this](const MemoryID& entityID) -> PredictionWidget::EntityInfo
+        {
+            client::Reader reader = memoryReaders.at(entityID.memoryName);
+            if (!reader.predictionPrx)
             {
-                client::Reader reader = memoryReaders.at(entityID.memoryName);
-                if (!reader.predictionPrx)
-                {
-                    std::stringstream sstream;
-                    sstream << "Predictions are not available for memory '" << entityID.memoryName
-                       << "'.";
-                    this->statusLabel->setText(QString::fromStdString(sstream.str()));
-                    return {nullptr, {}};
-                }
-                std::map<MemoryID, std::vector<PredictionEngine>> predictionEngines;
-                client::QueryResult queryResult;
-                try
-                {
-                    predictionEngines = reader.getAvailablePredictionEngines();
-                    queryResult = reader.queryMemoryIDs({entityID}, DataMode::NoData);
-                }
-                catch (const Ice::LocalException& e)
-                {
-                    std::stringstream sstream;
-                    sstream << "Could not get prediction engines and type from memory: "
-                            << e.what();
-                    this->statusLabel->setText(QString::fromStdString(sstream.str()));
-                    return {nullptr, {}};
-                }
-                aron::type::ObjectPtr entityType;
-                if (queryResult.success)
+                std::stringstream sstream;
+                sstream << "Predictions are not available for memory '" << entityID.memoryName
+                   << "'.";
+                this->statusLabel->setText(QString::fromStdString(sstream.str()));
+                return {};
+            }
+
+            std::map<MemoryID, std::vector<PredictionEngine>> predictionEngines;
+            client::QueryResult queryResult;
+            try
+            {
+                predictionEngines = reader.getAvailablePredictionEngines();
+                queryResult = reader.queryMemoryIDs({entityID}, DataMode::NoData);
+            }
+            catch (const Ice::LocalException& e)
+            {
+                std::stringstream sstream;
+                sstream << "Could not get prediction engines and type from memory: "
+                        << e.what();
+                this->statusLabel->setText(QString::fromStdString(sstream.str()));
+                return {nullptr, {}};
+            }
+
+            aron::type::ObjectPtr entityType;
+            if (queryResult.success)
+            {
+                auto* providerSegment = queryResult.memory.findProviderSegment(entityID);
+                if (providerSegment != nullptr)
                 {
-                    auto* providerSegment = queryResult.memory.findProviderSegment(entityID);
-                    if (providerSegment != nullptr)
-                    {
-                        entityType = providerSegment->aronType();
-                    }
+                    entityType = providerSegment->aronType();
                 }
-                return {entityType,
-                        armem::accumulateEntriesContainingID(predictionEngines, entityID)};
-            });
+            }
+            return PredictionWidget::EntityInfo{
+                .type = entityType,
+                .engines = armem::accumulateEntriesContainingID(predictionEngines, entityID)
+            };
+        };
+        memoryGroup = new armem::gui::MemoryGroupBox(std::move(retrieveEntityInfo));
 
         armarx::gui::replaceWidget(memoryGroupBox, memoryGroup, memoryGroupBoxParentLayout);
         ARMARX_CHECK_NULL(memoryGroupBox);
diff --git a/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp b/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp
index 6574c2c19..8267e1fc5 100644
--- a/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp
+++ b/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp
@@ -140,15 +140,12 @@ namespace armarx::armem::gui::instance
 
     void InstanceView::prepareTreeContextMenu(const QPoint& pos)
     {
-        auto* menu = buildActionsMenu(pos);
-
-        if (menu->actions().isEmpty())
-        {
-            emit actionsMenuRequested(currentInstance->id(), this, tree->mapToGlobal(pos), nullptr);
-        }
-        else
+        if (currentInstance.has_value())
         {
-            emit actionsMenuRequested(currentInstance->id(), this, tree->mapToGlobal(pos), menu);
+            auto* menu = buildActionsMenu(pos);
+
+            emit actionsMenuRequested(currentInstance->id(), this, tree->mapToGlobal(pos),
+                                      menu->actions().isEmpty() ? nullptr : menu);
         }
     }
 
diff --git a/source/RobotAPI/libraries/armem_gui/memory/GroupBox.cpp b/source/RobotAPI/libraries/armem_gui/memory/GroupBox.cpp
index 3ac7c7f56..2c34cb5b3 100644
--- a/source/RobotAPI/libraries/armem_gui/memory/GroupBox.cpp
+++ b/source/RobotAPI/libraries/armem_gui/memory/GroupBox.cpp
@@ -11,9 +11,7 @@
 namespace armarx::armem::gui::memory
 {
 
-    GroupBox::GroupBox(
-        std::function<std::pair<aron::type::ObjectPtr, std::vector<PredictionEngine>>(
-            const MemoryID&)> entityInfoRetriever)
+    GroupBox::GroupBox(PredictionWidget::GetEntityInfoFn&& entityInfoRetriever)
     {
         QVBoxLayout* layout = new QVBoxLayout();
         this->setLayout(layout);
diff --git a/source/RobotAPI/libraries/armem_gui/memory/GroupBox.h b/source/RobotAPI/libraries/armem_gui/memory/GroupBox.h
index 51682bcc4..cc9f376ee 100644
--- a/source/RobotAPI/libraries/armem_gui/memory/GroupBox.h
+++ b/source/RobotAPI/libraries/armem_gui/memory/GroupBox.h
@@ -21,8 +21,7 @@ namespace armarx::armem::gui::memory
         using This = GroupBox;
 
     public:
-        GroupBox(std::function<std::pair<aron::type::ObjectPtr, std::vector<PredictionEngine>>(
-                     const MemoryID&)> entityInfoRetriever);
+        GroupBox(PredictionWidget::GetEntityInfoFn&& entityInfoRetriever);
 
         TreeWidget* tree() const;
         QGroupBox* queryGroup() const;
diff --git a/source/RobotAPI/libraries/armem_gui/prediction_widget/PredictionWidget.cpp b/source/RobotAPI/libraries/armem_gui/prediction_widget/PredictionWidget.cpp
index 10ae1e7bc..cfd7e524e 100644
--- a/source/RobotAPI/libraries/armem_gui/prediction_widget/PredictionWidget.cpp
+++ b/source/RobotAPI/libraries/armem_gui/prediction_widget/PredictionWidget.cpp
@@ -32,16 +32,14 @@
 
 namespace armarx::armem::gui
 {
-    PredictionWidget::PredictionWidget(
-        std::function<std::pair<aron::type::ObjectPtr, std::vector<PredictionEngine>>(
-            const MemoryID&)> entityInfoRetriever) :
+    PredictionWidget::PredictionWidget(GetEntityInfoFn&& entityInfoRetriever) :
         memoryEntity(new QLineEdit()),
         timestampInputSelector(new QComboBox()),
         timestampLayout(new QHBoxLayout()),
         instanceSpinner(new QSpinBox()),
         predictionEngineSelector(new QComboBox()),
         predictButton(new QPushButton("Make prediction")),
-        entityInfoRetriever(std::move(entityInfoRetriever))
+        entityInfoRetriever(entityInfoRetriever)
     {
         auto* vlayout = new QVBoxLayout();
         auto* hlayout = new QHBoxLayout();
@@ -107,10 +105,10 @@ namespace armarx::armem::gui
         predictionEngineSelector->clear();
         if (!entityID.hasGap() && entityID.hasEntityName())
         {
-            auto [type, engines] = entityInfoRetriever(entityID);
-            currentType = type;
-            currentEngines = engines;
-            for (const auto& engine : engines)
+            auto info = entityInfoRetriever(entityID);
+            currentType = info.type;
+            currentEngines = info.engines;
+            for (const auto& engine : info.engines)
             {
                 predictionEngineSelector->addItem(QString::fromStdString(engine.engineID));
             }
diff --git a/source/RobotAPI/libraries/armem_gui/prediction_widget/PredictionWidget.h b/source/RobotAPI/libraries/armem_gui/prediction_widget/PredictionWidget.h
index b2beb84bd..460a1e94f 100644
--- a/source/RobotAPI/libraries/armem_gui/prediction_widget/PredictionWidget.h
+++ b/source/RobotAPI/libraries/armem_gui/prediction_widget/PredictionWidget.h
@@ -45,14 +45,17 @@ namespace armarx::armem::gui
     {
         Q_OBJECT // NOLINT
 
-        public :
-        PredictionWidget(
-            std::function<std::pair<aron::type::ObjectPtr, std::vector<PredictionEngine>>(
-                const MemoryID&)> entityInfoRetriever);
+    public:
 
-        // setEditingFinished -> get type and prediction engines via MemoryViewer, store them here.
-        // Use them to set the type of the aron data in makePrediction and the contents of the ComboBox.
-        // Filter here first, though, to check whether the entered text is a valid entity ID.
+        struct EntityInfo
+        {
+            aron::type::ObjectPtr type = nullptr;
+            std::vector<PredictionEngine> engines;
+        };
+        using GetEntityInfoFn = std::function<EntityInfo(const MemoryID&)>;
+
+    public:
+        PredictionWidget(GetEntityInfoFn&& entityInfoRetriever);
 
     signals:
         void makePrediction(const MemoryID& entityID,
@@ -70,9 +73,8 @@ namespace armarx::armem::gui
         QPushButton* predictButton;
 
         std::map<QString, TimestampInput*> timestampInputs;
-        std::function<std::pair<aron::type::ObjectPtr, std::vector<PredictionEngine>>(
-            const MemoryID&)>
-            entityInfoRetriever;
+
+        GetEntityInfoFn entityInfoRetriever;
 
         // Type of currently entered entity and engine availability for it
         aron::type::ObjectPtr currentType;
-- 
GitLab