@@ -26,6 +26,12 @@ namespace BT
2626 * <SetBlackboard value="42" output_key="the_answer" />
2727 *
2828 * Will store the string "42" in the entry with key "the_answer".
29+ *
30+ * Alternatively, you can use it to copy one port inside another port:
31+ *
32+ * <SetBlackboard value="{src_port}" output_key="dst_port" />
33+ *
34+ * This will copy the type and content of {src_port} into {dst_port}
2935 */
3036class SetBlackboard : public SyncActionNode
3137{
@@ -46,17 +52,36 @@ class SetBlackboard : public SyncActionNode
4652private:
4753 virtual BT::NodeStatus tick () override
4854 {
49- std::string key, value ;
50- if (!getInput (" output_key" , key ))
55+ std::string output_key ;
56+ if (!getInput (" output_key" , output_key ))
5157 {
5258 throw RuntimeError (" missing port [output_key]" );
5359 }
54- if (!getInput (" value" , value))
60+
61+ const std::string value_str = config ().input_ports .at (" value" );
62+
63+ StringView stripped_key;
64+ if (isBlackboardPointer (value_str, &stripped_key))
5565 {
56- throw RuntimeError (" missing port [value]" );
57- }
66+ const auto input_key = std::string (stripped_key);
67+ std::shared_ptr<Blackboard::Entry> src_entry = config ().blackboard ->getEntry (input_key);
68+ std::shared_ptr<Blackboard::Entry> dst_entry = config ().blackboard ->getEntry (output_key);
5869
59- config ().blackboard ->set (static_cast <std::string>(key), value);
70+ if (!src_entry)
71+ {
72+ throw RuntimeError (" Can't find the port referred by [value]" );
73+ }
74+ if (!dst_entry)
75+ {
76+ config ().blackboard ->createEntry (output_key, src_entry->info );
77+ dst_entry = config ().blackboard ->getEntry (output_key);
78+ }
79+ dst_entry->value = src_entry->value ;
80+ }
81+ else
82+ {
83+ config ().blackboard ->set (output_key, value_str);
84+ }
6085
6186 return NodeStatus::SUCCESS;
6287 }
0 commit comments