From 04ac72d49f8111d99f6919f7a75a66bf43042cee Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@student.kit.edu>
Date: Wed, 3 Apr 2019 14:01:06 +0200
Subject: [PATCH] Added Collector

---
 VirtualRobot/CMakeLists.txt              |  3 ++
 VirtualRobot/MJCF/visitors.h             |  3 ++
 VirtualRobot/MJCF/visitors/Collector.cpp |  7 ++++
 VirtualRobot/MJCF/visitors/Collector.h   | 49 ++++++++++++++++++++++++
 4 files changed, 62 insertions(+)
 create mode 100644 VirtualRobot/MJCF/visitors.h
 create mode 100644 VirtualRobot/MJCF/visitors/Collector.cpp
 create mode 100644 VirtualRobot/MJCF/visitors/Collector.h

diff --git a/VirtualRobot/CMakeLists.txt b/VirtualRobot/CMakeLists.txt
index 64ba542d4..d8608e962 100644
--- a/VirtualRobot/CMakeLists.txt
+++ b/VirtualRobot/CMakeLists.txt
@@ -329,6 +329,7 @@ SET(SOURCES
     MJCF/elements/types/statistic.cpp
     MJCF/elements/types/tendon.cpp
     MJCF/elements/types/visual.cpp
+    MJCF/visitors/Collector.cpp
     
     Nodes/CameraSensor.cpp
     Nodes/CameraSensorFactory.cpp
@@ -538,6 +539,8 @@ SET(INCLUDES
     MJCF/elements/types/statistic.h
     MJCF/elements/types/tendon.h
     MJCF/elements/types/visual.h
+    MJCF/visitors.h
+    MJCF/visitors/Collector.h
     
     Nodes/CameraSensor.h
     Nodes/CameraSensorFactory.h
diff --git a/VirtualRobot/MJCF/visitors.h b/VirtualRobot/MJCF/visitors.h
new file mode 100644
index 000000000..f2cec5530
--- /dev/null
+++ b/VirtualRobot/MJCF/visitors.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include "visitors/Collector.h"
diff --git a/VirtualRobot/MJCF/visitors/Collector.cpp b/VirtualRobot/MJCF/visitors/Collector.cpp
new file mode 100644
index 000000000..3f838bce5
--- /dev/null
+++ b/VirtualRobot/MJCF/visitors/Collector.cpp
@@ -0,0 +1,7 @@
+#include "Collector.h"
+
+
+namespace mjcf
+{
+
+}
diff --git a/VirtualRobot/MJCF/visitors/Collector.h b/VirtualRobot/MJCF/visitors/Collector.h
new file mode 100644
index 000000000..bb8ed7e45
--- /dev/null
+++ b/VirtualRobot/MJCF/visitors/Collector.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include "../elements.h"
+
+
+namespace mjcf
+{
+    
+    /**
+     * @brief A visitor that collects all elements of the specified type.
+     */
+    template <class ElementT>
+    class Collector : public Visitor
+    {
+    public:
+        
+        static std::vector<ElementT> collect(Document& document, AnyElement root);
+        
+        Collector(Document& document) : Visitor(document) {}
+        
+        // Visitor interface
+        virtual bool visitEnter(const AnyElement& element) override
+        {
+            if (element.is<ElementT>())
+            {
+                collected.push_back(element.as<ElementT>());
+            }
+            return true;
+        }
+        
+        std::vector<ElementT>& getCollected() { return collected; }
+        const std::vector<ElementT>& getCollected() const  { return collected; }
+        
+        
+    private:
+        
+        std::vector<ElementT> collected;
+        
+    };
+    
+    template <class ElementT>
+    std::vector<ElementT> Collector<ElementT>::collect(Document& document, AnyElement root)
+    {
+        mjcf::Collector<ElementT> collector(document);
+        root.accept(collector);
+        return collector.getCollected();
+    }
+}
+
-- 
GitLab