more on sigh, connection and scoped_connection

This commit is contained in:
Michele Caini
2019-07-04 15:04:17 +02:00
parent 00be58e65d
commit 0bea153aa0
2 changed files with 121 additions and 5 deletions

View File

@@ -160,19 +160,55 @@ class connection {
{}
public:
/*! Default constructor. */
connection() = default;
/*! @brief Default copy constructor. */
connection(const connection &) = default;
/*! @brief Default move constructor. */
connection(connection &&) = default;
/**
* @brief Default move constructor.
* @param other The instance to move from.
*/
connection(connection &&other)
: connection{}
{
std::swap(disconnect, other.disconnect);
std::swap(signal, other.signal);
}
/*! @brief Default copy assignment operator. @return This connection. */
connection & operator=(const connection &) = default;
/*! @brief Default move assignment operator. @return This connection. */
connection & operator=(connection &&) = default;
/**
* @brief Default move assignment operator.
* @param other The instance to move from.
* @return This connection.
*/
connection & operator=(connection &&other) {
if(this != &other) {
auto tmp{std::move(other)};
disconnect = tmp.disconnect;
signal = tmp.signal;
}
return *this;
}
/**
* @brief Checks whether a connection is properly initialized.
* @return True if the connection is properly initialized, false otherwise.
*/
explicit operator bool() const ENTT_NOEXCEPT {
return static_cast<bool>(disconnect);
}
/*! @brief Breaks the connection. */
void release() {
disconnect(signal);
if(disconnect) {
disconnect(signal);
disconnect.reset();
}
}
private:
@@ -191,6 +227,9 @@ private:
* when it goes out of scope.
*/
struct scoped_connection: private connection {
/*! Default constructor. */
scoped_connection() = default;
/**
* @brief Constructs a scoped connection from a basic connection.
* @param conn A valid connection object.
@@ -199,10 +238,51 @@ struct scoped_connection: private connection {
: connection{conn}
{}
/*! @brief Default copy constructor, deleted on purpose. */
scoped_connection(const scoped_connection &) = delete;
/*! @brief Default move constructor. */
scoped_connection(scoped_connection &&) = default;
/*! @brief Automatically breaks the link on destruction. */
~scoped_connection() {
connection::release();
}
/**
* @brief Default copy assignment operator, deleted on purpose.
* @return This scoped connection.
*/
scoped_connection & operator=(const scoped_connection &) = delete;
/**
* @brief Default move assignment operator.
* @return This scoped connection.
*/
scoped_connection & operator=(scoped_connection &&) = default;
/**
* @brief Copies a connection.
* @param other The connection object to copy.
* @return This scoped connection.
*/
scoped_connection & operator=(const connection &other) {
static_cast<connection &>(*this) = other;
return *this;
}
/**
* @brief Moves a connection.
* @param other The connection object to move.
* @return This scoped connection.
*/
scoped_connection & operator=(connection &&other) {
static_cast<connection &>(*this) = std::move(other);
return *this;
}
using connection::operator bool;
using connection::release;
};

View File

@@ -199,6 +199,7 @@ TEST(SigH, Connection) {
sigh.publish(v);
ASSERT_FALSE(sigh.empty());
ASSERT_TRUE(conn);
ASSERT_EQ(42, v);
v = 0;
@@ -206,6 +207,7 @@ TEST(SigH, Connection) {
sigh.publish(v);
ASSERT_TRUE(sigh.empty());
ASSERT_FALSE(conn);
ASSERT_EQ(0, v);
}
@@ -222,6 +224,7 @@ TEST(SigH, ScopedConnection) {
ASSERT_FALSE(sigh.empty());
ASSERT_TRUE(listener.k);
ASSERT_TRUE(conn);
}
sigh.publish(42);
@@ -230,6 +233,39 @@ TEST(SigH, ScopedConnection) {
ASSERT_TRUE(listener.k);
}
TEST(SigH, ScopedConnectionConstructorsAndOperators) {
sigh_listener listener;
entt::sigh<void(int)> sigh;
entt::sink sink{sigh};
entt::scoped_connection conn;
{
ASSERT_FALSE(listener.k);
ASSERT_FALSE(conn);
auto basic = sink.connect<&sigh_listener::g>(&listener);
entt::scoped_connection inner = std::move(basic);
sigh.publish(42);
ASSERT_FALSE(sigh.empty());
ASSERT_TRUE(listener.k);
ASSERT_TRUE(inner);
conn = std::move(inner);
ASSERT_FALSE(inner);
ASSERT_TRUE(conn);
}
ASSERT_TRUE(conn);
conn.release();
sigh.publish(42);
ASSERT_TRUE(sigh.empty());
ASSERT_TRUE(listener.k);
}
TEST(SigH, ConstNonConstNoExcept) {
entt::sigh<void()> sigh;
entt::sink sink{sigh};