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);
379 template <
typename T>
382 return TypeInfo{
typeid(T), GetAnyFromStringFunctor<T>() };
385 TypeInfo() : type_info_(
typeid(
AnyTypeAllowed)), type_str_(
"AnyTypeAllowed")
388 TypeInfo(std::type_index type_info, StringConverter conv)
389 : type_info_(type_info), converter_(conv), type_str_(
BT::demangle(type_info))
392 [[
nodiscard]]
const std::type_index& type()
const;
394 [[
nodiscard]]
const std::string& typeName()
const;
398 [[
nodiscard]]
Any parseString(
const std::string& str)
const;
400 template <
typename T>
401 [[nodiscard]]
Any parseString(
const T&)
const
407 [[
nodiscard]]
bool isStronglyTyped()
const
412 [[
nodiscard]]
const StringConverter& converter()
const
418 std::type_index type_info_;
419 StringConverter converter_;
420 std::string type_str_;
426 PortInfo(PortDirection direction = PortDirection::INOUT)
430 PortInfo(PortDirection direction, std::type_index type_info, StringConverter conv)
431 : TypeInfo(type_info, conv), direction_(direction)
434 [[
nodiscard]] PortDirection direction()
const;
436 void setDescription(StringView description);
438 template <
typename T>
439 void setDefaultValue(
const T& default_value)
441 default_value_ =
Any(default_value);
444 default_value_str_ =
BT::toStr(default_value);
453 [[
nodiscard]]
const std::string& description()
const;
457 [[
nodiscard]]
const std::string& defaultValueString()
const;
460 PortDirection direction_;
461 std::string description_;
463 std::string default_value_str_;
467[[nodiscard]] std::pair<std::string,
PortInfo> CreatePort(PortDirection direction,
469 StringView description = {})
471 auto sname =
static_cast<std::string>(name);
472 if(!IsAllowedPortName(sname))
474 if(
const char c = findForbiddenChar(sname); c !=
'\0')
476 throw RuntimeError(
"Port name '", sname,
"' contains forbidden character ",
477 formatForbiddenChar(c));
479 throw RuntimeError(
"The name of a port must not be `name` or `ID` "
480 "and must start with an alphabetic character. "
481 "Underscore is reserved.");
484 std::pair<std::string,
PortInfo> out;
486 if(std::is_same<T,
void>::value)
488 out = { sname, PortInfo(direction) };
492 out = { sname, PortInfo(direction,
typeid(T), GetAnyFromStringFunctor<T>()) };
494 if(!description.empty())
496 out.second.setDescription(description);
503
504
505
506
508[[nodiscard]]
inline std::pair<std::string,
PortInfo>
509InputPort(StringView name, StringView description = {})
511 return CreatePort<T>(PortDirection::INPUT, name, description);
515
516
517
518
520[[nodiscard]]
inline std::pair<std::string,
PortInfo>
521OutputPort(StringView name, StringView description = {})
523 return CreatePort<T>(PortDirection::OUTPUT, name, description);
527
528
529
530
532[[nodiscard]]
inline std::pair<std::string,
PortInfo>
535 return CreatePort<T>(PortDirection::INOUT, name, description);
543[[nodiscard]]
inline std::pair<std::string,
PortInfo>
544PortWithDefault(PortDirection direction, StringView name,
const DefaultT& default_value,
545 StringView description)
547 static_assert(IsConvertibleToString<DefaultT>() || std::is_convertible_v<T, DefaultT> ||
548 std::is_constructible_v<T, DefaultT>,
549 "The default value must be either the same of the port or string");
551 auto out = CreatePort<T>(direction, name, description);
553 if constexpr(std::is_constructible_v<T, DefaultT>)
555 out.second.setDefaultValue(T(default_value));
557 else if constexpr(IsConvertibleToString<DefaultT>())
559 out.second.setDefaultValue(std::string(default_value));
563 out.second.setDefaultValue(default_value);
571
572
573
574
575
576
578[[nodiscard]]
inline std::pair<std::string,
PortInfo>
579InputPort(StringView name,
const DefaultT& default_value, StringView description)
581 return details::PortWithDefault<T, DefaultT>(PortDirection::INPUT, name, default_value,
586
587
588
589
590
591
593[[nodiscard]]
inline std::pair<std::string,
PortInfo>
594BidirectionalPort(StringView name,
const DefaultT& default_value, StringView description)
596 return details::PortWithDefault<T, DefaultT>(PortDirection::INOUT, name, default_value,
601
602
603
604
605
606
609 StringView default_value,
610 StringView description)
612 if(default_value.empty() || default_value.front() !=
'{' || default_value.back() !=
'}')
614 throw LogicError(
"Output port can only refer to blackboard entries, i.e. use the "
615 "syntax '{port_name}'");
617 auto out = CreatePort<T>(PortDirection::OUTPUT, name, description);
618 out.second.setDefaultValue(default_value);
626template <
typename T,
typename =
void>
639template <
typename T,
typename =
void>
653[[nodiscard]]
inline PortsList
654getProvidedPorts(enable_if<has_static_method_providedPorts<T>> =
nullptr)
656 return T::providedPorts();
660[[nodiscard]]
inline PortsList
661getProvidedPorts(enable_if_not<has_static_method_providedPorts<T>> =
nullptr)
666using TimePoint = std::chrono::high_resolution_clock::time_point;
667using Duration = std::chrono::high_resolution_clock::duration;
Definition: safe_any.hpp:57
Definition: exceptions.h:48
Definition: basic_types.h:424
Definition: basic_types.h:377
The SwitchNode is equivalent to a switch statement, where a certain branch (child) is executed accord...
Definition: basic_types.h:540
Definition: action_node.h:24
std::pair< std::string, PortInfo > BidirectionalPort(StringView name, StringView description={})
Definition: basic_types.h:533
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:608
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:579
std::pair< std::string, PortInfo > OutputPort(StringView name, StringView description={})
Definition: basic_types.h:521
std::string formatForbiddenChar(char c)
Describes a character returned by findForbiddenChar() for an error message.
std::pair< std::string, PortInfo > InputPort(StringView name, StringView description={})
Definition: basic_types.h:509
std::pair< std::string, PortInfo > BidirectionalPort(StringView name, const DefaultT &default_value, StringView description)
Definition: basic_types.h:594
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:628