diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt index cf25aaef2d9eaee41a90d5dc5134df04c813b61a..4f9b5be30489e93151d9f4e5034b058bed520dc3 100644 --- a/source/RobotAPI/libraries/armem/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem/CMakeLists.txt @@ -20,6 +20,7 @@ set(LIB_FILES segments/CoreSegment.cpp segments/Entity.cpp segments/EntityData.cpp + segments/EntityStorage.cpp segments/Memory.cpp segments/ProviderSegment.cpp ) @@ -34,6 +35,7 @@ set(LIB_HEADERS segments/CoreSegment.h segments/Entity.h segments/EntityData.h + segments/EntityStorage.h segments/Memory.h segments/ProviderSegment.h ) diff --git a/source/RobotAPI/libraries/armem/client/Commit.h b/source/RobotAPI/libraries/armem/client/Commit.h index e280a6a19d89dc93646cbd0fcd0065925b8b135b..4fd0a2a5aa5199989a17e3ba4477776ebd6ea61b 100644 --- a/source/RobotAPI/libraries/armem/client/Commit.h +++ b/source/RobotAPI/libraries/armem/client/Commit.h @@ -20,7 +20,7 @@ namespace armarx::armem MemoryID entityID; /// The entity data. - aron::AronDataPtr data; + std::vector<aron::AronDataPtr> instancesData; /** * @brief Time when this entity update was created (e.g. time of image recording). diff --git a/source/RobotAPI/libraries/armem/segments/CoreSegment.cpp b/source/RobotAPI/libraries/armem/segments/CoreSegment.cpp index 9636c0abcf45d24d2517a896191b347491d6deaf..dcfdb18e8228ccd1aa3eb7b6d7dc5f0969d624f5 100644 --- a/source/RobotAPI/libraries/armem/segments/CoreSegment.cpp +++ b/source/RobotAPI/libraries/armem/segments/CoreSegment.cpp @@ -1,2 +1,24 @@ #include "CoreSegment.h" + +namespace armarx::armem +{ + + void CoreSegment::update(const EntityUpdate& update) + { + if (update.entityID.coreSegmentName != this->name) + { + // Throw some exception + } + auto it = this->providers.find(update.entityID.providerSegmentName); + if (it != providers.end()) + { + it->second->update(update); + } + else + { + // throw + } + } + +} diff --git a/source/RobotAPI/libraries/armem/segments/CoreSegment.h b/source/RobotAPI/libraries/armem/segments/CoreSegment.h index 9306bd762e119ba7fbd760eb62087af043cab1a5..6fbfba228308a1daf4e3a87880e56026632b541e 100644 --- a/source/RobotAPI/libraries/armem/segments/CoreSegment.h +++ b/source/RobotAPI/libraries/armem/segments/CoreSegment.h @@ -4,6 +4,7 @@ #include <memory> #include <string> +#include "EntityStorage.h" #include "ProviderSegment.h" @@ -13,15 +14,21 @@ namespace armarx::armem /** * @brief Data of a core segment containing multiple provider segments. */ - class CoreSegment + class CoreSegment : public EntityStorage { public: - CoreSegment(); - std::string name; - std::map<std::string, ProviderSegment> providers; + using EntityStorage::EntityStorage; + + virtual void update(const EntityUpdate& update) override; + + + public: + + std::map<std::string, ProviderSegmentPtr> providers; }; + using CoreSegmentPtr = std::unique_ptr<CoreSegment>; } diff --git a/source/RobotAPI/libraries/armem/segments/Entity.cpp b/source/RobotAPI/libraries/armem/segments/Entity.cpp index b0ae70b109e074413af04079233538628e5e8c47..595679fa7d8d0697b8f376ad3679a1413adea61c 100644 --- a/source/RobotAPI/libraries/armem/segments/Entity.cpp +++ b/source/RobotAPI/libraries/armem/segments/Entity.cpp @@ -1,2 +1,46 @@ #include "Entity.h" + +namespace armarx::armem +{ + + Entity::Entity() + { + } + + Entity::Entity(const std::string& name) : name(name) + { + } + + void Entity::update(const EntityUpdate& update) + { + if (update.entityID.entityName != this->name) + { + // Throw name exception + } + + auto it = history.find(update.timeCreated); + if (it == history.end()) + { + // Insert into history. + it = history.emplace(update.timeCreated, + std::make_unique<EntitySnapshot>()).first; + } + // Update entry. + it->second->update(update); + } + + + void EntitySnapshot::update(const EntityUpdate& update) + { + id = update.timeCreated; + + instances.clear(); + for (int i = 0; i < int(update.instancesData.size()); ++i) + { + EntityDataPtr& data = instances.emplace_back(std::make_unique<EntityData>()); + data->update(update, i); + } + } + +} diff --git a/source/RobotAPI/libraries/armem/segments/Entity.h b/source/RobotAPI/libraries/armem/segments/Entity.h index 7bf8f61190d0b5865c43ad654e9ad4932af70c86..f21467acbb41335d3dea46dfd19ea7a0dca65e24 100644 --- a/source/RobotAPI/libraries/armem/segments/Entity.h +++ b/source/RobotAPI/libraries/armem/segments/Entity.h @@ -9,18 +9,51 @@ #include "../core/Time.h" #include "../core/MemoryID.h" #include "EntityData.h" +#include "EntityStorage.h" namespace armarx::armem { + class EntitySnapshot; + using EntitySnapshotPtr = std::unique_ptr<EntitySnapshot>; + + + /** + * @brief Data of an entity over a period of time. + */ + class Entity + { + public: + + Entity(); + Entity(const std::string& name); + + void update(const EntityUpdate& update); + + + public: + + std::string name; + std::map<Time, EntitySnapshotPtr> history; + + }; + + using EntityPtr = std::unique_ptr<Entity>; + + /** * @brief Data of an entity at one point in time. */ - struct EntitySnapshot + class EntitySnapshot { - Time id; - std::vector<EntityDataPtr> instances; + public: + + EntitySnapshot() = default; + + + void update(const EntityUpdate& update); + EntityData* getInstance(int index) { @@ -31,18 +64,13 @@ namespace armarx::armem { return id.hasInstanceIndex() ? getInstance(id.instanceIndex) : nullptr; } - }; - using EntitySnapshotPtr = std::unique_ptr<EntitySnapshot>; - /** - * @brief Data of an entity over a period of time. - */ - struct Entity - { - std::string name; - std::map<Time, EntitySnapshot> history; + public: + + Time id; + std::vector<EntityDataPtr> instances; + }; - using EntityPtr = std::unique_ptr<Entity>; } diff --git a/source/RobotAPI/libraries/armem/segments/EntityData.cpp b/source/RobotAPI/libraries/armem/segments/EntityData.cpp index 450e88904d4fae6f3a8bdb54248677d548492fc4..0a2fd172bc52e04508f464af7165978829124803 100644 --- a/source/RobotAPI/libraries/armem/segments/EntityData.cpp +++ b/source/RobotAPI/libraries/armem/segments/EntityData.cpp @@ -1,2 +1,22 @@ #include "EntityData.h" +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + + +namespace armarx::armem +{ + + void EntityData::update(const EntityUpdate& update, int index) + { + ARMARX_CHECK_FITS_SIZE(index, update.instancesData.size()); + + this->index = index; + this->data = update.instancesData.at(size_t(index)); + + this->metadata.importance = update.importance; + this->metadata.timeCreated = update.timeCreated; + this->metadata.timeSent = update.timeSent; + this->metadata.timeArrived = Time::now(); // todo; + } + +} diff --git a/source/RobotAPI/libraries/armem/segments/EntityData.h b/source/RobotAPI/libraries/armem/segments/EntityData.h index 5c46d6e58bfaad35ef72fa2e3eeb415015456b57..4fa91a181a8ae1f9375c7058412466f9115000bd 100644 --- a/source/RobotAPI/libraries/armem/segments/EntityData.h +++ b/source/RobotAPI/libraries/armem/segments/EntityData.h @@ -5,6 +5,7 @@ #include <RobotAPI/interface/aron.h> #include "../core/Time.h" +#include "../client/Commit.h" namespace armarx::armem @@ -13,7 +14,7 @@ namespace armarx::armem /** * @brief Metadata of an entity value. */ - struct Metadata + struct EntityMetadata { /// Time when this value was created. Time timeCreated; @@ -35,7 +36,10 @@ namespace armarx::armem int index; aron::AronDataPtr data; - Metadata metadata; + EntityMetadata metadata; + + void update(const EntityUpdate& update, int index); + }; using EntityDataPtr = std::unique_ptr<EntityData>; diff --git a/source/RobotAPI/libraries/armem/segments/EntityStorage.cpp b/source/RobotAPI/libraries/armem/segments/EntityStorage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ed344d85132e6695b4b1de5555bab6900ace1b5 --- /dev/null +++ b/source/RobotAPI/libraries/armem/segments/EntityStorage.cpp @@ -0,0 +1,22 @@ +#include "EntityStorage.h" + + +namespace armarx::armem +{ + + EntityStorage::EntityStorage() + { + } + + EntityStorage::EntityStorage(const std::string& name) : name(name) + { + } + + void EntityStorage::update(const Commit& commit) + { + for (const auto& update : commit.updates) + { + this->update(update); + } + } +} diff --git a/source/RobotAPI/libraries/armem/segments/EntityStorage.h b/source/RobotAPI/libraries/armem/segments/EntityStorage.h new file mode 100644 index 0000000000000000000000000000000000000000..9a50056942348f4db2b678eaad05f8f85dccd55e --- /dev/null +++ b/source/RobotAPI/libraries/armem/segments/EntityStorage.h @@ -0,0 +1,34 @@ +#pragma once + +#include "../client/Commit.h" + + +namespace armarx::armem +{ + + /** + * @brief A container of entities at some point in the hierarchy. + * + * Can be updated by multiple entity updates. + */ + class EntityStorage + { + public: + + EntityStorage(); + EntityStorage(const std::string& name); + + virtual ~EntityStorage() = default; + + void update(const Commit& commit); + virtual void update(const EntityUpdate& update) = 0; + + + public: + + std::string name; + + }; + + +} diff --git a/source/RobotAPI/libraries/armem/segments/Memory.cpp b/source/RobotAPI/libraries/armem/segments/Memory.cpp index 02d00ef8fc185d1a2534a0abd755f164c80e2a04..cf6d5fb62831722e8c760990554e38fca0b7643e 100644 --- a/source/RobotAPI/libraries/armem/segments/Memory.cpp +++ b/source/RobotAPI/libraries/armem/segments/Memory.cpp @@ -1 +1,24 @@ #include "Memory.h" + + +namespace armarx::armem +{ + + void Memory::update(const EntityUpdate& update) + { + if (update.entityID.memoryName != this->name) + { + // Throw some exception + } + auto it = this->coreSegments.find(update.entityID.coreSegmentName); + if (it != coreSegments.end()) + { + it->second->update(update); + } + else + { + // throw + } + } + +} diff --git a/source/RobotAPI/libraries/armem/segments/Memory.h b/source/RobotAPI/libraries/armem/segments/Memory.h index 2266a8a7b81a0575b5dd61d5dd6452b251b86f1a..c436acfea7e964a58e1d45f44b6342725afa0c8c 100644 --- a/source/RobotAPI/libraries/armem/segments/Memory.h +++ b/source/RobotAPI/libraries/armem/segments/Memory.h @@ -5,6 +5,7 @@ #include <string> #include "CoreSegment.h" +#include "EntityStorage.h" namespace armarx::armem @@ -13,13 +14,18 @@ namespace armarx::armem /** * @brief Data of a memory consisting of multiple core segments. */ - class Memory + class Memory : public EntityStorage { public: - Memory(); - std::string name; - std::map<std::string, CoreSegment> coreSegments; + using EntityStorage::EntityStorage; + + virtual void update(const EntityUpdate& update) override; + + + public: + + std::map<std::string, CoreSegmentPtr> coreSegments; }; using MemoryPtr = std::unique_ptr<Memory>; diff --git a/source/RobotAPI/libraries/armem/segments/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/segments/ProviderSegment.cpp index 318413dba6d9b7e9cd8a9b68493b296d563253d8..e30e617a13cdb37e395c65f926ae43353ca6067c 100644 --- a/source/RobotAPI/libraries/armem/segments/ProviderSegment.cpp +++ b/source/RobotAPI/libraries/armem/segments/ProviderSegment.cpp @@ -1,2 +1,25 @@ #include "ProviderSegment.h" + +namespace armarx::armem +{ + + void ProviderSegment::update(const EntityUpdate& update) + { + if (update.entityID.coreSegmentName != this->name) + { + // Throw some exception + } + + auto it = this->entities.find(update.entityID.providerSegmentName); + if (it == entities.end()) + { + // Add entity entry. + it = entities.emplace(update.entityID.entityName, + std::make_unique<Entity>(update.entityID.entityName)).first; + } + // Update entity. + it->second->update(update); + } + +} diff --git a/source/RobotAPI/libraries/armem/segments/ProviderSegment.h b/source/RobotAPI/libraries/armem/segments/ProviderSegment.h index c6e9e454d393b7deec73329564979b9cb1805f14..d0a111a5dd4b64afcdcbbeeacc345331662198d7 100644 --- a/source/RobotAPI/libraries/armem/segments/ProviderSegment.h +++ b/source/RobotAPI/libraries/armem/segments/ProviderSegment.h @@ -5,6 +5,7 @@ #include <string> #include "Entity.h" +#include "EntityStorage.h" namespace armarx::armem @@ -13,16 +14,21 @@ namespace armarx::armem /** * @brief Data of a provider segment containing multiple entities. */ - class ProviderSegment + class ProviderSegment : public EntityStorage { public: - using ID = std::string; + + using EntityStorage::EntityStorage; + + virtual void update(const EntityUpdate& update) override; + + public: - ProviderSegment(); - std::string name; - std::map<std::string, Entity> entities; + std::map<std::string, EntityPtr> entities; + }; + using ProviderSegmentPtr = std::unique_ptr<ProviderSegment>; }