| 626 | |
| 627 | template <typename T> |
| 628 | inline Result TreeNode::setOutput(const std::string& key, const T& value) |
| 629 | { |
| 630 | if(!config().blackboard) |
| 631 | { |
| 632 | return nonstd::make_unexpected("setOutput() failed: trying to access a " |
| 633 | "Blackboard(BB) entry, but BB is invalid"); |
| 634 | } |
| 635 | |
| 636 | auto remap_it = config().output_ports.find(key); |
| 637 | if(remap_it == config().output_ports.end()) |
| 638 | { |
| 639 | return nonstd::make_unexpected(StrCat("setOutput() failed: " |
| 640 | "NodeConfig::output_ports " |
| 641 | "does not contain the key: [", |
| 642 | key, "]")); |
| 643 | } |
| 644 | StringView remapped_key = remap_it->second; |
| 645 | if(remapped_key == "{=}" || remapped_key == "=") |
| 646 | { |
| 647 | config().blackboard->set(static_cast<std::string>(key), value); |
| 648 | return {}; |
| 649 | } |
| 650 | |
| 651 | if(!isBlackboardPointer(remapped_key)) |
| 652 | { |
| 653 | return nonstd::make_unexpected("setOutput requires a blackboard pointer. Use {}"); |
| 654 | } |
| 655 | |
| 656 | if constexpr(std::is_same_v<BT::Any, T>) |
| 657 | { |
| 658 | auto port_type = config().manifest->ports.at(key).type(); |
| 659 | if(port_type != typeid(BT::Any) && port_type != typeid(BT::AnyTypeAllowed)) |
| 660 | { |
| 661 | throw LogicError("setOutput<Any> is not allowed, unless the port " |
| 662 | "was declared using OutputPort<Any>"); |
| 663 | } |
| 664 | } |
| 665 | |
| 666 | remapped_key = stripBlackboardPointer(remapped_key); |
| 667 | config().blackboard->set(static_cast<std::string>(remapped_key), value); |
| 668 | |
| 669 | return {}; |
| 670 | } |
| 671 | |
| 672 | // Utility function to fill the list of ports using T::providedPorts(); |
| 673 | template <typename T> |