Skip to content

Commit 1217c7e

Browse files
Fix #937: enable returning BehaviorTreeFactory by value (#1082)
* Fix #937: allow BehaviorTreeFactory to be returned by value Move constructor and move assignment were defaulted in the header where PImpl is an incomplete type, preventing compilation when returning BehaviorTreeFactory by value from inline functions. Move the definitions to bt_factory.cpp where PImpl is complete, matching the existing pattern used for the destructor. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix clang-tidy readability-implicit-bool-conversion warning Use explicit != nullptr comparison for pointer-to-bool conversion flagged by clang-tidy. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent e0684b0 commit 1217c7e

File tree

4 files changed

+29
-3
lines changed

4 files changed

+29
-3
lines changed

include/behaviortree_cpp/bt_factory.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,8 @@ class BehaviorTreeFactory
224224
BehaviorTreeFactory(const BehaviorTreeFactory& other) = delete;
225225
BehaviorTreeFactory& operator=(const BehaviorTreeFactory& other) = delete;
226226

227-
BehaviorTreeFactory(BehaviorTreeFactory&& other) noexcept = default;
228-
BehaviorTreeFactory& operator=(BehaviorTreeFactory&& other) noexcept = default;
227+
BehaviorTreeFactory(BehaviorTreeFactory&& other) noexcept;
228+
BehaviorTreeFactory& operator=(BehaviorTreeFactory&& other) noexcept;
229229

230230
/// Remove a registered ID.
231231
bool unregisterBuilder(const std::string& ID);

src/bt_factory.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ BehaviorTreeFactory::BehaviorTreeFactory() : _p(new PImpl)
106106

107107
BehaviorTreeFactory::~BehaviorTreeFactory() = default;
108108

109+
BehaviorTreeFactory::BehaviorTreeFactory(BehaviorTreeFactory&& other) noexcept = default;
110+
BehaviorTreeFactory&
111+
BehaviorTreeFactory::operator=(BehaviorTreeFactory&& other) noexcept = default;
112+
109113
bool BehaviorTreeFactory::unregisterBuilder(const std::string& ID)
110114
{
111115
if(builtinNodes().count(ID) != 0)

src/tree_node.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ AnyPtrLocked BT::TreeNode::getLockedPortContent(const std::string& key)
481481
{
482482
const auto bb_key = std::string(*remapped_key);
483483
auto result = _p->config.blackboard->getAnyLocked(bb_key);
484-
if(!result && _p->config.manifest)
484+
if(!result && _p->config.manifest != nullptr)
485485
{
486486
// Entry doesn't exist yet. Create it using the port's type info
487487
// from the manifest so that getLockedPortContent works even when

tests/gtest_factory.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,28 @@ TEST(BehaviorTreeFactory, ManifestMethod)
450450
EXPECT_NE(xml.find(expectedXML), std::string::npos);
451451
}
452452

453+
TEST(BehaviorTreeFactory, ReturnByValue)
454+
{
455+
// Issue #937: BehaviorTreeFactory cannot be returned by value from
456+
// a function because the move constructor/assignment were defaulted
457+
// in the header where PImpl is an incomplete type.
458+
auto make_factory = []() -> BT::BehaviorTreeFactory {
459+
BT::BehaviorTreeFactory factory;
460+
factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");
461+
return factory;
462+
};
463+
auto factory = make_factory();
464+
465+
// Verify the moved-into factory is fully functional
466+
const auto& manifests = factory.manifests();
467+
ASSERT_TRUE(manifests.count("SaySomething"));
468+
469+
// Also test move assignment
470+
BT::BehaviorTreeFactory factory2;
471+
factory2 = std::move(factory);
472+
ASSERT_TRUE(factory2.manifests().count("SaySomething"));
473+
}
474+
453475
TEST(BehaviorTreeFactory, addMetadataToManifest)
454476
{
455477
BehaviorTreeFactory factory;

0 commit comments

Comments
 (0)