diff --git a/source/RobotAPI/components/armem/MemoryNameSystem/CMakeLists.txt b/source/RobotAPI/components/armem/MemoryNameSystem/CMakeLists.txt index 75a50c54304d11e5452f1e4d1f8287a65fd0e9f6..fa06c3e77bf057e9ca37e790f908e981db1147af 100644 --- a/source/RobotAPI/components/armem/MemoryNameSystem/CMakeLists.txt +++ b/source/RobotAPI/components/armem/MemoryNameSystem/CMakeLists.txt @@ -19,4 +19,6 @@ set(HEADERS armarx_add_component("${SOURCES}" "${HEADERS}") #generate the application -armarx_generate_and_add_component_executable() +armarx_generate_and_add_component_executable( + COMPONENT_NAMESPACE "armarx::armem" +) diff --git a/source/RobotAPI/components/armem/MemoryNameSystem/MemoryNameSystem.cpp b/source/RobotAPI/components/armem/MemoryNameSystem/MemoryNameSystem.cpp index 47131a79a44f25dabc1e3364fcc7d3d044b3e506..0ebd0eac1dad18f7c53374c4a4fcc5ba173bbf14 100644 --- a/source/RobotAPI/components/armem/MemoryNameSystem/MemoryNameSystem.cpp +++ b/source/RobotAPI/components/armem/MemoryNameSystem/MemoryNameSystem.cpp @@ -29,16 +29,12 @@ #include <RobotAPI/libraries/armem/core/error.h> -namespace armarx +namespace armarx::armem { - MemoryNameSystemPropertyDefinitions::MemoryNameSystemPropertyDefinitions(std::string prefix) : - armarx::ComponentPropertyDefinitions(prefix) - { - } armarx::PropertyDefinitionsPtr MemoryNameSystem::createPropertyDefinitions() { - armarx::PropertyDefinitionsPtr defs = new MemoryNameSystemPropertyDefinitions(getConfigIdentifier()); + armarx::PropertyDefinitionsPtr defs = new ComponentPropertyDefinitions(getConfigIdentifier()); return defs; } @@ -58,7 +54,7 @@ namespace armarx void MemoryNameSystem::onConnectComponent() { - RemoteGui__createTab(); + createRemoteGuiTab(); RemoteGui_startRunningTask(); } @@ -73,19 +69,19 @@ namespace armarx } - armem::data::RegisterMemoryResult MemoryNameSystem::registerMemory( - const armem::data::RegisterMemoryInput& input, const Ice::Current& c) + mns::dto::RegisterServerResult MemoryNameSystem::registerServer( + const mns::dto::RegisterServerInput& input, const Ice::Current& c) { - armem::data::RegisterMemoryResult result = Plugin::registerMemory(input, c); + mns::dto::RegisterServerResult result = PluginUser::registerServer(input, c); tab.rebuild = true; return result; } - armem::data::RemoveMemoryResult MemoryNameSystem::removeMemory( - const armem::data::RemoveMemoryInput& input, const Ice::Current& c) + mns::dto::RemoveServerResult MemoryNameSystem::removeServer( + const mns::dto::RemoveServerInput& input, const Ice::Current& c) { - armem::data::RemoveMemoryResult result = Plugin::removeMemory(input, c); + mns::dto::RemoveServerResult result = PluginUser::removeServer(input, c); tab.rebuild = true; return result; } @@ -94,12 +90,12 @@ namespace armarx // REMOTE GUI - void MemoryNameSystem::RemoteGui__createTab() + void MemoryNameSystem::createRemoteGuiTab() { using namespace armarx::RemoteGui::Client; std::scoped_lock lock(mnsMutex); - GridLayout grid = mns.RemoteGui_buildInfoGrid(); + GridLayout grid = mns().RemoteGui_buildInfoGrid(); VBoxLayout root = {grid, VSpacer()}; RemoteGui_createTab(getName(), root, &tab); @@ -110,7 +106,7 @@ namespace armarx { if (tab.rebuild.exchange(false)) { - RemoteGui__createTab(); + createRemoteGuiTab(); } } diff --git a/source/RobotAPI/components/armem/MemoryNameSystem/MemoryNameSystem.h b/source/RobotAPI/components/armem/MemoryNameSystem/MemoryNameSystem.h index 795aecc66f96423aa29b28660694e09ea50a1426..f0279f4a1103a6b6f5a88f4b31ab5692cc5bda74 100644 --- a/source/RobotAPI/components/armem/MemoryNameSystem/MemoryNameSystem.h +++ b/source/RobotAPI/components/armem/MemoryNameSystem/MemoryNameSystem.h @@ -22,33 +22,16 @@ #pragma once -#include <mutex> - -#include <ArmarXCore/core/Component.h> +#include <RobotAPI/libraries/armem/mns/plugins/PluginUser.h> +#include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h> #include <ArmarXGui/libraries/ArmarXGuiComponentPlugins/LightweightRemoteGuiComponentPlugin.h> -// #include <RobotAPI/libraries/RobotAPIComponentPlugins/ArVizComponentPlugin.h> -#include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h> - -#include <RobotAPI/libraries/armem/mns/ComponentPlugin.h> +#include <ArmarXCore/core/Component.h> -namespace armarx +namespace armarx::armem { - /** - * @class MemoryNameSystemPropertyDefinitions - * @brief Property definitions of `MemoryNameSystem`. - */ - class MemoryNameSystemPropertyDefinitions : - public armarx::ComponentPropertyDefinitions - { - public: - MemoryNameSystemPropertyDefinitions(std::string prefix); - }; - - - /** * @defgroup Component-MemoryNameSystem MemoryNameSystem * @ingroup RobotAPI-Components @@ -62,11 +45,9 @@ namespace armarx */ class MemoryNameSystem : virtual public armarx::Component - , virtual public armem::mns::ComponentPluginUser + , virtual public armem::mns::plugins::PluginUser , virtual public LightweightRemoteGuiComponentPluginUser - // , virtual public armarx::ArVizComponentPluginUser { - using Plugin = ComponentPluginUser; public: /// @see armarx::ManagedIceObject::getDefaultName() @@ -75,20 +56,23 @@ namespace armarx // mns::MemoryNameSystemInterface interface public: - armem::data::RegisterMemoryResult registerMemory(const armem::data::RegisterMemoryInput& input, const Ice::Current&) override; - armem::data::RemoveMemoryResult removeMemory(const armem::data::RemoveMemoryInput& input, const Ice::Current&) override; + mns::dto::RegisterServerResult registerServer(const mns::dto::RegisterServerInput& input, const Ice::Current&) override; + mns::dto::RemoveServerResult removeServer(const mns::dto::RemoveServerInput& input, const Ice::Current&) override; // Others are inherited from ComponentPluginUser // LightweightRemoteGuiComponentPluginUser interface public: - void RemoteGui__createTab(); + void createRemoteGuiTab(); void RemoteGui_update() override; protected: + /// @see PropertyUser::createPropertyDefinitions() + armarx::PropertyDefinitionsPtr createPropertyDefinitions() override; + /// @see armarx::ManagedIceObject::onInitComponent() void onInitComponent() override; @@ -101,17 +85,13 @@ namespace armarx /// @see armarx::ManagedIceObject::onExitComponent() void onExitComponent() override; - /// @see PropertyUser::createPropertyDefinitions() - armarx::PropertyDefinitionsPtr createPropertyDefinitions() override; - private: struct Properties { - }; - Properties p; + Properties properties; struct RemoteGuiTab : RemoteGui::Client::Tab diff --git a/source/RobotAPI/interface/armem/mns/MemoryNameSystemInterface.ice b/source/RobotAPI/interface/armem/mns/MemoryNameSystemInterface.ice index 85a862f4cd815168d6163d2d085426d71b298068..95b6a9fa6b03d8f7d4644d2538ecfd64d5258229 100644 --- a/source/RobotAPI/interface/armem/mns/MemoryNameSystemInterface.ice +++ b/source/RobotAPI/interface/armem/mns/MemoryNameSystemInterface.ice @@ -1,87 +1,116 @@ #pragma once -#include <RobotAPI/interface/armem/server/MemoryInterface.ice> +#include <RobotAPI/interface/armem/server/ReadingMemoryInterface.ice> +#include <RobotAPI/interface/armem/server/WritingMemoryInterface.ice> module armarx { module armem { - module data + module mns { - struct RegisterMemoryInput - { - string name; - server::MemoryInterface* proxy; - - bool existOk = true; - }; - struct RegisterMemoryResult - { - bool success; - string errorMessage; - }; - - struct RemoveMemoryInput - { - string name; - bool notExistOk = true; - }; - struct RemoveMemoryResult - { - bool success; - string errorMessage; - }; - - dictionary<string, server::MemoryInterface*> MemoryInterfaces; - struct GetAllRegisteredMemoriesResult - { - bool success; - string errorMessage; - - MemoryInterfaces proxies; - }; - - struct ResolveMemoryNameInput - { - string name; - }; - struct ResolveMemoryNameResult - { - bool success; - string errorMessage; - - server::MemoryInterface* proxy; - }; - - struct WaitForMemoryInput - { - /// The memory name. - string name; - /// Negative for no timeout. - long timeoutMilliSeconds = -1; - }; - struct WaitForMemoryResult + module dto { - bool success; - string errorMessage; - - server::MemoryInterface* proxy; + /** + * A memory server can implement the reading and/or writing + * memory interface. They should be handled individually. + */ + struct MemoryServerInterfaces + { + server::ReadingMemoryInterface* reading; + server::WritingMemoryInterface* writing; + }; + dictionary<string, MemoryServerInterfaces> MemoryServerInterfacesMap; + + + /** + * @brief Register a memory server. + */ + struct RegisterServerInput + { + string name; + MemoryServerInterfaces server; + + bool existOk = true; + }; + struct RegisterServerResult + { + bool success; + string errorMessage; + }; + + + /** + * @brief Remove a memory server. + */ + struct RemoveServerInput + { + string name; + bool notExistOk = true; + }; + struct RemoveServerResult + { + bool success; + string errorMessage; + }; + + /** + * @brief Resolve a memory name. + */ + struct ResolveServerInput + { + string name; + }; + struct ResolveServerResult + { + bool success; + string errorMessage; + + MemoryServerInterfaces server; + }; + + + /** + * @brief Get all registered entries. + */ + struct GetAllRegisteredServersResult + { + bool success; + string errorMessage; + + MemoryServerInterfacesMap servers; + }; + + + /** + * @brief Wait until a server is registered. + */ + struct WaitForServerInput + { + string name; + }; + struct WaitForServerResult + { + bool success; + string errorMessage; + + MemoryServerInterfaces server; + }; }; - }; - module mns - { interface MemoryNameSystemInterface { - data::RegisterMemoryResult registerMemory(data::RegisterMemoryInput input); - data::RemoveMemoryResult removeMemory(data::RemoveMemoryInput input); + dto::RegisterServerResult registerServer(dto::RegisterServerInput input); + dto::RemoveServerResult removeServer(dto::RemoveServerInput input); + + dto::GetAllRegisteredServersResult getAllRegisteredServers(); - data::GetAllRegisteredMemoriesResult getAllRegisteredMemories(); + dto::ResolveServerResult resolveServer(dto::ResolveServerInput input); - data::ResolveMemoryNameResult resolveMemoryName(data::ResolveMemoryNameInput input); - data::WaitForMemoryResult waitForMemory(data::WaitForMemoryInput input); + ["amd"] // Asynchronous Method Dispatch + dto::WaitForServerResult waitForServer(dto::WaitForServerInput input); }; } diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt index e6c3f1a8533c15e1b20a71c34e741bebcb50d12f..32c3b9b949577ab7f91b4993c186f181151abc6d 100644 --- a/source/RobotAPI/libraries/armem/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem/CMakeLists.txt @@ -103,7 +103,9 @@ set(LIB_FILES server/query_proc/wm.cpp mns/MemoryNameSystem.cpp - mns/ComponentPlugin.cpp + mns/Registry.cpp + mns/plugins/Plugin.cpp + mns/plugins/PluginUser.cpp util/util.cpp ) @@ -210,7 +212,9 @@ set(LIB_HEADERS mns.h mns/MemoryNameSystem.h - mns/ComponentPlugin.h + mns/Registry.h + mns/plugins/Plugin.h + mns/plugins/PluginUser.h util/util.h ) diff --git a/source/RobotAPI/libraries/armem/client/MemoryNameSystem.cpp b/source/RobotAPI/libraries/armem/client/MemoryNameSystem.cpp index 79140344ee99a143e29bcc655d6e1ed23d77b041..4dcb3d624e42b901fe0d70d91a89c136ff1692ba 100644 --- a/source/RobotAPI/libraries/armem/client/MemoryNameSystem.cpp +++ b/source/RobotAPI/libraries/armem/client/MemoryNameSystem.cpp @@ -27,10 +27,10 @@ namespace armarx::armem::client { ARMARX_CHECK_NOT_NULL(mns); - data::GetAllRegisteredMemoriesResult result; + mns::dto::GetAllRegisteredServersResult result; try { - result = mns->getAllRegisteredMemories(); + result = mns->getAllRegisteredServers(); } catch (const Ice::NotRegisteredException& e) { @@ -39,24 +39,32 @@ namespace armarx::armem::client if (result.success) { - for (const auto& [name, proxy] : result.proxies) + for (const auto& [name, server] : result.servers) { - auto [it, inserted] = servers.try_emplace(name, proxy); - // inserted: OK - if (not inserted) + auto [it, inserted] = servers.try_emplace(name, server); + if (inserted) + { + // OK + } + else { // Compare ice identities, update if it changed. - if (it->second->ice_getIdentity() != proxy->ice_getIdentity()) + auto foo = [](auto & oldProxy, const auto & newProxy) { - // Replace old proxy by new one. - it->second = proxy; - } + if (oldProxy->ice_getIdentity() != newProxy->ice_getIdentity()) + { + // Replace old proxy by new one. + oldProxy = newProxy; + } + }; + foo(it->second.reading, server.reading); + foo(it->second.writing, server.writing); } } // Remove all entries which are not there anymore. for (auto it = servers.begin(); it != servers.end();) { - if (result.proxies.count(it->first) == 0) + if (result.servers.count(it->first) == 0) { it = servers.erase(it); } @@ -73,7 +81,8 @@ namespace armarx::armem::client } - server::MemoryInterfacePrx MemoryNameSystem::resolveServer(const MemoryID& memoryID) + mns::dto::MemoryServerInterfaces + MemoryNameSystem::resolveServer(const MemoryID& memoryID) { if (auto it = servers.find(memoryID.memoryName); it != servers.end()) { @@ -94,7 +103,7 @@ namespace armarx::armem::client } - server::MemoryInterfacePrx MemoryNameSystem::waitForServer(const MemoryID& memoryID, Time timeout) + mns::dto::MemoryServerInterfaces MemoryNameSystem::waitForServer(const MemoryID& memoryID) { if (auto it = servers.find(memoryID.memoryName); it != servers.end()) { @@ -102,15 +111,14 @@ namespace armarx::armem::client } else { - armem::data::WaitForMemoryInput input; + mns::dto::WaitForServerInput input; input.name = memoryID.memoryName; - input.timeoutMilliSeconds = timeout.toMilliSeconds(); ARMARX_CHECK_NOT_NULL(mns); - armem::data::WaitForMemoryResult result = mns->waitForMemory(input); + mns::dto::WaitForServerResult result = mns->waitForServer(input); if (result.success) { - return result.proxy; + return result.server; } else { @@ -119,7 +127,7 @@ namespace armarx::armem::client } } - server::MemoryInterfacePrx MemoryNameSystem::useServer(const MemoryID& memoryID) + mns::dto::MemoryServerInterfaces MemoryNameSystem::useServer(const MemoryID& memoryID) { ARMARX_CHECK_NOT_NULL(component) << "Owning component not set when using a memory server. \n" @@ -131,22 +139,22 @@ namespace armarx::armem::client } - server::MemoryInterfacePrx MemoryNameSystem::useServer(const MemoryID& memoryID, ManagedIceObject& component) + mns::dto::MemoryServerInterfaces MemoryNameSystem::useServer(const MemoryID& memoryID, ManagedIceObject& component) { - server::MemoryInterfacePrx server = waitForServer(memoryID); + mns::dto::MemoryServerInterfaces server = waitForServer(memoryID); // Add dependency. - component.usingProxy(server->ice_getIdentity().name); + component.usingProxy(server.reading->ice_getIdentity().name); return server; } - server::MemoryInterfacePrx MemoryNameSystem::useServer(const std::string& memoryName) + mns::dto::MemoryServerInterfaces MemoryNameSystem::useServer(const std::string& memoryName) { return useServer(MemoryID().withMemoryName(memoryName)); } - server::MemoryInterfacePrx MemoryNameSystem::useServer(const std::string& memoryName, ManagedIceObject& component) + mns::dto::MemoryServerInterfaces MemoryNameSystem::useServer(const std::string& memoryName, ManagedIceObject& component) { return useServer(MemoryID().withMemoryName(memoryName), component); } @@ -154,19 +162,19 @@ namespace armarx::armem::client Reader MemoryNameSystem::getReader(const MemoryID& memoryID) { - return Reader(resolveServer(memoryID)); + return Reader(resolveServer(memoryID).reading); } Reader MemoryNameSystem::useReader(const MemoryID& memoryID) { - return Reader(useServer(memoryID)); + return Reader(useServer(memoryID).reading); } Reader MemoryNameSystem::useReader(const MemoryID& memoryID, ManagedIceObject& component) { - return Reader(useServer(memoryID, component)); + return Reader(useServer(memoryID, component).reading); } @@ -183,55 +191,50 @@ namespace armarx::armem::client template <class ClientT> - std::map<std::string, ClientT> MemoryNameSystem::_getAllClients() const + std::map<std::string, ClientT> + MemoryNameSystem::_getAllClients(auto&& getProxyFn) const { std::map<std::string, ClientT> result; for (const auto& [name, server] : servers) { - result[name] = ClientT(server); + result[name] = ClientT(getProxyFn(server)); } return result; } - template <class ClientT> - std::map<std::string, ClientT> MemoryNameSystem::_getAllClients(bool update) + + std::map<std::string, Reader> MemoryNameSystem::getAllReaders(bool update) { if (update) { this->update(); } - return const_cast<const MemoryNameSystem&>(*this)._getAllClients<ClientT>(); - } - - - std::map<std::string, Reader> MemoryNameSystem::getAllReaders(bool update) - { - return _getAllClients<Reader>(update); + return _getAllClients<Reader>(&mns::getReadingInterface); } std::map<std::string, Reader> MemoryNameSystem::getAllReaders() const { - return _getAllClients<Reader>(); + return _getAllClients<Reader>(&mns::getReadingInterface); } Writer MemoryNameSystem::getWriter(const MemoryID& memoryID) { - return Writer(resolveServer(memoryID)); + return Writer(resolveServer(memoryID).writing); } Writer MemoryNameSystem::useWriter(const MemoryID& memoryID) { - return Writer(useServer(memoryID)); + return Writer(useServer(memoryID).writing); } Writer MemoryNameSystem::useWriter(const MemoryID& memoryID, ManagedIceObject& component) { - return Writer(useServer(memoryID, component)); + return Writer(useServer(memoryID, component).writing); } @@ -249,13 +252,17 @@ namespace armarx::armem::client std::map<std::string, Writer> MemoryNameSystem::getAllWriters(bool update) { - return _getAllClients<Writer>(update); + if (update) + { + this->update(); + } + return _getAllClients<Writer>(&mns::getWritingInterface); } std::map<std::string, Writer> MemoryNameSystem::getAllWriters() const { - return _getAllClients<Writer>(); + return _getAllClients<Writer>(&mns::getWritingInterface); } @@ -341,15 +348,15 @@ namespace armarx::armem::client } - void MemoryNameSystem::registerServer(const MemoryID& memoryID, server::MemoryInterfacePrx proxy) + void MemoryNameSystem::registerServer(const MemoryID& memoryID, mns::dto::MemoryServerInterfaces server) { - data::RegisterMemoryInput input; + mns::dto::RegisterServerInput input; input.name = memoryID.memoryName; - input.proxy = proxy; - ARMARX_CHECK_NOT_NULL(input.proxy); + input.server = server; + ARMARX_CHECK(server.reading or server.writing) << VAROUT(server.reading) << " | " << VAROUT(server.writing); ARMARX_CHECK_NOT_NULL(mns); - data::RegisterMemoryResult result = mns->registerMemory(input); + mns::dto::RegisterServerResult result = mns->registerServer(input); if (!result.success) { throw error::ServerRegistrationOrRemovalFailed("register", memoryID, result.errorMessage); @@ -359,11 +366,11 @@ namespace armarx::armem::client void MemoryNameSystem::removeServer(const MemoryID& memoryID) { - data::RemoveMemoryInput input; + mns::dto::RemoveServerInput input; input.name = memoryID.memoryName; ARMARX_CHECK_NOT_NULL(mns); - data::RemoveMemoryResult result = mns->removeMemory(input); + mns::dto::RemoveServerResult result = mns->removeServer(input); if (!result.success) { throw error::ServerRegistrationOrRemovalFailed("remove", memoryID, result.errorMessage); diff --git a/source/RobotAPI/libraries/armem/client/MemoryNameSystem.h b/source/RobotAPI/libraries/armem/client/MemoryNameSystem.h index d981bab0383f0d04fdc221fbbd2cbd062d061c53..7779ca2d8b1a65b07ef446675685695dc243de58 100644 --- a/source/RobotAPI/libraries/armem/client/MemoryNameSystem.h +++ b/source/RobotAPI/libraries/armem/client/MemoryNameSystem.h @@ -30,6 +30,7 @@ #include <RobotAPI/libraries/armem/core/MemoryID.h> #include <RobotAPI/libraries/armem/client/util/MemoryListener.h> +#include <RobotAPI/libraries/armem/mns/Registry.h> namespace armarx @@ -97,41 +98,6 @@ namespace armarx::armem::client */ void update(); - /** - * @brief Resolve the given memory server for the given memory ID. - * - * @param memoryID The memory ID. - * @return The memory server proxy. - * - * @throw `error::CouldNotResolveMemoryServer` If the memory name could not be resolved. - */ - server::MemoryInterfacePrx resolveServer(const MemoryID& memoryID); - - /** - * @brief Wait for the given memory server. - * - * @param memoryID The memory ID. - * @param timeout How long to wait at maximum. Negative values indicate infinite wait. - * @return The memory server proxy. - * - * @throw `error::CouldNotResolveMemoryServer` If the memory name could not be resolved. - */ - server::MemoryInterfacePrx waitForServer(const MemoryID& memoryID, Time timeout = Time::milliSeconds(-1)); - - /** - * @brief Wait for the given memory server and add a dependency to the memory server. - * - * @param memoryID The memory ID. - * @param component The component that should depend on the memory server. - * @return The memory server proxy. - * - * @throw `error::CouldNotResolveMemoryServer` If the memory name could not be resolved. - */ - server::MemoryInterfacePrx useServer(const MemoryID& memoryID); - server::MemoryInterfacePrx useServer(const MemoryID& memoryID, ManagedIceObject& component); - server::MemoryInterfacePrx useServer(const std::string& memoryName); - server::MemoryInterfacePrx useServer(const std::string& memoryName, ManagedIceObject& component); - // Reader/Writer construction @@ -225,7 +191,7 @@ namespace armarx::armem::client * * @throw `error::ServerRegistrationOrRemovalFailed` If the registration failed. */ - void registerServer(const MemoryID& memoryID, server::MemoryInterfacePrx server); + void registerServer(const MemoryID& memoryID, mns::dto::MemoryServerInterfaces server); /** * @brief Remove a memory server from the MNS. @@ -247,12 +213,47 @@ namespace armarx::armem::client } + private: + + /** + * @brief Resolve the given memory server for the given memory ID. + * + * @param memoryID The memory ID. + * @return The memory server proxy. + * + * @throw `error::CouldNotResolveMemoryServer` If the memory name could not be resolved. + */ + mns::dto::MemoryServerInterfaces resolveServer(const MemoryID& memoryID); + + /** + * @brief Wait for the given memory server. + * + * @param memoryID The memory ID. + * @return The memory server proxy. + * + * @throw `error::CouldNotResolveMemoryServer` If the memory name could not be resolved. + */ + mns::dto::MemoryServerInterfaces waitForServer(const MemoryID& memoryID); + + /** + * @brief Wait for the given memory server and add a dependency to the memory server. + * + * @param memoryID The memory ID. + * @param component The component that should depend on the memory server. + * @return The memory server proxy. + * + * @throw `error::CouldNotResolveMemoryServer` If the memory name could not be resolved. + */ + mns::dto::MemoryServerInterfaces useServer(const MemoryID& memoryID); + mns::dto::MemoryServerInterfaces useServer(const MemoryID& memoryID, ManagedIceObject& component); + mns::dto::MemoryServerInterfaces useServer(const std::string& memoryName); + mns::dto::MemoryServerInterfaces useServer(const std::string& memoryName, ManagedIceObject& component); + + private: template <class ClientT> - std::map<std::string, ClientT> _getAllClients(bool update); - template <class ClientT> - std::map<std::string, ClientT> _getAllClients() const; + std::map<std::string, ClientT> _getAllClients(auto&& proxyFn) const; /// The MNS proxy. @@ -262,7 +263,7 @@ namespace armarx::armem::client ManagedIceObject* component = nullptr; /// The registered memory servers. - std::map<std::string, server::MemoryInterfacePrx> servers; + std::map<std::string, mns::dto::MemoryServerInterfaces> servers; }; diff --git a/source/RobotAPI/libraries/armem/mns/ComponentPlugin.cpp b/source/RobotAPI/libraries/armem/mns/ComponentPlugin.cpp deleted file mode 100644 index 79e58300a6968dfda3f60d89ff0511f9ec72f267..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/mns/ComponentPlugin.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "ComponentPlugin.h" - -#include <ArmarXCore/core/exceptions/local/ExpressionException.h> -#include <ArmarXCore/core/time/CycleUtil.h> - -#include "../error.h" - - -namespace armarx::armem::mns::plugins -{ - -} - - -namespace armarx::armem::mns -{ - - ComponentPluginUser::ComponentPluginUser() - { - addPlugin(plugin); - } - - - armem::data::RegisterMemoryResult ComponentPluginUser::registerMemory(const armem::data::RegisterMemoryInput& input, const Ice::Current&) - { - std::scoped_lock lock(mnsMutex); - armem::data::RegisterMemoryResult result = mns.registerMemory(input); - return result; - } - - - armem::data::RemoveMemoryResult ComponentPluginUser::removeMemory(const armem::data::RemoveMemoryInput& input, const Ice::Current&) - { - std::scoped_lock lock(mnsMutex); - armem::data::RemoveMemoryResult result = mns.removeMemory(input); - return result; - } - - - armem::data::GetAllRegisteredMemoriesResult - ComponentPluginUser::getAllRegisteredMemories(const Ice::Current&) - { - std::scoped_lock lock(mnsMutex); - armem::data::GetAllRegisteredMemoriesResult result = mns.getAllRegisteredMemories(); - return result; - } - - - armem::data::ResolveMemoryNameResult ComponentPluginUser::resolveMemoryName(const armem::data::ResolveMemoryNameInput& input, const Ice::Current&) - { - std::scoped_lock lock(mnsMutex); - armem::data::ResolveMemoryNameResult result = mns.resolveMemoryName(input); - return result; - } - - - armem::data::WaitForMemoryResult ComponentPluginUser::waitForMemory(const armem::data::WaitForMemoryInput& input, const Ice::Current&) - { - // No lock - this call blocks internally. - return mns.waitForMemory(input); - } - -} diff --git a/source/RobotAPI/libraries/armem/mns/ComponentPlugin.h b/source/RobotAPI/libraries/armem/mns/ComponentPlugin.h deleted file mode 100644 index 1347c197e6d4f560b5773abfed30b92e8f8a7604..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/mns/ComponentPlugin.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include <mutex> - -#include <ArmarXCore/core/Component.h> - -#include <RobotAPI/interface/armem/server/MemoryInterface.h> -#include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h> - -#include "MemoryNameSystem.h" - - -namespace armarx::armem::mns::plugins -{ - - class ComponentPlugin : public armarx::ComponentPlugin - { - public: - using armarx::ComponentPlugin::ComponentPlugin; - }; - -} - - -namespace armarx::armem::mns -{ - - /** - * @brief Utility for connecting a Memory to Ice. - */ - class ComponentPluginUser : - virtual public ManagedIceObject - , virtual public mns::MemoryNameSystemInterface - { - public: - - ComponentPluginUser(); - - // mns::MemoryNameSystemInterface interface - public: - armem::data::RegisterMemoryResult registerMemory(const armem::data::RegisterMemoryInput& input, const Ice::Current& = Ice::emptyCurrent) override; - armem::data::RemoveMemoryResult removeMemory(const armem::data::RemoveMemoryInput& input, const Ice::Current& = Ice::emptyCurrent) override; - armem::data::GetAllRegisteredMemoriesResult getAllRegisteredMemories(const Ice::Current&) override; - armem::data::ResolveMemoryNameResult resolveMemoryName(const armem::data::ResolveMemoryNameInput& input, const Ice::Current& = Ice::emptyCurrent) override; - armem::data::WaitForMemoryResult waitForMemory(const armem::data::WaitForMemoryInput& input, const Ice::Current& = Ice::emptyCurrent) override; - - - public: - - std::mutex mnsMutex; - MemoryNameSystem mns; - - - private: - - plugins::ComponentPlugin* plugin = nullptr; - - - }; - - -} diff --git a/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.cpp b/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.cpp index 6e001784b90104580a49b2510bdb6583fa36783c..a80a189ff585c7610bebe0978468aec82ebe48b9 100644 --- a/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.cpp +++ b/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.cpp @@ -4,185 +4,41 @@ namespace armarx::armem::mns { - MemoryNameSystem::MemoryNameSystem(const std::string& logTag) + // dto::WaitForServerResult MemoryNameSystem::waitForServer(const dto::WaitForServerInput& input) + void MemoryNameSystem::waitForServer_async( + const AMD_MemoryNameSystemInterface_waitForServerPtr& future, + const dto::WaitForServerInput& input) { - armarx::Logging::setTag(logTag); + waitForServerFutures[input.name].push_back(future); + waitForServer_processOnce(); } - armem::data::RegisterMemoryResult MemoryNameSystem::registerMemory(const armem::data::RegisterMemoryInput& input) + void MemoryNameSystem::waitForServer_processOnce() { - armem::data::RegisterMemoryResult result; - - if (!input.proxy) - { - result.success = false; - std::stringstream ss; - ss << "Could not register the memory '" << input.name << "'." - << "\nGiven proxy is null." - << "\nIf you want to remove a memory, use `removeMemory()`."; - result.errorMessage = ss.str(); - return result; - } - - auto it = memoryMap.find(input.name); - if (it == memoryMap.end()) - { - it = memoryMap.emplace(input.name, MemoryInfo{}).first; - } - else if (!input.existOk) - { - result.success = false; - std::stringstream ss; - ss << "Could not register the memory '" << input.name << "'." - << "\nMemory '" << input.name << "' is already registered. " - << "\nIf this is ok, set 'existOk' to true when registering the memory."; - result.errorMessage = ss.str(); - return result; - } - - MemoryInfo& info = it->second; - info.name = input.name; - info.proxy = input.proxy; - info.timeRegistered = armem::Time::now(); - ARMARX_DEBUG << "Registered memory '" << info.name << "'."; - - { - std::unique_lock lock(waitForMemoryMutex); - waitForMemoryCond.notify_all(); - } - - result.success = true; - return result; - } - - - armem::data::RemoveMemoryResult MemoryNameSystem::removeMemory(const armem::data::RemoveMemoryInput& input) - { - armem::data::RemoveMemoryResult result; - - if (auto it = memoryMap.find(input.name); it != memoryMap.end()) - { - result.success = true; - memoryMap.erase(it); - - ARMARX_DEBUG << "Removed memory '" << input.name << "'."; - } - else if (!input.notExistOk) - { - result.success = false; - std::stringstream ss; - ss << "Could not remove the memory '" << input.name << "." - << "\nMemory '" << input.name << "' is not registered. " - << "\nIf this is ok, set 'notExistOk' to true when removing the memory."; - result.errorMessage = ss.str(); - } - - return result; - } - - - data::GetAllRegisteredMemoriesResult - MemoryNameSystem::getAllRegisteredMemories() - { - data::GetAllRegisteredMemoriesResult result; - result.success = true; - result.errorMessage = ""; - - for (const auto& [name, info] : memoryMap) + for (auto it = waitForServerFutures.begin(); it != waitForServerFutures.end();) { - try + auto& [name, futures] = *it; + if (auto st = servers.find(name); st != servers.end()) { - info.proxy->ice_ping(); - result.proxies[name] = info.proxy; - } - catch (const Ice::Exception&) - { - } - } - - return result; - } - - - armem::data::ResolveMemoryNameResult MemoryNameSystem::resolveMemoryName(const armem::data::ResolveMemoryNameInput& input) - { - armem::data::ResolveMemoryNameResult result; - try - { - MemoryInfo& info = memoryMap.at(input.name); - - result.success = true; - result.proxy = info.proxy; - - ARMARX_DEBUG << "Resolved memory name '" << input.name << "'."; - } - catch (const std::out_of_range&) - { - result.success = false; - std::stringstream ss; - ss << "Could not resolve the memory name '" << input.name << "'." - << "\nMemory '" << input.name << "' is not registered."; - result.errorMessage = ss.str(); - } - - return result; - } - - - data::WaitForMemoryResult MemoryNameSystem::waitForMemory(const data::WaitForMemoryInput& input) - { - data::ResolveMemoryNameInput resInput; - resInput.name = input.name; - - Time start = Time::now(); - data::ResolveMemoryNameResult resResult; - { - std::unique_lock lock(waitForMemoryMutex); - auto pred = [this, resInput, &resResult]() - { - resResult = resolveMemoryName(resInput); - return resResult.success; - }; - if (input.timeoutMilliSeconds >= 0) - { - waitForMemoryCond.wait_for(lock, std::chrono::milliseconds(input.timeoutMilliSeconds), pred); + ServerInfo& info = st->second; + + dto::WaitForServerResult result; + result.success = true; + result.server = info.server; + + // Send responses and remove entry. + for (auto& future : futures) + { + future->ice_response(result); + } + it = waitForServerFutures.erase(it); } else { - waitForMemoryCond.wait(lock, pred); + ++it; // Skip. } } - - armem::data::WaitForMemoryResult result; - result.success = resResult.success; - - if (resResult.success) - { - ARMARX_CHECK(resResult.proxy); - result.proxy = resResult.proxy; - } - else - { - ARMARX_CHECK((Time::now() - start).toMilliSeconds() > input.timeoutMilliSeconds) - << (Time::now() - start).toMilliSeconds() << " > " << input.timeoutMilliSeconds; - - std::stringstream ss; - ss << "Timeout (" << input.timeoutMilliSeconds << " ms) while waiting for memory '" << input.name << "'."; - if (resResult.errorMessage.size() > 0) - { - ss << "\n" << resResult.errorMessage; - } - result.errorMessage = ss.str(); - } - - return result; - } - - - bool MemoryNameSystem::hasMemory(const std::string& memoryName) const - { - return memoryMap.count(memoryName) > 0; } @@ -195,20 +51,41 @@ namespace armarx::armem::mns int row = 0; grid.add(Label("Memory Name"), {row, 0}) .add(Label("Component Name"), {row, 1}) - .add(Label("Registration Time"), {row, 2}) + .add(Label("R/W"), {row, 2}) + .add(Label("Registration Time"), {row, 3}) ; row++; - for (const auto& [name, info] : memoryMap) + for (const auto& [name, info] : servers) { ARMARX_CHECK_EQUAL(name, info.name); - grid - .add(Label(name), {row, 0}) - .add(Label(info.proxy->ice_getIdentity().name), {row, 1}) - .add(Label(armem::toDateTimeMilliSeconds(info.timeRegistered, 0)), {row, 2}) - ; + std::string componentName = ""; + std::string mode = ""; + if (info.server.reading) + { + componentName = info.server.reading->ice_getIdentity().name; + mode += "R"; + } + if (info.server.writing) + { + componentName = info.server.writing->ice_getIdentity().name; + mode += "W"; + } + + int col = 0; + grid.add(Label(name), {row, col}); + ++col; + + grid.add(Label(componentName), {row, col}); + ++col; + + grid.add(Label(mode), {row, col}); + ++col; + + grid.add(Label(armem::toDateTimeMilliSeconds(info.timeRegistered, 0)), {row, col}); + ++col; - row++; + ++row; } return grid; diff --git a/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.h b/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.h index 7372246d7e8059787f97f117931830d12c9dc082..51e4719f127ee576073e0c9b45cb0635241a185d 100644 --- a/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.h +++ b/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.h @@ -1,55 +1,36 @@ #pragma once -#include <condition_variable> -#include <mutex> - -#include <ArmarXCore/core/logging/Logging.h> +#include "Registry.h" #include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h> -#include <RobotAPI/interface/armem/server/MemoryInterface.h> #include <ArmarXGui/libraries/ArmarXGuiComponentPlugins/LightweightRemoteGuiComponentPlugin.h> -#include "../core/Time.h" +#include <map> +#include <string> namespace armarx::armem::mns { - class MemoryNameSystem : armarx::Logging + class MemoryNameSystem : public Registry { public: - MemoryNameSystem(const std::string& logTag = "MemoryNameSystem"); - - - /** - * @brief Register a new memory or update an existing entry. - * - * Causes threads waiting in `waitForMemory()` to resume if the respective - * memory was added. - */ - data::RegisterMemoryResult registerMemory(const data::RegisterMemoryInput& input); - /** - * @brief Remove a memory entry. - */ - data::RemoveMemoryResult removeMemory(const data::RemoveMemoryInput& input); + using WaitForServerFuturePtr = AMD_MemoryNameSystemInterface_waitForServerPtr; - data::GetAllRegisteredMemoriesResult getAllRegisteredMemories(); - /** - * @brief Gets a memory entry, if it is available. - */ - data::ResolveMemoryNameResult resolveMemoryName(const data::ResolveMemoryNameInput& input); + public: /** - * @brief Blocks until the specified memory is available, returning its proxy. + * @brief Store the call in a container for later response. */ - data::WaitForMemoryResult waitForMemory(const data::WaitForMemoryInput& input); + void waitForServer_async( + const AMD_MemoryNameSystemInterface_waitForServerPtr& future, + const dto::WaitForServerInput& input); + void waitForServer_processOnce(); - /// Indicates whether a memory entry for that name exists. - bool hasMemory(const std::string& memoryName) const; /// Builds a RemoteGui grid containing information about registered memories. armarx::RemoteGui::Client::GridLayout RemoteGui_buildInfoGrid(); @@ -57,22 +38,8 @@ namespace armarx::armem::mns public: - /// Information about a memory entry. - struct MemoryInfo - { - std::string name; - server::MemoryInterfacePrx proxy; - Time timeRegistered; - }; - - /// The registered memories. - std::map<std::string, MemoryInfo> memoryMap; - - - /// Mutex for `waitForMemoryCond`. - std::mutex waitForMemoryMutex; - /// Condition variable used by `waitForMemory()`. - std::condition_variable waitForMemoryCond; + /// Queued calls to `waitForServer`. + std::map<std::string, std::vector<WaitForServerFuturePtr>> waitForServerFutures; }; diff --git a/source/RobotAPI/libraries/armem/mns/Registry.cpp b/source/RobotAPI/libraries/armem/mns/Registry.cpp new file mode 100644 index 0000000000000000000000000000000000000000..260cfcd818a426ae7b4f18c6cde5a4180a459f0b --- /dev/null +++ b/source/RobotAPI/libraries/armem/mns/Registry.cpp @@ -0,0 +1,162 @@ +#include "Registry.h" + +#include <ArmarXCore/core/logging/Logging.h> + + +namespace armarx::armem::mns +{ + + Registry::Registry(const std::string& logTag) + { + armarx::Logging::setTag(logTag); + } + + + bool Registry::hasServer(const std::string& memoryName) const + { + return servers.count(memoryName) > 0; + } + + + dto::RegisterServerResult Registry::registerServer(const dto::RegisterServerInput& input) + { + dto::RegisterServerResult result; + + if (not(input.server.reading or input.server.writing)) + { + result.success = false; + std::stringstream ss; + ss << "Could not register the memory server '" << input.name << "'." + << "\nGiven proxies are null." + << "\nIf you want to remove a memory server, use `removeServer()`."; + result.errorMessage = ss.str(); + return result; + } + + auto it = servers.find(input.name); + if (it == servers.end()) + { + it = servers.emplace(input.name, ServerInfo{}).first; + } + else if (not input.existOk) + { + result.success = false; + std::stringstream ss; + ss << "Could not register the memory '" << input.name << "'." + << "\nMemory '" << input.name << "' is already registered. " + << "\nIf this is ok, set 'existOk' to true when registering the memory."; + result.errorMessage = ss.str(); + return result; + } + + ServerInfo& info = it->second; + info.name = input.name; + info.server = input.server; + info.timeRegistered = armem::Time::now(); + ARMARX_DEBUG << "Registered memory '" << info.name << "'."; + + result.success = true; + return result; + } + + + dto::RemoveServerResult Registry::removeServer(const dto::RemoveServerInput& input) + { + dto::RemoveServerResult result; + + if (auto it = servers.find(input.name); it != servers.end()) + { + result.success = true; + servers.erase(it); + + ARMARX_DEBUG << "Removed memory '" << input.name << "'."; + } + else if (!input.notExistOk) + { + result.success = false; + std::stringstream ss; + ss << "Could not remove the memory '" << input.name << "." + << "\nMemory '" << input.name << "' is not registered. " + << "\nIf this is ok, set 'notExistOk' to true when removing the memory."; + result.errorMessage = ss.str(); + } + + return result; + } + + + template <class Prx> + bool isAvailable(const Prx& proxy) + { + if (proxy) + { + try + { + proxy->ice_ping(); + return true; + } + catch (const Ice::Exception&) + { + } + } + return false; + } + + + dto::GetAllRegisteredServersResult + Registry::getAllRegisteredServers() + { + dto::GetAllRegisteredServersResult result; + result.success = true; + result.errorMessage = ""; + + for (const auto& [name, info] : servers) + { + if (isAvailable(info.server.reading) or isAvailable(info.server.writing)) + { + result.servers[name] = info.server; + } + } + + return result; + } + + + dto::ResolveServerResult Registry::resolveServer(const dto::ResolveServerInput& input) + { + dto::ResolveServerResult result; + try + { + ServerInfo& info = servers.at(input.name); + + result.success = true; + result.server = info.server; + + ARMARX_DEBUG << "Resolved memory name '" << input.name << "'."; + } + catch (const std::out_of_range&) + { + result.success = false; + std::stringstream ss; + ss << "Could not resolve the memory name '" << input.name << "'." + << "\nServer '" << input.name << "' is not registered."; + result.errorMessage = ss.str(); + } + + return result; + } + + + server::ReadingMemoryInterfacePrx getReadingInterface(const dto::MemoryServerInterfaces& server) + { + return server.reading; + } + + + server::WritingMemoryInterfacePrx getWritingInterface(const dto::MemoryServerInterfaces& server) + { + return server.writing; + } + +} + diff --git a/source/RobotAPI/libraries/armem/mns/Registry.h b/source/RobotAPI/libraries/armem/mns/Registry.h new file mode 100644 index 0000000000000000000000000000000000000000..bf9348d157ee990f6032c4cf115b9fd56c70f716 --- /dev/null +++ b/source/RobotAPI/libraries/armem/mns/Registry.h @@ -0,0 +1,71 @@ +#pragma once + +#include <RobotAPI/libraries/armem/core/Time.h> + +#include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h> +#include <RobotAPI/interface/armem/server/ReadingMemoryInterface.h> +#include <RobotAPI/interface/armem/server/WritingMemoryInterface.h> + +#include <ArmarXCore/core/logging/Logging.h> + +#include <map> +#include <string> + + +namespace armarx::armem::mns +{ + + /** + * @brief A registry for memory servers. + */ + class Registry : armarx::Logging + { + public: + + Registry(const std::string& logTag = "MemoryNameSystem Registry"); + + + /// Indicates whether a server entry for that name exists. + bool hasServer(const std::string& memoryName) const; + + + /** + * @brief Register a new memory server or update an existing entry. + * + * Causes threads waiting in `waitForMemory()` to resume if the respective + * memory server was added. + */ + dto::RegisterServerResult registerServer(const dto::RegisterServerInput& input); + /** + * @brief Remove a server entry. + */ + dto::RemoveServerResult removeServer(const dto::RemoveServerInput& input); + + + /** + * @brief Gets a server entry, if it is available. + */ + dto::ResolveServerResult resolveServer(const dto::ResolveServerInput& input); + + dto::GetAllRegisteredServersResult getAllRegisteredServers(); + + + public: + + /// Information about a memory entry. + struct ServerInfo + { + std::string name; + mns::dto::MemoryServerInterfaces server; + Time timeRegistered; + }; + + /// The registered memories. + std::map<std::string, ServerInfo> servers; + + }; + + + server::ReadingMemoryInterfacePrx getReadingInterface(const dto::MemoryServerInterfaces& server); + server::WritingMemoryInterfacePrx getWritingInterface(const dto::MemoryServerInterfaces& server); +} diff --git a/source/RobotAPI/libraries/armem/mns/plugins/Plugin.cpp b/source/RobotAPI/libraries/armem/mns/plugins/Plugin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a2e7c5dbf3fe87d6fdf24fee0181504a5f85abe9 --- /dev/null +++ b/source/RobotAPI/libraries/armem/mns/plugins/Plugin.cpp @@ -0,0 +1,8 @@ +#include "Plugin.h" + + +namespace armarx::armem::mns::plugins +{ + +} + diff --git a/source/RobotAPI/libraries/armem/mns/plugins/Plugin.h b/source/RobotAPI/libraries/armem/mns/plugins/Plugin.h new file mode 100644 index 0000000000000000000000000000000000000000..5caa973a9ebb7025f42978c608c033ce47722074 --- /dev/null +++ b/source/RobotAPI/libraries/armem/mns/plugins/Plugin.h @@ -0,0 +1,24 @@ +#pragma once + +#include <RobotAPI/libraries/armem/mns/MemoryNameSystem.h> + +#include <ArmarXCore/core/ComponentPlugin.h> + + +namespace armarx::armem::mns::plugins +{ + + class Plugin : public armarx::ComponentPlugin + { + public: + + using armarx::ComponentPlugin::ComponentPlugin; + + + public: + + MemoryNameSystem mns; + + }; + +} diff --git a/source/RobotAPI/libraries/armem/mns/plugins/PluginUser.cpp b/source/RobotAPI/libraries/armem/mns/plugins/PluginUser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4ad29cdeec3c2b732cf1b9074931ab3c116fa42b --- /dev/null +++ b/source/RobotAPI/libraries/armem/mns/plugins/PluginUser.cpp @@ -0,0 +1,69 @@ +#include "PluginUser.h" +#include "Plugin.h" + + +namespace armarx::armem::mns::plugins +{ + + PluginUser::PluginUser() + { + addPlugin(plugin); + } + + + dto::RegisterServerResult PluginUser::registerServer(const dto::RegisterServerInput& input, const Ice::Current&) + { + std::scoped_lock lock(mnsMutex); + dto::RegisterServerResult result = plugin->mns.registerServer(input); + return result; + } + + + dto::RemoveServerResult PluginUser::removeServer(const dto::RemoveServerInput& input, const Ice::Current&) + { + std::scoped_lock lock(mnsMutex); + dto::RemoveServerResult result = plugin->mns.removeServer(input); + return result; + } + + + dto::GetAllRegisteredServersResult + PluginUser::getAllRegisteredServers(const Ice::Current&) + { + std::scoped_lock lock(mnsMutex); + dto::GetAllRegisteredServersResult result = plugin->mns.getAllRegisteredServers(); + return result; + } + + + dto::ResolveServerResult PluginUser::resolveServer(const dto::ResolveServerInput& input, const Ice::Current&) + { + std::scoped_lock lock(mnsMutex); + dto::ResolveServerResult result = plugin->mns.resolveServer(input); + return result; + } + + + // dto::WaitForServerResult PluginUser::waitForServer(const dto::WaitForServerInput& input, const Ice::Current&) + void PluginUser::waitForServer_async( + const AMD_MemoryNameSystemInterface_waitForServerPtr& future, + const dto::WaitForServerInput& input, + const Ice::Current&) + { + std::scoped_lock lock(mnsMutex); + plugin->mns.waitForServer_async(future, input); + } + + + MemoryNameSystem& PluginUser::mns() + { + return plugin->mns; + } + + + const MemoryNameSystem& PluginUser::mns() const + { + return plugin->mns; + } + +} diff --git a/source/RobotAPI/libraries/armem/mns/plugins/PluginUser.h b/source/RobotAPI/libraries/armem/mns/plugins/PluginUser.h new file mode 100644 index 0000000000000000000000000000000000000000..1e8134ad5d372b1d69252cdc0cf2f5916c948b1e --- /dev/null +++ b/source/RobotAPI/libraries/armem/mns/plugins/PluginUser.h @@ -0,0 +1,55 @@ +#pragma once + +#include <RobotAPI/libraries/armem/mns/MemoryNameSystem.h> + +#include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h> + +#include <ArmarXCore/core/ManagedIceObject.h> + +#include <mutex> + + +namespace armarx::armem::mns::plugins +{ + class Plugin; + + + class PluginUser : + virtual public ManagedIceObject + , virtual public mns::MemoryNameSystemInterface + { + public: + + PluginUser(); + + // mns::MemoryNameSystemInterface interface + public: + + dto::RegisterServerResult registerServer(const dto::RegisterServerInput& input, const Ice::Current& = Ice::emptyCurrent) override; + dto::RemoveServerResult removeServer(const dto::RemoveServerInput& input, const Ice::Current& = Ice::emptyCurrent) override; + + dto::GetAllRegisteredServersResult getAllRegisteredServers(const Ice::Current&) override; + + dto::ResolveServerResult resolveServer(const dto::ResolveServerInput& input, const Ice::Current& = Ice::emptyCurrent) override; + + // Uses Asynchronous Method Dispatch (AMD) + void waitForServer_async( + const AMD_MemoryNameSystemInterface_waitForServerPtr& future, + const dto::WaitForServerInput& input, + const Ice::Current& = Ice::emptyCurrent) override; + + + protected: + + std::mutex mnsMutex; + MemoryNameSystem& mns(); + const MemoryNameSystem& mns() 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 93246434d7579368907c320b73379951765c548f..cc0d28920fd0500dfb36f0c8c30c83d1762810db 100644 --- a/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp +++ b/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp @@ -71,16 +71,17 @@ namespace armarx::armem::server::plugins } - data::RegisterMemoryResult ComponentPlugin::registerMemory(ComponentPluginUser& parent) + mns::dto::RegisterServerResult ComponentPlugin::registerMemory(ComponentPluginUser& parent) { MemoryID id = MemoryID().withMemoryName(parent.workingMemory().name()); - MemoryInterfacePrx proxy = MemoryInterfacePrx::checkedCast(parent.getProxy()); - ARMARX_CHECK_NOT_NULL(proxy); + mns::dto::MemoryServerInterfaces server; + server.reading = ReadingMemoryInterfacePrx::uncheckedCast(parent.getProxy()); + server.writing = WritingMemoryInterfacePrx::uncheckedCast(parent.getProxy()); - data::RegisterMemoryResult result; + mns::dto::RegisterServerResult result; try { - parent.memoryNameSystem().registerServer(id, proxy); + parent.memoryNameSystem().registerServer(id, server); result.success = true; ARMARX_DEBUG << "Registered memory server for " << id << " in the Memory Name System (MNS)."; } @@ -94,11 +95,11 @@ namespace armarx::armem::server::plugins } - data::RemoveMemoryResult ComponentPlugin::removeMemory(ComponentPluginUser& parent) + mns::dto::RemoveServerResult ComponentPlugin::removeMemory(ComponentPluginUser& parent) { MemoryID id = MemoryID().withMemoryName(parent.workingMemory().name()); - data::RemoveMemoryResult result; + mns::dto::RemoveServerResult result; try { parent.memoryNameSystem().removeServer(id); diff --git a/source/RobotAPI/libraries/armem/server/ComponentPlugin.h b/source/RobotAPI/libraries/armem/server/ComponentPlugin.h index 4c9c66ee02ac3416da4b229df75d81522f6724a6..f198a23b1d4b969e41ddfaa3e2eb341b803bee40 100644 --- a/source/RobotAPI/libraries/armem/server/ComponentPlugin.h +++ b/source/RobotAPI/libraries/armem/server/ComponentPlugin.h @@ -47,14 +47,14 @@ namespace armarx::armem::server::plugins * * Called before onConnect() if MNS is enabled. */ - data::RegisterMemoryResult registerMemory(ComponentPluginUser& parent); + mns::dto::RegisterServerResult registerMemory(ComponentPluginUser& parent); /** * @brief Remove the parent component from the MNS. * * Called before onDisconnect() if MNS is enabled. */ - data::RemoveMemoryResult removeMemory(ComponentPluginUser& parent); + mns::dto::RemoveServerResult removeMemory(ComponentPluginUser& parent);