Skip to content

Commit

Permalink
Add "other ports" to NodeConfig (#910)
Browse files Browse the repository at this point in the history
  • Loading branch information
facontidavide authored Jan 10, 2025
1 parent 17a9c35 commit 48f6c5b
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 34 deletions.
2 changes: 2 additions & 0 deletions include/behaviortree_cpp/basic_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ struct Timestamp

[[nodiscard]] bool IsAllowedPortName(StringView str);

[[nodiscard]] bool IsReservedAttribute(StringView str);

class TypeInfo
{
public:
Expand Down
17 changes: 15 additions & 2 deletions include/behaviortree_cpp/tree_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct TreeNodeManifest
};

using PortsRemapping = std::unordered_map<std::string, std::string>;
using NonPortAttributes = std::unordered_map<std::string, std::string>;

enum class PreCond
{
Expand All @@ -52,6 +53,10 @@ enum class PreCond
COUNT_
};

static const std::array<std::string, 4> PreCondNames = { //
"_failureIf", "_successIf", "_skipIf", "_while"
};

enum class PostCond
{
// order of the enums also tell us the execution order
Expand All @@ -62,11 +67,15 @@ enum class PostCond
COUNT_
};

static const std::array<std::string, 4> PostCondNames = { //
"_onHalted", "_onFailure", "_onSuccess", "_post"
};

template <>
[[nodiscard]] std::string toStr<BT::PostCond>(const BT::PostCond& status);
[[nodiscard]] std::string toStr<BT::PostCond>(const BT::PostCond& cond);

template <>
[[nodiscard]] std::string toStr<BT::PreCond>(const BT::PreCond& status);
[[nodiscard]] std::string toStr<BT::PreCond>(const BT::PreCond& cond);

using ScriptingEnumsRegistry = std::unordered_map<std::string, int>;

Expand All @@ -84,6 +93,10 @@ struct NodeConfig
// output ports
PortsRemapping output_ports;

// Any other attributes found in the xml that are not parsed as ports
// or built-in identifier (e.g. anything with a leading '_')
NonPortAttributes other_attributes;

const TreeNodeManifest* manifest = nullptr;

// Numberic unique identifier
Expand Down
26 changes: 19 additions & 7 deletions src/basic_types.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "behaviortree_cpp/basic_types.h"
#include "behaviortree_cpp/tree_node.h"
#include "behaviortree_cpp/json_export.h"

#include <cstdlib>
Expand Down Expand Up @@ -420,10 +421,6 @@ const std::string& PortInfo::defaultValueString() const

bool IsAllowedPortName(StringView str)
{
if(str == "_autoremap")
{
return true;
}
if(str.empty())
{
return false;
Expand All @@ -433,11 +430,26 @@ bool IsAllowedPortName(StringView str)
{
return false;
}
if(str == "name" || str == "ID")
return !IsReservedAttribute(str);
}

bool IsReservedAttribute(StringView str)
{
for(const auto& name : PreCondNames)
{
return false;
if(name == str)
{
return true;
}
}
for(const auto& name : PostCondNames)
{
if(name == str)
{
return true;
}
}
return true;
return str == "name" || str == "ID" || str == "_autoremap";
}

Any convertFromJSON(StringView json_text, std::type_index type)
Expand Down
32 changes: 8 additions & 24 deletions src/tree_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,39 +464,23 @@ void TreeNode::modifyPortsRemapping(const PortsRemapping& new_remapping)
}

template <>
std::string toStr<PreCond>(const PreCond& pre)
std::string toStr<PreCond>(const PreCond& cond)
{
switch(pre)
if(cond < PreCond::COUNT_)
{
case PreCond::SUCCESS_IF:
return "_successIf";
case PreCond::FAILURE_IF:
return "_failureIf";
case PreCond::SKIP_IF:
return "_skipIf";
case PreCond::WHILE_TRUE:
return "_while";
default:
return "Undefined";
return BT::PreCondNames[static_cast<size_t>(cond)];
}
return "Undefined";
}

template <>
std::string toStr<PostCond>(const PostCond& pre)
std::string toStr<PostCond>(const PostCond& cond)
{
switch(pre)
if(cond < BT::PostCond::COUNT_)
{
case PostCond::ON_SUCCESS:
return "_onSuccess";
case PostCond::ON_FAILURE:
return "_onFailure";
case PostCond::ALWAYS:
return "_post";
case PostCond::ON_HALTED:
return "_onHalted";
default:
return "Undefined";
return BT::PostCondNames[static_cast<size_t>(cond)];
}
return "Undefined";
}

AnyPtrLocked BT::TreeNode::getLockedPortContent(const std::string& key)
Expand Down
13 changes: 12 additions & 1 deletion src/xml_parsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <sstream>
#include <string>
#include <typeindex>
#include "behaviortree_cpp/basic_types.h"

#if defined(_MSVC_LANG) && !defined(__clang__)
#define __bt_cplusplus (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
Expand Down Expand Up @@ -677,9 +678,13 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
}

PortsRemapping port_remap;
NonPortAttributes other_attributes;

for(const XMLAttribute* att = element->FirstAttribute(); att; att = att->Next())
{
if(IsAllowedPortName(att->Name()))
const std::string port_name = att->Name();
const std::string port_value = att->Value();
if(IsAllowedPortName(port_name))
{
const std::string port_name = att->Name();
const std::string port_value = att->Value();
Expand Down Expand Up @@ -721,6 +726,10 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,

port_remap[port_name] = port_value;
}
else if(!IsReservedAttribute(port_name))
{
other_attributes[port_name] = port_value;
}
}

NodeConfig config;
Expand All @@ -738,6 +747,7 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
if(auto script = element->Attribute(attr_name))
{
conditions.insert({ ID, std::string(script) });
other_attributes.erase(attr_name);
}
};

Expand All @@ -752,6 +762,7 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
AddCondition(config.post_conditions, toStr(post).c_str(), post);
}

config.other_attributes = other_attributes;
//---------------------------------------------
TreeNode::Ptr new_node;

Expand Down
25 changes: 25 additions & 0 deletions tests/gtest_ports.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <gtest/gtest.h>
#include "behaviortree_cpp/basic_types.h"
#include "behaviortree_cpp/bt_factory.h"
#include "behaviortree_cpp/xml_parsing.h"
#include "behaviortree_cpp/json_export.h"
Expand Down Expand Up @@ -129,6 +130,30 @@ TEST(PortTest, Descriptions)
ASSERT_EQ(status, NodeStatus::FAILURE); // failure because in_port_B="99"
}

TEST(PortsTest, NonPorts)
{
std::string xml_txt =
R"(
<root BTCPP_format="4" >
<BehaviorTree ID="MainTree">
<Action ID="NodeWithPorts" name="NodeWithPortsName" in_port_B="66" _not_da_port="whateva" _skipIf="true" />
</BehaviorTree>
</root>)";

BehaviorTreeFactory factory;
factory.registerNodeType<NodeWithPorts>("NodeWithPorts");

auto tree = factory.createTreeFromText(xml_txt);

const TreeNode* root = tree.rootNode();
ASSERT_NE(root, nullptr);
ASSERT_EQ(root->type(), NodeType::ACTION);

EXPECT_EQ(root->config().other_attributes.size(), 1);
ASSERT_TRUE(root->config().other_attributes.contains("_not_da_port"));
EXPECT_EQ(root->config().other_attributes.at("_not_da_port"), "whateva");
}

struct MyType
{
std::string value;
Expand Down

0 comments on commit 48f6c5b

Please sign in to comment.