event_dispatcher.hpp 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484
  1. // eventpp library
  2. // Copyright (C) 2018 Wang Qi (wqking)
  3. // Github: https://github.com/wqking/eventpp
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. /*
  14. * This code is modified from eventpp
  15. *
  16. * author : zhllxt
  17. * email : 37792738@qq.com
  18. *
  19. */
  20. //{
  21. // std::cout << std::endl << "event_dispatcher tutorial 1, basic" << std::endl;
  22. //
  23. // // The namespace is asio2
  24. // // The first template parameter int is the event type,
  25. // // the event type can be any type such as std::string, int, etc.
  26. // // The second is the prototype of the listener.
  27. // asio2::event_dispatcher<int, void ()> dispatcher;
  28. //
  29. // // Add a listener. As the type of dispatcher,
  30. // // here 3 and 5 is the event type,
  31. // // []() {} is the listener.
  32. // // Lambda is not required, any function or std::function
  33. // // or whatever function object with the required prototype is fine.
  34. // dispatcher.append_listener(3, []() {
  35. // std::cout << "Got event 3." << std::endl;
  36. // });
  37. // dispatcher.append_listener(5, []() {
  38. // std::cout << "Got event 5." << std::endl;
  39. // });
  40. // dispatcher.append_listener(5, []() {
  41. // std::cout << "Got another event 5." << std::endl;
  42. // });
  43. //
  44. // // Dispatch the events, the first argument is always the event type.
  45. // dispatcher.dispatch(3);
  46. // dispatcher.dispatch(5);
  47. //}
  48. //
  49. //{
  50. // std::cout << std::endl << "event_dispatcher tutorial 2, listener with parameters" << std::endl;
  51. //
  52. // // The listener has two parameters.
  53. // asio2::event_dispatcher<int, void (const std::string &, const bool)> dispatcher;
  54. //
  55. // dispatcher.append_listener(3, [](const std::string & s, const bool b) {
  56. // std::cout << std::boolalpha << "Got event 3, s is " << s << " b is " << b << std::endl;
  57. // });
  58. // // The listener prototype doesn't need to be exactly same as the dispatcher.
  59. // // It would be find as long as the arguments is compatible with the dispatcher.
  60. // dispatcher.append_listener(5, [](std::string s, int b) {
  61. // std::cout << std::boolalpha << "Got event 5, s is " << s << " b is " << b << std::endl;
  62. // });
  63. // dispatcher.append_listener(5, [](const std::string & s, const bool b) {
  64. // std::cout << std::boolalpha << "Got another event 5, s is " << s << " b is " << b << std::endl;
  65. // });
  66. //
  67. // // Dispatch the events, the first argument is always the event type.
  68. // dispatcher.dispatch(3, "Hello", true);
  69. // dispatcher.dispatch(5, "World", false);
  70. //}
  71. //
  72. //{
  73. // std::cout << std::endl << "event_dispatcher tutorial 3, customized Event struct" << std::endl;
  74. //
  75. // // Define an Event to hold all parameters.
  76. // struct MyEvent
  77. // {
  78. // int type;
  79. // std::string message;
  80. // int param;
  81. // };
  82. //
  83. // // Define policies to let the dispatcher knows how to
  84. // // extract the event type.
  85. // struct MyEventPolicies
  86. // {
  87. // static int get_event(const MyEvent & e, bool /*b*/)
  88. // {
  89. // return e.type;
  90. // }
  91. //
  92. // // single_thread, free lock
  93. // using thread_t = asio2::dispatcheres::single_thread;
  94. // };
  95. //
  96. // // Pass MyEventPolicies as the third template argument of event_dispatcher.
  97. // // Note: the first template argument is the event type type int, not MyEvent.
  98. // asio2::event_dispatcher<
  99. // int,
  100. // void (const MyEvent &, bool),
  101. // MyEventPolicies
  102. // > dispatcher;
  103. //
  104. // // Add a listener.
  105. // // Note: the first argument is the event type of type int, not MyEvent.
  106. // dispatcher.append_listener(3, [](const MyEvent & e, bool b) {
  107. // std::cout
  108. // << std::boolalpha
  109. // << "Got event 3" << std::endl
  110. // << "Event::type is " << e.type << std::endl
  111. // << "Event::message is " << e.message << std::endl
  112. // << "Event::param is " << e.param << std::endl
  113. // << "b is " << b << std::endl
  114. // ;
  115. // });
  116. //
  117. // // Dispatch the event.
  118. // // The first argument is Event.
  119. // dispatcher.dispatch(MyEvent { 3, "Hello world", 38 }, true);
  120. //}
  121. //
  122. //struct Tutor4MyEvent {
  123. // Tutor4MyEvent() : type(0), canceled(false)
  124. // {
  125. // }
  126. // explicit Tutor4MyEvent(const int type)
  127. // : type(type), canceled(false)
  128. // {
  129. // }
  130. //
  131. // int type;
  132. // mutable bool canceled;
  133. //};
  134. //
  135. //struct Tutor4MyEventPolicies
  136. //{
  137. // // E is Tutor4MyEvent and get_event doesn't need to be template.
  138. // // We make it template to show get_event can be templated member.
  139. // template <typename E>
  140. // static int get_event(const E & e)
  141. // {
  142. // return e.type;
  143. // }
  144. //
  145. // // E is Tutor4MyEvent and can_continue_invoking doesn't need to be template.
  146. // // We make it template to show can_continue_invoking can be templated member.
  147. // template <typename E>
  148. // static bool can_continue_invoking(const E & e)
  149. // {
  150. // return ! e.canceled;
  151. // }
  152. //};
  153. //
  154. //{
  155. // std::cout << std::endl << "event_dispatcher tutorial 4, event canceling" << std::endl;
  156. //
  157. // asio2::event_dispatcher<int, void (const Tutor4MyEvent &), Tutor4MyEventPolicies> dispatcher;
  158. //
  159. // dispatcher.append_listener(3, [](const Tutor4MyEvent & e) {
  160. // std::cout << "Got event 3" << std::endl;
  161. // e.canceled = true;
  162. // });
  163. // dispatcher.append_listener(3, [](const Tutor4MyEvent & /*e*/) {
  164. // std::cout << "Should not get this event 3" << std::endl;
  165. // });
  166. //
  167. // dispatcher.dispatch(Tutor4MyEvent(3));
  168. //}
  169. //
  170. //{
  171. // std::cout << std::endl << "event_dispatcher tutorial 5, event filter" << std::endl;
  172. //
  173. // struct MyPolicies {
  174. // using mixins_t = asio2::dispatcheres::mixin_list<asio2::dispatcheres::mixin_filter>;
  175. // };
  176. // asio2::event_dispatcher<int, void (int e, int i, std::string), MyPolicies> dispatcher;
  177. //
  178. // dispatcher.append_listener(3, [](const int /*e*/, const int i, const std::string & s) {
  179. // std::cout
  180. // << "Got event 3, i was 1 but actural is " << i
  181. // << " s was Hello but actural is " << s
  182. // << std::endl
  183. // ;
  184. // });
  185. // dispatcher.append_listener(5, [](const int /*e*/, const int /*i*/, const std::string & /*s*/) {
  186. // std::cout << "Shout not got event 5" << std::endl;
  187. // });
  188. //
  189. // // Add three event filters.
  190. //
  191. // // The first filter modifies the input arguments to other values, then the subsequence filters
  192. // // and listeners will see the modified values.
  193. // dispatcher.append_filter([](const int e, int & i, std::string & s) -> bool {
  194. // std::cout << "Filter 1, e is " << e << " passed in i is " << i << " s is " << s << std::endl;
  195. // i = 38;
  196. // s = "Hi";
  197. // std::cout << "Filter 1, changed i is " << i << " s is " << s << std::endl;
  198. // return true;
  199. // });
  200. //
  201. // // The second filter filters out all event of 5. So no listeners on event 5 can be triggered.
  202. // // The third filter is not invoked on event 5 also.
  203. // dispatcher.append_filter([](const int e, int & i, std::string & s) -> bool {
  204. // std::cout << "Filter 2, e is " << e << " passed in i is " << i << " s is " << s << std::endl;
  205. // if(e == 5) {
  206. // return false;
  207. // }
  208. // return true;
  209. // });
  210. //
  211. // // The third filter just prints the input arguments.
  212. // dispatcher.append_filter([](const int e, int & i, std::string & s) -> bool {
  213. // std::cout << "Filter 3, e is " << e << " passed in i is " << i << " s is " << s << std::endl;
  214. // return true;
  215. // });
  216. //
  217. // // Dispatch the events, the first argument is always the event type.
  218. // dispatcher.dispatch(3, 1, "Hello");
  219. // dispatcher.dispatch(5, 2, "World");
  220. //}
  221. #ifndef __ASIO2_EVENT_DISPATCHER_HPP__
  222. #define __ASIO2_EVENT_DISPATCHER_HPP__
  223. #include <cassert>
  224. #include <string>
  225. #include <functional>
  226. #include <type_traits>
  227. #include <mutex>
  228. #include <shared_mutex>
  229. #include <memory>
  230. #include <utility>
  231. #include <tuple>
  232. #include <atomic>
  233. #include <condition_variable>
  234. #include <map>
  235. #include <unordered_map>
  236. #include <list>
  237. #include <thread>
  238. #include <initializer_list>
  239. #include <vector>
  240. #include <optional>
  241. // when compiled with "Visual Studio 2017 - Windows XP (v141_xp)"
  242. // there is hasn't shared_mutex
  243. #ifndef ASIO2_HAS_SHARED_MUTEX
  244. #if defined(_MSC_VER)
  245. #if defined(_HAS_SHARED_MUTEX)
  246. #if _HAS_SHARED_MUTEX
  247. #define ASIO2_HAS_SHARED_MUTEX 1
  248. #define asio2_shared_mutex std::shared_mutex
  249. #define asio2_shared_lock std::shared_lock
  250. #define asio2_unique_lock std::unique_lock
  251. #else
  252. #define ASIO2_HAS_SHARED_MUTEX 0
  253. #define asio2_shared_mutex std::mutex
  254. #define asio2_shared_lock std::lock_guard
  255. #define asio2_unique_lock std::lock_guard
  256. #endif
  257. #else
  258. #define ASIO2_HAS_SHARED_MUTEX 1
  259. #define asio2_shared_mutex std::shared_mutex
  260. #define asio2_shared_lock std::shared_lock
  261. #define asio2_unique_lock std::unique_lock
  262. #endif
  263. #else
  264. #define ASIO2_HAS_SHARED_MUTEX 1
  265. #define asio2_shared_mutex std::shared_mutex
  266. #define asio2_shared_lock std::shared_lock
  267. #define asio2_unique_lock std::unique_lock
  268. #endif
  269. #endif
  270. namespace asio2 {
  271. namespace dispatcheres {
  272. template <typename F, template <typename> class T>
  273. struct transform_arguments;
  274. template <template <typename> class T, typename RT, typename ...Args>
  275. struct transform_arguments <RT (Args...), T>
  276. {
  277. using type = RT (typename T<Args>::type...);
  278. };
  279. template <typename F, typename Replacement>
  280. struct replace_return_type;
  281. template <typename Replacement, typename RT, typename ...Args>
  282. struct replace_return_type <RT (Args...), Replacement>
  283. {
  284. using type = Replacement (Args...);
  285. };
  286. template <int N, int M>
  287. struct int_to_constant_helper
  288. {
  289. template <typename C, typename ...Args>
  290. static auto find(const int index, C && c, Args && ...args)
  291. -> decltype(std::declval<C>().template operator()<0>(std::declval<Args>()...))
  292. {
  293. if(N == index)
  294. {
  295. return c.template operator()<N>(std::forward<Args>(args)...);
  296. }
  297. else
  298. {
  299. return int_to_constant_helper<N + 1, M>::find(index, std::forward<C>(c), std::forward<Args>(args)...);
  300. }
  301. }
  302. };
  303. template <int M>
  304. struct int_to_constant_helper <M, M>
  305. {
  306. template <typename C, typename ...Args>
  307. static auto find(const int /*index*/, C && c, Args && ...args)
  308. -> decltype(std::declval<C>().template operator()<0>(std::declval<Args>()...))
  309. {
  310. return decltype(c.template operator()<0>(std::forward<Args>(args)...))();
  311. }
  312. };
  313. template <int M, typename C, typename ...Args>
  314. auto int_to_constant(const int index, C && c, Args && ...args)
  315. -> decltype(std::declval<C>().template operator()<0>(std::declval<Args>()...))
  316. {
  317. return int_to_constant_helper<0, M>::find(index, std::forward<C>(c), std::forward<Args>(args)...);
  318. }
  319. template <typename F, typename ...Args>
  320. struct can_invoke
  321. {
  322. template <typename U, typename ...X>
  323. static auto invoke(int) -> decltype(std::declval<U>()(std::declval<X>()...), std::true_type());
  324. template <typename U, typename ...X>
  325. static auto invoke(...) -> std::false_type;
  326. enum
  327. {
  328. value = !! decltype(invoke<F, Args...>(0))()
  329. };
  330. };
  331. template <typename T>
  332. struct shift_tuple;
  333. template <typename A, typename ...Args>
  334. struct shift_tuple <std::tuple<A, Args...> >
  335. {
  336. using type = std::tuple<Args...>;
  337. };
  338. template <>
  339. struct shift_tuple <std::tuple<> >
  340. {
  341. using type = std::tuple<>;
  342. };
  343. // for compile time debug
  344. template<typename T>
  345. void print_type_in_compile_time(T * = 0)
  346. {
  347. static_assert(std::is_same<T, int>::value && ! std::is_same<T, int>::value, "The error shows the type name.");
  348. }
  349. template<int N>
  350. void print_int_in_compile_time()
  351. {
  352. int n = 0;
  353. switch(n)
  354. {
  355. case N:
  356. case N:
  357. break;
  358. };
  359. }
  360. } //namespace dispatcheres
  361. //-------------------------------------------------------------------------------------------------
  362. namespace dispatcheres {
  363. struct tag_homo {};
  364. struct tag_callback_list : public tag_homo {};
  365. struct tag_event_dispatcher : public tag_homo {};
  366. struct tag_event_queue : public tag_homo {};
  367. template <
  368. typename MutexT = asio2_shared_mutex,
  369. template <typename > class SharedLockT = asio2_shared_lock,
  370. template <typename > class UniqueLockT = asio2_unique_lock,
  371. template <typename > class AtomicT = std::atomic,
  372. typename ConditionVariableT = std::condition_variable
  373. >
  374. struct general_thread
  375. {
  376. using mutex = MutexT;
  377. template <typename T>
  378. using shared_lock = SharedLockT<T>;
  379. template <typename T>
  380. using unique_lock = UniqueLockT<T>;
  381. template <typename T>
  382. using atomic = AtomicT<T>;
  383. using condition_variable = ConditionVariableT;
  384. };
  385. struct multiple_thread
  386. {
  387. using mutex = asio2_shared_mutex;
  388. template <typename T>
  389. using shared_lock = asio2_shared_lock<T>;
  390. template <typename T>
  391. using unique_lock = asio2_unique_lock<T>;
  392. template <typename T>
  393. using atomic = std::atomic<T>;
  394. using condition_variable = std::condition_variable;
  395. };
  396. struct single_thread
  397. {
  398. struct mutex
  399. {
  400. inline void lock () noexcept {}
  401. inline void unlock() noexcept {}
  402. };
  403. template <typename T>
  404. struct shared_lock
  405. {
  406. using mutex_type = T;
  407. inline shared_lock() noexcept = default;
  408. inline shared_lock(shared_lock&& other) noexcept = default;
  409. inline explicit shared_lock(mutex_type&) noexcept {}
  410. inline ~shared_lock() noexcept {};
  411. inline void lock () noexcept {}
  412. inline void unlock() noexcept {}
  413. };
  414. template <typename T>
  415. struct unique_lock
  416. {
  417. using mutex_type = T;
  418. inline unique_lock() noexcept = default;
  419. inline unique_lock(unique_lock&& other) noexcept = default;
  420. inline explicit unique_lock(mutex_type&) noexcept {}
  421. inline ~unique_lock() noexcept {};
  422. inline void lock () noexcept {}
  423. inline void unlock() noexcept {}
  424. };
  425. template <typename T>
  426. struct atomic
  427. {
  428. inline atomic() = default;
  429. constexpr atomic(T desired) noexcept
  430. : value(desired)
  431. {
  432. }
  433. inline void store(T desired, std::memory_order /*order*/ = std::memory_order_seq_cst) noexcept
  434. {
  435. value = desired;
  436. }
  437. inline T load(std::memory_order /*order*/ = std::memory_order_seq_cst) const noexcept
  438. {
  439. return value;
  440. }
  441. inline T exchange(T desired, std::memory_order /*order*/ = std::memory_order_seq_cst) noexcept
  442. {
  443. const T old = value;
  444. value = desired;
  445. return old;
  446. }
  447. inline T operator ++ () noexcept
  448. {
  449. return ++value;
  450. }
  451. inline T operator -- () noexcept
  452. {
  453. return --value;
  454. }
  455. T value{};
  456. };
  457. struct condition_variable
  458. {
  459. inline void notify_one() noexcept
  460. {
  461. }
  462. template <class Predicate>
  463. inline void wait(std::unique_lock<std::mutex> & /*lock*/, Predicate /*pred*/) noexcept
  464. {
  465. }
  466. template <class Rep, class Period, class Predicate>
  467. inline bool wait_for(std::unique_lock<std::mutex> & /*lock*/,
  468. const std::chrono::duration<Rep, Period> & /*rel_time*/,
  469. Predicate /*pred*/) noexcept
  470. {
  471. return true;
  472. }
  473. };
  474. };
  475. struct argument_passing_auto_detect
  476. {
  477. enum
  478. {
  479. can_include_event_type = true,
  480. can_exclude_event_type = true
  481. };
  482. };
  483. struct argument_passing_include_event
  484. {
  485. enum
  486. {
  487. can_include_event_type = true,
  488. can_exclude_event_type = false
  489. };
  490. };
  491. struct argument_passing_exclude_event
  492. {
  493. enum
  494. {
  495. can_include_event_type = false,
  496. can_exclude_event_type = true
  497. };
  498. };
  499. struct default_policy
  500. {
  501. };
  502. template <template <typename> class ...user_mixins>
  503. struct mixin_list
  504. {
  505. };
  506. } //namespace dispatcheres
  507. //-------------------------------------------------------------------------------------------------
  508. namespace dispatcheres {
  509. template <typename T>
  510. struct has_type_argument_passing_mode
  511. {
  512. template <typename C> static std::true_type test(typename C::argument_passing_mode *) ;
  513. template <typename C> static std::false_type test(...);
  514. enum { value = !! decltype(test<T>(0))() };
  515. };
  516. template <typename T, bool, typename Default>
  517. struct select_argument_passing_mode { using type = typename T::argument_passing_mode; };
  518. template <typename T, typename Default>
  519. struct select_argument_passing_mode <T, false, Default> { using type = Default; };
  520. // https://en.cppreference.com/w/cpp/types/void_t
  521. // primary template handles types that have no nested ::type member:
  522. template< class, class = void >
  523. struct has_type_thread_t : std::false_type { };
  524. // specialization recognizes types that do have a nested ::type member:
  525. template< class T >
  526. struct has_type_thread_t<T, std::void_t<typename T::thread_t>> : std::true_type { };
  527. template <typename T, bool> struct select_thread { using type = typename T::thread_t; };
  528. template <typename T> struct select_thread <T, false> { using type = multiple_thread; };
  529. // primary template handles types that have no nested ::type member:
  530. template< class, class = void >
  531. struct has_type_callback_t : std::false_type { };
  532. // specialization recognizes types that do have a nested ::type member:
  533. template< class T >
  534. struct has_type_callback_t<T, std::void_t<typename T::callback_t>> : std::true_type { };
  535. template <typename T, bool, typename D> struct select_callback { using type = typename T::callback_t; };
  536. template <typename T, typename D> struct select_callback<T, false, D> { using type = D; };
  537. // primary template handles types that have no nested ::type member:
  538. template< class, class = void >
  539. struct has_type_user_data_t : std::false_type { };
  540. // specialization recognizes types that do have a nested ::type member:
  541. template< class T >
  542. struct has_type_user_data_t<T, std::void_t<typename T::user_data_t>> : std::true_type { };
  543. // primary template handles types that have no nested ::type member:
  544. template< class, class = void >
  545. struct has_type_listener_name_t : std::false_type { };
  546. // specialization recognizes types that do have a nested ::type member:
  547. template< class T >
  548. struct has_type_listener_name_t<T, std::void_t<typename T::listener_name_t>> : std::true_type { };
  549. template <typename T, bool, typename D> struct select_listener_name { using type = typename T::listener_name_t; };
  550. template <typename T, typename D> struct select_listener_name<T, false, D> { using type = D; };
  551. template <typename T, typename ...Args>
  552. struct has_function_get_event
  553. {
  554. template <typename C> static std::true_type test(decltype(C::get_event(std::declval<Args>()...)) *);
  555. template <typename C> static std::false_type test(...);
  556. enum { value = !! decltype(test<T>(0))() };
  557. };
  558. template <typename E>
  559. struct default_get_event
  560. {
  561. template <typename U, typename ...Args>
  562. static E get_event(U && e, Args && ...)
  563. {
  564. return e;
  565. }
  566. };
  567. template <typename T, typename Key, bool> struct select_get_event { using type = T; };
  568. template <typename T, typename Key> struct select_get_event<T, Key, false> { using type = default_get_event<Key>; };
  569. template <typename T, typename ...Args>
  570. struct has_function_can_continue_invoking
  571. {
  572. template <typename C> static std::true_type test(decltype(C::can_continue_invoking(std::declval<Args>()...)) *) ;
  573. template <typename C> static std::false_type test(...);
  574. enum { value = !! decltype(test<T>(0))() };
  575. };
  576. struct default_can_continue_invoking
  577. {
  578. template <typename ...Args>
  579. static bool can_continue_invoking(Args && ...)
  580. {
  581. return true;
  582. }
  583. };
  584. template <typename T, bool> struct select_can_continue_invoking { using type = T; };
  585. template <typename T> struct select_can_continue_invoking<T, false> { using type = default_can_continue_invoking; };
  586. template <typename T>
  587. struct has_template_map_t
  588. {
  589. template <typename C> static std::true_type test(typename C::template map_t<int, int> *) ;
  590. template <typename C> static std::false_type test(...);
  591. enum { value = !! decltype(test<T>(0))() };
  592. };
  593. template <typename T>
  594. class has_std_hash
  595. {
  596. template <typename C> static std::true_type test(decltype(std::hash<C>()(std::declval<C>())) *) ;
  597. template <typename C> static std::false_type test(...);
  598. public:
  599. enum { value = !! decltype(test<T>(0))() };
  600. };
  601. template<class T, class R, class... Args>
  602. struct has_member_reserve : std::false_type {};
  603. template<class T, class... Args>
  604. struct has_member_reserve<T, decltype(std::declval<std::decay_t<T>>().
  605. reserve((std::declval<Args>())...)), Args...> : std::true_type {};
  606. template <typename Key, typename Value, typename T, bool>
  607. struct select_map
  608. {
  609. using type = typename T::template map_t<Key, Value>;
  610. };
  611. template <typename Key, typename Value, typename T>
  612. struct select_map<Key, Value, T, false>
  613. {
  614. using type = typename std::conditional<
  615. has_std_hash<Key>::value,
  616. std::unordered_map<Key, Value>,
  617. std::map<Key, Value>
  618. >::type;
  619. };
  620. template <typename ListenerNameType, typename EventType, typename Value, typename T, bool>
  621. struct select_listener_name_map
  622. {
  623. using type = typename T::template map_t<ListenerNameType, typename T::template map_t<EventType, Value>>;
  624. };
  625. template <typename ListenerNameType, typename EventType, typename Value, typename T>
  626. struct select_listener_name_map<ListenerNameType, EventType, Value, T, false>
  627. {
  628. using type = typename std::conditional<
  629. has_std_hash<ListenerNameType>::value,
  630. typename std::conditional_t<
  631. has_std_hash<EventType>::value,
  632. std::unordered_map<ListenerNameType, std::unordered_multimap<EventType, Value>>,
  633. std::unordered_map<ListenerNameType, std::multimap<EventType, Value>>
  634. >,
  635. typename std::conditional_t<
  636. has_std_hash<EventType>::value,
  637. std::map<ListenerNameType, std::unordered_multimap<EventType, Value>>,
  638. std::map<ListenerNameType, std::multimap<EventType, Value>>
  639. >
  640. >::type;
  641. };
  642. template <typename T>
  643. struct has_template_queue_list_t
  644. {
  645. template <typename C> static std::true_type test(typename C::template queue_list_t<int> *);
  646. template <typename C> static std::false_type test(...);
  647. enum { value = !! decltype(test<T>(0))() };
  648. };
  649. template <typename Value, typename T, bool>
  650. struct select_queue_list
  651. {
  652. using type = typename T::template queue_list_t<Value>;
  653. };
  654. template <typename Value, typename T>
  655. struct select_queue_list<Value, T, false>
  656. {
  657. using type = std::list<Value>;
  658. };
  659. template <typename T>
  660. struct has_type_mixins_t
  661. {
  662. template <typename C> static std::true_type test(typename C::mixins_t *) ;
  663. template <typename C> static std::false_type test(...);
  664. enum { value = !! decltype(test<T>(0))() };
  665. };
  666. template <typename T, bool> struct select_mixins { using type = typename T::mixins_t; };
  667. template <typename T> struct select_mixins <T, false> { using type = mixin_list<>; };
  668. template <typename Root, typename TList>
  669. struct inherit_mixins;
  670. template <typename Root, template <typename> class T, template <typename> class ...Args>
  671. struct inherit_mixins <Root, mixin_list<T, Args...> >
  672. {
  673. using type = T <typename inherit_mixins<Root, mixin_list<Args...> >::type>;
  674. };
  675. template <typename Root>
  676. struct inherit_mixins <Root, mixin_list<> >
  677. {
  678. using type = Root;
  679. };
  680. template <typename Root, typename TList, typename Func>
  681. struct for_each_mixins;
  682. template <typename Func, typename Root, template <typename> class T, template <typename> class ...Args>
  683. struct for_each_mixins <Root, mixin_list<T, Args...>, Func>
  684. {
  685. using type = typename inherit_mixins<Root, mixin_list<T, Args...> >::type;
  686. template <typename ...A>
  687. static bool for_each(A && ...args)
  688. {
  689. if(Func::template for_each<type>(args...))
  690. {
  691. return for_each_mixins<Root, mixin_list<Args...>, Func>::for_each(std::forward<A>(args)...);
  692. }
  693. return false;
  694. }
  695. };
  696. template <typename Root, typename Func>
  697. struct for_each_mixins <Root, mixin_list<>, Func>
  698. {
  699. using type = Root;
  700. template <typename ...A>
  701. static bool for_each(A && .../*args*/)
  702. {
  703. return true;
  704. }
  705. };
  706. template <typename T, typename ...Args>
  707. struct has_function_mixin_before_dispatch
  708. {
  709. template <typename C> static std::true_type test(
  710. decltype(std::declval<C>().mixin_before_dispatch(std::declval<Args>()...)) *
  711. );
  712. template <typename C> static std::false_type test(...);
  713. enum { value = !! decltype(test<T>(0))() };
  714. };
  715. } //namespace dispatcheres
  716. //-------------------------------------------------------------------------------------------------
  717. namespace dispatcheres {
  718. template <
  719. typename EventTypeT,
  720. typename ProtoType,
  721. typename PolicyType
  722. >
  723. class callback_list_base;
  724. template <
  725. typename EventTypeT,
  726. typename PrototypeT,
  727. typename PolicyT,
  728. typename MixinRootT
  729. >
  730. class event_dispatcher_base;
  731. template <
  732. typename EventTypeT,
  733. typename PolicyType,
  734. bool HasTypeUserData,
  735. typename ProtoType
  736. >
  737. class node_traits;
  738. template <
  739. typename EventTypeT,
  740. typename PolicyType,
  741. typename ReturnType, typename ...Args
  742. >
  743. class node_traits<
  744. EventTypeT,
  745. PolicyType,
  746. true,
  747. ReturnType (Args...)
  748. >
  749. {
  750. private:
  751. template <
  752. typename,
  753. typename,
  754. typename
  755. >
  756. friend class callback_list_base;
  757. template <
  758. typename,
  759. typename,
  760. typename,
  761. typename
  762. >
  763. friend class event_dispatcher_base;
  764. public:
  765. using policy_type = PolicyType;
  766. using event_type = EventTypeT;
  767. using callback_type = typename select_callback<
  768. policy_type,
  769. has_type_callback_t<policy_type>::value,
  770. std::function<ReturnType (Args...)>
  771. >::type;
  772. using listener_name_type = typename select_listener_name<
  773. policy_type,
  774. has_type_listener_name_t<policy_type>::value,
  775. std::string
  776. >::type;
  777. using user_data_type = typename policy_type::user_data_t;
  778. struct node;
  779. using node_ptr = std::shared_ptr<node>;
  780. struct node
  781. {
  782. private:
  783. template <
  784. typename,
  785. typename,
  786. typename
  787. >
  788. friend class callback_list_base;
  789. template <
  790. typename,
  791. typename,
  792. typename,
  793. typename
  794. >
  795. friend class event_dispatcher_base;
  796. public:
  797. using counter_type = unsigned int;
  798. node(const listener_name_type& nm, const event_type& e, callback_type cb, const counter_type count)
  799. : evt(e), callback(std::move(cb)), counter(count), name(nm)
  800. {
  801. }
  802. inline const event_type get_event_type() const noexcept { return evt; }
  803. inline const listener_name_type& get_listener_name() const noexcept { return name; }
  804. inline node& set_user_data(user_data_type data) noexcept { userdata = std::move(data); return (*this); }
  805. inline const user_data_type& get_user_data() const noexcept { return userdata; }
  806. protected:
  807. event_type evt;
  808. callback_type callback;
  809. counter_type counter;
  810. listener_name_type name{};
  811. user_data_type userdata{};
  812. node_ptr prev;
  813. node_ptr next;
  814. };
  815. };
  816. template <
  817. typename EventTypeT,
  818. typename PolicyType,
  819. typename ReturnType, typename ...Args
  820. >
  821. class node_traits<
  822. EventTypeT,
  823. PolicyType,
  824. false,
  825. ReturnType (Args...)
  826. >
  827. {
  828. private:
  829. template <
  830. typename,
  831. typename,
  832. typename
  833. >
  834. friend class callback_list_base;
  835. template <
  836. typename,
  837. typename,
  838. typename,
  839. typename
  840. >
  841. friend class event_dispatcher_base;
  842. public:
  843. using policy_type = PolicyType;
  844. using event_type = EventTypeT;
  845. using callback_type = typename select_callback<
  846. policy_type,
  847. has_type_callback_t<policy_type>::value,
  848. std::function<ReturnType (Args...)>
  849. >::type;
  850. using listener_name_type = typename select_listener_name<
  851. policy_type,
  852. has_type_listener_name_t<policy_type>::value,
  853. std::string
  854. >::type;
  855. using user_data_type = void;
  856. struct node;
  857. using node_ptr = std::shared_ptr<node>;
  858. struct node
  859. {
  860. private:
  861. template <
  862. typename,
  863. typename,
  864. typename
  865. >
  866. friend class callback_list_base;
  867. template <
  868. typename,
  869. typename,
  870. typename,
  871. typename
  872. >
  873. friend class event_dispatcher_base;
  874. public:
  875. using counter_type = unsigned int;
  876. node(const listener_name_type& nm, const event_type& e, callback_type cb, const counter_type count)
  877. : evt(e), callback(std::move(cb)), counter(count), name(nm)
  878. {
  879. }
  880. inline const event_type get_event_type() const noexcept { return evt; }
  881. inline const listener_name_type& get_listener_name() const noexcept { return name; }
  882. protected:
  883. event_type evt;
  884. callback_type callback;
  885. counter_type counter;
  886. listener_name_type name{};
  887. node_ptr prev;
  888. node_ptr next;
  889. };
  890. };
  891. template <
  892. typename EventTypeT,
  893. typename PolicyType,
  894. typename ReturnType, typename ...Args
  895. >
  896. class callback_list_base<
  897. EventTypeT,
  898. ReturnType (Args...),
  899. PolicyType
  900. > : public node_traits<EventTypeT, PolicyType, has_type_user_data_t<PolicyType>::value, ReturnType(Args...)>
  901. {
  902. private:
  903. template <
  904. typename,
  905. typename,
  906. typename,
  907. typename
  908. >
  909. friend class event_dispatcher_base;
  910. public:
  911. using node_traits_type =
  912. node_traits<EventTypeT, PolicyType, has_type_user_data_t<PolicyType>::value, ReturnType(Args...)>;
  913. using this_type = callback_list_base<
  914. EventTypeT,
  915. ReturnType(Args...),
  916. PolicyType
  917. >;
  918. using policy_type = PolicyType;
  919. using event_type = EventTypeT;
  920. using thread_type = typename select_thread<policy_type, has_type_thread_t<policy_type>::value>::type;
  921. using callback_type = typename node_traits_type::callback_type;
  922. using listener_name_type = typename node_traits_type::listener_name_type;
  923. using can_continue_invoking_type = typename select_can_continue_invoking<
  924. policy_type, has_function_can_continue_invoking<policy_type, Args...>::value
  925. >::type;
  926. using node = typename node_traits_type::node;
  927. using node_ptr = typename node_traits_type::node_ptr;
  928. class handle_type : public std::weak_ptr<node>
  929. {
  930. private:
  931. using super = std::weak_ptr<node>;
  932. public:
  933. using super::super;
  934. inline operator bool () const noexcept
  935. {
  936. return ! this->expired();
  937. }
  938. };
  939. using counter_type = typename node::counter_type;
  940. static constexpr counter_type removed_counter = 0;
  941. public:
  942. using node_wptr = handle_type;
  943. using mutex_type = typename thread_type::mutex;
  944. public:
  945. callback_list_base() noexcept
  946. : head()
  947. , tail()
  948. , list_mtx_()
  949. , current_counter_(0)
  950. {
  951. }
  952. callback_list_base(const callback_list_base & other)
  953. : callback_list_base()
  954. {
  955. size_ = other.size_;
  956. copy_from(other.head);
  957. }
  958. callback_list_base(callback_list_base && other) noexcept
  959. : callback_list_base()
  960. {
  961. swap(other);
  962. }
  963. // If we use pass by value idiom and omit the 'this' check,
  964. // when assigning to self there is a deep copy which is inefficient.
  965. callback_list_base & operator = (const callback_list_base & other)
  966. {
  967. if(this != std::addressof(other))
  968. {
  969. callback_list_base copied(other);
  970. swap(copied);
  971. }
  972. return *this;
  973. }
  974. callback_list_base & operator = (callback_list_base && other) noexcept
  975. {
  976. if(this != std::addressof(other))
  977. {
  978. do_free_all_nodes();
  979. head = std::move(other.head);
  980. tail = std::move(other.tail);
  981. current_counter_ = other.current_counter_.load();
  982. size_ = other.size_;
  983. }
  984. return *this;
  985. }
  986. ~callback_list_base()
  987. {
  988. // Don't lock mutex here since it may throw exception
  989. do_free_all_nodes();
  990. }
  991. void swap(callback_list_base & other) noexcept
  992. {
  993. using std::swap;
  994. swap(head, other.head);
  995. swap(tail, other.tail);
  996. swap(size_, other.size_);
  997. const auto value = current_counter_.load();
  998. current_counter_.exchange(other.current_counter_.load());
  999. other.current_counter_.exchange(value);
  1000. }
  1001. inline bool empty() const noexcept
  1002. {
  1003. // Don't lock the mutex for performance reason.
  1004. // !head still works even when the underlying raw pointer is garbled (for other thread is writting to head)
  1005. // And empty() doesn't guarantee the list is still empty after the function returned.
  1006. //std::lock_guard<mutex_type> guard(list_mtx_);
  1007. return ! head;
  1008. }
  1009. inline operator bool() const noexcept
  1010. {
  1011. return ! empty();
  1012. }
  1013. node_wptr append(const listener_name_type& name, const event_type& e, callback_type cb)
  1014. {
  1015. node_ptr n(do_allocate_node(name, e, std::move(cb)));
  1016. typename thread_type::template unique_lock<mutex_type> guard(list_mtx_);
  1017. if(head)
  1018. {
  1019. n->prev = tail;
  1020. tail->next = n;
  1021. tail = n;
  1022. }
  1023. else
  1024. {
  1025. head = n;
  1026. tail = n;
  1027. }
  1028. ++size_;
  1029. return node_wptr(n);
  1030. }
  1031. node_wptr prepend(const listener_name_type& name, const event_type& e, callback_type cb)
  1032. {
  1033. node_ptr n(do_allocate_node(name, e, std::move(cb)));
  1034. typename thread_type::template unique_lock<mutex_type> guard(list_mtx_);
  1035. if(head)
  1036. {
  1037. n->next = head;
  1038. head->prev = n;
  1039. head = n;
  1040. }
  1041. else
  1042. {
  1043. head = n;
  1044. tail = n;
  1045. }
  1046. ++size_;
  1047. return node_wptr(n);
  1048. }
  1049. node_wptr insert(const listener_name_type& name, const event_type& e, callback_type cb, const node_wptr & before)
  1050. {
  1051. node_ptr before_node = before.lock();
  1052. if(before_node)
  1053. {
  1054. node_ptr n(do_allocate_node(name, e, std::move(cb)));
  1055. typename thread_type::template unique_lock<mutex_type> guard(list_mtx_);
  1056. do_insert(n, before_node);
  1057. ++size_;
  1058. return node_wptr(n);
  1059. }
  1060. return append(name, e, std::move(cb));
  1061. }
  1062. bool remove(const node_wptr & nwptr)
  1063. {
  1064. auto n = nwptr.lock();
  1065. if (n)
  1066. {
  1067. typename thread_type::template unique_lock<mutex_type> guard(list_mtx_);
  1068. do_free_node(n);
  1069. --size_;
  1070. return true;
  1071. }
  1072. return false;
  1073. }
  1074. inline std::size_t size() const noexcept
  1075. {
  1076. return size_;
  1077. }
  1078. inline void clear() noexcept
  1079. {
  1080. callback_list_base other{};
  1081. swap(other);
  1082. }
  1083. protected:
  1084. inline void iterator_move_to_next(node_ptr& n) noexcept
  1085. {
  1086. typename thread_type::template shared_lock<mutex_type> guard(list_mtx_);
  1087. n = n->next;
  1088. }
  1089. inline void iterator_move_to_prev(node_ptr& n) noexcept
  1090. {
  1091. typename thread_type::template shared_lock<mutex_type> guard(list_mtx_);
  1092. n = n->prev;
  1093. }
  1094. public:
  1095. class iterator
  1096. {
  1097. public:
  1098. using iterator_category = std::bidirectional_iterator_tag;
  1099. using value_type = node_ptr;
  1100. using difference_type = std::ptrdiff_t;
  1101. using pointer = value_type&;
  1102. using reference = value_type&;
  1103. explicit iterator(this_type& m) : master_(m)
  1104. {
  1105. }
  1106. explicit iterator(this_type& m, value_type v) : master_(m), value_(std::move(v))
  1107. {
  1108. }
  1109. explicit iterator(const this_type& m) : master_(const_cast<this_type&>(m))
  1110. {
  1111. }
  1112. explicit iterator(const this_type& m, value_type v) : master_(const_cast<this_type&>(m)), value_(std::move(v))
  1113. {
  1114. }
  1115. [[nodiscard]] reference operator*() noexcept
  1116. {
  1117. return value_;
  1118. }
  1119. [[nodiscard]] pointer operator->() noexcept
  1120. {
  1121. return value_;
  1122. }
  1123. iterator& operator++() noexcept
  1124. {
  1125. if (value_)
  1126. {
  1127. master_.iterator_move_to_next(value_);
  1128. }
  1129. return (*this);
  1130. }
  1131. iterator& operator--() noexcept
  1132. {
  1133. if (value_)
  1134. {
  1135. master_.iterator_move_to_prev(value_);
  1136. }
  1137. return (*this);
  1138. }
  1139. [[nodiscard]] bool operator==(const iterator& right) const
  1140. {
  1141. return (value_.get() == right.value_.get());
  1142. }
  1143. [[nodiscard]] bool operator!=(const iterator& right) const
  1144. {
  1145. return (value_.get() != right.value_.get());
  1146. }
  1147. protected:
  1148. this_type& master_;
  1149. value_type value_{};
  1150. };
  1151. using const_iterator = iterator;
  1152. /// Return a const iterator to the beginning of the field sequence.
  1153. inline iterator begin() noexcept
  1154. {
  1155. typename thread_type::template shared_lock<mutex_type> guard(list_mtx_);
  1156. return iterator(*this, head);
  1157. }
  1158. /// Return a const iterator to the end of the field sequence.
  1159. inline iterator end() noexcept
  1160. {
  1161. return iterator(*this);
  1162. }
  1163. /// Return a const iterator to the beginning of the field sequence.
  1164. inline const_iterator begin() const noexcept
  1165. {
  1166. typename thread_type::template shared_lock<mutex_type> guard(list_mtx_);
  1167. return (const_iterator(*this, head));
  1168. }
  1169. /// Return a const iterator to the end of the field sequence.
  1170. inline const_iterator end() const noexcept
  1171. {
  1172. return (const_iterator(*this));
  1173. }
  1174. /// Return a const iterator to the beginning of the field sequence.
  1175. inline const_iterator cbegin() const noexcept
  1176. {
  1177. return (begin());
  1178. }
  1179. /// Return a const iterator to the end of the field sequence.
  1180. inline const_iterator cend() const noexcept
  1181. {
  1182. return (end());
  1183. }
  1184. template <typename Func>
  1185. void for_each(Func && func) const
  1186. {
  1187. do_for_each_if([&func, this](node_ptr & n) -> bool
  1188. {
  1189. do_for_each_invoke<void>(func, n);
  1190. return true;
  1191. });
  1192. }
  1193. template <typename Func>
  1194. bool for_each_if(Func && func) const
  1195. {
  1196. return do_for_each_if([&func, this](node_ptr & n) -> bool
  1197. {
  1198. return do_for_each_invoke<bool>(func, n);
  1199. });
  1200. }
  1201. #if !defined(__GNUC__) || __GNUC__ >= 5
  1202. void operator() (Args ...args) const
  1203. {
  1204. for_each_if([&args...](callback_type & cb) -> bool
  1205. {
  1206. // We can't use std::forward here, because if we use std::forward,
  1207. // for arg that is passed by value, and the callback prototype accepts it by value,
  1208. // std::forward will move it and may cause the original value invalid.
  1209. // That happens on any value-to-value passing, no matter the callback moves it or not.
  1210. cb(args...);
  1211. return can_continue_invoking_type::can_continue_invoking(args...);
  1212. });
  1213. }
  1214. #else
  1215. // This is a patch version for GCC 4. It inlines the unrolled do_for_each_if.
  1216. // GCC 4.8.3 doesn't supporting parameter pack catpure in lambda, see,
  1217. // https://github.com/wqking/eventpp/issues/19
  1218. // This is a compromised patch for GCC 4, it may be not maintained or updated unless there are bugs.
  1219. // We don't use the patch as main code because the patch generates longer code, and duplicated with do_for_each_if.
  1220. void operator() (Args ...args) const
  1221. {
  1222. node_ptr n;
  1223. {
  1224. typename thread_type::template shared_lock<mutex_type> guard(list_mtx_);
  1225. n = head;
  1226. }
  1227. const counter_type counter = current_counter_.load(std::memory_order_acquire);
  1228. while(n)
  1229. {
  1230. if(n->counter != removed_counter && counter >= n->counter)
  1231. {
  1232. n->callback(args...);
  1233. if(! can_continue_invoking_type::can_continue_invoking(args...))
  1234. {
  1235. break;
  1236. }
  1237. }
  1238. {
  1239. typename thread_type::template shared_lock<mutex_type> guard(list_mtx_);
  1240. n = n->next;
  1241. }
  1242. }
  1243. }
  1244. #endif
  1245. private:
  1246. template <typename F>
  1247. bool do_for_each_if(F && f) const
  1248. {
  1249. node_ptr n;
  1250. {
  1251. typename thread_type::template shared_lock<mutex_type> guard(list_mtx_);
  1252. n = head;
  1253. }
  1254. const counter_type counter = current_counter_.load(std::memory_order_acquire);
  1255. while(n)
  1256. {
  1257. if(n->counter != removed_counter && counter >= n->counter)
  1258. {
  1259. if(! f(n))
  1260. {
  1261. return false;
  1262. }
  1263. }
  1264. {
  1265. typename thread_type::template shared_lock<mutex_type> guard(list_mtx_);
  1266. n = n->next;
  1267. }
  1268. }
  1269. return true;
  1270. }
  1271. template <typename RT, typename Func>
  1272. inline auto do_for_each_invoke(Func && func, node_ptr & n) const
  1273. -> typename std::enable_if<can_invoke<Func, node_wptr, callback_type &>::value, RT>::type
  1274. {
  1275. return func(node_wptr(n), n->callback);
  1276. }
  1277. template <typename RT, typename Func>
  1278. inline auto do_for_each_invoke(Func && func, node_ptr & n) const
  1279. -> typename std::enable_if<can_invoke<Func, callback_type &>::value, RT>::type
  1280. {
  1281. return func(n->callback);
  1282. }
  1283. void do_insert(node_ptr & n, node_ptr & before_node)
  1284. {
  1285. n->prev = before_node->prev;
  1286. n->next = before_node;
  1287. if(before_node->prev)
  1288. {
  1289. before_node->prev->next = n;
  1290. }
  1291. before_node->prev = n;
  1292. if(before_node == head)
  1293. {
  1294. head = n;
  1295. }
  1296. }
  1297. inline node_ptr do_allocate_node(const listener_name_type& name, const event_type& e, callback_type cb)
  1298. {
  1299. return std::make_shared<node>(name, e, std::move(cb), get_next_counter());
  1300. }
  1301. void do_free_node(const node_ptr & cn)
  1302. {
  1303. node_ptr & n = const_cast<node_ptr &>(cn);
  1304. if(n->next)
  1305. {
  1306. n->next->prev = n->prev;
  1307. }
  1308. if(n->prev)
  1309. {
  1310. n->prev->next = n->next;
  1311. }
  1312. // Mark it as deleted, this must be before the assignment of head and tail below,
  1313. // because node can be a reference to head or tail, and after the assignment, node
  1314. // can be null pointer.
  1315. n->counter = removed_counter;
  1316. if(head == n)
  1317. {
  1318. head = n->next;
  1319. }
  1320. if(tail == n)
  1321. {
  1322. tail = n->prev;
  1323. }
  1324. // don't modify n->prev or n->next
  1325. // because node may be still used in a loop.
  1326. }
  1327. void do_free_all_nodes()
  1328. {
  1329. node_ptr n = head;
  1330. head.reset();
  1331. while(n)
  1332. {
  1333. node_ptr next = n->next;
  1334. n->prev.reset();
  1335. n->next.reset();
  1336. n = next;
  1337. }
  1338. n.reset();
  1339. }
  1340. counter_type get_next_counter()
  1341. {
  1342. counter_type result = ++current_counter_;;
  1343. if(result == 0)
  1344. {
  1345. // overflow, let's reset all nodes' counters.
  1346. {
  1347. typename thread_type::template unique_lock<mutex_type> guard(list_mtx_);
  1348. node_ptr n = head;
  1349. while(n)
  1350. {
  1351. n->counter = 1;
  1352. n = n->next;
  1353. }
  1354. }
  1355. result = ++current_counter_;
  1356. }
  1357. return result;
  1358. }
  1359. void copy_from(const node_ptr & from_head)
  1360. {
  1361. node_ptr from_node(from_head);
  1362. node_ptr n;
  1363. const counter_type counter = get_next_counter();
  1364. while(from_node)
  1365. {
  1366. const node_ptr next_node(std::make_shared<node>(from_node->evt, from_node->callback, counter));
  1367. next_node->prev = n;
  1368. if(n)
  1369. {
  1370. n->next = next_node;
  1371. }
  1372. else
  1373. {
  1374. n = next_node;
  1375. head = n;
  1376. }
  1377. n = next_node;
  1378. from_node = from_node->next;
  1379. }
  1380. tail = n;
  1381. }
  1382. private:
  1383. node_ptr head;
  1384. node_ptr tail;
  1385. mutable mutex_type list_mtx_;
  1386. typename thread_type::template atomic<counter_type> current_counter_;
  1387. std::size_t size_ = 0;
  1388. };
  1389. } //namespace dispatcheres
  1390. namespace dispatcheres {
  1391. template <
  1392. typename EventTypeT,
  1393. typename PrototypeT,
  1394. typename PolicyT = default_policy
  1395. >
  1396. class callback_list : public dispatcheres::callback_list_base<EventTypeT, PrototypeT, PolicyT>, public tag_callback_list
  1397. {
  1398. private:
  1399. using super = dispatcheres::callback_list_base<EventTypeT, PrototypeT, PolicyT>;
  1400. public:
  1401. using super::super;
  1402. friend void swap(callback_list & first, callback_list & second) noexcept
  1403. {
  1404. first.swap(second);
  1405. }
  1406. };
  1407. } //namespace dispatcheres
  1408. //-------------------------------------------------------------------------------------------------
  1409. namespace dispatcheres {
  1410. template <
  1411. typename EventTypeT,
  1412. typename PolicyT,
  1413. typename MixinRootT,
  1414. typename ReturnType, typename ...Args
  1415. >
  1416. class event_dispatcher_base <
  1417. EventTypeT,
  1418. ReturnType (Args...),
  1419. PolicyT,
  1420. MixinRootT
  1421. >
  1422. {
  1423. public:
  1424. using this_type = event_dispatcher_base<
  1425. EventTypeT,
  1426. ReturnType (Args...),
  1427. PolicyT,
  1428. MixinRootT
  1429. >;
  1430. using mixin_root_type = typename std::conditional<
  1431. std::is_same<MixinRootT, void>::value,
  1432. this_type,
  1433. MixinRootT
  1434. >::type;
  1435. using policy_type = PolicyT;
  1436. using thread_type = typename select_thread<PolicyT, has_type_thread_t<PolicyT>::value>::type;
  1437. using argument_passing_mode_type = typename select_argument_passing_mode<
  1438. PolicyT,
  1439. has_type_argument_passing_mode<PolicyT>::value,
  1440. argument_passing_auto_detect
  1441. >::type;
  1442. using callback_type = typename select_callback<
  1443. PolicyT,
  1444. has_type_callback_t<PolicyT>::value,
  1445. std::function<ReturnType (Args...)>
  1446. >::type;
  1447. using callback_list_type = callback_list<EventTypeT, ReturnType (Args...), PolicyT>;
  1448. using listener_name_type = typename callback_list_type::listener_name_type;
  1449. using proto_type = ReturnType (Args...);
  1450. using map_type = typename select_map<
  1451. EventTypeT,
  1452. callback_list_type,
  1453. PolicyT,
  1454. has_template_map_t<PolicyT>::value
  1455. >::type;
  1456. using listener_name_map_type = typename select_listener_name_map<
  1457. listener_name_type,
  1458. EventTypeT,
  1459. typename callback_list_type::node_wptr,
  1460. PolicyT,
  1461. has_template_map_t<PolicyT>::value
  1462. >::type;
  1463. using mixins_type = typename dispatcheres::select_mixins<
  1464. PolicyT,
  1465. dispatcheres::has_type_mixins_t<PolicyT>::value
  1466. >::type;
  1467. public:
  1468. using listener_wptr = typename callback_list_type::node_wptr;
  1469. using listener_type = listener_wptr;
  1470. using event_type = EventTypeT;
  1471. using mutex_type = typename thread_type::mutex;
  1472. public:
  1473. event_dispatcher_base()
  1474. : listener_mtx_()
  1475. , listener_map_()
  1476. , listener_name_map_()
  1477. {
  1478. }
  1479. event_dispatcher_base(const event_dispatcher_base & other)
  1480. : listener_mtx_()
  1481. , listener_map_(other.listener_map_)
  1482. , listener_name_map_(other.listener_name_map_)
  1483. {
  1484. }
  1485. event_dispatcher_base(event_dispatcher_base && other) noexcept
  1486. : listener_mtx_()
  1487. , listener_map_(std::move(other.listener_map_))
  1488. , listener_name_map_(std::move(other.listener_name_map_))
  1489. {
  1490. }
  1491. event_dispatcher_base & operator = (const event_dispatcher_base & other)
  1492. {
  1493. listener_map_ = other.listener_map_;
  1494. listener_name_map_ = other.listener_name_map_;
  1495. return *this;
  1496. }
  1497. event_dispatcher_base & operator = (event_dispatcher_base && other) noexcept
  1498. {
  1499. listener_map_ = std::move(other.listener_map_);
  1500. listener_name_map_ = std::move(other.listener_name_map_);
  1501. return *this;
  1502. }
  1503. void swap(event_dispatcher_base & other) noexcept
  1504. {
  1505. using std::swap;
  1506. swap(listener_map_, other.listener_map_);
  1507. swap(listener_name_map_, other.listener_name_map_);
  1508. }
  1509. listener_wptr append_listener(const event_type& e, callback_type cb)
  1510. {
  1511. return append_listener(listener_name_type{}, e, std::move(cb));
  1512. }
  1513. std::vector<listener_wptr> append_listener(const std::initializer_list<event_type>& es, const callback_type& cb)
  1514. {
  1515. return append_listener(listener_name_type{}, es, cb);
  1516. }
  1517. listener_wptr prepend_listener(const event_type& e, callback_type cb)
  1518. {
  1519. return prepend_listener(listener_name_type{}, e, std::move(cb));
  1520. }
  1521. std::vector<listener_wptr> prepend_listener(const std::initializer_list<event_type>& es, const callback_type& cb)
  1522. {
  1523. return prepend_listener(listener_name_type{}, es, cb);
  1524. }
  1525. listener_wptr insert_listener(const event_type& e, callback_type cb, const listener_wptr & before)
  1526. {
  1527. return insert_listener(listener_name_type{}, e, std::move(cb), before);
  1528. }
  1529. template<class Function>
  1530. typename std::enable_if_t<can_invoke<Function, typename callback_list_type::node_ptr&>::value, listener_wptr>
  1531. insert_listener(const event_type& e, callback_type cb, Function&& pred)
  1532. {
  1533. return insert_listener(listener_name_type{}, e, std::move(cb), std::forward<Function>(pred));
  1534. }
  1535. listener_wptr append_listener(const listener_name_type& name, const event_type& e, callback_type cb)
  1536. {
  1537. typename thread_type::template unique_lock<mutex_type> guard(listener_mtx_);
  1538. listener_wptr ptr = listener_map_[e].append(name, e, std::move(cb));
  1539. listener_name_map_[name].emplace(e, ptr);
  1540. return ptr;
  1541. }
  1542. std::vector<listener_wptr> append_listener(
  1543. const listener_name_type& name, const std::initializer_list<event_type>& es, const callback_type& cb)
  1544. {
  1545. typename thread_type::template unique_lock<mutex_type> guard(listener_mtx_);
  1546. std::vector<listener_wptr> v;
  1547. v.reserve(es.size());
  1548. for (auto& e : es)
  1549. {
  1550. listener_wptr ptr = listener_map_[e].append(name, e, cb);
  1551. listener_name_map_[name].emplace(e, ptr);
  1552. v.emplace_back(std::move(ptr));
  1553. }
  1554. return v;
  1555. }
  1556. listener_wptr prepend_listener(const listener_name_type& name, const event_type & e, callback_type cb)
  1557. {
  1558. typename thread_type::template unique_lock<mutex_type> guard(listener_mtx_);
  1559. listener_wptr ptr = listener_map_[e].prepend(name, e, std::move(cb));
  1560. listener_name_map_[name].emplace(e, ptr);
  1561. return ptr;
  1562. }
  1563. std::vector<listener_wptr> prepend_listener(
  1564. const listener_name_type& name, const std::initializer_list<event_type>& es, const callback_type& cb)
  1565. {
  1566. typename thread_type::template unique_lock<mutex_type> guard(listener_mtx_);
  1567. std::vector<listener_wptr> v;
  1568. v.reserve(es.size());
  1569. for (auto it = std::rbegin(es); it != std::rend(es); ++it)
  1570. {
  1571. listener_wptr ptr = listener_map_[*it].prepend(name, *it, cb);
  1572. listener_name_map_[name].emplace(*it, ptr);
  1573. v.emplace(v.begin(), std::move(ptr));
  1574. }
  1575. return v;
  1576. }
  1577. listener_wptr insert_listener(
  1578. const listener_name_type& name, const event_type& e, callback_type cb, const listener_wptr & before)
  1579. {
  1580. auto n = before.lock();
  1581. typename thread_type::template unique_lock<mutex_type> guard(listener_mtx_);
  1582. if (n)
  1583. {
  1584. if (n->evt != e)
  1585. {
  1586. #if defined(_DEBUG) || defined(DEBUG)
  1587. assert(false);
  1588. #endif
  1589. return listener_wptr();
  1590. }
  1591. }
  1592. listener_wptr ptr = listener_map_[e].insert(name, e, std::move(cb), before);
  1593. listener_name_map_[name].emplace(e, ptr);
  1594. return ptr;
  1595. }
  1596. /**
  1597. * @param pred The check function, use to determin which listener of the new listener will be insert before
  1598. * the "pred" Function signature : bool(auto& listener_ptr)
  1599. * eg:
  1600. * dispatcher.insert_listener("listener_a", 3,
  1601. * []()
  1602. * {
  1603. * // this is the listener callback function
  1604. * },
  1605. * [index](auto& listener_ptr) -> bool
  1606. * {
  1607. * // this is the check function
  1608. *
  1609. * return (index < listener_ptr->get_user_data());
  1610. *
  1611. * // if this function return true , the new listener will be insert before "listener_ptr"
  1612. * // if this function return false, then will be check the next listener in the list
  1613. * // if all checks return false, then the new listener will be append after the tail.
  1614. * }
  1615. * );
  1616. */
  1617. template<class Function>
  1618. typename std::enable_if_t<can_invoke<Function, typename callback_list_type::node_ptr&>::value, listener_wptr>
  1619. insert_listener(const listener_name_type& name, const event_type & e, callback_type cb, Function&& pred)
  1620. {
  1621. typename thread_type::template unique_lock<mutex_type> guard(listener_mtx_);
  1622. // Returns a reference to the value that is mapped to a key equivalent to key,
  1623. // performing an insertion if such key does not already exist.
  1624. callback_list_type& cblist = listener_map_[e];
  1625. for (auto it = cblist.begin(); it != cblist.end(); ++it)
  1626. {
  1627. if (pred(*it))
  1628. {
  1629. listener_wptr ptr = cblist.insert(name, e, std::move(cb), *it);
  1630. listener_name_map_[name].emplace(e, ptr);
  1631. return ptr;
  1632. }
  1633. }
  1634. listener_wptr ptr = cblist.append(name, e, std::move(cb));
  1635. listener_name_map_[name].emplace(e, ptr);
  1636. return ptr;
  1637. }
  1638. bool remove_listener(const listener_wptr& listener)
  1639. {
  1640. auto n = listener.lock();
  1641. if (n)
  1642. {
  1643. typename thread_type::template unique_lock<mutex_type> guard(listener_mtx_);
  1644. auto it1 = listener_name_map_.find(n->name);
  1645. if (it1 != this->listener_name_map_.end())
  1646. {
  1647. auto& inner_map = it1->second;
  1648. auto&& [beg, end] = inner_map.equal_range(n->evt);
  1649. for (auto it = beg; it != end; ++it)
  1650. {
  1651. if (it->second.lock().get() == n.get())
  1652. {
  1653. inner_map.erase(it);
  1654. break;
  1655. }
  1656. }
  1657. if (inner_map.empty())
  1658. {
  1659. listener_name_map_.erase(n->name);
  1660. }
  1661. }
  1662. auto it2 = this->listener_map_.find(n->evt);
  1663. if (it2 != this->listener_map_.end())
  1664. {
  1665. callback_list_type& cblist = it2->second;
  1666. bool r = cblist.remove(listener);
  1667. if (cblist.empty())
  1668. {
  1669. this->listener_map_.erase(n->evt);
  1670. }
  1671. return r;
  1672. }
  1673. }
  1674. return false;
  1675. }
  1676. bool remove_listener(const listener_name_type& name, const event_type & e)
  1677. {
  1678. typename thread_type::template unique_lock<mutex_type> guard(listener_mtx_);
  1679. auto it1 = this->listener_name_map_.find(name);
  1680. auto it2 = this->listener_map_.find(e);
  1681. if (it1 != this->listener_name_map_.end() && it2 != this->listener_map_.end())
  1682. {
  1683. callback_list_type& cblist = it2->second;
  1684. auto& inner_map = it1->second;
  1685. auto&& [beg, end] = inner_map.equal_range(e);
  1686. bool r = false;
  1687. for (auto it = beg; it != end;)
  1688. {
  1689. r |= cblist.remove(it->second);
  1690. it = inner_map.erase(it);
  1691. }
  1692. if (inner_map.empty())
  1693. {
  1694. this->listener_name_map_.erase(name);
  1695. }
  1696. if (cblist.empty())
  1697. {
  1698. this->listener_map_.erase(e);
  1699. }
  1700. return r;
  1701. }
  1702. return false;
  1703. }
  1704. bool remove_listener(const listener_name_type& name)
  1705. {
  1706. typename thread_type::template unique_lock<mutex_type> guard(listener_mtx_);
  1707. auto it1 = listener_name_map_.find(name);
  1708. if (it1 != this->listener_name_map_.end())
  1709. {
  1710. bool r = false;
  1711. auto& inner_map = it1->second;
  1712. for (auto it = inner_map.begin(); it != inner_map.end();)
  1713. {
  1714. auto n = it->second.lock();
  1715. if (n)
  1716. {
  1717. auto it2 = this->listener_map_.find(n->evt);
  1718. if (it2 != this->listener_map_.end())
  1719. {
  1720. callback_list_type& cblist = it2->second;
  1721. r |= cblist.remove(it->second);
  1722. if (cblist.empty())
  1723. {
  1724. this->listener_map_.erase(n->evt);
  1725. }
  1726. }
  1727. }
  1728. it = inner_map.erase(it);
  1729. }
  1730. if (inner_map.empty())
  1731. {
  1732. listener_name_map_.erase(name);
  1733. }
  1734. return r;
  1735. }
  1736. return false;
  1737. }
  1738. void clear_all_listeners() noexcept
  1739. {
  1740. typename thread_type::template unique_lock<mutex_type> guard(listener_mtx_);
  1741. for (auto& [e, cblist] : listener_map_)
  1742. {
  1743. std::ignore = e;
  1744. cblist.clear();
  1745. }
  1746. listener_map_.clear();
  1747. listener_name_map_.clear();
  1748. }
  1749. void reserve(std::size_t new_cap)
  1750. {
  1751. typename thread_type::template unique_lock<mutex_type> guard(listener_mtx_);
  1752. this->do_reserve(listener_map_, new_cap);
  1753. this->do_reserve(listener_name_map_, new_cap);
  1754. }
  1755. std::size_t get_listener_count(const event_type& e)
  1756. {
  1757. const callback_list_type* callable_list = do_find_callable_list(e);
  1758. if (callable_list)
  1759. {
  1760. return callable_list->size();
  1761. }
  1762. return 0;
  1763. }
  1764. /**
  1765. * Note : the "listener_name_type" maybe equal to the "event_type".
  1766. * so we can't use this function overloading, but we can use the std::optional<event_type>.
  1767. */
  1768. //std::size_t get_listener_count_by_name(const listener_name_type& name) {...}
  1769. std::size_t get_listener_count(const listener_name_type& name, std::optional<event_type> e = std::nullopt)
  1770. {
  1771. typename thread_type::template shared_lock<mutex_type> guard(listener_mtx_);
  1772. if (listener_name_map_.empty())
  1773. return 0;
  1774. auto it = listener_name_map_.find(name);
  1775. if (it != listener_name_map_.end())
  1776. {
  1777. if (e.has_value())
  1778. return it->second.count(e.value());
  1779. else
  1780. return it->second.size();
  1781. }
  1782. return 0;
  1783. }
  1784. std::size_t get_listener_count()
  1785. {
  1786. std::size_t count = 0;
  1787. typename thread_type::template shared_lock<mutex_type> guard(listener_mtx_);
  1788. if (listener_map_.empty())
  1789. return 0;
  1790. for (auto& [e, cblist] : listener_map_)
  1791. {
  1792. std::ignore = e;
  1793. count += cblist.size();
  1794. }
  1795. #if defined(_DEBUG) || defined(DEBUG)
  1796. std::size_t count2 = 0;
  1797. for (auto&[name, mulmap] : listener_name_map_)
  1798. {
  1799. std::ignore = name;
  1800. count2 += mulmap.size();
  1801. }
  1802. assert(count == count2);
  1803. #endif
  1804. return count;
  1805. }
  1806. bool has_any_listener(const event_type & e) const
  1807. {
  1808. const callback_list_type * callable_list = do_find_callable_list(e);
  1809. if(callable_list)
  1810. {
  1811. return ! callable_list->empty();
  1812. }
  1813. return false;
  1814. }
  1815. inline callback_list_type* find_listeners(const event_type & e)
  1816. {
  1817. return do_find_callable_list(e);
  1818. }
  1819. /**
  1820. * @param pred Find the listener by user defined rule
  1821. * the "pred" Function signature : bool(auto& listener_ptr)
  1822. */
  1823. template<class Function>
  1824. inline listener_wptr find_listener_if(const event_type & e, Function&& pred)
  1825. {
  1826. typename thread_type::template shared_lock<mutex_type> guard(listener_mtx_);
  1827. auto it1 = this->listener_map_.find(e);
  1828. if (it1 != this->listener_map_.end())
  1829. {
  1830. callback_list_type& cblist = it1->second;
  1831. for (auto it2 = cblist.begin(); it2 != cblist.end(); ++it2)
  1832. {
  1833. if (pred(*it2))
  1834. {
  1835. return listener_wptr(*it2);
  1836. }
  1837. }
  1838. }
  1839. return listener_wptr();
  1840. }
  1841. template <typename Func>
  1842. void for_each(Func&& func) const
  1843. {
  1844. typename thread_type::template shared_lock<mutex_type> guard(listener_mtx_);
  1845. for (auto& [e, cblist] : this->listener_map_)
  1846. {
  1847. std::ignore = e;
  1848. cblist.for_each(func);
  1849. }
  1850. }
  1851. template <typename Func>
  1852. void for_each(const event_type & e, Func && func) const
  1853. {
  1854. const callback_list_type * callable_list = do_find_callable_list(e);
  1855. if(callable_list)
  1856. {
  1857. callable_list->for_each(std::forward<Func>(func));
  1858. }
  1859. }
  1860. template <typename Func>
  1861. bool for_each_if(const event_type & e, Func && func) const
  1862. {
  1863. const callback_list_type * callable_list = do_find_callable_list(e);
  1864. if (callable_list)
  1865. {
  1866. return callable_list->for_each_if(std::forward<Func>(func));
  1867. }
  1868. return true;
  1869. }
  1870. void dispatch(Args ...args) const
  1871. {
  1872. static_assert(argument_passing_mode_type::can_include_event_type,
  1873. "Dispatching arguments count doesn't match required (event type should be included).");
  1874. using get_event_t = typename select_get_event<
  1875. PolicyT, EventTypeT, has_function_get_event<PolicyT, Args...>::value>::type;
  1876. const event_type e = get_event_t::get_event(args...);
  1877. direct_dispatch(e, std::forward<Args>(args)...);
  1878. }
  1879. template <typename T>
  1880. void dispatch(T && first, Args ...args) const
  1881. {
  1882. static_assert(argument_passing_mode_type::can_exclude_event_type,
  1883. "Dispatching arguments count doesn't match required (event type should NOT be included).");
  1884. using get_event_t = typename select_get_event<
  1885. PolicyT, EventTypeT, has_function_get_event<PolicyT, T &&, Args...>::value>::type;
  1886. const event_type e = get_event_t::get_event(std::forward<T>(first), args...);
  1887. direct_dispatch(e, std::forward<Args>(args)...);
  1888. }
  1889. // Bypass any get_event policy. The first argument is the event type.
  1890. // Most used for internal purpose.
  1891. void direct_dispatch(const event_type & e, Args ...args) const
  1892. {
  1893. if(! dispatcheres::for_each_mixins<mixin_root_type, mixins_type, do_mixin_before_dispatch>::for_each(
  1894. this, typename std::add_lvalue_reference<Args>::type(args)...))
  1895. {
  1896. return;
  1897. }
  1898. const callback_list_type * callable_list = do_find_callable_list(e);
  1899. if(callable_list)
  1900. {
  1901. (*callable_list)(std::forward<Args>(args)...);
  1902. }
  1903. }
  1904. protected:
  1905. inline const callback_list_type * do_find_callable_list(const event_type & e) const
  1906. {
  1907. return do_find_callable_list_helper(this, e);
  1908. }
  1909. inline callback_list_type * do_find_callable_list(const event_type & e)
  1910. {
  1911. return do_find_callable_list_helper(this, e);
  1912. }
  1913. template<class M>
  1914. inline void do_reserve(M& map, std::size_t new_cap)
  1915. {
  1916. if constexpr (has_member_reserve<M, void, std::size_t>::value)
  1917. {
  1918. map.reserve(new_cap);
  1919. }
  1920. else
  1921. {
  1922. std::ignore = map;
  1923. std::ignore = new_cap;
  1924. }
  1925. }
  1926. private:
  1927. // template helper to avoid code duplication in do_find_callable_list
  1928. template <typename T>
  1929. static auto do_find_callable_list_helper(T * self, const event_type & e)
  1930. -> typename std::conditional<std::is_const<T>::value, const callback_list_type *, callback_list_type *>::type
  1931. {
  1932. if (self->listener_map_.empty())
  1933. return nullptr;
  1934. typename thread_type::template shared_lock<mutex_type> guard(self->listener_mtx_);
  1935. auto it = self->listener_map_.find(e);
  1936. if(it != self->listener_map_.end())
  1937. {
  1938. return std::addressof(it->second);
  1939. }
  1940. else
  1941. {
  1942. return nullptr;
  1943. }
  1944. }
  1945. private:
  1946. // Mixin related
  1947. struct do_mixin_before_dispatch
  1948. {
  1949. template <typename T, typename Self, typename ...A>
  1950. static auto for_each(const Self * self, A && ...args)
  1951. -> typename std::enable_if<has_function_mixin_before_dispatch<T, A...>::value, bool>::type
  1952. {
  1953. return static_cast<const T *>(self)->mixin_before_dispatch(std::forward<A>(args)...);
  1954. }
  1955. template <typename T, typename Self, typename ...A>
  1956. static auto for_each(const Self * /*self*/, A && ... /*args*/)
  1957. -> typename std::enable_if<! has_function_mixin_before_dispatch<T, A...>::value, bool>::type
  1958. {
  1959. return true;
  1960. }
  1961. };
  1962. private:
  1963. mutable mutex_type listener_mtx_;
  1964. map_type listener_map_;
  1965. listener_name_map_type listener_name_map_;
  1966. };
  1967. } //namespace dispatcheres
  1968. //-------------------------------------------------------------------------------------------------
  1969. namespace dispatcheres {
  1970. template <typename Base>
  1971. class mixin_filter : public Base
  1972. {
  1973. private:
  1974. using super = Base;
  1975. using bool_reference_prototype = typename dispatcheres::replace_return_type<
  1976. typename dispatcheres::transform_arguments<
  1977. typename super::proto_type,
  1978. std::add_lvalue_reference
  1979. >::type,
  1980. bool
  1981. >::type;
  1982. using filter_func_type = std::function<bool_reference_prototype>;
  1983. using filter_list_type = callback_list<char, bool_reference_prototype>;
  1984. using listener_name_type = typename filter_list_type::listener_name_type;
  1985. public:
  1986. using filter_wptr = typename filter_list_type::node_wptr;
  1987. using filter_type = filter_wptr;
  1988. public:
  1989. inline filter_wptr append_filter(const filter_func_type& filter_func)
  1990. {
  1991. return filter_list_.append(listener_name_type{}, '0', filter_func);
  1992. }
  1993. inline bool remove_filter(const filter_wptr & filter)
  1994. {
  1995. return filter_list_.remove(filter);
  1996. }
  1997. inline void clear_all_filters() noexcept
  1998. {
  1999. return filter_list_.clear();
  2000. }
  2001. inline std::size_t get_filter_count() const noexcept
  2002. {
  2003. return filter_list_.size();
  2004. }
  2005. template <typename ...Args>
  2006. inline bool mixin_before_dispatch(Args && ...args) const
  2007. {
  2008. if(! filter_list_.empty())
  2009. {
  2010. if(! filter_list_.for_each_if([&args...](typename filter_list_type::callback_type & cb)
  2011. {
  2012. return cb(args...);
  2013. })
  2014. )
  2015. {
  2016. return false;
  2017. }
  2018. }
  2019. return true;
  2020. }
  2021. private:
  2022. filter_list_type filter_list_;
  2023. };
  2024. } //namespace dispatcheres
  2025. //-------------------------------------------------------------------------------------------------
  2026. template <
  2027. typename EventT,
  2028. typename PrototypeT,
  2029. typename PolicyT = dispatcheres::default_policy
  2030. >
  2031. class event_dispatcher : public dispatcheres::inherit_mixins<
  2032. dispatcheres::event_dispatcher_base<EventT, PrototypeT, PolicyT, void>,
  2033. typename dispatcheres::select_mixins<PolicyT, dispatcheres::has_type_mixins_t<PolicyT>::value >::type
  2034. >::type, public dispatcheres::tag_event_dispatcher
  2035. {
  2036. private:
  2037. using super = typename dispatcheres::inherit_mixins<
  2038. dispatcheres::event_dispatcher_base<EventT, PrototypeT, PolicyT, void>,
  2039. typename dispatcheres::select_mixins<PolicyT, dispatcheres::has_type_mixins_t<PolicyT>::value >::type
  2040. >::type;
  2041. public:
  2042. using super::super;
  2043. friend void swap(event_dispatcher & first, event_dispatcher & second) noexcept
  2044. {
  2045. first.swap(second);
  2046. }
  2047. };
  2048. } //namespace asio2
  2049. #endif