From c021a1d2ddf2d8465a99bfa2cd65870b87b73caa Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Mon, 30 Aug 2021 10:35:45 +0200
Subject: [PATCH] Refactor client plugins

---
 .../RobotAPI/libraries/armem/CMakeLists.txt   | 17 ++--
 source/RobotAPI/libraries/armem/client.h      |  9 +-
 .../armem/client/ComponentPlugin.cpp          | 41 --------
 .../libraries/armem/client/ComponentPlugin.h  | 47 ----------
 .../armem/client/ReaderComponentPlugin.cpp    | 48 ----------
 .../armem/client/ReaderComponentPlugin.h      | 67 -------------
 .../armem/client/WriterComponentPlugin.cpp    | 59 ------------
 .../armem/client/WriterComponentPlugin.h      | 64 -------------
 .../armem/client/forward_declarations.h       | 16 +++-
 .../RobotAPI/libraries/armem/client/plugins.h | 13 +++
 .../client/plugins/ListeningPluginUser.cpp    | 26 ++++++
 .../client/plugins/ListeningPluginUser.h      | 35 +++++++
 .../Plugin.cpp}                               | 58 ++++--------
 .../Plugin.h}                                 | 93 +++++--------------
 .../armem/client/plugins/PluginUser.cpp       | 34 +++++++
 .../armem/client/plugins/PluginUser.h         | 48 ++++++++++
 .../armem/server/ComponentPlugin.cpp          | 15 ++-
 .../libraries/armem/server/ComponentPlugin.h  | 35 +++----
 18 files changed, 252 insertions(+), 473 deletions(-)
 delete mode 100644 source/RobotAPI/libraries/armem/client/ComponentPlugin.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/client/ComponentPlugin.h
 delete mode 100644 source/RobotAPI/libraries/armem/client/ReaderComponentPlugin.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/client/ReaderComponentPlugin.h
 delete mode 100644 source/RobotAPI/libraries/armem/client/WriterComponentPlugin.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/client/WriterComponentPlugin.h
 create mode 100644 source/RobotAPI/libraries/armem/client/plugins.h
 create mode 100644 source/RobotAPI/libraries/armem/client/plugins/ListeningPluginUser.cpp
 create mode 100644 source/RobotAPI/libraries/armem/client/plugins/ListeningPluginUser.h
 rename source/RobotAPI/libraries/armem/client/{MemoryNameSystemComponentPlugin.cpp => plugins/Plugin.cpp} (60%)
 rename source/RobotAPI/libraries/armem/client/{MemoryNameSystemComponentPlugin.h => plugins/Plugin.h} (51%)
 create mode 100644 source/RobotAPI/libraries/armem/client/plugins/PluginUser.cpp
 create mode 100644 source/RobotAPI/libraries/armem/client/plugins/PluginUser.h

diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt
index 1fdf140a9..e6c3f1a85 100644
--- a/source/RobotAPI/libraries/armem/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem/CMakeLists.txt
@@ -60,13 +60,13 @@ set(LIB_FILES
     core/error/ArMemError.cpp
     core/error/mns.cpp
 
-    client/ComponentPlugin.cpp
     client/MemoryNameSystem.cpp
-    client/MemoryNameSystemComponentPlugin.cpp
     client/Reader.cpp
-    client/ReaderComponentPlugin.cpp
     client/Writer.cpp
-    client/WriterComponentPlugin.cpp
+
+    client/plugins/ListeningPluginUser.cpp
+    client/plugins/PluginUser.cpp
+    client/plugins/Plugin.cpp
 
     client/util/MemoryListener.cpp
     client/util/SimpleReaderBase.cpp
@@ -155,13 +155,14 @@ set(LIB_HEADERS
 
     client.h
     client/forward_declarations.h
-    client/ComponentPlugin.h
     client/MemoryNameSystem.h
-    client/MemoryNameSystemComponentPlugin.h
     client/Reader.h
-    client/ReaderComponentPlugin.h
     client/Writer.h
-    client/WriterComponentPlugin.h
+
+    client/plugins.h
+    client/plugins/ListeningPluginUser.h
+    client/plugins/PluginUser.h
+    client/plugins/Plugin.h
 
     client/query.h
     client/Query.h
diff --git a/source/RobotAPI/libraries/armem/client.h b/source/RobotAPI/libraries/armem/client.h
index 834d62ab4..fa61feb25 100644
--- a/source/RobotAPI/libraries/armem/client.h
+++ b/source/RobotAPI/libraries/armem/client.h
@@ -1,15 +1,12 @@
 #pragma once
 
-#include "client/ComponentPlugin.h"
 #include "client/MemoryNameSystem.h"
-#include "client/MemoryNameSystemComponentPlugin.h"
+#include "client/plugins.h"
 #include "client/Query.h"
 #include "client/query/Builder.h"
 #include "client/query/query_fns.h"
 #include "client/Reader.h"
-#include "client/ReaderComponentPlugin.h"
 #include "client/Writer.h"
-#include "client/WriterComponentPlugin.h"
 
 
 namespace armarx::armem
@@ -23,8 +20,4 @@ namespace armarx::armem
     using ClientQueryBuilder = client::query::Builder;
     namespace client_query_fns = client::query_fns;
 
-    using ClientComponentPluginUser = client::ComponentPluginUser;
-    using ClientReaderComponentPluginUser = client::ReaderComponentPluginUser;
-    using ClientWriterComponentPluginUser = client::WriterComponentPluginUser;
-
 }
diff --git a/source/RobotAPI/libraries/armem/client/ComponentPlugin.cpp b/source/RobotAPI/libraries/armem/client/ComponentPlugin.cpp
deleted file mode 100644
index a88f374d6..000000000
--- a/source/RobotAPI/libraries/armem/client/ComponentPlugin.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include <RobotAPI/libraries/armem/client/ComponentPlugin.h>
-
-
-// ArmarX
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-// RobotAPI
-#include <RobotAPI/libraries/armem/core/error.h>
-
-
-armarx::armem::client::ComponentPluginUser::ComponentPluginUser()
-{
-    // pass
-}
-
-
-armarx::armem::client::ComponentPluginUser::~ComponentPluginUser()
-{
-    // pass
-}
-
-
-void
-armarx::armem::client::ComponentPluginUser::setMemoryServer(server::MemoryInterfacePrx memory)
-{
-    setReadingMemoryServer(memory);
-    setWritingMemoryServer(memory);
-}
-
-
-armarx::armem::data::WaitForMemoryResult
-armarx::armem::client::ComponentPluginUser::useMemoryServer(const std::string& memoryName)
-{
-    armem::data::WaitForMemoryResult result;
-    result.proxy = memoryNameSystem.useServer(MemoryID().withMemoryName(memoryName));
-    if (result.proxy)
-    {
-        setMemoryServer(result.proxy);
-    }
-    return result;
-}
diff --git a/source/RobotAPI/libraries/armem/client/ComponentPlugin.h b/source/RobotAPI/libraries/armem/client/ComponentPlugin.h
deleted file mode 100644
index ae3f26b26..000000000
--- a/source/RobotAPI/libraries/armem/client/ComponentPlugin.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#pragma once
-
-
-// ArmarX
-#include <ArmarXCore/core/ComponentPlugin.h>
-
-// RobotAPI
-#include <RobotAPI/interface/armem/server/MemoryInterface.h>
-#include <RobotAPI/libraries/armem/client/ReaderComponentPlugin.h>
-#include <RobotAPI/libraries/armem/client/WriterComponentPlugin.h>
-
-
-
-namespace armarx::armem::client
-{
-
-    /**
-     * @brief Utility for connecting a Client via Ice to ArMem.
-     */
-    class ComponentPluginUser :
-        virtual public ReaderComponentPluginUser,
-        virtual public WriterComponentPluginUser
-    {
-
-    public:
-
-        ComponentPluginUser();
-        ~ComponentPluginUser() override;
-
-
-        /**
-         * @brief Resolve the given memory name, add it as dependency and update the readers and writers.
-         * @param The memory's name.
-         * @return The result of `waitForMemory()`.
-         * @see `armem::MemoryNameSystemComponentPluginUser::useMemory()`
-         */
-        virtual armem::data::WaitForMemoryResult useMemoryServer(const std::string& memoryName) override;
-        using MemoryNameSystemComponentPluginUser::useMemoryServer;
-
-
-    protected:
-
-        void setMemoryServer(server::MemoryInterfacePrx memory);
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/client/ReaderComponentPlugin.cpp b/source/RobotAPI/libraries/armem/client/ReaderComponentPlugin.cpp
deleted file mode 100644
index c2e4d5ed6..000000000
--- a/source/RobotAPI/libraries/armem/client/ReaderComponentPlugin.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <RobotAPI/libraries/armem/client/ReaderComponentPlugin.h>
-
-
-// ArmarX
-#include <ArmarXCore/core/Component.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-// RobotAPI
-#include <RobotAPI/libraries/armem/core/error.h>
-
-
-namespace armarx::armem::client::plugins
-{
-    ReaderComponentPlugin::ReaderComponentPlugin(ManagedIceObject& parent, std::string pre) :
-        ComponentPlugin(parent, pre)
-    {
-        addPlugin(mnsPlugin, pre);
-        addPluginDependency(mnsPlugin);
-    }
-
-
-    ReaderComponentPlugin::~ReaderComponentPlugin()
-    {
-    }
-}
-
-
-
-namespace armarx::armem::client
-{
-    ReaderComponentPluginUser::ReaderComponentPluginUser()
-    {
-        addPlugin(plugin);
-    }
-
-
-    ReaderComponentPluginUser::~ReaderComponentPluginUser()
-    {
-    }
-
-
-    void
-    ReaderComponentPluginUser::setReadingMemoryServer(server::ReadingMemoryInterfacePrx memory)
-    {
-        memoryReader.setReadingMemory(memory);
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/client/ReaderComponentPlugin.h b/source/RobotAPI/libraries/armem/client/ReaderComponentPlugin.h
deleted file mode 100644
index 059c5f93d..000000000
--- a/source/RobotAPI/libraries/armem/client/ReaderComponentPlugin.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#pragma once
-
-
-// STD/STL
-#include <vector>
-
-// ArmarX
-#include <ArmarXCore/core/ComponentPlugin.h>
-
-// RobotAPI
-#include <RobotAPI/libraries/aron/core/navigator/data/AllNavigators.h>
-#include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
-#include <RobotAPI/interface/armem/server/ReadingMemoryInterface.h>
-
-#include <RobotAPI/libraries/armem/client/Reader.h>
-#include <RobotAPI/libraries/armem/client/MemoryNameSystemComponentPlugin.h>
-
-
-namespace armarx::armem::client::plugins
-{
-
-    class ReaderComponentPlugin : public ComponentPlugin
-    {
-
-    public:
-
-        ReaderComponentPlugin(ManagedIceObject& parent, std::string pre);
-        ~ReaderComponentPlugin() override;
-
-
-    private:
-
-        plugins::MemoryNameSystemComponentPlugin* mnsPlugin = nullptr;
-
-    };
-
-}
-
-
-namespace armarx::armem::client
-{
-
-    class ReaderComponentPluginUser :
-        virtual public ManagedIceObject,
-        virtual public MemoryNameSystemComponentPluginUser
-    {
-
-    public:
-
-        ReaderComponentPluginUser();
-        ~ReaderComponentPluginUser() override;
-
-
-    protected:
-
-        void setReadingMemoryServer(server::ReadingMemoryInterfacePrx memory);
-
-        Reader memoryReader;
-
-
-    private:
-
-        plugins::ReaderComponentPlugin* plugin = nullptr;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/client/WriterComponentPlugin.cpp b/source/RobotAPI/libraries/armem/client/WriterComponentPlugin.cpp
deleted file mode 100644
index d4b95ca35..000000000
--- a/source/RobotAPI/libraries/armem/client/WriterComponentPlugin.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <RobotAPI/libraries/armem/client/WriterComponentPlugin.h>
-
-
-// ArmarX
-#include <ArmarXCore/core/Component.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-// RobotAPI
-#include <RobotAPI/libraries/armem/core/error.h>
-
-
-namespace armarx::armem::client::plugins
-{
-    WriterComponentPlugin::WriterComponentPlugin(ManagedIceObject& parent, std::string pre) :
-        ComponentPlugin(parent, pre)
-    {
-        addPlugin(mnsPlugin, pre);
-        addPluginDependency(mnsPlugin);
-    }
-
-    WriterComponentPlugin::~WriterComponentPlugin()
-    {
-    }
-}
-
-
-namespace armarx::armem::client
-{
-    WriterComponentPluginUser::WriterComponentPluginUser()
-    {
-        addPlugin(plugin);
-    }
-
-
-    WriterComponentPluginUser::~WriterComponentPluginUser()
-    {
-        // pass
-    }
-
-
-    void
-    WriterComponentPluginUser::setWritingMemoryServer(server::WritingMemoryInterfacePrx memory)
-    {
-        memoryWriter.setWritingMemory(memory);
-    }
-
-
-    armem::data::WaitForMemoryResult WriterComponentPluginUser::useMemoryServer(const std::string& memoryName)
-    {
-        armem::data::WaitForMemoryResult result;
-        result.proxy = memoryNameSystem.useServer(MemoryID().withMemoryName(memoryName));
-        if (result.proxy)
-        {
-            setWritingMemoryServer(result.proxy);
-        }
-        return result;
-    }
-}
-
diff --git a/source/RobotAPI/libraries/armem/client/WriterComponentPlugin.h b/source/RobotAPI/libraries/armem/client/WriterComponentPlugin.h
deleted file mode 100644
index 3ae9a66bf..000000000
--- a/source/RobotAPI/libraries/armem/client/WriterComponentPlugin.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#pragma once
-
-
-// ArmarX
-#include <ArmarXCore/core/ComponentPlugin.h>
-
-// RobotAPI
-#include <RobotAPI/libraries/aron/core/navigator/data/AllNavigators.h>
-#include <RobotAPI/interface/armem/server/WritingMemoryInterface.h>
-#include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
-
-#include <RobotAPI/libraries/armem/client/Writer.h>
-#include <RobotAPI/libraries/armem/client/MemoryNameSystemComponentPlugin.h>
-
-
-namespace armarx::armem::client::plugins
-{
-
-    class WriterComponentPlugin : public ComponentPlugin
-    {
-
-    public:
-
-        WriterComponentPlugin(ManagedIceObject& parent, std::string pre);
-        ~WriterComponentPlugin() override;
-
-    private:
-
-        plugins::MemoryNameSystemComponentPlugin* mnsPlugin = nullptr;
-
-    };
-}
-
-
-namespace armarx::armem::client
-{
-    class WriterComponentPluginUser :
-        virtual public ManagedIceObject,
-        virtual public MemoryNameSystemComponentPluginUser
-    {
-
-    public:
-
-        WriterComponentPluginUser();
-        ~WriterComponentPluginUser() override;
-
-        virtual armem::data::WaitForMemoryResult useMemoryServer(const std::string& memoryName) override;
-        using MemoryNameSystemComponentPluginUser::useMemoryServer;
-
-
-    protected:
-
-        void setWritingMemoryServer(server::WritingMemoryInterfacePrx memory);
-
-        Writer memoryWriter;
-
-
-    private:
-
-        plugins::WriterComponentPlugin* plugin = nullptr;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/client/forward_declarations.h b/source/RobotAPI/libraries/armem/client/forward_declarations.h
index 205f56634..ab6a8fb90 100644
--- a/source/RobotAPI/libraries/armem/client/forward_declarations.h
+++ b/source/RobotAPI/libraries/armem/client/forward_declarations.h
@@ -8,9 +8,9 @@ namespace armarx::armem::client::query
 {
     class Builder;
 }
+
 namespace armarx::armem::client
 {
-    class ComponentPluginUser;
     class MemoryNameSystem;
 
     class Reader;
@@ -19,6 +19,20 @@ namespace armarx::armem::client
     using QueryBuilder = query::Builder;
     struct QueryInput;
     struct QueryResult;
+}
 
+namespace armarx::armem::client::plugins
+{
+    class Plugin;
+    class PluginUser;
+    class ListeningPluginUser;
 }
 
+namespace armarx::armem
+{
+    using ClientPlugin = client::plugins::Plugin;
+    using ClientPluginUser = client::plugins::PluginUser;
+    using ListeningClientPluginUser = client::plugins::ListeningPluginUser;
+}
+
+
diff --git a/source/RobotAPI/libraries/armem/client/plugins.h b/source/RobotAPI/libraries/armem/client/plugins.h
new file mode 100644
index 000000000..b91ccec38
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/client/plugins.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <RobotAPI/libraries/armem/client/forward_declarations.h>
+
+#include <RobotAPI/libraries/armem/client/plugins/ListeningPluginUser.h>
+#include <RobotAPI/libraries/armem/client/plugins/Plugin.h>
+#include <RobotAPI/libraries/armem/client/plugins/PluginUser.h>
+
+
+namespace armarx::armem::client
+{
+    using ComponentPluginUser = plugins::ListeningPluginUser;
+}
diff --git a/source/RobotAPI/libraries/armem/client/plugins/ListeningPluginUser.cpp b/source/RobotAPI/libraries/armem/client/plugins/ListeningPluginUser.cpp
new file mode 100644
index 000000000..3b3027a38
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/client/plugins/ListeningPluginUser.cpp
@@ -0,0 +1,26 @@
+#include "ListeningPluginUser.h"
+
+#include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
+
+
+namespace armarx::armem::client::plugins
+{
+
+    ListeningPluginUser::ListeningPluginUser()
+    {
+    }
+
+
+    ListeningPluginUser::~ListeningPluginUser()
+    {
+    }
+
+
+    void ListeningPluginUser::memoryUpdated(
+        const std::vector<data::MemoryID>& updatedSnapshotIDs, const Ice::Current&)
+    {
+        memoryNameSystem().updated(updatedSnapshotIDs);
+    }
+
+}
+
diff --git a/source/RobotAPI/libraries/armem/client/plugins/ListeningPluginUser.h b/source/RobotAPI/libraries/armem/client/plugins/ListeningPluginUser.h
new file mode 100644
index 000000000..dd80b88e6
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/client/plugins/ListeningPluginUser.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include "PluginUser.h"
+
+#include <RobotAPI/interface/armem/client/MemoryListenerInterface.h>
+
+#include <vector>
+
+
+namespace armarx::armem::client::plugins
+{
+
+    /**
+     * @brief A memory name system client which listens to the memory updates
+     * topic (`MemoryListenerInterface`).
+     *
+     * Derive from this plugin user class to receive memory update events.
+     */
+    class ListeningPluginUser :
+        virtual public PluginUser,
+        virtual public MemoryListenerInterface
+    {
+    protected:
+
+        ListeningPluginUser();
+        virtual ~ListeningPluginUser() override;
+
+
+        // MemoryListenerInterface
+        virtual void memoryUpdated(const std::vector<data::MemoryID>& updatedSnapshotIDs,
+                                   const Ice::Current&) override;
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/client/MemoryNameSystemComponentPlugin.cpp b/source/RobotAPI/libraries/armem/client/plugins/Plugin.cpp
similarity index 60%
rename from source/RobotAPI/libraries/armem/client/MemoryNameSystemComponentPlugin.cpp
rename to source/RobotAPI/libraries/armem/client/plugins/Plugin.cpp
index 07ef49f0f..e31d2d0e5 100644
--- a/source/RobotAPI/libraries/armem/client/MemoryNameSystemComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/armem/client/plugins/Plugin.cpp
@@ -1,4 +1,4 @@
-#include "MemoryNameSystemComponentPlugin.h"
+#include "Plugin.h"
 
 #include <ArmarXCore/core/Component.h>
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
@@ -11,11 +11,18 @@
 namespace armarx::armem::client::plugins
 {
 
-    MemoryNameSystemComponentPlugin::~MemoryNameSystemComponentPlugin()
+    Plugin::Plugin(
+            ManagedIceObject& parent, std::string pre) :
+        ComponentPlugin(parent, pre)
+    {
+    }
+
+
+    Plugin::~Plugin()
     {}
 
 
-    void MemoryNameSystemComponentPlugin::postCreatePropertyDefinitions(armarx::PropertyDefinitionsPtr& properties)
+    void Plugin::postCreatePropertyDefinitions(armarx::PropertyDefinitionsPtr& properties)
     {
         if (!properties->hasDefinition(makePropertyName(PROPERTY_MNS_NAME_NAME)))
         {
@@ -38,7 +45,7 @@ namespace armarx::armem::client::plugins
     }
 
 
-    void MemoryNameSystemComponentPlugin::preOnInitComponent()
+    void Plugin::preOnInitComponent()
     {
         if (isMemoryNameSystemEnabled())
         {
@@ -47,7 +54,7 @@ namespace armarx::armem::client::plugins
     }
 
 
-    void MemoryNameSystemComponentPlugin::preOnConnectComponent()
+    void Plugin::preOnConnectComponent()
     {
         if (isMemoryNameSystemEnabled())
         {
@@ -58,21 +65,21 @@ namespace armarx::armem::client::plugins
 
 
     bool
-    MemoryNameSystemComponentPlugin::isMemoryNameSystemEnabled()
+    Plugin::isMemoryNameSystemEnabled()
     {
         return memoryNameSystemEnabled;
     }
 
 
     std::string
-    MemoryNameSystemComponentPlugin::getMemoryNameSystemName()
+    Plugin::getMemoryNameSystemName()
     {
         return memoryNameSystemName;
     }
 
 
     mns::MemoryNameSystemInterfacePrx
-    MemoryNameSystemComponentPlugin::getMemoryNameSystemProxy()
+    Plugin::getMemoryNameSystemProxy()
     {
         return isMemoryNameSystemEnabled() and parentDerives<ManagedIceObject>()
                ? parent<ManagedIceObject>().getProxy<mns::MemoryNameSystemInterfacePrx>(getMemoryNameSystemName())
@@ -81,47 +88,16 @@ namespace armarx::armem::client::plugins
 
 
     MemoryNameSystem&
-    MemoryNameSystemComponentPlugin::getMemoryNameSystemClient()
+    Plugin::getMemoryNameSystemClient()
     {
         return memoryNameSystem;
     }
 
 
     const MemoryNameSystem&
-    MemoryNameSystemComponentPlugin::getMemoryNameSystemClient() const
+    Plugin::getMemoryNameSystemClient() const
     {
         return memoryNameSystem;
     }
 
 }
-
-namespace armarx::armem::client
-{
-
-    MemoryNameSystemComponentPluginUser::MemoryNameSystemComponentPluginUser()
-    {
-        addPlugin(plugin);
-    }
-
-    MemoryNameSystemComponentPluginUser::~MemoryNameSystemComponentPluginUser()
-    {
-    }
-
-
-    ListeningMemoryNameSystemComponentPluginUser::ListeningMemoryNameSystemComponentPluginUser()
-    {
-    }
-
-    ListeningMemoryNameSystemComponentPluginUser::~ListeningMemoryNameSystemComponentPluginUser()
-    {
-    }
-
-
-    void ListeningMemoryNameSystemComponentPluginUser::memoryUpdated(
-        const std::vector<data::MemoryID>& updatedSnapshotIDs, const Ice::Current&)
-    {
-        memoryNameSystem().updated(updatedSnapshotIDs);
-    }
-
-}
-
diff --git a/source/RobotAPI/libraries/armem/client/MemoryNameSystemComponentPlugin.h b/source/RobotAPI/libraries/armem/client/plugins/Plugin.h
similarity index 51%
rename from source/RobotAPI/libraries/armem/client/MemoryNameSystemComponentPlugin.h
rename to source/RobotAPI/libraries/armem/client/plugins/Plugin.h
index b7276e844..550f893bf 100644
--- a/source/RobotAPI/libraries/armem/client/MemoryNameSystemComponentPlugin.h
+++ b/source/RobotAPI/libraries/armem/client/plugins/Plugin.h
@@ -1,26 +1,29 @@
 #pragma once
 
-#include <ArmarXCore/core/ComponentPlugin.h>
-
 #include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
-#include <RobotAPI/interface/armem/client/MemoryListenerInterface.h>
-#include <RobotAPI/libraries/armem/core/MemoryID.h>
 #include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
 
+#include <ArmarXCore/core/ComponentPlugin.h>
+
+#include <string>
+
 
 namespace armarx::armem::client::plugins
 {
+
     /**
-     * @brief A base plugin offering optional access and dependency
-     * to the Memory Name System (MNS).
+     * @brief A component plugin offering client-side access to to the
+     * working memory system by providing a Memory Name System (MNS) client.
+     *
+     * @see MemoryNameSystem
      */
-    class MemoryNameSystemComponentPlugin :
-        public ComponentPlugin
+    class Plugin :
+        public armarx::ComponentPlugin
     {
     public:
 
-        using ComponentPlugin::ComponentPlugin;
-        virtual ~MemoryNameSystemComponentPlugin() override;
+        Plugin(ManagedIceObject& parent, std::string pre);
+        virtual ~Plugin() override;
 
         void postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) override;
 
@@ -30,10 +33,20 @@ namespace armarx::armem::client::plugins
 
     public:
 
+        /**
+         * @brief Get the MNS client.
+         *
+         * Only valid when enabled.
+         */
+        MemoryNameSystem& getMemoryNameSystemClient();
+        const MemoryNameSystem& getMemoryNameSystemClient() const;
+
+
         /**
          * @brief Indicate whether the Memory Name System (MNS) is enabled.
          */
         bool isMemoryNameSystemEnabled();
+
         /**
          * @brief Get the name of the MNS component.
          */
@@ -45,16 +58,10 @@ namespace armarx::armem::client::plugins
          */
         mns::MemoryNameSystemInterfacePrx getMemoryNameSystemProxy();
 
-        /**
-         * @brief Get the MNS client.
-         * Only valid when enabled.
-         */
-        MemoryNameSystem& getMemoryNameSystemClient();
-        const MemoryNameSystem& getMemoryNameSystemClient() const;
-
 
     protected:
 
+        /// The MNS client.
         MemoryNameSystem memoryNameSystem;
 
         bool memoryNameSystemEnabled = true;
@@ -69,55 +76,3 @@ namespace armarx::armem::client::plugins
     };
 
 }
-
-
-#include <ArmarXCore/core/ManagedIceObject.h>
-
-namespace armarx::armem::client
-{
-
-    class MemoryNameSystemComponentPluginUser :
-        virtual public ManagedIceObject
-    {
-    protected:
-
-        MemoryNameSystemComponentPluginUser();
-        virtual ~MemoryNameSystemComponentPluginUser() override;
-
-
-    public:
-
-        MemoryNameSystem& memoryNameSystem()
-        {
-            return plugin->getMemoryNameSystemClient();
-        }
-        const MemoryNameSystem& memoryNameSystem() const
-        {
-            return plugin->getMemoryNameSystemClient();
-        }
-
-
-    private:
-
-        plugins::MemoryNameSystemComponentPlugin* plugin = nullptr;
-
-    };
-
-
-
-    class ListeningMemoryNameSystemComponentPluginUser :
-        virtual public MemoryNameSystemComponentPluginUser,
-        virtual public MemoryListenerInterface
-    {
-    protected:
-
-        ListeningMemoryNameSystemComponentPluginUser();
-        virtual ~ListeningMemoryNameSystemComponentPluginUser() override;
-
-
-        // MemoryListenerInterface
-        virtual void memoryUpdated(const std::vector<data::MemoryID>& updatedSnapshotIDs,
-                                   const Ice::Current&) override;
-
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/client/plugins/PluginUser.cpp b/source/RobotAPI/libraries/armem/client/plugins/PluginUser.cpp
new file mode 100644
index 000000000..91414da1c
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/client/plugins/PluginUser.cpp
@@ -0,0 +1,34 @@
+#include "PluginUser.h"
+#include "Plugin.h"
+
+#include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
+
+
+
+namespace armarx::armem::client::plugins
+{
+
+    PluginUser::PluginUser()
+    {
+        addPlugin(plugin);
+    }
+
+
+    PluginUser::~PluginUser()
+    {
+    }
+
+
+    MemoryNameSystem& PluginUser::memoryNameSystem()
+    {
+        return plugin->getMemoryNameSystemClient();
+    }
+
+
+    const MemoryNameSystem& PluginUser::memoryNameSystem() const
+    {
+        return plugin->getMemoryNameSystemClient();
+    }
+
+}
+
diff --git a/source/RobotAPI/libraries/armem/client/plugins/PluginUser.h b/source/RobotAPI/libraries/armem/client/plugins/PluginUser.h
new file mode 100644
index 000000000..f67afc8bc
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/client/plugins/PluginUser.h
@@ -0,0 +1,48 @@
+#pragma once
+
+// Let's not forward declare this one.
+#include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
+
+#include <ArmarXCore/core/ManagedIceObject.h>
+
+
+namespace armarx::armem::client::plugins
+{
+
+    class Plugin;
+
+
+    /**
+     * @brief Adds the Memory Name System client component plugin.
+     *
+     * This plugin class does not implement the `MemoryListenerInterface`.
+     * Therefore, it will not receive and process memory udpate events via the
+     * memory updates topic. If you want to receive these updates, use the
+     * `ListeningMemoryNameSystemPluginUser`.
+     *
+     *
+     * @see MemoryNameSystemPlugin
+     * @see ListeningMemoryNameSystemPluginUser
+     */
+    class PluginUser :
+        virtual public armarx::ManagedIceObject
+    {
+    protected:
+
+        PluginUser();
+        virtual ~PluginUser() override;
+
+
+    public:
+
+        MemoryNameSystem& memoryNameSystem();
+        const MemoryNameSystem& memoryNameSystem() const;
+
+
+    private:
+
+        plugins::Plugin* plugin = nullptr;
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp b/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp
index c97d55af4..93246434d 100644
--- a/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp
@@ -13,10 +13,17 @@ namespace armarx::armem::server::plugins
     ComponentPlugin::~ComponentPlugin() = default;
 
 
-    void ComponentPlugin::postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties)
+    ComponentPlugin::ComponentPlugin(ManagedIceObject& parent, std::string prefix) :
+        armarx::ComponentPlugin(parent, prefix)
     {
-        MemoryNameSystemComponentPlugin::postCreatePropertyDefinitions(properties);
+        addPlugin(clientPlugin);
+        ARMARX_CHECK_NOT_NULL(clientPlugin);
+        addPluginDependency(clientPlugin);
+    }
+
 
+    void ComponentPlugin::postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties)
+    {
         const std::string prefix = "mem.";
         if (not workingMemory.name().empty()
             and not properties->hasDefinition(prefix + "MemoryName"))
@@ -33,7 +40,7 @@ namespace armarx::armem::server::plugins
     {
         ComponentPluginUser& parent = this->parent<ComponentPluginUser>();
 
-        if (isMemoryNameSystemEnabled() && parent.memoryNameSystem())
+        if (clientPlugin->isMemoryNameSystemEnabled() && parent.memoryNameSystem())
         {
             registerMemory(parent);
         }
@@ -50,7 +57,7 @@ namespace armarx::armem::server::plugins
     void ComponentPlugin::preOnDisconnectComponent()
     {
         ComponentPluginUser& parent = this->parent<ComponentPluginUser>();
-        if (isMemoryNameSystemEnabled() && memoryNameSystem)
+        if (clientPlugin->isMemoryNameSystemEnabled() and clientPlugin->getMemoryNameSystemProxy())
         {
             removeMemory(parent);
         }
diff --git a/source/RobotAPI/libraries/armem/server/ComponentPlugin.h b/source/RobotAPI/libraries/armem/server/ComponentPlugin.h
index ba4e890f5..4c9c66ee0 100644
--- a/source/RobotAPI/libraries/armem/server/ComponentPlugin.h
+++ b/source/RobotAPI/libraries/armem/server/ComponentPlugin.h
@@ -1,36 +1,31 @@
 #pragma once
 
-#include <mutex>
+#include "MemoryToIceAdapter.h"
 
-#include <ArmarXCore/core/ComponentPlugin.h>
+#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem/server/ltm/mongodb/MemoryManager.h>
+#include <RobotAPI/libraries/armem/client/plugins/Plugin.h>
+#include <RobotAPI/libraries/armem/client/plugins/ListeningPluginUser.h>
 
 #include <RobotAPI/interface/armem/server/MemoryInterface.h>
 #include <RobotAPI/interface/armem/client/MemoryListenerInterface.h>
-#include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
 
-#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
-#include <RobotAPI/libraries/armem/server/ltm/mongodb/MemoryManager.h>
-#include <RobotAPI/libraries/armem/client/MemoryNameSystemComponentPlugin.h>
-
-#include "MemoryToIceAdapter.h"
+#include <ArmarXCore/core/ComponentPlugin.h>
 
 
 namespace armarx::armem::server
 {
     class ComponentPluginUser;
 }
-
-
 namespace armarx::armem::server::plugins
 {
 
-    class ComponentPlugin : public client::plugins::MemoryNameSystemComponentPlugin
+    class ComponentPlugin :
+        public armarx::ComponentPlugin
     {
-        using Base = client::plugins::MemoryNameSystemComponentPlugin;
-
     public:
 
-        using Base::MemoryNameSystemComponentPlugin;
+        ComponentPlugin(ManagedIceObject& parent, std::string prefix);
         virtual ~ComponentPlugin() override;
 
         virtual void postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) override;
@@ -41,7 +36,7 @@ namespace armarx::armem::server::plugins
 
     public:
 
-        /// Set the name of the wm and the ltm (if enabled)
+        /// Set the name of the wm and the ltm (if enabled).
         void setMemoryName(const std::string& memoryName);
 
 
@@ -49,11 +44,14 @@ namespace armarx::armem::server::plugins
 
         /**
          * @brief Register the parent component in the MNS.
+         *
          * Called before onConnect() if MNS is enabled.
          */
         data::RegisterMemoryResult registerMemory(ComponentPluginUser& parent);
+
         /**
          * @brief Remove the parent component from the MNS.
+         *
          * Called before onDisconnect() if MNS is enabled.
          */
         data::RemoveMemoryResult removeMemory(ComponentPluginUser& parent);
@@ -89,6 +87,11 @@ namespace armarx::armem::server::plugins
         std::string longTermMemoryDatabaseUser;
         std::string longTermMemoryDatabasePassword;
 
+
+    private:
+
+        client::plugins::Plugin* clientPlugin;
+
     };
 
 }
@@ -105,7 +108,7 @@ namespace armarx::armem::server
     class ComponentPluginUser :
         virtual public ManagedIceObject
         , virtual public MemoryInterface
-        , virtual public client::ListeningMemoryNameSystemComponentPluginUser
+        , virtual public client::plugins::ListeningPluginUser
     {
     public:
 
-- 
GitLab