util: add isConnected() in signal::Connection and signal::ScopedConnection
Change-Id: Iddf2a084ccf137a691cd85c54003182acf0e5afd
Refs: #2308
diff --git a/src/util/signal-connection.cpp b/src/util/signal-connection.cpp
index 8660e4d..7c74246 100644
--- a/src/util/signal-connection.cpp
+++ b/src/util/signal-connection.cpp
@@ -46,6 +46,12 @@
}
bool
+Connection::isConnected() const
+{
+ return !m_disconnect.expired();
+}
+
+bool
Connection::operator==(const Connection& other) const
{
shared_ptr<function<void()>> f1 = m_disconnect.lock();
diff --git a/src/util/signal-connection.hpp b/src/util/signal-connection.hpp
index 1276182..f2ac45e 100644
--- a/src/util/signal-connection.hpp
+++ b/src/util/signal-connection.hpp
@@ -45,6 +45,12 @@
void
disconnect();
+ /** \brief check if connected to the signal
+ * \return false if disconnected from the signal
+ */
+ bool
+ isConnected() const;
+
/** \brief compare for equality
*
* Two connections are equal if they both refer to the same connection that isn't disconnected,
diff --git a/src/util/signal-scoped-connection.cpp b/src/util/signal-scoped-connection.cpp
index ae90c5f..a0f2d1c 100644
--- a/src/util/signal-scoped-connection.cpp
+++ b/src/util/signal-scoped-connection.cpp
@@ -61,6 +61,12 @@
m_connection.disconnect();
}
+bool
+ScopedConnection::isConnected() const
+{
+ return m_connection.isConnected();
+}
+
void
ScopedConnection::release()
{
diff --git a/src/util/signal-scoped-connection.hpp b/src/util/signal-scoped-connection.hpp
index 9104791..80717e5 100644
--- a/src/util/signal-scoped-connection.hpp
+++ b/src/util/signal-scoped-connection.hpp
@@ -61,6 +61,13 @@
void
disconnect();
+ /** \brief check if the connection is connected to the signal
+ * \return false when a default-constructed connection is used, the connection is released,
+ * or the connection is disconnected
+ */
+ bool
+ isConnected() const;
+
/** \brief releases the connection so that it won't be disconnected
* when this ScopedConnection is destructed
*/
diff --git a/tests/unit-tests/util/signal.cpp b/tests/unit-tests/util/signal.cpp
index f538629..df137fe 100644
--- a/tests/unit-tests/util/signal.cpp
+++ b/tests/unit-tests/util/signal.cpp
@@ -164,12 +164,17 @@
int hit = 0;
Connection c1 = so.sig.connect([&hit] { ++hit; });
+ BOOST_CHECK_EQUAL(c1.isConnected(), true);
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit, 1); // handler called
Connection c2 = c1; // make a copy
+ BOOST_CHECK_EQUAL(c2.isConnected(), true);
+ BOOST_CHECK_EQUAL(c1.isConnected(), true);
c2.disconnect();
+ BOOST_CHECK_EQUAL(c2.isConnected(), false);
+ BOOST_CHECK_EQUAL(c1.isConnected(), false);
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit, 1); // handler not called
@@ -187,7 +192,9 @@
so->emitSignal(sig);
BOOST_CHECK_EQUAL(hit, 1); // handler called
+ BOOST_CHECK_EQUAL(connection.isConnected(), true);
so.reset(); // destruct EventEmitter
+ BOOST_CHECK_EQUAL(connection.isConnected(), false);
BOOST_CHECK_NO_THROW(connection.disconnect());
}
@@ -199,6 +206,7 @@
{
ScopedConnection sc = so.sig.connect([&hit] { ++hit; });
+ BOOST_CHECK_EQUAL(sc.isConnected(), true);
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit, 1); // handler called
@@ -215,11 +223,13 @@
int hit1 = 0, hit2 = 0;
ScopedConnection sc = so.sig.connect([&hit1] { ++hit1; });
+ BOOST_CHECK_EQUAL(sc.isConnected(), true);
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit1, 1); // handler1 called
sc = so.sig.connect([&hit2] { ++hit2; }); // handler1 is disconnected
+ BOOST_CHECK_EQUAL(sc.isConnected(), true);
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit1, 1); // handler1 not called
@@ -236,15 +246,22 @@
ScopedConnection sc(c1);
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit, 1); // handler called
+ BOOST_CHECK_EQUAL(c1.isConnected(), true);
+ BOOST_CHECK_EQUAL(sc.isConnected(), true);
sc = c1; // assign same connection
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit, 2); // handler called
+ BOOST_CHECK_EQUAL(c1.isConnected(), true);
+ BOOST_CHECK_EQUAL(sc.isConnected(), true);
Connection c2 = c1;
sc = c2; // assign a copy of same connection
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit, 3); // handler called
+ BOOST_CHECK_EQUAL(c1.isConnected(), true);
+ BOOST_CHECK_EQUAL(c2.isConnected(), true);
+ BOOST_CHECK_EQUAL(sc.isConnected(), true);
}
BOOST_AUTO_TEST_CASE(AutoDisconnectRelease)
@@ -257,8 +274,10 @@
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit, 1); // handler called
+ BOOST_CHECK_EQUAL(sc.isConnected(), true);
sc.release();
+ BOOST_CHECK_EQUAL(sc.isConnected(), false);
// sc goes out of scope, but not disconnecting
}
@@ -277,8 +296,11 @@
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit, 1); // handler called
+ BOOST_CHECK_EQUAL(sc.isConnected(), true);
sc2.reset(new ScopedConnection(std::move(sc)));
+ BOOST_CHECK_EQUAL(sc.isConnected(), false);
+ BOOST_CHECK_EQUAL(sc2->isConnected(), true);
// sc goes out of scope, but not disconnecting
}
@@ -307,7 +329,9 @@
int hit = 0;
Connection conn = so.sig.connectSingleShot([&hit] { ++hit; });
+ BOOST_CHECK_EQUAL(conn.isConnected(), true);
conn.disconnect();
+ BOOST_CHECK_EQUAL(conn.isConnected(), false);
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit, 0); // handler not called
@@ -356,9 +380,12 @@
int hit = 0;
Connection connection;
+ BOOST_CHECK_EQUAL(connection.isConnected(), false);
connection = so.sig.connect(bind([&] (SignalOwner0& so) {
++hit;
+ BOOST_CHECK_EQUAL(connection.isConnected(), true);
connection.disconnect();
+ BOOST_CHECK_EQUAL(connection.isConnected(), false);
BOOST_CHECK_EQUAL(so.isSigEmpty(), false); // disconnecting hasn't taken effect
}, ref(so)));
// Bug 2302: 'so' needs to be bound to the handler;
@@ -366,6 +393,7 @@
so.emitSignal(sig);
BOOST_CHECK_EQUAL(hit, 1); // handler called
+ BOOST_CHECK_EQUAL(connection.isConnected(), false);
// disconnecting takes effect
BOOST_CHECK_EQUAL(so.isSigEmpty(), true);