Merge lp:~3v1n0/unity/glib-signals-blocking into lp:unity

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
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

To post a comment you must log in.
Revision history for this message
Andrea Azzarone (azzar1) wrote :

+1

review: Approve

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;