diff --git a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h index 6dc77c57625b0a8ebd33200885f06045eef49bbf..5e22ba7036a7d0b94a4a329e3d73e591b29a9543 100644 --- a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h +++ b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h @@ -150,38 +150,49 @@ namespace armarx::armem::base * * Missing entity entries are added before updating. */ - UpdateResult update(const EntityUpdate& update) + virtual UpdateResult update(const EntityUpdate& update) { this->_checkContainerName(update.entityID.coreSegmentName, this->name()); + auto [inserted, provSeg] = addProviderSegmentIfMissing(update.entityID.providerSegmentName); + + + // Update entry. + UpdateResult ret(provSeg->update(update)); + if (inserted) + { + ret.coreSegmentUpdateType = UpdateType::InsertedNew; + } + else + { + ret.coreSegmentUpdateType = UpdateType::UpdatedExisting; + } + return ret; + } + + std::pair<bool, ProviderSegmentT*> addProviderSegmentIfMissing(const std::string& providerSegmentName) + { ProviderSegmentT* provSeg; - UpdateType updateType = UpdateType::InsertedNew; - auto it = this->_container.find(update.entityID.providerSegmentName); + auto it = this->_container.find(providerSegmentName); if (it == this->_container.end()) { if (_addMissingProviderSegmentDuringUpdate) { // Insert into map. - provSeg = &addProviderSegment(update.entityID.providerSegmentName); - provSeg->setMaxHistorySize(_maxHistorySize); - updateType = UpdateType::InsertedNew; + provSeg = &addProviderSegment(providerSegmentName); + return {true, provSeg}; } else { - throw error::MissingEntry::create<EntitySnapshotT>(update.entityID.providerSegmentName, *this); + throw error::MissingEntry::create<EntitySnapshotT>(providerSegmentName, *this); } } else { provSeg = &it->second; - updateType = UpdateType::UpdatedExisting; + return {false, provSeg}; } - - // Update entry. - UpdateResult ret(provSeg->update(update)); - ret.coreSegmentUpdateType = updateType; - return ret; } void append(const _Derived& m) diff --git a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h index 73e70478fb9713536c266b01e9004ceb838be2a4..781322b5493388f2e88d5b0b7d20242b79048ca4 100644 --- a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h +++ b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h @@ -242,16 +242,43 @@ namespace armarx::armem::base { this->_checkContainerName(update.entityID.memoryName, this->name()); - auto it = this->_container.find(update.entityID.coreSegmentName); - if (it != this->_container.end()) + auto [inserted, coreSeg] = addCoreSegmentIfMissing(update.entityID.coreSegmentName); + + // Update entry. + UpdateResult ret(coreSeg->update(update)); + if (inserted) + { + ret.memoryUpdateType = UpdateType::InsertedNew; + } + else { - UpdateResult ret(it->second.update(update)); ret.memoryUpdateType = UpdateType::UpdatedExisting; - return ret; + } + return ret; + } + + std::pair<bool, CoreSegmentT*> addCoreSegmentIfMissing(const std::string& coreSegmentName) + { + CoreSegmentT* coreSeg; + + auto it = this->_container.find(coreSegmentName); + if (it == this->_container.end()) + { + if (_addMissingCoreSegmentDuringUpdate) + { + // Insert into map. + coreSeg = &addCoreSegment(coreSegmentName); + return {true, coreSeg}; + } + else + { + throw error::MissingEntry::create<EntitySnapshotT>(coreSegmentName, *this); + } } else { - throw armem::error::MissingEntry::create<CoreSegmentT>(update.entityID.coreSegmentName, *this); + coreSeg = &it->second; + return {false, coreSeg}; } } @@ -308,5 +335,22 @@ namespace armarx::armem::base { return this->name(); } + + protected: + + virtual void _copySelf(DerivedT& other) const override + { + Base::_copySelf(other); + other._addMissingCoreSegmentDuringUpdate = _addMissingCoreSegmentDuringUpdate; + } + virtual void _copySelfEmpty(DerivedT& other) const override + { + Base::_copySelfEmpty(other); + other._addMissingCoreSegmentDuringUpdate = _addMissingCoreSegmentDuringUpdate; + } + + public: + + bool _addMissingCoreSegmentDuringUpdate = false; }; } diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp index cd6c9cc58887cd5bd8833ffd06c92e30a0606ecb..70fd41e7c451175d5964a81d48f4e8270c2e611c 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp +++ b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp @@ -7,18 +7,7 @@ namespace armarx::armem::wm { - std::vector<Memory::Base::UpdateResult> - Memory::update(const Commit& commit) - { - std::vector<Memory::Base::UpdateResult> result; - for (const EntityUpdate& update : commit.updates) - { - result.push_back(this->update(update)); - } - return result; - } - - + // TODO: add core segment if param is set std::vector<Memory::Base::UpdateResult> Memory::updateLocking(const Commit& commit) { @@ -30,7 +19,7 @@ namespace armarx::armem::wm } std::vector<Memory::Base::UpdateResult> result; - // To throw an exception after the commit if a core segment is missing. + // To throw an exception after the commit if a core segment is missing and the memory should not create new ones std::vector<std::string> missingCoreSegmentNames; for (const auto& [coreSegmentName, updates] : updatesPerCoreSegment) { @@ -66,18 +55,7 @@ namespace armarx::armem::wm } - Memory::Base::UpdateResult - Memory::update(const EntityUpdate& update) - { - this->_checkContainerName(update.entityID.memoryName, this->name()); - - CoreSegment& segment = getCoreSegment(update.entityID.coreSegmentName); - Base::UpdateResult result = segment.update(update); - result.memoryUpdateType = UpdateType::UpdatedExisting; - return result; - } - - + // TODO: Add core segment if param is set Memory::Base::UpdateResult Memory::updateLocking(const EntityUpdate& update) { diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h index 99a14dbdd291b0619733347cf2aec2ba365871f9..d52bce5ca30d2a464881e73f4cd4994a29429751 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h +++ b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h @@ -27,8 +27,6 @@ namespace armarx::armem::wm Memory& operator=(const Memory& other) = default; Memory& operator=(Memory&& other) = default; - - virtual std::vector<Base::UpdateResult> update(const Commit& commit) override; /** * @brief Perform the commit, locking the core segments. * @@ -37,7 +35,6 @@ namespace armarx::armem::wm */ std::vector<Base::UpdateResult> updateLocking(const Commit& commit); - virtual Base::UpdateResult update(const EntityUpdate& update) override; /** * @brief Update the memory, locking the updated core segment. */ diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp index 0d6685c451645176371d6483e0795d6a558c8945..8015368837e3ea37c8e5a87837d8a3a69536e04e 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp +++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp @@ -178,6 +178,7 @@ namespace armarx::armem::server if (longtermMemory->alwaysTransferSettings.enabled) { wm::Memory tmp(longtermMemory->name()); + tmp._addMissingCoreSegmentDuringUpdate = true; tmp.update(update); longtermMemory->append(tmp); }