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 
shutdown()23     void shutdown() {}
24 
25     Context& create();
26     void destroy(Context& context);
27 
28     template <class T>
send(const T & event)29     void send(const T& event)
30     {
31         using HandlerType = std::function<void(const T&)>;
32 
33         for (const auto& context : contexts_)
34         {
35             for (const auto& any : context->handlers)
36             {
37                 if (const HandlerType* handler =
38                         std::any_cast<HandlerType>(&any))
39                 {
40                     (*handler)(event);
41                 }
42             }
43         }
44     }
45 
46     static boost::asio::execution_context::id id;
47 
48   private:
49     std::vector<std::unique_ptr<Context>> contexts_;
50 };
51 
52 } // namespace utils
53