Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 994650d

Browse files
Merge pull request BehaviorTree#730 from adlarkin/add_metadata
Add optional metadata to TreeNodeManifest
2 parents db5789e + 96910f2 commit 994650d

File tree

6 files changed

+72
-33
lines changed

6 files changed

+72
-33
lines changed

include/behaviortree_cpp/basic_types.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
#include <chrono>
1111
#include <memory>
1212
#include <string_view>
13+
#include <utility>
1314
#include <variant>
15+
#include <vector>
1416
#include <optional>
1517

1618
#include "behaviortree_cpp/utils/safe_any.hpp"
@@ -438,14 +440,14 @@ struct has_static_method_providedPorts<
438440
};
439441

440442
template <typename T, typename = void>
441-
struct has_static_method_description : std::false_type
443+
struct has_static_method_metadata : std::false_type
442444
{
443445
};
444446

445447
template <typename T>
446-
struct has_static_method_description<
448+
struct has_static_method_metadata<
447449
T, typename std::enable_if<
448-
std::is_same<decltype(T::description()), std::string>::value>::type>
450+
std::is_same<decltype(T::metadata()), std::vector<std::pair<std::string, std::string>>>::value>::type>
449451
: std::true_type
450452
{
451453
};
@@ -467,4 +469,3 @@ using TimePoint = std::chrono::high_resolution_clock::time_point;
467469
using Duration = std::chrono::high_resolution_clock::duration;
468470

469471
} // namespace BT
470-

include/behaviortree_cpp/bt_factory.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include <unordered_map>
2323
#include <unordered_set>
2424
#include <set>
25+
#include <utility>
26+
#include <vector>
2527

2628
#include "behaviortree_cpp/contrib/magic_enum.hpp"
2729
#include "behaviortree_cpp/behavior_tree.h"
@@ -44,13 +46,11 @@ template <typename T>
4446
inline TreeNodeManifest CreateManifest(const std::string& ID,
4547
PortsList portlist = getProvidedPorts<T>())
4648
{
47-
if constexpr( has_static_method_description<T>::value)
49+
if constexpr( has_static_method_metadata<T>::value )
4850
{
49-
return {getType<T>(), ID, portlist, T::description()};
50-
}
51-
else {
52-
return {getType<T>(), ID, portlist, {}};
51+
return {getType<T>(), ID, portlist, T::metadata()};
5352
}
53+
return {getType<T>(), ID, portlist, {}};
5454
}
5555

5656
#ifdef BT_PLUGIN_EXPORT
@@ -425,10 +425,10 @@ class BehaviorTreeFactory
425425
Tree createTree(const std::string& tree_name,
426426
Blackboard::Ptr blackboard = Blackboard::create());
427427

428-
/// Add a description to a specific manifest. This description will be added
428+
/// Add metadata to a specific manifest. This metadata will be added
429429
/// to <TreeNodesModel> with the function writeTreeNodesModelXML()
430-
void addDescriptionToManifest(const std::string& node_id,
431-
const std::string& description);
430+
void addMetadataToManifest(const std::string& node_id,
431+
const std::vector<std::pair<std::string, std::string>>& metadata);
432432

433433
/**
434434
* @brief Add an Enum to the scripting language.

include/behaviortree_cpp/tree_node.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include <exception>
1818
#include <mutex>
1919
#include <map>
20+
#include <utility>
21+
#include <vector>
2022

2123
#include "behaviortree_cpp/utils/signal.h"
2224
#include "behaviortree_cpp/basic_types.h"
@@ -38,7 +40,7 @@ struct TreeNodeManifest
3840
NodeType type;
3941
std::string registration_ID;
4042
PortsList ports;
41-
std::string description;
43+
std::vector<std::pair<std::string, std::string>> metadata;
4244
};
4345

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

src/bt_factory.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ BehaviorTreeFactory::BehaviorTreeFactory():
9191
registerNodeType<SwitchNode<4>>("Switch4");
9292
registerNodeType<SwitchNode<5>>("Switch5");
9393
registerNodeType<SwitchNode<6>>("Switch6");
94-
94+
9595
registerNodeType<LoopNode<int>>("LoopInt");
9696
registerNodeType<LoopNode<bool>>("LoopBool");
9797
registerNodeType<LoopNode<double>>("LoopDouble");
@@ -435,15 +435,15 @@ Tree BehaviorTreeFactory::createTree(const std::string& tree_name,
435435
return tree;
436436
}
437437

438-
void BehaviorTreeFactory::addDescriptionToManifest(const std::string& node_id,
439-
const std::string& description)
438+
void BehaviorTreeFactory::addMetadataToManifest(const std::string& node_id,
439+
const std::vector<std::pair<std::string, std::string>>& metadata)
440440
{
441441
auto it = _p->manifests.find(node_id);
442442
if (it == _p->manifests.end())
443443
{
444-
throw std::runtime_error("addDescriptionToManifest: wrong ID");
444+
throw std::runtime_error("addMetadataToManifest: wrong ID");
445445
}
446-
it->second.description = description;
446+
it->second.metadata = metadata;
447447
}
448448

449449
void BehaviorTreeFactory::registerScriptingEnum(StringView name, int value)

src/xml_parsing.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ struct XMLParser::PImpl
8383
std::map<std::string, SubtreeModel> subtree_models;
8484

8585
int suffix_count;
86-
86+
8787
explicit PImpl(const BehaviorTreeFactory& fact) :
8888
factory(fact), current_path(std::filesystem::current_path()), suffix_count(0)
8989
{}
@@ -982,11 +982,18 @@ void addNodeModelToXML(const TreeNodeManifest& model,
982982
element->InsertEndChild(port_element);
983983
}
984984

985-
if (!model.description.empty())
985+
if (!model.metadata.empty())
986986
{
987-
auto description_element = doc.NewElement("description");
988-
description_element->SetText(model.description.c_str());
989-
element->InsertEndChild(description_element);
987+
auto metadata_root = doc.NewElement("MetadataFields");
988+
989+
for (const auto& [name, value] : model.metadata)
990+
{
991+
auto metadata_element = doc.NewElement("Metadata");
992+
metadata_element->SetAttribute(name.c_str(), value.c_str());
993+
metadata_root->InsertEndChild(metadata_element);
994+
}
995+
996+
element->InsertEndChild(metadata_root);
990997
}
991998

992999
model_root->InsertEndChild(element);
@@ -997,7 +1004,7 @@ void addTreeToXML(const Tree& tree,
9971004
XMLElement* rootXML,
9981005
bool add_metadata,
9991006
bool add_builtin_models)
1000-
{
1007+
{
10011008
std::function<void(const TreeNode&, XMLElement*)> addNode;
10021009
addNode = [&](const TreeNode& node,
10031010
XMLElement* parent_elem)

tests/gtest_factory.cpp

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include <gtest/gtest.h>
22
#include <filesystem>
3+
#include <string>
4+
#include <utility>
5+
#include <vector>
36
#include "behaviortree_cpp/xml_parsing.h"
47
#include "../sample_nodes/crossdoor_nodes.h"
58
#include "../sample_nodes/dummy_nodes.h"
@@ -388,10 +391,18 @@ TEST(BehaviorTreeReload, ReloadSameTree)
388391
}
389392
}
390393

391-
class DescriptiveAction : public SyncActionNode
394+
std::vector<std::pair<std::string, std::string>> makeTestMetadata()
395+
{
396+
return {
397+
std::make_pair<std::string, std::string>("foo", "hello"),
398+
std::make_pair<std::string, std::string>("bar", "42"),
399+
};
400+
}
401+
402+
class ActionWithMetadata : public SyncActionNode
392403
{
393404
public:
394-
DescriptiveAction(const std::string& name, const NodeConfig& config):
405+
ActionWithMetadata(const std::string& name, const NodeConfig& config):
395406
SyncActionNode(name, config) {}
396407

397408
BT::NodeStatus tick() override {
@@ -402,21 +413,39 @@ class DescriptiveAction : public SyncActionNode
402413
return {};
403414
}
404415

405-
static std::string description() {
406-
return "THE DESCRIPTION";
416+
static std::vector<std::pair<std::string, std::string>> metadata() {
417+
return makeTestMetadata();
407418
}
408419
};
409420

410-
TEST(BehaviorTreeFactory, DescriptionMethod)
421+
TEST(BehaviorTreeFactory, ManifestMethod)
411422
{
423+
const char* expectedXML = R"(
424+
<Action ID="ActionWithMetadata">
425+
<MetadataFields>
426+
<Metadata foo="hello"/>
427+
<Metadata bar="42"/>
428+
</MetadataFields>
429+
</Action>)";
412430

413431
BehaviorTreeFactory factory;
414-
factory.registerNodeType<DescriptiveAction>("DescriptiveAction");
415-
const auto& manifest = factory.manifests().at("DescriptiveAction");
416-
ASSERT_EQ(manifest.description, "THE DESCRIPTION");
432+
factory.registerNodeType<ActionWithMetadata>("ActionWithMetadata");
433+
const auto& manifest = factory.manifests().at("ActionWithMetadata");
434+
EXPECT_EQ(manifest.metadata, makeTestMetadata());
417435

418436
auto xml = writeTreeNodesModelXML(factory, false);
419437
std::cout << xml << std::endl;
420438

421-
ASSERT_NE(xml.find( "<description>THE DESCRIPTION</description>"), std::string::npos);
439+
EXPECT_NE(xml.find(expectedXML), std::string::npos);
440+
}
441+
442+
TEST(BehaviorTreeFactory, addMetadataToManifest)
443+
{
444+
BehaviorTreeFactory factory;
445+
factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");
446+
const auto& initial_manifest = factory.manifests().at("SaySomething");
447+
EXPECT_TRUE(initial_manifest.metadata.empty());
448+
factory.addMetadataToManifest("SaySomething", makeTestMetadata());
449+
const auto& modified_manifest = factory.manifests().at("SaySomething");
450+
EXPECT_EQ(modified_manifest.metadata, makeTestMetadata());
422451
}

0 commit comments

Comments
 (0)