From 53ade4baf18d8880e6dec97abf4e6f9d8bd8f2b3 Mon Sep 17 00:00:00 2001 From: Chris Thrasher Date: Mon, 20 May 2024 19:04:40 -0600 Subject: [PATCH] Remove default empty state of `sf::Cursor` --- include/SFML/Window/Cursor.hpp | 30 +++++++--------- src/SFML/Window/Cursor.cpp | 20 +++++++---- test/Window/Cursor.test.cpp | 62 +++++++++++----------------------- 3 files changed, 47 insertions(+), 65 deletions(-) diff --git a/include/SFML/Window/Cursor.hpp b/include/SFML/Window/Cursor.hpp index e721f01dc..5bd955632 100644 --- a/include/SFML/Window/Cursor.hpp +++ b/include/SFML/Window/Cursor.hpp @@ -32,6 +32,7 @@ #include #include +#include #include @@ -110,17 +111,6 @@ public: NotAllowed //!< Action not allowed cursor }; - //////////////////////////////////////////////////////////// - /// \brief Default constructor - /// - /// This constructor doesn't actually create the cursor; - /// initially the new instance is invalid and must not be - /// used until either loadFromPixels() or loadFromSystem() - /// is called and successfully created a cursor. - /// - //////////////////////////////////////////////////////////// - Cursor(); - //////////////////////////////////////////////////////////// /// \brief Destructor /// @@ -180,11 +170,11 @@ public: /// \param pixels Array of pixels of the image /// \param size Width and height of the image /// \param hotspot (x,y) location of the hotspot - /// \return true if the cursor was successfully loaded; - /// false otherwise + /// \return Cursor if the cursor was successfully loaded; + /// `std::nullopt` otherwise /// //////////////////////////////////////////////////////////// - [[nodiscard]] bool loadFromPixels(const std::uint8_t* pixels, Vector2u size, Vector2u hotspot); + [[nodiscard]] static std::optional loadFromPixels(const std::uint8_t* pixels, Vector2u size, Vector2u hotspot); //////////////////////////////////////////////////////////// /// \brief Create a native system cursor @@ -195,16 +185,22 @@ public: /// the operating system. /// /// \param type Native system cursor type - /// \return true if and only if the corresponding cursor is + /// \return Cursor if and only if the corresponding cursor is /// natively supported by the operating system; - /// false otherwise + /// `std::nullopt` otherwise /// //////////////////////////////////////////////////////////// - [[nodiscard]] bool loadFromSystem(Type type); + [[nodiscard]] static std::optional loadFromSystem(Type type); private: friend class WindowBase; + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + //////////////////////////////////////////////////////////// + Cursor(); + //////////////////////////////////////////////////////////// /// \brief Get access to the underlying implementation /// diff --git a/src/SFML/Window/Cursor.cpp b/src/SFML/Window/Cursor.cpp index bed8ea25f..d5a02810e 100644 --- a/src/SFML/Window/Cursor.cpp +++ b/src/SFML/Window/Cursor.cpp @@ -54,19 +54,27 @@ Cursor& Cursor::operator=(Cursor&&) noexcept = default; //////////////////////////////////////////////////////////// -bool Cursor::loadFromPixels(const std::uint8_t* pixels, Vector2u size, Vector2u hotspot) +std::optional Cursor::loadFromPixels(const std::uint8_t* pixels, Vector2u size, Vector2u hotspot) { if ((pixels == nullptr) || (size.x == 0) || (size.y == 0)) - return false; - else - return m_impl->loadFromPixels(pixels, size, hotspot); + return std::nullopt; + + Cursor cursor; + if (!cursor.m_impl->loadFromPixels(pixels, size, hotspot)) + return std::nullopt; + + return cursor; } //////////////////////////////////////////////////////////// -bool Cursor::loadFromSystem(Type type) +std::optional Cursor::loadFromSystem(Type type) { - return m_impl->loadFromSystem(type); + Cursor cursor; + if (!cursor.m_impl->loadFromSystem(type)) + return std::nullopt; + + return cursor; } diff --git a/test/Window/Cursor.test.cpp b/test/Window/Cursor.test.cpp index 751d4d853..c3f4bad09 100644 --- a/test/Window/Cursor.test.cpp +++ b/test/Window/Cursor.test.cpp @@ -10,60 +10,38 @@ TEST_CASE("[Window] sf::Cursor", runDisplayTests()) { SECTION("Type traits") { + STATIC_CHECK(!std::is_default_constructible_v); 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); } - SECTION("Construction") - { - const sf::Cursor cursor; - } - - SECTION("Move semantics") - { - SECTION("Construction") - { - sf::Cursor movedCursor; - const sf::Cursor cursor(std::move(movedCursor)); - } - - SECTION("Assignment") - { - sf::Cursor movedCursor; - sf::Cursor cursor; - cursor = std::move(movedCursor); - } - } - SECTION("loadFromPixels()") { - sf::Cursor cursor; - std::array pixels{}; + static constexpr std::array pixels{}; - CHECK(!cursor.loadFromPixels(nullptr, {}, {})); - CHECK(!cursor.loadFromPixels(pixels.data(), {0, 1}, {})); - CHECK(!cursor.loadFromPixels(pixels.data(), {1, 0}, {})); - CHECK(cursor.loadFromPixels(pixels.data(), {1, 1}, {})); + CHECK(!sf::Cursor::loadFromPixels(nullptr, {}, {})); + CHECK(!sf::Cursor::loadFromPixels(pixels.data(), {0, 1}, {})); + CHECK(!sf::Cursor::loadFromPixels(pixels.data(), {1, 0}, {})); + CHECK(sf::Cursor::loadFromPixels(pixels.data(), {1, 1}, {})); } SECTION("loadFromSystem()") { - sf::Cursor cursor; - CHECK(cursor.loadFromSystem(sf::Cursor::Type::Hand)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeHorizontal)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeVertical)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeLeft)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeRight)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeTop)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeBottom)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeTopLeft)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeTopRight)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeBottomLeft)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeBottomRight)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::Cross)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::Help)); - CHECK(cursor.loadFromSystem(sf::Cursor::Type::NotAllowed)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::Hand)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeHorizontal)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeVertical)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeLeft)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeRight)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeTop)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeBottom)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeTopLeft)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeTopRight)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeBottomLeft)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeBottomRight)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::Cross)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::Help)); + CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::NotAllowed)); } }