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
=== modified file 'UnityCore/GLibSignal-inl.h'
--- UnityCore/GLibSignal-inl.h 2014-10-15 05:16:46 +0000
+++ UnityCore/GLibSignal-inl.h 2017-07-12 17:46:51 +0000
@@ -34,11 +34,11 @@
34}34}
3535
36template <typename R, typename G, typename... Ts>36template <typename R, typename G, typename... Ts>
37void Signal<R, G, Ts...>::Connect(G object, std::string const& signal_name,37bool Signal<R, G, Ts...>::Connect(G object, std::string const& signal_name,
38 SignalCallback const& callback)38 SignalCallback const& callback)
39{39{
40 if (!callback || !G_IS_OBJECT(object) || signal_name.empty())40 if (!callback || !G_IS_OBJECT(object) || signal_name.empty())
41 return;41 return false;
4242
43 Disconnect();43 Disconnect();
4444
@@ -47,6 +47,8 @@
47 callback_ = callback;47 callback_ = callback;
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);
49 g_object_add_weak_pointer(object_, reinterpret_cast<gpointer*>(&object_));49 g_object_add_weak_pointer(object_, reinterpret_cast<gpointer*>(&object_));
50
51 return true;
50}52}
5153
52template <typename R, typename G, typename... Ts>54template <typename R, typename G, typename... Ts>
@@ -59,6 +61,12 @@
59 return R();61 return R();
60}62}
6163
64template <typename R, typename G, typename... Ts>
65SignalBase::Ptr SignalManager::Add(G object, std::string const& signal_name, typename Signal<R, G, Ts...>::SignalCallback const& callback)
66{
67 return Add(std::make_shared<Signal<R, G, Ts...>>(object, signal_name, callback));
68}
69
62}70}
63}71}
6472
6573
=== modified file 'UnityCore/GLibSignal.cpp'
--- UnityCore/GLibSignal.cpp 2012-08-15 16:58:14 +0000
+++ UnityCore/GLibSignal.cpp 2017-07-12 17:46:51 +0000
@@ -35,16 +35,46 @@
35 Disconnect();35 Disconnect();
36}36}
3737
38void SignalBase::Disconnect()38bool SignalBase::Disconnect()
39{39{
40 bool disconnected = false;
41
40 if (connection_id_ && G_IS_OBJECT(object_))42 if (connection_id_ && G_IS_OBJECT(object_))
41 {43 {
42 g_signal_handler_disconnect(object_, connection_id_);44 g_signal_handler_disconnect(object_, connection_id_);
43 g_object_remove_weak_pointer(object_, reinterpret_cast<gpointer*>(&object_));45 g_object_remove_weak_pointer(object_, reinterpret_cast<gpointer*>(&object_));
46 disconnected = true;
44 }47 }
4548
46 object_ = nullptr;49 object_ = nullptr;
47 connection_id_ = 0;50 connection_id_ = 0;
51 return disconnected;
52}
53
54bool SignalBase::Block() const
55{
56 bool blocked = false;
57
58 if (connection_id_ && G_IS_OBJECT(object_))
59 {
60 g_signal_handler_block(object_, connection_id_);
61 blocked = true;
62 }
63
64 return blocked;
65}
66
67bool SignalBase::Unblock() const
68{
69 bool unblocked = false;
70
71 if (connection_id_ && G_IS_OBJECT(object_))
72 {
73 g_signal_handler_unblock(object_, connection_id_);
74 unblocked = true;
75 }
76
77 return unblocked;
48}78}
4979
50GObject* SignalBase::object() const80GObject* SignalBase::object() const
@@ -75,57 +105,73 @@
75// was too messy to try and write a copy constructor/operator that would steal105// was too messy to try and write a copy constructor/operator that would steal
76// from "other" and make the new one the owner. Not only did it create106// from "other" and make the new one the owner. Not only did it create
77// opportunity for random bugs, it also made the API bad.107// opportunity for random bugs, it also made the API bad.
78void SignalManager::Add(SignalBase* signal)108SignalBase::Ptr SignalManager::Add(SignalBase* signal)
79{109{
80 Add(SignalBase::Ptr(signal));110 return Add(SignalBase::Ptr(signal));
81}111}
82112
83void SignalManager::Add(SignalBase::Ptr const& signal)113SignalBase::Ptr SignalManager::Add(SignalBase::Ptr const& signal)
84{114{
85 connections_.push_back(signal);115 connections_.push_back(signal);
86 g_object_weak_ref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this);116 g_object_weak_ref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this);
87}117 return signal;
88
89void SignalManager::OnObjectDestroyed(SignalManager* self, GObject* old_obj)
90{
91 for (auto it = self->connections_.begin(); it != self->connections_.end();)
92 {
93 auto const& signal = *it;
94
95 // When an object has been destroyed, the signal member is nullified,
96 // so at this point we can be sure that removing signal with a null object,
97 // means removing invalid signals.
98 if (!signal->object())
99 {
100 it = self->connections_.erase(it);
101 }
102 else
103 {
104 ++it;
105 }
106 }
107}118}
108119
109// This uses void* to keep in line with the g_signal* functions120// This uses void* to keep in line with the g_signal* functions
110// (it allows you to pass in a GObject without casting up).121// (it allows you to pass in a GObject without casting up).
111void SignalManager::Disconnect(void* object, std::string const& signal_name)122bool SignalManager::ForeachMatchedSignal(void* object, std::string const& signal_name, std::function<void(SignalBase::Ptr const&)> action, bool erase_after)
112{123{
113 bool all_signals = signal_name.empty();124 bool action_performed = false;
125 bool all_objects = (object == reinterpret_cast<void*>(std::numeric_limits<uintptr_t>::max()));
126 bool all_signals = all_objects || signal_name.empty();
114127
115 for (auto it = connections_.begin(); it != connections_.end();)128 for (auto it = connections_.begin(); it != connections_.end();)
116 {129 {
117 auto const& signal = *it;130 auto const& signal = *it;
118131
119 if (signal->object() == object && (all_signals || signal->name() == signal_name))132 if ((all_objects || signal->object() == object) && (all_signals || signal->name() == signal_name))
120 {133 {
121 g_object_weak_unref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this);134 if (action)
122 it = connections_.erase(it);135 {
136 action_performed = true;
137 action(signal);
138 }
139
140 it = erase_after ? connections_.erase(it) : ++it;
123 }141 }
124 else142 else
125 {143 {
126 ++it;144 ++it;
127 }145 }
128 }146 }
147
148 return action_performed;
149}
150
151void SignalManager::OnObjectDestroyed(SignalManager* self, GObject* old_obj)
152{
153 self->ForeachMatchedSignal(nullptr, "", nullptr, /*erase_after*/ true);
154}
155
156bool SignalManager::Block(void* object, std::string const& signal_name)
157{
158 return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) {
159 signal->Block();
160 });
161}
162
163bool SignalManager::Unblock(void* object, std::string const& signal_name)
164{
165 return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) {
166 signal->Unblock();
167 });
168}
169
170bool SignalManager::Disconnect(void* object, std::string const& signal_name)
171{
172 return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) {
173 g_object_weak_unref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this);
174 }, true);
129}175}
130176
131}177}
132178
=== modified file 'UnityCore/GLibSignal.h'
--- UnityCore/GLibSignal.h 2012-08-15 16:58:14 +0000
+++ UnityCore/GLibSignal.h 2017-07-12 17:46:51 +0000
@@ -21,6 +21,7 @@
21#ifndef UNITY_GLIB_SIGNAL_H21#ifndef UNITY_GLIB_SIGNAL_H
22#define UNITY_GLIB_SIGNAL_H22#define UNITY_GLIB_SIGNAL_H
2323
24#include <limits>
24#include <string>25#include <string>
25#include <vector>26#include <vector>
26#include <memory>27#include <memory>
@@ -39,7 +40,10 @@
3940
40 virtual ~SignalBase();41 virtual ~SignalBase();
4142
42 void Disconnect();43 bool Disconnect();
44
45 bool Block() const;
46 bool Unblock() const;
4347
44 GObject* object() const;48 GObject* object() const;
45 std::string const& name() const;49 std::string const& name() const;
@@ -71,9 +75,9 @@
71#endif75#endif
7276
73 inline Signal() {};77 inline Signal() {};
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&);
7579
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&);
7781
78private:82private:
79 static R Callback(G Object, Ts... vs, Signal* self);83 static R Callback(G Object, Ts... vs, Signal* self);
@@ -86,17 +90,18 @@
86public:90public:
87 SignalManager();91 SignalManager();
88 ~SignalManager();92 ~SignalManager();
89 void Add(SignalBase* signal);93 SignalBase::Ptr Add(SignalBase* signal);
90 void Add(SignalBase::Ptr const& signal);94 SignalBase::Ptr Add(SignalBase::Ptr const& signal);
91 template <typename R, typename G, typename... Ts>95 template <typename R, typename G, typename... Ts>
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&);
93 {97
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 = "");
95 }99 bool Unblock(void* object = (void*) std::numeric_limits<uintptr_t>::max(), std::string const& signal_name = "");
96100
97 void Disconnect(void* object, std::string const& signal_name = "");101 bool Disconnect(void* object, std::string const& signal_name = "");
98102
99private:103private:
104 bool ForeachMatchedSignal(void* object, std::string const& signal_name, std::function<void(SignalBase::Ptr const&)> action, bool erase_after = false);
100 static void OnObjectDestroyed(SignalManager* self, GObject* old_obj);105 static void OnObjectDestroyed(SignalManager* self, GObject* old_obj);
101106
102protected:107protected:
103108
=== modified file 'tests/test_glib_signals.cpp'
--- tests/test_glib_signals.cpp 2016-11-29 14:43:12 +0000
+++ tests/test_glib_signals.cpp 2017-07-12 17:46:51 +0000
@@ -34,7 +34,8 @@
3434
35 virtual ~TestGLibSignals()35 virtual ~TestGLibSignals()
36 {36 {
37 g_object_unref(test_signals_);37 if (test_signals_)
38 g_object_unref(test_signals_);
38 }39 }
3940
40 void Signal0Callback(TestSignals* signals)41 void Signal0Callback(TestSignals* signals)
@@ -136,8 +137,8 @@
136TEST_F(TestGLibSignals, TestSignal0)137TEST_F(TestGLibSignals, TestSignal0)
137{138{
138 Signal<void, TestSignals*> signal;139 Signal<void, TestSignals*> signal;
139 signal.Connect(test_signals_, "signal0",140 ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
140 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));141 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
141142
142 g_signal_emit_by_name(test_signals_, "signal0");143 g_signal_emit_by_name(test_signals_, "signal0");
143144
@@ -148,8 +149,8 @@
148TEST_F(TestGLibSignals, TestSignal1)149TEST_F(TestGLibSignals, TestSignal1)
149{150{
150 Signal<void, TestSignals*, const char*> signal;151 Signal<void, TestSignals*, const char*> signal;
151 signal.Connect(test_signals_, "signal1",152 ASSERT_TRUE(signal.Connect(test_signals_, "signal1",
152 sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));153 sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)));
153154
154 g_signal_emit_by_name(test_signals_, "signal1", "test");155 g_signal_emit_by_name(test_signals_, "signal1", "test");
155156
@@ -161,8 +162,8 @@
161TEST_F(TestGLibSignals, TestSignal2)162TEST_F(TestGLibSignals, TestSignal2)
162{163{
163 Signal<void, TestSignals*, const char*, int> signal;164 Signal<void, TestSignals*, const char*, int> signal;
164 signal.Connect(test_signals_, "signal2",165 ASSERT_TRUE(signal.Connect(test_signals_, "signal2",
165 sigc::mem_fun(this, &TestGLibSignals::Signal2Callback));166 sigc::mem_fun(this, &TestGLibSignals::Signal2Callback)));
166167
167 g_signal_emit_by_name(test_signals_, "signal2", "test", 100);168 g_signal_emit_by_name(test_signals_, "signal2", "test", 100);
168169
@@ -175,8 +176,8 @@
175TEST_F(TestGLibSignals, TestSignal3)176TEST_F(TestGLibSignals, TestSignal3)
176{177{
177 Signal<void, TestSignals*, const char*, int, float> signal;178 Signal<void, TestSignals*, const char*, int, float> signal;
178 signal.Connect(test_signals_, "signal3",179 ASSERT_TRUE(signal.Connect(test_signals_, "signal3",
179 sigc::mem_fun(this, &TestGLibSignals::Signal3Callback));180 sigc::mem_fun(this, &TestGLibSignals::Signal3Callback)));
180181
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);
182183
@@ -191,8 +192,8 @@
191TEST_F(TestGLibSignals, TestSignal4)192TEST_F(TestGLibSignals, TestSignal4)
192{193{
193 Signal<void, TestSignals*, const char*, int, float, double> signal;194 Signal<void, TestSignals*, const char*, int, float, double> signal;
194 signal.Connect(test_signals_, "signal4",195 ASSERT_TRUE(signal.Connect(test_signals_, "signal4",
195 sigc::mem_fun(this, &TestGLibSignals::Signal4Callback));196 sigc::mem_fun(this, &TestGLibSignals::Signal4Callback)));
196197
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);
198199
@@ -207,8 +208,8 @@
207TEST_F(TestGLibSignals, TestSignal5)208TEST_F(TestGLibSignals, TestSignal5)
208{209{
209 Signal<void, TestSignals*, const char*, int, float, double, gboolean> signal;210 Signal<void, TestSignals*, const char*, int, float, double, gboolean> signal;
210 signal.Connect(test_signals_, "signal5",211 ASSERT_TRUE(signal.Connect(test_signals_, "signal5",
211 sigc::mem_fun(this, &TestGLibSignals::Signal5Callback));212 sigc::mem_fun(this, &TestGLibSignals::Signal5Callback)));
212213
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,
214 TRUE);215 TRUE);
@@ -226,8 +227,8 @@
226TEST_F(TestGLibSignals, TestSignal6)227TEST_F(TestGLibSignals, TestSignal6)
227{228{
228 Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char> signal;229 Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char> signal;
229 signal.Connect(test_signals_, "signal6",230 ASSERT_TRUE(signal.Connect(test_signals_, "signal6",
230 sigc::mem_fun(this, &TestGLibSignals::Signal6Callback));231 sigc::mem_fun(this, &TestGLibSignals::Signal6Callback)));
231232
232 gboolean ret = FALSE;233 gboolean ret = FALSE;
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,
@@ -243,12 +244,46 @@
243 EXPECT_EQ(ret, TRUE);244 EXPECT_EQ(ret, TRUE);
244}245}
245246
247TEST_F(TestGLibSignals, TestBlock)
248{
249 Signal<void, TestSignals*> signal;
250 ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
251 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
252 EXPECT_TRUE(signal.Block());
253
254 g_signal_emit_by_name(test_signals_, "signal0");
255 EXPECT_FALSE(signal0_received_);
256
257 signal0_received_ = false;
258 EXPECT_TRUE(signal.Unblock());
259
260 g_signal_emit_by_name(test_signals_, "signal0");
261 EXPECT_TRUE(signal0_received_);
262}
263
264TEST_F(TestGLibSignals, TestUnblock)
265{
266 Signal<void, TestSignals*> signal;
267 ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
268 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
269 EXPECT_TRUE(signal.Unblock());
270
271 g_signal_emit_by_name(test_signals_, "signal0");
272 EXPECT_TRUE(signal0_received_);
273
274 signal0_received_ = false;
275 EXPECT_TRUE(signal.Block());
276
277 g_signal_emit_by_name(test_signals_, "signal0");
278 EXPECT_FALSE(signal0_received_);
279}
280
246TEST_F(TestGLibSignals, TestDisconnection)281TEST_F(TestGLibSignals, TestDisconnection)
247{282{
248 Signal<void, TestSignals*> signal;283 Signal<void, TestSignals*> signal;
249 signal.Connect(test_signals_, "signal0",284 ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
250 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));285 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
251 signal.Disconnect();286 EXPECT_TRUE(signal.Disconnect());
252287
253 g_signal_emit_by_name(test_signals_, "signal0");288 g_signal_emit_by_name(test_signals_, "signal0");
254289
@@ -259,8 +294,8 @@
259{294{
260 {295 {
261 Signal<void, TestSignals*> signal;296 Signal<void, TestSignals*> signal;
262 signal.Connect(test_signals_, "signal0",297 ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
263 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));298 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
264 }299 }
265300
266 g_signal_emit_by_name(test_signals_, "signal0");301 g_signal_emit_by_name(test_signals_, "signal0");
@@ -271,8 +306,8 @@
271TEST_F(TestGLibSignals, TestCleanDestruction)306TEST_F(TestGLibSignals, TestCleanDestruction)
272{307{
273 Signal<void, TestSignals*> signal;308 Signal<void, TestSignals*> signal;
274 signal.Connect(test_signals_, "signal0",309 ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
275 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));310 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
276 g_clear_object(&test_signals_);311 g_clear_object(&test_signals_);
277 EXPECT_EQ(signal.object(), nullptr);312 EXPECT_EQ(signal.object(), nullptr);
278}313}
@@ -280,11 +315,11 @@
280TEST_F(TestGLibSignals, TestConnectReplacePreviousConnection)315TEST_F(TestGLibSignals, TestConnectReplacePreviousConnection)
281{316{
282 Signal<void, TestSignals*> signal;317 Signal<void, TestSignals*> signal;
283 signal.Connect(test_signals_, "signal0",318 ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
284 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));319 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
285320
286 unsigned signal0_num_cb = 0;321 unsigned signal0_num_cb = 0;
287 signal.Connect(test_signals_, "signal0", [&] (TestSignals*) {++signal0_num_cb;});322 ASSERT_TRUE(signal.Connect(test_signals_, "signal0", [&] (TestSignals*) {++signal0_num_cb;}));
288323
289 g_signal_emit_by_name(test_signals_, "signal0");324 g_signal_emit_by_name(test_signals_, "signal0");
290325
@@ -302,27 +337,62 @@
302{337{
303 MockSignalManager manager;338 MockSignalManager manager;
304339
305 manager.Add(new Signal<void, TestSignals*>(test_signals_,340 auto signal0 = \
306 "signal0",341 std::make_shared<Signal<void, TestSignals*>>(test_signals_,
307 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));342 "signal0",
308 manager.Add(new Signal<void, TestSignals*, const char*>(test_signals_,343 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
309 "signal1",344 auto signal0_added = manager.Add(signal0);
310 sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)));345 ASSERT_NE(nullptr, signal0_added);
311 manager.Add(new Signal<void, TestSignals*, const char*, int>(test_signals_,346 EXPECT_EQ(signal0, signal0_added);
312 "signal2",347
313 sigc::mem_fun(this, &TestGLibSignals::Signal2Callback)));348 auto signal1 = \
314 manager.Add(new Signal<void, TestSignals*, const char*, int, float>(test_signals_,349 std::make_shared<Signal<void, TestSignals*, const char*>>(test_signals_,
315 "signal3",350 "signal1",
316 sigc::mem_fun(this, &TestGLibSignals::Signal3Callback)));351 sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));
317 manager.Add(new Signal<void, TestSignals*, const char*, int, float, double>(test_signals_,352 auto signal1_added = manager.Add(signal1);
318 "signal4",353 ASSERT_NE(nullptr, signal1_added);
319 sigc::mem_fun(this, &TestGLibSignals::Signal4Callback)));354 EXPECT_EQ(signal1, signal1_added);
320 manager.Add(new Signal<void, TestSignals*, const char*, int, float, double, gboolean>(test_signals_,355
321 "signal5",356 auto signal2 = \
322 sigc::mem_fun(this, &TestGLibSignals::Signal5Callback)));357 std::make_shared<Signal<void, TestSignals*, const char*, int>>(test_signals_,
323 manager.Add(new Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char>(test_signals_,358 "signal2",
324 "signal6",359 sigc::mem_fun(this, &TestGLibSignals::Signal2Callback));
325 sigc::mem_fun(this, &TestGLibSignals::Signal6Callback)));360 auto signal2_added = manager.Add(signal2);
361 ASSERT_NE(nullptr, signal2_added);
362 EXPECT_EQ(signal2, signal2_added);
363
364 auto signal3 = \
365 std::make_shared<Signal<void, TestSignals*, const char*, int, float>>(test_signals_,
366 "signal3",
367 sigc::mem_fun(this, &TestGLibSignals::Signal3Callback));
368 auto signal3_added = manager.Add(signal3);
369 ASSERT_NE(nullptr, signal3_added);
370 EXPECT_EQ(signal3, signal3_added);
371
372 auto signal4 = \
373 std::make_shared<Signal<void, TestSignals*, const char*, int, float, double>>(test_signals_,
374 "signal4",
375 sigc::mem_fun(this, &TestGLibSignals::Signal4Callback));
376 auto signal4_added = manager.Add(signal4);
377 ASSERT_NE(nullptr, signal4_added);
378 EXPECT_EQ(signal4, signal4_added);
379
380 auto signal5 = \
381 std::make_shared<Signal<void, TestSignals*, const char*, int, float, double, gboolean>>(test_signals_,
382 "signal5",
383 sigc::mem_fun(this, &TestGLibSignals::Signal5Callback));
384 auto signal5_added = manager.Add(signal5);
385 ASSERT_NE(nullptr, signal5_added);
386 EXPECT_EQ(signal5, signal5_added);
387
388 auto signal6 = \
389 std::make_shared<Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char>>(test_signals_,
390 "signal6",
391 sigc::mem_fun(this, &TestGLibSignals::Signal6Callback));
392 auto signal6_added = manager.Add(signal6);
393 ASSERT_NE(nullptr, signal6_added);
394 EXPECT_EQ(signal6, signal6_added);
395
326396
327 EXPECT_EQ(manager.GetConnections().size(), 7u);397 EXPECT_EQ(manager.GetConnections().size(), 7u);
328}398}
@@ -331,19 +401,20 @@
331{401{
332 MockSignalManager manager;402 MockSignalManager manager;
333403
334 manager.Add<void, TestSignals*>(test_signals_, "signal0",404 EXPECT_NE(nullptr, (manager.Add<void, TestSignals*>(test_signals_, "signal0",
335 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));405 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback))));
336 manager.Add<void, TestSignals*, const char*>(test_signals_, "signal1",406 EXPECT_NE(nullptr, (manager.Add<void, TestSignals*, const char*>(test_signals_, "signal1",
337 sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));407 sigc::mem_fun(this, &TestGLibSignals::Signal1Callback))));
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",
339 sigc::mem_fun(this, &TestGLibSignals::Signal2Callback));409 sigc::mem_fun(this, &TestGLibSignals::Signal2Callback))));
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",
341 sigc::mem_fun(this, &TestGLibSignals::Signal3Callback));411 sigc::mem_fun(this, &TestGLibSignals::Signal3Callback))));
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",
343 sigc::mem_fun(this, &TestGLibSignals::Signal4Callback));413 sigc::mem_fun(this, &TestGLibSignals::Signal4Callback))));
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",
345 sigc::mem_fun(this, &TestGLibSignals::Signal5Callback));415 sigc::mem_fun(this, &TestGLibSignals::Signal5Callback))));
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",
417 sigc::mem_fun(this, &TestGLibSignals::Signal6Callback))));
347418
348 EXPECT_EQ(manager.GetConnections().size(), 7u);419 EXPECT_EQ(manager.GetConnections().size(), 7u);
349}420}
@@ -399,6 +470,73 @@
399 EXPECT_FALSE(signal0_received_);470 EXPECT_FALSE(signal0_received_);
400}471}
401472
473TEST_F(TestGLibSignals, TestManagerBlock)
474{
475 SignalManager manager;
476
477 manager.Add<void, TestSignals*>(test_signals_,
478 "signal0",
479 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
480 EXPECT_TRUE(manager.Block(test_signals_, "signal0"));
481
482 g_signal_emit_by_name(test_signals_, "signal0");
483 EXPECT_FALSE(signal0_received_);
484
485 EXPECT_TRUE(manager.Unblock(test_signals_, "signal0"));
486 g_signal_emit_by_name(test_signals_, "signal0");
487 EXPECT_TRUE(signal0_received_);
488}
489
490TEST_F(TestGLibSignals, TestManagerBlockAll)
491{
492 SignalManager manager;
493
494 manager.Add<void, TestSignals*>(test_signals_,
495 "signal0",
496 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
497 manager.Add<void, TestSignals*, const char*>(test_signals_,
498 "signal1",
499 sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));
500 EXPECT_TRUE(manager.Block(test_signals_));
501
502 g_signal_emit_by_name(test_signals_, "signal0");
503 g_signal_emit_by_name(test_signals_, "signal1", "blocked");
504 EXPECT_FALSE(signal0_received_);
505 EXPECT_FALSE(signal1_received_);
506
507 EXPECT_TRUE(manager.Unblock(test_signals_));
508
509 g_signal_emit_by_name(test_signals_, "signal0");
510 EXPECT_TRUE(signal0_received_);
511 g_signal_emit_by_name(test_signals_, "signal1", "unblocked");
512 EXPECT_TRUE(signal1_received_);
513}
514
515TEST_F(TestGLibSignals, TestManagerBlockAllObjects)
516{
517 SignalManager manager;
518
519 manager.Add<void, TestSignals*>(test_signals_,
520 "signal0",
521 sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
522 manager.Add<void, TestSignals*, const char*>(test_signals_,
523 "signal1",
524 sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));
525 EXPECT_TRUE(manager.Block());
526
527 g_signal_emit_by_name(test_signals_, "signal0");
528 g_signal_emit_by_name(test_signals_, "signal1", "blocked");
529 EXPECT_FALSE(signal0_received_);
530 EXPECT_FALSE(signal1_received_);
531
532 EXPECT_TRUE(manager.Unblock());
533
534 g_signal_emit_by_name(test_signals_, "signal0");
535 EXPECT_TRUE(signal0_received_);
536 g_signal_emit_by_name(test_signals_, "signal1", "unblocked");
537 EXPECT_TRUE(signal1_received_);
538}
539
402TEST_F(TestGLibSignals, TestManagerObjectDisconnection)540TEST_F(TestGLibSignals, TestManagerObjectDisconnection)
403{541{
404 SignalManager manager;542 SignalManager manager;