From 5ab8b2adc60e046f3d767e82b4a4412e96417383 Mon Sep 17 00:00:00 2001 From: Aysha Afrah Ziya Date: Sun, 16 Aug 2026 17:41:36 +0530 Subject: [PATCH] fix @ root remapping in Blackboard::createEntryImpl --- src/blackboard.cpp | 9 +++++++++ tests/gtest_blackboard.cpp | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/blackboard.cpp b/src/blackboard.cpp index 7858b4655..03d2f6e25 100644 --- a/src/blackboard.cpp +++ b/src/blackboard.cpp @@ -282,6 +282,15 @@ Blackboard::Ptr Blackboard::parent() std::shared_ptr Blackboard::createEntryImpl(const std::string& key, const TypeInfo& info) { + // special syntax: "@" always refers to the root blackboard, the same + // redirection getEntry() applies. Without it, a key remapped to a root + // entry (port="{@foo}") is created here as a literal "@foo" entry that + // getEntry() then strips to "foo" and can never find again. + if(StartWith(key, '@')) + { + return rootBlackboard()->createEntryImpl(key.substr(1, key.size() - 1), info); + } + const std::unique_lock storage_lock(storage_mutex_); // This function might be called recursively, when we do remapping, because we move // to the top scope to find already existing entries diff --git a/tests/gtest_blackboard.cpp b/tests/gtest_blackboard.cpp index 857388e45..b5bf614b8 100644 --- a/tests/gtest_blackboard.cpp +++ b/tests/gtest_blackboard.cpp @@ -636,6 +636,29 @@ TEST(BlackboardTest, RootBlackboard) ASSERT_EQ(4, tree.rootBlackboard()->get("var5")); } +TEST(BlackboardTest, RemapToRootBlackboard) +{ + // A subtree port remapped to a root key (XML: param="{@shared}") must resolve + // to the "shared" entry in the root blackboard. createEntryImpl used to create + // it as a literal "@shared" entry instead, so getEntry("param") -- which strips + // the '@' and looks up "shared" in the root -- never found it again. That made + // ImportBlackboardFromJSON dereference a null entry, and set()/get() disagree. + auto root = Blackboard::create(); + auto child = Blackboard::create(root); + child->addSubtreeRemapping("param", "@shared"); + + nlohmann::json js; + js["param"] = 42; + ASSERT_NO_THROW(ImportBlackboardFromJSON(js, *child)); + + ASSERT_EQ(42, child->get("param")); + ASSERT_EQ(42, root->get("shared")); + + child->set("param", 7); + ASSERT_EQ(7, child->get("param")); + ASSERT_EQ(7, root->get("shared")); +} + TEST(BlackboardTest, TimestampedInterface) { auto bb = BT::Blackboard::create();