Remove default empty state of sf::Cursor

This commit is contained in:
Chris Thrasher 2024-05-20 19:04:40 -06:00
parent 9f71ad3b24
commit 53ade4baf1
3 changed files with 47 additions and 65 deletions

View File

@ -32,6 +32,7 @@
#include <SFML/System/Vector2.hpp> #include <SFML/System/Vector2.hpp>
#include <memory> #include <memory>
#include <optional>
#include <cstdint> #include <cstdint>
@ -110,17 +111,6 @@ public:
NotAllowed //!< Action not allowed cursor 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 /// \brief Destructor
/// ///
@ -180,11 +170,11 @@ public:
/// \param pixels Array of pixels of the image /// \param pixels Array of pixels of the image
/// \param size Width and height of the image /// \param size Width and height of the image
/// \param hotspot (x,y) location of the hotspot /// \param hotspot (x,y) location of the hotspot
/// \return true if the cursor was successfully loaded; /// \return Cursor if the cursor was successfully loaded;
/// false otherwise /// `std::nullopt` otherwise
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] bool loadFromPixels(const std::uint8_t* pixels, Vector2u size, Vector2u hotspot); [[nodiscard]] static std::optional<Cursor> loadFromPixels(const std::uint8_t* pixels, Vector2u size, Vector2u hotspot);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create a native system cursor /// \brief Create a native system cursor
@ -195,16 +185,22 @@ public:
/// the operating system. /// the operating system.
/// ///
/// \param type Native system cursor type /// \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; /// natively supported by the operating system;
/// false otherwise /// `std::nullopt` otherwise
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] bool loadFromSystem(Type type); [[nodiscard]] static std::optional<Cursor> loadFromSystem(Type type);
private: private:
friend class WindowBase; friend class WindowBase;
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
Cursor();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get access to the underlying implementation /// \brief Get access to the underlying implementation
/// ///

View File

@ -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> Cursor::loadFromPixels(const std::uint8_t* pixels, Vector2u size, Vector2u hotspot)
{ {
if ((pixels == nullptr) || (size.x == 0) || (size.y == 0)) if ((pixels == nullptr) || (size.x == 0) || (size.y == 0))
return false; return std::nullopt;
else
return m_impl->loadFromPixels(pixels, size, hotspot); Cursor cursor;
if (!cursor.m_impl->loadFromPixels(pixels, size, hotspot))
return std::nullopt;
return cursor;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool Cursor::loadFromSystem(Type type) std::optional<Cursor> Cursor::loadFromSystem(Type type)
{ {
return m_impl->loadFromSystem(type); Cursor cursor;
if (!cursor.m_impl->loadFromSystem(type))
return std::nullopt;
return cursor;
} }

View File

@ -10,60 +10,38 @@ TEST_CASE("[Window] sf::Cursor", runDisplayTests())
{ {
SECTION("Type traits") SECTION("Type traits")
{ {
STATIC_CHECK(!std::is_default_constructible_v<sf::Cursor>);
STATIC_CHECK(!std::is_copy_constructible_v<sf::Cursor>); STATIC_CHECK(!std::is_copy_constructible_v<sf::Cursor>);
STATIC_CHECK(!std::is_copy_assignable_v<sf::Cursor>); STATIC_CHECK(!std::is_copy_assignable_v<sf::Cursor>);
STATIC_CHECK(std::is_nothrow_move_constructible_v<sf::Cursor>); STATIC_CHECK(std::is_nothrow_move_constructible_v<sf::Cursor>);
STATIC_CHECK(std::is_nothrow_move_assignable_v<sf::Cursor>); STATIC_CHECK(std::is_nothrow_move_assignable_v<sf::Cursor>);
} }
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()") SECTION("loadFromPixels()")
{ {
sf::Cursor cursor; static constexpr std::array<std::uint8_t, 4> pixels{};
std::array<std::uint8_t, 4> pixels{};
CHECK(!cursor.loadFromPixels(nullptr, {}, {})); CHECK(!sf::Cursor::loadFromPixels(nullptr, {}, {}));
CHECK(!cursor.loadFromPixels(pixels.data(), {0, 1}, {})); CHECK(!sf::Cursor::loadFromPixels(pixels.data(), {0, 1}, {}));
CHECK(!cursor.loadFromPixels(pixels.data(), {1, 0}, {})); CHECK(!sf::Cursor::loadFromPixels(pixels.data(), {1, 0}, {}));
CHECK(cursor.loadFromPixels(pixels.data(), {1, 1}, {})); CHECK(sf::Cursor::loadFromPixels(pixels.data(), {1, 1}, {}));
} }
SECTION("loadFromSystem()") SECTION("loadFromSystem()")
{ {
sf::Cursor cursor; CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::Hand));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::Hand)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeHorizontal));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeHorizontal)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeVertical));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeVertical)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeLeft));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeLeft)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeRight));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeRight)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeTop));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeTop)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeBottom));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeBottom)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeTopLeft));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeTopLeft)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeTopRight));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeTopRight)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeBottomLeft));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeBottomLeft)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::SizeBottomRight));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::SizeBottomRight)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::Cross));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::Cross)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::Help));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::Help)); CHECK(sf::Cursor::loadFromSystem(sf::Cursor::Type::NotAllowed));
CHECK(cursor.loadFromSystem(sf::Cursor::Type::NotAllowed));
} }
} }