summaryrefslogtreecommitdiff
diff options
authorMarco Trevisan (TreviƱo) <mail@3v1n0.net>2017-07-21 08:51:47 +0000
committerBileto Bot <ci-train-bot@canonical.com>2017-07-21 08:51:47 +0000
commitc7f4437d4f98c58d6f7a6c1e5ada9752464edb34 (patch)
tree5fc09cd9aac403af03ae9d500ea96abf17a06d78
parentd1eff3a612fbeebf72b4b201b123a93578ba8657 (diff)
parent1bc51823be590e56e6a3efeff626506640e7b508 (diff)
GLibSignal: allow to block, unblock signals
Added support also to SignalManager, changed a bit the interface Approved by: Andrea Azzarone (bzr r4248)
-rw-r--r--UnityCore/GLibSignal-inl.h12
-rw-r--r--UnityCore/GLibSignal.cpp102
-rw-r--r--UnityCore/GLibSignal.h25
-rw-r--r--tests/test_glib_signals.cpp256
4 files changed, 296 insertions, 99 deletions
diff --git a/UnityCore/GLibSignal-inl.h b/UnityCore/GLibSignal-inl.h
index e1cab8dd4..e7d786ea6 100644
--- a/UnityCore/GLibSignal-inl.h
+++ b/UnityCore/GLibSignal-inl.h
@@ -34,11 +34,11 @@ Signal<R, G, Ts...>::Signal(G object, std::string const& signal_name,
}
template <typename R, typename G, typename... Ts>
-void Signal<R, G, Ts...>::Connect(G object, std::string const& signal_name,
+bool Signal<R, G, Ts...>::Connect(G object, std::string const& signal_name,
SignalCallback const& callback)
{
if (!callback || !G_IS_OBJECT(object) || signal_name.empty())
- return;
+ return false;
Disconnect();
@@ -47,6 +47,8 @@ void Signal<R, G, Ts...>::Connect(G object, std::string const& signal_name,
callback_ = callback;
connection_id_ = g_signal_connect(object_, signal_name.c_str(), G_CALLBACK(Callback), this);
g_object_add_weak_pointer(object_, reinterpret_cast<gpointer*>(&object_));
+
+ return true;
}
template <typename R, typename G, typename... Ts>
@@ -59,6 +61,12 @@ R Signal<R, G, Ts...>::Callback(G object, Ts... vs, Signal* self)
return R();
}
+template <typename R, typename G, typename... Ts>
+SignalBase::Ptr SignalManager::Add(G object, std::string const& signal_name, typename Signal<R, G, Ts...>::SignalCallback const& callback)
+{
+ return Add(std::make_shared<Signal<R, G, Ts...>>(object, signal_name, callback));
+}
+
}
}
diff --git a/UnityCore/GLibSignal.cpp b/UnityCore/GLibSignal.cpp
index 6173a09b4..d577c2f2e 100644
--- a/UnityCore/GLibSignal.cpp
+++ b/UnityCore/GLibSignal.cpp
@@ -35,16 +35,46 @@ SignalBase::~SignalBase()
Disconnect();
}
-void SignalBase::Disconnect()
+bool SignalBase::Disconnect()
{
+ bool disconnected = false;
+
if (connection_id_ && G_IS_OBJECT(object_))
{
g_signal_handler_disconnect(object_, connection_id_);
g_object_remove_weak_pointer(object_, reinterpret_cast<gpointer*>(&object_));
+ disconnected = true;
}
object_ = nullptr;
connection_id_ = 0;
+ return disconnected;
+}
+
+bool SignalBase::Block() const
+{
+ bool blocked = false;
+
+ if (connection_id_ && G_IS_OBJECT(object_))
+ {
+ g_signal_handler_block(object_, connection_id_);
+ blocked = true;
+ }
+
+ return blocked;
+}
+
+bool SignalBase::Unblock() const
+{
+ bool unblocked = false;
+
+ if (connection_id_ && G_IS_OBJECT(object_))
+ {
+ g_signal_handler_unblock(object_, connection_id_);
+ unblocked = true;
+ }
+
+ return unblocked;
}
GObject* SignalBase::object() const
@@ -75,57 +105,73 @@ SignalManager::~SignalManager()
// was too messy to try and write a copy constructor/operator that would steal
// from "other" and make the new one the owner. Not only did it create
// opportunity for random bugs, it also made the API bad.
-void SignalManager::Add(SignalBase* signal)
+SignalBase::Ptr SignalManager::Add(SignalBase* signal)
{
- Add(SignalBase::Ptr(signal));
+ return Add(SignalBase::Ptr(signal));
}
-void SignalManager::Add(SignalBase::Ptr const& signal)
+SignalBase::Ptr SignalManager::Add(SignalBase::Ptr const& signal)
{
connections_.push_back(signal);
g_object_weak_ref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this);
+ return signal;
}
-void SignalManager::OnObjectDestroyed(SignalManager* self, GObject* old_obj)
+// This uses void* to keep in line with the g_signal* functions
+// (it allows you to pass in a GObject without casting up).
+bool SignalManager::ForeachMatchedSignal(void* object, std::string const& signal_name, std::function<void(SignalBase::Ptr const&)> action, bool erase_after)
{
- for (auto it = self->connections_.begin(); it != self->connections_.end();)
+ bool action_performed = false;
+ bool all_objects = (object == reinterpret_cast<void*>(std::numeric_limits<uintptr_t>::max()));
+ bool all_signals = all_objects || signal_name.empty();
+
+ for (auto it = connections_.begin(); it != connections_.end();)
{
auto const& signal = *it;
- // When an object has been destroyed, the signal member is nullified,
- // so at this point we can be sure that removing signal with a null object,
- // means removing invalid signals.
- if (!signal->object())
+ if ((all_objects || signal->object() == object) && (all_signals || signal->name() == signal_name))
{
- it = self->connections_.erase(it);
+ if (action)
+ {
+ action_performed = true;
+ action(signal);
+ }
+
+ it = erase_after ? connections_.erase(it) : ++it;
}
else
{
++it;
}
}
+
+ return action_performed;
}
-// This uses void* to keep in line with the g_signal* functions
-// (it allows you to pass in a GObject without casting up).
-void SignalManager::Disconnect(void* object, std::string const& signal_name)
+void SignalManager::OnObjectDestroyed(SignalManager* self, GObject* old_obj)
{
- bool all_signals = signal_name.empty();
+ self->ForeachMatchedSignal(nullptr, "", nullptr, /*erase_after*/ true);
+}
- for (auto it = connections_.begin(); it != connections_.end();)
- {
- auto const& signal = *it;
+bool SignalManager::Block(void* object, std::string const& signal_name)
+{
+ return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) {
+ signal->Block();
+ });
+}
- if (signal->object() == object && (all_signals || signal->name() == signal_name))
- {
- g_object_weak_unref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this);
- it = connections_.erase(it);
- }
- else
- {
- ++it;
- }
- }
+bool SignalManager::Unblock(void* object, std::string const& signal_name)
+{
+ return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) {
+ signal->Unblock();
+ });
+}
+
+bool SignalManager::Disconnect(void* object, std::string const& signal_name)
+{
+ return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) {
+ g_object_weak_unref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this);
+ }, true);
}
}
diff --git a/UnityCore/GLibSignal.h b/UnityCore/GLibSignal.h
index 392ff3382..6dc536111 100644
--- a/UnityCore/GLibSignal.h
+++ b/UnityCore/GLibSignal.h
@@ -21,6 +21,7 @@
#ifndef UNITY_GLIB_SIGNAL_H
#define UNITY_GLIB_SIGNAL_H
+#include <limits>
#include <string>
#include <vector>
#include <memory>
@@ -39,7 +40,10 @@ public:
virtual ~SignalBase();
- void Disconnect();
+ bool Disconnect();
+
+ bool Block() const;
+ bool Unblock() const;
GObject* object() const;
std::string const& name() const;
@@ -71,9 +75,9 @@ public:
#endif
inline Signal() {};
- inline Signal(G object, std::string const& signal_name, SignalCallback const& callback);
+ inline Signal(G object, std::string const& signal_name, SignalCallback const&);
- inline void Connect(G Object, std::string const& signal_name, SignalCallback const& callback);
+ inline bool Connect(G Object, std::string const& signal_name, SignalCallback const&);
private:
static R Callback(G Object, Ts... vs, Signal* self);
@@ -86,17 +90,18 @@ class SignalManager : boost::noncopyable
public:
SignalManager();
~SignalManager();
- void Add(SignalBase* signal);
- void Add(SignalBase::Ptr const& signal);
+ SignalBase::Ptr Add(SignalBase* signal);
+ SignalBase::Ptr Add(SignalBase::Ptr const& signal);
template <typename R, typename G, typename... Ts>
- void Add(G object, std::string const& signal_name, typename Signal<R, G, Ts...>::SignalCallback const& callback)
- {
- Add(std::make_shared<Signal<R, G, Ts...>>(object, signal_name, callback));
- }
+ SignalBase::Ptr Add(G object, std::string const& signal_name, typename Signal<R, G, Ts...>::SignalCallback const&);
+
+ bool Block(void* object = (void*) std::numeric_limits<uintptr_t>::max(), std::string const& signal_name = "");
+ bool Unblock(void* object = (void*) std::numeric_limits<uintptr_t>::max(), std::string const& signal_name = "");
- void Disconnect(void* object, std::string const& signal_name = "");
+ bool Disconnect(void* object, std::string const& signal_name = "");
private:
+ bool ForeachMatchedSignal(void* object, std::string const& signal_name, std::function<void(SignalBase::Ptr const&)> action, bool erase_after = false);
static void OnObjectDestroyed(SignalManager* self, GObject* old_obj);
protected:
diff --git a/tests/test_glib_signals.cpp b/tests/test_glib_signals.cpp
index 1c0b20bf7..724e18fec 100644
--- a/tests/test_glib_signals.cpp
+++ b/tests/test_glib_signals.cpp
@@ -34,7 +34,8 @@ public:
virtual ~TestGLibSignals()
{
- g_object_unref(test_signals_);
+ if (test_signals_)
+ g_object_unref(test_signals_);
}
void Signal0Callback(TestSignals* signals)
@@ -136,8 +137,8 @@ TEST_F(TestGLibSignals, TestConstructions)
TEST_F(TestGLibSignals, TestSignal0)
{
Signal<void, TestSignals*> signal;
- signal.Connect(test_signals_, "signal0",
- sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
g_signal_emit_by_name(test_signals_, "signal0");
@@ -148,8 +149,8 @@ TEST_F(TestGLibSignals, TestSignal0)
TEST_F(TestGLibSignals, TestSignal1)
{
Signal<void, TestSignals*, const char*> signal;
- signal.Connect(test_signals_, "signal1",
- sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal1",
+ sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)));
g_signal_emit_by_name(test_signals_, "signal1", "test");
@@ -161,8 +162,8 @@ TEST_F(TestGLibSignals, TestSignal1)
TEST_F(TestGLibSignals, TestSignal2)
{
Signal<void, TestSignals*, const char*, int> signal;
- signal.Connect(test_signals_, "signal2",
- sigc::mem_fun(this, &TestGLibSignals::Signal2Callback));
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal2",
+ sigc::mem_fun(this, &TestGLibSignals::Signal2Callback)));
g_signal_emit_by_name(test_signals_, "signal2", "test", 100);
@@ -175,8 +176,8 @@ TEST_F(TestGLibSignals, TestSignal2)
TEST_F(TestGLibSignals, TestSignal3)
{
Signal<void, TestSignals*, const char*, int, float> signal;
- signal.Connect(test_signals_, "signal3",
- sigc::mem_fun(this, &TestGLibSignals::Signal3Callback));
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal3",
+ sigc::mem_fun(this, &TestGLibSignals::Signal3Callback)));
g_signal_emit_by_name(test_signals_, "signal3", "test", 100, 200.0f);
@@ -191,8 +192,8 @@ TEST_F(TestGLibSignals, TestSignal3)
TEST_F(TestGLibSignals, TestSignal4)
{
Signal<void, TestSignals*, const char*, int, float, double> signal;
- signal.Connect(test_signals_, "signal4",
- sigc::mem_fun(this, &TestGLibSignals::Signal4Callback));
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal4",
+ sigc::mem_fun(this, &TestGLibSignals::Signal4Callback)));
g_signal_emit_by_name(test_signals_, "signal4", "test", 100, 200.0f, 300.00);
@@ -207,8 +208,8 @@ TEST_F(TestGLibSignals, TestSignal4)
TEST_F(TestGLibSignals, TestSignal5)
{
Signal<void, TestSignals*, const char*, int, float, double, gboolean> signal;
- signal.Connect(test_signals_, "signal5",
- sigc::mem_fun(this, &TestGLibSignals::Signal5Callback));
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal5",
+ sigc::mem_fun(this, &TestGLibSignals::Signal5Callback)));
g_signal_emit_by_name(test_signals_, "signal5", "test", 100, 200.0f, 300.00,
TRUE);
@@ -226,8 +227,8 @@ TEST_F(TestGLibSignals, TestSignal5)
TEST_F(TestGLibSignals, TestSignal6)
{
Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char> signal;
- signal.Connect(test_signals_, "signal6",
- sigc::mem_fun(this, &TestGLibSignals::Signal6Callback));
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal6",
+ sigc::mem_fun(this, &TestGLibSignals::Signal6Callback)));
gboolean ret = FALSE;
g_signal_emit_by_name(test_signals_, "signal6", "test", 100, 200.0f, 300.00,
@@ -243,12 +244,46 @@ TEST_F(TestGLibSignals, TestSignal6)
EXPECT_EQ(ret, TRUE);
}
+TEST_F(TestGLibSignals, TestBlock)
+{
+ Signal<void, TestSignals*> signal;
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
+ EXPECT_TRUE(signal.Block());
+
+ g_signal_emit_by_name(test_signals_, "signal0");
+ EXPECT_FALSE(signal0_received_);
+
+ signal0_received_ = false;
+ EXPECT_TRUE(signal.Unblock());
+
+ g_signal_emit_by_name(test_signals_, "signal0");
+ EXPECT_TRUE(signal0_received_);
+}
+
+TEST_F(TestGLibSignals, TestUnblock)
+{
+ Signal<void, TestSignals*> signal;
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
+ EXPECT_TRUE(signal.Unblock());
+
+ g_signal_emit_by_name(test_signals_, "signal0");
+ EXPECT_TRUE(signal0_received_);
+
+ signal0_received_ = false;
+ EXPECT_TRUE(signal.Block());
+
+ g_signal_emit_by_name(test_signals_, "signal0");
+ EXPECT_FALSE(signal0_received_);
+}
+
TEST_F(TestGLibSignals, TestDisconnection)
{
Signal<void, TestSignals*> signal;
- signal.Connect(test_signals_, "signal0",
- sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
- signal.Disconnect();
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
+ EXPECT_TRUE(signal.Disconnect());
g_signal_emit_by_name(test_signals_, "signal0");
@@ -259,8 +294,8 @@ TEST_F(TestGLibSignals, TestAutoDisconnection)
{
{
Signal<void, TestSignals*> signal;
- signal.Connect(test_signals_, "signal0",
- sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
}
g_signal_emit_by_name(test_signals_, "signal0");
@@ -271,8 +306,8 @@ TEST_F(TestGLibSignals, TestAutoDisconnection)
TEST_F(TestGLibSignals, TestCleanDestruction)
{
Signal<void, TestSignals*> signal;
- signal.Connect(test_signals_, "signal0",
- sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
g_clear_object(&test_signals_);
EXPECT_EQ(signal.object(), nullptr);
}
@@ -280,11 +315,11 @@ TEST_F(TestGLibSignals, TestCleanDestruction)
TEST_F(TestGLibSignals, TestConnectReplacePreviousConnection)
{
Signal<void, TestSignals*> signal;
- signal.Connect(test_signals_, "signal0",
- sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
unsigned signal0_num_cb = 0;
- signal.Connect(test_signals_, "signal0", [&] (TestSignals*) {++signal0_num_cb;});
+ ASSERT_TRUE(signal.Connect(test_signals_, "signal0", [&] (TestSignals*) {++signal0_num_cb;}));
g_signal_emit_by_name(test_signals_, "signal0");
@@ -302,27 +337,62 @@ TEST_F(TestGLibSignals, TestManagerAddition)
{
MockSignalManager manager;
- manager.Add(new Signal<void, TestSignals*>(test_signals_,
- "signal0",
- sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
- manager.Add(new Signal<void, TestSignals*, const char*>(test_signals_,
- "signal1",
- sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)));
- manager.Add(new Signal<void, TestSignals*, const char*, int>(test_signals_,
- "signal2",
- sigc::mem_fun(this, &TestGLibSignals::Signal2Callback)));
- manager.Add(new Signal<void, TestSignals*, const char*, int, float>(test_signals_,
- "signal3",
- sigc::mem_fun(this, &TestGLibSignals::Signal3Callback)));
- manager.Add(new Signal<void, TestSignals*, const char*, int, float, double>(test_signals_,
- "signal4",
- sigc::mem_fun(this, &TestGLibSignals::Signal4Callback)));
- manager.Add(new Signal<void, TestSignals*, const char*, int, float, double, gboolean>(test_signals_,
- "signal5",
- sigc::mem_fun(this, &TestGLibSignals::Signal5Callback)));
- manager.Add(new Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char>(test_signals_,
- "signal6",
- sigc::mem_fun(this, &TestGLibSignals::Signal6Callback)));
+ auto signal0 = \
+ std::make_shared<Signal<void, TestSignals*>>(test_signals_,
+ "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
+ auto signal0_added = manager.Add(signal0);
+ ASSERT_NE(nullptr, signal0_added);
+ EXPECT_EQ(signal0, signal0_added);
+
+ auto signal1 = \
+ std::make_shared<Signal<void, TestSignals*, const char*>>(test_signals_,
+ "signal1",
+ sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));
+ auto signal1_added = manager.Add(signal1);
+ ASSERT_NE(nullptr, signal1_added);
+ EXPECT_EQ(signal1, signal1_added);
+
+ auto signal2 = \
+ std::make_shared<Signal<void, TestSignals*, const char*, int>>(test_signals_,
+ "signal2",
+ sigc::mem_fun(this, &TestGLibSignals::Signal2Callback));
+ auto signal2_added = manager.Add(signal2);
+ ASSERT_NE(nullptr, signal2_added);
+ EXPECT_EQ(signal2, signal2_added);
+
+ auto signal3 = \
+ std::make_shared<Signal<void, TestSignals*, const char*, int, float>>(test_signals_,
+ "signal3",
+ sigc::mem_fun(this, &TestGLibSignals::Signal3Callback));
+ auto signal3_added = manager.Add(signal3);
+ ASSERT_NE(nullptr, signal3_added);
+ EXPECT_EQ(signal3, signal3_added);
+
+ auto signal4 = \
+ std::make_shared<Signal<void, TestSignals*, const char*, int, float, double>>(test_signals_,
+ "signal4",
+ sigc::mem_fun(this, &TestGLibSignals::Signal4Callback));
+ auto signal4_added = manager.Add(signal4);
+ ASSERT_NE(nullptr, signal4_added);
+ EXPECT_EQ(signal4, signal4_added);
+
+ auto signal5 = \
+ std::make_shared<Signal<void, TestSignals*, const char*, int, float, double, gboolean>>(test_signals_,
+ "signal5",
+ sigc::mem_fun(this, &TestGLibSignals::Signal5Callback));
+ auto signal5_added = manager.Add(signal5);
+ ASSERT_NE(nullptr, signal5_added);
+ EXPECT_EQ(signal5, signal5_added);
+
+ auto signal6 = \
+ std::make_shared<Signal<gboolean, TestSignals*, const char*, int, float, double, gboolean, char>>(test_signals_,
+ "signal6",
+ sigc::mem_fun(this, &TestGLibSignals::Signal6Callback));
+ auto signal6_added = manager.Add(signal6);
+ ASSERT_NE(nullptr, signal6_added);
+ EXPECT_EQ(signal6, signal6_added);
+
EXPECT_EQ(manager.GetConnections().size(), 7u);
}
@@ -331,19 +401,20 @@ TEST_F(TestGLibSignals, TestManagerAdditionTemplate)
{
MockSignalManager manager;
- manager.Add<void, TestSignals*>(test_signals_, "signal0",
- sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
- manager.Add<void, TestSignals*, const char*>(test_signals_, "signal1",
- sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));
- manager.Add<void, TestSignals*, const char*, int>(test_signals_, "signal2",
- sigc::mem_fun(this, &TestGLibSignals::Signal2Callback));
- manager.Add<void, TestSignals*, const char*, int, float>(test_signals_, "signal3",
- sigc::mem_fun(this, &TestGLibSignals::Signal3Callback));
- manager.Add<void, TestSignals*, const char*, int, float, double>(test_signals_, "signal4",
- sigc::mem_fun(this, &TestGLibSignals::Signal4Callback));
- manager.Add<void, TestSignals*, const char*, int, float, double, gboolean>(test_signals_, "signal5",
- sigc::mem_fun(this, &TestGLibSignals::Signal5Callback));
- manager.Add<gboolean, TestSignals*, const char*, int, float, double, gboolean, char>(test_signals_, "signal6", sigc::mem_fun(this, &TestGLibSignals::Signal6Callback));
+ EXPECT_NE(nullptr, (manager.Add<void, TestSignals*>(test_signals_, "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback))));
+ EXPECT_NE(nullptr, (manager.Add<void, TestSignals*, const char*>(test_signals_, "signal1",
+ sigc::mem_fun(this, &TestGLibSignals::Signal1Callback))));
+ EXPECT_NE(nullptr, (manager.Add<void, TestSignals*, const char*, int>(test_signals_, "signal2",
+ sigc::mem_fun(this, &TestGLibSignals::Signal2Callback))));
+ EXPECT_NE(nullptr, (manager.Add<void, TestSignals*, const char*, int, float>(test_signals_, "signal3",
+ sigc::mem_fun(this, &TestGLibSignals::Signal3Callback))));
+ EXPECT_NE(nullptr, (manager.Add<void, TestSignals*, const char*, int, float, double>(test_signals_, "signal4",
+ sigc::mem_fun(this, &TestGLibSignals::Signal4Callback))));
+ EXPECT_NE(nullptr, (manager.Add<void, TestSignals*, const char*, int, float, double, gboolean>(test_signals_, "signal5",
+ sigc::mem_fun(this, &TestGLibSignals::Signal5Callback))));
+ EXPECT_NE(nullptr, (manager.Add<gboolean, TestSignals*, const char*, int, float, double, gboolean, char>(test_signals_, "signal6",
+ sigc::mem_fun(this, &TestGLibSignals::Signal6Callback))));
EXPECT_EQ(manager.GetConnections().size(), 7u);
}
@@ -399,6 +470,73 @@ TEST_F(TestGLibSignals, TestManagerDisconnection)
EXPECT_FALSE(signal0_received_);
}
+TEST_F(TestGLibSignals, TestManagerBlock)
+{
+ SignalManager manager;
+
+ manager.Add<void, TestSignals*>(test_signals_,
+ "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
+ EXPECT_TRUE(manager.Block(test_signals_, "signal0"));
+
+ g_signal_emit_by_name(test_signals_, "signal0");
+ EXPECT_FALSE(signal0_received_);
+
+ EXPECT_TRUE(manager.Unblock(test_signals_, "signal0"));
+ g_signal_emit_by_name(test_signals_, "signal0");
+ EXPECT_TRUE(signal0_received_);
+}
+
+TEST_F(TestGLibSignals, TestManagerBlockAll)
+{
+ SignalManager manager;
+
+ manager.Add<void, TestSignals*>(test_signals_,
+ "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
+ manager.Add<void, TestSignals*, const char*>(test_signals_,
+ "signal1",
+ sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));
+ EXPECT_TRUE(manager.Block(test_signals_));
+
+ g_signal_emit_by_name(test_signals_, "signal0");
+ g_signal_emit_by_name(test_signals_, "signal1", "blocked");
+ EXPECT_FALSE(signal0_received_);
+ EXPECT_FALSE(signal1_received_);
+
+ EXPECT_TRUE(manager.Unblock(test_signals_));
+
+ g_signal_emit_by_name(test_signals_, "signal0");
+ EXPECT_TRUE(signal0_received_);
+ g_signal_emit_by_name(test_signals_, "signal1", "unblocked");
+ EXPECT_TRUE(signal1_received_);
+}
+
+TEST_F(TestGLibSignals, TestManagerBlockAllObjects)
+{
+ SignalManager manager;
+
+ manager.Add<void, TestSignals*>(test_signals_,
+ "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
+ manager.Add<void, TestSignals*, const char*>(test_signals_,
+ "signal1",
+ sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));
+ EXPECT_TRUE(manager.Block());
+
+ g_signal_emit_by_name(test_signals_, "signal0");
+ g_signal_emit_by_name(test_signals_, "signal1", "blocked");
+ EXPECT_FALSE(signal0_received_);
+ EXPECT_FALSE(signal1_received_);
+
+ EXPECT_TRUE(manager.Unblock());
+
+ g_signal_emit_by_name(test_signals_, "signal0");
+ EXPECT_TRUE(signal0_received_);
+ g_signal_emit_by_name(test_signals_, "signal1", "unblocked");
+ EXPECT_TRUE(signal1_received_);
+}
+
TEST_F(TestGLibSignals, TestManagerObjectDisconnection)
{
SignalManager manager;