Go to the documentation of this file.
28 #pragma warning(disable : 4127)
66 [[nodiscard]] std::string toStr<BT::PostCond>(
const BT::PostCond& status);
69 [[nodiscard]] std::string toStr<BT::PreCond>(
const BT::PreCond& status);
81 std::shared_ptr<ScriptingEnumsRegistry>
enums;
104 template <
typename T>
110 template <
typename T,
typename... ExtraArgs>
114 ExtraArgs...>::value;
121 typedef std::shared_ptr<TreeNode>
Ptr;
148 [[nodiscard]]
bool isHalted()
const;
153 [[nodiscard]]
const std::string&
name()
const;
215 [[nodiscard]] uint16_t
UID()
const;
219 [[nodiscard]]
const std::string&
fullPath()
const;
236 template <
typename T>
247 template <
typename T>
249 T& destination)
const;
256 template <
typename T>
261 return (res) ?
Expected<T>(out) : nonstd::make_unexpected(res.error());
269 template <
typename T>
280 return nonstd::make_unexpected(res.error());
290 template <
typename T>
346 template <
class DerivedT,
typename... ExtraArgs>
351 static_assert(hasNodeFullCtor<DerivedT, ExtraArgs...>() ||
352 hasNodeNameCtor<DerivedT>());
354 if constexpr(hasNodeFullCtor<DerivedT, ExtraArgs...>())
356 return std::make_unique<DerivedT>(
name,
config, args...);
358 else if constexpr(hasNodeNameCtor<DerivedT>())
360 auto node_ptr =
new DerivedT(
name, args...);
361 node_ptr->config() =
config;
362 return std::unique_ptr<DerivedT>(node_ptr);
400 template <
typename T>
405 std::unique_ptr<PImpl>
_p;
412 virtual void halt() = 0;
417 template <
typename T>
420 if constexpr(std::is_enum_v<T> && !std::is_same_v<T, NodeStatus>)
424 if(it !=
config().enums->end())
426 return static_cast<T
>(it->second);
431 return static_cast<T
>(convertFromString<int>(str));
434 return convertFromString<T>(str);
437 template <
typename T>
439 T& destination)
const
441 std::string port_value_str;
444 if(input_port_it !=
config().input_ports.end())
446 port_value_str = input_port_it->second;
450 return nonstd::make_unexpected(
StrCat(
"getInput() of node '",
fullPath(),
451 "' failed because the manifest is "
452 "nullptr (WTF?) and the key: [",
453 key,
"] is missing"));
461 return nonstd::make_unexpected(
StrCat(
"getInput() of node '",
fullPath(),
462 "' failed because the manifest doesn't "
463 "contain the key: [",
466 const auto& port_info = port_manifest_it->second;
468 if(port_info.defaultValue().empty())
470 return nonstd::make_unexpected(
StrCat(
"getInput() of node '",
fullPath(),
471 "' failed because nor the manifest or the "
472 "XML contain the key: [",
475 if(port_info.defaultValue().isString())
477 port_value_str = port_info.defaultValue().cast<std::string>();
481 destination = port_info.defaultValue().cast<T>();
494 destination = parseString<T>(port_value_str);
496 catch(std::exception& ex)
498 return nonstd::make_unexpected(
StrCat(
"getInput(): ", ex.what()));
502 const auto& blackboard_key = blackboard_ptr.value();
506 return nonstd::make_unexpected(
"getInput(): trying to access "
507 "an invalid Blackboard");
510 if(
auto entry =
config().blackboard->getEntry(std::string(blackboard_key)))
512 std::unique_lock lk(entry->entry_mutex);
513 auto& any_value = entry->value;
516 if constexpr(std::is_same_v<T, Any>)
518 destination = any_value;
519 return Timestamp{ entry->sequence_id, entry->stamp };
522 if(!entry->value.empty())
524 if(!std::is_same_v<T, std::string> && any_value.isString())
526 destination = parseString<T>(any_value.cast<std::string>());
530 destination = any_value.cast<T>();
532 return Timestamp{ entry->sequence_id, entry->stamp };
536 return nonstd::make_unexpected(
StrCat(
"getInput() failed because it was unable to "
538 key,
"] remapped to [", blackboard_key,
"]"));
540 catch(std::exception& err)
542 return nonstd::make_unexpected(err.what());
546 template <
typename T>
552 return nonstd::make_unexpected(res.error());
557 template <
typename T>
562 return nonstd::make_unexpected(
"setOutput() failed: trying to access a "
563 "Blackboard(BB) entry, but BB is invalid");
567 if(remap_it ==
config().output_ports.end())
569 return nonstd::make_unexpected(
StrCat(
"setOutput() failed: "
570 "NodeConfig::output_ports "
571 "does not contain the key: [",
575 if(remapped_key ==
"{=}" || remapped_key ==
"=")
583 return nonstd::make_unexpected(
"setOutput requires a blackboard pointer. Use {}");
586 if constexpr(std::is_same_v<BT::Any, T>)
590 throw LogicError(
"setOutput<Any> is not allowed, unless the port "
591 "was declared using OutputPort<Any>");
602 template <
typename T>
605 for(
const auto& it : getProvidedPorts<T>())
607 const auto& port_name = it.first;
608 const auto direction = it.second.direction();
Result getInput(const std::string &key, T &destination) const
std::shared_ptr< CallableFunction > Subscriber
NodeType
Enumerates the possible types of nodes.
bool requiresWakeUp() const
std::map< PreCond, std::string > pre_conditions
const NodeConfig & config() const
void emitWakeUpSignal()
Notify that the tree should be ticked again()
StatusChangeSignal::Subscriber StatusChangeSubscriber
std::function< void(TreeNode &, NodeStatus, std::chrono::microseconds)> TickMonitorCallback
constexpr bool hasNodeFullCtor()
nonstd::expected< T, std::string > Expected
virtual BT::NodeStatus executeTick()
The method that should be used to invoke tick() and setStatus();.
std::string_view StringView
PortsRemapping input_ports
std::function< Any(Ast::Environment &env)> ScriptFunction
void setPreTickFunction(PreTickCallback callback)
Abstract base class for Behavior Tree Nodes.
Struct used to store a tree. If this object goes out of scope, the tree is destroyed.
std::shared_ptr< TreeNode > Ptr
std::function< void(CallableArgs...)> CallableFunction
std::function< NodeStatus(TreeNode &)> PreTickCallback
constexpr E value(std::size_t i) noexcept
const std::string & registrationName() const
registrationName is the ID used by BehaviorTreeFactory to create an instance.
std::array< ScriptFunction, size_t(PostCond::COUNT_)> PostScripts
constexpr auto callback(Fns &&... fns)
Creates a callback.
std::shared_ptr< Blackboard > Ptr
Blackboard::Ptr blackboard
std::unordered_map< std::string, PortInfo > PortsList
NodeStatus status() const
void setPostTickFunction(PostTickCallback callback)
BT::NodeStatus waitValidStatus()
std::string registration_ID
void setStatus(NodeStatus new_status)
setStatus changes the status of the node. it will throw if you try to change the status to IDLE,...
void setTickMonitorCallback(TickMonitorCallback callback)
StringView getRawPortValue(const std::string &key) const
T parseString(const std::string &str) const
Expected< StampedValue< T > > getInputStamped(const std::string &key) const
static std::unique_ptr< TreeNode > Instantiate(const std::string &name, const NodeConfig &config, ExtraArgs... args)
This information is used mostly by the XMLParser.
virtual NodeType type() const =0
std::unordered_map< std::string, int > ScriptingEnumsRegistry
PostScripts & postConditionsScripts()
AnyPtrLocked getLockedPortContent(const std::string &key)
getLockedPortContent should be used when:
The LockedPtr class is used to share a pointer to an object and a mutex that protects the read/write ...
void setRegistrationID(StringView ID)
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
void checkPostConditions(NodeStatus status)
std::vector< std::pair< std::string, std::string > > KeyValueVector
Result setOutput(const std::string &key, const T &value)
setOutput modifies the content of an Output port
const TreeNodeManifest * manifest
Expected< T > getInput(const std::string &key) const
const std::string & name() const
Name of the instance, not the type.
virtual BT::NodeStatus tick()=0
Method to be implemented by the user.
void modifyPortsRemapping(const PortsRemapping &new_remapping)
TreeNode & operator=(const TreeNode &other)=delete
PreScripts & preConditionsScripts()
std::unordered_map< std::string, std::string > PortsRemapping
static Expected< StringView > getRemappedKey(StringView port_name, StringView remapped_port)
void setWakeUpInstance(std::shared_ptr< WakeUpSignal > instance)
Expected< Timestamp > getInputStamped(const std::string &key, T &destination) const
getInputStamped is similar to getInput(dey, destination), but it returne also the Timestamp object,...
StatusChangeSubscriber subscribeToStatusChange(StatusChangeCallback callback)
subscribeToStatusChange is used to attach a callback to a status change. When StatusChangeSubscriber ...
void assignDefaultRemapping(NodeConfig &config)
std::map< PostCond, std::string > post_conditions
TreeNode(std::string name, NodeConfig config)
TreeNode main constructor.
std::unique_ptr< PImpl > _p
void resetStatus()
Set the status to IDLE.
constexpr auto is_constructible
std::array< ScriptFunction, size_t(PreCond::COUNT_)> PreScripts
const std::string & fullPath() const
constexpr bool hasNodeNameCtor()
Expected< NodeStatus > checkPreConditions()
std::function< NodeStatus(TreeNode &, NodeStatus)> PostTickCallback
PortsRemapping output_ports
Expected< std::monostate > Result
static bool isBlackboardPointer(StringView str, StringView *stripped_pointer=nullptr)
Check a string and return true if it matches the pattern: {...}.
std::shared_ptr< ScriptingEnumsRegistry > enums
StatusChangeSignal::CallableFunction StatusChangeCallback
static StringView stripBlackboardPointer(StringView str)