1 #pragma once
2 
3 #include <boost/asio.hpp>
4 
5 #include <any>
6 
7 namespace utils
8 {
9 
10 class MessangerService : public boost::asio::execution_context::service
11 {
12   public:
13     using key_type = MessangerService;
14 
15     struct Context
16     {
17         std::vector<std::any> handlers;
18     };
19 
20     MessangerService(boost::asio::execution_context& execution_context);
21     ~MessangerService() = default;
22 
23     void shutdown()
24     {}
25 
26     Context& create();
27     void destroy(Context& context);
28 
29     template <class T>
30     void send(const T& event)
31     {
32         using HandlerType = std::function<void(const T&)>;
33 
34         for (const auto& context : contexts_)
35         {
36             for (const auto& any : context->handlers)
37             {
38                 if (const HandlerType* handler =
39                         std::any_cast<HandlerType>(&any))
40                 {
41                     (*handler)(event);
42                 }
43             }
44         }
45     }
46 
47     static boost::asio::execution_context::id id;
48 
49   private:
50     std::vector<std::unique_ptr<Context>> contexts_;
51 };
52 
53 } // namespace utils
54