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

Skip to content

Commit af243ad

Browse files
committed
improve Any::castPtr and add example
1 parent a5525fa commit af243ad

File tree

6 files changed

+124
-12
lines changed

6 files changed

+124
-12
lines changed

examples/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ CompileExample("ex01_wrap_legacy")
3737
CompileExample("ex02_runtime_ports")
3838
CompileExample("ex04_waypoints")
3939
CompileExample("ex05_subtree_model")
40+
CompileExample("ex06_access_by_ptr")
4041

4142
CompileExample("t13_plugin_executor")
4243

examples/ex04_waypoints.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "behaviortree_cpp/bt_factory.h"
22
#include "behaviortree_cpp/decorators/loop_node.h"
33
#include "behaviortree_cpp/loggers/bt_cout_logger.h"
4-
#include <list>
4+
#include <deque>
55

66
using namespace BT;
77

examples/ex06_access_by_ptr.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include "behaviortree_cpp/bt_factory.h"
2+
3+
using namespace BT;
4+
5+
/**
6+
* @brief Show how to access an entry in the blackboard by pointer.
7+
* This approach is more verbose, but thread-safe
8+
*
9+
*/
10+
class PushIntoVector : public SyncActionNode
11+
{
12+
public:
13+
PushIntoVector(const std::string& name, const NodeConfig& config) :
14+
SyncActionNode(name, config)
15+
{}
16+
17+
NodeStatus tick() override
18+
{
19+
const int number = getInput<int>("value").value();
20+
if(auto any_ptr = getLockedPortContent("vector"))
21+
{
22+
// inside this scope, any_ptr provides a mutex-protected,
23+
// thread-safe way to access an element inside the blackboard.
24+
if(auto vect_ptr = any_ptr->castPtr<std::vector<int>>())
25+
{
26+
vect_ptr->push_back(number);
27+
std::cout << "Value ["<< number <<"] pushed into the vector. New size: "
28+
<< vect_ptr->size() << "\n";
29+
}
30+
else {
31+
// This happens when the entry of the blackboard is empty or if
32+
// we tried to cast to the wrong type.
33+
// Let's insert a new vector<int> with a single value
34+
std::vector<int> vect = {number};
35+
any_ptr.assign(vect);
36+
std::cout << "We created a new vector, containing value ["<< number <<"]\n";
37+
}
38+
return NodeStatus::SUCCESS;
39+
}
40+
else {
41+
return NodeStatus::FAILURE;
42+
}
43+
}
44+
45+
static PortsList providedPorts()
46+
{
47+
return {BT::BidirectionalPort<std::vector<int>>("vector"),
48+
BT::InputPort<int>("value")};
49+
}
50+
};
51+
52+
//--------------------------------------------------------------
53+
54+
// clang-format off
55+
static const char* xml_tree = R"(
56+
<root BTCPP_format="4" >
57+
<BehaviorTree ID="TreeA">
58+
<Sequence>
59+
<PushIntoVector vector="{vect}" value="3"/>
60+
<PushIntoVector vector="{vect}" value="5"/>
61+
<PushIntoVector vector="{vect}" value="7"/>
62+
</Sequence>
63+
</BehaviorTree>
64+
</root>
65+
)";
66+
67+
// clang-format on
68+
69+
int main()
70+
{
71+
BehaviorTreeFactory factory;
72+
factory.registerNodeType<PushIntoVector>("PushIntoVector");
73+
74+
auto tree = factory.createTreeFromText(xml_tree);
75+
tree.tickWhileRunning();
76+
return 0;
77+
}

include/behaviortree_cpp/utils/locked_reference.hpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <mutex>
4+
#include "behaviortree_cpp/utils/safe_any.hpp"
45

56
namespace BT
67
{
@@ -9,15 +10,15 @@ namespace BT
910
* and a mutex that protects the read/write access to that object.
1011
*
1112
* As long as the object remains in scope, the mutex is locked, therefore
12-
* you must destroy this object as soon as the pointer was used.
13+
* you must destroy this instance as soon as the pointer was used.
1314
*/
1415
template <typename T>
1516
class LockedPtr {
1617
public:
1718

1819
LockedPtr() = default;
1920

20-
LockedPtr(const T* obj, std::mutex* obj_mutex):
21+
LockedPtr(T* obj, std::mutex* obj_mutex):
2122
ref_(obj), mutex_(obj_mutex) {
2223
mutex_->lock();
2324
}
@@ -65,8 +66,36 @@ class LockedPtr {
6566
return ref_;
6667
}
6768

69+
const T* operator->() const{
70+
return ref_;
71+
}
72+
73+
T* operator->() {
74+
return ref_;
75+
}
76+
77+
template <typename OtherT>
78+
void assign(const OtherT& other)
79+
{
80+
if(ref_ == nullptr)
81+
{
82+
throw std::runtime_error("Empty LockedPtr reference");
83+
}
84+
else if constexpr(std::is_same_v<T, OtherT>)
85+
{
86+
*ref_ = other;
87+
}
88+
else if constexpr( std::is_same_v<BT::Any, OtherT>)
89+
{
90+
other->copyInto(*ref_);
91+
}
92+
else {
93+
*ref_ = T(other);
94+
}
95+
}
96+
6897
private:
69-
const T* ref_ = nullptr;
98+
T* ref_ = nullptr;
7099
std::mutex* mutex_ = nullptr;
71100
};
72101

include/behaviortree_cpp/utils/safe_any.hpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,21 @@ class Any
160160
}
161161
}
162162

163-
// Method to access the value by pointer
163+
// Method to access the value by pointer.
164+
// It will return nullptr, if the user try to cast it to a
165+
// wrong type or if Any was empty.
164166
template <typename T>
165-
[[nodiscard]] T* castPtr() const {
167+
[[nodiscard]] T* castPtr() {
166168

167-
if( _any.empty() )
168-
{
169-
return nullptr;
170-
}
171-
return linb::any_cast<T>(&_any);
169+
static_assert(!std::is_same_v<T, float>,
170+
"The value has been casted internally to [double]. "
171+
"Use that instead");
172+
static_assert(!SafeAny::details::is_integer<T>() ||
173+
std::is_same_v<T, uint64_t>,
174+
"The value has been casted internally to [int64_t]. "
175+
"Use that instead");
176+
177+
return _any.empty() ? nullptr : linb::any_cast<T>(&_any);
172178
}
173179

174180
// This is the original type

src/loggers/groot2_publisher.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#include <future>
21
#include "behaviortree_cpp/json_export.h"
32
#include "behaviortree_cpp/loggers/groot2_publisher.h"
43
#include "behaviortree_cpp/loggers/groot2_protocol.h"

0 commit comments

Comments
 (0)