From 7f5d87dcd54481c7fe190a340a1d0850fdf1adf7 Mon Sep 17 00:00:00 2001 From: Chris Thrasher Date: Sun, 26 Nov 2023 13:36:19 -0700 Subject: [PATCH] Add move semantics to `sf::Context` --- include/SFML/Window/Context.hpp | 12 +++++++ src/SFML/Window/Context.cpp | 30 ++++++++++++---- test/Window/Context.test.cpp | 63 +++++++++++++++++++++++++++++++-- 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/include/SFML/Window/Context.hpp b/include/SFML/Window/Context.hpp index 6c3499f7d..377337610 100644 --- a/include/SFML/Window/Context.hpp +++ b/include/SFML/Window/Context.hpp @@ -84,6 +84,18 @@ public: //////////////////////////////////////////////////////////// Context& operator=(const Context&) = delete; + //////////////////////////////////////////////////////////// + /// \brief Move constructor + /// + //////////////////////////////////////////////////////////// + Context(Context&& context) noexcept; + + //////////////////////////////////////////////////////////// + /// \brief Move assignment + /// + //////////////////////////////////////////////////////////// + Context& operator=(Context&& context) noexcept; + //////////////////////////////////////////////////////////// /// \brief Activate or deactivate explicitly the context /// diff --git a/src/SFML/Window/Context.cpp b/src/SFML/Window/Context.cpp index 6ee6f5b3e..3db168380 100644 --- a/src/SFML/Window/Context.cpp +++ b/src/SFML/Window/Context.cpp @@ -49,19 +49,37 @@ namespace sf Context::Context() : m_context(priv::GlContext::create()) { if (!setActive(true)) - { err() << "Failed to set context as active during construction" << std::endl; - } } //////////////////////////////////////////////////////////// Context::~Context() { - if (!setActive(false)) - { + if (m_context && !setActive(false)) err() << "Failed to set context as inactive during destruction" << std::endl; - } +} + + +//////////////////////////////////////////////////////////// +Context::Context(Context&& context) noexcept : m_context(std::move(context.m_context)) +{ + if (&context == ContextImpl::currentContext) + ContextImpl::currentContext = this; +} + + +//////////////////////////////////////////////////////////// +Context& Context::operator=(Context&& context) noexcept +{ + if (this == &context) + return *this; + + m_context = std::move(context.m_context); + if (&context == ContextImpl::currentContext) + ContextImpl::currentContext = this; + + return *this; } @@ -125,9 +143,7 @@ Context::Context(const ContextSettings& settings, const Vector2u& size) : m_context(priv::GlContext::create(settings, size)) { if (!setActive(true)) - { err() << "Failed to set context as active during construction" << std::endl; - } } } // namespace sf diff --git a/test/Window/Context.test.cpp b/test/Window/Context.test.cpp index 4c9067775..8ab84a667 100644 --- a/test/Window/Context.test.cpp +++ b/test/Window/Context.test.cpp @@ -21,8 +21,8 @@ TEST_CASE("[Window] sf::Context", runDisplayTests()) { STATIC_CHECK(!std::is_copy_constructible_v); STATIC_CHECK(!std::is_copy_assignable_v); - STATIC_CHECK(!std::is_nothrow_move_constructible_v); - STATIC_CHECK(!std::is_nothrow_move_assignable_v); + STATIC_CHECK(std::is_nothrow_move_constructible_v); + STATIC_CHECK(std::is_nothrow_move_assignable_v); } SECTION("Construction") @@ -33,6 +33,65 @@ TEST_CASE("[Window] sf::Context", runDisplayTests()) CHECK(sf::Context::getActiveContextId() != 0); } + SECTION("Move semantics") + { + SECTION("Construction") + { + SECTION("From active context") + { + sf::Context movedContext; + const sf::Context context(std::move(movedContext)); + CHECK(context.getSettings().majorVersion > 0); + CHECK(sf::Context::getActiveContext() == &context); + CHECK(sf::Context::getActiveContextId() != 0); + } + + SECTION("From inactive context") + { + sf::Context movedContext; + CHECK(movedContext.setActive(false)); + CHECK(sf::Context::getActiveContext() == nullptr); + CHECK(sf::Context::getActiveContextId() == 0); + + const sf::Context context(std::move(movedContext)); + CHECK(context.getSettings().majorVersion > 0); + CHECK(sf::Context::getActiveContext() == nullptr); + CHECK(sf::Context::getActiveContextId() == 0); + } + } + + SECTION("Assignment") + { + SECTION("From active context") + { + sf::Context movedContext; + sf::Context context; + CHECK(movedContext.setActive(true)); + CHECK(sf::Context::getActiveContext() == &movedContext); + CHECK(sf::Context::getActiveContextId() != 0); + + context = std::move(movedContext); + CHECK(context.getSettings().majorVersion > 0); + CHECK(sf::Context::getActiveContext() == &context); + CHECK(sf::Context::getActiveContextId() != 0); + } + + SECTION("From inactive context") + { + sf::Context movedContext; + CHECK(movedContext.setActive(false)); + CHECK(sf::Context::getActiveContext() == nullptr); + CHECK(sf::Context::getActiveContextId() == 0); + + sf::Context context; + context = std::move(movedContext); + CHECK(context.getSettings().majorVersion > 0); + CHECK(sf::Context::getActiveContext() == nullptr); + CHECK(sf::Context::getActiveContextId() == 0); + } + } + } + SECTION("setActive()") { sf::Context context;