Easy3D 2.6.1
Loading...
Searching...
No Matches
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_UTIL_SIGNAL_H
28#define EASY3D_UTIL_SIGNAL_H
29
30
31#include <functional>
32#include <unordered_map>
33
34
35namespace easy3d {
36
52
53 template<typename... Args>
54 class Signal {
55
56 public:
57 Signal() = default;
58 ~Signal() { disconnect_all(); }
59
61 Signal(Signal const & /*unused*/) {}
62
64 Signal(Signal &&other) noexcept:
65 slots_(std::move(other.slots_)),
66 current_id_(other.current_id_) {
67 }
68
70 Signal &operator=(Signal &&other) noexcept {
71 if (this != &other) {
72 slots_ = std::move(other.slots_);
73 current_id_ = other.current_id_;
74 }
75 return *this;
76 }
77
79 Signal &operator=(Signal const &other) {
80 if (this != &other) {
82 }
83 return *this;
84 }
85
95 int connect(std::function<void(Args...)> const &slot) {
96 slots_.insert(std::make_pair(++current_id_, slot));
97 return current_id_;
98 }
99
112 template<typename Class>
113 int connect(Class *inst, void (Class::*func)(Args...)) {
114 return connect([=](Args... args) {
115 (inst->*func)(args...);
116 });
117 }
118
131 template<typename Class>
132 int connect(Class *inst, void (Class::*func)(Args...) const) {
133 return connect([=](Args... args) {
134 (inst->*func)(args...);
135 });
136 }
137
143 int connect(Signal<Args...> *receiver) {
144 return connect(receiver, &Signal<Args...>::send);
145 }
146
148 void disconnect(int id) {
149 slots_.erase(id);
150 }
151
154 slots_.clear();
155 }
156
158 void send(Args... p) {
159 for (auto const &it : slots_) {
160 it.second(p...);
161 }
162 }
163
165 void send_for_all_but_one(int excludedConnectionID, Args... p) {
166 for (auto const &it : slots_) {
167 if (it.first != excludedConnectionID) {
168 it.second(p...);
169 }
170 }
171 }
172
174 void emit_for(int connectionID, Args... p) {
175 auto const &it = slots_.find(connectionID);
176 if (it != slots_.end()) {
177 it->second(p...);
178 }
179 }
180
181 private:
182 std::unordered_map<int, std::function<void(Args...)>> slots_;
183 int current_id_{0};
184 };
185
186
188
189
199 template<typename SIGNAL, typename FUNCTION>
200 inline int connect(SIGNAL *signal, FUNCTION const &slot) {
201 return signal->connect(slot);
202 }
203
216 template<typename SIGNAL, typename CLASS, typename FUNCTION>
217 inline int connect(SIGNAL *signal, CLASS *inst, FUNCTION const &slot) {
218 return signal->connect(inst, slot);
219 }
220
226 template<typename... Args>
227 int connect(Signal<Args...> *sender, Signal<Args...> *receiver) {
228 return sender->connect(receiver);
229 }
230
232 template<typename SIGNAL>
233 inline void disconnect(SIGNAL *signal, int id) {
234 signal->disconnect(id);
235 }
236
238 template<typename SIGNAL>
239 inline void disconnect_all(SIGNAL *signal) {
240 signal->disconnect_all();
241 }
242
243
245
246
261 template <typename... Args>
262 inline constexpr auto overload(void (*func)(Args...)) -> void (*)(Args...) {
263 return func;
264 }
265
284 template <typename C, typename... Args>
285 inline constexpr auto overload(void (C::*func)(Args...)) -> void (C::*)(Args...) {
286 return func;
287 }
288
289
290
292
293
318}
319
320
321#endif // EASY3D_UTIL_SIGNAL_H
A light-weight implementation of the simple signal-slot mechanism.
Definition signal.h:54
void disconnect_all()
Disconnects all previously connected functions.
Definition signal.h:153
void send_for_all_but_one(int excludedConnectionID, Args... p)
Calls all connected functions except for one.
Definition signal.h:165
int connect(Class *inst, void(Class::*func)(Args...) const)
Connects a const member function of an object to this signal.
Definition signal.h:132
void emit_for(int connectionID, Args... p)
Calls only one connected function.
Definition signal.h:174
int connect(std::function< void(Args...)> const &slot)
Connects a function to this signal.
Definition signal.h:95
void send(Args... p)
Calls all connected functions.
Definition signal.h:158
Signal(Signal const &)
Copy constructor and assignment create a new signal.
Definition signal.h:61
int connect(Signal< Args... > *receiver)
Connects this signal to another signal receiver.
Definition signal.h:143
Signal(Signal &&other) noexcept
Move constructor.
Definition signal.h:64
Signal & operator=(Signal &&other) noexcept
The assignment operator.
Definition signal.h:70
int connect(Class *inst, void(Class::*func)(Args...))
Connects a member function of an object to this signal.
Definition signal.h:113
void disconnect(int id)
Disconnects a previously connected function.
Definition signal.h:148
Signal & operator=(Signal const &other)
The assignment operator.
Definition signal.h:79
Definition collider.cpp:182
constexpr auto overload(void(*func)(Args...)) -> void(*)(Args...)
Helper function for resolving overloaded non-member functions.
Definition signal.h:262
void disconnect(SIGNAL *signal, int id)
Disconnects a previously connected function.
Definition signal.h:233
void disconnect_all(SIGNAL *signal)
Disconnects all previously connected functions.
Definition signal.h:239
int connect(SIGNAL *signal, FUNCTION const &slot)
Connects a function to the signal.
Definition signal.h:200