From 9ca1072d28cb8d5d2eb40882ad46bcca24d23871 Mon Sep 17 00:00:00 2001 From: Davide Faconti Date: Tue, 8 Jan 2019 14:24:08 +0100 Subject: [PATCH] Add blackboard scope/hierarchy (issue #44) --- gtest/gtest_blackboard.cpp | 40 +++++++++++++++++-- .../behaviortree_cpp/blackboard/blackboard.h | 34 +++++++++++----- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/gtest/gtest_blackboard.cpp b/gtest/gtest_blackboard.cpp index 07af95a69..9b5d51db1 100644 --- a/gtest/gtest_blackboard.cpp +++ b/gtest/gtest_blackboard.cpp @@ -55,10 +55,6 @@ class BB_TestNode: public SyncActionNode }; - - -/****************TESTS START HERE***************************/ - TEST(BlackboardTest, GetInputsFromBlackboard) { auto bb = Blackboard::create(); @@ -154,6 +150,42 @@ TEST(BlackboardTest, WithFactory) ASSERT_EQ( bb->get("my_output_port_A"), 22 ); ASSERT_EQ( bb->get("my_output_port_B"), 84 ); ASSERT_EQ( bb->get("my_input_port"), 84 ); +} + +TEST(BlackboardTest, NestedBlackboards) +{ + + auto bb_A = Blackboard::create(); + auto bb_B = Blackboard::create(); + auto bb_C = Blackboard::create(); + + bb_B->setParentBlackboard( bb_A ); + bb_C->setParentBlackboard( bb_B ); + + bb_A->set("value", 11); + bb_B->set("value", 22); + bb_C->set("value", 33); + + bb_A->set("number", 44); + bb_B->set("number", 55); + + bb_A->set("answer", 66); + + ASSERT_EQ( bb_A->get("value"), 11 ); + ASSERT_EQ( bb_B->get("value"), 22 ); + ASSERT_EQ( bb_C->get("value"), 33 ); + + ASSERT_EQ( bb_A->get("number"), 44 ); + ASSERT_EQ( bb_B->get("number"), 55 ); + ASSERT_EQ( bb_C->get("number"), 55 ); + + ASSERT_EQ( bb_A->get("answer"), 66 ); + ASSERT_EQ( bb_B->get("answer"), 66 ); + ASSERT_EQ( bb_C->get("answer"), 66 ); + + ASSERT_ANY_THROW( bb_A->get("not_there") ); + ASSERT_ANY_THROW( bb_B->get("not_there") ); + ASSERT_ANY_THROW( bb_C->get("not_there") ); } diff --git a/include/behaviortree_cpp/blackboard/blackboard.h b/include/behaviortree_cpp/blackboard/blackboard.h index 400b837c9..c103d9643 100644 --- a/include/behaviortree_cpp/blackboard/blackboard.h +++ b/include/behaviortree_cpp/blackboard/blackboard.h @@ -73,17 +73,12 @@ class Blackboard template bool get(const std::string& key, T& value) const { - const SafeAny::Any* val = nullptr; + const SafeAny::Any* val = getAny(key); + if (val) { - std::unique_lock lock(mutex_); - val = impl_->get(key); + value = val->cast(); } - if (!val) - { - return false; - } - value = val->cast(); - return true; + return (bool)val; } /** @@ -95,7 +90,17 @@ class Blackboard const SafeAny::Any* getAny(const std::string& key) const { std::unique_lock lock(mutex_); - return impl_->get(key); + auto val = impl_->get(key); + + if (!val) // not found. try the parent + { + if( auto parent_bb = parent_blackboard_.lock() ) + { + // this should work recursively + val = parent_bb->getAny(key); + } + } + return val; } /** @@ -113,6 +118,11 @@ class Blackboard return value; } + void setParentBlackboard(const Blackboard::Ptr& parent_bb ) + { + parent_blackboard_ = parent_bb; + } + /// Update the entry with the given key template void set(const std::string& key, const T& value) @@ -131,7 +141,9 @@ class Blackboard private: std::unique_ptr impl_; mutable std::mutex mutex_; + mutable std::weak_ptr parent_blackboard_; }; -} + +} // end namespace #endif // BLACKBOARD_H