2
3
4
5
6
8#ifndef SUBSCRIBABLEEVENT_HPP
9#define SUBSCRIBABLEEVENT_HPP
20
21
22
23
24
25
27 template<
typename ...Args>
37
38
42
43
47
48
52
53
54
59 static constexpr Token Subscribe{};
62
63
64
65
69 static constexpr char Alive = 1;
70 std::shared_ptr<
char> alive;
77 std::vector<T> data{};
78 std::size_t endIdx{0};
80 ActiveList() =
default;
82 ActiveList(std::initializer_list<T> elems) : data(elems), endIdx(data.size()) {}
84 template<
typename ...Args>
85 explicit ActiveList(Args &&... args) : data(std::forward<Args>(args)...), endIdx(data.size()) {}
87 ActiveList(
const ActiveList &) =
default;
88 ActiveList(ActiveList &&other)
noexcept : ActiveList() {
91 ActiveList &operator=(ActiveList other)
noexcept {
96 ~ActiveList() =
default;
98 void swap(ActiveList &other)
noexcept {
100 swap(data, other.data);
101 swap(endIdx, other.endIdx);
104 void markInactive(std::vector<T>::iterator elem)
noexcept(std::is_nothrow_swappable_v<T>) {
109 const auto pos = elem - data.begin();
110 if (pos < 0
or static_cast<std::size_t>(pos) >= endIdx) {
115 if (endIdx !=
static_cast<std::size_t>(pos)) {
116 std::swap(data[pos], data[endIdx]);
120 auto begin()
const noexcept {
124 auto begin()
noexcept {
128 auto end()
const noexcept {
129 return data.begin() + endIdx;
132 auto end()
noexcept {
133 return data.begin() + endIdx;
137 data.erase(end(), data.end());
140 [[nodiscard]] std::size_t size()
const noexcept {
144 [[nodiscard]]
bool empty()
const noexcept {
148 template<
typename ...Args>
149 void add(Args &&...args) {
150 if (endIdx == data.size()) {
151 data.emplace_back(std::forward<Args>(args)...);
154 data.emplace_back(std::forward<Args>(args)...);
155 std::swap(data.back(), data[endIdx]);
161 auto &back()
const noexcept {
162 return data[endIdx - 1];
167 void swap(ActiveList<T> &a, ActiveList<T> &b)
noexcept {
173
174
175
176 template<
typename ...Args>
178 using handler = std::function<
void(Args...)>;
180 constexpr SubscribableEvent()
noexcept =
default;
187 ~SubscribableEvent() {
188 for (
auto &[_, handle]: handlers) {
194
195
196
197
198 template<
typename Handler>
200 subscribe(std::forward<Handler>(handlerFunction),
true);
204
205
206
207
208 template<
typename Handler>
210 return subscribe(std::forward<Handler>(handlerFunction),
false);
214
215
216
217 template<
typename ...InvokeArgs>
219 auto it = handlers.begin();
220 while (
not handlers.empty()
and it < handlers.end()) {
221 if (it->second.isSubscribed()) {
222 it->first(std::forward<InvokeArgs>(args)...);
225 handlers.markInactive(it);
231 template<
typename Handler>
232 SubscriberHandle subscribe(Handler &&handlerFunction,
bool discardHandler) {
233 static_assert(std::is_invocable_r_v<
void, Handler, Args...>,
"invalid event handler signature");
C# inspired event class that manages a list of event handlers that can be invoked together.
Definition SubscribableEvent.hpp:177
void subscribe_unhandled(Handler &&handlerFunction)
Definition SubscribableEvent.hpp:199
void trigger(InvokeArgs &&... args) const
Definition SubscribableEvent.hpp:218
SubscriberHandle subscribe_handled(Handler &&handlerFunction)
Definition SubscribableEvent.hpp:209
Identifies a function handler subscribed to a SubscribableEvent. Can be used to unsubscribe the funct...
Definition SubscribableEvent.hpp:26
void unregister() noexcept
Definition SubscribableEvent.cpp:9
SubscriberHandle(Token)
Definition SubscribableEvent.cpp:21
constexpr SubscriberHandle() noexcept=default
bool isSubscribed() const noexcept
Definition SubscribableEvent.cpp:23
~SubscriberHandle()
Definition SubscribableEvent.cpp:17
Definition heuristics.hpp:33
Definition basic_structures.cpp:10