loop_node.h
Go to the documentation of this file.
1 /* Copyright (C) 2022 Davide Faconti - All Rights Reserved
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
4 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
5 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
10 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 */
12 
13 #pragma once
14 
15 #include <deque>
17 
18 namespace BT
19 {
20 
21 // this object will allow us to modify the queue in place,
22 // when popping, in a thread safe-way and without copying the entire queue.
23 template <typename T>
24 using SharedQueue = std::shared_ptr<std::deque<T>>;
25 
36 template <typename T = Any>
37 class LoopNode : public DecoratorNode
38 {
39  bool child_running_ = false;
42 
43 public:
44  LoopNode(const std::string& name, const NodeConfig& config)
46  {
47  auto raw_port = getRawPortValue("queue");
48  if(!isBlackboardPointer(raw_port))
49  {
50  static_queue_ = convertFromString<SharedQueue<T>>(raw_port);
51  }
52  }
53 
54  NodeStatus tick() override
55  {
56  bool popped = false;
57  if(status() == NodeStatus::IDLE)
58  {
59  child_running_ = false;
60  // special case: the port contains a string that was converted to SharedQueue<T>
61  if(static_queue_)
62  {
63  current_queue_ = std::make_shared<std::deque<T>>();
65  }
66  }
67 
68  // Pop value from queue, if the child is not RUNNING
69  if(!child_running_)
70  {
71  // if the port is static, any_ref is empty, otherwise it will keep access to
72  // port locked for thread-safety
75  if(any_ref)
76  {
78  }
79 
80  if(current_queue_ && !current_queue_->empty())
81  {
82  auto value = std::move(current_queue_->front());
83  current_queue_->pop_front();
84  popped = true;
85  setOutput("value", value);
86  }
87  }
88 
89  if(!popped && !child_running_)
90  {
91  return getInput<NodeStatus>("if_empty").value();
92  }
93 
94  if(status() == NodeStatus::IDLE)
95  {
97  }
98 
99  NodeStatus child_state = child_node_->executeTick();
100  child_running_ = (child_state == NodeStatus::RUNNING);
101 
102  if(isStatusCompleted(child_state))
103  {
104  resetChild();
105  }
106 
107  if(child_state == NodeStatus::FAILURE)
108  {
109  return NodeStatus::FAILURE;
110  }
111  return NodeStatus::RUNNING;
112  }
113 
115  {
116  // we mark "queue" as BidirectionalPort, because the original element is modified
117  return { BidirectionalPort<SharedQueue<T>>("queue"),
118  InputPort<NodeStatus>("if_empty", NodeStatus::SUCCESS,
119  "Status to return if queue is empty: "
120  "SUCCESS, FAILURE, SKIPPED"),
121  OutputPort<T>("value") };
122  }
123 };
124 
125 template <>
126 inline SharedQueue<int> convertFromString<SharedQueue<int>>(StringView str)
127 {
128  auto parts = splitString(str, ';');
129  SharedQueue<int> output = std::make_shared<std::deque<int>>();
130  for(const StringView& part : parts)
131  {
132  output->push_back(convertFromString<int>(part));
133  }
134  return output;
135 }
136 
137 template <>
138 inline SharedQueue<bool> convertFromString<SharedQueue<bool>>(StringView str)
139 {
140  auto parts = splitString(str, ';');
141  SharedQueue<bool> output = std::make_shared<std::deque<bool>>();
142  for(const StringView& part : parts)
143  {
144  output->push_back(convertFromString<bool>(part));
145  }
146  return output;
147 }
148 
149 template <>
150 inline SharedQueue<double> convertFromString<SharedQueue<double>>(StringView str)
151 {
152  auto parts = splitString(str, ';');
153  SharedQueue<double> output = std::make_shared<std::deque<double>>();
154  for(const StringView& part : parts)
155  {
156  output->push_back(convertFromString<double>(part));
157  }
158  return output;
159 }
160 
161 template <>
162 inline SharedQueue<std::string>
163 convertFromString<SharedQueue<std::string>>(StringView str)
164 {
165  auto parts = splitString(str, ';');
166  SharedQueue<std::string> output = std::make_shared<std::deque<std::string>>();
167  for(const StringView& part : parts)
168  {
169  output->push_back(convertFromString<std::string>(part));
170  }
171  return output;
172 }
173 
174 } // namespace BT
BT
Definition: ex01_wrap_legacy.cpp:29
BT::LoopNode::LoopNode
LoopNode(const std::string &name, const NodeConfig &config)
Definition: loop_node.h:44
BT::LoopNode
The LoopNode class is used to pop_front elements from a std::deque. This element is copied into the p...
Definition: loop_node.h:37
BT::TreeNode::config
const NodeConfig & config() const
Definition: tree_node.cpp:351
BT::TreeNode::executeTick
virtual BT::NodeStatus executeTick()
The method that should be used to invoke tick() and setStatus();.
Definition: tree_node.cpp:71
BT::StringView
std::string_view StringView
Definition: basic_types.h:59
BT::LoopNode::current_queue_
SharedQueue< T > current_queue_
Definition: loop_node.h:41
BT::LoopNode::tick
NodeStatus tick() override
Method to be implemented by the user.
Definition: loop_node.h:54
BT::DecoratorNode
Definition: decorator_node.h:8
lexy::_detail::any_ref
any_base * any_ref
Definition: any_ref.hpp:43
BT::SharedQueue
std::shared_ptr< std::deque< T > > SharedQueue
Definition: loop_node.h:24
BT::PortsList
std::unordered_map< std::string, PortInfo > PortsList
Definition: basic_types.h:587
BT::TreeNode::status
NodeStatus status() const
Definition: tree_node.cpp:285
BT::NodeStatus::FAILURE
@ FAILURE
BT::LoopNode::child_running_
bool child_running_
Definition: loop_node.h:39
BT::TreeNode::setStatus
void setStatus(NodeStatus new_status)
setStatus changes the status of the node. it will throw if you try to change the status to IDLE,...
Definition: tree_node.cpp:160
BT::AnyPtrLocked
LockedPtr< Any > AnyPtrLocked
Definition: blackboard.h:19
BT::TreeNode::getRawPortValue
StringView getRawPortValue(const std::string &key) const
Definition: tree_node.cpp:361
BT::convertFromString< bool >
bool convertFromString< bool >(StringView str)
Definition: basic_types.cpp:254
BT::splitString
std::vector< StringView > splitString(const StringView &strToSplit, char delimeter)
Definition: basic_types.cpp:349
BT::TreeNode::getLockedPortContent
AnyPtrLocked getLockedPortContent(const std::string &key)
getLockedPortContent should be used when:
Definition: tree_node.cpp:486
BT::LockedPtr
The LockedPtr class is used to share a pointer to an object and a mutex that protects the read/write ...
Definition: locked_reference.hpp:16
BT::TreeNode::setOutput
Result setOutput(const std::string &key, const T &value)
setOutput modifies the content of an Output port
Definition: tree_node.h:571
BT::TreeNode::name
const std::string & name() const
Name of the instance, not the type.
Definition: tree_node.cpp:302
BT::NodeStatus::SUCCESS
@ SUCCESS
BT::NodeStatus::RUNNING
@ RUNNING
BT::LoopNode::providedPorts
static PortsList providedPorts()
Definition: loop_node.h:114
BT::isStatusCompleted
bool isStatusCompleted(const NodeStatus &status)
Definition: basic_types.h:47
BT::NodeStatus::IDLE
@ IDLE
BT::convertFromString< double >
double convertFromString< double >(StringView str)
Definition: basic_types.cpp:192
BT::NodeConfig
Definition: tree_node.h:82
BT::TreeNode::isBlackboardPointer
static bool isBlackboardPointer(StringView str, StringView *stripped_pointer=nullptr)
Check a string and return true if it matches the pattern: {...}.
Definition: tree_node.cpp:375
BT::DecoratorNode::resetChild
void resetChild()
Definition: decorator_node.cpp:53
decorator_node.h
BT::LoopNode::static_queue_
SharedQueue< T > static_queue_
Definition: loop_node.h:40
BT::NodeStatus
NodeStatus
Definition: basic_types.h:33
BT::DecoratorNode::child_node_
TreeNode * child_node_
Definition: decorator_node.h:11
lexy::_detail::any_base::get
constexpr T & get() noexcept
Definition: any_ref.hpp:25


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Wed Apr 16 2025 02:20:56