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);
179
180
181
182
183
184
185
186
187
188
189
190
191
193 bool require_full_consumption);
209[[nodiscard]] std::vector<std::string>
233[[nodiscard]]
inline StringConverter GetAnyFromStringFunctor()
235 if constexpr(std::is_constructible_v<StringView, T>)
237 return [](StringView str) {
return Any(str); };
239 else if constexpr(std::is_same_v<BT::AnyTypeAllowed, T> || std::is_enum_v<T>)
245 return [](StringView str) {
return Any(convertFromString<T>(str)); };
250[[nodiscard]]
inline StringConverter GetAnyFromStringFunctor<
void>()
258constexpr bool IsConvertibleToString()
260 return std::is_convertible_v<T, std::string> ||
261 std::is_convertible_v<T, std::string_view>;
264Expected<std::string> toJsonString(
const Any& value);
267
268
269
270
271
273[[nodiscard]] std::string
toStr(
const T& value)
275 if constexpr(IsConvertibleToString<T>())
277 return static_cast<std::string>(value);
279 else if constexpr(!std::is_arithmetic_v<T>)
281 if(
auto str = toJsonString(Any(value)))
286 throw LogicError(StrCat(
"Function BT::toStr<T>() not specialized for type [",
287 BT::demangle(
typeid(T)),
"]"));
291 return std::to_string(value);
296[[nodiscard]] std::string toStr<
bool>(
const bool& value);
299[[nodiscard]] std::string toStr<std::string>(
const std::string& value);
302[[nodiscard]] std::string toStr<BT::NodeStatus>(
const BT::
NodeStatus& status);
305
306
309std::ostream& operator<<(std::ostream& os,
const BT::
NodeStatus& status);
312[[nodiscard]] std::string toStr<BT::NodeType>(
const BT::
NodeType& type);
314std::ostream& operator<<(std::ostream& os,
const BT::
NodeType& type);
317[[nodiscard]] std::string toStr<BT::PortDirection>(
const BT::PortDirection& direction);
319std::ostream& operator<<(std::ostream& os,
const BT::PortDirection& type);
322[[
nodiscard]] std::vector<StringView> splitString(
const StringView& strToSplit,
331#ifdef USE_BTCPP3_OLD_NAMES
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
364[[
nodiscard]]
bool IsAllowedPortName(StringView str);
366[[
nodiscard]]
bool IsReservedAttribute(StringView str);
376 template <
typename T>
379 return TypeInfo{
typeid(T), GetAnyFromStringFunctor<T>() };
382 TypeInfo() : type_info_(
typeid(
AnyTypeAllowed)), type_str_(
"AnyTypeAllowed")
385 TypeInfo(std::type_index type_info, StringConverter conv)
386 : type_info_(type_info), converter_(conv), type_str_(
BT::demangle(type_info))
389 [[
nodiscard]]
const std::type_index& type()
const;
391 [[
nodiscard]]
const std::string& typeName()
const;
395 [[
nodiscard]]
Any parseString(
const std::string& str)
const;
397 template <
typename T>
398 [[nodiscard]]
Any parseString(
const T&)
const
404 [[
nodiscard]]
bool isStronglyTyped()
const
409 [[
nodiscard]]
const StringConverter& converter()
const
415 std::type_index type_info_;
416 StringConverter converter_;
417 std::string type_str_;
423 PortInfo(PortDirection direction = PortDirection::INOUT)
427 PortInfo(PortDirection direction, std::type_index type_info, StringConverter conv)
428 : TypeInfo(type_info, conv), direction_(direction)
431 [[
nodiscard]] PortDirection direction()
const;
433 void setDescription(StringView description);
435 template <
typename T>
436 void setDefaultValue(
const T& default_value)
438 default_value_ =
Any(default_value);
441 default_value_str_ =
BT::toStr(default_value);
450 [[
nodiscard]]
const std::string& description()
const;
454 [[
nodiscard]]
const std::string& defaultValueString()
const;
457 PortDirection direction_;
458 std::string description_;
460 std::string default_value_str_;
464[[nodiscard]] std::pair<std::string,
PortInfo> CreatePort(PortDirection direction,
466 StringView description = {})
468 auto sname =
static_cast<std::string>(name);
469 if(!IsAllowedPortName(sname))
471 throw RuntimeError(
"The name of a port must not be `name` or `ID` "
472 "and must start with an alphabetic character. "
473 "Underscore is reserved.");
476 std::pair<std::string,
PortInfo> out;
478 if(std::is_same<T,
void>::value)
480 out = { sname, PortInfo(direction) };
484 out = { sname, PortInfo(direction,
typeid(T), GetAnyFromStringFunctor<T>()) };
486 if(!description.empty())
488 out.second.setDescription(description);
495
496
497
498
500[[nodiscard]]
inline std::pair<std::string,
PortInfo>
501InputPort(StringView name, StringView description = {})
503 return CreatePort<T>(PortDirection::INPUT, name, description);
507
508
509
510
512[[nodiscard]]
inline std::pair<std::string,
PortInfo>
513OutputPort(StringView name, StringView description = {})
515 return CreatePort<T>(PortDirection::OUTPUT, name, description);
519
520
521
522
524[[nodiscard]]
inline std::pair<std::string,
PortInfo>
527 return CreatePort<T>(PortDirection::INOUT, name, description);
535[[nodiscard]]
inline std::pair<std::string,
PortInfo>
536PortWithDefault(PortDirection direction, StringView name,
const DefaultT& default_value,
537 StringView description)
539 static_assert(IsConvertibleToString<DefaultT>() || std::is_convertible_v<T, DefaultT> ||
540 std::is_constructible_v<T, DefaultT>,
541 "The default value must be either the same of the port or string");
543 auto out = CreatePort<T>(direction, name, description);
545 if constexpr(std::is_constructible_v<T, DefaultT>)
547 out.second.setDefaultValue(T(default_value));
549 else if constexpr(IsConvertibleToString<DefaultT>())
551 out.second.setDefaultValue(std::string(default_value));
555 out.second.setDefaultValue(default_value);
563
564
565
566
567
568
570[[nodiscard]]
inline std::pair<std::string,
PortInfo>
571InputPort(StringView name,
const DefaultT& default_value, StringView description)
573 return details::PortWithDefault<T, DefaultT>(PortDirection::INPUT, name, default_value,
578
579
580
581
582
583
585[[nodiscard]]
inline std::pair<std::string,
PortInfo>
586BidirectionalPort(StringView name,
const DefaultT& default_value, StringView description)
588 return details::PortWithDefault<T, DefaultT>(PortDirection::INOUT, name, default_value,
593
594
595
596
597
598
601 StringView default_value,
602 StringView description)
604 if(default_value.empty() || default_value.front() !=
'{' || default_value.back() !=
'}')
606 throw LogicError(
"Output port can only refer to blackboard entries, i.e. use the "
607 "syntax '{port_name}'");
609 auto out = CreatePort<T>(PortDirection::OUTPUT, name, description);
610 out.second.setDefaultValue(default_value);
618template <
typename T,
typename =
void>
631template <
typename T,
typename =
void>
645[[nodiscard]]
inline PortsList
646getProvidedPorts(enable_if<has_static_method_providedPorts<T>> =
nullptr)
648 return T::providedPorts();
652[[nodiscard]]
inline PortsList
653getProvidedPorts(enable_if_not<has_static_method_providedPorts<T>> =
nullptr)
658using TimePoint = std::chrono::high_resolution_clock::time_point;
659using Duration = std::chrono::high_resolution_clock::duration;
Definition: safe_any.hpp:50
Definition: exceptions.h:48
Definition: basic_types.h:421
Definition: basic_types.h:374
The SwitchNode is equivalent to a switch statement, where a certain branch (child) is executed accord...
Definition: basic_types.h:532
Definition: action_node.h:24
std::pair< std::string, PortInfo > BidirectionalPort(StringView name, StringView description={})
Definition: basic_types.h:525
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)
bool parseDouble(StringView str, double &out, bool require_full_consumption)
Parse a double from a string using the semantics of std::from_chars(std::chars_format::general): loca...
std::pair< std::string, PortInfo > OutputPort(StringView name, StringView default_value, StringView description)
Definition: basic_types.h:600
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:571
std::pair< std::string, PortInfo > OutputPort(StringView name, StringView description={})
Definition: basic_types.h:513
std::pair< std::string, PortInfo > InputPort(StringView name, StringView description={})
Definition: basic_types.h:501
std::pair< std::string, PortInfo > BidirectionalPort(StringView name, const DefaultT &default_value, StringView description)
Definition: basic_types.h:586
std::string toStr(const T &value)
toStr is the reverse operation of convertFromString.
Definition: basic_types.h:273
T convertFromString(StringView str)
Definition: basic_types.h:122
Definition: basic_types.h:88
Definition: basic_types.h:357
Definition: basic_types.h:620