Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
facontidavide authored Jan 10, 2025
2 parents 9dc3e8a + 48f6c5b commit 42f5ce2
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 40 deletions.
8 changes: 4 additions & 4 deletions Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.

OUTPUT_DIRECTORY = /home/davide.faconti/ws_behavior_tree/src/Behavior-Tree/doc
OUTPUT_DIRECTORY = ./doc

# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
Expand Down Expand Up @@ -781,7 +781,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.

INPUT = /home/davide.faconti/ws_behavior_tree/src/Behavior-Tree/include
INPUT = ./include

# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
Expand Down Expand Up @@ -863,8 +863,8 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.

EXCLUDE = /home/davide.faconti/ws_behavior_tree/src/Behavior-Tree/3rdparty \
/home/davide.faconti/ws_behavior_tree/src/Behavior-Tree/gtest
EXCLUDE = ./3rdparty \
./gtest

# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
Expand Down
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 @@ -53,6 +54,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 @@ -63,11 +68,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 @@ -85,6 +94,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
2 changes: 2 additions & 0 deletions src/decorators/retry_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ NodeStatus RetryNode::tick()

case NodeStatus::FAILURE: {
try_count_++;
// Refresh max_attempts_ in case it changed in one of the child nodes
getInput(NUM_ATTEMPTS, max_attempts_);
do_loop = try_count_ < max_attempts_ || max_attempts_ == -1;

resetChild();
Expand Down
34 changes: 8 additions & 26 deletions src/tree_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,41 +468,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";
case PreCond::ON_START:
return "_onStart";
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 42f5ce2

Please sign in to comment.