@@ -107,6 +107,111 @@ TEST(PreconditionsDecorator, StringEquals)
107
107
ASSERT_EQ (counters[1 ], 1 );
108
108
}
109
109
110
+ class KeepRunning : public BT ::StatefulActionNode
111
+ {
112
+ public:
113
+ KeepRunning (const std::string& name, const BT::NodeConfig& config)
114
+ : BT::StatefulActionNode(name, config)
115
+ {}
116
+
117
+ static BT::PortsList providedPorts ()
118
+ {
119
+ return {};
120
+ }
121
+
122
+ BT::NodeStatus onStart () override
123
+ {
124
+ return BT::NodeStatus::RUNNING;
125
+ }
126
+
127
+ BT::NodeStatus onRunning () override
128
+ {
129
+ return BT::NodeStatus::RUNNING;
130
+ }
131
+
132
+ void onHalted () override
133
+ {
134
+ std::cout << " Node halted\n " ;
135
+ }
136
+ };
137
+
138
+ TEST (PreconditionsDecorator, ChecksConditionOnce)
139
+ {
140
+ BehaviorTreeFactory factory;
141
+ factory.registerNodeType <KeepRunning>(" KeepRunning" );
142
+
143
+ const std::string xml_text = R"(
144
+
145
+ <root BTCPP_format="4" >
146
+ <BehaviorTree ID="MainTree">
147
+ <Sequence>
148
+ <Script code = "A:=0" />
149
+ <Script code = "B:=0" />
150
+ <Precondition if=" A==0 " else="FAILURE">
151
+ <KeepRunning _while="B==0" />
152
+ </Precondition>
153
+ </Sequence>
154
+ </BehaviorTree>
155
+ </root>)" ;
156
+
157
+ auto tree = factory.createTreeFromText (xml_text);
158
+
159
+ EXPECT_EQ (tree.tickOnce (), NodeStatus::RUNNING);
160
+ // While the child is still running, attempt to fail the precondition.
161
+ tree.rootBlackboard ()->set (" A" , 1 );
162
+ EXPECT_EQ (tree.tickOnce (), NodeStatus::RUNNING);
163
+ // Finish running the tree, the else condition should not be hit.
164
+ tree.rootBlackboard ()->set (" B" , 1 );
165
+ EXPECT_EQ (tree.tickOnce (), NodeStatus::SUCCESS);
166
+ }
167
+
168
+ TEST (PreconditionsDecorator, CanRunChildrenMultipleTimes)
169
+ {
170
+ BehaviorTreeFactory factory;
171
+ factory.registerNodeType <KeepRunning>(" KeepRunning" );
172
+ std::array<int , 1 > counters;
173
+ RegisterTestTick (factory, " Test" , counters);
174
+
175
+ const std::string xml_text = R"(
176
+
177
+ <root BTCPP_format="4" >
178
+ <BehaviorTree ID="MainTree">
179
+ <Sequence>
180
+ <Script code = "A:=0" />
181
+ <Script code = "B:=0" />
182
+ <Script code = "C:=1" />
183
+ <Repeat num_cycles="3">
184
+ <Sequence>
185
+ <Precondition if=" A==0 " else="SUCCESS">
186
+ <TestA/>
187
+ </Precondition>
188
+ <KeepRunning _while="C==0" />
189
+ <KeepRunning _while="B==0" />
190
+ </Sequence>
191
+ </Repeat>
192
+ </Sequence>
193
+ </BehaviorTree>
194
+ </root>)" ;
195
+
196
+ auto tree = factory.createTreeFromText (xml_text);
197
+
198
+ EXPECT_EQ (tree.tickOnce (), NodeStatus::RUNNING);
199
+ EXPECT_EQ (counters[0 ], 1 ); // Precondition hit once;
200
+
201
+ // In the second repeat, fail the precondition
202
+ tree.rootBlackboard ()->set (" A" , 1 );
203
+ tree.rootBlackboard ()->set (" B" , 1 );
204
+ tree.rootBlackboard ()->set (" C" , 0 );
205
+ EXPECT_EQ (tree.tickOnce (), NodeStatus::RUNNING);
206
+ EXPECT_EQ (counters[0 ], 1 ); // Precondition still only hit once.
207
+
208
+ // Finally in the last repeat, hit the condition again.
209
+ tree.rootBlackboard ()->set (" A" , 0 );
210
+ tree.rootBlackboard ()->set (" C" , 1 );
211
+ EXPECT_EQ (tree.tickOnce (), NodeStatus::SUCCESS);
212
+ EXPECT_EQ (counters[0 ], 2 ); // Precondition hit twice now.
213
+ }
214
+
110
215
TEST (Preconditions, Basic)
111
216
{
112
217
BehaviorTreeFactory factory;
@@ -246,34 +351,6 @@ TEST(Preconditions, Issue615_NoSkipWhenRunning_A)
246
351
ASSERT_EQ (tree.tickOnce (), NodeStatus::RUNNING);
247
352
}
248
353
249
- class KeepRunning : public BT ::StatefulActionNode
250
- {
251
- public:
252
- KeepRunning (const std::string& name, const BT::NodeConfig& config)
253
- : BT::StatefulActionNode(name, config)
254
- {}
255
-
256
- static BT::PortsList providedPorts ()
257
- {
258
- return {};
259
- }
260
-
261
- BT::NodeStatus onStart () override
262
- {
263
- return BT::NodeStatus::RUNNING;
264
- }
265
-
266
- BT::NodeStatus onRunning () override
267
- {
268
- return BT::NodeStatus::RUNNING;
269
- }
270
-
271
- void onHalted () override
272
- {
273
- std::cout << " Node halted\n " ;
274
- }
275
- };
276
-
277
354
TEST (Preconditions, Issue615_NoSkipWhenRunning_B)
278
355
{
279
356
static constexpr auto xml_text = R"(
0 commit comments