Antkeeper  0.0.1
dispatcher.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_EVENT_DISPATCHER_HPP
21 #define ANTKEEPER_EVENT_DISPATCHER_HPP
22 
25 #include <any>
26 #include <map>
27 #include <memory>
28 #include <typeindex>
29 #include <utility>
30 
31 namespace event {
32 
37 {
38 public:
49  template <class T>
50  [[nodiscard]] std::shared_ptr<subscription> subscribe(subscriber<T>&& subscriber)
51  {
52  // Allocate shared pointer to std::any object containing subscriber
53  std::shared_ptr<std::any> shared_subscriber = std::make_shared<std::any>(std::make_any<event::subscriber<T>>(std::move(subscriber)));
54 
55  // Append subscriber to subscriber list and store iterator
56  auto iterator = subscribers.emplace(std::type_index(typeid(T)), shared_subscriber);
57 
58  // Construct and return a shared subscription object which removes the subscriber from the subscriber list when unsubscribed or destructed
59  return std::make_shared<subscription>
60  (
61  std::static_pointer_cast<void>(shared_subscriber),
62  [this, iterator = std::move(iterator)]()
63  {
64  this->subscribers.erase(iterator);
65  }
66  );
67  }
68 
76  template <class T>
77  void dispatch(const T& message) const
78  {
79  // For each subscriber of the given message type
80  const auto range = subscribers.equal_range(std::type_index(typeid(T)));
81  for (auto i = range.first; i != range.second; ++i)
82  {
83  // Send message to subscriber
84  std::any_cast<subscriber<T>>(*(i->second))(message);
85  }
86  }
87 
88 private:
89  std::multimap<std::type_index, std::shared_ptr<std::any>> subscribers;
90 };
91 
92 } // namespace event
93 
94 #endif // ANTKEEPER_EVENT_DISPATCHER_HPP
Forwards messages from publishers to subscribers.
Definition: dispatcher.hpp:37
std::shared_ptr< subscription > subscribe(subscriber< T > &&subscriber)
Subscribes a function object to messages dispatched by this dispatcher.
Definition: dispatcher.hpp:50
void dispatch(const T &message) const
Dispatches a message to subscribers of the message type.
Definition: dispatcher.hpp:77
Publish-subscribe messaging.
Definition: channel.hpp:32
std::function< void(const T &)> subscriber
Subscriber function object type.
Definition: subscriber.hpp:33