Add move semantics to sf::VertexBuffer

This commit is contained in:
Chris Thrasher 2024-09-20 17:15:31 -05:00
parent c38b98c653
commit caf843c85c
No known key found for this signature in database
GPG Key ID: 56FB686C9DFC8E2C
3 changed files with 104 additions and 28 deletions

View File

@ -107,6 +107,12 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
VertexBuffer(PrimitiveType type, Usage usage); VertexBuffer(PrimitiveType type, Usage usage);
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
~VertexBuffer() override;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Copy constructor /// \brief Copy constructor
/// ///
@ -116,10 +122,32 @@ public:
VertexBuffer(const VertexBuffer& copy); VertexBuffer(const VertexBuffer& copy);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Destructor /// \brief Overload of assignment operator
///
/// \param right Instance to assign
///
/// \return Reference to self
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
~VertexBuffer() override; VertexBuffer& operator=(const VertexBuffer& right);
////////////////////////////////////////////////////////////
/// \brief Move constructor
///
/// \param right Instance to move
///
////////////////////////////////////////////////////////////
VertexBuffer(VertexBuffer&& right) noexcept;
////////////////////////////////////////////////////////////
/// \brief Move assignment
///
/// \param right Instance to assign
///
/// \return Reference to self
///
////////////////////////////////////////////////////////////
VertexBuffer& operator=(VertexBuffer&& right) noexcept;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create the vertex buffer /// \brief Create the vertex buffer
@ -210,16 +238,6 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] bool update(const VertexBuffer& vertexBuffer); [[nodiscard]] bool update(const VertexBuffer& vertexBuffer);
////////////////////////////////////////////////////////////
/// \brief Overload of assignment operator
///
/// \param right Instance to assign
///
/// \return Reference to self
///
////////////////////////////////////////////////////////////
VertexBuffer& operator=(const VertexBuffer& right);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Swap the contents of this vertex buffer with those of another /// \brief Swap the contents of this vertex buffer with those of another
/// ///

View File

@ -81,6 +81,18 @@ VertexBuffer::VertexBuffer(PrimitiveType type, Usage usage) : m_primitiveType(ty
} }
////////////////////////////////////////////////////////////
VertexBuffer::~VertexBuffer()
{
if (m_buffer)
{
const TransientContextLock contextLock;
glCheck(GLEXT_glDeleteBuffers(1, &m_buffer));
}
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
VertexBuffer::VertexBuffer(const VertexBuffer& copy) : VertexBuffer::VertexBuffer(const VertexBuffer& copy) :
GlResource(copy), GlResource(copy),
@ -102,14 +114,49 @@ m_usage(copy.m_usage)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
VertexBuffer::~VertexBuffer() VertexBuffer& VertexBuffer::operator=(const VertexBuffer& right)
{ {
VertexBuffer temp(right);
swap(temp);
return *this;
}
////////////////////////////////////////////////////////////
VertexBuffer::VertexBuffer(VertexBuffer&& right) noexcept :
m_buffer(std::exchange(right.m_buffer, 0)),
m_size(std::exchange(right.m_size, 0)),
m_primitiveType(std::exchange(right.m_primitiveType, PrimitiveType::Points)),
m_usage(std::exchange(right.m_usage, Usage::Stream))
{
}
////////////////////////////////////////////////////////////
VertexBuffer& VertexBuffer::operator=(VertexBuffer&& right) noexcept
{
// Make sure we aren't moving ourselves
if (&right == this)
{
return *this;
}
if (m_buffer) if (m_buffer)
{ {
const TransientContextLock contextLock; const TransientContextLock contextLock;
glCheck(GLEXT_glDeleteBuffers(1, &m_buffer)); glCheck(GLEXT_glDeleteBuffers(1, &m_buffer));
} }
// Move the contents of right
m_buffer = std::exchange(right.m_buffer, 0);
m_size = std::exchange(right.m_size, 0);
m_primitiveType = std::exchange(right.m_primitiveType, PrimitiveType::Points);
m_usage = std::exchange(right.m_usage, Usage::Stream);
return *this;
} }
@ -258,17 +305,6 @@ bool VertexBuffer::update([[maybe_unused]] const VertexBuffer& vertexBuffer)
} }
////////////////////////////////////////////////////////////
VertexBuffer& VertexBuffer::operator=(const VertexBuffer& right)
{
VertexBuffer temp(right);
swap(temp);
return *this;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void VertexBuffer::swap(VertexBuffer& right) noexcept void VertexBuffer::swap(VertexBuffer& right) noexcept
{ {

View File

@ -16,10 +16,8 @@ TEST_CASE("[Graphics] sf::VertexBuffer", "[.display]")
{ {
STATIC_CHECK(std::is_copy_constructible_v<sf::VertexBuffer>); STATIC_CHECK(std::is_copy_constructible_v<sf::VertexBuffer>);
STATIC_CHECK(std::is_copy_assignable_v<sf::VertexBuffer>); STATIC_CHECK(std::is_copy_assignable_v<sf::VertexBuffer>);
STATIC_CHECK(std::is_move_constructible_v<sf::VertexBuffer>); STATIC_CHECK(std::is_nothrow_move_constructible_v<sf::VertexBuffer>);
STATIC_CHECK(!std::is_nothrow_move_constructible_v<sf::VertexBuffer>); STATIC_CHECK(std::is_nothrow_move_assignable_v<sf::VertexBuffer>);
STATIC_CHECK(std::is_move_assignable_v<sf::VertexBuffer>);
STATIC_CHECK(!std::is_nothrow_move_assignable_v<sf::VertexBuffer>);
STATIC_CHECK(std::is_nothrow_swappable_v<sf::VertexBuffer>); STATIC_CHECK(std::is_nothrow_swappable_v<sf::VertexBuffer>);
} }
@ -90,6 +88,30 @@ TEST_CASE("[Graphics] sf::VertexBuffer", "[.display]")
} }
} }
SECTION("Move semantics")
{
SECTION("Construction")
{
sf::VertexBuffer vertexBuffer(sf::PrimitiveType::LineStrip, sf::VertexBuffer::Usage::Dynamic);
const sf::VertexBuffer vertexBufferCopy(std::move(vertexBuffer));
CHECK(vertexBufferCopy.getVertexCount() == 0);
CHECK(vertexBufferCopy.getNativeHandle() == 0);
CHECK(vertexBufferCopy.getPrimitiveType() == sf::PrimitiveType::LineStrip);
CHECK(vertexBufferCopy.getUsage() == sf::VertexBuffer::Usage::Dynamic);
}
SECTION("Assignment")
{
sf::VertexBuffer vertexBuffer(sf::PrimitiveType::LineStrip, sf::VertexBuffer::Usage::Dynamic);
sf::VertexBuffer vertexBufferCopy;
vertexBufferCopy = std::move(vertexBuffer);
CHECK(vertexBufferCopy.getVertexCount() == 0);
CHECK(vertexBufferCopy.getNativeHandle() == 0);
CHECK(vertexBufferCopy.getPrimitiveType() == sf::PrimitiveType::LineStrip);
CHECK(vertexBufferCopy.getUsage() == sf::VertexBuffer::Usage::Dynamic);
}
}
SECTION("create()") SECTION("create()")
{ {
sf::VertexBuffer vertexBuffer; sf::VertexBuffer vertexBuffer;