-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSignal.h
104 lines (91 loc) · 2.96 KB
/
Signal.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/**
* Signal-Slot object
*
* A signal may call multiple slots (i.e. - functions) with the same signature.
* When a signal 'emuit()' method is invoed, a function which was connected to that signal shall be called.
* Any argument passed to 'emit()' will be passed to the given function.
*
* Dan Israel Malta
**/
#pragma once
#include <functional>
#include <map>
/**
* \brief Signal
*
* @param {Args..., in} signature
**/
template<typename... Args> class Signal {
// properties
private:
mutable std::map<std::size_t, std::function<void(Args...)>> m_slots; // signal-slot dictionary
mutable std::size_t m_id; // slot index
// constructors
public:
// default constructor
constexpr Signal() : m_id(0) {}
// copy/move constructor
Signal(const Signal&) = delete;
Signal(Signal&&) noexcept = delete;
// copy/move assignment
Signal& operator=(const Signal&) = delete;
Signal& operator=(Signal&&) noexcept = delete;
// methods
public:
/**
* \brief connect an object member function (slot) to signal
*
* @param {T, in} object to be connected to singal
* @param {void, in} object's (connecteds to signal) member function
* @param {size_t, out} slot id
**/
template<typename T> std::size_t connect_member(T *inst, void (T::*func)(Args...)) {
return connect([=](Args... args) {
(inst->*func)(args...);
});
}
/**
* \brief connect an object member constant function (slot) to signal
*
* @param {T, in} object to be connected to singal
* @param {void, in} object's (connecteds to signal) member function
* @param {size_t, out} slot id
**/
template<typename T> std::size_t connect_member(T *inst, void (T::*func)(Args...) const ) {
return connect([=](Args... args) {
(inst->*func)(args...);
});
}
/**
* \brief connect std::function (slot) to signal.
*
* @param {std::function, in} std::function to be connected to singal
* @param {size_t, out} slot id
**/
std::size_t connect(const std::function<void(Args...)>& slot) const {
m_slots.insert(std::make_pair(++m_id, slot));
return m_id;
}
/**
* \brief disconnects an existent slot
*
* @param {size_t, in} slot id
**/
void disconnect(std::size_t id) const {
m_slots.erase(id);
}
/**
* \brief disconnects all existent slots
**/
void disconnect_all() const {
m_slots.clear();
}
/**
* \brief invoke all connected slots
**/
void emit(Args... p) {
for (auto it : m_slots) {
it.second(p...);
}
}
};