00001 /* Copyright (C) 2015-2018 Michele Colledanchise - All Rights Reserved 00002 * Copyright (C) 2018 Davide Faconti - All Rights Reserved 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 00005 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 00006 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 00007 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 00008 * 00009 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00010 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 00011 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00012 */ 00013 00014 #ifndef BEHAVIORTREECORE_ACTIONNODE_H 00015 #define BEHAVIORTREECORE_ACTIONNODE_H 00016 00017 #include <atomic> 00018 #include "leaf_node.h" 00019 00020 namespace BT 00021 { 00030 class ActionNodeBase : public LeafNode 00031 { 00032 public: 00033 00034 ActionNodeBase(const std::string& name, const NodeParameters& parameters = NodeParameters()); 00035 ~ActionNodeBase() override = default; 00036 00037 virtual NodeStatus executeTick() override; 00038 00039 virtual NodeType type() const override final 00040 { 00041 return NodeType::ACTION; 00042 } 00043 }; 00044 00050 class SyncActionNode : public ActionNodeBase 00051 { 00052 public: 00053 00054 SyncActionNode(const std::string& name, const NodeParameters& parameters = NodeParameters()); 00055 ~SyncActionNode() override = default; 00056 00057 virtual NodeStatus executeTick() override; 00058 00059 virtual void halt() override final // don't need to override this 00060 { 00061 setStatus(NodeStatus::IDLE); 00062 } 00063 }; 00064 00077 class SimpleActionNode : public ActionNodeBase 00078 { 00079 public: 00080 typedef std::function<NodeStatus(TreeNode&)> TickFunctor; 00081 00082 // Constructor: you must provide the function to call when tick() is invoked 00083 SimpleActionNode(const std::string& name, TickFunctor tick_functor, 00084 const NodeParameters ¶ms = NodeParameters()); 00085 00086 ~SimpleActionNode() override = default; 00087 00088 virtual void halt() override 00089 { 00090 // not supported 00091 } 00092 00093 protected: 00094 virtual NodeStatus tick() override; 00095 00096 TickFunctor tick_functor_; 00097 }; 00098 00110 class AsyncActionNode : public ActionNodeBase 00111 { 00112 public: 00113 00114 AsyncActionNode(const std::string& name, const NodeParameters& parameters = NodeParameters()); 00115 virtual ~AsyncActionNode() override; 00116 00117 // This method triggers the TickEngine. Do NOT remove the "final" keyword. 00118 virtual NodeStatus executeTick() override final; 00119 00120 void stopAndJoinThread(); 00121 00122 protected: 00123 00124 // The method that is going to be executed by the thread 00125 void waitForTick(); 00126 00127 // The thread that will execute the node 00128 std::thread thread_; 00129 00130 // Node semaphore to simulate the tick 00131 // (and to synchronize fathers and children) 00132 TickEngine tick_engine_; 00133 00134 std::atomic<bool> loop_; 00135 }; 00136 00137 // Why is the name "ActionNode" deprecated? 00138 // 00139 // ActionNode was renamed "AsyncActionNode" because it's implementation, i.e. one thread 00140 // per action, is too wastefull in terms of resources. 00141 // The name ActionNode seems to imply that it is the default Node to use for Actions. 00142 // But, in my opinion, the user should think twice if using it and carefully consider the cost of abstraction. 00143 // For this reason, AsyncActionNode is a much better name. 00144 00145 00146 // The right class to use for synchronous Actions is SyncActionBase 00147 [[deprecated]] 00148 typedef AsyncActionNode ActionNode; 00149 00158 class CoroActionNode : public ActionNodeBase 00159 { 00160 public: 00161 // Constructor 00162 CoroActionNode(const std::string& name, const NodeParameters& parameters = NodeParameters()); 00163 virtual ~CoroActionNode() override; 00164 00168 void setStatusRunningAndYield(); 00169 00170 // This method triggers the TickEngine. Do NOT remove the "final" keyword. 00171 virtual NodeStatus executeTick() override final; 00172 00184 void halt() override; 00185 00186 protected: 00187 00188 struct Pimpl; // The Pimpl idiom 00189 std::unique_ptr<Pimpl> _p; 00190 00191 }; 00192 00193 00194 } //end namespace 00195 00196 #endif