From 8ec899a8e7ac20278f0c06fb446af2fc28e66f88 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 13 Aug 2021 15:35:05 +0200 Subject: [PATCH] sigh: make scoped_connection move constructible/assignable (close #760) --- src/entt/signal/sigh.hpp | 18 ++++++++++++++ test/entt/signal/sigh.cpp | 51 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/entt/signal/sigh.hpp b/src/entt/signal/sigh.hpp index bcece0c5f..95edb71fd 100644 --- a/src/entt/signal/sigh.hpp +++ b/src/entt/signal/sigh.hpp @@ -208,6 +208,14 @@ struct scoped_connection { /*! @brief Default copy constructor, deleted on purpose. */ scoped_connection(const scoped_connection &) = delete; + /** + * @brief Move constructor. + * @param other The scoped connection to move from. + */ + scoped_connection(scoped_connection &&other) ENTT_NOEXCEPT + : conn{std::exchange(other.conn, {})} + {} + /*! @brief Automatically breaks the link on destruction. */ ~scoped_connection() { conn.release(); @@ -219,6 +227,16 @@ struct scoped_connection { */ scoped_connection & operator=(const scoped_connection &) = delete; + /** + * @brief Move assignment operator. + * @param other The scoped connection to move from. + * @return This scoped connection. + */ + scoped_connection & operator=(scoped_connection &&other) ENTT_NOEXCEPT { + conn = std::exchange(other.conn, {}); + return *this; + } + /** * @brief Acquires a connection. * @param other The connection object to acquire. diff --git a/test/entt/signal/sigh.cpp b/test/entt/signal/sigh.cpp index a768bf979..f7ae5c6c4 100644 --- a/test/entt/signal/sigh.cpp +++ b/test/entt/signal/sigh.cpp @@ -11,7 +11,7 @@ struct sigh_listener { void i() {} // useless definition just because msvc does weird things if both are empty - void l() { k = k && k; } + void l() { k = true && k; } bool k{false}; }; @@ -277,6 +277,55 @@ TEST_F(SigH, ScopedConnection) { ASSERT_TRUE(listener.k); } +TEST_F(SigH, ScopedConnectionMove) { + sigh_listener listener; + entt::sigh sigh; + entt::sink sink{sigh}; + + entt::scoped_connection outer{sink.connect<&sigh_listener::g>(listener)}; + + ASSERT_FALSE(sigh.empty()); + ASSERT_TRUE(outer); + + { + entt::scoped_connection inner{std::move(outer)}; + + ASSERT_FALSE(listener.k); + ASSERT_FALSE(outer); + ASSERT_TRUE(inner); + + sigh.publish(42); + + ASSERT_TRUE(listener.k); + } + + ASSERT_TRUE(sigh.empty()); + + outer = sink.connect<&sigh_listener::g>(listener); + + ASSERT_FALSE(sigh.empty()); + ASSERT_TRUE(outer); + + { + entt::scoped_connection inner{}; + + ASSERT_TRUE(listener.k); + ASSERT_TRUE(outer); + ASSERT_FALSE(inner); + + inner = std::move(outer); + + ASSERT_FALSE(outer); + ASSERT_TRUE(inner); + + sigh.publish(42); + + ASSERT_FALSE(listener.k); + } + + ASSERT_TRUE(sigh.empty()); +} + TEST_F(SigH, ScopedConnectionConstructorsAndOperators) { sigh_listener listener; entt::sigh sigh;