00001 /* Copyright (C) 2015-2018 Michele Colledanchise - All Rights Reserved 00002 * Copyright (C) 2018-2019 Davide Faconti, Eurecat - 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 <thread> 00019 #include "leaf_node.h" 00020 00021 namespace BT 00022 { 00023 00024 // IMPORTANT: Actions which returned SUCCESS or FAILURE will not be ticked 00025 // again unless setStatus(IDLE) is called first. 00026 // Keep this in mind when writing your custom Control and Decorator nodes. 00027 00028 00034 class ActionNodeBase : public LeafNode 00035 { 00036 public: 00037 00038 ActionNodeBase(const std::string& name, const NodeConfiguration& config); 00039 ~ActionNodeBase() override = default; 00040 00041 virtual NodeType type() const override final 00042 { 00043 return NodeType::ACTION; 00044 } 00045 }; 00046 00052 class SyncActionNode : public ActionNodeBase 00053 { 00054 public: 00055 00056 SyncActionNode(const std::string& name, const NodeConfiguration& config); 00057 ~SyncActionNode() override = default; 00058 00060 virtual NodeStatus executeTick() override; 00061 00063 virtual void halt() override final 00064 { 00065 setStatus(NodeStatus::IDLE); 00066 } 00067 }; 00068 00081 class SimpleActionNode : public SyncActionNode 00082 { 00083 public: 00084 typedef std::function<NodeStatus(TreeNode&)> TickFunctor; 00085 00086 // You must provide the function to call when tick() is invoked 00087 SimpleActionNode(const std::string& name, TickFunctor tick_functor, 00088 const NodeConfiguration& config); 00089 00090 ~SimpleActionNode() override = default; 00091 00092 protected: 00093 virtual NodeStatus tick() override final; 00094 00095 TickFunctor tick_functor_; 00096 }; 00097 00105 class AsyncActionNode : public ActionNodeBase 00106 { 00107 public: 00108 00109 AsyncActionNode(const std::string& name, const NodeConfiguration& config); 00110 virtual ~AsyncActionNode() override; 00111 00112 // This method triggers the TickEngine. Do NOT remove the "final" keyword. 00113 virtual NodeStatus executeTick() override final; 00114 00115 void stopAndJoinThread(); 00116 00117 private: 00118 00119 // The method that will be executed by the thread 00120 void asyncThreadLoop(); 00121 00122 void waitStart(); 00123 00124 void notifyStart(); 00125 00126 std::atomic<bool> keep_thread_alive_; 00127 00128 bool start_action_; 00129 00130 std::mutex start_mutex_; 00131 00132 std::condition_variable start_signal_; 00133 00134 std::exception_ptr exptr_; 00135 00136 std::thread thread_; 00137 }; 00138 00147 class CoroActionNode : public ActionNodeBase 00148 { 00149 public: 00150 00151 CoroActionNode(const std::string& name, const NodeConfiguration& config); 00152 virtual ~CoroActionNode() override; 00153 00155 void setStatusRunningAndYield(); 00156 00157 // This method triggers the TickEngine. Do NOT remove the "final" keyword. 00158 virtual NodeStatus executeTick() override final; 00159 00171 void halt() override; 00172 00173 protected: 00174 00175 struct Pimpl; // The Pimpl idiom 00176 std::unique_ptr<Pimpl> _p; 00177 00178 }; 00179 00180 00181 } //end namespace 00182 00183 #endif