diff --git a/examples/t03_sequence_star.cpp b/examples/t03_sequence_star.cpp
index 34b8f5667..a683c8235 100644
--- a/examples/t03_sequence_star.cpp
+++ b/examples/t03_sequence_star.cpp
@@ -15,7 +15,7 @@ using namespace BT;
// clang-format off
-const std::string xml_text_sequence = R"(
+static const char* xml_text_sequence = R"(
@@ -25,14 +25,14 @@ const std::string xml_text_sequence = R"(
-
+
)";
-const std::string xml_text_sequence_star = R"(
+static const char* xml_text_sequence_star = R"(
@@ -42,7 +42,7 @@ const std::string xml_text_sequence_star = R"(
-
+
@@ -67,6 +67,9 @@ int main()
factory.registerNodeType("MoveBase");
factory.registerNodeType("SaySomething");
+ PortsList say_something_ports = {{"message", PortType::INPUT}};
+ factory.registerSimpleAction("SaySomething2", SaySomethingSimple, say_something_ports );
+
// Compare the state transitions and messages using either
// xml_text_sequence and xml_text_sequence_star
diff --git a/include/behaviortree_cpp/bt_factory.h b/include/behaviortree_cpp/bt_factory.h
index 67fd398b7..eadbd4caa 100644
--- a/include/behaviortree_cpp/bt_factory.h
+++ b/include/behaviortree_cpp/bt_factory.h
@@ -51,19 +51,41 @@ class BehaviorTreeFactory
bool unregisterBuilder(const std::string& ID);
/// The most generic way to register your own builder.
- void registerBuilder(const TreeNodeManifest& manifest, NodeBuilder builder);
+ void registerBuilder(const TreeNodeManifest& manifest, const NodeBuilder& builder);
- /// Register a SimpleActionNode
+ /**
+ * @brief registerSimpleAction help you register nodes of type SimpleActionNode.
+ *
+ * @param ID registration ID
+ * @param tick_functor the callback to be invoked in the tick() method.
+ * @param ports if your SimpleNode requires ports, provide the list here.
+ *
+ * */
void registerSimpleAction(const std::string& ID,
- const SimpleActionNode::TickFunctor& tick_functor);
-
- /// Register a SimpleConditionNode
+ const SimpleActionNode::TickFunctor& tick_functor,
+ PortsList ports = {});
+ /**
+ * @brief registerSimpleCondition help you register nodes of type SimpleConditionNode.
+ *
+ * @param ID registration ID
+ * @param tick_functor the callback to be invoked in the tick() method.
+ * @param ports if your SimpleNode requires ports, provide the list here.
+ *
+ * */
void registerSimpleCondition(const std::string& ID,
- const SimpleConditionNode::TickFunctor& tick_functor);
-
- /// Register a SimpleDecoratorNode
+ const SimpleConditionNode::TickFunctor& tick_functor,
+ PortsList ports = {});
+ /**
+ * @brief registerSimpleDecorator help you register nodes of type SimpleDecoratorNode.
+ *
+ * @param ID registration ID
+ * @param tick_functor the callback to be invoked in the tick() method.
+ * @param ports if your SimpleNode requires ports, provide the list here.
+ *
+ * */
void registerSimpleDecorator(const std::string& ID,
- const SimpleDecoratorNode::TickFunctor& tick_functor);
+ const SimpleDecoratorNode::TickFunctor& tick_functor,
+ PortsList ports = {});
/**
* @brief registerFromPlugin load a shared library and execute the function BT_REGISTER_NODES (see macro).
diff --git a/sample_nodes/dummy_nodes.cpp b/sample_nodes/dummy_nodes.cpp
index 721cba6ac..3e2c397df 100644
--- a/sample_nodes/dummy_nodes.cpp
+++ b/sample_nodes/dummy_nodes.cpp
@@ -57,4 +57,16 @@ BT::NodeStatus SaySomething::tick()
std::cout << "Robot says: " << msg << std::endl;
return BT::NodeStatus::SUCCESS;
}
+
+BT::NodeStatus SaySomethingSimple(BT::TreeNode &self)
+{
+ std::string msg;
+ if (!self.getInput("message", msg))
+ {
+ throw BT::RuntimeError("missing required input [message]");
+ }
+ std::cout << "Robot says: " << msg << std::endl;
+ return BT::NodeStatus::SUCCESS;
+}
+
}
diff --git a/sample_nodes/dummy_nodes.h b/sample_nodes/dummy_nodes.h
index 331b8a5a0..0918381d1 100644
--- a/sample_nodes/dummy_nodes.h
+++ b/sample_nodes/dummy_nodes.h
@@ -64,6 +64,10 @@ class SaySomething : public BT::SyncActionNode
}
};
+//Same as class SaySomething, but to be registered with SimpleActionNode
+BT::NodeStatus SaySomethingSimple(BT::TreeNode& self);
+
+
inline void RegisterNodes(BT::BehaviorTreeFactory& factory)
{
static GripperInterface gi;
diff --git a/src/bt_factory.cpp b/src/bt_factory.cpp
index 2337d2c41..79f7df835 100644
--- a/src/bt_factory.cpp
+++ b/src/bt_factory.cpp
@@ -63,7 +63,7 @@ bool BehaviorTreeFactory::unregisterBuilder(const std::string& ID)
return true;
}
-void BehaviorTreeFactory::registerBuilder(const TreeNodeManifest& manifest, NodeBuilder builder)
+void BehaviorTreeFactory::registerBuilder(const TreeNodeManifest& manifest, const NodeBuilder& builder)
{
auto it = builders_.find( manifest.registration_ID);
if (it != builders_.end())
@@ -75,36 +75,39 @@ void BehaviorTreeFactory::registerBuilder(const TreeNodeManifest& manifest, Node
manifests_.insert( {manifest.registration_ID, manifest} );
}
-void BehaviorTreeFactory::registerSimpleCondition(
- const std::string& ID, const SimpleConditionNode::TickFunctor& tick_functor)
+void BehaviorTreeFactory::registerSimpleCondition(const std::string& ID,
+ const SimpleConditionNode::TickFunctor& tick_functor,
+ PortsList ports)
{
NodeBuilder builder = [tick_functor, ID](const std::string& name, const NodeConfiguration& config) {
return std::unique_ptr(new SimpleConditionNode(name, tick_functor, config));
};
- TreeNodeManifest manifest = { NodeType::CONDITION, ID, {} };
+ TreeNodeManifest manifest = { NodeType::CONDITION, ID, std::move(ports) };
registerBuilder(manifest, builder);
}
void BehaviorTreeFactory::registerSimpleAction(const std::string& ID,
- const SimpleActionNode::TickFunctor& tick_functor)
+ const SimpleActionNode::TickFunctor& tick_functor,
+ PortsList ports)
{
NodeBuilder builder = [tick_functor, ID](const std::string& name, const NodeConfiguration& config) {
return std::unique_ptr(new SimpleActionNode(name, tick_functor, config));
};
- TreeNodeManifest manifest = { NodeType::ACTION, ID, {} };
+ TreeNodeManifest manifest = { NodeType::ACTION, ID, std::move(ports) };
registerBuilder(manifest, builder);
}
-void BehaviorTreeFactory::registerSimpleDecorator(
- const std::string& ID, const SimpleDecoratorNode::TickFunctor& tick_functor)
+void BehaviorTreeFactory::registerSimpleDecorator(const std::string& ID,
+ const SimpleDecoratorNode::TickFunctor& tick_functor,
+ PortsList ports)
{
NodeBuilder builder = [tick_functor, ID](const std::string& name, const NodeConfiguration& config) {
return std::unique_ptr(new SimpleDecoratorNode(name, tick_functor, config));
};
- TreeNodeManifest manifest = { NodeType::DECORATOR, ID, {} };
+ TreeNodeManifest manifest = { NodeType::DECORATOR, ID, std::move(ports) };
registerBuilder(manifest, builder);
}
diff --git a/src/xml_parsing.cpp b/src/xml_parsing.cpp
index 1a9f02e71..48be702a4 100644
--- a/src/xml_parsing.cpp
+++ b/src/xml_parsing.cpp
@@ -417,20 +417,18 @@ TreeNode::Ptr XMLParser::Pimpl::createNodeFromXML(const XMLElement *element,
for(const auto& remap_it: remapping_parameters)
{
const auto& port_name = remap_it.first;
- auto port_type = PortType::INOUT; // default if missing from manifest
-
auto port_it = manifest.ports.find( port_name );
if( port_it != manifest.ports.end() )
{
- port_type = port_it->second;
- }
- if( port_type != PortType::OUTPUT )
- {
- config.input_ports.insert( remap_it );
- }
- if( port_type != PortType::INPUT )
- {
- config.output_ports.insert( remap_it );
+ auto port_type = port_it->second;
+ if( port_type != PortType::OUTPUT )
+ {
+ config.input_ports.insert( remap_it );
+ }
+ if( port_type != PortType::INPUT )
+ {
+ config.output_ports.insert( remap_it );
+ }
}
}
child_node = factory.instantiateTreeNode(instance_name, ID, config);