Botcraft 1.21.4
Loading...
Searching...
No Matches
BehaviourTree.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <vector>
4#include <memory>
5#include <functional>
6#include <string>
7#include <stdexcept>
8
12
13// A behaviour tree implementation following this blog article
14// https://www.gamasutra.com/blogs/ChrisSimpson/20140717/221339/Behavior_trees_for_AI_How_they_work.php
15
16// First version of this code was inspired by
17// https://github.com/arvidsson/BrainTree
18
19namespace Botcraft
20{
21 // Define some templates functions used as update
22 // notifications during node ticking
23 GENERATE_CHECK_HAS_FUNC(OnNodeStartTick);
25 GENERATE_CHECK_HAS_FUNC(OnNodeTickChild);
26
27 template<typename Context>
28 class Node : public BaseNode
29 {
31 public:
32 virtual ~Node() {}
33 Status Tick(Context& context) const
34 {
35 if constexpr (has_OnNodeStartTick<Context, void()>)
36 {
37 context.OnNodeStartTick();
38 }
39
40 const Status result = this->TickImpl(context);
41
42 if constexpr (has_OnNodeEndTick<Context, void(Status)>)
43 {
44 context.OnNodeEndTick(result);
45 }
46
47 return result;
48 }
49
50 protected:
51 virtual Status TickImpl(Context& context) const = 0;
52 };
53
54
55 template<typename Context>
56 class Composite : public Node<Context>
57 {
58 using Node<Context>::Node;
59 public:
60 virtual ~Composite() {}
61
62 void AddChild(const std::shared_ptr<Node<Context>>& child)
63 {
64 children.push_back(child);
65 }
66
67 virtual BehaviourNodeType GetNodeType() const override
68 {
70 }
71
72 virtual size_t GetNumChildren() const override
73 {
74 return children.size();
75 }
76
77 virtual const BaseNode* GetChild(const size_t index) const override
78 {
79 return children[index].get();
80 }
81
82 protected:
83 Status TickChild(Context& context, const size_t index) const
84 {
85 if (index >= children.size())
86 {
87 throw std::runtime_error(std::string("Out of bounds child ticking in ") + this->GetFullDescriptor() + " at index " + std::to_string(index));
88 }
89
90 if (children[index] == nullptr)
91 {
92 throw std::runtime_error(std::string("Nullptr child in ") + this->GetFullDescriptor() + " at index " + std::to_string(index));
93 }
94
95 if constexpr (has_OnNodeTickChild<Context, void(size_t)>)
96 {
97 context.OnNodeTickChild(index);
98 }
99
100 try
101 {
102 return children[index]->Tick(context);
103 }
104 catch (const std::exception& ex)
105 {
106 throw std::runtime_error(std::string("In ") + this->GetFullDescriptor() + " while Ticking child " + std::to_string(index) + "\n" +
107 ex.what());
108 }
109 }
110
111 private:
112 std::vector<std::shared_ptr<Node<Context>>> children;
113 };
114
115 template<typename Context>
116 class Decorator : public Node<Context>
117 {
118 using Node<Context>::Node;
119 public:
120 virtual ~Decorator() {}
121
122 void SetChild(std::shared_ptr<Node<Context>> child_)
123 {
124 child = child_;
125 }
126
127 virtual BehaviourNodeType GetNodeType() const override
128 {
130 }
131
132 virtual size_t GetNumChildren() const override
133 {
134 return child == nullptr ? 0 : 1;
135 }
136
137 virtual const BaseNode* GetChild(const size_t index) const override
138 {
139 return child.get();
140 }
141
142 protected:
143 Status TickChild(Context& context) const
144 {
145 if (child == nullptr)
146 {
147 throw std::runtime_error("Nullptr child in decorator " + this->GetFullDescriptor());
148 }
149
150 if constexpr (has_OnNodeTickChild<Context, void(size_t)>)
151 {
152 context.OnNodeTickChild(0);
153 }
154
155 try
156 {
157 return child->Tick(context);
158 }
159 catch (const std::exception& ex)
160 {
161 throw std::runtime_error(std::string("In ") + this->GetFullDescriptor() + "\n" +
162 ex.what());
163 }
164 }
165
166 private:
167 std::shared_ptr<Node<Context>> child;
168 };
169
170 template<typename Context>
171 class Leaf final : public Node<Context>
172 {
173 public:
174 Leaf() = delete;
175
176 template<typename FuncType>
177 Leaf(const std::string& s, FuncType func_) : Node<Context>(s), func(func_) {}
178
179 template<typename FuncType, typename... Args>
180 Leaf(const std::string& s, FuncType func_, Args&&... args) : Node<Context>(s)
181 {
182 func = [=](Context& c) -> Status { return func_(c, (args)...); };
183 }
184
185 virtual ~Leaf() {}
186
187 virtual BehaviourNodeType GetNodeType() const override
188 {
190 }
191
192 virtual size_t GetNumChildren() const override
193 {
194 return 0;
195 }
196
197 virtual const BaseNode* GetChild(const size_t index) const override
198 {
199 return nullptr;
200 }
201
202 protected:
203 virtual Status TickImpl(Context& context) const override
204 {
205 try
206 {
207 return func(context);
208 }
209 catch (const std::exception& ex)
210 {
211 if (this->name.empty())
212 {
213 throw;
214 }
215 throw std::runtime_error(std::string("In leaf \"") + this->name + "\"\n" +
216 ex.what());
217 }
218 }
219
220 private:
221 std::function<Status(Context&)> func;
222 };
223
224 template<typename Context>
225 class BehaviourTree final : public Node<Context>
226 {
227 using Node<Context>::Node;
228 public:
229 virtual ~BehaviourTree() {}
230
231 void SetRoot(const std::shared_ptr<Node<Context>> node) { root = node; }
232
233 virtual BehaviourNodeType GetNodeType() const override
234 {
236 }
237
238 virtual size_t GetNumChildren() const override
239 {
240 return root == nullptr ? 0 : 1;
241 }
242
243 virtual const BaseNode* GetChild(const size_t index) const override
244 {
245 return root.get();
246 }
247
248 protected:
249 virtual Status TickImpl(Context& context) const override
250 {
251 if (root == nullptr)
252 {
253 throw std::runtime_error(std::string("Nullptr tree when trying to tick tree ") + this->GetFullDescriptor());
254 }
255
256 if constexpr (has_OnNodeTickChild<Context, void(size_t)>)
257 {
258 context.OnNodeTickChild(0);
259 }
260
261 try
262 {
263 return root->Tick(context);
264 }
265 catch (const std::exception& ex)
266 {
267 if (this->name.empty())
268 {
269 throw;
270 }
271 throw std::runtime_error(std::string("In tree \"") + this->name + "\"\n" +
272 ex.what());
273 }
274 }
275
276 private:
277 std::shared_ptr<Node<Context>> root;
278 };
279
280 /// @brief Sequence implementation. Run all children until
281 /// one fails. Succeeds if all children succeed.
282 /// Equivalent to a logical AND.
283 /// @tparam Context The tree context type
284 template<typename Context>
285 class Sequence final : public Composite<Context>
286 {
287 using Composite<Context>::Composite;
288 protected:
289 virtual Status TickImpl(Context& context) const override
290 {
291 for (size_t i = 0; i < this->GetNumChildren(); ++i)
292 {
293 if (this->TickChild(context, i) == Status::Failure)
294 {
295 return Status::Failure;
296 }
297 }
298 // If we are here, all children succeeded
299 return Status::Success;
300 }
301 };
302
303 /// @brief Selector implementation. Run all children until
304 /// one succeeds. Fails if all children fail.
305 /// Equivalent to a logical OR.
306 /// @tparam Context The tree context type
307 template<typename Context>
308 class Selector final : public Composite<Context>
309 {
310 using Composite<Context>::Composite;
311 protected:
312 virtual Status TickImpl(Context& context) const override
313 {
314 for (size_t i = 0; i < this->GetNumChildren(); ++i)
315 {
316 if (this->TickChild(context, i) == Status::Success)
317 {
318 return Status::Success;
319 }
320 }
321
322 // If we are here, all children failed
323 return Status::Failure;
324 }
325 };
326
327
328
329 // Common Decorators implementations
330
331 /// @brief A Decorator that inverts the result of its child.
332 /// @tparam Context The tree context type
333 template<typename Context>
334 class Inverter final : public Decorator<Context>
335 {
336 using Decorator<Context>::Decorator;
337 protected:
338 virtual Status TickImpl(Context& context) const override
339 {
340 return this->TickChild(context) == Status::Failure ? Status::Success : Status::Failure;
341 }
342 };
343
344 /// @brief A Decorator that always return success,
345 /// independently of the result of its child.
346 /// Can be combined with an inverter for Failure.
347 /// @tparam Context The tree context type
348 template<typename Context>
349 class Succeeder final : public Decorator<Context>
350 {
351 using Decorator<Context>::Decorator;
352 protected:
353 virtual Status TickImpl(Context& context) const override
354 {
355 this->TickChild(context);
356 return Status::Success;
357 }
358 };
359
360 /// @brief A Decorator that ticks its child n times
361 /// (repeat until first success if n == 0).
362 /// Always returns success.
363 /// @tparam Context The tree context type
364 template<typename Context>
365 class Repeater final : public Decorator<Context>
366 {
367 public:
368 Repeater(const std::string& s, const size_t n_) : Decorator<Context>(s), n(n_) {}
369
370 protected:
371 virtual Status TickImpl(Context& context) const override
372 {
373 Status child_status = Status::Failure;
374 size_t counter = 0;
375 while ((child_status == Status::Failure && n == 0) || counter < n)
376 {
377 child_status = this->TickChild(context);
378 counter += 1;
379 }
380 return Status::Success;
381 }
382
383 private:
384 size_t n;
385 };
386
387
388
389
390 // Builder implementation for easy tree building
391
392 template<typename Parent, typename Context>
393 class DecoratorBuilder;
394
395 template<typename Context>
396 class Builder;
397
398 template<typename Parent, typename Context>
400 {
401 public:
403
404 /// @brief To add a named leaf
405 /// @tparam S std::string convertible type
406 /// @tparam ...Args leaf function and params
407 /// @tparam Do not use this template if first param is not a string
408 /// @param s Leaf name
409 /// @param ...args leaf function and params
410 /// @return A composite builder to continue building the tree
411 template<
412 typename S,
413 typename... Args,
414 typename = typename std::enable_if_t<std::is_convertible_v<S, std::string>>
415 >
416 CompositeBuilder leaf(const S& s, Args&&... args)
417 {
418 auto child = std::make_shared<Leaf<Context> >(s, std::forward<Args>(args)...);
419 node->AddChild(child);
420 return *this;
421 }
422
423 /// @brief To add an anonymous leaf
424 /// @tparam ...Args
425 /// @param ...args
426 /// @return
427 template<typename... Args>
428 CompositeBuilder leaf(Args&&... args)
429 {
430 auto child = std::make_shared<Leaf<Context> >("", std::forward<Args>(args)...);
431 node->AddChild(child);
432 return *this;
433 }
434
435 // To add a tree
437 {
438 node->AddChild(arg);
439 return *this;
440 }
441
442
443 // Composite
444 // Custom function to add a sequence
446 {
447 auto child = std::make_shared<Sequence<Context>>(s);
448 node->AddChild(child);
450 }
451
452 // Custom function to add a selector
454 {
455 auto child = std::make_shared<Selector<Context>>(s);
456 node->AddChild(child);
458 }
459
460 // To add any other type of composite
461 template<
462 typename CompositeType,
463 typename... Args,
464 typename S,
465 typename = typename std::enable_if_t<std::is_convertible_v<S, std::string>>
466 >
468 {
469 auto child = std::make_shared<CompositeType>(s, std::forward<Args>(args)...);
470 node->AddChild(child);
471 return CompositeBuilder<CompositeBuilder, Context>(this, (CompositeType*)child.get());
472 }
473
474 template<
475 typename CompositeType,
476 typename... Args
477 >
479 {
480 auto child = std::make_shared<CompositeType>("", std::forward<Args>(args)...);
481 node->AddChild(child);
482 return CompositeBuilder<CompositeBuilder, Context>(this, (CompositeType*)child.get());
483 }
484
485 // Decorator
486 // Inverter
488 {
489 auto child = std::make_shared<Inverter<Context>>(s);
490 node->AddChild(child);
492 }
493
494 // Succeeder
496 {
497 auto child = std::make_shared<Succeeder<Context>>(s);
498 node->AddChild(child);
500 }
501
502 // Repeater
504 {
505 auto child = std::make_shared<Repeater<Context>>("", n);
506 node->AddChild(child);
508 }
509
510 // Repeater
511 DecoratorBuilder<CompositeBuilder, Context> repeater(const std::string& s, const size_t n)
512 {
513 auto child = std::make_shared<Repeater<Context>>(s, n);
514 node->AddChild(child);
516 }
517
518 // To add any other type of decorator
519 template<
520 typename DecoratorType,
521 typename... Args,
522 typename S,
523 typename = typename std::enable_if_t<std::is_convertible_v<S, std::string>>
524 >
526 {
527 auto child = std::make_shared<DecoratorType>(s, std::forward<Args>(args)...);
528 node->AddChild(child);
529 return DecoratorBuilder<CompositeBuilder, Context>(this, (DecoratorType*)child.get());
530 }
531 template<
532 typename DecoratorType,
533 typename... Args
534 >
536 {
537 auto child = std::make_shared<DecoratorType>("", std::forward<Args>(args)...);
538 node->AddChild(child);
539 return DecoratorBuilder<CompositeBuilder, Context>(this, (DecoratorType*)child.get());
540 }
541
542 std::conditional_t<
543 std::is_same_v<Parent, Builder<Context>>, // If the parent is a Builder
544 std::shared_ptr<BehaviourTree<Context>>, // Then return the tree as we can't add anything else after the root
545 Parent& // Else return the parent to continue the chain
546 > end()
547 {
548 if constexpr (std::is_same_v<Parent, Builder<Context>>)
549 {
550 return parent->build();
551 }
552 else
553 {
554 return *parent;
555 }
556 }
557
558 private:
559 Parent* parent;
561 };
562
563 template<typename Parent, typename Context>
565 {
566 public:
568
569 // To add a leaf
570 template<
571 typename S,
572 typename... Args,
573 typename = typename std::enable_if_t<std::is_convertible_v<S, std::string>>
574 >
575 std::conditional_t<
576 std::is_same_v<Parent, Builder<Context>>, // If the parent is a Builder
577 std::shared_ptr<BehaviourTree<Context>>, // Then return the tree as we can't add anything else after the root
578 Parent& // Else return the parent to continue the chain
579 > leaf(const S& s, Args&&... args)
580 {
581 auto child = std::make_shared<Leaf<Context> >(s, std::forward<Args>(args)...);
582 node->SetChild(child);
583 if constexpr (std::is_same_v<Parent, Builder<Context>>)
584 {
585 return parent->build();
586 }
587 else
588 {
589 return *parent;
590 }
591 }
592 template<typename... Args>
593 std::conditional_t<
594 std::is_same_v<Parent, Builder<Context>>, // If the parent is a Builder
595 std::shared_ptr<BehaviourTree<Context>>, // Then return the tree as we can't add anything else after the root
596 Parent& // Else return the parent to continue the chain
597 > leaf(Args&&... args)
598 {
599 auto child = std::make_shared<Leaf<Context> >("", std::forward<Args>(args)...);
600 node->SetChild(child);
601 if constexpr (std::is_same_v<Parent, Builder<Context>>)
602 {
603 return parent->build();
604 }
605 else
606 {
607 return *parent;
608 }
609 }
610
611 // To add a tree
612 std::conditional_t<
613 std::is_same_v<Parent, Builder<Context>>, // If the parent is a Builder
614 std::shared_ptr<BehaviourTree<Context>>, // Then return the tree as we can't add anything else after the root
615 Parent& // Else return the parent to continue the chain
616 > tree(std::shared_ptr<BehaviourTree<Context> > arg)
617 {
618 node->SetChild(arg);
619 if constexpr (std::is_same_v<Parent, Builder<Context>>)
620 {
621 return parent->build();
622 }
623 else
624 {
625 return *parent;
626 }
627 }
628
629
630 // Composites
631 // Custom function to add a sequence
633 {
634 auto child = std::make_shared<Sequence<Context>>(s);
635 node->SetChild(child);
637 }
638
639 // Custom function to add a selector
641 {
642 auto child = std::make_shared<Selector<Context>>(s);
643 node->SetChild(child);
645 }
646
647 // To add any other type of composite
648 template<
649 typename CompositeType,
650 typename... Args,
651 typename S,
652 typename = typename std::enable_if_t<std::is_convertible_v<S, std::string>>
653 >
655 {
656 auto child = std::make_shared<CompositeType>(s, std::forward<Args>(args)...);
657 node->SetChild(child);
658 return CompositeBuilder<Parent, Context>(parent, (CompositeType*)child.get());
659 }
660 template<
661 typename CompositeType,
662 typename... Args
663 >
665 {
666 auto child = std::make_shared<CompositeType>("", std::forward<Args>(args)...);
667 node->SetChild(child);
668 return CompositeBuilder<Parent, Context>(parent, (CompositeType*)child.get());
669 }
670
671 // Decorator
672 // Inverter
674 {
675 auto child = std::make_shared<Inverter<Context>>(s);
676 node->SetChild(child);
678 }
679
680 // Succeeder
682 {
683 auto child = std::make_shared<Succeeder<Context>>(s);
684 node->SetChild(child);
686 }
687
688 // Repeater
690 {
691 auto child = std::make_shared<Repeater<Context>>("", n);
692 node->SetChild(child);
694 }
695
696 // Repeater
697 DecoratorBuilder<Parent, Context> repeater(const std::string& s, const size_t n)
698 {
699 auto child = std::make_shared<Repeater<Context>>(s, n);
700 node->SetChild(child);
702 }
703
704 // To add any other type of decorator
705 template<
706 typename DecoratorType,
707 typename... Args,
708 typename S,
709 typename = typename std::enable_if_t<std::is_convertible_v<S, std::string>>
710 >
712 {
713 auto child = std::make_shared<DecoratorType>(s, std::forward<Args>(args)...);
714 node->SetChild(child);
715 return DecoratorBuilder<Parent, Context>(parent, (DecoratorType*)child.get());
716 }
717 template<
718 typename DecoratorType,
719 typename... Args
720 >
722 {
723 auto child = std::make_shared<DecoratorType>("", std::forward<Args>(args)...);
724 node->SetChild(child);
725 return DecoratorBuilder<Parent, Context>(parent, (DecoratorType*)child.get());
726 }
727
728 private:
729 Parent* parent;
731 };
732
733 // Now that we have CompositeBuilder and DecoratorBuilder
734 // we can define the main Builder class
735 template<typename Context>
737 {
738 public:
739 Builder(const std::string& name = "") : root(nullptr), root_name(name) {}
740
741 template<
742 typename S,
743 typename... Args,
744 typename = typename std::enable_if_t<std::is_convertible_v<S, std::string>>
745 >
746 std::shared_ptr<BehaviourTree<Context>> leaf(const S& s, Args&&... args)
747 {
748 auto tree = std::make_shared<BehaviourTree<Context> >(root_name);
749 tree->SetRoot(std::make_shared<Leaf<Context> >(s, std::forward<Args>(args)...));
750 return tree;
751 }
752 template<typename... Args>
753 std::shared_ptr<BehaviourTree<Context>> leaf(Args&&... args)
754 {
755 auto tree = std::make_shared<BehaviourTree<Context> >(root_name);
756 tree->SetRoot(std::make_shared<Leaf<Context> >("", std::forward<Args>(args)...));
757 return tree;
758 }
759
760
761 // Composites
762 // Custom function to add a sequence
764 {
765 root = std::make_shared<Sequence<Context>>(s);
767 }
768
769 // Custom function to add a selector
771 {
772 root = std::make_shared<Selector<Context>>(s);
774 }
775
776 // To add any other type of composite
777 template<
778 typename CompositeType,
779 typename... Args,
780 typename S,
781 typename = typename std::enable_if_t<std::is_convertible_v<S, std::string>>
782 >
784 {
785 root = std::make_shared<CompositeType>(s, std::forward<Args>(args)...);
786 return CompositeBuilder<Builder, Context>(this, (CompositeType*)root.get());
787 }
788 template<
789 typename CompositeType,
790 typename... Args
791 >
793 {
794 root = std::make_shared<CompositeType>("", std::forward<Args>(args)...);
795 return CompositeBuilder<Builder, Context>(this, (CompositeType*)root.get());
796 }
797
798 // Decorator
799 // Inverter
801 {
802 root = std::make_shared<Inverter<Context>>(s);
804 }
805
806 // Succeeder
808 {
809 root = std::make_shared<Succeeder<Context>>(s);
811 }
812
813 // Repeater
815 {
816 root = std::make_shared<Repeater<Context>>("", n);
818 }
819
820 // Repeater
821 DecoratorBuilder<Builder, Context> repeater(const std::string& s, const size_t n)
822 {
823 root = std::make_shared<Repeater<Context>>(s, n);
825 }
826
827 // To add any other type of decorator
828 template<
829 typename DecoratorType,
830 typename... Args,
831 typename S,
832 typename = typename std::enable_if_t<std::is_convertible_v<S, std::string>>
833 >
835 {
836 root = std::make_shared<DecoratorType>(s, std::forward<Args>(args)...);
837 return DecoratorBuilder<Builder, Context>(this, (DecoratorType*)root.get());
838 }
839 template<
840 typename DecoratorType,
841 typename... Args
842 >
844 {
845 root = std::make_shared<DecoratorType>("", std::forward<Args>(args)...);
846 return DecoratorBuilder<Builder, Context>(this, (DecoratorType*)root.get());
847 }
848
849 private:
850 std::shared_ptr<BehaviourTree<Context> > build()
851 {
852 auto tree = std::make_shared<BehaviourTree<Context> >(root_name);
853 tree->SetRoot(root);
854 return tree;
855 }
858
859 private:
860 const std::string root_name;
861 std::shared_ptr<Node<Context> > root;
862 };
863} // namespace Botcraft
#define GENERATE_CHECK_HAS_FUNC(FuncName)
Definition Templates.hpp:9
std::string GetFullDescriptor() const
Definition BaseNode.cpp:19
const std::string name
Definition BaseNode.hpp:31
BaseNode(const std::string &name_)
Definition BaseNode.cpp:9
virtual BehaviourNodeType GetNodeType() const override
std::shared_ptr< Node< Context > > root
virtual size_t GetNumChildren() const override
virtual const BaseNode * GetChild(const size_t index) const override
void SetRoot(const std::shared_ptr< Node< Context > > node)
virtual Status TickImpl(Context &context) const override
CompositeBuilder< Builder, Context > sequence(const std::string &s="")
DecoratorBuilder< Builder, Context > repeater(const size_t n)
std::shared_ptr< Node< Context > > root
DecoratorBuilder< Builder, Context > decorator(Args &&... args)
Builder(const std::string &name="")
DecoratorBuilder< Builder, Context > decorator(const S &s, Args &&... args)
std::shared_ptr< BehaviourTree< Context > > build()
CompositeBuilder< Builder, Context > composite(Args &&... args)
std::shared_ptr< BehaviourTree< Context > > leaf(Args &&... args)
DecoratorBuilder< Builder, Context > repeater(const std::string &s, const size_t n)
const std::string root_name
CompositeBuilder< Builder, Context > composite(const S &s, Args &&... args)
DecoratorBuilder< Builder, Context > succeeder(const std::string &s="")
DecoratorBuilder< Builder, Context > inverter(const std::string &s="")
std::shared_ptr< BehaviourTree< Context > > leaf(const S &s, Args &&... args)
CompositeBuilder< Builder, Context > selector(const std::string &s="")
friend DecoratorBuilder< Builder, Context >
friend CompositeBuilder< Builder, Context >
DecoratorBuilder< CompositeBuilder, Context > inverter(const std::string &s="")
DecoratorBuilder< CompositeBuilder, Context > succeeder(const std::string &s="")
CompositeBuilder leaf(const S &s, Args &&... args)
To add a named leaf.
DecoratorBuilder< CompositeBuilder, Context > decorator(Args &&... args)
Composite< Context > * node
CompositeBuilder(Parent *parent, Composite< Context > *node)
CompositeBuilder< CompositeBuilder, Context > sequence(const std::string &s="")
CompositeBuilder tree(std::shared_ptr< BehaviourTree< Context > > arg)
std::conditional_t< std::is_same_v< Parent, Builder< Context > >, std::shared_ptr< BehaviourTree< Context > >, Parent & > end()
CompositeBuilder< CompositeBuilder, Context > composite(const S &s, Args &&... args)
CompositeBuilder< CompositeBuilder, Context > composite(Args &&... args)
DecoratorBuilder< CompositeBuilder, Context > repeater(const size_t n)
DecoratorBuilder< CompositeBuilder, Context > decorator(const S &s, Args &&... args)
CompositeBuilder leaf(Args &&... args)
To add an anonymous leaf.
CompositeBuilder< CompositeBuilder, Context > selector(const std::string &s="")
DecoratorBuilder< CompositeBuilder, Context > repeater(const std::string &s, const size_t n)
virtual size_t GetNumChildren() const override
virtual const BaseNode * GetChild(const size_t index) const override
Status TickChild(Context &context, const size_t index) const
std::vector< std::shared_ptr< Node< Context > > > children
virtual BehaviourNodeType GetNodeType() const override
void AddChild(const std::shared_ptr< Node< Context > > &child)
CompositeBuilder< Parent, Context > composite(Args &&... args)
CompositeBuilder< Parent, Context > selector(const std::string &s="")
DecoratorBuilder< Parent, Context > repeater(const std::string &s, const size_t n)
CompositeBuilder< Parent, Context > sequence(const std::string &s="")
Decorator< Context > * node
CompositeBuilder< Parent, Context > composite(const S &s, Args &&... args)
DecoratorBuilder< Parent, Context > decorator(const S &s, Args &&... args)
DecoratorBuilder< Parent, Context > repeater(const size_t n)
DecoratorBuilder< Parent, Context > inverter(const std::string &s="")
DecoratorBuilder< Parent, Context > decorator(Args &&... args)
DecoratorBuilder< Parent, Context > succeeder(const std::string &s="")
std::conditional_t< std::is_same_v< Parent, Builder< Context > >, std::shared_ptr< BehaviourTree< Context > >, Parent & > leaf(const S &s, Args &&... args)
std::conditional_t< std::is_same_v< Parent, Builder< Context > >, std::shared_ptr< BehaviourTree< Context > >, Parent & > leaf(Args &&... args)
std::conditional_t< std::is_same_v< Parent, Builder< Context > >, std::shared_ptr< BehaviourTree< Context > >, Parent & > tree(std::shared_ptr< BehaviourTree< Context > > arg)
DecoratorBuilder(Parent *parent, Decorator< Context > *node)
virtual const BaseNode * GetChild(const size_t index) const override
virtual size_t GetNumChildren() const override
std::shared_ptr< Node< Context > > child
virtual BehaviourNodeType GetNodeType() const override
Status TickChild(Context &context) const
void SetChild(std::shared_ptr< Node< Context > > child_)
A Decorator that inverts the result of its child.
virtual Status TickImpl(Context &context) const override
Leaf(const std::string &s, FuncType func_, Args &&... args)
virtual BehaviourNodeType GetNodeType() const override
std::function< Status(Context &)> func
virtual const BaseNode * GetChild(const size_t index) const override
virtual size_t GetNumChildren() const override
Leaf(const std::string &s, FuncType func_)
virtual Status TickImpl(Context &context) const override
virtual Status TickImpl(Context &context) const =0
Status Tick(Context &context) const
A Decorator that ticks its child n times (repeat until first success if n == 0).
Repeater(const std::string &s, const size_t n_)
virtual Status TickImpl(Context &context) const override
Selector implementation.
virtual Status TickImpl(Context &context) const override
Sequence implementation.
virtual Status TickImpl(Context &context) const override
A Decorator that always return success, independently of the result of its child.
virtual Status TickImpl(Context &context) const override
BehaviourNodeType
Definition BaseNode.hpp:8