EnTT 3.13.0
Loading...
Searching...
No Matches
emitter.hpp
1#ifndef ENTT_SIGNAL_EMITTER_HPP
2#define ENTT_SIGNAL_EMITTER_HPP
3
4#include <functional>
5#include <type_traits>
6#include <utility>
7#include "../container/dense_map.hpp"
8#include "../core/compressed_pair.hpp"
9#include "../core/fwd.hpp"
10#include "../core/type_info.hpp"
11#include "../core/utility.hpp"
12#include "fwd.hpp"
13
14namespace entt {
15
35template<typename Derived, typename Allocator>
36class emitter {
37 using key_type = id_type;
38 using mapped_type = std::function<void(void *)>;
39
40 using alloc_traits = std::allocator_traits<Allocator>;
41 using container_allocator = typename alloc_traits::template rebind_alloc<std::pair<const key_type, mapped_type>>;
43
44public:
46 using allocator_type = Allocator;
48 using size_type = std::size_t;
49
53
58 explicit emitter(const allocator_type &allocator)
59 : handlers{allocator, allocator} {}
60
62 virtual ~emitter() noexcept {
63 static_assert(std::is_base_of_v<emitter<Derived, Allocator>, Derived>, "Invalid emitter type");
64 }
65
70 emitter(emitter &&other) noexcept
71 : handlers{std::move(other.handlers)} {}
72
78 emitter(emitter &&other, const allocator_type &allocator) noexcept
79 : handlers{container_type{std::move(other.handlers.first()), allocator}, allocator} {
80 ENTT_ASSERT(alloc_traits::is_always_equal::value || handlers.second() == other.handlers.second(), "Copying an emitter is not allowed");
81 }
82
88 emitter &operator=(emitter &&other) noexcept {
89 ENTT_ASSERT(alloc_traits::is_always_equal::value || handlers.second() == other.handlers.second(), "Copying an emitter is not allowed");
90
91 handlers = std::move(other.handlers);
92 return *this;
93 }
94
99 void swap(emitter &other) {
100 using std::swap;
101 swap(handlers, other.handlers);
102 }
103
108 [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
109 return handlers.second();
110 }
111
117 template<typename Type>
118 void publish(Type &&value) {
119 if(const auto id = type_id<Type>().hash(); handlers.first().contains(id)) {
120 handlers.first()[id](&value);
121 }
122 }
123
129 template<typename Type>
130 void on(std::function<void(Type &, Derived &)> func) {
131 handlers.first().insert_or_assign(type_id<Type>().hash(), [func = std::move(func), this](void *value) {
132 func(*static_cast<Type *>(value), static_cast<Derived &>(*this));
133 });
134 }
135
140 template<typename Type>
141 void erase() {
142 handlers.first().erase(type_hash<std::remove_cv_t<std::remove_reference_t<Type>>>::value());
143 }
144
146 void clear() noexcept {
147 handlers.first().clear();
148 }
149
155 template<typename Type>
156 [[nodiscard]] bool contains() const {
157 return handlers.first().contains(type_hash<std::remove_cv_t<std::remove_reference_t<Type>>>::value());
158 }
159
164 [[nodiscard]] bool empty() const noexcept {
165 return handlers.first().empty();
166 }
167
168private:
170};
171
172} // namespace entt
173
174#endif
A compressed pair.
constexpr second_type & second() noexcept
Returns the second element that a pair stores.
constexpr first_type & first() noexcept
Returns the first element that a pair stores.
Associative container for key-value pairs with unique keys.
General purpose event emitter.
Definition emitter.hpp:36
Allocator allocator_type
Allocator type.
Definition emitter.hpp:46
emitter(emitter &&other) noexcept
Move constructor.
Definition emitter.hpp:70
emitter & operator=(emitter &&other) noexcept
Move assignment operator.
Definition emitter.hpp:88
emitter(const allocator_type &allocator)
Constructs an emitter with a given allocator.
Definition emitter.hpp:58
void clear() noexcept
Disconnects all the listeners.
Definition emitter.hpp:146
emitter()
Default constructor.
Definition emitter.hpp:51
bool contains() const
Checks if there are listeners registered for the specific event.
Definition emitter.hpp:156
void publish(Type &&value)
Publishes a given event.
Definition emitter.hpp:118
void swap(emitter &other)
Exchanges the contents with those of a given emitter.
Definition emitter.hpp:99
void erase()
Disconnects a listener from the event emitter.
Definition emitter.hpp:141
std::size_t size_type
Unsigned integer type.
Definition emitter.hpp:48
virtual ~emitter() noexcept
Default destructor.
Definition emitter.hpp:62
bool empty() const noexcept
Checks if there are listeners registered with the event emitter.
Definition emitter.hpp:164
void on(std::function< void(Type &, Derived &)> func)
Registers a listener with the event emitter.
Definition emitter.hpp:130
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
Definition emitter.hpp:108
emitter(emitter &&other, const allocator_type &allocator) noexcept
Allocator-extended move constructor.
Definition emitter.hpp:78
EnTT default namespace.
Definition dense_map.hpp:21
std::uint32_t id_type
Alias declaration for type identifiers.
Definition fwd.hpp:13
Type hash.
Definition type_info.hpp:92