Easy3D 2.5.3
signal.h
1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
27#ifndef EASY3D_CORE_SIGNAL_H
28#define EASY3D_CORE_SIGNAL_H
29
30
31#include <functional>
32#include <unordered_map>
33
34
35namespace easy3d {
36
55 template<typename... Args>
56 class Signal {
57
58 public:
59 Signal() = default;
60 ~Signal() { disconnect_all(); }
61
63 Signal(Signal const & /*unused*/) {}
64
66 Signal(Signal &&other) noexcept:
67 slots_(std::move(other.slots_)),
68 current_id_(other.current_id_) {
69 }
70
72 Signal &operator=(Signal &&other) noexcept {
73 if (this != &other) {
74 slots_ = std::move(other.slots_);
75 current_id_ = other.current_id_;
76 }
77 return *this;
78 }
79
81 Signal &operator=(Signal const &other) {
82 if (this != &other) {
84 }
85 return *this;
86 }
87
97 int connect(std::function<void(Args...)> const &slot) {
98 slots_.insert(std::make_pair(++current_id_, slot));
99 return current_id_;
100 }
101
114 template<typename Class>
115 int connect(Class *inst, void (Class::*func)(Args...)) {
116 return connect([=](Args... args) {
117 (inst->*func)(args...);
118 });
119 }
120
133 template<typename Class>
134 int connect(Class *inst, void (Class::*func)(Args...) const) {
135 return connect([=](Args... args) {
136 (inst->*func)(args...);
137 });
138 }
139
145 int connect(Signal<Args...> *receiver) {
146 return connect(receiver, &Signal<Args...>::send);
147 }
148
150 void disconnect(int id) {
151 slots_.erase(id);
152 }
153
156 slots_.clear();
157 }
158
160 void send(Args... p) {
161 for (auto const &it : slots_) {
162 it.second(p...);
163 }
164 }
165
167 void send_for_all_but_one(int excludedConnectionID, Args... p) {
168 for (auto const &it : slots_) {
169 if (it.first != excludedConnectionID) {
170 it.second(p...);
171 }
172 }
173 }
174
176 void emit_for(int connectionID, Args... p) {
177 auto const &it = slots_.find(connectionID);
178 if (it != slots_.end()) {
179 it->second(p...);
180 }
181 }
182
183 private:
184 std::unordered_map<int, std::function<void(Args...)>> slots_;
185 int current_id_{0};
186 };
187
188
190
191
201 template<typename SIGNAL, typename FUNCTION>
202 inline int connect(SIGNAL *signal, FUNCTION const &slot) {
203 return signal->connect(slot);
204 }
205
218 template<typename SIGNAL, typename CLASS, typename FUNCTION>
219 inline int connect(SIGNAL *signal, CLASS *inst, FUNCTION const &slot) {
220 return signal->connect(inst, slot);
221 }
222
228 template<typename... Args>
229 int connect(Signal<Args...> *sender, Signal<Args...> *receiver) {
230 return sender->connect(receiver);
231 }
232
234 template<typename SIGNAL>
235 inline void disconnect(SIGNAL *signal, int id) {
236 signal->disconnect(id);
237 }
238
240 template<typename SIGNAL>
241 inline void disconnect_all(SIGNAL *signal) {
242 signal->disconnect_all();
243 }
245
247
248
263 template <typename... Args>
264 inline constexpr auto overload(void (*func)(Args...)) -> void (*)(Args...) {
265 return func;
266 }
267
286 template <typename C, typename... Args>
287 inline constexpr auto overload(void (C::*func)(Args...)) -> void (C::*)(Args...) {
288 return func;
289 }
291
292
294
295
320}
321
322
323#endif // EASY3D_CORE_SIGNAL_H
A light-weight implementation of the simple signal-slot mechanism.
Definition: signal.h:56
void disconnect_all()
Disconnects all previously connected functions.
Definition: signal.h:155
void send_for_all_but_one(int excludedConnectionID, Args... p)
Calls all connected functions except for one.
Definition: signal.h:167
int connect(Class *inst, void(Class::*func)(Args...) const)
Connects a const member function of an object to this signal.
Definition: signal.h:134
void emit_for(int connectionID, Args... p)
Calls only one connected function.
Definition: signal.h:176
int connect(std::function< void(Args...)> const &slot)
Connects a function to this signal.
Definition: signal.h:97
void send(Args... p)
Calls all connected functions.
Definition: signal.h:160
Signal(Signal const &)
Copy constructor and assignment create a new signal.
Definition: signal.h:63
int connect(Signal< Args... > *receiver)
Connects this signal to another signal receiver.
Definition: signal.h:145
Signal(Signal &&other) noexcept
Move constructor.
Definition: signal.h:66
Signal & operator=(Signal &&other) noexcept
The assignment operator.
Definition: signal.h:72
int connect(Class *inst, void(Class::*func)(Args...))
Connects a member function of an object to this signal.
Definition: signal.h:115
void disconnect(int id)
Disconnects a previously connected function.
Definition: signal.h:150
Signal & operator=(Signal const &other)
The assignment operator.
Definition: signal.h:81
Definition: collider.cpp:182
void disconnect(SIGNAL *signal, int id)
Disconnects a previously connected function.
Definition: signal.h:235
int connect(SIGNAL *signal, FUNCTION const &slot)
Connects a function to the signal.
Definition: signal.h:202
void disconnect_all(SIGNAL *signal)
Disconnects all previously connected functions.
Definition: signal.h:241
constexpr auto overload(void(*func)(Args...)) -> void(*)(Args...)
Helper function for resolving overloaded non-member functions.
Definition: signal.h:264