github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/3rd_party/fflib/include/ff/functionflow/para/wait_impl.h (about) 1 /*********************************************** 2 The MIT License (MIT) 3 4 Copyright (c) 2012 Athrun Arthur <athrunarthur@gmail.com> 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy 7 of this software and associated documentation files (the "Software"), to deal 8 in the Software without restriction, including without limitation the rights 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 copies of the Software, and to permit persons to whom the Software is 11 furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in 14 all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 THE SOFTWARE. 23 *************************************************/ 24 #ifndef FF_PARA_WAIT_IMPL_H_ 25 #define FF_PARA_WAIT_IMPL_H_ 26 #include "ff/functionflow/common/common.h" 27 #include "ff/functionflow/para/bin_wait_func_deducer.h" 28 #include "ff/functionflow/para/para.h" 29 #include "ff/functionflow/para/paracontainer.h" 30 #include "ff/util/tuple_type.h" 31 32 namespace ff { 33 template <class RT> 34 class para; 35 namespace internal { 36 template <class T1, class T2> 37 class wait_and { 38 public: 39 typedef typename std::remove_reference<T1>::type T1_t; 40 typedef typename std::remove_reference<T2>::type T2_t; 41 typedef typename T1_t::ret_type RT1_t; 42 typedef typename T2_t::ret_type RT2_t; 43 typedef bin_wait_func_deducer<typename T1_t::ret_type, 44 typename T2_t::ret_type> deduct_t; 45 typedef typename deduct_t::and_type ret_type; 46 47 public: 48 wait_and(T1&& t1, T2&& t2) : m_1(t1), m_2(t2), m_iES(exe_state::exe_init) {} 49 50 template <class FT> 51 auto then(FT &&f) -> typename std::enable_if< 52 std::is_void<typename function_res_traits<FT>::ret_type>::value && 53 is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_and && 54 !util::function_args_traits<FT>::is_no_args, 55 void>::type { 56 if (!check_if_over()) { 57 ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); }); 58 } 59 deduct_t::void_func_and(std::forward<FT>(f), m_1, m_2); 60 } 61 62 template <class FT> 63 auto then(FT &&f) -> typename std::enable_if< 64 !std::is_void<typename function_res_traits<FT>::ret_type>::value && 65 is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_and && 66 !util::function_args_traits<FT>::is_no_args, 67 typename std::remove_reference< 68 typename function_res_traits<FT>::ret_type>::type>::type { 69 if (!check_if_over()) 70 ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); }); 71 return deduct_t::ret_func_and(std::forward<FT>(f), m_1, m_2); 72 } 73 74 template <class FT> 75 auto then(FT &&f) -> typename std::enable_if< 76 std::is_void<typename function_res_traits<FT>::ret_type>::value && 77 util::function_args_traits<FT>::is_no_args, 78 void>::type { 79 bool b = check_if_over(); 80 if (!b) 81 ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); }); 82 f(); 83 } 84 85 template <class FT> 86 auto then(FT &&f) -> typename std::enable_if< 87 !std::is_void<typename function_res_traits<FT>::ret_type>::value && 88 util::function_args_traits<FT>::is_no_args, 89 typename std::remove_reference< 90 typename function_res_traits<FT>::ret_type>::type>::type { 91 bool b = check_if_over(); 92 if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); }); 93 return f(); 94 } 95 96 template <class FT> 97 auto then(FT &&f) -> typename std::enable_if< 98 !util::function_args_traits<FT>::is_no_args && 99 !is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_and, 100 typename std::remove_reference< 101 typename function_res_traits<FT>::ret_type>::type>::type { 102 static_assert(Please_Check_The_Assert_Msg<FT>::value, 103 FF_EM_THEN_FUNC_TYPE_MISMATCH); 104 } 105 106 template <class FT> 107 auto internal_then(FT &&f) -> typename std::enable_if< 108 std::is_void<typename function_res_traits<FT>::ret_type>::value && 109 is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_and && 110 !util::function_args_traits<FT>::is_no_args, 111 void>::type { 112 deduct_t::void_func_and(std::forward<FT>(f), m_1, m_2); 113 } 114 115 template <class FT> 116 auto internal_then(FT &&f) -> typename std::enable_if< 117 !std::is_void<typename function_res_traits<FT>::ret_type>::value && 118 is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_and && 119 !util::function_args_traits<FT>::is_no_args, 120 typename std::remove_reference< 121 typename function_res_traits<FT>::ret_type>::type>::type { 122 return deduct_t::ret_func_and(std::forward<FT>(f), m_1, m_2); 123 } 124 125 template <class FT> 126 auto internal_then(FT &&f) -> typename std::enable_if< 127 std::is_void<typename function_res_traits<FT>::ret_type>::value && 128 util::function_args_traits<FT>::is_no_args, 129 void>::type { 130 f(); 131 } 132 133 template <class FT> 134 auto internal_then(FT &&f) -> typename std::enable_if< 135 !std::is_void<typename function_res_traits<FT>::ret_type>::value && 136 util::function_args_traits<FT>::is_no_args, 137 typename std::remove_reference< 138 typename function_res_traits<FT>::ret_type>::type>::type { 139 return f(); 140 } 141 142 auto get() -> typename deduct_t::and_type { 143 return deduct_t::wrap_ret_for_and(m_1, m_2); 144 } 145 146 exe_state get_state() { 147 if (m_iES != exe_state::exe_over) 148 m_iES = exe_state_and(m_1.get_state(), m_2.get_state()); 149 return m_iES; 150 } 151 bool check_if_over() { 152 if (m_iES == exe_state::exe_over) return true; 153 m_iES = exe_state_and(m_1.get_state(), m_2.get_state()); 154 if (m_iES == exe_state::exe_over) return true; 155 return false; 156 } 157 158 protected: 159 T1_t m_1; 160 T2_t m_2; 161 exe_state m_iES; 162 }; // end class wait_and 163 164 template <class T1, class T2> 165 class wait_or { 166 public: 167 typedef typename std::remove_reference<T1>::type T1_t; 168 typedef typename std::remove_reference<T2>::type T2_t; 169 typedef typename T1_t::ret_type RT1_t; 170 typedef typename T2_t::ret_type RT2_t; 171 typedef bin_wait_func_deducer<typename T1_t::ret_type, 172 typename T2_t::ret_type> deduct_t; 173 typedef typename deduct_t::or_type ret_type; 174 175 public: 176 wait_or(T1&& t1, T2&& t2) : m_1(t1), m_2(t2), m_iES(exe_state::exe_init) {} 177 178 template <class FT> 179 auto then(FT &&f) -> typename std::enable_if< 180 std::is_void<typename function_res_traits<FT>::ret_type>::value && 181 is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_or && 182 !util::function_args_traits<FT>::is_no_args, 183 void>::type { 184 bool b = check_if_over(); 185 if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); }); 186 deduct_t::void_func_or(std::forward<FT>(f), m_1, m_2); 187 } 188 189 template <class FT> 190 auto then(FT &&f) -> typename std::enable_if< 191 !std::is_void<typename function_res_traits<FT>::ret_type>::value && 192 is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_or && 193 !util::function_args_traits<FT>::is_no_args, 194 typename std::remove_reference< 195 typename function_res_traits<FT>::ret_type>::type>::type { 196 bool b = check_if_over(); 197 if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); }); 198 return deduct_t::ret_func_or(std::forward<FT>(f), m_1, m_2); 199 } 200 201 template <class FT> 202 auto then(FT &&f) -> typename std::enable_if< 203 std::is_void<typename function_res_traits<FT>::ret_type>::value && 204 util::function_args_traits<FT>::is_no_args, 205 void>::type { 206 bool b = check_if_over(); 207 if (!b) 208 ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); }); 209 f(); 210 } 211 212 template <class FT> 213 auto then(FT &&f) -> typename std::enable_if< 214 !std::is_void<typename function_res_traits<FT>::ret_type>::value && 215 util::function_args_traits<FT>::is_no_args, 216 typename std::remove_reference< 217 typename function_res_traits<FT>::ret_type>::type>::type { 218 bool b = check_if_over(); 219 if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); }); 220 return f(); 221 } 222 223 template <class FT> 224 auto then(FT &&f) -> typename std::enable_if< 225 !util::is_no_args_function<FT>::value && 226 !is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_or, 227 typename std::remove_reference< 228 typename function_res_traits<FT>::ret_type>::type>::type { 229 static_assert(Please_Check_The_Assert_Msg<FT>::value, 230 FF_EM_THEN_FUNC_TYPE_MISMATCH); 231 } 232 233 template <class FT> 234 auto internal_then(FT &&f) -> typename std::enable_if< 235 std::is_void<typename function_res_traits<FT>::ret_type>::value && 236 is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_or && 237 !util::function_args_traits<FT>::is_no_args, 238 void>::type { 239 deduct_t::void_func_or(std::forward<FT>(f), m_1, m_2); 240 } 241 242 template <class FT> 243 auto internal_then(FT &&f) -> typename std::enable_if< 244 !std::is_void<typename function_res_traits<FT>::ret_type>::value && 245 is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_or && 246 !util::function_args_traits<FT>::is_no_args, 247 typename std::remove_reference< 248 typename function_res_traits<FT>::ret_type>::type>::type { 249 return deduct_t::ret_func_or(std::forward<FT>(f), m_1, m_2); 250 } 251 252 template <class FT> 253 auto internal_then(FT &&f) -> typename std::enable_if< 254 std::is_void<typename function_res_traits<FT>::ret_type>::value && 255 util::function_args_traits<FT>::is_no_args, 256 void>::type { 257 f(); 258 } 259 260 template <class FT> 261 auto internal_then(FT &&f) -> typename std::enable_if< 262 !std::is_void<typename function_res_traits<FT>::ret_type>::value && 263 util::function_args_traits<FT>::is_no_args, 264 typename std::remove_reference< 265 typename function_res_traits<FT>::ret_type>::type>::type { 266 return f(); 267 } 268 269 auto get() -> typename deduct_t::or_type { 270 return deduct_t::wrap_ret_for_or(m_1, m_2); 271 } 272 273 exe_state get_state() { 274 if (m_iES != exe_state::exe_over) 275 m_iES = exe_state_or(m_1.get_state(), m_2.get_state()); 276 return m_iES; 277 } 278 bool check_if_over() { 279 if (m_iES == exe_state::exe_over) return true; 280 m_iES = exe_state_or(m_1.get_state(), m_2.get_state()); 281 if (m_iES == exe_state::exe_over) return true; 282 return false; 283 } 284 285 protected: 286 T1_t m_1; 287 T2_t m_2; 288 exe_state m_iES; 289 }; // end class wait_or 290 291 class wait_all { 292 public: 293 typedef void ret_type; 294 wait_all(std::shared_ptr<::ff::internal::paras_with_lock> ps); 295 296 template <class FT> 297 auto then(FT&& f) -> void { 298 bool b = check_if_over(); 299 if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); }); 300 f(); 301 } 302 303 exe_state get_state(); 304 bool check_if_over(); 305 306 protected: 307 std::shared_ptr<::ff::internal::paras_with_lock> all_ps; 308 exe_state m_iES; 309 }; // end class wait_all 310 311 class wait_any { 312 public: 313 typedef void ret_type; 314 wait_any(std::shared_ptr<::ff::internal::paras_with_lock> ps); 315 316 template <class FT> 317 auto then(FT&& f) -> void { 318 bool b = check_if_over(); 319 if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); }); 320 f(); 321 } 322 exe_state get_state(); 323 bool check_if_over(); 324 325 protected: 326 std::shared_ptr<::ff::internal::paras_with_lock> all_ps; 327 exe_state m_iES; 328 }; // end class wait_any 329 330 } // end namespace internal 331 } // end namespace ff 332 333 #endif