Skip to content

Commit 57a70d2

Browse files
committed
use PImpl and more comments
1 parent 28123db commit 57a70d2

14 files changed

+426
-339
lines changed

include/behaviortree_cpp/bt_factory.h

Lines changed: 50 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* Copyright (C) 2018 Michele Colledanchise - All Rights Reserved
2-
* Copyright (C) 2018-2020 Davide Faconti, Eurecat - All Rights Reserved
2+
* Copyright (C) 2018-2023 Davide Faconti - All Rights Reserved
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
55
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
@@ -14,12 +14,13 @@
1414
#ifndef BT_FACTORY_H
1515
#define BT_FACTORY_H
1616

17+
#include <algorithm>
18+
#include <cstring>
19+
#include <filesystem>
1720
#include <functional>
1821
#include <memory>
1922
#include <unordered_map>
2023
#include <unordered_set>
21-
#include <cstring>
22-
#include <algorithm>
2324
#include <set>
2425

2526
#include "behaviortree_cpp/contrib/magic_enum.hpp"
@@ -99,47 +100,19 @@ class Tree
99100
};
100101

101102
std::vector<Subtree::Ptr> subtrees;
102-
103103
std::unordered_map<std::string, TreeNodeManifest> manifests;
104104

105-
Tree()
106-
{}
105+
Tree();
107106

108-
// non-copyable. Only movable
109107
Tree(const Tree&) = delete;
110108
Tree& operator=(const Tree&) = delete;
111109

112-
Tree(Tree&& other)
113-
{
114-
(*this) = std::move(other);
115-
}
116-
117-
Tree& operator=(Tree&& other)
118-
{
119-
subtrees = std::move(other.subtrees);
120-
manifests = std::move(other.manifests);
121-
wake_up_ = other.wake_up_;
122-
return *this;
123-
}
110+
Tree(Tree&& other);
111+
Tree& operator=(Tree&& other);
124112

125113
void initialize();
126114

127-
void haltTree()
128-
{
129-
if (!rootNode())
130-
{
131-
return;
132-
}
133-
// the halt should propagate to all the node if the nodes
134-
// have been implemented correctly
135-
rootNode()->haltNode();
136-
137-
//but, just in case.... this should be no-op
138-
auto visitor = [](BT::TreeNode* node) { node->haltNode(); };
139-
BT::applyRecursiveVisitor(rootNode(), visitor);
140-
141-
rootNode()->resetStatus();
142-
}
115+
void haltTree();
143116

144117
[[nodiscard]] TreeNode* rootNode() const;
145118

@@ -226,6 +199,13 @@ class BehaviorTreeFactory
226199
{
227200
public:
228201
BehaviorTreeFactory();
202+
~BehaviorTreeFactory();
203+
204+
BehaviorTreeFactory(const BehaviorTreeFactory& other) = delete;
205+
BehaviorTreeFactory& operator=(const BehaviorTreeFactory& other) = delete;
206+
207+
BehaviorTreeFactory(BehaviorTreeFactory&& other) = default;
208+
BehaviorTreeFactory& operator=(BehaviorTreeFactory&& other) = default;
229209

230210
/// Remove a registered ID.
231211
bool unregisterBuilder(const std::string& ID);
@@ -302,14 +282,15 @@ class BehaviorTreeFactory
302282
* where "tree_id" come from the XML attribute <BehaviorTree ID="tree_id">
303283
*
304284
*/
305-
void registerBehaviorTreeFromFile(const std::string& filename);
285+
void registerBehaviorTreeFromFile(const std::filesystem::path& filename);
306286

307287
/// Same of registerBehaviorTreeFromFile, but passing the XML text,
308288
/// instead of the filename.
309289
void registerBehaviorTreeFromText(const std::string& xml_text);
310290

311291
/// Returns the ID of the trees registered either with
312292
/// registerBehaviorTreeFromFile or registerBehaviorTreeFromText.
293+
[[nodiscard]]
313294
std::vector<std::string> registeredBehaviorTrees() const;
314295

315296
/**
@@ -325,6 +306,7 @@ class BehaviorTreeFactory
325306
* @param config configuration that is passed to the constructor of the TreeNode.
326307
* @return new node.
327308
*/
309+
[[nodiscard]]
328310
std::unique_ptr<TreeNode> instantiateTreeNode(const std::string& name,
329311
const std::string& ID,
330312
const NodeConfig& config) const;
@@ -392,20 +374,48 @@ class BehaviorTreeFactory
392374
}
393375

394376
/// All the builders. Made available mostly for debug purposes.
377+
[[nodiscard]]
395378
const std::unordered_map<std::string, NodeBuilder>& builders() const;
396379

397380
/// Manifests of all the registered TreeNodes.
381+
[[nodiscard]]
398382
const std::unordered_map<std::string, TreeNodeManifest>& manifests() const;
399383

400384
/// List of builtin IDs.
385+
[[nodiscard]]
401386
const std::set<std::string>& builtinNodes() const;
402387

388+
/**
389+
* @brief createTreeFromText will parse the XML directly from string.
390+
* The XML needs to contain either a single <BehaviorTree> or specify
391+
* the attribute [main_tree_to_execute].
392+
*
393+
* Consider using instead registerBehaviorTreeFromText() and createTree().
394+
*
395+
* @param text string containing the XML
396+
* @param blackboard blackboard of the root tree
397+
* @return the newly created tree
398+
*/
399+
[[nodiscard]]
403400
Tree createTreeFromText(const std::string& text,
404401
Blackboard::Ptr blackboard = Blackboard::create());
405402

406-
Tree createTreeFromFile(const std::string& file_path,
403+
/**
404+
* @brief createTreeFromFile will parse the XML from a given file.
405+
* The XML needs to contain either a single <BehaviorTree> or specify
406+
* the attribute [main_tree_to_execute].
407+
*
408+
* Consider using instead registerBehaviorTreeFromFile() and createTree().
409+
*
410+
* @param file_path location of the file to load
411+
* @param blackboard blackboard of the root tree
412+
* @return the newly created tree
413+
*/
414+
[[nodiscard]]
415+
Tree createTreeFromFile(const std::filesystem::path& file_path,
407416
Blackboard::Ptr blackboard = Blackboard::create());
408417

418+
[[nodiscard]]
409419
Tree createTree(const std::string& tree_name,
410420
Blackboard::Ptr blackboard = Blackboard::create());
411421

@@ -476,20 +486,14 @@ class BehaviorTreeFactory
476486
/**
477487
* @brief substitutionRules return the current substitution rules.
478488
*/
489+
[[nodiscard]]
479490
const std::unordered_map<std::string, SubstitutionRule>&
480491
substitutionRules() const;
481492

482493
private:
483-
std::unordered_map<std::string, NodeBuilder> builders_;
484-
std::unordered_map<std::string, TreeNodeManifest> manifests_;
485-
std::set<std::string> builtin_IDs_;
486-
std::unordered_map<std::string, Any> behavior_tree_definitions_;
487-
488-
std::shared_ptr<std::unordered_map<std::string, int>> scripting_enums_;
489-
490-
std::shared_ptr<BT::Parser> parser_;
491494

492-
std::unordered_map<std::string, SubstitutionRule> substitution_rules_;
495+
struct PImpl;
496+
std::unique_ptr<PImpl> _p;
493497

494498
};
495499

include/behaviortree_cpp/bt_parser.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (C) 2022 Davide Faconti - All Rights Reserved
1+
/* Copyright (C) 2023 Davide Faconti - All Rights Reserved
22
*
33
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
44
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
@@ -12,6 +12,7 @@
1212

1313
#pragma once
1414

15+
#include <filesystem>
1516
#include "behaviortree_cpp/bt_factory.h"
1617
#include "behaviortree_cpp/blackboard.h"
1718

@@ -32,7 +33,10 @@ class Parser
3233
Parser(const Parser& other) = delete;
3334
Parser& operator=(const Parser& other) = delete;
3435

35-
virtual void loadFromFile(const std::string& filename, bool add_includes = true) = 0;
36+
Parser(Parser&& other) = default;
37+
Parser& operator=(Parser&& other) = default;
38+
39+
virtual void loadFromFile(const std::filesystem::path& filename, bool add_includes = true) = 0;
3640

3741
virtual void loadFromText(const std::string& xml_text, bool add_includes = true) = 0;
3842

include/behaviortree_cpp/loggers/abstract_logger.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ class StatusChangeLogger
1818
StatusChangeLogger(TreeNode* root_node);
1919
virtual ~StatusChangeLogger() = default;
2020

21+
StatusChangeLogger(const StatusChangeLogger& other) = delete;
22+
StatusChangeLogger& operator=(const StatusChangeLogger& other) = delete;
23+
24+
StatusChangeLogger(StatusChangeLogger&& other) = default;
25+
StatusChangeLogger& operator=(StatusChangeLogger&& other) = default;
26+
2127
virtual void callback(BT::Duration timestamp, const TreeNode& node,
2228
NodeStatus prev_status, NodeStatus status) = 0;
2329

include/behaviortree_cpp/loggers/bt_cout_logger.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,8 @@
77
namespace BT
88
{
99
/**
10-
* @brief AddStdCoutLoggerToTree. Give the root node of a tree,
11-
* a simple callback is subscribed to any status change of each node.
12-
*
13-
*
14-
* @param root_node
15-
* @return Important: the returned shared_ptr must not go out of scope,
16-
* otherwise the logger is removed.
10+
* @brief StdCoutLogger is a very simple logger that
11+
* displays all the transitions on the console.
1712
*/
1813

1914
class StdCoutLogger : public StatusChangeLogger
@@ -24,10 +19,13 @@ class StdCoutLogger : public StatusChangeLogger
2419
StdCoutLogger(const BT::Tree& tree);
2520
~StdCoutLogger() override;
2621

27-
virtual void callback(Duration timestamp, const TreeNode& node, NodeStatus prev_status,
28-
NodeStatus status) override;
29-
3022
virtual void flush() override;
23+
24+
private:
25+
26+
virtual void callback(Duration timestamp, const TreeNode& node,
27+
NodeStatus prev_status, NodeStatus status) override;
28+
3129
};
3230

3331
} // namespace BT

include/behaviortree_cpp/loggers/bt_file_logger_v2.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ namespace BT
99
{
1010
/**
1111
* @brief The FileLogger2 is a logger that saves the tree as
12-
* XML and all the transitions. Data is written to file in
13-
* a separate thread, to minimize latency.
12+
* XML and all the transitions.
13+
* Data is written to file in a separate thread, to minimize latency.
1414
*
1515
* Format:
1616
*
1717
* - first 4 bytes: size of the XML string (N)
1818
* - next N bytes: string containing the XML representing the tree.
1919
* - next 8 bytes: first timestamp (microseconds since epoch)
20-
* - next: each 8 bytes is a FileLogger2::Transition. See definition.
20+
* - next: each 9 bytes is a FileLogger2::Transition. See definition.
2121
*
2222
*/
2323
class FileLogger2 : public StatusChangeLogger
@@ -32,13 +32,21 @@ class FileLogger2 : public StatusChangeLogger
3232
*/
3333
FileLogger2(const Tree& tree, std::filesystem::path const& filepath);
3434

35+
FileLogger2(const FileLogger2& other) = delete;
36+
FileLogger2& operator=(const FileLogger2& other) = delete;
37+
38+
FileLogger2(FileLogger2&& other) = default;
39+
FileLogger2& operator=(FileLogger2&& other) = default;
40+
3541
virtual ~FileLogger2() override;
3642

3743
void callback(Duration timestamp, const TreeNode& node, NodeStatus prev_status,
3844
NodeStatus status) override;
3945

4046
struct Transition
4147
{
48+
// when serializing, we will remove the initial time and serialize only
49+
// 6 bytes, instead of 8
4250
uint64_t timestamp_usec;
4351
// if you have more than 64.000 nodes, you are doing something wrong :)
4452
uint16_t node_uid;
@@ -49,16 +57,8 @@ class FileLogger2 : public StatusChangeLogger
4957
void flush() override;
5058

5159
private:
52-
std::ofstream file_stream_;
53-
54-
Duration first_timestamp_ = {};
55-
56-
std::deque<Transition> transitions_queue_;
57-
std::condition_variable queue_cv_;
58-
std::mutex queue_mutex_;
59-
60-
std::thread writer_thread_;
61-
std::atomic_bool loop_ = true;
60+
struct PImpl;
61+
std::unique_ptr<PImpl> _p;
6262

6363
void writerLoop();
6464
};

include/behaviortree_cpp/loggers/bt_observer.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@
77
namespace BT
88
{
99

10+
/**
11+
* @brief The TreeObserver is used to collect statistics about which nodes
12+
* are executed and their returned status.
13+
*
14+
* It is particularly useful to create unit tests, since if allow to
15+
* determine if a certain transition happened as expected, in a non intrusive way.
16+
*/
1017
class TreeObserver : public StatusChangeLogger
1118
{
1219
public:
1320
TreeObserver(const BT::Tree& tree);
1421
~TreeObserver() override;
1522

16-
virtual void callback(Duration timestamp, const TreeNode& node, NodeStatus prev_status,
17-
NodeStatus status) override;
18-
1923
virtual void flush() override {}
2024

2125
void resetStatistics();
@@ -57,6 +61,9 @@ class TreeObserver : public StatusChangeLogger
5761
std::unordered_map<uint16_t, NodeStatistics> _statistics;
5862
std::unordered_map<std::string, uint16_t> _path_to_uid;
5963
std::map<uint16_t, std::string> _uid_to_path;
64+
65+
virtual void callback(Duration timestamp, const TreeNode& node,
66+
NodeStatus prev_status, NodeStatus status) override;
6067
};
6168

6269
} // namespace BT

0 commit comments

Comments
 (0)