Merge lp:~3v1n0/unity/glib-signals-blocking into lp:unity
- glib-signals-blocking
- Merge into trunk
Proposed by
Marco Trevisan (Treviño)
Status: | Merged |
---|---|
Approved by: | Andrea Azzarone |
Approved revision: | no longer in the source branch. |
Merged at revision: | 4248 |
Proposed branch: | lp:~3v1n0/unity/glib-signals-blocking |
Merge into: | lp:unity |
Diff against target: |
626 lines (+298/-101) 4 files modified
UnityCore/GLibSignal-inl.h (+10/-2) UnityCore/GLibSignal.cpp (+75/-29) UnityCore/GLibSignal.h (+16/-11) tests/test_glib_signals.cpp (+197/-59) |
To merge this branch: | bzr merge lp:~3v1n0/unity/glib-signals-blocking |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrea Azzarone (community) | Approve | ||
Review via email: mp+327319@code.launchpad.net |
Commit message
GLibSignal: allow to block, unblock signals
Added support also to SignalManager, changed a bit the interface
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'UnityCore/GLibSignal-inl.h' | |||
2 | --- UnityCore/GLibSignal-inl.h 2014-10-15 05:16:46 +0000 | |||
3 | +++ UnityCore/GLibSignal-inl.h 2017-07-12 17:46:51 +0000 | |||
4 | @@ -34,11 +34,11 @@ | |||
5 | 34 | } | 34 | } |
6 | 35 | 35 | ||
7 | 36 | template <typename R, typename G, typename... Ts> | 36 | template <typename R, typename G, typename... Ts> |
9 | 37 | void Signal<R, G, Ts...>::Connect(G object, std::string const& signal_name, | 37 | bool Signal<R, G, Ts...>::Connect(G object, std::string const& signal_name, |
10 | 38 | SignalCallback const& callback) | 38 | SignalCallback const& callback) |
11 | 39 | { | 39 | { |
12 | 40 | if (!callback || !G_IS_OBJECT(object) || signal_name.empty()) | 40 | if (!callback || !G_IS_OBJECT(object) || signal_name.empty()) |
14 | 41 | return; | 41 | return false; |
15 | 42 | 42 | ||
16 | 43 | Disconnect(); | 43 | Disconnect(); |
17 | 44 | 44 | ||
18 | @@ -47,6 +47,8 @@ | |||
19 | 47 | callback_ = callback; | 47 | callback_ = callback; |
20 | 48 | connection_id_ = g_signal_connect(object_, signal_name.c_str(), G_CALLBACK(Callback), this); | 48 | connection_id_ = g_signal_connect(object_, signal_name.c_str(), G_CALLBACK(Callback), this); |
21 | 49 | g_object_add_weak_pointer(object_, reinterpret_cast<gpointer*>(&object_)); | 49 | g_object_add_weak_pointer(object_, reinterpret_cast<gpointer*>(&object_)); |
22 | 50 | |||
23 | 51 | return true; | ||
24 | 50 | } | 52 | } |
25 | 51 | 53 | ||
26 | 52 | template <typename R, typename G, typename... Ts> | 54 | template <typename R, typename G, typename... Ts> |
27 | @@ -59,6 +61,12 @@ | |||
28 | 59 | return R(); | 61 | return R(); |
29 | 60 | } | 62 | } |
30 | 61 | 63 | ||
31 | 64 | template <typename R, typename G, typename... Ts> | ||
32 | 65 | SignalBase::Ptr SignalManager::Add(G object, std::string const& signal_name, typename Signal<R, G, Ts...>::SignalCallback const& callback) | ||
33 | 66 | { | ||
34 | 67 | return Add(std::make_shared<Signal<R, G, Ts...>>(object, signal_name, callback)); | ||
35 | 68 | } | ||
36 | 69 | |||
37 | 62 | } | 70 | } |
38 | 63 | } | 71 | } |
39 | 64 | 72 | ||
40 | 65 | 73 | ||
41 | === modified file 'UnityCore/GLibSignal.cpp' | |||
42 | --- UnityCore/GLibSignal.cpp 2012-08-15 16:58:14 +0000 | |||
43 | +++ UnityCore/GLibSignal.cpp 2017-07-12 17:46:51 +0000 | |||
44 | @@ -35,16 +35,46 @@ | |||
45 | 35 | Disconnect(); | 35 | Disconnect(); |
46 | 36 | } | 36 | } |
47 | 37 | 37 | ||
49 | 38 | void SignalBase::Disconnect() | 38 | bool SignalBase::Disconnect() |
50 | 39 | { | 39 | { |
51 | 40 | bool disconnected = false; | ||
52 | 41 | |||
53 | 40 | if (connection_id_ && G_IS_OBJECT(object_)) | 42 | if (connection_id_ && G_IS_OBJECT(object_)) |
54 | 41 | { | 43 | { |
55 | 42 | g_signal_handler_disconnect(object_, connection_id_); | 44 | g_signal_handler_disconnect(object_, connection_id_); |
56 | 43 | g_object_remove_weak_pointer(object_, reinterpret_cast<gpointer*>(&object_)); | 45 | g_object_remove_weak_pointer(object_, reinterpret_cast<gpointer*>(&object_)); |
57 | 46 | disconnected = true; | ||
58 | 44 | } | 47 | } |
59 | 45 | 48 | ||
60 | 46 | object_ = nullptr; | 49 | object_ = nullptr; |
61 | 47 | connection_id_ = 0; | 50 | connection_id_ = 0; |
62 | 51 | return disconnected; | ||
63 | 52 | } | ||
64 | 53 | |||
65 | 54 | bool SignalBase::Block() const | ||
66 | 55 | { | ||
67 | 56 | bool blocked = false; | ||
68 | 57 | |||
69 | 58 | if (connection_id_ && G_IS_OBJECT(object_)) | ||
70 | 59 | { | ||
71 | 60 | g_signal_handler_block(object_, connection_id_); | ||
72 | 61 | blocked = true; | ||
73 | 62 | } | ||
74 | 63 | |||
75 | 64 | return blocked; | ||
76 | 65 | } | ||
77 | 66 | |||
78 | 67 | bool SignalBase::Unblock() const | ||
79 | 68 | { | ||
80 | 69 | bool unblocked = false; | ||
81 | 70 | |||
82 | 71 | if (connection_id_ && G_IS_OBJECT(object_)) | ||
83 | 72 | { | ||
84 | 73 | g_signal_handler_unblock(object_, connection_id_); | ||
85 | 74 | unblocked = true; | ||
86 | 75 | } | ||
87 | 76 | |||
88 | 77 | return unblocked; | ||
89 | 48 | } | 78 | } |
90 | 49 | 79 | ||
91 | 50 | GObject* SignalBase::object() const | 80 | GObject* SignalBase::object() const |
92 | @@ -75,57 +105,73 @@ | |||
93 | 75 | // was too messy to try and write a copy constructor/operator that would steal | 105 | // was too messy to try and write a copy constructor/operator that would steal |
94 | 76 | // from "other" and make the new one the owner. Not only did it create | 106 | // from "other" and make the new one the owner. Not only did it create |
95 | 77 | // opportunity for random bugs, it also made the API bad. | 107 | // opportunity for random bugs, it also made the API bad. |
97 | 78 | void SignalManager::Add(SignalBase* signal) | 108 | SignalBase::Ptr SignalManager::Add(SignalBase* signal) |
98 | 79 | { | 109 | { |
100 | 80 | Add(SignalBase::Ptr(signal)); | 110 | return Add(SignalBase::Ptr(signal)); |
101 | 81 | } | 111 | } |
102 | 82 | 112 | ||
104 | 83 | void SignalManager::Add(SignalBase::Ptr const& signal) | 113 | SignalBase::Ptr SignalManager::Add(SignalBase::Ptr const& signal) |
105 | 84 | { | 114 | { |
106 | 85 | connections_.push_back(signal); | 115 | connections_.push_back(signal); |
107 | 86 | g_object_weak_ref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this); | 116 | g_object_weak_ref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this); |
128 | 87 | } | 117 | return signal; |
109 | 88 | |||
110 | 89 | void SignalManager::OnObjectDestroyed(SignalManager* self, GObject* old_obj) | ||
111 | 90 | { | ||
112 | 91 | for (auto it = self->connections_.begin(); it != self->connections_.end();) | ||
113 | 92 | { | ||
114 | 93 | auto const& signal = *it; | ||
115 | 94 | |||
116 | 95 | // When an object has been destroyed, the signal member is nullified, | ||
117 | 96 | // so at this point we can be sure that removing signal with a null object, | ||
118 | 97 | // means removing invalid signals. | ||
119 | 98 | if (!signal->object()) | ||
120 | 99 | { | ||
121 | 100 | it = self->connections_.erase(it); | ||
122 | 101 | } | ||
123 | 102 | else | ||
124 | 103 | { | ||
125 | 104 | ++it; | ||
126 | 105 | } | ||
127 | 106 | } | ||
129 | 107 | } | 118 | } |
130 | 108 | 119 | ||
131 | 109 | // This uses void* to keep in line with the g_signal* functions | 120 | // This uses void* to keep in line with the g_signal* functions |
132 | 110 | // (it allows you to pass in a GObject without casting up). | 121 | // (it allows you to pass in a GObject without casting up). |
134 | 111 | void SignalManager::Disconnect(void* object, std::string const& signal_name) | 122 | bool SignalManager::ForeachMatchedSignal(void* object, std::string const& signal_name, std::function<void(SignalBase::Ptr const&)> action, bool erase_after) |
135 | 112 | { | 123 | { |
137 | 113 | bool all_signals = signal_name.empty(); | 124 | bool action_performed = false; |
138 | 125 | bool all_objects = (object == reinterpret_cast<void*>(std::numeric_limits<uintptr_t>::max())); | ||
139 | 126 | bool all_signals = all_objects || signal_name.empty(); | ||
140 | 114 | 127 | ||
141 | 115 | for (auto it = connections_.begin(); it != connections_.end();) | 128 | for (auto it = connections_.begin(); it != connections_.end();) |
142 | 116 | { | 129 | { |
143 | 117 | auto const& signal = *it; | 130 | auto const& signal = *it; |
144 | 118 | 131 | ||
146 | 119 | if (signal->object() == object && (all_signals || signal->name() == signal_name)) | 132 | if ((all_objects || signal->object() == object) && (all_signals || signal->name() == signal_name)) |
147 | 120 | { | 133 | { |
150 | 121 | g_object_weak_unref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this); | 134 | if (action) |
151 | 122 | it = connections_.erase(it); | 135 | { |
152 | 136 | action_performed = true; | ||
153 | 137 | action(signal); | ||
154 | 138 | } | ||
155 | 139 | |||
156 | 140 | it = erase_after ? connections_.erase(it) : ++it; | ||
157 | 123 | } | 141 | } |
158 | 124 | else | 142 | else |
159 | 125 | { | 143 | { |
160 | 126 | ++it; | 144 | ++it; |
161 | 127 | } | 145 | } |
162 | 128 | } | 146 | } |
163 | 147 | |||
164 | 148 | return action_performed; | ||
165 | 149 | } | ||
166 | 150 | |||
167 | 151 | void SignalManager::OnObjectDestroyed(SignalManager* self, GObject* old_obj) | ||
168 | 152 | { | ||
169 | 153 | self->ForeachMatchedSignal(nullptr, "", nullptr, /*erase_after*/ true); | ||
170 | 154 | } | ||
171 | 155 | |||
172 | 156 | bool SignalManager::Block(void* object, std::string const& signal_name) | ||
173 | 157 | { | ||
174 | 158 | return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) { | ||
175 | 159 | signal->Block(); | ||
176 | 160 | }); | ||
177 | 161 | } | ||
178 | 162 | |||
179 | 163 | bool SignalManager::Unblock(void* object, std::string const& signal_name) | ||
180 | 164 | { | ||
181 | 165 | return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) { | ||
182 | 166 | signal->Unblock(); | ||
183 | 167 | }); | ||
184 | 168 | } | ||
185 | 169 | |||
186 | 170 | bool SignalManager::Disconnect(void* object, std::string const& signal_name) | ||
187 | 171 | { | ||
188 | 172 | return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) { | ||
189 | 173 | g_object_weak_unref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this); | ||
190 | 174 | }, true); | ||
191 | 129 | } | 175 | } |
192 | 130 | 176 | ||
193 | 131 | } | 177 | } |
194 | 132 | 178 | ||
195 | === modified file 'UnityCore/GLibSignal.h' | |||
196 | --- UnityCore/GLibSignal.h 2012-08-15 16:58:14 +0000 | |||
197 | +++ UnityCore/GLibSignal.h 2017-07-12 17:46:51 +0000 | |||
198 | @@ -21,6 +21,7 @@ | |||
199 | 21 | #ifndef UNITY_GLIB_SIGNAL_H | 21 | #ifndef UNITY_GLIB_SIGNAL_H |
200 | 22 | #define UNITY_GLIB_SIGNAL_H | 22 | #define UNITY_GLIB_SIGNAL_H |
201 | 23 | 23 | ||
202 | 24 | #include <limits> | ||
203 | 24 | #include <string> | 25 | #include <string> |
204 | 25 | #include <vector> | 26 | #include <vector> |
205 | 26 | #include <memory> | 27 | #include <memory> |
206 | @@ -39,7 +40,10 @@ | |||
207 | 39 | 40 | ||
208 | 40 | virtual ~SignalBase(); | 41 | virtual ~SignalBase(); |
209 | 41 | 42 | ||
211 | 42 | void Disconnect(); | 43 | bool Disconnect(); |
212 | 44 | |||
213 | 45 | bool Block() const; | ||
214 | 46 | bool Unblock() const; | ||
215 | 43 | 47 | ||
216 | 44 | GObject* object() const; | 48 | GObject* object() const; |
217 | 45 | std::string const& name() const; | 49 | std::string const& name() const; |
218 | @@ -71,9 +75,9 @@ | |||
219 | 71 | #endif | 75 | #endif |
220 | 72 | 76 | ||
221 | 73 | inline Signal() {}; | 77 | inline Signal() {}; |
223 | 74 | inline Signal(G object, std::string const& signal_name, SignalCallback const& callback); | 78 | inline Signal(G object, std::string const& signal_name, SignalCallback const&); |
224 | 75 | 79 | ||
226 | 76 | inline void Connect(G Object, std::string const& signal_name, SignalCallback const& callback); | 80 | inline bool Connect(G Object, std::string const& signal_name, SignalCallback const&); |
227 | 77 | 81 | ||
228 | 78 | private: | 82 | private: |
229 | 79 | static R Callback(G Object, Ts... vs, Signal* self); | 83 | static R Callback(G Object, Ts... vs, Signal* self); |
230 | @@ -86,17 +90,18 @@ | |||
231 | 86 | public: | 90 | public: |
232 | 87 | SignalManager(); | 91 | SignalManager(); |
233 | 88 | ~SignalManager(); | 92 | ~SignalManager(); |
236 | 89 | void Add(SignalBase* signal); | 93 | SignalBase::Ptr Add(SignalBase* signal); |
237 | 90 | void Add(SignalBase::Ptr const& signal); | 94 | SignalBase::Ptr Add(SignalBase::Ptr const& signal); |
238 | 91 | template <typename R, typename G, typename... Ts> | 95 | template <typename R, typename G, typename... Ts> |
245 | 92 | void Add(G object, std::string const& signal_name, typename Signal<R, G, Ts...>::SignalCallback const& callback) | 96 | SignalBase::Ptr Add(G object, std::string const& signal_name, typename Signal<R, G, Ts...>::SignalCallback const&); |
246 | 93 | { | 97 | |
247 | 94 | Add(std::make_shared<Signal<R, G, Ts...>>(object, signal_name, callback)); | 98 | bool Block(void* object = (void*) std::numeric_limits<uintptr_t>::max(), std::string const& signal_name = ""); |
248 | 95 | } | 99 | bool Unblock(void* object = (void*) std::numeric_limits<uintptr_t>::max(), std::string const& signal_name = ""); |
249 | 96 | 100 | ||
250 | 97 | void Disconnect(void* object, std::string const& signal_name = ""); | 101 | bool Disconnect(void* object, std::string const& signal_name = ""); |
251 | 98 | 102 | ||
252 | 99 | private: | 103 | private: |
253 | 104 | bool ForeachMatchedSignal(void* object, std::string const& signal_name, std::function<void(SignalBase::Ptr const&)> action, bool erase_after = false); | ||
254 | 100 | static void OnObjectDestroyed(SignalManager* self, GObject* old_obj); | 105 | static void OnObjectDestroyed(SignalManager* self, GObject* old_obj); |
255 | 101 | 106 | ||
256 | 102 | protected: | 107 | protected: |
257 | 103 | 108 | ||
258 | === modified file 'tests/test_glib_signals.cpp' | |||
259 | --- tests/test_glib_signals.cpp 2016-11-29 14:43:12 +0000 | |||
260 | +++ tests/test_glib_signals.cpp 2017-07-12 17:46:51 +0000 | |||
261 | @@ -34,7 +34,8 @@ | |||
262 | 34 | 34 | ||
263 | 35 | virtual ~TestGLibSignals() | 35 | virtual ~TestGLibSignals() |
264 | 36 | { | 36 | { |
266 | 37 | g_object_unref(test_signals_); | 37 | if (test_signals_) |
267 | 38 | g_object_unref(test_signals_); | ||
268 | 38 | } | 39 | } |
269 | 39 | 40 | ||
270 | 40 | void Signal0Callback(TestSignals* signals) | 41 | void Signal0Callback(TestSignals* signals) |
271 | @@ -136,8 +137,8 @@ | |||
272 | 136 | TEST_F(TestGLibSignals, TestSignal0) | 137 | TEST_F(TestGLibSignals, TestSignal0) |
273 | 137 | { | 138 | { |
274 | 138 | Signal<void, TestSignals*> signal; | 139 | Signal<void, TestSignals*> signal; |
277 | 139 | signal.Connect(test_signals_, "signal0", | 140 | ASSERT_TRUE(signal.Connect(test_signals_, "signal0", |
278 | 140 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)); | 141 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback))); |
279 | 141 | 142 | ||
280 | 142 | g_signal_emit_by_name(test_signals_, "signal0"); | 143 | g_signal_emit_by_name(test_signals_, "signal0"); |
281 | 143 | 144 | ||
282 | @@ -148,8 +149,8 @@ | |||
283 | 148 | TEST_F(TestGLibSignals, TestSignal1) | 149 | TEST_F(TestGLibSignals, TestSignal1) |
284 | 149 | { | 150 | { |
285 | 150 | Signal<void, TestSignals*, const char*> signal; | 151 | Signal<void, TestSignals*, const char*> signal; |
288 | 151 | signal.Connect(test_signals_, "signal1", | 152 | ASSERT_TRUE(signal.Connect(test_signals_, "signal1", |
289 | 152 | sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)); | 153 | sigc::mem_fun(this, &TestGLibSignals::Signal1Callback))); |
290 | 153 | 154 | ||
291 | 154 | g_signal_emit_by_name(test_signals_, "signal1", "test"); | 155 | g_signal_emit_by_name(test_signals_, "signal1", "test"); |
292 | 155 | 156 | ||
293 | @@ -161,8 +162,8 @@ | |||
294 | 161 | TEST_F(TestGLibSignals, TestSignal2) | 162 | TEST_F(TestGLibSignals, TestSignal2) |
295 | 162 | { | 163 | { |
296 | 163 | Signal<void, TestSignals*, const char*, int> signal; | 164 | Signal<void, TestSignals*, const char*, int> signal; |
299 | 164 | signal.Connect(test_signals_, "signal2", | 165 | ASSERT_TRUE(signal.Connect(test_signals_, "signal2", |
300 | 165 | sigc::mem_fun(this, &TestGLibSignals::Signal2Callback)); | 166 | sigc::mem_fun(this, &TestGLibSignals::Signal2Callback))); |
301 | 166 | 167 | ||
302 | 167 | g_signal_emit_by_name(test_signals_, "signal2", "test", 100); | 168 | g_signal_emit_by_name(test_signals_, "signal2", "test", 100); |
303 | 168 | 169 | ||
304 | @@ -175,8 +176,8 @@ | |||
305 | 175 | TEST_F(TestGLibSignals, TestSignal3) | 176 | TEST_F(TestGLibSignals, TestSignal3) |
306 | 176 | { | 177 | { |
307 | 177 | Signal<void, TestSignals*, const char*, int, float> signal; | 178 | Signal<void, TestSignals*, const char*, int, float> signal; |
310 | 178 | signal.Connect(test_signals_, "signal3", | 179 | ASSERT_TRUE(signal.Connect(test_signals_, "signal3", |
311 | 179 | sigc::mem_fun(this, &TestGLibSignals::Signal3Callback)); | 180 | sigc::mem_fun(this, &TestGLibSignals::Signal3Callback))); |
312 | 180 | 181 | ||
313 | 181 | g_signal_emit_by_name(test_signals_, "signal3", "test", 100, 200.0f); | 182 | g_signal_emit_by_name(test_signals_, "signal3", "test", 100, 200.0f); |
314 | 182 | 183 | ||
315 | @@ -191,8 +192,8 @@ | |||
316 | 191 | TEST_F(TestGLibSignals, TestSignal4) | 192 | TEST_F(TestGLibSignals, TestSignal4) |
317 | 192 | { | 193 | { |
318 | 193 | Signal<void, TestSignals*, const char*, int, float, double> signal; | 194 | Signal<void, TestSignals*, const char*, int, float, double> signal; |
321 | 194 | signal.Connect(test_signals_, "signal4", | 195 | ASSERT_TRUE(signal.Connect(test_signals_, "signal4", |
322 | 195 | sigc::mem_fun(this, &TestGLibSignals::Signal4Callback)); | 196 | sigc::mem_fun(this, &TestGLibSignals::Signal4Callback))); |
323 | 196 | 197 | ||
324 | 197 | g_signal_emit_by_name(test_signals_, "signal4", "test", 100, 200.0f, 300.00); | 198 | g_signal_emit_by_name(test_signals_, "signal4", "test", 100, 200.0f, 300.00); |
325 | 198 | 199 | ||
326 | @@ -207,8 +208,8 @@ | |||
327 | 207 | TEST_F(TestGLibSignals, TestSignal5) | 208 | TEST_F(TestGLibSignals, TestSignal5) |
328 | 208 | { | 209 | { |
329 | 209 | Signal<void, TestSignals*, const char*, int, float, double, gboolean> signal; | 210 | Signal<void, TestSignals*, const char*, int, float, double, gboolean> signal; |
332 | 210 | signal.Connect(test_signals_, "signal5", | 211 | ASSERT_TRUE(signal.Connect(test_signals_, "signal5", |
333 | 211 | sigc::mem_fun(this, &TestGLibSignals::Signal5Callback)); | 212 | sigc::mem_fun(this, &TestGLibSignals::Signal5Callback))); |
334 | 212 | 213 | ||
335 | 213 | g_signal_emit_by_name(test_signals_, "signal5", "test", 100, 200.0f, 300.00, | 214 | g_signal_emit_by_name(test_signals_, "signal5", "test", 100, 200.0f, 300.00, |
336 | 214 | TRUE); | 215 | TRUE); |
337 | @@ -226,8 +227,8 @@ | |||
338 | 226 | TEST_F(TestGLibSignals, TestSignal6) | 227 | TEST_F(TestGLibSignals, TestSignal6) |
339 | 227 | { | 228 | { |
340 | 228 | Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char> signal; | 229 | Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char> signal; |
343 | 229 | signal.Connect(test_signals_, "signal6", | 230 | ASSERT_TRUE(signal.Connect(test_signals_, "signal6", |
344 | 230 | sigc::mem_fun(this, &TestGLibSignals::Signal6Callback)); | 231 | sigc::mem_fun(this, &TestGLibSignals::Signal6Callback))); |
345 | 231 | 232 | ||
346 | 232 | gboolean ret = FALSE; | 233 | gboolean ret = FALSE; |
347 | 233 | g_signal_emit_by_name(test_signals_, "signal6", "test", 100, 200.0f, 300.00, | 234 | g_signal_emit_by_name(test_signals_, "signal6", "test", 100, 200.0f, 300.00, |
348 | @@ -243,12 +244,46 @@ | |||
349 | 243 | EXPECT_EQ(ret, TRUE); | 244 | EXPECT_EQ(ret, TRUE); |
350 | 244 | } | 245 | } |
351 | 245 | 246 | ||
352 | 247 | TEST_F(TestGLibSignals, TestBlock) | ||
353 | 248 | { | ||
354 | 249 | Signal<void, TestSignals*> signal; | ||
355 | 250 | ASSERT_TRUE(signal.Connect(test_signals_, "signal0", | ||
356 | 251 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback))); | ||
357 | 252 | EXPECT_TRUE(signal.Block()); | ||
358 | 253 | |||
359 | 254 | g_signal_emit_by_name(test_signals_, "signal0"); | ||
360 | 255 | EXPECT_FALSE(signal0_received_); | ||
361 | 256 | |||
362 | 257 | signal0_received_ = false; | ||
363 | 258 | EXPECT_TRUE(signal.Unblock()); | ||
364 | 259 | |||
365 | 260 | g_signal_emit_by_name(test_signals_, "signal0"); | ||
366 | 261 | EXPECT_TRUE(signal0_received_); | ||
367 | 262 | } | ||
368 | 263 | |||
369 | 264 | TEST_F(TestGLibSignals, TestUnblock) | ||
370 | 265 | { | ||
371 | 266 | Signal<void, TestSignals*> signal; | ||
372 | 267 | ASSERT_TRUE(signal.Connect(test_signals_, "signal0", | ||
373 | 268 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback))); | ||
374 | 269 | EXPECT_TRUE(signal.Unblock()); | ||
375 | 270 | |||
376 | 271 | g_signal_emit_by_name(test_signals_, "signal0"); | ||
377 | 272 | EXPECT_TRUE(signal0_received_); | ||
378 | 273 | |||
379 | 274 | signal0_received_ = false; | ||
380 | 275 | EXPECT_TRUE(signal.Block()); | ||
381 | 276 | |||
382 | 277 | g_signal_emit_by_name(test_signals_, "signal0"); | ||
383 | 278 | EXPECT_FALSE(signal0_received_); | ||
384 | 279 | } | ||
385 | 280 | |||
386 | 246 | TEST_F(TestGLibSignals, TestDisconnection) | 281 | TEST_F(TestGLibSignals, TestDisconnection) |
387 | 247 | { | 282 | { |
388 | 248 | Signal<void, TestSignals*> signal; | 283 | Signal<void, TestSignals*> signal; |
392 | 249 | signal.Connect(test_signals_, "signal0", | 284 | ASSERT_TRUE(signal.Connect(test_signals_, "signal0", |
393 | 250 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)); | 285 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback))); |
394 | 251 | signal.Disconnect(); | 286 | EXPECT_TRUE(signal.Disconnect()); |
395 | 252 | 287 | ||
396 | 253 | g_signal_emit_by_name(test_signals_, "signal0"); | 288 | g_signal_emit_by_name(test_signals_, "signal0"); |
397 | 254 | 289 | ||
398 | @@ -259,8 +294,8 @@ | |||
399 | 259 | { | 294 | { |
400 | 260 | { | 295 | { |
401 | 261 | Signal<void, TestSignals*> signal; | 296 | Signal<void, TestSignals*> signal; |
404 | 262 | signal.Connect(test_signals_, "signal0", | 297 | ASSERT_TRUE(signal.Connect(test_signals_, "signal0", |
405 | 263 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)); | 298 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback))); |
406 | 264 | } | 299 | } |
407 | 265 | 300 | ||
408 | 266 | g_signal_emit_by_name(test_signals_, "signal0"); | 301 | g_signal_emit_by_name(test_signals_, "signal0"); |
409 | @@ -271,8 +306,8 @@ | |||
410 | 271 | TEST_F(TestGLibSignals, TestCleanDestruction) | 306 | TEST_F(TestGLibSignals, TestCleanDestruction) |
411 | 272 | { | 307 | { |
412 | 273 | Signal<void, TestSignals*> signal; | 308 | Signal<void, TestSignals*> signal; |
415 | 274 | signal.Connect(test_signals_, "signal0", | 309 | ASSERT_TRUE(signal.Connect(test_signals_, "signal0", |
416 | 275 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)); | 310 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback))); |
417 | 276 | g_clear_object(&test_signals_); | 311 | g_clear_object(&test_signals_); |
418 | 277 | EXPECT_EQ(signal.object(), nullptr); | 312 | EXPECT_EQ(signal.object(), nullptr); |
419 | 278 | } | 313 | } |
420 | @@ -280,11 +315,11 @@ | |||
421 | 280 | TEST_F(TestGLibSignals, TestConnectReplacePreviousConnection) | 315 | TEST_F(TestGLibSignals, TestConnectReplacePreviousConnection) |
422 | 281 | { | 316 | { |
423 | 282 | Signal<void, TestSignals*> signal; | 317 | Signal<void, TestSignals*> signal; |
426 | 283 | signal.Connect(test_signals_, "signal0", | 318 | ASSERT_TRUE(signal.Connect(test_signals_, "signal0", |
427 | 284 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)); | 319 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback))); |
428 | 285 | 320 | ||
429 | 286 | unsigned signal0_num_cb = 0; | 321 | unsigned signal0_num_cb = 0; |
431 | 287 | signal.Connect(test_signals_, "signal0", [&] (TestSignals*) {++signal0_num_cb;}); | 322 | ASSERT_TRUE(signal.Connect(test_signals_, "signal0", [&] (TestSignals*) {++signal0_num_cb;})); |
432 | 288 | 323 | ||
433 | 289 | g_signal_emit_by_name(test_signals_, "signal0"); | 324 | g_signal_emit_by_name(test_signals_, "signal0"); |
434 | 290 | 325 | ||
435 | @@ -302,27 +337,62 @@ | |||
436 | 302 | { | 337 | { |
437 | 303 | MockSignalManager manager; | 338 | MockSignalManager manager; |
438 | 304 | 339 | ||
460 | 305 | manager.Add(new Signal<void, TestSignals*>(test_signals_, | 340 | auto signal0 = \ |
461 | 306 | "signal0", | 341 | std::make_shared<Signal<void, TestSignals*>>(test_signals_, |
462 | 307 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback))); | 342 | "signal0", |
463 | 308 | manager.Add(new Signal<void, TestSignals*, const char*>(test_signals_, | 343 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)); |
464 | 309 | "signal1", | 344 | auto signal0_added = manager.Add(signal0); |
465 | 310 | sigc::mem_fun(this, &TestGLibSignals::Signal1Callback))); | 345 | ASSERT_NE(nullptr, signal0_added); |
466 | 311 | manager.Add(new Signal<void, TestSignals*, const char*, int>(test_signals_, | 346 | EXPECT_EQ(signal0, signal0_added); |
467 | 312 | "signal2", | 347 | |
468 | 313 | sigc::mem_fun(this, &TestGLibSignals::Signal2Callback))); | 348 | auto signal1 = \ |
469 | 314 | manager.Add(new Signal<void, TestSignals*, const char*, int, float>(test_signals_, | 349 | std::make_shared<Signal<void, TestSignals*, const char*>>(test_signals_, |
470 | 315 | "signal3", | 350 | "signal1", |
471 | 316 | sigc::mem_fun(this, &TestGLibSignals::Signal3Callback))); | 351 | sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)); |
472 | 317 | manager.Add(new Signal<void, TestSignals*, const char*, int, float, double>(test_signals_, | 352 | auto signal1_added = manager.Add(signal1); |
473 | 318 | "signal4", | 353 | ASSERT_NE(nullptr, signal1_added); |
474 | 319 | sigc::mem_fun(this, &TestGLibSignals::Signal4Callback))); | 354 | EXPECT_EQ(signal1, signal1_added); |
475 | 320 | manager.Add(new Signal<void, TestSignals*, const char*, int, float, double, gboolean>(test_signals_, | 355 | |
476 | 321 | "signal5", | 356 | auto signal2 = \ |
477 | 322 | sigc::mem_fun(this, &TestGLibSignals::Signal5Callback))); | 357 | std::make_shared<Signal<void, TestSignals*, const char*, int>>(test_signals_, |
478 | 323 | manager.Add(new Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char>(test_signals_, | 358 | "signal2", |
479 | 324 | "signal6", | 359 | sigc::mem_fun(this, &TestGLibSignals::Signal2Callback)); |
480 | 325 | sigc::mem_fun(this, &TestGLibSignals::Signal6Callback))); | 360 | auto signal2_added = manager.Add(signal2); |
481 | 361 | ASSERT_NE(nullptr, signal2_added); | ||
482 | 362 | EXPECT_EQ(signal2, signal2_added); | ||
483 | 363 | |||
484 | 364 | auto signal3 = \ | ||
485 | 365 | std::make_shared<Signal<void, TestSignals*, const char*, int, float>>(test_signals_, | ||
486 | 366 | "signal3", | ||
487 | 367 | sigc::mem_fun(this, &TestGLibSignals::Signal3Callback)); | ||
488 | 368 | auto signal3_added = manager.Add(signal3); | ||
489 | 369 | ASSERT_NE(nullptr, signal3_added); | ||
490 | 370 | EXPECT_EQ(signal3, signal3_added); | ||
491 | 371 | |||
492 | 372 | auto signal4 = \ | ||
493 | 373 | std::make_shared<Signal<void, TestSignals*, const char*, int, float, double>>(test_signals_, | ||
494 | 374 | "signal4", | ||
495 | 375 | sigc::mem_fun(this, &TestGLibSignals::Signal4Callback)); | ||
496 | 376 | auto signal4_added = manager.Add(signal4); | ||
497 | 377 | ASSERT_NE(nullptr, signal4_added); | ||
498 | 378 | EXPECT_EQ(signal4, signal4_added); | ||
499 | 379 | |||
500 | 380 | auto signal5 = \ | ||
501 | 381 | std::make_shared<Signal<void, TestSignals*, const char*, int, float, double, gboolean>>(test_signals_, | ||
502 | 382 | "signal5", | ||
503 | 383 | sigc::mem_fun(this, &TestGLibSignals::Signal5Callback)); | ||
504 | 384 | auto signal5_added = manager.Add(signal5); | ||
505 | 385 | ASSERT_NE(nullptr, signal5_added); | ||
506 | 386 | EXPECT_EQ(signal5, signal5_added); | ||
507 | 387 | |||
508 | 388 | auto signal6 = \ | ||
509 | 389 | std::make_shared<Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char>>(test_signals_, | ||
510 | 390 | "signal6", | ||
511 | 391 | sigc::mem_fun(this, &TestGLibSignals::Signal6Callback)); | ||
512 | 392 | auto signal6_added = manager.Add(signal6); | ||
513 | 393 | ASSERT_NE(nullptr, signal6_added); | ||
514 | 394 | EXPECT_EQ(signal6, signal6_added); | ||
515 | 395 | |||
516 | 326 | 396 | ||
517 | 327 | EXPECT_EQ(manager.GetConnections().size(), 7u); | 397 | EXPECT_EQ(manager.GetConnections().size(), 7u); |
518 | 328 | } | 398 | } |
519 | @@ -331,19 +401,20 @@ | |||
520 | 331 | { | 401 | { |
521 | 332 | MockSignalManager manager; | 402 | MockSignalManager manager; |
522 | 333 | 403 | ||
536 | 334 | manager.Add<void, TestSignals*>(test_signals_, "signal0", | 404 | EXPECT_NE(nullptr, (manager.Add<void, TestSignals*>(test_signals_, "signal0", |
537 | 335 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)); | 405 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)))); |
538 | 336 | manager.Add<void, TestSignals*, const char*>(test_signals_, "signal1", | 406 | EXPECT_NE(nullptr, (manager.Add<void, TestSignals*, const char*>(test_signals_, "signal1", |
539 | 337 | sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)); | 407 | sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)))); |
540 | 338 | manager.Add<void, TestSignals*, const char*, int>(test_signals_, "signal2", | 408 | EXPECT_NE(nullptr, (manager.Add<void, TestSignals*, const char*, int>(test_signals_, "signal2", |
541 | 339 | sigc::mem_fun(this, &TestGLibSignals::Signal2Callback)); | 409 | sigc::mem_fun(this, &TestGLibSignals::Signal2Callback)))); |
542 | 340 | manager.Add<void, TestSignals*, const char*, int, float>(test_signals_, "signal3", | 410 | EXPECT_NE(nullptr, (manager.Add<void, TestSignals*, const char*, int, float>(test_signals_, "signal3", |
543 | 341 | sigc::mem_fun(this, &TestGLibSignals::Signal3Callback)); | 411 | sigc::mem_fun(this, &TestGLibSignals::Signal3Callback)))); |
544 | 342 | manager.Add<void, TestSignals*, const char*, int, float, double>(test_signals_, "signal4", | 412 | EXPECT_NE(nullptr, (manager.Add<void, TestSignals*, const char*, int, float, double>(test_signals_, "signal4", |
545 | 343 | sigc::mem_fun(this, &TestGLibSignals::Signal4Callback)); | 413 | sigc::mem_fun(this, &TestGLibSignals::Signal4Callback)))); |
546 | 344 | manager.Add<void, TestSignals*, const char*, int, float, double, gboolean>(test_signals_, "signal5", | 414 | EXPECT_NE(nullptr, (manager.Add<void, TestSignals*, const char*, int, float, double, gboolean>(test_signals_, "signal5", |
547 | 345 | sigc::mem_fun(this, &TestGLibSignals::Signal5Callback)); | 415 | sigc::mem_fun(this, &TestGLibSignals::Signal5Callback)))); |
548 | 346 | manager.Add<gboolean, TestSignals*, const char*, int, float, double, gboolean, char>(test_signals_, "signal6", sigc::mem_fun(this, &TestGLibSignals::Signal6Callback)); | 416 | EXPECT_NE(nullptr, (manager.Add<gboolean, TestSignals*, const char*, int, float, double, gboolean, char>(test_signals_, "signal6", |
549 | 417 | sigc::mem_fun(this, &TestGLibSignals::Signal6Callback)))); | ||
550 | 347 | 418 | ||
551 | 348 | EXPECT_EQ(manager.GetConnections().size(), 7u); | 419 | EXPECT_EQ(manager.GetConnections().size(), 7u); |
552 | 349 | } | 420 | } |
553 | @@ -399,6 +470,73 @@ | |||
554 | 399 | EXPECT_FALSE(signal0_received_); | 470 | EXPECT_FALSE(signal0_received_); |
555 | 400 | } | 471 | } |
556 | 401 | 472 | ||
557 | 473 | TEST_F(TestGLibSignals, TestManagerBlock) | ||
558 | 474 | { | ||
559 | 475 | SignalManager manager; | ||
560 | 476 | |||
561 | 477 | manager.Add<void, TestSignals*>(test_signals_, | ||
562 | 478 | "signal0", | ||
563 | 479 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)); | ||
564 | 480 | EXPECT_TRUE(manager.Block(test_signals_, "signal0")); | ||
565 | 481 | |||
566 | 482 | g_signal_emit_by_name(test_signals_, "signal0"); | ||
567 | 483 | EXPECT_FALSE(signal0_received_); | ||
568 | 484 | |||
569 | 485 | EXPECT_TRUE(manager.Unblock(test_signals_, "signal0")); | ||
570 | 486 | g_signal_emit_by_name(test_signals_, "signal0"); | ||
571 | 487 | EXPECT_TRUE(signal0_received_); | ||
572 | 488 | } | ||
573 | 489 | |||
574 | 490 | TEST_F(TestGLibSignals, TestManagerBlockAll) | ||
575 | 491 | { | ||
576 | 492 | SignalManager manager; | ||
577 | 493 | |||
578 | 494 | manager.Add<void, TestSignals*>(test_signals_, | ||
579 | 495 | "signal0", | ||
580 | 496 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)); | ||
581 | 497 | manager.Add<void, TestSignals*, const char*>(test_signals_, | ||
582 | 498 | "signal1", | ||
583 | 499 | sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)); | ||
584 | 500 | EXPECT_TRUE(manager.Block(test_signals_)); | ||
585 | 501 | |||
586 | 502 | g_signal_emit_by_name(test_signals_, "signal0"); | ||
587 | 503 | g_signal_emit_by_name(test_signals_, "signal1", "blocked"); | ||
588 | 504 | EXPECT_FALSE(signal0_received_); | ||
589 | 505 | EXPECT_FALSE(signal1_received_); | ||
590 | 506 | |||
591 | 507 | EXPECT_TRUE(manager.Unblock(test_signals_)); | ||
592 | 508 | |||
593 | 509 | g_signal_emit_by_name(test_signals_, "signal0"); | ||
594 | 510 | EXPECT_TRUE(signal0_received_); | ||
595 | 511 | g_signal_emit_by_name(test_signals_, "signal1", "unblocked"); | ||
596 | 512 | EXPECT_TRUE(signal1_received_); | ||
597 | 513 | } | ||
598 | 514 | |||
599 | 515 | TEST_F(TestGLibSignals, TestManagerBlockAllObjects) | ||
600 | 516 | { | ||
601 | 517 | SignalManager manager; | ||
602 | 518 | |||
603 | 519 | manager.Add<void, TestSignals*>(test_signals_, | ||
604 | 520 | "signal0", | ||
605 | 521 | sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)); | ||
606 | 522 | manager.Add<void, TestSignals*, const char*>(test_signals_, | ||
607 | 523 | "signal1", | ||
608 | 524 | sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)); | ||
609 | 525 | EXPECT_TRUE(manager.Block()); | ||
610 | 526 | |||
611 | 527 | g_signal_emit_by_name(test_signals_, "signal0"); | ||
612 | 528 | g_signal_emit_by_name(test_signals_, "signal1", "blocked"); | ||
613 | 529 | EXPECT_FALSE(signal0_received_); | ||
614 | 530 | EXPECT_FALSE(signal1_received_); | ||
615 | 531 | |||
616 | 532 | EXPECT_TRUE(manager.Unblock()); | ||
617 | 533 | |||
618 | 534 | g_signal_emit_by_name(test_signals_, "signal0"); | ||
619 | 535 | EXPECT_TRUE(signal0_received_); | ||
620 | 536 | g_signal_emit_by_name(test_signals_, "signal1", "unblocked"); | ||
621 | 537 | EXPECT_TRUE(signal1_received_); | ||
622 | 538 | } | ||
623 | 539 | |||
624 | 402 | TEST_F(TestGLibSignals, TestManagerObjectDisconnection) | 540 | TEST_F(TestGLibSignals, TestManagerObjectDisconnection) |
625 | 403 | { | 541 | { |
626 | 404 | SignalManager manager; | 542 | SignalManager manager; |
+1