3#include "behaviortree_cpp/contrib/expected.hpp"
4#include "behaviortree_cpp/exceptions.h"
5#include "behaviortree_cpp/utils/safe_any.hpp"
12#include <unordered_map>
42inline bool isStatusActive(
const NodeStatus& status)
47inline bool isStatusCompleted(
const NodeStatus& status)
52enum class PortDirection
61bool StartWith(StringView str, StringView prefix);
63bool StartWith(StringView str,
char prefix);
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
85using Expected = nonstd::expected<T, std::string>;
92
93
94
95
96
97
98
99
106 return convertFromJSON(str,
typeid(T)).cast<T>();
110
111
112
113
114
115
116
117
118
119
120
125 if(StartWith(str,
"json:"))
127 str.remove_prefix(5);
128 return convertFromJSON<T>(str);
131 auto type_name =
BT::demangle(
typeid(T));
133 std::cerr <<
"You (maybe indirectly) called BT::convertFromString() for type ["
134 << type_name <<
"], but I can't find the template specialization.\n"
137 throw LogicError(std::string(
"You didn't implement the template specialization of "
138 "convertFromString for this type: ") +
143[[nodiscard]] std::string convertFromString<std::string>(StringView str);
146[[nodiscard]]
const char* convertFromString<
const char*>(StringView str);
176[[nodiscard]]
double convertFromString<
double>(
StringView str);
192[[nodiscard]] std::vector<std::string>
216[[nodiscard]]
inline StringConverter GetAnyFromStringFunctor()
218 if constexpr(std::is_constructible_v<StringView, T>)
220 return [](StringView str) {
return Any(str); };
222 else if constexpr(std::is_same_v<BT::AnyTypeAllowed, T> || std::is_enum_v<T>)
228 return [](StringView str) {
return Any(convertFromString<T>(str)); };
233[[nodiscard]]
inline StringConverter GetAnyFromStringFunctor<
void>()
241constexpr bool IsConvertibleToString()
243 return std::is_convertible_v<T, std::string> ||
244 std::is_convertible_v<T, std::string_view>;
247Expected<std::string> toJsonString(
const Any& value);
250
251
252
253
254
256[[nodiscard]] std::string
toStr(
const T& value)
258 if constexpr(IsConvertibleToString<T>())
260 return static_cast<std::string>(value);
262 else if constexpr(!std::is_arithmetic_v<T>)
264 if(
auto str = toJsonString(Any(value)))
269 throw LogicError(StrCat(
"Function BT::toStr<T>() not specialized for type [",
270 BT::demangle(
typeid(T)),
"]"));
274 return std::to_string(value);
279[[nodiscard]] std::string toStr<
bool>(
const bool& value);
282[[nodiscard]] std::string toStr<std::string>(
const std::string& value);
285[[nodiscard]] std::string toStr<BT::NodeStatus>(
const BT::
NodeStatus& status);
288
289
292std::ostream& operator<<(std::ostream& os,
const BT::
NodeStatus& status);
295[[nodiscard]] std::string toStr<BT::NodeType>(
const BT::
NodeType& type);
297std::ostream& operator<<(std::ostream& os,
const BT::
NodeType& type);
300[[nodiscard]] std::string toStr<BT::PortDirection>(
const BT::PortDirection& direction);
302std::ostream& operator<<(std::ostream& os,
const BT::PortDirection& type);
305[[
nodiscard]] std::vector<StringView> splitString(
const StringView& strToSplit,
314#ifdef USE_BTCPP3_OLD_NAMES
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
347[[
nodiscard]]
bool IsAllowedPortName(StringView str);
349[[
nodiscard]]
bool IsReservedAttribute(StringView str);
359 template <
typename T>
362 return TypeInfo{
typeid(T), GetAnyFromStringFunctor<T>() };
365 TypeInfo() : type_info_(
typeid(
AnyTypeAllowed)), type_str_(
"AnyTypeAllowed")
368 TypeInfo(std::type_index type_info, StringConverter conv)
369 : type_info_(type_info), converter_(conv), type_str_(
BT::demangle(type_info))
372 [[
nodiscard]]
const std::type_index& type()
const;
374 [[
nodiscard]]
const std::string& typeName()
const;
378 [[
nodiscard]]
Any parseString(
const std::string& str)
const;
380 template <
typename T>
381 [[nodiscard]]
Any parseString(
const T&)
const
387 [[
nodiscard]]
bool isStronglyTyped()
const
392 [[
nodiscard]]
const StringConverter& converter()
const
398 std::type_index type_info_;
399 StringConverter converter_;
400 std::string type_str_;
406 PortInfo(PortDirection direction = PortDirection::INOUT)
410 PortInfo(PortDirection direction, std::type_index type_info, StringConverter conv)
411 : TypeInfo(type_info, conv), direction_(direction)
414 [[
nodiscard]] PortDirection direction()
const;
416 void setDescription(StringView description);
418 template <
typename T>
419 void setDefaultValue(
const T& default_value)
421 default_value_ =
Any(default_value);
424 default_value_str_ =
BT::toStr(default_value);
433 [[
nodiscard]]
const std::string& description()
const;
437 [[
nodiscard]]
const std::string& defaultValueString()
const;
440 PortDirection direction_;
441 std::string description_;
443 std::string default_value_str_;
447[[nodiscard]] std::pair<std::string,
PortInfo> CreatePort(PortDirection direction,
449 StringView description = {})
451 auto sname =
static_cast<std::string>(name);
452 if(!IsAllowedPortName(sname))
454 throw RuntimeError(
"The name of a port must not be `name` or `ID` "
455 "and must start with an alphabetic character. "
456 "Underscore is reserved.");
459 std::pair<std::string,
PortInfo> out;
461 if(std::is_same<T,
void>::value)
463 out = { sname, PortInfo(direction) };
467 out = { sname, PortInfo(direction,
typeid(T), GetAnyFromStringFunctor<T>()) };
469 if(!description.empty())
471 out.second.setDescription(description);
478
479
480
481
483[[nodiscard]]
inline std::pair<std::string,
PortInfo>
484InputPort(StringView name, StringView description = {})
486 return CreatePort<T>(PortDirection::INPUT, name, description);
490
491
492
493
495[[nodiscard]]
inline std::pair<std::string,
PortInfo>
496OutputPort(StringView name, StringView description = {})
498 return CreatePort<T>(PortDirection::OUTPUT, name, description);
502
503
504
505
507[[nodiscard]]
inline std::pair<std::string,
PortInfo>
510 return CreatePort<T>(PortDirection::INOUT, name, description);
518[[nodiscard]]
inline std::pair<std::string,
PortInfo>
519PortWithDefault(PortDirection direction, StringView name,
const DefaultT& default_value,
520 StringView description)
522 static_assert(IsConvertibleToString<DefaultT>() || std::is_convertible_v<T, DefaultT> ||
523 std::is_constructible_v<T, DefaultT>,
524 "The default value must be either the same of the port or string");
526 auto out = CreatePort<T>(direction, name, description);
528 if constexpr(std::is_constructible_v<T, DefaultT>)
530 out.second.setDefaultValue(T(default_value));
532 else if constexpr(IsConvertibleToString<DefaultT>())
534 out.second.setDefaultValue(std::string(default_value));
538 out.second.setDefaultValue(default_value);
546
547
548
549
550
551
553[[nodiscard]]
inline std::pair<std::string,
PortInfo>
554InputPort(StringView name,
const DefaultT& default_value, StringView description)
556 return details::PortWithDefault<T, DefaultT>(PortDirection::INPUT, name, default_value,
561
562
563
564
565
566
568[[nodiscard]]
inline std::pair<std::string,
PortInfo>
569BidirectionalPort(StringView name,
const DefaultT& default_value, StringView description)
571 return details::PortWithDefault<T, DefaultT>(PortDirection::INOUT, name, default_value,
576
577
578
579
580
581
584 StringView default_value,
585 StringView description)
587 if(default_value.empty() || default_value.front() !=
'{' || default_value.back() !=
'}')
589 throw LogicError(
"Output port can only refer to blackboard entries, i.e. use the "
590 "syntax '{port_name}'");
592 auto out = CreatePort<T>(PortDirection::OUTPUT, name, description);
593 out.second.setDefaultValue(default_value);
601template <
typename T,
typename =
void>
614template <
typename T,
typename =
void>
628[[nodiscard]]
inline PortsList
629getProvidedPorts(enable_if<has_static_method_providedPorts<T>> =
nullptr)
631 return T::providedPorts();
635[[nodiscard]]
inline PortsList
636getProvidedPorts(enable_if_not<has_static_method_providedPorts<T>> =
nullptr)
641using TimePoint = std::chrono::high_resolution_clock::time_point;
642using Duration = std::chrono::high_resolution_clock::duration;
Definition: safe_any.hpp:50
Definition: exceptions.h:48
Definition: basic_types.h:404
Definition: basic_types.h:357
The SwitchNode is equivalent to a switch statement, where a certain branch (child) is executed accord...
Definition: basic_types.h:515
Definition: action_node.h:24
std::pair< std::string, PortInfo > BidirectionalPort(StringView name, StringView description={})
Definition: basic_types.h:508
NodeStatus
Definition: basic_types.h:34
Any convertFromJSON(StringView json_text, std::type_index type)
convertFromJSON will parse a json string and use JsonExporter to convert its content to a given type....
char findForbiddenChar(StringView name)
std::pair< std::string, PortInfo > OutputPort(StringView name, StringView default_value, StringView description)
Definition: basic_types.h:583
std::string toStr(BT::NodeStatus status, bool colored)
toStr converts NodeStatus to string. Optionally colored.
T convertFromJSON(StringView str)
Same as the non template version, but with automatic casting.
Definition: basic_types.h:104
NodeType
Enumerates the possible types of nodes.
Definition: basic_types.h:21
std::pair< std::string, PortInfo > InputPort(StringView name, const DefaultT &default_value, StringView description)
Definition: basic_types.h:554
std::pair< std::string, PortInfo > OutputPort(StringView name, StringView description={})
Definition: basic_types.h:496
std::pair< std::string, PortInfo > InputPort(StringView name, StringView description={})
Definition: basic_types.h:484
std::pair< std::string, PortInfo > BidirectionalPort(StringView name, const DefaultT &default_value, StringView description)
Definition: basic_types.h:569
std::string toStr(const T &value)
toStr is the reverse operation of convertFromString.
Definition: basic_types.h:256
T convertFromString(StringView str)
Definition: basic_types.h:122
Definition: basic_types.h:88
Definition: basic_types.h:340
Definition: basic_types.h:603