Skip to content

Commit 05c0777

Browse files
authored
Merge pull request #4 from PickNikRobotics/non-port-fields
Adds "Other Attributes" to a Tree Node's configuration with contains non-port fields
2 parents 9336ead + 60b0964 commit 05c0777

File tree

5 files changed

+48
-9
lines changed

5 files changed

+48
-9
lines changed

include/behaviortree_cpp/basic_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ struct Timestamp
342342

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

345+
[[nodiscard]] bool IsNodeNameAttribute(StringView str);
346+
345347
class TypeInfo
346348
{
347349
public:

include/behaviortree_cpp/tree_node.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct TreeNodeManifest
4040
};
4141

4242
using PortsRemapping = std::unordered_map<std::string, std::string>;
43+
using OtherAttributes = std::unordered_map<std::string, std::string>;
4344

4445
enum class PreCond
4546
{
@@ -83,6 +84,9 @@ struct NodeConfig
8384
// output ports
8485
PortsRemapping output_ports;
8586

87+
// Any other attributes found in the xml that are not parsed as ports (e.g. anything with a leading '_')
88+
OtherAttributes other_attributes;
89+
8690
const TreeNodeManifest* manifest = nullptr;
8791

8892
// Numberic unique identifier

src/basic_types.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -433,11 +433,12 @@ bool IsAllowedPortName(StringView str)
433433
{
434434
return false;
435435
}
436-
if(str == "name" || str == "ID")
437-
{
438-
return false;
439-
}
440-
return true;
436+
return !IsNodeNameAttribute(str);
437+
}
438+
439+
bool IsNodeNameAttribute(StringView str)
440+
{
441+
return str == "name" || str == "ID";
441442
}
442443

443444
Any convertFromJSON(StringView json_text, std::type_index type)

src/xml_parsing.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <sstream>
1919
#include <string>
2020
#include <typeindex>
21+
#include "behaviortree_cpp/basic_types.h"
2122

2223
#if defined(_MSVC_LANG) && !defined(__clang__)
2324
#define __bt_cplusplus (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
@@ -654,13 +655,13 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
654655
}
655656

656657
PortsRemapping port_remap;
658+
OtherAttributes other_attributes;
657659
for(const XMLAttribute* att = element->FirstAttribute(); att; att = att->Next())
658660
{
659-
if(IsAllowedPortName(att->Name()))
661+
const std::string port_name = att->Name();
662+
const std::string port_value = att->Value();
663+
if(IsAllowedPortName(port_name))
660664
{
661-
const std::string port_name = att->Name();
662-
const std::string port_value = att->Value();
663-
664665
if(manifest)
665666
{
666667
auto port_model_it = manifest->ports.find(port_name);
@@ -696,6 +697,10 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
696697

697698
port_remap[port_name] = port_value;
698699
}
700+
else if(!IsNodeNameAttribute(port_name))
701+
{
702+
other_attributes[port_name] = port_value;
703+
}
699704
}
700705

701706
NodeConfig config;
@@ -713,6 +718,7 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
713718
if(auto script = element->Attribute(attr_name))
714719
{
715720
conditions.insert({ ID, std::string(script) });
721+
other_attributes.erase(attr_name);
716722
}
717723
};
718724

@@ -727,6 +733,7 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
727733
AddCondition(config.post_conditions, toStr(post).c_str(), post);
728734
}
729735

736+
config.other_attributes = other_attributes;
730737
//---------------------------------------------
731738
TreeNode::Ptr new_node;
732739

tests/gtest_ports.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <gtest/gtest.h>
2+
#include "behaviortree_cpp/basic_types.h"
23
#include "behaviortree_cpp/bt_factory.h"
34
#include "behaviortree_cpp/xml_parsing.h"
45
#include "behaviortree_cpp/json_export.h"
@@ -129,6 +130,30 @@ TEST(PortTest, Descriptions)
129130
ASSERT_EQ(status, NodeStatus::FAILURE); // failure because in_port_B="99"
130131
}
131132

133+
TEST(PortsTest, NonPorts)
134+
{
135+
std::string xml_txt =
136+
R"(
137+
<root BTCPP_format="4" >
138+
<BehaviorTree ID="MainTree">
139+
<Action ID="NodeWithPorts" name="NodeWithPortsName" in_port_B="66" _not_da_port="whateva" _skipIf="true" />
140+
</BehaviorTree>
141+
</root>)";
142+
143+
BehaviorTreeFactory factory;
144+
factory.registerNodeType<NodeWithPorts>("NodeWithPorts");
145+
146+
auto tree = factory.createTreeFromText(xml_txt);
147+
148+
const TreeNode* root = tree.rootNode();
149+
ASSERT_NE(root, nullptr);
150+
ASSERT_EQ(root->type(), NodeType::ACTION);
151+
152+
EXPECT_EQ(root->config().other_attributes.size(), 1);
153+
ASSERT_TRUE(root->config().other_attributes.contains("_not_da_port"));
154+
EXPECT_EQ(root->config().other_attributes.at("_not_da_port"), "whateva");
155+
}
156+
132157
struct MyType
133158
{
134159
std::string value;

0 commit comments

Comments
 (0)