Skip to content

Commit

Permalink
Convert vector to vector<Any> before placing on the blackboard
Browse files Browse the repository at this point in the history
Also update checks to allow mismatch when a port was declared as a
vector<T> and we have an input port that takes it in as a vector<Any>
  • Loading branch information
dyackzan committed Oct 22, 2024
1 parent e3b0cd7 commit 823f2a2
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 5 deletions.
3 changes: 2 additions & 1 deletion include/behaviortree_cpp/basic_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,8 @@ class TypeInfo

[[nodiscard]] bool isStronglyTyped() const
{
return type_info_ != typeid(AnyTypeAllowed) && type_info_ != typeid(BT::Any);
return type_info_ != typeid(AnyTypeAllowed) && type_info_ != typeid(BT::Any) &&
type_info_ != typeid(std::vector<BT::Any>);
}

[[nodiscard]] const StringConverter& converter() const
Expand Down
7 changes: 6 additions & 1 deletion include/behaviortree_cpp/blackboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,13 @@ inline void Blackboard::set(const std::string& key, const T& value)

std::type_index previous_type = entry.info.type();

// Allow mismatch if going from vector -> vector<Any>.
bool previous_is_vector = std::string(previous_type.name()).find("vector") != std::string::npos;
bool new_is_vector_any = new_value.type() == typeid(std::vector<Any>);

// check type mismatch
if(previous_type != std::type_index(typeid(T)) && previous_type != new_value.type())
if(previous_type != std::type_index(typeid(T)) && previous_type != new_value.type() &&
!(previous_is_vector && new_is_vector_any))
{
bool mismatching = true;
if(std::is_constructible<StringView, T>::value)
Expand Down
14 changes: 13 additions & 1 deletion include/behaviortree_cpp/tree_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,19 @@ inline Result TreeNode::setOutput(const std::string& key, const T& value)
}

remapped_key = stripBlackboardPointer(remapped_key);
config().blackboard->set(static_cast<std::string>(remapped_key), value);

if constexpr(is_vector<T>::value && !std::is_same_v<T, std::vector<Any>>)
{
// If the object is a vector but not a vector<Any>, convert it to vector<Any> before placing it on the blackboard.
auto any_vec = std::vector<Any>();
std::transform(value.begin(), value.end(), std::back_inserter(any_vec),
[](const auto &element) { return BT::Any(element); });
config().blackboard->set(static_cast<std::string>(remapped_key), any_vec);
}
else
{
config().blackboard->set(static_cast<std::string>(remapped_key), value);
}

return {};
}
Expand Down
8 changes: 6 additions & 2 deletions src/xml_parsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,10 +786,14 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,

// special case related to convertFromString
bool const string_input = (prev_info->type() == typeid(std::string));
// special case related to unwrapping vector<Any> objects.
// special case related to unwrapping vector<Any> -> vector<T> objects.
bool const vec_any_input = (prev_info->type() == typeid(std::vector<Any>));
// special case related to wrapping vector<T> -> vector<Any> objects.
bool previous_is_vector = std::string(prev_info->type().name()).find("vector") != std::string::npos;
bool new_is_vector_any = port_info.type() == typeid(std::vector<Any>);

if(port_type_mismatch && !string_input && !vec_any_input)
if(port_type_mismatch && !string_input &&
!vec_any_input & !(previous_is_vector && new_is_vector_any))
{
blackboard->debugMessage();

Expand Down

0 comments on commit 823f2a2

Please sign in to comment.