Skip to content

Commit 0cef2e2

Browse files
committed
fix issue BehaviorTree#451 and BehaviorTree#450. Optional renamed Expected
1 parent 90c2f47 commit 0cef2e2

File tree

7 files changed

+75
-27
lines changed

7 files changed

+75
-27
lines changed

examples/t03_generic_ports.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ static const char* xml_text = R"(
108108
<Sequence name="root">
109109
<CalculateGoal goal="{GoalPosition}" />
110110
<PrintTarget target="{GoalPosition}" />
111-
<SetBlackboard output_key="OtherGoal" value="-1;3" />
111+
<Script code="OtherGoal='-1;3'" />
112112
<PrintTarget target="{OtherGoal}" />
113113
</Sequence>
114114
</BehaviorTree>

include/behaviortree_cpp/basic_types.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <chrono>
1212
#include <memory>
1313
#include <string_view>
14+
#include <variant>
1415

1516
#include "behaviortree_cpp/utils/safe_any.hpp"
1617
#include "behaviortree_cpp/exceptions.h"
@@ -183,9 +184,9 @@ using enable_if = typename std::enable_if<Predicate::value>::type*;
183184
template <typename Predicate>
184185
using enable_if_not = typename std::enable_if<!Predicate::value>::type*;
185186

186-
/** Usage: given a function/method like:
187+
/** Usage: given a function/method like this:
187188
*
188-
* Optional<double> getAnswer();
189+
* Expected<double> getAnswer();
189190
*
190191
* User code can check result and error message like this:
191192
*
@@ -200,7 +201,11 @@ using enable_if_not = typename std::enable_if<!Predicate::value>::type*;
200201
*
201202
* */
202203
template <typename T>
204+
#ifdef USE_BTCPP3_OLD_NAMES
203205
using Optional = nonstd::expected<T, std::string>;
206+
#else
207+
using Expected = nonstd::expected<T, std::string>;
208+
#endif
204209
// note: we use the name Optional instead of expected because it is more intuitive
205210
// for users that are not up to date with "modern" C++
206211

@@ -220,7 +225,7 @@ using Optional = nonstd::expected<T, std::string>;
220225
* }
221226
*
222227
* */
223-
using Result = Optional<void>;
228+
using Result = Expected<std::monostate>;
224229

225230
bool IsAllowedPortName(StringView str);
226231

include/behaviortree_cpp/scripting/operators.hpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <utility>
2222

2323
#include "behaviortree_cpp/scripting/any_types.hpp"
24-
#include "behaviortree_cpp/blackboard.h"
24+
#include "behaviortree_cpp/scripting/script_parser.hpp"
2525

2626
// Naive implementation of an AST with simple evaluation function.
2727
namespace BT::Ast
@@ -30,13 +30,6 @@ using SimpleString = SafeAny::SimpleString;
3030

3131
using expr_ptr = std::shared_ptr<struct ExprBase>;
3232

33-
using EnumsTablePtr = std::shared_ptr<std::unordered_map<std::string, int>>;
34-
35-
struct Environment{
36-
BT::Blackboard::Ptr vars;
37-
EnumsTablePtr enums;
38-
};
39-
4033
struct ExprBase
4134
{
4235
using Ptr = std::shared_ptr<ExprBase>;

include/behaviortree_cpp/scripting/script_parser.hpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,39 @@
1212

1313
#pragma once
1414

15-
#include "behaviortree_cpp/scripting/operators.hpp"
15+
#include "behaviortree_cpp/blackboard.h"
1616

1717
namespace BT
1818
{
1919

20-
std::string ValidateScript(const std::string& script);
20+
/// Simple map (string->nt), used to convert enums in the
21+
/// scripting language
22+
using EnumsTable = std::unordered_map<std::string, int>;
23+
using EnumsTablePtr = std::shared_ptr<EnumsTable>;
24+
25+
namespace Ast
26+
{
27+
/**
28+
* @brief The Environment class is used to encapsulate
29+
* the information and states neded by the sriting language
30+
*/
31+
struct Environment{
32+
BT::Blackboard::Ptr vars;
33+
EnumsTablePtr enums;
34+
};
35+
}
36+
37+
/**
38+
* @brief ValidateScript will check if a certain string is valid.
39+
*/
40+
Result ValidateScript(const std::string& script);
2141

2242
using ScriptFunction = std::function<Any(Ast::Environment& env)>;
2343

24-
Optional<ScriptFunction> ParseScript(const std::string& script);
44+
Expected<ScriptFunction> ParseScript(const std::string& script);
2545

26-
Optional<Any> ParseScriptAndExecute(Ast::Environment& env, const std::string& script);
46+
Expected<Any> ParseScriptAndExecute(Ast::Environment& env,
47+
const std::string& script);
2748

2849
}
2950

include/behaviortree_cpp/tree_node.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@ class TreeNode
138138
using StatusChangeCallback = StatusChangeSignal::CallableFunction;
139139

140140
using PreTickOverrideCallback =
141-
std::function<Optional<NodeStatus>(TreeNode&, NodeStatus)>;
141+
std::function<Expected<NodeStatus>(TreeNode&, NodeStatus)>;
142142
using PostTickOverrideCallback =
143-
std::function<Optional<NodeStatus>(TreeNode&, NodeStatus, NodeStatus)>;
143+
std::function<Expected<NodeStatus>(TreeNode&, NodeStatus, NodeStatus)>;
144144

145145
/**
146146
* @brief subscribeToStatusChange is used to attach a callback to a status change.
@@ -198,11 +198,11 @@ class TreeNode
198198
* but using optional.
199199
*/
200200
template <typename T>
201-
Optional<T> getInput(const std::string& key) const
201+
Expected<T> getInput(const std::string& key) const
202202
{
203203
T out;
204204
auto res = getInput(key, out);
205-
return (res) ? Optional<T>(out) : nonstd::make_unexpected(res.error());
205+
return (res) ? Expected<T>(out) : nonstd::make_unexpected(res.error());
206206
}
207207

208208
template <typename T>
@@ -218,7 +218,7 @@ class TreeNode
218218

219219
static StringView stripBlackboardPointer(StringView str);
220220

221-
static Optional<StringView> getRemappedKey(StringView port_name,
221+
static Expected<StringView> getRemappedKey(StringView port_name,
222222
StringView remapped_port);
223223

224224
/// Notify that the tree should be ticked again()
@@ -304,7 +304,7 @@ class TreeNode
304304

305305
std::shared_ptr<ScriptingEnumsRegistry> scripting_enums_;
306306

307-
Optional<NodeStatus> checkPreConditions();
307+
Expected<NodeStatus> checkPreConditions();
308308
void checkPostConditions(NodeStatus status);
309309

310310
/// The method used to interrupt the execution of a RUNNING node.

src/script_parser.cpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88

99
namespace BT
1010
{
11-
Optional<ScriptFunction> ParseScript(const std::string& script)
11+
12+
using ErrorReport = lexy_ext::_report_error<char*>;
13+
14+
Expected<ScriptFunction> ParseScript(const std::string& script)
1215
{
13-
using ErrorReport = lexy_ext::_report_error<char*>;
1416
char error_msgs_buffer[2048];
1517

1618
auto input = lexy::string_input<lexy::utf8_encoding>(script);
@@ -45,7 +47,7 @@ Optional<ScriptFunction> ParseScript(const std::string& script)
4547
}
4648
}
4749

48-
BT::Optional<Any> ParseScriptAndExecute(Ast::Environment& env, const std::string& script)
50+
BT::Expected<Any> ParseScriptAndExecute(Ast::Environment& env, const std::string& script)
4951
{
5052
auto executor = ParseScript(script);
5153
if (executor)
@@ -58,4 +60,31 @@ BT::Optional<Any> ParseScriptAndExecute(Ast::Environment& env, const std::string
5860
}
5961
}
6062

63+
Result ValidateScript(const std::string &script)
64+
{
65+
char error_msgs_buffer[2048];
66+
67+
auto input = lexy::string_input<lexy::utf8_encoding>(script);
68+
auto result =
69+
lexy::parse<BT::Grammar::stmt>(input, ErrorReport().to(error_msgs_buffer));
70+
if (result.has_value() && result.error_count() == 0)
71+
{
72+
try
73+
{
74+
std::vector<BT::Ast::ExprBase::Ptr> exprs = LEXY_MOV(result).value();
75+
if (exprs.empty())
76+
{
77+
return nonstd::make_unexpected("Empty Script");
78+
}
79+
// valid script
80+
return {};
81+
}
82+
catch (std::runtime_error& err)
83+
{
84+
return nonstd::make_unexpected(err.what());
85+
}
86+
}
87+
return nonstd::make_unexpected(error_msgs_buffer);
88+
}
89+
6190
} // namespace BT

src/tree_node.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ void TreeNode::setStatus(NodeStatus new_status)
9898
}
9999
}
100100

101-
Optional<NodeStatus> TreeNode::checkPreConditions()
101+
Expected<NodeStatus> TreeNode::checkPreConditions()
102102
{
103103
// check the pre-conditions
104104
for (size_t index = 0; index < size_t(PreCond::COUNT_); index++)
@@ -269,7 +269,7 @@ StringView TreeNode::stripBlackboardPointer(StringView str)
269269
return {};
270270
}
271271

272-
Optional<StringView> TreeNode::getRemappedKey(StringView port_name,
272+
Expected<StringView> TreeNode::getRemappedKey(StringView port_name,
273273
StringView remapped_port)
274274
{
275275
if (remapped_port == "=")

0 commit comments

Comments
 (0)