Skip to content

Commit 0e1641e

Browse files
committed
Adding non-port attributes
1 parent d4d8ae1 commit 0e1641e

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
@@ -41,6 +41,7 @@ struct TreeNodeManifest
4141
};
4242

4343
using PortsRemapping = std::unordered_map<std::string, std::string>;
44+
using OtherAttributes = std::unordered_map<std::string, std::string>;
4445

4546
enum class PreCond
4647
{
@@ -84,6 +85,9 @@ struct NodeConfig
8485
// output ports
8586
PortsRemapping output_ports;
8687

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

8993
// 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)
@@ -677,13 +678,13 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
677678
}
678679

679680
PortsRemapping port_remap;
681+
OtherAttributes other_attributes;
680682
for(const XMLAttribute* att = element->FirstAttribute(); att; att = att->Next())
681683
{
682-
if(IsAllowedPortName(att->Name()))
684+
const std::string port_name = att->Name();
685+
const std::string port_value = att->Value();
686+
if(IsAllowedPortName(port_name))
683687
{
684-
const std::string port_name = att->Name();
685-
const std::string port_value = att->Value();
686-
687688
if(manifest)
688689
{
689690
auto port_model_it = manifest->ports.find(port_name);
@@ -721,6 +722,10 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
721722

722723
port_remap[port_name] = port_value;
723724
}
725+
else if(!IsNodeNameAttribute(port_name))
726+
{
727+
other_attributes[port_name] = port_value;
728+
}
724729
}
725730

726731
NodeConfig config;
@@ -738,6 +743,7 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
738743
if(auto script = element->Attribute(attr_name))
739744
{
740745
conditions.insert({ ID, std::string(script) });
746+
other_attributes.erase(attr_name);
741747
}
742748
};
743749

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

761+
config.other_attributes = other_attributes;
755762
//---------------------------------------------
756763
TreeNode::Ptr new_node;
757764

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)