diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt index 8e65efbcd2c10e3c68d4f6c23aade3293c8318e9..2b4b5344c2321ab58bc3fb6749dc6b2810405ecd 100644 --- a/source/RobotAPI/libraries/armem/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem/CMakeLists.txt @@ -30,7 +30,9 @@ set(LIB_FILES memory/InternalCommit.cpp memory/Memory.cpp memory/ProviderSegment.cpp + memory/detail/EntityStorage.cpp + memory/detail/MemoryLevel.cpp mns/MemoryNameSystem.cpp mns/MemoryNameSystemClientPlugin.cpp @@ -69,8 +71,10 @@ set(LIB_HEADERS memory/InternalCommit.h memory/Memory.h memory/ProviderSegment.h + memory/detail/EntityStorage.h memory/detail/MemoryContainer.h + memory/detail/MemoryLevel.h mns/MemoryNameSystem.h mns/MemoryNameSystemClientPlugin.h diff --git a/source/RobotAPI/libraries/armem/memory/CoreSegment.cpp b/source/RobotAPI/libraries/armem/memory/CoreSegment.cpp index f2590c4adb6bd6b3c021be6dd084c32f7e89e182..c5bbf7554d71b152e1e70e0ca9c984ba6794d69f 100644 --- a/source/RobotAPI/libraries/armem/memory/CoreSegment.cpp +++ b/source/RobotAPI/libraries/armem/memory/CoreSegment.cpp @@ -57,13 +57,13 @@ namespace armarx::armem } else { - throw armem::error::MissingEntry("provider segment", name, "core segment", this->name); + throw armem::error::MissingEntry("provider segment", name, getLevelName(), this->name); } } const Entity& CoreSegment::getEntity(const MemoryID& id) const { - checkStorageName(id.coreSegmentName, this->name, "core segment"); + checkStorageName(id.coreSegmentName, this->name, getLevelName()); return getProviderSegment(id.providerSegmentName).getEntity(id); } @@ -83,7 +83,7 @@ namespace armarx::armem { if (hasProviderSegment(name)) { - throw armem::error::StorageEntryAlreadyExists("provider segment", name, "core segment", this->name); + throw armem::error::StorageEntryAlreadyExists("provider segment", name, getLevelName(), this->name); } auto it = providerSegments.emplace(providerSegment->name, std::move(providerSegment)).first; ARMARX_CHECK_NOT_NULL(it->second); @@ -93,7 +93,7 @@ namespace armarx::armem MemoryID CoreSegment::update(const InternalEntityUpdate& update) { - checkStorageName(update.entityID.coreSegmentName, this->name, "core segment"); + checkStorageName(update.entityID.coreSegmentName, this->name, getLevelName()); auto it = this->providerSegments.find(update.entityID.providerSegmentName); if (it != providerSegments.end()) @@ -103,13 +103,8 @@ namespace armarx::armem else { throw armem::error::MissingEntry("provider segment", update.entityID.providerSegmentName, - "core segment", name); + getLevelName(), name); } } - void CoreSegment::clear() - { - providerSegments.clear(); - } - } diff --git a/source/RobotAPI/libraries/armem/memory/CoreSegment.h b/source/RobotAPI/libraries/armem/memory/CoreSegment.h index 6a9e30da50158a93bdaf6ee30d52f18f5321b12b..aeccaabb3d96c992d12ffa23eeffa832fbe9a228 100644 --- a/source/RobotAPI/libraries/armem/memory/CoreSegment.h +++ b/source/RobotAPI/libraries/armem/memory/CoreSegment.h @@ -56,9 +56,6 @@ namespace armarx::armem /// Move and insert a provider segment. ProviderSegment& addProviderSegment(ProviderSegmentPtr&& providerSegment); - /// Clear the provider segments. - void clear() override; - /// Get an cleared copy of `*this` (without provider segments). CoreSegmentPtr getEmptyCopy() const; @@ -69,12 +66,14 @@ namespace armarx::armem std::map<std::string, ProviderSegmentPtr> providerSegments; - // MemoryContainer interface + // MemoryLevel interface public: std::string getLevelName() const override { return "core segment"; } + + // MemoryContainer interface protected: ContainerT& _underlyingContainer() override { diff --git a/source/RobotAPI/libraries/armem/memory/Entity.cpp b/source/RobotAPI/libraries/armem/memory/Entity.cpp index 712f48380262c82b7bef372417843c21adb007a4..8387424e7f5f27e396106f117977d2bf1b8ab5c6 100644 --- a/source/RobotAPI/libraries/armem/memory/Entity.cpp +++ b/source/RobotAPI/libraries/armem/memory/Entity.cpp @@ -66,7 +66,7 @@ namespace armarx::armem else { throw error::MissingEntry("entity snapshot", toDateTimeMilliSeconds(time), - "entity", this->name); + getLevelName(), this->name); } } @@ -169,7 +169,7 @@ namespace armarx::armem { if (name != this->name) { - throw armem::error::StorageNameMismatch(name, "entity", this->name); + throw armem::error::StorageNameMismatch(name, getLevelName(), this->name); } } @@ -182,14 +182,4 @@ namespace armarx::armem return *history.rbegin(); } - std::string Entity::getLevelName() const - { - return "entity"; - } - - Entity::ContainerT& Entity::_underlyingContainer() - { - return history; - } - } diff --git a/source/RobotAPI/libraries/armem/memory/Entity.h b/source/RobotAPI/libraries/armem/memory/Entity.h index 46edfeffcecd6ba5ceda5b3389e216b90643fb12..5477509b17618509b24cc8efe7269ae69e3c4408 100644 --- a/source/RobotAPI/libraries/armem/memory/Entity.h +++ b/source/RobotAPI/libraries/armem/memory/Entity.h @@ -19,7 +19,9 @@ namespace armarx::armem /** * @brief Data of an entity over a period of time. */ - class Entity : public detail::MemoryContainer<std::map<Time, EntitySnapshotPtr>> + class Entity : + public detail::MemoryLevel, + public detail::MemoryContainer<std::map<Time, EntitySnapshotPtr>> { public: @@ -116,11 +118,23 @@ namespace armarx::armem - // MemoryContainer interface + // MemoryLevel interface public: - std::string getLevelName() const override; + std::string getKeyString() const override + { + return name; + } + std::string getLevelName() const override + { + return "entity"; + } + + // MemoryContainer interface protected: - ContainerT& _underlyingContainer() override; + ContainerT& _underlyingContainer() override + { + return history; + } }; diff --git a/source/RobotAPI/libraries/armem/memory/EntityData.h b/source/RobotAPI/libraries/armem/memory/EntityData.h index 66464130886214216b19fd18b14420678acef8bc..b01196f2dfd63b9564b67bcdbac7f303f84e2d0c 100644 --- a/source/RobotAPI/libraries/armem/memory/EntityData.h +++ b/source/RobotAPI/libraries/armem/memory/EntityData.h @@ -8,6 +8,7 @@ #include "../core/Time.h" #include "InternalCommit.h" +#include "detail/MemoryLevel.h" namespace armarx::armem @@ -33,7 +34,7 @@ namespace armarx::armem /** * @brief Data of a single entity instance. */ - struct EntityData + struct EntityData : public detail::MemoryLevel { int index; @@ -51,6 +52,18 @@ namespace armarx::armem */ void update(const InternalEntityUpdate& update, int index); + + // MemoryLevel interface + public: + std::string getKeyString() const override + { + return std::to_string(index); + } + std::string getLevelName() const override + { + return "entity data"; + } + }; using EntityDataPtr = std::unique_ptr<EntityData>; diff --git a/source/RobotAPI/libraries/armem/memory/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/memory/EntitySnapshot.cpp index 8b8882b4b03920ba90f49ab7d6aa232f2ffa2cea..abe7180ad9f75f81352fc9e40815207f7baa523c 100644 --- a/source/RobotAPI/libraries/armem/memory/EntitySnapshot.cpp +++ b/source/RobotAPI/libraries/armem/memory/EntitySnapshot.cpp @@ -54,7 +54,7 @@ namespace armarx::armem else { throw armem::error::MissingEntry("instance", std::to_string(index), - "entity snapshot", toDateTimeMilliSeconds(time)); + getLevelName(), toDateTimeMilliSeconds(time)); } } @@ -68,14 +68,8 @@ namespace armarx::armem return getInstance(id.instanceIndex); } - std::string EntitySnapshot::getLevelName() const - { - return "entity snapshot"; - } - EntitySnapshot::ContainerT& EntitySnapshot::_underlyingContainer() - { - return instances; - } + + } diff --git a/source/RobotAPI/libraries/armem/memory/EntitySnapshot.h b/source/RobotAPI/libraries/armem/memory/EntitySnapshot.h index 182450dad748433d34f3c8406b4ef7221289313b..ab607b09ce7e1eeb073172ad36f88bdc6c2158b4 100644 --- a/source/RobotAPI/libraries/armem/memory/EntitySnapshot.h +++ b/source/RobotAPI/libraries/armem/memory/EntitySnapshot.h @@ -7,6 +7,7 @@ #include "../core/MemoryID.h" #include "EntityData.h" +#include "detail/MemoryLevel.h" #include "detail/MemoryContainer.h" @@ -16,7 +17,9 @@ namespace armarx::armem /** * @brief Data of an entity at one point in time. */ - class EntitySnapshot : public detail::MemoryContainer<std::vector<EntityDataPtr>> + class EntitySnapshot : + public detail::MemoryLevel, + public detail::MemoryContainer<std::vector<EntityDataPtr>> { public: @@ -56,11 +59,23 @@ namespace armarx::armem - // MemoryContainer interface + // MemoryLevel interface public: - std::string getLevelName() const override; + std::string getKeyString() const override + { + return toDateTimeMilliSeconds(time); + } + std::string getLevelName() const override + { + return "entity snapshot"; + } + + // MemoryContainer interface protected: - ContainerT& _underlyingContainer() override; + ContainerT& _underlyingContainer() override + { + return instances; + } }; diff --git a/source/RobotAPI/libraries/armem/memory/Memory.cpp b/source/RobotAPI/libraries/armem/memory/Memory.cpp index 8f80ba8b61c77f6c615ff4549af424e28be0105d..40b11cf18dd36095ac2f441f90c9c8499aeca6a8 100644 --- a/source/RobotAPI/libraries/armem/memory/Memory.cpp +++ b/source/RobotAPI/libraries/armem/memory/Memory.cpp @@ -57,14 +57,14 @@ namespace armarx::armem } else { - throw armem::error::MissingEntry("core segment", name, "memory", this->name); + throw armem::error::MissingEntry("core segment", name, getLevelName(), this->name); } } const Entity& Memory::getEntity(const MemoryID& id) const { - checkStorageName(id.memoryName, this->name, "memory"); + checkStorageName(id.memoryName, this->name, getLevelName()); return getCoreSegment(id.coreSegmentName).getEntity(id); } @@ -82,7 +82,7 @@ namespace armarx::armem { if (coreSegments.count(name) > 0) { - throw armem::error::StorageEntryAlreadyExists("core segment", name, "memory", this->name); + throw armem::error::StorageEntryAlreadyExists("core segment", name, getLevelName(), this->name); } auto it = coreSegments.emplace(coreSegment->name, std::move(coreSegment)).first; ARMARX_CHECK_NOT_NULL(it->second); @@ -109,7 +109,7 @@ namespace armarx::armem MemoryID Memory::update(const InternalEntityUpdate& update) { - checkStorageName(update.entityID.memoryName, this->name, "memory"); + checkStorageName(update.entityID.memoryName, this->name, getLevelName()); auto it = this->coreSegments.find(update.entityID.coreSegmentName); if (it != coreSegments.end()) @@ -119,14 +119,9 @@ namespace armarx::armem else { throw armem::error::MissingEntry("core segment", update.entityID.coreSegmentName, - "memory", name); + getLevelName(), name); } } - void Memory::clear() - { - coreSegments.clear(); - } - } diff --git a/source/RobotAPI/libraries/armem/memory/Memory.h b/source/RobotAPI/libraries/armem/memory/Memory.h index 456114f5792935d3e3007fb582927f98e3be1fda..f8895e12389326fb2a270c5c0665ed2755ab8284 100644 --- a/source/RobotAPI/libraries/armem/memory/Memory.h +++ b/source/RobotAPI/libraries/armem/memory/Memory.h @@ -64,9 +64,6 @@ namespace armarx::armem virtual MemoryID update(const InternalEntityUpdate& update) override; using EntityStorage::update; - /// Clear the core segments. - void clear() override; - /// Get an cleared copy of `*this` (without core segments). MemoryPtr getEmptyCopy() const; @@ -76,12 +73,14 @@ namespace armarx::armem std::map<std::string, CoreSegmentPtr> coreSegments; - // MemoryContainer interface + // MemoryLevel interface public: std::string getLevelName() const override { return "memory"; } + + // MemoryContainer interface protected: ContainerT& _underlyingContainer() override { diff --git a/source/RobotAPI/libraries/armem/memory/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/memory/ProviderSegment.cpp index d78bf742815b34f84e59d7e0e60bcc8db0918075..23400ca9e54d74b7b60df32a8770de9d8a937606 100644 --- a/source/RobotAPI/libraries/armem/memory/ProviderSegment.cpp +++ b/source/RobotAPI/libraries/armem/memory/ProviderSegment.cpp @@ -58,19 +58,19 @@ namespace armarx::armem } else { - throw error::MissingEntry("entity", name, "provider segment", this->name); + throw error::MissingEntry("entity", name, getLevelName(), this->name); } } const Entity& ProviderSegment::getEntity(const MemoryID& id) const { - checkStorageName(id.providerSegmentName, this->name, "provider segment"); + checkStorageName(id.providerSegmentName, this->name, getLevelName()); return getEntity(id.entityName); } MemoryID ProviderSegment::update(const InternalEntityUpdate& update) { - checkStorageName(update.entityID.providerSegmentName, this->name, "provider segment"); + checkStorageName(update.entityID.providerSegmentName, this->name, getLevelName()); auto it = this->entities.find(update.entityID.providerSegmentName); if (it == entities.end()) @@ -100,11 +100,6 @@ namespace armarx::armem return *it->second; } - void ProviderSegment::clear() - { - entities.clear(); - } - void ProviderSegment::setMaxHistorySize(long maxSize) { this->maxHistorySize = maxSize; diff --git a/source/RobotAPI/libraries/armem/memory/ProviderSegment.h b/source/RobotAPI/libraries/armem/memory/ProviderSegment.h index 07580d23ee1a111d31c7f2acca06487491a1f2ab..217ef4f097aa1d1db7c413233f5022d53798b645 100644 --- a/source/RobotAPI/libraries/armem/memory/ProviderSegment.h +++ b/source/RobotAPI/libraries/armem/memory/ProviderSegment.h @@ -56,8 +56,6 @@ namespace armarx::armem /// Move and insert an entity. Entity& addEntity(EntityPtr&& entity); - /// Clear the entities. - virtual void clear() override; /// Get an cleared copy of `*this` (without entities). ProviderSegmentPtr getEmptyCopy() const; @@ -82,12 +80,14 @@ namespace armarx::armem long maxHistorySize = -1; - // MemoryContainer interface + // MemoryLevel interface public: std::string getLevelName() const override { return "provider segment"; } + + // MemoryContainer interface protected: ContainerT& _underlyingContainer() override { diff --git a/source/RobotAPI/libraries/armem/memory/detail/EntityStorage.cpp b/source/RobotAPI/libraries/armem/memory/detail/EntityStorage.cpp index f3637c1ac93db1792c22b42a6624d41d7599cc83..88e3dcfef5466022c8e1887f41f4b5d7b045a0f0 100644 --- a/source/RobotAPI/libraries/armem/memory/detail/EntityStorage.cpp +++ b/source/RobotAPI/libraries/armem/memory/detail/EntityStorage.cpp @@ -54,6 +54,11 @@ namespace armarx::armem::detail } } + string EntityStorage::getKeyString() const + { + return name; + } + void EntityStorage::checkStorageName(const std::string& expectedName, const std::string& actualName, const std::string& storageTerm) { diff --git a/source/RobotAPI/libraries/armem/memory/detail/EntityStorage.h b/source/RobotAPI/libraries/armem/memory/detail/EntityStorage.h index 25024e02273936aa9060cc69189793da051b2c6f..ef69c1d6fc9423c63b862c355c7c9fd9b8849c45 100644 --- a/source/RobotAPI/libraries/armem/memory/detail/EntityStorage.h +++ b/source/RobotAPI/libraries/armem/memory/detail/EntityStorage.h @@ -4,6 +4,7 @@ #include "../Entity.h" #include "../EntitySnapshot.h" +#include "MemoryLevel.h" namespace armarx::armem::detail @@ -14,14 +15,14 @@ namespace armarx::armem::detail * * Can be updated by multiple entity updates. */ - class EntityStorage + class EntityStorage : public MemoryLevel { public: EntityStorage(); EntityStorage(const std::string& name); - virtual ~EntityStorage(); + virtual ~EntityStorage() override; /** @@ -37,9 +38,6 @@ namespace armarx::armem::detail */ virtual MemoryID update(const InternalEntityUpdate& update) = 0; - /// Clear this storage of any elements. - virtual void clear() = 0; - /** * @brief Retrieve an entity. @@ -63,6 +61,9 @@ namespace armarx::armem::detail virtual const EntitySnapshot& getEntitySnapshot(const MemoryID& id) const; + /// Return `name`. + virtual std::string getKeyString() const override; + protected: @@ -78,6 +79,9 @@ namespace armarx::armem::detail }; + /** + * @brief An entity storage with a specific (Aron) type. + */ class TypedEntityStorage : public EntityStorage { public: diff --git a/source/RobotAPI/libraries/armem/memory/detail/MemoryContainer.h b/source/RobotAPI/libraries/armem/memory/detail/MemoryContainer.h index ac73ca0a7937b90cc22b4b7884ddc6e483480420..e1f5c1143cdfcb779c6b4ce1c0989d83116dbc46 100644 --- a/source/RobotAPI/libraries/armem/memory/detail/MemoryContainer.h +++ b/source/RobotAPI/libraries/armem/memory/detail/MemoryContainer.h @@ -7,7 +7,10 @@ namespace armarx::armem::detail { /** - * @brief A container of entities at some point in the hierarchy. + * @brief A memory container at some point in the hierarchy. + * + * This class containes some convenience functions to allow more uniform + * access to the different memory levels. */ template <class _ContainerT> class MemoryContainer @@ -17,18 +20,10 @@ namespace armarx::armem::detail public: - MemoryContainer() - {} - virtual ~MemoryContainer() {} - // Introspection - - virtual std::string getLevelName() const = 0; - - // Container methods virtual bool empty() const @@ -39,6 +34,10 @@ namespace armarx::armem::detail { return _underlyingContainer().size(); } + virtual void clear() + { + return _underlyingContainer().clear(); + } auto begin() const { diff --git a/source/RobotAPI/libraries/armem/memory/detail/MemoryLevel.cpp b/source/RobotAPI/libraries/armem/memory/detail/MemoryLevel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3fa1ea96e2bc95de4647418858ad52462b1c36bd --- /dev/null +++ b/source/RobotAPI/libraries/armem/memory/detail/MemoryLevel.cpp @@ -0,0 +1,10 @@ +#include "MemoryLevel.h" + + +namespace armarx::armem::detail +{ + + MemoryLevel::~MemoryLevel() + {} + +} diff --git a/source/RobotAPI/libraries/armem/memory/detail/MemoryLevel.h b/source/RobotAPI/libraries/armem/memory/detail/MemoryLevel.h new file mode 100644 index 0000000000000000000000000000000000000000..6516eb4b0ca93fa61305533c5cc429a59bed860b --- /dev/null +++ b/source/RobotAPI/libraries/armem/memory/detail/MemoryLevel.h @@ -0,0 +1,29 @@ +#pragma once + +#include <string> + + +namespace armarx::armem::detail +{ + + /** + * @brief Base class of memory classes on different levels. + */ + class MemoryLevel + { + public: + + virtual ~MemoryLevel(); + + + // Introspection + + /// Get a string version of `*this`' key. + virtual std::string getKeyString() const = 0; + + /// Get a readable name of this level for messages, errors etc. + virtual std::string getLevelName() const = 0; + + }; + +}