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